aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWladimir J. van der Laan <laanwj@gmail.com>2018-04-24 14:27:55 +0200
committerWladimir J. van der Laan <laanwj@gmail.com>2018-04-24 15:21:27 +0200
commitd1d54ae6a362f0761e0a7c35036b6a28d9fab457 (patch)
tree397cd1b1b779e126a53cf009401d375966a4b223
parent018c7e5dadc1c38af9985b54a9729296d050f0e3 (diff)
parentcead28bbecf032b49c01ca3ae4f47aa2536cbc55 (diff)
downloadbitcoin-d1d54ae6a362f0761e0a7c35036b6a28d9fab457.tar.xz
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
-rw-r--r--doc/release-notes-pr12892.md17
-rw-r--r--src/wallet/rpcwallet.cpp278
-rwxr-xr-xtest/functional/rpc_deprecated.py86
-rwxr-xr-xtest/functional/test_runner.py2
-rwxr-xr-xtest/functional/wallet_basic.py11
-rwxr-xr-xtest/functional/wallet_import_rescan.py2
-rwxr-xr-xtest/functional/wallet_importprunedfunds.py1
-rwxr-xr-xtest/functional/wallet_keypool_topup.py2
-rwxr-xr-xtest/functional/wallet_labels.py57
-rwxr-xr-xtest/functional/wallet_listreceivedby.py1
-rwxr-xr-xtest/functional/wallet_listsinceblock.py1
-rwxr-xr-xtest/functional/wallet_listtransactions.py (renamed from test/functional/rpc_listtransactions.py)1
-rwxr-xr-xtest/functional/wallet_txn_clone.py1
-rwxr-xr-xtest/functional/wallet_txn_doublespend.py1
14 files changed, 370 insertions, 91 deletions
diff --git a/doc/release-notes-pr12892.md b/doc/release-notes-pr12892.md
index 894bf19dee..8105eca5c0 100644
--- a/doc/release-notes-pr12892.md
+++ b/doc/release-notes-pr12892.md
@@ -1,8 +1,10 @@
-'label' API for wallet
-----------------------
+'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.
+replacement for the deprecated 'account' API. The 'account' can continue to
+be used in V0.17 by starting bitcoind with the '-deprecatedrpc=accounts'
+argument, and will be fully removed in V0.18.
The label RPC methods mirror the account functionality, with the following functional differences:
@@ -27,6 +29,9 @@ Here are the changes to RPC methods:
| 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. |
+| `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
index 9b5fb0b062..5bc8788c7c 100644
--- a/src/wallet/rpcwallet.cpp
+++ b/src/wallet/rpcwallet.cpp
@@ -205,6 +205,13 @@ UniValue getlabeladdress(const JSONRPCRequest& request)
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled("accounts") && request.strMethod == "getaccountaddress") {
+ if (request.fHelp) {
+ throw std::runtime_error("getaccountaddress (Deprecated, will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(RPC_METHOD_DEPRECATED, "getaccountaddress is deprecated and will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw std::runtime_error(
"getlabeladdress \"label\" ( force ) \n"
@@ -226,7 +233,7 @@ UniValue getlabeladdress(const JSONRPCRequest& request)
// Parse the label first so we don't generate a key if there's an error
std::string label = LabelFromValue(request.params[0]);
- bool force = request.strMethod == "getaccountaddress" ? true : false;
+ bool force = request.strMethod == "getaccountaddress";
if (!request.params[1].isNull()) {
force = request.params[1].get_bool();
}
@@ -305,6 +312,13 @@ UniValue setlabel(const JSONRPCRequest& request)
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled("accounts") && request.strMethod == "setaccount") {
+ if (request.fHelp) {
+ throw std::runtime_error("setaccount (Deprecated, will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(RPC_METHOD_DEPRECATED, "setaccount is deprecated and will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() != 2)
throw std::runtime_error(
"setlabel \"address\" \"label\"\n"
@@ -352,6 +366,13 @@ UniValue getaccount(const JSONRPCRequest& request)
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled("accounts")) {
+ if (request.fHelp) {
+ throw std::runtime_error("getaccount (Deprecated, will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(RPC_METHOD_DEPRECATED, "getaccount is deprecated and will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() != 1)
throw std::runtime_error(
"getaccount \"address\"\n"
@@ -388,6 +409,13 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request)
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled("accounts")) {
+ if (request.fHelp) {
+ throw std::runtime_error("getaddressbyaccount (Deprecated, will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(RPC_METHOD_DEPRECATED, "getaddressesbyaccount is deprecated and will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() != 1)
throw std::runtime_error(
"getaddressesbyaccount \"account\"\n"
@@ -743,6 +771,13 @@ UniValue getreceivedbylabel(const JSONRPCRequest& request)
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled("accounts") && request.strMethod == "getreceivedbyaccount") {
+ if (request.fHelp) {
+ throw std::runtime_error("getreceivedbyaccount (Deprecated, will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(RPC_METHOD_DEPRECATED, "getreceivedbyaccount is deprecated and will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() < 1 || request.params.size() > 2)
throw std::runtime_error(
"getreceivedbylabel \"label\" ( minconf )\n"
@@ -808,7 +843,7 @@ UniValue getbalance(const JSONRPCRequest& request)
return NullUniValue;
}
- if (request.fHelp || request.params.size() > 3)
+ if (request.fHelp || (request.params.size() > 3 && IsDeprecatedRPCEnabled("accounts")) || (request.params.size() != 0 && !IsDeprecatedRPCEnabled("accounts")))
throw std::runtime_error(
"getbalance ( \"account\" minconf include_watchonly )\n"
"\nIf account is not specified, returns the server's total available balance.\n"
@@ -818,7 +853,8 @@ UniValue getbalance(const JSONRPCRequest& request)
"Note that the account \"\" is not the same as leaving the parameter out.\n"
"The server total may be different to the balance in the default \"\" account.\n"
"\nArguments:\n"
- "1. \"account\" (string, optional) DEPRECATED. The account string may be given as a\n"
+ "1. \"account\" (string, optional) DEPRECATED. This argument will be removed in V0.18. \n"
+ " To use this deprecated argument, start bitcoind with -deprecatedrpc=accounts. The account string may be given as a\n"
" specific account name to find the balance associated with wallet keys in\n"
" a named account, or as the empty string (\"\") to find the balance\n"
" associated with wallet keys not in any named account, or as \"*\" to find\n"
@@ -830,8 +866,8 @@ UniValue getbalance(const JSONRPCRequest& request)
" balances. In general, account balance calculation is not considered\n"
" reliable and has resulted in confusing outcomes, so it is recommended to\n"
" avoid passing this argument.\n"
- "2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
- "3. include_watchonly (bool, optional, default=false) Also include balance in watch-only addresses (see 'importaddress')\n"
+ "2. minconf (numeric, optional, default=1) DEPRECATED. Only valid when an account is specified. This argument will be removed in V0.18. To use this deprecated argument, start bitcoind with -deprecatedrpc=accounts. Only include transactions confirmed at least this many times.\n"
+ "3. include_watchonly (bool, optional, default=false) DEPRECATED. Only valid when an account is specified. This argument will be removed in V0.18. To use this deprecated argument, start bitcoind with -deprecatedrpc=accounts. Also include balance in watch-only addresses (see 'importaddress')\n"
"\nResult:\n"
"amount (numeric) The total amount in " + CURRENCY_UNIT + " received for this account.\n"
"\nExamples:\n"
@@ -851,34 +887,38 @@ UniValue getbalance(const JSONRPCRequest& request)
LOCK2(cs_main, pwallet->cs_wallet);
- const UniValue& account_value = request.params[0];
- const UniValue& minconf = request.params[1];
- const UniValue& include_watchonly = request.params[2];
+ if (IsDeprecatedRPCEnabled("accounts")) {
+ const UniValue& account_value = request.params[0];
+ const UniValue& minconf = request.params[1];
+ const UniValue& include_watchonly = request.params[2];
- if (account_value.isNull()) {
- if (!minconf.isNull()) {
- throw JSONRPCError(RPC_INVALID_PARAMETER,
- "getbalance minconf option is only currently supported if an account is specified");
- }
- if (!include_watchonly.isNull()) {
- throw JSONRPCError(RPC_INVALID_PARAMETER,
- "getbalance include_watchonly option is only currently supported if an account is specified");
+ if (account_value.isNull()) {
+ if (!minconf.isNull()) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER,
+ "getbalance minconf option is only currently supported if an account is specified");
+ }
+ if (!include_watchonly.isNull()) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER,
+ "getbalance include_watchonly option is only currently supported if an account is specified");
+ }
+ return ValueFromAmount(pwallet->GetBalance());
}
- return ValueFromAmount(pwallet->GetBalance());
- }
- const std::string& account_param = account_value.get_str();
- const std::string* account = account_param != "*" ? &account_param : nullptr;
+ const std::string& account_param = account_value.get_str();
+ const std::string* account = account_param != "*" ? &account_param : nullptr;
- int nMinDepth = 1;
- if (!minconf.isNull())
- nMinDepth = minconf.get_int();
- isminefilter filter = ISMINE_SPENDABLE;
- if(!include_watchonly.isNull())
- if(include_watchonly.get_bool())
- filter = filter | ISMINE_WATCH_ONLY;
+ int nMinDepth = 1;
+ if (!minconf.isNull())
+ nMinDepth = minconf.get_int();
+ isminefilter filter = ISMINE_SPENDABLE;
+ if(!include_watchonly.isNull())
+ if(include_watchonly.get_bool())
+ filter = filter | ISMINE_WATCH_ONLY;
- return ValueFromAmount(pwallet->GetLegacyBalance(filter, nMinDepth, account));
+ return ValueFromAmount(pwallet->GetLegacyBalance(filter, nMinDepth, account));
+ }
+
+ return ValueFromAmount(pwallet->GetBalance());
}
UniValue getunconfirmedbalance(const JSONRPCRequest &request)
@@ -912,6 +952,13 @@ UniValue movecmd(const JSONRPCRequest& request)
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled("accounts")) {
+ if (request.fHelp) {
+ throw std::runtime_error("move (Deprecated, will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(RPC_METHOD_DEPRECATED, "move is deprecated and will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts.");
+ }
+
if (request.fHelp || request.params.size() < 3 || request.params.size() > 5)
throw std::runtime_error(
"move \"fromaccount\" \"toaccount\" amount ( minconf \"comment\" )\n"
@@ -1038,9 +1085,50 @@ UniValue sendmany(const JSONRPCRequest& request)
return NullUniValue;
}
- if (request.fHelp || request.params.size() < 2 || request.params.size() > 8)
- throw std::runtime_error(
- "sendmany \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] replaceable conf_target \"estimate_mode\")\n"
+ std::string help_text;
+ if (!IsDeprecatedRPCEnabled("accounts")) {
+ help_text = "sendmany \"\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] replaceable conf_target \"estimate_mode\")\n"
+ "\nSend multiple times. Amounts are double-precision floating point numbers.\n"
+ "Note that the \"fromaccount\" argument has been removed in V0.17. To use this RPC with a \"fromaccount\" argument, restart\n"
+ "bitcoind with -deprecatedrpc=accounts\n"
+ + HelpRequiringPassphrase(pwallet) + "\n"
+ "\nArguments:\n"
+ "1. \"dummy\" (string, required) Must be set to \"\" for backwards compatibility.\n"
+ "2. \"amounts\" (string, required) A json object with addresses and amounts\n"
+ " {\n"
+ " \"address\":amount (numeric or string) The bitcoin address is the key, the numeric amount (can be string) in " + CURRENCY_UNIT + " is the value\n"
+ " ,...\n"
+ " }\n"
+ "3. minconf (numeric, optional, default=1) Only use the balance confirmed at least this many times.\n"
+ "4. \"comment\" (string, optional) A comment\n"
+ "5. subtractfeefrom (array, optional) A json array with addresses.\n"
+ " The fee will be equally deducted from the amount of each selected address.\n"
+ " Those recipients will receive less bitcoins than you enter in their corresponding amount field.\n"
+ " If no addresses are specified here, the sender pays the fee.\n"
+ " [\n"
+ " \"address\" (string) Subtract fee from this address\n"
+ " ,...\n"
+ " ]\n"
+ "6. replaceable (boolean, optional) Allow this transaction to be replaced by a transaction with higher fees via BIP 125\n"
+ "7. conf_target (numeric, optional) Confirmation target (in blocks)\n"
+ "8. \"estimate_mode\" (string, optional, default=UNSET) The fee estimate mode, must be one of:\n"
+ " \"UNSET\"\n"
+ " \"ECONOMICAL\"\n"
+ " \"CONSERVATIVE\"\n"
+ "\nResult:\n"
+ "\"txid\" (string) The transaction id for the send. Only 1 transaction is created regardless of \n"
+ " the number of addresses.\n"
+ "\nExamples:\n"
+ "\nSend two amounts to two different addresses:\n"
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\"") +
+ "\nSend two amounts to two different addresses setting the confirmation and comment:\n"
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 6 \"testing\"") +
+ "\nSend two amounts to two different addresses, subtract fee from amount:\n"
+ + HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("sendmany", "\"\", {\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\":0.01,\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\":0.02}, 6, \"testing\"");
+ } else {
+ help_text = "sendmany \"\" \"fromaccount\" {\"address\":amount,...} ( minconf \"comment\" [\"address\",...] replaceable conf_target \"estimate_mode\")\n"
"\nSend multiple times. Amounts are double-precision floating point numbers."
+ HelpRequiringPassphrase(pwallet) + "\n"
"\nArguments:\n"
@@ -1077,8 +1165,10 @@ UniValue sendmany(const JSONRPCRequest& request)
"\nSend two amounts to two different addresses, subtract fee from amount:\n"
+ HelpExampleCli("sendmany", "\"\" \"{\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\":0.01,\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\":0.02}\" 1 \"\" \"[\\\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\\\",\\\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\\\"]\"") +
"\nAs a json rpc call\n"
- + HelpExampleRpc("sendmany", "\"\", {\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\":0.01,\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\":0.02}, 6, \"testing\"")
- );
+ + HelpExampleRpc("sendmany", "\"\", {\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\":0.01,\"1353tsE8YMTA4EuV7dgUXGjNFf9KpVvKHz\":0.02}, 6, \"testing\"");
+ }
+
+ if (request.fHelp || request.params.size() < 2 || request.params.size() > 8) throw std::runtime_error(help_text);
ObserveSafeMode();
@@ -1092,6 +1182,9 @@ UniValue sendmany(const JSONRPCRequest& request)
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
}
+ if (!IsDeprecatedRPCEnabled("accounts") && !request.params[0].get_str().empty()) {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Dummy value must be set to \"\"");
+ }
std::string strAccount = LabelFromValue(request.params[0]);
UniValue sendTo = request.params[1].get_obj();
int nMinDepth = 1;
@@ -1608,6 +1701,13 @@ UniValue listreceivedbylabel(const JSONRPCRequest& request)
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled("accounts") && request.strMethod == "listreceivedbyaccount") {
+ if (request.fHelp) {
+ throw std::runtime_error("listreceivedbyaccount (Deprecated, will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(RPC_METHOD_DEPRECATED, "listreceivedbyaccount is deprecated and will be removed in V0.18. 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"
@@ -1685,7 +1785,7 @@ void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, const std::s
if (involvesWatchonly || (::IsMine(*pwallet, s.destination) & ISMINE_WATCH_ONLY)) {
entry.pushKV("involvesWatchonly", true);
}
- entry.pushKV("account", strSentAccount);
+ if (IsDeprecatedRPCEnabled("accounts")) entry.pushKV("account", strSentAccount);
MaybePushAddress(entry, s.destination);
entry.pushKV("category", "send");
entry.pushKV("amount", ValueFromAmount(-s.amount));
@@ -1716,7 +1816,7 @@ void ListTransactions(CWallet* const pwallet, const CWalletTx& wtx, const std::s
if (involvesWatchonly || (::IsMine(*pwallet, r.destination) & ISMINE_WATCH_ONLY)) {
entry.pushKV("involvesWatchonly", true);
}
- entry.pushKV("account", account);
+ if (IsDeprecatedRPCEnabled("accounts")) entry.pushKV("account", account);
MaybePushAddress(entry, r.destination);
if (wtx.IsCoinBase())
{
@@ -1755,7 +1855,7 @@ void AcentryToJSON(const CAccountingEntry& acentry, const std::string& strAccoun
entry.pushKV("category", "move");
entry.pushKV("time", acentry.nTime);
entry.pushKV("amount", ValueFromAmount(acentry.nCreditDebit));
- entry.pushKV("otheraccount", acentry.strOtherAccount);
+ if (IsDeprecatedRPCEnabled("accounts")) entry.pushKV("otheraccount", acentry.strOtherAccount);
entry.pushKV("comment", acentry.strComment);
ret.push_back(entry);
}
@@ -1768,19 +1868,64 @@ UniValue listtransactions(const JSONRPCRequest& request)
return NullUniValue;
}
- if (request.fHelp || request.params.size() > 4)
- throw std::runtime_error(
- "listtransactions ( \"account\" count skip include_watchonly)\n"
+ std::string help_text {};
+ if (!IsDeprecatedRPCEnabled("accounts")) {
+ help_text = "listtransactions (dummy count skip include_watchonly)\n"
"\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
+ "Note that the \"account\" argument and \"otheraccount\" return value have been removed in V0.17. To use this RPC with an \"account\" argument, restart\n"
+ "bitcoind with -deprecatedrpc=accounts\n"
"\nArguments:\n"
- "1. \"account\" (string, optional) DEPRECATED. The account name. Should be \"*\".\n"
+ "1. \"dummy\" (string, optional) If set, should be \"*\" for backwards compatibility.\n"
"2. count (numeric, optional, default=10) The number of transactions to return\n"
"3. skip (numeric, optional, default=0) The number of transactions to skip\n"
"4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
"\nResult:\n"
"[\n"
" {\n"
- " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. \n"
+ " \"address\":\"address\", (string) The bitcoin address of the transaction.\n"
+ " \"category\":\"send|receive\", (string) The transaction category.\n"
+ " \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and is positive\n"
+ " for the 'receive' category,\n"
+ " \"label\": \"label\", (string) A comment for the address/transaction, if any\n"
+ " \"vout\": n, (numeric) the vout value\n"
+ " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n"
+ " 'send' category of transactions.\n"
+ " \"confirmations\": n, (numeric) The number of confirmations for the transaction. Negative confirmations indicate the\n"
+ " transaction conflicts with the block chain\n"
+ " \"trusted\": xxx, (bool) Whether we consider the outputs of this unconfirmed transaction safe to spend.\n"
+ " \"blockhash\": \"hashvalue\", (string) The block hash containing the transaction.\n"
+ " \"blockindex\": n, (numeric) The index of the transaction in the block that includes it.\n"
+ " \"blocktime\": xxx, (numeric) The block time in seconds since epoch (1 Jan 1970 GMT).\n"
+ " \"txid\": \"transactionid\", (string) The transaction id.\n"
+ " \"time\": xxx, (numeric) The transaction time in seconds since epoch (midnight Jan 1 1970 GMT).\n"
+ " \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT).\n"
+ " \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
+ " \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
+ " may be unknown for unconfirmed transactions not in the mempool\n"
+ " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n"
+ " 'send' category of transactions.\n"
+ " }\n"
+ "]\n"
+
+ "\nExamples:\n"
+ "\nList the most recent 10 transactions in the systems\n"
+ + HelpExampleCli("listtransactions", "") +
+ "\nList transactions 100 to 120\n"
+ + HelpExampleCli("listtransactions", "\"*\" 20 100") +
+ "\nAs a json rpc call\n"
+ + HelpExampleRpc("listtransactions", "\"*\", 20, 100");
+ } else {
+ help_text = "listtransactions ( \"account\" count skip include_watchonly)\n"
+ "\nReturns up to 'count' most recent transactions skipping the first 'from' transactions for account 'account'.\n"
+ "\nArguments:\n"
+ "1. \"account\" (string, optional) DEPRECATED. This argument will be removed in V0.18. The account name. Should be \"*\".\n"
+ "2. count (numeric, optional, default=10) The number of transactions to return\n"
+ "3. skip (numeric, optional, default=0) The number of transactions to skip\n"
+ "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n"
+ "\nResult:\n"
+ "[\n"
+ " {\n"
+ " \"account\":\"accountname\", (string) DEPRECATED. This field will be removed in V0.18. The account name associated with the transaction. \n"
" It will be \"\" for the default account.\n"
" \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for \n"
" move transactions (category = move).\n"
@@ -1809,7 +1954,7 @@ UniValue listtransactions(const JSONRPCRequest& request)
" \"timereceived\": xxx, (numeric) The time received in seconds since epoch (midnight Jan 1 1970 GMT). Available \n"
" for 'send' and 'receive' category of transactions.\n"
" \"comment\": \"...\", (string) If a comment is associated with the transaction.\n"
- " \"otheraccount\": \"accountname\", (string) DEPRECATED. For the 'move' category of transactions, the account the funds came \n"
+ " \"otheraccount\": \"accountname\", (string) DEPRECATED. This field will be removed in V0.18. For the 'move' category of transactions, the account the funds came \n"
" from (for receiving funds, positive amounts), or went to (for sending funds,\n"
" negative amounts).\n"
" \"bip125-replaceable\": \"yes|no|unknown\", (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n"
@@ -1825,8 +1970,9 @@ UniValue listtransactions(const JSONRPCRequest& request)
"\nList transactions 100 to 120\n"
+ HelpExampleCli("listtransactions", "\"*\" 20 100") +
"\nAs a json rpc call\n"
- + HelpExampleRpc("listtransactions", "\"*\", 20, 100")
- );
+ + HelpExampleRpc("listtransactions", "\"*\", 20, 100");
+ }
+ if (request.fHelp || request.params.size() > 4) throw std::runtime_error(help_text);
ObserveSafeMode();
@@ -1835,8 +1981,12 @@ UniValue listtransactions(const JSONRPCRequest& request)
pwallet->BlockUntilSyncedToCurrentChain();
std::string strAccount = "*";
- if (!request.params[0].isNull())
+ if (!request.params[0].isNull()) {
strAccount = request.params[0].get_str();
+ if (!IsDeprecatedRPCEnabled("accounts") && strAccount != "*") {
+ throw JSONRPCError(RPC_INVALID_PARAMETER, "Dummy value must be set to \"*\"");
+ }
+ }
int nCount = 10;
if (!request.params[1].isNull())
nCount = request.params[1].get_int();
@@ -1866,9 +2016,10 @@ UniValue listtransactions(const JSONRPCRequest& request)
CWalletTx *const pwtx = (*it).second.first;
if (pwtx != nullptr)
ListTransactions(pwallet, *pwtx, strAccount, 0, true, ret, filter);
- CAccountingEntry *const pacentry = (*it).second.second;
- if (pacentry != nullptr)
- AcentryToJSON(*pacentry, strAccount, ret);
+ if (IsDeprecatedRPCEnabled("accounts")) {
+ CAccountingEntry *const pacentry = (*it).second.second;
+ if (pacentry != nullptr) AcentryToJSON(*pacentry, strAccount, ret);
+ }
if ((int)ret.size() >= (nCount+nFrom)) break;
}
@@ -1907,6 +2058,13 @@ UniValue listaccounts(const JSONRPCRequest& request)
return NullUniValue;
}
+ if (!IsDeprecatedRPCEnabled("accounts")) {
+ if (request.fHelp) {
+ throw std::runtime_error("listaccounts (Deprecated, will be removed in V0.18. To use this command, start bitcoind with -deprecatedrpc=accounts)");
+ }
+ throw JSONRPCError(RPC_METHOD_DEPRECATED, "listaccounts is deprecated and will be removed in V0.18. 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"
@@ -2010,7 +2168,7 @@ UniValue listsinceblock(const JSONRPCRequest& request)
"\nResult:\n"
"{\n"
" \"transactions\": [\n"
- " \"account\":\"accountname\", (string) DEPRECATED. The account name associated with the transaction. Will be \"\" for the default account.\n"
+ " \"account\":\"accountname\", (string) DEPRECATED. This field will be removed in V0.18. To see this deprecated field, start bitcoind with -deprecatedrpc=accounts. The account name associated with the transaction. Will be \"\" for the default account.\n"
" \"address\":\"address\", (string) The bitcoin address of the transaction. Not present for move transactions (category = move).\n"
" \"category\":\"send|receive\", (string) The transaction category. 'send' has negative amounts, 'receive' has positive amounts.\n"
" \"amount\": x.xxx, (numeric) The amount in " + CURRENCY_UNIT + ". This is negative for the 'send' category, and for the 'move' category for moves \n"
@@ -2159,7 +2317,7 @@ UniValue gettransaction(const JSONRPCRequest& request)
" may be unknown for unconfirmed transactions not in the mempool\n"
" \"details\" : [\n"
" {\n"
- " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"
+ " \"account\" : \"accountname\", (string) DEPRECATED. This field will be removed in a V0.18. To see this deprecated field, start bitcoind with -deprecatedrpc=accounts. The account name involved in the transaction, can be \"\" for the default account.\n"
" \"address\" : \"address\", (string) The bitcoin address involved in the transaction\n"
" \"category\" : \"send|receive\", (string) The category, either 'send' or 'receive'\n"
" \"amount\" : x.xxx, (numeric) The amount in " + CURRENCY_UNIT + "\n"
@@ -2946,7 +3104,7 @@ UniValue listunspent(const JSONRPCRequest& request)
" \"vout\" : n, (numeric) the vout value\n"
" \"address\" : \"address\", (string) the bitcoin address\n"
" \"label\" : \"label\", (string) The associated label, or \"\" for the default label\n"
- " \"account\" : \"account\", (string) DEPRECATED. Backwards compatible alias for label.\n"
+ " \"account\" : \"account\", (string) DEPRECATED. This field will be removed in V0.18. To see this deprecated field, start bitcoind with -deprecatedrpc=accounts. The associated account, or \"\" for the default account\n"
" \"scriptPubKey\" : \"key\", (string) the script key\n"
" \"amount\" : x.xxx, (numeric) the transaction output amount in " + CURRENCY_UNIT + "\n"
" \"confirmations\" : n, (numeric) The number of confirmations\n"
@@ -3051,7 +3209,9 @@ UniValue listunspent(const JSONRPCRequest& request)
if (pwallet->mapAddressBook.count(address)) {
entry.pushKV("label", pwallet->mapAddressBook[address].name);
- entry.pushKV("account", pwallet->mapAddressBook[address].name);
+ if (IsDeprecatedRPCEnabled("accounts")) {
+ entry.pushKV("account", pwallet->mapAddressBook[address].name);
+ }
}
if (scriptPubKey.IsPayToScriptHash()) {
@@ -3779,7 +3939,8 @@ UniValue getaddressinfo(const JSONRPCRequest& request)
" \"pubkey\" : \"publickeyhex\", (string, optional) The hex value of the raw public key, for single-key addresses (possibly embedded in P2SH or P2WSH)\n"
" \"embedded\" : {...}, (object, optional) Information about the address embedded in P2SH or P2WSH, if relevant and known. It includes all getaddressinfo output fields for the embedded address, excluding metadata (\"timestamp\", \"hdkeypath\", \"hdmasterkeyid\") and relation to the wallet (\"ismine\", \"iswatchonly\", \"account\").\n"
" \"iscompressed\" : true|false, (boolean) If the address is compressed\n"
- " \"account\" : \"account\" (string) The account associated with the address, \"\" is the default account\n"
+ " \"label\" : \"label\" (string) The label associated with the address, \"\" is the default account\n"
+ " \"account\" : \"account\" (string) DEPRECATED. This field will be removed in V0.18. To see this deprecated field, start bitcoind with -deprecatedrpc=accounts. The account associated with the address, \"\" is the default account\n"
" \"timestamp\" : timestamp, (number, optional) The creation time of the key if available in seconds since epoch (Jan 1 1970 GMT)\n"
" \"hdkeypath\" : \"keypath\" (string, optional) The HD keypath if the key is HD and available\n"
" \"hdmasterkeyid\" : \"<hash160>\" (string, optional) The Hash160 of the HD master pubkey\n"
@@ -3819,7 +3980,10 @@ UniValue getaddressinfo(const JSONRPCRequest& request)
UniValue detail = DescribeWalletAddress(pwallet, dest);
ret.pushKVs(detail);
if (pwallet->mapAddressBook.count(dest)) {
- ret.pushKV("account", pwallet->mapAddressBook[dest].name);
+ ret.pushKV("label", pwallet->mapAddressBook[dest].name);
+ if (IsDeprecatedRPCEnabled("accounts")) {
+ ret.pushKV("account", pwallet->mapAddressBook[dest].name);
+ }
}
const CKeyMetadata* meta = nullptr;
CKeyID key_id = GetKeyForDestination(*pwallet, dest);
@@ -3994,16 +4158,14 @@ static const CRPCCommand commands[] =
{ "wallet", "keypoolrefill", &keypoolrefill, {"newsize"} },
{ "wallet", "listaddressgroupings", &listaddressgroupings, {} },
{ "wallet", "listlockunspent", &listlockunspent, {} },
- { "wallet", "listreceivedbylabel", &listreceivedbylabel, {"minconf","include_empty","include_watchonly"} },
- { "wallet", "listreceivedbyaccount", &listreceivedbylabel, {"minconf","include_empty","include_watchonly"} },
{ "wallet", "listreceivedbyaddress", &listreceivedbyaddress, {"minconf","include_empty","include_watchonly","address_filter"} },
{ "wallet", "listsinceblock", &listsinceblock, {"blockhash","target_confirmations","include_watchonly","include_removed"} },
- { "wallet", "listtransactions", &listtransactions, {"account","count","skip","include_watchonly"} },
+ { "wallet", "listtransactions", &listtransactions, {"account|dummy","count","skip","include_watchonly"} },
{ "wallet", "listunspent", &listunspent, {"minconf","maxconf","addresses","include_unsafe","query_options"} },
{ "wallet", "listwallets", &listwallets, {} },
{ "wallet", "lockunspent", &lockunspent, {"unlock","transactions"} },
{ "wallet", "sendfrom", &sendfrom, {"fromaccount","toaddress","amount","minconf","comment","comment_to"} },
- { "wallet", "sendmany", &sendmany, {"fromaccount","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} },
+ { "wallet", "sendmany", &sendmany, {"fromaccount|dummy","amounts","minconf","comment","subtractfeefrom","replaceable","conf_target","estimate_mode"} },
{ "wallet", "sendtoaddress", &sendtoaddress, {"address","amount","comment","comment_to","subtractfeefromamount","replaceable","conf_target","estimate_mode"} },
{ "wallet", "settxfee", &settxfee, {"amount"} },
{ "wallet", "signmessage", &signmessage, {"address","message"} },
diff --git a/test/functional/rpc_deprecated.py b/test/functional/rpc_deprecated.py
index b94b9d8fae..7b7c596506 100755
--- a/test/functional/rpc_deprecated.py
+++ b/test/functional/rpc_deprecated.py
@@ -4,12 +4,13 @@
# 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):
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
- self.extra_args = [[], ["-deprecatedrpc=validateaddress"]]
+ self.extra_args = [[], ["-deprecatedrpc=validateaddress", "-deprecatedrpc=accounts"]]
def run_test(self):
# This test should be used to verify correct behaviour of deprecated
@@ -20,11 +21,92 @@ class DeprecatedRpcTest(BitcoinTestFramework):
# self.nodes[1].createmultisig(1, [self.nodes[1].getnewaddress()])
self.log.info("Test validateaddress deprecation")
- SOME_ADDRESS = "mnvGjUy3NMj67yJ6gkK5o9e5RS33Z2Vqcu" # This is just some random address to pass as a parameter to validateaddress
+ SOME_ADDRESS = "mnvGjUy3NMj67yJ6gkK5o9e5RS33Z2Vqcu" # This is just some random address to pass as a parameter to validateaddress
dep_validate_address = self.nodes[0].validateaddress(SOME_ADDRESS)
assert "ismine" not in dep_validate_address
not_dep_val = self.nodes[1].validateaddress(SOME_ADDRESS)
assert "ismine" in not_dep_val
+ 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__':
DeprecatedRpcTest().main()
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index da43280ced..5e86e7ce64 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -70,7 +70,7 @@ BASE_SCRIPTS = [
'wallet_labels.py',
'p2p_segwit.py',
'wallet_dump.py',
- 'rpc_listtransactions.py',
+ 'wallet_listtransactions.py',
# vv Tests less than 60s vv
'p2p_sendheaders.py',
'wallet_zapwallettxes.py',
diff --git a/test/functional/wallet_basic.py b/test/functional/wallet_basic.py
index 0436aca6a4..bfe90957a7 100755
--- a/test/functional/wallet_basic.py
+++ b/test/functional/wallet_basic.py
@@ -10,9 +10,10 @@ class WalletTest(BitcoinTestFramework):
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)
@@ -376,9 +377,9 @@ class WalletTest(BitcoinTestFramework):
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 == [self.nodes[i].getblockcount() for i in range(3)])
@@ -426,7 +427,7 @@ class WalletTest(BitcoinTestFramework):
# Try with walletrejectlongchains
# 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)])
+ self.start_node(0, extra_args=["-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
index b66e9b5d91..6775d8b46d 100755
--- a/test/functional/wallet_import_rescan.py
+++ b/test/functional/wallet_import_rescan.py
@@ -119,7 +119,7 @@ class ImportRescanTest(BitcoinTestFramework):
self.num_nodes = 2 + len(IMPORT_NODES)
def setup_network(self):
- extra_args = [["-addresstype=legacy"] for _ in range(self.num_nodes)]
+ extra_args = [["-addresstype=legacy", '-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
index 5f5bfcf683..d0ec290f36 100755
--- a/test/functional/wallet_importprunedfunds.py
+++ b/test/functional/wallet_importprunedfunds.py
@@ -10,6 +10,7 @@ class ImportPrunedFundsTest(BitcoinTestFramework):
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
index 30a0c9a760..ab1493dd04 100755
--- a/test/functional/wallet_keypool_topup.py
+++ b/test/functional/wallet_keypool_topup.py
@@ -25,7 +25,7 @@ class KeypoolRestoreTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 2
- self.extra_args = [[], ['-keypool=100', '-keypoolmin=20']]
+ self.extra_args = [['-deprecatedrpc=accounts'], ['-deprecatedrpc=accounts', '-keypool=100', '-keypoolmin=20']]
def run_test(self):
wallet_path = os.path.join(self.nodes[1].datadir, "regtest", "wallets", "wallet.dat")
diff --git a/test/functional/wallet_labels.py b/test/functional/wallet_labels.py
index 90eefc0438..705dd8985e 100755
--- a/test/functional/wallet_labels.py
+++ b/test/functional/wallet_labels.py
@@ -6,25 +6,38 @@
RPCs tested are:
- getlabeladdress
- - getaddressesbyaccount
+ - getaddressesbyaccount/getaddressesbylabel
- listaddressgroupings
- setlabel
- sendfrom (with account arguments)
- move (with account arguments)
+
+Run the test twice - once using the accounts API and once using the labels API.
+The accounts API test can be removed in V0.18.
"""
from collections import defaultdict
from test_framework.test_framework import BitcoinTestFramework
-from test_framework.util import assert_equal
+from test_framework.util import assert_equal, assert_raises_rpc_error
class WalletLabelsTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
- self.num_nodes = 1
- self.extra_args = [[]]
+ self.num_nodes = 2
+ self.extra_args = [['-deprecatedrpc=accounts'], []]
+
+ def setup_network(self):
+ """Don't connect nodes."""
+ self.setup_nodes()
def run_test(self):
- node = self.nodes[0]
+ """Run the test twice - once using the accounts API and once using the labels API."""
+ self.log.info("Test accounts API")
+ self._run_subtest(True, self.nodes[0])
+ self.log.info("Test labels API")
+ self._run_subtest(False, self.nodes[1])
+
+ def _run_subtest(self, accounts_api, node):
# Check that there's no UTXO on any of the nodes
assert_equal(len(node.listunspent()), 0)
@@ -77,7 +90,7 @@ class WalletLabelsTest(BitcoinTestFramework):
# Create labels and make sure subsequent label API calls
# recognize the label/address associations.
- labels = [Label(name) for name in ("a", "b", "c", "d", "e")]
+ labels = [Label(name, accounts_api) for name in ("a", "b", "c", "d", "e")]
for label in labels:
label.add_receive_address(node.getlabeladdress(label=label.name, force=True))
label.verify(node)
@@ -101,21 +114,23 @@ class WalletLabelsTest(BitcoinTestFramework):
# Check that sendfrom label reduces listaccounts balances.
for i, label in enumerate(labels):
- to_label = labels[(i+1) % len(labels)]
+ to_label = labels[(i + 1) % len(labels)]
node.sendfrom(label.name, to_label.receive_address, amount_to_send)
node.generate(1)
for label in labels:
label.add_receive_address(node.getlabeladdress(label.name))
label.verify(node)
assert_equal(node.getreceivedbylabel(label.name), 2)
- node.move(label.name, "", node.getbalance(label.name))
+ if accounts_api:
+ node.move(label.name, "", node.getbalance(label.name))
label.verify(node)
node.generate(101)
expected_account_balances = {"": 5200}
for label in labels:
expected_account_balances[label.name] = 0
- assert_equal(node.listaccounts(), expected_account_balances)
- assert_equal(node.getbalance(""), 5200)
+ if accounts_api:
+ assert_equal(node.listaccounts(), expected_account_balances)
+ assert_equal(node.getbalance(""), 5200)
# Check that setlabel can assign a label to a new unused address.
for label in labels:
@@ -123,7 +138,10 @@ class WalletLabelsTest(BitcoinTestFramework):
node.setlabel(address, label.name)
label.add_address(address)
label.verify(node)
- assert(address not in node.getaddressesbyaccount(""))
+ if accounts_api:
+ assert(address not in node.getaddressesbyaccount(""))
+ else:
+ assert_raises_rpc_error(-11, "No addresses with label", node.getaddressesbylabel, "")
# Check that addmultisigaddress can assign labels.
for label in labels:
@@ -136,8 +154,9 @@ class WalletLabelsTest(BitcoinTestFramework):
label.verify(node)
node.sendfrom("", multisig_address, 50)
node.generate(101)
- for label in labels:
- assert_equal(node.getbalance(label.name), 50)
+ if accounts_api:
+ for label in labels:
+ assert_equal(node.getbalance(label.name), 50)
# Check that setlabel can change the label of an address from a
# different label.
@@ -156,9 +175,10 @@ class WalletLabelsTest(BitcoinTestFramework):
change_label(node, labels[2].receive_address, labels[2], labels[2])
class Label:
- def __init__(self, name):
+ def __init__(self, name, accounts_api):
# Label name
self.name = name
+ self.accounts_api = accounts_api
# Current receiving address associated with this label.
self.receive_address = None
# List of all addresses assigned with this label
@@ -184,13 +204,16 @@ class Label:
node.getaddressinfo(address)['labels'][0],
{"name": self.name,
"purpose": self.purpose[address]})
- assert_equal(node.getaccount(address), self.name)
+ if self.accounts_api:
+ assert_equal(node.getaccount(address), self.name)
+ else:
+ assert_equal(node.getaddressinfo(address)['label'], self.name)
assert_equal(
node.getaddressesbylabel(self.name),
{address: {"purpose": self.purpose[address]} for address in self.addresses})
- assert_equal(
- set(node.getaddressesbyaccount(self.name)), set(self.addresses))
+ if self.accounts_api:
+ assert_equal(set(node.getaddressesbyaccount(self.name)), set(self.addresses))
def change_label(node, address, old_label, new_label):
diff --git a/test/functional/wallet_listreceivedby.py b/test/functional/wallet_listreceivedby.py
index 7b34febddc..aba5d642bc 100755
--- a/test/functional/wallet_listreceivedby.py
+++ b/test/functional/wallet_listreceivedby.py
@@ -14,6 +14,7 @@ from test_framework.util import (assert_array_result,
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
index 0f2434ff0d..930bfcd7b0 100755
--- a/test/functional/wallet_listsinceblock.py
+++ b/test/functional/wallet_listsinceblock.py
@@ -11,6 +11,7 @@ class ListSinceBlockTest (BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
self.setup_clean_chain = True
+ self.extra_args = [['-deprecatedrpc=accounts']] * 4
def run_test(self):
self.nodes[2].generate(101)
diff --git a/test/functional/rpc_listtransactions.py b/test/functional/wallet_listtransactions.py
index 0dd7372e6b..5466bbf18b 100755
--- a/test/functional/rpc_listtransactions.py
+++ b/test/functional/wallet_listtransactions.py
@@ -18,6 +18,7 @@ def txFromHex(hexstring):
class ListTransactionsTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
+ self.extra_args = [['-deprecatedrpc=accounts']] * 2
self.enable_mocktime()
def run_test(self):
diff --git a/test/functional/wallet_txn_clone.py b/test/functional/wallet_txn_clone.py
index 7577c4a0d2..aee84f7e90 100755
--- a/test/functional/wallet_txn_clone.py
+++ b/test/functional/wallet_txn_clone.py
@@ -10,6 +10,7 @@ from test_framework.util import *
class TxnMallTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
+ self.extra_args = [['-deprecatedrpc=accounts']] * 4
def add_options(self, parser):
parser.add_option("--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
index 8419d6b545..d644a94c73 100755
--- a/test/functional/wallet_txn_doublespend.py
+++ b/test/functional/wallet_txn_doublespend.py
@@ -10,6 +10,7 @@ from test_framework.util import *
class TxnMallTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
+ self.extra_args = [['-deprecatedrpc=accounts']] * 4
def add_options(self, parser):
parser.add_option("--mineblock", dest="mine_block", default=False, action="store_true",