Browse Source

move update thread into the interface

283
thomasv 13 years ago
parent
commit
ee396a0633
  1. 15
      client/electrum
  2. 90
      client/gui.py
  3. 69
      client/interface.py
  4. 17
      client/wallet.py

15
client/electrum

@ -61,6 +61,7 @@ if __name__ == '__main__':
import gui import gui
gui.init_wallet(wallet) gui.init_wallet(wallet)
gui = gui.BitcoinGUI(wallet) gui = gui.BitcoinGUI(wallet)
interface.start(wallet)
if re.match('^bitcoin:', cmd): if re.match('^bitcoin:', cmd):
@ -111,12 +112,12 @@ if __name__ == '__main__':
else: else:
password = None password = None
host = raw_input("server (default:%s):"%wallet.interface.host) host = raw_input("server (default:%s):"%interface.host)
port = raw_input("port (default:%d):"%wallet.interface.port) port = raw_input("port (default:%d):"%interface.port)
fee = raw_input("fee (default:%s):"%( str(Decimal(wallet.fee)/100000000)) ) fee = raw_input("fee (default:%s):"%( str(Decimal(wallet.fee)/100000000)) )
if fee: wallet.fee = float(fee) if fee: wallet.fee = float(fee)
if host: wallet.interface.host = host if host: interface.host = host
if port: wallet.interface.port = int(port) if port: interface.port = int(port)
seed = raw_input("if you are restoring an existing wallet, enter the seed. otherwise just press enter: ") seed = raw_input("if you are restoring an existing wallet, enter the seed. otherwise just press enter: ")
wallet.gap_limit = 5 wallet.gap_limit = 5
if seed: if seed:
@ -153,8 +154,8 @@ if __name__ == '__main__':
# open session # open session
if cmd not in ['password', 'mktx', 'history', 'label', 'contacts', 'help', 'validateaddress', 'signmessage', 'verifymessage', 'eval']: if cmd not in ['password', 'mktx', 'history', 'label', 'contacts', 'help', 'validateaddress', 'signmessage', 'verifymessage', 'eval']:
wallet.interface.new_session(wallet.all_addresses(), wallet.electrum_version) interface.new_session(wallet.all_addresses(), wallet.electrum_version)
wallet.update() interface.update_wallet(wallet)
wallet.save() wallet.save()
# commands needing password # commands needing password
@ -311,7 +312,7 @@ if __name__ == '__main__':
print "invalid key pair" print "invalid key pair"
exit(1) exit(1)
addr = wallet.imported_keys.keys()[0] addr = wallet.imported_keys.keys()[0]
wallet.history[addr] = wallet.interface.retrieve_history(addr) wallet.history[addr] = interface.retrieve_history(addr)
wallet.synchronize() wallet.synchronize()
wallet.update_tx_history() wallet.update_tx_history()
wallet.addresses = [] wallet.addresses = []

90
client/gui.py

@ -486,10 +486,8 @@ class BitcoinGUI:
show_message(msg, self.window) show_message(msg, self.window)
def __init__(self, wallet): def __init__(self, wallet):
self.error = ''
self.wallet = wallet self.wallet = wallet
self.wallet.interface.is_connected = False self.funds_error = False # True if not enough funds
self.period = 5
self.window = MyWindow(gtk.WINDOW_TOPLEVEL) self.window = MyWindow(gtk.WINDOW_TOPLEVEL)
self.window.set_title(APP_NAME + " " + self.wallet.electrum_version) 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) ) 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(update_status_bar_thread, ())
thread.start_new_thread(check_recipient_thread, ()) thread.start_new_thread(check_recipient_thread, ())
self.notebook.set_current_page(0) self.notebook.set_current_page(0)
@ -719,11 +671,11 @@ class BitcoinGUI:
self.user_fee = False self.user_fee = False
def entry_changed( entry, is_fee ): def entry_changed( entry, is_fee ):
self.funds_error = False
amount = numbify(amount_entry) amount = numbify(amount_entry)
fee = numbify(fee_entry) fee = numbify(fee_entry)
if not is_fee: fee = None if not is_fee: fee = None
if amount is None: if amount is None:
#self.fee_box.hide();
return return
inputs, total, fee = self.wallet.choose_tx_inputs( amount, fee ) inputs, total, fee = self.wallet.choose_tx_inputs( amount, fee )
if not is_fee: if not is_fee:
@ -733,12 +685,11 @@ class BitcoinGUI:
amount_entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse("#000000")) amount_entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse("#000000"))
fee_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) send_button.set_sensitive(True)
self.error = ''
else: else:
send_button.set_sensitive(False) send_button.set_sensitive(False)
amount_entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse("#cc0000")) amount_entry.modify_text(gtk.STATE_NORMAL, gtk.gdk.color_parse("#cc0000"))
fee_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) amount_entry.connect('changed', entry_changed, False)
fee_entry.connect('changed', entry_changed, True) fee_entry.connect('changed', entry_changed, True)
@ -1173,18 +1124,35 @@ class BitcoinGUI:
return vbox return vbox
def update_status_bar(self): def update_status_bar(self):
c, u = self.wallet.get_balance()
if self.wallet.interface.is_connected: if self.funds_error:
self.status_image.set_from_stock(gtk.STOCK_YES, gtk.ICON_SIZE_MENU) text = "Not enough funds"
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)) 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: else:
self.status_image.set_from_stock(gtk.STOCK_NO, gtk.ICON_SIZE_MENU) 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)) 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) ) text = "Not connected"
if u: text += "[%s unconfirmed]"%( format_satoshis(u,True) )
if self.error: text = self.error
self.status_bar.pop(self.context_id) 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): def update_receiving_tab(self):
self.recv_list.clear() self.recv_list.clear()

69
client/interface.py

@ -20,6 +20,7 @@
import random, socket, ast import random, socket, ast
import thread, traceback, sys, time
class Interface: class Interface:
@ -31,6 +32,7 @@ class Interface:
self.message = '' self.message = ''
self.set_port(50000) self.set_port(50000)
self.is_connected = False self.is_connected = False
self.was_updated = True # fixme: use a semaphore
def set_port(self, port_number): def set_port(self, port_number):
self.port = port_number self.port = port_number
@ -105,6 +107,7 @@ class Interface:
def new_session(self, addresses, version): def new_session(self, addresses, version):
out = self.handler('session.new', [ version, addresses ] ) out = self.handler('session.new', [ version, addresses ] )
self.session_id, self.message = ast.literal_eval( out ) self.session_id, self.message = ast.literal_eval( out )
self.was_updated = True
def update_session(self, addresses): def update_session(self, addresses):
out = self.handler('session.update', [ self.session_id, addresses ] ) out = self.handler('session.update', [ self.session_id, addresses ] )
@ -113,3 +116,69 @@ class Interface:
def get_servers(self): def get_servers(self):
out = self.handler('peers') out = self.handler('peers')
self.servers = map( lambda x:x[1], out ) 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,))

17
client/wallet.py

@ -573,23 +573,6 @@ class Wallet:
unconf += u unconf += u
return conf, unconf 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 ): def choose_tx_inputs( self, amount, fixed_fee ):
""" todo: minimize tx size """ """ todo: minimize tx size """

Loading…
Cancel
Save