diff --git a/src/init.cpp b/src/init.cpp index 040ff0707..851c1f9bb 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -1678,18 +1678,12 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) #ifdef ENABLE_WALLET bool minerAddressInLocalWallet = false; if (pwalletMain) { - CTxDestination addr = keyIO.DecodeDestination(mapArgs["-mineraddress"]); - if (IsValidDestination(addr)) { - CKeyID keyID = std::get(addr); - minerAddressInLocalWallet = pwalletMain->HaveKey(keyID); - } else { - auto zaddr = keyIO.DecodePaymentAddress(mapArgs["-mineraddress"]); - if (!zaddr.has_value()) { - return InitError(_("-mineraddress is not a valid zcash address.")); - } - minerAddressInLocalWallet = std::visit( - HaveSpendingKeyForPaymentAddress(pwalletMain), zaddr.value()); + auto zaddr = keyIO.DecodePaymentAddress(mapArgs["-mineraddress"]); + if (!zaddr.has_value()) { + return InitError(_("-mineraddress is not a valid zcash address.")); } + minerAddressInLocalWallet = std::visit( + HaveSpendingKeyForPaymentAddress(pwalletMain), zaddr.value()); } if (GetBoolArg("-minetolocalwallet", true) && !minerAddressInLocalWallet) { return InitError(_("-mineraddress is not in the local wallet. Either use a local address, or set -minetolocalwallet=0")); diff --git a/src/key_io.cpp b/src/key_io.cpp index c8f180296..6c1a40344 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -16,6 +16,7 @@ #include #include #include +#include "util/match.h" namespace { @@ -113,6 +114,18 @@ private: public: PaymentAddressEncoder(const KeyConstants& keyConstants) : keyConstants(keyConstants) {} + std::string operator()(const CKeyID& id) const + { + std::vector data = keyConstants.Base58Prefix(KeyConstants::PUBKEY_ADDRESS); + data.insert(data.end(), id.begin(), id.end()); + return EncodeBase58Check(data); + } + std::string operator()(const CScriptID& id) const + { + std::vector data = keyConstants.Base58Prefix(KeyConstants::SCRIPT_ADDRESS); + data.insert(data.end(), id.begin(), id.end()); + return EncodeBase58Check(data); + } std::string operator()(const libzcash::SproutPaymentAddress& zaddr) const { CDataStream ss(SER_NETWORK, PROTOCOL_VERSION); @@ -349,17 +362,16 @@ std::string KeyIO::EncodePaymentAddress(const libzcash::PaymentAddress& zaddr) return std::visit(PaymentAddressEncoder(keyConstants), zaddr); } -template -std::optional DecodeAny( - const KeyConstants& keyConstants, - const std::string& str, - std::pair sprout, - std::pair sapling) +template +std::optional DecodeSprout( + const KeyConstants& keyConstants, + const std::string& str, + const std::pair& keyMeta) { std::vector data; if (DecodeBase58Check(str, data)) { - const std::vector& prefix = keyConstants.Base58Prefix(sprout.first); - if ((data.size() == sprout.second + prefix.size()) && + const std::vector& prefix = keyConstants.Base58Prefix(keyMeta.first); + if ((data.size() == keyMeta.second + prefix.size()) && std::equal(prefix.begin(), prefix.end(), data.begin())) { CSerializeData serialized(data.begin() + prefix.size(), data.end()); CDataStream ss(serialized, SER_NETWORK, PROTOCOL_VERSION); @@ -371,15 +383,26 @@ std::optional DecodeAny( } } - data.clear(); + memory_cleanse(data.data(), data.size()); + return std::nullopt; +} + +template +std::optional DecodeSapling( + const KeyConstants& keyConstants, + const std::string& str, + const std::pair& keyMeta) +{ + std::vector data; + auto bech = bech32::Decode(str); - if (bech.first == keyConstants.Bech32HRP(sapling.first) && - bech.second.size() == sapling.second) { + if (bech.first == keyConstants.Bech32HRP(keyMeta.first) && + bech.second.size() == keyMeta.second) { // Bech32 decoding data.reserve((bech.second.size() * 5) / 8); if (ConvertBits<5, 8, false>([&](unsigned char c) { data.push_back(c); }, bech.second.begin(), bech.second.end())) { CDataStream ss(data, SER_NETWORK, PROTOCOL_VERSION); - T3 ret; + T2 ret; ss >> ret; memory_cleanse(data.data(), data.size()); return ret; @@ -390,6 +413,26 @@ std::optional DecodeAny( return std::nullopt; } +template +std::optional DecodeAny( + const KeyConstants& keyConstants, + const std::string& str, + const std::pair& sproutKeyMeta, + const std::pair& saplingKeyMeta) +{ + auto sprout = DecodeSprout(keyConstants, str, sproutKeyMeta); + if (sprout.has_value()) { + return sprout.value(); + } + + auto sapling = DecodeSapling(keyConstants, str, saplingKeyMeta); + if (sapling.has_value()) { + return sapling.value(); + } + + return std::nullopt; +} + /** * `raw` MUST be 43 bytes. */ @@ -457,15 +500,39 @@ std::optional KeyIO::DecodePaymentAddress(const std::s return ua; } - // Fall back on trying Sprout or Sapling. - return DecodeAny( + // Try parsing as a Sapling address + auto sapling = DecodeSapling( keyConstants, str, - std::make_pair(KeyConstants::ZCPAYMENT_ADDRESS, libzcash::SerializedSproutPaymentAddressSize), - std::make_pair(KeyConstants::SAPLING_PAYMENT_ADDRESS, ConvertedSaplingPaymentAddressSize) - ); + std::make_pair(KeyConstants::SAPLING_PAYMENT_ADDRESS, ConvertedSaplingPaymentAddressSize)); + if (sapling.has_value()) { + return sapling.value(); + } + + // Try parsing as a Sprout address + auto sprout = DecodeSprout( + keyConstants, + str, + std::make_pair(KeyConstants::ZCPAYMENT_ADDRESS, libzcash::SerializedSproutPaymentAddressSize)); + if (sprout.has_value()) { + return sprout.value(); + } + + // Finally, try parsing as transparent + return std::visit(match { + [](const CKeyID& keyIdIn) { + std::optional keyId = keyIdIn; + return keyId; + }, + [](const CScriptID& scriptIdIn) { + std::optional scriptId = scriptIdIn; + return scriptId; + }, + [](const CNoDestination& d) { + std::optional result = std::nullopt; + return result; + } + }, DecodeDestination(str)); } bool KeyIO::IsValidPaymentAddressString(const std::string& str) { diff --git a/src/miner.h b/src/miner.h index 61dcc938b..6f9073dc5 100644 --- a/src/miner.h +++ b/src/miner.h @@ -32,6 +32,12 @@ class ExtractMinerAddress public: ExtractMinerAddress() {} + std::optional operator()(const CKeyID &addr) const { + return std::nullopt; + } + std::optional operator()(const CScriptID &addr) const { + return std::nullopt; + } std::optional operator()(const libzcash::SproutPaymentAddress &addr) const { return std::nullopt; } @@ -40,7 +46,7 @@ public: } std::optional operator()(const libzcash::UnifiedAddress &addr) const { auto recipient = RecipientForPaymentAddress()(addr); - if (recipient) { + if (recipient.has_value()) { // This looks like a recursive call, but we are actually calling // ExtractMinerAddress with a different type: // - libzcash::PaymentAddress has a libzcash::UnifiedAddress @@ -51,7 +57,7 @@ public: // This works because std::visit does not require the visitor to // solely match the std::variant, only that it can handle all of // the variant's alternatives. - return std::visit(ExtractMinerAddress(), *recipient); + return std::visit(ExtractMinerAddress(), recipient.value()); } else { // Either the UA only contains unknown shielded receivers (unlikely that we // wouldn't know about them), or it only contains transparent receivers diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 0f21145b7..14f28d8f6 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -217,6 +217,28 @@ UniValue validateaddress(const UniValue& params, bool fHelp) class DescribePaymentAddressVisitor { public: + UniValue operator()(const CKeyID &addr) const { + UniValue obj(UniValue::VOBJ); + obj.pushKV("type", "p2pkh"); +#ifdef ENABLE_WALLET + if (pwalletMain) { + obj.pushKV("ismine", pwalletMain->HaveKey(addr)); + } +#endif + return obj; + } + + UniValue operator()(const CScriptID &addr) const { + UniValue obj(UniValue::VOBJ); + obj.pushKV("type", "p2sh"); +#ifdef ENABLE_WALLET + if (pwalletMain) { + obj.pushKV("ismine", pwalletMain->HaveCScript(addr)); + } +#endif + return obj; + } + UniValue operator()(const libzcash::SproutPaymentAddress &zaddr) const { UniValue obj(UniValue::VOBJ); obj.pushKV("type", "sprout"); diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp index 0b1960b76..9c564110a 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.cpp +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.cpp @@ -202,6 +202,14 @@ bool AsyncRPCOperation_shieldcoinbase::main_impl() { return std::visit(ShieldToAddress(this, sendAmount), tozaddr_); } +bool ShieldToAddress::operator()(const CKeyID &addr) const { + return false; +} + +bool ShieldToAddress::operator()(const CScriptID &addr) const { + return false; +} + bool ShieldToAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const { // update the transaction with these inputs CMutableTransaction rawTx(m_op->tx_); diff --git a/src/wallet/asyncrpcoperation_shieldcoinbase.h b/src/wallet/asyncrpcoperation_shieldcoinbase.h index c1048c00a..403e9f40c 100644 --- a/src/wallet/asyncrpcoperation_shieldcoinbase.h +++ b/src/wallet/asyncrpcoperation_shieldcoinbase.h @@ -103,6 +103,8 @@ public: ShieldToAddress(AsyncRPCOperation_shieldcoinbase *op, CAmount sendAmount) : m_op(op), sendAmount(sendAmount) {} + bool operator()(const CKeyID &zaddr) const; + bool operator()(const CScriptID &zaddr) const; bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::UnifiedAddress &uaddr) const; diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 984d02969..60151e5bb 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2273,7 +2273,7 @@ UniValue z_listunspent(const UniValue& params, bool fHelp) // We want to return unspent notes corresponding to any receiver within a // Unified Address. - for (const auto ra : std::visit(GetRawAddresses(), zaddr.value())) { + for (const auto ra : std::visit(GetRawShieldedAddresses(), zaddr.value())) { bool hasSpendingKey = std::visit(match { [&](const SaplingPaymentAddress& addr) { return pwalletMain->HaveSaplingSpendingKeyForAddress(addr); @@ -3154,10 +3154,16 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, decoded, nMinDepth, false, false); std::visit(match { + [&](const CKeyID& addr) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transparent addresses are not supported by this endpoint."); + }, + [&](const CScriptID& addr) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Transparent addresses are not supported by this endpoint."); + }, [&](const libzcash::SproutPaymentAddress& addr) { bool hasSpendingKey = pwalletMain->HaveSproutSpendingKey(addr); auto nullifierSet = pwalletMain->GetNullifiersForAddresses({addr}); - for (SproutNoteEntry & entry : sproutEntries) { + for (const SproutNoteEntry& entry : sproutEntries) { UniValue obj(UniValue::VOBJ); obj.pushKV("txid", entry.jsop.hash.ToString()); obj.pushKV("amount", ValueFromAmount(CAmount(entry.note.value()))); @@ -3182,7 +3188,7 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) [&](const libzcash::SaplingPaymentAddress& addr) { bool hasSpendingKey = pwalletMain->HaveSaplingSpendingKeyForAddress(addr); auto nullifierSet = pwalletMain->GetNullifiersForAddresses({addr}); - for (SaplingNoteEntry & entry : saplingEntries) { + for (const SaplingNoteEntry& entry : saplingEntries) { UniValue obj(UniValue::VOBJ); obj.pushKV("txid", entry.op.hash.ToString()); obj.pushKV("amount", ValueFromAmount(CAmount(entry.note.value()))); @@ -3895,6 +3901,12 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) if (decoded.has_value()) { std::visit(match { + [&](const CKeyID&) { + // Handled elsewhere + }, + [&](const CScriptID&) { + // Handled elsewhere + }, [&](const libzcash::SaplingPaymentAddress& addr) { mtx.vShieldedOutput.push_back(OutputDescription()); }, @@ -4458,7 +4470,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) if (zaddr.has_value()) { // We want to merge notes corresponding to any receiver within a // Unified Address. - for (const libzcash::RawAddress& ra : std::visit(GetRawAddresses(), zaddr.value())) { + for (const libzcash::RawAddress& ra : std::visit(GetRawShieldedAddresses(), zaddr.value())) { zaddrs.insert(ra); if (std::holds_alternative(ra)) { isFromNonSprout = true; @@ -4489,30 +4501,34 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) // Validate the destination address auto destaddress = params[1].get_str(); + bool isToTaddr = false; bool isToSproutZaddr = false; bool isToSaplingZaddr = false; - CTxDestination taddr = keyIO.DecodeDestination(destaddress); - if (!IsValidDestination(taddr)) { - auto zaddr = keyIO.DecodePaymentAddress(destaddress); - if (zaddr.has_value()) { - std::visit(match { - [&](libzcash::SaplingPaymentAddress addr) { - isToSaplingZaddr = true; - // If Sapling is not active, do not allow sending to a sapling addresses. - if (!saplingActive) { - throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated"); - } - }, - [&](libzcash::SproutPaymentAddress addr) { - isToSproutZaddr = true; - }, - [&](libzcash::UnifiedAddress) { - // TODO UNIFIED + auto paymentAddress = keyIO.DecodePaymentAddress(destaddress); + if (paymentAddress.has_value()) { + std::visit(match { + [&](CKeyID addr) { + isToTaddr = true; + }, + [&](CScriptID addr) { + isToTaddr = true; + }, + [&](libzcash::SaplingPaymentAddress addr) { + isToSaplingZaddr = true; + // If Sapling is not active, do not allow sending to a sapling addresses. + if (!saplingActive) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated"); } - }, zaddr.value()); - } else { - throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress ); - } + }, + [&](libzcash::SproutPaymentAddress addr) { + isToSproutZaddr = true; + }, + [&](libzcash::UnifiedAddress) { + // TODO UNIFIED + } + }, paymentAddress.value()); + } else { + throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress ); } if (canopyActive && isFromNonSprout && isToSproutZaddr) { @@ -4750,7 +4766,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) contextInfo.pushKV("toaddress", params[1]); contextInfo.pushKV("fee", ValueFromAmount(nFee)); - if (!sproutNoteInputs.empty() || !saplingNoteInputs.empty() || !IsValidDestination(taddr)) { + if (!sproutNoteInputs.empty() || !saplingNoteInputs.empty() || !isToTaddr) { // We have shielded inputs or the recipient is a shielded address, and // therefore we cannot create transactions before Sapling activates. if (!saplingActive) { diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4504d5d30..ae0673c4a 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -5041,7 +5041,7 @@ void CWallet::GetFilteredNotes( std::set filterAddresses; if (address.has_value()) { - for (const auto ra : std::visit(GetRawAddresses(), address.value())) { + for (const auto ra : std::visit(GetRawShieldedAddresses(), address.value())) { filterAddresses.insert(ra); } } @@ -5185,37 +5185,57 @@ void CWallet::GetFilteredNotes( // -// Shielded key and address generalizations +// Payment address operations // +// PaymentAddressBelongsToWallet + +bool PaymentAddressBelongsToWallet::operator()(const CKeyID &addr) const +{ + CScript script = GetScriptForDestination(addr); + return m_wallet->HaveKey(addr) || m_wallet->HaveWatchOnly(script); +} +bool PaymentAddressBelongsToWallet::operator()(const CScriptID &addr) const +{ + CScript script = GetScriptForDestination(addr); + return m_wallet->HaveCScript(addr) || m_wallet->HaveWatchOnly(script); +} bool PaymentAddressBelongsToWallet::operator()(const libzcash::SproutPaymentAddress &zaddr) const { return m_wallet->HaveSproutSpendingKey(zaddr) || m_wallet->HaveSproutViewingKey(zaddr); } - bool PaymentAddressBelongsToWallet::operator()(const libzcash::SaplingPaymentAddress &zaddr) const { libzcash::SaplingIncomingViewingKey ivk; // If we have a SaplingExtendedSpendingKey in the wallet, then we will // also have the corresponding SaplingExtendedFullViewingKey. - return m_wallet->GetSaplingIncomingViewingKey(zaddr, ivk) && + return + m_wallet->GetSaplingIncomingViewingKey(zaddr, ivk) && m_wallet->HaveSaplingFullViewingKey(ivk); } - bool PaymentAddressBelongsToWallet::operator()(const libzcash::UnifiedAddress &uaddr) const { // TODO return false; } -/// +// GetSourceForPaymentAddress +PaymentAddressSource GetSourceForPaymentAddress::operator()(const CKeyID &zaddr) const +{ + // TODO + return AddressNotFound; +} +PaymentAddressSource GetSourceForPaymentAddress::operator()(const CScriptID &zaddr) const +{ + // TODO + return AddressNotFound; +} PaymentAddressSource GetSourceForPaymentAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const { return Random; } - PaymentAddressSource GetSourceForPaymentAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) const { libzcash::SaplingIncomingViewingKey ivk; @@ -5240,15 +5260,24 @@ PaymentAddressSource GetSourceForPaymentAddress::operator()(const libzcash::Sapl return AddressNotFound; } } - PaymentAddressSource GetSourceForPaymentAddress::operator()(const libzcash::UnifiedAddress &uaddr) const { // TODO return AddressNotFound; } -/// +// GetViewingKeyForPaymentAddress +std::optional GetViewingKeyForPaymentAddress::operator()( + const CKeyID &zaddr) const +{ + return std::nullopt; +} +std::optional GetViewingKeyForPaymentAddress::operator()( + const CScriptID &zaddr) const +{ + return std::nullopt; +} std::optional GetViewingKeyForPaymentAddress::operator()( const libzcash::SproutPaymentAddress &zaddr) const { @@ -5262,7 +5291,6 @@ std::optional GetViewingKeyForPaymentAddress::operator()( } return libzcash::ViewingKey(vk); } - std::optional GetViewingKeyForPaymentAddress::operator()( const libzcash::SaplingPaymentAddress &zaddr) const { @@ -5277,19 +5305,27 @@ std::optional GetViewingKeyForPaymentAddress::operator()( return std::nullopt; } } - std::optional GetViewingKeyForPaymentAddress::operator()( const libzcash::UnifiedAddress &uaddr) const { // TODO - return libzcash::ViewingKey(); + return std::nullopt; } +// HaveSpendingKeyForPaymentAddress + +bool HaveSpendingKeyForPaymentAddress::operator()(const CKeyID &addr) const +{ + return m_wallet->HaveKey(addr); +} +bool HaveSpendingKeyForPaymentAddress::operator()(const CScriptID &addr) const +{ + return m_wallet->HaveCScript(addr); +} bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SproutPaymentAddress &zaddr) const { return m_wallet->HaveSproutSpendingKey(zaddr); } - bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SaplingPaymentAddress &zaddr) const { libzcash::SaplingIncomingViewingKey ivk; @@ -5299,13 +5335,24 @@ bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::SaplingPayment m_wallet->GetSaplingFullViewingKey(ivk, extfvk) && m_wallet->HaveSaplingSpendingKey(extfvk); } - bool HaveSpendingKeyForPaymentAddress::operator()(const libzcash::UnifiedAddress &uaddr) const { // TODO return false; } +// GetSpendingKeyForPaymentAddress + +std::optional GetSpendingKeyForPaymentAddress::operator()( + const CKeyID &zaddr) const +{ + return std::nullopt; +} +std::optional GetSpendingKeyForPaymentAddress::operator()( + const CScriptID &zaddr) const +{ + return std::nullopt; +} std::optional GetSpendingKeyForPaymentAddress::operator()( const libzcash::SproutPaymentAddress &zaddr) const { @@ -5316,7 +5363,6 @@ std::optional GetSpendingKeyForPaymentAddress::operator() return std::nullopt; } } - std::optional GetSpendingKeyForPaymentAddress::operator()( const libzcash::SaplingPaymentAddress &zaddr) const { @@ -5327,7 +5373,6 @@ std::optional GetSpendingKeyForPaymentAddress::operator() return std::nullopt; } } - std::optional GetSpendingKeyForPaymentAddress::operator()( const libzcash::UnifiedAddress &uaddr) const { @@ -5335,6 +5380,8 @@ std::optional GetSpendingKeyForPaymentAddress::operator() return libzcash::SpendingKey(); } +// AddViewingKeyToWallet + KeyAddResult AddViewingKeyToWallet::operator()(const libzcash::SproutViewingKey &vkey) const { auto addr = vkey.address(); @@ -5348,7 +5395,6 @@ KeyAddResult AddViewingKeyToWallet::operator()(const libzcash::SproutViewingKey return KeyNotAdded; } } - KeyAddResult AddViewingKeyToWallet::operator()(const libzcash::SaplingExtendedFullViewingKey &extfvk) const { if (m_wallet->HaveSaplingSpendingKey(extfvk)) { return SpendingKeyExists; @@ -5361,6 +5407,8 @@ KeyAddResult AddViewingKeyToWallet::operator()(const libzcash::SaplingExtendedFu } } +// AddSpendingKeyToWallet + KeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKey &sk) const { auto addr = sk.address(); KeyIO keyIO(Params()); @@ -5376,7 +5424,6 @@ KeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SproutSpendingKe return KeyNotAdded; } } - KeyAddResult AddSpendingKeyToWallet::operator()(const libzcash::SaplingExtendedSpendingKey &sk) const { auto extfvk = sk.ToXFVK(); auto ivk = extfvk.fvk.in_viewing_key(); diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 57fda6366..e1790dad5 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -1369,6 +1369,8 @@ private: public: PaymentAddressBelongsToWallet(CWallet *wallet) : m_wallet(wallet) {} + bool operator()(const CKeyID &zaddr) const; + bool operator()(const CScriptID &zaddr) const; bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::UnifiedAddress &uaddr) const; @@ -1381,6 +1383,8 @@ private: public: GetViewingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} + std::optional operator()(const CKeyID &zaddr) const; + std::optional operator()(const CScriptID &zaddr) const; std::optional operator()(const libzcash::SproutPaymentAddress &zaddr) const; std::optional operator()(const libzcash::SaplingPaymentAddress &zaddr) const; std::optional operator()(const libzcash::UnifiedAddress &uaddr) const; @@ -1393,6 +1397,8 @@ private: public: HaveSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} + bool operator()(const CKeyID &addr) const; + bool operator()(const CScriptID &addr) const; bool operator()(const libzcash::SproutPaymentAddress &zaddr) const; bool operator()(const libzcash::SaplingPaymentAddress &zaddr) const; bool operator()(const libzcash::UnifiedAddress &uaddr) const; @@ -1405,8 +1411,11 @@ private: public: GetSpendingKeyForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} + std::optional operator()(const CKeyID &zaddr) const; + std::optional operator()(const CScriptID &zaddr) const; std::optional operator()(const libzcash::SproutPaymentAddress &zaddr) const; std::optional operator()(const libzcash::SaplingPaymentAddress &zaddr) const; + // FIXME: this doesn't make sense std::optional operator()(const libzcash::UnifiedAddress &uaddr) const; }; @@ -1426,6 +1435,8 @@ private: public: GetSourceForPaymentAddress(CWallet *wallet) : m_wallet(wallet) {} + PaymentAddressSource operator()(const CKeyID &zaddr) const; + PaymentAddressSource operator()(const CScriptID &zaddr) const; PaymentAddressSource operator()(const libzcash::SproutPaymentAddress &zaddr) const; PaymentAddressSource operator()(const libzcash::SaplingPaymentAddress &zaddr) const; PaymentAddressSource operator()(const libzcash::UnifiedAddress &uaddr) const; diff --git a/src/zcash/Address.cpp b/src/zcash/Address.cpp index fe048c1a9..121f90611 100644 --- a/src/zcash/Address.cpp +++ b/src/zcash/Address.cpp @@ -56,61 +56,67 @@ uint32_t TypecodeForReceiver::operator()( { return ZCASH_UA_TYPECODE_SAPLING; } - uint32_t TypecodeForReceiver::operator()( const CScriptID &p2sh) const { return ZCASH_UA_TYPECODE_P2SH; } - uint32_t TypecodeForReceiver::operator()( const CKeyID &p2sh) const { return ZCASH_UA_TYPECODE_P2PKH; } - uint32_t TypecodeForReceiver::operator()( const libzcash::UnknownReceiver &unknown) const { return unknown.typecode; } -std::optional ReceiverToRawAddress::operator()( - const libzcash::SaplingPaymentAddress &zaddr) const -{ - return zaddr; -} - -std::optional ReceiverToRawAddress::operator()( - const CScriptID &p2sh) const -{ - return std::nullopt; -} +// ReceiverToRawAddress std::optional ReceiverToRawAddress::operator()( const CKeyID &p2sh) const { return std::nullopt; } - +std::optional ReceiverToRawAddress::operator()( + const CScriptID &p2sh) const +{ + return std::nullopt; +} +std::optional ReceiverToRawAddress::operator()( + const libzcash::SaplingPaymentAddress &zaddr) const +{ + return zaddr; +} std::optional ReceiverToRawAddress::operator()( const libzcash::UnknownReceiver &p2sh) const { return std::nullopt; } +// RecipientForPaymentAddress + +std::optional RecipientForPaymentAddress::operator()( + const CKeyID &p2sh) const +{ + return std::nullopt; +} +std::optional RecipientForPaymentAddress::operator()( + const CScriptID &p2sh) const +{ + return std::nullopt; +} std::optional RecipientForPaymentAddress::operator()( const libzcash::SproutPaymentAddress &zaddr) const { return zaddr; } - std::optional RecipientForPaymentAddress::operator()( const libzcash::SaplingPaymentAddress &zaddr) const { return zaddr; } - std::optional RecipientForPaymentAddress::operator()( const libzcash::UnifiedAddress &uaddr) const { @@ -122,19 +128,29 @@ std::optional RecipientForPaymentAddress::operator()( return std::nullopt; } -std::set GetRawAddresses::operator()( +// GetRawShieldedAddresses + +std::set GetRawShieldedAddresses::operator()( + const CKeyID &addr) const +{ + return {}; +} +std::set GetRawShieldedAddresses::operator()( + const CScriptID &addr) const +{ + return {}; +} +std::set GetRawShieldedAddresses::operator()( const libzcash::SproutPaymentAddress &zaddr) const { return {zaddr}; } - -std::set GetRawAddresses::operator()( +std::set GetRawShieldedAddresses::operator()( const libzcash::SaplingPaymentAddress &zaddr) const { return {zaddr}; } - -std::set GetRawAddresses::operator()( +std::set GetRawShieldedAddresses::operator()( const libzcash::UnifiedAddress &uaddr) const { std::set ret; diff --git a/src/zcash/Address.hpp b/src/zcash/Address.hpp index 83792eddf..5cd709c6c 100644 --- a/src/zcash/Address.hpp +++ b/src/zcash/Address.hpp @@ -122,6 +122,8 @@ public: /** Addresses that can appear in a string encoding. */ typedef std::variant< + CKeyID, + CScriptID, SproutPaymentAddress, SaplingPaymentAddress, UnifiedAddress> PaymentAddress; @@ -181,6 +183,8 @@ class RecipientForPaymentAddress { public: RecipientForPaymentAddress() {} + std::optional operator()(const CKeyID &addr) const; + std::optional operator()(const CScriptID &addr) const; std::optional operator()(const libzcash::SproutPaymentAddress &zaddr) const; std::optional operator()(const libzcash::SaplingPaymentAddress &zaddr) const; std::optional operator()(const libzcash::UnifiedAddress &uaddr) const; @@ -189,10 +193,12 @@ public: /** * Returns all protocol addresses contained within the given payment address. */ -class GetRawAddresses { +class GetRawShieldedAddresses { public: - GetRawAddresses() {} + GetRawShieldedAddresses() {} + std::set operator()(const CKeyID &addr) const; + std::set operator()(const CScriptID &addr) const; std::set operator()(const libzcash::SproutPaymentAddress &zaddr) const; std::set operator()(const libzcash::SaplingPaymentAddress &zaddr) const; std::set operator()(const libzcash::UnifiedAddress &uaddr) const;