-
Notifications
You must be signed in to change notification settings - Fork 11.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix integer overflow and underflow in DeferralKey methods and add corresponding tests #20387
base: main
Are you sure you want to change the base?
Fix integer overflow and underflow in DeferralKey methods and add corresponding tests #20387
Conversation
Fix integer overflow in range_for_up_to_consensus_round Prevent integer underflow in transaction_deferral_within_limit
The latest updates on your projects. Learn more about Vercel for Git ↗︎
3 Skipped Deployments
|
@mystenmark and/or @aschran would be a better reviewer for this change |
@@ -54,7 +54,7 @@ impl DeferralKey { | |||
deferred_from_round: 0, | |||
}, | |||
Self::ConsensusRound { | |||
future_round: consensus_round.checked_add(1).unwrap(), | |||
future_round: consensus_round.saturating_add(1), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If an epoch runs for long enough that consensus_round
reaches u64::MAX
(or gets this close to it), then I think we want to panic, because there is no safe way for the system to handle that
Keep in mind that at our current rate of 14 rounds/s it would take an epoch of over 4e10 years for us to reach this limit, even if we somehow 1000x this rate (impossible I think) then it would take 10s of millions of years :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Additionally, if we did reach this point, doing a saturating add would cause incorrect behavior.
@xiaodi007 Thanks for the contribution - see the comments above. I believe it is impossible for either issue to occur, but in the second case we could be more defensive. |
Add a debug_assert! to enforce the invariant during object creation; and adjust future_round to be at least deferred_from_round in release builds to maintain the invariant without panicking in new_for_consensus_round Add debug_assert!(future_round >= deferred_from_round); and use saturating_sub in transaction_deferral_within_limit.
Revert the change in range_for_up_to_consensus_round to keep checked_add(1).unwrap()
import debug_fatal
@mystenmark @aschran I'm very grateful for your valuable feedback. I change my code to be more defensive. Add a Add Thanks again for your insightful feedback! I've made the updates to the PR as you suggested. I'll keep contributing actively. The updates are ready now—please take a look! |
Description
This PR addresses two critical issues in the
DeferralKey
implementation that could lead to integer overflow and underflow, potentially causing panics or incorrect behavior. It also includes new test cases to verify the correctness of the fixes.Issues Fixed:
Prevent Integer Overflow in
range_for_up_to_consensus_round
consensus_round
equalsu64::MAX
, usingchecked_add(1).unwrap()
inDeferralKey::range_for_up_to_consensus_round
causes a panic due to overflow.checked_add(1).unwrap()
withsaturating_add(1)
to safely handle the maximum value without causing a panic.Prevent Integer Underflow in
transaction_deferral_within_limit
transaction_deferral_within_limit
, whenfuture_round
is less thandeferred_from_round
, subtracting them causes an underflow, resulting in incorrect behavior.checked_sub
to safely perform the subtraction, and handle theNone
case by returningfalse
.Test plan
Test Name:
test_range_for_up_to_consensus_round_no_overflow
Description: Verifies that
DeferralKey::range_for_up_to_consensus_round
does not overflow whenconsensus_round
isu64::MAX
, and that it correctly returnsfuture_round
equal tou64::MAX
.Test Name:
test_transaction_deferral_within_limit_underflow
Description: Ensures that
transaction_deferral_within_limit
correctly handles cases wherefuture_round
is less thandeferred_from_round
, preventing integer underflow and returningfalse
.Release notes
Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required.
For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates.