@@ -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
@@ -941,6 +954,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
941
954
942
955
unsigned int nSigOps = GetLegacySigOpCount (tx);
943
956
nSigOps += GetP2SHSigOpCount (tx, view);
957
+ nSigOps += (GetWitnessSigOpCount (tx, view, STANDARD_SCRIPT_VERIFY_FLAGS) + 3 ) / 4 ;
958
+
959
+ if (nSigOps > MAX_STANDARD_TX_SIGOPS)
960
+ return state.DoS (0 , false , REJECT_NONSTANDARD, " bad-txns-too-many-sigops" , false ,
961
+ strprintf (" %d > %d" , nSigOps, MAX_STANDARD_TX_SIGOPS));
944
962
945
963
CAmount nValueOut = tx.GetValueOut ();
946
964
CAmount nFees = nValueIn-nValueOut;
@@ -2080,6 +2098,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
2080
2098
CAmount nFees = 0 ;
2081
2099
int nInputs = 0 ;
2082
2100
unsigned int nSigOps = 0 ;
2101
+ unsigned int nWitSigOps = 0 ;
2083
2102
CDiskTxPos pos (pindex->GetBlockPos (), GetSizeOfCompactSize (block.vtx .size ()));
2084
2103
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
2085
2104
vPos.reserve (block.vtx .size ());
@@ -2100,13 +2119,15 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
2100
2119
return state.DoS (100 , error (" ConnectBlock(): inputs missing/spent" ),
2101
2120
REJECT_INVALID, " bad-txns-inputs-missingorspent" );
2102
2121
2122
+ nWitSigOps += GetWitnessSigOpCount (tx, view, flags);
2123
+
2103
2124
if (fStrictPayToScriptHash )
2104
2125
{
2105
2126
// Add in sigops done by pay-to-script-hash inputs;
2106
2127
// this is to prevent a "rogue miner" from creating
2107
2128
// an incredibly-expensive-to-validate block.
2108
2129
nSigOps += GetP2SHSigOpCount (tx, view);
2109
- if (nSigOps > MAX_BLOCK_SIGOPS)
2130
+ if (nSigOps + (nWitSigOps + 3 ) / 4 > MAX_BLOCK_SIGOPS)
2110
2131
return state.DoS (100 , error (" ConnectBlock(): too many sigops" ),
2111
2132
REJECT_INVALID, " bad-blk-sigops" );
2112
2133
}
0 commit comments