diff --git a/doc/release-notes.md b/doc/release-notes.md
--- a/doc/release-notes.md
+++ b/doc/release-notes.md
@@ -10,35 +10,41 @@
- The `inactivehdmaster` property in the `dumpwallet` output has been
deprecated in favor of `inactivehdseed`. `inactivehdmaster` will be removed
in V0.21.
-'label' API for wallet
-----------------------
-
- A new 'label' API has been introduced for the wallet. This is intended as a
- replacement for the deprecated 'account' API.
-
- The label RPC methods mirror the account functionality, with the following functional differences:
-
- - Labels can be set on any address, not just receiving addresses. This functionality was previously only available through the GUI.
- - Labels can be deleted by reassigning all addresses using the `setlabel` RPC method.
- - There isn't support for sending transactions _from_ a label, or for determining which label a transaction was sent from.
- - Labels do not have a balance.
-
- Here are the changes to RPC methods:
-
- | Deprecated Method | New Method | Notes |
- | :---------------------- | :-------------------- | :-----------|
- | `getaccount` | `getaddressinfo` | `getaddressinfo` returns a json object with address information instead of just the name of the account as a string. |
- | `getaccountaddress` | `getlabeladdress` | `getlabeladdress` throws an error by default if the label does not already exist, but provides a `force` option for compatibility with existing applications. |
- | `getaddressesbyaccount` | `getaddressesbylabel` | `getaddressesbylabel` returns a json object with the addresses as keys, instead of a list of strings. |
- | `getreceivedbyaccount` | `getreceivedbylabel` | _no change in behavior_ |
- | `listaccounts` | `listlabels` | `listlabels` does not return a balance or accept `minconf` and `watchonly` arguments. |
- | `listreceivedbyaccount` | `listreceivedbylabel` | Both methods return new `label` fields, along with `account` fields for backward compatibility. |
- | `move` | n/a | _no replacement_ |
- | `sendfrom` | n/a | _no replacement_ |
- | `setaccount` | `setlabel` | Both methods now:
- allow assigning labels to any address, instead of raising an error if the address is not receiving address.
- delete the previous label associated with an address when the final address using that label is reassigned to a different label, instead of making an implicit `getaccountaddress` call to ensure the previous label still has a receiving address. |
-
- | Changed Method | Notes |
- | :--------------------- | :------ |
- | `addmultisigaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. |
- | `getnewaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. |
- | `listunspent` | Returns new `label` fields, along with `account` fields for backward compatibility. |
+
+'label' and 'account' APIs for wallet
+-------------------------------------
+
+A new 'label' API has been introduced for the wallet. This is intended as a
+replacement for the deprecated 'account' API. The 'account' can continue to
+be used in v0.20 by starting bitcoind with the '-deprecatedrpc=accounts'
+argument, and will be fully removed in v0.21.
+
+The label RPC methods mirror the account functionality, with the following functional differences:
+
+- Labels can be set on any address, not just receiving addresses. This functionality was previously only available through the GUI.
+- Labels can be deleted by reassigning all addresses using the `setlabel` RPC method.
+- There isn't support for sending transactions _from_ a label, or for determining which label a transaction was sent from.
+- Labels do not have a balance.
+
+Here are the changes to RPC methods:
+
+| Deprecated Method | New Method | Notes |
+| :---------------------- | :-------------------- | :-----------|
+| `getaccount` | `getaddressinfo` | `getaddressinfo` returns a json object with address information instead of just the name of the account as a string. |
+| `getaccountaddress` | `getlabeladdress` | `getlabeladdress` throws an error by default if the label does not already exist, but provides a `force` option for compatibility with existing applications. |
+| `getaddressesbyaccount` | `getaddressesbylabel` | `getaddressesbylabel` returns a json object with the addresses as keys, instead of a list of strings. |
+| `getreceivedbyaccount` | `getreceivedbylabel` | _no change in behavior_ |
+| `listaccounts` | `listlabels` | `listlabels` does not return a balance or accept `minconf` and `watchonly` arguments. |
+| `listreceivedbyaccount` | `listreceivedbylabel` | Both methods return new `label` fields, along with `account` fields for backward compatibility. |
+| `move` | n/a | _no replacement_ |
+| `sendfrom` | n/a | _no replacement_ |
+| `setaccount` | `setlabel` | Both methods now:
- allow assigning labels to any address, instead of raising an error if the address is not receiving address.
- delete the previous label associated with an address when the final address using that label is reassigned to a different label, instead of making an implicit `getaccountaddress` call to ensure the previous label still has a receiving address. |
+
+| Changed Method | Notes |
+| :--------------------- | :------ |
+| `addmultisigaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility if running with '-deprecatedrpc=accounts'. |
+| `getnewaddress` | Renamed `account` named parameter to `label`. Still accepts `account` for backward compatibility. if running with '-deprecatedrpc=accounts' |
+| `listunspent` | Returns new `label` fields. `account` field will be returned for backward compatibility if running with '-deprecatedrpc=accounts' |
+| `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). |
+| `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). |
+| `getbalance` | `account`, `minconf` and `include_watchonly` parameters are deprecated, and can only be used if running with '-deprecatedrpc=accounts' |
diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -240,6 +240,20 @@
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled(gArgs, "accounts") &&
+ request.strMethod == "getaccountaddress") {
+ if (request.fHelp) {
+ throw std::runtime_error(
+ "getaccountaddress (Deprecated, will be removed in v0.21. To "
+ "use this command, start bitcoind with "
+ "-deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(
+ RPC_METHOD_DEPRECATED,
+ "getaccountaddress is deprecated and will be removed in v0.21. To "
+ "use this command, start bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() < 1 ||
request.params.size() > 2) {
throw std::runtime_error(
@@ -357,6 +371,19 @@
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled(gArgs, "accounts") &&
+ request.strMethod == "setaccount") {
+ if (request.fHelp) {
+ throw std::runtime_error(
+ "setaccount (Deprecated, will be removed in v0.21. To use this "
+ "command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(
+ RPC_METHOD_DEPRECATED,
+ "setaccount is deprecated and will be removed in v0.21. To use "
+ "this command, start bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() != 2) {
throw std::runtime_error(
"setlabel \"address\" \"label\"\n"
@@ -414,6 +441,18 @@
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled(gArgs, "accounts")) {
+ if (request.fHelp) {
+ throw std::runtime_error(
+ "getaccount (Deprecated, will be removed in v0.21. To use this "
+ "command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(
+ RPC_METHOD_DEPRECATED,
+ "getaccount is deprecated and will be removed in v0.21. To use "
+ "this command, start bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() != 1) {
throw std::runtime_error(
"getaccount \"address\"\n"
@@ -459,6 +498,19 @@
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled(gArgs, "accounts")) {
+ if (request.fHelp) {
+ throw std::runtime_error(
+ "getaddressbyaccount (Deprecated, will be removed in v0.21. To "
+ "use this command, start bitcoind with "
+ "-deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(RPC_METHOD_DEPRECATED,
+ "getaddressesbyaccount is deprecated and will be "
+ "removed in v0.21. To use this command, start "
+ "bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() != 1) {
throw std::runtime_error(
"getaddressesbyaccount \"account\"\n"
@@ -880,6 +932,20 @@
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled(gArgs, "accounts") &&
+ request.strMethod == "getreceivedbyaccount") {
+ if (request.fHelp) {
+ throw std::runtime_error(
+ "getreceivedbyaccount (Deprecated, will be removed in v0.21. "
+ "To use this command, start bitcoind with "
+ "-deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(RPC_METHOD_DEPRECATED,
+ "getreceivedbyaccount is deprecated and will be "
+ "removed in v0.21. To use this command, start "
+ "bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() < 1 ||
request.params.size() > 2) {
throw std::runtime_error(
@@ -1087,6 +1153,18 @@
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled(gArgs, "accounts")) {
+ if (request.fHelp) {
+ throw std::runtime_error(
+ "move (Deprecated, will be removed in v0.21. To use this "
+ "command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(
+ RPC_METHOD_DEPRECATED,
+ "move is deprecated and will be removed in v0.21. To use this "
+ "command, start bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() < 3 ||
request.params.size() > 5) {
throw std::runtime_error(
@@ -1781,6 +1859,20 @@
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled(gArgs, "accounts") &&
+ request.strMethod == "listreceivedbyaccount") {
+ if (request.fHelp) {
+ throw std::runtime_error(
+ "listreceivedbyaccount (Deprecated, will be removed in v0.21. "
+ "To use this command, start bitcoind with "
+ "-deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(RPC_METHOD_DEPRECATED,
+ "listreceivedbyaccount is deprecated and will be "
+ "removed in v0.21. To use this command, start "
+ "bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() > 3) {
throw std::runtime_error(
"listreceivedbylabel ( minconf include_empty include_watchonly)\n"
@@ -2143,6 +2235,18 @@
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled(gArgs, "accounts")) {
+ if (request.fHelp) {
+ throw std::runtime_error(
+ "listaccounts (Deprecated, will be removed in v0.21. To use "
+ "this command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(
+ RPC_METHOD_DEPRECATED,
+ "listaccounts is deprecated and will be removed in v0.21. To use "
+ "this command, start bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() > 2) {
throw std::runtime_error(
"listaccounts ( minconf include_watchonly)\n"
diff --git a/test/functional/rpc_deprecated.py b/test/functional/rpc_deprecated.py
--- a/test/functional/rpc_deprecated.py
+++ b/test/functional/rpc_deprecated.py
@@ -4,6 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test deprecation of RPC calls."""
from test_framework.test_framework import BitcoinTestFramework
+from test_framework.util import assert_raises_rpc_error
class DeprecatedRpcTest(BitcoinTestFramework):
@@ -11,7 +12,7 @@
self.num_nodes = 2
self.setup_clean_chain = True
self.extra_args = [
- [], []]
+ [], ["-deprecatedrpc=accounts"]]
def run_test(self):
# This test should be used to verify correct behaviour of deprecated
@@ -20,7 +21,95 @@
# self.log.info("Make sure that -deprecatedrpc=createmultisig allows it to take addresses")
# assert_raises_rpc_error(-5, "Invalid public key", self.nodes[0].createmultisig, 1, [self.nodes[0].getnewaddress()])
# self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()])
- self.log.info("No tested deprecated RPC methods")
+
+ self.log.info("Test accounts deprecation")
+ # The following account RPC methods are deprecated:
+ # - getaccount
+ # - getaccountaddress
+ # - getaddressesbyaccount
+ # - getreceivedbyaccount
+ # - listaccouts
+ # - listreceivedbyaccount
+ # - move
+ # - setaccount
+ #
+ # The following 'label' RPC methods are usable both with and without the
+ # -deprecatedrpc=accounts switch enabled.
+ # - getlabeladdress
+ # - getaddressesbylabel
+ # - getreceivedbylabel
+ # - listlabels
+ # - listreceivedbylabel
+ # - setlabel
+ #
+ address0 = self.nodes[0].getnewaddress()
+ self.nodes[0].generatetoaddress(101, address0)
+ address1 = self.nodes[1].getnewaddress()
+ self.nodes[1].generatetoaddress(101, address1)
+
+ self.log.info("- getaccount")
+ assert_raises_rpc_error(-32, "getaccount is deprecated",
+ self.nodes[0].getaccount, address0)
+ self.nodes[1].getaccount(address1)
+
+ self.log.info("- setaccount")
+ assert_raises_rpc_error(-32, "setaccount is deprecated",
+ self.nodes[0].setaccount, address0, "label0")
+ self.nodes[1].setaccount(address1, "label1")
+
+ self.log.info("- setlabel")
+ self.nodes[0].setlabel(address0, "label0")
+ self.nodes[1].setlabel(address1, "label1")
+
+ self.log.info("- getaccountaddress")
+ assert_raises_rpc_error(-32, "getaccountaddress is deprecated",
+ self.nodes[0].getaccountaddress, "label0")
+ self.nodes[1].getaccountaddress("label1")
+
+ self.log.info("- getlabeladdress")
+ self.nodes[0].getlabeladdress("label0")
+ self.nodes[1].getlabeladdress("label1")
+
+ self.log.info("- getaddressesbyaccount")
+ assert_raises_rpc_error(-32, "getaddressesbyaccount is deprecated",
+ self.nodes[0].getaddressesbyaccount, "label0")
+ self.nodes[1].getaddressesbyaccount("label1")
+
+ self.log.info("- getaddressesbylabel")
+ self.nodes[0].getaddressesbylabel("label0")
+ self.nodes[1].getaddressesbylabel("label1")
+
+ self.log.info("- getreceivedbyaccount")
+ assert_raises_rpc_error(-32, "getreceivedbyaccount is deprecated",
+ self.nodes[0].getreceivedbyaccount, "label0")
+ self.nodes[1].getreceivedbyaccount("label1")
+
+ self.log.info("- getreceivedbylabel")
+ self.nodes[0].getreceivedbylabel("label0")
+ self.nodes[1].getreceivedbylabel("label1")
+
+ self.log.info("- listaccounts")
+ assert_raises_rpc_error(-32, "listaccounts is deprecated",
+ self.nodes[0].listaccounts)
+ self.nodes[1].listaccounts()
+
+ self.log.info("- listlabels")
+ self.nodes[0].listlabels()
+ self.nodes[1].listlabels()
+
+ self.log.info("- listreceivedbyaccount")
+ assert_raises_rpc_error(-32, "listreceivedbyaccount is deprecated",
+ self.nodes[0].listreceivedbyaccount)
+ self.nodes[1].listreceivedbyaccount()
+
+ self.log.info("- listreceivedbylabel")
+ self.nodes[0].listreceivedbylabel()
+ self.nodes[1].listreceivedbylabel()
+
+ self.log.info("- move")
+ assert_raises_rpc_error(-32, "move is deprecated",
+ self.nodes[0].move, "label0", "label0b", 10)
+ self.nodes[1].move("label1", "label1b", 10)
if __name__ == '__main__':
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -25,9 +25,10 @@
def set_test_params(self):
self.num_nodes = 4
self.setup_clean_chain = True
+ self.extra_args = [['-deprecatedrpc=accounts']] * 4
def setup_network(self):
- self.add_nodes(4)
+ self.add_nodes(4, self.extra_args)
self.start_node(0)
self.start_node(1)
self.start_node(2)
@@ -415,9 +416,12 @@
self.log.info("check " + m)
self.stop_nodes()
# set lower ancestor limit for later
- self.start_node(0, [m, "-limitancestorcount=" + str(chainlimit)])
- self.start_node(1, [m, "-limitancestorcount=" + str(chainlimit)])
- self.start_node(2, [m, "-limitancestorcount=" + str(chainlimit)])
+ self.start_node(0, [m, "-deprecatedrpc=accounts",
+ "-limitancestorcount=" + str(chainlimit)])
+ self.start_node(1, [m, "-deprecatedrpc=accounts",
+ "-limitancestorcount=" + str(chainlimit)])
+ self.start_node(2, [m, "-deprecatedrpc=accounts",
+ "-limitancestorcount=" + str(chainlimit)])
if m == '-reindex':
# reindex will leave rpc warm up "early"; Wait for it to finish
wait_until(lambda: [block_count] * 3 ==
@@ -475,7 +479,7 @@
# Double chain limit but require combining inputs, so we pass SelectCoinsMinConf
self.stop_node(0)
self.start_node(0, extra_args=[
- "-walletrejectlongchains", "-limitancestorcount=" + str(2 * chainlimit)])
+ "-deprecatedrpc=accounts", "-walletrejectlongchains", "-limitancestorcount=" + str(2 * chainlimit)])
# wait for loadmempool
timeout = 10
diff --git a/test/functional/wallet_import_rescan.py b/test/functional/wallet_import_rescan.py
--- a/test/functional/wallet_import_rescan.py
+++ b/test/functional/wallet_import_rescan.py
@@ -131,7 +131,8 @@
self.num_nodes = 2 + len(IMPORT_NODES)
def setup_network(self):
- extra_args = [[] for _ in range(self.num_nodes)]
+ extra_args = [['-deprecatedrpc=accounts']
+ for _ in range(self.num_nodes)]
for i, import_node in enumerate(IMPORT_NODES, 2):
if import_node.prune:
extra_args[i] += ["-prune=1"]
diff --git a/test/functional/wallet_importprunedfunds.py b/test/functional/wallet_importprunedfunds.py
--- a/test/functional/wallet_importprunedfunds.py
+++ b/test/functional/wallet_importprunedfunds.py
@@ -14,6 +14,7 @@
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
+ self.extra_args = [['-deprecatedrpc=accounts']] * 2
def run_test(self):
self.log.info("Mining blocks...")
diff --git a/test/functional/wallet_keypool_topup.py b/test/functional/wallet_keypool_topup.py
--- a/test/functional/wallet_keypool_topup.py
+++ b/test/functional/wallet_keypool_topup.py
@@ -25,7 +25,8 @@
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
- self.extra_args = [[], ['-keypool=100']]
+ self.extra_args = [['-deprecatedrpc=accounts'],
+ ['-deprecatedrpc=accounts', '-keypool=100']]
def run_test(self):
wallet_path = os.path.join(
diff --git a/test/functional/wallet_labels.py b/test/functional/wallet_labels.py
--- a/test/functional/wallet_labels.py
+++ b/test/functional/wallet_labels.py
@@ -22,7 +22,7 @@
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
- self.extra_args = [[]]
+ self.extra_args = [['-deprecatedrpc=accounts']]
def run_test(self):
node = self.nodes[0]
diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py
--- a/test/functional/wallet_listreceivedby.py
+++ b/test/functional/wallet_listreceivedby.py
@@ -18,6 +18,7 @@
class ReceivedByTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
+ self.extra_args = [['-deprecatedrpc=accounts']] * 2
def run_test(self):
# Generate block to get out of IBD
diff --git a/test/functional/wallet_listsinceblock.py b/test/functional/wallet_listsinceblock.py
--- a/test/functional/wallet_listsinceblock.py
+++ b/test/functional/wallet_listsinceblock.py
@@ -11,7 +11,9 @@
def set_test_params(self):
self.num_nodes = 4
self.setup_clean_chain = True
- self.extra_args = [["-noparkdeepreorg"], ["-noparkdeepreorg"], [], []]
+ self.extra_args = [["-noparkdeepreorg", '-deprecatedrpc=accounts'],
+ ["-noparkdeepreorg", '-deprecatedrpc=accounts'],
+ ['-deprecatedrpc=accounts'], ['-deprecatedrpc=accounts']]
def run_test(self):
self.nodes[2].generate(101)
diff --git a/test/functional/wallet_listtransactions.py b/test/functional/wallet_listtransactions.py
--- a/test/functional/wallet_listtransactions.py
+++ b/test/functional/wallet_listtransactions.py
@@ -13,6 +13,8 @@
class ListTransactionsTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
+ self.extra_args = [['-deprecatedrpc=accounts'],
+ ['-deprecatedrpc=accounts']]
def run_test(self):
# Leave IBD
diff --git a/test/functional/wallet_txn_clone.py b/test/functional/wallet_txn_clone.py
--- a/test/functional/wallet_txn_clone.py
+++ b/test/functional/wallet_txn_clone.py
@@ -16,7 +16,9 @@
class TxnMallTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
- self.extra_args = [["-noparkdeepreorg"], ["-noparkdeepreorg"], [], []]
+ self.extra_args = [["-noparkdeepreorg", '-deprecatedrpc=accounts'],
+ ["-noparkdeepreorg", '-deprecatedrpc=accounts'],
+ ['-deprecatedrpc=accounts'], ['-deprecatedrpc=accounts']]
def add_options(self, parser):
parser.add_argument("--mineblock", dest="mine_block", default=False, action="store_true",
diff --git a/test/functional/wallet_txn_doublespend.py b/test/functional/wallet_txn_doublespend.py
--- a/test/functional/wallet_txn_doublespend.py
+++ b/test/functional/wallet_txn_doublespend.py
@@ -18,7 +18,9 @@
class TxnMallTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
- self.extra_args = [["-noparkdeepreorg"], ["-noparkdeepreorg"], [], []]
+ self.extra_args = [["-noparkdeepreorg", '-deprecatedrpc=accounts'],
+ ["-noparkdeepreorg", '-deprecatedrpc=accounts'],
+ ['-deprecatedrpc=accounts'], ['-deprecatedrpc=accounts']]
def add_options(self, parser):
parser.add_argument("--mineblock", dest="mine_block", default=False, action="store_true",