Skip to content

Commit d1d54ae

Browse files
committed
Merge #12953: Deprecate accounts
cead28b [docs] Add release notes for deprecated 'account' API (John Newbery) 72c9575 [wallet] [tests] Add tests for accounts/labels APIs (John Newbery) 109e05d [wallet] [rpc] Deprecate wallet 'account' API (John Newbery) 3576ab1 [wallet] [rpc] Deprecate account RPC methods (John Newbery) 3db1ba0 [tests] Set -deprecatedrpc=accounts in tests (John Newbery) 4e671f0 [tests] Rename rpc_listtransactions.py to wallet_listtransactions.py (John Newbery) a28b907 [wallet] [rpc] Remove duplicate entries in rpcwallet.cpp's CRPCCommand table (John Newbery) Pull request description: Deprecate all accounts functionality and make it only accessible by using `-deprecatedrpc=accounts`. Accounts specific RPCs, account arguments, and account related results all require the `-deprecatedrpc=accunts` startup option now in order to see account things. Several wallet functional tests use the accounts system. Those tests are unchanged, except to start the nodes with `-deprecatedrpc=accounts`. We can slowly migrate those tests to use the 'label' API instead of the 'account' API before accounts are fully removed. Tree-SHA512: 89f4ae2fe6de4a1422f1817b0997ae22d63ab5a1a558362ce923a3871f3e42963405d6573c69c27f1764679cdee5b51bf52202cc407f1361bfd8066d652f3f37
2 parents 018c7e5 + cead28b commit d1d54ae

14 files changed

+370
-91
lines changed

doc/release-notes-pr12892.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1-
'label' API for wallet
2-
----------------------
1+
'label' and 'account' APIs for wallet
2+
-------------------------------------
33

44
A new 'label' API has been introduced for the wallet. This is intended as a
5-
replacement for the deprecated 'account' API.
5+
replacement for the deprecated 'account' API. The 'account' can continue to
6+
be used in V0.17 by starting bitcoind with the '-deprecatedrpc=accounts'
7+
argument, and will be fully removed in V0.18.
68

79
The label RPC methods mirror the account functionality, with the following functional differences:
810

@@ -27,6 +29,9 @@ Here are the changes to RPC methods:
2729

2830
| Changed Method | Notes |
2931
| :--------------------- | :------ |
30-
| `addmultisigaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. |
31-
| `getnewaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. |
32-
| `listunspent` | Returns new `label` fields, along with `account` fields for backward compatibility. |
32+
| `addmultisigaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility if running with '-deprecatedrpc=accounts'. |
33+
| `getnewaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. if running with '-deprecatedrpc=accounts' |
34+
| `listunspent` | Returns new `label` fields. `account` field will be returned for backward compatibility if running with '-deprecatedrpc=accounts' |
35+
| `sendmany` | The `account` named parameter has been renamed to `dummy`. If provided, the `dummy` parameter must be set to the empty string, unless running with the `-deprecatedrpc=accounts` argument (in which case functionality is unchanged). |
36+
| `listtransactions` | The `account` named parameter has been renamed to `dummy`. If provided, the `dummy` parameter must be set to the string `*`, unless running with the `-deprecatedrpc=accounts` argument (in which case functionality is unchanged). |
37+
| `getbalance` | `account`, `minconf` and `include_watchonly` parameters are deprecated, and can only be used if running with '-deprecatedrpc=accounts' |

src/wallet/rpcwallet.cpp

Lines changed: 220 additions & 58 deletions
Large diffs are not rendered by default.

test/functional/rpc_deprecated.py

Lines changed: 84 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55
"""Test deprecation of RPC calls."""
66
from test_framework.test_framework import BitcoinTestFramework
7+
from test_framework.util import assert_raises_rpc_error
78

89
class DeprecatedRpcTest(BitcoinTestFramework):
910
def set_test_params(self):
1011
self.num_nodes = 2
1112
self.setup_clean_chain = True
12-
self.extra_args = [[], ["-deprecatedrpc=validateaddress"]]
13+
self.extra_args = [[], ["-deprecatedrpc=validateaddress", "-deprecatedrpc=accounts"]]
1314

1415
def run_test(self):
1516
# This test should be used to verify correct behaviour of deprecated
@@ -20,11 +21,92 @@ def run_test(self):
2021
# self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()])
2122

2223
self.log.info("Test validateaddress deprecation")
23-
SOME_ADDRESS = "mnvGjUy3NMj67yJ6gkK5o9e5RS33Z2Vqcu" # This is just some random address to pass as a parameter to validateaddress
24+
SOME_ADDRESS = "mnvGjUy3NMj67yJ6gkK5o9e5RS33Z2Vqcu" # This is just some random address to pass as a parameter to validateaddress
2425
dep_validate_address = self.nodes[0].validateaddress(SOME_ADDRESS)
2526
assert "ismine" not in dep_validate_address
2627
not_dep_val = self.nodes[1].validateaddress(SOME_ADDRESS)
2728
assert "ismine" in not_dep_val
2829

30+
self.log.info("Test accounts deprecation")
31+
# The following account RPC methods are deprecated:
32+
# - getaccount
33+
# - getaccountaddress
34+
# - getaddressesbyaccount
35+
# - getreceivedbyaccount
36+
# - listaccouts
37+
# - listreceivedbyaccount
38+
# - move
39+
# - setaccount
40+
#
41+
# The following 'label' RPC methods are usable both with and without the
42+
# -deprecatedrpc=accounts switch enabled.
43+
# - getlabeladdress
44+
# - getaddressesbylabel
45+
# - getreceivedbylabel
46+
# - listlabels
47+
# - listreceivedbylabel
48+
# - setlabel
49+
#
50+
address0 = self.nodes[0].getnewaddress()
51+
self.nodes[0].generatetoaddress(101, address0)
52+
address1 = self.nodes[1].getnewaddress()
53+
self.nodes[1].generatetoaddress(101, address1)
54+
55+
self.log.info("- getaccount")
56+
assert_raises_rpc_error(-32, "getaccount is deprecated", self.nodes[0].getaccount, address0)
57+
self.nodes[1].getaccount(address1)
58+
59+
self.log.info("- setaccount")
60+
assert_raises_rpc_error(-32, "setaccount is deprecated", self.nodes[0].setaccount, address0, "label0")
61+
self.nodes[1].setaccount(address1, "label1")
62+
63+
self.log.info("- setlabel")
64+
self.nodes[0].setlabel(address0, "label0")
65+
self.nodes[1].setlabel(address1, "label1")
66+
67+
self.log.info("- getaccountaddress")
68+
assert_raises_rpc_error(-32, "getaccountaddress is deprecated", self.nodes[0].getaccountaddress, "label0")
69+
self.nodes[1].getaccountaddress("label1")
70+
71+
self.log.info("- getlabeladdress")
72+
self.nodes[0].getlabeladdress("label0")
73+
self.nodes[1].getlabeladdress("label1")
74+
75+
self.log.info("- getaddressesbyaccount")
76+
assert_raises_rpc_error(-32, "getaddressesbyaccount is deprecated", self.nodes[0].getaddressesbyaccount, "label0")
77+
self.nodes[1].getaddressesbyaccount("label1")
78+
79+
self.log.info("- getaddressesbylabel")
80+
self.nodes[0].getaddressesbylabel("label0")
81+
self.nodes[1].getaddressesbylabel("label1")
82+
83+
self.log.info("- getreceivedbyaccount")
84+
assert_raises_rpc_error(-32, "getreceivedbyaccount is deprecated", self.nodes[0].getreceivedbyaccount, "label0")
85+
self.nodes[1].getreceivedbyaccount("label1")
86+
87+
self.log.info("- getreceivedbylabel")
88+
self.nodes[0].getreceivedbylabel("label0")
89+
self.nodes[1].getreceivedbylabel("label1")
90+
91+
self.log.info("- listaccounts")
92+
assert_raises_rpc_error(-32, "listaccounts is deprecated", self.nodes[0].listaccounts)
93+
self.nodes[1].listaccounts()
94+
95+
self.log.info("- listlabels")
96+
self.nodes[0].listlabels()
97+
self.nodes[1].listlabels()
98+
99+
self.log.info("- listreceivedbyaccount")
100+
assert_raises_rpc_error(-32, "listreceivedbyaccount is deprecated", self.nodes[0].listreceivedbyaccount)
101+
self.nodes[1].listreceivedbyaccount()
102+
103+
self.log.info("- listreceivedbylabel")
104+
self.nodes[0].listreceivedbylabel()
105+
self.nodes[1].listreceivedbylabel()
106+
107+
self.log.info("- move")
108+
assert_raises_rpc_error(-32, "move is deprecated", self.nodes[0].move, "label0", "label0b", 10)
109+
self.nodes[1].move("label1", "label1b", 10)
110+
29111
if __name__ == '__main__':
30112
DeprecatedRpcTest().main()

test/functional/test_runner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
'wallet_labels.py',
7171
'p2p_segwit.py',
7272
'wallet_dump.py',
73-
'rpc_listtransactions.py',
73+
'wallet_listtransactions.py',
7474
# vv Tests less than 60s vv
7575
'p2p_sendheaders.py',
7676
'wallet_zapwallettxes.py',

test/functional/wallet_basic.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ class WalletTest(BitcoinTestFramework):
1010
def set_test_params(self):
1111
self.num_nodes = 4
1212
self.setup_clean_chain = True
13+
self.extra_args = [['-deprecatedrpc=accounts']] * 4
1314

1415
def setup_network(self):
15-
self.add_nodes(4)
16+
self.add_nodes(4, self.extra_args)
1617
self.start_node(0)
1718
self.start_node(1)
1819
self.start_node(2)
@@ -376,9 +377,9 @@ def run_test(self):
376377
self.log.info("check " + m)
377378
self.stop_nodes()
378379
# set lower ancestor limit for later
379-
self.start_node(0, [m, "-limitancestorcount="+str(chainlimit)])
380-
self.start_node(1, [m, "-limitancestorcount="+str(chainlimit)])
381-
self.start_node(2, [m, "-limitancestorcount="+str(chainlimit)])
380+
self.start_node(0, [m, "-deprecatedrpc=accounts", "-limitancestorcount="+str(chainlimit)])
381+
self.start_node(1, [m, "-deprecatedrpc=accounts", "-limitancestorcount="+str(chainlimit)])
382+
self.start_node(2, [m, "-deprecatedrpc=accounts", "-limitancestorcount="+str(chainlimit)])
382383
if m == '-reindex':
383384
# reindex will leave rpc warm up "early"; Wait for it to finish
384385
wait_until(lambda: [block_count] * 3 == [self.nodes[i].getblockcount() for i in range(3)])
@@ -426,7 +427,7 @@ def run_test(self):
426427
# Try with walletrejectlongchains
427428
# Double chain limit but require combining inputs, so we pass SelectCoinsMinConf
428429
self.stop_node(0)
429-
self.start_node(0, extra_args=["-walletrejectlongchains", "-limitancestorcount="+str(2*chainlimit)])
430+
self.start_node(0, extra_args=["-deprecatedrpc=accounts", "-walletrejectlongchains", "-limitancestorcount="+str(2*chainlimit)])
430431

431432
# wait for loadmempool
432433
timeout = 10

test/functional/wallet_import_rescan.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def set_test_params(self):
119119
self.num_nodes = 2 + len(IMPORT_NODES)
120120

121121
def setup_network(self):
122-
extra_args = [["-addresstype=legacy"] for _ in range(self.num_nodes)]
122+
extra_args = [["-addresstype=legacy", '-deprecatedrpc=accounts'] for _ in range(self.num_nodes)]
123123
for i, import_node in enumerate(IMPORT_NODES, 2):
124124
if import_node.prune:
125125
extra_args[i] += ["-prune=1"]

test/functional/wallet_importprunedfunds.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
1010
def set_test_params(self):
1111
self.setup_clean_chain = True
1212
self.num_nodes = 2
13+
self.extra_args = [['-deprecatedrpc=accounts']] * 2
1314

1415
def run_test(self):
1516
self.log.info("Mining blocks...")

test/functional/wallet_keypool_topup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class KeypoolRestoreTest(BitcoinTestFramework):
2525
def set_test_params(self):
2626
self.setup_clean_chain = True
2727
self.num_nodes = 2
28-
self.extra_args = [[], ['-keypool=100', '-keypoolmin=20']]
28+
self.extra_args = [['-deprecatedrpc=accounts'], ['-deprecatedrpc=accounts', '-keypool=100', '-keypoolmin=20']]
2929

3030
def run_test(self):
3131
wallet_path = os.path.join(self.nodes[1].datadir, "regtest", "wallets", "wallet.dat")

test/functional/wallet_labels.py

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,38 @@
66
77
RPCs tested are:
88
- getlabeladdress
9-
- getaddressesbyaccount
9+
- getaddressesbyaccount/getaddressesbylabel
1010
- listaddressgroupings
1111
- setlabel
1212
- sendfrom (with account arguments)
1313
- move (with account arguments)
14+
15+
Run the test twice - once using the accounts API and once using the labels API.
16+
The accounts API test can be removed in V0.18.
1417
"""
1518
from collections import defaultdict
1619

1720
from test_framework.test_framework import BitcoinTestFramework
18-
from test_framework.util import assert_equal
21+
from test_framework.util import assert_equal, assert_raises_rpc_error
1922

2023
class WalletLabelsTest(BitcoinTestFramework):
2124
def set_test_params(self):
2225
self.setup_clean_chain = True
23-
self.num_nodes = 1
24-
self.extra_args = [[]]
26+
self.num_nodes = 2
27+
self.extra_args = [['-deprecatedrpc=accounts'], []]
28+
29+
def setup_network(self):
30+
"""Don't connect nodes."""
31+
self.setup_nodes()
2532

2633
def run_test(self):
27-
node = self.nodes[0]
34+
"""Run the test twice - once using the accounts API and once using the labels API."""
35+
self.log.info("Test accounts API")
36+
self._run_subtest(True, self.nodes[0])
37+
self.log.info("Test labels API")
38+
self._run_subtest(False, self.nodes[1])
39+
40+
def _run_subtest(self, accounts_api, node):
2841
# Check that there's no UTXO on any of the nodes
2942
assert_equal(len(node.listunspent()), 0)
3043

@@ -77,7 +90,7 @@ def run_test(self):
7790

7891
# Create labels and make sure subsequent label API calls
7992
# recognize the label/address associations.
80-
labels = [Label(name) for name in ("a", "b", "c", "d", "e")]
93+
labels = [Label(name, accounts_api) for name in ("a", "b", "c", "d", "e")]
8194
for label in labels:
8295
label.add_receive_address(node.getlabeladdress(label=label.name, force=True))
8396
label.verify(node)
@@ -101,29 +114,34 @@ def run_test(self):
101114

102115
# Check that sendfrom label reduces listaccounts balances.
103116
for i, label in enumerate(labels):
104-
to_label = labels[(i+1) % len(labels)]
117+
to_label = labels[(i + 1) % len(labels)]
105118
node.sendfrom(label.name, to_label.receive_address, amount_to_send)
106119
node.generate(1)
107120
for label in labels:
108121
label.add_receive_address(node.getlabeladdress(label.name))
109122
label.verify(node)
110123
assert_equal(node.getreceivedbylabel(label.name), 2)
111-
node.move(label.name, "", node.getbalance(label.name))
124+
if accounts_api:
125+
node.move(label.name, "", node.getbalance(label.name))
112126
label.verify(node)
113127
node.generate(101)
114128
expected_account_balances = {"": 5200}
115129
for label in labels:
116130
expected_account_balances[label.name] = 0
117-
assert_equal(node.listaccounts(), expected_account_balances)
118-
assert_equal(node.getbalance(""), 5200)
131+
if accounts_api:
132+
assert_equal(node.listaccounts(), expected_account_balances)
133+
assert_equal(node.getbalance(""), 5200)
119134

120135
# Check that setlabel can assign a label to a new unused address.
121136
for label in labels:
122137
address = node.getlabeladdress(label="", force=True)
123138
node.setlabel(address, label.name)
124139
label.add_address(address)
125140
label.verify(node)
126-
assert(address not in node.getaddressesbyaccount(""))
141+
if accounts_api:
142+
assert(address not in node.getaddressesbyaccount(""))
143+
else:
144+
assert_raises_rpc_error(-11, "No addresses with label", node.getaddressesbylabel, "")
127145

128146
# Check that addmultisigaddress can assign labels.
129147
for label in labels:
@@ -136,8 +154,9 @@ def run_test(self):
136154
label.verify(node)
137155
node.sendfrom("", multisig_address, 50)
138156
node.generate(101)
139-
for label in labels:
140-
assert_equal(node.getbalance(label.name), 50)
157+
if accounts_api:
158+
for label in labels:
159+
assert_equal(node.getbalance(label.name), 50)
141160

142161
# Check that setlabel can change the label of an address from a
143162
# different label.
@@ -156,9 +175,10 @@ def run_test(self):
156175
change_label(node, labels[2].receive_address, labels[2], labels[2])
157176

158177
class Label:
159-
def __init__(self, name):
178+
def __init__(self, name, accounts_api):
160179
# Label name
161180
self.name = name
181+
self.accounts_api = accounts_api
162182
# Current receiving address associated with this label.
163183
self.receive_address = None
164184
# List of all addresses assigned with this label
@@ -184,13 +204,16 @@ def verify(self, node):
184204
node.getaddressinfo(address)['labels'][0],
185205
{"name": self.name,
186206
"purpose": self.purpose[address]})
187-
assert_equal(node.getaccount(address), self.name)
207+
if self.accounts_api:
208+
assert_equal(node.getaccount(address), self.name)
209+
else:
210+
assert_equal(node.getaddressinfo(address)['label'], self.name)
188211

189212
assert_equal(
190213
node.getaddressesbylabel(self.name),
191214
{address: {"purpose": self.purpose[address]} for address in self.addresses})
192-
assert_equal(
193-
set(node.getaddressesbyaccount(self.name)), set(self.addresses))
215+
if self.accounts_api:
216+
assert_equal(set(node.getaddressesbyaccount(self.name)), set(self.addresses))
194217

195218

196219
def change_label(node, address, old_label, new_label):

test/functional/wallet_listreceivedby.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
class ReceivedByTest(BitcoinTestFramework):
1515
def set_test_params(self):
1616
self.num_nodes = 2
17+
self.extra_args = [['-deprecatedrpc=accounts']] * 2
1718

1819
def run_test(self):
1920
# Generate block to get out of IBD

0 commit comments

Comments
 (0)