Skip to content

Commit 20066bd

Browse files
committed
checksum: use array::from_fn
Along the way, fix a bunch of other instances of "manual" slice construction that can be done with try_from or from_fn. Instances where the closure to `from_fn` would be several lines long, I left alone, but we could revisit those later. Fixes #774
1 parent df75cbc commit 20066bd

File tree

4 files changed

+14
-36
lines changed

4 files changed

+14
-36
lines changed

src/descriptor/checksum.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
//! [BIP-380]: <https://github.com/bitcoin/bips/blob/master/bip-0380.mediawiki>
99
1010
use core::convert::TryFrom;
11-
use core::fmt;
1211
use core::iter::FromIterator;
12+
use core::{array, fmt};
1313

1414
use bech32::primitives::checksum::PackedFe32;
1515
use bech32::{Checksum, Fe32};
@@ -115,10 +115,10 @@ pub fn verify_checksum(s: &str) -> Result<&str, Error> {
115115
eng.input_unchecked(s[..last_hash_pos].as_bytes());
116116

117117
let expected = eng.checksum_chars();
118-
let mut actual = ['_'; CHECKSUM_LENGTH];
119-
for (act, ch) in actual.iter_mut().zip(checksum_str.chars()) {
120-
*act = ch;
121-
}
118+
119+
let mut iter = checksum_str.chars();
120+
let actual: [char; CHECKSUM_LENGTH] =
121+
array::from_fn(|_| iter.next().expect("length checked above"));
122122

123123
if expected != actual {
124124
return Err(Error::InvalidChecksum { actual, expected });

src/interpreter/inner.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -429,8 +429,7 @@ mod tests {
429429
",
430430
)
431431
.unwrap();
432-
let mut dummy_sig = [0u8; 48];
433-
dummy_sig.copy_from_slice(&dummy_sig_vec[..]);
432+
let dummy_sig = <[u8; 48]>::try_from(&dummy_sig_vec[..]).unwrap();
434433

435434
let pkhash = key.to_pubkeyhash(SigType::Ecdsa).into();
436435
let wpkhash = key.to_pubkeyhash(SigType::Ecdsa).into();

src/interpreter/stack.rs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ impl<'txin> Stack<'txin> {
261261
self.push(Element::Satisfied);
262262
Some(Ok(SatisfiedConstraint::HashLock {
263263
hash: HashLockType::Sha256(*hash),
264-
preimage: preimage_from_sl(preimage),
264+
preimage: <[u8; 32]>::try_from(preimage).expect("length checked above"),
265265
}))
266266
} else {
267267
self.push(Element::Dissatisfied);
@@ -286,7 +286,7 @@ impl<'txin> Stack<'txin> {
286286
self.push(Element::Satisfied);
287287
Some(Ok(SatisfiedConstraint::HashLock {
288288
hash: HashLockType::Hash256(*hash),
289-
preimage: preimage_from_sl(preimage),
289+
preimage: <[u8; 32]>::try_from(preimage).expect("length checked above"),
290290
}))
291291
} else {
292292
self.push(Element::Dissatisfied);
@@ -311,7 +311,7 @@ impl<'txin> Stack<'txin> {
311311
self.push(Element::Satisfied);
312312
Some(Ok(SatisfiedConstraint::HashLock {
313313
hash: HashLockType::Hash160(*hash),
314-
preimage: preimage_from_sl(preimage),
314+
preimage: <[u8; 32]>::try_from(preimage).expect("length checked above"),
315315
}))
316316
} else {
317317
self.push(Element::Dissatisfied);
@@ -336,7 +336,7 @@ impl<'txin> Stack<'txin> {
336336
self.push(Element::Satisfied);
337337
Some(Ok(SatisfiedConstraint::HashLock {
338338
hash: HashLockType::Ripemd160(*hash),
339-
preimage: preimage_from_sl(preimage),
339+
preimage: <[u8; 32]>::try_from(preimage).expect("length checked above"),
340340
}))
341341
} else {
342342
self.push(Element::Dissatisfied);
@@ -376,14 +376,3 @@ impl<'txin> Stack<'txin> {
376376
}
377377
}
378378
}
379-
380-
// Helper function to compute preimage from slice
381-
fn preimage_from_sl(sl: &[u8]) -> [u8; 32] {
382-
if sl.len() != 32 {
383-
unreachable!("Internal: Preimage length checked to be 32")
384-
} else {
385-
let mut preimage = [0u8; 32];
386-
preimage.copy_from_slice(sl);
387-
preimage
388-
}
389-
}

src/psbt/mod.rs

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -340,38 +340,28 @@ impl<Pk: MiniscriptKey + ToPublicKey> Satisfier<Pk> for PsbtInputSatisfier<'_> {
340340
self.psbt.inputs[self.index]
341341
.hash160_preimages
342342
.get(&Pk::to_hash160(h))
343-
.and_then(|x: &Vec<u8>| try_vec_as_preimage32(x))
343+
.and_then(|x: &Vec<u8>| <[u8; 32]>::try_from(&x[..]).ok())
344344
}
345345

346346
fn lookup_sha256(&self, h: &Pk::Sha256) -> Option<Preimage32> {
347347
self.psbt.inputs[self.index]
348348
.sha256_preimages
349349
.get(&Pk::to_sha256(h))
350-
.and_then(|x: &Vec<u8>| try_vec_as_preimage32(x))
350+
.and_then(|x: &Vec<u8>| <[u8; 32]>::try_from(&x[..]).ok())
351351
}
352352

353353
fn lookup_hash256(&self, h: &Pk::Hash256) -> Option<Preimage32> {
354354
self.psbt.inputs[self.index]
355355
.hash256_preimages
356356
.get(&sha256d::Hash::from_byte_array(Pk::to_hash256(h).to_byte_array())) // upstream psbt operates on hash256
357-
.and_then(|x: &Vec<u8>| try_vec_as_preimage32(x))
357+
.and_then(|x: &Vec<u8>| <[u8; 32]>::try_from(&x[..]).ok())
358358
}
359359

360360
fn lookup_ripemd160(&self, h: &Pk::Ripemd160) -> Option<Preimage32> {
361361
self.psbt.inputs[self.index]
362362
.ripemd160_preimages
363363
.get(&Pk::to_ripemd160(h))
364-
.and_then(|x: &Vec<u8>| try_vec_as_preimage32(x))
365-
}
366-
}
367-
368-
fn try_vec_as_preimage32(vec: &[u8]) -> Option<Preimage32> {
369-
if vec.len() == 32 {
370-
let mut arr = [0u8; 32];
371-
arr.copy_from_slice(vec);
372-
Some(arr)
373-
} else {
374-
None
364+
.and_then(|x: &Vec<u8>| <[u8; 32]>::try_from(&x[..]).ok())
375365
}
376366
}
377367

0 commit comments

Comments
 (0)