Skip to content

Commit

Permalink
Merge pull request rust-bitcoin#31 from sanket1729/2019-08-opscount
Browse files Browse the repository at this point in the history
Op Code Count for Miniscript
  • Loading branch information
apoelstra committed Aug 21, 2019
2 parents 7de55d8 + 9909d2a commit 974ce40
Show file tree
Hide file tree
Showing 3 changed files with 230 additions and 40 deletions.
144 changes: 144 additions & 0 deletions src/miniscript/types/extra_props.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@

use super::{Error, ErrorKind, Property};
use script_num_size;
use std::cmp;
use MiniscriptKey;
use Terminal;

pub const MAX_OPS_PER_SCRIPT: usize = 201;

/// Whether a fragment is OK to be used in non-segwit scripts
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
pub enum LegacySafe {
Expand All @@ -31,6 +34,12 @@ pub struct ExtData {
pub pk_cost: usize,
/// Whether this fragment can be verify-wrapped for free
pub has_verify_form: bool,
/// The worst case static(unexecuted) ops-count for this Miniscript fragment.
pub ops_count_static: usize,
/// The worst case ops-count for satisfying this Miniscript fragment.
pub ops_count_sat: Option<usize>,
/// The worst case ops-count for dissatisfying this Miniscript fragment.
pub ops_count_nsat: Option<usize>,
}

impl Property for ExtData {
Expand All @@ -43,6 +52,9 @@ impl Property for ExtData {
legacy_safe: LegacySafe::LegacySafe,
pk_cost: 1,
has_verify_form: false,
ops_count_static: 0,
ops_count_sat: Some(0),
ops_count_nsat: None,
}
}

Expand All @@ -51,6 +63,9 @@ impl Property for ExtData {
legacy_safe: LegacySafe::LegacySafe,
pk_cost: 1,
has_verify_form: false,
ops_count_static: 0,
ops_count_sat: None,
ops_count_nsat: Some(0),
}
}

Expand All @@ -59,6 +74,9 @@ impl Property for ExtData {
legacy_safe: LegacySafe::LegacySafe,
pk_cost: 34,
has_verify_form: false,
ops_count_static: 0,
ops_count_sat: Some(0),
ops_count_nsat: Some(0),
}
}

Expand All @@ -67,6 +85,9 @@ impl Property for ExtData {
legacy_safe: LegacySafe::SegwitOnly,
pk_cost: 24,
has_verify_form: false,
ops_count_static: 3,
ops_count_sat: Some(3),
ops_count_nsat: Some(3),
}
}

Expand All @@ -81,6 +102,9 @@ impl Property for ExtData {
legacy_safe: LegacySafe::LegacySafe,
pk_cost: num_cost + 34 * n + 1,
has_verify_form: true,
ops_count_static: 1,
ops_count_sat: Some(n + 1),
ops_count_nsat: Some(n + 1),
}
}

Expand All @@ -94,6 +118,9 @@ impl Property for ExtData {
legacy_safe: LegacySafe::LegacySafe,
pk_cost: 33 + 6,
has_verify_form: true,
ops_count_static: 3,
ops_count_sat: Some(3),
ops_count_nsat: Some(3),
}
}

Expand All @@ -102,6 +129,9 @@ impl Property for ExtData {
legacy_safe: LegacySafe::LegacySafe,
pk_cost: 33 + 6,
has_verify_form: true,
ops_count_static: 3,
ops_count_sat: Some(3),
ops_count_nsat: Some(3),
}
}

Expand All @@ -110,6 +140,9 @@ impl Property for ExtData {
legacy_safe: LegacySafe::LegacySafe,
pk_cost: 21 + 6,
has_verify_form: true,
ops_count_static: 3,
ops_count_sat: Some(3),
ops_count_nsat: Some(3),
}
}

Expand All @@ -118,6 +151,9 @@ impl Property for ExtData {
legacy_safe: LegacySafe::LegacySafe,
pk_cost: 21 + 6,
has_verify_form: true,
ops_count_static: 3,
ops_count_sat: Some(3),
ops_count_nsat: Some(3),
}
}

Expand All @@ -126,13 +162,19 @@ impl Property for ExtData {
legacy_safe: LegacySafe::LegacySafe,
pk_cost: script_num_size(t as usize) + 1,
has_verify_form: false,
ops_count_static: 1,
ops_count_sat: Some(1),
ops_count_nsat: None,
}
}
fn cast_alt(self) -> Result<Self, ErrorKind> {
Ok(ExtData {
legacy_safe: self.legacy_safe,
pk_cost: self.pk_cost + 2,
has_verify_form: false,
ops_count_static: self.ops_count_static + 2,
ops_count_sat: self.ops_count_sat.map(|x| x + 2),
ops_count_nsat: self.ops_count_nsat.map(|x| x + 2),
})
}

Expand All @@ -141,6 +183,9 @@ impl Property for ExtData {
legacy_safe: self.legacy_safe,
pk_cost: self.pk_cost + 1,
has_verify_form: self.has_verify_form,
ops_count_static: self.ops_count_static + 1,
ops_count_sat: self.ops_count_sat.map(|x| x + 1),
ops_count_nsat: self.ops_count_nsat.map(|x| x + 1),
})
}

Expand All @@ -149,6 +194,9 @@ impl Property for ExtData {
legacy_safe: self.legacy_safe,
pk_cost: self.pk_cost + 1,
has_verify_form: true,
ops_count_static: self.ops_count_static + 1,
ops_count_sat: self.ops_count_sat.map(|x| x + 1),
ops_count_nsat: self.ops_count_nsat.map(|x| x + 1),
})
}

Expand All @@ -157,14 +205,21 @@ impl Property for ExtData {
legacy_safe: LegacySafe::SegwitOnly,
pk_cost: self.pk_cost + 3,
has_verify_form: false,
ops_count_static: self.ops_count_static + 3,
ops_count_sat: self.ops_count_sat.map(|x| x + 3),
ops_count_nsat: Some(self.ops_count_static + 3),
})
}

fn cast_verify(self) -> Result<Self, ErrorKind> {
let verify_cost = if self.has_verify_form { 0 } else { 1 };
Ok(ExtData {
legacy_safe: self.legacy_safe,
pk_cost: self.pk_cost + if self.has_verify_form { 0 } else { 1 },
has_verify_form: false,
ops_count_static: self.ops_count_static + verify_cost,
ops_count_sat: self.ops_count_sat.map(|x| x + verify_cost),
ops_count_nsat: None,
})
}

Expand All @@ -173,6 +228,9 @@ impl Property for ExtData {
legacy_safe: self.legacy_safe,
pk_cost: self.pk_cost + 4,
has_verify_form: false,
ops_count_static: self.ops_count_static + 4,
ops_count_sat: self.ops_count_sat.map(|x| x + 4),
ops_count_nsat: Some(self.ops_count_static + 4),
})
}

Expand All @@ -181,6 +239,9 @@ impl Property for ExtData {
legacy_safe: self.legacy_safe,
pk_cost: self.pk_cost + 1,
has_verify_form: false,
ops_count_static: self.ops_count_static + 1,
ops_count_sat: self.ops_count_sat.map(|x| x + 1),
ops_count_nsat: self.ops_count_nsat.map(|x| x + 1),
})
}

Expand All @@ -189,6 +250,9 @@ impl Property for ExtData {
legacy_safe: self.legacy_safe,
pk_cost: self.pk_cost + 1,
has_verify_form: false,
ops_count_static: self.ops_count_static,
ops_count_sat: self.ops_count_sat,
ops_count_nsat: None,
})
}

Expand All @@ -202,6 +266,9 @@ impl Property for ExtData {
legacy_safe: self.legacy_safe,
pk_cost: self.pk_cost + 4,
has_verify_form: false,
ops_count_static: self.ops_count_static + 3,
ops_count_sat: self.ops_count_sat.map(|x| x + 3),
ops_count_nsat: Some(self.ops_count_static + 3),
})
}

Expand All @@ -210,6 +277,9 @@ impl Property for ExtData {
legacy_safe: self.legacy_safe,
pk_cost: self.pk_cost + 4,
has_verify_form: false,
ops_count_static: self.ops_count_static + 3,
ops_count_sat: self.ops_count_sat.map(|x| x + 3),
ops_count_nsat: Some(self.ops_count_static + 3),
})
}

Expand All @@ -218,6 +288,13 @@ impl Property for ExtData {
legacy_safe: legacy_safe2(l.legacy_safe, r.legacy_safe),
pk_cost: l.pk_cost + r.pk_cost + 1,
has_verify_form: false,
ops_count_static: l.ops_count_static + r.ops_count_static + 1,
ops_count_sat: l
.ops_count_sat
.and_then(|x| r.ops_count_sat.map(|y| x + y + 1)),
ops_count_nsat: l
.ops_count_nsat
.and_then(|x| r.ops_count_nsat.map(|y| x + y + 1)),
})
}

Expand All @@ -226,6 +303,11 @@ impl Property for ExtData {
legacy_safe: legacy_safe2(l.legacy_safe, r.legacy_safe),
pk_cost: l.pk_cost + r.pk_cost,
has_verify_form: r.has_verify_form,
ops_count_static: l.ops_count_static + r.ops_count_static,
ops_count_sat: l
.ops_count_sat
.and_then(|x| r.ops_count_sat.map(|y| x + y + 1)),
ops_count_nsat: None,
})
}

Expand All @@ -234,6 +316,14 @@ impl Property for ExtData {
legacy_safe: legacy_safe2(l.legacy_safe, r.legacy_safe),
pk_cost: l.pk_cost + r.pk_cost + 1,
has_verify_form: false,
ops_count_static: l.ops_count_static + r.ops_count_static + 1,
ops_count_sat: cmp::max(
l.ops_count_sat.map(|x| x + r.ops_count_nsat.unwrap() + 1),
r.ops_count_sat.map(|x| x + l.ops_count_nsat.unwrap() + 1),
),
ops_count_nsat: l
.ops_count_nsat
.and_then(|x| r.ops_count_nsat.map(|y| x + y + 1)),
})
}

Expand All @@ -242,6 +332,14 @@ impl Property for ExtData {
legacy_safe: LegacySafe::SegwitOnly,
pk_cost: l.pk_cost + r.pk_cost + 3,
has_verify_form: false,
ops_count_static: l.ops_count_static + r.ops_count_static + 1,
ops_count_sat: cmp::max(
l.ops_count_sat.map(|x| x + 3 + r.ops_count_static),
r.ops_count_sat.map(|x| x + l.ops_count_nsat.unwrap() + 3),
),
ops_count_nsat: l
.ops_count_nsat
.and_then(|x| r.ops_count_nsat.map(|y| x + y + 3)),
})
}

Expand All @@ -250,6 +348,12 @@ impl Property for ExtData {
legacy_safe: legacy_safe2(l.legacy_safe, r.legacy_safe),
pk_cost: l.pk_cost + r.pk_cost + 2,
has_verify_form: false,
ops_count_static: l.ops_count_static + r.ops_count_static + 2,
ops_count_sat: cmp::max(
l.ops_count_sat.map(|x| x + 2 + r.ops_count_static),
r.ops_count_sat.map(|x| x + l.ops_count_nsat.unwrap() + 2),
),
ops_count_nsat: None,
})
}

Expand All @@ -258,6 +362,16 @@ impl Property for ExtData {
legacy_safe: legacy_safe2(l.legacy_safe, r.legacy_safe),
pk_cost: l.pk_cost + r.pk_cost + 3,
has_verify_form: false,
ops_count_static: l.ops_count_static + r.ops_count_static + 3,
ops_count_sat: cmp::max(
l.ops_count_sat.map(|x| x + 3 + r.ops_count_static),
r.ops_count_sat.map(|x| x + 3 + l.ops_count_static),
),
ops_count_nsat: match (l.ops_count_nsat, r.ops_count_nsat) {
(Some(a), Some(b)) => Some(cmp::min(a, b)),
(_, Some(x)) | (Some(x), _) => Some(x),
(None, None) => None,
},
})
}

Expand All @@ -266,6 +380,16 @@ impl Property for ExtData {
legacy_safe: legacy_safe2(legacy_safe2(a.legacy_safe, b.legacy_safe), c.legacy_safe),
pk_cost: a.pk_cost + b.pk_cost + c.pk_cost + 3,
has_verify_form: false,
ops_count_static: a.ops_count_static + b.ops_count_static + c.ops_count_static + 3,
ops_count_sat: cmp::max(
a.ops_count_sat
.and_then(|x| b.ops_count_sat.map(|y| x + y + c.ops_count_static + 3)),
c.ops_count_sat
.map(|z| z + b.ops_count_static + a.ops_count_nsat.unwrap() + 3),
),
ops_count_nsat: c
.ops_count_nsat
.map(|z| a.ops_count_nsat.unwrap() + b.ops_count_static + z + 3),
})
}

Expand All @@ -275,15 +399,35 @@ impl Property for ExtData {
{
let mut pk_cost = 1 + script_num_size(k); //Equal and k
let mut legacy_safe = LegacySafe::LegacySafe;
let mut ops_count_static = 0 as usize;
let mut ops_count_sat_vec = Vec::with_capacity(n);
let mut ops_count_nsat = 0 as usize;
for i in 0..n {
let sub = sub_ck(i)?;
pk_cost += sub.pk_cost;
ops_count_static += sub.ops_count_static;
ops_count_nsat += sub.ops_count_nsat.unwrap();
ops_count_sat_vec.push(sub.ops_count_sat.map(|x| x + sub.ops_count_nsat.unwrap()));
legacy_safe = legacy_safe2(legacy_safe, sub.legacy_safe);
}
ops_count_sat_vec.sort();
let mut ops_count_sat = None;
if !ops_count_sat_vec.contains(&None) {
ops_count_sat = Some(
ops_count_sat_vec
.split_off(k)
.iter()
.map(|z| z.unwrap())
.sum(),
);
}
Ok(ExtData {
legacy_safe: legacy_safe,
pk_cost: pk_cost + n - 1, //all pk cost + (n-1)*ADD
has_verify_form: true,
ops_count_static: ops_count_static,
ops_count_sat: ops_count_sat,
ops_count_nsat: Some(ops_count_nsat),
})
}

Expand Down
Loading

0 comments on commit 974ce40

Please sign in to comment.