rpc_psbt.py raw

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