Use libzcash::RecipientAddress for z_sendmany recipients.

This commit is contained in:
Kris Nuttycombe 2022-01-13 15:12:02 -07:00
parent 0abe07c73b
commit babc11eb52
4 changed files with 27 additions and 32 deletions

View File

@ -96,10 +96,6 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
transparentRecipients_ += 1;
txOutputAmounts_.t_outputs_total += recipient.amount;
},
[&](const libzcash::SproutPaymentAddress& addr) {
// unreachable; currently disallowed by checks at construction
throw JSONRPCError(RPC_INVALID_PARAMETER, "Sending to Sprout is disabled.");
},
[&](const libzcash::SaplingPaymentAddress& addr) {
txOutputAmounts_.z_outputs_total += recipient.amount;
if (isfromsprout_ && !allowRevealedAmounts_) {
@ -110,10 +106,6 @@ AsyncRPCOperation_sendmany::AsyncRPCOperation_sendmany(
"Resubmit with the `allowRevealedAmounts` parameter set to `true` if "
"you wish to allow this transaction to proceed anyway.");
}
},
[&](const libzcash::UnifiedAddress& ua) {
// unreachable; currently disallowed by checks at construction
throw JSONRPCError(RPC_INVALID_PARAMETER, "Sending to unified addresses is disabled.");
}
}, recipient.address);
}
@ -414,23 +406,11 @@ uint256 AsyncRPCOperation_sendmany::main_impl() {
[&](const CScriptID& scriptId) {
builder_.AddTransparentOutput(scriptId, r.amount);
},
[&](const libzcash::SproutPaymentAddress& addr) {
//unreachable
throw JSONRPCError(
RPC_INVALID_ADDRESS_OR_KEY,
"Sending funds to Sprout is disabled.");
},
[&](const libzcash::SaplingPaymentAddress& addr) {
auto value = r.amount;
auto memo = get_memo_from_hex_string(r.memo.has_value() ? r.memo.value() : "");
builder_.AddSaplingOutput(ovk, addr, value, memo);
},
[&](const libzcash::UnifiedAddress& addr) {
//unreachable
throw JSONRPCError(
RPC_INVALID_ADDRESS_OR_KEY,
"Unified addresses are not yet supported by z_sendmany");
}
}, r.address);
}

View File

@ -27,11 +27,11 @@ using namespace libzcash;
class SendManyRecipient {
public:
PaymentAddress address;
RecipientAddress address;
CAmount amount;
std::optional<std::string> memo;
SendManyRecipient(PaymentAddress address_, CAmount amount_, std::optional<std::string> memo_) :
SendManyRecipient(RecipientAddress address_, CAmount amount_, std::optional<std::string> memo_) :
address(address_), amount(amount_), memo(memo_) {}
};

View File

@ -4318,21 +4318,25 @@ UniValue z_sendmany(const UniValue& params, bool fHelp)
}
std::string addrStr = find_value(o, "address").get_str();
auto addr = keyIO.DecodePaymentAddress(addrStr);
if (addr.has_value()) {
// TODO: If we want to continue to support sending to Sprout, we'll simply relax the
// restriction here to allow sprout->sprout; these transfers will not be forbidden
// by later code.
bool toSprout = std::holds_alternative<libzcash::SproutPaymentAddress>(addr.value());
auto decoded = keyIO.DecodePaymentAddress(addrStr);
if (!decoded.has_value()) {
throw JSONRPCError(
RPC_INVALID_PARAMETER,
std::string("Invalid parameter, unknown address format: ") + addrStr);
}
std::optional<RecipientAddress> addr = std::visit(SelectRecipientAddress(), decoded.value());
if (!addr.has_value()) {
bool toSprout = std::holds_alternative<libzcash::SproutPaymentAddress>(decoded.value());
if (toSprout) {
throw JSONRPCError(
RPC_INVALID_PARAMETER,
"Sending funds into the Sprout pool is not supported by z_sendmany");
}
} else {
throw JSONRPCError(
} else {
throw JSONRPCError(
RPC_INVALID_PARAMETER,
std::string("Invalid parameter, unknown address format: ") + addrStr);
"Unified address contained no recognized receiver types.");
}
}
if (!addrStrings.insert(addrStr).second) {

View File

@ -269,6 +269,17 @@ public:
bool operator()(const UnifiedAddress& addr) { return true; }
};
class SelectRecipientAddress {
public:
std::optional<RecipientAddress> operator()(const CKeyID& p2pkh) { return p2pkh; }
std::optional<RecipientAddress> operator()(const CScriptID& p2sh) { return p2sh; }
std::optional<RecipientAddress> operator()(const SproutPaymentAddress& addr) { return std::nullopt; }
std::optional<RecipientAddress> operator()(const SaplingPaymentAddress& addr) { return addr; }
std::optional<RecipientAddress> operator()(const UnifiedAddress& addr) {
return addr.GetPreferredRecipientAddress();
}
};
class AddressInfoFromSpendingKey {
public:
std::pair<std::string, PaymentAddress> operator()(const SproutSpendingKey&) const;