Skip to content

Commit 861503a

Browse files
MacroFakevijaydasmp
MacroFake
authored andcommitted
Merge bitcoin#25512: test: remove wallet dependency and refactor rpc_signrawtransaction.py
0ee43d1 test: refactor rpc_signrawtransaction.py (Ayush Sharma) Pull request description: `rpc_signrawtransaction.py` currently tests the `signrawtransactionwithkey` and `signrawtransactionwithwallet` RPCs. This PR splits `rpc_signrawtransaction.py` into 1. `rpc_signrawtransactionwithkey.py`: the tests for `signrawtransactionwithkey` are moved here and this test can now be run with the wallet disabled. 2. `wallet_signrawtransactionwithwallet.py`: wallet only tests for `signrawtransactionwithwallet.py` ACKs for top commit: aureleoules: tACK 0ee43d1. Tree-SHA512: c7bd2ea746345c978eae231a781fc52953b9d277eb9f8abb9c3270fe1d9f678f23f3784377d7303a2aa23d7ad90097245e517d386b27b4e0016585dfddcb9d49
1 parent 26ea618 commit 861503a

File tree

3 files changed

+147
-35
lines changed

3 files changed

+147
-35
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2015-2022 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
"""Test transaction signing using the signrawtransactionwithkey RPC."""
6+
7+
from test_framework.blocktools import (
8+
COINBASE_MATURITY,
9+
)
10+
from test_framework.address import (
11+
script_to_p2sh,
12+
)
13+
from test_framework.key import ECKey
14+
from test_framework.test_framework import BitcoinTestFramework
15+
from test_framework.util import (
16+
assert_equal,
17+
find_vout_for_address,
18+
)
19+
from test_framework.script_util import (
20+
key_to_p2pk_script,
21+
key_to_p2pkh_script,
22+
script_to_p2sh_p2wsh_script,
23+
script_to_p2wsh_script,
24+
)
25+
from test_framework.wallet_util import (
26+
bytes_to_wif,
27+
)
28+
29+
from decimal import (
30+
Decimal,
31+
)
32+
from test_framework.wallet import (
33+
getnewdestination,
34+
)
35+
36+
37+
class SignRawTransactionWithKeyTest(BitcoinTestFramework):
38+
def set_test_params(self):
39+
self.setup_clean_chain = True
40+
self.num_nodes = 2
41+
42+
def send_to_address(self, addr, amount):
43+
input = {"txid": self.nodes[0].getblock(self.block_hash[self.blk_idx])["tx"][0], "vout": 0}
44+
output = {addr: amount}
45+
self.blk_idx += 1
46+
rawtx = self.nodes[0].createrawtransaction([input], output)
47+
txid = self.nodes[0].sendrawtransaction(self.nodes[0].signrawtransactionwithkey(rawtx, [self.nodes[0].get_deterministic_priv_key().key])["hex"], 0)
48+
return txid
49+
50+
def successful_signing_test(self):
51+
"""Create and sign a valid raw transaction with one input.
52+
53+
Expected results:
54+
55+
1) The transaction has a complete set of signatures
56+
2) No script verification error occurred"""
57+
self.log.info("Test valid raw transaction with one input")
58+
privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N', 'cVKpPfVKSJxKqVpE9awvXNWuLHCa5j5tiE7K6zbUSptFpTEtiFrA']
59+
60+
inputs = [
61+
# Valid pay-to-pubkey scripts
62+
{'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0,
63+
'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'},
64+
{'txid': '83a4f6a6b73660e13ee6cb3c6063fa3759c50c9b7521d0536022961898f4fb02', 'vout': 0,
65+
'scriptPubKey': '76a914669b857c03a5ed269d5d85a1ffac9ed5d663072788ac'},
66+
]
67+
68+
outputs = {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1}
69+
70+
rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
71+
rawTxSigned = self.nodes[0].signrawtransactionwithkey(rawTx, privKeys, inputs)
72+
73+
# 1) The transaction has a complete set of signatures
74+
assert rawTxSigned['complete']
75+
76+
# 2) No script verification error occurred
77+
assert 'errors' not in rawTxSigned
78+
79+
def witness_script_test(self):
80+
self.log.info("Test signing transaction to P2SH-P2WSH addresses without wallet")
81+
# Create a new P2SH-P2WSH 1-of-1 multisig address:
82+
eckey = ECKey()
83+
eckey.generate()
84+
embedded_privkey = bytes_to_wif(eckey.get_bytes())
85+
embedded_pubkey = eckey.get_pubkey().get_bytes().hex()
86+
p2sh_p2wsh_address = self.nodes[1].createmultisig(1, [embedded_pubkey], "p2sh-segwit")
87+
# send transaction to P2SH-P2WSH 1-of-1 multisig address
88+
self.block_hash = self.generate(self.nodes[0], COINBASE_MATURITY + 1)
89+
self.blk_idx = 0
90+
self.send_to_address(p2sh_p2wsh_address["address"], 49.999)
91+
self.generate(self.nodes[0], 1)
92+
# Get the UTXO info from scantxoutset
93+
unspent_output = self.nodes[1].scantxoutset('start', [p2sh_p2wsh_address['descriptor']])['unspents'][0]
94+
spk = script_to_p2sh_p2wsh_script(p2sh_p2wsh_address['redeemScript']).hex()
95+
unspent_output['witnessScript'] = p2sh_p2wsh_address['redeemScript']
96+
unspent_output['redeemScript'] = script_to_p2wsh_script(unspent_output['witnessScript']).hex()
97+
assert_equal(spk, unspent_output['scriptPubKey'])
98+
# Now create and sign a transaction spending that output on node[0], which doesn't know the scripts or keys
99+
spending_tx = self.nodes[0].createrawtransaction([unspent_output], {getnewdestination()[2]: Decimal("49.998")})
100+
spending_tx_signed = self.nodes[0].signrawtransactionwithkey(spending_tx, [embedded_privkey], [unspent_output])
101+
# Check the signing completed successfully
102+
assert 'complete' in spending_tx_signed
103+
assert_equal(spending_tx_signed['complete'], True)
104+
105+
# Now test with P2PKH and P2PK scripts as the witnessScript
106+
for tx_type in ['P2PKH', 'P2PK']: # these tests are order-independent
107+
self.verify_txn_with_witness_script(tx_type)
108+
109+
def verify_txn_with_witness_script(self, tx_type):
110+
self.log.info("Test with a {} script as the witnessScript".format(tx_type))
111+
eckey = ECKey()
112+
eckey.generate()
113+
embedded_privkey = bytes_to_wif(eckey.get_bytes())
114+
embedded_pubkey = eckey.get_pubkey().get_bytes().hex()
115+
witness_script = {
116+
'P2PKH': key_to_p2pkh_script(embedded_pubkey).hex(),
117+
'P2PK': key_to_p2pk_script(embedded_pubkey).hex()
118+
}.get(tx_type, "Invalid tx_type")
119+
redeem_script = script_to_p2wsh_script(witness_script).hex()
120+
addr = script_to_p2sh(redeem_script)
121+
script_pub_key = self.nodes[1].validateaddress(addr)['scriptPubKey']
122+
# Fund that address
123+
txid = self.send_to_address(addr, 10)
124+
vout = find_vout_for_address(self.nodes[0], txid, addr)
125+
self.generate(self.nodes[0], 1)
126+
# Now create and sign a transaction spending that output on node[0], which doesn't know the scripts or keys
127+
spending_tx = self.nodes[0].createrawtransaction([{'txid': txid, 'vout': vout}], {getnewdestination()[2]: Decimal("9.999")})
128+
spending_tx_signed = self.nodes[0].signrawtransactionwithkey(spending_tx, [embedded_privkey], [{'txid': txid, 'vout': vout, 'scriptPubKey': script_pub_key, 'redeemScript': redeem_script, 'witnessScript': witness_script, 'amount': 10}])
129+
# Check the signing completed successfully
130+
assert 'complete' in spending_tx_signed
131+
assert_equal(spending_tx_signed['complete'], True)
132+
self.nodes[0].sendrawtransaction(spending_tx_signed['hex'])
133+
134+
def run_test(self):
135+
self.successful_signing_test()
136+
self.witness_script_test()
137+
138+
139+
if __name__ == '__main__':
140+
SignRawTransactionWithKeyTest().main()

test/functional/test_runner.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,10 @@
201201
'rpc_users.py',
202202
'rpc_whitelist.py',
203203
'feature_proxy.py',
204-
'rpc_signrawtransaction.py --legacy-wallet',
205-
'rpc_signrawtransaction.py --descriptors',
204+
'feature_syscall_sandbox.py',
205+
'wallet_signrawtransactionwithwallet.py --legacy-wallet',
206+
'wallet_signrawtransactionwithwallet.py --descriptors',
207+
'rpc_signrawtransactionwithkey.py',
206208
'rpc_rawtransaction.py --legacy-wallet',
207209
'rpc_rawtransaction.py --descriptors',
208210
'p2p_addrv2_relay.py',

test/functional/rpc_signrawtransaction.py test/functional/wallet_signrawtransactionwithwallet.py

+3-33
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# Copyright (c) 2015-2020 The Bitcoin Core developers
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5-
"""Test transaction signing using the signrawtransaction* RPCs."""
5+
"""Test transaction signing using the signrawtransactionwithwallet RPC."""
66

77
from test_framework.test_framework import BitcoinTestFramework
88
from test_framework.util import (
@@ -11,43 +11,14 @@
1111
)
1212

1313

14-
class SignRawTransactionsTest(BitcoinTestFramework):
14+
class SignRawTransactionWithWalletTest(BitcoinTestFramework):
1515
def set_test_params(self):
1616
self.setup_clean_chain = True
1717
self.num_nodes = 1
1818

1919
def skip_test_if_missing_module(self):
2020
self.skip_if_no_wallet()
2121

22-
def successful_signing_test(self):
23-
"""Create and sign a valid raw transaction with one input.
24-
25-
Expected results:
26-
27-
1) The transaction has a complete set of signatures
28-
2) No script verification error occurred"""
29-
self.log.info("Test valid raw transaction with one input")
30-
privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N', 'cVKpPfVKSJxKqVpE9awvXNWuLHCa5j5tiE7K6zbUSptFpTEtiFrA']
31-
32-
inputs = [
33-
# Valid pay-to-pubkey scripts
34-
{'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0,
35-
'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'},
36-
{'txid': '83a4f6a6b73660e13ee6cb3c6063fa3759c50c9b7521d0536022961898f4fb02', 'vout': 0,
37-
'scriptPubKey': '76a914669b857c03a5ed269d5d85a1ffac9ed5d663072788ac'},
38-
]
39-
40-
outputs = {'ycwedq2f3sz2Yf9JqZsBCQPxp18WU3Hp4J': 0.1}
41-
42-
rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
43-
rawTxSigned = self.nodes[0].signrawtransactionwithkey(rawTx, privKeys, inputs)
44-
45-
# 1) The transaction has a complete set of signatures
46-
assert rawTxSigned['complete']
47-
48-
# 2) No script verification error occurred
49-
assert 'errors' not in rawTxSigned
50-
5122
def test_with_lock_outputs(self):
5223
self.log.info("Test correct error reporting when trying to sign a locked output")
5324
self.nodes[0].encryptwallet("password")
@@ -122,10 +93,9 @@ def script_verification_error_test(self):
12293
assert_equal(rawTxSigned['errors'][1]['vout'], inputs[2]['vout'])
12394

12495
def run_test(self):
125-
self.successful_signing_test()
12696
self.script_verification_error_test()
12797
self.test_with_lock_outputs()
12898

12999

130100
if __name__ == '__main__':
131-
SignRawTransactionsTest().main()
101+
SignRawTransactionWithWalletTest().main()

0 commit comments

Comments
 (0)