Skip to content

Commit bf43cd3

Browse files
committed
Merge #546: Fix ForEachKey impls for policies
f2f95fa cargo fmt (Andrew Poelstra) a6340fe remove a bunch of unnecessary where clauses (Andrew Poelstra) 663bc00 concrete: fix infinite recursion in Policy (Andrew Poelstra) 520b9db semantic: fix todo and infinite recursion in Policy (Andrew Poelstra) Pull request description: Our `ForEachKey` impls for the two policy types did not work. Both had an infinite type recursion which meant that if anybody had tried to use them they would not have compiled. (Though the fact that this has been happening for at least 2 years with zero bug reports suggests that nobody *has* tried to use them..) Recent Rust compiler nightlies have started failing compilation even when the offending impls are *not* used, which means we need to prioritize fixing this. Possibly we should even backport it. Fixes #541 ACKs for top commit: sanket1729: ACK f2f95fa Tree-SHA512: a5d673929cd43187b157cd09941e9f922c605668085870d849fff84a404cb19dbc64694d1c173d4dcb5ff0d85dff450de1c6c6d4ceae038971dafca88ba40447
2 parents 7c28bd3 + f2f95fa commit bf43cd3

File tree

10 files changed

+66
-65
lines changed

10 files changed

+66
-65
lines changed

src/descriptor/bare.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,7 @@ impl_from_str!(
176176
);
177177

178178
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Bare<Pk> {
179-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
180-
where
181-
Pk: 'a,
182-
{
179+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
183180
self.ms.for_each_key(pred)
184181
}
185182
}
@@ -361,10 +358,7 @@ impl_from_str!(
361358
);
362359

363360
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Pkh<Pk> {
364-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
365-
where
366-
Pk: 'a,
367-
{
361+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
368362
pred(&self.pk)
369363
}
370364
}

src/descriptor/mod.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,7 @@ where
536536
}
537537

538538
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Descriptor<Pk> {
539-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
540-
where
541-
Pk: 'a,
542-
{
539+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
543540
match *self {
544541
Descriptor::Bare(ref bare) => bare.for_each_key(pred),
545542
Descriptor::Pkh(ref pkh) => pkh.for_each_key(pred),

src/descriptor/segwitv0.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -267,10 +267,7 @@ impl_from_str!(
267267
);
268268

269269
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Wsh<Pk> {
270-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
271-
where
272-
Pk: 'a,
273-
{
270+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
274271
match self.inner {
275272
WshInner::SortedMulti(ref smv) => smv.for_each_key(pred),
276273
WshInner::Ms(ref ms) => ms.for_each_key(pred),
@@ -474,10 +471,7 @@ impl_from_str!(
474471
);
475472

476473
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Wpkh<Pk> {
477-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
478-
where
479-
Pk: 'a,
480-
{
474+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
481475
pred(&self.pk)
482476
}
483477
}

src/descriptor/sh.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -420,10 +420,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Sh<Pk> {
420420
}
421421

422422
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Sh<Pk> {
423-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
424-
where
425-
Pk: 'a,
426-
{
423+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
427424
match self.inner {
428425
ShInner::Wsh(ref wsh) => wsh.for_each_key(pred),
429426
ShInner::SortedMulti(ref smv) => smv.for_each_key(pred),

src/descriptor/sortedmulti.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,10 +102,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> SortedMultiVec<Pk, Ctx> {
102102
}
103103

104104
impl<Pk: MiniscriptKey, Ctx: ScriptContext> ForEachKey<Pk> for SortedMultiVec<Pk, Ctx> {
105-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool
106-
where
107-
Pk: 'a,
108-
{
105+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: F) -> bool {
109106
self.pks.iter().all(pred)
110107
}
111108
}

src/descriptor/tr.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -612,10 +612,7 @@ impl<Pk: MiniscriptKey> Liftable<Pk> for Tr<Pk> {
612612
}
613613

614614
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Tr<Pk> {
615-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
616-
where
617-
Pk: 'a,
618-
{
615+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
619616
let script_keys_res = self
620617
.iter_scripts()
621618
.all(|(_d, ms)| ms.for_each_key(&mut pred));

src/miniscript/astelem.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,7 @@ where
6464
}
6565

6666
impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
67-
pub(super) fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool
68-
where
69-
Pk: 'a,
70-
{
67+
pub(super) fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool {
7168
match *self {
7269
Terminal::PkK(ref p) => pred(p),
7370
Terminal::PkH(ref p) => pred(p),
@@ -182,10 +179,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Terminal<Pk, Ctx> {
182179
}
183180

184181
impl<Pk: MiniscriptKey, Ctx: ScriptContext> ForEachKey<Pk> for Terminal<Pk, Ctx> {
185-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
186-
where
187-
Pk: 'a,
188-
{
182+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
189183
self.real_for_each_key(&mut pred)
190184
}
191185
}

src/miniscript/mod.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,7 @@ impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
273273
}
274274

275275
impl<Pk: MiniscriptKey, Ctx: ScriptContext> ForEachKey<Pk> for Miniscript<Pk, Ctx> {
276-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
277-
where
278-
Pk: 'a,
279-
{
276+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
280277
self.real_for_each_key(&mut pred)
281278
}
282279
}
@@ -300,10 +297,7 @@ where
300297
}
301298

302299
impl<Pk: MiniscriptKey, Ctx: ScriptContext> Miniscript<Pk, Ctx> {
303-
fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool
304-
where
305-
Pk: 'a,
306-
{
300+
fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool {
307301
self.node.real_for_each_key(pred)
308302
}
309303

src/policy/concrete.rs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -664,10 +664,13 @@ impl<Pk: MiniscriptKey> PolicyArc<Pk> {
664664
}
665665

666666
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Policy<Pk> {
667-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
668-
where
669-
Pk: 'a,
670-
{
667+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
668+
self.real_for_each_key(&mut pred)
669+
}
670+
}
671+
672+
impl<Pk: MiniscriptKey> Policy<Pk> {
673+
fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool {
671674
match *self {
672675
Policy::Unsatisfiable | Policy::Trivial => true,
673676
Policy::Key(ref pk) => pred(pk),
@@ -678,14 +681,14 @@ impl<Pk: MiniscriptKey> ForEachKey<Pk> for Policy<Pk> {
678681
| Policy::After(..)
679682
| Policy::Older(..) => true,
680683
Policy::Threshold(_, ref subs) | Policy::And(ref subs) => {
681-
subs.iter().all(|sub| sub.for_each_key(&mut pred))
684+
subs.iter().all(|sub| sub.real_for_each_key(&mut *pred))
682685
}
683-
Policy::Or(ref subs) => subs.iter().all(|(_, sub)| sub.for_each_key(&mut pred)),
686+
Policy::Or(ref subs) => subs
687+
.iter()
688+
.all(|(_, sub)| sub.real_for_each_key(&mut *pred)),
684689
}
685690
}
686-
}
687691

688-
impl<Pk: MiniscriptKey> Policy<Pk> {
689692
/// Convert a policy using one kind of public key to another
690693
/// type of public key
691694
///
@@ -1291,7 +1294,7 @@ fn generate_combination<Pk: MiniscriptKey>(
12911294
}
12921295

12931296
#[cfg(all(test, feature = "compiler"))]
1294-
mod tests {
1297+
mod compiler_tests {
12951298
use core::str::FromStr;
12961299

12971300
use sync::Arc;
@@ -1352,3 +1355,22 @@ mod tests {
13521355
assert_eq!(combinations, expected_comb);
13531356
}
13541357
}
1358+
1359+
#[cfg(test)]
1360+
mod tests {
1361+
use std::str::FromStr;
1362+
1363+
use super::*;
1364+
1365+
#[test]
1366+
fn for_each_key() {
1367+
let liquid_pol = Policy::<String>::from_str(
1368+
"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();
1369+
let mut count = 0;
1370+
assert!(liquid_pol.for_each_key(|_| {
1371+
count += 1;
1372+
true
1373+
}));
1374+
assert_eq!(count, 17);
1375+
}
1376+
}

src/policy/semantic.rs

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,25 +61,28 @@ where
6161
}
6262

6363
impl<Pk: MiniscriptKey> ForEachKey<Pk> for Policy<Pk> {
64-
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool
65-
where
66-
Pk: 'a,
67-
{
64+
fn for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, mut pred: F) -> bool {
65+
self.real_for_each_key(&mut pred)
66+
}
67+
}
68+
69+
impl<Pk: MiniscriptKey> Policy<Pk> {
70+
fn real_for_each_key<'a, F: FnMut(&'a Pk) -> bool>(&'a self, pred: &mut F) -> bool {
6871
match *self {
6972
Policy::Unsatisfiable | Policy::Trivial => true,
70-
Policy::Key(ref _pkh) => todo!("Semantic Policy KeyHash must store Pk"),
73+
Policy::Key(ref pk) => pred(pk),
7174
Policy::Sha256(..)
7275
| Policy::Hash256(..)
7376
| Policy::Ripemd160(..)
7477
| Policy::Hash160(..)
7578
| Policy::After(..)
7679
| Policy::Older(..) => true,
77-
Policy::Threshold(_, ref subs) => subs.iter().all(|sub| sub.for_each_key(&mut pred)),
80+
Policy::Threshold(_, ref subs) => {
81+
subs.iter().all(|sub| sub.real_for_each_key(&mut *pred))
82+
}
7883
}
7984
}
80-
}
8185

82-
impl<Pk: MiniscriptKey> Policy<Pk> {
8386
/// Convert a policy using one kind of public key to another
8487
/// type of public key
8588
///
@@ -970,4 +973,16 @@ mod tests {
970973
assert!(auth_alice.entails(htlc_pol.clone()).unwrap());
971974
assert!(htlc_pol.entails(control_alice).unwrap());
972975
}
976+
977+
#[test]
978+
fn for_each_key() {
979+
let liquid_pol = StringPolicy::from_str(
980+
"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();
981+
let mut count = 0;
982+
assert!(liquid_pol.for_each_key(|_| {
983+
count += 1;
984+
true
985+
}));
986+
assert_eq!(count, 17);
987+
}
973988
}

0 commit comments

Comments
 (0)