Context
PR #5500 replaced the panicking + 1 arithmetic in ethexe/malachite/core/src/streaming.rs:101 with (msg.sequence as usize).saturating_add(1). This closes the Fin@u64::MAX panic / silent-wrap path on our supported (64-bit) targets.
A follow-up review note from Gemini surfaced a residual concern about the as usize cast itself:
The as usize cast for the peer-controlled u64 sequence can truncate on 32-bit platforms (e.g., wasm32), potentially triggering a premature is_done() completion with incomplete data.
Why this is open and not closed in PR #5500
- ethexe-service today only targets 64-bit Linux / macOS / Windows. On those,
usize == u64, so msg.sequence as usize is a no-op cast and the saturating add covers the original failure modes.
- The malachite consensus engine is not compiled to
wasm32 — wasm32-unknown-unknown is exclusively a Gear-program artifact and never executes consensus code.
- So in practice the truncation path is unreachable from any currently supported deployment.
What to do
If we ever broaden target platforms (32-bit ARM, etc.), replace the cast with an explicit, lossless saturating conversion. Suggested one-liner that keeps the function signature (Option<ProposalParts>) intact and survives any target width:
self.total_messages = usize::try_from(msg.sequence)
.unwrap_or(usize::MAX)
.saturating_add(1);
Behaviour summary:
- 64-bit (today):
try_from always succeeds, identical to current code.
- 32-bit (hypothetical future): values above
u32::MAX saturate to usize::MAX instead of truncating to their low 32 bits.
- Never panics; signature unchanged.
Scope
Acceptance
- Replace the
as usize cast at streaming.rs with usize::try_from(...).unwrap_or(usize::MAX).
- Add a regression test that the saturation also engages when
sequence > u32::MAX (so the test remains meaningful even on 64-bit).
Context
PR #5500 replaced the panicking
+ 1arithmetic inethexe/malachite/core/src/streaming.rs:101with(msg.sequence as usize).saturating_add(1). This closes theFin@u64::MAXpanic / silent-wrap path on our supported (64-bit) targets.A follow-up review note from Gemini surfaced a residual concern about the
as usizecast itself:Why this is open and not closed in PR #5500
usize == u64, somsg.sequence as usizeis a no-op cast and the saturating add covers the original failure modes.wasm32—wasm32-unknown-unknownis exclusively a Gear-program artifact and never executes consensus code.What to do
If we ever broaden target platforms (32-bit ARM, etc.), replace the cast with an explicit, lossless saturating conversion. Suggested one-liner that keeps the function signature (
Option<ProposalParts>) intact and survives any target width:Behaviour summary:
try_fromalways succeeds, identical to current code.u32::MAXsaturate tousize::MAXinstead of truncating to their low 32 bits.Scope
ethexe/malachite/core/src/streaming.rs.Acceptance
as usizecast atstreaming.rswithusize::try_from(...).unwrap_or(usize::MAX).sequence > u32::MAX(so the test remains meaningful even on 64-bit).