-
Notifications
You must be signed in to change notification settings - Fork 155
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
Task/improve evm tracer performance #3521
base: develop
Are you sure you want to change the base?
Task/improve evm tracer performance #3521
Conversation
depth int | ||
interrupt atomic.Bool // Atomic flag to signal execution interruption | ||
reason error // Textual reason for the interruption | ||
txToStack map[common.Hash][]CallFrame |
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.
Isn't it possible to avoid changing this struct and also prestateTracer
?
I'm asking because these files are almost a 1 to 1 copy of the code in go-ethereum, and so they are very easy to update whenever there are changes upstream. These changes will make it more difficult to keep the code updated.
Also, I see that there is some duplicated logic in the call and prestate tracers, surrounding the map[common.Hash]
, currentTxHash
, traceBlock
and fakeTxs
, so maybe there is a different solution? How does go-ethereum solve this problem?
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.
Geth does not have N^2 problem because their VM layer is different, the bottom line is that geth's VM allows transactions to be executed individually (meaning that each tx has it's own tracer) but reusing the same state (thus allowing txs to see the changes made by previous txs in the same block). Basically they loop through the block transactions and for each one they run VM with tracing.
Out VM however accepts a list of transactions to run and only then it gets the state to base on. I'm sure that we could change our VM to work like geth, but for me it's hard to understand how difficult that would be (maybe it's easy).
That's why I decided to alter the tracers itself. But I agree that it would make it difficult to copy fixes from geth
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.
Ok, I see. Anyway, do you think it's possible to fix or at least decrease the amount of duplicated code?
Maybe moving that logic to our own Tracer
struct:
type Tracer struct {
txTracers map[common.Hash]*tracers.Tracer
currentTx common.Hash
traceBlock bool
fakeTxs []*types.Transaction
}
fakeTxs := make([]*types.Transaction, 0, len(blockTxs)) | ||
for _, tx := range blockTxs { | ||
if evmutil.IsFakeTransaction(tx) { | ||
fakeTxs = append(fakeTxs, tx) |
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.
So fakeTxs
contains the list of fake txs in the block. But it doesn't record their tx index. I don't remember, is it possible that a block contains regular and fake txs interleaved? Shouldn't the trace ouput respect the transaction indices?
block:
tx #0: regular tx
tx #1: fake tx
tx #2: regular tx
tx #3: fake tx
Fix N^2 behavior of block tracers