@@ -738,6 +738,19 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& in
738738 return nSigOps;
739739}
740740
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+ }
741754
742755
743756
@@ -941,6 +954,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState &state, const C
941954
942955 unsigned int nSigOps = GetLegacySigOpCount (tx);
943956 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));
944962
945963 CAmount nValueOut = tx.GetValueOut ();
946964 CAmount nFees = nValueIn-nValueOut;
@@ -2080,6 +2098,7 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
20802098 CAmount nFees = 0 ;
20812099 int nInputs = 0 ;
20822100 unsigned int nSigOps = 0 ;
2101+ unsigned int nWitSigOps = 0 ;
20832102 CDiskTxPos pos (pindex->GetBlockPos (), GetSizeOfCompactSize (block.vtx .size ()));
20842103 std::vector<std::pair<uint256, CDiskTxPos> > vPos;
20852104 vPos.reserve (block.vtx .size ());
@@ -2100,13 +2119,15 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
21002119 return state.DoS (100 , error (" ConnectBlock(): inputs missing/spent" ),
21012120 REJECT_INVALID, " bad-txns-inputs-missingorspent" );
21022121
2122+ nWitSigOps += GetWitnessSigOpCount (tx, view, flags);
2123+
21032124 if (fStrictPayToScriptHash )
21042125 {
21052126 // Add in sigops done by pay-to-script-hash inputs;
21062127 // this is to prevent a "rogue miner" from creating
21072128 // an incredibly-expensive-to-validate block.
21082129 nSigOps += GetP2SHSigOpCount (tx, view);
2109- if (nSigOps > MAX_BLOCK_SIGOPS)
2130+ if (nSigOps + (nWitSigOps + 3 ) / 4 > MAX_BLOCK_SIGOPS)
21102131 return state.DoS (100 , error (" ConnectBlock(): too many sigops" ),
21112132 REJECT_INVALID, " bad-blk-sigops" );
21122133 }
0 commit comments