diff --git a/qa/rpc-tests/wallet_accounts.py b/qa/rpc-tests/wallet_accounts.py index 779af5c32..f693599c0 100755 --- a/qa/rpc-tests/wallet_accounts.py +++ b/qa/rpc-tests/wallet_accounts.py @@ -46,13 +46,13 @@ class WalletAccountsTest(BitcoinTestFramework): # address in account 0; this is however not necessarily at diversifier index 0. # We should be able to generate it directly and get the exact same data. j = addr0['diversifier_index'] - assert_equal(self.nodes[0].z_getaddressforaccount(0, j), addr0) + assert_equal(self.nodes[0].z_getaddressforaccount(0, [], j), addr0) if j > 0: # We should get an error if we generate the address at diversifier index 0. assert_raises_message( JSONRPCException, 'no address at diversifier index 0', - self.nodes[0].z_getaddressforaccount, 0, 0) + self.nodes[0].z_getaddressforaccount, 0, [], 0) # The first address for account 1 is different to account 0. addr1 = self.nodes[0].z_getaddressforaccount(1) diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 1ae42b106..01461035f 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3057,13 +3057,13 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp) return NullUniValue; if (fHelp || params.size() < 1 || params.size() > 3) throw runtime_error( - "z_getaddressforaccount account ( diversifier_index [\"pool\", ...] )\n" + "z_getaddressforaccount account ( [\"pool\", ...] diversifier_index )\n" "\nFor the given account number, derives a Unified Address in accordance" "\nwith the remaining arguments:\n" - "\n- If no list of pools is given, the best and second-best shielded pools," - "\n along with the transparent pool, will be used." - "\n- If no diversifier index is given (or the string \"*\"), the next unused" - "\n index (that is valid for the list of pools) will be selected.\n" + "\n- If no list of pools is given (or the empty list \"[]\"), the best and" + "\n second-best shielded pools, along with the transparent pool, will be used." + "\n- If no diversifier index is given, the next unused index (that is valid" + "\n for the list of pools) will be selected.\n" "\nThe account number must have been previously generated by a call to the" "\nz_getnewaccount RPC method.\n" "\nOnce a Unified Address has been derived at a specific diversifier index," @@ -3079,8 +3079,8 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp) "}\n" "\nExamples:\n" + HelpExampleCli("z_getaddressforaccount", "4") - + HelpExampleCli("z_getaddressforaccount", "4 1") - + HelpExampleCli("z_getaddressforaccount", "4 1 '[\"transparent\",\"sapling\",\"orchard\"]'") + + HelpExampleCli("z_getaddressforaccount", "4 '[]' 1") + + HelpExampleCli("z_getaddressforaccount", "4 '[\"transparent\",\"sapling\",\"orchard\"]' 1") + HelpExampleRpc("z_getaddressforaccount", "4") ); @@ -3096,28 +3096,9 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp) } libzcash::AccountId account = accountInt; - std::optional j = std::nullopt; - if (params.size() >= 2) { - // TODO: Handle '*' - if (params[1].getType() != UniValue::VNUM) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid diversifier index, must be an unsigned integer."); - } - auto parsed_diversifier_index_opt = ParseArbitraryInt(params[1].getValStr()); - if (!parsed_diversifier_index_opt.has_value()) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "diversifier index must be a decimal integer."); - } - auto parsed_diversifier_index = parsed_diversifier_index_opt.value(); - if (parsed_diversifier_index.size() > ZC_DIVERSIFIER_SIZE) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "diversifier index is too large."); - } - // Extend the byte array to the correct length for diversifier_index_t. - parsed_diversifier_index.resize(ZC_DIVERSIFIER_SIZE); - j = libzcash::diversifier_index_t(parsed_diversifier_index); - } - std::set receivers; - if (params.size() >= 3) { - const auto& pools = params[2].get_array(); + if (params.size() >= 2) { + const auto& pools = params[1].get_array(); for (unsigned int i = 0; i < pools.size(); i++) { const std::string& p = pools[i].get_str(); if (p == "transparent") { @@ -3128,11 +3109,30 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_PARAMETER, "pool arguments must be \"transparent\", or \"sapling\""); } } - } else { + } + if (receivers.empty()) { // Default is the best and second-best shielded pools, and the transparent pool. receivers = {ReceiverType::P2PKH, ReceiverType::Sapling}; } + std::optional j = std::nullopt; + if (params.size() >= 3) { + if (params[2].getType() != UniValue::VNUM) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid diversifier index, must be an unsigned integer."); + } + auto parsed_diversifier_index_opt = ParseArbitraryInt(params[2].getValStr()); + if (!parsed_diversifier_index_opt.has_value()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "diversifier index must be a decimal integer."); + } + auto parsed_diversifier_index = parsed_diversifier_index_opt.value(); + if (parsed_diversifier_index.size() > ZC_DIVERSIFIER_SIZE) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "diversifier index is too large."); + } + // Extend the byte array to the correct length for diversifier_index_t. + parsed_diversifier_index.resize(ZC_DIVERSIFIER_SIZE); + j = libzcash::diversifier_index_t(parsed_diversifier_index); + } + EnsureWalletIsUnlocked(); // Generate the first UA for this account, using the best and next-best shielded pools @@ -3158,7 +3158,7 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp) case AddressGenerationError::ExistingAddressMismatch: strErr = tfm::format( "Error: address at diversifier index %s was already generated with different receiver types.", - params[1].getValStr()); + params[2].getValStr()); break; case AddressGenerationError::NoAddressForDiversifier: strErr = tfm::format(