Skip to content

Commit b9aa66d

Browse files
authored
Merge pull request #253 from SarcasticNastik/master
2 parents 518f810 + 925ae34 commit b9aa66d

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

src/policy/semantic.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,34 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
499499
ret
500500
}
501501

502+
/// Helper function for recursion in `absolute timelocks`
503+
fn real_absolute_timelocks(&self) -> Vec<u32> {
504+
match *self {
505+
Policy::Unsatisfiable
506+
| Policy::Trivial
507+
| Policy::KeyHash(..)
508+
| Policy::Sha256(..)
509+
| Policy::Hash256(..)
510+
| Policy::Ripemd160(..)
511+
| Policy::Hash160(..) => vec![],
512+
Policy::Older(..) => vec![],
513+
Policy::After(t) => vec![t],
514+
Policy::Threshold(_, ref subs) => subs.iter().fold(vec![], |mut acc, x| {
515+
acc.extend(x.real_absolute_timelocks());
516+
acc
517+
}),
518+
}
519+
}
520+
521+
/// Returns a list of all absolute timelocks, not including 0,
522+
/// which appear in the policy
523+
pub fn absolute_timelocks(&self) -> Vec<u32> {
524+
let mut ret = self.real_absolute_timelocks();
525+
ret.sort();
526+
ret.dedup();
527+
ret
528+
}
529+
502530
/// Filter a policy by eliminating relative timelock constraints
503531
/// that are not satisfied at the given age.
504532
pub fn at_age(mut self, time: u32) -> Policy<Pk> {
@@ -518,6 +546,25 @@ impl<Pk: MiniscriptKey> Policy<Pk> {
518546
self.normalized()
519547
}
520548

549+
/// Filter a policy by eliminating absolute timelock constraints
550+
/// that are not satisfied at the given age.
551+
pub fn at_height(mut self, time: u32) -> Policy<Pk> {
552+
self = match self {
553+
Policy::After(t) => {
554+
if t > time {
555+
Policy::Unsatisfiable
556+
} else {
557+
Policy::After(t)
558+
}
559+
}
560+
Policy::Threshold(k, subs) => {
561+
Policy::Threshold(k, subs.into_iter().map(|sub| sub.at_height(time)).collect())
562+
}
563+
x => x,
564+
};
565+
self.normalized()
566+
}
567+
521568
/// Count the number of public keys and keyhashes referenced in a policy.
522569
/// Duplicate keys will be double-counted.
523570
pub fn n_keys(&self) -> usize {
@@ -604,13 +651,15 @@ mod tests {
604651
let policy = StringPolicy::from_str("pkh()").unwrap();
605652
assert_eq!(policy, Policy::KeyHash("".to_owned()));
606653
assert_eq!(policy.relative_timelocks(), vec![]);
654+
assert_eq!(policy.absolute_timelocks(), vec![]);
607655
assert_eq!(policy.clone().at_age(0), policy.clone());
608656
assert_eq!(policy.clone().at_age(10000), policy.clone());
609657
assert_eq!(policy.n_keys(), 1);
610658
assert_eq!(policy.minimum_n_keys(), 1);
611659

612660
let policy = StringPolicy::from_str("older(1000)").unwrap();
613661
assert_eq!(policy, Policy::Older(1000));
662+
assert_eq!(policy.absolute_timelocks(), vec![]);
614663
assert_eq!(policy.relative_timelocks(), vec![1000]);
615664
assert_eq!(policy.clone().at_age(0), Policy::Unsatisfiable);
616665
assert_eq!(policy.clone().at_age(999), Policy::Unsatisfiable);
@@ -628,6 +677,7 @@ mod tests {
628677
)
629678
);
630679
assert_eq!(policy.relative_timelocks(), vec![1000]);
680+
assert_eq!(policy.absolute_timelocks(), vec![]);
631681
assert_eq!(policy.clone().at_age(0), Policy::KeyHash("".to_owned()));
632682
assert_eq!(policy.clone().at_age(999), Policy::KeyHash("".to_owned()));
633683
assert_eq!(policy.clone().at_age(1000), policy.clone().normalized());
@@ -658,6 +708,17 @@ mod tests {
658708
policy.relative_timelocks(),
659709
vec![1000, 2000, 10000] //sorted and dedup'd
660710
);
711+
712+
let policy = StringPolicy::from_str("after(1000)").unwrap();
713+
assert_eq!(policy, Policy::After(1000));
714+
assert_eq!(policy.absolute_timelocks(), vec![1000]);
715+
assert_eq!(policy.relative_timelocks(), vec![]);
716+
assert_eq!(policy.clone().at_height(0), Policy::Unsatisfiable);
717+
assert_eq!(policy.clone().at_height(999), Policy::Unsatisfiable);
718+
assert_eq!(policy.clone().at_height(1000), policy.clone());
719+
assert_eq!(policy.clone().at_height(10000), policy.clone());
720+
assert_eq!(policy.n_keys(), 0);
721+
assert_eq!(policy.minimum_n_keys(), 0);
661722
}
662723

663724
#[test]

0 commit comments

Comments
 (0)