Add raw transparent address types to PaymentAddress

The addition of `UnifiedAddress` to the `PaymentAddress` type
introduced the need for methods that interact with payment addresses
to support transparent receivers as shielded ones, which is somewhat
inconsistent with previous uses of the `PaymentAddress` type.

This commit adds both `CKeyID` and `CScriptID` as new variants
of the `PaymentAddress` type. Following commits will shift encoding
and decoding to use the `PaymentAddress` type exclusively wherever
possible, rather than the current mix of `CDestination` and
`PaymentAddress` that complicates the wallet codebase.
This commit is contained in:
Kris Nuttycombe 2021-12-23 15:08:11 -07:00
parent c35e2b4438
commit 890e1d841d
11 changed files with 295 additions and 100 deletions

View File

@ -1678,18 +1678,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
#ifdef ENABLE_WALLET
bool minerAddressInLocalWallet = false;
if (pwalletMain) {
CTxDestination addr = keyIO.DecodeDestination(mapArgs["-mineraddress"]);
if (IsValidDestination(addr)) {
CKeyID keyID = std::get<CKeyID>(addr);
minerAddressInLocalWallet = pwalletMain->HaveKey(keyID);
} else {
auto zaddr = keyIO.DecodePaymentAddress(mapArgs["-mineraddress"]);
if (!zaddr.has_value()) {
return InitError(_("-mineraddress is not a valid zcash address."));
}
minerAddressInLocalWallet = std::visit(
HaveSpendingKeyForPaymentAddress(pwalletMain), zaddr.value());
auto zaddr = keyIO.DecodePaymentAddress(mapArgs["-mineraddress"]);
if (!zaddr.has_value()) {
return InitError(_("-mineraddress is not a valid zcash address."));
}
minerAddressInLocalWallet = std::visit(
HaveSpendingKeyForPaymentAddress(pwalletMain), zaddr.value());
}
if (GetBoolArg("-minetolocalwallet", true) && !minerAddressInLocalWallet) {
return InitError(_("-mineraddress is not in the local wallet. Either use a local address, or set -minetolocalwallet=0"));

View File

@ -16,6 +16,7 @@
#include <string.h>
#include <algorithm>
#include <variant>
#include "util/match.h"
namespace
{
@ -113,6 +114,18 @@ private:
public:
PaymentAddressEncoder(const KeyConstants& keyConstants) : keyConstants(keyConstants) {}
std::string operator()(const CKeyID& id) const
{
std::vector<unsigned char> data = keyConstants.Base58Prefix(KeyConstants::PUBKEY_ADDRESS);
data.insert(data.end(), id.begin(), id.end());
return EncodeBase58Check(data);
}
std::string operator()(const CScriptID& id) const
{
std::vector<unsigned char> data = keyConstants.Base58Prefix(KeyConstants::SCRIPT_ADDRESS);
data.insert(data.end(), id.begin(), id.end());
return EncodeBase58Check(data);
}
std::string operator()(const libzcash::SproutPaymentAddress& zaddr) const
{
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
@ -349,17 +362,16 @@ std::string KeyIO::EncodePaymentAddress(const libzcash::PaymentAddress& zaddr)
return std::visit(PaymentAddressEncoder(keyConstants), zaddr);
}
template<typename T1, typename T2, typename T3>
std::optional<T1> DecodeAny(
const KeyConstants& keyConstants,
const std::string& str,
std::pair<KeyConstants::Base58Type, size_t> sprout,
std::pair<KeyConstants::Bech32Type, size_t> sapling)
template<typename T1, typename T2>
std::optional<T1> DecodeSprout(
const KeyConstants& keyConstants,
const std::string& str,
const std::pair<KeyConstants::Base58Type, size_t>& keyMeta)
{
std::vector<unsigned char> data;
if (DecodeBase58Check(str, data)) {
const std::vector<unsigned char>& prefix = keyConstants.Base58Prefix(sprout.first);
if ((data.size() == sprout.second + prefix.size()) &&
const std::vector<unsigned char>& prefix = keyConstants.Base58Prefix(keyMeta.first);
if ((data.size() == keyMeta.second + prefix.size()) &&
std::equal(prefix.begin(), prefix.end(), data.begin())) {
CSerializeData serialized(data.begin() + prefix.size(), data.end());
CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION);
@ -371,15 +383,26 @@ std::optional<T1> DecodeAny(
}
}
data.clear();
memory_cleanse(data.data(), data.size());
return std::nullopt;
}
template<typename T1, typename T2>
std::optional<T1> DecodeSapling(
const KeyConstants& keyConstants,
const std::string& str,
const std::pair<KeyConstants::Bech32Type, size_t>& keyMeta)
{
std::vector<unsigned char> data;
auto bech = bech32::Decode(str);
if (bech.first == keyConstants.Bech32HRP(sapling.first) &&
bech.second.size() == sapling.second) {
if (bech.first == keyConstants.Bech32HRP(keyMeta.first) &&
bech.second.size() == keyMeta.second) {
// Bech32 decoding
data.reserve((bech.second.size() * 5) / 8);
if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, bech.second.begin(), bech.second.end())) {
CDataStream ss(data, SER_NETWORK, PROTOCOL_VERSION);
T3 ret;
T2 ret;
ss >> ret;
memory_cleanse(data.data(), data.size());
return ret;
@ -390,6 +413,26 @@ std::optional<T1> DecodeAny(
return std::nullopt;
}
template<typename T1, typename T2, typename T3>
std::optional<T1> DecodeAny(
const KeyConstants& keyConstants,
const std::string& str,
const std::pair<KeyConstants::Base58Type, size_t>& sproutKeyMeta,
const std::pair<KeyConstants::Bech32Type, size_t>& saplingKeyMeta)
{
auto sprout = DecodeSprout<T1, T2>(keyConstants, str, sproutKeyMeta);
if (sprout.has_value()) {
return sprout.value();
}
auto sapling = DecodeSapling<T1, T3>(keyConstants, str, saplingKeyMeta);
if (sapling.has_value()) {
return sapling.value();
}
return std::nullopt;
}
/**
* `raw` MUST be 43 bytes.
*/
@ -457,15 +500,39 @@ std::optional<libzcash::PaymentAddress> KeyIO::DecodePaymentAddress(const std::s
return ua;
}
// Fall back on trying Sprout or Sapling.
return DecodeAny<libzcash::PaymentAddress,
libzcash::SproutPaymentAddress,
libzcash::SaplingPaymentAddress>(
// Try parsing as a Sapling address
auto sapling = DecodeSapling<libzcash::SaplingPaymentAddress, libzcash::SaplingPaymentAddress>(
keyConstants,
str,
std::make_pair(KeyConstants::ZCPAYMENT_ADDRESS, libzcash::SerializedSproutPaymentAddressSize),
std::make_pair(KeyConstants::SAPLING_PAYMENT_ADDRESS, ConvertedSaplingPaymentAddressSize)
);
std::make_pair(KeyConstants::SAPLING_PAYMENT_ADDRESS, ConvertedSaplingPaymentAddressSize));
if (sapling.has_value()) {
return sapling.value();
}
// Try parsing as a Sprout address
auto sprout = DecodeSprout<libzcash::SproutPaymentAddress, libzcash::SproutPaymentAddress>(
keyConstants,
str,
std::make_pair(KeyConstants::ZCPAYMENT_ADDRESS, libzcash::SerializedSproutPaymentAddressSize));
if (sprout.has_value()) {
return sprout.value();
}
// Finally, try parsing as transparent
return std::visit(match {
[](const CKeyID& keyIdIn) {
std::optional<libzcash::PaymentAddress> keyId = keyIdIn;
return keyId;
},
[](const CScriptID& scriptIdIn) {
std::optional<libzcash::PaymentAddress> scriptId = scriptIdIn;
return scriptId;
},
[](const CNoDestination& d) {
std::optional<libzcash::PaymentAddress> result = std::nullopt;
return result;
}
}, DecodeDestination(str));
}
bool KeyIO::IsValidPaymentAddressString(const std::string& str) {

View File

@ -32,6 +32,12 @@ class ExtractMinerAddress
public:
ExtractMinerAddress() {}
std::optional<MinerAddress> operator()(const CKeyID &addr) const {
return std::nullopt;
}
std::optional<MinerAddress> operator()(const CScriptID &addr) const {
return std::nullopt;
}
std::optional<MinerAddress> operator()(const libzcash::SproutPaymentAddress &addr) const {
return std::nullopt;
}
@ -40,7 +46,7 @@ public:
}
std::optional<MinerAddress> operator()(const libzcash::UnifiedAddress &addr) const {
auto recipient = RecipientForPaymentAddress()(addr);
if (recipient) {
if (recipient.has_value()) {
// This looks like a recursive call, but we are actually calling
// ExtractMinerAddress with a different type:
// - libzcash::PaymentAddress has a libzcash::UnifiedAddress
@ -51,7 +57,7 @@ public:
// This works because std::visit does not require the visitor to
// solely match the std::variant, only that it can handle all of
// the variant's alternatives.
return std::visit(ExtractMinerAddress(), *recipient);
return std::visit(ExtractMinerAddress(), recipient.value());
} else {
// Either the UA only contains unknown shielded receivers (unlikely that we
// wouldn't know about them), or it only contains transparent receivers

View File

@ -217,6 +217,28 @@ UniValue validateaddress(const UniValue& params, bool fHelp)
class DescribePaymentAddressVisitor
{
public:
UniValue operator()(const CKeyID &addr) const {
UniValue obj(UniValue::VOBJ);
obj.pushKV("type", "p2pkh");
#ifdef ENABLE_WALLET
if (pwalletMain) {
obj.pushKV("ismine", pwalletMain->HaveKey(addr));
}
#endif
return obj;
}
UniValue operator()(const CScriptID &addr) const {
UniValue obj(UniValue::VOBJ);
obj.pushKV("type", "p2sh");
#ifdef ENABLE_WALLET
if (pwalletMain) {
obj.pushKV("ismine", pwalletMain->HaveCScript(addr));
}
#endif
return obj;
}
UniValue operator()(const libzcash::SproutPaymentAddress &zaddr) const {
UniValue obj(UniValue::VOBJ);
obj.pushKV("type", "sprout");

View File

@ -202,6 +202,14 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() {
return std::visit(ShieldToAddress(this, sendAmount), tozaddr_);
}
bool ShieldToAddress::operator()(const CKeyID &addr) const {
return false;
}
bool ShieldToAddress::operator()(const CScriptID &addr) const {
return false;
}
bool ShieldToAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const {
// update the transaction with these inputs
CMutableTransaction rawTx(m_op->tx_);

View File

@ -103,6 +103,8 @@ public:
ShieldToAddress(AsyncRPCOperation_shieldcoinbase *op, CAmount sendAmount) :
m_op(op), sendAmount(sendAmount) {}
bool operator()(const CKeyID &zaddr) const;
bool operator()(const CScriptID &zaddr) const;
bool operator()(const libzcash::SproutPaymentAddress &zaddr) const;
bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
bool operator()(const libzcash::UnifiedAddress &uaddr) const;

View File

@ -2273,7 +2273,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp)
// We want to return unspent notes corresponding to any receiver within a
// Unified Address.
for (const auto ra : std::visit(GetRawAddresses(), zaddr.value())) {
for (const auto ra : std::visit(GetRawShieldedAddresses(), zaddr.value())) {
bool hasSpendingKey = std::visit(match {
[&](const SaplingPaymentAddress& addr) {
return pwalletMain->HaveSaplingSpendingKeyForAddress(addr);
@ -3154,10 +3154,16 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, decoded, nMinDepth, false, false);
std::visit(match {
[&](const CKeyID& addr) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transparent addresses are not supported by this endpoint.");
},
[&](const CScriptID& addr) {
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transparent addresses are not supported by this endpoint.");
},
[&](const libzcash::SproutPaymentAddress& addr) {
bool hasSpendingKey = pwalletMain->HaveSproutSpendingKey(addr);
auto nullifierSet = pwalletMain->GetNullifiersForAddresses({addr});
for (SproutNoteEntry & entry : sproutEntries) {
for (const SproutNoteEntry& entry : sproutEntries) {
UniValue obj(UniValue::VOBJ);
obj.pushKV("txid", entry.jsop.hash.ToString());
obj.pushKV("amount", ValueFromAmount(CAmount(entry.note.value())));
@ -3182,7 +3188,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
[&](const libzcash::SaplingPaymentAddress& addr) {
bool hasSpendingKey = pwalletMain->HaveSaplingSpendingKeyForAddress(addr);
auto nullifierSet = pwalletMain->GetNullifiersForAddresses({addr});
for (SaplingNoteEntry & entry : saplingEntries) {
for (const SaplingNoteEntry& entry : saplingEntries) {
UniValue obj(UniValue::VOBJ);
obj.pushKV("txid", entry.op.hash.ToString());
obj.pushKV("amount", ValueFromAmount(CAmount(entry.note.value())));
@ -3895,6 +3901,12 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
if (decoded.has_value()) {
std::visit(match {
[&](const CKeyID&) {
// Handled elsewhere
},
[&](const CScriptID&) {
// Handled elsewhere
},
[&](const libzcash::SaplingPaymentAddress& addr) {
mtx.vShieldedOutput.push_back(OutputDescription());
},
@ -4458,7 +4470,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
if (zaddr.has_value()) {
// We want to merge notes corresponding to any receiver within a
// Unified Address.
for (const libzcash::RawAddress& ra : std::visit(GetRawAddresses(), zaddr.value())) {
for (const libzcash::RawAddress& ra : std::visit(GetRawShieldedAddresses(), zaddr.value())) {
zaddrs.insert(ra);
if (std::holds_alternative<libzcash::SaplingPaymentAddress>(ra)) {
isFromNonSprout = true;
@ -4489,30 +4501,34 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
// Validate the destination address
auto destaddress = params[1].get_str();
bool isToTaddr = false;
bool isToSproutZaddr = false;
bool isToSaplingZaddr = false;
CTxDestination taddr = keyIO.DecodeDestination(destaddress);
if (!IsValidDestination(taddr)) {
auto zaddr = keyIO.DecodePaymentAddress(destaddress);
if (zaddr.has_value()) {
std::visit(match {
[&](libzcash::SaplingPaymentAddress addr) {
isToSaplingZaddr = true;
// If Sapling is not active, do not allow sending to a sapling addresses.
if (!saplingActive) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated");
}
},
[&](libzcash::SproutPaymentAddress addr) {
isToSproutZaddr = true;
},
[&](libzcash::UnifiedAddress) {
// TODO UNIFIED
auto paymentAddress = keyIO.DecodePaymentAddress(destaddress);
if (paymentAddress.has_value()) {
std::visit(match {
[&](CKeyID addr) {
isToTaddr = true;
},
[&](CScriptID addr) {
isToTaddr = true;
},
[&](libzcash::SaplingPaymentAddress addr) {
isToSaplingZaddr = true;
// If Sapling is not active, do not allow sending to a sapling addresses.
if (!saplingActive) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated");
}
}, zaddr.value());
} else {
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
}
},
[&](libzcash::SproutPaymentAddress addr) {
isToSproutZaddr = true;
},
[&](libzcash::UnifiedAddress) {
// TODO UNIFIED
}
}, paymentAddress.value());
} else {
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
}
if (canopyActive && isFromNonSprout && isToSproutZaddr) {
@ -4750,7 +4766,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
contextInfo.pushKV("toaddress", params[1]);
contextInfo.pushKV("fee", ValueFromAmount(nFee));
if (!sproutNoteInputs.empty() || !saplingNoteInputs.empty() || !IsValidDestination(taddr)) {
if (!sproutNoteInputs.empty() || !saplingNoteInputs.empty() || !isToTaddr) {
// We have shielded inputs or the recipient is a shielded address, and
// therefore we cannot create transactions before Sapling activates.
if (!saplingActive) {

View File

@ -5041,7 +5041,7 @@ void CWallet::GetFilteredNotes(
std::set<libzcash::RawAddress> filterAddresses;
if (address.has_value()) {
for (const auto ra : std::visit(GetRawAddresses(), address.value())) {
for (const auto ra : std::visit(GetRawShieldedAddresses(), address.value())) {
filterAddresses.insert(ra);
}
}
@ -5185,37 +5185,57 @@ void CWallet::GetFilteredNotes(
//
// Shielded key and address generalizations
// Payment address operations
//
// PaymentAddressBelongsToWallet
bool PaymentAddressBelongsToWallet::operator()(const CKeyID &addr) const
{
CScript script = GetScriptForDestination(addr);
return m_wallet->HaveKey(addr) || m_wallet->HaveWatchOnly(script);
}
bool PaymentAddressBelongsToWallet::operator()(const CScriptID &addr) const
{
CScript script = GetScriptForDestination(addr);
return m_wallet->HaveCScript(addr) || m_wallet->HaveWatchOnly(script);
}
bool PaymentAddressBelongsToWallet::operator()(const libzcash::SproutPaymentAddress &zaddr) const
{
return m_wallet->HaveSproutSpendingKey(zaddr) || m_wallet->HaveSproutViewingKey(zaddr);
}
bool PaymentAddressBelongsToWallet::operator()(const libzcash::SaplingPaymentAddress &zaddr) const
{
libzcash::SaplingIncomingViewingKey ivk;
// If we have a SaplingExtendedSpendingKey in the wallet, then we will
// also have the corresponding SaplingExtendedFullViewingKey.
return m_wallet->GetSaplingIncomingViewingKey(zaddr, ivk) &&
return
m_wallet->GetSaplingIncomingViewingKey(zaddr, ivk) &&
m_wallet->HaveSaplingFullViewingKey(ivk);
}
bool PaymentAddressBelongsToWallet::operator()(const libzcash::UnifiedAddress &uaddr) const
{
// TODO
return false;
}
///
// GetSourceForPaymentAddress
PaymentAddressSource GetSourceForPaymentAddress::operator()(const CKeyID &zaddr) const
{
// TODO
return AddressNotFound;
}
PaymentAddressSource GetSourceForPaymentAddress::operator()(const CScriptID &zaddr) const
{
// TODO
return AddressNotFound;
}
PaymentAddressSource GetSourceForPaymentAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const
{
return Random;
}
PaymentAddressSource GetSourceForPaymentAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) const
{
libzcash::SaplingIncomingViewingKey ivk;
@ -5240,15 +5260,24 @@ PaymentAddressSource GetSourceForPaymentAddress::operator()(const libzcash::Sapl
return AddressNotFound;
}
}
PaymentAddressSource GetSourceForPaymentAddress::operator()(const libzcash::UnifiedAddress &uaddr) const
{
// TODO
return AddressNotFound;
}
///
// GetViewingKeyForPaymentAddress
std::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
const CKeyID &zaddr) const
{
return std::nullopt;
}
std::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
const CScriptID &zaddr) const
{
return std::nullopt;
}
std::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
const libzcash::SproutPaymentAddress &zaddr) const
{
@ -5262,7 +5291,6 @@ std::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
}
return libzcash::ViewingKey(vk);
}
std::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
const libzcash::SaplingPaymentAddress &zaddr) const
{
@ -5277,19 +5305,27 @@ std::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
return std::nullopt;
}
}
std::optional<libzcash::ViewingKey> GetViewingKeyForPaymentAddress::operator()(
const libzcash::UnifiedAddress &uaddr) const
{
// TODO
return libzcash::ViewingKey();
return std::nullopt;
}
// HaveSpendingKeyForPaymentAddress
bool HaveSpendingKeyForPaymentAddress::operator()(const CKeyID &addr) const
{
return m_wallet->HaveKey(addr);
}
bool HaveSpendingKeyForPaymentAddress::operator()(const CScriptID &addr) const
{
return m_wallet->HaveCScript(addr);
}
bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const
{
return m_wallet->HaveSproutSpendingKey(zaddr);
}
bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) const
{
libzcash::SaplingIncomingViewingKey ivk;
@ -5299,13 +5335,24 @@ bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SaplingPayment
m_wallet->GetSaplingFullViewingKey(ivk, extfvk) &&
m_wallet->HaveSaplingSpendingKey(extfvk);
}
bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::UnifiedAddress &uaddr) const
{
// TODO
return false;
}
// GetSpendingKeyForPaymentAddress
std::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
const CKeyID &zaddr) const
{
return std::nullopt;
}
std::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
const CScriptID &zaddr) const
{
return std::nullopt;
}
std::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
const libzcash::SproutPaymentAddress &zaddr) const
{
@ -5316,7 +5363,6 @@ std::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()
return std::nullopt;
}
}
std::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
const libzcash::SaplingPaymentAddress &zaddr) const
{
@ -5327,7 +5373,6 @@ std::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()
return std::nullopt;
}
}
std::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()(
const libzcash::UnifiedAddress &uaddr) const
{
@ -5335,6 +5380,8 @@ std::optional<libzcash::SpendingKey> GetSpendingKeyForPaymentAddress::operator()
return libzcash::SpendingKey();
}
// AddViewingKeyToWallet
KeyAddResult AddViewingKeyToWallet::operator()(const libzcash::SproutViewingKey &vkey) const {
auto addr = vkey.address();
@ -5348,7 +5395,6 @@ KeyAddResult AddViewingKeyToWallet::operator()(const libzcash::SproutViewingKey
return KeyNotAdded;
}
}
KeyAddResult AddViewingKeyToWallet::operator()(const libzcash::SaplingExtendedFullViewingKey &extfvk) const {
if (m_wallet->HaveSaplingSpendingKey(extfvk)) {
return SpendingKeyExists;
@ -5361,6 +5407,8 @@ KeyAddResult AddViewingKeyToWallet::operator()(const libzcash::SaplingExtendedFu
}
}
// AddSpendingKeyToWallet
KeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKey &sk) const {
auto addr = sk.address();
KeyIO keyIO(Params());
@ -5376,7 +5424,6 @@ KeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKe
return KeyNotAdded;
}
}
KeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingExtendedSpendingKey &sk) const {
auto extfvk = sk.ToXFVK();
auto ivk = extfvk.fvk.in_viewing_key();

View File

@ -1369,6 +1369,8 @@ private:
public:
PaymentAddressBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {}
bool operator()(const CKeyID &zaddr) const;
bool operator()(const CScriptID &zaddr) const;
bool operator()(const libzcash::SproutPaymentAddress &zaddr) const;
bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
bool operator()(const libzcash::UnifiedAddress &uaddr) const;
@ -1381,6 +1383,8 @@ private:
public:
GetViewingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
std::optional<libzcash::ViewingKey> operator()(const CKeyID &zaddr) const;
std::optional<libzcash::ViewingKey> operator()(const CScriptID &zaddr) const;
std::optional<libzcash::ViewingKey> operator()(const libzcash::SproutPaymentAddress &zaddr) const;
std::optional<libzcash::ViewingKey> operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
std::optional<libzcash::ViewingKey> operator()(const libzcash::UnifiedAddress &uaddr) const;
@ -1393,6 +1397,8 @@ private:
public:
HaveSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
bool operator()(const CKeyID &addr) const;
bool operator()(const CScriptID &addr) const;
bool operator()(const libzcash::SproutPaymentAddress &zaddr) const;
bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
bool operator()(const libzcash::UnifiedAddress &uaddr) const;
@ -1405,8 +1411,11 @@ private:
public:
GetSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
std::optional<libzcash::SpendingKey> operator()(const CKeyID &zaddr) const;
std::optional<libzcash::SpendingKey> operator()(const CScriptID &zaddr) const;
std::optional<libzcash::SpendingKey> operator()(const libzcash::SproutPaymentAddress &zaddr) const;
std::optional<libzcash::SpendingKey> operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
// FIXME: this doesn't make sense
std::optional<libzcash::SpendingKey> operator()(const libzcash::UnifiedAddress &uaddr) const;
};
@ -1426,6 +1435,8 @@ private:
public:
GetSourceForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {}
PaymentAddressSource operator()(const CKeyID &zaddr) const;
PaymentAddressSource operator()(const CScriptID &zaddr) const;
PaymentAddressSource operator()(const libzcash::SproutPaymentAddress &zaddr) const;
PaymentAddressSource operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
PaymentAddressSource operator()(const libzcash::UnifiedAddress &uaddr) const;

View File

@ -56,61 +56,67 @@ uint32_t TypecodeForReceiver::operator()(
{
return ZCASH_UA_TYPECODE_SAPLING;
}
uint32_t TypecodeForReceiver::operator()(
const CScriptID &p2sh) const
{
return ZCASH_UA_TYPECODE_P2SH;
}
uint32_t TypecodeForReceiver::operator()(
const CKeyID &p2sh) const
{
return ZCASH_UA_TYPECODE_P2PKH;
}
uint32_t TypecodeForReceiver::operator()(
const libzcash::UnknownReceiver &unknown) const
{
return unknown.typecode;
}
std::optional<libzcash::RawAddress> ReceiverToRawAddress::operator()(
const libzcash::SaplingPaymentAddress &zaddr) const
{
return zaddr;
}
std::optional<libzcash::RawAddress> ReceiverToRawAddress::operator()(
const CScriptID &p2sh) const
{
return std::nullopt;
}
// ReceiverToRawAddress
std::optional<libzcash::RawAddress> ReceiverToRawAddress::operator()(
const CKeyID &p2sh) const
{
return std::nullopt;
}
std::optional<libzcash::RawAddress> ReceiverToRawAddress::operator()(
const CScriptID &p2sh) const
{
return std::nullopt;
}
std::optional<libzcash::RawAddress> ReceiverToRawAddress::operator()(
const libzcash::SaplingPaymentAddress &zaddr) const
{
return zaddr;
}
std::optional<libzcash::RawAddress> ReceiverToRawAddress::operator()(
const libzcash::UnknownReceiver &p2sh) const
{
return std::nullopt;
}
// RecipientForPaymentAddress
std::optional<libzcash::RawAddress> RecipientForPaymentAddress::operator()(
const CKeyID &p2sh) const
{
return std::nullopt;
}
std::optional<libzcash::RawAddress> RecipientForPaymentAddress::operator()(
const CScriptID &p2sh) const
{
return std::nullopt;
}
std::optional<libzcash::RawAddress> RecipientForPaymentAddress::operator()(
const libzcash::SproutPaymentAddress &zaddr) const
{
return zaddr;
}
std::optional<libzcash::RawAddress> RecipientForPaymentAddress::operator()(
const libzcash::SaplingPaymentAddress &zaddr) const
{
return zaddr;
}
std::optional<libzcash::RawAddress> RecipientForPaymentAddress::operator()(
const libzcash::UnifiedAddress &uaddr) const
{
@ -122,19 +128,29 @@ std::optional<libzcash::RawAddress> RecipientForPaymentAddress::operator()(
return std::nullopt;
}
std::set<libzcash::RawAddress> GetRawAddresses::operator()(
// GetRawShieldedAddresses
std::set<libzcash::RawAddress> GetRawShieldedAddresses::operator()(
const CKeyID &addr) const
{
return {};
}
std::set<libzcash::RawAddress> GetRawShieldedAddresses::operator()(
const CScriptID &addr) const
{
return {};
}
std::set<libzcash::RawAddress> GetRawShieldedAddresses::operator()(
const libzcash::SproutPaymentAddress &zaddr) const
{
return {zaddr};
}
std::set<libzcash::RawAddress> GetRawAddresses::operator()(
std::set<libzcash::RawAddress> GetRawShieldedAddresses::operator()(
const libzcash::SaplingPaymentAddress &zaddr) const
{
return {zaddr};
}
std::set<libzcash::RawAddress> GetRawAddresses::operator()(
std::set<libzcash::RawAddress> GetRawShieldedAddresses::operator()(
const libzcash::UnifiedAddress &uaddr) const
{
std::set<libzcash::RawAddress> ret;

View File

@ -122,6 +122,8 @@ public:
/** Addresses that can appear in a string encoding. */
typedef std::variant<
CKeyID,
CScriptID,
SproutPaymentAddress,
SaplingPaymentAddress,
UnifiedAddress> PaymentAddress;
@ -181,6 +183,8 @@ class RecipientForPaymentAddress {
public:
RecipientForPaymentAddress() {}
std::optional<libzcash::RawAddress> operator()(const CKeyID &addr) const;
std::optional<libzcash::RawAddress> operator()(const CScriptID &addr) const;
std::optional<libzcash::RawAddress> operator()(const libzcash::SproutPaymentAddress &zaddr) const;
std::optional<libzcash::RawAddress> operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
std::optional<libzcash::RawAddress> operator()(const libzcash::UnifiedAddress &uaddr) const;
@ -189,10 +193,12 @@ public:
/**
* Returns all protocol addresses contained within the given payment address.
*/
class GetRawAddresses {
class GetRawShieldedAddresses {
public:
GetRawAddresses() {}
GetRawShieldedAddresses() {}
std::set<libzcash::RawAddress> operator()(const CKeyID &addr) const;
std::set<libzcash::RawAddress> operator()(const CScriptID &addr) const;
std::set<libzcash::RawAddress> operator()(const libzcash::SproutPaymentAddress &zaddr) const;
std::set<libzcash::RawAddress> operator()(const libzcash::SaplingPaymentAddress &zaddr) const;
std::set<libzcash::RawAddress> operator()(const libzcash::UnifiedAddress &uaddr) const;