Skip to content
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 embedded/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn main() -> ! {
assert!(desc.sanity_check().is_ok());

// Estimate the satisfaction cost
assert_eq!(desc.max_weight_to_satisfy().unwrap(), 288);
assert_eq!(desc.max_weight_to_satisfy().unwrap().to_wu(), 288);
// end miniscript test

// exit QEMU
Expand Down
2 changes: 1 addition & 1 deletion examples/sign_multisig.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn main() {
// Check weight for witness satisfaction cost ahead of time.
// 106 (serialized witnessScript)
// + 73*2 (signature length + signatures + sighash bytes) + 1 (dummy byte) = 253
assert_eq!(descriptor.max_weight_to_satisfy().unwrap(), 253);
assert_eq!(descriptor.max_weight_to_satisfy().unwrap().to_wu(), 253);

// Sometimes it is necessary to have additional information to get the
// `bitcoin::PublicKey` from the `MiniscriptKey` which can be supplied by
Expand Down
2 changes: 1 addition & 1 deletion examples/taproot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ fn main() {
// max_witness_size = varint(control_block_size) + control_block size +
// varint(script_size) + script_size + max_satisfaction_size
// = 1 + 65 + 1 + 68 + 132 = 269
let max_sat_wt = real_desc.max_weight_to_satisfy().unwrap();
let max_sat_wt = real_desc.max_weight_to_satisfy().unwrap().to_wu();
assert_eq!(max_sat_wt, 267);

// Compute the bitcoin address and check if it matches
Expand Down
11 changes: 6 additions & 5 deletions src/descriptor/bare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use core::fmt;

use bitcoin::script::{self, PushBytes};
use bitcoin::{Address, Network, ScriptBuf};
use bitcoin::{Address, Network, ScriptBuf, Weight};

use super::checksum::verify_checksum;
use crate::descriptor::{write_descriptor, DefiniteDescriptorKey};
Expand Down Expand Up @@ -67,11 +67,12 @@ impl<Pk: MiniscriptKey> Bare<Pk> {
///
/// # Errors
/// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
pub fn max_weight_to_satisfy(&self) -> Result<usize, Error> {
pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
let scriptsig_size = self.ms.max_satisfaction_size()?;
// scriptSig varint difference between non-satisfied (0) and satisfied
let scriptsig_varint_diff = varint_len(scriptsig_size) - varint_len(0);
Ok(4 * (scriptsig_varint_diff + scriptsig_size))
Weight::from_vb((scriptsig_varint_diff + scriptsig_size) as u64)
.ok_or(Error::CouldNotSatisfy)
}

/// Computes an upper bound on the weight of a satisfying witness to the
Expand Down Expand Up @@ -240,12 +241,12 @@ impl<Pk: MiniscriptKey> Pkh<Pk> {
///
/// # Errors
/// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
pub fn max_weight_to_satisfy(&self) -> usize {
pub fn max_weight_to_satisfy(&self) -> Weight {
// OP_72 + <sig(71)+sigHash(1)> + OP_33 + <pubkey>
let scriptsig_size = 73 + BareCtx::pk_len(&self.pk);
// scriptSig varint different between non-satisfied (0) and satisfied
let scriptsig_varint_diff = varint_len(scriptsig_size) - varint_len(0);
4 * (scriptsig_varint_diff + scriptsig_size)
Weight::from_vb((scriptsig_varint_diff + scriptsig_size) as u64).unwrap()
}

/// Computes an upper bound on the weight of a satisfying witness to the
Expand Down
6 changes: 4 additions & 2 deletions src/descriptor/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ use core::ops::Range;
use core::str::{self, FromStr};

use bitcoin::hashes::{hash160, ripemd160, sha256};
use bitcoin::{secp256k1, Address, Network, Script, ScriptBuf, TxIn, Witness, WitnessVersion};
use bitcoin::{
secp256k1, Address, Network, Script, ScriptBuf, TxIn, Weight, Witness, WitnessVersion,
};
use sync::Arc;

use self::checksum::verify_checksum;
Expand Down Expand Up @@ -320,7 +322,7 @@ impl<Pk: MiniscriptKey> Descriptor<Pk> {
///
/// # Errors
/// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
pub fn max_weight_to_satisfy(&self) -> Result<usize, Error> {
pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
let weight = match *self {
Descriptor::Bare(ref bare) => bare.max_weight_to_satisfy()?,
Descriptor::Pkh(ref pkh) => pkh.max_weight_to_satisfy(),
Expand Down
13 changes: 8 additions & 5 deletions src/descriptor/segwitv0.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

use core::fmt;

use bitcoin::{Address, Network, ScriptBuf};
use bitcoin::{Address, Network, ScriptBuf, Weight};

use super::checksum::verify_checksum;
use super::SortedMultiVec;
Expand Down Expand Up @@ -72,7 +72,7 @@ impl<Pk: MiniscriptKey> Wsh<Pk> {
///
/// # Errors
/// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
pub fn max_weight_to_satisfy(&self) -> Result<usize, Error> {
pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
let (redeem_script_size, max_sat_elems, max_sat_size) = match self.inner {
WshInner::SortedMulti(ref smv) => (
smv.script_size(),
Expand All @@ -89,7 +89,10 @@ impl<Pk: MiniscriptKey> Wsh<Pk> {
// `max_sat_elems` is inclusive of the "witness script" (redeem script)
let stack_varint_diff = varint_len(max_sat_elems) - varint_len(0);

Ok(stack_varint_diff + varint_len(redeem_script_size) + redeem_script_size + max_sat_size)
Ok(Weight::from_wu(
(stack_varint_diff + varint_len(redeem_script_size) + redeem_script_size + max_sat_size)
as u64,
))
}

/// Computes an upper bound on the weight of a satisfying witness to the
Expand Down Expand Up @@ -347,12 +350,12 @@ impl<Pk: MiniscriptKey> Wpkh<Pk> {
///
/// Assumes all ec-signatures are 73 bytes, including push opcode and
/// sighash suffix.
pub fn max_weight_to_satisfy(&self) -> usize {
pub fn max_weight_to_satisfy(&self) -> Weight {
// stack items: <varint(sig+sigHash)> <sig(71)+sigHash(1)> <varint(pubkey)> <pubkey>
let stack_items_size = 73 + Segwitv0::pk_len(&self.pk);
// stackLen varint difference between non-satisfied (0) and satisfied
let stack_varint_diff = varint_len(2) - varint_len(0);
stack_varint_diff + stack_items_size
Weight::from_wu((stack_varint_diff + stack_items_size) as u64)
}

/// Computes an upper bound on the weight of a satisfying witness to the
Expand Down
14 changes: 9 additions & 5 deletions src/descriptor/sh.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use core::convert::TryFrom;
use core::fmt;

use bitcoin::script::PushBytes;
use bitcoin::{script, Address, Network, ScriptBuf};
use bitcoin::{script, Address, Network, ScriptBuf, Weight};

use super::checksum::verify_checksum;
use super::{SortedMultiVec, Wpkh, Wsh};
Expand Down Expand Up @@ -185,7 +185,7 @@ impl<Pk: MiniscriptKey> Sh<Pk> {
///
/// # Errors
/// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
pub fn max_weight_to_satisfy(&self) -> Result<usize, Error> {
pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
let (scriptsig_size, witness_size) = match self.inner {
// add weighted script sig, len byte stays the same
ShInner::Wsh(ref wsh) => {
Expand All @@ -198,7 +198,7 @@ impl<Pk: MiniscriptKey> Sh<Pk> {
let ss = smv.script_size();
let ps = push_opcode_size(ss);
let scriptsig_size = ps + ss + smv.max_satisfaction_size();
(scriptsig_size, 0)
(scriptsig_size, Weight::ZERO)
}
// add weighted script sig, len byte stays the same
ShInner::Wpkh(ref wpkh) => {
Expand All @@ -211,14 +211,18 @@ impl<Pk: MiniscriptKey> Sh<Pk> {
let ss = ms.script_size();
let ps = push_opcode_size(ss);
let scriptsig_size = ps + ss + ms.max_satisfaction_size()?;
(scriptsig_size, 0)
(scriptsig_size, Weight::ZERO)
}
};

// scriptSigLen varint difference between non-satisfied (0) and satisfied
let scriptsig_varint_diff = varint_len(scriptsig_size) - varint_len(0);

Ok(4 * (scriptsig_varint_diff + scriptsig_size) + witness_size)
let wu = Weight::from_vb((scriptsig_varint_diff + scriptsig_size) as u64);
match wu {
Some(w) => Ok(w + witness_size),
None => Err(Error::CouldNotSatisfy),
}
}

/// Computes an upper bound on the weight of a satisfying witness to the
Expand Down
13 changes: 8 additions & 5 deletions src/descriptor/tr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use bitcoin::taproot::{
LeafVersion, TaprootBuilder, TaprootSpendInfo, TAPROOT_CONTROL_BASE_SIZE,
TAPROOT_CONTROL_MAX_NODE_COUNT, TAPROOT_CONTROL_NODE_SIZE,
};
use bitcoin::{opcodes, Address, Network, ScriptBuf};
use bitcoin::{opcodes, Address, Network, ScriptBuf, Weight};
use sync::Arc;

use super::checksum::{self, verify_checksum};
Expand Down Expand Up @@ -261,7 +261,7 @@ impl<Pk: MiniscriptKey> Tr<Pk> {
///
/// # Errors
/// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
pub fn max_weight_to_satisfy(&self) -> Result<usize, Error> {
pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
let tree = match self.tap_tree() {
None => {
// key spend path
Expand All @@ -270,13 +270,14 @@ impl<Pk: MiniscriptKey> Tr<Pk> {
// 1 stack item
let stack_varint_diff = varint_len(1) - varint_len(0);

return Ok(stack_varint_diff + item_sig_size);
return Ok(Weight::from_wu((stack_varint_diff + item_sig_size) as u64));
}
// script path spend..
Some(tree) => tree,
};

tree.iter()
let wu = tree
.iter()
.filter_map(|(depth, ms)| {
let script_size = ms.script_size();
let max_sat_elems = ms.max_satisfaction_witness_elements().ok()?;
Expand All @@ -299,7 +300,9 @@ impl<Pk: MiniscriptKey> Tr<Pk> {
)
})
.max()
.ok_or(Error::ImpossibleSatisfaction)
.ok_or(Error::ImpossibleSatisfaction)?;

Ok(Weight::from_wu(wu as u64))
}

/// Computes an upper bound on the weight of a satisfying witness to the
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
//! // stackItem[Sig]: varint <sig+sighash>
//! // = 1 + 73 = 74 WU
//! // Expected satisfaction weight: 140 + 74 + 74 = 288
//! assert_eq!(desc.max_weight_to_satisfy().unwrap(), 288);
//! assert_eq!(desc.max_weight_to_satisfy().unwrap().to_wu(), 288);
//! ```
//!

Expand Down