Skip to content

Commit 8160817

Browse files
committed
[wallet] [rpc] Remove getlabeladdress RPC
labels are associated with addresses (rather than addresses being associated with labels, as was the case with accounts). The getlabeladdress does not make sense in this model, so remove it. getaccountaddress is still supported for one release as the accounts API is deprecated.
1 parent 4cfe17c commit 8160817

File tree

4 files changed

+85
-78
lines changed

4 files changed

+85
-78
lines changed

src/rpc/client.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ static const CRPCConvertParam vRPCConvertParams[] =
5252
{ "listreceivedbylabel", 0, "minconf" },
5353
{ "listreceivedbylabel", 1, "include_empty" },
5454
{ "listreceivedbylabel", 2, "include_watchonly" },
55-
{ "getlabeladdress", 1, "force" },
5655
{ "getbalance", 1, "minconf" },
5756
{ "getbalance", 2, "include_watchonly" },
5857
{ "getblockhash", 0, "height" },

src/wallet/rpcwallet.cpp

Lines changed: 34 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -196,60 +196,43 @@ CTxDestination GetLabelDestination(CWallet* const pwallet, const std::string& la
196196
return dest;
197197
}
198198

199-
static UniValue getlabeladdress(const JSONRPCRequest& request)
199+
static UniValue getaccountaddress(const JSONRPCRequest& request)
200200
{
201201
CWallet * const pwallet = GetWalletForJSONRPCRequest(request);
202202
if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) {
203203
return NullUniValue;
204204
}
205205

206-
if (!IsDeprecatedRPCEnabled("accounts") && request.strMethod == "getaccountaddress") {
206+
if (!IsDeprecatedRPCEnabled("accounts")) {
207207
if (request.fHelp) {
208208
throw std::runtime_error("getaccountaddress (Deprecated, will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts)");
209209
}
210210
throw JSONRPCError(RPC_METHOD_DEPRECATED, "getaccountaddress is deprecated and will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts.");
211211
}
212212

213-
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
213+
if (request.fHelp || request.params.size() != 1)
214214
throw std::runtime_error(
215-
"getlabeladdress \"label\" ( force ) \n"
216-
"\nReturns the default receiving address for this label. This will reset to a fresh address once there's a transaction that spends to it.\n"
215+
"getaccountaddress \"account\"\n"
216+
"\n\nDEPRECATED. Returns the current Bitcoin address for receiving payments to this account.\n"
217217
"\nArguments:\n"
218-
"1. \"label\" (string, required) The label for the address. It can also be set to the empty string \"\" to represent the default label.\n"
219-
"2. \"force\" (bool, optional) Whether the label should be created if it does not yet exist. If False, the RPC will return an error if called with a label that doesn't exist.\n"
220-
" Defaults to false (unless the getaccountaddress method alias is being called, in which case defaults to true for backwards compatibility).\n"
218+
"1. \"account\" (string, required) The account for the address. It can also be set to the empty string \"\" to represent the default account. The account does not need to exist, it will be created and a new address created if there is no account by the given name.\n"
221219
"\nResult:\n"
222-
"\"address\" (string) The current receiving address for the label.\n"
220+
"\"address\" (string) The account bitcoin address\n"
223221
"\nExamples:\n"
224-
+ HelpExampleCli("getlabeladdress", "")
225-
+ HelpExampleCli("getlabeladdress", "\"\"")
226-
+ HelpExampleCli("getlabeladdress", "\"mylabel\"")
227-
+ HelpExampleRpc("getlabeladdress", "\"mylabel\"")
222+
+ HelpExampleCli("getaccountaddress", "")
223+
+ HelpExampleCli("getaccountaddress", "\"\"")
224+
+ HelpExampleCli("getaccountaddress", "\"myaccount\"")
225+
+ HelpExampleRpc("getaccountaddress", "\"myaccount\"")
228226
);
229227

230228
LOCK2(cs_main, pwallet->cs_wallet);
231229

232-
// Parse the label first so we don't generate a key if there's an error
233-
std::string label = LabelFromValue(request.params[0]);
234-
bool force = request.strMethod == "getaccountaddress";
235-
if (!request.params[1].isNull()) {
236-
force = request.params[1].get_bool();
237-
}
238-
239-
bool label_found = false;
240-
for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
241-
if (item.second.name == label) {
242-
label_found = true;
243-
break;
244-
}
245-
}
246-
if (!force && !label_found) {
247-
throw JSONRPCError(RPC_WALLET_INVALID_LABEL_NAME, std::string("No addresses with label " + label));
248-
}
230+
// Parse the account first so we don't generate a key if there's an error
231+
std::string account = LabelFromValue(request.params[0]);
249232

250233
UniValue ret(UniValue::VSTR);
251234

252-
ret = EncodeDestination(GetLabelDestination(pwallet, label));
235+
ret = EncodeDestination(GetLabelDestination(pwallet, account));
253236
return ret;
254237
}
255238

@@ -335,23 +318,33 @@ static UniValue setlabel(const JSONRPCRequest& request)
335318
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Bitcoin address");
336319
}
337320

321+
std::string old_label = pwallet->mapAddressBook[dest].name;
338322
std::string label = LabelFromValue(request.params[1]);
339323

340324
if (IsMine(*pwallet, dest)) {
341-
// Detect when changing the label of an address that is the receiving address of another label:
342-
// If so, delete the account record for it. Labels, unlike addresses, can be deleted,
343-
// and if we wouldn't do this, the record would stick around forever.
344-
if (pwallet->mapAddressBook.count(dest)) {
345-
std::string old_label = pwallet->mapAddressBook[dest].name;
346-
if (old_label != label && dest == GetLabelDestination(pwallet, old_label)) {
347-
pwallet->DeleteLabel(old_label);
348-
}
349-
}
350325
pwallet->SetAddressBook(dest, label, "receive");
326+
if (request.strMethod == "setaccount" && old_label != label && dest == GetLabelDestination(pwallet, old_label)) {
327+
// for setaccount, call GetLabelDestination so a new receive address is created for the old account
328+
GetLabelDestination(pwallet, old_label, true);
329+
}
351330
} else {
352331
pwallet->SetAddressBook(dest, label, "send");
353332
}
354333

334+
// Detect when there are no addresses using this label.
335+
// If so, delete the account record for it. Labels, unlike addresses, can be deleted,
336+
// and if we wouldn't do this, the record would stick around forever.
337+
bool found_address = false;
338+
for (const std::pair<CTxDestination, CAddressBookData>& item : pwallet->mapAddressBook) {
339+
if (item.second.name == label) {
340+
found_address = true;
341+
break;
342+
}
343+
}
344+
if (!found_address) {
345+
pwallet->DeleteLabel(old_label);
346+
}
347+
355348
return NullUniValue;
356349
}
357350

@@ -4260,7 +4253,7 @@ static const CRPCCommand commands[] =
42604253
{ "wallet", "sethdseed", &sethdseed, {"newkeypool","seed"} },
42614254

42624255
/** Account functions (deprecated) */
4263-
{ "wallet", "getaccountaddress", &getlabeladdress, {"account"} },
4256+
{ "wallet", "getaccountaddress", &getaccountaddress, {"account"} },
42644257
{ "wallet", "getaccount", &getaccount, {"address"} },
42654258
{ "wallet", "getaddressesbyaccount", &getaddressesbyaccount, {"account"} },
42664259
{ "wallet", "getreceivedbyaccount", &getreceivedbylabel, {"account","minconf"} },
@@ -4270,7 +4263,6 @@ static const CRPCCommand commands[] =
42704263
{ "wallet", "move", &movecmd, {"fromaccount","toaccount","amount","minconf","comment"} },
42714264

42724265
/** Label functions (to replace non-balance account functions) */
4273-
{ "wallet", "getlabeladdress", &getlabeladdress, {"label","force"} },
42744266
{ "wallet", "getaddressesbylabel", &getaddressesbylabel, {"label"} },
42754267
{ "wallet", "getreceivedbylabel", &getreceivedbylabel, {"label","minconf"} },
42764268
{ "wallet", "listlabels", &listlabels, {"purpose"} },

test/functional/rpc_deprecated.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ def run_test(self):
4040
#
4141
# The following 'label' RPC methods are usable both with and without the
4242
# -deprecatedrpc=accounts switch enabled.
43-
# - getlabeladdress
4443
# - getaddressesbylabel
4544
# - getreceivedbylabel
4645
# - listlabels
@@ -69,10 +68,6 @@ def run_test(self):
6968
assert_raises_rpc_error(-32, "getaccountaddress is deprecated", self.nodes[0].getaccountaddress, "label0")
7069
self.nodes[1].getaccountaddress("label1")
7170

72-
self.log.info("- getlabeladdress")
73-
self.nodes[0].getlabeladdress("label0")
74-
self.nodes[1].getlabeladdress("label1")
75-
7671
self.log.info("- getaddressesbyaccount")
7772
assert_raises_rpc_error(-32, "getaddressesbyaccount is deprecated", self.nodes[0].getaddressesbyaccount, "label0")
7873
self.nodes[1].getaddressesbyaccount("label1")

test/functional/wallet_labels.py

Lines changed: 51 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
"""Test label RPCs.
66
77
RPCs tested are:
8-
- getlabeladdress
8+
- getaccountaddress
99
- getaddressesbyaccount/getaddressesbylabel
1010
- listaddressgroupings
1111
- setlabel
@@ -92,17 +92,24 @@ def _run_subtest(self, accounts_api, node):
9292
# recognize the label/address associations.
9393
labels = [Label(name, accounts_api) for name in ("a", "b", "c", "d", "e")]
9494
for label in labels:
95-
label.add_receive_address(node.getlabeladdress(label=label.name, force=True))
95+
if accounts_api:
96+
address = node.getaccountaddress(label.name)
97+
else:
98+
address = node.getnewaddress(label.name)
99+
label.add_receive_address(address)
96100
label.verify(node)
97101

98102
# Check all labels are returned by listlabels.
99103
assert_equal(node.listlabels(), [label.name for label in labels])
100104

101105
# Send a transaction to each label, and make sure this forces
102-
# getlabeladdress to generate a new receiving address.
106+
# getaccountaddress to generate a new receiving address.
103107
for label in labels:
104-
node.sendtoaddress(label.receive_address, amount_to_send)
105-
label.add_receive_address(node.getlabeladdress(label.name))
108+
if accounts_api:
109+
node.sendtoaddress(label.receive_address, amount_to_send)
110+
label.add_receive_address(node.getaccountaddress(label.name))
111+
else:
112+
node.sendtoaddress(label.addresses[0], amount_to_send)
106113
label.verify(node)
107114

108115
# Check the amounts received.
@@ -115,10 +122,17 @@ def _run_subtest(self, accounts_api, node):
115122
# Check that sendfrom label reduces listaccounts balances.
116123
for i, label in enumerate(labels):
117124
to_label = labels[(i + 1) % len(labels)]
118-
node.sendfrom(label.name, to_label.receive_address, amount_to_send)
125+
if accounts_api:
126+
node.sendfrom(label.name, to_label.receive_address, amount_to_send)
127+
else:
128+
node.sendfrom(label.name, to_label.addresses[0], amount_to_send)
119129
node.generate(1)
120130
for label in labels:
121-
label.add_receive_address(node.getlabeladdress(label.name))
131+
if accounts_api:
132+
address = node.getaccountaddress(label.name)
133+
else:
134+
address = node.getnewaddress(label.name)
135+
label.add_receive_address(address)
122136
label.verify(node)
123137
assert_equal(node.getreceivedbylabel(label.name), 2)
124138
if accounts_api:
@@ -134,12 +148,12 @@ def _run_subtest(self, accounts_api, node):
134148

135149
# Check that setlabel can assign a label to a new unused address.
136150
for label in labels:
137-
address = node.getlabeladdress(label="", force=True)
151+
address = node.getnewaddress()
138152
node.setlabel(address, label.name)
139153
label.add_address(address)
140154
label.verify(node)
141155
if accounts_api:
142-
assert(address not in node.getaddressesbyaccount(""))
156+
assert address not in node.getaddressesbyaccount("")
143157
else:
144158
assert_raises_rpc_error(-11, "No addresses with label", node.getaddressesbylabel, "")
145159

@@ -160,19 +174,20 @@ def _run_subtest(self, accounts_api, node):
160174

161175
# Check that setlabel can change the label of an address from a
162176
# different label.
163-
change_label(node, labels[0].addresses[0], labels[0], labels[1])
164-
165-
# Check that setlabel can change the label of an address which
166-
# is the receiving address of a different label.
167-
change_label(node, labels[0].receive_address, labels[0], labels[1])
177+
change_label(node, labels[0].addresses[0], labels[0], labels[1], accounts_api)
168178

169179
# Check that setlabel can set the label of an address already
170180
# in the label. This is a no-op.
171-
change_label(node, labels[2].addresses[0], labels[2], labels[2])
181+
change_label(node, labels[2].addresses[0], labels[2], labels[2], accounts_api)
182+
183+
if accounts_api:
184+
# Check that setaccount can change the label of an address which
185+
# is the receiving address of a different label.
186+
change_label(node, labels[0].receive_address, labels[0], labels[1], accounts_api)
172187

173-
# Check that setlabel can set the label of an address which is
174-
# already the receiving address of the label. This is a no-op.
175-
change_label(node, labels[2].receive_address, labels[2], labels[2])
188+
# Check that setaccount can set the label of an address which is
189+
# already the receiving address of the label. This is a no-op.
190+
change_label(node, labels[2].receive_address, labels[2], labels[2], accounts_api)
176191

177192
class Label:
178193
def __init__(self, name, accounts_api):
@@ -192,12 +207,14 @@ def add_address(self, address):
192207

193208
def add_receive_address(self, address):
194209
self.add_address(address)
195-
self.receive_address = address
210+
if self.accounts_api:
211+
self.receive_address = address
196212

197213
def verify(self, node):
198214
if self.receive_address is not None:
199215
assert self.receive_address in self.addresses
200-
assert_equal(node.getlabeladdress(self.name), self.receive_address)
216+
if self.accounts_api:
217+
assert_equal(node.getaccountaddress(self.name), self.receive_address)
201218

202219
for address in self.addresses:
203220
assert_equal(
@@ -216,22 +233,26 @@ def verify(self, node):
216233
assert_equal(set(node.getaddressesbyaccount(self.name)), set(self.addresses))
217234

218235

219-
def change_label(node, address, old_label, new_label):
236+
def change_label(node, address, old_label, new_label, accounts_api):
220237
assert_equal(address in old_label.addresses, True)
221-
node.setlabel(address, new_label.name)
238+
if accounts_api:
239+
node.setaccount(address, new_label.name)
240+
else:
241+
node.setlabel(address, new_label.name)
222242

223243
old_label.addresses.remove(address)
224244
new_label.add_address(address)
225245

226-
# Calling setlabel on an address which was previously the receiving
227-
# address of a different label should reset the receiving address of
228-
# the old label, causing getlabeladdress to return a brand new
246+
# Calling setaccount on an address which was previously the receiving
247+
# address of a different account should reset the receiving address of
248+
# the old account, causing getaccountaddress to return a brand new
229249
# address.
230-
if old_label.name != new_label.name and address == old_label.receive_address:
231-
new_address = node.getlabeladdress(old_label.name)
232-
assert_equal(new_address not in old_label.addresses, True)
233-
assert_equal(new_address not in new_label.addresses, True)
234-
old_label.add_receive_address(new_address)
250+
if accounts_api:
251+
if old_label.name != new_label.name and address == old_label.receive_address:
252+
new_address = node.getaccountaddress(old_label.name)
253+
assert_equal(new_address not in old_label.addresses, True)
254+
assert_equal(new_address not in new_label.addresses, True)
255+
old_label.add_receive_address(new_address)
235256

236257
old_label.verify(node)
237258
new_label.verify(node)

0 commit comments

Comments
 (0)