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):
|
def receive_tx_callback(self, tx_hash, tx):
|
||||||
#print "updating history for", addr
|
|
||||||
#with self.lock:
|
if not self.check_new_tx(tx_hash, tx):
|
||||||
self.transactions[tx_hash] = d
|
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.update_tx_outputs(tx_hash)
|
||||||
|
|
||||||
self.save()
|
self.save()
|
||||||
|
|
||||||
|
|
||||||
def receive_history_callback(self, addr, hist):
|
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:
|
with self.lock:
|
||||||
self.history[addr] = hist
|
self.history[addr] = hist
|
||||||
self.save()
|
self.save()
|
||||||
|
@ -557,6 +566,7 @@ class Wallet:
|
||||||
self.verifier.add(tx_hash)
|
self.verifier.add(tx_hash)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def get_tx_history(self):
|
def get_tx_history(self):
|
||||||
with self.lock:
|
with self.lock:
|
||||||
lines = self.transactions.values()
|
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):
|
class WalletSynchronizer(threading.Thread):
|
||||||
|
@ -915,17 +972,18 @@ class WalletSynchronizer(threading.Thread):
|
||||||
new_addresses = self.wallet.synchronize()
|
new_addresses = self.wallet.synchronize()
|
||||||
if new_addresses:
|
if new_addresses:
|
||||||
self.subscribe_to_addresses(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.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 self.wallet.up_to_date:
|
if self.wallet.up_to_date:
|
||||||
self.wallet.up_to_date = False
|
self.wallet.up_to_date = False
|
||||||
self.was_updated = True
|
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):
|
def subscribe_to_addresses(self, addresses):
|
||||||
|
|
Loading…
Reference in New Issue