diff --git a/bitcoind-tests/tests/test_desc.rs b/bitcoind-tests/tests/test_desc.rs index 0300f5bde..b35e67c00 100644 --- a/bitcoind-tests/tests/test_desc.rs +++ b/bitcoind-tests/tests/test_desc.rs @@ -475,7 +475,7 @@ fn test_plan_satisfy( let plan = definite_desc .clone() - .plan(&assets) + .into_plan(&assets) .expect("plan creation failed"); let mut unsigned_tx = Transaction { diff --git a/src/descriptor/bare.rs b/src/descriptor/bare.rs index b41ee2850..844516779 100644 --- a/src/descriptor/bare.rs +++ b/src/descriptor/bare.rs @@ -12,7 +12,7 @@ use core::fmt; use bitcoin::script::{self, PushBytes}; use bitcoin::{Address, Network, ScriptBuf, Weight}; -use crate::descriptor::{write_descriptor, DefiniteDescriptorKey}; +use crate::descriptor::write_descriptor; use crate::expression::{self, FromTree}; use crate::miniscript::context::{ScriptContext, ScriptContextError}; use crate::miniscript::satisfy::{Placeholder, Satisfaction, Witness}; @@ -138,25 +138,19 @@ impl Bare { } } -impl Bare { +impl Bare { /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction - pub fn plan_satisfaction

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { self.ms.build_template(provider) } /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction - pub fn plan_satisfaction_mall

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction_mall

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { self.ms.build_template_mall(provider) } @@ -316,16 +310,11 @@ impl Pkh { { self.get_satisfaction(satisfier) } -} -impl Pkh { /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction - pub fn plan_satisfaction

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { let stack = if provider.provider_lookup_ecdsa_sig(&self.pk) { let stack = vec![ @@ -341,12 +330,9 @@ impl Pkh { } /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction - pub fn plan_satisfaction_mall

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction_mall

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { self.plan_satisfaction(provider) } diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 2ad51c838..5dc6e7592 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -552,14 +552,26 @@ impl Descriptor { } } -impl Descriptor { +impl Descriptor { + /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction + /// + /// If the assets aren't sufficient for generating a Plan, the descriptor is returned + #[deprecated(since = "TBD", note = "use into_plan instead")] + #[allow(clippy::result_large_err)] // our "error type" is the original descriptor + pub fn plan

(self, provider: &P) -> Result, Self> + where + P: AssetProvider, + { + self.into_plan(provider) + } + /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction /// /// If the assets aren't sufficient for generating a Plan, the descriptor is returned #[allow(clippy::result_large_err)] // our "error type" is the original descriptor - pub fn plan

(self, provider: &P) -> Result + pub fn into_plan

(self, provider: &P) -> Result, Self> where - P: AssetProvider, + P: AssetProvider, { let satisfaction = match self { Descriptor::Bare(ref bare) => bare.plan_satisfaction(provider), @@ -582,13 +594,25 @@ impl Descriptor { } } + /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction + /// + /// If the assets aren't sufficient for generating a Plan, the descriptor is returned + #[deprecated(since = "TBD", note = "use into_plan_mall instead")] + #[allow(clippy::result_large_err)] // our "error type" is the original descriptor + pub fn plan_mall

(self, provider: &P) -> Result, Self> + where + P: AssetProvider, + { + self.into_plan_mall(provider) + } + /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction /// /// If the assets aren't sufficient for generating a Plan, the descriptor is returned #[allow(clippy::result_large_err)] // our "error type" is the original descriptor - pub fn plan_mall

(self, provider: &P) -> Result + pub fn into_plan_mall

(self, provider: &P) -> Result, Self> where - P: AssetProvider, + P: AssetProvider, { let satisfaction = match self { Descriptor::Bare(ref bare) => bare.plan_satisfaction_mall(provider), diff --git a/src/descriptor/segwitv0.rs b/src/descriptor/segwitv0.rs index b1398ba68..883ac7b1b 100644 --- a/src/descriptor/segwitv0.rs +++ b/src/descriptor/segwitv0.rs @@ -10,7 +10,7 @@ use core::fmt; use bitcoin::{Address, Network, ScriptBuf, Weight}; -use crate::descriptor::{write_descriptor, DefiniteDescriptorKey}; +use crate::descriptor::write_descriptor; use crate::expression::{self, FromTree}; use crate::miniscript::context::{ScriptContext, ScriptContextError}; use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG; @@ -159,27 +159,19 @@ impl Wsh { let script_sig = ScriptBuf::new(); Ok((witness, script_sig)) } -} -impl Wsh { /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction - pub fn plan_satisfaction

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { self.ms.build_template(provider) } /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction - pub fn plan_satisfaction_mall

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction_mall

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { if let Terminal::SortedMulti(..) = self.ms.node { self.ms.build_template(provider) @@ -363,16 +355,11 @@ impl Wpkh { { self.get_satisfaction(satisfier) } -} -impl Wpkh { /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction - pub fn plan_satisfaction

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { let stack = if provider.provider_lookup_ecdsa_sig(&self.pk) { let stack = vec![ @@ -388,12 +375,9 @@ impl Wpkh { } /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction - pub fn plan_satisfaction_mall

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction_mall

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { self.plan_satisfaction(provider) } diff --git a/src/descriptor/sh.rs b/src/descriptor/sh.rs index 3c235b777..c824c7bda 100644 --- a/src/descriptor/sh.rs +++ b/src/descriptor/sh.rs @@ -14,7 +14,7 @@ use bitcoin::script::PushBytes; use bitcoin::{script, Address, Network, ScriptBuf, Weight}; use super::{Wpkh, Wsh}; -use crate::descriptor::{write_descriptor, DefiniteDescriptorKey}; +use crate::descriptor::write_descriptor; use crate::expression::{self, FromTree}; use crate::miniscript::context::ScriptContext; use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG; @@ -377,16 +377,11 @@ impl Sh { _ => self.get_satisfaction(satisfier), } } -} -impl Sh { /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction - pub fn plan_satisfaction

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { match &self.inner { ShInner::Wsh(ref wsh) => wsh.plan_satisfaction(provider), @@ -396,12 +391,9 @@ impl Sh { } /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction - pub fn plan_satisfaction_mall

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction_mall

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { match &self.inner { ShInner::Wsh(ref wsh) => wsh.plan_satisfaction_mall(provider), diff --git a/src/descriptor/tr/mod.rs b/src/descriptor/tr/mod.rs index 203e3cee2..47a72cfff 100644 --- a/src/descriptor/tr/mod.rs +++ b/src/descriptor/tr/mod.rs @@ -7,7 +7,6 @@ use bitcoin::{opcodes, Address, Network, ScriptBuf, Weight}; use sync::Arc; use super::checksum; -use crate::descriptor::DefiniteDescriptorKey; use crate::expression::{self, FromTree}; use crate::miniscript::satisfy::{Placeholder, Satisfaction, SchnorrSigType, Witness}; use crate::miniscript::Miniscript; @@ -318,27 +317,19 @@ impl Tr { Err(Error::CouldNotSatisfy) } } -} -impl Tr { /// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction - pub fn plan_satisfaction

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { best_tap_spend(self, provider, false /* allow_mall */) } /// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction - pub fn plan_satisfaction_mall

( - &self, - provider: &P, - ) -> Satisfaction> + pub fn plan_satisfaction_mall

(&self, provider: &P) -> Satisfaction> where - P: AssetProvider, + P: AssetProvider, { best_tap_spend(self, provider, true /* allow_mall */) } diff --git a/src/miniscript/satisfy/mod.rs b/src/miniscript/satisfy/mod.rs index 49bdc8ef5..fc2202e90 100644 --- a/src/miniscript/satisfy/mod.rs +++ b/src/miniscript/satisfy/mod.rs @@ -621,7 +621,7 @@ mod tests { let descriptor = Descriptor::::from_str(&descriptor_str).unwrap(); // Compute plan and confirm the timelock is correct. - let plan = descriptor.plan(&satisfier).unwrap(); + let plan = descriptor.into_plan(&satisfier).unwrap(); assert_eq!(plan.absolute_timelock, Some(absolute::LockTime::from_height(144).unwrap()),); // Same descriptor as above, except that now we use a time-based timelock rather than a @@ -642,7 +642,7 @@ mod tests { let descriptor = Descriptor::::from_str(&descriptor_str).unwrap(); - let plan = descriptor.plan(&satisfier).unwrap(); + let plan = descriptor.into_plan(&satisfier).unwrap(); assert_eq!( plan.absolute_timelock, Some(absolute::LockTime::from_time(1000000000).unwrap()), diff --git a/src/plan.rs b/src/plan.rs index 6f56895a4..f1f57b10e 100644 --- a/src/plan.rs +++ b/src/plan.rs @@ -210,20 +210,20 @@ where /// Calling `plan` on a Descriptor will return this structure, /// containing the cheapest spending path possible (considering the `Assets` given) #[derive(Debug, Clone)] -pub struct Plan { +pub struct Plan { /// This plan's witness template - pub(crate) template: Vec>, + pub(crate) template: Vec>, /// The absolute timelock this plan uses pub absolute_timelock: Option, /// The relative timelock this plan uses pub relative_timelock: Option, - pub(crate) descriptor: Descriptor, + pub(crate) descriptor: Descriptor, } -impl Plan { +impl Plan { /// Returns the witness template - pub fn witness_template(&self) -> &Vec> { &self.template } + pub fn witness_template(&self) -> &Vec> { &self.template } /// Returns the witness version pub fn witness_version(&self) -> Option { @@ -264,7 +264,7 @@ impl Plan { } /// Try creating the final script_sig and witness using a [`Satisfier`] - pub fn satisfy>( + pub fn satisfy>( &self, stfr: &Sat, ) -> Result<(Vec>, ScriptBuf), Error> { @@ -302,7 +302,9 @@ impl Plan { } }) } +} +impl Plan { /// Update a PSBT input with the metadata required to complete this plan /// /// This will only add the metadata for items required to complete this plan. For example, if @@ -764,7 +766,7 @@ mod test { assets = assets.add(hashes[hi]); } - let result = desc.clone().plan(&assets); + let result = desc.clone().into_plan(&assets); assert_eq!( result.as_ref().ok().map(|plan| plan.satisfaction_weight()), expected, @@ -1103,7 +1105,7 @@ mod test { let mut psbt_input = bitcoin::psbt::Input::default(); let assets = Assets::new().add(internal_key); desc.clone() - .plan(&assets) + .into_plan(&assets) .unwrap() .update_psbt_input(&mut psbt_input); assert!(psbt_input.tap_internal_key.is_some(), "Internal key is missing"); @@ -1114,7 +1116,7 @@ mod test { let mut psbt_input = bitcoin::psbt::Input::default(); let assets = Assets::new().add(first_branch); desc.clone() - .plan(&assets) + .into_plan(&assets) .unwrap() .update_psbt_input(&mut psbt_input); assert!(psbt_input.tap_internal_key.is_none(), "Internal key is present"); @@ -1124,7 +1126,7 @@ mod test { let mut psbt_input = bitcoin::psbt::Input::default(); let assets = Assets::new().add(second_branch); - desc.plan(&assets) + desc.into_plan(&assets) .unwrap() .update_psbt_input(&mut psbt_input); assert!(psbt_input.tap_internal_key.is_none(), "Internal key is present"); @@ -1147,7 +1149,7 @@ mod test { let mut psbt_input = bitcoin::psbt::Input::default(); let assets = Assets::new().add(asset_key); - desc.plan(&assets) + desc.into_plan(&assets) .unwrap() .update_psbt_input(&mut psbt_input); assert!(psbt_input.witness_script.is_some(), "Witness script missing"); @@ -1200,7 +1202,7 @@ mod test { assets = assets.add(DescriptorPublicKey::from_str(&pk.to_string()).unwrap()); } - let plan = desc.plan(&assets).expect("plan should succeed"); + let plan = desc.into_plan(&assets).expect("plan should succeed"); let (witness, script_sig) = plan.satisfy(&satisfier).expect("satisfy should succeed"); assert_eq!(witness.last().unwrap(), &exp_witness_script.into_bytes());