Do not use CScript for tapleaf scripts until the tapleaf version is known

Prevents use of CScript methods until the tapleaf is known to be a tapscript.
This commit is contained in:
Russell O'Connor
2022-08-19 10:40:28 -04:00
parent 60a00889b0
commit 8e3fc99427
8 changed files with 29 additions and 29 deletions

View File

@@ -1825,9 +1825,9 @@ static bool ExecuteWitnessScript(const Span<const valtype>& stack_span, const CS
return true;
}
uint256 ComputeTapleafHash(uint8_t leaf_version, const CScript& script)
uint256 ComputeTapleafHash(uint8_t leaf_version, Span<const unsigned char> script)
{
return (HashWriter{HASHER_TAPLEAF} << leaf_version << script).GetSHA256();
return (HashWriter{HASHER_TAPLEAF} << leaf_version << CompactSizeWriter(script.size()) << script).GetSHA256();
}
uint256 ComputeTaprootMerkleRoot(Span<const unsigned char> control, const uint256& tapleaf_hash)
@@ -1917,18 +1917,18 @@ static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion,
} else {
// Script path spending (stack size is >1 after removing optional annex)
const valtype& control = SpanPopBack(stack);
const valtype& script_bytes = SpanPopBack(stack);
exec_script = CScript(script_bytes.begin(), script_bytes.end());
const valtype& script = SpanPopBack(stack);
if (control.size() < TAPROOT_CONTROL_BASE_SIZE || control.size() > TAPROOT_CONTROL_MAX_SIZE || ((control.size() - TAPROOT_CONTROL_BASE_SIZE) % TAPROOT_CONTROL_NODE_SIZE) != 0) {
return set_error(serror, SCRIPT_ERR_TAPROOT_WRONG_CONTROL_SIZE);
}
execdata.m_tapleaf_hash = ComputeTapleafHash(control[0] & TAPROOT_LEAF_MASK, exec_script);
execdata.m_tapleaf_hash = ComputeTapleafHash(control[0] & TAPROOT_LEAF_MASK, script);
if (!VerifyTaprootCommitment(control, program, execdata.m_tapleaf_hash)) {
return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
}
execdata.m_tapleaf_hash_init = true;
if ((control[0] & TAPROOT_LEAF_MASK) == TAPROOT_LEAF_TAPSCRIPT) {
// Tapscript (leaf version 0xc0)
exec_script = CScript(script.begin(), script.end());
execdata.m_validation_weight_left = ::GetSerializeSize(witness.stack, PROTOCOL_VERSION) + VALIDATION_WEIGHT_OFFSET;
execdata.m_validation_weight_left_init = true;
return ExecuteWitnessScript(stack, exec_script, flags, SigVersion::TAPSCRIPT, checker, execdata, serror);