1
0

wallet: organise get_tx_fee. store calculated fees. storage version 19.

This commit is contained in:
SomberNight
2019-09-12 03:44:16 +02:00
committed by ThomasV
parent 5c83e8bd1c
commit 482605edbb
4 changed files with 121 additions and 42 deletions

View File

@@ -213,7 +213,8 @@ class AddressSynchronizer(Logger):
conflicting_txns -= {tx_hash}
return conflicting_txns
def add_transaction(self, tx_hash, tx, allow_unrelated=False):
def add_transaction(self, tx_hash, tx, allow_unrelated=False) -> bool:
"""Returns whether the tx was successfully added to the wallet history."""
assert tx_hash, tx_hash
assert tx, tx
assert tx.is_complete()
@@ -300,6 +301,7 @@ class AddressSynchronizer(Logger):
self._add_tx_to_local_history(tx_hash)
# save
self.db.add_transaction(tx_hash, tx)
self.db.add_num_inputs_to_tx(tx_hash, len(tx.inputs()))
return True
def remove_transaction(self, tx_hash):
@@ -329,6 +331,7 @@ class AddressSynchronizer(Logger):
self._get_addr_balance_cache.pop(addr, None) # invalidate cache
self.db.remove_txi(tx_hash)
self.db.remove_txo(tx_hash)
self.db.remove_tx_fee(tx_hash)
def get_depending_transactions(self, tx_hash):
"""Returns all (grand-)children of tx_hash in this wallet."""
@@ -344,7 +347,7 @@ class AddressSynchronizer(Logger):
self.add_unverified_tx(tx_hash, tx_height)
self.add_transaction(tx_hash, tx, allow_unrelated=True)
def receive_history_callback(self, addr, hist, tx_fees):
def receive_history_callback(self, addr: str, hist, tx_fees: Dict[str, int]):
with self.lock:
old_hist = self.get_address_history(addr)
for tx_hash, height in old_hist:
@@ -366,7 +369,8 @@ class AddressSynchronizer(Logger):
self.add_transaction(tx_hash, tx, allow_unrelated=True)
# Store fees
self.db.update_tx_fees(tx_fees)
for tx_hash, fee_sat in tx_fees.items():
self.db.add_tx_fee_from_server(tx_hash, fee_sat)
@profiler
def load_local_history(self):
@@ -447,8 +451,7 @@ class AddressSynchronizer(Logger):
for tx_hash in tx_deltas:
delta = tx_deltas[tx_hash]
tx_mined_status = self.get_tx_height(tx_hash)
# FIXME: db should only store fees computed by us...
fee = self.db.get_tx_fee(tx_hash)
fee, is_calculated_by_us = self.get_tx_fee(tx_hash)
history.append((tx_hash, tx_mined_status, delta, fee))
history.sort(key = lambda x: self.get_txpos(x[0]), reverse=True)
# 3. add balance
@@ -468,7 +471,7 @@ class AddressSynchronizer(Logger):
h2.reverse()
# fixme: this may happen if history is incomplete
if balance not in [None, 0]:
self.logger.info("Error: history not synchronized")
self.logger.warning("history not synchronized")
return []
return h2
@@ -686,20 +689,39 @@ class AddressSynchronizer(Logger):
fee = None
return is_relevant, is_mine, v, fee
def get_tx_fee(self, tx: Transaction) -> Optional[int]:
def get_tx_fee(self, txid: str) -> Tuple[Optional[int], bool]:
"""Returns (tx_fee, is_calculated_by_us)."""
# check if stored fee is available
# return that, if is_calc_by_us
fee = None
fee_and_bool = self.db.get_tx_fee(txid)
if fee_and_bool is not None:
fee, is_calc_by_us = fee_and_bool
if is_calc_by_us:
return fee, is_calc_by_us
elif self.get_tx_height(txid).conf > 0:
# delete server-sent fee for confirmed txns
self.db.add_tx_fee_from_server(txid, None)
fee = None
# if all inputs are ismine, try to calc fee now;
# otherwise, return stored value
num_all_inputs = self.db.get_num_all_inputs_of_tx(txid)
if num_all_inputs is not None:
num_ismine_inputs = self.db.get_num_ismine_inputs_of_tx(txid)
assert num_ismine_inputs <= num_all_inputs, (num_ismine_inputs, num_all_inputs)
if num_ismine_inputs < num_all_inputs:
return fee, False
# lookup tx and deserialize it.
# note that deserializing is expensive, hence above hacks
tx = self.db.get_transaction(txid)
if not tx:
return None
if hasattr(tx, '_cached_fee'):
return tx._cached_fee
return None, False
with self.lock, self.transaction_lock:
is_relevant, is_mine, v, fee = self.get_wallet_delta(tx)
if fee is None:
txid = tx.txid()
fee = self.db.get_tx_fee(txid)
# only cache non-None, as None can still change while syncing
if fee is not None:
tx._cached_fee = fee
return fee
# save result
self.db.add_tx_fee_we_calculated(txid, fee)
self.db.add_num_inputs_to_tx(txid, len(tx.inputs()))
return fee, True
def get_addr_io(self, address):
with self.lock, self.transaction_lock: