diff options
author | fanquake <fanquake@gmail.com> | 2020-03-27 13:07:35 +0800 |
---|---|---|
committer | fanquake <fanquake@gmail.com> | 2020-03-27 14:49:50 +0800 |
commit | 54646167db5ec86e1f532b6dcf8a1713ea026b6b (patch) | |
tree | e76d49ef9cbb9e88c152bcf8c756984e6166d6ed /src/script | |
parent | e3154aacf444a29f9f5642b6c937e875ab9a2c13 (diff) | |
parent | 2b0fcff7f26d59fed4bcafd1602325122a206c67 (diff) |
Merge #18388: Make VerifyWitnessProgram use a Span stack
2b0fcff7f26d59fed4bcafd1602325122a206c67 Make VerifyWitnessProgram use a Span stack (Pieter Wuille)
Pull request description:
Here is a follow-up to #18002, again with the goal of simplifying (potential) BIP341 code.
Instead of passing a begin and end iterator of the initial stack to `ExecuteWitnessScript`, they are turned into a `Span<const valtype>`, representing a span of `valtype`s in memory. This allows `VerifyWitnessProgram` to operate on that span directly, instead of juggling iterators around (which would be exacerbated by #17977 if trying to avoid copying the stack).
ACKs for top commit:
ajtowns:
ACK 2b0fcff7f26d59fed4bcafd1602325122a206c67
elichai:
ReACK on the diff 2b0fcff7f26d59fed4bcafd1602325122a206c67
instagibbs:
re-ACK https://github.com/bitcoin/bitcoin/pull/18388/commits/2b0fcff7f26d59fed4bcafd1602325122a206c67
theStack:
re-ACK https://github.com/bitcoin/bitcoin/commit/2b0fcff7f26d59fed4bcafd1602325122a206c67
Empact:
ACK https://github.com/bitcoin/bitcoin/commit/2b0fcff7f26d59fed4bcafd1602325122a206c67
jnewbery:
utACK 2b0fcff7f26d59fed4bcafd1602325122a206c67
Tree-SHA512: 38eb4ce17f1947674c1c274caa40feb6ea8266bd96134d9cf1bc41e6fbf1114d4dde6c7a9e26e1ca8f3d0155429ef0911cc8ec0c1037d8fe7d6ec7f9e7184e93
Diffstat (limited to 'src/script')
-rw-r--r-- | src/script/interpreter.cpp | 16 |
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); } |