What changed, and why it matters
This commit is a routine code cleanup triggered by new warnings from the Rust linter (Clippy). It replaces hand-written 'round up to next multiple' calculations with Rust's newer built-in `div_ceil` method, and swaps one `map_or(false, ...)` for `is_some_and(...)`. The commit message itself jokes that at least one of these might have been a panic bug, but the actual diff shows no change in behavior or fix for a known crash. There is no disclosed security issue and no evidence this patch addresses an active vulnerability.
No security action required. Treat as normal maintenance. If reviewing, confirm each `div_ceil` site uses unsigned integers and that no overflow edge cases were introduced (none are visible in the diff).
Security signals we found
Refactor only: no functional change in arithmetic semantics
Commit message is speculative, not a vulnerability disclosure
No new tests, no advisory references, no CVE mentioned
Uses standard library helper that is equivalent for unsigned types
Evidence from the diff
The diff is a pure refactor across seven files. In every div_ceil case the old expression (x + d - 1) / d is replaced by x.div_ceil(d), which is mathematically equivalent for the unsigned integer types involved. The is_some_and change in bip32.rs is also semantically identical. No bounds checks, error handling, or public APIs change. The commit message is speculative (‘I’ll bet at least one was actually a panic bug’) and not a security disclosure.
Changed components
bitcoin/src/bip32.rsbitcoin/src/merkle_tree/block.rsbitcoin/src/pow.rshashes/src/hkdf/mod.rshashes/src/sha256/crypto.rsunits/src/amount/mod.rsunits/src/locktime/relative/mod.rsInspect captured patch +10 / −10
diff --git a/bitcoin/src/bip32.rs b/bitcoin/src/bip32.rs
index fa30b130..cb4088d7 100644
--- a/bitcoin/src/bip32.rs
+++ b/bitcoin/src/bip32.rs
@@ -271,7 +271,7 @@ impl FromStr for ChildNumber {
type Err = ParseChildNumberError;
fn from_str(inp: &str) -> Result<Self, Self::Err> {
- let is_hardened = inp.chars().last().map_or(false, |l| l == '\'' || l == 'h');
+ let is_hardened = inp.chars().last().is_some_and(|l| l == '\'' || l == 'h');
Ok(if is_hardened {
ChildNumber::from_hardened_idx(
inp[0..inp.len() - 1].parse().map_err(ParseChildNumberError::ParseInt)?,
diff --git a/bitcoin/src/merkle_tree/block.rs b/bitcoin/src/merkle_tree/block.rs
index 3629585f..01dec4cd 100644
--- a/bitcoin/src/merkle_tree/block.rs
+++ b/bitcoin/src/merkle_tree/block.rs
@@ -271,7 +271,7 @@ impl PartialMerkleTree {
self.traverse_and_extract(height, 0, &mut bits_used, &mut hash_used, matches, indexes)?;
// Verify that all bits were consumed (except for the padding caused by
// serializing it as a byte sequence)
- if (bits_used + 7) / 8 != (self.bits.len() as u32 + 7) / 8 {
+ if bits_used.div_ceil(8) != self.bits.len().div_ceil(8) as u32 {
return Err(NotAllBitsConsumed);
}
// Verify that all hashes were consumed
@@ -409,7 +409,7 @@ impl Encodable for PartialMerkleTree {
let mut ret = self.num_transactions.consensus_encode(w)?;
ret += self.hashes.consensus_encode(w)?;
- let nb_bytes_for_bits = (self.bits.len() + 7) / 8;
+ let nb_bytes_for_bits = self.bits.len().div_ceil(8);
ret += w.emit_compact_size(nb_bytes_for_bits)?;
for chunk in self.bits.chunks(8) {
let mut byte = 0u8;
@@ -588,7 +588,7 @@ mod tests {
let mut height = 1;
let mut ntx = tx_count;
while ntx > 1 {
- ntx = (ntx + 1) / 2;
+ ntx = ntx.div_ceil(2);
height += 1;
}
@@ -616,7 +616,7 @@ mod tests {
// Verify PartialMerkleTree's size guarantees
let n = cmp::min(tx_count, 1 + match_txid1.len() * height);
- assert!(serialized.len() <= 10 + (258 * n + 7) / 8);
+ assert!(serialized.len() <= 10 + (258 * n).div_ceil(8));
// Deserialize into a tester copy
let pmt2: PartialMerkleTree =
diff --git a/bitcoin/src/pow.rs b/bitcoin/src/pow.rs
index eda6329a..cdd16ade 100644
--- a/bitcoin/src/pow.rs
+++ b/bitcoin/src/pow.rs
@@ -196,7 +196,7 @@ impl Target {
/// The compact form is by definition lossy, this means that
/// `t == Target::from_compact(t.to_compact_lossy())` does not always hold.
pub fn to_compact_lossy(self) -> CompactTarget {
- let mut size = (self.0.bits() + 7) / 8;
+ let mut size = self.0.bits().div_ceil(8);
let mut compact = if size <= 3 {
(self.0.low_u64() << (8 * (3 - size))) as u32
} else {
diff --git a/hashes/src/hkdf/mod.rs b/hashes/src/hkdf/mod.rs
index 30a80362..ce789989 100644
--- a/hashes/src/hkdf/mod.rs
+++ b/hashes/src/hkdf/mod.rs
@@ -62,7 +62,7 @@ where
// Counter starts at "1" based on RFC5869 spec and is committed to in the hash.
let mut counter = 1u8;
// Ceiling calculation for the total number of blocks (iterations) required for the expand.
- let total_blocks = (okm.len() + T::Bytes::LEN - 1) / T::Bytes::LEN;
+ let total_blocks = okm.len().div_ceil(T::Bytes::LEN);
while counter <= total_blocks as u8 {
let mut engine: HmacEngine<T> = HmacEngine::new(self.prk.as_ref());
diff --git a/hashes/src/sha256/crypto.rs b/hashes/src/sha256/crypto.rs
index ef4b0f25..8bb0d90c 100644
--- a/hashes/src/sha256/crypto.rs
+++ b/hashes/src/sha256/crypto.rs
@@ -110,7 +110,7 @@ impl Midstate {
0x5be0cd19,
];
- let num_chunks = (bytes.len() + 9 + 63) / 64;
+ let num_chunks = (bytes.len() + 9).div_ceil(64);
let mut chunk = 0;
#[allow(clippy::precedence)]
while chunk < num_chunks {
diff --git a/units/src/amount/mod.rs b/units/src/amount/mod.rs
index 9169ad99..c62d8054 100644
--- a/units/src/amount/mod.rs
+++ b/units/src/amount/mod.rs
@@ -493,7 +493,7 @@ fn fmt_satoshi_in(
(true, false, fmt::Alignment::Left) => (0, width - num_width),
// If the required padding is odd it needs to be skewed to the left
(true, false, fmt::Alignment::Center) =>
- ((width - num_width) / 2, (width - num_width + 1) / 2),
+ ((width - num_width) / 2, (width - num_width).div_ceil(2)),
};
if !options.sign_aware_zero_pad {
diff --git a/units/src/locktime/relative/mod.rs b/units/src/locktime/relative/mod.rs
index c5fcecf5..643e41e2 100644
--- a/units/src/locktime/relative/mod.rs
+++ b/units/src/locktime/relative/mod.rs
@@ -538,7 +538,7 @@ impl NumberOf512Seconds {
#[rustfmt::skip] // moves comments to unrelated code
pub const fn from_seconds_ceil(seconds: u32) -> Result<Self, TimeOverflowError> {
if seconds <= u16::MAX as u32 * 512 {
- let interval = (seconds + 511) / 512;
+ let interval = seconds.div_ceil(512);
Ok(NumberOf512Seconds::from_512_second_intervals(interval as u16)) // Cast checked above, needed by const code.
} else {
Err(TimeOverflowError { seconds })
Why this scored 11/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.