@@ -739,6 +739,19 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
739
739
return nSigOps;
740
740
}
741
741
742
+ unsigned int GetWitnessSigOpCount (const CTransaction& tx, const CCoinsViewCache& inputs, int flags)
743
+ {
744
+ if (tx.IsCoinBase ())
745
+ return 0 ;
746
+
747
+ unsigned int nSigOps = 0 ;
748
+ for (unsigned int i = 0 ; i < tx.vin .size (); i++)
749
+ {
750
+ const CTxOut &prevout = inputs.GetOutputFor (tx.vin [i]);
751
+ nSigOps += CountWitnessSigOps (tx.vin [i].scriptSig , prevout.scriptPubKey , i < tx.wit .vtxinwit .size () ? &tx.wit .vtxinwit [i].scriptWitness : NULL , flags);
752
+ }
753
+ return nSigOps;
754
+ }
742
755
743
756
744
757
@@ -945,6 +958,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
945
958
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
+
963
+ if (nSigOps > MAX_STANDARD_TX_SIGOPS)
964
+ return state.DoS (0 , false , REJECT_NONSTANDARD, " bad-txns-too-many-sigops" , false ,
965
+ strprintf (" %d > %d" , nSigOps, MAX_STANDARD_TX_SIGOPS));
948
966
949
967
CAmount nValueOut = tx.GetValueOut ();
950
968
CAmount nFees = nValueIn-nValueOut;
@@ -2084,6 +2102,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
2084
2102
CAmount nFees = 0 ;
2085
2103
int nInputs = 0 ;
2086
2104
unsigned int nSigOps = 0 ;
2105
+ unsigned int nWitSigOps = 0 ;
2087
2106
CDiskTxPos pos (pindex->GetBlockPos (), GetSizeOfCompactSize (block.vtx .size ()));
2088
2107
std::vector<std::pair<uint256, CDiskTxPos> > vPos;
2089
2108
vPos.reserve (block.vtx .size ());
@@ -2104,13 +2123,15 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
2104
2123
return state.DoS (100 , error (" ConnectBlock(): inputs missing/spent" ),
2105
2124
REJECT_INVALID, " bad-txns-inputs-missingorspent" );
2106
2125
2126
+ nWitSigOps += GetWitnessSigOpCount (tx, view, flags);
2127
+
2107
2128
if (fStrictPayToScriptHash )
2108
2129
{
2109
2130
// Add in sigops done by pay-to-script-hash inputs;
2110
2131
// this is to prevent a "rogue miner" from creating
2111
2132
// an incredibly-expensive-to-validate block.
2112
2133
nSigOps += GetP2SHSigOpCount (tx, view);
2113
- if (nSigOps > MAX_BLOCK_SIGOPS)
2134
+ if (nSigOps + (nWitSigOps + 3 ) / 4 > MAX_BLOCK_SIGOPS)
2114
2135
return state.DoS (100 , error (" ConnectBlock(): too many sigops" ),
2115
2136
REJECT_INVALID, " bad-blk-sigops" );
2116
2137
}
0 commit comments