Skip to content

Commit 4109aaf

Browse files
committed
Merge #917: Fix panic in compile_tr_private_experimental for non-expandable policies
f728d78 fix(policy): fix panic in compile_tr_private_experimental for non-expandable policies (Yeji Han) Pull request description: Closes #902. - 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))`). - Adds regression tests for both cases. ACKs for top commit: apoelstra: ACK f728d78; successfully ran local tests Tree-SHA512: da733d9d60329ef909c50fac87675542056fa441cf3bc1bb101581ec89f885dc23cdeafe7786c6414fcb50b0560f1aff17da3dca91604d1acbac117e8607857f
2 parents b2f21d2 + f728d78 commit 4109aaf

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)