Merge pull request #5671 from therealyingtong/ua-z_getbalance
z_getbalance: Handle Unified Address case.
This commit is contained in:
commit
5c9b7ec4df
|
@ -35,14 +35,19 @@ class WalletAccountsTest(BitcoinTestFramework):
|
||||||
# Remember that empty pools are omitted from the output.
|
# Remember that empty pools are omitted from the output.
|
||||||
def _check_balance_for_rpc(self, rpcmethod, node, account, expected, minconf):
|
def _check_balance_for_rpc(self, rpcmethod, node, account, expected, minconf):
|
||||||
rpc = getattr(self.nodes[node], rpcmethod)
|
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']))
|
assert_equal(set(expected), set(actual['pools']))
|
||||||
|
total_balance = 0
|
||||||
for pool in expected:
|
for pool in expected:
|
||||||
assert_equal(expected[pool] * COIN, actual['pools'][pool]['valueZat'])
|
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):
|
def check_balance(self, node, account, address, expected, minconf=1):
|
||||||
self._check_balance_for_rpc('z_getbalanceforaccount', node, account, expected, minconf)
|
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)
|
fvk = self.nodes[node].z_exportviewingkey(address)
|
||||||
self._check_balance_for_rpc('z_getbalanceforviewingkey', node, fvk, expected, minconf)
|
self._check_balance_for_rpc('z_getbalanceforviewingkey', node, fvk, expected, minconf)
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,8 @@ class WalletShieldCoinbaseUANU5(WalletShieldCoinbaseTest):
|
||||||
assert('transparent' not in balances['pools'])
|
assert('transparent' not in balances['pools'])
|
||||||
assert('sprout' not in balances['pools'])
|
assert('sprout' not in balances['pools'])
|
||||||
# assert('sapling' 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)
|
# assert_equal(balances['pools']['orchard']['valueZat'], expected * COIN)
|
||||||
|
|
||||||
# While we're at it, check that z_listunspent only shows outputs with
|
# 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],
|
[{'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__':
|
if __name__ == '__main__':
|
||||||
print("Test shielding to a unified address with NU5 activated")
|
print("Test shielding to a unified address with NU5 activated")
|
||||||
|
|
|
@ -21,7 +21,8 @@ class WalletShieldCoinbaseUASapling(WalletShieldCoinbaseTest):
|
||||||
balances = node.z_getbalanceforaccount(self.account)
|
balances = node.z_getbalanceforaccount(self.account)
|
||||||
assert('transparent' not in balances['pools'])
|
assert('transparent' not in balances['pools'])
|
||||||
assert('sprout' 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'])
|
assert('orchard' not in balances['pools'])
|
||||||
|
|
||||||
# While we're at it, check that z_listunspent only shows outputs with
|
# 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],
|
[{'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__':
|
if __name__ == '__main__':
|
||||||
print("Test shielding to a unified address with sapling activated (but not NU5)")
|
print("Test shielding to a unified address with sapling activated (but not NU5)")
|
||||||
|
|
|
@ -27,14 +27,19 @@ class WalletZSendmanyTest(BitcoinTestFramework):
|
||||||
# Remember that empty pools are omitted from the output.
|
# Remember that empty pools are omitted from the output.
|
||||||
def _check_balance_for_rpc(self, rpcmethod, node, account, expected, minconf):
|
def _check_balance_for_rpc(self, rpcmethod, node, account, expected, minconf):
|
||||||
rpc = getattr(self.nodes[node], rpcmethod)
|
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']))
|
assert_equal(set(expected), set(actual['pools']))
|
||||||
|
total_balance = 0
|
||||||
for pool in expected:
|
for pool in expected:
|
||||||
assert_equal(expected[pool] * COIN, actual['pools'][pool]['valueZat'])
|
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):
|
def check_balance(self, node, account, address, expected, minconf=1):
|
||||||
self._check_balance_for_rpc('z_getbalanceforaccount', node, account, expected, minconf)
|
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)
|
fvk = self.nodes[node].z_exportviewingkey(address)
|
||||||
self._check_balance_for_rpc('z_getbalanceforviewingkey', node, fvk, expected, minconf)
|
self._check_balance_for_rpc('z_getbalanceforviewingkey', node, fvk, expected, minconf)
|
||||||
|
|
||||||
|
|
|
@ -3649,11 +3649,10 @@ UniValue z_getbalance(const UniValue& params, bool fHelp)
|
||||||
if (fHelp || params.size() == 0 || params.size() > 3)
|
if (fHelp || params.size() == 0 || params.size() > 3)
|
||||||
throw runtime_error(
|
throw runtime_error(
|
||||||
"z_getbalance \"address\" ( minconf inZat )\n"
|
"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"
|
"\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"
|
"\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."
|
"\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"
|
"\nArguments:\n"
|
||||||
"1. \"address\" (string) The selected address. It may be a transparent or shielded address.\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"
|
"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);
|
nBalance = getBalanceZaddr(addr, nMinDepth, INT_MAX, false);
|
||||||
},
|
},
|
||||||
[&](const libzcash::UnifiedAddress& addr) {
|
[&](const libzcash::UnifiedAddress& addr) {
|
||||||
|
auto selector = pwalletMain->ZTXOSelectorForAddress(addr, true);
|
||||||
|
if (!selector.has_value()) {
|
||||||
throw JSONRPCError(
|
throw JSONRPCError(
|
||||||
RPC_INVALID_ADDRESS_OR_KEY,
|
RPC_INVALID_ADDRESS_OR_KEY,
|
||||||
"Unified addresses are not yet supported for z_getbalance.");
|
"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());
|
}, pa.value());
|
||||||
|
|
||||||
|
|
|
@ -6341,6 +6341,9 @@ NoteFilter NoteFilter::ForPaymentAddresses(const std::vector<libzcash::PaymentAd
|
||||||
[&](const libzcash::UnifiedAddress& uaddr) {
|
[&](const libzcash::UnifiedAddress& uaddr) {
|
||||||
for (auto& receiver : uaddr) {
|
for (auto& receiver : uaddr) {
|
||||||
std::visit(match {
|
std::visit(match {
|
||||||
|
[&](const libzcash::OrchardRawAddress& addr) {
|
||||||
|
addrs.orchardAddresses.insert(addr);
|
||||||
|
},
|
||||||
[&](const libzcash::SaplingPaymentAddress& addr) {
|
[&](const libzcash::SaplingPaymentAddress& addr) {
|
||||||
addrs.saplingAddresses.insert(addr);
|
addrs.saplingAddresses.insert(addr);
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue