fix recovery procedure

This commit is contained in:
ThomasV 2012-03-30 14:15:05 +02:00
parent d0dd8c847a
commit 81bb04378f
3 changed files with 76 additions and 79 deletions

View File

@ -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

View File

@ -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 )

View File

@ -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)