Browse Source

Warn user if higher priority confirmation target than requested is provided by blockchain source

master
Kristaps Kaupe 2 years ago
parent
commit
18222796d2
No known key found for this signature in database
GPG Key ID: 33E472FE870C7E5D
  1. 29
      src/jmclient/blockchaininterface.py
  2. 2
      test/jmclient/commontest.py

29
src/jmclient/blockchaininterface.py

@ -183,11 +183,12 @@ class BlockchainInterface(ABC):
"""
@abstractmethod
def _estimate_fee_basic(self, conf_target: int) -> Optional[int]:
def _estimate_fee_basic(self,
conf_target: int) -> Optional[Tuple[int, int]]:
"""Returns basic fee estimation for confirmation target in blocks.
Additional JoinMarket fee logic is added on top, see
`estimate_fee_per_kb` for details. Returns feerate in sats per vB
or None in case of error.
`estimate_fee_per_kb` for details. Returns tuple of feerate in sats
per kvB and actual used conf_target or None in case of error.
"""
def yield_transactions(self) -> Generator[dict, None, None]:
@ -292,9 +293,18 @@ class BlockchainInterface(ABC):
btc.fee_per_kb_to_str(fallback_fee_randomized) + ".")
return int(fallback_fee_randomized)
retval = random.uniform(retval, retval * float(1 + tx_fees_factor))
feerate, blocks = retval
# 1 block difference is tolerated with intent, Core will often return
# 2 block target for `estimatesmartfee 1`.
if tx_fees - blocks > 1:
log.warning(
f"Fee estimation for {tx_fees} block confirmation target "
f"was requested, but {blocks} block target was provided by "
"blockchain source. Tx fee may be higher then expected.")
feerate = random.uniform(feerate, feerate * float(1 + tx_fees_factor))
if retval < mempoolminfee_in_sat:
if feerate < mempoolminfee_in_sat:
msg = "Using this mempool min fee as tx feerate"
if tx_fees_factor != 0:
msg = msg + " (randomized for privacy)"
@ -306,8 +316,8 @@ class BlockchainInterface(ABC):
" block confirmation target"
if tx_fees_factor != 0:
msg = msg + " (randomized for privacy)"
log.info(msg + ": " + btc.fee_per_kb_to_str(retval))
return int(retval)
log.info(msg + ": " + btc.fee_per_kb_to_str(feerate))
return int(feerate)
def core_proof_to_merkle_branch(self, core_proof: str) -> bytes:
core_proof = binascii.unhexlify(core_proof)
@ -577,7 +587,8 @@ class BitcoinCoreInterface(BlockchainInterface):
rpc_result = self._getmempoolinfo()
return 'fullrbf' in rpc_result and rpc_result['fullrbf']
def _estimate_fee_basic(self, conf_target: int) -> Optional[int]:
def _estimate_fee_basic(self,
conf_target: int) -> Optional[Tuple[int, int]]:
# Special bitcoin core case: sometimes the highest priority
# cannot be estimated in that case the 2nd highest priority
# should be used instead of falling back to hardcoded values
@ -593,7 +604,7 @@ class BitcoinCoreInterface(BlockchainInterface):
# if it is not able to make an estimate. We insist that
# the 'feerate' key is found and contains a positive value:
if estimate and estimate > 0:
return btc.btc_to_sat(estimate)
return (btc.btc_to_sat(estimate), rpc_result.get('blocks'))
# cannot get a valid estimate after `tries` tries:
log.warn("Could not source a fee estimate from Core")
return None

2
test/jmclient/commontest.py

@ -84,7 +84,7 @@ class DummyBlockchainInterface(BlockchainInterface):
pass
def _get_mempool_min_fee(self) -> Optional[int]:
pass
def _estimate_fee_basic(self, conf_target: int) -> Optional[int]:
def _estimate_fee_basic(self, conf_target: int) -> Optional[Tuple[int, int]]:
pass
def get_wallet_rescan_status(self) -> Tuple[bool, Optional[Decimal]]:
pass

Loading…
Cancel
Save