@@ -36,7 +36,6 @@ import (
36
36
"github.com/ethereum/go-ethereum/internal/ethapi/override"
37
37
"github.com/ethereum/go-ethereum/params"
38
38
"github.com/ethereum/go-ethereum/rpc"
39
- "github.com/ethereum/go-ethereum/trie"
40
39
)
41
40
42
41
const (
@@ -95,6 +94,47 @@ type simOpts struct {
95
94
ReturnFullTransactions bool
96
95
}
97
96
97
+ // simChainHeadReader implements ChainHeaderReader which is needed as input for FinalizeAndAssemble.
98
+ type simChainHeadReader struct {
99
+ context.Context
100
+ Backend
101
+ }
102
+
103
+ func (m * simChainHeadReader ) Config () * params.ChainConfig {
104
+ return m .Backend .ChainConfig ()
105
+ }
106
+
107
+ func (m * simChainHeadReader ) CurrentHeader () * types.Header {
108
+ return m .Backend .CurrentHeader ()
109
+ }
110
+
111
+ func (m * simChainHeadReader ) GetHeader (hash common.Hash , number uint64 ) * types.Header {
112
+ header , err := m .Backend .HeaderByNumber (m .Context , rpc .BlockNumber (number ))
113
+ if err != nil || header == nil {
114
+ return nil
115
+ }
116
+ if header .Hash () != hash {
117
+ return nil
118
+ }
119
+ return header
120
+ }
121
+
122
+ func (m * simChainHeadReader ) GetHeaderByNumber (number uint64 ) * types.Header {
123
+ header , err := m .Backend .HeaderByNumber (m .Context , rpc .BlockNumber (number ))
124
+ if err != nil {
125
+ return nil
126
+ }
127
+ return header
128
+ }
129
+
130
+ func (m * simChainHeadReader ) GetHeaderByHash (hash common.Hash ) * types.Header {
131
+ header , err := m .Backend .HeaderByHash (m .Context , hash )
132
+ if err != nil {
133
+ return nil
134
+ }
135
+ return header
136
+ }
137
+
98
138
// simulator is a stateful object that simulates a series of blocks.
99
139
// it is not safe for concurrent use.
100
140
type simulator struct {
@@ -209,6 +249,9 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
209
249
if sim .chainConfig .IsPrague (header .Number , header .Time ) || sim .chainConfig .IsVerkle (header .Number , header .Time ) {
210
250
core .ProcessParentBlockHash (header .ParentHash , evm )
211
251
}
252
+ if header .ParentBeaconRoot != nil {
253
+ core .ProcessBeaconBlockRoot (* header .ParentBeaconRoot , evm )
254
+ }
212
255
var allLogs []* types.Log
213
256
for i , call := range block .Calls {
214
257
if err := ctx .Err (); err != nil {
@@ -258,6 +301,10 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
258
301
}
259
302
callResults [i ] = callRes
260
303
}
304
+ header .GasUsed = gasUsed
305
+ if sim .chainConfig .IsCancun (header .Number , header .Time ) {
306
+ header .BlobGasUsed = & blobGasUsed
307
+ }
261
308
var requests [][]byte
262
309
// Process EIP-7685 requests
263
310
if sim .chainConfig .IsPrague (header .Number , header .Time ) {
@@ -271,20 +318,16 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header,
271
318
// EIP-7251
272
319
core .ProcessConsolidationQueue (& requests , evm )
273
320
}
274
- header .Root = sim .state .IntermediateRoot (true )
275
- header .GasUsed = gasUsed
276
- if sim .chainConfig .IsCancun (header .Number , header .Time ) {
277
- header .BlobGasUsed = & blobGasUsed
278
- }
279
- var withdrawals types.Withdrawals
280
- if sim .chainConfig .IsShanghai (header .Number , header .Time ) {
281
- withdrawals = make ([]* types.Withdrawal , 0 )
282
- }
283
321
if requests != nil {
284
322
reqHash := types .CalcRequestsHash (requests )
285
323
header .RequestsHash = & reqHash
286
324
}
287
- b := types .NewBlock (header , & types.Body {Transactions : txes , Withdrawals : withdrawals }, receipts , trie .NewStackTrie (nil ))
325
+ blockBody := & types.Body {Transactions : txes , Withdrawals : * block .BlockOverrides .Withdrawals }
326
+ chainHeadReader := & simChainHeadReader {ctx , sim .b }
327
+ b , err := sim .b .Engine ().FinalizeAndAssemble (chainHeadReader , header , sim .state , blockBody , receipts )
328
+ if err != nil {
329
+ return nil , nil , err
330
+ }
288
331
repairLogs (callResults , b .Hash ())
289
332
return b , callResults , nil
290
333
}
@@ -346,6 +389,9 @@ func (sim *simulator) sanitizeChain(blocks []simBlock) ([]simBlock, error) {
346
389
n := new (big.Int ).Add (prevNumber , big .NewInt (1 ))
347
390
block .BlockOverrides .Number = (* hexutil .Big )(n )
348
391
}
392
+ if block .BlockOverrides .Withdrawals == nil {
393
+ block .BlockOverrides .Withdrawals = & types.Withdrawals {}
394
+ }
349
395
diff := new (big.Int ).Sub (block .BlockOverrides .Number .ToInt (), prevNumber )
350
396
if diff .Cmp (common .Big0 ) <= 0 {
351
397
return nil , & invalidBlockNumberError {fmt .Sprintf ("block numbers must be in order: %d <= %d" , block .BlockOverrides .Number .ToInt ().Uint64 (), prevNumber )}
@@ -360,7 +406,13 @@ func (sim *simulator) sanitizeChain(blocks []simBlock) ([]simBlock, error) {
360
406
for i := uint64 (0 ); i < gap .Uint64 (); i ++ {
361
407
n := new (big.Int ).Add (prevNumber , big .NewInt (int64 (i + 1 )))
362
408
t := prevTimestamp + timestampIncrement
363
- b := simBlock {BlockOverrides : & override.BlockOverrides {Number : (* hexutil .Big )(n ), Time : (* hexutil .Uint64 )(& t )}}
409
+ b := simBlock {
410
+ BlockOverrides : & override.BlockOverrides {
411
+ Number : (* hexutil .Big )(n ),
412
+ Time : (* hexutil .Uint64 )(& t ),
413
+ Withdrawals : & types.Withdrawals {},
414
+ },
415
+ }
364
416
prevTimestamp = t
365
417
res = append (res , b )
366
418
}
@@ -405,6 +457,9 @@ func (sim *simulator) makeHeaders(blocks []simBlock) ([]*types.Header, error) {
405
457
var parentBeaconRoot * common.Hash
406
458
if sim .chainConfig .IsCancun (overrides .Number .ToInt (), (uint64 )(* overrides .Time )) {
407
459
parentBeaconRoot = & common.Hash {}
460
+ if overrides .BeaconRoot != nil {
461
+ parentBeaconRoot = overrides .BeaconRoot
462
+ }
408
463
}
409
464
header = overrides .MakeHeader (& types.Header {
410
465
UncleHash : types .EmptyUncleHash ,
0 commit comments