check that histories and transactions are consistent
This commit is contained in:
parent
a48a971ae6
commit
62be41161b
|
@ -538,17 +538,26 @@ class Wallet:
|
|||
|
||||
|
||||
|
||||
def receive_tx_callback(self, tx_hash, d):
|
||||
#print "updating history for", addr
|
||||
#with self.lock:
|
||||
self.transactions[tx_hash] = d
|
||||
def receive_tx_callback(self, tx_hash, tx):
|
||||
|
||||
if not self.check_new_tx(tx_hash, tx):
|
||||
print "error: transaction not consistent with history", tx_hash
|
||||
return
|
||||
|
||||
with self.lock:
|
||||
self.transactions[tx_hash] = tx
|
||||
|
||||
self.update_tx_outputs(tx_hash)
|
||||
|
||||
self.save()
|
||||
|
||||
|
||||
def receive_history_callback(self, addr, hist):
|
||||
#print "updating history for", addr
|
||||
|
||||
if not self.check_new_history(addr, hist):
|
||||
print "error: history check failed", tx_hash
|
||||
return
|
||||
|
||||
with self.lock:
|
||||
self.history[addr] = hist
|
||||
self.save()
|
||||
|
@ -557,6 +566,7 @@ class Wallet:
|
|||
self.verifier.add(tx_hash)
|
||||
|
||||
|
||||
|
||||
def get_tx_history(self):
|
||||
with self.lock:
|
||||
lines = self.transactions.values()
|
||||
|
@ -896,6 +906,53 @@ class Wallet:
|
|||
|
||||
|
||||
|
||||
def is_addr_in_tx(self, addr, tx):
|
||||
found = False
|
||||
for txin in tx.get('inputs'):
|
||||
if addr == txin.get('address'):
|
||||
found = True
|
||||
break
|
||||
for txout in tx.get('outputs'):
|
||||
if addr == txout.get('address'):
|
||||
found = True
|
||||
break
|
||||
return found
|
||||
|
||||
|
||||
def check_new_history(self, addr, hist):
|
||||
# - check that all tx in hist are relevant
|
||||
for tx_hash, height in hist:
|
||||
tx = self.transactions.get(tx_hash)
|
||||
if not tx: continue
|
||||
if not self.is_addr_in_tx(addr,tx):
|
||||
return False
|
||||
|
||||
# todo: check that we are not "orphaning" a transaction
|
||||
# if we are, reject tx if unconfirmed, else reject the server
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
||||
def check_new_tx(self, tx_hash, tx):
|
||||
# 1 check that tx is referenced in addr_history.
|
||||
addresses = []
|
||||
for addr, hist in self.history.items():
|
||||
for txh, height in hist:
|
||||
if txh == tx_hash:
|
||||
addresses.append(addr)
|
||||
|
||||
if not addresses:
|
||||
return False
|
||||
|
||||
# 2 check that referencing addresses are in the tx
|
||||
for addr in addresses:
|
||||
if not self.is_addr_in_tx(addr, tx):
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
|
||||
|
||||
class WalletSynchronizer(threading.Thread):
|
||||
|
@ -915,17 +972,18 @@ class WalletSynchronizer(threading.Thread):
|
|||
new_addresses = self.wallet.synchronize()
|
||||
if new_addresses:
|
||||
self.subscribe_to_addresses(new_addresses)
|
||||
self.wallet.up_to_date = False
|
||||
return
|
||||
|
||||
if self.interface.is_up_to_date('synchronizer'):
|
||||
if not self.wallet.up_to_date:
|
||||
self.wallet.up_to_date = True
|
||||
self.was_updated = True
|
||||
self.wallet.up_to_date_event.set()
|
||||
else:
|
||||
if not self.interface.is_up_to_date('synchronizer'):
|
||||
if self.wallet.up_to_date:
|
||||
self.wallet.up_to_date = False
|
||||
self.was_updated = True
|
||||
return
|
||||
|
||||
self.wallet.up_to_date = True
|
||||
self.was_updated = True
|
||||
self.wallet.up_to_date_event.set()
|
||||
|
||||
|
||||
def subscribe_to_addresses(self, addresses):
|
||||
|
|
Loading…
Reference in New Issue