MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / ValidateInputsStandardness

Function ValidateInputsStandardness

src/policy/policy.cpp:214–263  ·  view source on GitHub ↗

* Check transaction inputs. * * This does three things: * * Prevents mempool acceptance of spends of future * segwit versions we don't know how to validate * * Mitigates a potential denial-of-service attack with * P2SH scripts with a crazy number of expensive * CHECKSIG/CHECKMULTISIG operations. * * Prevents spends of unknown/irregular scriptPubKeys, * which mitigates poten

Source from the content-addressed store, hash-verified

212 * We also check the total number of non-witness sigops across the whole transaction, as per BIP54.
213 */
214TxValidationState ValidateInputsStandardness(const CTransaction& tx, const CCoinsViewCache& mapInputs)
215{
216 TxValidationState state;
217 if (tx.IsCoinBase()) {
218 return state; // Coinbases don't use vin normally
219 }
220
221 if (!CheckSigopsBIP54(tx, mapInputs)) {
222 state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs", "non-witness sigops exceed bip54 limit");
223 return state;
224 }
225
226 for (unsigned int i = 0; i < tx.vin.size(); i++) {
227 const CTxOut& prev = mapInputs.AccessCoin(tx.vin[i].prevout).out;
228
229 std::vector<std::vector<unsigned char> > vSolutions;
230 TxoutType whichType = Solver(prev.scriptPubKey, vSolutions);
231 if (whichType == TxoutType::NONSTANDARD) {
232 state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs", strprintf("input %u script unknown", i));
233 return state;
234 } else if (whichType == TxoutType::WITNESS_UNKNOWN) {
235 // WITNESS_UNKNOWN failures are typically also caught with a policy
236 // flag in the script interpreter, but it can be helpful to catch
237 // this type of NONSTANDARD transaction earlier in transaction
238 // validation.
239 state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs", strprintf("input %u witness program is undefined", i));
240 return state;
241 } else if (whichType == TxoutType::SCRIPTHASH) {
242 std::vector<std::vector<unsigned char> > stack;
243 ScriptError serror;
244 // convert the scriptSig into a stack, so we can inspect the redeemScript
245 if (!EvalScript(stack, tx.vin[i].scriptSig, SCRIPT_VERIFY_NONE, BaseSignatureChecker(), SigVersion::BASE, &serror)) {
246 state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs", strprintf("p2sh scriptsig malformed (input %u: %s)", i, ScriptErrorString(serror)));
247 return state;
248 }
249 if (stack.empty()) {
250 state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs", strprintf("input %u P2SH redeemscript missing", i));
251 return state;
252 }
253 CScript subscript(stack.back().begin(), stack.back().end());
254 unsigned int sigop_count = subscript.GetSigOpCount(true);
255 if (sigop_count > MAX_P2SH_SIGOPS) {
256 state.Invalid(TxValidationResult::TX_INPUTS_NOT_STANDARD, "bad-txns-nonstandard-inputs", strprintf("p2sh redeemscript sigops exceed limit (input %u: %u > %u)", i, sigop_count, MAX_P2SH_SIGOPS));
257 return state;
258 }
259 }
260 }
261
262 return state;
263}
264
265bool IsWitnessStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
266{

Callers 6

PreChecksMethod · 0.85
BOOST_AUTO_TEST_CASEFunction · 0.85
BOOST_AUTO_TEST_CASEFunction · 0.85
TestCoinsViewFunction · 0.85
transaction.cppFile · 0.85
CCoinsCachingFunction · 0.85

Calls 13

CheckSigopsBIP54Function · 0.85
SolverFunction · 0.85
EvalScriptFunction · 0.85
ScriptErrorStringFunction · 0.85
InvalidMethod · 0.80
IsCoinBaseMethod · 0.45
sizeMethod · 0.45
emptyMethod · 0.45
beginMethod · 0.45
backMethod · 0.45
endMethod · 0.45

Tested by 3

BOOST_AUTO_TEST_CASEFunction · 0.68
BOOST_AUTO_TEST_CASEFunction · 0.68
TestCoinsViewFunction · 0.68