@@ -738,6 +738,19 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
738
738
return nSigOps;
739
739
}
740
740
741
+ unsigned int GetWitnessSigOpCount (const CTransaction& tx, const CCoinsViewCache& inputs, int flags)
742
+ {
743
+ if (tx.IsCoinBase ())
744
+ return 0 ;
745
+
746
+ unsigned int nSigOps = 0 ;
747
+ for (unsigned int i = 0 ; i < tx.vin .size (); i++)
748
+ {
749
+ const CTxOut &prevout = inputs.GetOutputFor (tx.vin [i]);
750
+ nSigOps += CountWitnessSigOps (tx.vin [i].scriptSig , prevout.scriptPubKey , i < tx.wit .vtxinwit .size () ? &tx.wit .vtxinwit [i].scriptWitness : NULL , flags);
751
+ }
752
+ return nSigOps;
753
+ }
741
754
742
755
743
756
@@ -940,6 +953,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
940
953
941
954
unsigned int nSigOps = GetLegacySigOpCount (tx);
942
955
nSigOps += GetP2SHSigOpCount (tx, view);
956
+ nSigOps += (GetWitnessSigOpCount (tx, view, STANDARD_SCRIPT_VERIFY_FLAGS) + 3 ) / 4 ;
957
+
958
+ if (nSigOps > MAX_STANDARD_TX_SIGOPS)
959
+ return state.DoS (0 , false , REJECT_NONSTANDARD, " bad-txns-too-many-sigops" , false ,
960
+ strprintf (" %d > %d" , nSigOps, MAX_STANDARD_TX_SIGOPS));
943
961
944
962
CAmount nValueOut = tx.GetValueOut ();
945
963
CAmount nFees = nValueIn-nValueOut;
@@ -2079,6 +2097,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
2079
2097
CAmount nFees = 0 ;
2080
2098
int nInputs = 0 ;
2081
2099
unsigned int nSigOps = 0 ;
2100
+ unsigned int nWitSigOps = 0 ;
2082
2101
CDiskTxPos pos (pindex->GetBlockPos (), GetSizeOfCompactSize (block.vtx .size ()));
2083
2102
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
2084
2103
vPos.reserve (block.vtx .size ());
@@ -2099,13 +2118,15 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
2099
2118
return state.DoS (100 , error (" ConnectBlock(): inputs missing/spent" ),
2100
2119
REJECT_INVALID, " bad-txns-inputs-missingorspent" );
2101
2120
2121
+ nWitSigOps += GetWitnessSigOpCount (tx, view, flags);
2122
+
2102
2123
if (fStrictPayToScriptHash )
2103
2124
{
2104
2125
// Add in sigops done by pay-to-script-hash inputs;
2105
2126
// this is to prevent a "rogue miner" from creating
2106
2127
// an incredibly-expensive-to-validate block.
2107
2128
nSigOps += GetP2SHSigOpCount (tx, view);
2108
- if (nSigOps > MAX_BLOCK_SIGOPS)
2129
+ if (nSigOps + (nWitSigOps + 3 ) / 4 > MAX_BLOCK_SIGOPS)
2109
2130
return state.DoS (100 , error (" ConnectBlock(): too many sigops" ),
2110
2131
REJECT_INVALID, " bad-blk-sigops" );
2111
2132
}
0 commit comments