/ test / functional / rpc_psbt.py
rpc_psbt.py
   1  #!/usr/bin/env python3
   2  # Copyright (c) 2018-present 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 Partially Signed Transaction RPCs.
   6  """
   7  from decimal import Decimal
   8  from itertools import product
   9  from random import randbytes
  10  
  11  from test_framework.blocktools import (
  12      MAX_STANDARD_TX_WEIGHT,
  13  )
  14  from test_framework.descriptors import descsum_create
  15  from test_framework.key import H_POINT
  16  from test_framework.messages import (
  17      COutPoint,
  18      CTransaction,
  19      CTxIn,
  20      CTxOut,
  21      MAX_BIP125_RBF_SEQUENCE,
  22      WITNESS_SCALE_FACTOR,
  23  )
  24  from test_framework.psbt import (
  25      PSBT,
  26      PSBTMap,
  27      PSBT_GLOBAL_UNSIGNED_TX,
  28      PSBT_IN_RIPEMD160,
  29      PSBT_IN_SHA256,
  30      PSBT_IN_SIGHASH_TYPE,
  31      PSBT_IN_HASH160,
  32      PSBT_IN_HASH256,
  33      PSBT_IN_MUSIG2_PARTIAL_SIG,
  34      PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS,
  35      PSBT_IN_MUSIG2_PUB_NONCE,
  36      PSBT_IN_NON_WITNESS_UTXO,
  37      PSBT_IN_WITNESS_UTXO,
  38      PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS,
  39      PSBT_OUT_TAP_TREE,
  40  )
  41  from test_framework.script import CScript, OP_TRUE, SIGHASH_ALL, SIGHASH_ANYONECANPAY
  42  from test_framework.script_util import MIN_STANDARD_TX_NONWITNESS_SIZE
  43  from test_framework.test_framework import BitcoinTestFramework
  44  from test_framework.util import (
  45      assert_not_equal,
  46      assert_approx,
  47      assert_equal,
  48      assert_greater_than,
  49      assert_greater_than_or_equal,
  50      assert_raises_rpc_error,
  51      find_vout_for_address,
  52      wallet_importprivkey,
  53  )
  54  from test_framework.wallet_util import (
  55      calculate_input_weight,
  56      generate_keypair,
  57      get_generate_key,
  58  )
  59  
  60  import json
  61  import os
  62  
  63  
  64  class PSBTTest(BitcoinTestFramework):
  65      def set_test_params(self):
  66          self.num_nodes = 3
  67          self.extra_args = [
  68              ["-walletrbf=1", "-addresstype=bech32", "-changetype=bech32"], #TODO: Remove address type restrictions once taproot has psbt extensions
  69              ["-walletrbf=0", "-changetype=legacy"],
  70              []
  71          ]
  72          # whitelist peers to speed up tx relay / mempool sync
  73          for args in self.extra_args:
  74              args.append("-whitelist=noban@127.0.0.1")
  75  
  76      def skip_test_if_missing_module(self):
  77          self.skip_if_no_wallet()
  78  
  79      def test_psbt_incomplete_after_invalid_modification(self):
  80          self.log.info("Check that PSBT is correctly marked as incomplete after invalid modification")
  81          node = self.nodes[2]
  82          wallet = node.get_wallet_rpc(self.default_wallet_name)
  83          address = wallet.getnewaddress()
  84          wallet.sendtoaddress(address=address, amount=1.0)
  85          self.generate(node, nblocks=1)
  86  
  87          utxos = wallet.listunspent(addresses=[address])
  88          psbt = wallet.createpsbt([{"txid": utxos[0]["txid"], "vout": utxos[0]["vout"]}], [{wallet.getnewaddress(): 0.9999}])
  89          signed_psbt = wallet.walletprocesspsbt(psbt)["psbt"]
  90  
  91          # Modify the raw transaction by changing the output address, so the signature is no longer valid
  92          signed_psbt_obj = PSBT.from_base64(signed_psbt)
  93          substitute_addr = wallet.getnewaddress()
  94          raw = wallet.createrawtransaction([{"txid": utxos[0]["txid"], "vout": utxos[0]["vout"]}], [{substitute_addr: 0.9999}])
  95          signed_psbt_obj.g.map[PSBT_GLOBAL_UNSIGNED_TX] = bytes.fromhex(raw)
  96  
  97          # Check that the walletprocesspsbt call succeeds but also recognizes that the transaction is not complete
  98          signed_psbt_incomplete = wallet.walletprocesspsbt(psbt=signed_psbt_obj.to_base64(), finalize=False)
  99          assert signed_psbt_incomplete["complete"] is False
 100  
 101      def test_utxo_conversion(self):
 102          self.log.info("Check that non-witness UTXOs are removed for segwit v1+ inputs")
 103          mining_node = self.nodes[2]
 104          offline_node = self.nodes[0]
 105          online_node = self.nodes[1]
 106  
 107          # Disconnect offline node from others
 108          # Topology of test network is linear, so this one call is enough
 109          self.disconnect_nodes(0, 1)
 110  
 111          # Create watchonly on online_node
 112          online_node.createwallet(wallet_name='wonline', disable_private_keys=True)
 113          wonline = online_node.get_wallet_rpc('wonline')
 114          w2 = online_node.get_wallet_rpc(self.default_wallet_name)
 115  
 116          # Mine a transaction that credits the offline address
 117          offline_addr = offline_node.getnewaddress(address_type="bech32m")
 118          online_addr = w2.getnewaddress(address_type="bech32m")
 119          import_res = wonline.importdescriptors([{"desc": offline_node.getaddressinfo(offline_addr)["desc"], "timestamp": "now"}])
 120          assert_equal(import_res[0]["success"], True)
 121          mining_wallet = mining_node.get_wallet_rpc(self.default_wallet_name)
 122          mining_wallet.sendtoaddress(address=offline_addr, amount=1.0)
 123          self.generate(mining_node, nblocks=1, sync_fun=lambda: self.sync_all([online_node, mining_node]))
 124  
 125          # Construct an unsigned PSBT on the online node
 126          utxos = wonline.listunspent(addresses=[offline_addr])
 127          raw = wonline.createrawtransaction([{"txid":utxos[0]["txid"], "vout":utxos[0]["vout"]}],[{online_addr:0.9999}])
 128          psbt = wonline.walletprocesspsbt(online_node.converttopsbt(raw))["psbt"]
 129          assert "not_witness_utxo" not in mining_node.decodepsbt(psbt)["inputs"][0]
 130  
 131          # add non-witness UTXO manually
 132          psbt_new = PSBT.from_base64(psbt)
 133          prev_tx = wonline.gettransaction(utxos[0]["txid"])["hex"]
 134          psbt_new.i[0].map[PSBT_IN_NON_WITNESS_UTXO] = bytes.fromhex(prev_tx)
 135          assert "non_witness_utxo" in mining_node.decodepsbt(psbt_new.to_base64())["inputs"][0]
 136  
 137          # Have the offline node sign the PSBT (which will remove the non-witness UTXO)
 138          signed_psbt = offline_node.walletprocesspsbt(psbt_new.to_base64())
 139          assert "non_witness_utxo" not in mining_node.decodepsbt(signed_psbt["psbt"])["inputs"][0]
 140  
 141          # Make sure we can mine the resulting transaction
 142          txid = mining_node.sendrawtransaction(signed_psbt["hex"])
 143          self.generate(mining_node, nblocks=1, sync_fun=lambda: self.sync_all([online_node, mining_node]))
 144          assert_equal(online_node.gettxout(txid,0)["confirmations"], 1)
 145  
 146          wonline.unloadwallet()
 147  
 148          # Reconnect
 149          self.connect_nodes(1, 0)
 150          self.connect_nodes(0, 2)
 151  
 152      def test_input_confs_control(self):
 153          self.nodes[0].createwallet("minconf")
 154          wallet = self.nodes[0].get_wallet_rpc("minconf")
 155  
 156          # Fund the wallet with different chain heights
 157          for _ in range(2):
 158              self.nodes[1].sendmany("", {wallet.getnewaddress():1, wallet.getnewaddress():1})
 159              self.generate(self.nodes[1], 1)
 160  
 161          unconfirmed_txid = wallet.sendtoaddress(wallet.getnewaddress(), 0.5)
 162  
 163          self.log.info("Crafting PSBT using an unconfirmed input")
 164          target_address = self.nodes[1].getnewaddress()
 165          psbtx1 = wallet.walletcreatefundedpsbt([], {target_address: 0.1}, 0, {'fee_rate': 1, 'maxconf': 0})['psbt']
 166  
 167          # Make sure we only had the one input
 168          tx1_inputs = self.nodes[0].decodepsbt(psbtx1)['tx']['vin']
 169          assert_equal(len(tx1_inputs), 1)
 170  
 171          utxo1 = tx1_inputs[0]
 172          assert_equal(unconfirmed_txid, utxo1['txid'])
 173  
 174          signed_tx1 = wallet.walletprocesspsbt(psbtx1)
 175          txid1 = self.nodes[0].sendrawtransaction(signed_tx1['hex'])
 176  
 177          mempool = self.nodes[0].getrawmempool()
 178          assert txid1 in mempool
 179  
 180          self.log.info("Fail to craft a new PSBT that sends more funds with add_inputs = False")
 181          assert_raises_rpc_error(-4, "The preselected coins total amount does not cover the transaction target. Please allow other inputs to be automatically selected or include more coins manually", wallet.walletcreatefundedpsbt, [{'txid': utxo1['txid'], 'vout': utxo1['vout']}], {target_address: 1}, 0, {'add_inputs': False})
 182  
 183          self.log.info("Fail to craft a new PSBT with minconf above highest one")
 184          assert_raises_rpc_error(-4, "Insufficient funds", wallet.walletcreatefundedpsbt, [{'txid': utxo1['txid'], 'vout': utxo1['vout']}], {target_address: 1}, 0, {'add_inputs': True, 'minconf': 3, 'fee_rate': 10})
 185  
 186          self.log.info("Fail to broadcast a new PSBT with maxconf 0 due to BIP125 rules to verify it actually chose unconfirmed outputs")
 187          psbt_invalid = wallet.walletcreatefundedpsbt([{'txid': utxo1['txid'], 'vout': utxo1['vout']}], {target_address: 1}, 0, {'add_inputs': True, 'maxconf': 0, 'fee_rate': 10})['psbt']
 188          signed_invalid = wallet.walletprocesspsbt(psbt_invalid)
 189          assert_raises_rpc_error(-26, "bad-txns-spends-conflicting-tx", self.nodes[0].sendrawtransaction, signed_invalid['hex'])
 190  
 191          self.log.info("Craft a replacement adding inputs with highest confs possible")
 192          psbtx2 = wallet.walletcreatefundedpsbt([{'txid': utxo1['txid'], 'vout': utxo1['vout']}], {target_address: 1}, 0, {'add_inputs': True, 'minconf': 2, 'fee_rate': 10})['psbt']
 193          tx2_inputs = self.nodes[0].decodepsbt(psbtx2)['tx']['vin']
 194          assert_greater_than_or_equal(len(tx2_inputs), 2)
 195          for vin in tx2_inputs:
 196              if vin['txid'] != unconfirmed_txid:
 197                  assert_greater_than_or_equal(self.nodes[0].gettxout(vin['txid'], vin['vout'])['confirmations'], 2)
 198  
 199          signed_tx2 = wallet.walletprocesspsbt(psbtx2)
 200          txid2 = self.nodes[0].sendrawtransaction(signed_tx2['hex'])
 201  
 202          mempool = self.nodes[0].getrawmempool()
 203          assert txid1 not in mempool
 204          assert txid2 in mempool
 205  
 206          wallet.unloadwallet()
 207  
 208      def test_decodepsbt_musig2_input_output_types(self):
 209          self.log.info("Test decoding PSBT with MuSig2 per-input and per-output types")
 210          # create 2-of-2 musig2 using fake aggregate key, leaf hash, pubnonce, and partial sig
 211          # TODO: actually implement MuSig2 aggregation (for decoding only it doesn't matter though)
 212          _, in_pubkey1 = generate_keypair()
 213          _, in_pubkey2 = generate_keypair()
 214          _, in_fake_agg_pubkey = generate_keypair()
 215          fake_leaf_hash = randbytes(32)
 216          fake_pubnonce = randbytes(66)
 217          fake_partialsig = randbytes(32)
 218          tx = CTransaction()
 219          tx.vin = [CTxIn(outpoint=COutPoint(hash=int('ee' * 32, 16), n=0), scriptSig=b"")]
 220          tx.vout = [CTxOut(nValue=0, scriptPubKey=b"")]
 221          psbt = PSBT()
 222          psbt.g = PSBTMap({PSBT_GLOBAL_UNSIGNED_TX: tx.serialize()})
 223          participant1_keydata = in_pubkey1 + in_fake_agg_pubkey + fake_leaf_hash
 224          psbt.i = [PSBTMap({
 225                      bytes([PSBT_IN_MUSIG2_PARTICIPANT_PUBKEYS]) + in_fake_agg_pubkey: [in_pubkey1, in_pubkey2],
 226                      bytes([PSBT_IN_MUSIG2_PUB_NONCE]) + participant1_keydata: fake_pubnonce,
 227                      bytes([PSBT_IN_MUSIG2_PARTIAL_SIG]) + participant1_keydata: fake_partialsig,
 228                   })]
 229          _, out_pubkey1 = generate_keypair()
 230          _, out_pubkey2 = generate_keypair()
 231          _, out_fake_agg_pubkey = generate_keypair()
 232          psbt.o = [PSBTMap({
 233                      bytes([PSBT_OUT_MUSIG2_PARTICIPANT_PUBKEYS]) + out_fake_agg_pubkey: [out_pubkey1, out_pubkey2],
 234                   })]
 235          res = self.nodes[0].decodepsbt(psbt.to_base64())
 236          assert_equal(len(res["inputs"]), 1)
 237          res_input = res["inputs"][0]
 238          assert_equal(len(res["outputs"]), 1)
 239          res_output = res["outputs"][0]
 240  
 241          assert "musig2_participant_pubkeys" in res_input
 242          in_participant_pks = res_input["musig2_participant_pubkeys"][0]
 243          assert "aggregate_pubkey" in in_participant_pks
 244          assert_equal(in_participant_pks["aggregate_pubkey"], in_fake_agg_pubkey.hex())
 245          assert "participant_pubkeys" in in_participant_pks
 246          assert_equal(in_participant_pks["participant_pubkeys"], [in_pubkey1.hex(), in_pubkey2.hex()])
 247  
 248          assert "musig2_pubnonces" in res_input
 249          in_pubnonce = res_input["musig2_pubnonces"][0]
 250          assert "participant_pubkey" in in_pubnonce
 251          assert_equal(in_pubnonce["participant_pubkey"], in_pubkey1.hex())
 252          assert "aggregate_pubkey" in in_pubnonce
 253          assert_equal(in_pubnonce["aggregate_pubkey"], in_fake_agg_pubkey.hex())
 254          assert "leaf_hash" in in_pubnonce
 255          assert_equal(in_pubnonce["leaf_hash"], fake_leaf_hash.hex())
 256          assert "pubnonce" in in_pubnonce
 257          assert_equal(in_pubnonce["pubnonce"], fake_pubnonce.hex())
 258  
 259          assert "musig2_partial_sigs" in res_input
 260          in_partialsig = res_input["musig2_partial_sigs"][0]
 261          assert "participant_pubkey" in in_partialsig
 262          assert_equal(in_partialsig["participant_pubkey"], in_pubkey1.hex())
 263          assert "aggregate_pubkey" in in_partialsig
 264          assert_equal(in_partialsig["aggregate_pubkey"], in_fake_agg_pubkey.hex())
 265          assert "leaf_hash" in in_partialsig
 266          assert_equal(in_partialsig["leaf_hash"], fake_leaf_hash.hex())
 267          assert "partial_sig" in in_partialsig
 268          assert_equal(in_partialsig["partial_sig"], fake_partialsig.hex())
 269  
 270          assert "musig2_participant_pubkeys" in res_output
 271          out_participant_pks = res_output["musig2_participant_pubkeys"][0]
 272          assert "aggregate_pubkey" in out_participant_pks
 273          assert_equal(out_participant_pks["aggregate_pubkey"], out_fake_agg_pubkey.hex())
 274          assert "participant_pubkeys" in out_participant_pks
 275          assert_equal(out_participant_pks["participant_pubkeys"], [out_pubkey1.hex(), out_pubkey2.hex()])
 276  
 277      def test_sighash_mismatch(self):
 278          self.log.info("Test sighash type mismatches")
 279          self.nodes[0].createwallet("sighash_mismatch")
 280          wallet = self.nodes[0].get_wallet_rpc("sighash_mismatch")
 281          def_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
 282  
 283          addr = wallet.getnewaddress(address_type="bech32")
 284          def_wallet.sendtoaddress(addr, 5)
 285          self.generate(self.nodes[0], 6)
 286  
 287          # Retrieve the descriptors so we can do all of the tests with descriptorprocesspsbt as well
 288          descs = wallet.listdescriptors(True)["descriptors"]
 289  
 290          # Make a PSBT
 291          psbt = wallet.walletcreatefundedpsbt([], [{def_wallet.getnewaddress(): 1}])["psbt"]
 292  
 293          # Modify the PSBT and insert a sighash field for ALL|ANYONECANPAY on input 0
 294          mod_psbt = PSBT.from_base64(psbt)
 295          mod_psbt.i[0].map[PSBT_IN_SIGHASH_TYPE] = (SIGHASH_ALL | SIGHASH_ANYONECANPAY).to_bytes(4, byteorder="little")
 296          psbt = mod_psbt.to_base64()
 297  
 298          # Mismatching sighash type fails, including when no type is specified
 299          for sighash in ["DEFAULT", "ALL", "NONE", "SINGLE", "NONE|ANYONECANPAY", "SINGLE|ANYONECANPAY", None]:
 300              assert_raises_rpc_error(-22, "Specified sighash value does not match value stored in PSBT", wallet.walletprocesspsbt, psbt, True, sighash)
 301  
 302          # Matching sighash type succeeds
 303          proc = wallet.walletprocesspsbt(psbt, True, "ALL|ANYONECANPAY")
 304          assert_equal(proc["complete"], True)
 305  
 306          # Repeat with descriptorprocesspsbt
 307          # Mismatching sighash type fails, including when no type is specified
 308          for sighash in ["DEFAULT", "ALL", "NONE", "SINGLE", "NONE|ANYONECANPAY", "SINGLE|ANYONECANPAY", None]:
 309              assert_raises_rpc_error(-22, "Specified sighash value does not match value stored in PSBT", self.nodes[0].descriptorprocesspsbt, psbt, descs, sighash)
 310  
 311          # Matching sighash type succeeds
 312          proc = self.nodes[0].descriptorprocesspsbt(psbt, descs, "ALL|ANYONECANPAY")
 313          assert_equal(proc["complete"], True)
 314  
 315          wallet.unloadwallet()
 316  
 317      def test_sighash_adding(self):
 318          self.log.info("Test adding of sighash type field")
 319          self.nodes[0].createwallet("sighash_adding")
 320          wallet = self.nodes[0].get_wallet_rpc("sighash_adding")
 321          def_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
 322  
 323          outputs = [{wallet.getnewaddress(address_type="bech32"): 1}]
 324          outputs.append({wallet.getnewaddress(address_type="bech32m"): 1})
 325          descs = wallet.listdescriptors(True)["descriptors"]
 326          def_wallet.send(outputs)
 327          self.generate(self.nodes[0], 6)
 328          utxos = wallet.listunspent()
 329  
 330          # Make a PSBT
 331          psbt = wallet.walletcreatefundedpsbt(utxos, [{def_wallet.getnewaddress(): 0.5}])["psbt"]
 332  
 333          # Process the PSBT with the wallet
 334          wallet_psbt = wallet.walletprocesspsbt(psbt=psbt, sighashtype="ALL|ANYONECANPAY", finalize=False)["psbt"]
 335  
 336          # Separately process the PSBT with descriptors
 337          desc_psbt = self.nodes[0].descriptorprocesspsbt(psbt=psbt, descriptors=descs, sighashtype="ALL|ANYONECANPAY", finalize=False)["psbt"]
 338  
 339          for psbt in [wallet_psbt, desc_psbt]:
 340              # Check that the PSBT has a sighash field on all inputs
 341              dec_psbt = self.nodes[0].decodepsbt(psbt)
 342              for input in dec_psbt["inputs"]:
 343                  assert_equal(input["sighash"], "ALL|ANYONECANPAY")
 344  
 345              # Make sure we can still finalize the transaction
 346              fin_res = self.nodes[0].finalizepsbt(psbt)
 347              assert_equal(fin_res["complete"], True)
 348              fin_hex = fin_res["hex"]
 349              assert_equal(self.nodes[0].testmempoolaccept([fin_hex])[0]["allowed"], True)
 350  
 351              # Change the sighash field to a different value and make sure we can no longer finalize
 352              mod_psbt = PSBT.from_base64(psbt)
 353              mod_psbt.i[0].map[PSBT_IN_SIGHASH_TYPE] = (SIGHASH_ALL).to_bytes(4, byteorder="little")
 354              mod_psbt.i[1].map[PSBT_IN_SIGHASH_TYPE] = (SIGHASH_ALL).to_bytes(4, byteorder="little")
 355              psbt = mod_psbt.to_base64()
 356              fin_res = self.nodes[0].finalizepsbt(psbt)
 357              assert_equal(fin_res["complete"], False)
 358  
 359          self.nodes[0].sendrawtransaction(fin_hex)
 360          self.generate(self.nodes[0], 1)
 361  
 362          wallet.unloadwallet()
 363  
 364      def assert_change_type(self, psbtx, expected_type):
 365          """Assert that the given PSBT has a change output with the given type."""
 366  
 367          # The decodepsbt RPC is stateless and independent of any settings, we can always just call it on the first node
 368          decoded_psbt = self.nodes[0].decodepsbt(psbtx["psbt"])
 369          changepos = psbtx["changepos"]
 370          assert_equal(decoded_psbt["tx"]["vout"][changepos]["scriptPubKey"]["type"], expected_type)
 371  
 372      def test_psbt_named_parameter_handling(self):
 373          """Test that PSBT Base64 parameters with '=' padding are handled correctly in -named mode"""
 374          self.log.info("Testing PSBT Base64 parameter handling with '=' padding characters")
 375          node = self.nodes[0]
 376          psbt_with_padding = "cHNidP8BAJoCAAAAAqvNEjSrzRI0q80SNKvNEjSrzRI0q80SNKvNEjSrzRI0AAAAAAD9////NBLNqzQSzas0Es2rNBLNqzQSzas0Es2rNBLNqzQSzasBAAAAAP3///8CoIYBAAAAAAAWABQVQBGVs/sqFAmC8HZ8O+g1htqivkANAwAAAAAAFgAUir7MzgyzDnRMjdkVa7d+Dwr07jsAAAAAAAAAAAA="
 377  
 378          # Test decodepsbt with explicit named parameter containing '=' padding
 379          result = node.cli("-named", "decodepsbt", f"psbt={psbt_with_padding}").send_cli()
 380          assert 'tx' in result
 381  
 382          # Test decodepsbt with positional argument containing '=' padding
 383          result = node.cli("-named", "decodepsbt", psbt_with_padding).send_cli()
 384          assert 'tx' in result
 385  
 386          # Test analyzepsbt with positional argument containing '=' padding
 387          result = node.cli("-named", "analyzepsbt", psbt_with_padding).send_cli()
 388          assert 'inputs' in result
 389  
 390          # Test finalizepsbt with positional argument containing '=' padding
 391          result = node.cli("-named", "finalizepsbt", psbt_with_padding, "extract=true").send_cli()
 392          assert 'complete' in result
 393  
 394          # Test walletprocesspsbt with positional argument containing '=' padding
 395          result = node.cli("-named", "walletprocesspsbt", psbt_with_padding).send_cli()
 396          assert 'complete' in result
 397  
 398          # Test utxoupdatepsbt with positional argument containing '=' padding
 399          result = node.cli("-named", "utxoupdatepsbt", psbt_with_padding).send_cli()
 400          assert isinstance(result, str) and len(result) > 0
 401  
 402          # Test that unknown parameter with '=' gets treated as positional and return error
 403          unknown_psbt_param = "unknown_param_data=more_data="
 404          # This should be treated as positional and fail with decode error, not parameter error
 405          assert_raises_rpc_error(-22, "TX decode failed invalid base64", node.cli("-named", "finalizepsbt", unknown_psbt_param).send_cli)
 406  
 407          self.log.info("PSBT parameter handling test completed successfully")
 408  
 409      def run_test(self):
 410          # Create and fund a raw tx for sending 10 BTC
 411          psbtx1 = self.nodes[0].walletcreatefundedpsbt([], {self.nodes[2].getnewaddress():10})['psbt']
 412  
 413          self.log.info("Test for invalid maximum transaction weights")
 414          dest_arg = [{self.nodes[0].getnewaddress(): 1}]
 415          min_tx_weight = MIN_STANDARD_TX_NONWITNESS_SIZE * WITNESS_SCALE_FACTOR
 416          assert_raises_rpc_error(-4, f"Maximum transaction weight must be between {min_tx_weight} and {MAX_STANDARD_TX_WEIGHT}", self.nodes[0].walletcreatefundedpsbt, [], dest_arg, 0, {"max_tx_weight": -1})
 417          assert_raises_rpc_error(-4, f"Maximum transaction weight must be between {min_tx_weight} and {MAX_STANDARD_TX_WEIGHT}", self.nodes[0].walletcreatefundedpsbt, [], dest_arg, 0, {"max_tx_weight": 0})
 418          assert_raises_rpc_error(-4, f"Maximum transaction weight must be between {min_tx_weight} and {MAX_STANDARD_TX_WEIGHT}", self.nodes[0].walletcreatefundedpsbt, [], dest_arg, 0, {"max_tx_weight": MAX_STANDARD_TX_WEIGHT + 1})
 419  
 420          # Base transaction vsize: version (4) + locktime (4) + input count (1) + witness overhead (1) = 10 vbytes
 421          base_tx_vsize = 10
 422          # One P2WPKH output vsize: outpoint (31 vbytes)
 423          p2wpkh_output_vsize = 31
 424          # 1 vbyte for output count
 425          output_count = 1
 426          tx_weight_without_inputs = (base_tx_vsize + output_count + p2wpkh_output_vsize) * WITNESS_SCALE_FACTOR
 427          # min_tx_weight is greater than transaction weight without inputs
 428          assert_greater_than(min_tx_weight, tx_weight_without_inputs)
 429  
 430          # In order to test for when the passed max weight is less than the transaction weight without inputs
 431          # Define destination with two outputs.
 432          dest_arg_large = [{self.nodes[0].getnewaddress(): 1}, {self.nodes[0].getnewaddress(): 1}]
 433          large_tx_vsize_without_inputs = base_tx_vsize + output_count + (p2wpkh_output_vsize * 2)
 434          large_tx_weight_without_inputs = large_tx_vsize_without_inputs * WITNESS_SCALE_FACTOR
 435          assert_greater_than(large_tx_weight_without_inputs, min_tx_weight)
 436          # Test for max_tx_weight less than Transaction weight without inputs
 437          assert_raises_rpc_error(-4, "Maximum transaction weight is less than transaction weight without inputs", self.nodes[0].walletcreatefundedpsbt, [], dest_arg_large, 0, {"max_tx_weight": min_tx_weight})
 438          assert_raises_rpc_error(-4, "Maximum transaction weight is less than transaction weight without inputs", self.nodes[0].walletcreatefundedpsbt, [], dest_arg_large, 0, {"max_tx_weight": large_tx_weight_without_inputs})
 439  
 440          # Test for max_tx_weight just enough to include inputs but not change output
 441          assert_raises_rpc_error(-4, "Maximum transaction weight is too low, can not accommodate change output", self.nodes[0].walletcreatefundedpsbt, [], dest_arg_large, 0, {"max_tx_weight": (large_tx_vsize_without_inputs + 1) * WITNESS_SCALE_FACTOR})
 442          self.log.info("Test that a funded PSBT is always faithful to max_tx_weight option")
 443          large_tx_vsize_with_change = large_tx_vsize_without_inputs + p2wpkh_output_vsize
 444          # It's enough but won't accommodate selected input size
 445          assert_raises_rpc_error(-4, "The inputs size exceeds the maximum weight", self.nodes[0].walletcreatefundedpsbt, [], dest_arg_large, 0, {"max_tx_weight": (large_tx_vsize_with_change) * WITNESS_SCALE_FACTOR})
 446  
 447          max_tx_weight_sufficient = 1000 # 1k vbytes is enough
 448          psbt = self.nodes[0].walletcreatefundedpsbt(outputs=dest_arg,locktime=0, options={"max_tx_weight": max_tx_weight_sufficient})["psbt"]
 449          weight = self.nodes[0].decodepsbt(psbt)["tx"]["weight"]
 450          # ensure the transaction's weight is below the specified max_tx_weight.
 451          assert_greater_than_or_equal(max_tx_weight_sufficient, weight)
 452  
 453          # If inputs are specified, do not automatically add more:
 454          utxo1 = self.nodes[0].listunspent()[0]
 455          assert_raises_rpc_error(-4, "The preselected coins total amount does not cover the transaction target. "
 456                                      "Please allow other inputs to be automatically selected or include more coins manually",
 457                                  self.nodes[0].walletcreatefundedpsbt, [{"txid": utxo1['txid'], "vout": utxo1['vout']}], {self.nodes[2].getnewaddress():90})
 458  
 459          psbtx1 = self.nodes[0].walletcreatefundedpsbt([{"txid": utxo1['txid'], "vout": utxo1['vout']}], {self.nodes[2].getnewaddress():90}, 0, {"add_inputs": True})['psbt']
 460          assert_equal(len(self.nodes[0].decodepsbt(psbtx1)['tx']['vin']), 2)
 461  
 462          # Inputs argument can be null
 463          self.nodes[0].walletcreatefundedpsbt(None, {self.nodes[2].getnewaddress():10})
 464  
 465          # Node 1 should not be able to add anything to it but still return the psbtx same as before
 466          psbtx = self.nodes[1].walletprocesspsbt(psbtx1)['psbt']
 467          assert_equal(psbtx1, psbtx)
 468  
 469          # Node 0 should not be able to sign the transaction with the wallet is locked
 470          self.nodes[0].encryptwallet("password")
 471          assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first", self.nodes[0].walletprocesspsbt, psbtx)
 472  
 473          # Node 0 should be able to process without signing though
 474          unsigned_tx = self.nodes[0].walletprocesspsbt(psbtx, False)
 475          assert_equal(unsigned_tx['complete'], False)
 476  
 477          self.nodes[0].walletpassphrase(passphrase="password", timeout=1000000)
 478  
 479          # Sign the transaction but don't finalize
 480          processed_psbt = self.nodes[0].walletprocesspsbt(psbt=psbtx, finalize=False)
 481          assert "hex" not in processed_psbt
 482          signed_psbt = processed_psbt['psbt']
 483  
 484          # Finalize and send
 485          finalized_hex = self.nodes[0].finalizepsbt(signed_psbt)['hex']
 486          self.nodes[0].sendrawtransaction(finalized_hex)
 487  
 488          # Alternative method: sign AND finalize in one command
 489          processed_finalized_psbt = self.nodes[0].walletprocesspsbt(psbt=psbtx, finalize=True)
 490          finalized_psbt = processed_finalized_psbt['psbt']
 491          finalized_psbt_hex = processed_finalized_psbt['hex']
 492          assert_not_equal(signed_psbt, finalized_psbt)
 493          assert finalized_psbt_hex == finalized_hex
 494  
 495          # Manually selected inputs can be locked:
 496          assert_equal(len(self.nodes[0].listlockunspent()), 0)
 497          utxo1 = self.nodes[0].listunspent()[0]
 498          psbtx1 = self.nodes[0].walletcreatefundedpsbt([{"txid": utxo1['txid'], "vout": utxo1['vout']}], {self.nodes[2].getnewaddress():1}, 0,{"lockUnspents": True})["psbt"]
 499          assert_equal(len(self.nodes[0].listlockunspent()), 1)
 500  
 501          # Locks are ignored for manually selected inputs
 502          self.nodes[0].walletcreatefundedpsbt([{"txid": utxo1['txid'], "vout": utxo1['vout']}], {self.nodes[2].getnewaddress():1}, 0)
 503  
 504          # Create p2sh, p2wpkh, and p2wsh addresses
 505          pubkey0 = self.nodes[0].getaddressinfo(self.nodes[0].getnewaddress())['pubkey']
 506          pubkey1 = self.nodes[1].getaddressinfo(self.nodes[1].getnewaddress())['pubkey']
 507          pubkey2 = self.nodes[2].getaddressinfo(self.nodes[2].getnewaddress())['pubkey']
 508  
 509          # Setup watchonly wallets
 510          self.nodes[2].createwallet(wallet_name='wmulti', disable_private_keys=True)
 511          wmulti = self.nodes[2].get_wallet_rpc('wmulti')
 512  
 513          # Create all the addresses
 514          p2sh_ms = wmulti.createmultisig(2, [pubkey0, pubkey1, pubkey2], address_type="legacy")
 515          p2sh = p2sh_ms["address"]
 516          p2wsh_ms = wmulti.createmultisig(2, [pubkey0, pubkey1, pubkey2], address_type="bech32")
 517          p2wsh = p2wsh_ms["address"]
 518          p2sh_p2wsh_ms = wmulti.createmultisig(2, [pubkey0, pubkey1, pubkey2], address_type="p2sh-segwit")
 519          p2sh_p2wsh = p2sh_p2wsh_ms["address"]
 520          import_res = wmulti.importdescriptors(
 521              [
 522                  {"desc": p2sh_ms["descriptor"], "timestamp": "now"},
 523                  {"desc": p2wsh_ms["descriptor"], "timestamp": "now"},
 524                  {"desc": p2sh_p2wsh_ms["descriptor"], "timestamp": "now"},
 525              ])
 526          assert_equal(all([r["success"] for r in import_res]), True)
 527          p2wpkh = self.nodes[1].getnewaddress("", "bech32")
 528          p2pkh = self.nodes[1].getnewaddress("", "legacy")
 529          p2sh_p2wpkh = self.nodes[1].getnewaddress("", "p2sh-segwit")
 530  
 531          # fund those addresses
 532          rawtx = self.nodes[0].createrawtransaction([], {p2sh:10, p2wsh:10, p2wpkh:10, p2sh_p2wsh:10, p2sh_p2wpkh:10, p2pkh:10})
 533          rawtx = self.nodes[0].fundrawtransaction(rawtx, {"changePosition":3})
 534          signed_tx = self.nodes[0].signrawtransactionwithwallet(rawtx['hex'])['hex']
 535          txid = self.nodes[0].sendrawtransaction(signed_tx)
 536          self.generate(self.nodes[0], 6)
 537  
 538          # Find the output pos
 539          p2sh_pos = -1
 540          p2wsh_pos = -1
 541          p2wpkh_pos = -1
 542          p2pkh_pos = -1
 543          p2sh_p2wsh_pos = -1
 544          p2sh_p2wpkh_pos = -1
 545          decoded = self.nodes[0].decoderawtransaction(signed_tx)
 546          for out in decoded['vout']:
 547              if out['scriptPubKey']['address'] == p2sh:
 548                  p2sh_pos = out['n']
 549              elif out['scriptPubKey']['address'] == p2wsh:
 550                  p2wsh_pos = out['n']
 551              elif out['scriptPubKey']['address'] == p2wpkh:
 552                  p2wpkh_pos = out['n']
 553              elif out['scriptPubKey']['address'] == p2sh_p2wsh:
 554                  p2sh_p2wsh_pos = out['n']
 555              elif out['scriptPubKey']['address'] == p2sh_p2wpkh:
 556                  p2sh_p2wpkh_pos = out['n']
 557              elif out['scriptPubKey']['address'] == p2pkh:
 558                  p2pkh_pos = out['n']
 559  
 560          inputs = [{"txid": txid, "vout": p2wpkh_pos}, {"txid": txid, "vout": p2sh_p2wpkh_pos}, {"txid": txid, "vout": p2pkh_pos}]
 561          outputs = [{self.nodes[1].getnewaddress(): 29.99}]
 562  
 563          # spend single key from node 1
 564          created_psbt = self.nodes[1].walletcreatefundedpsbt(inputs, outputs)
 565          walletprocesspsbt_out = self.nodes[1].walletprocesspsbt(created_psbt['psbt'])
 566          # Make sure it has both types of UTXOs
 567          decoded = self.nodes[1].decodepsbt(walletprocesspsbt_out['psbt'])
 568          assert 'non_witness_utxo' in decoded['inputs'][0]
 569          assert 'witness_utxo' in decoded['inputs'][0]
 570          # Check decodepsbt fee calculation (input values shall only be counted once per UTXO)
 571          assert_equal(decoded['fee'], created_psbt['fee'])
 572          assert_equal(walletprocesspsbt_out['complete'], True)
 573          self.nodes[1].sendrawtransaction(walletprocesspsbt_out['hex'])
 574  
 575          self.log.info("Test walletcreatefundedpsbt fee rate of 10000 sat/vB and 0.1 BTC/kvB produces a total fee at or slightly below -maxtxfee (~0.05290000)")
 576          res1 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": 10000, "add_inputs": True})
 577          assert_approx(res1["fee"], 0.055, 0.005)
 578          res2 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": "0.1", "add_inputs": True})
 579          assert_approx(res2["fee"], 0.055, 0.005)
 580  
 581          self.log.info("Test min fee rate checks with walletcreatefundedpsbt are bypassed, e.g. a fee_rate under 1 sat/vB is allowed")
 582          res3 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"fee_rate": "0.999", "add_inputs": True})
 583          assert_approx(res3["fee"], 0.00000381, 0.0000001)
 584          res4 = self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {"feeRate": 0.00000999, "add_inputs": True})
 585          assert_approx(res4["fee"], 0.00000381, 0.0000001)
 586  
 587          self.log.info("Test min fee rate checks with walletcreatefundedpsbt are bypassed and that funding non-standard 'zero-fee' transactions is valid")
 588          for param, zero_value in product(["fee_rate", "feeRate"], [0, 0.000, 0.00000000, "0", "0.000", "0.00000000"]):
 589              assert_equal(0, self.nodes[1].walletcreatefundedpsbt(inputs, outputs, 0, {param: zero_value, "add_inputs": True})["fee"])
 590  
 591          self.log.info("Test invalid fee rate settings")
 592          for param, value in {("fee_rate", 100000), ("feeRate", 1)}:
 593              assert_raises_rpc_error(-4, "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)",
 594                  self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: value, "add_inputs": True})
 595              assert_raises_rpc_error(-3, "Amount out of range",
 596                  self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: -1, "add_inputs": True})
 597              assert_raises_rpc_error(-3, "Amount is not a number or string",
 598                  self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: {"foo": "bar"}, "add_inputs": True})
 599              # Test fee rate values that don't pass fixed-point parsing checks.
 600              for invalid_value in ["", 0.000000001, 1e-09, 1.111111111, 1111111111111111, "31.999999999999999999999"]:
 601                  assert_raises_rpc_error(-3, "Invalid amount",
 602                      self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {param: invalid_value, "add_inputs": True})
 603          # Test fee_rate values that cannot be represented in sat/vB.
 604          for invalid_value in [0.0001, 0.00000001, 0.00099999, 31.99999999]:
 605              assert_raises_rpc_error(-3, "Invalid amount",
 606                  self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": invalid_value, "add_inputs": True})
 607  
 608          self.log.info("- raises RPC error if both feeRate and fee_rate are passed")
 609          assert_raises_rpc_error(-8, "Cannot specify both fee_rate (sat/vB) and feeRate (BTC/kvB)",
 610              self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"fee_rate": 0.1, "feeRate": 0.1, "add_inputs": True})
 611  
 612          self.log.info("- raises RPC error if both feeRate and estimate_mode passed")
 613          assert_raises_rpc_error(-8, "Cannot specify both estimate_mode and feeRate",
 614              self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": "economical", "feeRate": 0.1, "add_inputs": True})
 615  
 616          for param in ["feeRate", "fee_rate"]:
 617              self.log.info("- raises RPC error if both {} and conf_target are passed".format(param))
 618              assert_raises_rpc_error(-8, "Cannot specify both conf_target and {}. Please provide either a confirmation "
 619                  "target in blocks for automatic fee estimation, or an explicit fee rate.".format(param),
 620                  self.nodes[1].walletcreatefundedpsbt ,inputs, outputs, 0, {param: 1, "conf_target": 1, "add_inputs": True})
 621  
 622          self.log.info("- raises RPC error if both fee_rate and estimate_mode are passed")
 623          assert_raises_rpc_error(-8, "Cannot specify both estimate_mode and fee_rate",
 624              self.nodes[1].walletcreatefundedpsbt ,inputs, outputs, 0, {"fee_rate": 1, "estimate_mode": "economical", "add_inputs": True})
 625  
 626          self.log.info("- raises RPC error with invalid estimate_mode settings")
 627          for k, v in {"number": 42, "object": {"foo": "bar"}}.items():
 628              assert_raises_rpc_error(-3, f"JSON value of type {k} for field estimate_mode is not of expected type string",
 629                  self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": v, "conf_target": 0.1, "add_inputs": True})
 630          for mode in ["", "foo", Decimal("3.141592")]:
 631              assert_raises_rpc_error(-8, 'Invalid estimate_mode parameter, must be one of: "unset", "economical", "conservative"',
 632                  self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": mode, "conf_target": 0.1, "add_inputs": True})
 633  
 634          self.log.info("- raises RPC error with invalid conf_target settings")
 635          for mode in ["unset", "economical", "conservative"]:
 636              self.log.debug("{}".format(mode))
 637              for k, v in {"string": "", "object": {"foo": "bar"}}.items():
 638                  assert_raises_rpc_error(-3, f"JSON value of type {k} for field conf_target is not of expected type number",
 639                      self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": mode, "conf_target": v, "add_inputs": True})
 640              for n in [-1, 0, 1009]:
 641                  assert_raises_rpc_error(-8, "Invalid conf_target, must be between 1 and 1008",  # max value of 1008 per src/policy/fees/block_policy_estimator.h
 642                      self.nodes[1].walletcreatefundedpsbt, inputs, outputs, 0, {"estimate_mode": mode, "conf_target": n, "add_inputs": True})
 643  
 644          self.log.info("Test walletcreatefundedpsbt with too-high fee rate produces total fee well above -maxtxfee and raises RPC error")
 645          # previously this was silently capped at -maxtxfee
 646          for bool_add, outputs_array in {True: outputs, False: [{self.nodes[1].getnewaddress(): 1}]}.items():
 647              msg = "Fee exceeds maximum configured by user (e.g. -maxtxfee, maxfeerate)"
 648              assert_raises_rpc_error(-4, msg, self.nodes[1].walletcreatefundedpsbt, inputs, outputs_array, 0, {"fee_rate": 1000000, "add_inputs": bool_add})
 649              assert_raises_rpc_error(-4, msg, self.nodes[1].walletcreatefundedpsbt, inputs, outputs_array, 0, {"feeRate": 1, "add_inputs": bool_add})
 650  
 651          self.log.info("Test various PSBT operations")
 652          # partially sign multisig things with node 1
 653          psbtx = wmulti.walletcreatefundedpsbt(inputs=[{"txid":txid,"vout":p2wsh_pos},{"txid":txid,"vout":p2sh_pos},{"txid":txid,"vout":p2sh_p2wsh_pos}], outputs={self.nodes[1].getnewaddress():29.99}, changeAddress=self.nodes[1].getrawchangeaddress())['psbt']
 654          walletprocesspsbt_out = self.nodes[1].walletprocesspsbt(psbtx)
 655          psbtx = walletprocesspsbt_out['psbt']
 656          assert_equal(walletprocesspsbt_out['complete'], False)
 657  
 658          # Unload wmulti, we don't need it anymore
 659          wmulti.unloadwallet()
 660  
 661          # partially sign with node 2. This should be complete and sendable
 662          walletprocesspsbt_out = self.nodes[2].walletprocesspsbt(psbtx)
 663          assert_equal(walletprocesspsbt_out['complete'], True)
 664          self.nodes[2].sendrawtransaction(walletprocesspsbt_out['hex'])
 665  
 666          # check that walletprocesspsbt fails to decode a non-psbt
 667          rawtx = self.nodes[1].createrawtransaction([{"txid":txid,"vout":p2wpkh_pos}], {self.nodes[1].getnewaddress():9.99})
 668          assert_raises_rpc_error(-22, "TX decode failed", self.nodes[1].walletprocesspsbt, rawtx)
 669  
 670          # Convert a non-psbt to psbt and make sure we can decode it
 671          rawtx = self.nodes[0].createrawtransaction([], {self.nodes[1].getnewaddress():10})
 672          rawtx = self.nodes[0].fundrawtransaction(rawtx)
 673          new_psbt = self.nodes[0].converttopsbt(rawtx['hex'])
 674          self.nodes[0].decodepsbt(new_psbt)
 675  
 676          # Make sure that a non-psbt with signatures cannot be converted
 677          signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx['hex'])
 678          assert_raises_rpc_error(-22, "Inputs must not have scriptSigs and scriptWitnesses",
 679                                  self.nodes[0].converttopsbt, hexstring=signedtx['hex'])  # permitsigdata=False by default
 680          assert_raises_rpc_error(-22, "Inputs must not have scriptSigs and scriptWitnesses",
 681                                  self.nodes[0].converttopsbt, hexstring=signedtx['hex'], permitsigdata=False)
 682          assert_raises_rpc_error(-22, "Inputs must not have scriptSigs and scriptWitnesses",
 683                                  self.nodes[0].converttopsbt, hexstring=signedtx['hex'], permitsigdata=False, iswitness=True)
 684          # Unless we allow it to convert and strip signatures
 685          self.nodes[0].converttopsbt(hexstring=signedtx['hex'], permitsigdata=True)
 686  
 687          # Create outputs to nodes 1 and 2
 688          # (note that we intentionally create two different txs here, as we want
 689          #  to check that each node is missing prevout data for one of the two
 690          #  utxos, see "should only have data for one input" test below)
 691          node1_addr = self.nodes[1].getnewaddress()
 692          node2_addr = self.nodes[2].getnewaddress()
 693          utxo1 = self.create_outpoints(self.nodes[0], outputs=[{node1_addr: 13}])[0]
 694          utxo2 = self.create_outpoints(self.nodes[0], outputs=[{node2_addr: 13}])[0]
 695          self.generate(self.nodes[0], 6)[0]
 696  
 697          # Create a psbt spending outputs from nodes 1 and 2
 698          psbt_orig = self.nodes[0].createpsbt([utxo1, utxo2], {self.nodes[0].getnewaddress():25.999})
 699  
 700          # Update psbts, should only have data for one input and not the other
 701          psbt1 = self.nodes[1].walletprocesspsbt(psbt_orig, False, "ALL")['psbt']
 702          psbt1_decoded = self.nodes[0].decodepsbt(psbt1)
 703          assert psbt1_decoded['inputs'][0] and not psbt1_decoded['inputs'][1]
 704          # Check that BIP32 path was added
 705          assert "bip32_derivs" in psbt1_decoded['inputs'][0]
 706          psbt2 = self.nodes[2].walletprocesspsbt(psbt_orig, False, "ALL", False)['psbt']
 707          psbt2_decoded = self.nodes[0].decodepsbt(psbt2)
 708          assert not psbt2_decoded['inputs'][0] and psbt2_decoded['inputs'][1]
 709          # Check that BIP32 paths were not added
 710          assert "bip32_derivs" not in psbt2_decoded['inputs'][1]
 711  
 712          # Sign PSBTs (workaround issue #18039)
 713          psbt1 = self.nodes[1].walletprocesspsbt(psbt_orig)['psbt']
 714          psbt2 = self.nodes[2].walletprocesspsbt(psbt_orig)['psbt']
 715  
 716          # Combine, finalize, and send the psbts
 717          combined = self.nodes[0].combinepsbt([psbt1, psbt2])
 718          finalized = self.nodes[0].finalizepsbt(combined)['hex']
 719          self.nodes[0].sendrawtransaction(finalized)
 720          self.generate(self.nodes[0], 6)
 721  
 722          # Test additional args in walletcreatepsbt
 723          # Make sure both pre-included and funded inputs
 724          # have the correct sequence numbers based on
 725          # replaceable arg
 726          block_height = self.nodes[0].getblockcount()
 727          unspent = self.nodes[0].listunspent()[0]
 728          psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height+2, {"replaceable": False, "add_inputs": True}, False)
 729          decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"])
 730          for tx_in, psbt_in in zip(decoded_psbt["tx"]["vin"], decoded_psbt["inputs"]):
 731              assert_greater_than(tx_in["sequence"], MAX_BIP125_RBF_SEQUENCE)
 732              assert "bip32_derivs" not in psbt_in
 733          assert_equal(decoded_psbt["tx"]["locktime"], block_height+2)
 734  
 735          # Same construction with only locktime set and RBF explicitly enabled
 736          psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height, {"replaceable": True, "add_inputs": True}, True)
 737          decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"])
 738          for tx_in, psbt_in in zip(decoded_psbt["tx"]["vin"], decoded_psbt["inputs"]):
 739              assert_equal(tx_in["sequence"], MAX_BIP125_RBF_SEQUENCE)
 740              assert "bip32_derivs" in psbt_in
 741          assert_equal(decoded_psbt["tx"]["locktime"], block_height)
 742  
 743          # Same construction without optional arguments
 744          psbtx_info = self.nodes[0].walletcreatefundedpsbt([], [{self.nodes[2].getnewaddress():unspent["amount"]+1}])
 745          decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"])
 746          for tx_in, psbt_in in zip(decoded_psbt["tx"]["vin"], decoded_psbt["inputs"]):
 747              assert_equal(tx_in["sequence"], MAX_BIP125_RBF_SEQUENCE)
 748              assert "bip32_derivs" in psbt_in
 749          assert_equal(decoded_psbt["tx"]["locktime"], 0)
 750  
 751          # Same construction without optional arguments, for a node with -walletrbf=0
 752          unspent1 = self.nodes[1].listunspent()[0]
 753          psbtx_info = self.nodes[1].walletcreatefundedpsbt([{"txid":unspent1["txid"], "vout":unspent1["vout"]}], [{self.nodes[2].getnewaddress():unspent1["amount"]+1}], block_height, {"add_inputs": True})
 754          decoded_psbt = self.nodes[1].decodepsbt(psbtx_info["psbt"])
 755          for tx_in, psbt_in in zip(decoded_psbt["tx"]["vin"], decoded_psbt["inputs"]):
 756              assert_greater_than(tx_in["sequence"], MAX_BIP125_RBF_SEQUENCE)
 757              assert "bip32_derivs" in psbt_in
 758  
 759          # Make sure change address wallet does not have P2SH innerscript access to results in success
 760          # when attempting BnB coin selection
 761          self.nodes[0].walletcreatefundedpsbt([], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height+2, {"changeAddress":self.nodes[1].getnewaddress()}, False)
 762  
 763          # Make sure the wallet's change type is respected by default
 764          small_output = {self.nodes[0].getnewaddress():0.1}
 765          psbtx_native = self.nodes[0].walletcreatefundedpsbt([], [small_output])
 766          self.assert_change_type(psbtx_native, "witness_v0_keyhash")
 767          psbtx_legacy = self.nodes[1].walletcreatefundedpsbt([], [small_output])
 768          self.assert_change_type(psbtx_legacy, "pubkeyhash")
 769  
 770          # Make sure the change type of the wallet can also be overwritten
 771          psbtx_np2wkh = self.nodes[1].walletcreatefundedpsbt([], [small_output], 0, {"change_type":"p2sh-segwit"})
 772          self.assert_change_type(psbtx_np2wkh, "scripthash")
 773  
 774          # Make sure the change type cannot be specified if a change address is given
 775          invalid_options = {"change_type":"legacy","changeAddress":self.nodes[0].getnewaddress()}
 776          assert_raises_rpc_error(-8, "both change address and address type options", self.nodes[0].walletcreatefundedpsbt, [], [small_output], 0, invalid_options)
 777  
 778          # Regression test for 14473 (mishandling of already-signed witness transaction):
 779          psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], 0, {"add_inputs": True})
 780          complete_psbt = self.nodes[0].walletprocesspsbt(psbtx_info["psbt"])
 781          double_processed_psbt = self.nodes[0].walletprocesspsbt(complete_psbt["psbt"])
 782          assert_equal(complete_psbt, double_processed_psbt)
 783          # We don't care about the decode result, but decoding must succeed.
 784          self.nodes[0].decodepsbt(double_processed_psbt["psbt"])
 785  
 786          # Make sure unsafe inputs are included if specified
 787          self.nodes[2].createwallet(wallet_name="unsafe")
 788          wunsafe = self.nodes[2].get_wallet_rpc("unsafe")
 789          self.nodes[0].sendtoaddress(wunsafe.getnewaddress(), 2)
 790          self.sync_mempools()
 791          assert_raises_rpc_error(-4, "Insufficient funds", wunsafe.walletcreatefundedpsbt, [], [{self.nodes[0].getnewaddress(): 1}])
 792          wunsafe.walletcreatefundedpsbt([], [{self.nodes[0].getnewaddress(): 1}], 0, {"include_unsafe": True})
 793  
 794          # BIP 174 Test Vectors
 795  
 796          # Check that unknown values are just passed through
 797          unknown_psbt = "cHNidP8BAD8CAAAAAf//////////////////////////////////////////AAAAAAD/////AQAAAAAAAAAAA2oBAAAAAAAACg8BAgMEBQYHCAkPAQIDBAUGBwgJCgsMDQ4PAAA="
 798          unknown_out = self.nodes[0].walletprocesspsbt(unknown_psbt)['psbt']
 799          assert_equal(unknown_psbt, unknown_out)
 800  
 801          # Open the data file
 802          with open(os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data/rpc_psbt.json')) as f:
 803              d = json.load(f)
 804              invalids = d['invalid']
 805              invalid_with_msgs = d["invalid_with_msg"]
 806              valids = d['valid']
 807              creators = d['creator']
 808              signers = d['signer']
 809              combiners = d['combiner']
 810              finalizers = d['finalizer']
 811              extractors = d['extractor']
 812  
 813          # Invalid PSBTs
 814          for invalid in invalids:
 815              assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].decodepsbt, invalid)
 816          for invalid in invalid_with_msgs:
 817              psbt, msg = invalid
 818              assert_raises_rpc_error(-22, f"TX decode failed {msg}", self.nodes[0].decodepsbt, psbt)
 819  
 820          # Valid PSBTs
 821          for valid in valids:
 822              self.nodes[0].decodepsbt(valid)
 823  
 824          # Creator Tests
 825          for creator in creators:
 826              created_tx = self.nodes[0].createpsbt(inputs=creator['inputs'], outputs=creator['outputs'], replaceable=False)
 827              assert_equal(created_tx, creator['result'])
 828  
 829          # Signer tests
 830          for i, signer in enumerate(signers):
 831              self.nodes[2].createwallet(wallet_name="wallet{}".format(i))
 832              wrpc = self.nodes[2].get_wallet_rpc("wallet{}".format(i))
 833              for key in signer['privkeys']:
 834                  wallet_importprivkey(wrpc, key, "now")
 835              signed_tx = wrpc.walletprocesspsbt(signer['psbt'], True, "ALL")['psbt']
 836              assert_equal(signed_tx, signer['result'])
 837  
 838          # Combiner test
 839          for combiner in combiners:
 840              combined = self.nodes[2].combinepsbt(combiner['combine'])
 841              assert_equal(combined, combiner['result'])
 842  
 843          # Empty combiner test
 844          assert_raises_rpc_error(-8, "Parameter 'txs' cannot be empty", self.nodes[0].combinepsbt, [])
 845  
 846          # Finalizer test
 847          for finalizer in finalizers:
 848              finalized = self.nodes[2].finalizepsbt(finalizer['finalize'], False)['psbt']
 849              assert_equal(finalized, finalizer['result'])
 850  
 851          # Extractor test
 852          for extractor in extractors:
 853              extracted = self.nodes[2].finalizepsbt(extractor['extract'], True)['hex']
 854              assert_equal(extracted, extractor['result'])
 855  
 856          # Unload extra wallets
 857          for i, signer in enumerate(signers):
 858              self.nodes[2].unloadwallet("wallet{}".format(i))
 859  
 860          self.test_utxo_conversion()
 861          self.test_psbt_incomplete_after_invalid_modification()
 862  
 863          self.test_input_confs_control()
 864  
 865          # Test that psbts with p2pkh outputs are created properly
 866          p2pkh = self.nodes[0].getnewaddress(address_type='legacy')
 867          psbt = self.nodes[1].walletcreatefundedpsbt(inputs=[], outputs=[{p2pkh : 1}], bip32derivs=True)
 868          self.nodes[0].decodepsbt(psbt['psbt'])
 869  
 870          # Test decoding error: invalid base64
 871          assert_raises_rpc_error(-22, "TX decode failed invalid base64", self.nodes[0].decodepsbt, ";definitely not base64;")
 872  
 873          # Send to all types of addresses
 874          addr1 = self.nodes[1].getnewaddress("", "bech32")
 875          addr2 = self.nodes[1].getnewaddress("", "legacy")
 876          addr3 = self.nodes[1].getnewaddress("", "p2sh-segwit")
 877          utxo1, utxo2, utxo3 = self.create_outpoints(self.nodes[1], outputs=[{addr1: 11}, {addr2: 11}, {addr3: 11}])
 878          self.sync_all()
 879  
 880          def test_psbt_input_keys(psbt_input, keys):
 881              """Check that the psbt input has only the expected keys."""
 882              assert_equal(set(keys), set(psbt_input.keys()))
 883  
 884          # Create a PSBT. None of the inputs are filled initially
 885          psbt = self.nodes[1].createpsbt([utxo1, utxo2, utxo3], {self.nodes[0].getnewaddress():32.999})
 886          decoded = self.nodes[1].decodepsbt(psbt)
 887          test_psbt_input_keys(decoded['inputs'][0], [])
 888          test_psbt_input_keys(decoded['inputs'][1], [])
 889          test_psbt_input_keys(decoded['inputs'][2], [])
 890  
 891          # Update a PSBT with UTXOs from the node
 892          # Bech32 inputs should be filled with witness UTXO. Other inputs should not be filled because they are non-witness
 893          updated = self.nodes[1].utxoupdatepsbt(psbt)
 894          decoded = self.nodes[1].decodepsbt(updated)
 895          test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo'])
 896          test_psbt_input_keys(decoded['inputs'][1], ['non_witness_utxo'])
 897          test_psbt_input_keys(decoded['inputs'][2], ['non_witness_utxo'])
 898  
 899          # Try again, now while providing descriptors, making P2SH-segwit work, and causing bip32_derivs and redeem_script to be filled in
 900          descs = [self.nodes[1].getaddressinfo(addr)['desc'] for addr in [addr1,addr2,addr3]]
 901          updated = self.nodes[1].utxoupdatepsbt(psbt=psbt, descriptors=descs)
 902          decoded = self.nodes[1].decodepsbt(updated)
 903          test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo', 'bip32_derivs'])
 904          test_psbt_input_keys(decoded['inputs'][1], ['non_witness_utxo', 'bip32_derivs'])
 905          test_psbt_input_keys(decoded['inputs'][2], ['non_witness_utxo','witness_utxo', 'bip32_derivs', 'redeem_script'])
 906  
 907          # Two PSBTs with a common input should not be joinable
 908          psbt1 = self.nodes[1].createpsbt([utxo1], {self.nodes[0].getnewaddress():Decimal('10.999')})
 909          assert_raises_rpc_error(-8, "exists in multiple PSBTs", self.nodes[1].joinpsbts, [psbt1, updated])
 910  
 911          # Join two distinct PSBTs
 912          addr4 = self.nodes[1].getnewaddress("", "p2sh-segwit")
 913          utxo4 = self.create_outpoints(self.nodes[0], outputs=[{addr4: 5}])[0]
 914          self.generate(self.nodes[0], 6)
 915          psbt2 = self.nodes[1].createpsbt([utxo4], {self.nodes[0].getnewaddress():Decimal('4.999')})
 916          psbt2 = self.nodes[1].walletprocesspsbt(psbt2)['psbt']
 917          psbt2_decoded = self.nodes[0].decodepsbt(psbt2)
 918          assert "final_scriptwitness" in psbt2_decoded['inputs'][0] and "final_scriptSig" in psbt2_decoded['inputs'][0]
 919          joined = self.nodes[0].joinpsbts([psbt, psbt2])
 920          joined_decoded = self.nodes[0].decodepsbt(joined)
 921          assert len(joined_decoded['inputs']) == 4 and len(joined_decoded['outputs']) == 2 and "final_scriptwitness" not in joined_decoded['inputs'][3] and "final_scriptSig" not in joined_decoded['inputs'][3]
 922  
 923          # Check that joining shuffles the inputs and outputs
 924          # 10 attempts should be enough to get a shuffled join
 925          shuffled = False
 926          for _ in range(10):
 927              shuffled_joined = self.nodes[0].joinpsbts([psbt, psbt2])
 928              shuffled |= joined != shuffled_joined
 929              if shuffled:
 930                  break
 931          assert shuffled
 932  
 933          # Newly created PSBT needs UTXOs and updating
 934          addr = self.nodes[1].getnewaddress("", "p2sh-segwit")
 935          utxo = self.create_outpoints(self.nodes[0], outputs=[{addr: 7}])[0]
 936          addrinfo = self.nodes[1].getaddressinfo(addr)
 937          self.generate(self.nodes[0], 6)[0]
 938          psbt = self.nodes[1].createpsbt([utxo], {self.nodes[0].getnewaddress("", "p2sh-segwit"):Decimal('6.999')})
 939          analyzed = self.nodes[0].analyzepsbt(psbt)
 940          assert not analyzed['inputs'][0]['has_utxo'] and not analyzed['inputs'][0]['is_final'] and analyzed['inputs'][0]['next'] == 'updater' and analyzed['next'] == 'updater'
 941  
 942          # After update with wallet, only needs signing
 943          updated = self.nodes[1].walletprocesspsbt(psbt, False, 'ALL', True)['psbt']
 944          analyzed = self.nodes[0].analyzepsbt(updated)
 945          assert analyzed['inputs'][0]['has_utxo'] and not analyzed['inputs'][0]['is_final'] and analyzed['inputs'][0]['next'] == 'signer' and analyzed['next'] == 'signer' and analyzed['inputs'][0]['missing']['signatures'][0] == addrinfo['embedded']['witness_program']
 946  
 947          # Check fee and size things
 948          assert analyzed['fee'] == Decimal('0.001') and analyzed['estimated_vsize'] == 134 and analyzed['estimated_feerate'] == Decimal('0.00746268')
 949  
 950          # After signing and finalizing, needs extracting
 951          signed = self.nodes[1].walletprocesspsbt(updated)['psbt']
 952          analyzed = self.nodes[0].analyzepsbt(signed)
 953          assert analyzed['inputs'][0]['has_utxo'] and analyzed['inputs'][0]['is_final'] and analyzed['next'] == 'extractor'
 954  
 955          self.log.info("PSBT spending unspendable outputs should have error message and Creator as next")
 956          analysis = self.nodes[0].analyzepsbt('cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWAEHYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFv8/wADXYP/7//////8JxOh0LR2HAI8AAAAAAAEBIADC6wsAAAAAF2oUt/X69ELjeX2nTof+fZ10l+OyAokDAQcJAwEHEAABAACAAAEBIADC6wsAAAAAF2oUt/X69ELjeX2nTof+fZ10l+OyAokDAQcJAwEHENkMak8AAAAA')
 957          assert_equal(analysis['next'], 'creator')
 958          assert_equal(analysis['error'], 'PSBT is not valid. Input 0 spends unspendable output')
 959  
 960          self.log.info("PSBT with invalid values should have error message and Creator as next")
 961          analysis = self.nodes[0].analyzepsbt('cHNidP8BAHECAAAAAfA00BFgAm6tp86RowwH6BMImQNL5zXUcTT97XoLGz0BAAAAAAD/////AgD5ApUAAAAAFgAUKNw0x8HRctAgmvoevm4u1SbN7XL87QKVAAAAABYAFPck4gF7iL4NL4wtfRAKgQbghiTUAAAAAAABAR8AgIFq49AHABYAFJUDtxf2PHo641HEOBOAIvFMNTr2AAAA')
 962          assert_equal(analysis['next'], 'creator')
 963          assert_equal(analysis['error'], 'PSBT is not valid. Input 0 has invalid value')
 964  
 965          self.log.info("PSBT with signed, but not finalized, inputs should have Finalizer as next")
 966          analysis = self.nodes[0].analyzepsbt('cHNidP8BAHECAAAAAZYezcxdnbXoQCmrD79t/LzDgtUo9ERqixk8wgioAobrAAAAAAD9////AlDDAAAAAAAAFgAUy/UxxZuzZswcmFnN/E9DGSiHLUsuGPUFAAAAABYAFLsH5o0R38wXx+X2cCosTMCZnQ4baAAAAAABAR8A4fUFAAAAABYAFOBI2h5thf3+Lflb2LGCsVSZwsltIgIC/i4dtVARCRWtROG0HHoGcaVklzJUcwo5homgGkSNAnJHMEQCIGx7zKcMIGr7cEES9BR4Kdt/pzPTK3fKWcGyCJXb7MVnAiALOBgqlMH4GbC1HDh/HmylmO54fyEy4lKde7/BT/PWxwEBAwQBAAAAIgYC/i4dtVARCRWtROG0HHoGcaVklzJUcwo5homgGkSNAnIYDwVpQ1QAAIABAACAAAAAgAAAAAAAAAAAAAAiAgL+CIiB59NSCssOJRGiMYQK1chahgAaaJpIXE41Cyir+xgPBWlDVAAAgAEAAIAAAACAAQAAAAAAAAAA')
 967          assert_equal(analysis['next'], 'finalizer')
 968  
 969          analysis = self.nodes[0].analyzepsbt('cHNidP8BAHECAAAAAfA00BFgAm6tp86RowwH6BMImQNL5zXUcTT97XoLGz0BAAAAAAD/////AgCAgWrj0AcAFgAUKNw0x8HRctAgmvoevm4u1SbN7XL87QKVAAAAABYAFPck4gF7iL4NL4wtfRAKgQbghiTUAAAAAAABAR8A8gUqAQAAABYAFJUDtxf2PHo641HEOBOAIvFMNTr2AAAA')
 970          assert_equal(analysis['next'], 'creator')
 971          assert_equal(analysis['error'], 'PSBT is not valid. Output amount invalid')
 972  
 973          assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].analyzepsbt, "cHNidP8BAJoCAAAAAkvEW8NnDtdNtDpsmze+Ht2LH35IJcKv00jKAlUs21RrAwAAAAD/////S8Rbw2cO1020OmybN74e3Ysffkglwq/TSMoCVSzbVGsBAAAAAP7///8CwLYClQAAAAAWABSNJKzjaUb3uOxixsvh1GGE3fW7zQD5ApUAAAAAFgAUKNw0x8HRctAgmvoevm4u1SbN7XIAAAAAAAEAnQIAAAACczMa321tVHuN4GKWKRncycI22aX3uXgwSFUKM2orjRsBAAAAAP7///9zMxrfbW1Ue43gYpYpGdzJwjbZpfe5eDBIVQozaiuNGwAAAAAA/v///wIA+QKVAAAAABl2qRT9zXUVA8Ls5iVqynLHe5/vSe1XyYisQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAAAAAQEfQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAA==")
 974  
 975          assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].walletprocesspsbt, "cHNidP8BAJoCAAAAAkvEW8NnDtdNtDpsmze+Ht2LH35IJcKv00jKAlUs21RrAwAAAAD/////S8Rbw2cO1020OmybN74e3Ysffkglwq/TSMoCVSzbVGsBAAAAAP7///8CwLYClQAAAAAWABSNJKzjaUb3uOxixsvh1GGE3fW7zQD5ApUAAAAAFgAUKNw0x8HRctAgmvoevm4u1SbN7XIAAAAAAAEAnQIAAAACczMa321tVHuN4GKWKRncycI22aX3uXgwSFUKM2orjRsBAAAAAP7///9zMxrfbW1Ue43gYpYpGdzJwjbZpfe5eDBIVQozaiuNGwAAAAAA/v///wIA+QKVAAAAABl2qRT9zXUVA8Ls5iVqynLHe5/vSe1XyYisQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAAAAAQEfQM0ClQAAAAAWABRmWQUcjSjghQ8/uH4Bn/zkakwLtAAAAA==")
 976  
 977          self.log.info("Test that we can fund psbts with external inputs specified")
 978  
 979          privkey, _ = generate_keypair(wif=True)
 980  
 981          self.nodes[1].createwallet("extfund")
 982          wallet = self.nodes[1].get_wallet_rpc("extfund")
 983  
 984          # Make a weird but signable script. sh(wsh(pkh())) descriptor accomplishes this
 985          desc = descsum_create("sh(wsh(pkh({})))".format(privkey))
 986          res = self.nodes[0].importdescriptors([{"desc": desc, "timestamp": "now"}])
 987          assert res[0]["success"]
 988          addr = self.nodes[0].deriveaddresses(desc)[0]
 989          addr_info = self.nodes[0].getaddressinfo(addr)
 990  
 991          self.nodes[0].sendtoaddress(addr, 10)
 992          self.nodes[0].sendtoaddress(wallet.getnewaddress(), 10)
 993          self.generate(self.nodes[0], 6)
 994          ext_utxo = self.nodes[0].listunspent(addresses=[addr])[0]
 995  
 996          # An external input without solving data should result in an error
 997          assert_raises_rpc_error(-4, "Not solvable pre-selected input COutPoint(%s, %s)" % (ext_utxo["txid"][0:10], ext_utxo["vout"]), wallet.walletcreatefundedpsbt, [ext_utxo], {self.nodes[0].getnewaddress(): 15})
 998  
 999          # But funding should work when the solving data is provided
1000          psbt = wallet.walletcreatefundedpsbt([ext_utxo], {self.nodes[0].getnewaddress(): 15}, 0, {"add_inputs": True, "solving_data": {"pubkeys": [addr_info['pubkey']], "scripts": [addr_info["embedded"]["scriptPubKey"], addr_info["embedded"]["embedded"]["scriptPubKey"]]}})
1001          signed = wallet.walletprocesspsbt(psbt['psbt'])
1002          assert not signed['complete']
1003          signed = self.nodes[0].walletprocesspsbt(signed['psbt'])
1004          assert signed['complete']
1005  
1006          psbt = wallet.walletcreatefundedpsbt([ext_utxo], {self.nodes[0].getnewaddress(): 15}, 0, {"add_inputs": True, "solving_data":{"descriptors": [desc]}})
1007          signed = wallet.walletprocesspsbt(psbt['psbt'])
1008          assert not signed['complete']
1009          signed = self.nodes[0].walletprocesspsbt(signed['psbt'])
1010          assert signed['complete']
1011          final = signed['hex']
1012  
1013          dec = self.nodes[0].decodepsbt(signed["psbt"])
1014          for i, txin in enumerate(dec["tx"]["vin"]):
1015              if txin["txid"] == ext_utxo["txid"] and txin["vout"] == ext_utxo["vout"]:
1016                  input_idx = i
1017                  break
1018          psbt_in = dec["inputs"][input_idx]
1019          scriptsig_hex = psbt_in["final_scriptSig"]["hex"] if "final_scriptSig" in psbt_in else ""
1020          witness_stack_hex = psbt_in["final_scriptwitness"] if "final_scriptwitness" in psbt_in else None
1021          input_weight = calculate_input_weight(scriptsig_hex, witness_stack_hex)
1022          low_input_weight = input_weight // 2
1023          high_input_weight = input_weight * 2
1024  
1025          # Input weight error conditions
1026          assert_raises_rpc_error(
1027              -8,
1028              "Input weights should be specified in inputs rather than in options.",
1029              wallet.walletcreatefundedpsbt,
1030              inputs=[ext_utxo],
1031              outputs={self.nodes[0].getnewaddress(): 15},
1032              options={"input_weights": [{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": 1000}]}
1033          )
1034  
1035          # Funding should also work if the input weight is provided
1036          psbt = wallet.walletcreatefundedpsbt(
1037              inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": input_weight}],
1038              outputs={self.nodes[0].getnewaddress(): 15},
1039              add_inputs=True,
1040          )
1041          signed = wallet.walletprocesspsbt(psbt["psbt"])
1042          signed = self.nodes[0].walletprocesspsbt(signed["psbt"])
1043          final = signed["hex"]
1044          assert self.nodes[0].testmempoolaccept([final])[0]["allowed"]
1045          # Reducing the weight should have a lower fee
1046          psbt2 = wallet.walletcreatefundedpsbt(
1047              inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": low_input_weight}],
1048              outputs={self.nodes[0].getnewaddress(): 15},
1049              add_inputs=True,
1050          )
1051          assert_greater_than(psbt["fee"], psbt2["fee"])
1052          # Increasing the weight should have a higher fee
1053          psbt2 = wallet.walletcreatefundedpsbt(
1054              inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": high_input_weight}],
1055              outputs={self.nodes[0].getnewaddress(): 15},
1056              add_inputs=True,
1057          )
1058          assert_greater_than(psbt2["fee"], psbt["fee"])
1059          # The provided weight should override the calculated weight when solving data is provided
1060          psbt3 = wallet.walletcreatefundedpsbt(
1061              inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": high_input_weight}],
1062              outputs={self.nodes[0].getnewaddress(): 15},
1063              add_inputs=True, solving_data={"descriptors": [desc]},
1064          )
1065          assert_equal(psbt2["fee"], psbt3["fee"])
1066  
1067          # Import the external utxo descriptor so that we can sign for it from the test wallet
1068          res = wallet.importdescriptors([{"desc": desc, "timestamp": "now"}])
1069          assert res[0]["success"]
1070          # The provided weight should override the calculated weight for a wallet input
1071          psbt3 = wallet.walletcreatefundedpsbt(
1072              inputs=[{"txid": ext_utxo["txid"], "vout": ext_utxo["vout"], "weight": high_input_weight}],
1073              outputs={self.nodes[0].getnewaddress(): 15},
1074              add_inputs=True,
1075          )
1076          assert_equal(psbt2["fee"], psbt3["fee"])
1077  
1078          self.log.info("Test signing inputs that the wallet has keys for but is not watching the scripts")
1079          self.nodes[1].createwallet(wallet_name="scriptwatchonly", disable_private_keys=True)
1080          watchonly = self.nodes[1].get_wallet_rpc("scriptwatchonly")
1081  
1082          privkey, pubkey = generate_keypair(wif=True)
1083  
1084          desc = descsum_create("wsh(pkh({}))".format(pubkey.hex()))
1085          res = watchonly.importdescriptors([{"desc": desc, "timestamp": "now"}])
1086          assert res[0]["success"]
1087          addr = self.nodes[0].deriveaddresses(desc)[0]
1088          self.nodes[0].sendtoaddress(addr, 10)
1089          self.generate(self.nodes[0], 1)
1090          wallet_importprivkey(self.nodes[0], privkey, "now")
1091  
1092          psbt = watchonly.sendall([wallet.getnewaddress()])["psbt"]
1093          signed_tx = self.nodes[0].walletprocesspsbt(psbt)
1094          self.nodes[0].sendrawtransaction(signed_tx["hex"])
1095  
1096          # Same test but for taproot
1097          privkey, pubkey = generate_keypair(wif=True)
1098  
1099          desc = descsum_create("tr({},pk({}))".format(H_POINT, pubkey.hex()))
1100          res = watchonly.importdescriptors([{"desc": desc, "timestamp": "now"}])
1101          assert res[0]["success"]
1102          addr = self.nodes[0].deriveaddresses(desc)[0]
1103          self.nodes[0].sendtoaddress(addr, 10)
1104          self.generate(self.nodes[0], 1)
1105          self.nodes[0].importdescriptors([{"desc": descsum_create("tr({})".format(privkey)), "timestamp":"now"}])
1106  
1107          psbt = watchonly.sendall([wallet.getnewaddress(), addr])["psbt"]
1108          processed_psbt = self.nodes[0].walletprocesspsbt(psbt)
1109          txid = self.nodes[0].sendrawtransaction(processed_psbt["hex"])
1110          vout = find_vout_for_address(self.nodes[0], txid, addr)
1111  
1112          # Make sure tap tree is in psbt
1113          parsed_psbt = PSBT.from_base64(psbt)
1114          assert_greater_than(len(parsed_psbt.o[vout].map[PSBT_OUT_TAP_TREE]), 0)
1115          assert "taproot_tree" in self.nodes[0].decodepsbt(psbt)["outputs"][vout]
1116          parsed_psbt.make_blank()
1117          comb_psbt = self.nodes[0].combinepsbt([psbt, parsed_psbt.to_base64()])
1118          assert_equal(comb_psbt, psbt)
1119  
1120          self.log.info("Test that walletprocesspsbt both updates and signs a non-updated psbt containing Taproot inputs")
1121          addr = self.nodes[0].getnewaddress("", "bech32m")
1122          utxo = self.create_outpoints(self.nodes[0], outputs=[{addr: 1}])[0]
1123          psbt = self.nodes[0].createpsbt([utxo], [{self.nodes[0].getnewaddress(): 0.9999}])
1124          signed = self.nodes[0].walletprocesspsbt(psbt)
1125          rawtx = signed["hex"]
1126          self.nodes[0].sendrawtransaction(rawtx)
1127          self.generate(self.nodes[0], 1)
1128  
1129          # Make sure tap tree is not in psbt
1130          parsed_psbt = PSBT.from_base64(psbt)
1131          assert PSBT_OUT_TAP_TREE not in parsed_psbt.o[0].map
1132          assert "taproot_tree" not in self.nodes[0].decodepsbt(psbt)["outputs"][0]
1133          parsed_psbt.make_blank()
1134          comb_psbt = self.nodes[0].combinepsbt([psbt, parsed_psbt.to_base64()])
1135          assert_equal(comb_psbt, psbt)
1136  
1137          self.log.info("Test walletprocesspsbt raises if an invalid sighashtype is passed")
1138          assert_raises_rpc_error(-8, "'all' is not a valid sighash parameter.", self.nodes[0].walletprocesspsbt, psbt, sighashtype="all")
1139  
1140          self.log.info("Test decoding PSBT with per-input preimage types")
1141          # note that the decodepsbt RPC doesn't check whether preimages and hashes match
1142          hash_ripemd160, preimage_ripemd160 = randbytes(20), randbytes(50)
1143          hash_sha256, preimage_sha256 = randbytes(32), randbytes(50)
1144          hash_hash160, preimage_hash160 = randbytes(20), randbytes(50)
1145          hash_hash256, preimage_hash256 = randbytes(32), randbytes(50)
1146  
1147          tx = CTransaction()
1148          tx.vin = [CTxIn(outpoint=COutPoint(hash=int('aa' * 32, 16), n=0), scriptSig=b""),
1149                    CTxIn(outpoint=COutPoint(hash=int('bb' * 32, 16), n=0), scriptSig=b""),
1150                    CTxIn(outpoint=COutPoint(hash=int('cc' * 32, 16), n=0), scriptSig=b""),
1151                    CTxIn(outpoint=COutPoint(hash=int('dd' * 32, 16), n=0), scriptSig=b"")]
1152          tx.vout = [CTxOut(nValue=0, scriptPubKey=b"")]
1153          psbt = PSBT()
1154          psbt.g = PSBTMap({PSBT_GLOBAL_UNSIGNED_TX: tx.serialize()})
1155          psbt.i = [PSBTMap({bytes([PSBT_IN_RIPEMD160]) + hash_ripemd160: preimage_ripemd160}),
1156                    PSBTMap({bytes([PSBT_IN_SHA256]) + hash_sha256: preimage_sha256}),
1157                    PSBTMap({bytes([PSBT_IN_HASH160]) + hash_hash160: preimage_hash160}),
1158                    PSBTMap({bytes([PSBT_IN_HASH256]) + hash_hash256: preimage_hash256})]
1159          psbt.o = [PSBTMap()]
1160          res_inputs = self.nodes[0].decodepsbt(psbt.to_base64())["inputs"]
1161          assert_equal(len(res_inputs), 4)
1162          preimage_keys = ["ripemd160_preimages", "sha256_preimages", "hash160_preimages", "hash256_preimages"]
1163          expected_hashes = [hash_ripemd160, hash_sha256, hash_hash160, hash_hash256]
1164          expected_preimages = [preimage_ripemd160, preimage_sha256, preimage_hash160, preimage_hash256]
1165          for res_input, preimage_key, hash, preimage in zip(res_inputs, preimage_keys, expected_hashes, expected_preimages):
1166              assert preimage_key in res_input
1167              assert_equal(len(res_input[preimage_key]), 1)
1168              assert hash.hex() in res_input[preimage_key]
1169              assert_equal(res_input[preimage_key][hash.hex()], preimage.hex())
1170  
1171          self.test_decodepsbt_musig2_input_output_types()
1172  
1173          self.log.info("Test that combining PSBTs with different transactions fails")
1174          tx = CTransaction()
1175          tx.vin = [CTxIn(outpoint=COutPoint(hash=int('aa' * 32, 16), n=0), scriptSig=b"")]
1176          tx.vout = [CTxOut(nValue=0, scriptPubKey=b"")]
1177          psbt1 = PSBT(g=PSBTMap({PSBT_GLOBAL_UNSIGNED_TX: tx.serialize()}), i=[PSBTMap()], o=[PSBTMap()]).to_base64()
1178          tx.vout[0].nValue += 1  # slightly modify tx
1179          psbt2 = PSBT(g=PSBTMap({PSBT_GLOBAL_UNSIGNED_TX: tx.serialize()}), i=[PSBTMap()], o=[PSBTMap()]).to_base64()
1180          assert_raises_rpc_error(-8, "PSBTs not compatible (different transactions)", self.nodes[0].combinepsbt, [psbt1, psbt2])
1181          assert_equal(self.nodes[0].combinepsbt([psbt1, psbt1]), psbt1)
1182  
1183          self.log.info("Test that PSBT inputs are being checked via script execution")
1184          acs_prevout = CTxOut(nValue=0, scriptPubKey=CScript([OP_TRUE]))
1185          tx = CTransaction()
1186          tx.vin = [CTxIn(outpoint=COutPoint(hash=int('dd' * 32, 16), n=0), scriptSig=b"")]
1187          tx.vout = [CTxOut(nValue=0, scriptPubKey=b"")]
1188          psbt = PSBT()
1189          psbt.g = PSBTMap({PSBT_GLOBAL_UNSIGNED_TX: tx.serialize()})
1190          psbt.i = [PSBTMap({bytes([PSBT_IN_WITNESS_UTXO]) : acs_prevout.serialize()})]
1191          psbt.o = [PSBTMap()]
1192          assert_equal(self.nodes[0].finalizepsbt(psbt.to_base64()),
1193              {'hex': '0200000001dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd0000000000000000000100000000000000000000000000', 'complete': True})
1194  
1195          self.log.info("Test we don't crash when making a 0-value funded transaction at 0 fee without forcing an input selection")
1196          assert_raises_rpc_error(-4, "Transaction requires one destination of non-zero value, a non-zero feerate, or a pre-selected input", self.nodes[0].walletcreatefundedpsbt, [], [{"data": "deadbeef"}], 0, {"fee_rate": "0"})
1197  
1198          self.log.info("Test descriptorprocesspsbt updates and signs a psbt with descriptors")
1199  
1200          self.generate(self.nodes[2], 1)
1201  
1202          # Disable the wallet for node 2 since `descriptorprocesspsbt` does not use the wallet
1203          self.restart_node(2, extra_args=["-disablewallet"])
1204          self.connect_nodes(0, 2)
1205          self.connect_nodes(1, 2)
1206  
1207          key_info = get_generate_key()
1208          key = key_info.privkey
1209          address = key_info.p2wpkh_addr
1210  
1211          descriptor = descsum_create(f"wpkh({key})")
1212  
1213          utxo = self.create_outpoints(self.nodes[0], outputs=[{address: 1}])[0]
1214          self.sync_all()
1215  
1216          psbt = self.nodes[2].createpsbt([utxo], {self.nodes[0].getnewaddress(): 0.99999})
1217          decoded = self.nodes[2].decodepsbt(psbt)
1218          test_psbt_input_keys(decoded['inputs'][0], [])
1219  
1220          # Test that even if the wrong descriptor is given, `witness_utxo` and `non_witness_utxo`
1221          # are still added to the psbt
1222          alt_descriptor = descsum_create(f"wpkh({get_generate_key().privkey})")
1223          alt_psbt = self.nodes[2].descriptorprocesspsbt(psbt=psbt, descriptors=[alt_descriptor], sighashtype="ALL")["psbt"]
1224          decoded = self.nodes[2].decodepsbt(alt_psbt)
1225          test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo'])
1226  
1227          # Test that the psbt is not finalized and does not have bip32_derivs unless specified
1228          processed_psbt = self.nodes[2].descriptorprocesspsbt(psbt=psbt, descriptors=[descriptor], sighashtype="ALL", bip32derivs=True, finalize=False)
1229          decoded = self.nodes[2].decodepsbt(processed_psbt['psbt'])
1230          test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo', 'partial_signatures', 'bip32_derivs'])
1231  
1232          # If psbt not finalized, test that result does not have hex
1233          assert "hex" not in processed_psbt
1234  
1235          processed_psbt = self.nodes[2].descriptorprocesspsbt(psbt=psbt, descriptors=[descriptor], sighashtype="ALL", bip32derivs=False, finalize=True)
1236          decoded = self.nodes[2].decodepsbt(processed_psbt['psbt'])
1237          test_psbt_input_keys(decoded['inputs'][0], ['witness_utxo', 'non_witness_utxo', 'final_scriptwitness'])
1238  
1239          # Test psbt is complete
1240          assert_equal(processed_psbt['complete'], True)
1241  
1242          # Broadcast transaction
1243          self.nodes[2].sendrawtransaction(processed_psbt['hex'])
1244  
1245          self.log.info("Test descriptorprocesspsbt raises if an invalid sighashtype is passed")
1246          assert_raises_rpc_error(-8, "'all' is not a valid sighash parameter.", self.nodes[2].descriptorprocesspsbt, psbt, [descriptor], sighashtype="all")
1247  
1248          if not self.options.usecli:
1249              self.test_sighash_mismatch()
1250          self.test_sighash_adding()
1251          self.test_psbt_named_parameter_handling()
1252  
1253  if __name__ == '__main__':
1254      PSBTTest(__file__).main()