Skip to content
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

core, eth, internal, cmd: rework EVM constructor #30745

Merged
merged 4 commits into from
Nov 20, 2024

Conversation

rjl493456442
Copy link
Member

@rjl493456442 rjl493456442 commented Nov 12, 2024

This pull request refactors the EVM constructor by removing the TxContext parameter.

The EVM object is frequently overused. Ideally, only a single EVM instance should be created and reused throughout the entire state transition of a block, with the transaction context switched as needed by calling evm.SetTxContext.

Unfortunately, in some parts of the code, the EVM object is repeatedly created, resulting in unnecessary complexity. This pull request is the first step towards gradually improving and simplifying this setup.

core/chain_makers.go Outdated Show resolved Hide resolved
Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very good initiative!

@rjl493456442 rjl493456442 added this to the 1.14.12 milestone Nov 13, 2024
Comment on lines +248 to +249
// TODO (rjl493456442) it's a bit weird to reset the tracer in the
// middle of block execution, please improve it somehow.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, the tracer can be set earlier, on the vmconfig before it is passed to the evm. The thing that changes between transactions is the traceOutput. So we would need to split up getTracerFn. I'll take a look

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, yeah it's not quite that simple. Maybe let's leave it for a different PR

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! Did we run it on benches anything?

@rjl493456442
Copy link
Member Author

rjl493456442 commented Nov 18, 2024 via email

@holiman
Copy link
Contributor

holiman commented Nov 18, 2024

Not yet! Is 7 or 8 available?

I think so -- I'm not using them, at least

@rjl493456442
Copy link
Member Author

It's deployed on 7/8. I will try to test the tracing functionalities tomorrow.

@@ -159,7 +157,7 @@ func ApplyTransactionWithEVM(msg *Message, config *params.ChainConfig, gp *GasPo
// Update the state with pending changes.
var root []byte
if config.IsByzantium(blockNumber) {
tracingStateDB.Finalise(true)
evm.StateDB.Finalise(true)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should use tracingStateDB here. Finalise is hooked in some cases.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The EVM is constructed with tracingStateDB.

But I agree it's a bit confusing here for have two stateDB instances, (a) the one in the EVM object (b) the supplied one for calling IntermediateRoot and making receipts.

The next step is to unify these two instances into a single one. The ideal status is we always use the evm.StateDB for interacting throughout the entire state transition.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The next step is to unify these two instances into a single one. The ideal status is we always use the evm.StateDB for interacting throughout the entire state transition.

Yeah. One way to do it would be, to instead of IntermediateState/Finalize, have func TxEnd(isEip158, isByzantium bool) common.Hash and BlockEnd(isEip158 bool) common.Hash. And instead of

			var root []byte
			if chainConfig.IsByzantium(vmContext.BlockNumber) {
				statedb.Finalise(true)
			} else {
				root = statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber)).Bytes()
			}

we would do

			isEip158 := chainConfig.IsEIP158(vmContext.BlockNumber)
			isByzantium := chainConfig.IsByzantium(vmContext.BlockNumber)
			root := statedb.TxEnd(isEip158, isByzantium)

As it is right now, we pass the statedb struct in order to

  1. Calculate root, via IntermediateRoot which is not exposed in vm.StateDB interface,
  2. To pass to receipt-building, which invokes the following methods on it
	if statedb.GetTrie().IsVerkle() {
		statedb.AccessEvents().Merge(evm.AccessEvents)
	}

and
statedb.GetLogs(tx.Hash(), blockNumber.Uint64(), blockHash) and statedb.TxIndex()

So, in order to unify them into one, we need to do something clever about the receipt-building too. They way this PR works now is ok to me, as Gary pointed out -- the evm already uses the hookedstate, so Finalise does indeed operate on the hooked one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Initially, I did unify them, by expanding the vm.StateDB interface quite a lot. It's not a great solution to do that, so @fjl instead suggested we do the conversion lower down. So now we have a bit of a compromise.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if statedb.GetTrie().IsVerkle() {
		statedb.AccessEvents().Merge(evm.AccessEvents)
	}

I would like to move the accessEvent into the EVM itself. So we can remove it from the statedb.

@holiman holiman modified the milestones: 1.14.12, 1.14.13 Nov 19, 2024
@holiman holiman merged commit e3d61e6 into ethereum:master Nov 20, 2024
3 checks passed
holiman pushed a commit that referenced this pull request Nov 22, 2024
Follow-up to #30745 , this change removes some unnecessary parameters.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants