aboutsummaryrefslogtreecommitdiff
path: root/test/functional/wallet_send.py
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/wallet_send.py')
-rwxr-xr-xtest/functional/wallet_send.py55
1 files changed, 50 insertions, 5 deletions
diff --git a/test/functional/wallet_send.py b/test/functional/wallet_send.py
index d24d1693af..c9daeabeb9 100755
--- a/test/functional/wallet_send.py
+++ b/test/functional/wallet_send.py
@@ -9,6 +9,7 @@ from itertools import product
from test_framework.authproxy import JSONRPCException
from test_framework.descriptors import descsum_create
+from test_framework.key import ECKey
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
@@ -16,6 +17,7 @@ from test_framework.util import (
assert_greater_than,
assert_raises_rpc_error,
)
+from test_framework.wallet_util import bytes_to_wif
class WalletSendTest(BitcoinTestFramework):
def set_test_params(self):
@@ -35,7 +37,7 @@ class WalletSendTest(BitcoinTestFramework):
conf_target=None, estimate_mode=None, fee_rate=None, add_to_wallet=None, psbt=None,
inputs=None, add_inputs=None, include_unsafe=None, change_address=None, change_position=None, change_type=None,
include_watching=None, locktime=None, lock_unspents=None, replaceable=None, subtract_fee_from_outputs=None,
- expect_error=None):
+ expect_error=None, solving_data=None):
assert (amount is None) != (data is None)
from_balance_before = from_wallet.getbalances()["mine"]["trusted"]
@@ -94,6 +96,8 @@ class WalletSendTest(BitcoinTestFramework):
options["replaceable"] = replaceable
if subtract_fee_from_outputs is not None:
options["subtract_fee_from_outputs"] = subtract_fee_from_outputs
+ if solving_data is not None:
+ options["solving_data"] = solving_data
if len(options.keys()) == 0:
options = None
@@ -241,7 +245,7 @@ class WalletSendTest(BitcoinTestFramework):
assert_equal(res, [{"success": True}, {"success": True}])
w0.sendtoaddress(a2_receive, 10) # fund w3
- self.nodes[0].generate(1)
+ self.generate(self.nodes[0], 1)
self.sync_blocks()
if not self.options.descriptors:
@@ -260,7 +264,7 @@ class WalletSendTest(BitcoinTestFramework):
assert_equal(res, [{"success": True}])
w0.sendtoaddress(a2_receive, 10) # fund w4
- self.nodes[0].generate(1)
+ self.generate(self.nodes[0], 1)
self.sync_blocks()
self.log.info("Send to address...")
@@ -435,14 +439,14 @@ class WalletSendTest(BitcoinTestFramework):
assert not res[0]["allowed"]
assert_equal(res[0]["reject-reason"], "non-final")
# It shouldn't be confirmed in the next block
- self.nodes[0].generate(1)
+ self.generate(self.nodes[0], 1)
assert_equal(self.nodes[0].gettransaction(txid)["confirmations"], 0)
# The mempool should allow it now:
res = self.nodes[0].testmempoolaccept([hex])
assert res[0]["allowed"]
# Don't wait for wallet to add it to the mempool:
res = self.nodes[0].sendrawtransaction(hex)
- self.nodes[0].generate(1)
+ self.generate(self.nodes[0], 1)
assert_equal(self.nodes[0].gettransaction(txid)["confirmations"], 1)
self.sync_all()
@@ -476,6 +480,47 @@ class WalletSendTest(BitcoinTestFramework):
res = self.test_send(from_wallet=w5, to_wallet=w0, amount=1, include_unsafe=True)
assert res["complete"]
+ self.log.info("External outputs")
+ eckey = ECKey()
+ eckey.generate()
+ privkey = bytes_to_wif(eckey.get_bytes())
+
+ self.nodes[1].createwallet("extsend")
+ ext_wallet = self.nodes[1].get_wallet_rpc("extsend")
+ self.nodes[1].createwallet("extfund")
+ ext_fund = self.nodes[1].get_wallet_rpc("extfund")
+
+ # Make a weird but signable script. sh(pkh()) descriptor accomplishes this
+ desc = descsum_create("sh(pkh({}))".format(privkey))
+ if self.options.descriptors:
+ res = ext_fund.importdescriptors([{"desc": desc, "timestamp": "now"}])
+ else:
+ res = ext_fund.importmulti([{"desc": desc, "timestamp": "now"}])
+ assert res[0]["success"]
+ addr = self.nodes[0].deriveaddresses(desc)[0]
+ addr_info = ext_fund.getaddressinfo(addr)
+
+ self.nodes[0].sendtoaddress(addr, 10)
+ self.nodes[0].sendtoaddress(ext_wallet.getnewaddress(), 10)
+ self.generate(self.nodes[0], 6)
+ self.sync_all()
+ ext_utxo = ext_fund.listunspent(addresses=[addr])[0]
+
+ # An external input without solving data should result in an error
+ self.test_send(from_wallet=ext_wallet, to_wallet=self.nodes[0], amount=15, inputs=[ext_utxo], add_inputs=True, psbt=True, include_watching=True, expect_error=(-4, "Insufficient funds"))
+
+ # But funding should work when the solving data is provided
+ res = self.test_send(from_wallet=ext_wallet, to_wallet=self.nodes[0], amount=15, inputs=[ext_utxo], add_inputs=True, psbt=True, include_watching=True, solving_data={"pubkeys": [addr_info['pubkey']], "scripts": [addr_info["embedded"]["scriptPubKey"]]})
+ signed = ext_wallet.walletprocesspsbt(res["psbt"])
+ signed = ext_fund.walletprocesspsbt(res["psbt"])
+ assert signed["complete"]
+ self.nodes[0].finalizepsbt(signed["psbt"])
+
+ res = self.test_send(from_wallet=ext_wallet, to_wallet=self.nodes[0], amount=15, inputs=[ext_utxo], add_inputs=True, psbt=True, include_watching=True, solving_data={"descriptors": [desc]})
+ signed = ext_wallet.walletprocesspsbt(res["psbt"])
+ signed = ext_fund.walletprocesspsbt(res["psbt"])
+ assert signed["complete"]
+ self.nodes[0].finalizepsbt(signed["psbt"])
if __name__ == '__main__':
WalletSendTest().main()