Skip to content

Commit 9c7bb5b

Browse files
committed
Refactor out type_check
1 parent fe8f040 commit 9c7bb5b

File tree

6 files changed

+176
-207
lines changed

6 files changed

+176
-207
lines changed

src/miniscript/astelem.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ use bitcoin::{absolute, opcodes, script, Sequence};
1515
use sync::Arc;
1616

1717
use crate::miniscript::context::SigType;
18-
use crate::miniscript::types::{self, Property};
19-
use crate::miniscript::ScriptContext;
18+
use crate::miniscript::{types, ScriptContext};
2019
use crate::prelude::*;
2120
use crate::util::MsKeyBuilder;
2221
use crate::{

src/miniscript/decode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use sync::Arc;
1717
use crate::miniscript::lex::{Token as Tk, TokenIter};
1818
use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG;
1919
use crate::miniscript::types::extra_props::ExtData;
20-
use crate::miniscript::types::{Property, Type};
20+
use crate::miniscript::types::Type;
2121
use crate::miniscript::ScriptContext;
2222
use crate::prelude::*;
2323
#[cfg(doc)]

src/miniscript/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ use core::cmp;
4040
use sync::Arc;
4141

4242
use self::lex::{lex, TokenIter};
43-
use self::types::Property;
4443
pub use crate::miniscript::context::ScriptContext;
4544
use crate::miniscript::decode::Terminal;
4645
use crate::miniscript::types::extra_props::ExtData;

src/miniscript/types/extra_props.rs

+3-13
Original file line numberDiff line numberDiff line change
@@ -856,22 +856,12 @@ impl Property for ExtData {
856856
exec_stack_elem_count_dissat,
857857
})
858858
}
859+
}
859860

860-
fn type_check_with_child<Pk, Ctx, C>(
861-
_fragment: &Terminal<Pk, Ctx>,
862-
mut _child: C,
863-
) -> Result<Self, Error<Pk, Ctx>>
864-
where
865-
C: FnMut(usize) -> Self,
866-
Pk: MiniscriptKey,
867-
Ctx: ScriptContext,
868-
{
869-
unreachable!()
870-
}
871-
861+
impl ExtData {
872862
/// Compute the type of a fragment assuming all the children of
873863
/// Miniscript have been computed already.
874-
fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Result<Self, Error<Pk, Ctx>>
864+
pub fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Result<Self, Error<Pk, Ctx>>
875865
where
876866
Ctx: ScriptContext,
877867
Pk: MiniscriptKey,

src/miniscript/types/mod.rs

+3-182
Original file line numberDiff line numberDiff line change
@@ -344,175 +344,6 @@ pub trait Property: Sized {
344344
fn threshold<S>(k: usize, n: usize, sub_ck: S) -> Result<Self, ErrorKind>
345345
where
346346
S: FnMut(usize) -> Result<Self, ErrorKind>;
347-
348-
/// Compute the type of a fragment, given a function to look up
349-
/// the types of its children, if available and relevant for the
350-
/// given fragment
351-
fn type_check_common<'a, Pk, Ctx, C>(
352-
fragment: &'a Terminal<Pk, Ctx>,
353-
mut get_child: C,
354-
) -> Result<Self, Error<Pk, Ctx>>
355-
where
356-
C: FnMut(&'a Terminal<Pk, Ctx>, usize) -> Result<Self, Error<Pk, Ctx>>,
357-
Pk: MiniscriptKey,
358-
Ctx: ScriptContext,
359-
{
360-
let wrap_err = |result: Result<Self, ErrorKind>| {
361-
result.map_err(|kind| Error { fragment: fragment.clone(), error: kind })
362-
};
363-
364-
let ret = match *fragment {
365-
Terminal::True => Ok(Self::from_true()),
366-
Terminal::False => Ok(Self::from_false()),
367-
Terminal::PkK(..) => Ok(Self::from_pk_k::<Ctx>()),
368-
Terminal::PkH(..) | Terminal::RawPkH(..) => Ok(Self::from_pk_h::<Ctx>()),
369-
Terminal::Multi(k, ref pks) | Terminal::MultiA(k, ref pks) => {
370-
if k == 0 {
371-
return Err(Error {
372-
fragment: fragment.clone(),
373-
error: ErrorKind::ZeroThreshold,
374-
});
375-
}
376-
if k > pks.len() {
377-
return Err(Error {
378-
fragment: fragment.clone(),
379-
error: ErrorKind::OverThreshold(k, pks.len()),
380-
});
381-
}
382-
match *fragment {
383-
Terminal::Multi(..) => Ok(Self::from_multi(k, pks.len())),
384-
Terminal::MultiA(..) => Ok(Self::from_multi_a(k, pks.len())),
385-
_ => unreachable!(),
386-
}
387-
}
388-
Terminal::After(t) => {
389-
// Note that for CLTV this is a limitation not of Bitcoin but Miniscript. The
390-
// number on the stack would be a 5 bytes signed integer but Miniscript's B type
391-
// only consumes 4 bytes from the stack.
392-
if t == absolute::LockTime::ZERO.into() {
393-
return Err(Error {
394-
fragment: fragment.clone(),
395-
error: ErrorKind::InvalidTime,
396-
});
397-
}
398-
Ok(Self::from_after(t.into()))
399-
}
400-
Terminal::Older(t) => {
401-
if t == Sequence::ZERO || !t.is_relative_lock_time() {
402-
return Err(Error {
403-
fragment: fragment.clone(),
404-
error: ErrorKind::InvalidTime,
405-
});
406-
}
407-
Ok(Self::from_older(t))
408-
}
409-
Terminal::Sha256(..) => Ok(Self::from_sha256()),
410-
Terminal::Hash256(..) => Ok(Self::from_hash256()),
411-
Terminal::Ripemd160(..) => Ok(Self::from_ripemd160()),
412-
Terminal::Hash160(..) => Ok(Self::from_hash160()),
413-
Terminal::Alt(ref sub) => wrap_err(Self::cast_alt(get_child(&sub.node, 0)?)),
414-
Terminal::Swap(ref sub) => wrap_err(Self::cast_swap(get_child(&sub.node, 0)?)),
415-
Terminal::Check(ref sub) => wrap_err(Self::cast_check(get_child(&sub.node, 0)?)),
416-
Terminal::DupIf(ref sub) => wrap_err(Self::cast_dupif(get_child(&sub.node, 0)?)),
417-
Terminal::Verify(ref sub) => wrap_err(Self::cast_verify(get_child(&sub.node, 0)?)),
418-
Terminal::NonZero(ref sub) => wrap_err(Self::cast_nonzero(get_child(&sub.node, 0)?)),
419-
Terminal::ZeroNotEqual(ref sub) => {
420-
wrap_err(Self::cast_zeronotequal(get_child(&sub.node, 0)?))
421-
}
422-
Terminal::AndB(ref l, ref r) => {
423-
let ltype = get_child(&l.node, 0)?;
424-
let rtype = get_child(&r.node, 1)?;
425-
wrap_err(Self::and_b(ltype, rtype))
426-
}
427-
Terminal::AndV(ref l, ref r) => {
428-
let ltype = get_child(&l.node, 0)?;
429-
let rtype = get_child(&r.node, 1)?;
430-
wrap_err(Self::and_v(ltype, rtype))
431-
}
432-
Terminal::OrB(ref l, ref r) => {
433-
let ltype = get_child(&l.node, 0)?;
434-
let rtype = get_child(&r.node, 1)?;
435-
wrap_err(Self::or_b(ltype, rtype))
436-
}
437-
Terminal::OrD(ref l, ref r) => {
438-
let ltype = get_child(&l.node, 0)?;
439-
let rtype = get_child(&r.node, 1)?;
440-
wrap_err(Self::or_d(ltype, rtype))
441-
}
442-
Terminal::OrC(ref l, ref r) => {
443-
let ltype = get_child(&l.node, 0)?;
444-
let rtype = get_child(&r.node, 1)?;
445-
wrap_err(Self::or_c(ltype, rtype))
446-
}
447-
Terminal::OrI(ref l, ref r) => {
448-
let ltype = get_child(&l.node, 0)?;
449-
let rtype = get_child(&r.node, 1)?;
450-
wrap_err(Self::or_i(ltype, rtype))
451-
}
452-
Terminal::AndOr(ref a, ref b, ref c) => {
453-
let atype = get_child(&a.node, 0)?;
454-
let btype = get_child(&b.node, 1)?;
455-
let ctype = get_child(&c.node, 2)?;
456-
wrap_err(Self::and_or(atype, btype, ctype))
457-
}
458-
Terminal::Thresh(k, ref subs) => {
459-
if k == 0 {
460-
return Err(Error {
461-
fragment: fragment.clone(),
462-
error: ErrorKind::ZeroThreshold,
463-
});
464-
}
465-
if k > subs.len() {
466-
return Err(Error {
467-
fragment: fragment.clone(),
468-
error: ErrorKind::OverThreshold(k, subs.len()),
469-
});
470-
}
471-
472-
let mut last_err_frag = None;
473-
let res = Self::threshold(k, subs.len(), |n| match get_child(&subs[n].node, n) {
474-
Ok(x) => Ok(x),
475-
Err(e) => {
476-
last_err_frag = Some(e.fragment);
477-
Err(e.error)
478-
}
479-
});
480-
481-
res.map_err(|kind| Error {
482-
fragment: last_err_frag.unwrap_or_else(|| fragment.clone()),
483-
error: kind,
484-
})
485-
}
486-
};
487-
if let Ok(ref ret) = ret {
488-
ret.sanity_checks()
489-
}
490-
ret
491-
}
492-
493-
/// Compute the type of a fragment, given a function to look up
494-
/// the types of its children.
495-
fn type_check_with_child<Pk, Ctx, C>(
496-
fragment: &Terminal<Pk, Ctx>,
497-
mut child: C,
498-
) -> Result<Self, Error<Pk, Ctx>>
499-
where
500-
C: FnMut(usize) -> Self,
501-
Pk: MiniscriptKey,
502-
Ctx: ScriptContext,
503-
{
504-
let get_child = |_sub, n| Ok(child(n));
505-
Self::type_check_common(fragment, get_child)
506-
}
507-
508-
/// Compute the type of a fragment.
509-
fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Result<Self, Error<Pk, Ctx>>
510-
where
511-
Pk: MiniscriptKey,
512-
Ctx: ScriptContext,
513-
{
514-
Self::type_check_common(fragment, |sub, _n| Self::type_check(sub))
515-
}
516347
}
517348

518349
impl Property for Type {
@@ -693,22 +524,12 @@ impl Property for Type {
693524
mall: Property::threshold(k, n, |n| Ok(sub_ck(n)?.mall))?,
694525
})
695526
}
527+
}
696528

697-
fn type_check_with_child<Pk, Ctx, C>(
698-
_fragment: &Terminal<Pk, Ctx>,
699-
mut _child: C,
700-
) -> Result<Self, Error<Pk, Ctx>>
701-
where
702-
C: FnMut(usize) -> Self,
703-
Pk: MiniscriptKey,
704-
Ctx: ScriptContext,
705-
{
706-
unreachable!()
707-
}
708-
529+
impl Type {
709530
/// Compute the type of a fragment assuming all the children of
710531
/// Miniscript have been computed already.
711-
fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Result<Self, Error<Pk, Ctx>>
532+
pub fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Result<Self, Error<Pk, Ctx>>
712533
where
713534
Pk: MiniscriptKey,
714535
Ctx: ScriptContext,

0 commit comments

Comments
 (0)