wallet: Reverse order of arguments to z_getaddressforaccount

We now use the empty array of pools to indicate that the default pools
should be used when providing a diversifier index parameter, instead of
needing a default sentinel value for the diversifier index parameter
(which was previously suggested as '*' which would have caused issues
for defining a consistent type for that parameter).
This commit is contained in:
Jack Grigg 2022-01-18 20:02:13 +00:00
parent ff0e9f6b95
commit 96c9333b74
2 changed files with 32 additions and 32 deletions

View File

@ -46,13 +46,13 @@ class WalletAccountsTest(BitcoinTestFramework):
# address in account 0; this is however not necessarily at diversifier index 0. # 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. # We should be able to generate it directly and get the exact same data.
j = addr0['diversifier_index'] 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: if j > 0:
# We should get an error if we generate the address at diversifier index 0. # We should get an error if we generate the address at diversifier index 0.
assert_raises_message( assert_raises_message(
JSONRPCException, JSONRPCException,
'no address at diversifier index 0', '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. # The first address for account 1 is different to account 0.
addr1 = self.nodes[0].z_getaddressforaccount(1) addr1 = self.nodes[0].z_getaddressforaccount(1)

View File

@ -3057,13 +3057,13 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp)
return NullUniValue; return NullUniValue;
if (fHelp || params.size() < 1 || params.size() > 3) if (fHelp || params.size() < 1 || params.size() > 3)
throw runtime_error( 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" "\nFor the given account number, derives a Unified Address in accordance"
"\nwith the remaining arguments:\n" "\nwith the remaining arguments:\n"
"\n- If no list of pools is given, the best and second-best shielded pools," "\n- If no list of pools is given (or the empty list \"[]\"), the best and"
"\n along with the transparent pool, will be used." "\n second-best shielded pools, along with the transparent pool, will be used."
"\n- If no diversifier index is given (or the string \"*\"), the next unused" "\n- If no diversifier index is given, the next unused index (that is valid"
"\n index (that is valid for the list of pools) will be selected.\n" "\n for the list of pools) will be selected.\n"
"\nThe account number must have been previously generated by a call to the" "\nThe account number must have been previously generated by a call to the"
"\nz_getnewaccount RPC method.\n" "\nz_getnewaccount RPC method.\n"
"\nOnce a Unified Address has been derived at a specific diversifier index," "\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" "}\n"
"\nExamples:\n" "\nExamples:\n"
+ HelpExampleCli("z_getaddressforaccount", "4") + HelpExampleCli("z_getaddressforaccount", "4")
+ HelpExampleCli("z_getaddressforaccount", "4 1") + HelpExampleCli("z_getaddressforaccount", "4 '[]' 1")
+ HelpExampleCli("z_getaddressforaccount", "4 1 '[\"transparent\",\"sapling\",\"orchard\"]'") + HelpExampleCli("z_getaddressforaccount", "4 '[\"transparent\",\"sapling\",\"orchard\"]' 1")
+ HelpExampleRpc("z_getaddressforaccount", "4") + HelpExampleRpc("z_getaddressforaccount", "4")
); );
@ -3096,28 +3096,9 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp)
} }
libzcash::AccountId account = accountInt; libzcash::AccountId account = accountInt;
std::optional<libzcash::diversifier_index_t> 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<libzcash::ReceiverType> receivers; std::set<libzcash::ReceiverType> receivers;
if (params.size() >= 3) { if (params.size() >= 2) {
const auto& pools = params[2].get_array(); const auto& pools = params[1].get_array();
for (unsigned int i = 0; i < pools.size(); i++) { for (unsigned int i = 0; i < pools.size(); i++) {
const std::string& p = pools[i].get_str(); const std::string& p = pools[i].get_str();
if (p == "transparent") { 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\""); 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. // Default is the best and second-best shielded pools, and the transparent pool.
receivers = {ReceiverType::P2PKH, ReceiverType::Sapling}; receivers = {ReceiverType::P2PKH, ReceiverType::Sapling};
} }
std::optional<libzcash::diversifier_index_t> 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(); EnsureWalletIsUnlocked();
// Generate the first UA for this account, using the best and next-best shielded pools // 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: case AddressGenerationError::ExistingAddressMismatch:
strErr = tfm::format( strErr = tfm::format(
"Error: address at diversifier index %s was already generated with different receiver types.", "Error: address at diversifier index %s was already generated with different receiver types.",
params[1].getValStr()); params[2].getValStr());
break; break;
case AddressGenerationError::NoAddressForDiversifier: case AddressGenerationError::NoAddressForDiversifier:
strErr = tfm::format( strErr = tfm::format(