wallet_bumpfee.py raw

   1  #!/usr/bin/env python3
   2  # Copyright (c) 2016-2022 The Limenka 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  
   7  Verifies that the bumpfee RPC creates replacement transactions successfully when
   8  its preconditions are met, and returns appropriate errors in other cases.
   9  
  10  This module consists of around a dozen individual test cases implemented in the
  11  top-level functions named as test_<test_case_description>. The test functions
  12  can be disabled or reordered if needed for debugging. If new test cases are
  13  added in the future, they should try to follow the same convention and not
  14  make assumptions about execution order.
  15  """
  16  from decimal import Decimal
  17  
  18  from test_framework.blocktools import (
  19      COINBASE_MATURITY,
  20  )
  21  from test_framework.messages import (
  22      COIN,
  23      MAX_BIP125_RBF_SEQUENCE,
  24  )
  25  from test_framework.test_framework import LimenkaTestFramework
  26  from test_framework.util import (
  27      assert_approx,
  28      assert_equal,
  29      assert_fee_amount,
  30      assert_greater_than,
  31      assert_raises_rpc_error,
  32      get_fee,
  33      find_vout_for_address,
  34  )
  35  from test_framework.wallet import MiniWallet
  36  
  37  
  38  WALLET_PASSPHRASE = "test"
  39  WALLET_PASSPHRASE_TIMEOUT = 3600
  40  
  41  # Fee rates (sat/vB)
  42  INSUFFICIENT =      1
  43  ECONOMICAL   =     50
  44  NORMAL       =    100
  45  HIGH         =    500
  46  TOO_HIGH     = 100000
  47  
  48  def get_change_address(tx, node):
  49      tx_details = node.getrawtransaction(tx, 1)
  50      txout_addresses = [txout['scriptPubKey']['address'] for txout in tx_details["vout"]]
  51      return [address for address in txout_addresses if node.getaddressinfo(address)["ischange"]]
  52  
  53  class BumpFeeTest(LimenkaTestFramework):
  54      def add_options(self, parser):
  55          self.add_wallet_options(parser)
  56  
  57      def set_test_params(self):
  58          self.num_nodes = 2
  59          self.setup_clean_chain = True
  60          # whitelist peers to speed up tx relay / mempool sync
  61          self.noban_tx_relay = True
  62          self.extra_args = [[
  63              "-walletrbf={}".format(i),
  64              "-incrementalrelayfee=0.00001",
  65              "-mintxfee=0.00002",
  66              "-addresstype=bech32",
  67          ] for i in range(self.num_nodes)]
  68          self.wallet_names = [self.default_wallet_name, "RBF wallet"]
  69  
  70      def skip_test_if_missing_module(self):
  71          self.skip_if_no_wallet()
  72  
  73      def clear_mempool(self):
  74          # Clear mempool between subtests. The subtests may only depend on chainstate (utxos)
  75          self.generate(self.nodes[1], 1)
  76  
  77      def run_test(self):
  78          # Encrypt wallet for test_locked_wallet_fails test
  79          self.nodes[1].encryptwallet(WALLET_PASSPHRASE)
  80          self.nodes[1].walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
  81  
  82          peer_node, rbf_node = self.nodes
  83          rbf_node_address = rbf_node.getnewaddress()
  84  
  85          # fund rbf node with 10 coins of 0.001 btc (100,000 satoshis)
  86          self.log.info("Mining blocks...")
  87          self.generate(peer_node, 110)
  88          for _ in range(25):
  89              peer_node.sendtoaddress(rbf_node_address, 0.001)
  90          self.sync_all()
  91          self.generate(peer_node, 1)
  92          assert_equal(rbf_node.getbalance(), Decimal("0.025"))
  93  
  94          self.log.info("Running tests")
  95          dest_address = peer_node.getnewaddress()
  96          for mode in ["default", "fee_rate", "new_outputs"]:
  97              test_simple_bumpfee_succeeds(self, mode, rbf_node, peer_node, dest_address)
  98          self.test_invalid_parameters(rbf_node, peer_node, dest_address)
  99          test_segwit_bumpfee_succeeds(self, rbf_node, dest_address)
 100          test_nonrbf_bumpfee_succeeds(self, peer_node, dest_address)
 101          test_nonrbf_bumpfee_fails(self, peer_node, dest_address)
 102          test_notmine_bumpfee(self, rbf_node, peer_node, dest_address)
 103          test_bumpfee_with_descendant_fails(self, rbf_node, rbf_node_address, dest_address)
 104          test_bumpfee_with_abandoned_descendant_succeeds(self, rbf_node, rbf_node_address, dest_address)
 105          test_dust_to_fee(self, rbf_node, dest_address)
 106          test_watchonly_psbt(self, peer_node, rbf_node, dest_address)
 107          test_rebumping(self, rbf_node, dest_address)
 108          test_rebumping_not_replaceable(self, rbf_node, dest_address)
 109          test_bumpfee_already_spent(self, rbf_node, dest_address)
 110          test_unconfirmed_not_spendable(self, rbf_node, rbf_node_address)
 111          test_bumpfee_metadata(self, rbf_node, dest_address)
 112          test_locked_wallet_fails(self, rbf_node, dest_address)
 113          test_change_script_match(self, rbf_node, dest_address)
 114          test_setfeerate(self, rbf_node, dest_address)
 115          test_settxfee(self, rbf_node, dest_address)
 116          test_maxtxfee_fails(self, rbf_node, dest_address)
 117          # These tests wipe out a number of utxos that are expected in other tests
 118          test_small_output_with_feerate_succeeds(self, rbf_node, dest_address)
 119          test_no_more_inputs_fails(self, rbf_node, dest_address)
 120          self.test_bump_back_to_yourself()
 121          self.test_provided_change_pos(rbf_node)
 122          self.test_single_output()
 123  
 124          # Context independent tests
 125          test_feerate_checks_replaced_outputs(self, rbf_node, peer_node)
 126          test_bumpfee_with_feerate_ignores_walletincrementalrelayfee(self, rbf_node, peer_node)
 127  
 128      def test_invalid_parameters(self, rbf_node, peer_node, dest_address):
 129          self.log.info('Test invalid parameters')
 130          rbfid = spend_one_input(rbf_node, dest_address)
 131          self.sync_mempools((rbf_node, peer_node))
 132          assert rbfid in rbf_node.getrawmempool() and rbfid in peer_node.getrawmempool()
 133  
 134          for key in ["totalFee", "feeRate"]:
 135              assert_raises_rpc_error(-3, "Unexpected key {}".format(key), rbf_node.bumpfee, rbfid, {key: NORMAL})
 136  
 137          # Bumping to just above minrelay should fail to increase the total fee enough.
 138          assert_raises_rpc_error(-8, "Insufficient total fee 0.00000141", rbf_node.bumpfee, rbfid, fee_rate=INSUFFICIENT)
 139  
 140          self.log.info("Test invalid fee rate settings")
 141          assert_raises_rpc_error(-4, "Specified or calculated fee 0.141 is too high (cannot be higher than -maxtxfee 0.10",
 142              rbf_node.bumpfee, rbfid, fee_rate=TOO_HIGH)
 143          # Test fee_rate with zero values.
 144          msg = "Insufficient total fee 0.00"
 145          for zero_value in [0, 0.000, 0.00000000, "0", "0.000", "0.00000000"]:
 146              assert_raises_rpc_error(-8, msg, rbf_node.bumpfee, rbfid, fee_rate=zero_value)
 147          msg = "Invalid amount"
 148          # Test fee_rate values that don't pass fixed-point parsing checks.
 149          for invalid_value in ["", 0.000000001, 1e-09, 1.111111111, 1111111111111111, "31.999999999999999999999"]:
 150              assert_raises_rpc_error(-3, msg, rbf_node.bumpfee, rbfid, fee_rate=invalid_value)
 151          # Test fee_rate values that cannot be represented in sat/vB.
 152          for invalid_value in [0.0001, 0.00000001, 0.00099999, 31.99999999]:
 153              assert_raises_rpc_error(-3, msg, rbf_node.bumpfee, rbfid, fee_rate=invalid_value)
 154          # Test fee_rate out of range (negative number).
 155          assert_raises_rpc_error(-3, "Amount out of range", rbf_node.bumpfee, rbfid, fee_rate=-1)
 156          # Test type error.
 157          for value in [{"foo": "bar"}, True]:
 158              assert_raises_rpc_error(-3, "Amount is not a number or string", rbf_node.bumpfee, rbfid, fee_rate=value)
 159  
 160          self.log.info("Test explicit fee rate raises RPC error if both fee_rate and conf_target are passed")
 161          assert_raises_rpc_error(-8, "Cannot specify both conf_target and fee_rate. Please provide either a confirmation "
 162              "target in blocks for automatic fee estimation, or an explicit fee rate.",
 163              rbf_node.bumpfee, rbfid, conf_target=NORMAL, fee_rate=NORMAL)
 164  
 165          self.log.info("Test explicit fee rate raises RPC error if both fee_rate and estimate_mode are passed")
 166          assert_raises_rpc_error(-8, "Cannot specify both estimate_mode and fee_rate",
 167              rbf_node.bumpfee, rbfid, estimate_mode="economical", fee_rate=NORMAL)
 168  
 169          self.log.info("Test invalid conf_target settings")
 170          assert_raises_rpc_error(-8, "confTarget and conf_target options should not both be set",
 171              rbf_node.bumpfee, rbfid, {"confTarget": 123, "conf_target": 456})
 172  
 173          self.log.info("Test invalid estimate_mode settings")
 174          for k, v in {"number": 42, "object": {"foo": "bar"}}.items():
 175              assert_raises_rpc_error(-3, f"JSON value of type {k} for field estimate_mode is not of expected type string",
 176                  rbf_node.bumpfee, rbfid, estimate_mode=v)
 177          for mode in ["foo", Decimal("3.1415"), "sat/B", "BTC/kB"]:
 178              assert_raises_rpc_error(-8, 'Invalid estimate_mode parameter, must be one of: "unset", "economical", "conservative"',
 179                  rbf_node.bumpfee, rbfid, estimate_mode=mode)
 180  
 181          self.log.info("Test invalid outputs values")
 182          assert_raises_rpc_error(-8, "Invalid parameter, output argument cannot be an empty array",
 183                  rbf_node.bumpfee, rbfid, {"outputs": []})
 184          assert_raises_rpc_error(-8, "Invalid parameter, duplicated address: " + dest_address,
 185                  rbf_node.bumpfee, rbfid, {"outputs": [{dest_address: 0.1}, {dest_address: 0.2}]})
 186          assert_raises_rpc_error(-8, "Invalid parameter, duplicate key: data",
 187                  rbf_node.bumpfee, rbfid, {"outputs": [{"data": "deadbeef"}, {"data": "deadbeef"}]})
 188  
 189          self.log.info("Test original_change_index option")
 190          assert_raises_rpc_error(-1, "JSON integer out of range", rbf_node.bumpfee, rbfid, {"original_change_index": -1})
 191          assert_raises_rpc_error(-8, "Change position is out of range", rbf_node.bumpfee, rbfid, {"original_change_index": 2})
 192  
 193          self.log.info("Test outputs and original_change_index cannot both be provided")
 194          assert_raises_rpc_error(-8, "The options 'outputs' and 'original_change_index' are incompatible. You can only either specify a new set of outputs, or designate a change output to be recycled.", rbf_node.bumpfee, rbfid, {"original_change_index": 2, "outputs": [{dest_address: 0.1}]})
 195  
 196          self.clear_mempool()
 197  
 198      def test_bump_back_to_yourself(self):
 199          self.log.info("Test that bumpfee can send coins back to yourself")
 200          node = self.nodes[1]
 201  
 202          node.createwallet("back_to_yourself")
 203          wallet = node.get_wallet_rpc("back_to_yourself")
 204  
 205          # Make 3 UTXOs
 206          addr = wallet.getnewaddress()
 207          for _ in range(3):
 208              self.nodes[0].sendtoaddress(addr, 5)
 209          self.generate(self.nodes[0], 1)
 210  
 211          # Create a tx with two outputs. recipient and change.
 212          tx = wallet.send(outputs={wallet.getnewaddress(): 9}, fee_rate=2)
 213          tx_info = wallet.gettransaction(txid=tx["txid"], verbose=True)
 214          assert_equal(len(tx_info["decoded"]["vout"]), 2)
 215          assert_equal(len(tx_info["decoded"]["vin"]), 2)
 216  
 217          # Bump tx, send coins back to change address.
 218          change_addr = get_change_address(tx["txid"], wallet)[0]
 219          out_amount = 10
 220          bumped = wallet.bumpfee(txid=tx["txid"], options={"fee_rate": 20, "outputs": [{change_addr: out_amount}]})
 221          bumped_tx = wallet.gettransaction(txid=bumped["txid"], verbose=True)
 222          assert_equal(len(bumped_tx["decoded"]["vout"]), 1)
 223          assert_equal(len(bumped_tx["decoded"]["vin"]), 2)
 224          assert_equal(bumped_tx["decoded"]["vout"][0]["value"] + bumped["fee"], out_amount)
 225  
 226          # Bump tx again, now test send fewer coins back to change address.
 227          out_amount = 6
 228          bumped = wallet.bumpfee(txid=bumped["txid"], options={"fee_rate": 40, "outputs": [{change_addr: out_amount}]})
 229          bumped_tx = wallet.gettransaction(txid=bumped["txid"], verbose=True)
 230          assert_equal(len(bumped_tx["decoded"]["vout"]), 2)
 231          assert_equal(len(bumped_tx["decoded"]["vin"]), 2)
 232          assert any(txout['value'] == out_amount - bumped["fee"] and txout['scriptPubKey']['address'] == change_addr for txout in bumped_tx['decoded']['vout'])
 233          # Check that total out amount is still equal to the previously bumped tx
 234          assert_equal(bumped_tx["decoded"]["vout"][0]["value"] + bumped_tx["decoded"]["vout"][1]["value"] + bumped["fee"], 10)
 235  
 236          # Bump tx again, send more coins back to change address. The process will add another input to cover the target.
 237          out_amount = 12
 238          bumped = wallet.bumpfee(txid=bumped["txid"], options={"fee_rate": 80, "outputs": [{change_addr: out_amount}]})
 239          bumped_tx = wallet.gettransaction(txid=bumped["txid"], verbose=True)
 240          assert_equal(len(bumped_tx["decoded"]["vout"]), 2)
 241          assert_equal(len(bumped_tx["decoded"]["vin"]), 3)
 242          assert any(txout['value'] == out_amount - bumped["fee"] and txout['scriptPubKey']['address'] == change_addr for txout in bumped_tx['decoded']['vout'])
 243          assert_equal(bumped_tx["decoded"]["vout"][0]["value"] + bumped_tx["decoded"]["vout"][1]["value"] + bumped["fee"], 15)
 244  
 245          node.unloadwallet("back_to_yourself")
 246  
 247      def test_provided_change_pos(self, rbf_node):
 248          self.log.info("Test the original_change_index option")
 249  
 250          change_addr = rbf_node.getnewaddress()
 251          dest_addr = rbf_node.getnewaddress()
 252          assert_equal(rbf_node.getaddressinfo(change_addr)["ischange"], False)
 253          assert_equal(rbf_node.getaddressinfo(dest_addr)["ischange"], False)
 254  
 255          send_res = rbf_node.send(outputs=[{dest_addr: 1}], options={"change_address": change_addr})
 256          assert send_res["complete"]
 257          txid = send_res["txid"]
 258  
 259          tx = rbf_node.gettransaction(txid=txid, verbose=True)
 260          assert_equal(len(tx["decoded"]["vout"]), 2)
 261  
 262          change_pos = find_vout_for_address(rbf_node, txid, change_addr)
 263          change_value = tx["decoded"]["vout"][change_pos]["value"]
 264  
 265          bumped = rbf_node.bumpfee(txid, {"original_change_index": change_pos})
 266          new_txid = bumped["txid"]
 267  
 268          new_tx = rbf_node.gettransaction(txid=new_txid, verbose=True)
 269          assert_equal(len(new_tx["decoded"]["vout"]), 2)
 270          new_change_pos = find_vout_for_address(rbf_node, new_txid, change_addr)
 271          new_change_value = new_tx["decoded"]["vout"][new_change_pos]["value"]
 272  
 273          assert_greater_than(change_value, new_change_value)
 274  
 275  
 276      def test_single_output(self):
 277          self.log.info("Test that single output txs can be bumped")
 278          node = self.nodes[1]
 279  
 280          node.createwallet("single_out_rbf")
 281          wallet = node.get_wallet_rpc("single_out_rbf")
 282  
 283          addr = wallet.getnewaddress()
 284          amount = Decimal("0.001")
 285          # Make 2 UTXOs
 286          self.nodes[0].sendtoaddress(addr, amount)
 287          self.nodes[0].sendtoaddress(addr, amount)
 288          self.generate(self.nodes[0], 1)
 289          utxos = wallet.listunspent()
 290  
 291          tx = wallet.sendall(recipients=[wallet.getnewaddress()], fee_rate=2, options={"inputs": [utxos[0]]})
 292  
 293          # Set the only output with a crazy high feerate as change, should fail as the output would be dust
 294          assert_raises_rpc_error(-4, "The transaction amount is too small to pay the fee", wallet.bumpfee, txid=tx["txid"], options={"fee_rate": 1100, "original_change_index": 0})
 295  
 296          # Specify single output as change successfully
 297          bumped = wallet.bumpfee(txid=tx["txid"], options={"fee_rate": 10, "original_change_index": 0})
 298          bumped_tx = wallet.gettransaction(txid=bumped["txid"], verbose=True)
 299          assert_equal(len(bumped_tx["decoded"]["vout"]), 1)
 300          assert_equal(len(bumped_tx["decoded"]["vin"]), 1)
 301          assert_equal(bumped_tx["decoded"]["vout"][0]["value"] + bumped["fee"], amount)
 302          assert_fee_amount(bumped["fee"], bumped_tx["decoded"]["vsize"], Decimal(10) / Decimal(1e8) * 1000)
 303  
 304          # Bumping without specifying change adds a new input and output
 305          bumped = wallet.bumpfee(txid=bumped["txid"], options={"fee_rate": 20})
 306          bumped_tx = wallet.gettransaction(txid=bumped["txid"], verbose=True)
 307          assert_equal(len(bumped_tx["decoded"]["vout"]), 2)
 308          assert_equal(len(bumped_tx["decoded"]["vin"]), 2)
 309          assert_fee_amount(bumped["fee"], bumped_tx["decoded"]["vsize"], Decimal(20) / Decimal(1e8) * 1000)
 310  
 311          wallet.unloadwallet()
 312  
 313  def test_simple_bumpfee_succeeds(self, mode, rbf_node, peer_node, dest_address):
 314      self.log.info('Test simple bumpfee: {}'.format(mode))
 315      rbfid = spend_one_input(rbf_node, dest_address)
 316      rbftx = rbf_node.gettransaction(rbfid)
 317      self.sync_mempools((rbf_node, peer_node))
 318      assert rbfid in rbf_node.getrawmempool() and rbfid in peer_node.getrawmempool()
 319      if mode == "fee_rate":
 320          bumped_psbt = rbf_node.psbtbumpfee(rbfid, fee_rate=str(NORMAL))
 321          bumped_tx = rbf_node.bumpfee(rbfid, fee_rate=NORMAL)
 322      elif mode == "new_outputs":
 323          new_address = peer_node.getnewaddress()
 324          bumped_psbt = rbf_node.psbtbumpfee(rbfid, outputs={new_address: 0.0003})
 325          bumped_tx = rbf_node.bumpfee(rbfid, outputs={new_address: 0.0003})
 326      else:
 327          bumped_psbt = rbf_node.psbtbumpfee(rbfid)
 328          bumped_tx = rbf_node.bumpfee(rbfid)
 329      assert_equal(bumped_tx["errors"], [])
 330      assert bumped_tx["fee"] > -rbftx["fee"]
 331      assert_equal(bumped_tx["origfee"], -rbftx["fee"])
 332      assert "psbt" not in bumped_tx
 333      assert_equal(bumped_psbt["errors"], [])
 334      assert bumped_psbt["fee"] > -rbftx["fee"]
 335      assert_equal(bumped_psbt["origfee"], -rbftx["fee"])
 336      assert "psbt" in bumped_psbt
 337      # check that bumped_tx propagates, original tx was evicted and has a wallet conflict
 338      self.sync_mempools((rbf_node, peer_node))
 339      assert bumped_tx["txid"] in rbf_node.getrawmempool()
 340      assert bumped_tx["txid"] in peer_node.getrawmempool()
 341      assert rbfid not in rbf_node.getrawmempool()
 342      assert rbfid not in peer_node.getrawmempool()
 343      oldwtx = rbf_node.gettransaction(rbfid)
 344      assert len(oldwtx["walletconflicts"]) > 0
 345      # check wallet transaction replaces and replaced_by values
 346      bumpedwtx = rbf_node.gettransaction(bumped_tx["txid"])
 347      assert_equal(oldwtx["replaced_by_txid"], bumped_tx["txid"])
 348      assert_equal(bumpedwtx["replaces_txid"], rbfid)
 349      # if this is a new_outputs test, check that outputs were indeed replaced
 350      if mode == "new_outputs":
 351          assert len(bumpedwtx["details"]) == 1
 352          assert bumpedwtx["details"][0]["address"] == new_address
 353      self.clear_mempool()
 354  
 355  
 356  def test_segwit_bumpfee_succeeds(self, rbf_node, dest_address):
 357      self.log.info('Test that segwit-sourcing bumpfee works')
 358      # Create a transaction with segwit output, then create an RBF transaction
 359      # which spends it, and make sure bumpfee can be called on it.
 360  
 361      segwit_out = rbf_node.getnewaddress(address_type='bech32')
 362      segwitid = rbf_node.send({segwit_out: "0.0009"}, options={"change_position": 1})["txid"]
 363  
 364      rbfraw = rbf_node.createrawtransaction([{
 365          'txid': segwitid,
 366          'vout': 0,
 367          "sequence": MAX_BIP125_RBF_SEQUENCE
 368      }], {dest_address: Decimal("0.0005"),
 369           rbf_node.getrawchangeaddress(): Decimal("0.0003")})
 370      rbfsigned = rbf_node.signrawtransactionwithwallet(rbfraw)
 371      rbfid = rbf_node.sendrawtransaction(rbfsigned["hex"])
 372      assert rbfid in rbf_node.getrawmempool()
 373  
 374      bumped_tx = rbf_node.bumpfee(rbfid)
 375      assert bumped_tx["txid"] in rbf_node.getrawmempool()
 376      assert rbfid not in rbf_node.getrawmempool()
 377      self.clear_mempool()
 378  
 379  
 380  def test_nonrbf_bumpfee_succeeds(self, peer_node, dest_address):
 381      self.log.info("Test that we can replace a non RBF transaction (RPC require_replacable=false)")
 382      not_rbfid = peer_node.sendtoaddress(dest_address, Decimal("0.00090000"))
 383      peer_node.bumpfee(not_rbfid, require_replacable=False)
 384      self.clear_mempool()
 385  
 386  
 387  def test_nonrbf_bumpfee_fails(self, peer_node, dest_address):
 388      self.log.info('Test that we cannot replace a non RBF transaction')
 389      not_rbfid = peer_node.sendtoaddress(dest_address, Decimal("0.00090000"))
 390      assert_raises_rpc_error(-4, "Transaction is not BIP 125 replaceable", peer_node.bumpfee, not_rbfid)
 391      self.clear_mempool()
 392  
 393  
 394  def test_notmine_bumpfee(self, rbf_node, peer_node, dest_address):
 395      self.log.info('Test that it cannot bump fee if non-owned inputs are included')
 396      # here, the rbftx has a peer_node coin and then adds a rbf_node input
 397      # Note that this test depends upon the RPC code checking input ownership prior to change outputs
 398      # (since it can't use fundrawtransaction, it lacks a proper change output)
 399      fee = Decimal("0.001")
 400      utxos = [node.listunspent(minimumAmount=fee)[-1] for node in (rbf_node, peer_node)]
 401      inputs = [{
 402          "txid": utxo["txid"],
 403          "vout": utxo["vout"],
 404          "address": utxo["address"],
 405          "sequence": MAX_BIP125_RBF_SEQUENCE
 406      } for utxo in utxos]
 407      output_val = sum(utxo["amount"] for utxo in utxos) - fee
 408      rawtx = rbf_node.createrawtransaction(inputs, {dest_address: output_val})
 409      signedtx = rbf_node.signrawtransactionwithwallet(rawtx)
 410      signedtx = peer_node.signrawtransactionwithwallet(signedtx["hex"])
 411      rbfid = rbf_node.sendrawtransaction(signedtx["hex"])
 412      entry = rbf_node.getmempoolentry(rbfid)
 413      old_fee = entry["fees"]["base"]
 414      old_feerate = int(old_fee / entry["vsize"] * Decimal(1e8))
 415      assert_raises_rpc_error(-4, "Transaction contains inputs that don't belong to this wallet",
 416                              rbf_node.bumpfee, rbfid)
 417  
 418      def finish_psbtbumpfee(psbt):
 419          psbt = rbf_node.walletprocesspsbt(psbt)
 420          psbt = peer_node.walletprocesspsbt(psbt["psbt"])
 421          res = rbf_node.testmempoolaccept([psbt["hex"]])
 422          assert res[0]["allowed"]
 423          assert_greater_than(res[0]["fees"]["base"], old_fee)
 424  
 425      self.log.info("Test that psbtbumpfee works for non-owned inputs")
 426      psbt = rbf_node.psbtbumpfee(txid=rbfid)
 427      finish_psbtbumpfee(psbt["psbt"])
 428  
 429      psbt = rbf_node.psbtbumpfee(txid=rbfid, fee_rate=old_feerate + 10)
 430      finish_psbtbumpfee(psbt["psbt"])
 431  
 432      self.clear_mempool()
 433  
 434  
 435  def test_bumpfee_with_descendant_fails(self, rbf_node, rbf_node_address, dest_address):
 436      self.log.info('Test that fee cannot be bumped when it has descendant')
 437      # parent is send-to-self, so we don't have to check which output is change when creating the child tx
 438      parent_id = spend_one_input(rbf_node, rbf_node_address)
 439      tx = rbf_node.createrawtransaction([{"txid": parent_id, "vout": 0}], {dest_address: 0.00020000})
 440      tx = rbf_node.signrawtransactionwithwallet(tx)
 441      rbf_node.sendrawtransaction(tx["hex"])
 442      assert_raises_rpc_error(-8, "Transaction has descendants in the wallet", rbf_node.bumpfee, parent_id)
 443  
 444      # create tx with descendant in the mempool by using MiniWallet
 445      miniwallet = MiniWallet(rbf_node)
 446      parent_id = spend_one_input(rbf_node, miniwallet.get_address())
 447      tx = rbf_node.gettransaction(txid=parent_id, verbose=True)['decoded']
 448      miniwallet.scan_tx(tx)
 449      miniwallet.send_self_transfer(from_node=rbf_node)
 450      assert_raises_rpc_error(-8, "Transaction has descendants in the mempool", rbf_node.bumpfee, parent_id)
 451      self.clear_mempool()
 452  
 453  
 454  def test_bumpfee_with_abandoned_descendant_succeeds(self, rbf_node, rbf_node_address, dest_address):
 455      self.log.info('Test that fee can be bumped when it has abandoned descendant')
 456      # parent is send-to-self, so we don't have to check which output is change when creating the child tx
 457      parent_id = spend_one_input(rbf_node, rbf_node_address)
 458      # Submit child transaction with low fee
 459      child_id = rbf_node.send(outputs={dest_address: 0.00020000},
 460                               options={"inputs": [{"txid": parent_id, "vout": 0}], "fee_rate": 2})["txid"]
 461      assert child_id in rbf_node.getrawmempool()
 462  
 463      # Restart the node with higher min relay fee so the descendant tx is no longer in mempool so that we can abandon it
 464      self.restart_node(1, ['-minrelaytxfee=0.00005'] + self.extra_args[1])
 465      rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
 466      self.connect_nodes(1, 0)
 467      assert parent_id in rbf_node.getrawmempool()
 468      assert child_id not in rbf_node.getrawmempool()
 469      # Should still raise an error even if not in mempool
 470      assert_raises_rpc_error(-8, "Transaction has descendants in the wallet", rbf_node.bumpfee, parent_id)
 471      # Now abandon the child transaction and bump the original
 472      rbf_node.abandontransaction(child_id)
 473      bumped_result = rbf_node.bumpfee(parent_id, {"fee_rate": HIGH})
 474      assert bumped_result['txid'] in rbf_node.getrawmempool()
 475      assert parent_id not in rbf_node.getrawmempool()
 476      # Cleanup
 477      self.restart_node(1, self.extra_args[1])
 478      rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
 479      self.connect_nodes(1, 0)
 480      self.clear_mempool()
 481  
 482  
 483  def test_small_output_with_feerate_succeeds(self, rbf_node, dest_address):
 484      self.log.info('Testing small output with feerate bump succeeds')
 485  
 486      # Make sure additional inputs exist
 487      self.generatetoaddress(rbf_node, COINBASE_MATURITY + 1, rbf_node.getnewaddress())
 488      rbfid = spend_one_input(rbf_node, dest_address)
 489      input_list = rbf_node.getrawtransaction(rbfid, 1)["vin"]
 490      assert_equal(len(input_list), 1)
 491      original_txin = input_list[0]
 492      self.log.info('Keep bumping until transaction fee out-spends non-destination value')
 493      tx_fee = 0
 494      while True:
 495          input_list = rbf_node.getrawtransaction(rbfid, 1)["vin"]
 496          new_item = list(input_list)[0]
 497          assert_equal(len(input_list), 1)
 498          assert_equal(original_txin["txid"], new_item["txid"])
 499          assert_equal(original_txin["vout"], new_item["vout"])
 500          rbfid_new_details = rbf_node.bumpfee(rbfid)
 501          rbfid_new = rbfid_new_details["txid"]
 502          raw_pool = rbf_node.getrawmempool()
 503          assert rbfid not in raw_pool
 504          assert rbfid_new in raw_pool
 505          rbfid = rbfid_new
 506          tx_fee = rbfid_new_details["fee"]
 507  
 508          # Total value from input not going to destination
 509          if tx_fee > Decimal('0.00050000'):
 510              break
 511  
 512      # input(s) have been added
 513      final_input_list = rbf_node.getrawtransaction(rbfid, 1)["vin"]
 514      assert_greater_than(len(final_input_list), 1)
 515      # Original input is in final set
 516      assert [txin for txin in final_input_list
 517              if txin["txid"] == original_txin["txid"]
 518              and txin["vout"] == original_txin["vout"]]
 519  
 520      self.generatetoaddress(rbf_node, 1, rbf_node.getnewaddress())
 521      assert_equal(rbf_node.gettransaction(rbfid)["confirmations"], 1)
 522      self.clear_mempool()
 523  
 524  
 525  def test_dust_to_fee(self, rbf_node, dest_address):
 526      self.log.info('Test that bumped output that is dust is dropped to fee')
 527      rbfid = spend_one_input(rbf_node, dest_address)
 528      fulltx = rbf_node.getrawtransaction(rbfid, 1)
 529      # The DER formatting used by Limenka to serialize ECDSA signatures means that signatures can have a
 530      # variable size of 70-72 bytes (or possibly even less), with most being 71 or 72 bytes. The signature
 531      # in the witness is divided by 4 for the vsize, so this variance can take the weight across a 4-byte
 532      # boundary. Thus expected transaction size (p2wpkh, 1 input, 2 outputs) is 140-141 vbytes, usually 141.
 533      if not 140 <= fulltx["vsize"] <= 141:
 534          raise AssertionError("Invalid tx vsize of {} (140-141 expected), full tx: {}".format(fulltx["vsize"], fulltx))
 535      # Bump with fee_rate of 350.25 sat/vB vbytes to create dust.
 536      # Expected fee is 141 vbytes * fee_rate 0.00350250 BTC / 1000 vbytes = 0.00049385 BTC.
 537      # or occasionally 140 vbytes * fee_rate 0.00350250 BTC / 1000 vbytes = 0.00049035 BTC.
 538      # Dust should be dropped to the fee, so actual bump fee is 0.00050000 BTC.
 539      bumped_tx = rbf_node.bumpfee(rbfid, fee_rate=350.25)
 540      full_bumped_tx = rbf_node.getrawtransaction(bumped_tx["txid"], 1)
 541      assert_equal(bumped_tx["fee"], Decimal("0.00050000"))
 542      assert_equal(len(fulltx["vout"]), 2)
 543      assert_equal(len(full_bumped_tx["vout"]), 1)  # change output is eliminated
 544      assert_equal(full_bumped_tx["vout"][0]['value'], Decimal("0.00050000"))
 545      self.clear_mempool()
 546  
 547  
 548  def test_setfeerate(self, rbf_node, dest_address):
 549      self.log.info("Test setfeerate")
 550  
 551      def test_response(*, wallet="RBF wallet", requested=0, expected=0, error=None, msg):
 552          assert_equal(rbf_node.setfeerate(requested), {"wallet_name": wallet, "fee_rate": expected, ("error" if error else "result"): msg})
 553  
 554      # Test setfeerate with too high/low values returns expected errors
 555      new = Decimal("10000.001")
 556      test_response(requested=new, error=True, msg=f"The requested fee rate of {new} sat/vB cannot be greater than the wallet max fee rate of 10000.000 sat/vB. The current setting of 0 (unset) for this wallet remains unchanged.")
 557      new = Decimal("0.999")
 558      test_response(requested=new, error=True, msg=f"The requested fee rate of {new} sat/vB cannot be less than the minimum relay fee rate of 1.000 sat/vB. The current setting of 0 (unset) for this wallet remains unchanged.")
 559      fee_rate = Decimal("2.001")
 560      test_response(requested=fee_rate, expected=fee_rate, msg=f"Fee rate for transactions with this wallet successfully set to {fee_rate} sat/vB")
 561      new = Decimal("1.999")
 562      test_response(requested=new, expected=fee_rate, error=True, msg=f"The requested fee rate of {new} sat/vB cannot be less than the wallet min fee rate of 2.000 sat/vB. The current setting of {fee_rate} sat/vB for this wallet remains unchanged.")
 563  
 564      # Test setfeerate with valid values returns expected results
 565      rbfid = spend_one_input(rbf_node, dest_address)
 566      fee_rate = 25
 567      test_response(requested=fee_rate, expected=fee_rate, msg="Fee rate for transactions with this wallet successfully set to 25.000 sat/vB")
 568      bumped_tx = rbf_node.bumpfee(rbfid)
 569      bumped_txdetails = rbf_node.getrawtransaction(bumped_tx["txid"], True)
 570      allow_for_bytes_offset = len(bumped_txdetails['vout']) * 2  # potentially up to 2 bytes per output
 571      actual_fee = bumped_tx["fee"] * COIN
 572      assert_approx(actual_fee, fee_rate * bumped_txdetails['vsize'], fee_rate * allow_for_bytes_offset)
 573      test_response(msg="Fee rate for transactions with this wallet successfully unset. By default, automatic fee selection will be used.")
 574  
 575      # Test setfeerate with a different -maxtxfee
 576      self.restart_node(1, ["-maxtxfee=0.000025"] + self.extra_args[1])
 577      new = "2.501"
 578      test_response(requested=new, error=True, msg=f"The requested fee rate of {new} sat/vB cannot be greater than the wallet max fee rate of 2.500 sat/vB. The current setting of 0 (unset) for this wallet remains unchanged.")
 579  
 580      self.restart_node(1, self.extra_args[1])
 581      rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
 582      self.connect_nodes(1, 0)
 583      self.clear_mempool()
 584  
 585  
 586  def test_settxfee(self, rbf_node, dest_address):
 587      self.log.info('Test settxfee')
 588      assert_raises_rpc_error(-8, "txfee cannot be less than min relay tx fee", rbf_node.settxfee, Decimal('0.0000005'))
 589      assert_raises_rpc_error(-8, "txfee cannot be less than wallet min fee", rbf_node.settxfee, Decimal('0.000015'))
 590      # check that bumpfee reacts correctly to the use of settxfee (paytxfee)
 591      rbfid = spend_one_input(rbf_node, dest_address)
 592      requested_feerate = Decimal("0.00025000")
 593      rbf_node.settxfee(requested_feerate)
 594      bumped_tx = rbf_node.bumpfee(rbfid)
 595      actual_feerate = bumped_tx["fee"] * 1000 / rbf_node.getrawtransaction(bumped_tx["txid"], True)["vsize"]
 596      # Assert that the difference between the requested feerate and the actual
 597      # feerate of the bumped transaction is small.
 598      assert_greater_than(Decimal("0.00001000"), abs(requested_feerate - actual_feerate))
 599      rbf_node.settxfee(Decimal("0.00000000"))  # unset paytxfee
 600  
 601      # check that settxfee respects -maxtxfee
 602      self.restart_node(1, ['-maxtxfee=0.000025'] + self.extra_args[1])
 603      assert_raises_rpc_error(-8, "txfee cannot be more than wallet max tx fee", rbf_node.settxfee, Decimal('0.00003'))
 604      self.restart_node(1, self.extra_args[1])
 605      rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
 606      self.connect_nodes(1, 0)
 607      self.clear_mempool()
 608  
 609  
 610  def test_maxtxfee_fails(self, rbf_node, dest_address):
 611      self.log.info('Test that bumpfee fails when it hits -maxtxfee')
 612      # size of bumped transaction (p2wpkh, 1 input, 2 outputs): 141 vbytes
 613      # expected bump fee of 141 vbytes * 0.00200000 BTC / 1000 vbytes = 0.00002820 BTC
 614      # which exceeds maxtxfee and is expected to raise
 615      self.restart_node(1, ['-maxtxfee=0.000025'] + self.extra_args[1])
 616      rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
 617      rbfid = spend_one_input(rbf_node, dest_address)
 618      assert_raises_rpc_error(-4, "Unable to create transaction. Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)", rbf_node.bumpfee, rbfid)
 619      self.restart_node(1, self.extra_args[1])
 620      rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
 621      self.connect_nodes(1, 0)
 622      self.clear_mempool()
 623  
 624  
 625  def test_watchonly_psbt(self, peer_node, rbf_node, dest_address):
 626      self.log.info('Test that PSBT is returned for bumpfee in watchonly wallets')
 627      priv_rec_desc = "wpkh([00000001/84'/1'/0']tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0/*)#rweraev0"
 628      pub_rec_desc = rbf_node.getdescriptorinfo(priv_rec_desc)["descriptor"]
 629      priv_change_desc = "wpkh([00000001/84'/1'/0']tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/*)#j6uzqvuh"
 630      pub_change_desc = rbf_node.getdescriptorinfo(priv_change_desc)["descriptor"]
 631      # Create a wallet with private keys that can sign PSBTs
 632      rbf_node.createwallet(wallet_name="signer", disable_private_keys=False, blank=True)
 633      signer = rbf_node.get_wallet_rpc("signer")
 634      assert signer.getwalletinfo()['private_keys_enabled']
 635      reqs = [{
 636          "desc": priv_rec_desc,
 637          "timestamp": 0,
 638          "range": [0,1],
 639          "internal": False,
 640          "keypool": False # Keys can only be imported to the keypool when private keys are disabled
 641      },
 642      {
 643          "desc": priv_change_desc,
 644          "timestamp": 0,
 645          "range": [0, 0],
 646          "internal": True,
 647          "keypool": False
 648      }]
 649      if self.options.descriptors:
 650          result = signer.importdescriptors(reqs)
 651      else:
 652          result = signer.importmulti(reqs)
 653      assert_equal(result, [{'success': True}, {'success': True}])
 654  
 655      # Create another wallet with just the public keys, which creates PSBTs
 656      rbf_node.createwallet(wallet_name="watcher", disable_private_keys=True, blank=True)
 657      watcher = rbf_node.get_wallet_rpc("watcher")
 658      assert not watcher.getwalletinfo()['private_keys_enabled']
 659  
 660      reqs = [{
 661          "desc": pub_rec_desc,
 662          "timestamp": 0,
 663          "range": [0, 10],
 664          "internal": False,
 665          "keypool": True,
 666          "watchonly": True,
 667          "active": True,
 668      }, {
 669          "desc": pub_change_desc,
 670          "timestamp": 0,
 671          "range": [0, 10],
 672          "internal": True,
 673          "keypool": True,
 674          "watchonly": True,
 675          "active": True,
 676      }]
 677      if self.options.descriptors:
 678          result = watcher.importdescriptors(reqs)
 679      else:
 680          result = watcher.importmulti(reqs)
 681      assert_equal(result, [{'success': True}, {'success': True}])
 682  
 683      funding_address1 = watcher.getnewaddress(address_type='bech32')
 684      funding_address2 = watcher.getnewaddress(address_type='bech32')
 685      peer_node.sendmany("", {funding_address1: 0.001, funding_address2: 0.001})
 686      self.generate(peer_node, 1)
 687  
 688      # Create single-input PSBT for transaction to be bumped
 689      # Ensure the payment amount + change can be fully funded using one of the 0.001BTC inputs.
 690      psbt = watcher.walletcreatefundedpsbt([watcher.listunspent()[0]], {dest_address: 0.0005}, 0,
 691              {"fee_rate": 1, "add_inputs": False}, True)['psbt']
 692      psbt_signed = signer.walletprocesspsbt(psbt=psbt, sign=True, sighashtype="ALL", bip32derivs=True)
 693      original_txid = watcher.sendrawtransaction(psbt_signed["hex"])
 694      assert_equal(len(watcher.decodepsbt(psbt)["tx"]["vin"]), 1)
 695  
 696      # bumpfee can't be used on watchonly wallets
 697      assert_raises_rpc_error(-4, "bumpfee is not available with wallets that have private keys disabled. Use psbtbumpfee instead.", watcher.bumpfee, original_txid)
 698  
 699      # Bump fee, obnoxiously high to add additional watchonly input
 700      bumped_psbt = watcher.psbtbumpfee(original_txid, fee_rate=HIGH)
 701      assert_greater_than(len(watcher.decodepsbt(bumped_psbt['psbt'])["tx"]["vin"]), 1)
 702      assert "txid" not in bumped_psbt
 703      assert_equal(bumped_psbt["origfee"], -watcher.gettransaction(original_txid)["fee"])
 704      assert not watcher.finalizepsbt(bumped_psbt["psbt"])["complete"]
 705  
 706      # Sign bumped transaction
 707      bumped_psbt_signed = signer.walletprocesspsbt(psbt=bumped_psbt["psbt"], sign=True, sighashtype="ALL", bip32derivs=True)
 708      assert bumped_psbt_signed["complete"]
 709  
 710      # Broadcast bumped transaction
 711      bumped_txid = watcher.sendrawtransaction(bumped_psbt_signed["hex"])
 712      assert bumped_txid in rbf_node.getrawmempool()
 713      assert original_txid not in rbf_node.getrawmempool()
 714  
 715      rbf_node.unloadwallet("watcher")
 716      rbf_node.unloadwallet("signer")
 717      self.clear_mempool()
 718  
 719  
 720  def test_rebumping(self, rbf_node, dest_address):
 721      self.log.info('Test that re-bumping the original tx fails, but bumping successor works')
 722      rbfid = spend_one_input(rbf_node, dest_address)
 723      bumped = rbf_node.bumpfee(rbfid, fee_rate=ECONOMICAL)
 724      assert_raises_rpc_error(-4, f"Cannot bump transaction {rbfid} which was already bumped by transaction {bumped['txid']}",
 725                              rbf_node.bumpfee, rbfid, fee_rate=NORMAL)
 726      rbf_node.bumpfee(bumped["txid"], fee_rate=NORMAL)
 727      self.clear_mempool()
 728  
 729  
 730  def test_rebumping_not_replaceable(self, rbf_node, dest_address):
 731      self.log.info('Test that re-bumping non-replaceable fails')
 732      rbfid = spend_one_input(rbf_node, dest_address)
 733      bumped = rbf_node.bumpfee(rbfid, fee_rate=ECONOMICAL, replaceable=False)
 734      assert_raises_rpc_error(-4, "Transaction is not BIP 125 replaceable", rbf_node.bumpfee, bumped["txid"],
 735                              {"fee_rate": NORMAL})
 736      self.clear_mempool()
 737  
 738  
 739  def test_bumpfee_already_spent(self, rbf_node, dest_address):
 740      self.log.info('Test that bumping tx with already spent coin fails')
 741      txid = spend_one_input(rbf_node, dest_address)
 742      self.generate(rbf_node, 1)  # spend coin simply by mining block with tx
 743      spent_input = rbf_node.gettransaction(txid=txid, verbose=True)['decoded']['vin'][0]
 744      assert_raises_rpc_error(-1, f"{spent_input['txid']}:{spent_input['vout']} is already spent",
 745                              rbf_node.bumpfee, txid, fee_rate=NORMAL)
 746  
 747  
 748  def test_unconfirmed_not_spendable(self, rbf_node, rbf_node_address):
 749      self.log.info('Test that unconfirmed outputs from bumped txns are not spendable')
 750      rbfid = spend_one_input(rbf_node, rbf_node_address)
 751      rbftx = rbf_node.gettransaction(rbfid)["hex"]
 752      assert rbfid in rbf_node.getrawmempool()
 753      bumpid = rbf_node.bumpfee(rbfid)["txid"]
 754      assert bumpid in rbf_node.getrawmempool()
 755      assert rbfid not in rbf_node.getrawmempool()
 756  
 757      # check that outputs from the bump transaction are not spendable
 758      # due to the replaces_txid check in CWallet::AvailableCoins
 759      assert_equal([t for t in rbf_node.listunspent(minconf=0, include_unsafe=False) if t["txid"] == bumpid], [])
 760  
 761      # submit a block with the rbf tx to clear the bump tx out of the mempool,
 762      # then invalidate the block so the rbf tx will be put back in the mempool.
 763      # This makes it possible to check whether the rbf tx outputs are
 764      # spendable before the rbf tx is confirmed.
 765      block = self.generateblock(rbf_node, output="raw(51)", transactions=[rbftx])
 766      # Can not abandon conflicted tx
 767      assert_raises_rpc_error(-5, 'Transaction not eligible for abandonment', lambda: rbf_node.abandontransaction(txid=bumpid))
 768      rbf_node.invalidateblock(block["hash"])
 769      # Call abandon to make sure the wallet doesn't attempt to resubmit
 770      # the bump tx and hope the wallet does not rebroadcast before we call.
 771      rbf_node.abandontransaction(bumpid)
 772  
 773      tx_bump_abandoned = rbf_node.gettransaction(bumpid)
 774      for tx in tx_bump_abandoned['details']:
 775          assert_equal(tx['abandoned'], True)
 776  
 777      assert bumpid not in rbf_node.getrawmempool()
 778      assert rbfid in rbf_node.getrawmempool()
 779  
 780      # check that outputs from the rbf tx are not spendable before the
 781      # transaction is confirmed, due to the replaced_by_txid check in
 782      # CWallet::AvailableCoins
 783      assert_equal([t for t in rbf_node.listunspent(minconf=0, include_unsafe=False) if t["txid"] == rbfid], [])
 784  
 785      # check that the main output from the rbf tx is spendable after confirmed
 786      self.generate(rbf_node, 1, sync_fun=self.no_op)
 787      assert_equal(
 788          sum(1 for t in rbf_node.listunspent(minconf=0, include_unsafe=False)
 789              if t["txid"] == rbfid and t["address"] == rbf_node_address and t["spendable"]), 1)
 790      self.clear_mempool()
 791  
 792  
 793  def test_bumpfee_metadata(self, rbf_node, dest_address):
 794      self.log.info('Test that bumped txn metadata persists to new txn record')
 795      assert rbf_node.getbalance() < 49
 796      self.generatetoaddress(rbf_node, 101, rbf_node.getnewaddress())
 797      rbfid = rbf_node.sendtoaddress(dest_address, 49, "comment value", "to value")
 798      bumped_tx = rbf_node.bumpfee(rbfid)
 799      bumped_wtx = rbf_node.gettransaction(bumped_tx["txid"])
 800      assert_equal(bumped_wtx["comment"], "comment value")
 801      assert_equal(bumped_wtx["to"], "to value")
 802      self.clear_mempool()
 803  
 804  
 805  def test_locked_wallet_fails(self, rbf_node, dest_address):
 806      self.log.info('Test that locked wallet cannot bump txn')
 807      rbfid = spend_one_input(rbf_node, dest_address)
 808      rbf_node.walletlock()
 809      assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first.",
 810                              rbf_node.bumpfee, rbfid)
 811      rbf_node.walletpassphrase(WALLET_PASSPHRASE, WALLET_PASSPHRASE_TIMEOUT)
 812      self.clear_mempool()
 813  
 814  
 815  def test_change_script_match(self, rbf_node, dest_address):
 816      self.log.info('Test that the same change addresses is used for the replacement transaction when possible')
 817  
 818      # Check that there is only one change output
 819      rbfid = spend_one_input(rbf_node, dest_address)
 820      change_addresses = get_change_address(rbfid, rbf_node)
 821      assert_equal(len(change_addresses), 1)
 822  
 823      # Now find that address in each subsequent tx, and no other change
 824      bumped_total_tx = rbf_node.bumpfee(rbfid, fee_rate=ECONOMICAL)
 825      assert_equal(change_addresses, get_change_address(bumped_total_tx['txid'], rbf_node))
 826      bumped_rate_tx = rbf_node.bumpfee(bumped_total_tx["txid"])
 827      assert_equal(change_addresses, get_change_address(bumped_rate_tx['txid'], rbf_node))
 828      self.clear_mempool()
 829  
 830  
 831  def spend_one_input(node, dest_address, change_size=Decimal("0.00049000"), data=None):
 832      tx_input = dict(
 833          sequence=MAX_BIP125_RBF_SEQUENCE, **next(u for u in node.listunspent() if u["amount"] == Decimal("0.00100000")))
 834      destinations = {dest_address: Decimal("0.00050000")}
 835      if change_size > 0:
 836          destinations[node.getrawchangeaddress()] = change_size
 837      if data:
 838          destinations['data'] = data
 839      rawtx = node.createrawtransaction([tx_input], destinations)
 840      signedtx = node.signrawtransactionwithwallet(rawtx)
 841      txid = node.sendrawtransaction(signedtx["hex"])
 842      return txid
 843  
 844  
 845  def test_no_more_inputs_fails(self, rbf_node, dest_address):
 846      self.log.info('Test that bumpfee fails when there are no available confirmed outputs')
 847      # feerate rbf requires confirmed outputs when change output doesn't exist or is insufficient
 848      self.generatetoaddress(rbf_node, 1, dest_address)
 849      # spend all funds, no change output
 850      rbfid = rbf_node.sendall(recipients=[rbf_node.getnewaddress()])['txid']
 851      assert_raises_rpc_error(-4, "Unable to create transaction. Insufficient funds", rbf_node.bumpfee, rbfid)
 852      self.clear_mempool()
 853  
 854  
 855  def test_feerate_checks_replaced_outputs(self, rbf_node, peer_node):
 856      # Make sure there is enough balance
 857      peer_node.sendtoaddress(rbf_node.getnewaddress(), 60)
 858      self.generate(peer_node, 1)
 859  
 860      self.log.info("Test that feerate checks use replaced outputs")
 861      outputs = []
 862      for i in range(50):
 863          outputs.append({rbf_node.getnewaddress(address_type="bech32"): 1})
 864      tx_res = rbf_node.send(outputs=outputs, fee_rate=5)
 865      tx_details = rbf_node.gettransaction(txid=tx_res["txid"], verbose=True)
 866  
 867      # Calculate the minimum feerate required for the bump to work.
 868      # Since the bumped tx will replace all of the outputs with a single output, we can estimate that its size will 31 * (len(outputs) - 1) bytes smaller
 869      tx_size = tx_details["decoded"]["vsize"]
 870      est_bumped_size = tx_size - (len(tx_details["decoded"]["vout"]) - 1) * 31
 871      inc_fee_rate = rbf_node.getmempoolinfo()["incrementalrelayfee"]
 872      # RPC gives us fee as negative
 873      min_fee = (-tx_details["fee"] + get_fee(est_bumped_size, inc_fee_rate)) * Decimal(1e8)
 874      min_fee_rate = (min_fee / est_bumped_size).quantize(Decimal("1.000"))
 875  
 876      # Attempt to bumpfee and replace all outputs with a single one using a feerate slightly less than the minimum
 877      new_outputs = [{rbf_node.getnewaddress(address_type="bech32"): 49}]
 878      assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx_res["txid"], {"fee_rate": min_fee_rate - 1, "outputs": new_outputs})
 879  
 880      # Bumpfee and replace all outputs with a single one using the minimum feerate
 881      rbf_node.bumpfee(tx_res["txid"], {"fee_rate": min_fee_rate, "outputs": new_outputs})
 882      self.clear_mempool()
 883  
 884  
 885  def test_bumpfee_with_feerate_ignores_walletincrementalrelayfee(self, rbf_node, peer_node):
 886      self.log.info('Test that bumpfee with fee_rate ignores walletincrementalrelayfee')
 887      # Make sure there is enough balance
 888      peer_node.sendtoaddress(rbf_node.getnewaddress(), 2)
 889      self.generate(peer_node, 1)
 890  
 891      dest_address = peer_node.getnewaddress(address_type="bech32")
 892      tx = rbf_node.send(outputs=[{dest_address: 1}], fee_rate=2)
 893  
 894      # Ensure you can not fee bump with a fee_rate below or equal to the original fee_rate
 895      assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 1})
 896      assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2})
 897  
 898      # Ensure you can not fee bump if the fee_rate is more than original fee_rate but the total fee from new fee_rate is
 899      # less than (original fee + incrementalrelayfee)
 900      assert_raises_rpc_error(-8, "Insufficient total fee", rbf_node.bumpfee, tx["txid"], {"fee_rate": 2.05})
 901  
 902      # You can fee bump as long as the new fee set from fee_rate is at least (original fee + incrementalrelayfee)
 903      rbf_node.bumpfee(tx["txid"], {"fee_rate": 3})
 904      self.clear_mempool()
 905  
 906  
 907  if __name__ == "__main__":
 908      BumpFeeTest(__file__).main()
 909