Skip to content

Commit cd1fcfa

Browse files
committed
descriptor: print descriptor's checksum in Display
But not in Debug, as it would be a checksum of the Debug representation of the policy. Signed-off-by: Antoine Poinsot <[email protected]>
1 parent bfc0360 commit cd1fcfa

File tree

3 files changed

+37
-27
lines changed

3 files changed

+37
-27
lines changed

examples/htlc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ fn main() {
4141
assert!(htlc_descriptor.sanity_check().is_ok());
4242
assert_eq!(
4343
format!("{}", htlc_descriptor),
44-
"wsh(andor(pk(022222222222222222222222222222222222222222222222222222222222222222),sha256(1111111111111111111111111111111111111111111111111111111111111111),and_v(v:pkh(51814f108670aced2d77c1805ddd6634bc9d4731),older(4444))))"
44+
"wsh(andor(pk(022222222222222222222222222222222222222222222222222222222222222222),sha256(1111111111111111111111111111111111111111111111111111111111111111),and_v(v:pkh(51814f108670aced2d77c1805ddd6634bc9d4731),older(4444))))#s0qq76ng"
4545
);
4646

4747
assert_eq!(

fuzz/fuzz_targets/roundtrip_descriptor.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::str::FromStr;
88
fn do_test(data: &[u8]) {
99
let s = String::from_utf8_lossy(data);
1010
if let Ok(desc) = Descriptor::<DummyKey>::from_str(&s) {
11-
let output = desc.to_string();
11+
let output = format!("{:?}", desc);
1212

1313
let multi_wrap_pk_re = Regex::new("([a-z]+)c:pk_k\\(").unwrap();
1414
let multi_wrap_pkh_re = Regex::new("([a-z]+)c:pk_h\\(").unwrap();

src/descriptor/mod.rs

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -826,19 +826,22 @@ impl<Pk: MiniscriptKey> fmt::Debug for Descriptor<Pk> {
826826

827827
impl<Pk: MiniscriptKey> fmt::Display for Descriptor<Pk> {
828828
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
829-
match *self {
830-
Descriptor::Bare(ref sub) => write!(f, "{}", sub),
831-
Descriptor::Pk(ref p) => write!(f, "pk({})", p),
832-
Descriptor::Pkh(ref p) => write!(f, "pkh({})", p),
833-
Descriptor::Wpkh(ref p) => write!(f, "wpkh({})", p),
834-
Descriptor::ShWpkh(ref p) => write!(f, "sh(wpkh({}))", p),
835-
Descriptor::Sh(ref sub) => write!(f, "sh({})", sub),
836-
Descriptor::Wsh(ref sub) => write!(f, "wsh({})", sub),
837-
Descriptor::ShWsh(ref sub) => write!(f, "sh(wsh({}))", sub),
838-
Descriptor::ShSortedMulti(ref smv) => write!(f, "sh({})", smv),
839-
Descriptor::WshSortedMulti(ref smv) => write!(f, "wsh({})", smv),
840-
Descriptor::ShWshSortedMulti(ref smv) => write!(f, "sh(wsh({}))", smv),
841-
}
829+
let desc = match *self {
830+
Descriptor::Bare(ref sub) => format!("{}", sub),
831+
Descriptor::Pk(ref p) => format!("pk({})", p),
832+
Descriptor::Pkh(ref p) => format!("pkh({})", p),
833+
Descriptor::Wpkh(ref p) => format!("wpkh({})", p),
834+
Descriptor::ShWpkh(ref p) => format!("sh(wpkh({}))", p),
835+
Descriptor::Sh(ref sub) => format!("sh({})", sub),
836+
Descriptor::Wsh(ref sub) => format!("wsh({})", sub),
837+
Descriptor::ShWsh(ref sub) => format!("sh(wsh({}))", sub),
838+
Descriptor::ShSortedMulti(ref smv) => format!("sh({})", smv),
839+
Descriptor::WshSortedMulti(ref smv) => format!("wsh({})", smv),
840+
Descriptor::ShWshSortedMulti(ref smv) => format!("sh(wsh({}))", smv),
841+
};
842+
let checksum = desc_checksum(&desc).map_err(|_| fmt::Error)?;
843+
844+
write!(f, "{}#{}", &desc, &checksum)
842845
}
843846
}
844847

@@ -1053,7 +1056,7 @@ serde_string_impl_pk!(Descriptor, "a script descriptor");
10531056

10541057
#[cfg(test)]
10551058
mod tests {
1056-
use super::DescriptorPublicKeyCtx;
1059+
use super::{desc_checksum, DescriptorPublicKeyCtx};
10571060
use bitcoin::blockdata::opcodes::all::{OP_CLTV, OP_CSV};
10581061
use bitcoin::blockdata::script::Instruction;
10591062
use bitcoin::blockdata::{opcodes, script};
@@ -1100,7 +1103,14 @@ mod tests {
11001103
let desc = Descriptor::<DummyKey>::from_str(&s).unwrap();
11011104
let output = desc.to_string();
11021105
let normalize_aliases = s.replace("c:pk_k(", "pk(").replace("c:pk_h(", "pkh(");
1103-
assert_eq!(normalize_aliases, output);
1106+
assert_eq!(
1107+
format!(
1108+
"{}#{}",
1109+
&normalize_aliases,
1110+
desc_checksum(&normalize_aliases).unwrap()
1111+
),
1112+
output
1113+
);
11041114
}
11051115

11061116
#[test]
@@ -1763,35 +1773,35 @@ mod tests {
17631773

17641774
// P2SH and pubkeys
17651775
_test_sortedmulti(
1766-
"sh(sortedmulti(1,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352))",
1767-
"sh(sortedmulti(1,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))",
1776+
"sh(sortedmulti(1,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352))#uetvewm2",
1777+
"sh(sortedmulti(1,0250863ad64a87ae8a2fe83c1af1a8403cb53f53e486d8511dad8a04887e5b2352,03fff97bd5755eeea420453a14355235d382f6472f8568a18b2f057a1460297556))#7l8smyg9",
17681778
"3JZJNxvDKe6Y55ZaF5223XHwfF2eoMNnoV",
17691779
);
17701780

17711781
// P2WSH and single-xpub descriptor
17721782
_test_sortedmulti(
1773-
"wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))",
1774-
"wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB))",
1783+
"wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH))#7etm7zk7",
1784+
"wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB))#ppmeel9k",
17751785
"bc1qpq2cfgz5lktxzr5zqv7nrzz46hsvq3492ump9pz8rzcl8wqtwqcspx5y6a",
17761786
);
17771787

17781788
// P2WSH-P2SH and ranged descriptor
17791789
_test_sortedmulti(
1780-
"sh(wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*)))",
1781-
"sh(wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*)))",
1790+
"sh(wsh(sortedmulti(1,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*)))#u60cee0u",
1791+
"sh(wsh(sortedmulti(1,xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH/0/0/*,xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB/1/0/*)))#75dkf44w",
17821792
"325zcVBN5o2eqqqtGwPjmtDd8dJRyYP82s",
17831793
);
17841794
}
17851795

17861796
#[test]
17871797
fn test_parse_descriptor() {
17881798
let (descriptor, key_map) = Descriptor::parse_descriptor("wpkh(tprv8ZgxMBicQKsPcwcD4gSnMti126ZiETsuX7qwrtMypr6FBwAP65puFn4v6c3jrN9VwtMRMph6nyT63NrfUL4C3nBzPcduzVSuHD7zbX2JKVc/44'/0'/0'/0/*)").unwrap();
1789-
assert_eq!(descriptor.to_string(), "wpkh([2cbe2a6d/44'/0'/0']tpubDCvNhURocXGZsLNqWcqD3syHTqPXrMSTwi8feKVwAcpi29oYKsDD3Vex7x2TDneKMVN23RbLprfxB69v94iYqdaYHsVz3kPR37NQXeqouVz/0/*)");
1799+
assert_eq!(descriptor.to_string(), "wpkh([2cbe2a6d/44'/0'/0']tpubDCvNhURocXGZsLNqWcqD3syHTqPXrMSTwi8feKVwAcpi29oYKsDD3Vex7x2TDneKMVN23RbLprfxB69v94iYqdaYHsVz3kPR37NQXeqouVz/0/*)#nhdxg96s");
17901800
assert_eq!(key_map.len(), 1);
17911801

17921802
// https://github.com/bitcoin/bitcoin/blob/7ae86b3c6845873ca96650fc69beb4ae5285c801/src/test/descriptor_tests.cpp#L355-L360
17931803
macro_rules! check_invalid_checksum {
1794-
($($desc: literal),*) => {
1804+
($($desc: expr),*) => {
17951805
$(
17961806
match Descriptor::parse_descriptor($desc) {
17971807
Err(Error::BadDescriptor(_)) => {},
@@ -1844,11 +1854,11 @@ pk(03f28773c2d975288bc7d1d205c3748651b075fbc6610e58cddeeddf8f19405aa8))";
18441854

18451855
#[test]
18461856
fn parse_with_secrets() {
1847-
let descriptor_str = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)";
1857+
let descriptor_str = "wpkh(xprv9s21ZrQH143K4CTb63EaMxja1YiTnSEWKMbn23uoEnAzxjdUJRQkazCAtzxGm4LSoTSVTptoV9RbchnKPW9HxKtZumdyxyikZFDLhogJ5Uj/44'/0'/0'/0/*)#v20xlvm9";
18481858
let (descriptor, keymap) =
18491859
Descriptor::<DescriptorPublicKey>::parse_descriptor(descriptor_str).unwrap();
18501860

1851-
let expected = "wpkh([a12b02f4/44'/0'/0']xpub6BzhLAQUDcBUfHRQHZxDF2AbcJqp4Kaeq6bzJpXrjrWuK26ymTFwkEFbxPra2bJ7yeZKbDjfDeFwxe93JMqpo5SsPJH6dZdvV9kMzJkAZ69/0/*)";
1861+
let expected = "wpkh([a12b02f4/44'/0'/0']xpub6BzhLAQUDcBUfHRQHZxDF2AbcJqp4Kaeq6bzJpXrjrWuK26ymTFwkEFbxPra2bJ7yeZKbDjfDeFwxe93JMqpo5SsPJH6dZdvV9kMzJkAZ69/0/*)#u37l7u8u";
18521862
assert_eq!(expected, descriptor.to_string());
18531863
assert_eq!(keymap.len(), 1);
18541864

0 commit comments

Comments
 (0)