1#!/usr/bin/env python3 2# Copyright (c) 2016-2020 The Bitcoin Core developers 3# Distributed under the MIT software license, see the accompanying 4# file COPYING or http://www.opensource.org/licenses/mit-license.php. 5"""Test the bumpfee RPC. 6 7Verifies that the bumpfee RPC creates replacement transactions successfully when 8its preconditions are met, and returns appropriate errors in other cases. 9 10This module consists of around a dozen individual test cases implemented in the 11top-level functions named as test_<test_case_description>. The test functions 12can be disabled or reordered if needed for debugging. If new test cases are 13added in the future, they should try to follow the same convention and not 14make assumptions about execution order. 15""" 16from decimal import Decimal 17 18from test_framework.blocktools import ( 19 COINBASE_MATURITY, 20 add_witness_commitment, 21 create_block, 22 create_coinbase, 23 send_to_witness, 24) 25from test_framework.messages import ( 26 BIP125_SEQUENCE_NUMBER, 27 tx_from_hex, 28) 29from test_framework.test_framework import BitcoinTestFramework 30from test_framework.util import ( 31 assert_equal, 32 assert_greater_than, 33 assert_raises_rpc_error, 34) 35 36WALLET_PASSPHRASE = "test" 37WALLET_PASSPHRASE_TIMEOUT = 3600 38 39# Fee rates (sat/vB) 40INSUFFICIENT = 1 41ECONOMICAL = 50 42NORMAL = 100 43HIGH = 500 44TOO_HIGH = 100000 45 46 47class BumpFeeTest(BitcoinTestFramework): 48 def set_test_params(self): 49 self.num_nodes = 2 50 self.setup_clean_chain = True 51 self.extra_args = [[ 52 "-walletrbf={}".format(i), 53 "-mintxfee=0.00002", 54 "-addresstype=bech32", 55 ] for i in range(self.num_nodes)] 56 57 def skip_test_if_missing_module(self): 58 self.skip_if_no_wallet() 59 60 def clear_mempool(self): 61 # Clear mempool between subtests. The subtests may only depend on chainstate (utxos) 62 self.nodes[1].generate(1) 63 self.sync_all() 64 65 def run_test(self): 66 # Encrypt wallet for test_locked_wallet_fails test 67 self.nodes[1].encryptwallet(WALLET_PASSPHRASE) 68 self.nodes[1].walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT) 69 70 peer_node, rbf_node = self.nodes 71 rbf_node_address = rbf_node.getnewaddress() 72 73 # fund rbf node with 10 coins of 0.001 btc (100,000 satoshis) 74 self.log.info("Mining blocks...") 75 peer_node.generate(110) 76 self.sync_all() 77 for _ in range(25): 78 peer_node.sendtoaddress(rbf_node_address, 0.001) 79 self.sync_all() 80 peer_node.generate(1) 81 self.sync_all() 82 assert_equal(rbf_node.getbalance(), Decimal("0.025")) 83 84 self.log.info("Running tests") 85 dest_address = peer_node.getnewaddress() 86 for mode in ["default", "fee_rate"]: 87 test_simple_bumpfee_succeeds(self, mode, rbf_node, peer_node, dest_address) 88 self.test_invalid_parameters(rbf_node, peer_node, dest_address) 89 test_segwit_bumpfee_succeeds(self, rbf_node, dest_address) 90 test_nonrbf_bumpfee_fails(self, peer_node, dest_address) 91 test_notmine_bumpfee_fails(self, rbf_node, peer_node, dest_address) 92 test_bumpfee_with_descendant_fails(self, rbf_node, rbf_node_address, dest_address) 93 test_dust_to_fee(self, rbf_node, dest_address) 94 test_watchonly_psbt(self, peer_node, rbf_node, dest_address) 95 test_rebumping(self, rbf_node, dest_address) 96 test_rebumping_not_replaceable(self, rbf_node, dest_address) 97 test_unconfirmed_not_spendable(self, rbf_node, rbf_node_address) 98 test_bumpfee_metadata(self, rbf_node, dest_address) 99 test_locked_wallet_fails(self, rbf_node, dest_address) 100 test_change_script_match(self, rbf_node, dest_address) 101 test_settxfee(self, rbf_node, dest_address) 102 test_maxtxfee_fails(self, rbf_node, dest_address) 103 # These tests wipe out a number of utxos that are expected in other tests 104 test_small_output_with_feerate_succeeds(self, rbf_node, dest_address) 105 test_no_more_inputs_fails(self, rbf_node, dest_address) 106 107 def test_invalid_parameters(self, rbf_node, peer_node, dest_address): 108 self.log.info('Test invalid parameters') 109 rbfid = spend_one_input(rbf_node, dest_address) 110 self.sync_mempools((rbf_node, peer_node)) 111 assert rbfid in rbf_node.getrawmempool() and rbfid in peer_node.getrawmempool() 112 113 for key in ["totalFee", "feeRate"]: 114 assert_raises_rpc_error(-3, "Unexpected key {}".format(key), rbf_node.bumpfee, rbfid, {key: NORMAL}) 115 116 # Bumping to just above minrelay should fail to increase the total fee enough. 117 assert_raises_rpc_error(-8, "Insufficient total fee 0.00000141", rbf_node.bumpfee, rbfid, {"fee_rate": INSUFFICIENT}) 118 119 self.log.info("Test invalid fee rate settings") 120 assert_raises_rpc_error(-4, "Specified or calculated fee 0.141 is too high (cannot be higher than -maxtxfee 0.10", 121 rbf_node.bumpfee, rbfid, {"fee_rate": TOO_HIGH}) 122 # Test fee_rate with zero values. 123 msg = "Insufficient total fee 0.00" 124 for zero_value in [0, 0.000, 0.00000000, "0", "0.000", "0.00000000"]: 125 assert_raises_rpc_error(-8, msg, rbf_node.bumpfee, rbfid, {"fee_rate": zero_value}) 126 msg = "Invalid amount" 127 # Test fee_rate values that don't pass fixed-point parsing checks. 128 for invalid_value in ["", 0.000000001, 1e-09, 1.111111111, 1111111111111111, "31.999999999999999999999"]: 129 assert_raises_rpc_error(-3, msg, rbf_node.bumpfee, rbfid, {"fee_rate": invalid_value}) 130 # Test fee_rate values that cannot be represented in sat/vB. 131 for invalid_value in [0.0001, 0.00000001, 0.00099999, 31.99999999, "0.0001", "0.00000001", "0.00099999", "31.99999999"]: 132 assert_raises_rpc_error(-3, msg, rbf_node.bumpfee, rbfid, {"fee_rate": invalid_value}) 133 # Test fee_rate out of range (negative number). 134 assert_raises_rpc_error(-3, "Amount out of range", rbf_node.bumpfee, rbfid, {"fee_rate": -1}) 135 # Test type error. 136 for value in [{"foo": "bar"}, True]: 137 assert_raises_rpc_error(-3, "Amount is not a number or string", rbf_node.bumpfee, rbfid, {"fee_rate": value}) 138 139 self.log.info("Test explicit fee rate raises RPC error if both fee_rate and conf_target are passed") 140 assert_raises_rpc_error(-8, "Cannot specify both conf_target and fee_rate. Please provide either a confirmation " 141 "target in blocks for automatic fee estimation, or an explicit fee rate.", 142 rbf_node.bumpfee, rbfid, {"conf_target": NORMAL, "fee_rate": NORMAL}) 143 144 self.log.info("Test explicit fee rate raises RPC error if both fee_rate and estimate_mode are passed") 145 assert_raises_rpc_error(-8, "Cannot specify both estimate_mode and fee_rate", 146 rbf_node.bumpfee, rbfid, {"estimate_mode": "economical", "fee_rate": NORMAL}) 147 148 self.log.info("Test invalid conf_target settings") 149 assert_raises_rpc_error(-8, "confTarget and conf_target options should not both be set", 150 rbf_node.bumpfee, rbfid, {"confTarget": 123, "conf_target": 456}) 151 152 self.log.info("Test invalid estimate_mode settings") 153 for k, v in {"number": 42, "object": {"foo": "bar"}}.items(): 154 assert_raises_rpc_error(-3, "Expected type string for estimate_mode, got {}".format(k), 155 rbf_node.bumpfee, rbfid, {"estimate_mode": v}) 156 for mode in ["foo", Decimal("3.1415"), "sat/B", "BTC/kB"]: 157 assert_raises_rpc_error(-8, 'Invalid estimate_mode parameter, must be one of: "unset", "economical", "conservative"', 158 rbf_node.bumpfee, rbfid, {"estimate_mode": mode}) 159 160 self.clear_mempool() 161 162 163def test_simple_bumpfee_succeeds(self, mode, rbf_node, peer_node, dest_address): 164 self.log.info('Test simple bumpfee: {}'.format(mode)) 165 rbfid = spend_one_input(rbf_node, dest_address) 166 rbftx = rbf_node.gettransaction(rbfid) 167 self.sync_mempools((rbf_node, peer_node)) 168 assert rbfid in rbf_node.getrawmempool() and rbfid in peer_node.getrawmempool() 169 if mode == "fee_rate": 170 bumped_psbt = rbf_node.psbtbumpfee(rbfid, {"fee_rate": str(NORMAL)}) 171 bumped_tx = rbf_node.bumpfee(rbfid, {"fee_rate": NORMAL}) 172 else: 173 bumped_psbt = rbf_node.psbtbumpfee(rbfid) 174 bumped_tx = rbf_node.bumpfee(rbfid) 175 assert_equal(bumped_tx["errors"], []) 176 assert bumped_tx["fee"] > -rbftx["fee"] 177 assert_equal(bumped_tx["origfee"], -rbftx["fee"]) 178 assert "psbt" not in bumped_tx 179 assert_equal(bumped_psbt["errors"], []) 180 assert bumped_psbt["fee"] > -rbftx["fee"] 181 assert_equal(bumped_psbt["origfee"], -rbftx["fee"]) 182 assert "psbt" in bumped_psbt 183 # check that bumped_tx propagates, original tx was evicted and has a wallet conflict 184 self.sync_mempools((rbf_node, peer_node)) 185 assert bumped_tx["txid"] in rbf_node.getrawmempool() 186 assert bumped_tx["txid"] in peer_node.getrawmempool() 187 assert rbfid not in rbf_node.getrawmempool() 188 assert rbfid not in peer_node.getrawmempool() 189 oldwtx = rbf_node.gettransaction(rbfid) 190 assert len(oldwtx["walletconflicts"]) > 0 191 # check wallet transaction replaces and replaced_by values 192 bumpedwtx = rbf_node.gettransaction(bumped_tx["txid"]) 193 assert_equal(oldwtx["replaced_by_txid"], bumped_tx["txid"]) 194 assert_equal(bumpedwtx["replaces_txid"], rbfid) 195 self.clear_mempool() 196 197 198def test_segwit_bumpfee_succeeds(self, rbf_node, dest_address): 199 self.log.info('Test that segwit-sourcing bumpfee works') 200 # Create a transaction with segwit output, then create an RBF transaction 201 # which spends it, and make sure bumpfee can be called on it. 202 203 segwit_in = next(u for u in rbf_node.listunspent() if u["amount"] == Decimal("0.001")) 204 segwit_out = rbf_node.getaddressinfo(rbf_node.getnewaddress(address_type='bech32')) 205 segwitid = send_to_witness( 206 use_p2wsh=False, 207 node=rbf_node, 208 utxo=segwit_in, 209 pubkey=segwit_out["pubkey"], 210 encode_p2sh=False, 211 amount=Decimal("0.0009"), 212 sign=True) 213 214 rbfraw = rbf_node.createrawtransaction([{ 215 'txid': segwitid, 216 'vout': 0, 217 "sequence": BIP125_SEQUENCE_NUMBER 218 }], {dest_address: Decimal("0.0005"), 219 rbf_node.getrawchangeaddress(): Decimal("0.0003")}) 220 rbfsigned = rbf_node.signrawtransactionwithwallet(rbfraw) 221 rbfid = rbf_node.sendrawtransaction(rbfsigned["hex"]) 222 assert rbfid in rbf_node.getrawmempool() 223 224 bumped_tx = rbf_node.bumpfee(rbfid) 225 assert bumped_tx["txid"] in rbf_node.getrawmempool() 226 assert rbfid not in rbf_node.getrawmempool() 227 self.clear_mempool() 228 229 230def test_nonrbf_bumpfee_fails(self, peer_node, dest_address): 231 self.log.info('Test that we cannot replace a non RBF transaction') 232 not_rbfid = peer_node.sendtoaddress(dest_address, Decimal("0.00090000")) 233 assert_raises_rpc_error(-4, "not BIP 125 replaceable", peer_node.bumpfee, not_rbfid) 234 self.clear_mempool() 235 236 237def test_notmine_bumpfee_fails(self, rbf_node, peer_node, dest_address): 238 self.log.info('Test that it cannot bump fee if non-owned inputs are included') 239 # here, the rbftx has a peer_node coin and then adds a rbf_node input 240 # Note that this test depends upon the RPC code checking input ownership prior to change outputs 241 # (since it can't use fundrawtransaction, it lacks a proper change output) 242 fee = Decimal("0.001") 243 utxos = [node.listunspent(query_options={'minimumAmount': fee})[-1] for node in (rbf_node, peer_node)] 244 inputs = [{ 245 "txid": utxo["txid"], 246 "vout": utxo["vout"], 247 "address": utxo["address"], 248 "sequence": BIP125_SEQUENCE_NUMBER 249 } for utxo in utxos] 250 output_val = sum(utxo["amount"] for utxo in utxos) - fee 251 rawtx = rbf_node.createrawtransaction(inputs, {dest_address: output_val}) 252 signedtx = rbf_node.signrawtransactionwithwallet(rawtx) 253 signedtx = peer_node.signrawtransactionwithwallet(signedtx["hex"]) 254 rbfid = rbf_node.sendrawtransaction(signedtx["hex"]) 255 assert_raises_rpc_error(-4, "Transaction contains inputs that don't belong to this wallet", 256 rbf_node.bumpfee, rbfid) 257 self.clear_mempool() 258 259 260def test_bumpfee_with_descendant_fails(self, rbf_node, rbf_node_address, dest_address): 261 self.log.info('Test that fee cannot be bumped when it has descendant') 262 # parent is send-to-self, so we don't have to check which output is change when creating the child tx 263 parent_id = spend_one_input(rbf_node, rbf_node_address) 264 tx = rbf_node.createrawtransaction([{"txid": parent_id, "vout": 0}], {dest_address: 0.00020000}) 265 tx = rbf_node.signrawtransactionwithwallet(tx) 266 rbf_node.sendrawtransaction(tx["hex"]) 267 assert_raises_rpc_error(-8, "Transaction has descendants in the wallet", rbf_node.bumpfee, parent_id) 268 self.clear_mempool() 269 270 271def test_small_output_with_feerate_succeeds(self, rbf_node, dest_address): 272 self.log.info('Testing small output with feerate bump succeeds') 273 274 # Make sure additional inputs exist 275 rbf_node.generatetoaddress(COINBASE_MATURITY + 1, rbf_node.getnewaddress()) 276 rbfid = spend_one_input(rbf_node, dest_address) 277 input_list = rbf_node.getrawtransaction(rbfid, 1)["vin"] 278 assert_equal(len(input_list), 1) 279 original_txin = input_list[0] 280 self.log.info('Keep bumping until transaction fee out-spends non-destination value') 281 tx_fee = 0 282 while True: 283 input_list = rbf_node.getrawtransaction(rbfid, 1)["vin"] 284 new_item = list(input_list)[0] 285 assert_equal(len(input_list), 1) 286 assert_equal(original_txin["txid"], new_item["txid"]) 287 assert_equal(original_txin["vout"], new_item["vout"]) 288 rbfid_new_details = rbf_node.bumpfee(rbfid) 289 rbfid_new = rbfid_new_details["txid"] 290 raw_pool = rbf_node.getrawmempool() 291 assert rbfid not in raw_pool 292 assert rbfid_new in raw_pool 293 rbfid = rbfid_new 294 tx_fee = rbfid_new_details["fee"] 295 296 # Total value from input not going to destination 297 if tx_fee > Decimal('0.00050000'): 298 break 299 300 # input(s) have been added 301 final_input_list = rbf_node.getrawtransaction(rbfid, 1)["vin"] 302 assert_greater_than(len(final_input_list), 1) 303 # Original input is in final set 304 assert [txin for txin in final_input_list 305 if txin["txid"] == original_txin["txid"] 306 and txin["vout"] == original_txin["vout"]] 307 308 rbf_node.generatetoaddress(1, rbf_node.getnewaddress()) 309 assert_equal(rbf_node.gettransaction(rbfid)["confirmations"], 1) 310 self.clear_mempool() 311 312 313def test_dust_to_fee(self, rbf_node, dest_address): 314 self.log.info('Test that bumped output that is dust is dropped to fee') 315 rbfid = spend_one_input(rbf_node, dest_address) 316 fulltx = rbf_node.getrawtransaction(rbfid, 1) 317 # The DER formatting used by Bitcoin to serialize ECDSA signatures means that signatures can have a 318 # variable size of 70-72 bytes (or possibly even less), with most being 71 or 72 bytes. The signature 319 # in the witness is divided by 4 for the vsize, so this variance can take the weight across a 4-byte 320 # boundary. Thus expected transaction size (p2wpkh, 1 input, 2 outputs) is 140-141 vbytes, usually 141. 321 if not 140 <= fulltx["vsize"] <= 141: 322 raise AssertionError("Invalid tx vsize of {} (140-141 expected), full tx: {}".format(fulltx["vsize"], fulltx)) 323 # Bump with fee_rate of 350.25 sat/vB vbytes to create dust. 324 # Expected fee is 141 vbytes * fee_rate 0.00350250 BTC / 1000 vbytes = 0.00049385 BTC. 325 # or occasionally 140 vbytes * fee_rate 0.00350250 BTC / 1000 vbytes = 0.00049035 BTC. 326 # Dust should be dropped to the fee, so actual bump fee is 0.00050000 BTC. 327 bumped_tx = rbf_node.bumpfee(rbfid, {"fee_rate": 350.25}) 328 full_bumped_tx = rbf_node.getrawtransaction(bumped_tx["txid"], 1) 329 assert_equal(bumped_tx["fee"], Decimal("0.00050000")) 330 assert_equal(len(fulltx["vout"]), 2) 331 assert_equal(len(full_bumped_tx["vout"]), 1) # change output is eliminated 332 assert_equal(full_bumped_tx["vout"][0]['value'], Decimal("0.00050000")) 333 self.clear_mempool() 334 335 336def test_settxfee(self, rbf_node, dest_address): 337 self.log.info('Test settxfee') 338 assert_raises_rpc_error(-8, "txfee cannot be less than min relay tx fee", rbf_node.settxfee, Decimal('0.000005')) 339 assert_raises_rpc_error(-8, "txfee cannot be less than wallet min fee", rbf_node.settxfee, Decimal('0.000015')) 340 # check that bumpfee reacts correctly to the use of settxfee (paytxfee) 341 rbfid = spend_one_input(rbf_node, dest_address) 342 requested_feerate = Decimal("0.00025000") 343 rbf_node.settxfee(requested_feerate) 344 bumped_tx = rbf_node.bumpfee(rbfid) 345 actual_feerate = bumped_tx["fee"] * 1000 / rbf_node.getrawtransaction(bumped_tx["txid"], True)["vsize"] 346 # Assert that the difference between the requested feerate and the actual 347 # feerate of the bumped transaction is small. 348 assert_greater_than(Decimal("0.00001000"), abs(requested_feerate - actual_feerate)) 349 rbf_node.settxfee(Decimal("0.00000000")) # unset paytxfee 350 351 # check that settxfee respects -maxtxfee 352 self.restart_node(1, ['-maxtxfee=0.000025'] + self.extra_args[1]) 353 assert_raises_rpc_error(-8, "txfee cannot be more than wallet max tx fee", rbf_node.settxfee, Decimal('0.00003')) 354 self.restart_node(1, self.extra_args[1]) 355 rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT) 356 self.connect_nodes(1, 0) 357 self.clear_mempool() 358 359 360def test_maxtxfee_fails(self, rbf_node, dest_address): 361 self.log.info('Test that bumpfee fails when it hits -maxtxfee') 362 # size of bumped transaction (p2wpkh, 1 input, 2 outputs): 141 vbytes 363 # expected bump fee of 141 vbytes * 0.00200000 BTC / 1000 vbytes = 0.00002820 BTC 364 # which exceeds maxtxfee and is expected to raise 365 self.restart_node(1, ['-maxtxfee=0.000025'] + self.extra_args[1]) 366 rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT) 367 rbfid = spend_one_input(rbf_node, dest_address) 368 assert_raises_rpc_error(-4, "Unable to create transaction. Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)", rbf_node.bumpfee, rbfid) 369 self.restart_node(1, self.extra_args[1]) 370 rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT) 371 self.connect_nodes(1, 0) 372 self.clear_mempool() 373 374 375def test_watchonly_psbt(self, peer_node, rbf_node, dest_address): 376 self.log.info('Test that PSBT is returned for bumpfee in watchonly wallets') 377 priv_rec_desc = "wpkh([00000001/84'/1'/0']tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0/*)#rweraev0" 378 pub_rec_desc = rbf_node.getdescriptorinfo(priv_rec_desc)["descriptor"] 379 priv_change_desc = "wpkh([00000001/84'/1'/0']tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/*)#j6uzqvuh" 380 pub_change_desc = rbf_node.getdescriptorinfo(priv_change_desc)["descriptor"] 381 # Create a wallet with private keys that can sign PSBTs 382 rbf_node.createwallet(wallet_name="signer", disable_private_keys=False, blank=True) 383 signer = rbf_node.get_wallet_rpc("signer") 384 assert signer.getwalletinfo()['private_keys_enabled'] 385 reqs = [{ 386 "desc": priv_rec_desc, 387 "timestamp": 0, 388 "range": [0,1], 389 "internal": False, 390 "keypool": False # Keys can only be imported to the keypool when private keys are disabled 391 }, 392 { 393 "desc": priv_change_desc, 394 "timestamp": 0, 395 "range": [0, 0], 396 "internal": True, 397 "keypool": False 398 }] 399 if self.options.descriptors: 400 result = signer.importdescriptors(reqs) 401 else: 402 result = signer.importmulti(reqs) 403 assert_equal(result, [{'success': True}, {'success': True}]) 404 405 # Create another wallet with just the public keys, which creates PSBTs 406 rbf_node.createwallet(wallet_name="watcher", disable_private_keys=True, blank=True) 407 watcher = rbf_node.get_wallet_rpc("watcher") 408 assert not watcher.getwalletinfo()['private_keys_enabled'] 409 410 reqs = [{ 411 "desc": pub_rec_desc, 412 "timestamp": 0, 413 "range": [0, 10], 414 "internal": False, 415 "keypool": True, 416 "watchonly": True, 417 "active": True, 418 }, { 419 "desc": pub_change_desc, 420 "timestamp": 0, 421 "range": [0, 10], 422 "internal": True, 423 "keypool": True, 424 "watchonly": True, 425 "active": True, 426 }] 427 if self.options.descriptors: 428 result = watcher.importdescriptors(reqs) 429 else: 430 result = watcher.importmulti(reqs) 431 assert_equal(result, [{'success': True}, {'success': True}]) 432 433 funding_address1 = watcher.getnewaddress(address_type='bech32') 434 funding_address2 = watcher.getnewaddress(address_type='bech32') 435 peer_node.sendmany("", {funding_address1: 0.001, funding_address2: 0.001}) 436 peer_node.generate(1) 437 self.sync_all() 438 439 # Create single-input PSBT for transaction to be bumped 440 psbt = watcher.walletcreatefundedpsbt([], {dest_address: 0.0005}, 0, {"fee_rate": 1}, True)['psbt'] 441 psbt_signed = signer.walletprocesspsbt(psbt=psbt, sign=True, sighashtype="ALL", bip32derivs=True) 442 psbt_final = watcher.finalizepsbt(psbt_signed["psbt"]) 443 original_txid = watcher.sendrawtransaction(psbt_final["hex"]) 444 assert_equal(len(watcher.decodepsbt(psbt)["tx"]["vin"]), 1) 445 446 # bumpfee can't be used on watchonly wallets 447 assert_raises_rpc_error(-4, "bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead.", watcher.bumpfee, original_txid) 448 449 # Bump fee, obnoxiously high to add additional watchonly input 450 bumped_psbt = watcher.psbtbumpfee(original_txid, {"fee_rate": HIGH}) 451 assert_greater_than(len(watcher.decodepsbt(bumped_psbt['psbt'])["tx"]["vin"]), 1) 452 assert "txid" not in bumped_psbt 453 assert_equal(bumped_psbt["origfee"], -watcher.gettransaction(original_txid)["fee"]) 454 assert not watcher.finalizepsbt(bumped_psbt["psbt"])["complete"] 455 456 # Sign bumped transaction 457 bumped_psbt_signed = signer.walletprocesspsbt(psbt=bumped_psbt["psbt"], sign=True, sighashtype="ALL", bip32derivs=True) 458 bumped_psbt_final = watcher.finalizepsbt(bumped_psbt_signed["psbt"]) 459 assert bumped_psbt_final["complete"] 460 461 # Broadcast bumped transaction 462 bumped_txid = watcher.sendrawtransaction(bumped_psbt_final["hex"]) 463 assert bumped_txid in rbf_node.getrawmempool() 464 assert original_txid not in rbf_node.getrawmempool() 465 466 rbf_node.unloadwallet("watcher") 467 rbf_node.unloadwallet("signer") 468 self.clear_mempool() 469 470 471def test_rebumping(self, rbf_node, dest_address): 472 self.log.info('Test that re-bumping the original tx fails, but bumping successor works') 473 rbfid = spend_one_input(rbf_node, dest_address) 474 bumped = rbf_node.bumpfee(rbfid, {"fee_rate": ECONOMICAL}) 475 assert_raises_rpc_error(-4, "already bumped", rbf_node.bumpfee, rbfid, {"fee_rate": NORMAL}) 476 rbf_node.bumpfee(bumped["txid"], {"fee_rate": NORMAL}) 477 self.clear_mempool() 478 479 480def test_rebumping_not_replaceable(self, rbf_node, dest_address): 481 self.log.info('Test that re-bumping non-replaceable fails') 482 rbfid = spend_one_input(rbf_node, dest_address) 483 bumped = rbf_node.bumpfee(rbfid, {"fee_rate": ECONOMICAL, "replaceable": False}) 484 assert_raises_rpc_error(-4, "Transaction is not BIP 125 replaceable", rbf_node.bumpfee, bumped["txid"], 485 {"fee_rate": NORMAL}) 486 self.clear_mempool() 487 488 489def test_unconfirmed_not_spendable(self, rbf_node, rbf_node_address): 490 self.log.info('Test that unconfirmed outputs from bumped txns are not spendable') 491 rbfid = spend_one_input(rbf_node, rbf_node_address) 492 rbftx = rbf_node.gettransaction(rbfid)["hex"] 493 assert rbfid in rbf_node.getrawmempool() 494 bumpid = rbf_node.bumpfee(rbfid)["txid"] 495 assert bumpid in rbf_node.getrawmempool() 496 assert rbfid not in rbf_node.getrawmempool() 497 498 # check that outputs from the bump transaction are not spendable 499 # due to the replaces_txid check in CWallet::AvailableCoins 500 assert_equal([t for t in rbf_node.listunspent(minconf=0, include_unsafe=False) if t["txid"] == bumpid], []) 501 502 # submit a block with the rbf tx to clear the bump tx out of the mempool, 503 # then invalidate the block so the rbf tx will be put back in the mempool. 504 # This makes it possible to check whether the rbf tx outputs are 505 # spendable before the rbf tx is confirmed. 506 block = submit_block_with_tx(rbf_node, rbftx) 507 # Can not abandon conflicted tx 508 assert_raises_rpc_error(-5, 'Transaction not eligible for abandonment', lambda: rbf_node.abandontransaction(txid=bumpid)) 509 rbf_node.invalidateblock(block.hash) 510 # Call abandon to make sure the wallet doesn't attempt to resubmit 511 # the bump tx and hope the wallet does not rebroadcast before we call. 512 rbf_node.abandontransaction(bumpid) 513 assert bumpid not in rbf_node.getrawmempool() 514 assert rbfid in rbf_node.getrawmempool() 515 516 # check that outputs from the rbf tx are not spendable before the 517 # transaction is confirmed, due to the replaced_by_txid check in 518 # CWallet::AvailableCoins 519 assert_equal([t for t in rbf_node.listunspent(minconf=0, include_unsafe=False) if t["txid"] == rbfid], []) 520 521 # check that the main output from the rbf tx is spendable after confirmed 522 rbf_node.generate(1) 523 assert_equal( 524 sum(1 for t in rbf_node.listunspent(minconf=0, include_unsafe=False) 525 if t["txid"] == rbfid and t["address"] == rbf_node_address and t["spendable"]), 1) 526 self.clear_mempool() 527 528 529def test_bumpfee_metadata(self, rbf_node, dest_address): 530 self.log.info('Test that bumped txn metadata persists to new txn record') 531 assert(rbf_node.getbalance() < 49) 532 rbf_node.generatetoaddress(101, rbf_node.getnewaddress()) 533 rbfid = rbf_node.sendtoaddress(dest_address, 49, "comment value", "to value") 534 bumped_tx = rbf_node.bumpfee(rbfid) 535 bumped_wtx = rbf_node.gettransaction(bumped_tx["txid"]) 536 assert_equal(bumped_wtx["comment"], "comment value") 537 assert_equal(bumped_wtx["to"], "to value") 538 self.clear_mempool() 539 540 541def test_locked_wallet_fails(self, rbf_node, dest_address): 542 self.log.info('Test that locked wallet cannot bump txn') 543 rbfid = spend_one_input(rbf_node, dest_address) 544 rbf_node.walletlock() 545 assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first.", 546 rbf_node.bumpfee, rbfid) 547 rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT) 548 self.clear_mempool() 549 550 551def test_change_script_match(self, rbf_node, dest_address): 552 self.log.info('Test that the same change addresses is used for the replacement transaction when possible') 553 554 def get_change_address(tx): 555 tx_details = rbf_node.getrawtransaction(tx, 1) 556 txout_addresses = [txout['scriptPubKey']['address'] for txout in tx_details["vout"]] 557 return [address for address in txout_addresses if rbf_node.getaddressinfo(address)["ischange"]] 558 559 # Check that there is only one change output 560 rbfid = spend_one_input(rbf_node, dest_address) 561 change_addresses = get_change_address(rbfid) 562 assert_equal(len(change_addresses), 1) 563 564 # Now find that address in each subsequent tx, and no other change 565 bumped_total_tx = rbf_node.bumpfee(rbfid, {"fee_rate": ECONOMICAL}) 566 assert_equal(change_addresses, get_change_address(bumped_total_tx['txid'])) 567 bumped_rate_tx = rbf_node.bumpfee(bumped_total_tx["txid"]) 568 assert_equal(change_addresses, get_change_address(bumped_rate_tx['txid'])) 569 self.clear_mempool() 570 571 572def spend_one_input(node, dest_address, change_size=Decimal("0.00049000")): 573 tx_input = dict( 574 sequence=BIP125_SEQUENCE_NUMBER, **next(u for u in node.listunspent() if u["amount"] == Decimal("0.00100000"))) 575 destinations = {dest_address: Decimal("0.00050000")} 576 if change_size > 0: 577 destinations[node.getrawchangeaddress()] = change_size 578 rawtx = node.createrawtransaction([tx_input], destinations) 579 signedtx = node.signrawtransactionwithwallet(rawtx) 580 txid = node.sendrawtransaction(signedtx["hex"]) 581 return txid 582 583 584def submit_block_with_tx(node, tx): 585 ctx = tx_from_hex(tx) 586 tip = node.getbestblockhash() 587 height = node.getblockcount() + 1 588 block_time = node.getblockheader(tip)["mediantime"] + 1 589 block = create_block(int(tip, 16), create_coinbase(height), block_time) 590 block.vtx.append(ctx) 591 block.rehash() 592 block.hashMerkleRoot = block.calc_merkle_root() 593 add_witness_commitment(block) 594 block.solve() 595 node.submitblock(block.serialize().hex()) 596 return block 597 598 599def test_no_more_inputs_fails(self, rbf_node, dest_address): 600 self.log.info('Test that bumpfee fails when there are no available confirmed outputs') 601 # feerate rbf requires confirmed outputs when change output doesn't exist or is insufficient 602 rbf_node.generatetoaddress(1, dest_address) 603 # spend all funds, no change output 604 rbfid = rbf_node.sendtoaddress(rbf_node.getnewaddress(), rbf_node.getbalance(), "", "", True) 605 assert_raises_rpc_error(-4, "Unable to create transaction. Insufficient funds", rbf_node.bumpfee, rbfid) 606 self.clear_mempool() 607 608 609if __name__ == "__main__": 610 BumpFeeTest().main() 611