Skip to content

descriptor_string: crash due to resource limits #73

Description

@brunoerg

Descriptor:
"wsh(thresh(1,pk(xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U/840/94709400'),slnnnnnnnnnnnnnntvtvtvtvtvtvtvtvnn:0))".

Bitcoin Core successfully parses it but rust-miniscript returns the following error: "at least one spend path exceeds the resource limits". I noticed that rust-miniscript is throwing an "impossible satisfaction" error from:

fn check_local_consensus_validity<Pk: MiniscriptKey>(
    ms: &Miniscript<Pk, Self>,
) -> Result<(), ScriptContextError> {
    match ms.ext.ops.op_count() {
        None => Err(ScriptContextError::ImpossibleSatisfaction),
        Some(op_count) if op_count > MAX_OPS_PER_SCRIPT => {
            Err(ScriptContextError::MaxOpCountExceeded {
                actual: op_count,
                limit: MAX_OPS_PER_SCRIPT,
            })
        }
        _ => Ok(()),
    }
}

In the case of Bitcoin Core, CheckOpsLimit does not return false when it cannot get the maximum number of ops needed to satisfy the script because non-malleable satisfactions are guaranteed to be valid if ValidSatisfactions() (this function checks whether the node is valid at all, then check ops limit and stack size):

//! Check the ops limit of this script against the consensus limit.
bool CheckOpsLimit() const {
    if (IsTapscript(m_script_ctx)) return true;
    if (const auto ops = GetOps()) return *ops <= MAX_OPS_PER_SCRIPT;
    return true;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions