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

Inline descriptor inner types #587

Closed
wants to merge 2 commits into from
Closed
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
4 changes: 2 additions & 2 deletions bitcoind-tests/tests/test_cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,8 @@ pub fn test_from_cpp_ms(cl: &Client, testdata: &TestData) {
for i in 0..psbts.len() {
let wsh_derived = desc_vec[i].derived_descriptor(&secp).unwrap();
let ms = if let Descriptor::Wsh(wsh) = &wsh_derived {
match wsh.as_inner() {
miniscript::descriptor::WshInner::Ms(ms) => ms,
match wsh {
miniscript::descriptor::Wsh::Ms(ms) => ms,
_ => unreachable!(),
}
} else {
Expand Down
20 changes: 10 additions & 10 deletions bitcoind-tests/tests/test_desc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,29 +215,29 @@ pub fn test_desc_satisfy(
Descriptor::Bare(bare) => find_sks_ms(&bare.as_inner(), testdata),
Descriptor::Pkh(pk) => find_sk_single_key(*pk.as_inner(), testdata),
Descriptor::Wpkh(pk) => find_sk_single_key(*pk.as_inner(), testdata),
Descriptor::Sh(sh) => match sh.as_inner() {
miniscript::descriptor::ShInner::Wsh(wsh) => match wsh.as_inner() {
miniscript::descriptor::WshInner::SortedMulti(ref smv) => {
Descriptor::Sh(sh) => match sh {
miniscript::descriptor::Sh::Wsh(wsh) => match wsh {
miniscript::descriptor::Wsh::SortedMulti(ref smv) => {
let ms = Miniscript::from_ast(smv.sorted_node()).unwrap();
find_sks_ms(&ms, testdata)
}
miniscript::descriptor::WshInner::Ms(ref ms) => find_sks_ms(&ms, testdata),
miniscript::descriptor::Wsh::Ms(ref ms) => find_sks_ms(&ms, testdata),
},
miniscript::descriptor::ShInner::Wpkh(pk) => {
miniscript::descriptor::Sh::Wpkh(pk) => {
find_sk_single_key(*pk.as_inner(), testdata)
}
miniscript::descriptor::ShInner::SortedMulti(smv) => {
miniscript::descriptor::Sh::SortedMulti(smv) => {
let ms = Miniscript::from_ast(smv.sorted_node()).unwrap();
find_sks_ms(&ms, testdata)
}
miniscript::descriptor::ShInner::Ms(ms) => find_sks_ms(&ms, testdata),
miniscript::descriptor::Sh::Ms(ms) => find_sks_ms(&ms, testdata),
},
Descriptor::Wsh(wsh) => match wsh.as_inner() {
miniscript::descriptor::WshInner::SortedMulti(ref smv) => {
Descriptor::Wsh(wsh) => match wsh {
miniscript::descriptor::Wsh::SortedMulti(ref smv) => {
let ms = Miniscript::from_ast(smv.sorted_node()).unwrap();
find_sks_ms(&ms, testdata)
}
miniscript::descriptor::WshInner::Ms(ref ms) => find_sks_ms(&ms, testdata),
miniscript::descriptor::Wsh::Ms(ref ms) => find_sks_ms(&ms, testdata),
},
Descriptor::Tr(_tr) => unreachable!("Tr checked earlier"),
};
Expand Down
24 changes: 12 additions & 12 deletions src/descriptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ mod tr;

// Descriptor Exports
pub use self::bare::{Bare, Pkh};
pub use self::segwitv0::{Wpkh, Wsh, WshInner};
pub use self::sh::{Sh, ShInner};
pub use self::segwitv0::{Wpkh, Wsh};
pub use self::sh::Sh;
pub use self::sortedmulti::SortedMultiVec;
pub use self::tr::{TapTree, Tr};

Expand Down Expand Up @@ -246,18 +246,18 @@ impl<Pk: MiniscriptKey> Descriptor<Pk> {
Descriptor::Bare(ref _bare) => DescriptorType::Bare,
Descriptor::Pkh(ref _pkh) => DescriptorType::Pkh,
Descriptor::Wpkh(ref _wpkh) => DescriptorType::Wpkh,
Descriptor::Sh(ref sh) => match sh.as_inner() {
ShInner::Wsh(ref wsh) => match wsh.as_inner() {
WshInner::SortedMulti(ref _smv) => DescriptorType::ShWshSortedMulti,
WshInner::Ms(ref _ms) => DescriptorType::ShWsh,
Descriptor::Sh(ref sh) => match sh {
Sh::Wsh(ref wsh) => match wsh {
Wsh::SortedMulti(ref _smv) => DescriptorType::ShWshSortedMulti,
Wsh::Ms(ref _ms) => DescriptorType::ShWsh,
},
ShInner::Wpkh(ref _wpkh) => DescriptorType::ShWpkh,
ShInner::SortedMulti(ref _smv) => DescriptorType::ShSortedMulti,
ShInner::Ms(ref _ms) => DescriptorType::Sh,
Sh::Wpkh(ref _wpkh) => DescriptorType::ShWpkh,
Sh::SortedMulti(ref _smv) => DescriptorType::ShSortedMulti,
Sh::Ms(ref _ms) => DescriptorType::Sh,
},
Descriptor::Wsh(ref wsh) => match wsh.as_inner() {
WshInner::SortedMulti(ref _smv) => DescriptorType::WshSortedMulti,
WshInner::Ms(ref _ms) => DescriptorType::Wsh,
Descriptor::Wsh(ref wsh) => match wsh {
Wsh::SortedMulti(ref _smv) => DescriptorType::WshSortedMulti,
Wsh::Ms(ref _ms) => DescriptorType::Wsh,
},
Descriptor::Tr(ref _tr) => DescriptorType::Tr,
}
Expand Down
118 changes: 53 additions & 65 deletions src/descriptor/segwitv0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,32 +23,29 @@ use crate::{
Error, ForEachKey, Miniscript, MiniscriptKey, Satisfier, Segwitv0, ToPublicKey, TranslateErr,
TranslatePk, Translator,
};

/// A Segwitv0 wsh descriptor
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub struct Wsh<Pk: MiniscriptKey> {
/// underlying miniscript
inner: WshInner<Pk>,
pub enum Wsh<Pk: MiniscriptKey> {
/// Sorted Multi
SortedMulti(SortedMultiVec<Pk, Segwitv0>),
/// Wsh Miniscript
Ms(Miniscript<Pk, Segwitv0>),
}

impl<Pk: MiniscriptKey> Wsh<Pk> {
/// Get the Inner
pub fn into_inner(self) -> WshInner<Pk> { self.inner }

/// Get a reference to inner
pub fn as_inner(&self) -> &WshInner<Pk> { &self.inner }

/// Create a new wsh descriptor
pub fn new(ms: Miniscript<Pk, Segwitv0>) -> Result<Self, Error> {
// do the top-level checks
Segwitv0::top_level_checks(&ms)?;
Ok(Self { inner: WshInner::Ms(ms) })
Ok(Self::Ms(ms))
}

/// Create a new sortedmulti wsh descriptor
pub fn new_sortedmulti(k: usize, pks: Vec<Pk>) -> Result<Self, Error> {
// The context checks will be carried out inside new function for
// sortedMultiVec
Ok(Self { inner: WshInner::SortedMulti(SortedMultiVec::new(k, pks)?) })
Ok(Self::SortedMulti(SortedMultiVec::new(k, pks)?))
}

/// Get the descriptor without the checksum
Expand All @@ -57,9 +54,9 @@ impl<Pk: MiniscriptKey> Wsh<Pk> {

/// Checks whether the descriptor is safe.
pub fn sanity_check(&self) -> Result<(), Error> {
match self.inner {
WshInner::SortedMulti(ref smv) => smv.sanity_check()?,
WshInner::Ms(ref ms) => ms.sanity_check()?,
match *self {
Wsh::SortedMulti(ref smv) => smv.sanity_check()?,
Wsh::Ms(ref ms) => ms.sanity_check()?,
}
Ok(())
}
Expand All @@ -73,13 +70,13 @@ impl<Pk: MiniscriptKey> Wsh<Pk> {
/// # Errors
/// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
pub fn max_weight_to_satisfy(&self) -> Result<usize, Error> {
let (redeem_script_size, max_sat_elems, max_sat_size) = match self.inner {
WshInner::SortedMulti(ref smv) => (
let (redeem_script_size, max_sat_elems, max_sat_size) = match *self {
Wsh::SortedMulti(ref smv) => (
smv.script_size(),
smv.max_satisfaction_witness_elements(),
smv.max_satisfaction_size(),
),
WshInner::Ms(ref ms) => (
Wsh::Ms(ref ms) => (
ms.script_size(),
ms.max_satisfaction_witness_elements()?,
ms.max_satisfaction_size()?,
Expand All @@ -103,13 +100,13 @@ impl<Pk: MiniscriptKey> Wsh<Pk> {
/// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
#[deprecated(note = "use max_weight_to_satisfy instead")]
pub fn max_satisfaction_weight(&self) -> Result<usize, Error> {
let (script_size, max_sat_elems, max_sat_size) = match self.inner {
WshInner::SortedMulti(ref smv) => (
let (script_size, max_sat_elems, max_sat_size) = match *self {
Wsh::SortedMulti(ref smv) => (
smv.script_size(),
smv.max_satisfaction_witness_elements(),
smv.max_satisfaction_size(),
),
WshInner::Ms(ref ms) => (
Wsh::Ms(ref ms) => (
ms.script_size(),
ms.max_satisfaction_witness_elements()?,
ms.max_satisfaction_size()?,
Expand All @@ -129,17 +126,17 @@ impl<Pk: MiniscriptKey + ToPublicKey> Wsh<Pk> {

/// Obtains the corresponding script pubkey for this descriptor.
pub fn address(&self, network: Network) -> Address {
match self.inner {
WshInner::SortedMulti(ref smv) => Address::p2wsh(&smv.encode(), network),
WshInner::Ms(ref ms) => Address::p2wsh(&ms.encode(), network),
match *self {
Wsh::SortedMulti(ref smv) => Address::p2wsh(&smv.encode(), network),
Wsh::Ms(ref ms) => Address::p2wsh(&ms.encode(), network),
}
}

/// Obtains the underlying miniscript for this descriptor.
pub fn inner_script(&self) -> ScriptBuf {
match self.inner {
WshInner::SortedMulti(ref smv) => smv.encode(),
WshInner::Ms(ref ms) => ms.encode(),
match *self {
Wsh::SortedMulti(ref smv) => smv.encode(),
Wsh::Ms(ref ms) => ms.encode(),
}
}

Expand All @@ -153,9 +150,9 @@ impl<Pk: MiniscriptKey + ToPublicKey> Wsh<Pk> {
where
S: Satisfier<Pk>,
{
let mut witness = match self.inner {
WshInner::SortedMulti(ref smv) => smv.satisfy(satisfier)?,
WshInner::Ms(ref ms) => ms.satisfy(satisfier)?,
let mut witness = match *self {
Wsh::SortedMulti(ref smv) => smv.satisfy(satisfier)?,
Wsh::Ms(ref ms) => ms.satisfy(satisfier)?,
};
let witness_script = self.inner_script();
witness.push(witness_script.into_bytes());
Expand All @@ -170,9 +167,9 @@ impl<Pk: MiniscriptKey + ToPublicKey> Wsh<Pk> {
where
S: Satisfier<Pk>,
{
let mut witness = match self.inner {
WshInner::SortedMulti(ref smv) => smv.satisfy(satisfier)?,
WshInner::Ms(ref ms) => ms.satisfy_malleable(satisfier)?,
let mut witness = match *self {
Wsh::SortedMulti(ref smv) => smv.satisfy(satisfier)?,
Wsh::Ms(ref ms) => ms.satisfy_malleable(satisfier)?,
};
witness.push(self.inner_script().into_bytes());
let script_sig = ScriptBuf::new();
Expand All @@ -189,9 +186,9 @@ impl Wsh<DefiniteDescriptorKey> {
where
P: AssetProvider<DefiniteDescriptorKey>,
{
match &self.inner {
WshInner::SortedMulti(sm) => sm.build_template(provider),
WshInner::Ms(ms) => ms.build_template(provider),
match *self {
Wsh::SortedMulti(ref sm) => sm.build_template(provider),
Wsh::Ms(ref ms) => ms.build_template(provider),
}
}

Expand All @@ -203,27 +200,18 @@ impl Wsh<DefiniteDescriptorKey> {
where
P: AssetProvider<DefiniteDescriptorKey>,
{
match &self.inner {
WshInner::SortedMulti(sm) => sm.build_template(provider),
WshInner::Ms(ms) => ms.build_template_mall(provider),
match *self {
Wsh::SortedMulti(ref sm) => sm.build_template(provider),
Wsh::Ms(ref ms) => ms.build_template_mall(provider),
}
}
}

/// Wsh Inner
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
pub enum WshInner<Pk: MiniscriptKey> {
/// Sorted Multi
SortedMulti(SortedMultiVec<Pk, Segwitv0>),
/// Wsh Miniscript
Ms(Miniscript<Pk, Segwitv0>),
}

impl<Pk: MiniscriptKey> Liftable<Pk> for Wsh<Pk> {
fn lift(&self) -> Result<semantic::Policy<Pk>, Error> {
match self.inner {
WshInner::SortedMulti(ref smv) => smv.lift(),
WshInner::Ms(ref ms) => ms.lift(),
match *self {
Wsh::SortedMulti(ref smv) => smv.lift(),
Wsh::Ms(ref ms) => ms.lift(),
}
}
}
Expand All @@ -234,11 +222,11 @@ impl_from_tree!(
if top.name == "wsh" && top.args.len() == 1 {
let top = &top.args[0];
if top.name == "sortedmulti" {
return Ok(Wsh { inner: WshInner::SortedMulti(SortedMultiVec::from_tree(top)?) });
return Ok(Wsh::SortedMulti(SortedMultiVec::from_tree(top)?));
}
let sub = Miniscript::from_tree(top)?;
Segwitv0::top_level_checks(&sub)?;
Ok(Wsh { inner: WshInner::Ms(sub) })
Ok(Wsh::Ms(sub))
} else {
Err(Error::Unexpected(format!(
"{}({} args) while parsing wsh descriptor",
Expand All @@ -251,9 +239,9 @@ impl_from_tree!(

impl<Pk: MiniscriptKey> fmt::Debug for Wsh<Pk> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.inner {
WshInner::SortedMulti(ref smv) => write!(f, "wsh({:?})", smv),
WshInner::Ms(ref ms) => write!(f, "wsh({:?})", ms),
match *self {
Wsh::SortedMulti(ref smv) => write!(f, "wsh({:?})", smv),
Wsh::Ms(ref ms) => write!(f, "wsh({:?})", ms),
}
}
}
Expand All @@ -262,9 +250,9 @@ impl<Pk: MiniscriptKey> fmt::Display for Wsh<Pk> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
use fmt::Write;
let mut wrapped_f = checksum::Formatter::new(f);
match self.inner {
WshInner::SortedMulti(ref smv) => write!(wrapped_f, "wsh({})", smv)?,
WshInner::Ms(ref ms) => write!(wrapped_f, "wsh({})", ms)?,
match *self {
Wsh::SortedMulti(ref smv) => write!(wrapped_f, "wsh({})", smv)?,
Wsh::Ms(ref ms) => write!(wrapped_f, "wsh({})", ms)?,
}
wrapped_f.write_checksum_if_not_alt()
}
Expand All @@ -282,9 +270,9 @@ impl_from_str!(

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Wsh<Pk> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
match self.inner {
WshInner::SortedMulti(ref smv) => smv.for_each_key(pred),
WshInner::Ms(ref ms) => ms.for_each_key(pred),
match *self {
Wsh::SortedMulti(ref smv) => smv.for_each_key(pred),
Wsh::Ms(ref ms) => ms.for_each_key(pred),
}
}
}
Expand All @@ -300,11 +288,11 @@ where
where
T: Translator<P, Q, E>,
{
let inner = match self.inner {
WshInner::SortedMulti(ref smv) => WshInner::SortedMulti(smv.translate_pk(t)?),
WshInner::Ms(ref ms) => WshInner::Ms(ms.translate_pk(t)?),
let wsh = match *self {
Wsh::SortedMulti(ref smv) => Wsh::SortedMulti(smv.translate_pk(t)?),
Wsh::Ms(ref ms) => Wsh::Ms(ms.translate_pk(t)?),
};
Ok(Wsh { inner })
Ok(wsh)
}
}

Expand Down
Loading
Loading