diff --git a/qa/rpc-tests/wallet_listreceived.py b/qa/rpc-tests/wallet_listreceived.py index fd67ebb76..3dfd5ff55 100755 --- a/qa/rpc-tests/wallet_listreceived.py +++ b/qa/rpc-tests/wallet_listreceived.py @@ -384,6 +384,15 @@ class ListReceivedTest (BitcoinTestFramework): assert_equal(len(receivers), 2) assert 'transparent' in receivers assert 'sapling' in receivers + assert_raises_message( + JSONRPCException, + "The provided address is a bare receiver from a Unified Address in this wallet.", + node.z_listreceivedbyaddress, receivers['transparent'], 0) + assert_raises_message( + JSONRPCException, + "The provided address is a bare receiver from a Unified Address in this wallet.", + node.z_listreceivedbyaddress, receivers['sapling'], 0) + # Wallet contains no notes r = node.z_listreceivedbyaddress(unified_addr, 0) assert_equal(len(r), 0, "unified_addr should have received zero notes") diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index da4553e9e..502ff71eb 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3470,6 +3470,30 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr."); } + // A non-unified address argument that is a receiver within a + // unified address known to this wallet is not allowed. + if (std::visit(match { + [&](const CKeyID& addr) { + return pwalletMain->FindUnifiedAddressByReceiver(addr).has_value(); + }, + [&](const CScriptID& addr) { + return pwalletMain->FindUnifiedAddressByReceiver(addr).has_value(); + }, + [&](const libzcash::SaplingPaymentAddress& addr) { + return pwalletMain->FindUnifiedAddressByReceiver(addr).has_value(); + }, + [&](const libzcash::SproutPaymentAddress& addr) { + // A unified address can't contain a Sprout receiver. + return false; + }, + [&](const libzcash::UnifiedAddress& addr) { + // 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."); + } + // Visitor to support Sprout and Sapling addrs if (!std::visit(PaymentAddressBelongsToWallet(pwalletMain), decoded.value())) { throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");