Skip to content

Commit 7cd03d0

Browse files
committed
Merge #929: refactor: make Descriptor plan API available for generic Pk
b646120 refactor: rename `plan` and `plan_mall` to have `into_` prefix (Trevor Arjeski) e02bfd7 refactor: make `Descriptor` plan API available for generic `Pk` (Trevor Arjeski) Pull request description: - Migrate `plan` and `plan_mall` methods from `DefiniteDescriptorKey` to generic `Pk: MiniscriptKey + ToPublicKey`. - Made the `Plan` struct generic over `Pk` (excluding `update_psbt_input` since it needs descriptor key data). Adding this to same PR in a separate commit since it's trivial: - Rename `plan` and `plan_mall` to have `into_` prefix Closes #927 and #928 ACKs for top commit: apoelstra: ACK b646120; successfully ran local tests Tree-SHA512: c0da097415fc6e9bf6b27ad4cc9bd6962ac55bec6c662dd8fcc322a3f5d2ddbc241ae2f1abf35087e565ab5cb27996c072f140cd7ada4c0bf8b45d28daed9efa
2 parents 8ab549a + b646120 commit 7cd03d0

8 files changed

Lines changed: 74 additions & 95 deletions

File tree

bitcoind-tests/tests/test_desc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -475,7 +475,7 @@ fn test_plan_satisfy(
475475

476476
let plan = definite_desc
477477
.clone()
478-
.plan(&assets)
478+
.into_plan(&assets)
479479
.expect("plan creation failed");
480480

481481
let mut unsigned_tx = Transaction {

src/descriptor/bare.rs

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use core::fmt;
1212
use bitcoin::script::{self, PushBytes};
1313
use bitcoin::{Address, Network, ScriptBuf, Weight};
1414

15-
use crate::descriptor::{write_descriptor, DefiniteDescriptorKey};
15+
use crate::descriptor::write_descriptor;
1616
use crate::expression::{self, FromTree};
1717
use crate::miniscript::context::{ScriptContext, ScriptContextError};
1818
use crate::miniscript::satisfy::{Placeholder, Satisfaction, Witness};
@@ -138,25 +138,19 @@ impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
138138
}
139139
}
140140

141-
impl Bare<DefiniteDescriptorKey> {
141+
impl<Pk: MiniscriptKey + ToPublicKey> Bare<Pk> {
142142
/// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
143-
pub fn plan_satisfaction<P>(
144-
&self,
145-
provider: &P,
146-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
143+
pub fn plan_satisfaction<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
147144
where
148-
P: AssetProvider<DefiniteDescriptorKey>,
145+
P: AssetProvider<Pk>,
149146
{
150147
self.ms.build_template(provider)
151148
}
152149

153150
/// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
154-
pub fn plan_satisfaction_mall<P>(
155-
&self,
156-
provider: &P,
157-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
151+
pub fn plan_satisfaction_mall<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
158152
where
159-
P: AssetProvider<DefiniteDescriptorKey>,
153+
P: AssetProvider<Pk>,
160154
{
161155
self.ms.build_template_mall(provider)
162156
}
@@ -316,16 +310,11 @@ impl<Pk: MiniscriptKey + ToPublicKey> Pkh<Pk> {
316310
{
317311
self.get_satisfaction(satisfier)
318312
}
319-
}
320313

321-
impl Pkh<DefiniteDescriptorKey> {
322314
/// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
323-
pub fn plan_satisfaction<P>(
324-
&self,
325-
provider: &P,
326-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
315+
pub fn plan_satisfaction<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
327316
where
328-
P: AssetProvider<DefiniteDescriptorKey>,
317+
P: AssetProvider<Pk>,
329318
{
330319
let stack = if provider.provider_lookup_ecdsa_sig(&self.pk) {
331320
let stack = vec![
@@ -341,12 +330,9 @@ impl Pkh<DefiniteDescriptorKey> {
341330
}
342331

343332
/// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
344-
pub fn plan_satisfaction_mall<P>(
345-
&self,
346-
provider: &P,
347-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
333+
pub fn plan_satisfaction_mall<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
348334
where
349-
P: AssetProvider<DefiniteDescriptorKey>,
335+
P: AssetProvider<Pk>,
350336
{
351337
self.plan_satisfaction(provider)
352338
}

src/descriptor/mod.rs

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -552,14 +552,26 @@ impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
552552
}
553553
}
554554

555-
impl Descriptor<DefiniteDescriptorKey> {
555+
impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk> {
556+
/// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
557+
///
558+
/// If the assets aren't sufficient for generating a Plan, the descriptor is returned
559+
#[deprecated(since = "TBD", note = "use into_plan instead")]
560+
#[allow(clippy::result_large_err)] // our "error type" is the original descriptor
561+
pub fn plan<P>(self, provider: &P) -> Result<Plan<Pk>, Self>
562+
where
563+
P: AssetProvider<Pk>,
564+
{
565+
self.into_plan(provider)
566+
}
567+
556568
/// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
557569
///
558570
/// If the assets aren't sufficient for generating a Plan, the descriptor is returned
559571
#[allow(clippy::result_large_err)] // our "error type" is the original descriptor
560-
pub fn plan<P>(self, provider: &P) -> Result<Plan, Self>
572+
pub fn into_plan<P>(self, provider: &P) -> Result<Plan<Pk>, Self>
561573
where
562-
P: AssetProvider<DefiniteDescriptorKey>,
574+
P: AssetProvider<Pk>,
563575
{
564576
let satisfaction = match self {
565577
Descriptor::Bare(ref bare) => bare.plan_satisfaction(provider),
@@ -582,13 +594,25 @@ impl Descriptor<DefiniteDescriptorKey> {
582594
}
583595
}
584596

597+
/// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
598+
///
599+
/// If the assets aren't sufficient for generating a Plan, the descriptor is returned
600+
#[deprecated(since = "TBD", note = "use into_plan_mall instead")]
601+
#[allow(clippy::result_large_err)] // our "error type" is the original descriptor
602+
pub fn plan_mall<P>(self, provider: &P) -> Result<Plan<Pk>, Self>
603+
where
604+
P: AssetProvider<Pk>,
605+
{
606+
self.into_plan_mall(provider)
607+
}
608+
585609
/// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
586610
///
587611
/// If the assets aren't sufficient for generating a Plan, the descriptor is returned
588612
#[allow(clippy::result_large_err)] // our "error type" is the original descriptor
589-
pub fn plan_mall<P>(self, provider: &P) -> Result<Plan, Self>
613+
pub fn into_plan_mall<P>(self, provider: &P) -> Result<Plan<Pk>, Self>
590614
where
591-
P: AssetProvider<DefiniteDescriptorKey>,
615+
P: AssetProvider<Pk>,
592616
{
593617
let satisfaction = match self {
594618
Descriptor::Bare(ref bare) => bare.plan_satisfaction_mall(provider),

src/descriptor/segwitv0.rs

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use core::fmt;
1010

1111
use bitcoin::{Address, Network, ScriptBuf, Weight};
1212

13-
use crate::descriptor::{write_descriptor, DefiniteDescriptorKey};
13+
use crate::descriptor::write_descriptor;
1414
use crate::expression::{self, FromTree};
1515
use crate::miniscript::context::{ScriptContext, ScriptContextError};
1616
use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG;
@@ -159,27 +159,19 @@ impl<Pk: MiniscriptKey + ToPublicKey> Wsh<Pk> {
159159
let script_sig = ScriptBuf::new();
160160
Ok((witness, script_sig))
161161
}
162-
}
163162

164-
impl Wsh<DefiniteDescriptorKey> {
165163
/// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
166-
pub fn plan_satisfaction<P>(
167-
&self,
168-
provider: &P,
169-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
164+
pub fn plan_satisfaction<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
170165
where
171-
P: AssetProvider<DefiniteDescriptorKey>,
166+
P: AssetProvider<Pk>,
172167
{
173168
self.ms.build_template(provider)
174169
}
175170

176171
/// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
177-
pub fn plan_satisfaction_mall<P>(
178-
&self,
179-
provider: &P,
180-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
172+
pub fn plan_satisfaction_mall<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
181173
where
182-
P: AssetProvider<DefiniteDescriptorKey>,
174+
P: AssetProvider<Pk>,
183175
{
184176
if let Terminal::SortedMulti(..) = self.ms.node {
185177
self.ms.build_template(provider)
@@ -363,16 +355,11 @@ impl<Pk: MiniscriptKey + ToPublicKey> Wpkh<Pk> {
363355
{
364356
self.get_satisfaction(satisfier)
365357
}
366-
}
367358

368-
impl Wpkh<DefiniteDescriptorKey> {
369359
/// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
370-
pub fn plan_satisfaction<P>(
371-
&self,
372-
provider: &P,
373-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
360+
pub fn plan_satisfaction<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
374361
where
375-
P: AssetProvider<DefiniteDescriptorKey>,
362+
P: AssetProvider<Pk>,
376363
{
377364
let stack = if provider.provider_lookup_ecdsa_sig(&self.pk) {
378365
let stack = vec![
@@ -388,12 +375,9 @@ impl Wpkh<DefiniteDescriptorKey> {
388375
}
389376

390377
/// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
391-
pub fn plan_satisfaction_mall<P>(
392-
&self,
393-
provider: &P,
394-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
378+
pub fn plan_satisfaction_mall<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
395379
where
396-
P: AssetProvider<DefiniteDescriptorKey>,
380+
P: AssetProvider<Pk>,
397381
{
398382
self.plan_satisfaction(provider)
399383
}

src/descriptor/sh.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use bitcoin::script::PushBytes;
1414
use bitcoin::{script, Address, Network, ScriptBuf, Weight};
1515

1616
use super::{Wpkh, Wsh};
17-
use crate::descriptor::{write_descriptor, DefiniteDescriptorKey};
17+
use crate::descriptor::write_descriptor;
1818
use crate::expression::{self, FromTree};
1919
use crate::miniscript::context::ScriptContext;
2020
use crate::miniscript::limits::MAX_PUBKEYS_PER_MULTISIG;
@@ -377,16 +377,11 @@ impl<Pk: MiniscriptKey + ToPublicKey> Sh<Pk> {
377377
_ => self.get_satisfaction(satisfier),
378378
}
379379
}
380-
}
381380

382-
impl Sh<DefiniteDescriptorKey> {
383381
/// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
384-
pub fn plan_satisfaction<P>(
385-
&self,
386-
provider: &P,
387-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
382+
pub fn plan_satisfaction<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
388383
where
389-
P: AssetProvider<DefiniteDescriptorKey>,
384+
P: AssetProvider<Pk>,
390385
{
391386
match &self.inner {
392387
ShInner::Wsh(ref wsh) => wsh.plan_satisfaction(provider),
@@ -396,12 +391,9 @@ impl Sh<DefiniteDescriptorKey> {
396391
}
397392

398393
/// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
399-
pub fn plan_satisfaction_mall<P>(
400-
&self,
401-
provider: &P,
402-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
394+
pub fn plan_satisfaction_mall<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
403395
where
404-
P: AssetProvider<DefiniteDescriptorKey>,
396+
P: AssetProvider<Pk>,
405397
{
406398
match &self.inner {
407399
ShInner::Wsh(ref wsh) => wsh.plan_satisfaction_mall(provider),

src/descriptor/tr/mod.rs

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use bitcoin::{opcodes, Address, Network, ScriptBuf, Weight};
77
use sync::Arc;
88

99
use super::checksum;
10-
use crate::descriptor::DefiniteDescriptorKey;
1110
use crate::expression::{self, FromTree};
1211
use crate::miniscript::satisfy::{Placeholder, Satisfaction, SchnorrSigType, Witness};
1312
use crate::miniscript::Miniscript;
@@ -318,27 +317,19 @@ impl<Pk: MiniscriptKey + ToPublicKey> Tr<Pk> {
318317
Err(Error::CouldNotSatisfy)
319318
}
320319
}
321-
}
322320

323-
impl Tr<DefiniteDescriptorKey> {
324321
/// Returns a plan if the provided assets are sufficient to produce a non-malleable satisfaction
325-
pub fn plan_satisfaction<P>(
326-
&self,
327-
provider: &P,
328-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
322+
pub fn plan_satisfaction<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
329323
where
330-
P: AssetProvider<DefiniteDescriptorKey>,
324+
P: AssetProvider<Pk>,
331325
{
332326
best_tap_spend(self, provider, false /* allow_mall */)
333327
}
334328

335329
/// Returns a plan if the provided assets are sufficient to produce a malleable satisfaction
336-
pub fn plan_satisfaction_mall<P>(
337-
&self,
338-
provider: &P,
339-
) -> Satisfaction<Placeholder<DefiniteDescriptorKey>>
330+
pub fn plan_satisfaction_mall<P>(&self, provider: &P) -> Satisfaction<Placeholder<Pk>>
340331
where
341-
P: AssetProvider<DefiniteDescriptorKey>,
332+
P: AssetProvider<Pk>,
342333
{
343334
best_tap_spend(self, provider, true /* allow_mall */)
344335
}

src/miniscript/satisfy/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ mod tests {
621621
let descriptor =
622622
Descriptor::<crate::DefiniteDescriptorKey>::from_str(&descriptor_str).unwrap();
623623
// Compute plan and confirm the timelock is correct.
624-
let plan = descriptor.plan(&satisfier).unwrap();
624+
let plan = descriptor.into_plan(&satisfier).unwrap();
625625
assert_eq!(plan.absolute_timelock, Some(absolute::LockTime::from_height(144).unwrap()),);
626626

627627
// Same descriptor as above, except that now we use a time-based timelock rather than a
@@ -642,7 +642,7 @@ mod tests {
642642
let descriptor =
643643
Descriptor::<crate::DefiniteDescriptorKey>::from_str(&descriptor_str).unwrap();
644644

645-
let plan = descriptor.plan(&satisfier).unwrap();
645+
let plan = descriptor.into_plan(&satisfier).unwrap();
646646
assert_eq!(
647647
plan.absolute_timelock,
648648
Some(absolute::LockTime::from_time(1000000000).unwrap()),

0 commit comments

Comments
 (0)