From 05d3cc2c1d8a47cd94f911d45d01f9ab35cb1019 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Mon, 21 Apr 2025 20:48:47 +0000 Subject: [PATCH 1/2] descriptor: fix key parsing error handling in parse_desc --- src/descriptor/mod.rs | 2 +- src/lib.rs | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 47da23b8b..9681c1d0f 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -771,7 +771,7 @@ impl Descriptor { let descriptor = Descriptor::::from_str(s)?; let descriptor = descriptor .translate_pk(&mut keymap_pk) - .map_err(|e| e.expect_translator_err("No Outer context errors"))?; + .map_err(TranslateErr::flatten)?; Ok((descriptor, keymap_pk.0)) } diff --git a/src/lib.rs b/src/lib.rs index 3b0c0d3bf..c470a05ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -364,6 +364,17 @@ impl TranslateErr { } } +impl TranslateErr { + /// If we are doing a translation where our "outer error" is the generic + /// Miniscript error, eliminate the `TranslateErr` type which is just noise. + pub fn flatten(self) -> Error { + match self { + Self::TranslatorErr(e) => e, + Self::OuterError(e) => e, + } + } +} + impl From for TranslateErr { fn from(v: E) -> Self { Self::TranslatorErr(v) } } From 6bff186d01bc22e061aba7ea584d55d9faf7a5b3 Mon Sep 17 00:00:00 2001 From: Andrew Poelstra Date: Mon, 21 Apr 2025 20:46:11 +0000 Subject: [PATCH 2/2] add regression test for #806 When parsing a descriptor with `Descriptor::parse_descriptor`, we first parse as a string and then parse the keys. We fail to consider parsing errors in the keys, resulting in a panic. Also, clean up the panic message so it's clearer what's going on. --- src/descriptor/mod.rs | 15 +++++++++++++++ src/lib.rs | 9 +++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/descriptor/mod.rs b/src/descriptor/mod.rs index 9681c1d0f..5c9c5293f 100644 --- a/src/descriptor/mod.rs +++ b/src/descriptor/mod.rs @@ -2168,4 +2168,19 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))"; Desc::from_str(&format!("tr({},pk({}))", x_only_key, uncomp_key)).unwrap_err(); Desc::from_str(&format!("tr({},pk({}))", x_only_key, x_only_key)).unwrap(); } + + #[test] + fn regression_806() { + let secp = secp256k1::Secp256k1::signing_only(); + type Desc = Descriptor; + // OK + Desc::from_str("pkh(111111111111111111111111111111110000008375319363688624584A111111)") + .unwrap_err(); + // ERR: crashes in translate_pk + Desc::parse_descriptor( + &secp, + "pkh(111111111111111111111111111111110000008375319363688624584A111111)", + ) + .unwrap_err(); + } } diff --git a/src/lib.rs b/src/lib.rs index c470a05ea..fb096e430 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -356,10 +356,11 @@ impl TranslateErr { /// /// This function will panic if the Error is OutError. pub fn expect_translator_err(self, msg: &str) -> E { - if let Self::TranslatorErr(v) = self { - v - } else { - panic!("{}", msg) + match self { + Self::TranslatorErr(v) => v, + Self::OuterError(ref e) => { + panic!("Unexpected Miniscript error when translating: {}\nMessage: {}", e, msg) + } } } }