Skip to content

Descriptors parsing checks #128

Description

@darosior

I was previously reluctant to do parsing checks on the descriptors as it's harder to get the semantics right than when compiling the policy. But the compile-time checks don't achieve much, and we can already check a number of things without much semantics (like the maximum number of keys, check for duplicates).

Also, we already analyze the Unvault descriptor semantic with success to get the threshold, so why not for parsing checks?

revault_tx/src/scripts.rs

Lines 510 to 560 in 4bddb1d

fn unvault_descriptor_managers_threshold<Pk: MiniscriptKey>(
desc: &Descriptor<Pk>,
) -> Option<usize> {
let ms = match &desc {
Descriptor::Wsh(ref wsh) => match wsh.as_inner() {
WshInner::Ms(ms) => ms,
WshInner::SortedMulti(_) => unreachable!("Unvault descriptor is not a sorted multi"),
},
_ => unreachable!("Unvault descriptor is always a P2WSH"),
};
let policy = ms
.lift()
.expect("Lifting can't fail on a Miniscript")
.normalized();
// The Unvault descriptor is always of the form 'or(mans_branch, stks_branch)'
match policy {
SemanticPolicy::Threshold(1, ref subs) => {
assert_eq!(subs.len(), 2);
// The 'mans_branch' can be identified as the one containing the CSV. It is always an
// 'and()' of CSV + Managers (the latter being potentially a thresh) and optionally
// along with Cosigning Servers
for sub in subs {
match sub {
SemanticPolicy::Threshold(k, ref subs)
if k == &subs.len()
&& subs
.iter()
.any(|sub| matches!(sub, SemanticPolicy::Older(..))) =>
{
// Now, the mans are either a Threshold or directly pks (in the case the
// thresh is an 'and()', pks are flattened in the upper 'and()').
return subs.iter().find_map(|sub| match sub {
SemanticPolicy::Threshold(k, _) => Some(*k),
_ => None,
});
}
_ => continue,
}
}
unreachable!(
"Given an Unvault descriptor which doesn't contain a second-to-top \
branch with a CSV"
);
}
_ => unreachable!("Given an Unvault descriptor that doesn't contain a 'or()' at the root"),
}
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions