Add Orchard to default UA receiver types
We also add Orchard-specific information to several RPCs in order for tests to pass: - `z_listunifiedreceivers` - `z_getbalanceforaccount` - `z_getbalanceforviewingkey`
This commit is contained in:
parent
235fde5193
commit
b0769e3f1d
|
@ -55,7 +55,7 @@ class WalletAccountsTest(BitcoinTestFramework):
|
|||
# Generate the first address for account 0.
|
||||
addr0 = self.nodes[0].z_getaddressforaccount(0)
|
||||
assert_equal(addr0['account'], 0)
|
||||
assert_equal(set(addr0['pools']), set(['transparent', 'sapling']))
|
||||
assert_equal(set(addr0['pools']), set(['transparent', 'sapling', 'orchard']))
|
||||
ua0 = addr0['unifiedaddress']
|
||||
|
||||
# We pick mnemonic phrases to ensure that we can always generate the default
|
||||
|
@ -70,16 +70,38 @@ class WalletAccountsTest(BitcoinTestFramework):
|
|||
'no address at diversifier index 0',
|
||||
self.nodes[0].z_getaddressforaccount, 0, [], 0)
|
||||
|
||||
# The second address for account 0 is different to the first address.
|
||||
addr0_2 = self.nodes[0].z_getaddressforaccount(0)
|
||||
assert_equal(addr0_2['account'], 0)
|
||||
assert_equal(set(addr0_2['pools']), set(['transparent', 'sapling', 'orchard']))
|
||||
ua0_2 = addr0_2['unifiedaddress']
|
||||
assert(ua0 != ua0_2)
|
||||
|
||||
# We can generate a fully-shielded address.
|
||||
addr0_3 = self.nodes[0].z_getaddressforaccount(0, ['sapling', 'orchard'])
|
||||
assert_equal(addr0_3['account'], 0)
|
||||
assert_equal(set(addr0_3['pools']), set(['sapling', 'orchard']))
|
||||
ua0_3 = addr0_3['unifiedaddress']
|
||||
|
||||
# We can generate an address without a Sapling receiver.
|
||||
addr0_4 = self.nodes[0].z_getaddressforaccount(0, ['transparent', 'orchard'])
|
||||
assert_equal(addr0_4['account'], 0)
|
||||
assert_equal(set(addr0_4['pools']), set(['transparent', 'orchard']))
|
||||
ua0_4 = addr0_4['unifiedaddress']
|
||||
|
||||
# The first address for account 1 is different to account 0.
|
||||
addr1 = self.nodes[0].z_getaddressforaccount(1)
|
||||
assert_equal(addr1['account'], 1)
|
||||
assert_equal(set(addr1['pools']), set(['transparent', 'sapling']))
|
||||
assert_equal(set(addr1['pools']), set(['transparent', 'sapling', 'orchard']))
|
||||
ua1 = addr1['unifiedaddress']
|
||||
assert(ua0 != ua1)
|
||||
|
||||
# The UA contains the expected receiver kinds.
|
||||
self.check_receiver_types(ua0, ['transparent', 'sapling'])
|
||||
self.check_receiver_types(ua1, ['transparent', 'sapling'])
|
||||
self.check_receiver_types(ua0, ['transparent', 'sapling', 'orchard'])
|
||||
self.check_receiver_types(ua0_2, ['transparent', 'sapling', 'orchard'])
|
||||
self.check_receiver_types(ua0_3, [ 'sapling', 'orchard'])
|
||||
self.check_receiver_types(ua0_4, ['transparent', 'orchard'])
|
||||
self.check_receiver_types(ua1, ['transparent', 'sapling', 'orchard'])
|
||||
|
||||
# The balances of the accounts are all zero.
|
||||
self.check_balance(0, 0, ua0, {})
|
||||
|
|
|
@ -381,9 +381,10 @@ class ListReceivedTest (BitcoinTestFramework):
|
|||
r = node.z_getaddressforaccount(account)
|
||||
unified_addr = r['unifiedaddress']
|
||||
receivers = node.z_listunifiedreceivers(unified_addr)
|
||||
assert_equal(len(receivers), 2)
|
||||
assert_equal(len(receivers), 3)
|
||||
assert 'transparent' in receivers
|
||||
assert 'sapling' in receivers
|
||||
assert 'orchard' in receivers
|
||||
# Wallet contains no notes
|
||||
r = node.z_listreceivedbyaddress(unified_addr, 0)
|
||||
assert_equal(len(r), 0, "unified_addr should have received zero notes")
|
||||
|
|
|
@ -3119,14 +3119,16 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp)
|
|||
receivers.insert(ReceiverType::P2PKH);
|
||||
} else if (p == "sapling") {
|
||||
receivers.insert(ReceiverType::Sapling);
|
||||
} else if (p == "orchard") {
|
||||
receivers.insert(ReceiverType::Orchard);
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "pool arguments must be \"transparent\", or \"sapling\"");
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "pool arguments must be \"transparent\", \"sapling\", or \"orchard\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (receivers.empty()) {
|
||||
// Default is the best and second-best shielded pools, and the transparent pool.
|
||||
receivers = {ReceiverType::P2PKH, ReceiverType::Sapling};
|
||||
receivers = {ReceiverType::P2PKH, ReceiverType::Sapling, ReceiverType::Orchard};
|
||||
}
|
||||
|
||||
std::optional<libzcash::diversifier_index_t> j = std::nullopt;
|
||||
|
@ -3220,6 +3222,9 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp)
|
|||
case ReceiverType::Sapling:
|
||||
pools.push_back("sapling");
|
||||
break;
|
||||
case ReceiverType::Orchard:
|
||||
pools.push_back("orchard");
|
||||
break;
|
||||
default:
|
||||
// Unreachable
|
||||
assert(false);
|
||||
|
@ -3331,6 +3336,12 @@ UniValue z_listunifiedreceivers(const UniValue& params, bool fHelp)
|
|||
UniValue result(UniValue::VOBJ);
|
||||
for (const auto& receiver : ua) {
|
||||
std::visit(match {
|
||||
[&](const libzcash::OrchardRawAddress& addr) {
|
||||
// Create a single-receiver UA that just contains this Orchard receiver.
|
||||
UnifiedAddress singleReceiver;
|
||||
singleReceiver.AddReceiver(addr);
|
||||
result.pushKV("orchard", keyIO.EncodePaymentAddress(singleReceiver));
|
||||
},
|
||||
[&](const libzcash::SaplingPaymentAddress& addr) {
|
||||
result.pushKV("sapling", keyIO.EncodePaymentAddress(addr));
|
||||
},
|
||||
|
@ -3762,6 +3773,7 @@ UniValue z_getbalanceforviewingkey(const UniValue& params, bool fHelp)
|
|||
CAmount transparentBalance = 0;
|
||||
CAmount sproutBalance = 0;
|
||||
CAmount saplingBalance = 0;
|
||||
CAmount orchardBalance = 0;
|
||||
for (const auto& t : spendableInputs.utxos) {
|
||||
transparentBalance += t.Value();
|
||||
}
|
||||
|
@ -3771,6 +3783,9 @@ UniValue z_getbalanceforviewingkey(const UniValue& params, bool fHelp)
|
|||
for (const auto& t : spendableInputs.saplingNoteEntries) {
|
||||
saplingBalance += t.note.value();
|
||||
}
|
||||
for (const auto& t : spendableInputs.orchardNoteMetadata) {
|
||||
orchardBalance += t.GetNoteValue();
|
||||
}
|
||||
|
||||
UniValue pools(UniValue::VOBJ);
|
||||
auto renderBalance = [&](std::string poolName, CAmount balance) {
|
||||
|
@ -3783,6 +3798,7 @@ UniValue z_getbalanceforviewingkey(const UniValue& params, bool fHelp)
|
|||
renderBalance("transparent", transparentBalance);
|
||||
renderBalance("sprout", sproutBalance);
|
||||
renderBalance("sapling", saplingBalance);
|
||||
renderBalance("orchard", orchardBalance);
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("pools", pools);
|
||||
|
@ -3863,12 +3879,16 @@ UniValue z_getbalanceforaccount(const UniValue& params, bool fHelp)
|
|||
|
||||
CAmount transparentBalance = 0;
|
||||
CAmount saplingBalance = 0;
|
||||
CAmount orchardBalance = 0;
|
||||
for (const auto& t : spendableInputs.utxos) {
|
||||
transparentBalance += t.Value();
|
||||
}
|
||||
for (const auto& t : spendableInputs.saplingNoteEntries) {
|
||||
saplingBalance += t.note.value();
|
||||
}
|
||||
for (const auto& t : spendableInputs.orchardNoteMetadata) {
|
||||
orchardBalance += t.GetNoteValue();
|
||||
}
|
||||
|
||||
UniValue pools(UniValue::VOBJ);
|
||||
auto renderBalance = [&](std::string poolName, CAmount balance) {
|
||||
|
@ -3880,6 +3900,7 @@ UniValue z_getbalanceforaccount(const UniValue& params, bool fHelp)
|
|||
};
|
||||
renderBalance("transparent", transparentBalance);
|
||||
renderBalance("sapling", saplingBalance);
|
||||
renderBalance("orchard", orchardBalance);
|
||||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("pools", pools);
|
||||
|
|
|
@ -605,7 +605,7 @@ std::optional<libzcash::ZcashdUnifiedSpendingKey>
|
|||
// when the user calls z_getaddressforaccount.
|
||||
auto orchardInternalFvk = orchardSk.ToFullViewingKey().ToInternalIncomingViewingKey();
|
||||
if (!AddOrchardRawAddress(orchardInternalFvk, orchardInternalFvk.Address(0))) {
|
||||
throw std::runtime_error("CWallet::GenerateUnifiedSpendingKeyForAccount(): Failed to add Sapling change address to the wallet.");
|
||||
throw std::runtime_error("CWallet::GenerateUnifiedSpendingKeyForAccount(): Failed to add Orchard change address to the wallet.");
|
||||
};
|
||||
|
||||
auto zufvk = ZcashdUnifiedFullViewingKey::FromUnifiedFullViewingKey(Params(), ufvk);
|
||||
|
|
|
@ -794,6 +794,7 @@ public:
|
|||
std::vector<COutput> utxos;
|
||||
std::vector<SproutNoteEntry> sproutNoteEntries;
|
||||
std::vector<SaplingNoteEntry> saplingNoteEntries;
|
||||
std::vector<OrchardNoteMetadata> orchardNoteMetadata;
|
||||
|
||||
/**
|
||||
* Selectively discard notes that are not required to obtain the desired
|
||||
|
@ -816,6 +817,9 @@ public:
|
|||
for (const auto& t : saplingNoteEntries) {
|
||||
result += t.note.value();
|
||||
}
|
||||
for (const auto& t : orchardNoteMetadata) {
|
||||
result += t.GetNoteValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -150,7 +150,7 @@ UnifiedAddressGenerationResult ZcashdUnifiedFullViewingKey::FindAddress(
|
|||
|
||||
UnifiedAddressGenerationResult ZcashdUnifiedFullViewingKey::FindAddress(
|
||||
const diversifier_index_t& j) const {
|
||||
return FindAddress(j, {ReceiverType::P2PKH, ReceiverType::Sapling});
|
||||
return FindAddress(j, {ReceiverType::P2PKH, ReceiverType::Sapling, ReceiverType::Orchard});
|
||||
}
|
||||
|
||||
std::optional<RecipientAddress> ZcashdUnifiedFullViewingKey::GetChangeAddress(const ChangeRequest& req) const {
|
||||
|
|
Loading…
Reference in New Issue