Changeset View
Changeset View
Standalone View
Standalone View
src/script/interpreter.cpp
Show First 20 Lines • Show All 157 Lines • ▼ Show 20 Lines | void toggle_top() { | ||||
} else { | } else { | ||||
// There is a false value, but not on top. No action is needed as | // There is a false value, but not on top. No action is needed as | ||||
// toggling anything but the first false value is unobservable. | // toggling anything but the first false value is unobservable. | ||||
} | } | ||||
} | } | ||||
}; | }; | ||||
} // namespace | } // namespace | ||||
/** | |||||
* Helper for OP_CHECKSIG and OP_CHECKSIGVERIFY | |||||
* | |||||
* A return value of false means the script fails entirely. When true is | |||||
* returned, the fSuccess variable indicates whether the signature check itself | |||||
* succeeded. | |||||
*/ | |||||
static bool EvalChecksig(const valtype &vchSig, const valtype &vchPubKey, | |||||
CScript::const_iterator pbegincodehash, | |||||
CScript::const_iterator pend, uint32_t flags, | |||||
const BaseSignatureChecker &checker, | |||||
ScriptExecutionMetrics &metrics, ScriptError *serror, | |||||
bool &fSuccess) { | |||||
if (!CheckTransactionSignatureEncoding(vchSig, flags, serror) || | |||||
!CheckPubKeyEncoding(vchPubKey, flags, serror)) { | |||||
// serror is set | |||||
return false; | |||||
} | |||||
if (vchSig.size()) { | |||||
// Subset of script starting at the most recent | |||||
// codeseparator | |||||
CScript scriptCode(pbegincodehash, pend); | |||||
// Remove signature for pre-fork scripts | |||||
CleanupScriptCode(scriptCode, vchSig, flags); | |||||
fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode, flags); | |||||
metrics.nSigChecks += 1; | |||||
if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL)) { | |||||
return set_error(serror, ScriptError::SIG_NULLFAIL); | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
bool EvalScript(std::vector<valtype> &stack, const CScript &script, | bool EvalScript(std::vector<valtype> &stack, const CScript &script, | ||||
uint32_t flags, const BaseSignatureChecker &checker, | uint32_t flags, const BaseSignatureChecker &checker, | ||||
ScriptExecutionMetrics &metrics, ScriptError *serror) { | ScriptExecutionMetrics &metrics, ScriptError *serror) { | ||||
static const CScriptNum bnZero(0); | static const CScriptNum bnZero(0); | ||||
static const CScriptNum bnOne(1); | static const CScriptNum bnOne(1); | ||||
static const valtype vchFalse(0); | static const valtype vchFalse(0); | ||||
static const valtype vchTrue(1, 1); | static const valtype vchTrue(1, 1); | ||||
▲ Show 20 Lines • Show All 751 Lines • ▼ Show 20 Lines | try { | ||||
// (sig pubkey -- bool) | // (sig pubkey -- bool) | ||||
if (stack.size() < 2) { | if (stack.size() < 2) { | ||||
return set_error( | return set_error( | ||||
serror, ScriptError::INVALID_STACK_OPERATION); | serror, ScriptError::INVALID_STACK_OPERATION); | ||||
} | } | ||||
valtype &vchSig = stacktop(-2); | valtype &vchSig = stacktop(-2); | ||||
valtype &vchPubKey = stacktop(-1); | valtype &vchPubKey = stacktop(-1); | ||||
if (!CheckTransactionSignatureEncoding(vchSig, flags, | |||||
serror) || | |||||
!CheckPubKeyEncoding(vchPubKey, flags, serror)) { | |||||
// serror is set | |||||
return false; | |||||
} | |||||
bool fSuccess = false; | bool fSuccess = false; | ||||
if (vchSig.size()) { | if (!EvalChecksig(vchSig, vchPubKey, pbegincodehash, | ||||
// Subset of script starting at the most recent | pend, flags, checker, metrics, serror, | ||||
// codeseparator | fSuccess)) { | ||||
CScript scriptCode(pbegincodehash, pend); | return false; | ||||
// Remove signature for pre-fork scripts | |||||
CleanupScriptCode(scriptCode, vchSig, flags); | |||||
fSuccess = checker.CheckSig(vchSig, vchPubKey, | |||||
scriptCode, flags); | |||||
metrics.nSigChecks += 1; | |||||
if (!fSuccess && (flags & SCRIPT_VERIFY_NULLFAIL)) { | |||||
return set_error(serror, | |||||
ScriptError::SIG_NULLFAIL); | |||||
} | |||||
} | } | ||||
popstack(stack); | popstack(stack); | ||||
popstack(stack); | popstack(stack); | ||||
stack.push_back(fSuccess ? vchTrue : vchFalse); | stack.push_back(fSuccess ? vchTrue : vchFalse); | ||||
if (opcode == OP_CHECKSIGVERIFY) { | if (opcode == OP_CHECKSIGVERIFY) { | ||||
if (fSuccess) { | if (fSuccess) { | ||||
popstack(stack); | popstack(stack); | ||||
} else { | } else { | ||||
return set_error(serror, | return set_error(serror, | ||||
▲ Show 20 Lines • Show All 916 Lines • Show Last 20 Lines |