Skip to content

Commit c0311b1

Browse files
committed
Merge bitcoin/bitcoin#27349: test: use address_to_scriptpubkey instead of RPC call
e47ce42 refactor: use address_to_scriptpubkey to retrieve addresses scriptpubkey (ismaelsadeeq) 4142d19 refactor: move address_to_scriptpubkey to address.py (ismaelsadeeq) Pull request description: PR #27269 enables the function address_to_scriptpubkey() to decode all address types and return their corresponding scriptpubkeys. As a result, there is no longer any need to call getaddressinfo or validateaddress RPCs in order to retrieve an address scriptpubkey, as explained in the comments on this pull request (see bitcoin/bitcoin#27269 (review) and bitcoin/bitcoin#27269 (comment)). Instead of using RPC calls, this update replaces the process of obtaining an address scriptPubkey with the address_to_scriptpubkey method, resulting in improved performance for functional tests. ACKs for top commit: josibake: re-ACK bitcoin/bitcoin@e47ce42 theStack: ACK e47ce42 🌱 Tree-SHA512: 05285349a7d5ce7097b8f2582e573a5135c6deef85ea9936f68f6ce94e9ebb1d84d94f7fc7e5ed833a698e01585addd80deb52e6338f8aee985bf14db45417d2
2 parents 6882828 + e47ce42 commit c0311b1

10 files changed

+38
-29
lines changed

test/functional/feature_nulldummy.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"""
1515
import time
1616

17+
from test_framework.address import address_to_scriptpubkey
1718
from test_framework.blocktools import (
1819
COINBASE_MATURITY,
1920
NORMAL_GBT_REQUEST_PARAMS,
@@ -77,7 +78,7 @@ def run_test(self):
7778
cms = self.nodes[0].createmultisig(1, [self.pubkey])
7879
wms = self.nodes[0].createmultisig(1, [self.pubkey], 'p2sh-segwit')
7980
self.ms_address = cms["address"]
80-
ms_unlock_details = {"scriptPubKey": self.nodes[0].validateaddress(self.ms_address)["scriptPubKey"],
81+
ms_unlock_details = {"scriptPubKey": address_to_scriptpubkey(self.ms_address).hex(),
8182
"redeemScript": cms["redeemScript"]}
8283
self.wit_ms_address = wms['address']
8384

test/functional/rpc_createmultisig.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import json
99
import os
1010

11+
from test_framework.address import address_to_scriptpubkey
1112
from test_framework.blocktools import COINBASE_MATURITY
1213
from test_framework.authproxy import JSONRPCException
1314
from test_framework.descriptors import descsum_create, drop_origins
@@ -193,7 +194,7 @@ def do_multisig(self):
193194
assert mredeemw == mredeem
194195
wmulti.unloadwallet()
195196

196-
spk = bytes.fromhex(node0.validateaddress(madd)["scriptPubKey"])
197+
spk = address_to_scriptpubkey(madd)
197198
txid, _ = self.wallet.send_to(from_node=self.nodes[0], scriptPubKey=spk, amount=1300)
198199
tx = node0.getrawtransaction(txid, True)
199200
vout = [v["n"] for v in tx["vout"] if madd == v["scriptPubKey"]["address"]]

test/functional/rpc_scanblocks.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Test the scanblocks RPC call."""
6+
from test_framework.address import address_to_scriptpubkey
67
from test_framework.blockfilter import (
78
bip158_basic_element_hash,
89
bip158_relevant_scriptpubkeys,
@@ -36,7 +37,7 @@ def run_test(self):
3637
# send 1.0, mempool only
3738
# childkey 5 of `parent_key`
3839
wallet.send_to(from_node=node,
39-
scriptPubKey=bytes.fromhex(node.validateaddress("mkS4HXoTYWRTescLGaUTGbtTTYX5EjJyEE")['scriptPubKey']),
40+
scriptPubKey=address_to_scriptpubkey("mkS4HXoTYWRTescLGaUTGbtTTYX5EjJyEE"),
4041
amount=1 * COIN)
4142

4243
# mine a block and assure that the mined blockhash is in the filterresult

test/functional/rpc_scantxoutset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Test the scantxoutset rpc call."""
6+
from test_framework.address import address_to_scriptpubkey
67
from test_framework.messages import COIN
78
from test_framework.test_framework import BitcoinTestFramework
89
from test_framework.util import assert_equal, assert_raises_rpc_error
910
from test_framework.wallet import (
1011
MiniWallet,
11-
address_to_scriptpubkey,
1212
getnewdestination,
1313
)
1414

test/functional/rpc_signrawtransactionwithkey.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
COINBASE_MATURITY,
99
)
1010
from test_framework.address import (
11+
address_to_scriptpubkey,
1112
script_to_p2sh,
1213
)
1314
from test_framework.key import ECKey
@@ -118,7 +119,7 @@ def verify_txn_with_witness_script(self, tx_type):
118119
}.get(tx_type, "Invalid tx_type")
119120
redeem_script = script_to_p2wsh_script(witness_script).hex()
120121
addr = script_to_p2sh(redeem_script)
121-
script_pub_key = self.nodes[1].validateaddress(addr)['scriptPubKey']
122+
script_pub_key = address_to_scriptpubkey(addr).hex()
122123
# Fund that address
123124
txid = self.send_to_address(addr, 10)
124125
vout = find_vout_for_address(self.nodes[0], txid, addr)

test/functional/test_framework/address.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,17 @@
2121
taproot_construct,
2222
)
2323
from .util import assert_equal
24+
from test_framework.script_util import (
25+
keyhash_to_p2pkh_script,
26+
program_to_witness_script,
27+
scripthash_to_p2sh_script,
28+
)
2429
from test_framework.segwit_addr import (
2530
decode_segwit_address,
2631
encode_segwit_address,
2732
)
2833

34+
2935
ADDRESS_BCRT1_UNSPENDABLE = 'bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj'
3036
ADDRESS_BCRT1_UNSPENDABLE_DESCRIPTOR = 'addr(bcrt1qqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq3xueyj)#juyq9d97'
3137
# Coins sent to this address can be spent with a witness stack of just OP_TRUE
@@ -172,6 +178,21 @@ def bech32_to_bytes(address):
172178
return version, bytearray(payload)
173179

174180

181+
def address_to_scriptpubkey(address):
182+
"""Converts a given address to the corresponding output script (scriptPubKey)."""
183+
version, payload = bech32_to_bytes(address)
184+
if version is not None:
185+
return program_to_witness_script(version, payload) # testnet segwit scriptpubkey
186+
payload, version = base58_to_byte(address)
187+
if version == 111: # testnet pubkey hash
188+
return keyhash_to_p2pkh_script(payload)
189+
elif version == 196: # testnet script hash
190+
return scripthash_to_p2sh_script(payload)
191+
# TODO: also support other address formats
192+
else:
193+
assert False
194+
195+
175196
class TestFrameworkScript(unittest.TestCase):
176197
def test_base58encodedecode(self):
177198
def check_base58(data, version):

test/functional/test_framework/blocktools.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import unittest
1010

1111
from .address import (
12+
address_to_scriptpubkey,
1213
key_to_p2sh_p2wpkh,
1314
key_to_p2wpkh,
1415
script_to_p2sh_p2wsh,
@@ -205,7 +206,7 @@ def create_witness_tx(node, use_p2wsh, utxo, pubkey, encode_p2sh, amount):
205206
else:
206207
addr = key_to_p2sh_p2wpkh(pubkey) if encode_p2sh else key_to_p2wpkh(pubkey)
207208
if not encode_p2sh:
208-
assert_equal(node.getaddressinfo(addr)['scriptPubKey'], witness_script(use_p2wsh, pubkey))
209+
assert_equal(address_to_scriptpubkey(addr).hex(), witness_script(use_p2wsh, pubkey))
209210
return node.createrawtransaction([utxo], {addr: amount})
210211

211212
def send_to_witness(use_p2wsh, node, utxo, pubkey, encode_p2sh, amount, sign=True, insert_redeem_script=""):

test/functional/test_framework/wallet.py

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@
1313
Optional,
1414
)
1515
from test_framework.address import (
16-
base58_to_byte,
17-
bech32_to_bytes,
16+
address_to_scriptpubkey,
1817
create_deterministic_address_bcrt1_p2tr_op_true,
1918
key_to_p2pkh,
2019
key_to_p2sh_p2wpkh,
@@ -49,9 +48,6 @@
4948
key_to_p2pkh_script,
5049
key_to_p2sh_p2wpkh_script,
5150
key_to_p2wpkh_script,
52-
keyhash_to_p2pkh_script,
53-
program_to_witness_script,
54-
scripthash_to_p2sh_script,
5551
)
5652
from test_framework.util import (
5753
assert_equal,
@@ -101,7 +97,7 @@ def __init__(self, test_node, *, mode=MiniWalletMode.ADDRESS_OP_TRUE):
10197
self._scriptPubKey = key_to_p2pk_script(pub_key.get_bytes())
10298
elif mode == MiniWalletMode.ADDRESS_OP_TRUE:
10399
self._address, self._internal_key = create_deterministic_address_bcrt1_p2tr_op_true()
104-
self._scriptPubKey = bytes.fromhex(self._test_node.validateaddress(self._address)['scriptPubKey'])
100+
self._scriptPubKey = address_to_scriptpubkey(self._address)
105101

106102
# When the pre-mined test framework chain is used, it contains coinbase
107103
# outputs to the MiniWallet's default address in blocks 76-100
@@ -412,18 +408,3 @@ def getnewdestination(address_type='bech32m'):
412408
else:
413409
assert False
414410
return pubkey, scriptpubkey, address
415-
416-
417-
def address_to_scriptpubkey(address):
418-
"""Converts a given address to the corresponding output script (scriptPubKey)."""
419-
version, payload = bech32_to_bytes(address)
420-
if version is not None:
421-
return program_to_witness_script(version, payload) # testnet segwit scriptpubkey
422-
payload, version = base58_to_byte(address)
423-
if version == 111: # testnet pubkey hash
424-
return keyhash_to_p2pkh_script(payload)
425-
elif version == 196: # testnet script hash
426-
return scripthash_to_p2sh_script(payload)
427-
# TODO: also support other address formats
428-
else:
429-
assert False

test/functional/wallet_avoidreuse.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Test the avoid_reuse and setwalletflag features."""
66

7+
from test_framework.address import address_to_scriptpubkey
78
from test_framework.test_framework import BitcoinTestFramework
89
from test_framework.util import (
910
assert_approx,
@@ -257,7 +258,7 @@ def test_sending_from_reused_address_fails(self, second_addr_type):
257258
if not self.options.descriptors:
258259
# For the second send, we transmute it to a related single-key address
259260
# to make sure it's also detected as re-use
260-
fund_spk = self.nodes[0].getaddressinfo(fundaddr)["scriptPubKey"]
261+
fund_spk = address_to_scriptpubkey(fundaddr).hex()
261262
fund_decoded = self.nodes[0].decodescript(fund_spk)
262263
if second_addr_type == "p2sh-segwit":
263264
new_fundaddr = fund_decoded["segwit"]["p2sh-segwit"]

test/functional/wallet_fast_rescan.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import os
88
from typing import List
99

10+
from test_framework.address import address_to_scriptpubkey
1011
from test_framework.descriptors import descsum_create
1112
from test_framework.test_framework import BitcoinTestFramework
1213
from test_framework.test_node import TestNode
@@ -58,7 +59,7 @@ def run_test(self):
5859
if 'range' in desc_info:
5960
start_range, end_range = desc_info['range']
6061
addr = w.deriveaddresses(desc_info['desc'], [end_range, end_range])[0]
61-
spk = bytes.fromhex(w.getaddressinfo(addr)['scriptPubKey'])
62+
spk = address_to_scriptpubkey(addr)
6263
self.log.info(f"-> range [{start_range},{end_range}], last address {addr}")
6364
else:
6465
spk = bytes.fromhex(fixed_key.p2wpkh_script)

0 commit comments

Comments
 (0)