-
Notifications
You must be signed in to change notification settings - Fork 21.1k
Block access list changes - BAL construction, execution and validation #32263
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
base: master
Are you sure you want to change the base?
Conversation
A lot of the comments in the code are straight-up wrong/misleading. There's a lot of notes/reminders I made as I was implementing this, and not all of them have been removed/corrected at this point. |
I've pushed parallel execution changes here. Still failing 2 tests (other than modexp repricing ones which will be fixed with a rebase on master):
I've been trying to debug these but it's proving to be exceedingly difficult with the parallel execution enabled. The tests seem to relate to behavior of some system contracts on the fork boundaries, so I will just proceed with gathering numbers on mainnet performance for the meantime. |
ab1c562
to
8f200db
Compare
Broke the block count on the insertion log statement here. Will try to fix tomorrow. |
Getting some empty accounts in the BAL. example:
|
…hen enabled, post-Cancun blocks which lack access lists will have them constructed on execution during import. When importing blocks which contain access lists, transaction execution and state root calculation is performed in parallel.
…ved from BALs, there's not much gain from having a BAL state prefetcher
…ulation in statedb across multiple calls to Finalise. instead, Finalise now returns the diff that occurred from that call
…ges in tx execution.
869b300
to
e14a463
Compare
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.
Looking good so far, just a few comments.
var resCh chan *ProcessResultWithMetrics | ||
resCh, err = bc.processor.ProcessWithAccessList(block, statedb, bc.cfg.VmConfig) | ||
if err != nil { | ||
// TODO: okay to pass nil here as execution result? |
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.
Should be fine, we just use it to get out the receipts (if it is non nil).
// Process block using the parent state as reference point | ||
pstart := time.Now() | ||
var resCh chan *ProcessResultWithMetrics | ||
resCh, err = bc.processor.ProcessWithAccessList(block, statedb, bc.cfg.VmConfig) |
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.
Why does this need to return a channel? Seems like it could be a blocking operation. Also I would probably do the branching for access list vs. not in the Process
function instead of here since it is really more related to the processing of the block than the broader chain. It should also simplify the changes a bit since both branches of this if
are quite similar, especially if you then roll the checks from ValidateProcessResult
into ValidateState
.
return prev | ||
} | ||
|
||
func (s *stateObject) setCode(codeHash common.Hash, code []byte) { | ||
s.code = code | ||
s.data.CodeHash = codeHash[:] | ||
} | ||
|
||
// setCode sets the code and hash and dirty markers. |
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.
// setCode sets the code and hash and dirty markers. | |
// setCodeModified sets the code and hash and dirty markers. |
// performs post-tx state transition (system contracts and withdrawals) | ||
// and calculates the ProcessResult, returning it to be sent on resCh | ||
// by resultHandler | ||
prepareExecResult := func(postTxState *state.StateDB, receipts types.Receipts) *ProcessResult { |
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.
It's fairly hard to follow the logic with these larger function variables. I think it's reasonable to separate this logic into separate methods or create a new object the focuses solely on validating blocks with access lists.
CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun) | ||
PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague) | ||
OsakaTime *uint64 `json:"osakaTime,omitempty"` // Osaka switch time (nil = no fork, 0 = already on osaka) | ||
GlamsterdamTime *uint64 `json:"glamsterdamTime,omitempty"` // Glamsterdam switch time (nil = no fork, 0 = already on glamsterdam) |
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.
GlamsterdamTime *uint64 `json:"glamsterdamTime,omitempty"` // Glamsterdam switch time (nil = no fork, 0 = already on glamsterdam) | |
AmsterdamTime *uint64 `json:"amsterdamTime,omitempty"` // Aamsterdam switch time (nil = no fork, 0 = already on Amsterdam) |
WIP. currently passes blockchain spec tests (tests that make use of balances >16 bytes are excluded).
Change summary:
--experimentalbal
is enabled:Deviations from EIP-7928:
txindex=0
correspond to state reads/changes which occur from system contract execution before transactions.txindx=1..len(block.transactions)
correspond to state reads/changes occurring for each transaction.txindex=len(block.transactions)+1
correspond to the post-block system contracts and EIP-4895 withdrawals.TODO: