Backport meaningful parts of 8149/2b1f6f9ccf36f1e0a2c9d99154e1642f796d7c2b

This commit is contained in:
UdjinM6 2019-09-08 23:06:25 +03:00 committed by Pasta
parent 6fd35565a3
commit 70e386580d
No known key found for this signature in database
GPG Key ID: 52527BEDABE87984
3 changed files with 37 additions and 17 deletions

View File

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

View File

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

View File

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