simplify get_tx_fee

This commit is contained in:
ThomasV 2019-09-12 12:26:49 +02:00
parent 482605edbb
commit 7b828359c6
3 changed files with 24 additions and 24 deletions

View file

@ -451,7 +451,7 @@ class AddressSynchronizer(Logger):
for tx_hash in tx_deltas: for tx_hash in tx_deltas:
delta = tx_deltas[tx_hash] delta = tx_deltas[tx_hash]
tx_mined_status = self.get_tx_height(tx_hash) tx_mined_status = self.get_tx_height(tx_hash)
fee, is_calculated_by_us = self.get_tx_fee(tx_hash) fee = self.get_tx_fee(tx_hash)
history.append((tx_hash, tx_mined_status, delta, fee)) history.append((tx_hash, tx_mined_status, delta, fee))
history.sort(key = lambda x: self.get_txpos(x[0]), reverse=True) history.sort(key = lambda x: self.get_txpos(x[0]), reverse=True)
# 3. add balance # 3. add balance
@ -689,39 +689,37 @@ class AddressSynchronizer(Logger):
fee = None fee = None
return is_relevant, is_mine, v, fee return is_relevant, is_mine, v, fee
def get_tx_fee(self, txid: str) -> Tuple[Optional[int], bool]: def get_tx_fee(self, txid: str) -> Optional[int]:
"""Returns (tx_fee, is_calculated_by_us).""" """ Returns tx_fee or None. Use server fee only if tx is unconfirmed and not mine"""
# check if stored fee is available # check if stored fee is available
# return that, if is_calc_by_us fee = self.db.get_tx_fee(txid, trust_server=False)
fee = None if fee is not None:
fee_and_bool = self.db.get_tx_fee(txid) return fee
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 # delete server-sent fee for confirmed txns
confirmed = self.get_tx_height(txid).conf > 0
if confirmed:
self.db.add_tx_fee_from_server(txid, None) self.db.add_tx_fee_from_server(txid, None)
fee = None
# if all inputs are ismine, try to calc fee now; # if all inputs are ismine, try to calc fee now;
# otherwise, return stored value # otherwise, return stored value
num_all_inputs = self.db.get_num_all_inputs_of_tx(txid) num_all_inputs = self.db.get_num_all_inputs_of_tx(txid)
if num_all_inputs is not None: if num_all_inputs is not None:
# check if tx is mine
num_ismine_inputs = self.db.get_num_ismine_inputs_of_tx(txid) 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) assert num_ismine_inputs <= num_all_inputs, (num_ismine_inputs, num_all_inputs)
# trust server if tx is unconfirmed and not mine
if num_ismine_inputs < num_all_inputs: if num_ismine_inputs < num_all_inputs:
return fee, False return None if confirmed else self.db.get_tx_fee(txid, trust_server=True)
# lookup tx and deserialize it. # lookup tx and deserialize it.
# note that deserializing is expensive, hence above hacks # note that deserializing is expensive, hence above hacks
tx = self.db.get_transaction(txid) tx = self.db.get_transaction(txid)
if not tx: if not tx:
return None, False return None
with self.lock, self.transaction_lock: with self.lock, self.transaction_lock:
is_relevant, is_mine, v, fee = self.get_wallet_delta(tx) is_relevant, is_mine, v, fee = self.get_wallet_delta(tx)
# save result # save result
self.db.add_tx_fee_we_calculated(txid, fee) self.db.add_tx_fee_we_calculated(txid, fee)
self.db.add_num_inputs_to_tx(txid, len(tx.inputs())) self.db.add_num_inputs_to_tx(txid, len(tx.inputs()))
return fee, True return fee
def get_addr_io(self, address): def get_addr_io(self, address):
with self.lock, self.transaction_lock: with self.lock, self.transaction_lock:

View file

@ -699,12 +699,14 @@ class JsonDB(Logger):
self.tx_fees[txid] = self.tx_fees[txid]._replace(fee=fee_sat, is_calculated_by_us=True) self.tx_fees[txid] = self.tx_fees[txid]._replace(fee=fee_sat, is_calculated_by_us=True)
@locked @locked
def get_tx_fee(self, txid: str) -> Optional[Tuple[Optional[int], bool]]: def get_tx_fee(self, txid: str, *, trust_server=False) -> Optional[int]:
"""Returns (tx_fee, is_calculated_by_us).""" """Returns tx_fee."""
tx_fees_value = self.tx_fees.get(txid) tx_fees_value = self.tx_fees.get(txid)
if tx_fees_value is None: if tx_fees_value is None:
return None return None
return tx_fees_value.fee, tx_fees_value.is_calculated_by_us if not trust_server and not tx_fees_value.is_calculated_by_us:
return None
return tx_fees_value.fee
@modifier @modifier
def add_num_inputs_to_tx(self, txid: str, num_inputs: int) -> None: def add_num_inputs_to_tx(self, txid: str, num_inputs: int) -> None:

View file

@ -409,7 +409,7 @@ class Abstract_Wallet(AddressSynchronizer):
elif tx_mined_status.height in (TX_HEIGHT_UNCONF_PARENT, TX_HEIGHT_UNCONFIRMED): elif tx_mined_status.height in (TX_HEIGHT_UNCONF_PARENT, TX_HEIGHT_UNCONFIRMED):
status = _('Unconfirmed') status = _('Unconfirmed')
if fee is None: if fee is None:
fee, _calc_by_us = self.get_tx_fee(tx_hash) fee = self.get_tx_fee(tx_hash, trust_server=True)
if fee and self.network and self.config.has_fee_mempool(): if fee and self.network and self.config.has_fee_mempool():
size = tx.estimated_size() size = tx.estimated_size()
fee_per_byte = fee / size fee_per_byte = fee / size
@ -722,7 +722,7 @@ class Abstract_Wallet(AddressSynchronizer):
is_final = tx and tx.is_final() is_final = tx and tx.is_final()
if not is_final: if not is_final:
extra.append('rbf') extra.append('rbf')
fee, _calc_by_us = self.get_tx_fee(tx_hash) fee = self.get_tx_fee(tx_hash, trust_server=True)
if fee is not None: if fee is not None:
size = tx.estimated_size() size = tx.estimated_size()
fee_per_byte = fee / size fee_per_byte = fee / size
@ -1004,8 +1004,8 @@ class Abstract_Wallet(AddressSynchronizer):
old_tx_size = tx.estimated_size() old_tx_size = tx.estimated_size()
old_txid = tx.txid() old_txid = tx.txid()
assert old_txid assert old_txid
old_fee, is_calc_by_us = self.get_tx_fee(old_txid) old_fee = self.get_tx_fee(old_txid)
if old_fee is None or not is_calc_by_us: if old_fee is None:
raise CannotBumpFee(_('Cannot bump fee') + ': ' + _('current fee unknown')) raise CannotBumpFee(_('Cannot bump fee') + ': ' + _('current fee unknown'))
old_fee_rate = old_fee / old_tx_size # sat/vbyte old_fee_rate = old_fee / old_tx_size # sat/vbyte
if new_fee_rate <= old_fee_rate: if new_fee_rate <= old_fee_rate: