Skip to content

Commit 7710a31

Browse files
committed
Merge bitcoin/bitcoin#32452: test: Remove legacy wallet RPC overloads
b104d44 test: Remove RPCOverloadWrapper (Ava Chow) 4d32c19 test: Replace importpubkey (Ava Chow) fe838dd test: Replace usage of addmultisigaddress (Ava Chow) d314207 test: Replace usage of importaddress (Ava Chow) fcc4575 test: Replace importprivkey with wallet_importprivkey (Ava Chow) 94c87bb test: Remove unnecessary importprivkey from wallet_createwallet (Ava Chow) Pull request description: `RPCOverloadWrapper` implemented overloads for legacy wallet only RPCs so that the same function call could be used within tests for both legacy wallets and descriptor wallets. With legacy wallets now removed, there is no need to continue to have these overloads. For `importaddress`, `addmultisigaddress`, and `importpubkey`, the uses of these are converted to `importdescriptors`. For `importprivkey`, a new helper function `wallet_imporprivkey` is introduced that does what the overload did. This is mainly to reduce verbosity as `importprivkey` was more widely used throughout the tests. Some tests that used these RPCs are now also no longer relevant and have been removed. ACKs for top commit: Sjors: ACK b104d44 pablomartin4btc: cr ACK b104d44 rkrux: ACK b104d44 w0xlt: ACK bitcoin/bitcoin@b104d44 Tree-SHA512: ded2f73829e2ce28466d4a9738eb382783ad990daee5d1859dbc4d354e6f8eec0c483ed5ecb1287fe0dd24ac332065b733a30d71b126b841bd7cd49e9a094b6d
2 parents b81e507 + b104d44 commit 7710a31

18 files changed

+106
-136
lines changed

test/functional/rpc_getblockstats.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from test_framework.util import (
1313
assert_equal,
1414
assert_raises_rpc_error,
15+
wallet_importprivkey,
1516
)
1617
import json
1718
import os
@@ -45,7 +46,7 @@ def generate_test_data(self, filename):
4546
self.nodes[0].setmocktime(mocktime)
4647
self.nodes[0].createwallet(wallet_name='test')
4748
privkey = self.nodes[0].get_deterministic_priv_key().key
48-
self.nodes[0].importprivkey(privkey)
49+
wallet_importprivkey(self.nodes[0], privkey, 0)
4950

5051
self.generate(self.nodes[0], COINBASE_MATURITY + 1)
5152

test/functional/rpc_psbt.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
assert_greater_than_or_equal,
4949
assert_raises_rpc_error,
5050
find_vout_for_address,
51+
wallet_importprivkey,
5152
)
5253
from test_framework.wallet_util import (
5354
calculate_input_weight,
@@ -115,7 +116,8 @@ def test_utxo_conversion(self):
115116
# Mine a transaction that credits the offline address
116117
offline_addr = offline_node.getnewaddress(address_type="bech32m")
117118
online_addr = w2.getnewaddress(address_type="bech32m")
118-
wonline.importaddress(offline_addr, label="", rescan=False)
119+
import_res = wonline.importdescriptors([{"desc": offline_node.getaddressinfo(offline_addr)["desc"], "timestamp": "now"}])
120+
assert_equal(import_res[0]["success"], True)
119121
mining_wallet = mining_node.get_wallet_rpc(self.default_wallet_name)
120122
mining_wallet.sendtoaddress(address=offline_addr, amount=1.0)
121123
self.generate(mining_node, nblocks=1, sync_fun=lambda: self.sync_all([online_node, mining_node]))
@@ -385,9 +387,19 @@ def run_test(self):
385387
wmulti = self.nodes[2].get_wallet_rpc('wmulti')
386388

387389
# Create all the addresses
388-
p2sh = wmulti.addmultisigaddress(2, [pubkey0, pubkey1, pubkey2], label="", address_type="legacy")["address"]
389-
p2wsh = wmulti.addmultisigaddress(2, [pubkey0, pubkey1, pubkey2], label="", address_type="bech32")["address"]
390-
p2sh_p2wsh = wmulti.addmultisigaddress(2, [pubkey0, pubkey1, pubkey2], label="", address_type="p2sh-segwit")["address"]
390+
p2sh_ms = wmulti.createmultisig(2, [pubkey0, pubkey1, pubkey2], address_type="legacy")
391+
p2sh = p2sh_ms["address"]
392+
p2wsh_ms = wmulti.createmultisig(2, [pubkey0, pubkey1, pubkey2], address_type="bech32")
393+
p2wsh = p2wsh_ms["address"]
394+
p2sh_p2wsh_ms = wmulti.createmultisig(2, [pubkey0, pubkey1, pubkey2], address_type="p2sh-segwit")
395+
p2sh_p2wsh = p2sh_p2wsh_ms["address"]
396+
import_res = wmulti.importdescriptors(
397+
[
398+
{"desc": p2sh_ms["descriptor"], "timestamp": "now"},
399+
{"desc": p2wsh_ms["descriptor"], "timestamp": "now"},
400+
{"desc": p2sh_p2wsh_ms["descriptor"], "timestamp": "now"},
401+
])
402+
assert_equal(all([r["success"] for r in import_res]), True)
391403
p2wpkh = self.nodes[1].getnewaddress("", "bech32")
392404
p2pkh = self.nodes[1].getnewaddress("", "legacy")
393405
p2sh_p2wpkh = self.nodes[1].getnewaddress("", "p2sh-segwit")
@@ -695,7 +707,7 @@ def run_test(self):
695707
self.nodes[2].createwallet(wallet_name="wallet{}".format(i))
696708
wrpc = self.nodes[2].get_wallet_rpc("wallet{}".format(i))
697709
for key in signer['privkeys']:
698-
wrpc.importprivkey(key)
710+
wallet_importprivkey(wrpc, key, "now")
699711
signed_tx = wrpc.walletprocesspsbt(signer['psbt'], True, "ALL")['psbt']
700712
assert_equal(signed_tx, signer['result'])
701713

@@ -951,7 +963,7 @@ def test_psbt_input_keys(psbt_input, keys):
951963
addr = self.nodes[0].deriveaddresses(desc)[0]
952964
self.nodes[0].sendtoaddress(addr, 10)
953965
self.generate(self.nodes[0], 1)
954-
self.nodes[0].importprivkey(privkey)
966+
wallet_importprivkey(self.nodes[0], privkey, "now")
955967

956968
psbt = watchonly.sendall([wallet.getnewaddress()])["psbt"]
957969
signed_tx = self.nodes[0].walletprocesspsbt(psbt)

test/functional/test_framework/test_framework.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
initialize_datadir,
3636
p2p_port,
3737
wait_until_helper_internal,
38+
wallet_importprivkey,
3839
)
3940

4041

@@ -485,7 +486,7 @@ def init_wallet(self, *, node):
485486
n = self.nodes[node]
486487
if wallet_name is not None:
487488
n.createwallet(wallet_name=wallet_name, load_on_startup=True)
488-
n.importprivkey(privkey=n.get_deterministic_priv_key().key, label='coinbase', rescan=True)
489+
wallet_importprivkey(n.get_wallet_rpc(wallet_name), n.get_deterministic_priv_key().key, 0, label="coinbase")
489490

490491
def run_test(self):
491492
"""Tests must override this method to define test logic"""

test/functional/test_framework/test_node.py

Lines changed: 4 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
JSONRPCException,
2727
serialization_fallback,
2828
)
29-
from .descriptors import descsum_create
3029
from .messages import NODE_P2P_V2
3130
from .p2p import P2P_SERVICES, P2P_SUBVERSION
3231
from .util import (
@@ -208,10 +207,10 @@ def __del__(self):
208207
def __getattr__(self, name):
209208
"""Dispatches any unrecognised messages to the RPC connection or a CLI instance."""
210209
if self.use_cli:
211-
return getattr(RPCOverloadWrapper(self.cli), name)
210+
return getattr(self.cli, name)
212211
else:
213212
assert self.rpc_connected and self.rpc is not None, self._node_msg("Error: no RPC connection")
214-
return getattr(RPCOverloadWrapper(self.rpc), name)
213+
return getattr(self.rpc, name)
215214

216215
def start(self, extra_args=None, *, cwd=None, stdout=None, stderr=None, env=None, **kwargs):
217216
"""Start the node."""
@@ -388,11 +387,11 @@ def setmocktime(self, timestamp):
388387

389388
def get_wallet_rpc(self, wallet_name):
390389
if self.use_cli:
391-
return RPCOverloadWrapper(self.cli("-rpcwallet={}".format(wallet_name)))
390+
return self.cli("-rpcwallet={}".format(wallet_name))
392391
else:
393392
assert self.rpc_connected and self.rpc, self._node_msg("RPC not connected")
394393
wallet_path = "wallet/{}".format(urllib.parse.quote(wallet_name))
395-
return RPCOverloadWrapper(self.rpc / wallet_path)
394+
return self.rpc / wallet_path
396395

397396
def version_is_at_least(self, ver):
398397
return self.version is None or self.version >= ver
@@ -937,80 +936,3 @@ def send_cli(self, clicommand=None, *args, **kwargs):
937936
return json.loads(cli_stdout, parse_float=decimal.Decimal)
938937
except (json.JSONDecodeError, decimal.InvalidOperation):
939938
return cli_stdout.rstrip("\n")
940-
941-
class RPCOverloadWrapper():
942-
def __init__(self, rpc):
943-
self.rpc = rpc
944-
945-
def __getattr__(self, name):
946-
return getattr(self.rpc, name)
947-
948-
def importprivkey(self, privkey, *, label=None, rescan=None):
949-
wallet_info = self.getwalletinfo()
950-
if 'descriptors' not in wallet_info or ('descriptors' in wallet_info and not wallet_info['descriptors']):
951-
return self.__getattr__('importprivkey')(privkey, label, rescan)
952-
desc = descsum_create('combo(' + privkey + ')')
953-
req = [{
954-
'desc': desc,
955-
'timestamp': 0 if rescan else 'now',
956-
'label': label if label else '',
957-
}]
958-
import_res = self.importdescriptors(req)
959-
if not import_res[0]['success']:
960-
raise JSONRPCException(import_res[0]['error'])
961-
962-
def addmultisigaddress(self, nrequired, keys, *, label=None, address_type=None):
963-
wallet_info = self.getwalletinfo()
964-
if 'descriptors' not in wallet_info or ('descriptors' in wallet_info and not wallet_info['descriptors']):
965-
return self.__getattr__('addmultisigaddress')(nrequired, keys, label, address_type)
966-
cms = self.createmultisig(nrequired, keys, address_type)
967-
req = [{
968-
'desc': cms['descriptor'],
969-
'timestamp': 0,
970-
'label': label if label else '',
971-
}]
972-
import_res = self.importdescriptors(req)
973-
if not import_res[0]['success']:
974-
raise JSONRPCException(import_res[0]['error'])
975-
return cms
976-
977-
def importpubkey(self, pubkey, *, label=None, rescan=None):
978-
wallet_info = self.getwalletinfo()
979-
if 'descriptors' not in wallet_info or ('descriptors' in wallet_info and not wallet_info['descriptors']):
980-
return self.__getattr__('importpubkey')(pubkey, label, rescan)
981-
desc = descsum_create('combo(' + pubkey + ')')
982-
req = [{
983-
'desc': desc,
984-
'timestamp': 0 if rescan else 'now',
985-
'label': label if label else '',
986-
}]
987-
import_res = self.importdescriptors(req)
988-
if not import_res[0]['success']:
989-
raise JSONRPCException(import_res[0]['error'])
990-
991-
def importaddress(self, address, *, label=None, rescan=None, p2sh=None):
992-
wallet_info = self.getwalletinfo()
993-
if 'descriptors' not in wallet_info or ('descriptors' in wallet_info and not wallet_info['descriptors']):
994-
return self.__getattr__('importaddress')(address, label, rescan, p2sh)
995-
is_hex = False
996-
try:
997-
int(address ,16)
998-
is_hex = True
999-
desc = descsum_create('raw(' + address + ')')
1000-
except Exception:
1001-
desc = descsum_create('addr(' + address + ')')
1002-
reqs = [{
1003-
'desc': desc,
1004-
'timestamp': 0 if rescan else 'now',
1005-
'label': label if label else '',
1006-
}]
1007-
if is_hex and p2sh:
1008-
reqs.append({
1009-
'desc': descsum_create('p2sh(raw(' + address + '))'),
1010-
'timestamp': 0 if rescan else 'now',
1011-
'label': label if label else '',
1012-
})
1013-
import_res = self.importdescriptors(reqs)
1014-
for res in import_res:
1015-
if not res['success']:
1016-
raise JSONRPCException(res['error'])

test/functional/test_framework/util.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
from . import coverage
2222
from .authproxy import AuthServiceProxy, JSONRPCException
23+
from .descriptors import descsum_create
2324
from collections.abc import Callable
2425
from typing import Optional, Union
2526

@@ -608,3 +609,13 @@ def sync_txindex(test_framework, node):
608609
sync_start = int(time.time())
609610
test_framework.wait_until(lambda: node.getindexinfo("txindex")["txindex"]["synced"])
610611
test_framework.log.debug(f"Synced in {time.time() - sync_start} seconds")
612+
613+
def wallet_importprivkey(wallet_rpc, privkey, timestamp, *, label=""):
614+
desc = descsum_create("combo(" + privkey + ")")
615+
req = [{
616+
"desc": desc,
617+
"timestamp": timestamp,
618+
"label": label,
619+
}]
620+
import_res = wallet_rpc.importdescriptors(req)
621+
assert_equal(import_res[0]["success"], True)

test/functional/tool_signet_miner.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
from test_framework.key import ECKey
1515
from test_framework.script_util import key_to_p2wpkh_script
1616
from test_framework.test_framework import BitcoinTestFramework
17-
from test_framework.util import assert_equal
17+
from test_framework.util import (
18+
assert_equal,
19+
wallet_importprivkey,
20+
)
1821
from test_framework.wallet_util import bytes_to_wif
1922

2023

@@ -42,7 +45,7 @@ def skip_test_if_missing_module(self):
4245
def run_test(self):
4346
node = self.nodes[0]
4447
# import private key needed for signing block
45-
node.importprivkey(bytes_to_wif(CHALLENGE_PRIVATE_KEY))
48+
wallet_importprivkey(node, bytes_to_wif(CHALLENGE_PRIVATE_KEY), "now")
4649

4750
# generate block with signet miner tool
4851
base_dir = self.config["environment"]["SRCDIR"]

test/functional/wallet_address_types.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,11 @@ def run_test(self):
260260
else:
261261
address = self.nodes[to_node].getnewaddress(address_type=address_type)
262262
else:
263-
addr1 = self.nodes[to_node].getnewaddress()
264-
addr2 = self.nodes[to_node].getnewaddress()
265-
address = self.nodes[to_node].addmultisigaddress(2, [addr1, addr2])['address']
263+
pubkey1 = self.nodes[to_node].getaddressinfo(self.nodes[to_node].getnewaddress())["pubkey"]
264+
pubkey2 = self.nodes[to_node].getaddressinfo(self.nodes[to_node].getnewaddress())["pubkey"]
265+
ms = self.nodes[to_node].createmultisig(2, [pubkey1, pubkey2])
266+
import_res = self.nodes[to_node].importdescriptors([{"desc": ms["descriptor"], "timestamp": 0}])
267+
assert_equal(import_res[0]["success"], True)
266268

267269
# Do some sanity checking on the created address
268270
if address_type is not None:
@@ -344,7 +346,7 @@ def run_test(self):
344346
self.test_address(3, self.nodes[3].getrawchangeaddress(), multisig=False, typ='bech32')
345347

346348
self.log.info('test invalid address type arguments')
347-
assert_raises_rpc_error(-5, "Unknown address type ''", self.nodes[3].addmultisigaddress, 2, [compressed_1, compressed_2], address_type="")
349+
assert_raises_rpc_error(-5, "Unknown address type ''", self.nodes[3].createmultisig, 2, [compressed_1, compressed_2], address_type="")
348350
assert_raises_rpc_error(-5, "Unknown address type ''", self.nodes[3].getnewaddress, None, '')
349351
assert_raises_rpc_error(-5, "Unknown address type ''", self.nodes[3].getrawchangeaddress, '')
350352
assert_raises_rpc_error(-5, "Unknown address type 'bech23'", self.nodes[3].getrawchangeaddress, 'bech23')

test/functional/wallet_basic.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,8 @@ def test_chain_listunspent(self):
678678
self.generate(self.wallet, 1, sync_fun=self.no_op)
679679
self.nodes[0].createwallet("watch_wallet", disable_private_keys=True)
680680
watch_wallet = self.nodes[0].get_wallet_rpc("watch_wallet")
681-
watch_wallet.importaddress(self.wallet.get_address())
681+
import_res = watch_wallet.importdescriptors([{"desc": self.wallet.get_descriptor(), "timestamp": "now"}])
682+
assert_equal(import_res[0]["success"], True)
682683

683684
# DEFAULT_ANCESTOR_LIMIT transactions off a confirmed tx should be fine
684685
chain = self.wallet.create_self_transfer_chain(chain_length=DEFAULT_ANCESTOR_LIMIT)

test/functional/wallet_createwallet.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
from test_framework.util import (
1111
assert_equal,
1212
assert_raises_rpc_error,
13+
wallet_importprivkey,
1314
)
1415
from test_framework.wallet_util import generate_keypair, WalletUnlock
1516

@@ -41,11 +42,11 @@ def run_test(self):
4142
w1 = node.get_wallet_rpc('w1')
4243
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w1.getnewaddress)
4344
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w1.getrawchangeaddress)
44-
w1.importpubkey(w0.getaddressinfo(address1)['pubkey'])
45+
import_res = w1.importdescriptors([{"desc": w0.getaddressinfo(address1)['desc'], "timestamp": "now"}])
46+
assert_equal(import_res[0]["success"], True)
4547

4648
self.log.info('Test that private keys cannot be imported')
4749
privkey, pubkey = generate_keypair(wif=True)
48-
assert_raises_rpc_error(-4, 'Cannot import private keys to a wallet with private keys disabled', w1.importprivkey, privkey)
4950
result = w1.importdescriptors([{'desc': descsum_create('wpkh(' + privkey + ')'), 'timestamp': 'now'}])
5051
assert not result[0]['success']
5152
assert 'warnings' not in result[0]
@@ -57,7 +58,8 @@ def run_test(self):
5758
w2 = node.get_wallet_rpc('w2')
5859
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w2.getnewaddress)
5960
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w2.getrawchangeaddress)
60-
w2.importpubkey(w0.getaddressinfo(address1)['pubkey'])
61+
import_res = w2.importdescriptors([{"desc": w0.getaddressinfo(address1)['desc'], "timestamp": "now"}])
62+
assert_equal(import_res[0]["success"], True)
6163

6264
self.log.info("Test blank creation with private keys enabled.")
6365
self.nodes[0].createwallet(wallet_name='w3', disable_private_keys=False, blank=True)
@@ -66,7 +68,7 @@ def run_test(self):
6668
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w3.getnewaddress)
6769
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w3.getrawchangeaddress)
6870
# Import private key
69-
w3.importprivkey(generate_keypair(wif=True)[0])
71+
wallet_importprivkey(w3, generate_keypair(wif=True)[0], "now")
7072
# Imported private keys are currently ignored by the keypool
7173
assert_equal(w3.getwalletinfo()['keypoolsize'], 0)
7274
assert_raises_rpc_error(-4, "Error: This wallet has no available keys", w3.getnewaddress)

test/functional/wallet_fundrawtransaction.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -190,9 +190,9 @@ def test_change_position(self):
190190
self.nodes[3].createwallet(wallet_name="wwatch", disable_private_keys=True)
191191
wwatch = self.nodes[3].get_wallet_rpc('wwatch')
192192
watchonly_address = self.nodes[0].getnewaddress()
193-
watchonly_pubkey = self.nodes[0].getaddressinfo(watchonly_address)["pubkey"]
194193
self.watchonly_amount = Decimal(200)
195-
wwatch.importpubkey(watchonly_pubkey, label="", rescan=True)
194+
import_res = wwatch.importdescriptors([{"desc": self.nodes[0].getaddressinfo(watchonly_address)["desc"], "timestamp": "now"}])
195+
assert_equal(import_res[0]["success"], True)
196196
self.watchonly_utxo = self.create_outpoints(self.nodes[0], outputs=[{watchonly_address: self.watchonly_amount}])[0]
197197

198198
# Lock UTXO so nodes[0] doesn't accidentally spend it
@@ -565,16 +565,18 @@ def test_spend_2of2(self):
565565
self.nodes[2].createwallet(wallet_name='wmulti', disable_private_keys=True)
566566
wmulti = self.nodes[2].get_wallet_rpc('wmulti')
567567
w2 = self.nodes[2].get_wallet_rpc(self.default_wallet_name)
568-
mSigObj = wmulti.addmultisigaddress(
568+
mSigObj = self.nodes[2].createmultisig(
569569
2,
570570
[
571571
addr1Obj['pubkey'],
572572
addr2Obj['pubkey'],
573573
]
574-
)['address']
574+
)
575+
import_res = wmulti.importdescriptors([{"desc": mSigObj["descriptor"], "timestamp": "now"}])
576+
assert_equal(import_res[0]["success"], True)
575577

576578
# Send 1.2 BTC to msig addr.
577-
self.nodes[0].sendtoaddress(mSigObj, 1.2)
579+
self.nodes[0].sendtoaddress(mSigObj["address"], 1.2)
578580
self.generate(self.nodes[0], 1)
579581

580582
oldBalance = self.nodes[1].getbalance()

0 commit comments

Comments
 (0)