From 1914effbbb5316ecf933fd24809eae0e67f3d419 Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Fri, 20 Oct 2017 13:27:55 -0400 Subject: [PATCH 01/11] Merge bitcoin#11536: Rename account to label where appropriate d2527bd Rename wallet_accounts.py test (Russell Yanofsky) 045eeb8 Rename account to label where appropriate (Russell Yanofsky) Pull request description: Rename account to label where appropriate This change only updates strings and adds RPC aliases, but should simplify the implementation of address labels in #7729, by getting renaming out of the way and letting that change focus on semantics. The difference between accounts and labels is that labels apply only to addresses, while accounts apply to both addresses and transactions (transactions have "from" and "to" accounts). The code associating accounts with transactions is clumsy and unreliable so we would like get rid of it. --- There is a rebased version of #7729 atop this PR at https://github.com/ryanofsky/bitcoin/commits/pr/label, see #7729 (comment). Tree-SHA512: b3f934e612922d6290f50137f8ba71ddfaea4485713c7d97e89400a8b73b09b254f9186dffa462c77f5847721f5af9852b5572ade5443d8ee95dd150b3edb7ff --- src/rpc/client.cpp | 6 + src/rpc/protocol.h | 4 +- src/wallet/rpcwallet.cpp | 206 +++++++++++----------- src/wallet/wallet.cpp | 22 +-- src/wallet/wallet.h | 6 +- test/functional/test_runner.py | 2 +- test/functional/wallet_accounts.py | 208 ----------------------- test/functional/wallet_import_rescan.py | 2 +- test/functional/wallet_labels.py | 208 +++++++++++++++++++++++ test/functional/wallet_listreceivedby.py | 60 +++---- 10 files changed, 369 insertions(+), 355 deletions(-) delete mode 100755 test/functional/wallet_accounts.py create mode 100755 test/functional/wallet_labels.py diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 5ab6f86264c34..ef0a819cfd1c8 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -46,6 +46,8 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getreceivedbyaddress", 2, "addlocked" }, { "getreceivedbyaccount", 1, "minconf" }, { "getreceivedbyaccount", 2, "addlocked" }, + { "getreceivedbylabel", 1, "minconf" }, + { "getreceivedbylabel", 2, "addlocked" }, { "listaddressbalances", 0, "minamount" }, { "listreceivedbyaddress", 0, "minconf" }, { "listreceivedbyaddress", 1, "addlocked" }, @@ -56,6 +58,10 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listreceivedbyaccount", 1, "addlocked" }, { "listreceivedbyaccount", 2, "include_empty" }, { "listreceivedbyaccount", 3, "include_watchonly" }, + { "listreceivedbylabel", 0, "minconf" }, + { "listreceivedbylabel", 1, "addlocked" }, + { "listreceivedbylabel", 2, "include_empty" }, + { "listreceivedbylabel", 3, "include_watchonly" }, { "getbalance", 1, "minconf" }, { "getbalance", 2, "addlocked" }, { "getbalance", 3, "include_watchonly" }, diff --git a/src/rpc/protocol.h b/src/rpc/protocol.h index 5c545e0da89c4..dfb0289219109 100644 --- a/src/rpc/protocol.h +++ b/src/rpc/protocol.h @@ -76,7 +76,7 @@ enum RPCErrorCode //! Wallet errors RPC_WALLET_ERROR = -4, //!< Unspecified problem with wallet (key not found etc.) RPC_WALLET_INSUFFICIENT_FUNDS = -6, //!< Not enough funds in wallet or account - RPC_WALLET_INVALID_ACCOUNT_NAME = -11, //!< Invalid account name + RPC_WALLET_INVALID_LABEL_NAME = -11, //!< Invalid label name RPC_WALLET_KEYPOOL_RAN_OUT = -12, //!< Keypool ran out, call keypoolrefill first RPC_WALLET_UNLOCK_NEEDED = -13, //!< Enter the wallet passphrase with walletpassphrase first RPC_WALLET_PASSPHRASE_INCORRECT = -14, //!< The wallet passphrase entered was incorrect @@ -87,6 +87,8 @@ enum RPCErrorCode RPC_WALLET_NOT_SPECIFIED = -19, //!< No wallet specified (error when there are multiple wallets loaded) + //! Backwards compatible aliases + RPC_WALLET_INVALID_ACCOUNT_NAME = RPC_WALLET_INVALID_LABEL_NAME, //! Unused reserved codes, kept around for backwards compatibility. Do not reuse. RPC_FORBIDDEN_BY_SAFE_MODE = -2, //!< Server is in safe mode, and command is not allowed in safe mode }; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index d7d4d0028c633..4aa8a51bc61e7 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -124,12 +124,12 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) entry.pushKV(item.first, item.second); } -std::string AccountFromValue(const UniValue& value) +std::string LabelFromValue(const UniValue& value) { - std::string strAccount = value.get_str(); - if (strAccount == "*") - throw JSONRPCError(RPC_WALLET_INVALID_ACCOUNT_NAME, "Invalid account name"); - return strAccount; + std::string label = value.get_str(); + if (label == "*") + throw JSONRPCError(RPC_WALLET_INVALID_LABEL_NAME, "Invalid label name"); + return label; } UniValue getnewaddress(const JSONRPCRequest& request) @@ -141,12 +141,12 @@ UniValue getnewaddress(const JSONRPCRequest& request) if (request.fHelp || request.params.size() > 1) throw std::runtime_error( - "getnewaddress ( \"account\" )\n" + "getnewaddress ( \"label\" )\n" "\nReturns a new Dash address for receiving payments.\n" - "If 'account' is specified (DEPRECATED), it is added to the address book \n" - "so payments received with the address will be credited to 'account'.\n" + "If 'label' is specified, it is added to the address book \n" + "so payments received with the address will be associated with 'label'.\n" "\nArguments:\n" - "1. \"account\" (string, optional) DEPRECATED. The account name for the address to be linked to. If not provided, the default account \"\" is used. 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 if there is no account by the given name.\n" + "1. \"label\" (string, optional) The label name for the address to be linked to. If not provided, the default label \"\" is used. It can also be set to the empty string \"\" to represent the default label. The label does not need to exist, it will be created if there is no label by the given name.\n" "\nResult:\n" "\"address\" (string) The new dash address\n" "\nExamples:\n" @@ -156,10 +156,10 @@ UniValue getnewaddress(const JSONRPCRequest& request) LOCK2(cs_main, pwallet->cs_wallet); - // Parse the account first so we don't generate a key if there's an error - std::string strAccount; + // Parse the label first so we don't generate a key if there's an error + std::string label; if (!request.params[0].isNull()) - strAccount = AccountFromValue(request.params[0]); + label = LabelFromValue(request.params[0]); if (!pwallet->IsLocked(true)) { pwallet->TopUpKeyPool(); @@ -172,23 +172,23 @@ UniValue getnewaddress(const JSONRPCRequest& request) } CKeyID keyID = newKey.GetID(); - pwallet->SetAddressBook(keyID, strAccount, "receive"); + pwallet->SetAddressBook(keyID, label, "receive"); return EncodeDestination(keyID); } -CTxDestination GetAccountDestination(CWallet* const pwallet, std::string strAccount, bool bForceNew=false) +CTxDestination GetLabelDestination(CWallet* const pwallet, const std::string& label, bool bForceNew=false) { CTxDestination dest; - if (!pwallet->GetAccountDestination(dest, strAccount, bForceNew)) { + if (!pwallet->GetLabelDestination(dest, label, bForceNew)) { throw JSONRPCError(RPC_WALLET_KEYPOOL_RAN_OUT, "Error: Keypool ran out, please call keypoolrefill first"); } return dest; } -UniValue getaccountaddress(const JSONRPCRequest& request) +UniValue getlabeladdress(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { @@ -197,27 +197,27 @@ UniValue getaccountaddress(const JSONRPCRequest& request) if (request.fHelp || request.params.size() != 1) throw std::runtime_error( - "getaccountaddress \"account\"\n" - "\nDEPRECATED. Returns the current Dash address for receiving payments to this account.\n" + "getlabeladdress \"label\"\n" + "\nReturns the current Dash address for receiving payments to this label.\n" "\nArguments:\n" - "1. \"account\" (string, required) The account name 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" + "1. \"label\" (string, required) The label name for the address. It can also be set to the empty string \"\" to represent the default label. The label does not need to exist, it will be created and a new address created if there is no label by the given name.\n" "\nResult:\n" - "\"address\" (string) The account dash address\n" + "\"address\" (string) The label dash address\n" "\nExamples:\n" - + HelpExampleCli("getaccountaddress", "") - + HelpExampleCli("getaccountaddress", "\"\"") - + HelpExampleCli("getaccountaddress", "\"myaccount\"") - + HelpExampleRpc("getaccountaddress", "\"myaccount\"") + + HelpExampleCli("getlabeladdress", "") + + HelpExampleCli("getlabeladdress", "\"\"") + + HelpExampleCli("getlabeladdress", "\"mylabel\"") + + HelpExampleRpc("getlabeladdress", "\"mylabel\"") ); LOCK2(cs_main, pwallet->cs_wallet); - // Parse the account first so we don't generate a key if there's an error - std::string strAccount = AccountFromValue(request.params[0]); + // Parse the label first so we don't generate a key if there's an error + std::string label = LabelFromValue(request.params[0]); UniValue ret(UniValue::VSTR); - ret = EncodeDestination(GetAccountDestination(pwallet, strAccount)); + ret = EncodeDestination(GetLabelDestination(pwallet, label)); return ret; } @@ -260,7 +260,7 @@ UniValue getrawchangeaddress(const JSONRPCRequest& request) } -UniValue setaccount(const JSONRPCRequest& request) +UniValue setlabel(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { @@ -269,14 +269,14 @@ UniValue setaccount(const JSONRPCRequest& request) if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) throw std::runtime_error( - "setaccount \"address\" \"account\"\n" - "\nDEPRECATED. Sets the account associated with the given address.\n" + "setlabel \"address\" \"label\"\n" + "\nSets the label associated with the given address.\n" "\nArguments:\n" - "1. \"address\" (string, required) The dash address to be associated with an account.\n" - "2. \"account\" (string, required) The account to assign the address to.\n" + "1. \"address\" (string, required) The dash address to be associated with a label.\n" + "2. \"label\" (string, required) The label to assign the address to.\n" "\nExamples:\n" - + HelpExampleCli("setaccount", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" \"tabby\"") - + HelpExampleRpc("setaccount", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\", \"tabby\"") + + HelpExampleCli("setlabel", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\" \"tabby\"") + + HelpExampleRpc("setlabel", "\"XwnLY9Tf7Zsef8gMGL2fhWA9ZmMjt4KPwG\", \"tabby\"") ); LOCK2(cs_main, pwallet->cs_wallet); @@ -286,23 +286,23 @@ UniValue setaccount(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid Dash address"); } - std::string strAccount; + std::string label; if (!request.params[1].isNull()) - strAccount = AccountFromValue(request.params[1]); + label = LabelFromValue(request.params[1]); - // Only add the account if the address is yours. + // Only add the label if the address is yours. if (IsMine(*pwallet, dest)) { - // Detect when changing the account of an address that is the 'unused current key' of another account: + // Detect when changing the label of an address that is the 'unused current key' of another label: if (pwallet->mapAddressBook.count(dest)) { - std::string strOldAccount = pwallet->mapAddressBook[dest].name; - if (dest == GetAccountDestination(pwallet, strOldAccount)) { - GetAccountDestination(pwallet, strOldAccount, true); + std::string old_label = pwallet->mapAddressBook[dest].name; + if (dest == GetLabelDestination(pwallet, old_label)) { + GetLabelDestination(pwallet, old_label, true); } } - pwallet->SetAddressBook(dest, strAccount, "receive"); + pwallet->SetAddressBook(dest, label, "receive"); } else - throw JSONRPCError(RPC_MISC_ERROR, "setaccount can only be used with own address"); + throw JSONRPCError(RPC_MISC_ERROR, "setlabel can only be used with own address"); return NullUniValue; } @@ -369,7 +369,7 @@ UniValue getaddressesbyaccount(const JSONRPCRequest& request) LOCK2(cs_main, pwallet->cs_wallet); - std::string strAccount = AccountFromValue(request.params[0]); + std::string strAccount = LabelFromValue(request.params[0]); // Find all addresses that have the given account UniValue ret(UniValue::VARR); @@ -545,7 +545,7 @@ UniValue listaddressgroupings(const JSONRPCRequest& request) " [\n" " \"address\", (string) The dash address\n" " amount, (numeric) The amount in " + CURRENCY_UNIT + "\n" - " \"account\" (string, optional) DEPRECATED. The account\n" + " \"label\" (string, optional) The label\n" " ]\n" " ,...\n" " ]\n" @@ -753,7 +753,7 @@ UniValue getreceivedbyaddress(const JSONRPCRequest& request) } -UniValue getreceivedbyaccount(const JSONRPCRequest& request) +UniValue getreceivedbylabel(const JSONRPCRequest& request) { CWallet * const pwallet = GetWalletForJSONRPCRequest(request); if (!EnsureWalletIsAvailable(pwallet, request.fHelp)) { @@ -762,23 +762,23 @@ UniValue getreceivedbyaccount(const JSONRPCRequest& request) if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) throw std::runtime_error( - "getreceivedbyaccount \"account\" ( minconf addlocked )\n" - "\nDEPRECATED. Returns the total amount received by addresses with in transactions with specified minimum number of confirmations.\n" + "getreceivedbylabel \"account\" ( minconf addlocked )\n" + "\nReturns the total amount received by addresses with