fix recovery procedure
This commit is contained in:
parent
d0dd8c847a
commit
81bb04378f
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue