Skip to content

Commit c6835f7

Browse files
committed
Merge #352: Allow direct compilation of a Policy into a valid Descriptor
169d849 Add policy to descriptor target compilation method (Aman Rojjha) Pull request description: This PR works on top of #291 and #342. It introduces a new function `compile_to_descriptor` which requires a `DescriptorCtx` (suggestions for a better enum name are welcome!) allowing directly compilation of a policy into the specified descriptor type. ACKs for top commit: apoelstra: ACK 169d849 sanket1729: ACK 169d849 Tree-SHA512: 0f895f4774ea4f56db76280ac756df616a70e5d7d60cc128f9a050ef86658f786b2d45885d748dba51751146a6e93b3731f4ae193b7d80284ffaea20be1e8f92
2 parents e0650ab + 169d849 commit c6835f7

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

src/policy/concrete.rs

+40
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,21 @@ pub enum PolicyError {
100100
DuplicatePubKeys,
101101
}
102102

103+
/// Descriptor context for [`Policy`] compilation into a [`Descriptor`]
104+
pub enum DescriptorCtx<Pk> {
105+
/// [Bare][`Descriptor::Bare`]
106+
Bare,
107+
/// [Sh][`Descriptor::Sh`]
108+
Sh,
109+
/// [Wsh][`Descriptor::Wsh`]
110+
Wsh,
111+
/// Sh-wrapped [Wsh][`Descriptor::Wsh`]
112+
ShWsh,
113+
/// [Tr][`Descriptor::Tr`] where the Option<Pk> corresponds to the internal_key if no internal
114+
/// key can be inferred from the given policy
115+
Tr(Option<Pk>),
116+
}
117+
103118
impl fmt::Display for PolicyError {
104119
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
105120
match *self {
@@ -289,6 +304,31 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
289304
}
290305
}
291306

307+
/// Compile the [`Policy`] into desc_ctx [`Descriptor`]
308+
///
309+
/// In case of [Tr][`DescriptorCtx::Tr`], `internal_key` is used for the Taproot comilation when
310+
/// no public key can be inferred from the given policy
311+
#[cfg(feature = "compiler")]
312+
pub fn compile_to_descriptor<Ctx: ScriptContext>(
313+
&self,
314+
desc_ctx: DescriptorCtx<Pk>,
315+
) -> Result<Descriptor<Pk>, Error> {
316+
self.is_valid()?;
317+
match self.is_safe_nonmalleable() {
318+
(false, _) => Err(Error::from(CompilerError::TopLevelNonSafe)),
319+
(_, false) => Err(Error::from(
320+
CompilerError::ImpossibleNonMalleableCompilation,
321+
)),
322+
_ => match desc_ctx {
323+
DescriptorCtx::Bare => Descriptor::new_bare(compiler::best_compilation(self)?),
324+
DescriptorCtx::Sh => Descriptor::new_sh(compiler::best_compilation(self)?),
325+
DescriptorCtx::Wsh => Descriptor::new_wsh(compiler::best_compilation(self)?),
326+
DescriptorCtx::ShWsh => Descriptor::new_sh_wsh(compiler::best_compilation(self)?),
327+
DescriptorCtx::Tr(unspendable_key) => self.compile_tr(unspendable_key),
328+
},
329+
}
330+
}
331+
292332
/// Compile the descriptor into an optimized `Miniscript` representation
293333
#[cfg(feature = "compiler")]
294334
pub fn compile<Ctx: ScriptContext>(&self) -> Result<Miniscript<Pk, Ctx>, CompilerError> {

0 commit comments

Comments
 (0)