Raise 100kB transaction size limit from Sapling activation

Closes #2864.
This commit is contained in:
Jack Grigg
2018-04-26 14:18:36 +01:00
parent d97bfb766b
commit 15ec5525e3
5 changed files with 81 additions and 15 deletions

View File

@@ -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;