commit ee396a063303a341c6615904561b8ac2b4531797
parent a00b1e73a2c83f1528b9ee674ecef1a57f534e82
Author: thomasv <thomasv@gitorious>
Date: Wed, 8 Feb 2012 13:37:14 +0100
move update thread into the interface
Diffstat:
4 files changed, 106 insertions(+), 85 deletions(-)
diff --git a/client/electrum b/client/electrum
@@ -61,6 +61,7 @@ if __name__ == '__main__':
import gui
gui.init_wallet(wallet)
gui = gui.BitcoinGUI(wallet)
+ interface.start(wallet)
if re.match('^bitcoin:', cmd):
@@ -111,12 +112,12 @@ if __name__ == '__main__':
else:
password = None
- host = raw_input("server (default:%s):"%wallet.interface.host)
- port = raw_input("port (default:%d):"%wallet.interface.port)
+ host = raw_input("server (default:%s):"%interface.host)
+ port = raw_input("port (default:%d):"%interface.port)
fee = raw_input("fee (default:%s):"%( str(Decimal(wallet.fee)/100000000)) )
if fee: wallet.fee = float(fee)
- if host: wallet.interface.host = host
- if port: wallet.interface.port = int(port)
+ if host: interface.host = host
+ if port: interface.port = int(port)
seed = raw_input("if you are restoring an existing wallet, enter the seed. otherwise just press enter: ")
wallet.gap_limit = 5
if seed:
@@ -153,8 +154,8 @@ if __name__ == '__main__':
# open session
if cmd not in ['password', 'mktx', 'history', 'label', 'contacts', 'help', 'validateaddress', 'signmessage', 'verifymessage', 'eval']:
- wallet.interface.new_session(wallet.all_addresses(), wallet.electrum_version)
- wallet.update()
+ interface.new_session(wallet.all_addresses(), wallet.electrum_version)
+ interface.update_wallet(wallet)
wallet.save()
# commands needing password
@@ -311,7 +312,7 @@ if __name__ == '__main__':
print "invalid key pair"
exit(1)
addr = wallet.imported_keys.keys()[0]
- wallet.history[addr] = wallet.interface.retrieve_history(addr)
+ wallet.history[addr] = interface.retrieve_history(addr)
wallet.synchronize()
wallet.update_tx_history()
wallet.addresses = []
diff --git a/client/gui.py b/client/gui.py
@@ -486,10 +486,8 @@ class BitcoinGUI:
show_message(msg, self.window)
def __init__(self, wallet):
- self.error = ''
self.wallet = wallet
- self.wallet.interface.is_connected = False
- self.period = 5
+ self.funds_error = False # True if not enough funds
self.window = MyWindow(gtk.WINDOW_TOPLEVEL)
self.window.set_title(APP_NAME + " " + self.wallet.electrum_version)
@@ -596,52 +594,6 @@ class BitcoinGUI:
gobject.idle_add( lambda: self.payto_entry.set_text(s) )
- def update_wallet_thread():
- while True:
- try:
- self.wallet.interface.is_connected = False
- self.wallet.interface.new_session(self.wallet.all_addresses(), self.wallet.electrum_version)
- self.update_session = False
- self.info.set_text( self.wallet.interface.message)
- except:
- traceback.print_exc(file=sys.stdout)
- time.sleep(self.period)
- continue
-
- get_servers_time = 0
- while True:
- try:
- if self.wallet.interface.is_connected and self.update_session:
- self.wallet.interface.update_session( self.wallet.all_addresses() )
- self.update_session = False
-
- if time.time() - get_servers_time > 5*60:
- wallet.interface.get_servers()
- get_servers_time = time.time()
-
- self.period = 15 if self.wallet.interface.use_http() else 5
- if self.wallet.update():
- self.wallet.interface.update_session( self.wallet.all_addresses() )
- gobject.idle_add( self.update_history_tab )
- gobject.idle_add( self.update_receiving_tab )
- # addressbook too...
-
- time.sleep(self.period)
- except BaseException:
- traceback.print_exc(file=sys.stdout)
- print "starting new session"
- break
- except socket.gaierror:
- self.wallet.interface.is_connected = False
- break
- except:
- self.wallet.interface.is_connected = False
- print "error"
- traceback.print_exc(file=sys.stdout)
- break
- self.error = '' if self.wallet.interface.is_connected else "Not connected"
-
- thread.start_new_thread(update_wallet_thread, ())
thread.start_new_thread(update_status_bar_thread, ())
thread.start_new_thread(check_recipient_thread, ())
self.notebook.set_current_page(0)
@@ -719,11 +671,11 @@ class BitcoinGUI:
self.user_fee = False
def entry_changed( entry, is_fee ):
+ self.funds_error = False
amount = numbify(amount_entry)
fee = numbify(fee_entry)
if not is_fee: fee = None
- if amount is None:
- #self.fee_box.hide();
+ if amount is None:
return
inputs, total, fee = self.wallet.choose_tx_inputs( amount, fee )
if not is_fee:
@@ -733,12 +685,11 @@ class BitcoinGUI:
amount_entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse("#000000"))
fee_entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse("#000000"))
send_button.set_sensitive(True)
- self.error = ''
else:
send_button.set_sensitive(False)
amount_entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse("#cc0000"))
fee_entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse("#cc0000"))
- self.error = 'Not enough funds'
+ self.funds_error = True
amount_entry.connect('changed', entry_changed, False)
fee_entry.connect('changed', entry_changed, True)
@@ -1173,18 +1124,35 @@ class BitcoinGUI:
return vbox
def update_status_bar(self):
- c, u = self.wallet.get_balance()
- if self.wallet.interface.is_connected:
- self.status_image.set_from_stock(gtk.STOCK_YES, gtk.ICON_SIZE_MENU)
- self.network_button.set_tooltip_text("Connected to %s.\n%d blocks\nresponse time: %f"%(self.wallet.interface.host, self.wallet.interface.blocks, self.wallet.interface.rtime))
+
+ if self.funds_error:
+ text = "Not enough funds"
+ elif self.wallet.interface.is_connected:
+ if self.wallet.interface.blocks > 0:
+ self.status_image.set_from_stock(gtk.STOCK_YES, gtk.ICON_SIZE_MENU)
+ self.network_button.set_tooltip_text("Connected to %s.\n%d blocks\nresponse time: %f"%(self.wallet.interface.host, self.wallet.interface.blocks, self.wallet.interface.rtime))
+ c, u = self.wallet.get_balance()
+ text = "Balance: %s "%( format_satoshis(c) )
+ if u: text += "[%s unconfirmed]"%( format_satoshis(u,True) )
+ else:
+ self.status_image.set_from_stock(gtk.STOCK_STOP, gtk.ICON_SIZE_MENU)
+ self.network_button.set_tooltip_text("Connected to %s.\n%d blocks\nresponse time: %f"%(self.wallet.interface.host, self.wallet.interface.blocks, self.wallet.interface.rtime))
+ text = "Server not ready"
else:
self.status_image.set_from_stock(gtk.STOCK_NO, gtk.ICON_SIZE_MENU)
self.network_button.set_tooltip_text("Trying to contact %s.\n%d blocks"%(self.wallet.interface.host, self.wallet.interface.blocks))
- text = "Balance: %s "%( format_satoshis(c) )
- if u: text += "[%s unconfirmed]"%( format_satoshis(u,True) )
- if self.error: text = self.error
+ text = "Not connected"
+
self.status_bar.pop(self.context_id)
- self.status_bar.push(self.context_id, text)
+ self.status_bar.push(self.context_id, text)
+
+ if self.wallet.interface.was_updated:
+ self.update_history_tab()
+ self.update_receiving_tab()
+ # addressbook too...
+ self.info.set_text( self.wallet.interface.message )
+ self.wallet.interface.was_updated = False
+
def update_receiving_tab(self):
self.recv_list.clear()
diff --git a/client/interface.py b/client/interface.py
@@ -20,6 +20,7 @@
import random, socket, ast
+import thread, traceback, sys, time
class Interface:
@@ -31,6 +32,7 @@ class Interface:
self.message = ''
self.set_port(50000)
self.is_connected = False
+ self.was_updated = True # fixme: use a semaphore
def set_port(self, port_number):
self.port = port_number
@@ -105,6 +107,7 @@ class Interface:
def new_session(self, addresses, version):
out = self.handler('session.new', [ version, addresses ] )
self.session_id, self.message = ast.literal_eval( out )
+ self.was_updated = True
def update_session(self, addresses):
out = self.handler('session.update', [ self.session_id, addresses ] )
@@ -113,3 +116,69 @@ class Interface:
def get_servers(self):
out = self.handler('peers')
self.servers = map( lambda x:x[1], out )
+
+ def poll_interval(self):
+ return 15 if self.use_http() else 5
+
+ def update_wallet(self, wallet):
+ is_new = False
+ changed_addresses = self.poll()
+ for addr, blk_hash in changed_addresses.items():
+ if wallet.status.get(addr) != blk_hash:
+ print "updating history for", addr
+ wallet.history[addr] = self.retrieve_history(addr)
+ wallet.status[addr] = blk_hash
+ is_new = True
+
+ if is_new:
+ wallet.synchronize()
+ wallet.update_tx_history()
+ wallet.save()
+ return True
+ else:
+ return False
+
+ def update_thread(self, wallet):
+ while True:
+ try:
+ self.is_connected = False
+ self.new_session(wallet.all_addresses(), wallet.electrum_version)
+ self.update_session = False
+ except:
+ traceback.print_exc(file=sys.stdout)
+ time.sleep(self.poll_interval())
+ continue
+
+ get_servers_time = 0
+ while True:
+ try:
+ if self.is_connected and self.update_session:
+ self.update_session( wallet.all_addresses() )
+ self.update_session = False
+
+ if time.time() - get_servers_time > 5*60:
+ self.get_servers()
+ get_servers_time = time.time()
+
+ # define a method to update the list
+ if self.update_wallet(wallet):
+ self.update_session( wallet.all_addresses() )
+ self.was_updated = True # for gui
+
+ time.sleep(self.poll_interval())
+ except BaseException:
+ traceback.print_exc(file=sys.stdout)
+ print "starting new session"
+ break
+ except socket.gaierror:
+ self.is_connected = False
+ break
+ except:
+ self.is_connected = False
+ print "error"
+ traceback.print_exc(file=sys.stdout)
+ break
+
+
+ def start(self, wallet):
+ thread.start_new_thread(self.update_thread, (wallet,))
diff --git a/client/wallet.py b/client/wallet.py
@@ -573,23 +573,6 @@ class Wallet:
unconf += u
return conf, unconf
- def update(self):
- is_new = False
- changed_addresses = self.interface.poll()
- for addr, blk_hash in changed_addresses.items():
- if self.status.get(addr) != blk_hash:
- print "updating history for", addr
- self.history[addr] = self.interface.retrieve_history(addr)
- self.status[addr] = blk_hash
- is_new = True
-
- if is_new:
- self.synchronize()
- self.update_tx_history()
- self.save()
- return True
- else:
- return False
def choose_tx_inputs( self, amount, fixed_fee ):
""" todo: minimize tx size """