Skip to content

Commit 981354e

Browse files
committed
move TranslatePk traits to root of the crate
1 parent c745f81 commit 981354e

File tree

5 files changed

+134
-140
lines changed

5 files changed

+134
-140
lines changed

src/descriptor/bare.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ use expression::{self, FromTree};
2626
use miniscript::context::ScriptContext;
2727
use policy::{semantic, Liftable};
2828
use util::{varint_len, witness_to_scriptsig};
29-
use {BareCtx, Error, Miniscript, MiniscriptKey, Satisfier, ToPublicKey};
29+
use {BareCtx, Error, Miniscript, MiniscriptKey, Satisfier, ToPublicKey, TranslatePk};
3030

3131
use super::{
3232
checksum::{desc_checksum, verify_checksum},
33-
DescriptorTrait, TranslatePk,
33+
DescriptorTrait,
3434
};
3535

3636
/// Create a Bare Descriptor. That is descriptor that is

src/descriptor/mod.rs

Lines changed: 3 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -29,19 +29,14 @@ use std::{
2929
str::{self, FromStr},
3030
};
3131

32-
use bitcoin::hashes::hash160;
3332
use bitcoin::secp256k1;
3433
use bitcoin::{self, Script};
3534

3635
use self::checksum::verify_checksum;
3736
use expression;
3837
use miniscript;
3938
use miniscript::{Legacy, Miniscript, Segwitv0};
40-
use BareCtx;
41-
use Error;
42-
use MiniscriptKey;
43-
use Satisfier;
44-
use ToPublicKey;
39+
use {BareCtx, Error, MiniscriptKey, Satisfier, ToPublicKey, TranslatePk, TranslatePk2};
4540

4641
mod bare;
4742
mod segwitv0;
@@ -153,131 +148,6 @@ pub trait DescriptorTrait<Pk: MiniscriptKey> {
153148
Pk: ToPublicKey;
154149
}
155150

156-
/// Convert a descriptor using abstract keys to one using specific keys
157-
/// This will panic if translatefpk returns an uncompressed key when
158-
/// converting to a Segwit descriptor. To prevent this panic, ensure
159-
/// translatefpk returns an error in this case instead.
160-
pub trait TranslatePk<P: MiniscriptKey, Q: MiniscriptKey> {
161-
/// The associated output type. This must be Self<Q>
162-
type Output;
163-
164-
/// Translate a struct from one Generic to another where the
165-
/// translation for Pk is provided by translatefpk, and translation for
166-
/// PkH is provided by translatefpkh
167-
fn translate_pk<Fpk, Fpkh, E>(
168-
&self,
169-
translatefpk: Fpk,
170-
translatefpkh: Fpkh,
171-
) -> Result<Self::Output, E>
172-
where
173-
Fpk: FnMut(&P) -> Result<Q, E>,
174-
Fpkh: FnMut(&P::Hash) -> Result<Q::Hash, E>;
175-
176-
/// Calls `translate_pk` with conversion functions that cannot fail
177-
fn translate_pk_infallible<Fpk, Fpkh>(
178-
&self,
179-
mut translatefpk: Fpk,
180-
mut translatefpkh: Fpkh,
181-
) -> Self::Output
182-
where
183-
Fpk: FnMut(&P) -> Q,
184-
Fpkh: FnMut(&P::Hash) -> Q::Hash,
185-
{
186-
self.translate_pk::<_, _, ()>(|pk| Ok(translatefpk(pk)), |pkh| Ok(translatefpkh(pkh)))
187-
.expect("infallible translation function")
188-
}
189-
}
190-
191-
/// Variant of `TranslatePk` where P and Q both have the same hash
192-
/// type, and the hashes can be converted by just cloning them
193-
pub trait TranslatePk1<P: MiniscriptKey, Q: MiniscriptKey<Hash = P::Hash>>:
194-
TranslatePk<P, Q>
195-
{
196-
/// Translate a struct from one generic to another where the
197-
/// translation for Pk is provided by translatefpk
198-
fn translate_pk1<Fpk, E>(
199-
&self,
200-
translatefpk: Fpk,
201-
) -> Result<<Self as TranslatePk<P, Q>>::Output, E>
202-
where
203-
Fpk: FnMut(&P) -> Result<Q, E>,
204-
{
205-
self.translate_pk(translatefpk, |h| Ok(h.clone()))
206-
}
207-
208-
/// Translate a struct from one generic to another where the
209-
/// translation for Pk is provided by translatefpk
210-
fn translate_pk1_infallible<Fpk: FnMut(&P) -> Q>(
211-
&self,
212-
translatefpk: Fpk,
213-
) -> <Self as TranslatePk<P, Q>>::Output {
214-
self.translate_pk_infallible(translatefpk, P::Hash::clone)
215-
}
216-
}
217-
impl<P: MiniscriptKey, Q: MiniscriptKey<Hash = P::Hash>, T: TranslatePk<P, Q>> TranslatePk1<P, Q>
218-
for T
219-
{
220-
}
221-
222-
/// Variant of `TranslatePk` where P's hash is P, so the hashes
223-
/// can be converted by reusing the key-conversion function
224-
pub trait TranslatePk2<P: MiniscriptKey<Hash = P>, Q: MiniscriptKey>: TranslatePk<P, Q> {
225-
/// Translate a struct from one generic to another where the
226-
/// translation for Pk is provided by translatefpk
227-
fn translate_pk2<Fpk: Fn(&P) -> Result<Q, E>, E>(
228-
&self,
229-
translatefpk: Fpk,
230-
) -> Result<<Self as TranslatePk<P, Q>>::Output, E> {
231-
self.translate_pk(&translatefpk, |h| {
232-
translatefpk(h).map(|q| q.to_pubkeyhash())
233-
})
234-
}
235-
236-
/// Translate a struct from one generic to another where the
237-
/// translation for Pk is provided by translatefpk
238-
fn translate_pk2_infallible<Fpk: Fn(&P) -> Q>(
239-
&self,
240-
translatefpk: Fpk,
241-
) -> <Self as TranslatePk<P, Q>>::Output {
242-
self.translate_pk_infallible(&translatefpk, |h| translatefpk(h).to_pubkeyhash())
243-
}
244-
}
245-
impl<P: MiniscriptKey<Hash = P>, Q: MiniscriptKey, T: TranslatePk<P, Q>> TranslatePk2<P, Q> for T {}
246-
247-
/// Variant of `TranslatePk` where Q's hash is `hash160` so we can
248-
/// derive hashes by calling `hash_to_hash160`
249-
pub trait TranslatePk3<P: MiniscriptKey + ToPublicKey, Q: MiniscriptKey<Hash = hash160::Hash>>:
250-
TranslatePk<P, Q>
251-
{
252-
/// Translate a struct from one generic to another where the
253-
/// translation for Pk is provided by translatefpk
254-
fn translate_pk3<Fpk, E>(
255-
&self,
256-
translatefpk: Fpk,
257-
) -> Result<<Self as TranslatePk<P, Q>>::Output, E>
258-
where
259-
Fpk: FnMut(&P) -> Result<Q, E>,
260-
{
261-
self.translate_pk(translatefpk, |h| Ok(P::hash_to_hash160(h)))
262-
}
263-
264-
/// Translate a struct from one generic to another where the
265-
/// translation for Pk is provided by translatefpk
266-
fn translate_pk3_infallible<Fpk: FnMut(&P) -> Q>(
267-
&self,
268-
translatefpk: Fpk,
269-
) -> <Self as TranslatePk<P, Q>>::Output {
270-
self.translate_pk_infallible(translatefpk, P::hash_to_hash160)
271-
}
272-
}
273-
impl<
274-
P: MiniscriptKey + ToPublicKey,
275-
Q: MiniscriptKey<Hash = hash160::Hash>,
276-
T: TranslatePk<P, Q>,
277-
> TranslatePk3<P, Q> for T
278-
{
279-
}
280-
281151
/// Script descriptor
282152
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
283153
pub enum Descriptor<Pk: MiniscriptKey> {
@@ -680,7 +550,7 @@ serde_string_impl_pk!(Descriptor, "a script descriptor");
680550
#[cfg(test)]
681551
mod tests {
682552
use super::checksum::desc_checksum;
683-
use super::{DescriptorTrait, TranslatePk2};
553+
use super::DescriptorTrait;
684554
use bitcoin::blockdata::opcodes::all::{OP_CLTV, OP_CSV};
685555
use bitcoin::blockdata::script::Instruction;
686556
use bitcoin::blockdata::{opcodes, script};
@@ -697,7 +567,7 @@ mod tests {
697567
use std::cmp;
698568
use std::collections::HashMap;
699569
use std::str::FromStr;
700-
use {Descriptor, DummyKey, Error, Miniscript, Satisfier};
570+
use {Descriptor, DummyKey, Error, Miniscript, Satisfier, TranslatePk2};
701571

702572
#[cfg(feature = "compiler")]
703573
use policy;

src/descriptor/segwitv0.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ use expression::{self, FromTree};
2424
use miniscript::context::{ScriptContext, ScriptContextError};
2525
use policy::{semantic, Liftable};
2626
use util::varint_len;
27-
use {Error, Miniscript, MiniscriptKey, Satisfier, Segwitv0, ToPublicKey};
27+
use {Error, Miniscript, MiniscriptKey, Satisfier, Segwitv0, ToPublicKey, TranslatePk};
2828

2929
use super::{
3030
checksum::{desc_checksum, verify_checksum},
31-
DescriptorTrait, SortedMultiVec, TranslatePk,
31+
DescriptorTrait, SortedMultiVec,
3232
};
3333
/// A Segwitv0 wsh descriptor
3434
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq)]

src/descriptor/sh.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ use miniscript::context::ScriptContext;
2727
use policy::{semantic, Liftable};
2828
use push_opcode_size;
2929
use util::{varint_len, witness_to_scriptsig};
30-
use {Error, Legacy, Miniscript, MiniscriptKey, Satisfier, Segwitv0, ToPublicKey};
30+
use {Error, Legacy, Miniscript, MiniscriptKey, Satisfier, Segwitv0, ToPublicKey, TranslatePk};
3131

3232
use super::{
3333
checksum::{desc_checksum, verify_checksum},
34-
DescriptorTrait, SortedMultiVec, TranslatePk, Wpkh, Wsh,
34+
DescriptorTrait, SortedMultiVec, Wpkh, Wsh,
3535
};
3636

3737
/// A Legacy p2sh Descriptor

src/lib.rs

Lines changed: 125 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ use bitcoin::blockdata::{opcodes, script};
124124
use bitcoin::hashes::{hash160, sha256, Hash};
125125

126126
pub use descriptor::{Descriptor, DescriptorPublicKey, DescriptorTrait};
127-
pub use descriptor::{TranslatePk, TranslatePk1, TranslatePk2, TranslatePk3};
128127
pub use interpreter::Interpreter;
129128
pub use miniscript::context::{BareCtx, Legacy, ScriptContext, Segwitv0};
130129
pub use miniscript::decode::Terminal;
@@ -280,6 +279,131 @@ impl hash::Hash for DummyKeyHash {
280279
}
281280
}
282281

282+
/// Convert a descriptor using abstract keys to one using specific keys
283+
/// This will panic if translatefpk returns an uncompressed key when
284+
/// converting to a Segwit descriptor. To prevent this panic, ensure
285+
/// translatefpk returns an error in this case instead.
286+
pub trait TranslatePk<P: MiniscriptKey, Q: MiniscriptKey> {
287+
/// The associated output type. This must be Self<Q>
288+
type Output;
289+
290+
/// Translate a struct from one Generic to another where the
291+
/// translation for Pk is provided by translatefpk, and translation for
292+
/// PkH is provided by translatefpkh
293+
fn translate_pk<Fpk, Fpkh, E>(
294+
&self,
295+
translatefpk: Fpk,
296+
translatefpkh: Fpkh,
297+
) -> Result<Self::Output, E>
298+
where
299+
Fpk: FnMut(&P) -> Result<Q, E>,
300+
Fpkh: FnMut(&P::Hash) -> Result<Q::Hash, E>;
301+
302+
/// Calls `translate_pk` with conversion functions that cannot fail
303+
fn translate_pk_infallible<Fpk, Fpkh>(
304+
&self,
305+
mut translatefpk: Fpk,
306+
mut translatefpkh: Fpkh,
307+
) -> Self::Output
308+
where
309+
Fpk: FnMut(&P) -> Q,
310+
Fpkh: FnMut(&P::Hash) -> Q::Hash,
311+
{
312+
self.translate_pk::<_, _, ()>(|pk| Ok(translatefpk(pk)), |pkh| Ok(translatefpkh(pkh)))
313+
.expect("infallible translation function")
314+
}
315+
}
316+
317+
/// Variant of `TranslatePk` where P and Q both have the same hash
318+
/// type, and the hashes can be converted by just cloning them
319+
pub trait TranslatePk1<P: MiniscriptKey, Q: MiniscriptKey<Hash = P::Hash>>:
320+
TranslatePk<P, Q>
321+
{
322+
/// Translate a struct from one generic to another where the
323+
/// translation for Pk is provided by translatefpk
324+
fn translate_pk1<Fpk, E>(
325+
&self,
326+
translatefpk: Fpk,
327+
) -> Result<<Self as TranslatePk<P, Q>>::Output, E>
328+
where
329+
Fpk: FnMut(&P) -> Result<Q, E>,
330+
{
331+
self.translate_pk(translatefpk, |h| Ok(h.clone()))
332+
}
333+
334+
/// Translate a struct from one generic to another where the
335+
/// translation for Pk is provided by translatefpk
336+
fn translate_pk1_infallible<Fpk: FnMut(&P) -> Q>(
337+
&self,
338+
translatefpk: Fpk,
339+
) -> <Self as TranslatePk<P, Q>>::Output {
340+
self.translate_pk_infallible(translatefpk, P::Hash::clone)
341+
}
342+
}
343+
impl<P: MiniscriptKey, Q: MiniscriptKey<Hash = P::Hash>, T: TranslatePk<P, Q>> TranslatePk1<P, Q>
344+
for T
345+
{
346+
}
347+
348+
/// Variant of `TranslatePk` where P's hash is P, so the hashes
349+
/// can be converted by reusing the key-conversion function
350+
pub trait TranslatePk2<P: MiniscriptKey<Hash = P>, Q: MiniscriptKey>: TranslatePk<P, Q> {
351+
/// Translate a struct from one generic to another where the
352+
/// translation for Pk is provided by translatefpk
353+
fn translate_pk2<Fpk: Fn(&P) -> Result<Q, E>, E>(
354+
&self,
355+
translatefpk: Fpk,
356+
) -> Result<<Self as TranslatePk<P, Q>>::Output, E> {
357+
self.translate_pk(&translatefpk, |h| {
358+
translatefpk(h).map(|q| q.to_pubkeyhash())
359+
})
360+
}
361+
362+
/// Translate a struct from one generic to another where the
363+
/// translation for Pk is provided by translatefpk
364+
fn translate_pk2_infallible<Fpk: Fn(&P) -> Q>(
365+
&self,
366+
translatefpk: Fpk,
367+
) -> <Self as TranslatePk<P, Q>>::Output {
368+
self.translate_pk_infallible(&translatefpk, |h| translatefpk(h).to_pubkeyhash())
369+
}
370+
}
371+
impl<P: MiniscriptKey<Hash = P>, Q: MiniscriptKey, T: TranslatePk<P, Q>> TranslatePk2<P, Q> for T {}
372+
373+
/// Variant of `TranslatePk` where Q's hash is `hash160` so we can
374+
/// derive hashes by calling `hash_to_hash160`
375+
pub trait TranslatePk3<P: MiniscriptKey + ToPublicKey, Q: MiniscriptKey<Hash = hash160::Hash>>:
376+
TranslatePk<P, Q>
377+
{
378+
/// Translate a struct from one generic to another where the
379+
/// translation for Pk is provided by translatefpk
380+
fn translate_pk3<Fpk, E>(
381+
&self,
382+
translatefpk: Fpk,
383+
) -> Result<<Self as TranslatePk<P, Q>>::Output, E>
384+
where
385+
Fpk: FnMut(&P) -> Result<Q, E>,
386+
{
387+
self.translate_pk(translatefpk, |h| Ok(P::hash_to_hash160(h)))
388+
}
389+
390+
/// Translate a struct from one generic to another where the
391+
/// translation for Pk is provided by translatefpk
392+
fn translate_pk3_infallible<Fpk: FnMut(&P) -> Q>(
393+
&self,
394+
translatefpk: Fpk,
395+
) -> <Self as TranslatePk<P, Q>>::Output {
396+
self.translate_pk_infallible(translatefpk, P::hash_to_hash160)
397+
}
398+
}
399+
impl<
400+
P: MiniscriptKey + ToPublicKey,
401+
Q: MiniscriptKey<Hash = hash160::Hash>,
402+
T: TranslatePk<P, Q>,
403+
> TranslatePk3<P, Q> for T
404+
{
405+
}
406+
283407
/// Miniscript
284408
285409
#[derive(Debug)]

0 commit comments

Comments
 (0)