commit 81bb04378f7f2a0d00ec0c904f110a4dba6f0143
parent d0dd8c847a2f79c1131e937ebcb8db6394722f57
Author: ThomasV <thomasv@gitorious>
Date: Fri, 30 Mar 2012 14:15:05 +0200
fix recovery procedure
Diffstat:
3 files changed, 76 insertions(+), 79 deletions(-)
diff --git a/client/gui_qt.py b/client/gui_qt.py
@@ -839,15 +839,11 @@ class ElectrumWindow(QMainWindow):
status = "Connected to %s:%d\n%d blocks\nresponse time: %f"%(interface.host, interface.port, wallet.blocks, interface.rtime)
else:
status = "Not connected"
- host = wallet.host
- port = wallet.port
- protocol = wallet.protocol
+ server = wallet.server
else:
import random
status = "Please choose a server."
- host = random.choice( interface.servers )
- port = wallet.port
- protocol = 's'
+ server = random.choice( interface.servers )
d = QDialog(parent)
d.setModal(1)
@@ -867,7 +863,7 @@ class ElectrumWindow(QMainWindow):
hbox = QHBoxLayout()
host_line = QLineEdit()
- host_line.setText("%s:%d:%s"% (host,port,protocol) )
+ host_line.setText(server)
hbox.addWidget(QLabel('Connect to:'))
hbox.addWidget(host_line)
vbox.addLayout(hbox)
@@ -877,7 +873,7 @@ class ElectrumWindow(QMainWindow):
servers_list.setHeaderLabels( [ 'Active servers'] )
servers_list.setMaximumHeight(150)
for item in wallet.interface.servers:
- servers_list.addTopLevelItem(QTreeWidgetItem( [ item[1] + ':' + item[0] ] ))
+ servers_list.addTopLevelItem(QTreeWidgetItem( [ item ] ))
servers_list.connect(servers_list, SIGNAL('itemClicked(QTreeWidgetItem*, int)'), lambda x:host_line.setText( x.text(0) ))
vbox.addWidget(servers_list)
else:
@@ -891,16 +887,11 @@ class ElectrumWindow(QMainWindow):
d.setLayout(vbox)
if not d.exec_(): return
- hh = unicode( host_line.text() )
+ server = unicode( host_line.text() )
try:
- if ':' in hh:
- host, port, protocol = hh.split(':')
- port = int(port)
- else:
- host = hh
- port = wallet.port
- protocol = wallet.protocol
+ a,b,c = server.split(':')
+ b = int(b)
except:
QMessageBox.information(None, 'Error', 'error', 'OK')
if parent == None:
@@ -908,7 +899,7 @@ class ElectrumWindow(QMainWindow):
else:
return
- wallet.set_server(host, port, protocol)
+ wallet.set_server(server)
return True
diff --git a/client/interface.py b/client/interface.py
@@ -42,20 +42,15 @@ class Interface:
self.rtime = 0
self.is_connected = True
-
- #only asynchrnous
- self.addresses_waiting_for_status = []
- self.addresses_waiting_for_history = []
+ self.poll_interval = 1
#json
self.message_id = 0
self.responses = Queue.Queue()
-
- def is_up_to_date(self):
- return self.responses.empty() and not ( self.addresses_waiting_for_status or self.addresses_waiting_for_history )
-
-
+ def poke(self):
+ # push a fake response so that the getting thread exits its loop
+ self.responses.put(None)
def queue_json_response(self, c):
#print repr(c)
@@ -70,26 +65,13 @@ class Interface:
if error:
print "received error:", c, method, params
else:
- self.update_waiting_lists(method, params)
self.responses.put({'method':method, 'params':params, 'result':result})
- def update_waiting_lists(self, method, params):
- if method == 'blockchain.address.subscribe':
- addr = params[-1]
- if addr in self.addresses_waiting_for_status:
- self.addresses_waiting_for_status.remove(addr)
- elif method == 'blockchain.address.get_history':
- addr = params[0]
- if addr in self.addresses_waiting_for_history:
- self.addresses_waiting_for_history.remove(addr)
-
-
def subscribe(self, addresses):
messages = []
for addr in addresses:
messages.append(('blockchain.address.subscribe', [addr]))
- self.addresses_waiting_for_status.append(addr)
self.send(messages)
@@ -140,11 +122,11 @@ class PollingInterface(Interface):
#else:
# return False
- def poll_thread(self, poll_interval):
+ def poll_thread(self):
while self.is_connected:
try:
self.poll()
- time.sleep(poll_interval)
+ time.sleep(self.poll_interval)
except socket.gaierror:
break
except socket.error:
@@ -166,7 +148,7 @@ class NativeInterface(PollingInterface):
def start_session(self, addresses, version):
self.send([('session.new', [ version, addresses ])] )
self.send([('server.peers.subscribe',[])])
- thread.start_new_thread(self.poll_thread, (5,))
+ thread.start_new_thread(self.poll_thread, ())
def send(self, messages):
import time
@@ -186,7 +168,7 @@ class NativeInterface(PollingInterface):
params = self.session_id
if cmd == 'address.subscribe':
- params = [ self.session_id] + params
+ params = [ self.session_id ] + params
if cmd in ['h', 'tx']:
str_params = params[0]
@@ -212,16 +194,16 @@ class NativeInterface(PollingInterface):
if cmd == 'h':
out = old_to_new(out)
- if cmd in[ 'peers','h','poll']:
+ if cmd in ['peers','h','poll']:
out = ast.literal_eval( out )
- if out=='': out=None #fixme
+ if out == '':
+ out = None
if cmd == 'new_session':
self.session_id, msg = ast.literal_eval( out )
self.responses.put({'method':'server.banner', 'params':[], 'result':msg})
else:
- self.update_waiting_lists(method, params)
self.responses.put({'method':method, 'params':params, 'result':out})
@@ -231,7 +213,7 @@ class HttpInterface(PollingInterface):
def start(self):
self.session_id = None
- thread.start_new_thread(self.poll_thread, (15,))
+ thread.start_new_thread(self.poll_thread, ())
def poll(self):
if self.session_id:
@@ -280,6 +262,13 @@ class HttpInterface(PollingInterface):
for item in response:
self.queue_json_response(item)
+ if response:
+ self.poll_interval = 1
+ else:
+ if self.poll_interval < 15:
+ self.poll_interval += 1
+ #print self.poll_interval, response
+
self.rtime = time.time() - t1
self.is_connected = True
@@ -313,8 +302,7 @@ class AsynchronousInterface(Interface):
traceback.print_exc(file=sys.stdout)
self.is_connected = False
- # push None so that the getting thread exits its loop
- self.responses.put(None)
+ self.poke()
def send(self, messages):
out = ''
@@ -327,7 +315,6 @@ class AsynchronousInterface(Interface):
def get_history(self, addr):
self.send([('blockchain.address.get_history', [addr])])
- self.addresses_waiting_for_history.append(addr)
def start(self):
self.s = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
diff --git a/client/wallet.py b/client/wallet.py
@@ -251,7 +251,6 @@ class Wallet:
self.addresses = [] # receiving addresses visible for user
self.change_addresses = [] # addresses used as change
self.seed = '' # encrypted
- self.status = {} # current status of addresses
self.history = {}
self.labels = {} # labels for addresses and transactions
self.aliases = {} # aliases for addresses
@@ -261,9 +260,7 @@ class Wallet:
self.receipt = None # next receipt
self.addressbook = [] # outgoing addresses, for payments
- self.host = random.choice( DEFAULT_SERVERS ) # random choice when the wallet is created
- self.port = DEFAULT_PORT
- self.protocol = 'n'
+ self.server = random.choice( DEFAULT_SERVERS ) + ':50000:n' # random choice when the wallet is created
# not saved
self.tx_history = {}
@@ -280,12 +277,18 @@ class Wallet:
self.interface_lock = threading.Lock()
self.tx_event = threading.Event()
+ #
+ self.addresses_waiting_for_status = []
+ self.addresses_waiting_for_history = []
- def set_server(self, host, port, protocol):
- if host!= self.host or port!=self.port or protocol!=self.protocol:
- self.host = host
- self.port = port
- self.protocol = protocol
+
+ def is_up_to_date(self):
+ return self.interface.responses.empty() and not ( self.addresses_waiting_for_status or self.addresses_waiting_for_history )
+
+
+ def set_server(self, server):
+ if server != self.server:
+ self.server = server
self.interface.is_connected = False # this exits the polling loop
def set_path(self, wallet_path):
@@ -460,7 +463,6 @@ class Wallet:
self.addresses.append(address)
self.history[address] = []
- self.status[address] = None
print address
return address
@@ -530,13 +532,10 @@ class Wallet:
'use_encryption':self.use_encryption,
'master_public_key': self.master_public_key.encode('hex'),
'fee':self.fee,
- 'host':self.host,
- 'port':self.port,
- 'protocol':self.protocol,
+ 'server':self.server,
'seed':self.seed,
'addresses':self.addresses,
'change_addresses':self.change_addresses,
- 'status':self.status,
'history':self.history,
'labels':self.labels,
'contacts':self.addressbook,
@@ -568,13 +567,10 @@ class Wallet:
self.use_encryption = d.get('use_encryption')
self.fee = int( d.get('fee') )
self.seed = d.get('seed')
- self.host = d.get('host')
- self.protocol = d.get('protocol','n')
- self.port = d.get('port')
+ self.server = d.get('server')
blocks = d.get('blocks')
self.addresses = d.get('addresses')
self.change_addresses = d.get('change_addresses')
- self.status = d.get('status')
self.history = d.get('history')
self.labels = d.get('labels')
self.addressbook = d.get('contacts')
@@ -692,17 +688,30 @@ class Wallet:
else:
return s
+ def get_status(self, address):
+ h = self.history.get(address)
+ if not h:
+ status = None
+ else:
+ lastpoint = h[-1]
+ status = lastpoint['block_hash']
+ if status == 'mempool':
+ status = status + ':%d'% len(h)
+ return status
+
def receive_status_callback(self, addr, status):
- if self.status.get(addr) != status:
- #print "updating status for", addr, repr(self.status.get(addr)), repr(status)
- self.status[addr] = status
+ if self.get_status(addr) != status:
+ #print "updating status for", addr, status
+ self.addresses_waiting_for_history.append(addr)
self.interface.get_history(addr)
+ if addr in self.addresses_waiting_for_status: self.addresses_waiting_for_status.remove(addr)
def receive_history_callback(self, addr, data):
#print "updating history for", addr
self.history[addr] = data
self.update_tx_history()
self.save()
+ if addr in self.addresses_waiting_for_history: self.addresses_waiting_for_history.remove(addr)
def get_tx_history(self):
lines = self.tx_history.values()
@@ -948,11 +957,11 @@ class Wallet:
if len(item)>2:
for v in item[2]:
if re.match("[nsh]\d+",v):
- s.append((v[0],host+":"+v[1:]))
+ s.append(host+":"+v[1:]+":"+v[0])
if not s:
- s.append(("n",host+":50000"))
+ s.append(host+":50000:n")
else:
- s.append(("n",host+":50000"))
+ s.append(host+":50000:n")
servers = servers + s
self.interface.servers = servers
@@ -980,6 +989,7 @@ class Wallet:
def update(self):
+ self.interface.poke()
self.up_to_date_event.wait()
@@ -988,7 +998,10 @@ class Wallet:
new_addresses = self.synchronize()
if new_addresses:
self.interface.subscribe(new_addresses)
- if self.interface.is_up_to_date() and not new_addresses:
+ for addr in new_addresses:
+ self.addresses_waiting_for_status.append(addr)
+
+ if self.is_up_to_date():
self.up_to_date = True
self.up_to_date_event.set()
else:
@@ -999,19 +1012,25 @@ class Wallet:
def start_interface(self):
- if self.protocol == 'n':
+
+ host, port, protocol = self.server.split(':')
+ port = int(port)
+
+ if protocol == 'n':
InterfaceClass = NativeInterface
- elif self.protocol == 's':
+ elif protocol == 's':
InterfaceClass = AsynchronousInterface
- elif self.protocol == 'h':
+ elif protocol == 'h':
InterfaceClass = HttpInterface
else:
print "unknown protocol"
InterfaceClass = NativeInterface
- self.interface = InterfaceClass(self.host, self.port)
+ self.interface = InterfaceClass(host, port)
addresses = self.all_addresses()
version = self.electrum_version
+ for addr in addresses:
+ self.addresses_waiting_for_status.append(addr)
self.interface.start_session(addresses,version)