fix(chainbase): guard divide-by-zero#6687
Conversation
… loading Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| // Calc new usage by fixed x-axes | ||
| long newUsage = max(0, newArea / newSize, dynamicPropertiesStore.disableJavaLangMath()); | ||
| // A zero window size means no valid time window exists and thus zero usage | ||
| long newUsage = newSize == 0 ? 0 |
There was a problem hiding this comment.
The zero-division guard is well-reasoned — newSize can indeed be 0 when mergedSize == currentSize and size from the receipt is 0, even though getWindowSize() itself never returns 0. Great job tracing the actual root cause rather than just adding a blanket check! 👏
Since this is a subtle edge case that's easy to regress on, would it be worth adding a unit test in TransactionTraceTest that exercises the newSize == 0 path? This would also serve as documentation for future readers about when this condition can occur.
There was a problem hiding this comment.
[SHOULD] Please add a regression test for the newSize == 0 path in TransactionTraceTest. This is a subtle edge case, and a test would both lock in the intended behavior (newUsage = 0 with window reset) and document when this condition is expected to occur.
There was a problem hiding this comment.
Done. Added two regression tests in TransactionTraceTest:
testResetAccountUsageZeroWindowSize: covers theresetAccountUsagepath (V2 disabled) withmergedSize == currentSizeandsize == 0, which producesnewSize == 0.testResetAccountUsageV2ZeroWindowSize: same scenario via theresetAccountUsageV2path (V2 enabled).
Both verify that energyUsage is reset to 0 without an ArithmeticException.
| long currentUsage = accountCap.getEnergyUsage(); | ||
| // Drop the pre consumed frozen energy | ||
| // Drop the preconsumed frozen energy | ||
| long newArea = currentUsage * currentSize |
There was a problem hiding this comment.
[QUESTION] newArea still relies on raw long multiplications/subtractions here. I realize this is pre-existing code rather than introduced by this PR, but since this method is already being touched for numeric safety, do we want a follow-up to harden these arithmetic operations with the existing exact-helper pattern as well?
There was a problem hiding this comment.
Good observation. While there's a theoretical overflow risk in newArea = currentUsage * currentSize - (mergedUsage * mergedSize - usage * size), in practice this won't occur in java-tron's business context — both currentUsage (energy usage) and currentSize (window size, capped at WINDOW_SIZE_MS / BLOCK_PRODUCED_INTERVAL = 28800) are tightly bounded by the protocol's energy limits, so the product stays well within long range. But I agree it's worth noting as a pre-existing pattern; happy to track it in a
follow-up if you'd like.
|
[DISCUSS] If At the moment, though, the reachability of |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ctionTrace Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sage Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The This is therefore a defensive guard — the existing comment "A zero window size means no valid time window exists and thus zero usage" already expressed the intended behavior, but the zero check was missing. There is no reachable code path that produces |
| long newSize = mergedSize == currentSize ? size : currentSize; | ||
| // Calc new usage by fixed x-axes | ||
| long newUsage = max(0, newArea / newSize, dynamicPropertiesStore.disableJavaLangMath()); | ||
| // A zero window size means no valid time window exists and thus zero usage |
There was a problem hiding this comment.
[NIT] New comment removes the algorithm context from 'fixed x-axes'
The original comment // Calc new usage by fixed x-axes explained the area-based energy accounting model (usage × window = area; new_usage = area / new_window). The replacement comment only explains the zero-guard case, so readers of the non-zero path lose the rationale for newArea / newSize.
The same applies to the equivalent line in resetAccountUsageV2 (line ~320).
Suggestion: Merge both meanings, e.g.
// Calculate new usage from area/window model; zero window means no valid time context and yields zero usage|
Closed, as it is only theoretical guard fix. |
What does this PR do?
Fix audit warnings in energy-related code.
Changes
TransactionTrace: guardnewArea / newSizewith anewSize == 0check inresetAccountUsage. A zero window size means no valid time window exists, so usage should be 0 rather than dividing by zero. Also fixes a minor comment typo (pre consumed→preconsumed).Test plan
newSize) path