Skip to content

Commit 393bbd1

Browse files
committed
compiler: replace AstElemExt::terminal with explicit functions
There is a ton of over-abstraction in AstElemeExt. Our original goal was to save on code by having one function, AstElemExt::type_check_common, which would match on a Terminal and do all the "fragment-specific" logic. But the consequence is that this needs to be really general to handle all the data that each fragment might need. In particular, disjunctions need "weights" which are provided by the user to indicate which branches are likely to be taken. No other kind of astelem needs extra data, but all the wrappers need infrastructure to carry this stuff around. By eliminating the terminal() function in place of direct constructors for each terminal type, we simplify the code and are able to also get rid of the type_check function. The next commits will eventually get rid of type_check_common, the branch_prob field of AstElemExt, a bunch of mutability and unwrap paths, and possibly more.
1 parent 87b04a0 commit 393bbd1

1 file changed

Lines changed: 77 additions & 35 deletions

File tree

src/policy/compiler.rs

Lines changed: 77 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use std::error;
1212
use sync::Arc;
1313

1414
use crate::miniscript::context::SigType;
15+
use crate::miniscript::limits::{MAX_PUBKEYS_IN_CHECKSIGADD, MAX_PUBKEYS_PER_MULTISIG};
1516
use crate::miniscript::types::{self, ErrorKind, ExtData, Type};
1617
use crate::miniscript::ScriptContext;
1718
use crate::policy::Concrete;
@@ -194,7 +195,7 @@ impl CompilerExtData {
194195
}
195196
}
196197

197-
fn multi(k: usize, _n: usize) -> Self {
198+
fn multi(k: usize) -> Self {
198199
Self {
199200
branch_prob: None,
200201
sat_cost: 1.0 + 73.0 * k as f64,
@@ -398,16 +399,6 @@ impl CompilerExtData {
398399
Self::type_check_common(fragment, get_child)
399400
}
400401

401-
/// Compute the type of a fragment.
402-
fn type_check<Pk, Ctx>(fragment: &Terminal<Pk, Ctx>) -> Self
403-
where
404-
Pk: MiniscriptKey,
405-
Ctx: ScriptContext,
406-
{
407-
let check_child = |sub, _n| Self::type_check(sub);
408-
Self::type_check_common(fragment, check_child)
409-
}
410-
411402
/// Compute the type of a fragment, given a function to look up
412403
/// the types of its children, if available and relevant for the
413404
/// given fragment
@@ -422,7 +413,7 @@ impl CompilerExtData {
422413
Terminal::False => Self::FALSE,
423414
Terminal::PkK(..) => Self::pk_k::<Ctx>(),
424415
Terminal::PkH(..) | Terminal::RawPkH(..) => Self::pk_h::<Ctx>(),
425-
Terminal::Multi(ref thresh) => Self::multi(thresh.k(), thresh.n()),
416+
Terminal::Multi(ref thresh) => Self::multi(thresh.k()),
426417
Terminal::SortedMulti(ref thresh) => Self::sortedmulti(thresh.k(), thresh.n()),
427418
Terminal::MultiA(ref thresh) => Self::multi_a(thresh.k(), thresh.n()),
428419
Terminal::SortedMultiA(ref thresh) => Self::sortedmulti_a(thresh.k(), thresh.n()),
@@ -508,8 +499,67 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> AstElemExt<Pk, Ctx> {
508499
}
509500

510501
impl<Pk: MiniscriptKey, Ctx: ScriptContext> AstElemExt<Pk, Ctx> {
511-
fn terminal(ms: Miniscript<Pk, Ctx>) -> Self {
512-
Self { comp_ext_data: CompilerExtData::type_check(ms.as_inner()), ms: Arc::new(ms) }
502+
fn unsatisfiable() -> Self {
503+
Self { ms: Arc::new(Miniscript::FALSE), comp_ext_data: CompilerExtData::FALSE }
504+
}
505+
506+
fn trivial() -> Self {
507+
Self { ms: Arc::new(Miniscript::TRUE), comp_ext_data: CompilerExtData::TRUE }
508+
}
509+
510+
fn pk_h(key: Pk) -> Self {
511+
Self {
512+
ms: Arc::new(Miniscript::pk_h(key)),
513+
comp_ext_data: CompilerExtData::pk_h::<Ctx>(),
514+
}
515+
}
516+
517+
fn pk_k(key: Pk) -> Self {
518+
Self {
519+
ms: Arc::new(Miniscript::pk_k(key)),
520+
comp_ext_data: CompilerExtData::pk_k::<Ctx>(),
521+
}
522+
}
523+
524+
fn after(t: crate::AbsLockTime) -> Self {
525+
Self { ms: Arc::new(Miniscript::after(t)), comp_ext_data: CompilerExtData::time() }
526+
}
527+
528+
fn older(t: crate::RelLockTime) -> Self {
529+
Self { ms: Arc::new(Miniscript::older(t)), comp_ext_data: CompilerExtData::time() }
530+
}
531+
532+
fn sha256(h: Pk::Sha256) -> Self {
533+
Self { ms: Arc::new(Miniscript::sha256(h)), comp_ext_data: CompilerExtData::hash() }
534+
}
535+
536+
fn hash256(h: Pk::Hash256) -> Self {
537+
Self { ms: Arc::new(Miniscript::hash256(h)), comp_ext_data: CompilerExtData::hash() }
538+
}
539+
540+
fn ripemd160(h: Pk::Ripemd160) -> Self {
541+
Self { ms: Arc::new(Miniscript::ripemd160(h)), comp_ext_data: CompilerExtData::hash() }
542+
}
543+
544+
fn hash160(h: Pk::Hash160) -> Self {
545+
Self { ms: Arc::new(Miniscript::hash160(h)), comp_ext_data: CompilerExtData::hash() }
546+
}
547+
548+
fn multi(thresh: crate::Threshold<Pk, MAX_PUBKEYS_PER_MULTISIG>) -> Self {
549+
let k = thresh.k();
550+
Self {
551+
ms: Arc::new(Miniscript::multi(thresh)),
552+
comp_ext_data: CompilerExtData::multi(k),
553+
}
554+
}
555+
556+
fn multi_a(thresh: crate::Threshold<Pk, MAX_PUBKEYS_IN_CHECKSIGADD>) -> Self {
557+
let k = thresh.k();
558+
let n = thresh.n();
559+
Self {
560+
ms: Arc::new(Miniscript::multi_a(thresh)),
561+
comp_ext_data: CompilerExtData::multi_a(k, n),
562+
}
513563
}
514564

515565
fn binary(ast: Terminal<Pk, Ctx>, l: &Self, r: &Self) -> Result<Self, types::Error> {
@@ -793,30 +843,22 @@ where
793843

794844
match *policy {
795845
Concrete::Unsatisfiable => {
796-
insert_wrap!(AstElemExt::terminal(Miniscript::FALSE));
846+
insert_wrap!(AstElemExt::unsatisfiable());
797847
}
798848
Concrete::Trivial => {
799-
insert_wrap!(AstElemExt::terminal(Miniscript::TRUE));
849+
insert_wrap!(AstElemExt::trivial());
800850
}
801851
Concrete::Key(ref pk) => {
802-
insert_wrap!(AstElemExt::terminal(Miniscript::pk_h(pk.clone())));
803-
insert_wrap!(AstElemExt::terminal(Miniscript::pk_k(pk.clone())));
804-
}
805-
Concrete::After(n) => insert_wrap!(AstElemExt::terminal(Miniscript::after(n))),
806-
Concrete::Older(n) => insert_wrap!(AstElemExt::terminal(Miniscript::older(n))),
807-
Concrete::Sha256(ref hash) => {
808-
insert_wrap!(AstElemExt::terminal(Miniscript::sha256(hash.clone())))
852+
insert_wrap!(AstElemExt::pk_h(pk.clone()));
853+
insert_wrap!(AstElemExt::pk_k(pk.clone()));
809854
}
855+
Concrete::After(n) => insert_wrap!(AstElemExt::after(n)),
856+
Concrete::Older(n) => insert_wrap!(AstElemExt::older(n)),
857+
Concrete::Sha256(ref hash) => insert_wrap!(AstElemExt::sha256(hash.clone())),
810858
// Satisfaction-cost + script-cost
811-
Concrete::Hash256(ref hash) => {
812-
insert_wrap!(AstElemExt::terminal(Miniscript::hash256(hash.clone())))
813-
}
814-
Concrete::Ripemd160(ref hash) => {
815-
insert_wrap!(AstElemExt::terminal(Miniscript::ripemd160(hash.clone())))
816-
}
817-
Concrete::Hash160(ref hash) => {
818-
insert_wrap!(AstElemExt::terminal(Miniscript::hash160(hash.clone())))
819-
}
859+
Concrete::Hash256(ref hash) => insert_wrap!(AstElemExt::hash256(hash.clone())),
860+
Concrete::Ripemd160(ref hash) => insert_wrap!(AstElemExt::ripemd160(hash.clone())),
861+
Concrete::Hash160(ref hash) => insert_wrap!(AstElemExt::hash160(hash.clone())),
820862
Concrete::And(ref subs) => {
821863
assert_eq!(subs.len(), 2, "and takes 2 args");
822864
let mut left =
@@ -835,7 +877,7 @@ where
835877
let mut zero_comp = BTreeMap::new();
836878
zero_comp.insert(
837879
CompilationKey::from_type(Type::FALSE, ExtData::FALSE.has_free_verify, dissat_prob),
838-
AstElemExt::terminal(Miniscript::FALSE),
880+
AstElemExt::unsatisfiable(),
839881
);
840882
compile_tern!(&mut left, &mut q_zero_right, &mut zero_comp, [1.0, 0.0]);
841883
compile_tern!(&mut right, &mut q_zero_left, &mut zero_comp, [1.0, 0.0]);
@@ -1022,12 +1064,12 @@ where
10221064
match Ctx::sig_type() {
10231065
SigType::Schnorr => {
10241066
if let Ok(pk_thresh) = pk_thresh.set_maximum() {
1025-
insert_wrap!(AstElemExt::terminal(Miniscript::multi_a(pk_thresh)))
1067+
insert_wrap!(AstElemExt::multi_a(pk_thresh))
10261068
}
10271069
}
10281070
SigType::Ecdsa => {
10291071
if let Ok(pk_thresh) = pk_thresh.set_maximum() {
1030-
insert_wrap!(AstElemExt::terminal(Miniscript::multi(pk_thresh)))
1072+
insert_wrap!(AstElemExt::multi(pk_thresh))
10311073
}
10321074
}
10331075
}

0 commit comments

Comments
 (0)