Skip to content
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

test: Add max_weight_to_satisfy test #673

Closed
Closed
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
60 changes: 60 additions & 0 deletions src/descriptor/bare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -410,3 +410,63 @@ where
}
}
}

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

use crate::interpreter::inner::{Inner, PubkeyType};
use crate::interpreter::BitcoinKey;
use crate::miniscript::context::ScriptContextError::UncompressedKeysNotAllowed;
use crate::Error::{ContextError, Unexpected};
use crate::Interpreter;

fn build_interpreter<'txin>(pk_type: PubkeyType) -> Interpreter<'txin> {
let pk = bitcoin::PublicKey::from_str("042e58afe51f9ed8ad3cc7897f634d881fdbe49a81564629ded8156bebd2ffd1af191923a2964c177f5b5923ae500fca49e99492d534aa3759d6b25a8bc971b133").unwrap();
let bk = BitcoinKey::Fullkey(pk);

let inner = Inner::PublicKey(bk, pk_type);
let stack = crate::interpreter::stack::Stack::from(vec![]);
let script_code: Option<bitcoin::ScriptBuf> = None; // can get from txin
let sequence = bitcoin::Sequence::ZERO; // can get from txin
let lock_time = bitcoin::absolute::LockTime::ZERO;

Interpreter { inner, stack, script_code, sequence, lock_time }
}

#[test]
fn max_weight_to_satisfy_by_key_type() {
// Pk
let max_weight = build_interpreter(PubkeyType::Pk)
.inferred_descriptor()
.unwrap()
.max_weight_to_satisfy()
.unwrap();
assert_eq!(max_weight.to_wu(), 292);

// Pkh
let max_weight = build_interpreter(PubkeyType::Pkh)
.inferred_descriptor()
.unwrap()
.max_weight_to_satisfy()
.unwrap();
assert_eq!(max_weight.to_wu(), 556);

// Wpkh
let e = build_interpreter(PubkeyType::Wpkh).inferred_descriptor();
assert_eq!(e, Err(ContextError(UncompressedKeysNotAllowed)));

// ShWpkh
let e = build_interpreter(PubkeyType::ShWpkh).inferred_descriptor();
assert_eq!(e, Err(ContextError(UncompressedKeysNotAllowed)));

// Tr
let e = build_interpreter(PubkeyType::Tr).inferred_descriptor();
assert_eq!(
e,
Err(Unexpected(
"rawtr_not_supported_yet(1 args) while parsing Miniscript".to_string()
))
);
}
}
12 changes: 11 additions & 1 deletion src/interpreter/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,26 +54,36 @@ fn script_from_stack_elem<Ctx: ScriptContext>(
/// Helper type to indicate the origin of the bare pubkey that the interpereter uses
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum PubkeyType {
/// TODO
Pk,
/// TODO
Pkh,
/// TODO
Wpkh,
/// TODO
ShWpkh,
/// TODO
Tr, // Key Spend
}

/// Helper type to indicate the origin of the bare miniscript that the interpereter uses
#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
pub enum ScriptType {
/// TODO
Bare,
/// TODO
Sh,
/// TODO
Wsh,
/// TODO
ShWsh,
/// TODO
Tr, // Script Spend
}

/// Structure representing a script under evaluation as a Miniscript
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub(super) enum Inner {
pub enum Inner {
/// The script being evaluated is a simple public key check (pay-to-pk,
/// pay-to-pkhash or pay-to-witness-pkhash)
// Technically, this allows representing a (XonlyKey, Sh) output but we make sure
Expand Down
27 changes: 17 additions & 10 deletions src/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ use crate::prelude::*;
use crate::{hash256, Descriptor, Miniscript, Terminal, ToPublicKey};

mod error;
mod inner;
mod stack;
/// TODO
pub mod inner;
/// TODO
pub mod stack;

pub use self::error::Error;
use self::error::PkEvalErrInner;
Expand All @@ -30,13 +32,17 @@ use crate::MiniscriptKey;

/// An iterable Miniscript-structured representation of the spending of a coin
pub struct Interpreter<'txin> {
inner: inner::Inner,
stack: Stack<'txin>,
/// TODO
pub inner: inner::Inner,
/// TODO
pub stack: Stack<'txin>,
/// For non-Taproot spends, the scriptCode; for Taproot script-spends, this
/// is the leaf script; for key-spends it is `None`.
script_code: Option<bitcoin::ScriptBuf>,
sequence: Sequence,
lock_time: absolute::LockTime,
pub script_code: Option<bitcoin::ScriptBuf>,
/// TODO
pub sequence: Sequence,
/// TODO
pub lock_time: absolute::LockTime,
}

// A type representing functions for checking signatures that accept both
Expand Down Expand Up @@ -84,10 +90,11 @@ impl KeySigPair {
// require changing Miniscript struct to three generics Miniscript<Pk, Pkh, Ctx> and bound on
// all of the methods of Miniscript to ensure that Pkh = Pk::Hash
#[derive(Hash, Eq, Ord, PartialEq, PartialOrd, Clone, Copy, Debug)]
enum BitcoinKey {
// Full key
/// TODO
pub enum BitcoinKey {
/// Full key
Fullkey(bitcoin::PublicKey),
// Xonly key
/// Xonly key
XOnlyPublicKey(bitcoin::key::XOnlyPublicKey),
}

Expand Down
Loading