Skip to content

Commit 928bf29

Browse files
committed
descriptor: make (almost) all methods generic over the extension type
1 parent 9a4a5a0 commit 928bf29

File tree

1 file changed

+31
-32
lines changed

1 file changed

+31
-32
lines changed

src/descriptor/mod.rs

Lines changed: 31 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use elements::{secp256k1_zkp as secp256k1, secp256k1_zkp, Script, TxIn};
3737
use {bitcoin, elements};
3838

3939
use self::checksum::verify_checksum;
40-
use crate::extensions::{CovExtArgs, ExtParam, NoExtParam};
40+
use crate::extensions::{CovExtArgs, ExtParam, ParseableExt};
4141
use crate::miniscript::{Legacy, Miniscript, Segwitv0};
4242
use crate::{
4343
expression, miniscript, BareCtx, CovenantExt, Error, Extension, ExtTranslator, ForEach, ForEachKey,
@@ -245,42 +245,42 @@ pub enum Descriptor<Pk: MiniscriptKey, T: Extension = CovenantExt<CovExtArgs>> {
245245
LegacyCSFSCov(LegacyCSFSCov<Pk, T>),
246246
}
247247

248-
impl<Pk: MiniscriptKey> From<Bare<Pk>> for Descriptor<Pk, CovenantExt<NoExtParam>> {
248+
impl<Pk: MiniscriptKey, Ext: Extension> From<Bare<Pk>> for Descriptor<Pk, Ext> {
249249
#[inline]
250250
fn from(inner: Bare<Pk>) -> Self {
251251
Descriptor::Bare(inner)
252252
}
253253
}
254254

255-
impl<Pk: MiniscriptKey> From<Pkh<Pk>> for Descriptor<Pk, CovenantExt<NoExtParam>> {
255+
impl<Pk: MiniscriptKey, Ext: Extension> From<Pkh<Pk>> for Descriptor<Pk, Ext> {
256256
#[inline]
257257
fn from(inner: Pkh<Pk>) -> Self {
258258
Descriptor::Pkh(inner)
259259
}
260260
}
261261

262-
impl<Pk: MiniscriptKey> From<Wpkh<Pk>> for Descriptor<Pk, CovenantExt<NoExtParam>> {
262+
impl<Pk: MiniscriptKey, Ext: Extension> From<Wpkh<Pk>> for Descriptor<Pk, Ext> {
263263
#[inline]
264264
fn from(inner: Wpkh<Pk>) -> Self {
265265
Descriptor::Wpkh(inner)
266266
}
267267
}
268268

269-
impl<Pk: MiniscriptKey> From<Sh<Pk>> for Descriptor<Pk, CovenantExt<NoExtParam>> {
269+
impl<Pk: MiniscriptKey, Ext: Extension> From<Sh<Pk>> for Descriptor<Pk, Ext> {
270270
#[inline]
271271
fn from(inner: Sh<Pk>) -> Self {
272272
Descriptor::Sh(inner)
273273
}
274274
}
275275

276-
impl<Pk: MiniscriptKey> From<Wsh<Pk>> for Descriptor<Pk, CovenantExt<NoExtParam>> {
276+
impl<Pk: MiniscriptKey, Ext: Extension> From<Wsh<Pk>> for Descriptor<Pk, Ext> {
277277
#[inline]
278278
fn from(inner: Wsh<Pk>) -> Self {
279279
Descriptor::Wsh(inner)
280280
}
281281
}
282282

283-
impl<Pk: MiniscriptKey> From<Tr<Pk, NoExt>> for Descriptor<Pk, CovenantExt<NoExtParam>> {
283+
impl<Pk: MiniscriptKey, Ext: Extension> From<Tr<Pk, NoExt>> for Descriptor<Pk, Ext> {
284284
#[inline]
285285
fn from(inner: Tr<Pk, NoExt>) -> Self {
286286
Descriptor::Tr(inner)
@@ -313,7 +313,7 @@ impl DescriptorType {
313313
}
314314
}
315315

316-
impl<Pk: MiniscriptKey, Arg: ExtParam> Descriptor<Pk, CovenantExt<Arg>> {
316+
impl<Pk: MiniscriptKey, Ext: Extension> Descriptor<Pk, Ext> {
317317
// Keys
318318

319319
/// Create a new pk descriptor
@@ -419,7 +419,7 @@ impl<Pk: MiniscriptKey, Arg: ExtParam> Descriptor<Pk, CovenantExt<Arg>> {
419419
/// Errors when miniscript exceeds resource limits under Tap context
420420
pub fn new_tr_ext(
421421
key: Pk,
422-
script: Option<tr::TapTree<Pk, CovenantExt<Arg>>>,
422+
script: Option<tr::TapTree<Pk, Ext>>,
423423
) -> Result<Self, Error> {
424424
Ok(Descriptor::TrExt(Tr::new(key, script)?))
425425
}
@@ -520,7 +520,7 @@ impl<Pk: MiniscriptKey, Arg: ExtParam> Descriptor<Pk, CovenantExt<Arg>> {
520520
}
521521
}
522522

523-
impl<Pk: MiniscriptKey + ToPublicKey> Descriptor<Pk, CovenantExt<CovExtArgs>> {
523+
impl<Pk: MiniscriptKey + ToPublicKey, Ext: Extension + ParseableExt> Descriptor<Pk, Ext> {
524524
///
525525
/// Obtains the blinded address for this descriptor
526526
///
@@ -774,7 +774,7 @@ impl<Pk: MiniscriptKey, T: Extension> ForEachKey<Pk> for Descriptor<Pk, T> {
774774
}
775775
}
776776

777-
impl Descriptor<DescriptorPublicKey> {
777+
impl<Ext: Extension + ParseableExt> Descriptor<DescriptorPublicKey, Ext> {
778778
/// Whether or not the descriptor has any wildcards
779779
pub fn is_deriveable(&self) -> bool {
780780
self.for_any_key(|key| key.as_key().is_deriveable())
@@ -786,7 +786,7 @@ impl Descriptor<DescriptorPublicKey> {
786786
///
787787
/// In most cases, you would want to use [`Self::derived_descriptor`] directly to obtain
788788
/// a [`Descriptor<bitcoin::PublicKey>`]
789-
pub fn derive(&self, index: u32) -> Descriptor<DerivedDescriptorKey> {
789+
pub fn derive(&self, index: u32) -> Descriptor<DerivedDescriptorKey, Ext> {
790790
struct Derivator(u32);
791791

792792
impl Translator<DescriptorPublicKey, DerivedDescriptorKey, ()> for Derivator {
@@ -834,7 +834,7 @@ impl Descriptor<DescriptorPublicKey> {
834834
&self,
835835
secp: &secp256k1_zkp::Secp256k1<C>,
836836
index: u32,
837-
) -> Result<Descriptor<bitcoin::PublicKey>, ConversionError> {
837+
) -> Result<Descriptor<bitcoin::PublicKey, Ext>, ConversionError> {
838838
struct Derivator<'a, C: secp256k1::Verification>(&'a secp256k1::Secp256k1<C>);
839839

840840
impl<'a, C: secp256k1::Verification>
@@ -871,7 +871,7 @@ impl Descriptor<DescriptorPublicKey> {
871871
pub fn parse_descriptor<C: secp256k1_zkp::Signing>(
872872
secp: &secp256k1_zkp::Secp256k1<C>,
873873
s: &str,
874-
) -> Result<(Descriptor<DescriptorPublicKey>, KeyMap), Error> {
874+
) -> Result<(Descriptor<DescriptorPublicKey, Ext>, KeyMap), Error> {
875875
fn parse_key<C: secp256k1::Signing>(
876876
s: &String,
877877
key_map: &mut KeyMap,
@@ -919,7 +919,7 @@ impl Descriptor<DescriptorPublicKey> {
919919
}
920920
}
921921

922-
let descriptor = Descriptor::<String>::from_str(s)?;
922+
let descriptor = Descriptor::<String, Ext>::from_str(s)?;
923923
let descriptor = descriptor
924924
.translate_pk(&mut keymap_pk)
925925
.map_err(|e| Error::Unexpected(e.to_string()))?;
@@ -960,7 +960,7 @@ impl Descriptor<DescriptorPublicKey> {
960960
}
961961
}
962962

963-
impl Descriptor<DescriptorPublicKey, CovenantExt<CovExtArgs>> {
963+
impl<Ext: Extension + ParseableExt> Descriptor<DescriptorPublicKey, Ext> {
964964
/// Utility method for deriving the descriptor at each index in a range to find one matching
965965
/// `script_pubkey`.
966966
///
@@ -973,12 +973,11 @@ impl Descriptor<DescriptorPublicKey, CovenantExt<CovExtArgs>> {
973973
secp: &secp256k1_zkp::Secp256k1<C>,
974974
script_pubkey: &Script,
975975
range: Range<u32>,
976-
) -> Result<Option<(u32, Descriptor<bitcoin::PublicKey, CovenantExt<CovExtArgs>>)>, ConversionError> {
976+
) -> Result<Option<(u32, Descriptor<bitcoin::PublicKey, Ext>)>, ConversionError> {
977977
let range = if self.is_deriveable() { range } else { 0..1 };
978978

979979
for i in range {
980980
let concrete = self.derived_descriptor(secp, i)?;
981-
println!("{} {} {}", i, &concrete, concrete.script_pubkey());
982981
if &concrete.script_pubkey() == script_pubkey {
983982
return Ok(Some((i, concrete)));
984983
}
@@ -1416,7 +1415,7 @@ mod tests {
14161415
asset_issuance: elements::AssetIssuance::default(),
14171416
witness: elements::TxInWitness::default(),
14181417
};
1419-
let bare = Descriptor::new_bare(ms.clone()).unwrap();
1418+
let bare: Descriptor<_, NoExt> = Descriptor::new_bare(ms.clone()).unwrap();
14201419

14211420
bare.satisfy(&mut txin, &satisfier).expect("satisfaction");
14221421
assert_eq!(
@@ -1428,7 +1427,7 @@ mod tests {
14281427
);
14291428
assert_eq!(bare.unsigned_script_sig(), elements::Script::new());
14301429

1431-
let pkh = Descriptor::new_pkh(pk);
1430+
let pkh: Descriptor<_, NoExt> = Descriptor::new_pkh(pk);
14321431
pkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
14331432
assert_eq!(
14341433
txin,
@@ -1442,15 +1441,15 @@ mod tests {
14421441
);
14431442
assert_eq!(pkh.unsigned_script_sig(), elements::Script::new());
14441443

1445-
let wpkh = Descriptor::new_wpkh(pk).unwrap();
1444+
let wpkh: Descriptor<_, NoExt> = Descriptor::new_wpkh(pk).unwrap();
14461445
wpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
14471446
assert_eq!(
14481447
txin,
14491448
elements_txin(Script::new(), vec![sigser.clone(), pk.to_bytes(),])
14501449
);
14511450
assert_eq!(wpkh.unsigned_script_sig(), elements::Script::new());
14521451

1453-
let shwpkh = Descriptor::new_sh_wpkh(pk).unwrap();
1452+
let shwpkh: Descriptor<_, NoExt> = Descriptor::new_sh_wpkh(pk).unwrap();
14541453
shwpkh.satisfy(&mut txin, &satisfier).expect("satisfaction");
14551454
let redeem_script = script::Builder::new()
14561455
.push_opcode(opcodes::all::OP_PUSHBYTES_0)
@@ -1468,7 +1467,7 @@ mod tests {
14681467
assert_eq!(shwpkh.unsigned_script_sig(), expected_ssig);
14691468

14701469
let ms = ms_str!("c:pk_k({})", pk);
1471-
let sh = Descriptor::new_sh(ms.clone()).unwrap();
1470+
let sh: Descriptor<_, NoExt> = Descriptor::new_sh(ms.clone()).unwrap();
14721471
sh.satisfy(&mut txin, &satisfier).expect("satisfaction");
14731472
let expected_ssig = script::Builder::new()
14741473
.push_slice(&sigser[..])
@@ -1479,7 +1478,7 @@ mod tests {
14791478

14801479
let ms = ms_str!("c:pk_k({})", pk);
14811480

1482-
let wsh = Descriptor::new_wsh(ms.clone()).unwrap();
1481+
let wsh: Descriptor<_, NoExt> = Descriptor::new_wsh(ms.clone()).unwrap();
14831482
wsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
14841483
assert_eq!(
14851484
txin,
@@ -1490,7 +1489,7 @@ mod tests {
14901489
);
14911490
assert_eq!(wsh.unsigned_script_sig(), Script::new());
14921491

1493-
let shwsh = Descriptor::new_sh_wsh(ms.clone()).unwrap();
1492+
let shwsh: Descriptor<_, NoExt> = Descriptor::new_sh_wsh(ms.clone()).unwrap();
14941493
shwsh.satisfy(&mut txin, &satisfier).expect("satisfaction");
14951494
let expected_ssig = script::Builder::new()
14961495
.push_slice(&ms.encode().to_v0_p2wsh()[..])
@@ -1856,15 +1855,15 @@ mod tests {
18561855
#[test]
18571856
fn test_parse_descriptor() {
18581857
let secp = &secp256k1_zkp::Secp256k1::signing_only();
1859-
let (descriptor, key_map) = Descriptor::parse_descriptor(secp, "elwpkh(tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/44'/0'/0'/0/*)").unwrap();
1858+
let (descriptor, key_map) = Descriptor::<_, NoExt>::parse_descriptor(secp, "elwpkh(tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/44'/0'/0'/0/*)").unwrap();
18601859
assert_eq!(descriptor.to_string(), "elwpkh([2cbe2a6d/44'/0'/0']tpubDCvNhURocXGZsLNqWcqD3syHTqPXrMSTwi8feKVwAcpi29oYKsDD3Vex7x2TDneKMVN23RbLprfxB69v94iYqdaYHsVz3kPR37NQXeqouVz/0/*)#pznhhta9");
18611860
assert_eq!(key_map.len(), 1);
18621861

18631862
// https://github.com/bitcoin/bitcoin/blob/7ae86b3c6845873ca96650fc69beb4ae5285c801/src/test/descriptor_tests.cpp#L355-L360
18641863
macro_rules! check_invalid_checksum {
18651864
($secp: ident,$($desc: expr),*) => {
18661865
$(
1867-
match Descriptor::parse_descriptor($secp, $desc) {
1866+
match Descriptor::<_, NoExt>::parse_descriptor($secp, $desc) {
18681867
Err(Error::BadDescriptor(_)) => {},
18691868
Err(e) => panic!("Expected bad checksum for {}, got '{}'", $desc, e),
18701869
_ => panic!("Invalid checksum treated as valid: {}", $desc),
@@ -1886,8 +1885,8 @@ mod tests {
18861885
"elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))##tjq09x4t"
18871886
);
18881887

1889-
Descriptor::parse_descriptor(&secp, "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#9s2ngs7u").expect("Valid descriptor with checksum");
1890-
Descriptor::parse_descriptor(&secp, "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#uklept69").expect("Valid descriptor with checksum");
1888+
Descriptor::<_, NoExt>::parse_descriptor(&secp, "elsh(multi(2,[00000000/111'/222]xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc,xprv9uPDJpEQgRQfDcW7BkF7eTya6RPxXeJCqCJGHuCJ4GiRVLzkTXBAJMu2qaMWPrS7AANYqdq6vcBcBUdJCVVFceUvJFjaPdGZ2y9WACViL4L/0))#9s2ngs7u").expect("Valid descriptor with checksum");
1889+
Descriptor::<_, NoExt>::parse_descriptor(&secp, "elsh(multi(2,[00000000/111'/222]xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL,xpub68NZiKmJWnxxS6aaHmn81bvJeTESw724CRDs6HbuccFQN9Ku14VQrADWgqbhhTHBaohPX4CjNLf9fq9MYo6oDaPPLPxSb7gwQN3ih19Zm4Y/0))#uklept69").expect("Valid descriptor with checksum");
18911890
}
18921891

18931892
#[test]
@@ -1898,7 +1897,7 @@ pk([d34db33f/44'/0'/0']xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgb
18981897
pk(xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL/1),\
18991898
pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
19001899
let policy: policy::concrete::Policy<DescriptorPublicKey> = descriptor_str.parse().unwrap();
1901-
let descriptor = Descriptor::new_sh(policy.compile().unwrap()).unwrap();
1900+
let descriptor = Descriptor::<_, NoExt>::new_sh(policy.compile().unwrap()).unwrap();
19021901
let derived_descriptor = descriptor.derive(42);
19031902

19041903
let res_descriptor_str = "thresh(2,\
@@ -1908,7 +1907,7 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
19081907
let res_policy: policy::concrete::Policy<DescriptorPublicKey> =
19091908
res_descriptor_str.parse().unwrap();
19101909
let res_descriptor =
1911-
Descriptor::<DescriptorPublicKey, CovenantExt<NoExtParam>>::new_sh(res_policy.compile().unwrap())
1910+
Descriptor::<DescriptorPublicKey, NoExt>::new_sh(res_policy.compile().unwrap())
19121911
.unwrap();
19131912

19141913
assert_eq!(res_descriptor.to_string(), derived_descriptor.to_string());
@@ -1958,7 +1957,7 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
19581957
#[test]
19591958
fn test_find_derivation_index_for_spk() {
19601959
let secp = secp256k1_zkp::Secp256k1::verification_only();
1961-
let descriptor = Descriptor::from_str("eltr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)").unwrap();
1960+
let descriptor = Descriptor::<_, NoExt>::from_str("eltr([73c5da0a/86'/0'/0']xpub6BgBgsespWvERF3LHQu6CnqdvfEvtMcQjYrcRzx53QJjSxarj2afYWcLteoGVky7D3UKDP9QyrLprQ3VCECoY49yfdDEHGCtMMj92pReUsQ/0/*)").unwrap();
19621961
let script_at_0_1 = Script::from_str(
19631962
"5120c73ac1b7a518499b9642aed8cfa15d5401e5bd85ad760b937b69521c297722f0",
19641963
)

0 commit comments

Comments
 (0)