aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rwxr-xr-xtest/functional/rpc_psbt.py14
-rwxr-xr-xtest/functional/wallet_sendall.py35
2 files changed, 49 insertions, 0 deletions
diff --git a/test/functional/rpc_psbt.py b/test/functional/rpc_psbt.py
index 1fe3b21542..3b78a7d095 100755
--- a/test/functional/rpc_psbt.py
+++ b/test/functional/rpc_psbt.py
@@ -27,8 +27,10 @@ from test_framework.psbt import (
PSBT_IN_SHA256,
PSBT_IN_HASH160,
PSBT_IN_HASH256,
+ PSBT_IN_WITNESS_UTXO,
PSBT_OUT_TAP_TREE,
)
+from test_framework.script import CScript, OP_TRUE
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_approx,
@@ -852,6 +854,18 @@ class PSBTTest(BitcoinTestFramework):
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)
+ self.log.info("Test that PSBT inputs are being checked via script execution")
+ acs_prevout = CTxOut(nValue=0, scriptPubKey=CScript([OP_TRUE]))
+ tx = CTransaction()
+ tx.vin = [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_WITNESS_UTXO]) : acs_prevout.serialize()})]
+ psbt.o = [PSBTMap()]
+ assert_equal(self.nodes[0].finalizepsbt(psbt.to_base64()),
+ {'hex': '0200000001dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd0000000000000000000100000000000000000000000000', 'complete': True})
+
if __name__ == '__main__':
PSBTTest().main()
diff --git a/test/functional/wallet_sendall.py b/test/functional/wallet_sendall.py
index db4f32fe16..4fe11455b1 100755
--- a/test/functional/wallet_sendall.py
+++ b/test/functional/wallet_sendall.py
@@ -221,6 +221,11 @@ class SendallTest(BitcoinTestFramework):
self.add_utxos([16, 5])
spent_utxo = self.wallet.listunspent()[0]
+ # fails on out of bounds vout
+ assert_raises_rpc_error(-8,
+ "Input not found. UTXO ({}:{}) is not part of wallet.".format(spent_utxo["txid"], 1000),
+ self.wallet.sendall, recipients=[self.remainder_target], options={"inputs": [{"txid": spent_utxo["txid"], "vout": 1000}]})
+
# fails on unconfirmed spent UTXO
self.wallet.sendall(recipients=[self.remainder_target])
assert_raises_rpc_error(-8,
@@ -276,6 +281,33 @@ class SendallTest(BitcoinTestFramework):
recipients=[self.remainder_target],
fee_rate=100000)
+ @cleanup
+ def sendall_watchonly_specific_inputs(self):
+ self.log.info("Test sendall with a subset of UTXO pool in a watchonly wallet")
+ self.add_utxos([17, 4])
+ utxo = self.wallet.listunspent()[0]
+
+ self.nodes[0].createwallet(wallet_name="watching", disable_private_keys=True)
+ watchonly = self.nodes[0].get_wallet_rpc("watching")
+
+ import_req = [{
+ "desc": utxo["desc"],
+ "timestamp": 0,
+ }]
+ if self.options.descriptors:
+ watchonly.importdescriptors(import_req)
+ else:
+ watchonly.importmulti(import_req)
+
+ sendall_tx_receipt = watchonly.sendall(recipients=[self.remainder_target], options={"inputs": [utxo]})
+ psbt = sendall_tx_receipt["psbt"]
+ decoded = self.nodes[0].decodepsbt(psbt)
+ assert_equal(len(decoded["inputs"]), 1)
+ assert_equal(len(decoded["outputs"]), 1)
+ assert_equal(decoded["tx"]["vin"][0]["txid"], utxo["txid"])
+ assert_equal(decoded["tx"]["vin"][0]["vout"], utxo["vout"])
+ assert_equal(decoded["tx"]["vout"][0]["scriptPubKey"]["address"], self.remainder_target)
+
# This tests needs to be the last one otherwise @cleanup will fail with "Transaction too large" error
def sendall_fails_with_transaction_too_large(self):
self.log.info("Test that sendall fails if resulting transaction is too large")
@@ -341,6 +373,9 @@ class SendallTest(BitcoinTestFramework):
# Sendall fails when providing a fee that is too high
self.sendall_fails_on_high_fee()
+ # Sendall succeeds with watchonly wallets spending specific UTXOs
+ self.sendall_watchonly_specific_inputs()
+
# Sendall fails when many inputs result to too large transaction
self.sendall_fails_with_transaction_too_large()