Closes #2639. Adds optional limit parameter with a default value of 50.

The new parameter is to satisfy the principle of least astonishment
by providing a sensible default for the maximum number of transparent
inputs to shield.  If users do not configure -mempooltxinputlimit
it is possible for them to create transactions with hundreds of
inputs which suffer from mining delay, due to the current state of
the network where some miners have configured -mempooltxinputlimit
as a way to deal with the problem of quadratic hashing.
This commit is contained in:
Simon
2017-11-01 10:40:24 -07:00
parent c2d3bafeaa
commit c5dabd2b66
5 changed files with 65 additions and 10 deletions

View File

@@ -3522,18 +3522,21 @@ When estimating the number of coinbase utxos we can shield in a single transacti
*/
#define CTXIN_SPEND_P2SH_SIZE 400
#define SHIELD_COINBASE_DEFAULT_LIMIT 50
UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
{
if (!EnsureWalletIsAvailable(fHelp))
return NullUniValue;
if (fHelp || params.size() < 2 || params.size() > 3)
if (fHelp || params.size() < 2 || params.size() > 4)
throw runtime_error(
"z_shieldcoinbase \"fromaddress\" \"tozaddress\" ( fee )\n"
"z_shieldcoinbase \"fromaddress\" \"tozaddress\" ( fee ) ( limit )\n"
"\nShield transparent coinbase funds by sending to a shielded zaddr. This is an asynchronous operation and utxos"
"\nselected for shielding will be locked. If there is an error, they are unlocked. The RPC call `listlockunspent`"
"\ncan be used to return a list of locked utxos. The number of coinbase utxos selected for shielding is limited by"
"\nboth the -mempooltxinputlimit=xxx option and a consensus rule defining a maximum transaction size of "
"\ncan be used to return a list of locked utxos. The number of coinbase utxos selected for shielding can be limited"
"\nby the caller. If the limit parameter is set to zero, the -mempooltxinputlimit option will determine the number"
"\nof uxtos. Any limit is constrained by the consensus rule defining a maximum transaction size of "
+ strprintf("%d bytes.", MAX_TX_SIZE)
+ HelpRequiringPassphrase() + "\n"
"\nArguments:\n"
@@ -3541,6 +3544,8 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
"2. \"toaddress\" (string, required) The address is a zaddr.\n"
"3. fee (numeric, optional, default="
+ strprintf("%s", FormatMoney(SHIELD_COINBASE_DEFAULT_MINERS_FEE)) + ") The fee amount to attach to this transaction.\n"
"4. limit (numeric, optional, default="
+ strprintf("%d", SHIELD_COINBASE_DEFAULT_LIMIT) + ") Limit on the maximum number of utxos to shield. Set to 0 to use node option -mempooltxinputlimit.\n"
"\nResult:\n"
"{\n"
" \"operationid\": xxx (string) An operationid to pass to z_getoperationstatus to get the result of the operation.\n"
@@ -3583,6 +3588,14 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
}
}
int nLimit = SHIELD_COINBASE_DEFAULT_LIMIT;
if (params.size() > 3) {
nLimit = params[3].get_int();
if (nLimit < 0) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "Limit on maximum number of utxos cannot be negative");
}
}
// Prepare to get coinbase utxos
std::vector<ShieldCoinbaseUTXO> inputs;
CAmount shieldedValue = 0;
@@ -3590,7 +3603,7 @@ UniValue z_shieldcoinbase(const UniValue& params, bool fHelp)
size_t estimatedTxSize = 2000; // 1802 joinsplit description + tx overhead + wiggle room
size_t utxoCounter = 0;
bool maxedOutFlag = false;
size_t mempoolLimit = (size_t)GetArg("-mempooltxinputlimit", 0);
size_t mempoolLimit = (nLimit != 0) ? nLimit : (size_t)GetArg("-mempooltxinputlimit", 0);
// Set of addresses to filter utxos by
set<CBitcoinAddress> setAddress = {};