-
Notifications
You must be signed in to change notification settings - Fork 11.7k
Merge AccumulatorEvents in temporary_store so that transaction effects are accurate #24176
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
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
3fa273f to
8175d6b
Compare
8175d6b to
242bbd6
Compare
| }; | ||
| let amount_u64 = amount | ||
| .try_into() | ||
| .expect("accumulator value overflow: merged amount exceeds u64::MAX"); |
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.
hmm, i think this expect could be triggered by malicious code. You can create balance amounts of u64::max (not on a "real" currency, but nevertheless), and if you just do that twice you will overflow.
so we either have to use u128s in effects, or else detect the overflow during execution (at emit_accumulator_event in object_runtime.rs) and abort the transaction.
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.
I added validation in emit_accumulator_event. I didn't do the merging here because it would have required changing the types in MoveAccumulatorValue and it seemed cleaner this way, happy to revisit this if you have a different opinion.
d46664d to
da06499
Compare
da06499 to
10ea44d
Compare
| let mut merge_total = 0u128; | ||
| let mut split_total = 0u128; | ||
|
|
||
| for event in &self.state.accumulator_events { |
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.
This gives contracts the ability to cause quadratic execution time.
I'd prefer to track the running total in self.state, which should be simple enough, but if for some reason we can't do that, we should make sure there is a reasonable cap on max accumulator events and enforce it here.
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.
Addressed, moved to self.state
10ea44d to
b3eba0e
Compare
b3eba0e to
9a15fa9
Compare
9a15fa9 to
82f372c
Compare
82f372c to
068e6e2
Compare
| //> 1: test::large_balance::create_holder(); | ||
| //> TransferObjects([Result(0), Result(1)], Input(0)) | ||
|
|
||
| //# run test::large_balance::send_large_balance --args object(2,0) @A 18446744073709551614 --sender A |
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.
before this, we should have a case that sends two large transfers in a single PTB, to test that it causes a move abort
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.
Test added
| //> 0: sui::balance::redeem_funds<test::large_balance::MARKER>(Input(0)); | ||
| //> 1: sui::balance::redeem_funds<test::large_balance::MARKER>(Input(1)); | ||
| //> 2: sui::balance::join<test::large_balance::MARKER>(Result(0), Result(1)); | ||
| //> 3: sui::balance::send_funds<test::large_balance::MARKER>(Result(0), Input(2)); |
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.
can we follow this up with a check that we can successfully withdraw the large amounts one at a time? Or do we already have that?
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.
Test added
| match w.operation { | ||
| //we validate that these do not overflow in object_runtime | ||
| AccumulatorOperation::Merge => (merge + v, split), | ||
| AccumulatorOperation::Split => (merge, split + v), |
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.
lets do merge.checked_add(v).expect("validated in object runtime")
(Or you can wrap the code with the checked_arithmetic! { ... } macro to rewrite it automatically)
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.
Used checked_add :)
mystenmark
left a comment
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.
approved with some small nits. thanks!
068e6e2 to
bfb71dd
Compare
Description
Merge AccumulatorWriteV1 objects in temporary_store. This allows authenticated events to be indexed correctly in rpc_index and provides accurate transaction_effects.
Test plan
Address Balance and Authenticated Events tests added; they fail without this change.
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.