Skip to content

Fix ForEachKey impls for policies #546

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions src/descriptor/bare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,7 @@ impl_from_str!(
);

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Bare<Pk> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
self.ms.for_each_key(pred)
}
}
Expand Down Expand Up @@ -361,10 +358,7 @@ impl_from_str!(
);

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Pkh<Pk> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
pred(&self.pk)
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/descriptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -536,10 +536,7 @@ where
}

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Descriptor<Pk> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
match *self {
Descriptor::Bare(ref bare) => bare.for_each_key(pred),
Descriptor::Pkh(ref pkh) => pkh.for_each_key(pred),
Expand Down
10 changes: 2 additions & 8 deletions src/descriptor/segwitv0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,10 +267,7 @@ impl_from_str!(
);

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Wsh<Pk> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
match self.inner {
WshInner::SortedMulti(ref smv) => smv.for_each_key(pred),
WshInner::Ms(ref ms) => ms.for_each_key(pred),
Expand Down Expand Up @@ -474,10 +471,7 @@ impl_from_str!(
);

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Wpkh<Pk> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
pred(&self.pk)
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/descriptor/sh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,10 +420,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Sh<Pk> {
}

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Sh<Pk> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
match self.inner {
ShInner::Wsh(ref wsh) => wsh.for_each_key(pred),
ShInner::SortedMulti(ref smv) => smv.for_each_key(pred),
Expand Down
5 changes: 1 addition & 4 deletions src/descriptor/sortedmulti.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
}

impl<Pk: MiniscriptKey, Ctx: ScriptContext> ForEachKey<Pk> for SortedMultiVec<Pk, Ctx> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
self.pks.iter().all(pred)
}
}
Expand Down
5 changes: 1 addition & 4 deletions src/descriptor/tr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -612,10 +612,7 @@ impl<Pk: MiniscriptKey> Liftable<Pk> for Tr<Pk> {
}

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Tr<Pk> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
let script_keys_res = self
.iter_scripts()
.all(|(_d, ms)| ms.for_each_key(&mut pred));
Expand Down
10 changes: 2 additions & 8 deletions src/miniscript/astelem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,7 @@ where
}

impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
pub(super) fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool
where
Pk: 'a,
{
pub(super) fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool {
match *self {
Terminal::PkK(ref p) => pred(p),
Terminal::PkH(ref p) => pred(p),
Expand Down Expand Up @@ -182,10 +179,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
}

impl<Pk: MiniscriptKey, Ctx: ScriptContext> ForEachKey<Pk> for Terminal<Pk, Ctx> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
self.real_for_each_key(&mut pred)
}
}
Expand Down
10 changes: 2 additions & 8 deletions src/miniscript/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,10 +273,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
}

impl<Pk: MiniscriptKey, Ctx: ScriptContext> ForEachKey<Pk> for Miniscript<Pk, Ctx> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
self.real_for_each_key(&mut pred)
}
}
Expand All @@ -300,10 +297,7 @@ where
}

impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool
where
Pk: 'a,
{
fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool {
self.node.real_for_each_key(pred)
}

Expand Down
40 changes: 31 additions & 9 deletions src/policy/concrete.rs
Original file line number Diff line number Diff line change
Expand Up @@ -664,10 +664,13 @@ impl<Pk: MiniscriptKey> PolicyArc<Pk> {
}

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Policy<Pk> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
self.real_for_each_key(&mut pred)
}
}

impl<Pk: MiniscriptKey> Policy<Pk> {
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),
Expand All @@ -678,14 +681,14 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Policy<Pk> {
| 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<Pk: MiniscriptKey> Policy<Pk> {
/// Convert a policy using one kind of public key to another
/// type of public key
///
Expand Down Expand Up @@ -1291,7 +1294,7 @@ fn generate_combination<Pk: MiniscriptKey>(
}

#[cfg(all(test, feature = "compiler"))]
mod tests {
mod compiler_tests {
use core::str::FromStr;

use sync::Arc;
Expand Down Expand Up @@ -1352,3 +1355,22 @@ mod tests {
assert_eq!(combinations, expected_comb);
}
}

#[cfg(test)]
mod tests {
use std::str::FromStr;

use super::*;

#[test]
fn for_each_key() {
let liquid_pol = Policy::<String>::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);
}
}
31 changes: 23 additions & 8 deletions src/policy/semantic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,28 @@ where
}

impl<Pk: MiniscriptKey> ForEachKey<Pk> for Policy<Pk> {
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
where
Pk: 'a,
{
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
self.real_for_each_key(&mut pred)
}
}

impl<Pk: MiniscriptKey> Policy<Pk> {
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<Pk: MiniscriptKey> Policy<Pk> {
/// Convert a policy using one kind of public key to another
/// type of public key
///
Expand Down Expand Up @@ -970,4 +973,16 @@ 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);
}
}