diff --git a/src/init.cpp b/src/init.cpp index ec3553c46..c3b4dc45d 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -332,6 +332,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-dbcache=", strprintf(_("Set database cache size in megabytes (%d to %d, default: %d)"), nMinDbCache, nMaxDbCache, nDefaultDbCache)); strUsage += HelpMessageOpt("-loadblock=", _("Imports blocks from external blk000??.dat file") + " " + _("on startup")); strUsage += HelpMessageOpt("-maxorphantx=", strprintf(_("Keep at most unconnectable transactions in memory (default: %u)"), DEFAULT_MAX_ORPHAN_TRANSACTIONS)); + strUsage += HelpMessageOpt("-mempooltxinputlimit=", _("Set the maximum number of transparent inputs in a transaction that the mempool will accept (default: 0 = no limit applied)")); strUsage += HelpMessageOpt("-par=", strprintf(_("Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)"), -(int)boost::thread::hardware_concurrency(), MAX_SCRIPTCHECK_THREADS, DEFAULT_SCRIPTCHECK_THREADS)); #ifndef WIN32 @@ -1009,6 +1010,17 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler) } #endif + // Default value of 0 for mempooltxinputlimit means no limit is applied + if (mapArgs.count("-mempooltxinputlimit")) { + int64_t limit = GetArg("-mempooltxinputlimit", 0); + if (limit < 0) { + return InitError(_("Mempool limit on transparent inputs to a transaction cannot be negative")); + } else if (limit > 0) { + LogPrintf("Mempool configured to reject transactions with greater than %lld transparent inputs\n", limit); + } + } + + // ********************************************************* Step 4: application initialization: dir lock, daemonize, pidfile, debug log // Initialize libsodium diff --git a/src/main.cpp b/src/main.cpp index ab91ee41e..e68970300 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1057,6 +1057,17 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (pfMissingInputs) *pfMissingInputs = false; + // Node operator can choose to reject tx by number of transparent inputs + static_assert(std::numeric_limits::max() >= std::numeric_limits::max(), "size_t too small"); + size_t limit = (size_t) GetArg("-mempooltxinputlimit", 0); + if (limit > 0) { + size_t n = tx.vin.size(); + if (n > limit) { + LogPrint("mempool", "Dropping txid %s : too many transparent inputs %zu > limit %zu\n", tx.GetHash().ToString(), n, limit ); + return false; + } + } + auto verifier = libzcash::ProofVerifier::Strict(); if (!CheckTransaction(tx, state, verifier)) return error("AcceptToMemoryPool: CheckTransaction failed");