Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create the lift module #607

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion examples/htlc.rs
Original file line number Diff line number Diff line change
@@ -7,7 +7,8 @@ use std::str::FromStr;

use miniscript::bitcoin::Network;
use miniscript::descriptor::Wsh;
use miniscript::policy::{Concrete, Liftable};
use miniscript::lift::Lift;
use miniscript::policy::Concrete;

fn main() {
// HTLC policy with 10:1 odds for happy (co-operative) case compared to uncooperative case.
2 changes: 1 addition & 1 deletion fuzz/fuzz_targets/compile_descriptor.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::str::FromStr;

use honggfuzz::fuzz;
use miniscript::lift::Lift;
use miniscript::{policy, Miniscript, Segwitv0};
use policy::Liftable;

type Script = Miniscript<String, Segwitv0>;
type Policy = policy::Concrete<String>;
4 changes: 2 additions & 2 deletions fuzz/fuzz_targets/roundtrip_semantic.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use std::str::FromStr;

use honggfuzz::fuzz;
use miniscript::policy;
use miniscript::lift::lifted;

type Policy = policy::Semantic<String>;
type Policy = lifted::Policy<String>;

fn do_test(data: &[u8]) {
let data_str = String::from_utf8_lossy(data);
12 changes: 5 additions & 7 deletions src/descriptor/bare.rs
Original file line number Diff line number Diff line change
@@ -15,10 +15,10 @@ use bitcoin::{Address, Network, ScriptBuf};
use super::checksum::{self, verify_checksum};
use crate::descriptor::DefiniteDescriptorKey;
use crate::expression::{self, FromTree};
use crate::lift::{Lift, Lifted};
use crate::miniscript::context::{ScriptContext, ScriptContextError};
use crate::miniscript::satisfy::{Placeholder, Satisfaction, Witness};
use crate::plan::AssetProvider;
use crate::policy::{semantic, Liftable};
use crate::prelude::*;
use crate::util::{varint_len, witness_to_scriptsig};
use crate::{
@@ -164,8 +164,8 @@ impl<Pk: MiniscriptKey> fmt::Display for Bare<Pk> {
}
}

impl<Pk: MiniscriptKey> Liftable<Pk> for Bare<Pk> {
fn lift(&self) -> Result<semantic::Policy<Pk>, Error> { self.ms.lift() }
impl<Pk: MiniscriptKey> Lift<Pk> for Bare<Pk> {
fn lift(&self) -> Result<Lifted<Pk>, Error> { self.ms.lift() }
}

impl_from_tree!(
@@ -361,10 +361,8 @@ impl<Pk: MiniscriptKey> fmt::Display for Pkh<Pk> {
}
}

impl<Pk: MiniscriptKey> Liftable<Pk> for Pkh<Pk> {
fn lift(&self) -> Result<semantic::Policy<Pk>, Error> {
Ok(semantic::Policy::Key(self.pk.clone()))
}
impl<Pk: MiniscriptKey> Lift<Pk> for Pkh<Pk> {
fn lift(&self) -> Result<Lifted<Pk>, Error> { Ok(Lifted::Key(self.pk.clone())) }
}

impl_from_tree!(
12 changes: 5 additions & 7 deletions src/descriptor/segwitv0.rs
Original file line number Diff line number Diff line change
@@ -13,10 +13,10 @@ use super::checksum::{self, verify_checksum};
use super::SortedMultiVec;
use crate::descriptor::DefiniteDescriptorKey;
use crate::expression::{self, FromTree};
use crate::lift::{Lift, Lifted};
use crate::miniscript::context::{ScriptContext, ScriptContextError};
use crate::miniscript::satisfy::{Placeholder, Satisfaction, Witness};
use crate::plan::AssetProvider;
use crate::policy::{semantic, Liftable};
use crate::prelude::*;
use crate::util::varint_len;
use crate::{
@@ -219,8 +219,8 @@ pub enum WshInner<Pk: MiniscriptKey> {
Ms(Miniscript<Pk, Segwitv0>),
}

impl<Pk: MiniscriptKey> Liftable<Pk> for Wsh<Pk> {
fn lift(&self) -> Result<semantic::Policy<Pk>, Error> {
impl<Pk: MiniscriptKey> Lift<Pk> for Wsh<Pk> {
fn lift(&self) -> Result<Lifted<Pk>, Error> {
match self.inner {
WshInner::SortedMulti(ref smv) => smv.lift(),
WshInner::Ms(ref ms) => ms.lift(),
@@ -468,10 +468,8 @@ impl<Pk: MiniscriptKey> fmt::Display for Wpkh<Pk> {
}
}

impl<Pk: MiniscriptKey> Liftable<Pk> for Wpkh<Pk> {
fn lift(&self) -> Result<semantic::Policy<Pk>, Error> {
Ok(semantic::Policy::Key(self.pk.clone()))
}
impl<Pk: MiniscriptKey> Lift<Pk> for Wpkh<Pk> {
fn lift(&self) -> Result<Lifted<Pk>, Error> { Ok(Lifted::Key(self.pk.clone())) }
}

impl_from_tree!(
8 changes: 4 additions & 4 deletions src/descriptor/sh.rs
Original file line number Diff line number Diff line change
@@ -17,10 +17,10 @@ use super::checksum::{self, verify_checksum};
use super::{SortedMultiVec, Wpkh, Wsh};
use crate::descriptor::DefiniteDescriptorKey;
use crate::expression::{self, FromTree};
use crate::lift::{Lift, Lifted};
use crate::miniscript::context::ScriptContext;
use crate::miniscript::satisfy::{Placeholder, Satisfaction};
use crate::plan::AssetProvider;
use crate::policy::{semantic, Liftable};
use crate::prelude::*;
use crate::util::{varint_len, witness_to_scriptsig};
use crate::{
@@ -48,11 +48,11 @@ pub enum ShInner<Pk: MiniscriptKey> {
Ms(Miniscript<Pk, Legacy>),
}

impl<Pk: MiniscriptKey> Liftable<Pk> for Sh<Pk> {
fn lift(&self) -> Result<semantic::Policy<Pk>, Error> {
impl<Pk: MiniscriptKey> Lift<Pk> for Sh<Pk> {
fn lift(&self) -> Result<Lifted<Pk>, Error> {
match self.inner {
ShInner::Wsh(ref wsh) => wsh.lift(),
ShInner::Wpkh(ref pk) => Ok(semantic::Policy::Key(pk.as_inner().clone())),
ShInner::Wpkh(ref pk) => Ok(Lifted::Key(pk.as_inner().clone())),
ShInner::SortedMulti(ref smv) => smv.lift(),
ShInner::Ms(ref ms) => ms.lift(),
}
18 changes: 7 additions & 11 deletions src/descriptor/sortedmulti.rs
Original file line number Diff line number Diff line change
@@ -11,15 +11,16 @@ use core::str::FromStr;

use bitcoin::script;

use crate::lift::{Lift, Lifted};
use crate::miniscript::context::ScriptContext;
use crate::miniscript::decode::Terminal;
use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG;
use crate::miniscript::satisfy::{Placeholder, Satisfaction};
use crate::plan::AssetProvider;
use crate::prelude::*;
use crate::{
errstr, expression, policy, script_num_size, Error, ForEachKey, Miniscript, MiniscriptKey,
Satisfier, ToPublicKey, TranslateErr, Translator,
errstr, expression, script_num_size, Error, ForEachKey, Miniscript, MiniscriptKey, Satisfier,
ToPublicKey, TranslateErr, Translator,
};

/// Contents of a "sortedmulti" descriptor
@@ -195,15 +196,10 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
pub fn max_satisfaction_size(&self) -> usize { 1 + 73 * self.k }
}

impl<Pk: MiniscriptKey, Ctx: ScriptContext> policy::Liftable<Pk> for SortedMultiVec<Pk, Ctx> {
fn lift(&self) -> Result<policy::semantic::Policy<Pk>, Error> {
let ret = policy::semantic::Policy::Threshold(
self.k,
self.pks
.iter()
.map(|k| policy::semantic::Policy::Key(k.clone()))
.collect(),
);
impl<Pk: MiniscriptKey, Ctx: ScriptContext> Lift<Pk> for SortedMultiVec<Pk, Ctx> {
fn lift(&self) -> Result<Lifted<Pk>, Error> {
let ret =
Lifted::Threshold(self.k, self.pks.iter().map(|k| Lifted::Key(k.clone())).collect());
Ok(ret)
}
}
19 changes: 9 additions & 10 deletions src/descriptor/tr.rs
Original file line number Diff line number Diff line change
@@ -13,11 +13,10 @@ use sync::Arc;
use super::checksum::{self, verify_checksum};
use crate::descriptor::DefiniteDescriptorKey;
use crate::expression::{self, FromTree};
use crate::lift::{Lift, Lifted};
use crate::miniscript::satisfy::{Placeholder, Satisfaction, SchnorrSigType, Witness};
use crate::miniscript::Miniscript;
use crate::plan::AssetProvider;
use crate::policy::semantic::Policy;
use crate::policy::Liftable;
use crate::prelude::*;
use crate::util::{varint_len, witness_size};
use crate::{
@@ -616,12 +615,12 @@ fn split_once(inp: &str, delim: char) -> Option<(&str, &str)> {
}
}

impl<Pk: MiniscriptKey> Liftable<Pk> for TapTree<Pk> {
fn lift(&self) -> Result<Policy<Pk>, Error> {
fn lift_helper<Pk: MiniscriptKey>(s: &TapTree<Pk>) -> Result<Policy<Pk>, Error> {
impl<Pk: MiniscriptKey> Lift<Pk> for TapTree<Pk> {
fn lift(&self) -> Result<Lifted<Pk>, Error> {
fn lift_helper<Pk: MiniscriptKey>(s: &TapTree<Pk>) -> Result<Lifted<Pk>, Error> {
match *s {
TapTree::Tree { ref left, ref right, height: _ } => {
Ok(Policy::Threshold(1, vec![lift_helper(left)?, lift_helper(right)?]))
Ok(Lifted::Threshold(1, vec![lift_helper(left)?, lift_helper(right)?]))
}
TapTree::Leaf(ref leaf) => leaf.lift(),
}
@@ -632,13 +631,13 @@ impl<Pk: MiniscriptKey> Liftable<Pk> for TapTree<Pk> {
}
}

impl<Pk: MiniscriptKey> Liftable<Pk> for Tr<Pk> {
fn lift(&self) -> Result<Policy<Pk>, Error> {
impl<Pk: MiniscriptKey> Lift<Pk> for Tr<Pk> {
fn lift(&self) -> Result<Lifted<Pk>, Error> {
match &self.tree {
Some(root) => {
Ok(Policy::Threshold(1, vec![Policy::Key(self.internal_key.clone()), root.lift()?]))
Ok(Lifted::Threshold(1, vec![Lifted::Key(self.internal_key.clone()), root.lift()?]))
}
None => Ok(Policy::Key(self.internal_key.clone())),
None => Ok(Lifted::Key(self.internal_key.clone())),
}
}
}
7 changes: 4 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -122,6 +122,7 @@ pub mod descriptor;
pub mod expression;
pub mod interpreter;
pub mod iter;
pub mod lift;
pub mod miniscript;
pub mod plan;
pub mod policy;
@@ -474,7 +475,7 @@ pub enum Error {
/// Errors related to policy
PolicyError(policy::concrete::PolicyError),
/// Errors related to lifting
LiftError(policy::LiftError),
LiftError(lift::LiftError),
/// Forward script context related errors
ContextError(miniscript::context::ScriptContextError),
/// Recursion depth exceeded when parsing policy/miniscript from string
@@ -644,8 +645,8 @@ where
}

#[doc(hidden)]
impl From<policy::LiftError> for Error {
fn from(e: policy::LiftError) -> Error { Error::LiftError(e) }
impl From<lift::LiftError> for Error {
fn from(e: lift::LiftError) -> Error { Error::LiftError(e) }
}

#[doc(hidden)]
10 changes: 5 additions & 5 deletions src/policy/semantic.rs → src/lift/lifted.rs
Original file line number Diff line number Diff line change
@@ -10,8 +10,8 @@ use core::{fmt, str};

use bitcoin::{absolute, Sequence};

use super::concrete::PolicyError;
use super::ENTAILMENT_MAX_TERMINALS;
use crate::lift::ENTAILMENT_MAX_TERMINALS;
use crate::policy::concrete::PolicyError;
use crate::prelude::*;
use crate::{errstr, expression, AbsLockTime, Error, ForEachKey, MiniscriptKey, Translator};

@@ -93,10 +93,10 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
/// use std::collections::HashMap;
/// use std::str::FromStr;
/// use miniscript::bitcoin::{hashes::hash160, PublicKey};
/// use miniscript::{translate_hash_fail, policy::semantic::Policy, Translator};
/// use miniscript::{translate_hash_fail, lift::Lifted, Translator};
/// let alice_pk = "02c79ef3ede6d14f72a00d0e49b4becfb152197b64c0707425c4f231df29500ee7";
/// let bob_pk = "03d008a849fbf474bd17e9d2c1a827077a468150e58221582ec3410ab309f5afe4";
/// let placeholder_policy = Policy::<String>::from_str("and(pk(alice_pk),pk(bob_pk))").unwrap();
/// let placeholder_policy = Lifted::<String>::from_str("and(pk(alice_pk),pk(bob_pk))").unwrap();
///
/// // Information to translate abstract string type keys to concrete `bitcoin::PublicKey`s.
/// // In practice, wallets would map from string key names to BIP32 keys.
@@ -123,7 +123,7 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
///
/// let real_policy = placeholder_policy.translate_pk(&mut t).unwrap();
///
/// let expected_policy = Policy::from_str(&format!("and(pk({}),pk({}))", alice_pk, bob_pk)).unwrap();
/// let expected_policy = Lifted::from_str(&format!("and(pk({}),pk({}))", alice_pk, bob_pk)).unwrap();
/// assert_eq!(real_policy, expected_policy);
/// ```
pub fn translate_pk<Q, E, T>(&self, t: &mut T) -> Result<Policy<Q>, E>
Loading