-
Notifications
You must be signed in to change notification settings - Fork 39
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
Notes about FIRST / FINAL #970
Comments
Meeting notes 06.09 For storage: just the block level Ex Many events revert at timestamp t Secondary timestamp will have a smaller value. first_in_Tx/last happen in the permuted domain Whenever we create an account fragment, we update the relevant map. AccountSection is a section for an instruction in the AccountFamily (related to a specific family of opcodes—like BALANCE, SELFBALANACE…) Map -> Pair(AccountFragment, AccountFragment) // (First, Las, Dom, Subt) (First, Last, Dom, Sub) Ordered list of sections, and inside each section there is an ordered list of fragments. (Dom, Sub) —— First/Last in Tx: start a new map with every transaction.
Example given by Olivier on (Dom, Sub) on a call:
undoing of this added in the resolvePostRollback:
When you reorder it you will get
Here tau is a fixed constant (I think it's actually 16 in the spec) and epsilon_rev also is a fixed constant. h represents the HUB_STAMP In the permutation domain we order (Dom, Sub) according to the (+,-) lex ordering. —————— For us: These will be the base transactions, that get bundled into blocks—test inputs. |
This issue is now solved in |
Modules cannot be live traced for the following reasons:
The general approach is to accumulate information (tracing a) and build the matrices later (tracing b).
HUB has another reason for not live tracing it:
The HUB isn't the only one that is revert sensitive, MMU/MMIO is too because of
LOG
s. In any case, the approach with the HUB as we can't know while tracing (a) what rows (i.e.fragments
) we will need, in what number and what actions they should represent is to just accumulatesections
(collections of rows i.e.fragments
) and resolve ambiguities when they have been lifted. We therefore accumulate dozens of tiny changes that have to be undone in case of a rollback or other events (context entry, exit, ...)The case of rollbacks is particularly complex as a single REVERT / exception may trigger a chain reaction where we undo hundreds of small changes at once. Our solution is:
SOLUTION: WHENEVER WE DO SOMETHING THAT MAY BE SUBJECT TO BEING REVERTED (any state change, accrued state changes, ...) WE RESERVE THE POSSIBILITY OF MODIFYING THE RELEVANT SECTION IN SUCH A WAY THAT THE FUTURE UNDOING IS WRITTEN IN THE TRACE AT THE PRESENT TIME IN SUCH A WAY THAT IT WILL ONLY TAKE EFFECT IN THE FUTURE.
This is the reason for defers: when we detect that something WILL be reverted (say) then we retroactively insert the correct rows all the relevant trace sections taht would be affected by this rollback.
This has an effect on state management: if you say touch storage, and a parent context reverts, then there will be, for every time you touch storage in the normal execution flow, a corresponding "undoing row" that undoes everything that current row did. Only from the point of view of the scp_ permutation (storage conssistency permutation) this is a future event. And it may have to be tagged as "FINAL"
There are several Besu hooks that we use to "act upon" the defers:
tracePreExecution
(pre-opcode)tracePostExectution
(post-opcode)traceContextEnter
traceContextExit
traceContextReEnter
traceTxEnd
traceConflationEnd
...
So ther are many registries for stuff that needs to be deferred
Each defer registry is "resolved" at one of those Besu hooks (if other conditions are met: e.g. REVERT)
E.g. you act on a RETURN;
you create a ReturnSection;
if the RETURN doesn't fail for exception or so it (the ReturnSection) may need to be amended at a future time given future evnets
so it schedules itself for the various future envent that may affect it
Then if the relevant Besu hook activates we RESOLVE these events.
E.G. for storage rows, what is there to do ?
For storage keys and accounts you'll have to do something similar to what is being done wrt SELFDESCTRUCT:
Taking inspiration from, e.g.
AccountFragment.java
'sNote: there is a preliminary "conflation level" version of this map in State.java:
The corresponding HashMap / Array, whatever, may have to be written for account data
Very similar for ACCOUNTs (just swap storage rows for account rows)
The text was updated successfully, but these errors were encountered: