Skip to content

Commit 0817cc3

Browse files
author
MacroFake
committed
Merge bitcoin/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
2 parents 327b7e9 + 0ee43d1 commit 0817cc3

File tree

3 files changed

+146
-99
lines changed

3 files changed

+146
-99
lines changed
Lines changed: 140 additions & 0 deletions
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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -182,8 +182,9 @@
182182
'rpc_whitelist.py',
183183
'feature_proxy.py',
184184
'feature_syscall_sandbox.py',
185-
'rpc_signrawtransaction.py --legacy-wallet',
186-
'rpc_signrawtransaction.py --descriptors',
185+
'wallet_signrawtransactionwithwallet.py --legacy-wallet',
186+
'wallet_signrawtransactionwithwallet.py --descriptors',
187+
'rpc_signrawtransactionwithkey.py',
187188
'rpc_rawtransaction.py --legacy-wallet',
188189
'wallet_groups.py --legacy-wallet',
189190
'wallet_transactiontime_rescan.py --descriptors',

test/functional/rpc_signrawtransaction.py renamed to test/functional/wallet_signrawtransactionwithwallet.py

Lines changed: 3 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,14 @@
22
# Copyright (c) 2015-2021 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.blocktools import (
88
COINBASE_MATURITY,
99
)
1010
from test_framework.address import (
11-
script_to_p2sh,
1211
script_to_p2wsh,
1312
)
14-
from test_framework.key import ECKey
1513
from test_framework.test_framework import BitcoinTestFramework
1614
from test_framework.util import (
1715
assert_equal,
@@ -29,56 +27,20 @@
2927
OP_DROP,
3028
OP_TRUE,
3129
)
32-
from test_framework.script_util import (
33-
key_to_p2pk_script,
34-
key_to_p2pkh_script,
35-
script_to_p2sh_p2wsh_script,
36-
script_to_p2wsh_script,
37-
)
38-
from test_framework.wallet_util import bytes_to_wif
3930

4031
from decimal import (
4132
Decimal,
4233
getcontext,
4334
)
4435

45-
class SignRawTransactionsTest(BitcoinTestFramework):
36+
class SignRawTransactionWithWalletTest(BitcoinTestFramework):
4637
def set_test_params(self):
4738
self.setup_clean_chain = True
4839
self.num_nodes = 2
4940

5041
def skip_test_if_missing_module(self):
5142
self.skip_if_no_wallet()
5243

53-
def successful_signing_test(self):
54-
"""Create and sign a valid raw transaction with one input.
55-
56-
Expected results:
57-
58-
1) The transaction has a complete set of signatures
59-
2) No script verification error occurred"""
60-
self.log.info("Test valid raw transaction with one input")
61-
privKeys = ['cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N', 'cVKpPfVKSJxKqVpE9awvXNWuLHCa5j5tiE7K6zbUSptFpTEtiFrA']
62-
63-
inputs = [
64-
# Valid pay-to-pubkey scripts
65-
{'txid': '9b907ef1e3c26fc71fe4a4b3580bc75264112f95050014157059c736f0202e71', 'vout': 0,
66-
'scriptPubKey': '76a91460baa0f494b38ce3c940dea67f3804dc52d1fb9488ac'},
67-
{'txid': '83a4f6a6b73660e13ee6cb3c6063fa3759c50c9b7521d0536022961898f4fb02', 'vout': 0,
68-
'scriptPubKey': '76a914669b857c03a5ed269d5d85a1ffac9ed5d663072788ac'},
69-
]
70-
71-
outputs = {'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB': 0.1}
72-
73-
rawTx = self.nodes[0].createrawtransaction(inputs, outputs)
74-
rawTxSigned = self.nodes[0].signrawtransactionwithkey(rawTx, privKeys, inputs)
75-
76-
# 1) The transaction has a complete set of signatures
77-
assert rawTxSigned['complete']
78-
79-
# 2) No script verification error occurred
80-
assert 'errors' not in rawTxSigned
81-
8244
def test_with_lock_outputs(self):
8345
self.log.info("Test correct error reporting when trying to sign a locked output")
8446
self.nodes[0].encryptwallet("password")
@@ -191,60 +153,6 @@ def test_fully_signed_tx(self):
191153
assert_equal(signedtx["hex"], signedtx2["hex"])
192154
self.nodes[0].walletlock()
193155

194-
def witness_script_test(self):
195-
self.log.info("Test signing transaction to P2SH-P2WSH addresses without wallet")
196-
# Create a new P2SH-P2WSH 1-of-1 multisig address:
197-
eckey = ECKey()
198-
eckey.generate()
199-
embedded_privkey = bytes_to_wif(eckey.get_bytes())
200-
embedded_pubkey = eckey.get_pubkey().get_bytes().hex()
201-
p2sh_p2wsh_address = self.nodes[1].createmultisig(1, [embedded_pubkey], "p2sh-segwit")
202-
# send transaction to P2SH-P2WSH 1-of-1 multisig address
203-
self.generate(self.nodes[0], COINBASE_MATURITY + 1)
204-
self.nodes[0].sendtoaddress(p2sh_p2wsh_address["address"], 49.999)
205-
self.generate(self.nodes[0], 1)
206-
# Get the UTXO info from scantxoutset
207-
unspent_output = self.nodes[1].scantxoutset('start', [p2sh_p2wsh_address['descriptor']])['unspents'][0]
208-
spk = script_to_p2sh_p2wsh_script(p2sh_p2wsh_address['redeemScript']).hex()
209-
unspent_output['witnessScript'] = p2sh_p2wsh_address['redeemScript']
210-
unspent_output['redeemScript'] = script_to_p2wsh_script(unspent_output['witnessScript']).hex()
211-
assert_equal(spk, unspent_output['scriptPubKey'])
212-
# Now create and sign a transaction spending that output on node[0], which doesn't know the scripts or keys
213-
spending_tx = self.nodes[0].createrawtransaction([unspent_output], {self.nodes[1].get_wallet_rpc(self.default_wallet_name).getnewaddress(): Decimal("49.998")})
214-
spending_tx_signed = self.nodes[0].signrawtransactionwithkey(spending_tx, [embedded_privkey], [unspent_output])
215-
# Check the signing completed successfully
216-
assert 'complete' in spending_tx_signed
217-
assert_equal(spending_tx_signed['complete'], True)
218-
219-
# Now test with P2PKH and P2PK scripts as the witnessScript
220-
for tx_type in ['P2PKH', 'P2PK']: # these tests are order-independent
221-
self.verify_txn_with_witness_script(tx_type)
222-
223-
def verify_txn_with_witness_script(self, tx_type):
224-
self.log.info("Test with a {} script as the witnessScript".format(tx_type))
225-
eckey = ECKey()
226-
eckey.generate()
227-
embedded_privkey = bytes_to_wif(eckey.get_bytes())
228-
embedded_pubkey = eckey.get_pubkey().get_bytes().hex()
229-
witness_script = {
230-
'P2PKH': key_to_p2pkh_script(embedded_pubkey).hex(),
231-
'P2PK': key_to_p2pk_script(embedded_pubkey).hex()
232-
}.get(tx_type, "Invalid tx_type")
233-
redeem_script = script_to_p2wsh_script(witness_script).hex()
234-
addr = script_to_p2sh(redeem_script)
235-
script_pub_key = self.nodes[1].validateaddress(addr)['scriptPubKey']
236-
# Fund that address
237-
txid = self.nodes[0].sendtoaddress(addr, 10)
238-
vout = find_vout_for_address(self.nodes[0], txid, addr)
239-
self.generate(self.nodes[0], 1)
240-
# Now create and sign a transaction spending that output on node[0], which doesn't know the scripts or keys
241-
spending_tx = self.nodes[0].createrawtransaction([{'txid': txid, 'vout': vout}], {self.nodes[1].getnewaddress(): Decimal("9.999")})
242-
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}])
243-
# Check the signing completed successfully
244-
assert 'complete' in spending_tx_signed
245-
assert_equal(spending_tx_signed['complete'], True)
246-
self.nodes[0].sendrawtransaction(spending_tx_signed['hex'])
247-
248156
def OP_1NEGATE_test(self):
249157
self.log.info("Test OP_1NEGATE (0x4f) satisfies BIP62 minimal push standardness rule")
250158
hex_str = (
@@ -385,9 +293,7 @@ def test_signing_with_missing_prevtx_info(self):
385293
])
386294

387295
def run_test(self):
388-
self.successful_signing_test()
389296
self.script_verification_error_test()
390-
self.witness_script_test()
391297
self.OP_1NEGATE_test()
392298
self.test_with_lock_outputs()
393299
self.test_fully_signed_tx()
@@ -397,4 +303,4 @@ def run_test(self):
397303

398304

399305
if __name__ == '__main__':
400-
SignRawTransactionsTest().main()
306+
SignRawTransactionWithWalletTest().main()

0 commit comments

Comments
 (0)