diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-01-08 12:00:19 +0100 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2015-01-08 12:01:22 +0100 |
commit | 48e1765e2781541c0f8b0893b26d02f27eb5c444 (patch) | |
tree | 112a2d69a7b1bd0f60d088e90696e294a9a84861 /src/script/interpreter.cpp | |
parent | e3f5727590f5a2bb65f1fc7688305fe440ef404d (diff) | |
parent | da918ac06e0d064e9584959ab3d241d03500e972 (diff) |
Merge pull request #5143
da918ac Make SCRIPT_VERIFY_CLEANSTACK a standardness requirement (Pieter Wuille)
b6e03cc Add SCRIPT_VERIFY_CLEANSTACK (BIP62 rule 6) (Pieter Wuille)
ae4151b No semantic change: reuse stack variable in P2SH evaluation (Pieter Wuille)
Diffstat (limited to 'src/script/interpreter.cpp')
-rw-r--r-- | src/script/interpreter.cpp | 32 |
1 files changed, 22 insertions, 10 deletions
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index e979f61f6e..d0f75ab672 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -1098,7 +1098,6 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne return false; if (stack.empty()) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); - if (CastToBool(stack.back()) == false) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); @@ -1109,24 +1108,37 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigne if (!scriptSig.IsPushOnly()) return set_error(serror, SCRIPT_ERR_SIG_PUSHONLY); - // stackCopy cannot be empty here, because if it was the + // Restore stack. + swap(stack, stackCopy); + + // stack cannot be empty here, because if it was the // P2SH HASH <> EQUAL scriptPubKey would be evaluated with // an empty stack and the EvalScript above would return false. - assert(!stackCopy.empty()); + assert(!stack.empty()); - const valtype& pubKeySerialized = stackCopy.back(); + const valtype& pubKeySerialized = stack.back(); CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end()); - popstack(stackCopy); + popstack(stack); - if (!EvalScript(stackCopy, pubKey2, flags, checker, serror)) + if (!EvalScript(stack, pubKey2, flags, checker, serror)) // serror is set return false; - if (stackCopy.empty()) + if (stack.empty()) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); - if (!CastToBool(stackCopy.back())) + if (!CastToBool(stack.back())) return set_error(serror, SCRIPT_ERR_EVAL_FALSE); - else - return set_success(serror); + } + + // The CLEANSTACK check is only performed after potential P2SH evaluation, + // as the non-P2SH evaluation of a P2SH script will obviously not result in + // a clean stack (the P2SH inputs remain). + if ((flags & SCRIPT_VERIFY_CLEANSTACK) != 0) { + // Disallow CLEANSTACK without P2SH, as otherwise a switch CLEANSTACK->P2SH+CLEANSTACK + // would be possible, which is not a softfork (and P2SH should be one). + assert((flags & SCRIPT_VERIFY_P2SH) != 0); + if (stack.size() != 1) { + return set_error(serror, SCRIPT_ERR_CLEANSTACK); + } } return set_success(serror); |