Skip to content

Commit 4d2181a

Browse files
authored
cmd, core, eth, miner: apply 7997 in block building (#35285)
This PR applies the 7997 irregular state transition in t8n, block building, simulation and tracing.
1 parent cf35a1b commit 4d2181a

7 files changed

Lines changed: 82 additions & 28 deletions

File tree

cmd/evm/internal/t8ntool/execution.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,13 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
242242
chainConfig.DAOForkBlock.Cmp(new(big.Int).SetUint64(pre.Env.Number)) == 0 {
243243
misc.ApplyDAOHardFork(statedb)
244244
}
245+
// EIP-7997: insert the deterministic deployment factory at the Amsterdam
246+
// activation block via an irregular state transition.
247+
if pre.Env.Number > 0 &&
248+
chainConfig.IsAmsterdam(new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp) &&
249+
!chainConfig.IsAmsterdam(new(big.Int).SetUint64(pre.Env.Number-1), pre.Env.ParentTimestamp) {
250+
misc.ApplyEIP7997(statedb)
251+
}
245252
evm := vm.NewEVM(vmContext, statedb, chainConfig, vmConfig)
246253
if beaconRoot := pre.Env.ParentBeaconBlockRoot; beaconRoot != nil {
247254
core.ProcessBeaconBlockRoot(*beaconRoot, evm, blockAccessList)

core/state_processor.go

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,9 @@ func (p *StateProcessor) Process(ctx context.Context, block *types.Block, stated
8181
if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(block.Number()) == 0 {
8282
misc.ApplyDAOHardFork(tracingStateDB)
8383
}
84-
// EIP-7997: insert the deterministic deployment factory at the Amsterdam
85-
// activation block via an irregular state transition.
86-
if isEIP7997Transition(config, p.chain, header) {
87-
misc.ApplyEIP7997(tracingStateDB)
84+
parent := p.chain.GetHeader(block.ParentHash(), block.NumberU64()-1)
85+
if parent == nil {
86+
return nil, fmt.Errorf("missing parent %#x", block.ParentHash())
8887
}
8988
var (
9089
context = NewEVMBlockContext(header, p.chain, nil)
@@ -98,7 +97,7 @@ func (p *StateProcessor) Process(ctx context.Context, block *types.Block, stated
9897
evm.SetJumpDestCache(jumpDestCache)
9998
}
10099
// Run the pre-execution system calls
101-
blockAccessList.Merge(PreExecution(ctx, block.BeaconRoot(), block.ParentHash(), config, evm, block.Number(), block.Time()))
100+
blockAccessList.Merge(PreExecution(ctx, block.BeaconRoot(), parent, config, evm, block.Number(), block.Time()))
102101

103102
// Iterate over and process the individual transactions
104103
for i, tx := range block.Transactions() {
@@ -142,35 +141,28 @@ func (p *StateProcessor) Process(ctx context.Context, block *types.Block, stated
142141
}, nil
143142
}
144143

145-
// isEIP7997Transition reports whether the given header belongs to the first block
146-
// on which the Amsterdam fork is active.
147-
func isEIP7997Transition(config *params.ChainConfig, chain ChainContext, header *types.Header) bool {
148-
if header.Number.Sign() == 0 || !config.IsAmsterdam(header.Number, header.Time) {
149-
return false
150-
}
151-
parent := chain.GetHeader(header.ParentHash, header.Number.Uint64()-1)
152-
if parent == nil {
153-
return false
154-
}
155-
return !config.IsAmsterdam(parent.Number, parent.Time)
156-
}
157-
158-
// PreExecution processes pre-execution system calls.
159-
func PreExecution(ctx context.Context, beaconRoot *common.Hash, parent common.Hash, config *params.ChainConfig, evm *vm.EVM, number *big.Int, time uint64) *bal.ConstructionBlockAccessList {
144+
// PreExecution processes pre-execution state changes and system calls.
145+
func PreExecution(ctx context.Context, beaconRoot *common.Hash, parent *types.Header, config *params.ChainConfig, evm *vm.EVM, number *big.Int, time uint64) *bal.ConstructionBlockAccessList {
160146
_, _, spanEnd := telemetry.StartSpan(ctx, "core.preExecution")
161147
defer spanEnd(nil)
162148

163149
var blockAccessList *bal.ConstructionBlockAccessList
164150
if config.IsAmsterdam(number, time) {
165151
blockAccessList = bal.NewConstructionBlockAccessList()
152+
153+
// EIP-7997: insert the deterministic deployment factory at the Amsterdam
154+
// activation block via an irregular state transition.
155+
if !config.IsAmsterdam(parent.Number, parent.Time) {
156+
misc.ApplyEIP7997(evm.StateDB)
157+
}
166158
}
167159
// EIP-4788
168160
if beaconRoot != nil {
169161
ProcessBeaconBlockRoot(*beaconRoot, evm, blockAccessList)
170162
}
171163
// EIP-2935
172164
if config.IsPrague(number, time) || config.IsUBT(number, time) {
173-
ProcessParentBlockHash(parent, evm, blockAccessList)
165+
ProcessParentBlockHash(parent.Hash(), evm, blockAccessList)
174166
}
175167
return blockAccessList
176168
}

eth/state_accessor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ func (eth *Ethereum) stateAtTransaction(ctx context.Context, block *types.Block,
250250
defer evm.Release()
251251

252252
// Run pre-execution system calls
253-
core.PreExecution(ctx, block.BeaconRoot(), block.ParentHash(), eth.blockchain.Config(), evm, block.Number(), block.Time())
253+
core.PreExecution(ctx, block.BeaconRoot(), parent.Header(), eth.blockchain.Config(), evm, block.Number(), block.Time())
254254

255255
if txIndex == 0 && len(block.Transactions()) == 0 {
256256
return nil, context, statedb, release, nil

eth/tracers/api.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,7 +373,7 @@ func (api *API) traceChain(start, end *types.Block, config *TraceConfig, closed
373373
context := core.NewEVMBlockContext(next.Header(), api.chainContext(ctx), nil)
374374
evm := vm.NewEVM(context, statedb, api.backend.ChainConfig(), vm.Config{})
375375

376-
core.PreExecution(ctx, next.BeaconRoot(), next.ParentHash(), api.backend.ChainConfig(), evm, next.Number(), next.Time())
376+
core.PreExecution(ctx, next.BeaconRoot(), block.Header(), api.backend.ChainConfig(), evm, next.Number(), next.Time())
377377
evm.Release()
378378
// Clean out any pending release functions of trace state. Note this
379379
// step must be done after constructing tracing state, because the
@@ -523,7 +523,7 @@ func (api *API) IntermediateRoots(ctx context.Context, hash common.Hash, config
523523
)
524524
defer evm.Release()
525525
// Run pre-execution system calls
526-
core.PreExecution(ctx, block.BeaconRoot(), block.ParentHash(), chainConfig, evm, block.Number(), block.Time())
526+
core.PreExecution(ctx, block.BeaconRoot(), parent.Header(), chainConfig, evm, block.Number(), block.Time())
527527

528528
for i, tx := range block.Transactions() {
529529
if err := ctx.Err(); err != nil {
@@ -582,7 +582,7 @@ func (api *API) traceBlock(ctx context.Context, block *types.Block, config *Trac
582582
defer evm.Release()
583583

584584
// Run pre-execution system calls
585-
core.PreExecution(ctx, block.BeaconRoot(), block.ParentHash(), api.backend.ChainConfig(), evm, block.Number(), block.Time())
585+
core.PreExecution(ctx, block.BeaconRoot(), parent.Header(), api.backend.ChainConfig(), evm, block.Number(), block.Time())
586586

587587
// JS tracers have high overhead. In this case run a parallel
588588
// process that generates states in one thread and traces txes
@@ -754,7 +754,7 @@ func (api *API) standardTraceBlockToFile(ctx context.Context, block *types.Block
754754
defer evm.Release()
755755

756756
// Run pre-execution system calls
757-
core.PreExecution(ctx, block.BeaconRoot(), block.ParentHash(), chainConfig, evm, block.Number(), block.Time())
757+
core.PreExecution(ctx, block.BeaconRoot(), parent.Header(), chainConfig, evm, block.Number(), block.Time())
758758

759759
for i, tx := range block.Transactions() {
760760
// Prepare the transaction for un-traced execution

internal/ethapi/simulate.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
322322
evm.SetPrecompiles(precompiles)
323323
}
324324
// Run pre-execution system calls
325-
blockAccessList.Merge(core.PreExecution(ctx, header.ParentBeaconRoot, header.ParentHash, sim.chainConfig, evm, header.Number, header.Time))
325+
blockAccessList.Merge(core.PreExecution(ctx, header.ParentBeaconRoot, parent, sim.chainConfig, evm, header.Number, header.Time))
326326

327327
var allLogs []*types.Log
328328
for i, call := range block.Calls {

miner/payload_building_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package miner
1818

1919
import (
20+
"bytes"
2021
"context"
2122
"math/big"
2223
"reflect"
@@ -26,6 +27,7 @@ import (
2627
"github.com/ethereum/go-ethereum/beacon/engine"
2728
"github.com/ethereum/go-ethereum/common"
2829
"github.com/ethereum/go-ethereum/consensus"
30+
"github.com/ethereum/go-ethereum/consensus/beacon"
2931
"github.com/ethereum/go-ethereum/consensus/clique"
3032
"github.com/ethereum/go-ethereum/consensus/ethash"
3133
"github.com/ethereum/go-ethereum/core"
@@ -115,6 +117,7 @@ func newTestWorkerBackend(t *testing.T, chainConfig *params.ChainConfig, engine
115117
copy(gspec.ExtraData[32:32+common.AddressLength], testBankAddress.Bytes())
116118
e.Authorize(testBankAddress)
117119
case *ethash.Ethash:
120+
case *beacon.Beacon:
118121
default:
119122
t.Fatalf("unexpected consensus engine type: %T", engine)
120123
}
@@ -194,6 +197,58 @@ func TestBuildPayload(t *testing.T) {
194197
}
195198
}
196199

200+
// TestBuildPayloadAmsterdamTransition verifies that a locally built payload for
201+
// the first Amsterdam block contains the EIP-7997 deterministic deployment
202+
// factory, i.e. the block-building path applies the same irregular state
203+
// transition as block processing and the resulting block is importable.
204+
func TestBuildPayloadAmsterdamTransition(t *testing.T) {
205+
var (
206+
db = rawdb.NewMemoryDatabase()
207+
recipient = common.HexToAddress("0xdeadbeef")
208+
)
209+
config := new(params.ChainConfig)
210+
*config = *params.MergedTestChainConfig
211+
config.AmsterdamTime = new(uint64)
212+
*config.AmsterdamTime = 1 // genesis (t=0) is pre-Amsterdam, the first block crosses the fork
213+
214+
w, b := newTestWorker(t, config, beacon.New(ethash.NewFaker()), db, 0)
215+
216+
var (
217+
beaconRoot = common.Hash{0x01}
218+
slotNum = uint64(1)
219+
)
220+
payload, err := w.buildPayload(context.Background(), &BuildPayloadArgs{
221+
Parent: b.chain.CurrentBlock().Hash(),
222+
Timestamp: 1,
223+
FeeRecipient: recipient,
224+
Withdrawals: types.Withdrawals{},
225+
BeaconRoot: &beaconRoot,
226+
SlotNum: &slotNum,
227+
}, false)
228+
if err != nil {
229+
t.Fatalf("Failed to build payload %v", err)
230+
}
231+
block := payload.empty
232+
if !config.IsAmsterdam(block.Number(), block.Time()) {
233+
t.Fatal("transition block is not an Amsterdam block")
234+
}
235+
// The block must be importable: Process applies EIP-7997 independently, so
236+
// a payload built without the factory would fail the state root check here.
237+
if _, err := b.chain.InsertChain(types.Blocks{block}); err != nil {
238+
t.Fatalf("failed to insert transition block: %v", err)
239+
}
240+
statedb, err := b.chain.StateAt(block.Header())
241+
if err != nil {
242+
t.Fatalf("failed to open state at transition block: %v", err)
243+
}
244+
if code := statedb.GetCode(params.DeterministicFactoryAddress); !bytes.Equal(code, params.DeterministicFactoryCode) {
245+
t.Fatalf("factory code missing from built payload state:\n got %x\nwant %x", code, params.DeterministicFactoryCode)
246+
}
247+
if nonce := statedb.GetNonce(params.DeterministicFactoryAddress); nonce != 1 {
248+
t.Fatalf("factory nonce = %d, want 1", nonce)
249+
}
250+
}
251+
197252
func TestPayloadId(t *testing.T) {
198253
t.Parallel()
199254
ids := make(map[string]int)

miner/worker.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ func (miner *Miner) prepareWork(ctx context.Context, genParams *generateParams,
326326
return nil, err
327327
}
328328
// Run pre-execution system calls
329-
env.bal.Merge(core.PreExecution(ctx, header.ParentBeaconRoot, header.ParentHash, miner.chainConfig, env.evm, header.Number, header.Time))
329+
env.bal.Merge(core.PreExecution(ctx, header.ParentBeaconRoot, parent, miner.chainConfig, env.evm, header.Number, header.Time))
330330
return env, nil
331331
}
332332

0 commit comments

Comments
 (0)