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.
# 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)

View File

@ -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<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;
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<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();
// 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(