Skip to content

Compiler #29

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 3 commits into from
Aug 12, 2019
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
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "miniscript"
version = "0.6.0"
version = "0.7.0"
authors = ["Andrew Poelstra <[email protected]>"]
repository = "https://github.com/apoelstra/miniscript"
description = "Miniscript: a subset of Bitcoin Script designed for analysis"
Expand Down
21 changes: 11 additions & 10 deletions fuzz/fuzz_targets/compile_descriptor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,17 @@ fn do_test(data: &[u8]) {
let data_str = String::from_utf8_lossy(data);
if let Ok(pol) = DummyPolicy::from_str(&data_str) {
// Compile
let desc = pol.compile();
// Lift
assert_eq!(desc.clone().lift(), pol.clone().lift());
// Try to roundtrip the output of the compiler
let output = desc.to_string();
if let Ok(desc) = DummyScript::from_str(&output) {
let rtt = desc.to_string();
assert_eq!(output, rtt);
} else {
panic!("compiler output something unparseable: {}", output)
if let Ok(desc) = pol.compile() {
// Lift
assert_eq!(desc.clone().lift(), pol.clone().lift());
// Try to roundtrip the output of the compiler
let output = desc.to_string();
if let Ok(desc) = DummyScript::from_str(&output) {
let rtt = desc.to_string();
assert_eq!(output, rtt);
} else {
panic!("compiler output something unparseable: {}", output)
}
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@ pub enum Error {
BadDescriptor,
///Forward-secp related errors
Secp(secp256k1::Error),
#[cfg(feature = "compiler")]
///Compiler related errors
CompilerError(policy::compiler::CompilerError),
///Interpreter related errors
InterpreterError(descriptor::InterpreterError),
/// Bad Script Sig. As per standardness rules, only pushes are allowed in
Expand Down Expand Up @@ -395,6 +398,8 @@ impl fmt::Display for Error {
Error::BadDescriptor => f.write_str("could not create a descriptor"),
Error::Secp(ref e) => fmt::Display::fmt(e, f),
Error::InterpreterError(ref e) => fmt::Display::fmt(e, f),
#[cfg(feature = "compiler")]
Error::CompilerError(ref e) => fmt::Display::fmt(e, f),
Error::BadScriptSig => f.write_str("Script sig must only consist of pushes"),
Error::NonEmptyWitness => f.write_str("Non empty witness for Pk/Pkh"),
Error::NonEmptyScriptSig => f.write_str("Non empty script sig for segwit spend"),
Expand All @@ -415,6 +420,14 @@ impl From<psbt::Error> for Error {
}
}

#[doc(hidden)]
#[cfg(feature = "compiler")]
impl From<policy::compiler::CompilerError> for Error {
fn from(e: policy::compiler::CompilerError) -> Error {
Error::CompilerError(e)
}
}

/// The size of an encoding of a number in Script
pub fn script_num_size(n: usize) -> usize {
match n {
Expand Down
29 changes: 20 additions & 9 deletions src/miniscript/satisfy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ pub trait Satisfier<Pk: MiniscriptKey + ToPublicKey> {
}

/// Given a keyhash, look up the signature and the associated key
/// Even if signatures for public key Hashes are not available, the users
/// can use this map to provide pkh -> pk mapping which can use useful
/// for dissatisfying pkh.
fn lookup_pkh(&self, p: &Pk::Hash) -> Option<(bitcoin::PublicKey, BitcoinSig)> {
self.lookup_pkh_pk(p)
.and_then(|ref pk| Some((pk.to_public_key(), self.lookup_pk(pk)?)))
Expand Down Expand Up @@ -296,19 +299,19 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfiable<Pk> for Terminal<Pk> {
r.node.satisfy(satisfier, age, height),
) {
(Some(lsat), None) => {
let mut rdissat = r.node.dissatisfy(satisfier).unwrap();
let mut rdissat = r.node.dissatisfy(satisfier)?;
rdissat.extend(lsat);
Some(rdissat)
}
(None, Some(mut rsat)) => {
let ldissat = l.node.dissatisfy(satisfier).unwrap();
let ldissat = l.node.dissatisfy(satisfier)?;
rsat.extend(ldissat);
Some(rsat)
}
(None, None) => None,
(Some(lsat), Some(mut rsat)) => {
let ldissat = l.node.dissatisfy(satisfier).unwrap();
let mut rdissat = r.node.dissatisfy(satisfier).unwrap();
let ldissat = l.node.dissatisfy(satisfier)?;
let mut rdissat = r.node.dissatisfy(satisfier)?;

if l.ty.mall.safe && !r.ty.mall.safe {
rsat.extend(ldissat);
Expand Down Expand Up @@ -339,13 +342,12 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfiable<Pk> for Terminal<Pk> {
(None, None) => None,
(Some(lsat), None) => Some(lsat),
(None, Some(mut rsat)) => {
let ldissat = l.node.dissatisfy(satisfier).unwrap();
let ldissat = l.node.dissatisfy(satisfier)?;
rsat.extend(ldissat);
Some(rsat)
}
(Some(lsat), Some(mut rsat)) => {
let ldissat = l.node.dissatisfy(satisfier).unwrap();

let ldissat = l.node.dissatisfy(satisfier)?;
if l.ty.mall.safe && !r.ty.mall.safe {
rsat.extend(ldissat);
Some(rsat)
Expand Down Expand Up @@ -412,7 +414,7 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfiable<Pk> for Terminal<Pk> {
let mut ret_dis = Vec::with_capacity(subs.len());

for sub in subs.iter().rev() {
let dissat = sub.node.dissatisfy(satisfier).unwrap();
let dissat = sub.node.dissatisfy(satisfier)?;
if let Some(sat) = sub.node.satisfy(satisfier, age, height) {
ret.push(sat);
satisfied += 1;
Expand Down Expand Up @@ -491,7 +493,16 @@ impl<Pk: MiniscriptKey + ToPublicKey> Dissatisfiable<Pk> for Terminal<Pk> {
fn dissatisfy<S: Satisfier<Pk>>(&self, satisfier: &S) -> Option<Vec<Vec<u8>>> {
match *self {
Terminal::Pk(..) => Some(vec![vec![]]),
Terminal::PkH(ref pkh) => satisfier.lookup_pkh_pk_wit(pkh),
Terminal::PkH(ref pkh) => {
let pk1 = satisfier.lookup_pkh_pk_wit(pkh);
let pk2 = satisfier
.lookup_pkh(pkh)
.and_then(|(pk, _sig)| Some(vec![pk.to_bytes()]));
match (pk1, pk2) {
(Some(x), _) | (_, Some(x)) => Some(x),
_ => None,
}
}
Terminal::False => Some(vec![]),
Terminal::AndB(ref left, ref right) => {
let mut ret = right.node.dissatisfy(satisfier)?;
Expand Down
2 changes: 1 addition & 1 deletion src/miniscript/types/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ pub trait Property: Sized {
Terminal::AndOr(ref a, ref b, ref c) => {
let atype = get_child(&a.node, 0)?;
let btype = get_child(&b.node, 1)?;
let ctype = get_child(&c.node, 1)?;
let ctype = get_child(&c.node, 2)?;
wrap_err(Self::and_or(atype, btype, ctype))
}
Terminal::Thresh(k, ref subs) => {
Expand Down
Loading