|
|
@ -3489,6 +3489,7 @@ UniValue z_getoperationstatus_IMPL(const UniValue& params, bool fRemoveFinishedO |
|
|
|
// If input notes are small, we might actually require more than one joinsplit per zaddr output.
|
|
|
|
// For now though, we assume we use one joinsplit per zaddr output (and the second output note is change).
|
|
|
|
// We reduce the result by 1 to ensure there is room for non-joinsplit CTransaction data.
|
|
|
|
#define Z_SENDMANY_MAX_ZADDR_OUTPUTS_BEFORE_SAPLING ((MAX_TX_SIZE_BEFORE_SAPLING / GetSerializeSize(JSDescription(), SER_NETWORK, PROTOCOL_VERSION)) - 1) |
|
|
|
#define Z_SENDMANY_MAX_ZADDR_OUTPUTS ((MAX_TX_SIZE / GetSerializeSize(JSDescription(), SER_NETWORK, PROTOCOL_VERSION)) - 1) |
|
|
|
|
|
|
|
// transaction.h comment: spending taddr output requires CTxIn >= 148 bytes and typical taddr txout is 34 bytes
|
|
|
@ -3620,8 +3621,16 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) |
|
|
|
nTotalOut += nAmount; |
|
|
|
} |
|
|
|
|
|
|
|
int nextBlockHeight = chainActive.Height() + 1; |
|
|
|
size_t max_zaddr_outputs = Z_SENDMANY_MAX_ZADDR_OUTPUTS; |
|
|
|
unsigned int max_tx_size = MAX_TX_SIZE; |
|
|
|
if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { |
|
|
|
max_zaddr_outputs = Z_SENDMANY_MAX_ZADDR_OUTPUTS_BEFORE_SAPLING; |
|
|
|
max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING; |
|
|
|
} |
|
|
|
|
|
|
|
// Check the number of zaddr outputs does not exceed the limit.
|
|
|
|
if (zaddrRecipients.size() > Z_SENDMANY_MAX_ZADDR_OUTPUTS) { |
|
|
|
if (zaddrRecipients.size() > max_zaddr_outputs) { |
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameter, too many zaddr outputs"); |
|
|
|
} |
|
|
|
|
|
|
@ -3640,8 +3649,8 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) |
|
|
|
txsize += CTXOUT_REGULAR_SIZE; // There will probably be taddr change
|
|
|
|
} |
|
|
|
txsize += CTXOUT_REGULAR_SIZE * taddrRecipients.size(); |
|
|
|
if (txsize > MAX_TX_SIZE) { |
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Too many outputs, size of raw transaction would be larger than limit of %d bytes", MAX_TX_SIZE )); |
|
|
|
if (txsize > max_tx_size) { |
|
|
|
throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Too many outputs, size of raw transaction would be larger than limit of %d bytes", max_tx_size )); |
|
|
|
} |
|
|
|
|
|
|
|
// Minimum confirmations
|
|
|
@ -3677,7 +3686,6 @@ UniValue z_sendmany(const UniValue& params, bool fHelp) |
|
|
|
UniValue contextInfo = o; |
|
|
|
|
|
|
|
// Contextual transaction we will build on
|
|
|
|
int nextBlockHeight = chainActive.Height() + 1; |
|
|
|
CMutableTransaction contextualTx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), nextBlockHeight); |
|
|
|
bool isShielded = !fromTaddr || zaddrRecipients.size() > 0; |
|
|
|
if (contextualTx.nVersion == 1 && isShielded) { |
|
|
@ -3725,7 +3733,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) |
|
|
|
"\nby the caller. If the limit parameter is set to zero, and Overwinter is not yet active, the -mempooltxinputlimit" |
|
|
|
"\noption will determine the number of uxtos. Any limit is constrained by the consensus rule defining a maximum" |
|
|
|
"\ntransaction size of " |
|
|
|
+ strprintf("%d bytes.", MAX_TX_SIZE) |
|
|
|
+ strprintf("%d bytes before Sapling, and %d bytes once Sapling activates.", MAX_TX_SIZE_BEFORE_SAPLING, MAX_TX_SIZE) |
|
|
|
+ HelpRequiringPassphrase() + "\n" |
|
|
|
"\nArguments:\n" |
|
|
|
"1. \"fromaddress\" (string, required) The address is a taddr or \"*\" for all taddrs belonging to the wallet.\n" |
|
|
@ -3789,6 +3797,10 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) |
|
|
|
|
|
|
|
int nextBlockHeight = chainActive.Height() + 1; |
|
|
|
bool overwinterActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER); |
|
|
|
unsigned int max_tx_size = MAX_TX_SIZE; |
|
|
|
if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { |
|
|
|
max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING; |
|
|
|
} |
|
|
|
|
|
|
|
// Prepare to get coinbase utxos
|
|
|
|
std::vector<ShieldCoinbaseUTXO> inputs; |
|
|
@ -3833,7 +3845,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp) |
|
|
|
|
|
|
|
if (!maxedOutFlag) { |
|
|
|
size_t increase = (boost::get<CScriptID>(&address) != nullptr) ? CTXIN_SPEND_P2SH_SIZE : CTXIN_SPEND_DUST_SIZE; |
|
|
|
if (estimatedTxSize + increase >= MAX_TX_SIZE || |
|
|
|
if (estimatedTxSize + increase >= max_tx_size || |
|
|
|
(mempoolLimit > 0 && utxoCounter > mempoolLimit)) |
|
|
|
{ |
|
|
|
maxedOutFlag = true; |
|
|
@ -3928,7 +3940,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) |
|
|
|
"\n\nThe number of UTXOs and notes selected for merging can be limited by the caller. If the transparent limit" |
|
|
|
"\nparameter is set to zero, and Overwinter is not yet active, the -mempooltxinputlimit option will determine the" |
|
|
|
"\nnumber of UTXOs. Any limit is constrained by the consensus rule defining a maximum transaction size of " |
|
|
|
+ strprintf("%d bytes.", MAX_TX_SIZE) |
|
|
|
+ strprintf("%d bytes before Sapling, and %d bytes once Sapling activates.", MAX_TX_SIZE_BEFORE_SAPLING, MAX_TX_SIZE) |
|
|
|
+ HelpRequiringPassphrase() + "\n" |
|
|
|
"\nArguments:\n" |
|
|
|
"1. fromaddresses (string, required) A JSON array with addresses.\n" |
|
|
@ -4081,6 +4093,10 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) |
|
|
|
|
|
|
|
int nextBlockHeight = chainActive.Height() + 1; |
|
|
|
bool overwinterActive = NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_OVERWINTER); |
|
|
|
unsigned int max_tx_size = MAX_TX_SIZE; |
|
|
|
if (!NetworkUpgradeActive(nextBlockHeight, Params().GetConsensus(), Consensus::UPGRADE_SAPLING)) { |
|
|
|
max_tx_size = MAX_TX_SIZE_BEFORE_SAPLING; |
|
|
|
} |
|
|
|
|
|
|
|
// Prepare to get UTXOs and notes
|
|
|
|
std::vector<MergeToAddressInputUTXO> utxoInputs; |
|
|
@ -4125,7 +4141,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) |
|
|
|
|
|
|
|
if (!maxedOutUTXOsFlag) { |
|
|
|
size_t increase = (boost::get<CScriptID>(&address) != nullptr) ? CTXIN_SPEND_P2SH_SIZE : CTXIN_SPEND_DUST_SIZE; |
|
|
|
if (estimatedTxSize + increase >= MAX_TX_SIZE || |
|
|
|
if (estimatedTxSize + increase >= max_tx_size || |
|
|
|
(mempoolLimit > 0 && utxoCounter > mempoolLimit)) |
|
|
|
{ |
|
|
|
maxedOutUTXOsFlag = true; |
|
|
@ -4157,7 +4173,7 @@ UniValue z_mergetoaddress(const UniValue& params, bool fHelp) |
|
|
|
// If we haven't added any notes yet and the merge is to a
|
|
|
|
// z-address, we have already accounted for the first JoinSplit.
|
|
|
|
size_t increase = (noteInputs.empty() && !isToZaddr) || (noteInputs.size() % 2 == 0) ? JOINSPLIT_SIZE : 0; |
|
|
|
if (estimatedTxSize + increase >= MAX_TX_SIZE || |
|
|
|
if (estimatedTxSize + increase >= max_tx_size || |
|
|
|
(nNoteLimit > 0 && noteCounter > nNoteLimit)) |
|
|
|
{ |
|
|
|
maxedOutNotesFlag = true; |
|
|
|