From c990a4da6bbf301196645f0209d8ae6b15a8e3a4 Mon Sep 17 00:00:00 2001 From: Kristaps Kaupe Date: Fri, 24 Nov 2023 12:38:15 +0200 Subject: [PATCH] Allow fee bump tx not signalling BIP125 if mempoolfullrbf is enabled --- scripts/bumpfee.py | 6 ++++-- src/jmclient/blockchaininterface.py | 14 +++++++++++++- test/jmclient/commontest.py | 2 ++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/scripts/bumpfee.py b/scripts/bumpfee.py index de72776e0..913af5046 100755 --- a/scripts/bumpfee.py +++ b/scripts/bumpfee.py @@ -74,8 +74,10 @@ def check_valid_candidate(orig_tx, wallet, output_index=-1): if own_inputs_n != tx_inputs_n: raise ValueError('Transaction inputs should belong to the wallet.') - # at least one input should signal opt-in rbf - if not any([vin.nSequence <= 0xffffffff - 2 for vin in orig_tx.vin]): + # either mempoolfullrbf must be enabled or at least one input must signal + # opt-in rbf + if not jm_single().bc_interface.mempoolfullrbf() and \ + not any([vin.nSequence <= 0xffffffff - 2 for vin in orig_tx.vin]): raise ValueError('Transaction not replaceable.') # 1. If output_index is specified, check that the output exist diff --git a/src/jmclient/blockchaininterface.py b/src/jmclient/blockchaininterface.py index e891c7f94..6409b3e35 100644 --- a/src/jmclient/blockchaininterface.py +++ b/src/jmclient/blockchaininterface.py @@ -171,6 +171,11 @@ def testmempoolaccept(self, rawtx: str) -> bool: """Checks that raw transaction would be accepted by mempool. """ + @abstractmethod + def mempoolfullrbf(self) -> bool: + """Whether mempool full-RBF is enabled. + """ + @abstractmethod def _get_mempool_min_fee(self) -> Optional[int]: """Returns minimum mempool fee as a floor to avoid relay problems @@ -558,13 +563,20 @@ def query_utxo_set(self, result.append(result_dict) return result + def _getmempoolinfo(self) -> Optional[dict]: + return self._rpc('getmempoolinfo') + def _get_mempool_min_fee(self) -> Optional[int]: - rpc_result = self._rpc('getmempoolinfo') + rpc_result = self._getmempoolinfo() if not rpc_result: # in case of connection error: return None return btc.btc_to_sat(rpc_result['mempoolminfee']) + def mempoolfullrbf(self) -> bool: + rpc_result = self._getmempoolinfo() + return 'fullrbf' in rpc_result and rpc_result['fullrbf'] + def _estimate_fee_basic(self, conf_target: int) -> Optional[int]: # Special bitcoin core case: sometimes the highest priority # cannot be estimated in that case the 2nd highest priority diff --git a/test/jmclient/commontest.py b/test/jmclient/commontest.py index c5553c5d3..ededb2d1f 100644 --- a/test/jmclient/commontest.py +++ b/test/jmclient/commontest.py @@ -90,6 +90,8 @@ def get_wallet_rescan_status(self) -> Tuple[bool, Optional[Decimal]]: pass def rescanblockchain(self, start_height: int, end_height: Optional[int] = None) -> None: pass + def mempoolfullrbf(self) -> bool: + pass def get_current_block_height(self) -> int: return 10**6