Merge pull request #5671 from therealyingtong/ua-z_getbalance

z_getbalance: Handle Unified Address case.
This commit is contained in:
Kris Nuttycombe 2022-03-15 19:29:37 -06:00 committed by GitHub
commit 5c9b7ec4df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 47 additions and 15 deletions

View File

@ -35,14 +35,19 @@ class WalletAccountsTest(BitcoinTestFramework):
# Remember that empty pools are omitted from the output.
def _check_balance_for_rpc(self, rpcmethod, node, account, expected, minconf):
rpc = getattr(self.nodes[node], rpcmethod)
actual = rpc(account) if minconf is None else rpc(account, minconf)
actual = rpc(account, minconf)
assert_equal(set(expected), set(actual['pools']))
total_balance = 0
for pool in expected:
assert_equal(expected[pool] * COIN, actual['pools'][pool]['valueZat'])
assert_equal(actual['minimum_confirmations'], 1 if minconf is None else minconf)
total_balance += expected[pool]
assert_equal(actual['minimum_confirmations'], minconf)
return total_balance
def check_balance(self, node, account, address, expected, minconf=None):
self._check_balance_for_rpc('z_getbalanceforaccount', node, account, expected, minconf)
def check_balance(self, node, account, address, expected, minconf=1):
acct_balance = self._check_balance_for_rpc('z_getbalanceforaccount', node, account, expected, minconf)
z_getbalance = self.nodes[node].z_getbalance(address, minconf)
assert_equal(acct_balance, z_getbalance)
fvk = self.nodes[node].z_exportviewingkey(address)
self._check_balance_for_rpc('z_getbalanceforviewingkey', node, fvk, expected, minconf)

View File

@ -23,7 +23,8 @@ class WalletShieldCoinbaseUANU5(WalletShieldCoinbaseTest):
assert('transparent' not in balances['pools'])
assert('sprout' not in balances['pools'])
# assert('sapling' not in balances['pools'])
assert_equal(balances['pools']['sapling']['valueZat'], expected * COIN)
sapling_balance = balances['pools']['sapling']['valueZat']
assert_equal(sapling_balance, expected * COIN)
# assert_equal(balances['pools']['orchard']['valueZat'], expected * COIN)
# While we're at it, check that z_listunspent only shows outputs with
@ -35,6 +36,8 @@ class WalletShieldCoinbaseUANU5(WalletShieldCoinbaseTest):
[{'type': x['type'], 'address': x['address']} for x in unspent],
)
total_balance = node.z_getbalance(self.addr) * COIN
assert_equal(total_balance, sapling_balance)
if __name__ == '__main__':
print("Test shielding to a unified address with NU5 activated")

View File

@ -21,7 +21,8 @@ class WalletShieldCoinbaseUASapling(WalletShieldCoinbaseTest):
balances = node.z_getbalanceforaccount(self.account)
assert('transparent' not in balances['pools'])
assert('sprout' not in balances['pools'])
assert_equal(balances['pools']['sapling']['valueZat'], expected * COIN)
sapling_balance = balances['pools']['sapling']['valueZat']
assert_equal(sapling_balance, expected * COIN)
assert('orchard' not in balances['pools'])
# While we're at it, check that z_listunspent only shows outputs with
@ -33,6 +34,8 @@ class WalletShieldCoinbaseUASapling(WalletShieldCoinbaseTest):
[{'type': x['type'], 'address': x['address']} for x in unspent],
)
total_balance = node.z_getbalance(self.addr) * COIN
assert_equal(total_balance, sapling_balance)
if __name__ == '__main__':
print("Test shielding to a unified address with sapling activated (but not NU5)")

View File

@ -27,14 +27,19 @@ class WalletZSendmanyTest(BitcoinTestFramework):
# Remember that empty pools are omitted from the output.
def _check_balance_for_rpc(self, rpcmethod, node, account, expected, minconf):
rpc = getattr(self.nodes[node], rpcmethod)
actual = rpc(account) if minconf is None else rpc(account, minconf)
actual = rpc(account, minconf)
assert_equal(set(expected), set(actual['pools']))
total_balance = 0
for pool in expected:
assert_equal(expected[pool] * COIN, actual['pools'][pool]['valueZat'])
assert_equal(actual['minimum_confirmations'], 1 if minconf is None else minconf)
total_balance += expected[pool]
assert_equal(actual['minimum_confirmations'], minconf)
return total_balance
def check_balance(self, node, account, address, expected, minconf=None):
self._check_balance_for_rpc('z_getbalanceforaccount', node, account, expected, minconf)
def check_balance(self, node, account, address, expected, minconf=1):
acct_balance = self._check_balance_for_rpc('z_getbalanceforaccount', node, account, expected, minconf)
z_getbalance = self.nodes[node].z_getbalance(address, minconf)
assert_equal(acct_balance, z_getbalance)
fvk = self.nodes[node].z_exportviewingkey(address)
self._check_balance_for_rpc('z_getbalanceforviewingkey', node, fvk, expected, minconf)

View File

@ -3649,11 +3649,10 @@ UniValue z_getbalance(const UniValue& params, bool fHelp)
if (fHelp || params.size() == 0 || params.size() > 3)
throw runtime_error(
"z_getbalance \"address\" ( minconf inZat )\n"
"\nDEPRECATED\n"
"\nDEPRECATED; please use z_getbalanceforviewingkey instead.`\n"
"\nReturns the balance of a taddr or zaddr belonging to the node's wallet.\n"
"\nCAUTION: If the wallet has only an incoming viewing key for this address, then spends cannot be"
"\ndetected, and so the returned balance may be larger than the actual balance."
"\nThe argument address may not be a Unified Address; please use z_getbalanceforviewingkey instead.\n"
"\nArguments:\n"
"1. \"address\" (string) The selected address. It may be a transparent or shielded address.\n"
"2. minconf (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n"
@ -3706,9 +3705,23 @@ UniValue z_getbalance(const UniValue& params, bool fHelp)
nBalance = getBalanceZaddr(addr, nMinDepth, INT_MAX, false);
},
[&](const libzcash::UnifiedAddress& addr) {
throw JSONRPCError(
RPC_INVALID_ADDRESS_OR_KEY,
"Unified addresses are not yet supported for z_getbalance.");
auto selector = pwalletMain->ZTXOSelectorForAddress(addr, true);
if (!selector.has_value()) {
throw JSONRPCError(
RPC_INVALID_ADDRESS_OR_KEY,
"Unified address does not correspond to an account in the wallet");
}
auto spendableInputs = pwalletMain->FindSpendableInputs(selector.value(), true, nMinDepth);
for (const auto& t : spendableInputs.utxos) {
nBalance += t.Value();
}
for (const auto& t : spendableInputs.saplingNoteEntries) {
nBalance += t.note.value();
}
for (const auto& t : spendableInputs.orchardNoteMetadata) {
nBalance += t.GetNoteValue();
}
},
}, pa.value());

View File

@ -6341,6 +6341,9 @@ NoteFilter NoteFilter::ForPaymentAddresses(const std::vector<libzcash::PaymentAd
[&](const libzcash::UnifiedAddress& uaddr) {
for (auto& receiver : uaddr) {
std::visit(match {
[&](const libzcash::OrchardRawAddress& addr) {
addrs.orchardAddresses.insert(addr);
},
[&](const libzcash::SaplingPaymentAddress& addr) {
addrs.saplingAddresses.insert(addr);
},