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
Show file tree
Hide file tree
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
Expand Up @@ -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.
Expand Down
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>;
Expand Down
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);
Expand Down
12 changes: 5 additions & 7 deletions src/descriptor/bare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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!(
Expand Down Expand Up @@ -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!(
Expand Down
12 changes: 5 additions & 7 deletions src/descriptor/segwitv0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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(),
Expand Down Expand Up @@ -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!(
Expand Down
8 changes: 4 additions & 4 deletions src/descriptor/sh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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(),
}
Expand Down
18 changes: 7 additions & 11 deletions src/descriptor/sortedmulti.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
}
Expand Down
19 changes: 9 additions & 10 deletions src/descriptor/tr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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(),
}
Expand All @@ -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())),
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)]
Expand Down
10 changes: 5 additions & 5 deletions src/policy/semantic.rs → src/lift/lifted.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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.
Expand All @@ -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>
Expand Down
Loading