Skip to content

Commit 869f7ab

Browse files
committed
tests: Add RPCOverloadWrapper which overloads some disabled RPCs
RPCOverloadWrapper overloads some deprecated or disabled RPCs with an implementation using other RPCs to avoid having a ton of code churn around replacing those RPCs.
1 parent cf06062 commit 869f7ab

File tree

3 files changed

+125
-24
lines changed

3 files changed

+125
-24
lines changed

test/functional/feature_backwards_compatibility.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def run_test(self):
9494

9595
# w1: regular wallet, created on master: update this test when default
9696
# wallets can no longer be opened by older versions.
97-
node_master.createwallet(wallet_name="w1")
97+
node_master.rpc.createwallet(wallet_name="w1")
9898
wallet = node_master.get_wallet_rpc("w1")
9999
info = wallet.getwalletinfo()
100100
assert info['private_keys_enabled']
@@ -120,17 +120,17 @@ def run_test(self):
120120
self.nodes[1].abandontransaction(tx3_id)
121121

122122
# w1_v19: regular wallet, created with v0.19
123-
node_v19.createwallet(wallet_name="w1_v19")
123+
node_v19.rpc.createwallet(wallet_name="w1_v19")
124124
wallet = node_v19.get_wallet_rpc("w1_v19")
125125
info = wallet.getwalletinfo()
126126
assert info['private_keys_enabled']
127127
assert info['keypoolsize'] > 0
128128
# Use addmultisigaddress (see #18075)
129-
address_18075 = wallet.addmultisigaddress(1, ["0296b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52", "037211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073"], "", "legacy")["address"]
129+
address_18075 = wallet.rpc.addmultisigaddress(1, ["0296b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52", "037211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073"], "", "legacy")["address"]
130130
assert wallet.getaddressinfo(address_18075)["solvable"]
131131

132132
# w1_v18: regular wallet, created with v0.18
133-
node_v18.createwallet(wallet_name="w1_v18")
133+
node_v18.rpc.createwallet(wallet_name="w1_v18")
134134
wallet = node_v18.get_wallet_rpc("w1_v18")
135135
info = wallet.getwalletinfo()
136136
assert info['private_keys_enabled']
@@ -139,43 +139,43 @@ def run_test(self):
139139
# w2: wallet with private keys disabled, created on master: update this
140140
# test when default wallets private keys disabled can no longer be
141141
# opened by older versions.
142-
node_master.createwallet(wallet_name="w2", disable_private_keys=True)
142+
node_master.rpc.createwallet(wallet_name="w2", disable_private_keys=True)
143143
wallet = node_master.get_wallet_rpc("w2")
144144
info = wallet.getwalletinfo()
145145
assert info['private_keys_enabled'] == False
146146
assert info['keypoolsize'] == 0
147147

148148
# w2_v19: wallet with private keys disabled, created with v0.19
149-
node_v19.createwallet(wallet_name="w2_v19", disable_private_keys=True)
149+
node_v19.rpc.createwallet(wallet_name="w2_v19", disable_private_keys=True)
150150
wallet = node_v19.get_wallet_rpc("w2_v19")
151151
info = wallet.getwalletinfo()
152152
assert info['private_keys_enabled'] == False
153153
assert info['keypoolsize'] == 0
154154

155155
# w2_v18: wallet with private keys disabled, created with v0.18
156-
node_v18.createwallet(wallet_name="w2_v18", disable_private_keys=True)
156+
node_v18.rpc.createwallet(wallet_name="w2_v18", disable_private_keys=True)
157157
wallet = node_v18.get_wallet_rpc("w2_v18")
158158
info = wallet.getwalletinfo()
159159
assert info['private_keys_enabled'] == False
160160
assert info['keypoolsize'] == 0
161161

162162
# w3: blank wallet, created on master: update this
163163
# test when default blank wallets can no longer be opened by older versions.
164-
node_master.createwallet(wallet_name="w3", blank=True)
164+
node_master.rpc.createwallet(wallet_name="w3", blank=True)
165165
wallet = node_master.get_wallet_rpc("w3")
166166
info = wallet.getwalletinfo()
167167
assert info['private_keys_enabled']
168168
assert info['keypoolsize'] == 0
169169

170170
# w3_v19: blank wallet, created with v0.19
171-
node_v19.createwallet(wallet_name="w3_v19", blank=True)
171+
node_v19.rpc.createwallet(wallet_name="w3_v19", blank=True)
172172
wallet = node_v19.get_wallet_rpc("w3_v19")
173173
info = wallet.getwalletinfo()
174174
assert info['private_keys_enabled']
175175
assert info['keypoolsize'] == 0
176176

177177
# w3_v18: blank wallet, created with v0.18
178-
node_v18.createwallet(wallet_name="w3_v18", blank=True)
178+
node_v18.rpc.createwallet(wallet_name="w3_v18", blank=True)
179179
wallet = node_v18.get_wallet_rpc("w3_v18")
180180
info = wallet.getwalletinfo()
181181
assert info['private_keys_enabled']
@@ -318,7 +318,7 @@ def run_test(self):
318318

319319
self.log.info("Test wallet upgrade path...")
320320
# u1: regular wallet, created with v0.17
321-
node_v17.createwallet(wallet_name="u1_v17")
321+
node_v17.rpc.createwallet(wallet_name="u1_v17")
322322
wallet = node_v17.get_wallet_rpc("u1_v17")
323323
address = wallet.getnewaddress("bech32")
324324
info = wallet.getaddressinfo(address)

test/functional/test_framework/test_node.py

Lines changed: 105 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import sys
2323

2424
from .authproxy import JSONRPCException
25+
from .descriptors import descsum_create
2526
from .util import (
2627
MAX_NODES,
2728
append_config,
@@ -170,10 +171,10 @@ def __del__(self):
170171
def __getattr__(self, name):
171172
"""Dispatches any unrecognised messages to the RPC connection or a CLI instance."""
172173
if self.use_cli:
173-
return getattr(self.cli, name)
174+
return getattr(RPCOverloadWrapper(self.cli, True), name)
174175
else:
175176
assert self.rpc_connected and self.rpc is not None, self._node_msg("Error: no RPC connection")
176-
return getattr(self.rpc, name)
177+
return getattr(RPCOverloadWrapper(self.rpc), name)
177178

178179
def start(self, extra_args=None, *, cwd=None, stdout=None, stderr=None, **kwargs):
179180
"""Start the node."""
@@ -265,11 +266,11 @@ def generate(self, nblocks, maxtries=1000000):
265266

266267
def get_wallet_rpc(self, wallet_name):
267268
if self.use_cli:
268-
return self.cli("-rpcwallet={}".format(wallet_name))
269+
return RPCOverloadWrapper(self.cli("-rpcwallet={}".format(wallet_name)), True)
269270
else:
270271
assert self.rpc_connected and self.rpc, self._node_msg("RPC not connected")
271272
wallet_path = "wallet/{}".format(urllib.parse.quote(wallet_name))
272-
return self.rpc / wallet_path
273+
return RPCOverloadWrapper(self.rpc / wallet_path)
273274

274275
def stop_node(self, expected_stderr='', wait=0):
275276
"""Stop the node."""
@@ -595,3 +596,103 @@ def send_cli(self, command=None, *args, **kwargs):
595596
return json.loads(cli_stdout, parse_float=decimal.Decimal)
596597
except json.JSONDecodeError:
597598
return cli_stdout.rstrip("\n")
599+
600+
class RPCOverloadWrapper():
601+
def __init__(self, rpc, cli=False):
602+
self.rpc = rpc
603+
self.is_cli = cli
604+
605+
def __getattr__(self, name):
606+
return getattr(self.rpc, name)
607+
608+
def importprivkey(self, privkey, label=None, rescan=None):
609+
wallet_info = self.getwalletinfo()
610+
if self.is_cli:
611+
if label is None:
612+
label = 'null'
613+
if rescan is None:
614+
rescan = 'null'
615+
if 'descriptors' not in wallet_info or ('descriptors' in wallet_info and not wallet_info['descriptors']):
616+
return self.__getattr__('importprivkey')(privkey, label, rescan)
617+
desc = descsum_create('combo(' + privkey + ')')
618+
req = [{
619+
'desc': desc,
620+
'timestamp': 0 if rescan else 'now',
621+
'label': label if label else ''
622+
}]
623+
import_res = self.importdescriptors(req)
624+
if not import_res[0]['success']:
625+
raise JSONRPCException(import_res[0]['error'])
626+
627+
def addmultisigaddress(self, nrequired, keys, label=None, address_type=None):
628+
wallet_info = self.getwalletinfo()
629+
if self.is_cli:
630+
if label is None:
631+
label = 'null'
632+
if address_type is None:
633+
address_type = 'null'
634+
if 'descriptors' not in wallet_info or ('descriptors' in wallet_info and not wallet_info['descriptors']):
635+
return self.__getattr__('addmultisigaddress')(nrequired, keys, label, address_type)
636+
cms = self.createmultisig(nrequired, keys, address_type)
637+
req = [{
638+
'desc': cms['descriptor'],
639+
'timestamp': 0,
640+
'label': label if label else ''
641+
}]
642+
import_res = self.importdescriptors(req)
643+
if not import_res[0]['success']:
644+
raise JSONRPCException(import_res[0]['error'])
645+
return cms
646+
647+
def importpubkey(self, pubkey, label=None, rescan=None):
648+
wallet_info = self.getwalletinfo()
649+
if self.is_cli:
650+
if label is None:
651+
label = 'null'
652+
if rescan is None:
653+
rescan = 'null'
654+
if 'descriptors' not in wallet_info or ('descriptors' in wallet_info and not wallet_info['descriptors']):
655+
return self.__getattr__('importpubkey')(pubkey, label, rescan)
656+
desc = descsum_create('combo(' + pubkey + ')')
657+
req = [{
658+
'desc': desc,
659+
'timestamp': 0 if rescan else 'now',
660+
'label': label if label else ''
661+
}]
662+
import_res = self.importdescriptors(req)
663+
if not import_res[0]['success']:
664+
raise JSONRPCException(import_res[0]['error'])
665+
666+
def importaddress(self, address, label=None, rescan=None, p2sh=None):
667+
wallet_info = self.getwalletinfo()
668+
if self.is_cli:
669+
if label is None:
670+
label = 'null'
671+
if rescan is None:
672+
rescan = 'null'
673+
if p2sh is None:
674+
p2sh = 'null'
675+
if 'descriptors' not in wallet_info or ('descriptors' in wallet_info and not wallet_info['descriptors']):
676+
return self.__getattr__('importaddress')(address, label, rescan, p2sh)
677+
is_hex = False
678+
try:
679+
int(address ,16)
680+
is_hex = True
681+
desc = descsum_create('raw(' + address + ')')
682+
except:
683+
desc = descsum_create('addr(' + address + ')')
684+
reqs = [{
685+
'desc': desc,
686+
'timestamp': 0 if rescan else 'now',
687+
'label': label if label else ''
688+
}]
689+
if is_hex and p2sh:
690+
reqs.append({
691+
'desc': descsum_create('p2sh(raw(' + address + '))'),
692+
'timestamp': 0 if rescan else 'now',
693+
'label': label if label else ''
694+
})
695+
import_res = self.importdescriptors(reqs)
696+
for res in import_res:
697+
if not res['success']:
698+
raise JSONRPCException(res['error'])

test/functional/wallet_descriptor.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,15 @@ def run_test(self):
8181

8282
# Make sure things are disabled
8383
self.log.info("Test disabled RPCs")
84-
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.importprivkey, "cVpF924EspNh8KjYsfhgY96mmxvT6DgdWiTYMtMjuM74hJaU5psW")
85-
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.importpubkey, send_wrpc.getaddressinfo(send_wrpc.getnewaddress()))
86-
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.importaddress, recv_wrpc.getnewaddress())
87-
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.importmulti, [])
88-
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.addmultisigaddress, 1, [recv_wrpc.getnewaddress()])
89-
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.dumpprivkey, recv_wrpc.getnewaddress())
90-
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.dumpwallet, 'wallet.dump')
91-
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.importwallet, 'wallet.dump')
92-
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.sethdseed)
84+
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.rpc.importprivkey, "cVpF924EspNh8KjYsfhgY96mmxvT6DgdWiTYMtMjuM74hJaU5psW")
85+
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.rpc.importpubkey, send_wrpc.getaddressinfo(send_wrpc.getnewaddress()))
86+
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.rpc.importaddress, recv_wrpc.getnewaddress())
87+
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.rpc.importmulti, [])
88+
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.rpc.addmultisigaddress, 1, [recv_wrpc.getnewaddress()])
89+
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.rpc.dumpprivkey, recv_wrpc.getnewaddress())
90+
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.rpc.dumpwallet, 'wallet.dump')
91+
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.rpc.importwallet, 'wallet.dump')
92+
assert_raises_rpc_error(-4, "This type of wallet does not support this command", recv_wrpc.rpc.sethdseed)
9393

9494
self.log.info("Test encryption")
9595
# Get the master fingerprint before encrypt

0 commit comments

Comments
 (0)