1
0

handle case where an unconfirmed transaction is pruned by the server. also, fix bug with fee sign in details

This commit is contained in:
thomasv
2012-11-23 15:35:54 +01:00
parent 6e0a62fada
commit 5ae15d6100

View File

@@ -414,7 +414,11 @@ class Wallet:
else:
# some inputs are mine:
fee = None
v = v_out_mine - v_in
if is_send:
v = v_out_mine - v_out
else:
# no input is mine
v = v_out_mine
return is_send, v, fee
@@ -438,7 +442,7 @@ class Wallet:
+ "Status: %d confirmations\n"%conf
if is_mine:
if fee:
tx_details += "Amount sent: %s\n"% format_satoshis(v+fee, False) \
tx_details += "Amount sent: %s\n"% format_satoshis(v-fee, False) \
+ "Transaction fee: %s\n"% format_satoshis(fee, False)
else:
tx_details += "Amount sent: %s\n"% format_satoshis(v, False) \
@@ -655,9 +659,8 @@ class Wallet:
def receive_history_callback(self, addr, hist):
if hist != ['*']:
if not self.check_new_history(addr, hist):
raise BaseException("error: received history for %s is not consistent with known transactions"%addr)
if not self.check_new_history(addr, hist):
raise BaseException("error: received history for %s is not consistent with known transactions"%addr)
with self.lock:
self.history[addr] = hist
@@ -697,12 +700,9 @@ class Wallet:
tx_hash = tx['tx_hash']
timestamp = tx.get('timestamp')
conf = self.verifier.get_confirmations(tx_hash) if self.verifier else None
is_mine, v, fee = self.get_tx_value(tx_hash)
if v is not None:
balance += v
value = v + fee if fee is not None else v
else:
value = None
is_mine, value, fee = self.get_tx_value(tx_hash)
if value is not None:
balance += value
result.append( (tx_hash, conf, is_mine, value, fee, balance, timestamp) )
@@ -1069,15 +1069,57 @@ class Wallet:
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
# check that all tx in hist are relevant
if hist != ['*']:
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
# check that we are not "orphaning" a transaction
old_hist = self.history.get(addr)
if old_hist == ['*']: return True
for tx_hash, height in old_hist:
if tx_hash in map(lambda x:x[0], hist): continue
found = False
for _addr, _hist in self.history.items():
if _addr == addr: continue
if _hist == ['*']: continue
_tx_hist = map(lambda x:x[0], _hist)
if tx_hash in _tx_hist:
found = True
break
if not found:
tx = self.transactions.get(tx_hash)
# already verified?
if tx.get('height'):
continue
# unconfirmed tx
print_error("new history is orphaning transaction:", tx_hash)
# check that all outputs are not mine, request histories
ext_requests = []
for o in tx.get('outputs'):
_addr = o.get('address')
assert not self.is_mine(_addr)
ext_requests.append( ('blockchain.address.get_history', [_addr]) )
ext_h = self.interface.synchronous_get(ext_requests)
height = None
for h in ext_h:
if h == ['*']: continue
for item in h:
if item.get('tx_hash') == tx_hash:
height = item.get('height')
if height:
print_error("found height for", tx_hash, height)
self.verifier.add(tx_hash, height)
else:
print_error("removing orphaned tx from history", tx_hash)
self.transactions.pop(tx_hash)
return True