Merge branch 'master' of gitorious.org:electrum/electrum
This commit is contained in:
commit
2a98d416ec
|
@ -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 = []
|
||||||
|
|
|
@ -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,19 +1124,39 @@ 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"
|
||||||
|
elif self.wallet.interface.is_connected:
|
||||||
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))
|
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.wallet.interface.blocks == 0:
|
||||||
|
self.status_image.set_from_stock(gtk.STOCK_STOP, gtk.ICON_SIZE_MENU)
|
||||||
|
text = "Server not ready"
|
||||||
|
elif not self.wallet.interface.was_polled:
|
||||||
|
self.status_image.set_from_stock(gtk.STOCK_STOP, gtk.ICON_SIZE_MENU)
|
||||||
|
text = "Synchronizing..."
|
||||||
|
else:
|
||||||
|
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:
|
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()
|
||||||
for address in self.wallet.all_addresses():
|
for address in self.wallet.all_addresses():
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
import random, socket, ast
|
import random, socket, ast
|
||||||
|
|
||||||
|
|
||||||
|
import thread, traceback, sys, time
|
||||||
|
|
||||||
|
|
||||||
class Interface:
|
class Interface:
|
||||||
|
@ -31,6 +32,8 @@ 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
|
||||||
|
self.was_polled = False # True after the first poll
|
||||||
|
|
||||||
def set_port(self, port_number):
|
def set_port(self, port_number):
|
||||||
self.port = port_number
|
self.port = port_number
|
||||||
|
@ -100,9 +103,12 @@ class Interface:
|
||||||
blocks, changed_addr = ast.literal_eval( out )
|
blocks, changed_addr = ast.literal_eval( out )
|
||||||
if blocks == -1: raise BaseException("session not found")
|
if blocks == -1: raise BaseException("session not found")
|
||||||
self.blocks = int(blocks)
|
self.blocks = int(blocks)
|
||||||
|
if changed_addr: self.was_updated = True
|
||||||
|
self.was_polled = True
|
||||||
return changed_addr
|
return changed_addr
|
||||||
|
|
||||||
def new_session(self, addresses, version):
|
def new_session(self, addresses, version):
|
||||||
|
self.was_polled = False
|
||||||
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 )
|
||||||
|
|
||||||
|
@ -113,3 +119,72 @@ 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 socket.error:
|
||||||
|
print "Not connected"
|
||||||
|
time.sleep(self.poll_interval())
|
||||||
|
continue
|
||||||
|
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() )
|
||||||
|
|
||||||
|
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,))
|
||||||
|
|
|
@ -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…
Reference in New Issue