aboutsummaryrefslogtreecommitdiff
path: root/src/script/interpreter.cpp
diff options
context:
space:
mode:
authorPieter Wuille <pieter@wuille.net>2020-03-17 20:02:48 -0700
committerPieter Wuille <pieter@wuille.net>2020-03-23 14:44:58 -0700
commit2b0fcff7f26d59fed4bcafd1602325122a206c67 (patch)
treec9284316d7d781da79bb7fe651db3764676c3de2 /src/script/interpreter.cpp
parent5bf45fe2a9642f8ae8f8a12bcbf8f8b4770421ad (diff)
downloadbitcoin-2b0fcff7f26d59fed4bcafd1602325122a206c67.tar.xz
Make VerifyWitnessProgram use a Span stack
This allows for very cheap transformations on the range of elements that are to be passed to ExecuteWitnessScript.
Diffstat (limited to 'src/script/interpreter.cpp')
-rw-r--r--src/script/interpreter.cpp16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index 5bf418472a..083022fbdd 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -1478,9 +1478,9 @@ bool GenericTransactionSignatureChecker<T>::CheckSequence(const CScriptNum& nSeq
template class GenericTransactionSignatureChecker<CTransaction>;
template class GenericTransactionSignatureChecker<CMutableTransaction>;
-static bool ExecuteWitnessScript(std::vector<valtype>::const_iterator begin, std::vector<valtype>::const_iterator end, const CScript& scriptPubKey, unsigned int flags, SigVersion sigversion, const BaseSignatureChecker& checker, ScriptError* serror)
+static bool ExecuteWitnessScript(const Span<const valtype>& stack_span, const CScript& scriptPubKey, unsigned int flags, SigVersion sigversion, const BaseSignatureChecker& checker, ScriptError* serror)
{
- std::vector<valtype> stack{begin, end};
+ std::vector<valtype> stack{stack_span.begin(), stack_span.end()};
// Disallow stack item size > MAX_SCRIPT_ELEMENT_SIZE in witness stack
for (const valtype& elem : stack) {
@@ -1499,27 +1499,29 @@ static bool ExecuteWitnessScript(std::vector<valtype>::const_iterator begin, std
static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, const std::vector<unsigned char>& program, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror)
{
CScript scriptPubKey;
+ Span<const valtype> stack = MakeSpan(witness.stack);
if (witversion == 0) {
if (program.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
// Version 0 segregated witness program: SHA256(CScript) inside the program, CScript + inputs in witness
- if (witness.stack.size() == 0) {
+ if (stack.size() == 0) {
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY);
}
- scriptPubKey = CScript(witness.stack.back().begin(), witness.stack.back().end());
+ const valtype& script_bytes = SpanPopBack(stack);
+ scriptPubKey = CScript(script_bytes.begin(), script_bytes.end());
uint256 hashScriptPubKey;
CSHA256().Write(&scriptPubKey[0], scriptPubKey.size()).Finalize(hashScriptPubKey.begin());
if (memcmp(hashScriptPubKey.begin(), program.data(), 32)) {
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
}
- return ExecuteWitnessScript(witness.stack.begin(), witness.stack.end() - 1, scriptPubKey, flags, SigVersion::WITNESS_V0, checker, serror);
+ return ExecuteWitnessScript(stack, scriptPubKey, flags, SigVersion::WITNESS_V0, checker, serror);
} else if (program.size() == WITNESS_V0_KEYHASH_SIZE) {
// Special case for pay-to-pubkeyhash; signature + pubkey in witness
- if (witness.stack.size() != 2) {
+ if (stack.size() != 2) {
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH); // 2 items in witness
}
scriptPubKey << OP_DUP << OP_HASH160 << program << OP_EQUALVERIFY << OP_CHECKSIG;
- return ExecuteWitnessScript(witness.stack.begin(), witness.stack.end(), scriptPubKey, flags, SigVersion::WITNESS_V0, checker, serror);
+ return ExecuteWitnessScript(stack, scriptPubKey, flags, SigVersion::WITNESS_V0, checker, serror);
} else {
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH);
}