diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d42e5863..78be78542 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# 9.0.2 - July 13, 2023 + +- Workaround for recursion bug in rustc https://github.com/rust-bitcoin/rust-miniscript/pull/566 + # 9.0.1 - March 8, 2023 - Fixed a typing rule in `multi_a` for taproot miniscript descriptors. Current typing rules diff --git a/Cargo.toml b/Cargo.toml index 2ad4b5154..0ff07c140 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "miniscript" -version = "9.0.1" +version = "9.0.2" authors = ["Andrew Poelstra , Sanket Kanjalkar "] license = "CC0-1.0" homepage = "https://github.com/rust-bitcoin/rust-miniscript/" @@ -63,4 +63,4 @@ required-features = ["compiler","std"] [[example]] name = "psbt_sign_finalize" -required-features = ["std"] \ No newline at end of file +required-features = ["std"] diff --git a/src/policy/concrete.rs b/src/policy/concrete.rs index b664c67be..a91545beb 100644 --- a/src/policy/concrete.rs +++ b/src/policy/concrete.rs @@ -657,6 +657,12 @@ impl ForEachKey for Policy { where Pk: 'a, { + self.real_for_each_key(&mut pred) + } +} + +impl Policy { + fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool { match *self { Policy::Unsatisfiable | Policy::Trivial => true, Policy::Key(ref pk) => pred(pk), @@ -667,14 +673,12 @@ impl ForEachKey for Policy { | Policy::After(..) | Policy::Older(..) => true, Policy::Threshold(_, ref subs) | Policy::And(ref subs) => { - subs.iter().all(|sub| sub.for_each_key(&mut pred)) + subs.iter().all(|sub| sub.real_for_each_key(&mut *pred)) } - Policy::Or(ref subs) => subs.iter().all(|(_, sub)| sub.for_each_key(&mut pred)), + Policy::Or(ref subs) => subs.iter().all(|(_, sub)| sub.real_for_each_key(&mut *pred)), } } -} -impl Policy { /// Convert a policy using one kind of public key to another /// type of public key /// @@ -1282,7 +1286,7 @@ fn generate_combination( } #[cfg(all(test, feature = "compiler"))] -mod tests { +mod compiler_tests { use core::str::FromStr; use sync::Arc; @@ -1343,3 +1347,18 @@ mod tests { assert_eq!(combinations, expected_comb); } } + +#[cfg(test)] +mod tests { + use super::*; + use std::str::FromStr; + + #[test] + fn for_each_key() { + let liquid_pol = Policy::::from_str( + "or(and(older(4096),thresh(2,pk(A),pk(B),pk(C))),thresh(11,pk(F1),pk(F2),pk(F3),pk(F4),pk(F5),pk(F6),pk(F7),pk(F8),pk(F9),pk(F10),pk(F11),pk(F12),pk(F13),pk(F14)))").unwrap(); + let mut count = 0; + assert!(liquid_pol.for_each_key(|_| { count +=1; true })); + assert_eq!(count, 17); + } +} diff --git a/src/policy/semantic.rs b/src/policy/semantic.rs index 19855ace1..62a71f1be 100644 --- a/src/policy/semantic.rs +++ b/src/policy/semantic.rs @@ -76,21 +76,25 @@ impl ForEachKey for Policy { where Pk: 'a, { + self.real_for_each_key(&mut pred) + } +} + +impl Policy { + fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool { match *self { Policy::Unsatisfiable | Policy::Trivial => true, - Policy::Key(ref _pkh) => todo!("Semantic Policy KeyHash must store Pk"), + Policy::Key(ref pk) => pred(pk), Policy::Sha256(..) | Policy::Hash256(..) | Policy::Ripemd160(..) | Policy::Hash160(..) | Policy::After(..) | Policy::Older(..) => true, - Policy::Threshold(_, ref subs) => subs.iter().all(|sub| sub.for_each_key(&mut pred)), + Policy::Threshold(_, ref subs) => subs.iter().all(|sub| sub.real_for_each_key(&mut *pred)), } } -} -impl Policy { /// Convert a policy using one kind of public key to another /// type of public key /// @@ -994,4 +998,13 @@ mod tests { assert!(auth_alice.entails(htlc_pol.clone()).unwrap()); assert!(htlc_pol.entails(control_alice).unwrap()); } + + #[test] + fn for_each_key() { + let liquid_pol = StringPolicy::from_str( + "or(and(older(4096),thresh(2,pk(A),pk(B),pk(C))),thresh(11,pk(F1),pk(F2),pk(F3),pk(F4),pk(F5),pk(F6),pk(F7),pk(F8),pk(F9),pk(F10),pk(F11),pk(F12),pk(F13),pk(F14)))").unwrap(); + let mut count = 0; + assert!(liquid_pol.for_each_key(|_| { count +=1; true })); + assert_eq!(count, 17); + } }