wallet: Show UAs owned by the wallet in `z_viewtransaction`

Part of zcash/zcash#5186.
This commit is contained in:
Jack Grigg 2022-01-14 15:34:46 +00:00
parent baaa3c4ac0
commit ff0e9f6b95
2 changed files with 56 additions and 2 deletions

View File

@ -8,9 +8,13 @@ from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
assert_raises_message,
get_coinbase_address,
start_nodes,
wait_and_assert_operationid_status,
)
from decimal import Decimal
# Test wallet accounts behaviour
class WalletAccountsTest(BitcoinTestFramework):
def setup_nodes(self):
@ -61,6 +65,36 @@ class WalletAccountsTest(BitcoinTestFramework):
self.check_receiver_types(ua0, ['transparent', 'sapling'])
self.check_receiver_types(ua1, ['transparent', 'sapling'])
# Manually send funds to one of the receivers in the UA.
# TODO: Once z_sendmany supports UAs, receive to the UA instead of the receiver.
sapling0 = self.nodes[0].z_listunifiedreceivers(ua0)['sapling']
recipients = [{'address': sapling0, 'amount': Decimal('10')}]
opid = self.nodes[0].z_sendmany(get_coinbase_address(self.nodes[0]), recipients, 1, 0)
txid = wait_and_assert_operationid_status(self.nodes[0], opid)
# The wallet should detect the new note as belonging to the UA.
tx_details = self.nodes[0].z_viewtransaction(txid)
assert_equal(len(tx_details['outputs']), 1)
assert_equal(tx_details['outputs'][0]['type'], 'sapling')
assert_equal(tx_details['outputs'][0]['address'], ua0)
self.sync_all()
self.nodes[2].generate(1)
self.sync_all()
# Manually send funds from the UA receiver.
# TODO: Once z_sendmany supports UAs, send from the UA instead of the receiver.
node1sapling = self.nodes[1].z_getnewaddress('sapling')
recipients = [{'address': node1sapling, 'amount': Decimal('1')}]
opid = self.nodes[0].z_sendmany(sapling0, recipients, 1, 0)
txid = wait_and_assert_operationid_status(self.nodes[0], opid)
# The wallet should detect the spent note as belonging to the UA.
tx_details = self.nodes[0].z_viewtransaction(txid)
assert_equal(len(tx_details['spends']), 1)
assert_equal(tx_details['spends'][0]['type'], 'sapling')
assert_equal(tx_details['spends'][0]['address'], ua0)
if __name__ == '__main__':
WalletAccountsTest().main()

View File

@ -3959,12 +3959,22 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp)
assert(pwalletMain->GetSaplingFullViewingKey(wtxPrev.mapSaplingNoteData.at(op).ivk, extfvk));
ovks.insert(extfvk.fvk.ovk);
// If the note belongs to a Sapling address that is part of an account in the
// wallet, show the corresponding Unified Address.
std::string address;
const auto ua = pwalletMain->GetUnifiedForReceiver(pa);
if (ua.has_value()) {
address = keyIO.EncodePaymentAddress(ua.value());
} else {
address = keyIO.EncodePaymentAddress(pa);
}
UniValue entry(UniValue::VOBJ);
entry.pushKV("type", ADDR_TYPE_SAPLING);
entry.pushKV("spend", (int)i);
entry.pushKV("txidPrev", op.hash.GetHex());
entry.pushKV("outputPrev", (int)op.n);
entry.pushKV("address", keyIO.EncodePaymentAddress(pa));
entry.pushKV("address", address);
entry.pushKV("value", ValueFromAmount(notePt.value()));
entry.pushKV("valueZat", notePt.value());
spends.push_back(entry);
@ -4002,11 +4012,21 @@ UniValue z_viewtransaction(const UniValue& params, bool fHelp)
}
auto memo = notePt.memo();
// If the note belongs to a Sapling address that is part of an account in the
// wallet, show the corresponding Unified Address.
std::string address;
const auto ua = pwalletMain->GetUnifiedForReceiver(pa);
if (ua.has_value()) {
address = keyIO.EncodePaymentAddress(ua.value());
} else {
address = keyIO.EncodePaymentAddress(pa);
}
UniValue entry(UniValue::VOBJ);
entry.pushKV("type", ADDR_TYPE_SAPLING);
entry.pushKV("output", (int)op.n);
entry.pushKV("outgoing", isOutgoing);
entry.pushKV("address", keyIO.EncodePaymentAddress(pa));
entry.pushKV("address", address);
entry.pushKV("value", ValueFromAmount(notePt.value()));
entry.pushKV("valueZat", notePt.value());
addMemo(entry, memo);