Skip to content

Commit fb3f36a

Browse files
committed
Merge #664: Return Weight type for max_weight_to_satisfy methods
7c5f3dc Return Weight type for max_weight_to_satisfy methods (yancy) Pull request description: Return Weight type for max_weight_to_satisfy methods. ACKs for top commit: apoelstra: ACK 7c5f3dc Tree-SHA512: 7e6f32dc1f55927b90ed739f54460546229f1958136bf67418fd738f30c51f674469cf69d2b24cf5e8ff99b152461b289682446f881f6ad6640deb057e3624d3
2 parents 4aaedf5 + 7c5f3dc commit fb3f36a

File tree

9 files changed

+39
-26
lines changed

9 files changed

+39
-26
lines changed

embedded/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ fn main() -> ! {
5151
assert!(desc.sanity_check().is_ok());
5252

5353
// Estimate the satisfaction cost
54-
assert_eq!(desc.max_weight_to_satisfy().unwrap(), 288);
54+
assert_eq!(desc.max_weight_to_satisfy().unwrap().to_wu(), 288);
5555
// end miniscript test
5656

5757
// exit QEMU

examples/sign_multisig.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn main() {
2020
// Check weight for witness satisfaction cost ahead of time.
2121
// 106 (serialized witnessScript)
2222
// + 73*2 (signature length + signatures + sighash bytes) + 1 (dummy byte) = 253
23-
assert_eq!(descriptor.max_weight_to_satisfy().unwrap(), 253);
23+
assert_eq!(descriptor.max_weight_to_satisfy().unwrap().to_wu(), 253);
2424

2525
// Sometimes it is necessary to have additional information to get the
2626
// `bitcoin::PublicKey` from the `MiniscriptKey` which can be supplied by

examples/taproot.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ fn main() {
102102
// max_witness_size = varint(control_block_size) + control_block size +
103103
// varint(script_size) + script_size + max_satisfaction_size
104104
// = 1 + 65 + 1 + 68 + 132 = 269
105-
let max_sat_wt = real_desc.max_weight_to_satisfy().unwrap();
105+
let max_sat_wt = real_desc.max_weight_to_satisfy().unwrap().to_wu();
106106
assert_eq!(max_sat_wt, 267);
107107

108108
// Compute the bitcoin address and check if it matches

src/descriptor/bare.rs

+6-5
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
use core::fmt;
1111

1212
use bitcoin::script::{self, PushBytes};
13-
use bitcoin::{Address, Network, ScriptBuf};
13+
use bitcoin::{Address, Network, ScriptBuf, Weight};
1414

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

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

251252
/// Computes an upper bound on the weight of a satisfying witness to the

src/descriptor/mod.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@ use core::ops::Range;
1616
use core::str::{self, FromStr};
1717

1818
use bitcoin::hashes::{hash160, ripemd160, sha256};
19-
use bitcoin::{secp256k1, Address, Network, Script, ScriptBuf, TxIn, Witness, WitnessVersion};
19+
use bitcoin::{
20+
secp256k1, Address, Network, Script, ScriptBuf, TxIn, Weight, Witness, WitnessVersion,
21+
};
2022
use sync::Arc;
2123

2224
use self::checksum::verify_checksum;
@@ -320,7 +322,7 @@ impl<Pk: MiniscriptKey> Descriptor<Pk> {
320322
///
321323
/// # Errors
322324
/// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
323-
pub fn max_weight_to_satisfy(&self) -> Result<usize, Error> {
325+
pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
324326
let weight = match *self {
325327
Descriptor::Bare(ref bare) => bare.max_weight_to_satisfy()?,
326328
Descriptor::Pkh(ref pkh) => pkh.max_weight_to_satisfy(),

src/descriptor/segwitv0.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
88
use core::fmt;
99

10-
use bitcoin::{Address, Network, ScriptBuf};
10+
use bitcoin::{Address, Network, ScriptBuf, Weight};
1111

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

92-
Ok(stack_varint_diff + varint_len(redeem_script_size) + redeem_script_size + max_sat_size)
92+
Ok(Weight::from_wu(
93+
(stack_varint_diff + varint_len(redeem_script_size) + redeem_script_size + max_sat_size)
94+
as u64,
95+
))
9396
}
9497

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

358361
/// Computes an upper bound on the weight of a satisfying witness to the

src/descriptor/sh.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use core::convert::TryFrom;
1111
use core::fmt;
1212

1313
use bitcoin::script::PushBytes;
14-
use bitcoin::{script, Address, Network, ScriptBuf};
14+
use bitcoin::{script, Address, Network, ScriptBuf, Weight};
1515

1616
use super::checksum::verify_checksum;
1717
use super::{SortedMultiVec, Wpkh, Wsh};
@@ -185,7 +185,7 @@ impl<Pk: MiniscriptKey> Sh<Pk> {
185185
///
186186
/// # Errors
187187
/// When the descriptor is impossible to safisfy (ex: sh(OP_FALSE)).
188-
pub fn max_weight_to_satisfy(&self) -> Result<usize, Error> {
188+
pub fn max_weight_to_satisfy(&self) -> Result<Weight, Error> {
189189
let (scriptsig_size, witness_size) = match self.inner {
190190
// add weighted script sig, len byte stays the same
191191
ShInner::Wsh(ref wsh) => {
@@ -198,7 +198,7 @@ impl<Pk: MiniscriptKey> Sh<Pk> {
198198
let ss = smv.script_size();
199199
let ps = push_opcode_size(ss);
200200
let scriptsig_size = ps + ss + smv.max_satisfaction_size();
201-
(scriptsig_size, 0)
201+
(scriptsig_size, Weight::ZERO)
202202
}
203203
// add weighted script sig, len byte stays the same
204204
ShInner::Wpkh(ref wpkh) => {
@@ -211,14 +211,18 @@ impl<Pk: MiniscriptKey> Sh<Pk> {
211211
let ss = ms.script_size();
212212
let ps = push_opcode_size(ss);
213213
let scriptsig_size = ps + ss + ms.max_satisfaction_size()?;
214-
(scriptsig_size, 0)
214+
(scriptsig_size, Weight::ZERO)
215215
}
216216
};
217217

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

221-
Ok(4 * (scriptsig_varint_diff + scriptsig_size) + witness_size)
221+
let wu = Weight::from_vb((scriptsig_varint_diff + scriptsig_size) as u64);
222+
match wu {
223+
Some(w) => Ok(w + witness_size),
224+
None => Err(Error::CouldNotSatisfy),
225+
}
222226
}
223227

224228
/// Computes an upper bound on the weight of a satisfying witness to the

src/descriptor/tr.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use bitcoin::taproot::{
99
LeafVersion, TaprootBuilder, TaprootSpendInfo, TAPROOT_CONTROL_BASE_SIZE,
1010
TAPROOT_CONTROL_MAX_NODE_COUNT, TAPROOT_CONTROL_NODE_SIZE,
1111
};
12-
use bitcoin::{opcodes, Address, Network, ScriptBuf};
12+
use bitcoin::{opcodes, Address, Network, ScriptBuf, Weight};
1313
use sync::Arc;
1414

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

273-
return Ok(stack_varint_diff + item_sig_size);
273+
return Ok(Weight::from_wu((stack_varint_diff + item_sig_size) as u64));
274274
}
275275
// script path spend..
276276
Some(tree) => tree,
277277
};
278278

279-
tree.iter()
279+
let wu = tree
280+
.iter()
280281
.filter_map(|(depth, ms)| {
281282
let script_size = ms.script_size();
282283
let max_sat_elems = ms.max_satisfaction_witness_elements().ok()?;
@@ -299,7 +300,9 @@ impl<Pk: MiniscriptKey> Tr<Pk> {
299300
)
300301
})
301302
.max()
302-
.ok_or(Error::ImpossibleSatisfaction)
303+
.ok_or(Error::ImpossibleSatisfaction)?;
304+
305+
Ok(Weight::from_wu(wu as u64))
303306
}
304307

305308
/// Computes an upper bound on the weight of a satisfying witness to the

src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@
6969
//! // stackItem[Sig]: varint <sig+sighash>
7070
//! // = 1 + 73 = 74 WU
7171
//! // Expected satisfaction weight: 140 + 74 + 74 = 288
72-
//! assert_eq!(desc.max_weight_to_satisfy().unwrap(), 288);
72+
//! assert_eq!(desc.max_weight_to_satisfy().unwrap().to_wu(), 288);
7373
//! ```
7474
//!
7575

0 commit comments

Comments
 (0)