Skip to content

Commit f728d78

Browse files
committed
fix(policy): fix panic in compile_tr_private_experimental for non-expandable policies
Keep pol_prob_map in sync with tapleaf_prob_vec by removing entries from both data structures together. Previously, removing a node from tapleaf_prob_vec without removing it from pol_prob_map caused a panic when expand_fn returned the same policy (e.g. for pk(A) or and(pk(A),pk(B))). Fixes #902
1 parent 78254b2 commit f728d78

1 file changed

Lines changed: 17 additions & 0 deletions

File tree

src/policy/concrete.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,10 +614,12 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
614614

615615
// Remove current node
616616
assert!(tapleaf_prob_vec.remove(&(prob, curr_policy.clone())));
617+
pol_prob_map.remove(&curr_policy);
617618

618619
// OPTIMIZATION - Move marked nodes into final vector
619620
for (p, pol) in to_del {
620621
assert!(tapleaf_prob_vec.remove(&(Reverse(OrdF64(p)), pol.clone())));
622+
pol_prob_map.remove(&pol);
621623
ret.push((p, pol.clone()));
622624
}
623625

@@ -1276,6 +1278,21 @@ mod compiler_tests {
12761278
// pk(A) promoted to the internal key, leaving the script tree empty
12771279
assert_eq!(desc.to_string(), "tr(A)#xyg3grex");
12781280
}
1281+
1282+
#[test]
1283+
fn compile_tr_private_non_expandable() {
1284+
// Single key: extract_key promotes it, leaving Unsatisfiable
1285+
let pol = Policy::<String>::from_str("pk(A)").unwrap();
1286+
let desc = pol.compile_tr_private_experimental(None).unwrap();
1287+
assert_eq!(desc.to_string(), "tr(A)#xyg3grex");
1288+
1289+
// Two keys: one promoted to internal key, other becomes single leaf
1290+
let pol = Policy::<String>::from_str("and(pk(A),pk(B))").unwrap();
1291+
let desc = pol
1292+
.compile_tr_private_experimental(Some("UNSPENDABLE".to_string()))
1293+
.unwrap();
1294+
assert_eq!(desc.to_string(), "tr(UNSPENDABLE,and_v(v:pk(A),pk(B)))#787dpsca");
1295+
}
12791296
}
12801297

12811298
#[cfg(test)]

0 commit comments

Comments
 (0)