desprout
This commit is contained in:
@@ -74,19 +74,17 @@ AsyncRPCOperation_mergetoaddress::AsyncRPCOperation_mergetoaddress(
|
||||
boost::optional<TransactionBuilder> builder,
|
||||
CMutableTransaction contextualTx,
|
||||
std::vector<MergeToAddressInputUTXO> utxoInputs,
|
||||
std::vector<MergeToAddressInputSproutNote> sproutNoteInputs,
|
||||
std::vector<MergeToAddressInputSaplingNote> saplingNoteInputs,
|
||||
MergeToAddressRecipient recipient,
|
||||
CAmount fee,
|
||||
UniValue contextInfo) :
|
||||
tx_(contextualTx), utxoInputs_(utxoInputs), sproutNoteInputs_(sproutNoteInputs),
|
||||
saplingNoteInputs_(saplingNoteInputs), recipient_(recipient), fee_(fee), contextinfo_(contextInfo)
|
||||
tx_(contextualTx), utxoInputs_(utxoInputs), saplingNoteInputs_(saplingNoteInputs), recipient_(recipient), fee_(fee), contextinfo_(contextInfo)
|
||||
{
|
||||
if (fee < 0 || fee > MAX_MONEY) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Fee is out of range");
|
||||
}
|
||||
|
||||
if (utxoInputs.empty() && sproutNoteInputs.empty() && saplingNoteInputs.empty()) {
|
||||
if (utxoInputs.empty() && saplingNoteInputs.empty()) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "No inputs");
|
||||
}
|
||||
|
||||
@@ -94,14 +92,6 @@ saplingNoteInputs_(saplingNoteInputs), recipient_(recipient), fee_(fee), context
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Recipient parameter missing");
|
||||
}
|
||||
|
||||
if (sproutNoteInputs.size() > 0 && saplingNoteInputs.size() > 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot send from both Sprout and Sapling addresses using z_mergetoaddress");
|
||||
}
|
||||
|
||||
if (sproutNoteInputs.size() > 0 && builder) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Sprout notes are not supported by the TransactionBuilder");
|
||||
}
|
||||
|
||||
isUsingBuilder_ = false;
|
||||
if (builder) {
|
||||
isUsingBuilder_ = true;
|
||||
@@ -215,7 +205,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||
{
|
||||
assert(isToTaddr_ != isToZaddr_);
|
||||
|
||||
bool isPureTaddrOnlyTx = (sproutNoteInputs_.empty() && saplingNoteInputs_.empty() && isToTaddr_);
|
||||
bool isPureTaddrOnlyTx = (saplingNoteInputs_.empty() && isToTaddr_);
|
||||
CAmount minersFee = fee_;
|
||||
|
||||
size_t numInputs = utxoInputs_.size();
|
||||
@@ -240,9 +230,6 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||
}
|
||||
|
||||
CAmount z_inputs_total = 0;
|
||||
for (const MergeToAddressInputSproutNote& t : sproutNoteInputs_) {
|
||||
z_inputs_total += std::get<2>(t);
|
||||
}
|
||||
|
||||
for (const MergeToAddressInputSaplingNote& t : saplingNoteInputs_) {
|
||||
z_inputs_total += std::get<2>(t);
|
||||
@@ -293,7 +280,7 @@ bool AsyncRPCOperation_mergetoaddress::main_impl()
|
||||
/**
|
||||
* SCENARIO #0
|
||||
*
|
||||
* Sprout not involved, so we just use the TransactionBuilder and we're done.
|
||||
* Only sapling involved, so we just use the TransactionBuilder and we're done.
|
||||
*
|
||||
* This is based on code from AsyncRPCOperation_sendmany::main_impl() and should be refactored.
|
||||
*/
|
||||
|
||||
@@ -57,7 +57,6 @@ public:
|
||||
boost::optional<TransactionBuilder> builder,
|
||||
CMutableTransaction contextualTx,
|
||||
std::vector<MergeToAddressInputUTXO> utxoInputs,
|
||||
std::vector<MergeToAddressInputSproutNote> sproutNoteInputs,
|
||||
std::vector<MergeToAddressInputSaplingNote> saplingNoteInputs,
|
||||
MergeToAddressRecipient recipient,
|
||||
CAmount fee = MERGE_TO_ADDRESS_OPERATION_DEFAULT_MINERS_FEE,
|
||||
@@ -94,9 +93,6 @@ private:
|
||||
uint256 joinSplitPubKey_;
|
||||
unsigned char joinSplitPrivKey_[crypto_sign_SECRETKEYBYTES];
|
||||
|
||||
// The key is the result string from calling JSOutPoint::ToString()
|
||||
std::unordered_map<std::string, MergeToAddressWitnessAnchorData> jsopWitnessAnchorMap;
|
||||
|
||||
std::vector<MergeToAddressInputUTXO> utxoInputs_;
|
||||
std::vector<MergeToAddressInputSaplingNote> saplingNoteInputs_;
|
||||
|
||||
|
||||
@@ -87,7 +87,6 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() {
|
||||
return status;
|
||||
}
|
||||
|
||||
std::vector<CSproutNotePlaintextEntry> sproutEntries;
|
||||
std::vector<SaplingNoteEntry> saplingEntries;
|
||||
std::set<libzcash::SaplingPaymentAddress> addresses;
|
||||
{
|
||||
@@ -95,7 +94,7 @@ bool AsyncRPCOperation_saplingconsolidation::main_impl() {
|
||||
// We set minDepth to 11 to avoid unconfirmed notes and in anticipation of specifying
|
||||
// an anchor at height N-10 for each SpendDescription
|
||||
// Consider, should notes be sorted?
|
||||
pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, "", 11);
|
||||
pwalletMain->GetFilteredNotes(saplingEntries, "", 11);
|
||||
if (fConsolidationMapUsed) {
|
||||
const vector<string>& v = mapMultiArgs["-consolidatesaplingaddress"];
|
||||
for(int i = 0; i < v.size(); i++) {
|
||||
|
||||
@@ -248,18 +248,12 @@ bool AsyncRPCOperation_sendmany::main_impl() {
|
||||
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds, no unspent notes found for zaddr from address.");
|
||||
}
|
||||
|
||||
// At least one of z_sprout_inputs_ and z_sapling_inputs_ must be empty by design
|
||||
assert(z_sprout_inputs_.empty() || z_sapling_inputs_.empty());
|
||||
|
||||
CAmount t_inputs_total = 0;
|
||||
for (SendManyInputUTXO & t : t_inputs_) {
|
||||
t_inputs_total += std::get<2>(t);
|
||||
}
|
||||
|
||||
CAmount z_inputs_total = 0;
|
||||
for (SendManyInputJSOP & t : z_sprout_inputs_) {
|
||||
z_inputs_total += std::get<2>(t);
|
||||
}
|
||||
for (auto t : z_sapling_inputs_) {
|
||||
z_inputs_total += t.note.value();
|
||||
}
|
||||
@@ -687,20 +681,10 @@ bool AsyncRPCOperation_sendmany::find_utxos(bool fAcceptCoinbase=false) {
|
||||
|
||||
|
||||
bool AsyncRPCOperation_sendmany::find_unspent_notes() {
|
||||
std::vector<CSproutNotePlaintextEntry> sproutEntries;
|
||||
std::vector<SaplingNoteEntry> saplingEntries;
|
||||
{
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, fromaddress_, mindepth_);
|
||||
}
|
||||
|
||||
// If using the TransactionBuilder, we only want Sapling notes.
|
||||
// If not using it, we only want Sprout notes.
|
||||
// TODO: Refactor `GetFilteredNotes()` so we only fetch what we need.
|
||||
if (isUsingBuilder_) {
|
||||
sproutEntries.clear();
|
||||
} else {
|
||||
saplingEntries.clear();
|
||||
pwalletMain->GetFilteredNotes(saplingEntries, fromaddress_, mindepth_);
|
||||
}
|
||||
|
||||
for (auto entry : saplingEntries) {
|
||||
|
||||
@@ -70,7 +70,6 @@ using namespace libzcash;
|
||||
|
||||
extern char ASSETCHAINS_SYMBOL[KOMODO_ASSETCHAIN_MAXLEN];
|
||||
extern std::string ASSETCHAINS_OVERRIDE_PUBKEY;
|
||||
const std::string ADDR_TYPE_SPROUT = "sprout";
|
||||
const std::string ADDR_TYPE_SAPLING = "sapling";
|
||||
extern UniValue TxJoinSplitToJSON(const CTransaction& tx);
|
||||
extern int32_t KOMODO_INSYNC;
|
||||
@@ -3787,9 +3786,8 @@ UniValue z_listunspent(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
UniValue results(UniValue::VARR);
|
||||
|
||||
if (zaddrs.size() > 0) {
|
||||
std::vector<CSproutNotePlaintextEntry> sproutEntries;
|
||||
std::vector<SaplingNoteEntry> saplingEntries;
|
||||
pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, zaddrs, nMinDepth, nMaxDepth, true, !fIncludeWatchonly, false);
|
||||
pwalletMain->GetFilteredNotes(saplingEntries, zaddrs, nMinDepth, nMaxDepth, true, !fIncludeWatchonly, false);
|
||||
std::set<std::pair<PaymentAddress, uint256>> nullifierSet = pwalletMain->GetNullifiersForAddresses(zaddrs);
|
||||
|
||||
for (auto & entry : saplingEntries) {
|
||||
@@ -4047,10 +4045,9 @@ CAmount getBalanceTaddr(std::string transparentAddress, int minDepth=1, bool ign
|
||||
|
||||
CAmount getBalanceZaddr(std::string address, int minDepth = 1, bool ignoreUnspendable=true) {
|
||||
CAmount balance = 0;
|
||||
std::vector<CSproutNotePlaintextEntry> sproutEntries;
|
||||
std::vector<SaplingNoteEntry> saplingEntries;
|
||||
LOCK2(cs_main, pwalletMain->cs_wallet);
|
||||
pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, address, minDepth, true, ignoreUnspendable);
|
||||
pwalletMain->GetFilteredNotes(saplingEntries, address, minDepth, true, ignoreUnspendable);
|
||||
for (auto & entry : saplingEntries) {
|
||||
balance += CAmount(entry.note.value());
|
||||
}
|
||||
@@ -4102,16 +4099,14 @@ UniValue z_listreceivedbyaddress(const UniValue& params, bool fHelp, const CPubK
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid zaddr.");
|
||||
}
|
||||
|
||||
// Visitor to support Sprout and Sapling addrs
|
||||
if (!boost::apply_visitor(PaymentAddressBelongsToWallet(pwalletMain), zaddr) &&
|
||||
!boost::apply_visitor(IncomingViewingKeyBelongsToWallet(pwalletMain), zaddr)) {
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key or viewing key not found.");
|
||||
}
|
||||
|
||||
UniValue result(UniValue::VARR);
|
||||
std::vector<CSproutNotePlaintextEntry> sproutEntries;
|
||||
std::vector<SaplingNoteEntry> saplingEntries;
|
||||
pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, fromaddress, nMinDepth, false, false);
|
||||
pwalletMain->GetFilteredNotes(saplingEntries, fromaddress, nMinDepth, false, false);
|
||||
|
||||
std::set<std::pair<PaymentAddress, uint256>> nullifierSet;
|
||||
auto hasSpendingKey = boost::apply_visitor(HaveSpendingKeyForPaymentAddress(pwalletMain), zaddr);
|
||||
@@ -4223,7 +4218,7 @@ UniValue z_getnotescount(const UniValue& params, bool fHelp,const CPubKey& mypk)
|
||||
"z_getnotescount\n"
|
||||
"\nArguments:\n"
|
||||
"1. minconf (numeric, optional, default=1) Only include notes in transactions confirmed at least this many times.\n"
|
||||
"\nReturns the number of sprout and sapling notes available in the wallet.\n"
|
||||
"\nReturns the number of sapling notes available in the wallet.\n"
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"sapling\" (numeric) the number of sapling notes in the wallet\n"
|
||||
@@ -4268,7 +4263,7 @@ UniValue z_gettotalbalance(const UniValue& params, bool fHelp, const CPubKey& my
|
||||
"\nResult:\n"
|
||||
"{\n"
|
||||
" \"transparent\": xxxxx, (numeric) the total balance of transparent funds\n"
|
||||
" \"private\": xxxxx, (numeric) the total balance of private funds (in both Sprout and Sapling addresses)\n"
|
||||
" \"private\": xxxxx, (numeric) the total balance of private funds\n"
|
||||
" \"total\": xxxxx, (numeric) the total balance of both transparent and private funds\n"
|
||||
"}\n"
|
||||
"\nExamples:\n"
|
||||
@@ -4650,14 +4645,9 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "From address does not belong to this node, zaddr spending key not found.");
|
||||
}
|
||||
|
||||
// Remember whether this is a Sprout or Sapling address
|
||||
// Remember whether this is a Sapling address
|
||||
fromSapling = boost::get<libzcash::SaplingPaymentAddress>(&res) != nullptr;
|
||||
}
|
||||
// This logic will need to be updated if we add a new shielded pool
|
||||
bool fromSprout = !(fromTaddr || fromSapling);
|
||||
|
||||
if (fromSprout)
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot send from a Sprout zaddr, only Sapling zaddrs supported.");
|
||||
|
||||
UniValue outputs = params[1].get_array();
|
||||
|
||||
@@ -4667,15 +4657,11 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
// Keep track of addresses to spot duplicates
|
||||
set<std::string> setAddress;
|
||||
|
||||
// Track whether we see any Sprout addresses
|
||||
bool noSproutAddrs = !fromSprout;
|
||||
|
||||
// Recipients
|
||||
std::vector<SendManyRecipient> taddrRecipients;
|
||||
std::vector<SendManyRecipient> zaddrRecipients;
|
||||
CAmount nTotalOut = 0;
|
||||
|
||||
bool containsSproutOutput = false;
|
||||
bool containsSaplingOutput = false;
|
||||
|
||||
for (const UniValue& o : outputs.getValues()) {
|
||||
@@ -4696,35 +4682,6 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
auto res = DecodePaymentAddress(address);
|
||||
if (IsValidPaymentAddress(res, branchId)) {
|
||||
isZaddr = true;
|
||||
|
||||
bool toSapling = boost::get<libzcash::SaplingPaymentAddress>(&res) != nullptr;
|
||||
bool toSprout = !toSapling;
|
||||
noSproutAddrs = noSproutAddrs && toSapling;
|
||||
|
||||
containsSproutOutput |= toSprout;
|
||||
containsSaplingOutput |= toSapling;
|
||||
|
||||
// Sending to both Sprout and Sapling is currently unsupported using z_sendmany
|
||||
if (containsSproutOutput && containsSaplingOutput) {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
"Cannot send to both Sprout and Sapling addresses using z_sendmany");
|
||||
}
|
||||
if ( GetTime() > KOMODO_SAPLING_DEADLINE )
|
||||
{
|
||||
if ( fromSprout || toSprout )
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER,"Sprout usage has expired");
|
||||
}
|
||||
if ( toSapling && ASSETCHAINS_SYMBOL[0] == 0 )
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER,"Sprout usage will expire soon");
|
||||
|
||||
// If we are sending from a shielded address, all recipient
|
||||
// shielded addresses must be of the same type.
|
||||
if ((fromSprout && toSapling) || (fromSapling && toSprout)) {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
"Cannot send between Sprout and Sapling addresses using z_sendmany");
|
||||
}
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ")+address );
|
||||
}
|
||||
@@ -4915,9 +4872,7 @@ UniValue z_sendmany(const UniValue& params, bool fHelp, const CPubKey& mypk)
|
||||
|
||||
// Builder (used if Sapling addresses are involved)
|
||||
boost::optional<TransactionBuilder> builder;
|
||||
if (noSproutAddrs) {
|
||||
builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain);
|
||||
}
|
||||
builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain);
|
||||
|
||||
// Contextual transaction we will build on
|
||||
// (used if no Sapling addresses are involved)
|
||||
@@ -5190,11 +5145,11 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
return NullUniValue;
|
||||
|
||||
string enableArg = "zmergetoaddress";
|
||||
auto fEnableMergeToAddress = fExperimentalMode && GetBoolArg("-" + enableArg, true);
|
||||
std::string strDisabledMsg = "";
|
||||
if (!fEnableMergeToAddress) {
|
||||
strDisabledMsg = experimentalDisabledHelpMsg("z_mergetoaddress", enableArg);
|
||||
}
|
||||
//auto fEnableMergeToAddress = fExperimentalMode && GetBoolArg("-" + enableArg, true);
|
||||
//std::string strDisabledMsg = "";
|
||||
//if (!fEnableMergeToAddress) {
|
||||
// strDisabledMsg = experimentalDisabledHelpMsg("z_mergetoaddress", enableArg);
|
||||
//}
|
||||
|
||||
if (fHelp || params.size() < 2 || params.size() > 7)
|
||||
throw runtime_error(
|
||||
@@ -5256,7 +5211,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
THROW_IF_SYNCING(KOMODO_INSYNC);
|
||||
|
||||
bool useAnyUTXO = false;
|
||||
bool useAnySprout = false;
|
||||
bool useAnySapling = false;
|
||||
std::set<CTxDestination> taddrs = {};
|
||||
std::set<libzcash::PaymentAddress> zaddrs = {};
|
||||
@@ -5277,8 +5231,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
|
||||
if (address == "ANY_TADDR") {
|
||||
useAnyUTXO = true;
|
||||
} else if (address == "ANY_SPROUT") {
|
||||
useAnySprout = true;
|
||||
} else if (address == "ANY_SAPLING") {
|
||||
useAnySapling = true;
|
||||
} else {
|
||||
@@ -5303,8 +5255,8 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
if (useAnyUTXO && taddrs.size() > 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific t-addrs when using \"ANY_TADDR\"");
|
||||
}
|
||||
if ((useAnySprout || useAnySapling) && zaddrs.size() > 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific z-addrs when using \"ANY_SPROUT\" or \"ANY_SAPLING\"");
|
||||
if ((useAnySapling) && zaddrs.size() > 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot specify specific z-addrs when using \"ANY_SAPLING\"");
|
||||
}
|
||||
|
||||
const int nextBlockHeight = chainActive.Height() + 1;
|
||||
@@ -5313,7 +5265,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
|
||||
// Validate the destination address
|
||||
auto destaddress = params[1].get_str();
|
||||
bool isToSproutZaddr = false;
|
||||
bool isToSaplingZaddr = false;
|
||||
CTxDestination taddr = DecodeDestination(destaddress);
|
||||
if (!IsValidDestination(taddr)) {
|
||||
@@ -5326,7 +5277,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated");
|
||||
}
|
||||
} else {
|
||||
isToSproutZaddr = true;
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Only Sapling zaddrs allowed!");
|
||||
}
|
||||
} else {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, string("Invalid parameter, unknown address format: ") + destaddress );
|
||||
@@ -5351,14 +5302,12 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
}
|
||||
}
|
||||
|
||||
int sproutNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SPROUT_LIMIT;
|
||||
int saplingNoteLimit = MERGE_TO_ADDRESS_DEFAULT_SAPLING_LIMIT;
|
||||
if (params.size() > 4) {
|
||||
int nNoteLimit = params[4].get_int();
|
||||
if (nNoteLimit < 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of notes cannot be negative");
|
||||
}
|
||||
sproutNoteLimit = nNoteLimit;
|
||||
saplingNoteLimit = nNoteLimit;
|
||||
}
|
||||
|
||||
@@ -5375,7 +5324,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
std::string memo;
|
||||
if (params.size() > 6) {
|
||||
memo = params[6].get_str();
|
||||
if (!(isToSproutZaddr || isToSaplingZaddr)) {
|
||||
if (!isToSaplingZaddr) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Memo can not be used with a taddr. It can only be used with a zaddr.");
|
||||
} else if (!IsHex(memo)) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, expected memo data in hexadecimal format.");
|
||||
@@ -5389,7 +5338,6 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
|
||||
// Prepare to get UTXOs and notes
|
||||
std::vector<MergeToAddressInputUTXO> utxoInputs;
|
||||
std::vector<MergeToAddressInputSproutNote> sproutNoteInputs;
|
||||
std::vector<MergeToAddressInputSaplingNote> saplingNoteInputs;
|
||||
CAmount mergedUTXOValue = 0;
|
||||
CAmount mergedNoteValue = 0;
|
||||
@@ -5403,9 +5351,8 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
|
||||
unsigned int max_tx_size = saplingActive ? MAX_TX_SIZE_AFTER_SAPLING : MAX_TX_SIZE_BEFORE_SAPLING;
|
||||
size_t estimatedTxSize = 200; // tx overhead + wiggle room
|
||||
if (isToSproutZaddr) {
|
||||
estimatedTxSize += JOINSPLIT_SIZE;
|
||||
} else if (isToSaplingZaddr) {
|
||||
|
||||
if (isToSaplingZaddr) {
|
||||
estimatedTxSize += OUTPUTDESCRIPTION_SIZE;
|
||||
}
|
||||
|
||||
@@ -5463,29 +5410,10 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
}
|
||||
}
|
||||
|
||||
if (useAnySprout || useAnySapling || zaddrs.size() > 0) {
|
||||
if (useAnySapling || zaddrs.size() > 0) {
|
||||
// Get available notes
|
||||
std::vector<CSproutNotePlaintextEntry> sproutEntries;
|
||||
//std::vector<SaplingNoteEntry> saplingEntries;
|
||||
//pwalletMain->GetFilteredNotes(sproutEntries, saplingEntries, zaddrs);
|
||||
std::vector<SaplingNoteEntry> saplingEntries,skipsapling;
|
||||
pwalletMain->GetFilteredNotes(sproutEntries, useAnySprout == 0 ? saplingEntries : skipsapling, zaddrs);
|
||||
// If Sapling is not active, do not allow sending from a sapling addresses.
|
||||
if (!saplingActive && saplingEntries.size() > 0) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, Sapling has not activated");
|
||||
}
|
||||
// Sending from both Sprout and Sapling is currently unsupported using z_mergetoaddress
|
||||
if (sproutEntries.size() > 0 && saplingEntries.size() > 0) {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
"Cannot send from both Sprout and Sapling addresses using z_mergetoaddress");
|
||||
}
|
||||
// If sending between shielded addresses, they must be the same type
|
||||
if ((saplingEntries.size() > 0 && isToSproutZaddr) || (sproutEntries.size() > 0 && isToSaplingZaddr)) {
|
||||
throw JSONRPCError(
|
||||
RPC_INVALID_PARAMETER,
|
||||
"Cannot send between Sprout and Sapling addresses using z_mergetoaddress");
|
||||
}
|
||||
std::vector<SaplingNoteEntry> saplingEntries;
|
||||
pwalletMain->GetFilteredNotes(saplingEntries, zaddrs);
|
||||
|
||||
for (const SaplingNoteEntry& entry : saplingEntries) {
|
||||
noteCounter++;
|
||||
@@ -5514,7 +5442,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
}
|
||||
|
||||
size_t numUtxos = utxoInputs.size();
|
||||
size_t numNotes = sproutNoteInputs.size() + saplingNoteInputs.size();
|
||||
size_t numNotes = saplingNoteInputs.size();
|
||||
|
||||
//fprintf(stderr, "num utxos.%li\n", numUtxos);
|
||||
if (numUtxos < 2 && numNotes == 0) {
|
||||
@@ -5552,22 +5480,19 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp, const CPubKey& myp
|
||||
CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(
|
||||
Params().GetConsensus(),
|
||||
nextBlockHeight);
|
||||
bool isSproutShielded = sproutNoteInputs.size() > 0 || isToSproutZaddr;
|
||||
if (contextualTx.nVersion == 1 && isSproutShielded) {
|
||||
contextualTx.nVersion = 2; // Tx format should support vjoinsplit
|
||||
}
|
||||
|
||||
// Builder (used if Sapling addresses are involved)
|
||||
boost::optional<TransactionBuilder> builder;
|
||||
if (isToSaplingZaddr || saplingNoteInputs.size() > 0) {
|
||||
builder = TransactionBuilder(Params().GetConsensus(), nextBlockHeight, pwalletMain);
|
||||
} else
|
||||
} else {
|
||||
contextualTx.nExpiryHeight = 0; // set non z-tx to have no expiry height.
|
||||
}
|
||||
|
||||
// Create operation and add to global queue
|
||||
std::shared_ptr<AsyncRPCQueue> q = getAsyncRPCQueue();
|
||||
std::shared_ptr<AsyncRPCOperation> operation(
|
||||
new AsyncRPCOperation_mergetoaddress(builder, contextualTx, utxoInputs, sproutNoteInputs, saplingNoteInputs, recipient, nFee, contextInfo) );
|
||||
new AsyncRPCOperation_mergetoaddress(builder, contextualTx, utxoInputs, saplingNoteInputs, recipient, nFee, contextInfo) );
|
||||
q->addOperation(operation);
|
||||
AsyncRPCOperationId operationId = operation->getId();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user