Skip to content

Commit d1dadc6

Browse files
committed
fuzz: add regression test for taptree behavior
This fuzztest currently does almost nothing, because both 12.x and master just pass through to rust-bitcoin's `TapRootSpendInfo` structure for everything related to taptrees. In a later PR we will move all this stuff into rust-miniscript and then we will want a regression test.
1 parent e0e6338 commit d1dadc6

File tree

4 files changed

+82
-3
lines changed

4 files changed

+82
-3
lines changed

.github/workflows/cron-daily-fuzz.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ parse_descriptor,
2525
parse_descriptor_priv,
2626
parse_descriptor_secret,
2727
regression_descriptor_parse,
28+
regression_taptree,
2829
roundtrip_concrete,
2930
roundtrip_descriptor,
3031
roundtrip_miniscript_script,

fuzz/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ path = "fuzz_targets/parse_descriptor_secret.rs"
4646
name = "regression_descriptor_parse"
4747
path = "fuzz_targets/regression_descriptor_parse.rs"
4848

49+
[[bin]]
50+
name = "regression_taptree"
51+
path = "fuzz_targets/regression_taptree.rs"
52+
4953
[[bin]]
5054
name = "roundtrip_concrete"
5155
path = "fuzz_targets/roundtrip_concrete.rs"
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
use descriptor_fuzz::FuzzPk;
2+
use honggfuzz::fuzz;
3+
use miniscript::descriptor::Tr;
4+
use old_miniscript::descriptor::Tr as OldTr;
5+
6+
fn do_test(data: &[u8]) {
7+
let data_str = String::from_utf8_lossy(data);
8+
match (data_str.parse::<Tr<FuzzPk>>(), data_str.parse::<OldTr<FuzzPk>>()) {
9+
(Err(_), Err(_)) => {}
10+
(Ok(_), Err(_)) => {} // 12.x logic rejects some parses for sanity reasons
11+
(Err(e), Ok(x)) => panic!("old logic parses {} as {:?}, new fails with {}", data_str, x, e),
12+
(Ok(new), Ok(old)) => {
13+
let new_si = new.spend_info();
14+
let old_si = old.spend_info();
15+
assert_eq!(
16+
old_si.internal_key(),
17+
new_si.internal_key(),
18+
"merkle root mismatch (left is old, new is right)",
19+
);
20+
assert_eq!(
21+
old_si.merkle_root(),
22+
new_si.merkle_root(),
23+
"merkle root mismatch (left is old, new is right)",
24+
);
25+
assert_eq!(
26+
old_si.output_key(),
27+
new_si.output_key(),
28+
"merkle root mismatch (left is old, new is right)",
29+
);
30+
}
31+
}
32+
}
33+
34+
fn main() {
35+
loop {
36+
fuzz!(|data| {
37+
do_test(data);
38+
});
39+
}
40+
}
41+
42+
#[cfg(test)]
43+
mod tests {
44+
#[test]
45+
fn duplicate_crash() { crate::do_test(b"tr(0,{0,0})"); }
46+
}

fuzz/src/lib.rs

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,42 @@ impl MiniscriptKey for FuzzPk {
4242
type Hash256 = u8;
4343
}
4444

45+
impl ToPublicKey for FuzzPk {
46+
fn to_public_key(&self) -> PublicKey {
47+
let secp_pk = secp256k1::PublicKey::from_slice(&[
48+
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x78,
49+
0xce, 0x56, 0x3f, 0x89, 0xa0, 0xed, 0x94, 0x14, 0xf5, 0xaa, 0x28, 0xad, 0x0d, 0x96,
50+
0xd6, 0x79, 0x5f, 0x9c, 0x63, 0x3f, 0x39, 0x79, 0xbf, 0x72, 0xae, 0x82, 0x02, 0x98,
51+
0x3d, 0xc9, 0x89, 0xae, 0xc7, 0xf2, 0xff, 0x2e, 0xd9, 0x1b, 0xdd, 0x69, 0xce, 0x02,
52+
0xfc, 0x07, 0x00, 0xca, 0x10, 0x0e, 0x59, 0xdd, 0xf3,
53+
])
54+
.unwrap();
55+
PublicKey { inner: secp_pk, compressed: self.compressed }
56+
}
57+
58+
fn to_sha256(hash: &Self::Sha256) -> sha256::Hash { sha256::Hash::from_byte_array([*hash; 32]) }
59+
60+
fn to_hash256(hash: &Self::Hash256) -> hash256::Hash {
61+
hash256::Hash::from_byte_array([*hash; 32])
62+
}
63+
64+
fn to_ripemd160(hash: &Self::Ripemd160) -> ripemd160::Hash {
65+
ripemd160::Hash::from_byte_array([*hash; 20])
66+
}
67+
68+
fn to_hash160(hash: &Self::Ripemd160) -> hash160::Hash {
69+
hash160::Hash::from_byte_array([*hash; 20])
70+
}
71+
}
72+
4573
impl old_miniscript::MiniscriptKey for FuzzPk {
4674
type Sha256 = u8;
4775
type Ripemd160 = u8;
4876
type Hash160 = u8;
4977
type Hash256 = u8;
5078
}
5179

52-
impl ToPublicKey for FuzzPk {
80+
impl old_miniscript::ToPublicKey for FuzzPk {
5381
fn to_public_key(&self) -> PublicKey {
5482
let secp_pk = secp256k1::PublicKey::from_slice(&[
5583
0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x78,
@@ -64,8 +92,8 @@ impl ToPublicKey for FuzzPk {
6492

6593
fn to_sha256(hash: &Self::Sha256) -> sha256::Hash { sha256::Hash::from_byte_array([*hash; 32]) }
6694

67-
fn to_hash256(hash: &Self::Hash256) -> hash256::Hash {
68-
hash256::Hash::from_byte_array([*hash; 32])
95+
fn to_hash256(hash: &Self::Hash256) -> old_miniscript::hash256::Hash {
96+
old_miniscript::hash256::Hash::from_byte_array([*hash; 32])
6997
}
7098

7199
fn to_ripemd160(hash: &Self::Ripemd160) -> ripemd160::Hash {

0 commit comments

Comments
 (0)