Use the new `examine` macro to replace all instances of

`std::visit(match {...}, specimen)`, improving code readability.

For ease of review, this commit includes only obviously correct
transformations that all follow the same pattern.

Signed-off-by: Daira Emma Hopwood <daira@jacaranda.org>
This commit is contained in:
Daira Emma Hopwood 2023-04-04 21:26:39 +01:00
parent 60755efaf1
commit 6bb8c60f41
19 changed files with 124 additions and 125 deletions

View File

@ -188,7 +188,7 @@ namespace Consensus {
throw std::runtime_error("Funding stream address was not a valid " PACKAGE_NAME " address."); throw std::runtime_error("Funding stream address was not a valid " PACKAGE_NAME " address.");
} }
std::visit(match { examine(addr.value(), match {
[&](const CKeyID& keyId) { [&](const CKeyID& keyId) {
addresses.push_back(GetScriptForDestination(keyId)); addresses.push_back(GetScriptForDestination(keyId));
}, },
@ -201,7 +201,7 @@ namespace Consensus {
[&](const auto& zaddr) { [&](const auto& zaddr) {
throw std::runtime_error("Funding stream address was not a valid transparent P2SH or Sapling address."); throw std::runtime_error("Funding stream address was not a valid transparent P2SH or Sapling address.");
} }
}, addr.value()); });
} }
auto validationResult = FundingStream::ValidateFundingStream(params, startHeight, endHeight, addresses); auto validationResult = FundingStream::ValidateFundingStream(params, startHeight, endHeight, addresses);

View File

@ -468,7 +468,7 @@ std::optional<libzcash::PaymentAddress> KeyIO::DecodePaymentAddress(const std::s
} }
// Finally, try parsing as transparent // Finally, try parsing as transparent
return std::visit(match { return examine(DecodeDestination(str), match {
[](const CKeyID& keyIdIn) { [](const CKeyID& keyIdIn) {
std::optional<libzcash::PaymentAddress> keyId = keyIdIn; std::optional<libzcash::PaymentAddress> keyId = keyIdIn;
return keyId; return keyId;
@ -481,7 +481,7 @@ std::optional<libzcash::PaymentAddress> KeyIO::DecodePaymentAddress(const std::s
std::optional<libzcash::PaymentAddress> result = std::nullopt; std::optional<libzcash::PaymentAddress> result = std::nullopt;
return result; return result;
} }
}, DecodeDestination(str)); });
} }
bool KeyIO::IsValidPaymentAddressString(const std::string& str) const bool KeyIO::IsValidPaymentAddressString(const std::string& str) const

View File

@ -19,10 +19,10 @@ std::optional<AddressUFVKMetadata> CKeyStore::GetUFVKMetadataForAddress(
const CTxDestination& address) const const CTxDestination& address) const
{ {
auto self = this; auto self = this;
return std::visit(match { return examine(address, match {
[](const CNoDestination&) -> std::optional<AddressUFVKMetadata> { return std::nullopt; }, [](const CNoDestination&) -> std::optional<AddressUFVKMetadata> { return std::nullopt; },
[&](const auto& addr) { return self->GetUFVKMetadataForReceiver(addr); } [&](const auto& addr) { return self->GetUFVKMetadataForReceiver(addr); }
}, address); });
} }
bool CBasicKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const bool CBasicKeyStore::GetPubKey(const CKeyID &address, CPubKey &vchPubKeyOut) const
@ -428,7 +428,7 @@ CBasicKeyStore::GetUFVKIdForAddress(const libzcash::UnifiedAddress& addr) const
std::optional<libzcash::UFVKId> CBasicKeyStore::GetUFVKIdForViewingKey(const libzcash::ViewingKey& vk) const std::optional<libzcash::UFVKId> CBasicKeyStore::GetUFVKIdForViewingKey(const libzcash::ViewingKey& vk) const
{ {
std::optional<libzcash::UFVKId> result; std::optional<libzcash::UFVKId> result;
std::visit(match { examine(vk, match {
[&](const libzcash::SproutViewingKey& vk) {}, [&](const libzcash::SproutViewingKey& vk) {},
[&](const libzcash::SaplingExtendedFullViewingKey& extfvk) { [&](const libzcash::SaplingExtendedFullViewingKey& extfvk) {
const auto saplingIvk = extfvk.ToIncomingViewingKey(); const auto saplingIvk = extfvk.ToIncomingViewingKey();
@ -456,7 +456,7 @@ std::optional<libzcash::UFVKId> CBasicKeyStore::GetUFVKIdForViewingKey(const lib
} }
} }
} }
}, vk); });
return result; return result;
} }

View File

@ -351,11 +351,11 @@ void BlockAssembler::resetBlock(const MinerAddress& minerAddress)
// Reserve space for coinbase tx // Reserve space for coinbase tx
// nBlockMaxSize already includes 1000 bytes for transaction structure overhead. // nBlockMaxSize already includes 1000 bytes for transaction structure overhead.
nBlockSize = std::visit(match { nBlockSize = examine(minerAddress, match {
[](const libzcash::OrchardRawAddress&) { return 9000; }, [](const libzcash::OrchardRawAddress&) { return 9000; },
[](const libzcash::SaplingPaymentAddress&) { return 1000; }, [](const libzcash::SaplingPaymentAddress&) { return 1000; },
[](const boost::shared_ptr<CReserveScript> &) { return 1000; }, [](const boost::shared_ptr<CReserveScript> &) { return 1000; },
}, minerAddress); });
nBlockSigOps = 100; nBlockSigOps = 100;
// These counters do not include coinbase tx // These counters do not include coinbase tx
@ -813,12 +813,12 @@ std::optional<MinerAddress> ExtractMinerAddress::operator()(const libzcash::Unif
auto preferred = addr.GetPreferredRecipientAddress(consensus, height); auto preferred = addr.GetPreferredRecipientAddress(consensus, height);
if (preferred.has_value()) { if (preferred.has_value()) {
std::optional<MinerAddress> ret; std::optional<MinerAddress> ret;
std::visit(match { examine(preferred.value(), match {
[&](const libzcash::OrchardRawAddress addr) { ret = MinerAddress(addr); }, [&](const libzcash::OrchardRawAddress addr) { ret = MinerAddress(addr); },
[&](const libzcash::SaplingPaymentAddress addr) { ret = MinerAddress(addr); }, [&](const libzcash::SaplingPaymentAddress addr) { ret = MinerAddress(addr); },
[&](const CKeyID keyID) { ret = operator()(keyID); }, [&](const CKeyID keyID) { ret = operator()(keyID); },
[&](const auto other) { ret = std::nullopt; } [&](const auto other) { ret = std::nullopt; }
}, preferred.value()); });
return ret; return ret;
} else { } else {
return std::nullopt; return std::nullopt;

View File

@ -457,7 +457,7 @@ void TransactionBuilder::SendChangeTo(
saplingChangeAddr = std::nullopt; saplingChangeAddr = std::nullopt;
sproutChangeAddr = std::nullopt; sproutChangeAddr = std::nullopt;
std::visit(match { examine(changeAddr, match {
[&](const CKeyID& keyId) { [&](const CKeyID& keyId) {
tChangeAddr = keyId; tChangeAddr = keyId;
}, },
@ -470,7 +470,7 @@ void TransactionBuilder::SendChangeTo(
[&](const libzcash::OrchardRawAddress& changeDest) { [&](const libzcash::OrchardRawAddress& changeDest) {
orchardChangeAddr = std::make_pair(ovk, changeDest); orchardChangeAddr = std::make_pair(ovk, changeDest);
} }
}, changeAddr); });
} }
void TransactionBuilder::SendChangeToSprout(const libzcash::SproutPaymentAddress& zaddr) { void TransactionBuilder::SendChangeToSprout(const libzcash::SproutPaymentAddress& zaddr) {

View File

@ -47,7 +47,7 @@ void ThrowInputSelectionError(
const ZTXOSelector& selector, const ZTXOSelector& selector,
const TransactionStrategy& strategy) const TransactionStrategy& strategy)
{ {
std::visit(match { examine(err, match {
[](const AddressResolutionError& err) { [](const AddressResolutionError& err) {
switch (err) { switch (err) {
case AddressResolutionError::SproutRecipientsNotSupported: case AddressResolutionError::SproutRecipientsNotSupported:
@ -105,7 +105,7 @@ void ThrowInputSelectionError(
strprintf( strprintf(
"Insufficient funds: have %s, %s", "Insufficient funds: have %s, %s",
FormatMoney(err.available), FormatMoney(err.available),
std::visit(match { examine(err.reason, match {
[](const InsufficientFundsError& ife) { [](const InsufficientFundsError& ife) {
return strprintf("need %s", FormatMoney(ife.required)); return strprintf("need %s", FormatMoney(ife.required));
}, },
@ -116,8 +116,7 @@ void ThrowInputSelectionError(
FormatMoney(dte.changeAmount), FormatMoney(dte.changeAmount),
FormatMoney(dte.dustThreshold)); FormatMoney(dte.dustThreshold));
} }
}, }))
err.reason))
+ (selector.TransparentCoinbasePolicy() != TransparentCoinbasePolicy::Disallow + (selector.TransparentCoinbasePolicy() != TransparentCoinbasePolicy::Disallow
? "" : ? "" :
"; note that coinbase outputs will not be selected if you specify " "; note that coinbase outputs will not be selected if you specify "
@ -161,5 +160,5 @@ void ThrowInputSelectionError(
err.maxNotes, err.maxNotes,
err.orchardNotes)); err.orchardNotes));
} }
}, err); });
} }

View File

@ -96,7 +96,7 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
isToTaddr_ = false; isToTaddr_ = false;
isToZaddr_ = false; isToZaddr_ = false;
std::visit(match { examine(recipient.first, match {
[&](const CKeyID& keyId) { [&](const CKeyID& keyId) {
toTaddr_ = keyId; toTaddr_ = keyId;
isToTaddr_ = true; isToTaddr_ = true;
@ -118,7 +118,7 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
RPC_INVALID_ADDRESS_OR_KEY, RPC_INVALID_ADDRESS_OR_KEY,
"z_mergetoaddress does not yet support sending to unified addresses"); "z_mergetoaddress does not yet support sending to unified addresses");
}, },
}, recipient.first); });
// Log the context info i.e. the call parameters to z_mergetoaddress // Log the context info i.e. the call parameters to z_mergetoaddress
if (LogAcceptCategory("zrpcunsafe")) { if (LogAcceptCategory("zrpcunsafe")) {

View File

@ -151,7 +151,7 @@ uint256 AsyncRPCOperation_sendmany::main_impl(CWallet& wallet) {
anchordepth_); anchordepth_);
uint256 txid; uint256 txid;
std::visit(match { examine(preparedTx, match {
[&](const InputSelectionError& err) { [&](const InputSelectionError& err) {
ThrowInputSelectionError(err, ztxoSelector_, strategy_); ThrowInputSelectionError(err, ztxoSelector_, strategy_);
}, },
@ -194,7 +194,7 @@ uint256 AsyncRPCOperation_sendmany::main_impl(CWallet& wallet) {
throw; throw;
} }
} }
}, preparedTx); });
return txid; return txid;
} }

View File

@ -80,7 +80,7 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase(
} }
// Check the destination address is valid for this network i.e. not testnet being used on mainnet // Check the destination address is valid for this network i.e. not testnet being used on mainnet
std::visit(match { examine(toAddress, match {
[&](CKeyID addr) { [&](CKeyID addr) {
throw JSONRPCError(RPC_VERIFY_REJECTED, "Cannot shield coinbase output to a p2pkh address."); throw JSONRPCError(RPC_VERIFY_REJECTED, "Cannot shield coinbase output to a p2pkh address.");
}, },
@ -96,7 +96,7 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase(
[&](libzcash::UnifiedAddress addr) { [&](libzcash::UnifiedAddress addr) {
tozaddr_ = addr; tozaddr_ = addr;
} }
}, toAddress); });
// Log the context info // Log the context info
if (LogAcceptCategory("zrpcunsafe")) { if (LogAcceptCategory("zrpcunsafe")) {

View File

@ -50,7 +50,7 @@ public:
} }
static Memo FromHexOrThrow(const std::string& memoHex) { static Memo FromHexOrThrow(const std::string& memoHex) {
return std::visit(match { return examine(Memo::FromHex(memoHex), match {
[&](Memo memo) { [&](Memo memo) {
return memo; return memo;
}, },
@ -69,7 +69,7 @@ public:
// unreachable, but the compiler can't tell // unreachable, but the compiler can't tell
return Memo::NoMemo(); return Memo::NoMemo();
} }
}, Memo::FromHex(memoHex)); });
} }
// This copies, because if it returns a reference to the underlying value, // This copies, because if it returns a reference to the underlying value,

View File

@ -929,7 +929,7 @@ UniValue z_exportkey(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr"); throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr");
} }
std::string result = std::visit(match { std::string result = examine(address.value(), match {
[&](const CKeyID& addr) { [&](const CKeyID& addr) {
CKey key; CKey key;
if (pwalletMain->GetKey(addr, key)) { if (pwalletMain->GetKey(addr, key)) {
@ -969,7 +969,7 @@ UniValue z_exportkey(const UniValue& params, bool fHelp)
"Use the emergency recovery phrase for this wallet for backup purposes instead."); "Use the emergency recovery phrase for this wallet for backup purposes instead.");
return std::string(); //unreachable, here to make the compiler happy return std::string(); //unreachable, here to make the compiler happy
} }
}, address.value()); });
return result; return result;
} }

View File

@ -530,7 +530,7 @@ UniValue listaddresses(const UniValue& params, bool fHelp)
// This will include any address that has been generated by this wallet. // This will include any address that has been generated by this wallet.
for (const std::pair<CTxDestination, CAddressBookData>& item : pwalletMain->mapAddressBook) { for (const std::pair<CTxDestination, CAddressBookData>& item : pwalletMain->mapAddressBook) {
std::optional<PaymentAddressSource> source; std::optional<PaymentAddressSource> source;
std::visit(match { examine(item.first, match {
[&](const CKeyID& addr) { [&](const CKeyID& addr) {
source = GetSourceForPaymentAddress(pwalletMain)(addr); source = GetSourceForPaymentAddress(pwalletMain)(addr);
}, },
@ -538,7 +538,7 @@ UniValue listaddresses(const UniValue& params, bool fHelp)
source = GetSourceForPaymentAddress(pwalletMain)(addr); source = GetSourceForPaymentAddress(pwalletMain)(addr);
}, },
[&](const CNoDestination& addr) {} [&](const CNoDestination& addr) {}
}, item.first); });
if (source.has_value()) { if (source.has_value()) {
switch (source.value()) { switch (source.value()) {
case PaymentAddressSource::Random: case PaymentAddressSource::Random:
@ -571,7 +571,7 @@ UniValue listaddresses(const UniValue& params, bool fHelp)
t_watchonly_dests.count(item.first) == 0) t_watchonly_dests.count(item.first) == 0)
{ {
std::optional<PaymentAddressSource> source; std::optional<PaymentAddressSource> source;
std::visit(match { examine(item.first, match {
[&](const CKeyID& addr) { [&](const CKeyID& addr) {
source = GetSourceForPaymentAddress(pwalletMain)(addr); source = GetSourceForPaymentAddress(pwalletMain)(addr);
}, },
@ -579,7 +579,7 @@ UniValue listaddresses(const UniValue& params, bool fHelp)
source = GetSourceForPaymentAddress(pwalletMain)(addr); source = GetSourceForPaymentAddress(pwalletMain)(addr);
}, },
[&](const CNoDestination& addr) {} [&](const CNoDestination& addr) {}
}, item.first); });
if (source.has_value()) { if (source.has_value()) {
switch (source.value()) { switch (source.value()) {
case PaymentAddressSource::Random: case PaymentAddressSource::Random:
@ -3296,7 +3296,7 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
result.pushKV("account", (uint64_t)account); result.pushKV("account", (uint64_t)account);
std::visit(match { examine(res, match {
[&](std::pair<libzcash::UnifiedAddress, libzcash::diversifier_index_t> addr) { [&](std::pair<libzcash::UnifiedAddress, libzcash::diversifier_index_t> addr) {
result.pushKV("address", KeyIO(Params()).EncodePaymentAddress(addr.first)); result.pushKV("address", KeyIO(Params()).EncodePaymentAddress(addr.first));
UniValue j; UniValue j;
@ -3349,7 +3349,7 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp)
} }
throw JSONRPCError(RPC_WALLET_ERROR, strErr); throw JSONRPCError(RPC_WALLET_ERROR, strErr);
}, },
}, res); });
UniValue receiver_types(UniValue::VARR); UniValue receiver_types(UniValue::VARR);
for (const auto& receiverType : receiverTypes) { for (const auto& receiverType : receiverTypes) {
@ -3543,7 +3543,7 @@ UniValue z_listunifiedreceivers(const UniValue& params, bool fHelp)
UniValue result(UniValue::VOBJ); UniValue result(UniValue::VOBJ);
for (const auto& receiver : ua) { for (const auto& receiver : ua) {
std::visit(match { examine(receiver, match {
[&](const libzcash::OrchardRawAddress& addr) { [&](const libzcash::OrchardRawAddress& addr) {
// Create a single-receiver UA that just contains this Orchard receiver. // Create a single-receiver UA that just contains this Orchard receiver.
UnifiedAddress singleReceiver; UnifiedAddress singleReceiver;
@ -3560,7 +3560,7 @@ UniValue z_listunifiedreceivers(const UniValue& params, bool fHelp)
result.pushKV("p2pkh", keyIO.EncodePaymentAddress(addr)); result.pushKV("p2pkh", keyIO.EncodePaymentAddress(addr));
}, },
[](auto rest) {}, [](auto rest) {},
}, receiver); });
} }
return result; return result;
} }
@ -3697,7 +3697,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
// A non-unified address argument that is a receiver within a // A non-unified address argument that is a receiver within a
// unified address known to this wallet is not allowed. // unified address known to this wallet is not allowed.
if (std::visit(match { if (examine(decoded.value(), match {
[&](const CKeyID& addr) { [&](const CKeyID& addr) {
return pwalletMain->FindUnifiedAddressByReceiver(addr).has_value(); return pwalletMain->FindUnifiedAddressByReceiver(addr).has_value();
}, },
@ -3715,7 +3715,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
// We allow unified addresses themselves, which cannot recurse. // We allow unified addresses themselves, which cannot recurse.
return false; return false;
} }
}, decoded.value())) { })) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "The provided address is a bare receiver from a Unified Address in this wallet. Provide the full UA instead."); throw JSONRPCError(RPC_INVALID_PARAMETER, "The provided address is a bare receiver from a Unified Address in this wallet. Provide the full UA instead.");
} }
@ -3820,7 +3820,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
} }
}; };
std::visit(match { examine(decoded.value(), match {
[&](const CKeyID& addr) { push_transparent_result(addr); }, [&](const CKeyID& addr) { push_transparent_result(addr); },
[&](const CScriptID& addr) { push_transparent_result(addr); }, [&](const CScriptID& addr) { push_transparent_result(addr); },
[&](const libzcash::SproutPaymentAddress& addr) { [&](const libzcash::SproutPaymentAddress& addr) {
@ -3857,7 +3857,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
}, },
[&](const libzcash::UnifiedAddress& addr) { [&](const libzcash::UnifiedAddress& addr) {
for (const auto& receiver : addr) { for (const auto& receiver : addr) {
std::visit(match { examine(receiver, match {
[&](const libzcash::SaplingPaymentAddress& addr) { [&](const libzcash::SaplingPaymentAddress& addr) {
push_sapling_result(addr); push_sapling_result(addr);
}, },
@ -3874,10 +3874,10 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
}, },
[&](const UnknownReceiver& unknown) {} [&](const UnknownReceiver& unknown) {}
}, receiver); });
} }
} }
}, decoded.value()); });
return result; return result;
} }
@ -3934,7 +3934,7 @@ UniValue z_getbalance(const UniValue& params, bool fHelp)
} }
CAmount nBalance = 0; CAmount nBalance = 0;
std::visit(match { examine(pa.value(), match {
[&](const CKeyID& addr) { [&](const CKeyID& addr) {
nBalance = getBalanceTaddr(addr, std::nullopt, nMinDepth, false); nBalance = getBalanceTaddr(addr, std::nullopt, nMinDepth, false);
}, },
@ -3966,7 +3966,7 @@ UniValue z_getbalance(const UniValue& params, bool fHelp)
nBalance += t.GetNoteValue(); nBalance += t.GetNoteValue();
} }
}, },
}, pa.value()); });
// inZat // inZat
if (params.size() > 2 && params[2].get_bool()) { if (params.size() > 2 && params[2].get_bool()) {
@ -4731,7 +4731,7 @@ size_t EstimateTxSize(
size_t taddrRecipientCount = 0; size_t taddrRecipientCount = 0;
size_t orchardRecipientCount = 0; size_t orchardRecipientCount = 0;
for (const Payment& recipient : recipients) { for (const Payment& recipient : recipients) {
std::visit(match { examine(recipient.GetAddress(), match {
[&](const CKeyID&) { [&](const CKeyID&) {
taddrRecipientCount += 1; taddrRecipientCount += 1;
}, },
@ -4756,7 +4756,7 @@ size_t EstimateTxSize(
taddrRecipientCount += 1; taddrRecipientCount += 1;
} }
} }
}, recipient.GetAddress()); });
} }
bool nu5Active = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_NU5); bool nu5Active = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_NU5);
@ -4905,7 +4905,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
std::optional<Memo> memo; std::optional<Memo> memo;
if (!memoValue.isNull()) { if (!memoValue.isNull()) {
auto memoHex = memoValue.get_str(); auto memoHex = memoValue.get_str();
std::visit(match { examine(Memo::FromHex(memoHex), match {
[&](MemoError err) { [&](MemoError err) {
switch (err) { switch (err) {
case MemoError::HexDecodeError: case MemoError::HexDecodeError:
@ -4923,7 +4923,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
[&](Memo result) { [&](Memo result) {
memo = result; memo = result;
} }
}, Memo::FromHex(memoHex)); });
} }
UniValue av = find_value(o, "amount"); UniValue av = find_value(o, "amount");
@ -4932,7 +4932,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, amount must be positive"); throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, amount must be positive");
} }
std::visit(match { examine(addr.value(), match {
[&](const CKeyID &) { [&](const CKeyID &) {
tcoinbasePolicy = TransparentCoinbasePolicy::Disallow; tcoinbasePolicy = TransparentCoinbasePolicy::Disallow;
}, },
@ -4944,7 +4944,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
auto preferredRecipient = auto preferredRecipient =
ua.GetPreferredRecipientAddress(chainparams.GetConsensus(), nextBlockHeight); ua.GetPreferredRecipientAddress(chainparams.GetConsensus(), nextBlockHeight);
if (preferredRecipient.has_value()) { if (preferredRecipient.has_value()) {
std::visit(match { examine(preferredRecipient.value(), match {
[&](const CKeyID &) { [&](const CKeyID &) {
tcoinbasePolicy = TransparentCoinbasePolicy::Disallow; tcoinbasePolicy = TransparentCoinbasePolicy::Disallow;
}, },
@ -4952,11 +4952,11 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
tcoinbasePolicy = TransparentCoinbasePolicy::Disallow; tcoinbasePolicy = TransparentCoinbasePolicy::Disallow;
}, },
[](const auto &) { } [](const auto &) { }
}, preferredRecipient.value()); });
} }
}, },
[](const auto &) { } [](const auto &) { }
}, addr.value()); });
recipients.push_back(Payment(addr.value(), nAmount, memo)); recipients.push_back(Payment(addr.value(), nAmount, memo));
nTotalOut += nAmount; nTotalOut += nAmount;
@ -4993,7 +4993,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
auto selectorAccount = pwalletMain->FindAccountForSelector(ztxoSelectorOpt.value()); auto selectorAccount = pwalletMain->FindAccountForSelector(ztxoSelectorOpt.value());
bool unknownOrLegacy = !selectorAccount.has_value() || selectorAccount.value() == ZCASH_LEGACY_ACCOUNT; bool unknownOrLegacy = !selectorAccount.has_value() || selectorAccount.value() == ZCASH_LEGACY_ACCOUNT;
std::visit(match { examine(decoded.value(), match {
[&](const libzcash::UnifiedAddress& ua) { [&](const libzcash::UnifiedAddress& ua) {
if (unknownOrLegacy) { if (unknownOrLegacy) {
throw JSONRPCError( throw JSONRPCError(
@ -5009,7 +5009,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
"Invalid from address: is a bare receiver from a Unified Address in this wallet. Provide the UA as returned by z_getaddressforaccount instead."); "Invalid from address: is a bare receiver from a Unified Address in this wallet. Provide the UA as returned by z_getaddressforaccount instead.");
} }
} }
}, decoded.value()); });
return ztxoSelectorOpt.value(); return ztxoSelectorOpt.value();
} }
@ -5292,7 +5292,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
auto destStr = params[1].get_str(); auto destStr = params[1].get_str();
auto destaddress = keyIO.DecodePaymentAddress(destStr); auto destaddress = keyIO.DecodePaymentAddress(destStr);
if (destaddress.has_value()) { if (destaddress.has_value()) {
std::visit(match { examine(destaddress.value(), match {
[&](const CKeyID& addr) { [&](const CKeyID& addr) {
throw JSONRPCError(RPC_VERIFY_REJECTED, "Cannot shield coinbase output to a p2pkh address."); throw JSONRPCError(RPC_VERIFY_REJECTED, "Cannot shield coinbase output to a p2pkh address.");
}, },
@ -5316,7 +5316,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
} }
involvesOrchard = ua.GetOrchardReceiver().has_value(); involvesOrchard = ua.GetOrchardReceiver().has_value();
} }
}, destaddress.value()); });
} else { } else {
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destStr); throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destStr);
} }
@ -5570,7 +5570,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
} else { } else {
auto addr = keyIO.DecodePaymentAddress(address); auto addr = keyIO.DecodePaymentAddress(address);
if (addr.has_value()) { if (addr.has_value()) {
std::visit(match { examine(addr.value(), match {
[&](const CKeyID& taddr) { [&](const CKeyID& taddr) {
taddrs.insert(taddr); taddrs.insert(taddr);
isFromNonSprout = true; isFromNonSprout = true;
@ -5591,7 +5591,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
RPC_INVALID_PARAMETER, RPC_INVALID_PARAMETER,
"Unified addresses are not supported in z_mergetoaddress"); "Unified addresses are not supported in z_mergetoaddress");
} }
}, addr.value()); });
} else { } else {
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Unknown address format: ") + address); throw JSONRPCError(RPC_INVALID_PARAMETER, string("Unknown address format: ") + address);
} }
@ -5621,7 +5621,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
bool isToSproutZaddr = false; bool isToSproutZaddr = false;
bool isToSaplingZaddr = false; bool isToSaplingZaddr = false;
if (destaddress.has_value()) { if (destaddress.has_value()) {
std::visit(match { examine(destaddress.value(), match {
[&](CKeyID addr) { [&](CKeyID addr) {
isToTaddr = true; isToTaddr = true;
}, },
@ -5643,7 +5643,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
RPC_INVALID_PARAMETER, RPC_INVALID_PARAMETER,
"Invalid parameter, unified addresses are not yet supported."); "Invalid parameter, unified addresses are not yet supported.");
} }
}, destaddress.value()); });
} else { } else {
throw JSONRPCError( throw JSONRPCError(
RPC_INVALID_PARAMETER, RPC_INVALID_PARAMETER,

View File

@ -680,14 +680,14 @@ std::optional<ZcashdUnifiedFullViewingKey> CWallet::GetUnifiedFullViewingKeyByAc
} }
WalletUAGenerationResult ToWalletUAGenerationResult(UnifiedAddressGenerationResult result) { WalletUAGenerationResult ToWalletUAGenerationResult(UnifiedAddressGenerationResult result) {
return std::visit(match { return examine(result, match {
[](const UnifiedAddressGenerationError& err) { [](const UnifiedAddressGenerationError& err) {
return WalletUAGenerationResult(err); return WalletUAGenerationResult(err);
}, },
[](const std::pair<UnifiedAddress, diversifier_index_t>& addrPair) { [](const std::pair<UnifiedAddress, diversifier_index_t>& addrPair) {
return WalletUAGenerationResult(addrPair); return WalletUAGenerationResult(addrPair);
} }
}, result); });
} }
WalletUAGenerationResult CWallet::GenerateUnifiedAddress( WalletUAGenerationResult CWallet::GenerateUnifiedAddress(
@ -882,7 +882,7 @@ std::pair<PaymentAddress, RecipientType> CWallet::GetPaymentAddressForRecipient(
} }
auto ufvk = self->GetUFVKForReceiver(RecipientAddressToReceiver(recipient)); auto ufvk = self->GetUFVKForReceiver(RecipientAddressToReceiver(recipient));
std::pair<PaymentAddress, RecipientType> defaultAddress = std::visit(match { std::pair<PaymentAddress, RecipientType> defaultAddress = examine(recipient, match {
[&](const CKeyID& addr) { [&](const CKeyID& addr) {
auto ua = self->FindUnifiedAddressByReceiver(addr); auto ua = self->FindUnifiedAddressByReceiver(addr);
if (ua.has_value()) { if (ua.has_value()) {
@ -979,7 +979,7 @@ std::pair<PaymentAddress, RecipientType> CWallet::GetPaymentAddressForRecipient(
return std::make_pair(PaymentAddress{UnifiedAddress::ForSingleReceiver(addr)}, RecipientType::CounterpartyAddress); return std::make_pair(PaymentAddress{UnifiedAddress::ForSingleReceiver(addr)}, RecipientType::CounterpartyAddress);
} }
}, recipient); });
auto recipientsPtr = sendRecipients.find(txid); auto recipientsPtr = sendRecipients.find(txid);
if (recipientsPtr == sendRecipients.end()) { if (recipientsPtr == sendRecipients.end()) {
@ -1005,7 +1005,7 @@ std::pair<PaymentAddress, RecipientType> CWallet::GetPaymentAddressForRecipient(
bool CWallet::IsInternalRecipient(const libzcash::RecipientAddress& recipient) const bool CWallet::IsInternalRecipient(const libzcash::RecipientAddress& recipient) const
{ {
auto self = this; auto self = this;
return std::visit(match { return examine(recipient, match {
[&](const CKeyID& addr) { [&](const CKeyID& addr) {
// we never send transparent change when sending to or from a // we never send transparent change when sending to or from a
// unified address // unified address
@ -1035,7 +1035,7 @@ bool CWallet::IsInternalRecipient(const libzcash::RecipientAddress& recipient) c
} }
return false; return false;
} }
}, recipient); });
} }
void CWallet::LoadRecipientMapping(const uint256& txid, const RecipientMapping& mapping) { void CWallet::LoadRecipientMapping(const uint256& txid, const RecipientMapping& mapping) {
@ -1092,7 +1092,7 @@ bool CWallet::LoadCaches()
// restore unified addresses that have been previously generated to the // restore unified addresses that have been previously generated to the
// keystore // keystore
for (const auto &[j, receiverTypes] : metadata->second.GetKnownReceiverSetsByDiversifierIndex()) { for (const auto &[j, receiverTypes] : metadata->second.GetKnownReceiverSetsByDiversifierIndex()) {
bool restored = std::visit(match { bool restored = examine(ufvk.value().Address(j, receiverTypes), match {
[&](const UnifiedAddressGenerationError& err) { [&](const UnifiedAddressGenerationError& err) {
LogPrintf("%s: Error: Unable to generate a unified address.\n", LogPrintf("%s: Error: Unable to generate a unified address.\n",
__func__); __func__);
@ -1115,7 +1115,7 @@ bool CWallet::LoadCaches()
return CCryptoKeyStore::AddTransparentReceiverForUnifiedAddress( return CCryptoKeyStore::AddTransparentReceiverForUnifiedAddress(
ufvkId, addr.second, addr.first); ufvkId, addr.second, addr.first);
} }
}, ufvk.value().Address(j, receiverTypes)); });
// failure to restore the generated address is an error // failure to restore the generated address is an error
if (!restored) return false; if (!restored) return false;
@ -1896,7 +1896,7 @@ std::optional<ZTXOSelector> CWallet::ZTXOSelectorForAddress(
{ {
auto self = this; auto self = this;
std::optional<ZTXOPattern> pattern = std::nullopt; std::optional<ZTXOPattern> pattern = std::nullopt;
std::visit(match { examine(addr, match {
[&](const CKeyID& addr) { [&](const CKeyID& addr) {
if (!requireSpendingKey || self->HaveKey(addr)) { if (!requireSpendingKey || self->HaveKey(addr)) {
pattern = addr; pattern = addr;
@ -1935,7 +1935,7 @@ std::optional<ZTXOSelector> CWallet::ZTXOSelectorForAddress(
} }
} }
} }
}, addr); });
if (pattern.has_value()) { if (pattern.has_value()) {
return ZTXOSelector(pattern.value(), requireSpendingKey, transparentCoinbasePolicy); return ZTXOSelector(pattern.value(), requireSpendingKey, transparentCoinbasePolicy);
@ -1951,7 +1951,7 @@ std::optional<ZTXOSelector> CWallet::ZTXOSelectorForViewingKey(
{ {
auto self = this; auto self = this;
std::optional<ZTXOPattern> pattern = std::nullopt; std::optional<ZTXOPattern> pattern = std::nullopt;
std::visit(match { examine(vk, match {
[&](const libzcash::SaplingExtendedFullViewingKey& vk) { [&](const libzcash::SaplingExtendedFullViewingKey& vk) {
if (!requireSpendingKey || self->HaveSaplingSpendingKey(vk)) { if (!requireSpendingKey || self->HaveSaplingSpendingKey(vk)) {
pattern = vk; pattern = vk;
@ -1971,7 +1971,7 @@ std::optional<ZTXOSelector> CWallet::ZTXOSelectorForViewingKey(
pattern = ufvk; pattern = ufvk;
} }
} }
}, vk); });
if (pattern.has_value()) { if (pattern.has_value()) {
return ZTXOSelector(pattern.value(), requireSpendingKey, transparentCoinbasePolicy); return ZTXOSelector(pattern.value(), requireSpendingKey, transparentCoinbasePolicy);
@ -1990,7 +1990,7 @@ ZTXOSelector CWallet::LegacyTransparentZTXOSelector(bool requireSpendingKey, Tra
std::optional<libzcash::AccountId> CWallet::FindAccountForSelector(const ZTXOSelector& selector) const { std::optional<libzcash::AccountId> CWallet::FindAccountForSelector(const ZTXOSelector& selector) const {
auto self = this; auto self = this;
std::optional<libzcash::AccountId> result{}; std::optional<libzcash::AccountId> result{};
std::visit(match { examine(selector.GetPattern(), match {
[&](const CKeyID& addr) { [&](const CKeyID& addr) {
auto meta = self->GetUFVKMetadataForReceiver(addr); auto meta = self->GetUFVKMetadataForReceiver(addr);
if (meta.has_value()) { if (meta.has_value()) {
@ -2034,7 +2034,7 @@ std::optional<libzcash::AccountId> CWallet::FindAccountForSelector(const ZTXOSel
result = acct.GetAccountId(); result = acct.GetAccountId();
} }
} }
}, selector.GetPattern()); });
return result; return result;
} }
@ -2044,7 +2044,7 @@ bool CWallet::SelectorMatchesAddress(
const ZTXOSelector& selector, const ZTXOSelector& selector,
const CTxDestination& address) const { const CTxDestination& address) const {
auto self = this; auto self = this;
return std::visit(match { return examine(selector.GetPattern(), match {
[&](const CKeyID& keyId) { [&](const CKeyID& keyId) {
CTxDestination keyIdDest = keyId; CTxDestination keyIdDest = keyId;
return address == keyIdDest; return address == keyIdDest;
@ -2061,7 +2061,7 @@ bool CWallet::SelectorMatchesAddress(
// for a UA selector when matching transparent addresses, we only match addresses // for a UA selector when matching transparent addresses, we only match addresses
// that explicitly appear as receivers in the UA. // that explicitly appear as receivers in the UA.
for (const auto& receiver : uaSelector) { for (const auto& receiver : uaSelector) {
bool matches = std::visit(match { bool matches = examine(receiver, match {
[&](const libzcash::OrchardRawAddress& orchardAddr) { return false; }, [&](const libzcash::OrchardRawAddress& orchardAddr) { return false; },
[&](const libzcash::SaplingPaymentAddress& saplingAddr) { return false; }, [&](const libzcash::SaplingPaymentAddress& saplingAddr) { return false; },
[&](const libzcash::UnknownReceiver& receiver) { return false; }, [&](const libzcash::UnknownReceiver& receiver) { return false; },
@ -2073,7 +2073,7 @@ bool CWallet::SelectorMatchesAddress(
CTxDestination keyIdDest = keyId; CTxDestination keyIdDest = keyId;
return address == keyIdDest; return address == keyIdDest;
} }
}, receiver); });
if (matches) return true; if (matches) return true;
} }
return false; return false;
@ -2098,24 +2098,24 @@ bool CWallet::SelectorMatchesAddress(
} }
return false; return false;
} }
}, selector.GetPattern()); });
} }
// Sprout // Sprout
bool CWallet::SelectorMatchesAddress( bool CWallet::SelectorMatchesAddress(
const ZTXOSelector& selector, const ZTXOSelector& selector,
const libzcash::SproutPaymentAddress& a0) const { const libzcash::SproutPaymentAddress& a0) const {
return std::visit(match { return examine(selector.GetPattern(), match {
[&](const libzcash::SproutPaymentAddress& a1) { return a0 == a1; }, [&](const libzcash::SproutPaymentAddress& a1) { return a0 == a1; },
[&](const libzcash::SproutViewingKey& vk) { return a0 == vk.address(); }, [&](const libzcash::SproutViewingKey& vk) { return a0 == vk.address(); },
[&](const auto& addr) { return false; }, [&](const auto& addr) { return false; },
}, selector.GetPattern()); });
} }
// Sapling // Sapling
bool CWallet::SelectorMatchesAddress( bool CWallet::SelectorMatchesAddress(
const ZTXOSelector& selector, const ZTXOSelector& selector,
const libzcash::SaplingPaymentAddress& a0) const { const libzcash::SaplingPaymentAddress& a0) const {
auto self = this; auto self = this;
return std::visit(match { return examine(selector.GetPattern(), match {
[&](const CKeyID& keyId) { return false; }, [&](const CKeyID& keyId) { return false; },
[&](const CScriptID& scriptId) { return false; }, [&](const CScriptID& scriptId) { return false; },
[&](const libzcash::SproutPaymentAddress& addr) { return false; }, [&](const libzcash::SproutPaymentAddress& addr) { return false; },
@ -2162,7 +2162,7 @@ bool CWallet::SelectorMatchesAddress(
} }
return false; return false;
} }
}, selector.GetPattern()); });
} }
std::optional<RecipientAddress> CWallet::GenerateChangeAddressForAccount( std::optional<RecipientAddress> CWallet::GenerateChangeAddressForAccount(
@ -2357,7 +2357,7 @@ SpendableInputs CWallet::FindSpendableInputs(
if (selectOrchard) { if (selectOrchard) {
// for Orchard, we select both the internal and external IVKs. // for Orchard, we select both the internal and external IVKs.
auto orchardIvks = std::visit(match { auto orchardIvks = examine(selector.GetPattern(), match {
[&](const libzcash::UnifiedAddress& selectorUA) -> std::vector<OrchardIncomingViewingKey> { [&](const libzcash::UnifiedAddress& selectorUA) -> std::vector<OrchardIncomingViewingKey> {
auto orchardReceiver = selectorUA.GetOrchardReceiver(); auto orchardReceiver = selectorUA.GetOrchardReceiver();
if (orchardReceiver.has_value()) { if (orchardReceiver.has_value()) {
@ -2392,7 +2392,7 @@ SpendableInputs CWallet::FindSpendableInputs(
return {}; return {};
}, },
[&](const auto& addr) -> std::vector<OrchardIncomingViewingKey> { return {}; } [&](const auto& addr) -> std::vector<OrchardIncomingViewingKey> { return {}; }
}, selector.GetPattern()); });
for (const auto& ivk : orchardIvks) { for (const auto& ivk : orchardIvks) {
std::vector<OrchardNoteMetadata> incomingNotes; std::vector<OrchardNoteMetadata> incomingNotes;
@ -3993,7 +3993,7 @@ bool CWallet::IsChange(const CTxOut& txout) const
// We look to key metadata to determine whether the address was generated // We look to key metadata to determine whether the address was generated
// using an internal key path. This could fail to identify some legacy // using an internal key path. This could fail to identify some legacy
// change addresses as change outputs. // change addresses as change outputs.
return std::visit(match { return examine(address, match {
[&](const CKeyID& key) { [&](const CKeyID& key) {
auto keyMetaIt = mapKeyMetadata.find(key); auto keyMetaIt = mapKeyMetadata.find(key);
return return
@ -4006,7 +4006,7 @@ bool CWallet::IsChange(const CTxOut& txout) const
IsInternalKeyPath(44, BIP44CoinType(), keyMetaIt->second.hdKeypath); IsInternalKeyPath(44, BIP44CoinType(), keyMetaIt->second.hdKeypath);
}, },
[&](const auto& other) { return false; } [&](const auto& other) { return false; }
}, address); });
} }
CAmount CWallet::GetChange(const CTxOut& txout) const CAmount CWallet::GetChange(const CTxOut& txout) const
@ -6905,7 +6905,7 @@ bool CMerkleTx::AcceptToMemoryPool(CValidationState& state, bool fLimitFree, boo
NoteFilter NoteFilter::ForPaymentAddresses(const std::vector<libzcash::PaymentAddress>& paymentAddrs) { NoteFilter NoteFilter::ForPaymentAddresses(const std::vector<libzcash::PaymentAddress>& paymentAddrs) {
NoteFilter addrs; NoteFilter addrs;
for (const auto& addr: paymentAddrs) { for (const auto& addr: paymentAddrs) {
std::visit(match { examine(addr, match {
[&](const CKeyID& keyId) { }, [&](const CKeyID& keyId) { },
[&](const CScriptID& scriptId) { }, [&](const CScriptID& scriptId) { },
[&](const libzcash::SproutPaymentAddress& addr) { [&](const libzcash::SproutPaymentAddress& addr) {
@ -6916,7 +6916,7 @@ 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 { examine(receiver, match {
[&](const libzcash::OrchardRawAddress& addr) { [&](const libzcash::OrchardRawAddress& addr) {
addrs.orchardAddresses.insert(addr); addrs.orchardAddresses.insert(addr);
}, },
@ -6924,10 +6924,10 @@ NoteFilter NoteFilter::ForPaymentAddresses(const std::vector<libzcash::PaymentAd
addrs.saplingAddresses.insert(addr); addrs.saplingAddresses.insert(addr);
}, },
[&](const auto& other) { } [&](const auto& other) { }
}, receiver); });
} }
}, },
}, addr); });
} }
return addrs; return addrs;
} }
@ -7735,7 +7735,7 @@ bool TransactionStrategy::IsCompatibleWith(PrivacyPolicy policy) const {
} }
bool ZTXOSelector::SelectsTransparent() const { bool ZTXOSelector::SelectsTransparent() const {
return std::visit(match { return examine(this->pattern, match {
[](const CKeyID& keyId) { return true; }, [](const CKeyID& keyId) { return true; },
[](const CScriptID& scriptId) { return true; }, [](const CScriptID& scriptId) { return true; },
[](const libzcash::SproutPaymentAddress& addr) { return false; }, [](const libzcash::SproutPaymentAddress& addr) { return false; },
@ -7747,32 +7747,32 @@ bool ZTXOSelector::SelectsTransparent() const {
}, },
[](const libzcash::UnifiedFullViewingKey& ufvk) { return ufvk.GetTransparentKey().has_value(); }, [](const libzcash::UnifiedFullViewingKey& ufvk) { return ufvk.GetTransparentKey().has_value(); },
[](const AccountZTXOPattern& acct) { return acct.IncludesP2PKH() || acct.IncludesP2SH(); } [](const AccountZTXOPattern& acct) { return acct.IncludesP2PKH() || acct.IncludesP2SH(); }
}, this->pattern); });
} }
bool ZTXOSelector::SelectsSprout() const { bool ZTXOSelector::SelectsSprout() const {
return transparentCoinbasePolicy != TransparentCoinbasePolicy::Require && std::visit(match { return transparentCoinbasePolicy != TransparentCoinbasePolicy::Require && examine(this->pattern, match {
[](const libzcash::SproutViewingKey& addr) { return true; }, [](const libzcash::SproutViewingKey& addr) { return true; },
[](const libzcash::SproutPaymentAddress& extfvk) { return true; }, [](const libzcash::SproutPaymentAddress& extfvk) { return true; },
[](const auto& addr) { return false; } [](const auto& addr) { return false; }
}, this->pattern); });
} }
bool ZTXOSelector::SelectsSapling() const { bool ZTXOSelector::SelectsSapling() const {
return transparentCoinbasePolicy != TransparentCoinbasePolicy::Require && std::visit(match { return transparentCoinbasePolicy != TransparentCoinbasePolicy::Require && examine(this->pattern, match {
[](const libzcash::SaplingPaymentAddress& addr) { return true; }, [](const libzcash::SaplingPaymentAddress& addr) { return true; },
[](const libzcash::SaplingExtendedSpendingKey& extfvk) { return true; }, [](const libzcash::SaplingExtendedSpendingKey& extfvk) { return true; },
[](const libzcash::UnifiedAddress& ua) { return ua.GetSaplingReceiver().has_value(); }, [](const libzcash::UnifiedAddress& ua) { return ua.GetSaplingReceiver().has_value(); },
[](const libzcash::UnifiedFullViewingKey& ufvk) { return ufvk.GetSaplingKey().has_value(); }, [](const libzcash::UnifiedFullViewingKey& ufvk) { return ufvk.GetSaplingKey().has_value(); },
[](const AccountZTXOPattern& acct) { return acct.IncludesSapling(); }, [](const AccountZTXOPattern& acct) { return acct.IncludesSapling(); },
[](const auto& addr) { return false; } [](const auto& addr) { return false; }
}, this->pattern); });
} }
bool ZTXOSelector::SelectsOrchard() const { bool ZTXOSelector::SelectsOrchard() const {
return transparentCoinbasePolicy != TransparentCoinbasePolicy::Require && std::visit(match { return transparentCoinbasePolicy != TransparentCoinbasePolicy::Require && examine(this->pattern, match {
[](const libzcash::UnifiedAddress& ua) { return ua.GetOrchardReceiver().has_value(); }, [](const libzcash::UnifiedAddress& ua) { return ua.GetOrchardReceiver().has_value(); },
[](const libzcash::UnifiedFullViewingKey& ufvk) { return ufvk.GetOrchardKey().has_value(); }, [](const libzcash::UnifiedFullViewingKey& ufvk) { return ufvk.GetOrchardKey().has_value(); },
[](const AccountZTXOPattern& acct) { return acct.IncludesOrchard(); }, [](const AccountZTXOPattern& acct) { return acct.IncludesOrchard(); },
[](const auto& addr) { return false; } [](const auto& addr) { return false; }
}, this->pattern); });
} }
bool SpendableInputs::LimitToAmount( bool SpendableInputs::LimitToAmount(

View File

@ -105,7 +105,7 @@ PrepareTransactionResult WalletTxBuilder::PrepareTransaction(
return addChangePayment(zufvk.GetChangeAddress(getAllowedChangePools(receiverTypes))); return addChangePayment(zufvk.GetChangeAddress(getAllowedChangePools(receiverTypes)));
}; };
changeAddr = std::visit(match { changeAddr = examine(selector.GetPattern(), match {
[&](const CKeyID&) -> ChangeAddress { [&](const CKeyID&) -> ChangeAddress {
return changeAddressForTransparentSelector({ReceiverType::P2PKH}); return changeAddressForTransparentSelector({ReceiverType::P2PKH});
}, },
@ -142,7 +142,7 @@ PrepareTransactionResult WalletTxBuilder::PrepareTransaction(
acct.GetAccountId(), acct.GetAccountId(),
getAllowedChangePools(acct.GetReceiverTypes()))); getAllowedChangePools(acct.GetReceiverTypes())));
} }
}, selector.GetPattern()); });
} }
auto ovks = SelectOVKs(wallet, selector, spendable); auto ovks = SelectOVKs(wallet, selector, spendable);
@ -216,7 +216,7 @@ InputSelectionResult WalletTxBuilder::ResolveInputsAndPayments(
std::vector<ResolvedPayment> resolvedPayments; std::vector<ResolvedPayment> resolvedPayments;
std::optional<AddressResolutionError> resolutionError; std::optional<AddressResolutionError> resolutionError;
for (const auto& payment : payments) { for (const auto& payment : payments) {
std::visit(match { examine(payment.GetAddress(), match {
[&](const CKeyID& p2pkh) { [&](const CKeyID& p2pkh) {
if (strategy.AllowRevealedRecipients()) { if (strategy.AllowRevealedRecipients()) {
resolvedPayments.emplace_back( resolvedPayments.emplace_back(
@ -289,7 +289,7 @@ InputSelectionResult WalletTxBuilder::ResolveInputsAndPayments(
} }
} }
} }
}, payment.GetAddress()); });
if (resolutionError.has_value()) { if (resolutionError.has_value()) {
return resolutionError.value(); return resolutionError.value();
@ -379,7 +379,7 @@ std::pair<uint256, uint256> WalletTxBuilder::SelectOVKs(
const ZTXOSelector& selector, const ZTXOSelector& selector,
const SpendableInputs& spendable) const const SpendableInputs& spendable) const
{ {
return std::visit(match { return examine(selector.GetPattern(), match {
[&](const CKeyID& keyId) { [&](const CKeyID& keyId) {
return wallet.GetLegacyAccountKey().ToAccountPubKey().GetOVKsForShielding(); return wallet.GetLegacyAccountKey().ToAccountPubKey().GetOVKsForShielding();
}, },
@ -420,7 +420,7 @@ std::pair<uint256, uint256> WalletTxBuilder::SelectOVKs(
return GetOVKsForUFVK(ufvk.value().ToFullViewingKey(), spendable); return GetOVKsForUFVK(ufvk.value().ToFullViewingKey(), spendable);
} }
}, },
}, selector.GetPattern()); });
} }
PrivacyPolicy TransactionEffects::GetRequiredPrivacyPolicy() const PrivacyPolicy TransactionEffects::GetRequiredPrivacyPolicy() const
@ -552,7 +552,7 @@ TransactionBuilderResult TransactionEffects::ApproveAndBuild(
// Add outputs // Add outputs
try { try {
for (const auto& r : payments.GetResolvedPayments()) { for (const auto& r : payments.GetResolvedPayments()) {
std::visit(match { examine(r.address, match {
[&](const CKeyID& keyId) { [&](const CKeyID& keyId) {
if (r.memo.has_value()) { if (r.memo.has_value()) {
throw TransactionBuilderResult( throw TransactionBuilderResult(
@ -579,7 +579,7 @@ TransactionBuilderResult TransactionEffects::ApproveAndBuild(
r.isInternal ? internalOVK : externalOVK, addr, r.amount, r.isInternal ? internalOVK : externalOVK, addr, r.amount,
r.memo.has_value() ? std::optional(r.memo.value().ToBytes()) : std::nullopt); r.memo.has_value() ? std::optional(r.memo.value().ToBytes()) : std::nullopt);
} }
}, r.address); });
} }
} catch (const TransactionBuilderResult& result) { } catch (const TransactionBuilderResult& result) {
return result; return result;
@ -635,14 +635,14 @@ TransactionBuilderResult TransactionEffects::ApproveAndBuild(
// (re)calculate the change. In future, we shouldnt rely on `TransactionBuilder` ever // (re)calculate the change. In future, we shouldnt rely on `TransactionBuilder` ever
// calculating change. // calculating change.
if (changeAddr.has_value()) { if (changeAddr.has_value()) {
std::visit(match { examine(changeAddr.value(), match {
[&](const SproutPaymentAddress& addr) { [&](const SproutPaymentAddress& addr) {
builder.SendChangeToSprout(addr); builder.SendChangeToSprout(addr);
}, },
[&](const RecipientAddress&) { [&](const RecipientAddress&) {
assert(totalSpend == payments.Total() + fee); assert(totalSpend == payments.Total() + fee);
} }
}, changeAddr.value()); });
} }
// Build the transaction // Build the transaction

View File

@ -80,7 +80,7 @@ public:
} }
void AddPayment(ResolvedPayment payment) { void AddPayment(ResolvedPayment payment) {
std::visit(match { examine(payment.address, match {
[&](const CKeyID& addr) { [&](const CKeyID& addr) {
t_outputs_total += payment.amount; t_outputs_total += payment.amount;
recipientPools.insert(OutputPool::Transparent); recipientPools.insert(OutputPool::Transparent);
@ -97,7 +97,7 @@ public:
orchard_outputs_total += payment.amount; orchard_outputs_total += payment.amount;
recipientPools.insert(OutputPool::Orchard); recipientPools.insert(OutputPool::Orchard);
} }
}, payment.address); });
payments.push_back(payment); payments.push_back(payment);
} }

View File

@ -336,7 +336,7 @@ class CSerializeRecipientAddress {
template<typename Stream> template<typename Stream>
void Serialize(Stream& s) const { void Serialize(Stream& s) const {
std::visit(match { examine(recipient, match {
[&](const CKeyID& keyId) { [&](const CKeyID& keyId) {
ReceiverTypeSer(libzcash::ReceiverType::P2PKH).Serialize(s); ReceiverTypeSer(libzcash::ReceiverType::P2PKH).Serialize(s);
s << keyId; s << keyId;
@ -353,7 +353,7 @@ class CSerializeRecipientAddress {
ReceiverTypeSer(libzcash::ReceiverType::Orchard).Serialize(s); ReceiverTypeSer(libzcash::ReceiverType::Orchard).Serialize(s);
s << orchardAddr; s << orchardAddr;
} }
}, recipient); });
} }
template<typename Stream> template<typename Stream>

View File

@ -178,13 +178,13 @@ std::optional<RecipientAddress> UnifiedAddress::GetPreferredRecipientAddress(
// order from most-preferred to least. // order from most-preferred to least.
std::optional<RecipientAddress> result; std::optional<RecipientAddress> result;
for (const auto& receiver : *this) { for (const auto& receiver : *this) {
std::visit(match { examine(receiver, match {
[&](const OrchardRawAddress& addr) { if (nu5Active) result = addr; }, [&](const OrchardRawAddress& addr) { if (nu5Active) result = addr; },
[&](const SaplingPaymentAddress& addr) { result = addr; }, [&](const SaplingPaymentAddress& addr) { result = addr; },
[&](const CScriptID& addr) { result = addr; }, [&](const CScriptID& addr) { result = addr; },
[&](const CKeyID& addr) { result = addr; }, [&](const CKeyID& addr) { result = addr; },
[&](const UnknownReceiver& addr) { } [&](const UnknownReceiver& addr) { }
}, receiver); });
if (result.has_value()) { if (result.has_value()) {
return result; return result;
@ -194,13 +194,13 @@ std::optional<RecipientAddress> UnifiedAddress::GetPreferredRecipientAddress(
} }
bool HasKnownReceiverType(const Receiver& receiver) { bool HasKnownReceiverType(const Receiver& receiver) {
return std::visit(match { return examine(receiver, match {
[](const OrchardRawAddress& addr) { return true; }, [](const OrchardRawAddress& addr) { return true; },
[](const SaplingPaymentAddress& addr) { return true; }, [](const SaplingPaymentAddress& addr) { return true; },
[](const CScriptID& addr) { return true; }, [](const CScriptID& addr) { return true; },
[](const CKeyID& addr) { return true; }, [](const CKeyID& addr) { return true; },
[](const UnknownReceiver& addr) { return false; } [](const UnknownReceiver& addr) { return false; }
}, receiver); });
} }
std::pair<std::string, PaymentAddress> AddressInfoFromSpendingKey::operator()(const SproutSpendingKey &sk) const { std::pair<std::string, PaymentAddress> AddressInfoFromSpendingKey::operator()(const SproutSpendingKey &sk) const {

View File

@ -102,7 +102,7 @@ public:
std::set<ReceiverType> GetKnownReceiverTypes() const { std::set<ReceiverType> GetKnownReceiverTypes() const {
std::set<ReceiverType> result; std::set<ReceiverType> result;
for (const auto& receiver : receivers) { for (const auto& receiver : receivers) {
std::visit(match { examine(receiver, match {
[&](const libzcash::OrchardRawAddress &zaddr) { [&](const libzcash::OrchardRawAddress &zaddr) {
result.insert(ReceiverType::Orchard); result.insert(ReceiverType::Orchard);
}, },
@ -117,7 +117,7 @@ public:
}, },
[&](const libzcash::UnknownReceiver &uaddr) { [&](const libzcash::UnknownReceiver &uaddr) {
} }
}, receiver); });
} }
return result; return result;
} }

View File

@ -33,16 +33,16 @@ bool libzcash::HasTransparent(const std::set<ReceiverType>& receiverTypes) {
} }
Receiver libzcash::RecipientAddressToReceiver(const RecipientAddress& recipient) { Receiver libzcash::RecipientAddressToReceiver(const RecipientAddress& recipient) {
return std::visit(match { return examine(recipient, match {
[](const CKeyID& key) { return Receiver(key); }, [](const CKeyID& key) { return Receiver(key); },
[](const CScriptID& scriptId) { return Receiver(scriptId); }, [](const CScriptID& scriptId) { return Receiver(scriptId); },
[](const libzcash::OrchardRawAddress& addr) { return Receiver(addr); }, [](const libzcash::OrchardRawAddress& addr) { return Receiver(addr); },
[](const libzcash::SaplingPaymentAddress& addr) { return Receiver(addr); } [](const libzcash::SaplingPaymentAddress& addr) { return Receiver(addr); }
}, recipient); });
} }
std::string libzcash::DebugPrintReceiver(const Receiver& receiver) { std::string libzcash::DebugPrintReceiver(const Receiver& receiver) {
return std::visit(match { return examine(receiver, match {
[&](const OrchardRawAddress &zaddr) { [&](const OrchardRawAddress &zaddr) {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss << zaddr; ss << zaddr;
@ -65,7 +65,7 @@ std::string libzcash::DebugPrintReceiver(const Receiver& receiver) {
unknown.typecode, unknown.typecode,
HexStr(unknown.data.begin(), unknown.data.end())); HexStr(unknown.data.begin(), unknown.data.end()));
} }
}, receiver); });
}; };
std::string libzcash::DebugPrintRecipientAddress(const RecipientAddress& addr) { std::string libzcash::DebugPrintRecipientAddress(const RecipientAddress& addr) {
@ -198,7 +198,7 @@ UnifiedAddressGenerationResult ZcashdUnifiedFullViewingKey::FindAddress(
std::optional<RecipientAddress> ZcashdUnifiedFullViewingKey::GetChangeAddress(const ChangeRequest& req) const { std::optional<RecipientAddress> ZcashdUnifiedFullViewingKey::GetChangeAddress(const ChangeRequest& req) const {
std::optional<RecipientAddress> addr; std::optional<RecipientAddress> addr;
std::visit(match { examine(req, match {
[&](const TransparentChangeRequest& req) { [&](const TransparentChangeRequest& req) {
if (transparentKey.has_value()) { if (transparentKey.has_value()) {
auto changeAddr = transparentKey.value().GetChangeAddress(req.GetIndex()); auto changeAddr = transparentKey.value().GetChangeAddress(req.GetIndex());
@ -217,7 +217,7 @@ std::optional<RecipientAddress> ZcashdUnifiedFullViewingKey::GetChangeAddress(co
addr = orchardKey.value().GetChangeAddress(); addr = orchardKey.value().GetChangeAddress();
} }
} }
}, req); });
return addr; return addr;
} }