test(ethexe-runtime-common): repro for take_actual_tasks u32::MAX overflow (auto-tester) b556aa218ff2#5522
Conversation
…rflow (auto-tester) b556aa218ff2 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-tester) b1ed02dd83bc Same function pair as parent commit. schedule_task uses plain `+` at transitions.rs:94 which panics on u32 overflow in debug builds and wraps silently in release builds (so a task ends up scheduled in the past). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Iter 9 of the auto-tester found a related bug in the same function pair. Pushed a follow-up test (
let scheduled_block = self.block_height + u32::from(in_blocks);This panics with Both the Reproduces 3/3 deterministically. — |
take_actual_tasks silently fails to drain tasks scheduled at u32::MAX block height because
saturating_add(1)returnsu32::MAX(not u32::MAX+1), causingsplit_off(&u32::MAX)to retain the task rather than drain it. This contradicts the documented invariant.Scenario:
gas_boundaryHash:
b556aa218ff2Unit:
ethexe-runtime-commonObserved
assertion left == right failed: Task at u32::MAX must be drained at block_height u32::MAX left: 0 right: 1The test reaches the bug through 100% public API:
InBlockTransitions::new(u32::MAX - 1, …)thenschedule_task(NonZero::new(1), …)→ scheduled_block = u32::MAX (no overflow)take_actual_tasks()at block_height = u32::MAX - 1 → correctly empty (task is in future)finalize()→ schedule preservedInBlockTransitions::new(u32::MAX, …, schedule)→take_actual_tasks()at block_height = u32::MAXReproduces 3/3 deterministically.
Rubric items satisfied
ethexe/runtime/common/src/transitions.rs:83-85says:/// Drain every scheduled task whose deadline is at or before /// block_height and return them in chronological order …. Atblock_height = u32::MAX, the function leaves the u32::MAX entry undrained, violating "at or before".Root cause
A possible fix: drop the +1 and use a different split point (e.g., compute the next key with
BTreeMap::range), or special-caseblock_height == u32::MAXto drain the whole map.Practical reachability
A
u32block height of u32::MAX requires ~1635 years at 12s block time, so this is unreachable in practice on Vara/Ethereum cadence. The PR exists to document the invariant gap, not because it can be triggered in production. Reviewers may choose to: (a) fix and close, (b) keep the test as documentation but adjust the comment to acknowledge the edge, (c) reject as not worth fixing.Generated by
/gear-dev:tester(auto-tester). This is a draft PR — requires human review before merge.