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