Changeset View
Changeset View
Standalone View
Standalone View
src/validation.cpp
Show First 20 Lines • Show All 1,247 Lines • ▼ Show 20 Lines | for (size_t i = 0; i < tx.vin.size(); i++) { | ||||
const Amount amount = coin.GetTxOut().nValue; | const Amount amount = coin.GetTxOut().nValue; | ||||
// Verify signature | // Verify signature | ||||
CScriptCheck check(scriptPubKey, amount, tx, i, flags, sigCacheStore, | CScriptCheck check(scriptPubKey, amount, tx, i, flags, sigCacheStore, | ||||
txdata); | txdata); | ||||
if (pvChecks) { | if (pvChecks) { | ||||
pvChecks->push_back(std::move(check)); | pvChecks->push_back(std::move(check)); | ||||
} else if (!check()) { | } else if (!check()) { | ||||
ScriptError scriptError = check.GetScriptError(); | |||||
// Compute flags without the optional standardness flags. | // Compute flags without the optional standardness flags. | ||||
// This differs from MANDATORY_SCRIPT_VERIFY_FLAGS as it contains | // This differs from MANDATORY_SCRIPT_VERIFY_FLAGS as it contains | ||||
// additional upgrade flags (see AcceptToMemoryPoolWorker variable | // additional upgrade flags (see AcceptToMemoryPoolWorker variable | ||||
// extraFlags). | // extraFlags). | ||||
uint32_t mandatoryFlags = | uint32_t mandatoryFlags = | ||||
flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS; | flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS; | ||||
if (flags != mandatoryFlags) { | if (flags != mandatoryFlags) { | ||||
// Check whether the failure was caused by a non-mandatory | // Check whether the failure was caused by a non-mandatory | ||||
// script verification check. If so, don't trigger DoS | // script verification check. If so, don't trigger DoS | ||||
// protection to avoid splitting the network on the basis of | // protection to avoid splitting the network on the basis of | ||||
// relay policy disagreements. | // relay policy disagreements. | ||||
CScriptCheck check2(scriptPubKey, amount, tx, i, mandatoryFlags, | CScriptCheck check2(scriptPubKey, amount, tx, i, mandatoryFlags, | ||||
sigCacheStore, txdata); | sigCacheStore, txdata); | ||||
if (check2()) { | if (check2()) { | ||||
return state.Invalid( | return state.Invalid( | ||||
false, REJECT_NONSTANDARD, | false, REJECT_NONSTANDARD, | ||||
strprintf("non-mandatory-script-verify-flag (%s)", | strprintf("non-mandatory-script-verify-flag (%s)", | ||||
ScriptErrorString(check.GetScriptError()))); | ScriptErrorString(scriptError))); | ||||
} | } | ||||
// update the error message to reflect the mandatory violation. | |||||
scriptError = check2.GetScriptError(); | |||||
} | } | ||||
// Before banning, we need to check whether the transaction would | // Before banning, we need to check whether the transaction would | ||||
// be valid on the other side of the upgrade, so as to avoid | // be valid on the other side of the upgrade, so as to avoid | ||||
// splitting the network between upgraded and non-upgraded nodes. | // splitting the network between upgraded and non-upgraded nodes. | ||||
// Note that this will create strange error messages like | |||||
// "upgrade-conditional-script-failure (Dummy CHECKMULTISIG argument | |||||
// must be zero)" -- the tx was initially refused entry due to | |||||
// NULLDUMMY, a standardness flag, but it is outright invalid before | |||||
// the upgrade as it contains schnorr signatures; it would however | |||||
// be valid after the upgrade. | |||||
CScriptCheck check3(scriptPubKey, amount, tx, i, | CScriptCheck check3(scriptPubKey, amount, tx, i, | ||||
mandatoryFlags ^ SCRIPT_ENABLE_SCHNORR_MULTISIG, | mandatoryFlags ^ SCRIPT_ENABLE_SCHNORR_MULTISIG, | ||||
sigCacheStore, txdata); | sigCacheStore, txdata); | ||||
if (check3()) { | if (check3()) { | ||||
return state.Invalid( | return state.Invalid( | ||||
false, REJECT_INVALID, | false, REJECT_INVALID, | ||||
strprintf("upgrade-conditional-script-failure (%s)", | strprintf("upgrade-conditional-script-failure (%s)", | ||||
ScriptErrorString(check.GetScriptError()))); | ScriptErrorString(scriptError))); | ||||
} | } | ||||
// Failures of other flags indicate a transaction that is invalid in | // Failures of other flags indicate a transaction that is invalid in | ||||
// new blocks, e.g. a invalid P2SH. We DoS ban such nodes as they | // new blocks, e.g. a invalid P2SH. We DoS ban such nodes as they | ||||
// are not following the protocol. That said during an upgrade | // are not following the protocol. That said during an upgrade | ||||
// careful thought should be taken as to the correct behavior - we | // careful thought should be taken as to the correct behavior - we | ||||
// may want to continue peering with non-upgraded nodes even after | // may want to continue peering with non-upgraded nodes even after | ||||
// soft-fork super-majority signaling has occurred. | // soft-fork super-majority signaling has occurred. | ||||
return state.DoS( | return state.DoS( | ||||
100, false, REJECT_INVALID, | 100, false, REJECT_INVALID, | ||||
strprintf("mandatory-script-verify-flag-failed (%s)", | strprintf("mandatory-script-verify-flag-failed (%s)", | ||||
ScriptErrorString(check.GetScriptError()))); | ScriptErrorString(scriptError))); | ||||
} | } | ||||
} | } | ||||
if (scriptCacheStore && !pvChecks) { | if (scriptCacheStore && !pvChecks) { | ||||
// We executed all of the provided scripts, and were told to cache the | // We executed all of the provided scripts, and were told to cache the | ||||
// result. Do so now. | // result. Do so now. | ||||
AddKeyInScriptCache(hashCacheEntry); | AddKeyInScriptCache(hashCacheEntry); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 4,352 Lines • Show Last 20 Lines |