| 156 | } |
| 157 | |
| 158 | int64_t GetTransactionSigOpCost(const CTransaction& tx, const CCoinsViewCache& inputs, uint32_t flags) |
| 159 | { |
| 160 | int64_t nSigOps = GetLegacySigOpCount(tx) * WITNESS_SCALE_FACTOR; |
| 161 | |
| 162 | if (tx.IsCoinBase()) |
| 163 | return nSigOps; |
| 164 | |
| 165 | if (flags & SCRIPT_VERIFY_P2SH) { |
| 166 | nSigOps += GetP2SHSigOpCount(tx, inputs) * WITNESS_SCALE_FACTOR; |
| 167 | } |
| 168 | |
| 169 | // Note that we only count segwit sigops for peg-in inputs |
| 170 | for (unsigned int i = 0; i < tx.vin.size(); i++) |
| 171 | { |
| 172 | CScript scriptPubKey; |
| 173 | if (tx.vin[i].m_is_pegin) { |
| 174 | std::string err; |
| 175 | // Make sure witness exists and has enough peg-in witness fields for |
| 176 | // the claim_script |
| 177 | if (tx.witness.vtxinwit.size() != tx.vin.size() || |
| 178 | tx.witness.vtxinwit[i].m_pegin_witness.stack.size() < 4) { |
| 179 | continue; |
| 180 | } |
| 181 | const auto pegin_witness = tx.witness.vtxinwit[i].m_pegin_witness; |
| 182 | scriptPubKey = CScript(pegin_witness.stack[3].begin(), pegin_witness.stack[3].end()); |
| 183 | } else { |
| 184 | const Coin& coin = inputs.AccessCoin(tx.vin[i].prevout); |
| 185 | assert(!coin.IsSpent()); |
| 186 | scriptPubKey = coin.out.scriptPubKey; |
| 187 | } |
| 188 | |
| 189 | const CScriptWitness* pScriptWitness = tx.witness.vtxinwit.size() > i ? &tx.witness.vtxinwit[i].scriptWitness : NULL; |
| 190 | nSigOps += CountWitnessSigOps(tx.vin[i].scriptSig, scriptPubKey, pScriptWitness, flags); |
| 191 | } |
| 192 | return nSigOps; |
| 193 | } |
| 194 | |
| 195 | bool Consensus::CheckTxInputs(const CTransaction& tx, TxValidationState& state, const CCoinsViewCache& inputs, int nSpendHeight, CAmountMap& fee_map, std::set<std::pair<uint256, COutPoint>>& setPeginsSpent, std::vector<CCheck*> *pvChecks, const bool cacheStore, bool fScriptChecks, const std::vector<std::pair<CScript, CScript>>& fedpegscripts) |
| 196 | { |