From c4d195733b0d6bc68bf58319cc573687c62a6b63 Mon Sep 17 00:00:00 2001 From: "Tobin C. Harding" Date: Tue, 1 Aug 2023 11:25:15 +1000 Subject: [PATCH] Inline descriptor inner types The `ShInner` and `WshInner` enum's provide no benefit that I can discern. Both include only tuple variants with private tuple fields. We can therefore inline the enums into `Sh` and `Wsh` respectively with no loss of type safety. Doing so marginally simplifies the code, the biggest benefit is it stops devs wondering why there is an inner type. --- bitcoind-tests/tests/test_cpp.rs | 2 +- bitcoind-tests/tests/test_desc.rs | 16 +-- src/descriptor/mod.rs | 24 ++-- src/descriptor/segwitv0.rs | 117 +++++++---------- src/descriptor/sh.rs | 205 +++++++++++++----------------- src/psbt/mod.rs | 8 +- 6 files changed, 158 insertions(+), 214 deletions(-) diff --git a/bitcoind-tests/tests/test_cpp.rs b/bitcoind-tests/tests/test_cpp.rs index 8e682386d..b5b0319cc 100644 --- a/bitcoind-tests/tests/test_cpp.rs +++ b/bitcoind-tests/tests/test_cpp.rs @@ -162,7 +162,7 @@ pub fn test_from_cpp_ms(cl: &Client, testdata: &TestData) { for i in 0..psbts.len() { let ms = if let Descriptor::Wsh(wsh) = &desc_vec[i] { match wsh.as_inner() { - miniscript::descriptor::WshInner::Ms(ms) => ms, + miniscript::descriptor::Wsh::Ms(ms) => ms, _ => unreachable!(), } } else { diff --git a/bitcoind-tests/tests/test_desc.rs b/bitcoind-tests/tests/test_desc.rs index 06c8e8f82..324e942e5 100644 --- a/bitcoind-tests/tests/test_desc.rs +++ b/bitcoind-tests/tests/test_desc.rs @@ -225,28 +225,28 @@ pub fn test_desc_satisfy( 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) => { + miniscript::descriptor::Sh::Wsh(wsh) => match wsh.as_inner() { + 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) => { + 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"), }; diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 4ccf50f18..a698c987e 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -37,8 +37,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}; @@ -267,18 +267,18 @@ impl Descriptor { 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, } diff --git a/src/descriptor/segwitv0.rs b/src/descriptor/segwitv0.rs index e0acc9b13..3485b6f5a 100644 --- a/src/descriptor/segwitv0.rs +++ b/src/descriptor/segwitv0.rs @@ -23,38 +23,26 @@ use crate::{ /// A Segwitv0 wsh descriptor #[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] -pub struct Wsh { - /// underlying miniscript - inner: WshInner, +pub enum Wsh { + /// Sorted Multi + SortedMulti(SortedMultiVec), + /// Wsh Miniscript + Ms(Miniscript), } impl Wsh { - /// Get the Inner - pub fn into_inner(self) -> WshInner { - self.inner - } - - /// Get a reference to inner - pub fn as_inner(&self) -> &WshInner { - &self.inner - } - /// Create a new wsh descriptor pub fn new(ms: Miniscript) -> Result { // 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) -> Result { // 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 @@ -65,9 +53,9 @@ impl Wsh { /// 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(()) } @@ -81,13 +69,13 @@ impl Wsh { /// # Errors /// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)). pub fn max_weight_to_satisfy(&self) -> Result { - 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()?, @@ -111,13 +99,13 @@ impl Wsh { /// 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 { - 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()?, @@ -139,17 +127,17 @@ impl Wsh { /// 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(), } } @@ -165,9 +153,9 @@ impl Wsh { where S: Satisfier, { - 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()); @@ -182,9 +170,9 @@ impl Wsh { where S: Satisfier, { - 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(); @@ -192,20 +180,11 @@ impl Wsh { } } -/// Wsh Inner -#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] -pub enum WshInner { - /// Sorted Multi - SortedMulti(SortedMultiVec), - /// Wsh Miniscript - Ms(Miniscript), -} - impl Liftable for Wsh { fn lift(&self) -> Result, 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(), } } } @@ -216,15 +195,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", @@ -237,9 +212,9 @@ impl_from_tree!( impl fmt::Debug for Wsh { 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), } } } @@ -248,9 +223,9 @@ impl fmt::Display for Wsh { 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() } @@ -268,9 +243,9 @@ impl_from_str!( impl ForEachKey for Wsh { 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), } } } @@ -286,11 +261,11 @@ where where T: Translator, { - 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) } } diff --git a/src/descriptor/sh.rs b/src/descriptor/sh.rs index 1f18c641a..757759c61 100644 --- a/src/descriptor/sh.rs +++ b/src/descriptor/sh.rs @@ -27,14 +27,7 @@ use crate::{ /// A Legacy p2sh Descriptor #[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] -pub struct Sh { - /// underlying miniscript - inner: ShInner, -} - -/// Sh Inner -#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Hash)] -pub enum ShInner { +pub enum Sh { /// Nested Wsh Wsh(Wsh), /// Nested Wpkh @@ -47,22 +40,22 @@ pub enum ShInner { impl Liftable for Sh { fn lift(&self) -> Result, Error> { - match self.inner { - ShInner::Wsh(ref wsh) => wsh.lift(), - ShInner::Wpkh(ref pk) => Ok(semantic::Policy::Key(pk.as_inner().clone())), - ShInner::SortedMulti(ref smv) => smv.lift(), - ShInner::Ms(ref ms) => ms.lift(), + match *self { + Sh::Wsh(ref wsh) => wsh.lift(), + Sh::Wpkh(ref pk) => Ok(semantic::Policy::Key(pk.as_inner().clone())), + Sh::SortedMulti(ref smv) => smv.lift(), + Sh::Ms(ref ms) => ms.lift(), } } } impl fmt::Debug for Sh { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - match self.inner { - ShInner::Wsh(ref wsh_inner) => write!(f, "sh({:?})", wsh_inner), - ShInner::Wpkh(ref pk) => write!(f, "sh({:?})", pk), - ShInner::SortedMulti(ref smv) => write!(f, "sh({:?})", smv), - ShInner::Ms(ref ms) => write!(f, "sh({:?})", ms), + match *self { + Sh::Wsh(ref wsh_inner) => write!(f, "sh({:?})", wsh_inner), + Sh::Wpkh(ref pk) => write!(f, "sh({:?})", pk), + Sh::SortedMulti(ref smv) => write!(f, "sh({:?})", smv), + Sh::Ms(ref ms) => write!(f, "sh({:?})", ms), } } } @@ -71,11 +64,11 @@ impl fmt::Display for Sh { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { use fmt::Write; let mut wrapped_f = checksum::Formatter::new(f); - match self.inner { - ShInner::Wsh(ref wsh) => write!(wrapped_f, "sh({:#})", wsh)?, - ShInner::Wpkh(ref pk) => write!(wrapped_f, "sh({:#})", pk)?, - ShInner::SortedMulti(ref smv) => write!(wrapped_f, "sh({})", smv)?, - ShInner::Ms(ref ms) => write!(wrapped_f, "sh({})", ms)?, + match *self { + Sh::Wsh(ref wsh) => write!(wrapped_f, "sh({:#})", wsh)?, + Sh::Wpkh(ref pk) => write!(wrapped_f, "sh({:#})", pk)?, + Sh::SortedMulti(ref smv) => write!(wrapped_f, "sh({})", smv)?, + Sh::Ms(ref ms) => write!(wrapped_f, "sh({})", ms)?, } wrapped_f.write_checksum_if_not_alt() } @@ -86,17 +79,17 @@ impl_from_tree!( fn from_tree(top: &expression::Tree) -> Result { if top.name == "sh" && top.args.len() == 1 { let top = &top.args[0]; - let inner = match top.name { - "wsh" => ShInner::Wsh(Wsh::from_tree(top)?), - "wpkh" => ShInner::Wpkh(Wpkh::from_tree(top)?), - "sortedmulti" => ShInner::SortedMulti(SortedMultiVec::from_tree(top)?), + let sh = match top.name { + "wsh" => Sh::Wsh(Wsh::from_tree(top)?), + "wpkh" => Sh::Wpkh(Wpkh::from_tree(top)?), + "sortedmulti" => Sh::SortedMulti(SortedMultiVec::from_tree(top)?), _ => { let sub = Miniscript::from_tree(top)?; Legacy::top_level_checks(&sub)?; - ShInner::Ms(sub) + Sh::Ms(sub) } }; - Ok(Sh { inner }) + Ok(sh) } else { Err(Error::Unexpected(format!( "{}({} args) while parsing sh descriptor", @@ -118,23 +111,11 @@ impl_from_str!( ); impl Sh { - /// Get the Inner - pub fn into_inner(self) -> ShInner { - self.inner - } - - /// Get a reference to inner - pub fn as_inner(&self) -> &ShInner { - &self.inner - } - /// Create a new p2sh descriptor with the raw miniscript pub fn new(ms: Miniscript) -> Result { // do the top-level checks Legacy::top_level_checks(&ms)?; - Ok(Self { - inner: ShInner::Ms(ms), - }) + Ok(Sh::Ms(ms)) } /// Create a new p2sh sortedmulti descriptor with threshold `k` @@ -142,32 +123,26 @@ impl Sh { pub fn new_sortedmulti(k: usize, pks: Vec) -> Result { // The context checks will be carried out inside new function for // sortedMultiVec - Ok(Self { - inner: ShInner::SortedMulti(SortedMultiVec::new(k, pks)?), - }) + Ok(Sh::SortedMulti(SortedMultiVec::new(k, pks)?)) } /// Create a new p2sh wrapped wsh descriptor with the raw miniscript pub fn new_wsh(ms: Miniscript) -> Result { - Ok(Self { - inner: ShInner::Wsh(Wsh::new(ms)?), - }) + Ok(Sh::Wsh(Wsh::new(ms)?)) } /// Create a new p2sh wrapper for the given wsh descriptor pub fn new_with_wsh(wsh: Wsh) -> Self { - Self { - inner: ShInner::Wsh(wsh), - } + Sh::Wsh(wsh) } /// Checks whether the descriptor is safe. pub fn sanity_check(&self) -> Result<(), Error> { - match self.inner { - ShInner::Wsh(ref wsh) => wsh.sanity_check()?, - ShInner::Wpkh(ref wpkh) => wpkh.sanity_check()?, - ShInner::SortedMulti(ref smv) => smv.sanity_check()?, - ShInner::Ms(ref ms) => ms.sanity_check()?, + match *self { + Sh::Wsh(ref wsh) => wsh.sanity_check()?, + Sh::Wpkh(ref wpkh) => wpkh.sanity_check()?, + Sh::SortedMulti(ref smv) => smv.sanity_check()?, + Sh::Ms(ref ms) => ms.sanity_check()?, } Ok(()) } @@ -177,23 +152,17 @@ impl Sh { pub fn new_wsh_sortedmulti(k: usize, pks: Vec) -> Result { // The context checks will be carried out inside new function for // sortedMultiVec - Ok(Self { - inner: ShInner::Wsh(Wsh::new_sortedmulti(k, pks)?), - }) + Ok(Sh::Wsh(Wsh::new_sortedmulti(k, pks)?)) } /// Create a new p2sh wrapped wpkh from `Pk` pub fn new_wpkh(pk: Pk) -> Result { - Ok(Self { - inner: ShInner::Wpkh(Wpkh::new(pk)?), - }) + Ok(Sh::Wpkh(Wpkh::new(pk)?)) } /// Create a new p2sh wrapper for the given wpkh descriptor pub fn new_with_wpkh(wpkh: Wpkh) -> Self { - Self { - inner: ShInner::Wpkh(wpkh), - } + Sh::Wpkh(wpkh) } /// Computes an upper bound on the difference between a non-satisfied @@ -210,28 +179,28 @@ impl Sh { /// # Errors /// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)). pub fn max_weight_to_satisfy(&self) -> Result { - let (scriptsig_size, witness_size) = match self.inner { + let (scriptsig_size, witness_size) = match *self { // add weighted script sig, len byte stays the same - ShInner::Wsh(ref wsh) => { + Sh::Wsh(ref wsh) => { // scriptSig: OP_34 > let scriptsig_size = 1 + 1 + 1 + 32; let witness_size = wsh.max_weight_to_satisfy()?; (scriptsig_size, witness_size) } - ShInner::SortedMulti(ref smv) => { + Sh::SortedMulti(ref smv) => { let ss = smv.script_size(); let ps = push_opcode_size(ss); let scriptsig_size = ps + ss + smv.max_satisfaction_size(); (scriptsig_size, 0) } // add weighted script sig, len byte stays the same - ShInner::Wpkh(ref wpkh) => { + Sh::Wpkh(ref wpkh) => { // scriptSig: OP_22 > let scriptsig_size = 1 + 1 + 1 + 20; let witness_size = wpkh.max_weight_to_satisfy(); (scriptsig_size, witness_size) } - ShInner::Ms(ref ms) => { + Sh::Ms(ref ms) => { let ss = ms.script_size(); let ps = push_opcode_size(ss); let scriptsig_size = ps + ss + ms.max_satisfaction_size()?; @@ -257,18 +226,18 @@ impl Sh { #[deprecated(note = "use max_weight_to_satisfy instead")] #[allow(deprecated)] pub fn max_satisfaction_weight(&self) -> Result { - Ok(match self.inner { + Ok(match *self { // add weighted script sig, len byte stays the same - ShInner::Wsh(ref wsh) => 4 * 35 + wsh.max_satisfaction_weight()?, - ShInner::SortedMulti(ref smv) => { + Sh::Wsh(ref wsh) => 4 * 35 + wsh.max_satisfaction_weight()?, + Sh::SortedMulti(ref smv) => { let ss = smv.script_size(); let ps = push_opcode_size(ss); let scriptsig_len = ps + ss + smv.max_satisfaction_size(); 4 * (varint_len(scriptsig_len) + scriptsig_len) } // add weighted script sig, len byte stays the same - ShInner::Wpkh(ref wpkh) => 4 * 23 + wpkh.max_satisfaction_weight(), - ShInner::Ms(ref ms) => { + Sh::Wpkh(ref wpkh) => 4 * 23 + wpkh.max_satisfaction_weight(), + Sh::Ms(ref ms) => { let ss = ms.script_size(); let ps = push_opcode_size(ss); let scriptsig_len = ps + ss + ms.max_satisfaction_size()?; @@ -281,11 +250,11 @@ impl Sh { impl Sh { /// Obtains the corresponding script pubkey for this descriptor. pub fn script_pubkey(&self) -> ScriptBuf { - match self.inner { - ShInner::Wsh(ref wsh) => wsh.script_pubkey().to_p2sh(), - ShInner::Wpkh(ref wpkh) => wpkh.script_pubkey().to_p2sh(), - ShInner::SortedMulti(ref smv) => smv.encode().to_p2sh(), - ShInner::Ms(ref ms) => ms.encode().to_p2sh(), + match *self { + Sh::Wsh(ref wsh) => wsh.script_pubkey().to_p2sh(), + Sh::Wpkh(ref wpkh) => wpkh.script_pubkey().to_p2sh(), + Sh::SortedMulti(ref smv) => smv.encode().to_p2sh(), + Sh::Ms(ref ms) => ms.encode().to_p2sh(), } } @@ -299,11 +268,11 @@ impl Sh { } fn address_fallible(&self, network: Network) -> Result { - let script = match self.inner { - ShInner::Wsh(ref wsh) => wsh.script_pubkey(), - ShInner::Wpkh(ref wpkh) => wpkh.script_pubkey(), - ShInner::SortedMulti(ref smv) => smv.encode(), - ShInner::Ms(ref ms) => ms.encode(), + let script = match *self { + Sh::Wsh(ref wsh) => wsh.script_pubkey(), + Sh::Wpkh(ref wpkh) => wpkh.script_pubkey(), + Sh::SortedMulti(ref smv) => smv.encode(), + Sh::Ms(ref ms) => ms.encode(), }; let address = Address::p2sh(&script, network)?; @@ -312,24 +281,24 @@ impl Sh { /// Obtain the underlying miniscript for this descriptor pub fn inner_script(&self) -> ScriptBuf { - match self.inner { - ShInner::Wsh(ref wsh) => wsh.inner_script(), - ShInner::Wpkh(ref wpkh) => wpkh.script_pubkey(), - ShInner::SortedMulti(ref smv) => smv.encode(), - ShInner::Ms(ref ms) => ms.encode(), + match *self { + Sh::Wsh(ref wsh) => wsh.inner_script(), + Sh::Wpkh(ref wpkh) => wpkh.script_pubkey(), + Sh::SortedMulti(ref smv) => smv.encode(), + Sh::Ms(ref ms) => ms.encode(), } } /// Obtains the pre bip-340 signature script code for this descriptor. pub fn ecdsa_sighash_script_code(&self) -> ScriptBuf { - match self.inner { + match *self { // - For P2WSH witness program, if the witnessScript does not contain any `OP_CODESEPARATOR`, // the `scriptCode` is the `witnessScript` serialized as scripts inside CTxOut. - ShInner::Wsh(ref wsh) => wsh.ecdsa_sighash_script_code(), - ShInner::SortedMulti(ref smv) => smv.encode(), - ShInner::Wpkh(ref wpkh) => wpkh.ecdsa_sighash_script_code(), + Sh::Wsh(ref wsh) => wsh.ecdsa_sighash_script_code(), + Sh::SortedMulti(ref smv) => smv.encode(), + Sh::Wpkh(ref wpkh) => wpkh.ecdsa_sighash_script_code(), // For "legacy" P2SH outputs, it is defined as the txo's redeemScript. - ShInner::Ms(ref ms) => ms.encode(), + Sh::Ms(ref ms) => ms.encode(), } } @@ -341,21 +310,21 @@ impl Sh { /// whose txid will not change during signing (since only the witness data /// will change). pub fn unsigned_script_sig(&self) -> ScriptBuf { - match self.inner { - ShInner::Wsh(ref wsh) => { + match *self { + Sh::Wsh(ref wsh) => { // wsh explicit must contain exactly 1 element let witness_script = wsh.inner_script().to_v0_p2wsh(); let push_bytes = <&PushBytes>::try_from(witness_script.as_bytes()) .expect("Witness script is not too large"); script::Builder::new().push_slice(push_bytes).into_script() } - ShInner::Wpkh(ref wpkh) => { + Sh::Wpkh(ref wpkh) => { let redeem_script = wpkh.script_pubkey(); let push_bytes: &PushBytes = <&PushBytes>::try_from(redeem_script.as_bytes()).expect("Script not too large"); script::Builder::new().push_slice(push_bytes).into_script() } - ShInner::SortedMulti(..) | ShInner::Ms(..) => ScriptBuf::new(), + Sh::SortedMulti(..) | Sh::Ms(..) => ScriptBuf::new(), } } @@ -367,23 +336,23 @@ impl Sh { S: Satisfier, { let script_sig = self.unsigned_script_sig(); - match self.inner { - ShInner::Wsh(ref wsh) => { + match *self { + Sh::Wsh(ref wsh) => { let (witness, _) = wsh.get_satisfaction(satisfier)?; Ok((witness, script_sig)) } - ShInner::Wpkh(ref wpkh) => { + Sh::Wpkh(ref wpkh) => { let (witness, _) = wpkh.get_satisfaction(satisfier)?; Ok((witness, script_sig)) } - ShInner::SortedMulti(ref smv) => { + Sh::SortedMulti(ref smv) => { let mut script_witness = smv.satisfy(satisfier)?; script_witness.push(smv.encode().into_bytes()); let script_sig = witness_to_scriptsig(&script_witness); let witness = vec![]; Ok((witness, script_sig)) } - ShInner::Ms(ref ms) => { + Sh::Ms(ref ms) => { let mut script_witness = ms.satisfy(satisfier)?; script_witness.push(ms.encode().into_bytes()); let script_sig = witness_to_scriptsig(&script_witness); @@ -401,12 +370,12 @@ impl Sh { S: Satisfier, { let script_sig = self.unsigned_script_sig(); - match self.inner { - ShInner::Wsh(ref wsh) => { + match *self { + Sh::Wsh(ref wsh) => { let (witness, _) = wsh.get_satisfaction_mall(satisfier)?; Ok((witness, script_sig)) } - ShInner::Ms(ref ms) => { + Sh::Ms(ref ms) => { let mut script_witness = ms.satisfy_malleable(satisfier)?; script_witness.push(ms.encode().into_bytes()); let script_sig = witness_to_scriptsig(&script_witness); @@ -420,11 +389,11 @@ impl Sh { impl ForEachKey for Sh { fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool { - match self.inner { - ShInner::Wsh(ref wsh) => wsh.for_each_key(pred), - ShInner::SortedMulti(ref smv) => smv.for_each_key(pred), - ShInner::Wpkh(ref wpkh) => wpkh.for_each_key(pred), - ShInner::Ms(ref ms) => ms.for_each_key(pred), + match *self { + Sh::Wsh(ref wsh) => wsh.for_each_key(pred), + Sh::SortedMulti(ref smv) => smv.for_each_key(pred), + Sh::Wpkh(ref wpkh) => wpkh.for_each_key(pred), + Sh::Ms(ref ms) => ms.for_each_key(pred), } } } @@ -440,12 +409,12 @@ where where T: Translator, { - let inner = match self.inner { - ShInner::Wsh(ref wsh) => ShInner::Wsh(wsh.translate_pk(t)?), - ShInner::Wpkh(ref wpkh) => ShInner::Wpkh(wpkh.translate_pk(t)?), - ShInner::SortedMulti(ref smv) => ShInner::SortedMulti(smv.translate_pk(t)?), - ShInner::Ms(ref ms) => ShInner::Ms(ms.translate_pk(t)?), + let sh = match *self { + Sh::Wsh(ref wsh) => Sh::Wsh(wsh.translate_pk(t)?), + Sh::Wpkh(ref wpkh) => Sh::Wpkh(wpkh.translate_pk(t)?), + Sh::SortedMulti(ref smv) => Sh::SortedMulti(smv.translate_pk(t)?), + Sh::Ms(ref ms) => Sh::Ms(ms.translate_pk(t)?), }; - Ok(Sh { inner }) + Ok(sh) } } diff --git a/src/psbt/mod.rs b/src/psbt/mod.rs index d9f0ed047..fff9d50a7 100644 --- a/src/psbt/mod.rs +++ b/src/psbt/mod.rs @@ -1249,13 +1249,13 @@ fn update_item_with_descriptor_helper( match &derived { Descriptor::Bare(_) | Descriptor::Pkh(_) | Descriptor::Wpkh(_) => {} - Descriptor::Sh(sh) => match sh.as_inner() { - descriptor::ShInner::Wsh(wsh) => { + Descriptor::Sh(sh) => match sh { + descriptor::Sh::Wsh(wsh) => { *item.witness_script() = Some(wsh.inner_script()); *item.redeem_script() = Some(wsh.inner_script().to_v0_p2wsh()); } - descriptor::ShInner::Wpkh(..) => *item.redeem_script() = Some(sh.inner_script()), - descriptor::ShInner::SortedMulti(_) | descriptor::ShInner::Ms(_) => { + descriptor::Sh::Wpkh(..) => *item.redeem_script() = Some(sh.inner_script()), + descriptor::Sh::SortedMulti(_) | descriptor::Sh::Ms(_) => { *item.redeem_script() = Some(sh.inner_script()) } },