Merge pull request #6494 from daira/examine
Improve code readability using `examine` macro
This commit is contained in:
commit
1feec6a3b4
|
@ -188,7 +188,7 @@ namespace Consensus {
|
|||
throw std::runtime_error("Funding stream address was not a valid " PACKAGE_NAME " address.");
|
||||
}
|
||||
|
||||
std::visit(match {
|
||||
examine(addr.value(), match {
|
||||
[&](const CKeyID& keyId) {
|
||||
addresses.push_back(GetScriptForDestination(keyId));
|
||||
},
|
||||
|
@ -201,7 +201,7 @@ namespace Consensus {
|
|||
[&](const auto& zaddr) {
|
||||
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);
|
||||
|
|
|
@ -468,7 +468,7 @@ std::optional<libzcash::PaymentAddress> KeyIO::DecodePaymentAddress(const std::s
|
|||
}
|
||||
|
||||
// Finally, try parsing as transparent
|
||||
return std::visit(match {
|
||||
return examine(DecodeDestination(str), match {
|
||||
[](const CKeyID& keyIdIn) {
|
||||
std::optional<libzcash::PaymentAddress> keyId = keyIdIn;
|
||||
return keyId;
|
||||
|
@ -481,7 +481,7 @@ std::optional<libzcash::PaymentAddress> KeyIO::DecodePaymentAddress(const std::s
|
|||
std::optional<libzcash::PaymentAddress> result = std::nullopt;
|
||||
return result;
|
||||
}
|
||||
}, DecodeDestination(str));
|
||||
});
|
||||
}
|
||||
|
||||
bool KeyIO::IsValidPaymentAddressString(const std::string& str) const
|
||||
|
|
|
@ -19,10 +19,10 @@ std::optional<AddressUFVKMetadata> CKeyStore::GetUFVKMetadataForAddress(
|
|||
const CTxDestination& address) const
|
||||
{
|
||||
auto self = this;
|
||||
return std::visit(match {
|
||||
return examine(address, match {
|
||||
[](const CNoDestination&) -> std::optional<AddressUFVKMetadata> { return std::nullopt; },
|
||||
[&](const auto& addr) { return self->GetUFVKMetadataForReceiver(addr); }
|
||||
}, address);
|
||||
});
|
||||
}
|
||||
|
||||
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> result;
|
||||
std::visit(match {
|
||||
examine(vk, match {
|
||||
[&](const libzcash::SproutViewingKey& vk) {},
|
||||
[&](const libzcash::SaplingExtendedFullViewingKey& extfvk) {
|
||||
const auto saplingIvk = extfvk.ToIncomingViewingKey();
|
||||
|
@ -456,7 +456,7 @@ std::optional<libzcash::UFVKId> CBasicKeyStore::GetUFVKIdForViewingKey(const lib
|
|||
}
|
||||
}
|
||||
}
|
||||
}, vk);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -351,11 +351,11 @@ void BlockAssembler::resetBlock(const MinerAddress& minerAddress)
|
|||
|
||||
// Reserve space for coinbase tx
|
||||
// nBlockMaxSize already includes 1000 bytes for transaction structure overhead.
|
||||
nBlockSize = std::visit(match {
|
||||
nBlockSize = examine(minerAddress, match {
|
||||
[](const libzcash::OrchardRawAddress&) { return 9000; },
|
||||
[](const libzcash::SaplingPaymentAddress&) { return 1000; },
|
||||
[](const boost::shared_ptr<CReserveScript> &) { return 1000; },
|
||||
}, minerAddress);
|
||||
});
|
||||
nBlockSigOps = 100;
|
||||
|
||||
// These counters do not include coinbase tx
|
||||
|
@ -812,14 +812,12 @@ std::optional<MinerAddress> ExtractMinerAddress::operator()(const libzcash::Sapl
|
|||
std::optional<MinerAddress> ExtractMinerAddress::operator()(const libzcash::UnifiedAddress &addr) const {
|
||||
auto preferred = addr.GetPreferredRecipientAddress(consensus, height);
|
||||
if (preferred.has_value()) {
|
||||
std::optional<MinerAddress> ret;
|
||||
std::visit(match {
|
||||
[&](const libzcash::OrchardRawAddress addr) { ret = MinerAddress(addr); },
|
||||
[&](const libzcash::SaplingPaymentAddress addr) { ret = MinerAddress(addr); },
|
||||
[&](const CKeyID keyID) { ret = operator()(keyID); },
|
||||
[&](const auto other) { ret = std::nullopt; }
|
||||
}, preferred.value());
|
||||
return ret;
|
||||
return examine(preferred.value(), match {
|
||||
[&](const libzcash::OrchardRawAddress addr) -> std::optional<MinerAddress> { return MinerAddress(addr); },
|
||||
[&](const libzcash::SaplingPaymentAddress addr) -> std::optional<MinerAddress> { return MinerAddress(addr); },
|
||||
[&](const CKeyID keyID) -> std::optional<MinerAddress> { return operator()(keyID); },
|
||||
[&](const auto other) -> std::optional<MinerAddress> { return std::nullopt; }
|
||||
});
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
|
@ -457,7 +457,7 @@ void TransactionBuilder::SendChangeTo(
|
|||
saplingChangeAddr = std::nullopt;
|
||||
sproutChangeAddr = std::nullopt;
|
||||
|
||||
std::visit(match {
|
||||
examine(changeAddr, match {
|
||||
[&](const CKeyID& keyId) {
|
||||
tChangeAddr = keyId;
|
||||
},
|
||||
|
@ -470,7 +470,7 @@ void TransactionBuilder::SendChangeTo(
|
|||
[&](const libzcash::OrchardRawAddress& changeDest) {
|
||||
orchardChangeAddr = std::make_pair(ovk, changeDest);
|
||||
}
|
||||
}, changeAddr);
|
||||
});
|
||||
}
|
||||
|
||||
void TransactionBuilder::SendChangeToSprout(const libzcash::SproutPaymentAddress& zaddr) {
|
||||
|
|
|
@ -21,4 +21,17 @@ template<class... Ts> struct match : Ts... { using Ts::operator()...; };
|
|||
// explicit deduction guide (not needed as of C++20)
|
||||
template<class... Ts> match(Ts...) -> match<Ts...>;
|
||||
|
||||
// A wrapper around two-argument `std::visit` that reverses the arguments, putting the
|
||||
// value to be visited first. This is normally used as:
|
||||
//
|
||||
// examine(specimen, match {
|
||||
// ...
|
||||
// })
|
||||
//
|
||||
// The return type is inferred as it would be for `std::visit`.
|
||||
template<class Specimen, class Visitor>
|
||||
decltype(auto) examine(Specimen&& specimen, Visitor&& visitor) {
|
||||
return std::visit(visitor, specimen);
|
||||
}
|
||||
|
||||
#endif // ZCASH_UTIL_MATCH_H
|
||||
|
|
|
@ -47,7 +47,7 @@ void ThrowInputSelectionError(
|
|||
const ZTXOSelector& selector,
|
||||
const TransactionStrategy& strategy)
|
||||
{
|
||||
std::visit(match {
|
||||
examine(err, match {
|
||||
[](const AddressResolutionError& err) {
|
||||
switch (err) {
|
||||
case AddressResolutionError::SproutRecipientsNotSupported:
|
||||
|
@ -105,7 +105,7 @@ void ThrowInputSelectionError(
|
|||
strprintf(
|
||||
"Insufficient funds: have %s, %s",
|
||||
FormatMoney(err.available),
|
||||
std::visit(match {
|
||||
examine(err.reason, match {
|
||||
[](const InsufficientFundsError& ife) {
|
||||
return strprintf("need %s", FormatMoney(ife.required));
|
||||
},
|
||||
|
@ -116,8 +116,7 @@ void ThrowInputSelectionError(
|
|||
FormatMoney(dte.changeAmount),
|
||||
FormatMoney(dte.dustThreshold));
|
||||
}
|
||||
},
|
||||
err.reason))
|
||||
}))
|
||||
+ (selector.TransparentCoinbasePolicy() != TransparentCoinbasePolicy::Disallow
|
||||
? "" :
|
||||
"; note that coinbase outputs will not be selected if you specify "
|
||||
|
@ -161,5 +160,5 @@ void ThrowInputSelectionError(
|
|||
err.maxNotes,
|
||||
err.orchardNotes));
|
||||
}
|
||||
}, err);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -96,7 +96,7 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
|||
isToTaddr_ = false;
|
||||
isToZaddr_ = false;
|
||||
|
||||
std::visit(match {
|
||||
examine(recipient.first, match {
|
||||
[&](const CKeyID& keyId) {
|
||||
toTaddr_ = keyId;
|
||||
isToTaddr_ = true;
|
||||
|
@ -118,7 +118,7 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
|||
RPC_INVALID_ADDRESS_OR_KEY,
|
||||
"z_mergetoaddress does not yet support sending to unified addresses");
|
||||
},
|
||||
}, recipient.first);
|
||||
});
|
||||
|
||||
// Log the context info i.e. the call parameters to z_mergetoaddress
|
||||
if (LogAcceptCategory("zrpcunsafe")) {
|
||||
|
|
|
@ -151,7 +151,7 @@ uint256 AsyncRPCOperation_sendmany::main_impl(CWallet& wallet) {
|
|||
anchordepth_);
|
||||
|
||||
uint256 txid;
|
||||
std::visit(match {
|
||||
examine(preparedTx, match {
|
||||
[&](const InputSelectionError& err) {
|
||||
ThrowInputSelectionError(err, ztxoSelector_, strategy_);
|
||||
},
|
||||
|
@ -194,7 +194,7 @@ uint256 AsyncRPCOperation_sendmany::main_impl(CWallet& wallet) {
|
|||
throw;
|
||||
}
|
||||
}
|
||||
}, preparedTx);
|
||||
});
|
||||
|
||||
return txid;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
std::visit(match {
|
||||
examine(toAddress, match {
|
||||
[&](CKeyID addr) {
|
||||
throw JSONRPCError(RPC_VERIFY_REJECTED, "Cannot shield coinbase output to a p2pkh address.");
|
||||
},
|
||||
|
@ -96,7 +96,7 @@ AsyncRPCOperation_shieldcoinbase::AsyncRPCOperation_shieldcoinbase(
|
|||
[&](libzcash::UnifiedAddress addr) {
|
||||
tozaddr_ = addr;
|
||||
}
|
||||
}, toAddress);
|
||||
});
|
||||
|
||||
// Log the context info
|
||||
if (LogAcceptCategory("zrpcunsafe")) {
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
}
|
||||
|
||||
static Memo FromHexOrThrow(const std::string& memoHex) {
|
||||
return std::visit(match {
|
||||
return examine(Memo::FromHex(memoHex), match {
|
||||
[&](Memo memo) {
|
||||
return memo;
|
||||
},
|
||||
|
@ -69,7 +69,7 @@ public:
|
|||
// unreachable, but the compiler can't tell
|
||||
return Memo::NoMemo();
|
||||
}
|
||||
}, Memo::FromHex(memoHex));
|
||||
});
|
||||
}
|
||||
|
||||
// This copies, because if it returns a reference to the underlying value,
|
||||
|
|
|
@ -929,7 +929,7 @@ UniValue z_exportkey(const UniValue& params, bool fHelp)
|
|||
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) {
|
||||
CKey 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.");
|
||||
return std::string(); //unreachable, here to make the compiler happy
|
||||
}
|
||||
}, address.value());
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -526,19 +526,23 @@ UniValue listaddresses(const UniValue& params, bool fHelp)
|
|||
std::set<CTxDestination> t_mnemonic_change_dests;
|
||||
std::set<CTxDestination> t_imported_dests;
|
||||
std::set<CTxDestination> t_watchonly_dests;
|
||||
|
||||
auto GetSourceForDestination = match {
|
||||
[&](const CKeyID& addr) -> std::optional<PaymentAddressSource> {
|
||||
return GetSourceForPaymentAddress(pwalletMain)(addr);
|
||||
},
|
||||
[&](const CScriptID& addr) -> std::optional<PaymentAddressSource> {
|
||||
return GetSourceForPaymentAddress(pwalletMain)(addr);
|
||||
},
|
||||
[&](const CNoDestination& addr) -> std::optional<PaymentAddressSource> {
|
||||
return std::nullopt;
|
||||
},
|
||||
};
|
||||
|
||||
// Get the CTxDestination values for all the entries in the transparent address book.
|
||||
// This will include any address that has been generated by this wallet.
|
||||
for (const std::pair<CTxDestination, CAddressBookData>& item : pwalletMain->mapAddressBook) {
|
||||
std::optional<PaymentAddressSource> source;
|
||||
std::visit(match {
|
||||
[&](const CKeyID& addr) {
|
||||
source = GetSourceForPaymentAddress(pwalletMain)(addr);
|
||||
},
|
||||
[&](const CScriptID& addr) {
|
||||
source = GetSourceForPaymentAddress(pwalletMain)(addr);
|
||||
},
|
||||
[&](const CNoDestination& addr) {}
|
||||
}, item.first);
|
||||
std::optional<PaymentAddressSource> source = std::visit(GetSourceForDestination, item.first);
|
||||
if (source.has_value()) {
|
||||
switch (source.value()) {
|
||||
case PaymentAddressSource::Random:
|
||||
|
@ -570,16 +574,7 @@ UniValue listaddresses(const UniValue& params, bool fHelp)
|
|||
t_imported_dests.count(item.first) == 0 &&
|
||||
t_watchonly_dests.count(item.first) == 0)
|
||||
{
|
||||
std::optional<PaymentAddressSource> source;
|
||||
std::visit(match {
|
||||
[&](const CKeyID& addr) {
|
||||
source = GetSourceForPaymentAddress(pwalletMain)(addr);
|
||||
},
|
||||
[&](const CScriptID& addr) {
|
||||
source = GetSourceForPaymentAddress(pwalletMain)(addr);
|
||||
},
|
||||
[&](const CNoDestination& addr) {}
|
||||
}, item.first);
|
||||
std::optional<PaymentAddressSource> source = std::visit(GetSourceForDestination, item.first);
|
||||
if (source.has_value()) {
|
||||
switch (source.value()) {
|
||||
case PaymentAddressSource::Random:
|
||||
|
@ -3296,7 +3291,7 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp)
|
|||
UniValue result(UniValue::VOBJ);
|
||||
result.pushKV("account", (uint64_t)account);
|
||||
|
||||
std::visit(match {
|
||||
examine(res, match {
|
||||
[&](std::pair<libzcash::UnifiedAddress, libzcash::diversifier_index_t> addr) {
|
||||
result.pushKV("address", KeyIO(Params()).EncodePaymentAddress(addr.first));
|
||||
UniValue j;
|
||||
|
@ -3349,7 +3344,7 @@ UniValue z_getaddressforaccount(const UniValue& params, bool fHelp)
|
|||
}
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, strErr);
|
||||
},
|
||||
}, res);
|
||||
});
|
||||
|
||||
UniValue receiver_types(UniValue::VARR);
|
||||
for (const auto& receiverType : receiverTypes) {
|
||||
|
@ -3543,7 +3538,7 @@ UniValue z_listunifiedreceivers(const UniValue& params, bool fHelp)
|
|||
|
||||
UniValue result(UniValue::VOBJ);
|
||||
for (const auto& receiver : ua) {
|
||||
std::visit(match {
|
||||
examine(receiver, match {
|
||||
[&](const libzcash::OrchardRawAddress& addr) {
|
||||
// Create a single-receiver UA that just contains this Orchard receiver.
|
||||
UnifiedAddress singleReceiver;
|
||||
|
@ -3560,7 +3555,7 @@ UniValue z_listunifiedreceivers(const UniValue& params, bool fHelp)
|
|||
result.pushKV("p2pkh", keyIO.EncodePaymentAddress(addr));
|
||||
},
|
||||
[](auto rest) {},
|
||||
}, receiver);
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -3697,7 +3692,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
|
|||
|
||||
// A non-unified address argument that is a receiver within a
|
||||
// unified address known to this wallet is not allowed.
|
||||
if (std::visit(match {
|
||||
if (examine(decoded.value(), match {
|
||||
[&](const CKeyID& addr) {
|
||||
return pwalletMain->FindUnifiedAddressByReceiver(addr).has_value();
|
||||
},
|
||||
|
@ -3715,7 +3710,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
|
|||
// We allow unified addresses themselves, which cannot recurse.
|
||||
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.");
|
||||
}
|
||||
|
||||
|
@ -3820,7 +3815,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
|
|||
}
|
||||
};
|
||||
|
||||
std::visit(match {
|
||||
examine(decoded.value(), match {
|
||||
[&](const CKeyID& addr) { push_transparent_result(addr); },
|
||||
[&](const CScriptID& addr) { push_transparent_result(addr); },
|
||||
[&](const libzcash::SproutPaymentAddress& addr) {
|
||||
|
@ -3857,7 +3852,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
|
|||
},
|
||||
[&](const libzcash::UnifiedAddress& addr) {
|
||||
for (const auto& receiver : addr) {
|
||||
std::visit(match {
|
||||
examine(receiver, match {
|
||||
[&](const libzcash::SaplingPaymentAddress& addr) {
|
||||
push_sapling_result(addr);
|
||||
},
|
||||
|
@ -3874,10 +3869,10 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp)
|
|||
},
|
||||
[&](const UnknownReceiver& unknown) {}
|
||||
|
||||
}, receiver);
|
||||
});
|
||||
}
|
||||
}
|
||||
}, decoded.value());
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -3934,7 +3929,7 @@ UniValue z_getbalance(const UniValue& params, bool fHelp)
|
|||
}
|
||||
|
||||
CAmount nBalance = 0;
|
||||
std::visit(match {
|
||||
examine(pa.value(), match {
|
||||
[&](const CKeyID& addr) {
|
||||
nBalance = getBalanceTaddr(addr, std::nullopt, nMinDepth, false);
|
||||
},
|
||||
|
@ -3966,7 +3961,7 @@ UniValue z_getbalance(const UniValue& params, bool fHelp)
|
|||
nBalance += t.GetNoteValue();
|
||||
}
|
||||
},
|
||||
}, pa.value());
|
||||
});
|
||||
|
||||
// inZat
|
||||
if (params.size() > 2 && params[2].get_bool()) {
|
||||
|
@ -4731,7 +4726,7 @@ size_t EstimateTxSize(
|
|||
size_t taddrRecipientCount = 0;
|
||||
size_t orchardRecipientCount = 0;
|
||||
for (const Payment& recipient : recipients) {
|
||||
std::visit(match {
|
||||
examine(recipient.GetAddress(), match {
|
||||
[&](const CKeyID&) {
|
||||
taddrRecipientCount += 1;
|
||||
},
|
||||
|
@ -4756,7 +4751,7 @@ size_t EstimateTxSize(
|
|||
taddrRecipientCount += 1;
|
||||
}
|
||||
}
|
||||
}, recipient.GetAddress());
|
||||
});
|
||||
}
|
||||
|
||||
bool nu5Active = Params().GetConsensus().NetworkUpgradeActive(nextBlockHeight, Consensus::UPGRADE_NU5);
|
||||
|
@ -4905,7 +4900,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
|||
std::optional<Memo> memo;
|
||||
if (!memoValue.isNull()) {
|
||||
auto memoHex = memoValue.get_str();
|
||||
std::visit(match {
|
||||
examine(Memo::FromHex(memoHex), match {
|
||||
[&](MemoError err) {
|
||||
switch (err) {
|
||||
case MemoError::HexDecodeError:
|
||||
|
@ -4923,7 +4918,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
|||
[&](Memo result) {
|
||||
memo = result;
|
||||
}
|
||||
}, Memo::FromHex(memoHex));
|
||||
});
|
||||
}
|
||||
|
||||
UniValue av = find_value(o, "amount");
|
||||
|
@ -4932,7 +4927,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
|||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, amount must be positive");
|
||||
}
|
||||
|
||||
std::visit(match {
|
||||
examine(addr.value(), match {
|
||||
[&](const CKeyID &) {
|
||||
tcoinbasePolicy = TransparentCoinbasePolicy::Disallow;
|
||||
},
|
||||
|
@ -4944,7 +4939,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
|||
auto preferredRecipient =
|
||||
ua.GetPreferredRecipientAddress(chainparams.GetConsensus(), nextBlockHeight);
|
||||
if (preferredRecipient.has_value()) {
|
||||
std::visit(match {
|
||||
examine(preferredRecipient.value(), match {
|
||||
[&](const CKeyID &) {
|
||||
tcoinbasePolicy = TransparentCoinbasePolicy::Disallow;
|
||||
},
|
||||
|
@ -4952,11 +4947,11 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
|||
tcoinbasePolicy = TransparentCoinbasePolicy::Disallow;
|
||||
},
|
||||
[](const auto &) { }
|
||||
}, preferredRecipient.value());
|
||||
});
|
||||
}
|
||||
},
|
||||
[](const auto &) { }
|
||||
}, addr.value());
|
||||
});
|
||||
|
||||
recipients.push_back(Payment(addr.value(), nAmount, memo));
|
||||
nTotalOut += nAmount;
|
||||
|
@ -4993,7 +4988,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
|
|||
|
||||
auto selectorAccount = pwalletMain->FindAccountForSelector(ztxoSelectorOpt.value());
|
||||
bool unknownOrLegacy = !selectorAccount.has_value() || selectorAccount.value() == ZCASH_LEGACY_ACCOUNT;
|
||||
std::visit(match {
|
||||
examine(decoded.value(), match {
|
||||
[&](const libzcash::UnifiedAddress& ua) {
|
||||
if (unknownOrLegacy) {
|
||||
throw JSONRPCError(
|
||||
|
@ -5009,7 +5004,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.");
|
||||
}
|
||||
}
|
||||
}, decoded.value());
|
||||
});
|
||||
|
||||
return ztxoSelectorOpt.value();
|
||||
}
|
||||
|
@ -5292,7 +5287,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
|
|||
auto destStr = params[1].get_str();
|
||||
auto destaddress = keyIO.DecodePaymentAddress(destStr);
|
||||
if (destaddress.has_value()) {
|
||||
std::visit(match {
|
||||
examine(destaddress.value(), match {
|
||||
[&](const CKeyID& addr) {
|
||||
throw JSONRPCError(RPC_VERIFY_REJECTED, "Cannot shield coinbase output to a p2pkh address.");
|
||||
},
|
||||
|
@ -5316,7 +5311,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
|
|||
}
|
||||
involvesOrchard = ua.GetOrchardReceiver().has_value();
|
||||
}
|
||||
}, destaddress.value());
|
||||
});
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destStr);
|
||||
}
|
||||
|
@ -5570,7 +5565,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
|||
} else {
|
||||
auto addr = keyIO.DecodePaymentAddress(address);
|
||||
if (addr.has_value()) {
|
||||
std::visit(match {
|
||||
examine(addr.value(), match {
|
||||
[&](const CKeyID& taddr) {
|
||||
taddrs.insert(taddr);
|
||||
isFromNonSprout = true;
|
||||
|
@ -5591,7 +5586,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
|||
RPC_INVALID_PARAMETER,
|
||||
"Unified addresses are not supported in z_mergetoaddress");
|
||||
}
|
||||
}, addr.value());
|
||||
});
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Unknown address format: ") + address);
|
||||
}
|
||||
|
@ -5621,7 +5616,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
|||
bool isToSproutZaddr = false;
|
||||
bool isToSaplingZaddr = false;
|
||||
if (destaddress.has_value()) {
|
||||
std::visit(match {
|
||||
examine(destaddress.value(), match {
|
||||
[&](CKeyID addr) {
|
||||
isToTaddr = true;
|
||||
},
|
||||
|
@ -5643,7 +5638,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp)
|
|||
RPC_INVALID_PARAMETER,
|
||||
"Invalid parameter, unified addresses are not yet supported.");
|
||||
}
|
||||
}, destaddress.value());
|
||||
});
|
||||
} else {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
|
|
|
@ -680,14 +680,14 @@ std::optional<ZcashdUnifiedFullViewingKey> CWallet::GetUnifiedFullViewingKeyByAc
|
|||
}
|
||||
|
||||
WalletUAGenerationResult ToWalletUAGenerationResult(UnifiedAddressGenerationResult result) {
|
||||
return std::visit(match {
|
||||
return examine(result, match {
|
||||
[](const UnifiedAddressGenerationError& err) {
|
||||
return WalletUAGenerationResult(err);
|
||||
},
|
||||
[](const std::pair<UnifiedAddress, diversifier_index_t>& addrPair) {
|
||||
return WalletUAGenerationResult(addrPair);
|
||||
}
|
||||
}, result);
|
||||
});
|
||||
}
|
||||
|
||||
WalletUAGenerationResult CWallet::GenerateUnifiedAddress(
|
||||
|
@ -882,7 +882,7 @@ std::pair<PaymentAddress, RecipientType> CWallet::GetPaymentAddressForRecipient(
|
|||
}
|
||||
|
||||
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) {
|
||||
auto ua = self->FindUnifiedAddressByReceiver(addr);
|
||||
if (ua.has_value()) {
|
||||
|
@ -979,7 +979,7 @@ std::pair<PaymentAddress, RecipientType> CWallet::GetPaymentAddressForRecipient(
|
|||
|
||||
return std::make_pair(PaymentAddress{UnifiedAddress::ForSingleReceiver(addr)}, RecipientType::CounterpartyAddress);
|
||||
}
|
||||
}, recipient);
|
||||
});
|
||||
|
||||
auto recipientsPtr = sendRecipients.find(txid);
|
||||
if (recipientsPtr == sendRecipients.end()) {
|
||||
|
@ -1005,7 +1005,7 @@ std::pair<PaymentAddress, RecipientType> CWallet::GetPaymentAddressForRecipient(
|
|||
bool CWallet::IsInternalRecipient(const libzcash::RecipientAddress& recipient) const
|
||||
{
|
||||
auto self = this;
|
||||
return std::visit(match {
|
||||
return examine(recipient, match {
|
||||
[&](const CKeyID& addr) {
|
||||
// we never send transparent change when sending to or from a
|
||||
// unified address
|
||||
|
@ -1035,7 +1035,7 @@ bool CWallet::IsInternalRecipient(const libzcash::RecipientAddress& recipient) c
|
|||
}
|
||||
return false;
|
||||
}
|
||||
}, recipient);
|
||||
});
|
||||
}
|
||||
|
||||
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
|
||||
// keystore
|
||||
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) {
|
||||
LogPrintf("%s: Error: Unable to generate a unified address.\n",
|
||||
__func__);
|
||||
|
@ -1115,7 +1115,7 @@ bool CWallet::LoadCaches()
|
|||
return CCryptoKeyStore::AddTransparentReceiverForUnifiedAddress(
|
||||
ufvkId, addr.second, addr.first);
|
||||
}
|
||||
}, ufvk.value().Address(j, receiverTypes));
|
||||
});
|
||||
|
||||
// failure to restore the generated address is an error
|
||||
if (!restored) return false;
|
||||
|
@ -1896,7 +1896,7 @@ std::optional<ZTXOSelector> CWallet::ZTXOSelectorForAddress(
|
|||
{
|
||||
auto self = this;
|
||||
std::optional<ZTXOPattern> pattern = std::nullopt;
|
||||
std::visit(match {
|
||||
examine(addr, match {
|
||||
[&](const CKeyID& addr) {
|
||||
if (!requireSpendingKey || self->HaveKey(addr)) {
|
||||
pattern = addr;
|
||||
|
@ -1935,7 +1935,7 @@ std::optional<ZTXOSelector> CWallet::ZTXOSelectorForAddress(
|
|||
}
|
||||
}
|
||||
}
|
||||
}, addr);
|
||||
});
|
||||
|
||||
if (pattern.has_value()) {
|
||||
return ZTXOSelector(pattern.value(), requireSpendingKey, transparentCoinbasePolicy);
|
||||
|
@ -1951,7 +1951,7 @@ std::optional<ZTXOSelector> CWallet::ZTXOSelectorForViewingKey(
|
|||
{
|
||||
auto self = this;
|
||||
std::optional<ZTXOPattern> pattern = std::nullopt;
|
||||
std::visit(match {
|
||||
examine(vk, match {
|
||||
[&](const libzcash::SaplingExtendedFullViewingKey& vk) {
|
||||
if (!requireSpendingKey || self->HaveSaplingSpendingKey(vk)) {
|
||||
pattern = vk;
|
||||
|
@ -1971,7 +1971,7 @@ std::optional<ZTXOSelector> CWallet::ZTXOSelectorForViewingKey(
|
|||
pattern = ufvk;
|
||||
}
|
||||
}
|
||||
}, vk);
|
||||
});
|
||||
|
||||
if (pattern.has_value()) {
|
||||
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 {
|
||||
auto self = this;
|
||||
std::optional<libzcash::AccountId> result{};
|
||||
std::visit(match {
|
||||
examine(selector.GetPattern(), match {
|
||||
[&](const CKeyID& addr) {
|
||||
auto meta = self->GetUFVKMetadataForReceiver(addr);
|
||||
if (meta.has_value()) {
|
||||
|
@ -2034,7 +2034,7 @@ std::optional<libzcash::AccountId> CWallet::FindAccountForSelector(const ZTXOSel
|
|||
result = acct.GetAccountId();
|
||||
}
|
||||
}
|
||||
}, selector.GetPattern());
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2044,7 +2044,7 @@ bool CWallet::SelectorMatchesAddress(
|
|||
const ZTXOSelector& selector,
|
||||
const CTxDestination& address) const {
|
||||
auto self = this;
|
||||
return std::visit(match {
|
||||
return examine(selector.GetPattern(), match {
|
||||
[&](const CKeyID& keyId) {
|
||||
CTxDestination keyIdDest = keyId;
|
||||
return address == keyIdDest;
|
||||
|
@ -2061,7 +2061,7 @@ bool CWallet::SelectorMatchesAddress(
|
|||
// for a UA selector when matching transparent addresses, we only match addresses
|
||||
// that explicitly appear as receivers in the UA.
|
||||
for (const auto& receiver : uaSelector) {
|
||||
bool matches = std::visit(match {
|
||||
bool matches = examine(receiver, match {
|
||||
[&](const libzcash::OrchardRawAddress& orchardAddr) { return false; },
|
||||
[&](const libzcash::SaplingPaymentAddress& saplingAddr) { return false; },
|
||||
[&](const libzcash::UnknownReceiver& receiver) { return false; },
|
||||
|
@ -2073,7 +2073,7 @@ bool CWallet::SelectorMatchesAddress(
|
|||
CTxDestination keyIdDest = keyId;
|
||||
return address == keyIdDest;
|
||||
}
|
||||
}, receiver);
|
||||
});
|
||||
if (matches) return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -2098,24 +2098,24 @@ bool CWallet::SelectorMatchesAddress(
|
|||
}
|
||||
return false;
|
||||
}
|
||||
}, selector.GetPattern());
|
||||
});
|
||||
}
|
||||
// Sprout
|
||||
bool CWallet::SelectorMatchesAddress(
|
||||
const ZTXOSelector& selector,
|
||||
const libzcash::SproutPaymentAddress& a0) const {
|
||||
return std::visit(match {
|
||||
return examine(selector.GetPattern(), match {
|
||||
[&](const libzcash::SproutPaymentAddress& a1) { return a0 == a1; },
|
||||
[&](const libzcash::SproutViewingKey& vk) { return a0 == vk.address(); },
|
||||
[&](const auto& addr) { return false; },
|
||||
}, selector.GetPattern());
|
||||
});
|
||||
}
|
||||
// Sapling
|
||||
bool CWallet::SelectorMatchesAddress(
|
||||
const ZTXOSelector& selector,
|
||||
const libzcash::SaplingPaymentAddress& a0) const {
|
||||
auto self = this;
|
||||
return std::visit(match {
|
||||
return examine(selector.GetPattern(), match {
|
||||
[&](const CKeyID& keyId) { return false; },
|
||||
[&](const CScriptID& scriptId) { return false; },
|
||||
[&](const libzcash::SproutPaymentAddress& addr) { return false; },
|
||||
|
@ -2162,7 +2162,7 @@ bool CWallet::SelectorMatchesAddress(
|
|||
}
|
||||
return false;
|
||||
}
|
||||
}, selector.GetPattern());
|
||||
});
|
||||
}
|
||||
|
||||
std::optional<RecipientAddress> CWallet::GenerateChangeAddressForAccount(
|
||||
|
@ -2357,7 +2357,7 @@ SpendableInputs CWallet::FindSpendableInputs(
|
|||
|
||||
if (selectOrchard) {
|
||||
// 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> {
|
||||
auto orchardReceiver = selectorUA.GetOrchardReceiver();
|
||||
if (orchardReceiver.has_value()) {
|
||||
|
@ -2392,7 +2392,7 @@ SpendableInputs CWallet::FindSpendableInputs(
|
|||
return {};
|
||||
},
|
||||
[&](const auto& addr) -> std::vector<OrchardIncomingViewingKey> { return {}; }
|
||||
}, selector.GetPattern());
|
||||
});
|
||||
|
||||
for (const auto& ivk : orchardIvks) {
|
||||
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
|
||||
// using an internal key path. This could fail to identify some legacy
|
||||
// change addresses as change outputs.
|
||||
return std::visit(match {
|
||||
return examine(address, match {
|
||||
[&](const CKeyID& key) {
|
||||
auto keyMetaIt = mapKeyMetadata.find(key);
|
||||
return
|
||||
|
@ -4006,7 +4006,7 @@ bool CWallet::IsChange(const CTxOut& txout) const
|
|||
IsInternalKeyPath(44, BIP44CoinType(), keyMetaIt->second.hdKeypath);
|
||||
},
|
||||
[&](const auto& other) { return false; }
|
||||
}, address);
|
||||
});
|
||||
}
|
||||
|
||||
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 addrs;
|
||||
for (const auto& addr: paymentAddrs) {
|
||||
std::visit(match {
|
||||
examine(addr, match {
|
||||
[&](const CKeyID& keyId) { },
|
||||
[&](const CScriptID& scriptId) { },
|
||||
[&](const libzcash::SproutPaymentAddress& addr) {
|
||||
|
@ -6916,7 +6916,7 @@ NoteFilter NoteFilter::ForPaymentAddresses(const std::vector<libzcash::PaymentAd
|
|||
},
|
||||
[&](const libzcash::UnifiedAddress& uaddr) {
|
||||
for (auto& receiver : uaddr) {
|
||||
std::visit(match {
|
||||
examine(receiver, match {
|
||||
[&](const libzcash::OrchardRawAddress& addr) {
|
||||
addrs.orchardAddresses.insert(addr);
|
||||
},
|
||||
|
@ -6924,10 +6924,10 @@ NoteFilter NoteFilter::ForPaymentAddresses(const std::vector<libzcash::PaymentAd
|
|||
addrs.saplingAddresses.insert(addr);
|
||||
},
|
||||
[&](const auto& other) { }
|
||||
}, receiver);
|
||||
});
|
||||
}
|
||||
},
|
||||
}, addr);
|
||||
});
|
||||
}
|
||||
return addrs;
|
||||
}
|
||||
|
@ -7735,7 +7735,7 @@ bool TransactionStrategy::IsCompatibleWith(PrivacyPolicy policy) const {
|
|||
}
|
||||
|
||||
bool ZTXOSelector::SelectsTransparent() const {
|
||||
return std::visit(match {
|
||||
return examine(this->pattern, match {
|
||||
[](const CKeyID& keyId) { return true; },
|
||||
[](const CScriptID& scriptId) { return true; },
|
||||
[](const libzcash::SproutPaymentAddress& addr) { return false; },
|
||||
|
@ -7747,32 +7747,32 @@ bool ZTXOSelector::SelectsTransparent() const {
|
|||
},
|
||||
[](const libzcash::UnifiedFullViewingKey& ufvk) { return ufvk.GetTransparentKey().has_value(); },
|
||||
[](const AccountZTXOPattern& acct) { return acct.IncludesP2PKH() || acct.IncludesP2SH(); }
|
||||
}, this->pattern);
|
||||
});
|
||||
}
|
||||
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::SproutPaymentAddress& extfvk) { return true; },
|
||||
[](const auto& addr) { return false; }
|
||||
}, this->pattern);
|
||||
});
|
||||
}
|
||||
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::SaplingExtendedSpendingKey& extfvk) { return true; },
|
||||
[](const libzcash::UnifiedAddress& ua) { return ua.GetSaplingReceiver().has_value(); },
|
||||
[](const libzcash::UnifiedFullViewingKey& ufvk) { return ufvk.GetSaplingKey().has_value(); },
|
||||
[](const AccountZTXOPattern& acct) { return acct.IncludesSapling(); },
|
||||
[](const auto& addr) { return false; }
|
||||
}, this->pattern);
|
||||
});
|
||||
}
|
||||
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::UnifiedFullViewingKey& ufvk) { return ufvk.GetOrchardKey().has_value(); },
|
||||
[](const AccountZTXOPattern& acct) { return acct.IncludesOrchard(); },
|
||||
[](const auto& addr) { return false; }
|
||||
}, this->pattern);
|
||||
});
|
||||
}
|
||||
|
||||
bool SpendableInputs::LimitToAmount(
|
||||
|
|
|
@ -105,7 +105,7 @@ PrepareTransactionResult WalletTxBuilder::PrepareTransaction(
|
|||
return addChangePayment(zufvk.GetChangeAddress(getAllowedChangePools(receiverTypes)));
|
||||
};
|
||||
|
||||
changeAddr = std::visit(match {
|
||||
changeAddr = examine(selector.GetPattern(), match {
|
||||
[&](const CKeyID&) -> ChangeAddress {
|
||||
return changeAddressForTransparentSelector({ReceiverType::P2PKH});
|
||||
},
|
||||
|
@ -142,7 +142,7 @@ PrepareTransactionResult WalletTxBuilder::PrepareTransaction(
|
|||
acct.GetAccountId(),
|
||||
getAllowedChangePools(acct.GetReceiverTypes())));
|
||||
}
|
||||
}, selector.GetPattern());
|
||||
});
|
||||
}
|
||||
|
||||
auto ovks = SelectOVKs(wallet, selector, spendable);
|
||||
|
@ -216,7 +216,7 @@ InputSelectionResult WalletTxBuilder::ResolveInputsAndPayments(
|
|||
std::vector<ResolvedPayment> resolvedPayments;
|
||||
std::optional<AddressResolutionError> resolutionError;
|
||||
for (const auto& payment : payments) {
|
||||
std::visit(match {
|
||||
examine(payment.GetAddress(), match {
|
||||
[&](const CKeyID& p2pkh) {
|
||||
if (strategy.AllowRevealedRecipients()) {
|
||||
resolvedPayments.emplace_back(
|
||||
|
@ -289,7 +289,7 @@ InputSelectionResult WalletTxBuilder::ResolveInputsAndPayments(
|
|||
}
|
||||
}
|
||||
}
|
||||
}, payment.GetAddress());
|
||||
});
|
||||
|
||||
if (resolutionError.has_value()) {
|
||||
return resolutionError.value();
|
||||
|
@ -379,7 +379,7 @@ std::pair<uint256, uint256> WalletTxBuilder::SelectOVKs(
|
|||
const ZTXOSelector& selector,
|
||||
const SpendableInputs& spendable) const
|
||||
{
|
||||
return std::visit(match {
|
||||
return examine(selector.GetPattern(), match {
|
||||
[&](const CKeyID& keyId) {
|
||||
return wallet.GetLegacyAccountKey().ToAccountPubKey().GetOVKsForShielding();
|
||||
},
|
||||
|
@ -420,7 +420,7 @@ std::pair<uint256, uint256> WalletTxBuilder::SelectOVKs(
|
|||
return GetOVKsForUFVK(ufvk.value().ToFullViewingKey(), spendable);
|
||||
}
|
||||
},
|
||||
}, selector.GetPattern());
|
||||
});
|
||||
}
|
||||
|
||||
PrivacyPolicy TransactionEffects::GetRequiredPrivacyPolicy() const
|
||||
|
@ -550,21 +550,19 @@ TransactionBuilderResult TransactionEffects::ApproveAndBuild(
|
|||
}
|
||||
|
||||
// Add outputs
|
||||
try {
|
||||
for (const auto& r : payments.GetResolvedPayments()) {
|
||||
std::visit(match {
|
||||
std::optional<TransactionBuilderResult> result;
|
||||
examine(r.address, match {
|
||||
[&](const CKeyID& keyId) {
|
||||
if (r.memo.has_value()) {
|
||||
throw TransactionBuilderResult(
|
||||
"Memos cannot be sent to transparent addresses.");
|
||||
result = TransactionBuilderResult("Memos cannot be sent to transparent addresses.");
|
||||
} else {
|
||||
builder.AddTransparentOutput(keyId, r.amount);
|
||||
}
|
||||
},
|
||||
[&](const CScriptID& scriptId) {
|
||||
if (r.memo.has_value()) {
|
||||
throw TransactionBuilderResult(
|
||||
"Memos cannot be sent to transparent addresses.");
|
||||
result = TransactionBuilderResult("Memos cannot be sent to transparent addresses.");
|
||||
} else {
|
||||
builder.AddTransparentOutput(scriptId, r.amount);
|
||||
}
|
||||
|
@ -578,11 +576,11 @@ TransactionBuilderResult TransactionEffects::ApproveAndBuild(
|
|||
builder.AddOrchardOutput(
|
||||
r.isInternal ? internalOVK : externalOVK, addr, r.amount,
|
||||
r.memo.has_value() ? std::optional(r.memo.value().ToBytes()) : std::nullopt);
|
||||
},
|
||||
});
|
||||
if (result.has_value()) {
|
||||
return result.value();
|
||||
}
|
||||
}, r.address);
|
||||
}
|
||||
} catch (const TransactionBuilderResult& result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Add transparent utxos
|
||||
|
@ -635,14 +633,14 @@ TransactionBuilderResult TransactionEffects::ApproveAndBuild(
|
|||
// (re)calculate the change. In future, we shouldn’t rely on `TransactionBuilder` ever
|
||||
// calculating change.
|
||||
if (changeAddr.has_value()) {
|
||||
std::visit(match {
|
||||
examine(changeAddr.value(), match {
|
||||
[&](const SproutPaymentAddress& addr) {
|
||||
builder.SendChangeToSprout(addr);
|
||||
},
|
||||
[&](const RecipientAddress&) {
|
||||
assert(totalSpend == payments.Total() + fee);
|
||||
}
|
||||
}, changeAddr.value());
|
||||
});
|
||||
}
|
||||
|
||||
// Build the transaction
|
||||
|
|
|
@ -80,7 +80,7 @@ public:
|
|||
}
|
||||
|
||||
void AddPayment(ResolvedPayment payment) {
|
||||
std::visit(match {
|
||||
examine(payment.address, match {
|
||||
[&](const CKeyID& addr) {
|
||||
t_outputs_total += payment.amount;
|
||||
recipientPools.insert(OutputPool::Transparent);
|
||||
|
@ -97,7 +97,7 @@ public:
|
|||
orchard_outputs_total += payment.amount;
|
||||
recipientPools.insert(OutputPool::Orchard);
|
||||
}
|
||||
}, payment.address);
|
||||
});
|
||||
payments.push_back(payment);
|
||||
}
|
||||
|
||||
|
|
|
@ -336,7 +336,7 @@ class CSerializeRecipientAddress {
|
|||
|
||||
template<typename Stream>
|
||||
void Serialize(Stream& s) const {
|
||||
std::visit(match {
|
||||
examine(recipient, match {
|
||||
[&](const CKeyID& keyId) {
|
||||
ReceiverTypeSer(libzcash::ReceiverType::P2PKH).Serialize(s);
|
||||
s << keyId;
|
||||
|
@ -353,7 +353,7 @@ class CSerializeRecipientAddress {
|
|||
ReceiverTypeSer(libzcash::ReceiverType::Orchard).Serialize(s);
|
||||
s << orchardAddr;
|
||||
}
|
||||
}, recipient);
|
||||
});
|
||||
}
|
||||
|
||||
template<typename Stream>
|
||||
|
|
|
@ -178,13 +178,13 @@ std::optional<RecipientAddress> UnifiedAddress::GetPreferredRecipientAddress(
|
|||
// order from most-preferred to least.
|
||||
std::optional<RecipientAddress> result;
|
||||
for (const auto& receiver : *this) {
|
||||
std::visit(match {
|
||||
examine(receiver, match {
|
||||
[&](const OrchardRawAddress& addr) { if (nu5Active) result = addr; },
|
||||
[&](const SaplingPaymentAddress& addr) { result = addr; },
|
||||
[&](const CScriptID& addr) { result = addr; },
|
||||
[&](const CKeyID& addr) { result = addr; },
|
||||
[&](const UnknownReceiver& addr) { }
|
||||
}, receiver);
|
||||
});
|
||||
|
||||
if (result.has_value()) {
|
||||
return result;
|
||||
|
@ -194,13 +194,13 @@ std::optional<RecipientAddress> UnifiedAddress::GetPreferredRecipientAddress(
|
|||
}
|
||||
|
||||
bool HasKnownReceiverType(const Receiver& receiver) {
|
||||
return std::visit(match {
|
||||
return examine(receiver, match {
|
||||
[](const OrchardRawAddress& addr) { return true; },
|
||||
[](const SaplingPaymentAddress& addr) { return true; },
|
||||
[](const CScriptID& addr) { return true; },
|
||||
[](const CKeyID& addr) { return true; },
|
||||
[](const UnknownReceiver& addr) { return false; }
|
||||
}, receiver);
|
||||
});
|
||||
}
|
||||
|
||||
std::pair<std::string, PaymentAddress> AddressInfoFromSpendingKey::operator()(const SproutSpendingKey &sk) const {
|
||||
|
|
|
@ -102,7 +102,7 @@ public:
|
|||
std::set<ReceiverType> GetKnownReceiverTypes() const {
|
||||
std::set<ReceiverType> result;
|
||||
for (const auto& receiver : receivers) {
|
||||
std::visit(match {
|
||||
examine(receiver, match {
|
||||
[&](const libzcash::OrchardRawAddress &zaddr) {
|
||||
result.insert(ReceiverType::Orchard);
|
||||
},
|
||||
|
@ -117,7 +117,7 @@ public:
|
|||
},
|
||||
[&](const libzcash::UnknownReceiver &uaddr) {
|
||||
}
|
||||
}, receiver);
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -33,16 +33,16 @@ bool libzcash::HasTransparent(const std::set<ReceiverType>& receiverTypes) {
|
|||
}
|
||||
|
||||
Receiver libzcash::RecipientAddressToReceiver(const RecipientAddress& recipient) {
|
||||
return std::visit(match {
|
||||
return examine(recipient, match {
|
||||
[](const CKeyID& key) { return Receiver(key); },
|
||||
[](const CScriptID& scriptId) { return Receiver(scriptId); },
|
||||
[](const libzcash::OrchardRawAddress& addr) { return Receiver(addr); },
|
||||
[](const libzcash::SaplingPaymentAddress& addr) { return Receiver(addr); }
|
||||
}, recipient);
|
||||
});
|
||||
}
|
||||
|
||||
std::string libzcash::DebugPrintReceiver(const Receiver& receiver) {
|
||||
return std::visit(match {
|
||||
return examine(receiver, match {
|
||||
[&](const OrchardRawAddress &zaddr) {
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss << zaddr;
|
||||
|
@ -65,7 +65,7 @@ std::string libzcash::DebugPrintReceiver(const Receiver& receiver) {
|
|||
unknown.typecode,
|
||||
HexStr(unknown.data.begin(), unknown.data.end()));
|
||||
}
|
||||
}, receiver);
|
||||
});
|
||||
};
|
||||
|
||||
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> addr;
|
||||
std::visit(match {
|
||||
examine(req, match {
|
||||
[&](const TransparentChangeRequest& req) {
|
||||
if (transparentKey.has_value()) {
|
||||
auto changeAddr = transparentKey.value().GetChangeAddress(req.GetIndex());
|
||||
|
@ -217,7 +217,7 @@ std::optional<RecipientAddress> ZcashdUnifiedFullViewingKey::GetChangeAddress(co
|
|||
addr = orchardKey.value().GetChangeAddress();
|
||||
}
|
||||
}
|
||||
}, req);
|
||||
});
|
||||
return addr;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue