* Check transaction inputs to mitigate two * potential denial-of-service attacks: * * 1. scriptSigs with extra data stuffed into them, * not consumed by scriptPubKey (or P2SH script) * 2. P2SH scripts with a crazy number of expensive * CHECKSIG/CHECKMULTISIG operations * * Why bother? To avoid denial-of-service attacks; an attacker * can submit a standard HASH... OP_EQUAL transactio
| 180 | * Note that only the non-witness portion of the transaction is checked here. |
| 181 | */ |
| 182 | bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) |
| 183 | { |
| 184 | if (tx.IsCoinBase()) { |
| 185 | return true; // Coinbases don't use vin normally |
| 186 | } |
| 187 | |
| 188 | for (unsigned int i = 0; i < tx.vin.size(); i++) { |
| 189 | if (tx.vin[i].m_is_pegin) { |
| 190 | // This deals with p2sh in general only |
| 191 | continue; |
| 192 | } |
| 193 | |
| 194 | const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out; |
| 195 | |
| 196 | std::vector<std::vector<unsigned char> > vSolutions; |
| 197 | TxoutType whichType = Solver(prev.scriptPubKey, vSolutions); |
| 198 | if (whichType == TxoutType::NONSTANDARD || whichType == TxoutType::WITNESS_UNKNOWN) { |
| 199 | // WITNESS_UNKNOWN failures are typically also caught with a policy |
| 200 | // flag in the script interpreter, but it can be helpful to catch |
| 201 | // this type of NONSTANDARD transaction earlier in transaction |
| 202 | // validation. |
| 203 | return false; |
| 204 | } else if (whichType == TxoutType::SCRIPTHASH) { |
| 205 | std::vector<std::vector<unsigned char> > stack; |
| 206 | // convert the scriptSig into a stack, so we can inspect the redeemScript |
| 207 | if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE)) |
| 208 | return false; |
| 209 | if (stack.empty()) |
| 210 | return false; |
| 211 | CScript subscript(stack.back().begin(), stack.back().end()); |
| 212 | if (subscript.GetSigOpCount(true) > MAX_P2SH_SIGOPS) { |
| 213 | return false; |
| 214 | } |
| 215 | } |
| 216 | } |
| 217 | |
| 218 | return true; |
| 219 | } |
| 220 | |
| 221 | bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs) |
| 222 | { |