From 70e386580daeda44f6fed3c1eba260018badb70b Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Sun, 8 Sep 2019 23:06:25 +0300 Subject: [PATCH] Backport meaningful parts of 8149/2b1f6f9ccf36f1e0a2c9d99154e1642f796d7c2b --- src/consensus/tx_verify.cpp | 14 ++++++++++++++ src/consensus/tx_verify.h | 9 +++++++++ src/validation.cpp | 31 ++++++++++++++----------------- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/src/consensus/tx_verify.cpp b/src/consensus/tx_verify.cpp index 38c3d8831..de6af5762 100644 --- a/src/consensus/tx_verify.cpp +++ b/src/consensus/tx_verify.cpp @@ -135,6 +135,20 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in return nSigOps; } +unsigned int GetTransactionSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs, int flags) +{ + unsigned int nSigOps = GetLegacySigOpCount(tx); + + if (tx.IsCoinBase()) + return nSigOps; + + if (flags & SCRIPT_VERIFY_P2SH) { + nSigOps += GetP2SHSigOpCount(tx, inputs); + } + + return nSigOps; +} + bool CheckTransaction(const CTransaction& tx, CValidationState &state) { bool allowEmptyTxInOut = false; diff --git a/src/consensus/tx_verify.h b/src/consensus/tx_verify.h index d2d7c441c..9673e0f2b 100644 --- a/src/consensus/tx_verify.h +++ b/src/consensus/tx_verify.h @@ -45,6 +45,15 @@ unsigned int GetLegacySigOpCount(const CTransaction& tx); */ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& mapInputs); +/** + * Count total signature operations for a transaction. + * @param[in] tx Transaction for which we are counting sigops + * @param[in] inputs Map of previous transactions that have outputs we're spending + * @param[out] flags Script verification flags + * @return Total signature operation count for a tx + */ +unsigned int GetTransactionSigOpCount(const CTransaction& tx, const CCoinsViewCache& inputs, int flags); + /** * Check if transaction is final and can be included in a block with the * specified height and time. Consensus critical. diff --git a/src/validation.cpp b/src/validation.cpp index 1f081f52f..5cbe07803 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -632,8 +632,7 @@ static bool AcceptToMemoryPoolWorker(const CChainParams& chainparams, CTxMemPool if (fRequireStandard && !AreInputsStandard(tx, view)) return state.Invalid(false, REJECT_NONSTANDARD, "bad-txns-nonstandard-inputs"); - unsigned int nSigOps = GetLegacySigOpCount(tx); - nSigOps += GetP2SHSigOpCount(tx, view); + unsigned int nSigOps = GetTransactionSigOpCount(tx, view, STANDARD_SCRIPT_VERIFY_FLAGS); CAmount nValueOut = tx.GetValueOut(); CAmount nFees = nValueIn-nValueOut; @@ -1945,12 +1944,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd const uint256 txhash = tx.GetHash(); nInputs += tx.vin.size(); - nSigOps += GetLegacySigOpCount(tx); - if (nSigOps > MaxBlockSigOps(fDIP0001Active_context)) - return state.DoS(100, error("ConnectBlock(): too many sigops"), - REJECT_INVALID, "bad-blk-sigops"); - txdata.emplace_back(tx); if (!tx.IsCoinBase()) { if (!view.HaveInputs(tx)) @@ -2010,16 +2004,19 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd } - if (fStrictPayToScriptHash) - { - // Add in sigops done by pay-to-script-hash inputs; - // this is to prevent a "rogue miner" from creating - // an incredibly-expensive-to-validate block. - nSigOps += GetP2SHSigOpCount(tx, view); - if (nSigOps > MaxBlockSigOps(fDIP0001Active_context)) - return state.DoS(100, error("ConnectBlock(): too many sigops"), - REJECT_INVALID, "bad-blk-sigops"); - } + } + + // GetTransactionSigOpCount counts 2 types of sigops: + // * legacy (always) + // * p2sh (when P2SH enabled in flags and excludes coinbase) + nSigOps += GetTransactionSigOpCount(tx, view, flags); + if (nSigOps > MaxBlockSigOps(fDIP0001Active_context)) + return state.DoS(100, error("ConnectBlock(): too many sigops"), + REJECT_INVALID, "bad-blk-sigops"); + + txdata.emplace_back(tx); + if (!tx.IsCoinBase()) + { nFees += view.GetValueIn(tx)-tx.GetValueOut();