aboutsummaryrefslogtreecommitdiff
path: root/test/functional/rpc_psbt.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/rpc_psbt.py')
-rwxr-xr-xtest/functional/rpc_psbt.py67
1 files changed, 67 insertions, 0 deletions
diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py
index 264b2ac32d..23a581469e 100755
--- a/test/functional/rpc_psbt.py
+++ b/test/functional/rpc_psbt.py
@@ -11,10 +11,23 @@ from itertools import product
from test_framework.descriptors import descsum_create
from test_framework.key import ECKey, H_POINT
from test_framework.messages import (
+ COutPoint,
+ CTransaction,
+ CTxIn,
+ CTxOut,
MAX_BIP125_RBF_SEQUENCE,
WITNESS_SCALE_FACTOR,
ser_compact_size,
)
+from test_framework.psbt import (
+ PSBT,
+ PSBTMap,
+ PSBT_GLOBAL_UNSIGNED_TX,
+ PSBT_IN_RIPEMD160,
+ PSBT_IN_SHA256,
+ PSBT_IN_HASH160,
+ PSBT_IN_HASH256,
+)
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_approx,
@@ -22,6 +35,8 @@ from test_framework.util import (
assert_greater_than,
assert_raises_rpc_error,
find_output,
+ find_vout_for_address,
+ random_bytes,
)
from test_framework.wallet_util import bytes_to_wif
@@ -764,5 +779,57 @@ class PSBTTest(BitcoinTestFramework):
psbt = self.nodes[0].walletprocesspsbt(psbt)["psbt"]
self.nodes[0].sendrawtransaction(self.nodes[0].finalizepsbt(psbt)["hex"])
+ self.log.info("Test that walletprocesspsbt both updates and signs a non-updated psbt containing Taproot inputs")
+ addr = self.nodes[0].getnewaddress("", "bech32m")
+ txid = self.nodes[0].sendtoaddress(addr, 1)
+ vout = find_vout_for_address(self.nodes[0], txid, addr)
+ psbt = self.nodes[0].createpsbt([{"txid": txid, "vout": vout}], [{self.nodes[0].getnewaddress(): 0.9999}])
+ signed = self.nodes[0].walletprocesspsbt(psbt)
+ rawtx = self.nodes[0].finalizepsbt(signed["psbt"])["hex"]
+ self.nodes[0].sendrawtransaction(rawtx)
+ self.generate(self.nodes[0], 1)
+
+ self.log.info("Test decoding PSBT with per-input preimage types")
+ # note that the decodepsbt RPC doesn't check whether preimages and hashes match
+ hash_ripemd160, preimage_ripemd160 = random_bytes(20), random_bytes(50)
+ hash_sha256, preimage_sha256 = random_bytes(32), random_bytes(50)
+ hash_hash160, preimage_hash160 = random_bytes(20), random_bytes(50)
+ hash_hash256, preimage_hash256 = random_bytes(32), random_bytes(50)
+
+ tx = CTransaction()
+ tx.vin = [CTxIn(outpoint=COutPoint(hash=int('aa' * 32, 16), n=0), scriptSig=b""),
+ CTxIn(outpoint=COutPoint(hash=int('bb' * 32, 16), n=0), scriptSig=b""),
+ CTxIn(outpoint=COutPoint(hash=int('cc' * 32, 16), n=0), scriptSig=b""),
+ CTxIn(outpoint=COutPoint(hash=int('dd' * 32, 16), n=0), scriptSig=b"")]
+ tx.vout = [CTxOut(nValue=0, scriptPubKey=b"")]
+ psbt = PSBT()
+ psbt.g = PSBTMap({PSBT_GLOBAL_UNSIGNED_TX: tx.serialize()})
+ psbt.i = [PSBTMap({bytes([PSBT_IN_RIPEMD160]) + hash_ripemd160: preimage_ripemd160}),
+ PSBTMap({bytes([PSBT_IN_SHA256]) + hash_sha256: preimage_sha256}),
+ PSBTMap({bytes([PSBT_IN_HASH160]) + hash_hash160: preimage_hash160}),
+ PSBTMap({bytes([PSBT_IN_HASH256]) + hash_hash256: preimage_hash256})]
+ psbt.o = [PSBTMap()]
+ res_inputs = self.nodes[0].decodepsbt(psbt.to_base64())["inputs"]
+ assert_equal(len(res_inputs), 4)
+ preimage_keys = ["ripemd160_preimages", "sha256_preimages", "hash160_preimages", "hash256_preimages"]
+ expected_hashes = [hash_ripemd160, hash_sha256, hash_hash160, hash_hash256]
+ expected_preimages = [preimage_ripemd160, preimage_sha256, preimage_hash160, preimage_hash256]
+ for res_input, preimage_key, hash, preimage in zip(res_inputs, preimage_keys, expected_hashes, expected_preimages):
+ assert preimage_key in res_input
+ assert_equal(len(res_input[preimage_key]), 1)
+ assert hash.hex() in res_input[preimage_key]
+ assert_equal(res_input[preimage_key][hash.hex()], preimage.hex())
+
+ self.log.info("Test that combining PSBTs with different transactions fails")
+ tx = CTransaction()
+ tx.vin = [CTxIn(outpoint=COutPoint(hash=int('aa' * 32, 16), n=0), scriptSig=b"")]
+ tx.vout = [CTxOut(nValue=0, scriptPubKey=b"")]
+ psbt1 = PSBT(g=PSBTMap({PSBT_GLOBAL_UNSIGNED_TX: tx.serialize()}), i=[PSBTMap()], o=[PSBTMap()]).to_base64()
+ tx.vout[0].nValue += 1 # slightly modify tx
+ psbt2 = PSBT(g=PSBTMap({PSBT_GLOBAL_UNSIGNED_TX: tx.serialize()}), i=[PSBTMap()], o=[PSBTMap()]).to_base64()
+ assert_raises_rpc_error(-8, "PSBTs not compatible (different transactions)", self.nodes[0].combinepsbt, [psbt1, psbt2])
+ assert_equal(self.nodes[0].combinepsbt([psbt1, psbt1]), psbt1)
+
+
if __name__ == '__main__':
PSBTTest().main()