diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go index 805b050c0a5..a396b0b8171 100644 --- a/accounts/abi/bind/backends/simulated.go +++ b/accounts/abi/bind/backends/simulated.go @@ -758,7 +758,7 @@ func (b *SimulatedBackend) SendTransaction(ctx context.Context, tx types.Transac b.pendingState, state.NewNoopWriter(), b.pendingHeader, tx, &b.pendingHeader.GasUsed, b.pendingHeader.BlobGasUsed, - vm.Config{}); err != nil { + vm.Config{}, nil, nil); err != nil { return err } //fmt.Printf("==== Start producing block %d\n", (b.prependBlock.NumberU64() + 1)) diff --git a/cl/phase1/execution_client/execution_client_rpc.go b/cl/phase1/execution_client/execution_client_rpc.go index 82515a2f5fb..457d0a0c865 100644 --- a/cl/phase1/execution_client/execution_client_rpc.go +++ b/cl/phase1/execution_client/execution_client_rpc.go @@ -57,12 +57,6 @@ func (cc *ExecutionClientRpc) NewPayload(payload *cltypes.Eth1Block, beaconParen if payload == nil { return } - - reversedBaseFeePerGas := libcommon.Copy(payload.BaseFeePerGas[:]) - for i, j := 0, len(reversedBaseFeePerGas)-1; i < j; i, j = i+1, j-1 { - reversedBaseFeePerGas[i], reversedBaseFeePerGas[j] = reversedBaseFeePerGas[j], reversedBaseFeePerGas[i] - } - baseFee := new(big.Int).SetBytes(reversedBaseFeePerGas) var engineMethod string // determine the engine method switch payload.Version() { @@ -92,8 +86,17 @@ func (cc *ExecutionClientRpc) NewPayload(payload *cltypes.Eth1Block, beaconParen BlockHash: payload.BlockHash, } - request.BaseFeePerGas = new(hexutil.Big) - *request.BaseFeePerGas = hexutil.Big(*baseFee) + request.BaseFeePerGas = nil + if payload.BaseFeePerGas == (libcommon.Hash{}) { + reversedBaseFeePerGas := libcommon.Copy(payload.BaseFeePerGas[:]) + for i, j := 0, len(reversedBaseFeePerGas)-1; i < j; i, j = i+1, j-1 { + reversedBaseFeePerGas[i], reversedBaseFeePerGas[j] = reversedBaseFeePerGas[j], reversedBaseFeePerGas[i] + } + baseFee := new(big.Int).SetBytes(reversedBaseFeePerGas) + request.BaseFeePerGas = new(hexutil.Big) + *request.BaseFeePerGas = hexutil.Big(*baseFee) + } + payloadBody := payload.Body() // Setup transactionbody request.Withdrawals = payloadBody.Withdrawals diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index 14401d0f94b..1a7d08186b8 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -310,7 +310,7 @@ func Main(ctx *cli.Context) error { t8logger := log.New("t8ntool") chainReader := stagedsync.NewChainReaderImpl(chainConfig, tx, nil, t8logger) - result, err := core.ExecuteBlockEphemerally(chainConfig, &vmConfig, getHash, engine, block, reader, writer, chainReader, getTracer, t8logger) + result, err := core.ExecuteBlockEphemerally(chainConfig, &vmConfig, getHash, engine, block, reader, writer, chainReader, getTracer, nil, nil, t8logger) if hashError != nil { return NewError(ErrorMissingBlockhash, fmt.Errorf("blockhash error: %v", err)) diff --git a/cmd/integration/commands/stages.go b/cmd/integration/commands/stages.go index 804c2b46555..912f10e0678 100644 --- a/cmd/integration/commands/stages.go +++ b/cmd/integration/commands/stages.go @@ -919,7 +919,7 @@ func stageExec(db kv.RwDB, ctx context.Context, logger log.Logger) error { br, _ := blocksIO(db, logger) cfg := stagedsync.StageExecuteBlocksCfg(db, pm, batchSize, nil, chainConfig, engine, vmConfig, nil, /*stateStream=*/ false, - /*badBlockHalt=*/ false, historyV3, dirs, br, nil, genesis, syncCfg, agg, nil) + /*badBlockHalt=*/ false, historyV3, dirs, br, nil, genesis, syncCfg, agg, nil, "", time.Second*10) var tx kv.RwTx //nil - means lower-level code (each stage) will manage transactions if noCommit { @@ -967,6 +967,7 @@ func stageTrie(db kv.RwDB, ctx context.Context, logger log.Logger) error { defer agg.Close() _, _, sync, _, _ := newSync(ctx, db, nil /* miningConfig */, logger) must(sync.SetCurrentStage(stages.IntermediateHashes)) + chainConfig := fromdb.ChainConfig(db) if warmup { return reset2.Warmup(ctx, db, log.LvlInfo, stages.IntermediateHashes) @@ -1009,7 +1010,7 @@ func stageTrie(db kv.RwDB, ctx context.Context, logger log.Logger) error { return err } } else { - if _, err := stagedsync.SpawnIntermediateHashesStage(s, sync /* Unwinder */, tx, cfg, ctx, logger); err != nil { + if _, err := stagedsync.SpawnIntermediateHashesStage(s, sync /* Unwinder */, tx, cfg, ctx, chainConfig, logger); err != nil { return err } } @@ -1581,10 +1582,10 @@ func newSync(ctx context.Context, db kv.RwDB, miningConfig *params.MiningConfig, stagedsync.MiningStages(ctx, stagedsync.StageMiningCreateBlockCfg(db, miner, *chainConfig, engine, nil, nil, dirs.Tmp, blockReader), stagedsync.StageBorHeimdallCfg(db, snapDb, miner, *chainConfig, heimdallClient, blockReader, nil, nil, recents, signatures), - stagedsync.StageMiningExecCfg(db, miner, events, *chainConfig, engine, &vm.Config{}, dirs.Tmp, nil, 0, nil, nil, blockReader), + stagedsync.StageMiningExecCfg(db, miner, events, *chainConfig, engine, &vm.Config{}, dirs.Tmp, nil, 0, nil, nil, blockReader, nil, nil), stagedsync.StageHashStateCfg(db, dirs, historyV3), stagedsync.StageTrieCfg(db, false, true, false, dirs.Tmp, blockReader, nil, historyV3, agg), - stagedsync.StageMiningFinishCfg(db, *chainConfig, engine, miner, miningCancel, blockReader, builder.NewLatestBlockBuiltStore()), + stagedsync.StageMiningFinishCfg(db, *chainConfig, engine, miner, miningCancel, blockReader, builder.NewLatestBlockBuiltStore(), nil, nil), ), stagedsync.MiningUnwindOrder, stagedsync.MiningPruneOrder, diff --git a/cmd/integration/commands/state_stages.go b/cmd/integration/commands/state_stages.go index 3401cf669de..f7f4c7b5d84 100644 --- a/cmd/integration/commands/state_stages.go +++ b/cmd/integration/commands/state_stages.go @@ -44,7 +44,7 @@ import ( var stateStages = &cobra.Command{ Use: "state_stages", Short: `Run all StateStages (which happen after senders) in loop. -Examples: +Examples: --unwind=1 --unwind.every=10 # 10 blocks forward, 1 block back, 10 blocks forward, ... --unwind=10 --unwind.every=1 # 1 block forward, 10 blocks back, 1 blocks forward, ... --unwind=10 # 10 blocks back, then stop @@ -222,7 +222,7 @@ func syncBySmallSteps(db kv.RwDB, miningConfig params.MiningConfig, ctx context. br, _ := blocksIO(db, logger1) execCfg := stagedsync.StageExecuteBlocksCfg(db, pm, batchSize, changeSetHook, chainConfig, engine, vmConfig, changesAcc, false, false, historyV3, dirs, - br, nil, genesis, syncCfg, agg, nil) + br, nil, genesis, syncCfg, agg, nil, "", time.Second*10) execUntilFunc := func(execToBlock uint64) func(firstCycle bool, badBlockUnwind bool, stageState *stagedsync.StageState, unwinder stagedsync.Unwinder, tx kv.RwTx, logger log.Logger) error { return func(firstCycle bool, badBlockUnwind bool, s *stagedsync.StageState, unwinder stagedsync.Unwinder, tx kv.RwTx, logger log.Logger) error { @@ -560,7 +560,7 @@ func loopExec(db kv.RwDB, ctx context.Context, unwind uint64, logger log.Logger) br, _ := blocksIO(db, logger) cfg := stagedsync.StageExecuteBlocksCfg(db, pm, batchSize, nil, chainConfig, engine, vmConfig, nil, /*stateStream=*/ false, - /*badBlockHalt=*/ false, historyV3, dirs, br, nil, genesis, syncCfg, agg, nil) + /*badBlockHalt=*/ false, historyV3, dirs, br, nil, genesis, syncCfg, agg, nil, "", time.Second*10) // set block limit of execute stage sync.MockExecFunc(stages.Execution, func(firstCycle bool, badBlockUnwind bool, stageState *stagedsync.StageState, unwinder stagedsync.Unwinder, tx kv.RwTx, logger log.Logger) error { diff --git a/cmd/state/commands/opcode_tracer.go b/cmd/state/commands/opcode_tracer.go index 8be9bcca465..4bef3e04890 100644 --- a/cmd/state/commands/opcode_tracer.go +++ b/cmd/state/commands/opcode_tracer.go @@ -721,7 +721,7 @@ func runBlock(engine consensus.Engine, ibs *state.IntraBlockState, txnWriter sta rules := chainConfig.Rules(block.NumberU64(), block.Time()) for i, tx := range block.Transactions() { ibs.SetTxContext(tx.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, txnWriter, header, tx, usedGas, usedBlobGas, vmConfig) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, txnWriter, header, tx, usedGas, usedBlobGas, vmConfig, nil, nil) if err != nil { return nil, fmt.Errorf("could not apply tx %d [%x] failed: %w", i, tx.Hash(), err) } diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 5c92c2061d5..ab484d0711e 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -209,8 +209,10 @@ func VerifyHeaderBasics(chain consensus.ChainHeaderReader, header, parent *types return consensus.ErrFutureBlock } } - if header.Time <= parent.Time { - return errOlderBlockTime + if !chain.Config().IsOptimismPreBedrock(header.Number.Uint64()) { + if header.Time <= parent.Time { + return errOlderBlockTime + } } // Verify that the gas limit is <= 2^63-1 if header.GasLimit > params.MaxGasLimit { @@ -662,11 +664,13 @@ func AccumulateRewards(config *chain.Config, header *types.Header, uncles []*typ // accumulateRewards retrieves rewards for a block and applies them to the coinbase accounts for miner and uncle miners func accumulateRewards(config *chain.Config, state *state.IntraBlockState, header *types.Header, uncles []*types.Header) { - minerReward, uncleRewards := AccumulateRewards(config, header, uncles) - for i, uncle := range uncles { - if i < len(uncleRewards) { - state.AddBalance(uncle.Coinbase, &uncleRewards[i]) + if !config.IsOptimismPreBedrock(header.Number.Uint64()) { + minerReward, uncleRewards := AccumulateRewards(config, header, uncles) + for i, uncle := range uncles { + if i < len(uncleRewards) { + state.AddBalance(uncle.Coinbase, &uncleRewards[i]) + } } + state.AddBalance(header.Coinbase, &minerReward) } - state.AddBalance(header.Coinbase, &minerReward) } diff --git a/consensus/merge/merge.go b/consensus/merge/merge.go index c5544ef33bd..4af3faebb9b 100644 --- a/consensus/merge/merge.go +++ b/consensus/merge/merge.go @@ -195,16 +195,18 @@ func (s *Merge) CalcDifficulty(chain consensus.ChainHeaderReader, time, parentTi // stock Ethereum consensus engine with EIP-3675 modifications. func (s *Merge) verifyHeader(chain consensus.ChainHeaderReader, header, parent *types.Header) error { - if uint64(len(header.Extra)) > params.MaximumExtraDataSize { - return fmt.Errorf("extra-data longer than %d bytes (%d)", params.MaximumExtraDataSize, len(header.Extra)) - } + if !chain.Config().IsOptimismPreBedrock(header.Number.Uint64()) { + if uint64(len(header.Extra)) > params.MaximumExtraDataSize { + return fmt.Errorf("extra-data longer than %d bytes (%d)", params.MaximumExtraDataSize, len(header.Extra)) + } - if header.Time <= parent.Time { - return errOlderBlockTime - } + if header.Time <= parent.Time { + return errOlderBlockTime + } - if header.Difficulty.Cmp(ProofOfStakeDifficulty) != 0 { - return errInvalidDifficulty + if header.Difficulty.Cmp(ProofOfStakeDifficulty) != 0 { + return errInvalidDifficulty + } } if !bytes.Equal(header.Nonce[:], ProofOfStakeNonce[:]) { @@ -229,8 +231,10 @@ func (s *Merge) verifyHeader(chain consensus.ChainHeaderReader, header, parent * return errInvalidUncleHash } - if err := misc.VerifyEip1559Header(chain.Config(), parent, header, false); err != nil { - return err + if !chain.Config().IsOptimismPreBedrock(header.Number.Uint64()) { + if err := misc.VerifyEip1559Header(chain.Config(), parent, header, false); err != nil { + return err + } } // Verify existence / non-existence of withdrawalsHash diff --git a/consensus/merge/merge_test.go b/consensus/merge/merge_test.go index aee7810cd2f..7a276398ce8 100644 --- a/consensus/merge/merge_test.go +++ b/consensus/merge/merge_test.go @@ -14,7 +14,9 @@ import ( type readerMock struct{} func (r readerMock) Config() *chain.Config { - return nil + return &chain.Config{ + BedrockBlock: libcommon.Big0, + } } func (r readerMock) CurrentHeader() *types.Header { @@ -49,6 +51,7 @@ func (r readerMock) BorSpan(spanId uint64) []byte { // and nonce so we are gonna test those func TestVerifyHeaderDifficulty(t *testing.T) { header := &types.Header{ + Number: big.NewInt(1), Difficulty: big.NewInt(1), Time: 1, } @@ -70,6 +73,7 @@ func TestVerifyHeaderDifficulty(t *testing.T) { func TestVerifyHeaderNonce(t *testing.T) { header := &types.Header{ + Number: big.NewInt(1), Nonce: types.BlockNonce{1, 0, 0, 0, 0, 0, 0, 0}, Difficulty: big.NewInt(0), Time: 1, diff --git a/core/blockchain.go b/core/blockchain.go index fae6b430081..bace928b895 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -41,6 +41,7 @@ import ( "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/core/vm/evmtypes" "github.com/ledgerwatch/erigon/rlp" + "github.com/ledgerwatch/erigon/rpc" ) var ( @@ -84,7 +85,7 @@ func ExecuteBlockEphemerally( engine consensus.Engine, block *types.Block, stateReader state.StateReader, stateWriter state.WriterWithChangeSets, chainReader consensus.ChainReader, getTracer func(txIndex int, txHash libcommon.Hash) (vm.EVMLogger, error), - logger log.Logger, + historicalRPCService *rpc.Client, historicalRPCTimeout *time.Duration, logger log.Logger, ) (*EphemeralExecResult, error) { defer BlockExecutionTimer.UpdateDuration(time.Now()) @@ -123,7 +124,7 @@ func ExecuteBlockEphemerally( vmConfig.Tracer = tracer writeTrace = true } - receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, usedBlobGas, *vmConfig) + receipt, _, err := ApplyTransaction(chainConfig, blockHashFunc, engine, nil, gp, ibs, noop, header, tx, usedGas, usedBlobGas, *vmConfig, historicalRPCService, historicalRPCTimeout) if writeTrace { if ftracer, ok := vmConfig.Tracer.(vm.FlushableTracer); ok { ftracer.Flush(tx) diff --git a/core/chain_makers.go b/core/chain_makers.go index d1525a8d60c..1f1684a7230 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -122,7 +122,7 @@ func (b *BlockGen) AddTxWithChain(getHeader func(hash libcommon.Hash, number uin b.SetCoinbase(libcommon.Address{}) } b.ibs.SetTxContext(tx.Hash(), libcommon.Hash{}, len(b.txs)) - receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, b.header.BlobGasUsed, vm.Config{}) + receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, b.header.BlobGasUsed, vm.Config{}, nil, nil) if err != nil { panic(err) } @@ -135,7 +135,7 @@ func (b *BlockGen) AddFailedTxWithChain(getHeader func(hash libcommon.Hash, numb b.SetCoinbase(libcommon.Address{}) } b.ibs.SetTxContext(tx.Hash(), libcommon.Hash{}, len(b.txs)) - receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, b.header.BlobGasUsed, vm.Config{}) + receipt, _, err := ApplyTransaction(b.config, GetHashFn(b.header, getHeader), engine, &b.header.Coinbase, b.gasPool, b.ibs, state.NewNoopWriter(), b.header, tx, &b.header.GasUsed, b.header.BlobGasUsed, vm.Config{}, nil, nil) _ = err // accept failed transactions b.txs = append(b.txs, tx) b.receipts = append(b.receipts, receipt) diff --git a/core/genesis_write.go b/core/genesis_write.go index 5da0f52f967..6a850491fb5 100644 --- a/core/genesis_write.go +++ b/core/genesis_write.go @@ -292,7 +292,12 @@ func write(tx kv.RwTx, g *types.Genesis, tmpDir string) (*types.Block, *state.In if err := rawdb.WriteBlock(tx, block); err != nil { return nil, nil, err } - if err := rawdb.WriteTd(tx, block.Hash(), block.NumberU64(), g.Difficulty); err != nil { + + difficulty := g.Difficulty + if g.Config.IsBobaLegacyBlock(block.NumberU64()) { + difficulty = libcommon.Big1 + } + if err := rawdb.WriteTd(tx, block.Hash(), block.NumberU64(), difficulty); err != nil { return nil, nil, err } if err := rawdbv3.TxNums.WriteForGenesis(tx, 1); err != nil { @@ -545,6 +550,13 @@ func DeveloperGenesisBlock(period uint64, faucet libcommon.Address) *types.Genes func GenesisToBlock(g *types.Genesis, tmpDir string) (*types.Block, *state.IntraBlockState, error) { _ = g.Alloc //nil-check + baseFee := g.BaseFee + isBobaLegacyBlock := false + if g.Config.IsBobaLegacyBlock(g.Number) { + isBobaLegacyBlock = true + baseFee = nil + } + head := &types.Header{ Number: new(big.Int).SetUint64(g.Number), Nonce: types.EncodeNonce(g.Nonce), @@ -556,7 +568,7 @@ func GenesisToBlock(g *types.Genesis, tmpDir string) (*types.Block, *state.Intra Difficulty: g.Difficulty, MixDigest: g.Mixhash, Coinbase: g.Coinbase, - BaseFee: g.BaseFee, + BaseFee: baseFee, BlobGasUsed: g.BlobGasUsed, ExcessBlobGas: g.ExcessBlobGas, AuRaStep: g.AuRaStep, @@ -568,7 +580,7 @@ func GenesisToBlock(g *types.Genesis, tmpDir string) (*types.Block, *state.Intra if g.Difficulty == nil { head.Difficulty = params.GenesisDifficulty } - if g.Config != nil && g.Config.IsLondon(0) { + if g.Config != nil && g.Config.IsLondon(0) && !isBobaLegacyBlock { if g.BaseFee != nil { head.BaseFee = g.BaseFee } else { @@ -599,6 +611,13 @@ func GenesisToBlock(g *types.Genesis, tmpDir string) (*types.Block, *state.Intra } } + if isBobaLegacyBlock && g.Number == 0 { + head.Time = 0 + head.Difficulty = big.NewInt(1) + head.Extra = libcommon.Hex2Bytes(g.Config.GetBobaGenesisExtraData()) + head.Coinbase = libcommon.HexToAddress(g.Config.GetBobaGenesisCoinbase()) + } + var root libcommon.Hash var statedb *state.IntraBlockState wg := sync.WaitGroup{} @@ -662,8 +681,10 @@ func GenesisToBlock(g *types.Genesis, tmpDir string) (*types.Block, *state.Intra if err = statedb.FinalizeTx(&chain.Rules{}, w); err != nil { return } - if root, err = trie.CalcRoot("genesis", tx); err != nil { - return + if !isBobaLegacyBlock { + if root, err = trie.CalcRoot("genesis", tx); err != nil { + return + } } }() wg.Wait() @@ -671,7 +692,11 @@ func GenesisToBlock(g *types.Genesis, tmpDir string) (*types.Block, *state.Intra return nil, nil, err } - head.Root = root + if isBobaLegacyBlock && g.Number == 0 { + head.Root = libcommon.HexToHash(g.Config.GetBobaGenesisRoot()) + } else { + head.Root = root + } return types.NewBlock(head, nil, nil, nil, withdrawals), statedb, nil } diff --git a/core/state_processor.go b/core/state_processor.go index 02dfa4ebb16..b8118b331df 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -17,6 +17,10 @@ package core import ( + "context" + "fmt" + "time" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/log/v3" @@ -27,6 +31,7 @@ import ( "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/core/vm/evmtypes" "github.com/ledgerwatch/erigon/crypto" + "github.com/ledgerwatch/erigon/rpc" ) // applyTransaction attempts to apply a transaction to the given state database @@ -35,7 +40,7 @@ import ( // indicating the block was invalid. func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *GasPool, ibs *state.IntraBlockState, stateWriter state.StateWriter, header *types.Header, tx types.Transaction, usedGas, usedBlobGas *uint64, - evm *vm.EVM, cfg vm.Config) (*types.Receipt, []byte, error) { + evm *vm.EVM, cfg vm.Config, historicalRPCService *rpc.Client, historicalRPCTimeout *time.Duration) (*types.Receipt, []byte, error) { rules := evm.ChainRules() msg, err := tx.AsMessage(*types.MakeSigner(config, header.Number.Uint64(), header.Time), header.BaseFee, rules) if err != nil { @@ -64,10 +69,21 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G nonce = ibs.GetNonce(msg.From()) } - result, err := ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */) - if err != nil { - return nil, nil, err + var legacyReceipt *types.Receipt + isOptimismPreBlock := evm.ChainConfig().IsOptimismPreBedrock(header.Number.Uint64()) + result := &ExecutionResult{ + UsedGas: msg.Gas(), + Err: nil, + ReturnData: []byte{}, } + + if !isOptimismPreBlock { + result, err = ApplyMessage(evm, msg, gp, true /* refunds */, false /* gasBailout */) + if err != nil { + return nil, nil, err + } + } + // Update the state with pending changes if err = ibs.FinalizeTx(rules, stateWriter); err != nil { return nil, nil, err @@ -77,6 +93,20 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G *usedBlobGas += tx.GetBlobGas() } + if isOptimismPreBlock { + if historicalRPCService != nil { + ctx, cancel := context.WithTimeout(context.Background(), *historicalRPCTimeout) + err = historicalRPCService.CallContext(ctx, &legacyReceipt, "eth_getTransactionReceipt", tx.Hash().String()) + cancel() + if err != nil { + return nil, nil, err + } + *usedGas = legacyReceipt.GasUsed + } else { + return nil, nil, fmt.Errorf("legacy block must be handled by the historicalRPCService") + } + } + // Set the receipt logs and create the bloom filter. // based on the eip phase, we're passing whether the root touch-delete accounts. var receipt *types.Receipt @@ -108,9 +138,22 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G } // Set the receipt logs and create a bloom for filtering receipt.Logs = ibs.GetLogs(tx.Hash()) - receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) receipt.BlockNumber = header.Number receipt.TransactionIndex = uint(ibs.TxIndex()) + + if isOptimismPreBlock { + receipt.GasUsed = legacyReceipt.GasUsed + receipt.Logs = legacyReceipt.Logs + receipt.Status = legacyReceipt.Status + // The following fields can not be set in the legacy receipt + // The math of calculating legacy and new receipts is not compatible + receipt.L1GasPrice = legacyReceipt.L1GasPrice + receipt.L1GasUsed = legacyReceipt.L1GasUsed + receipt.L1Fee = legacyReceipt.L1Fee + receipt.FeeScalar = legacyReceipt.FeeScalar + } + + receipt.Bloom = types.CreateBloom(types.Receipts{receipt}) } return receipt, result.ReturnData, err @@ -123,6 +166,7 @@ func applyTransaction(config *chain.Config, engine consensus.EngineReader, gp *G func ApplyTransaction(config *chain.Config, blockHashFunc func(n uint64) libcommon.Hash, engine consensus.EngineReader, author *libcommon.Address, gp *GasPool, ibs *state.IntraBlockState, stateWriter state.StateWriter, header *types.Header, tx types.Transaction, usedGas, usedBlobGas *uint64, cfg vm.Config, + historicalRPCService *rpc.Client, historicalRPCTimeout *time.Duration, ) (*types.Receipt, []byte, error) { log.Debug("ApplyTransaction called for", "txhash", tx.Hash(), "blockNum", header.Number.Uint64()) // Create a new context to be used in the EVM environment @@ -135,5 +179,5 @@ func ApplyTransaction(config *chain.Config, blockHashFunc func(n uint64) libcomm blockContext := NewEVMBlockContext(header, blockHashFunc, engine, author, l1CostFunc) vmenv := vm.NewEVM(blockContext, evmtypes.TxContext{}, ibs, config, cfg) - return applyTransaction(config, engine, gp, ibs, stateWriter, header, tx, usedGas, usedBlobGas, vmenv, cfg) + return applyTransaction(config, engine, gp, ibs, stateWriter, header, tx, usedGas, usedBlobGas, vmenv, cfg, historicalRPCService, historicalRPCTimeout) } diff --git a/core/types/blob_tx_wrapper.go b/core/types/blob_tx_wrapper.go index 2c4303d15f7..6b296cf666a 100644 --- a/core/types/blob_tx_wrapper.go +++ b/core/types/blob_tx_wrapper.go @@ -383,3 +383,5 @@ func (txw *BlobTxWrapper) MarshalBinary(w io.Writer) error { func (txw BlobTxWrapper) EncodeRLP(w io.Writer) error { return txw.Tx.EncodeRLP(w) } + +func (txw BlobTxWrapper) IsLegacyDepositTx() bool { return false } diff --git a/core/types/deposit_tx.go b/core/types/deposit_tx.go index 8a2e5e93066..9f5dce4cd5e 100644 --- a/core/types/deposit_tx.go +++ b/core/types/deposit_tx.go @@ -382,3 +382,5 @@ func (tx *DepositTransaction) SetSender(addr libcommon.Address) { } // otherwise a NOP } + +func (tx *DepositTransaction) IsLegacyDepositTx() bool { return false } diff --git a/core/types/dynamic_fee_tx.go b/core/types/dynamic_fee_tx.go index 0951a047981..ae2d01e23d0 100644 --- a/core/types/dynamic_fee_tx.go +++ b/core/types/dynamic_fee_tx.go @@ -463,3 +463,5 @@ func NewEIP1559Transaction(chainID uint256.Int, nonce uint64, to libcommon.Addre FeeCap: gasFeeCap, } } + +func (tx *DynamicFeeTransaction) IsLegacyDepositTx() bool { return false } diff --git a/core/types/legacy_tx.go b/core/types/legacy_tx.go index 30f3ba58db5..460735bc778 100644 --- a/core/types/legacy_tx.go +++ b/core/types/legacy_tx.go @@ -369,6 +369,10 @@ func (tx LegacyTx) AsMessage(s Signer, _ *big.Int, rules *chain.Rules) (Message, rollupDataGas: RollupDataGas(tx, rules), } + if tx.IsLegacyDepositTx() { + return msg, nil + } + var err error msg.from, err = tx.Sender(s) return msg, err @@ -456,3 +460,19 @@ func (tx *LegacyTx) Sender(signer Signer) (libcommon.Address, error) { tx.from.Store(addr) return addr, nil } + +func (tx *LegacyTx) IsLegacyDepositTx() bool { + V, R, S := tx.RawSignatureValues() + // contract creation + if tx.To == nil { + return false + } + MessengerAddress := libcommon.HexToAddress("0x4200000000000000000000000000000000000007") + if *tx.To == MessengerAddress && + *V == (uint256.Int{}) && + *R == (uint256.Int{}) && + *S == (uint256.Int{}) { + return true + } + return false +} diff --git a/core/types/transaction.go b/core/types/transaction.go index 8273f231f7a..cd1e20761cb 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -98,6 +98,7 @@ type Transaction interface { IsContractDeploy() bool Unwrap() Transaction // If this is a network wrapper, returns the unwrapped tx. Otherwise returns itself. IsDepositTx() bool + IsLegacyDepositTx() bool } // TransactionMisc is collection of miscelaneous fields for transaction that is supposed to be embedded into concrete diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index d264b06783e..070deab3230 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -275,6 +275,9 @@ func (sg Signer) SenderWithContext(context *secp256k1.Context, tx Transaction) ( default: return libcommon.Address{}, ErrTxTypeNotSupported } + if tx.IsLegacyDepositTx() { + return libcommon.Address{}, nil + } return recoverPlain(context, tx.SigningHash(signChainID), R, S, &V, !sg.malleable) } diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index 1686601c190..6cb55bf309d 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -26,6 +26,53 @@ import ( "github.com/ledgerwatch/erigon-lib/common/fixedgas" ) +// Boba chain config +var ( + // Mainnet + BobaMainnetChainId = big.NewInt(288) + // Boba Mainnet genesis gas limit + BobaMainnetGenesisGasLimit = 11000000 + // Boba Mainnet genesis block coinbase + BobaMainnetGenesisCoinbase = "0x0000000000000000000000000000000000000000" + // Boba Mainnet genesis block extra data + BobaMainnetGenesisExtraData = "000000000000000000000000000000000000000000000000000000000000000000000398232e2064f896018496b4b44b3d62751f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + // Boba Mainnet genesis root + BobaMainnetGenesisRoot = "0x7ec54492a4504ff1ef3491825cd55e01e5c75409e4287129170e98d4693848ce" + + // Boba Sepolia + BobaSepoliaChainId = big.NewInt(28882) + // Boba Sepolia genesis gas limit + BobaSepoliaGenesisGasLimit = 11000000 + // Boba Sepolia genesis block coinbase + BobaSepoliaGenesisCoinbase = "0x0000000000000000000000000000000000000000" + // Boba Sepolia genesis block extra data + BobaSepoliaGenesisExtraData = "000000000000000000000000000000000000000000000000000000000000000000000398232e2064f896018496b4b44b3d62751f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + // Boba Sepolia genesis root + BobaSepoliaGenesisRoot = "0x8c57d7486ebd810dc728748553b08919c81024f024651afdbd076780c48621b0" + + // Optimism Mainnet + OptimismMainnetChainId = big.NewInt(10) + // Optimism Mainnet genesis gas limit + OptimismMainnetGenesisGasLimit = 15000000 + // Optimism Mainnet genesis block coinbase + OptimismMainnetGenesisCoinbase = "0x0000000000000000000000000000000000000000" + // Optimism Mainnet genesis block extra data + OptimismMainnetGenesisExtraData = "000000000000000000000000000000000000000000000000000000000000000000000398232e2064f896018496b4b44b3d62751f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + // Optimism Mainnet genesis root + OptimismMainnetGenesisRoot = "0xeddb4c1786789419153a27c4c80ff44a2226b6eda04f7e22ce5bae892ea568eb" + + // Bnb Testnet + BnbTestnetChainId = big.NewInt(9728) + // Bnb Testnet genesis gas limit + BnbTestnetGenesisGasLimit = 11000000 + // Bnb Testnet genesis block coinbase + BnbTestnetGenesisCoinbase = "0x0000000000000000000000000000000000000000" + // Bnb Testnet genesis block extra data + BnbTestnetGenesisExtraData = "000000000000000000000000000000000000000000000000000000000000000000000398232e2064f896018496b4b44b3d62751f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" + // Bnb Testnet genesis root + BnbTestnetGenesisRoot = "0xdd0a18054de6e995f2c66f3e3aae590df9cbee1c7e5f602b8bcf5a0c3b1a2f46" +) + // Config is the core config which determines the blockchain settings. // // Config is stored in the database on a per block basis. This means @@ -321,6 +368,106 @@ func (c *Config) GetMaxBlobsPerBlock() uint64 { return c.GetMaxBlobGasPerBlock() / fixedgas.BlobGasPerBlob } +func (c *Config) IsBobaLegacyBlock(num uint64) bool { + // Boba Mainnet + if BobaMainnetChainId.Cmp(c.ChainID) == 0 { + return c.BedrockBlock.Uint64() > num + } + // Boba Sepolia + if BobaSepoliaChainId.Cmp(c.ChainID) == 0 { + return c.BedrockBlock.Uint64() > num + } + // Optimism Mainnet + if OptimismMainnetChainId.Cmp(c.ChainID) == 0 { + return c.BedrockBlock.Uint64() > num + } + // Bnb Testnet + if BnbTestnetChainId.Cmp(c.ChainID) == 0 { + return c.BedrockBlock.Uint64() > num + } + return false +} + +func (c *Config) GetBobaGenesisGasLimit() int { + // Boba Mainnet + if BobaMainnetChainId.Cmp(c.ChainID) == 0 { + return BobaMainnetGenesisGasLimit + } + // Boba Sepolia + if BobaSepoliaChainId.Cmp(c.ChainID) == 0 { + return BobaSepoliaGenesisGasLimit + } + // Optimism Mainnet + if OptimismMainnetChainId.Cmp(c.ChainID) == 0 { + return OptimismMainnetGenesisGasLimit + } + // Bnb Testnet + if BnbTestnetChainId.Cmp(c.ChainID) == 0 { + return BnbTestnetGenesisGasLimit + } + return 11000000 +} + +func (c *Config) GetBobaGenesisCoinbase() string { + // Boba Mainnet + if BobaMainnetChainId.Cmp(c.ChainID) == 0 { + return BobaMainnetGenesisCoinbase + } + // Boba Sepolia + if BobaSepoliaChainId.Cmp(c.ChainID) == 0 { + return BobaSepoliaGenesisCoinbase + } + // Optimism Mainnet + if OptimismMainnetChainId.Cmp(c.ChainID) == 0 { + return OptimismMainnetGenesisCoinbase + } + // Bnb Testnet + if BnbTestnetChainId.Cmp(c.ChainID) == 0 { + return BnbTestnetGenesisCoinbase + } + return "0x0000000000000000000000000000000000000000" +} + +func (c *Config) GetBobaGenesisExtraData() string { + // Boba Mainnet + if BobaMainnetChainId.Cmp(c.ChainID) == 0 { + return BobaMainnetGenesisExtraData + } + // Boba Sepolia + if BobaSepoliaChainId.Cmp(c.ChainID) == 0 { + return BobaSepoliaGenesisExtraData + } + // Optimism Mainnet + if OptimismMainnetChainId.Cmp(c.ChainID) == 0 { + return OptimismMainnetGenesisExtraData + } + // Bnb Testnet + if BnbTestnetChainId.Cmp(c.ChainID) == 0 { + return BnbTestnetGenesisExtraData + } + return "" +} + +func (c *Config) GetBobaGenesisRoot() string { + // Boba Mainnet + if BobaMainnetChainId.Cmp(c.ChainID) == 0 { + return BobaMainnetGenesisRoot + } + // Boba Sepolia + if BobaSepoliaChainId.Cmp(c.ChainID) == 0 { + return BobaSepoliaGenesisRoot + } + // Optimism Mainnet + if OptimismMainnetChainId.Cmp(c.ChainID) == 0 { + return OptimismMainnetGenesisRoot + } + // Bnb Testnet + if BnbTestnetChainId.Cmp(c.ChainID) == 0 { + return BnbTestnetGenesisRoot + } + return "" +} + // CheckCompatible checks whether scheduled fork transitions have been imported // with a mismatching chain configuration. func (c *Config) CheckCompatible(newcfg *Config, height uint64) *ConfigCompatError { diff --git a/eth/backend.go b/eth/backend.go index 0d83170b4f1..01ac49444da 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -552,7 +552,7 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger if err != nil { return err } - if progress < header.Number.Uint64() { + if progress < header.Number.Uint64() && !chainConfig.IsBobaLegacyBlock(header.Number.Uint64()) { return fmt.Errorf("unsuccessful execution, progress %d < expected %d", progress, header.Number.Uint64()) } return nil @@ -663,10 +663,10 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger stagedsync.MiningStages(backend.sentryCtx, stagedsync.StageMiningCreateBlockCfg(backend.chainDB, miner, *backend.chainConfig, backend.engine, backend.txPoolDB, nil, tmpdir, backend.blockReader), stagedsync.StageBorHeimdallCfg(backend.chainDB, snapDb, miner, *backend.chainConfig, heimdallClient, backend.blockReader, nil, nil, recents, signatures), - stagedsync.StageMiningExecCfg(backend.chainDB, miner, backend.notifications.Events, *backend.chainConfig, backend.engine, &vm.Config{}, tmpdir, nil, 0, backend.txPool, backend.txPoolDB, blockReader), + stagedsync.StageMiningExecCfg(backend.chainDB, miner, backend.notifications.Events, *backend.chainConfig, backend.engine, &vm.Config{}, tmpdir, nil, 0, backend.txPool, backend.txPoolDB, blockReader, nil, nil), stagedsync.StageHashStateCfg(backend.chainDB, dirs, config.HistoryV3), stagedsync.StageTrieCfg(backend.chainDB, false, true, true, tmpdir, blockReader, nil, config.HistoryV3, backend.agg), - stagedsync.StageMiningFinishCfg(backend.chainDB, *backend.chainConfig, backend.engine, miner, backend.miningSealingQuit, backend.blockReader, latestBlockBuiltStore), + stagedsync.StageMiningFinishCfg(backend.chainDB, *backend.chainConfig, backend.engine, miner, backend.miningSealingQuit, backend.blockReader, latestBlockBuiltStore, nil, nil), ), stagedsync.MiningUnwindOrder, stagedsync.MiningPruneOrder, logger) @@ -683,10 +683,10 @@ func New(ctx context.Context, stack *node.Node, config *ethconfig.Config, logger stagedsync.MiningStages(backend.sentryCtx, stagedsync.StageMiningCreateBlockCfg(backend.chainDB, miningStatePos, *backend.chainConfig, backend.engine, backend.txPoolDB, param, tmpdir, backend.blockReader), stagedsync.StageBorHeimdallCfg(backend.chainDB, snapDb, miningStatePos, *backend.chainConfig, heimdallClient, backend.blockReader, nil, nil, recents, signatures), - stagedsync.StageMiningExecCfg(backend.chainDB, miningStatePos, backend.notifications.Events, *backend.chainConfig, backend.engine, &vm.Config{}, tmpdir, interrupt, param.PayloadId, backend.txPool, backend.txPoolDB, blockReader), + stagedsync.StageMiningExecCfg(backend.chainDB, miningStatePos, backend.notifications.Events, *backend.chainConfig, backend.engine, &vm.Config{}, tmpdir, interrupt, param.PayloadId, backend.txPool, backend.txPoolDB, blockReader, backend.historicalRPCService, &config.RollupHistoricalRPCTimeout), stagedsync.StageHashStateCfg(backend.chainDB, dirs, config.HistoryV3), stagedsync.StageTrieCfg(backend.chainDB, false, true, true, tmpdir, blockReader, nil, config.HistoryV3, backend.agg), - stagedsync.StageMiningFinishCfg(backend.chainDB, *backend.chainConfig, backend.engine, miningStatePos, backend.miningSealingQuit, backend.blockReader, latestBlockBuiltStore), + stagedsync.StageMiningFinishCfg(backend.chainDB, *backend.chainConfig, backend.engine, miningStatePos, backend.miningSealingQuit, backend.blockReader, latestBlockBuiltStore, backend.historicalRPCService, &config.RollupHistoricalRPCTimeout), ), stagedsync.MiningUnwindOrder, stagedsync.MiningPruneOrder, logger) // We start the mining step diff --git a/eth/stagedsync/default_stages.go b/eth/stagedsync/default_stages.go index e4b52eefdb4..cd00a454e93 100644 --- a/eth/stagedsync/default_stages.go +++ b/eth/stagedsync/default_stages.go @@ -149,7 +149,7 @@ func DefaultStages(ctx context.Context, _, err := SpawnVerkleTrie(s, u, tx, trieCfg, ctx, logger) return err } - _, err := SpawnIntermediateHashesStage(s, u, tx, trieCfg, ctx, logger) + _, err := SpawnIntermediateHashesStage(s, u, tx, trieCfg, ctx, exec.chainConfig, logger) return err }, Unwind: func(firstCycle bool, u *UnwindState, s *StageState, tx kv.RwTx, logger log.Logger) error { @@ -328,7 +328,7 @@ func PipelineStages(ctx context.Context, snapshots SnapshotsCfg, blockHashCfg Bl _, err := SpawnVerkleTrie(s, u, tx, trieCfg, ctx, logger) return err } - _, err := SpawnIntermediateHashesStage(s, u, tx, trieCfg, ctx, logger) + _, err := SpawnIntermediateHashesStage(s, u, tx, trieCfg, ctx, exec.chainConfig, logger) return err }, Unwind: func(firstCycle bool, u *UnwindState, s *StageState, tx kv.RwTx, logger log.Logger) error { @@ -494,7 +494,7 @@ func StateStages(ctx context.Context, headers HeadersCfg, bodies BodiesCfg, bloc ID: stages.IntermediateHashes, Description: "Generate intermediate hashes and computing state root", Forward: func(firstCycle bool, badBlockUnwind bool, s *StageState, u Unwinder, tx kv.RwTx, logger log.Logger) error { - _, err := SpawnIntermediateHashesStage(s, u, tx, trieCfg, ctx, logger) + _, err := SpawnIntermediateHashesStage(s, u, tx, trieCfg, ctx, exec.chainConfig, logger) return err }, Unwind: func(firstCycle bool, u *UnwindState, s *StageState, tx kv.RwTx, logger log.Logger) error { diff --git a/eth/stagedsync/stage_execute.go b/eth/stagedsync/stage_execute.go index d6fa05570de..e34023d3dfa 100644 --- a/eth/stagedsync/stage_execute.go +++ b/eth/stagedsync/stage_execute.go @@ -44,6 +44,7 @@ import ( "github.com/ledgerwatch/erigon/eth/stagedsync/stages" trace_logger "github.com/ledgerwatch/erigon/eth/tracers/logger" "github.com/ledgerwatch/erigon/ethdb/prune" + "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/services" "github.com/ledgerwatch/erigon/turbo/shards" "github.com/ledgerwatch/erigon/turbo/silkworm" @@ -88,6 +89,9 @@ type ExecuteBlockCfg struct { agg *libstate.AggregatorV3 silkworm *silkworm.Silkworm + + rollupHistoricalRPC string + rollupHistoricalRPCTimeout time.Duration } func StageExecuteBlocksCfg( @@ -110,29 +114,34 @@ func StageExecuteBlocksCfg( syncCfg ethconfig.Sync, agg *libstate.AggregatorV3, silkworm *silkworm.Silkworm, + + rollupHistoricalRPC string, + rollupHistoricalRPCTimeout time.Duration, ) ExecuteBlockCfg { if genesis == nil { panic("assert: nil genesis") } return ExecuteBlockCfg{ - db: db, - prune: pm, - batchSize: batchSize, - changeSetHook: changeSetHook, - chainConfig: chainConfig, - engine: engine, - vmConfig: vmConfig, - dirs: dirs, - accumulator: accumulator, - stateStream: stateStream, - badBlockHalt: badBlockHalt, - blockReader: blockReader, - hd: hd, - genesis: genesis, - historyV3: historyV3, - syncCfg: syncCfg, - agg: agg, - silkworm: silkworm, + db: db, + prune: pm, + batchSize: batchSize, + changeSetHook: changeSetHook, + chainConfig: chainConfig, + engine: engine, + vmConfig: vmConfig, + dirs: dirs, + accumulator: accumulator, + stateStream: stateStream, + badBlockHalt: badBlockHalt, + blockReader: blockReader, + hd: hd, + genesis: genesis, + historyV3: historyV3, + syncCfg: syncCfg, + agg: agg, + silkworm: silkworm, + rollupHistoricalRPC: rollupHistoricalRPC, + rollupHistoricalRPCTimeout: rollupHistoricalRPCTimeout, } } @@ -174,7 +183,19 @@ func executeBlock( var execRs *core.EphemeralExecResult getHashFn := core.GetHashFn(block.Header(), getHeader) - execRs, err = core.ExecuteBlockEphemerally(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, NewChainReaderImpl(cfg.chainConfig, tx, cfg.blockReader, logger), getTracer, logger) + // Rollup History Client + var historicalRPCService *rpc.Client + if cfg.rollupHistoricalRPC != "" { + ctx, cancel := context.WithTimeout(context.Background(), cfg.rollupHistoricalRPCTimeout) + client, err := rpc.DialContext(ctx, cfg.rollupHistoricalRPC, logger) + cancel() + if err != nil { + return err + } + historicalRPCService = client + } + + execRs, err = core.ExecuteBlockEphemerally(cfg.chainConfig, &vmConfig, getHashFn, cfg.engine, block, stateReader, stateWriter, NewChainReaderImpl(cfg.chainConfig, tx, cfg.blockReader, logger), getTracer, historicalRPCService, &cfg.rollupHistoricalRPCTimeout, logger) if err != nil { return fmt.Errorf("%w: %v", consensus.ErrInvalidBlock, err) } diff --git a/eth/stagedsync/stage_interhashes.go b/eth/stagedsync/stage_interhashes.go index 92404c5a76d..79dfecddeb3 100644 --- a/eth/stagedsync/stage_interhashes.go +++ b/eth/stagedsync/stage_interhashes.go @@ -9,6 +9,7 @@ import ( "math/bits" "sync/atomic" + "github.com/ledgerwatch/erigon-lib/chain" libcommon "github.com/ledgerwatch/erigon-lib/common" "github.com/ledgerwatch/erigon-lib/common/hexutility" "github.com/ledgerwatch/erigon-lib/common/length" @@ -58,7 +59,7 @@ func StageTrieCfg(db kv.RwDB, checkRoot, saveNewHashesToDB, badBlockHalt bool, t } } -func SpawnIntermediateHashesStage(s *StageState, u Unwinder, tx kv.RwTx, cfg TrieCfg, ctx context.Context, logger log.Logger) (libcommon.Hash, error) { +func SpawnIntermediateHashesStage(s *StageState, u Unwinder, tx kv.RwTx, cfg TrieCfg, ctx context.Context, chain *chain.Config, logger log.Logger) (libcommon.Hash, error) { quit := ctx.Done() useExternalTx := tx != nil if !useExternalTx { @@ -123,22 +124,24 @@ func SpawnIntermediateHashesStage(s *StageState, u Unwinder, tx kv.RwTx, cfg Tri } } - if cfg.checkRoot && root != expectedRootHash { - logger.Error(fmt.Sprintf("[%s] Wrong trie root of block %d: %x, expected (from header): %x. Block hash: %x", logPrefix, to, root, expectedRootHash, headerHash)) - if cfg.badBlockHalt { - return trie.EmptyRoot, fmt.Errorf("%w: wrong trie root", consensus.ErrInvalidBlock) - } - if cfg.hd != nil { - cfg.hd.ReportBadHeaderPoS(headerHash, syncHeadHeader.ParentHash) - } + if !chain.IsOptimismPreBedrock(s.BlockNumber) { + if cfg.checkRoot && root != expectedRootHash { + logger.Error(fmt.Sprintf("[%s] Wrong trie root of block %d: %x, expected (from header): %x. Block hash: %x", logPrefix, to, root, expectedRootHash, headerHash)) + if cfg.badBlockHalt { + return trie.EmptyRoot, fmt.Errorf("%w: wrong trie root", consensus.ErrInvalidBlock) + } + if cfg.hd != nil { + cfg.hd.ReportBadHeaderPoS(headerHash, syncHeadHeader.ParentHash) + } - if to > s.BlockNumber { - unwindTo := (to + s.BlockNumber) / 2 // Binary search for the correct block, biased to the lower numbers - logger.Warn("Unwinding due to incorrect root hash", "to", unwindTo) - u.UnwindTo(unwindTo, BadBlock(headerHash, fmt.Errorf("Incorrect root hash"))) + if to > s.BlockNumber { + unwindTo := (to + s.BlockNumber) / 2 // Binary search for the correct block, biased to the lower numbers + logger.Warn("Unwinding due to incorrect root hash", "to", unwindTo) + u.UnwindTo(unwindTo, BadBlock(headerHash, fmt.Errorf("Incorrect root hash"))) + } + } else if err = s.Update(tx, to); err != nil { + return trie.EmptyRoot, err } - } else if err = s.Update(tx, to); err != nil { - return trie.EmptyRoot, err } if !useExternalTx { diff --git a/eth/stagedsync/stage_mining_create_block.go b/eth/stagedsync/stage_mining_create_block.go index e270f22c3ae..0d958e8664c 100644 --- a/eth/stagedsync/stage_mining_create_block.go +++ b/eth/stagedsync/stage_mining_create_block.go @@ -185,6 +185,7 @@ func SpawnMiningCreateBlockStage(s *StageState, tx kv.RwTx, cfg MiningCreateBloc stateReader := state.NewPlainStateReader(tx) ibs := state.New(stateReader) + isBobaLegacyBlock := cfg.chainConfig.IsBobaLegacyBlock(blockNum) if err = cfg.engine.Prepare(chain, header, ibs); err != nil { logger.Error("Failed to prepare header for mining", @@ -209,6 +210,13 @@ func SpawnMiningCreateBlockStage(s *StageState, tx kv.RwTx, cfg MiningCreateBloc current.Deposits = cfg.blockBuilderParameters.Deposits current.NoTxPool = cfg.blockBuilderParameters.NoTxPool + + if isBobaLegacyBlock { + current.Header.GasLimit = uint64(cfg.chainConfig.GetBobaGenesisGasLimit()) + current.Header.Coinbase = libcommon.HexToAddress(cfg.chainConfig.GetBobaGenesisCoinbase()) + current.Header.BaseFee = nil + } + return nil } @@ -290,6 +298,13 @@ func SpawnMiningCreateBlockStage(s *StageState, tx kv.RwTx, cfg MiningCreateBloc current.Header = header current.Uncles = makeUncles(env.uncles) current.Withdrawals = nil + + if isBobaLegacyBlock { + current.Header.GasLimit = uint64(cfg.chainConfig.GetBobaGenesisGasLimit()) + current.Header.Coinbase = libcommon.HexToAddress(cfg.chainConfig.GetBobaGenesisCoinbase()) + current.Header.BaseFee = nil + } + return nil } diff --git a/eth/stagedsync/stage_mining_exec.go b/eth/stagedsync/stage_mining_exec.go index 15d4dd1c6b7..93c7210f654 100644 --- a/eth/stagedsync/stage_mining_exec.go +++ b/eth/stagedsync/stage_mining_exec.go @@ -29,22 +29,25 @@ import ( "github.com/ledgerwatch/erigon/core/vm" "github.com/ledgerwatch/erigon/eth/stagedsync/stages" "github.com/ledgerwatch/erigon/params" + "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/services" ) type MiningExecCfg struct { - db kv.RwDB - miningState MiningState - notifier ChainEventNotifier - chainConfig chain.Config - engine consensus.Engine - blockReader services.FullBlockReader - vmConfig *vm.Config - tmpdir string - interrupt *int32 - payloadId uint64 - txPool2 TxPoolForMining - txPool2DB kv.RoDB + db kv.RwDB + miningState MiningState + notifier ChainEventNotifier + chainConfig chain.Config + engine consensus.Engine + blockReader services.FullBlockReader + vmConfig *vm.Config + tmpdir string + interrupt *int32 + payloadId uint64 + txPool2 TxPoolForMining + txPool2DB kv.RoDB + historicalRPCService *rpc.Client + historicalRPCTimeout *time.Duration } type TxPoolForMining interface { @@ -58,20 +61,24 @@ func StageMiningExecCfg( tmpdir string, interrupt *int32, payloadId uint64, txPool2 TxPoolForMining, txPool2DB kv.RoDB, blockReader services.FullBlockReader, + historicalRPCService *rpc.Client, + historicalRPCTimeout *time.Duration, ) MiningExecCfg { return MiningExecCfg{ - db: db, - miningState: miningState, - notifier: notifier, - chainConfig: chainConfig, - engine: engine, - blockReader: blockReader, - vmConfig: vmConfig, - tmpdir: tmpdir, - interrupt: interrupt, - payloadId: payloadId, - txPool2: txPool2, - txPool2DB: txPool2DB, + db: db, + miningState: miningState, + notifier: notifier, + chainConfig: chainConfig, + engine: engine, + blockReader: blockReader, + vmConfig: vmConfig, + tmpdir: tmpdir, + interrupt: interrupt, + payloadId: payloadId, + txPool2: txPool2, + txPool2DB: txPool2DB, + historicalRPCService: historicalRPCService, + historicalRPCTimeout: historicalRPCTimeout, } } @@ -126,7 +133,7 @@ func SpawnMiningExecStage(s *StageState, tx kv.RwTx, cfg MiningExecCfg, quit <-c } depTS := types.NewTransactionsFixedOrder(txs) - logs, _, err := addTransactionsToMiningBlock(logPrefix, current, cfg.chainConfig, cfg.vmConfig, getHeader, cfg.engine, depTS, cfg.miningState.MiningConfig.Etherbase, ibs, quit, cfg.interrupt, cfg.payloadId, logger) + logs, _, err := addTransactionsToMiningBlock(logPrefix, current, cfg.chainConfig, cfg.vmConfig, getHeader, cfg.engine, depTS, cfg.miningState.MiningConfig.Etherbase, ibs, quit, cfg.interrupt, cfg.payloadId, cfg.historicalRPCService, cfg.historicalRPCTimeout, logger) log.Debug("addTransactionsToMiningBlock (deposit) result", "err", err, "logs", logs) if err != nil { return err @@ -134,7 +141,7 @@ func SpawnMiningExecStage(s *StageState, tx kv.RwTx, cfg MiningExecCfg, quit <-c } if txs != nil && !txs.Empty() { - logs, _, err := addTransactionsToMiningBlock(logPrefix, current, cfg.chainConfig, cfg.vmConfig, getHeader, cfg.engine, txs, cfg.miningState.MiningConfig.Etherbase, ibs, quit, cfg.interrupt, cfg.payloadId, logger) + logs, _, err := addTransactionsToMiningBlock(logPrefix, current, cfg.chainConfig, cfg.vmConfig, getHeader, cfg.engine, txs, cfg.miningState.MiningConfig.Etherbase, ibs, quit, cfg.interrupt, cfg.payloadId, cfg.historicalRPCService, cfg.historicalRPCTimeout, logger) log.Debug("addTransactionsToMiningBlock (txs) result", "err", err, "logs", logs) if err != nil { return err @@ -165,7 +172,7 @@ func SpawnMiningExecStage(s *StageState, tx kv.RwTx, cfg MiningExecCfg, quit <-c } if !txs.Empty() { - logs, stop, err := addTransactionsToMiningBlock(logPrefix, current, cfg.chainConfig, cfg.vmConfig, getHeader, cfg.engine, txs, cfg.miningState.MiningConfig.Etherbase, ibs, quit, cfg.interrupt, cfg.payloadId, logger) + logs, stop, err := addTransactionsToMiningBlock(logPrefix, current, cfg.chainConfig, cfg.vmConfig, getHeader, cfg.engine, txs, cfg.miningState.MiningConfig.Etherbase, ibs, quit, cfg.interrupt, cfg.payloadId, cfg.historicalRPCService, cfg.historicalRPCTimeout, logger) log.Debug("addTransactionsToMiningBlock (regular)", "err", err, "logs", logs, "stop", stop) if err != nil { return err @@ -401,7 +408,7 @@ func filterBadTransactions(transactions []types.Transaction, config chain.Config func addTransactionsToMiningBlock(logPrefix string, current *MiningBlock, chainConfig chain.Config, vmConfig *vm.Config, getHeader func(hash libcommon.Hash, number uint64) *types.Header, engine consensus.Engine, txs types.TransactionsStream, coinbase libcommon.Address, ibs *state.IntraBlockState, quit <-chan struct{}, - interrupt *int32, payloadId uint64, logger log.Logger) (types.Logs, bool, error) { + interrupt *int32, payloadId uint64, historicalRPCService *rpc.Client, historicalRPCTimeout *time.Duration, logger log.Logger) (types.Logs, bool, error) { header := current.Header tcount := 0 gasPool := new(core.GasPool).AddGas(header.GasLimit - header.GasUsed) @@ -419,7 +426,7 @@ func addTransactionsToMiningBlock(logPrefix string, current *MiningBlock, chainC blobGasSnap := gasPool.BlobGas() snap := ibs.Snapshot() logger.Debug("addTransactionsToMiningBlock", "txn hash", txn.Hash()) - receipt, _, err := core.ApplyTransaction(&chainConfig, core.GetHashFn(header, getHeader), engine, &coinbase, gasPool, ibs, noop, header, txn, &header.GasUsed, header.BlobGasUsed, *vmConfig) + receipt, _, err := core.ApplyTransaction(&chainConfig, core.GetHashFn(header, getHeader), engine, &coinbase, gasPool, ibs, noop, header, txn, &header.GasUsed, header.BlobGasUsed, *vmConfig, historicalRPCService, historicalRPCTimeout) if err != nil { ibs.RevertToSnapshot(snap) gasPool = new(core.GasPool).AddGas(gasSnap).AddBlobGas(blobGasSnap) // restore gasPool as well as ibs @@ -474,7 +481,15 @@ LOOP: } // We use the eip155 signer regardless of the env hf. - from, err := txn.Sender(*signer) + var ( + from libcommon.Address + err error + ) + if chainConfig.IsBobaLegacyBlock(header.Number.Uint64()) && txn.IsLegacyDepositTx() { + from = libcommon.Address{} + } else { + from, err = txn.Sender(*signer) + } if err != nil { logger.Warn(fmt.Sprintf("[%s] Could not recover transaction sender", logPrefix), "hash", txn.Hash(), "err", err) txs.Pop() diff --git a/eth/stagedsync/stage_mining_finish.go b/eth/stagedsync/stage_mining_finish.go index 16d90e00667..738d1836265 100644 --- a/eth/stagedsync/stage_mining_finish.go +++ b/eth/stagedsync/stage_mining_finish.go @@ -1,10 +1,14 @@ package stagedsync import ( + "context" "fmt" + "time" "github.com/ledgerwatch/erigon-lib/chain" + "github.com/ledgerwatch/erigon-lib/common/hexutil" "github.com/ledgerwatch/erigon-lib/kv" + "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/builder" "github.com/ledgerwatch/erigon/turbo/services" "github.com/ledgerwatch/log/v3" @@ -21,6 +25,8 @@ type MiningFinishCfg struct { miningState MiningState blockReader services.FullBlockReader latestBlockBuiltStore *builder.LatestBlockBuiltStore + historicalRPC *rpc.Client + historicalRPCTimeout *time.Duration } func StageMiningFinishCfg( @@ -31,6 +37,8 @@ func StageMiningFinishCfg( sealCancel chan struct{}, blockReader services.FullBlockReader, latestBlockBuiltStore *builder.LatestBlockBuiltStore, + historicalRPC *rpc.Client, + historicalRPCTimeout *time.Duration, ) MiningFinishCfg { return MiningFinishCfg{ db: db, @@ -40,6 +48,8 @@ func StageMiningFinishCfg( sealCancel: sealCancel, blockReader: blockReader, latestBlockBuiltStore: latestBlockBuiltStore, + historicalRPC: historicalRPC, + historicalRPCTimeout: historicalRPCTimeout, } } @@ -52,6 +62,21 @@ func SpawnMiningFinishStage(s *StageState, tx kv.RwTx, cfg MiningFinishCfg, quit // continue //} + if cfg.historicalRPC != nil && cfg.chainConfig.IsOptimismPreBedrock(current.Header.Number.Uint64()) { + var r types.Header + ctx, cancel := context.WithTimeout(context.Background(), *cfg.historicalRPCTimeout) + err := cfg.historicalRPC.CallContext(ctx, &r, "eth_getBlockByNumber", hexutil.EncodeBig(current.Header.Number), false) + cancel() + if err != nil { + return err + } + current.Header.GasUsed = r.GasUsed + current.Header.GasLimit = r.GasLimit + current.Header.Difficulty = r.Difficulty + current.Header.Root = r.Root + current.Header.Extra = r.Extra + } + block := types.NewBlock(current.Header, current.Txs, current.Uncles, current.Receipts, current.Withdrawals) blockWithReceipts := &types.BlockWithReceipts{Block: block, Receipts: current.Receipts} *current = MiningBlock{} // hack to clean global data diff --git a/eth/stagedsync/stagebuilder.go b/eth/stagedsync/stagebuilder.go index 05ed4183ca6..72fd02370fc 100644 --- a/eth/stagedsync/stagebuilder.go +++ b/eth/stagedsync/stagebuilder.go @@ -76,7 +76,7 @@ func MiningStages( ID: stages.IntermediateHashes, Description: "Generate intermediate hashes and computing state root", Forward: func(firstCycle bool, badBlockUnwind bool, s *StageState, u Unwinder, tx kv.RwTx, logger log.Logger) error { - stateRoot, err := SpawnIntermediateHashesStage(s, u, tx, trieCfg, ctx, logger) + stateRoot, err := SpawnIntermediateHashesStage(s, u, tx, trieCfg, ctx, &finish.chainConfig, logger) if err != nil { return err } diff --git a/params/config.go b/params/config.go index 3c620f70f29..bb63694a4cf 100644 --- a/params/config.go +++ b/params/config.go @@ -192,7 +192,7 @@ var ( EIP1559Elasticity: 8, EIP1559Denominator: 1, }, - BedrockBlock: big.NewInt(1000000000000000000), + BedrockBlock: big.NewInt(1), } TestRules = TestChainConfig.Rules(0, 0) diff --git a/turbo/engineapi/engine_server.go b/turbo/engineapi/engine_server.go index d87976a6a5b..73a2934b7fb 100644 --- a/turbo/engineapi/engine_server.go +++ b/turbo/engineapi/engine_server.go @@ -191,6 +191,11 @@ func (s *EngineServer) newPayload(ctx context.Context, req *engine_types.Executi return nil, err } + if s.config.IsBobaLegacyBlock(uint64(req.BlockNumber)) { + header.BaseFee = nil + header.Difficulty = libcommon.Big2 + } + if version >= clparams.DenebVersion { if req.BlobGasUsed == nil || req.ExcessBlobGas == nil || parentBeaconBlockRoot == nil { return nil, &rpc.InvalidParamsError{Message: "blobGasUsed/excessBlobGas/beaconRoot missing"} @@ -421,8 +426,10 @@ func (s *EngineServer) getPayload(ctx context.Context, payloadId uint64, version return nil, &rpc.UnsupportedForkError{Message: "Unsupported fork"} } + isBobaLegacyBlock := s.config.IsBobaLegacyBlock(data.ExecutionPayload.BlockNumber) + return &engine_types.GetPayloadResponse{ - ExecutionPayload: engine_types.ConvertPayloadFromRpc(data.ExecutionPayload), + ExecutionPayload: engine_types.ConvertPayloadFromRpc(data.ExecutionPayload, isBobaLegacyBlock), BlockValue: (*hexutil.Big)(gointerfaces.ConvertH256ToUint256Int(data.BlockValue).ToBig()), BlobsBundle: engine_types.ConvertBlobsFromRpc(data.BlobsBundle), }, nil @@ -509,12 +516,15 @@ func (s *EngineServer) forkchoiceUpdated(ctx context.Context, forkchoiceState *e log.Debug("Continuing EngineForkChoiceUpdated", "headNumber", headHeader.Number, "headHash", headHeader.Hash(), "numDeposits", len(payloadAttributes.Transactions)) timestamp := uint64(payloadAttributes.Timestamp) - if headHeader.Time >= timestamp { - return nil, &engine_helpers.InvalidPayloadAttributesErr - } - if s.config.Optimism != nil && payloadAttributes.GasLimit == nil { - return nil, &engine_helpers.InvalidPayloadAttributesErr + if !s.config.IsBobaLegacyBlock(headHeader.Number.Uint64()) { + if headHeader.Time >= timestamp { + return nil, &engine_helpers.InvalidPayloadAttributesErr + } + + if s.config.Optimism != nil && payloadAttributes.GasLimit == nil { + return nil, &engine_helpers.InvalidPayloadAttributesErr + } } req := &execution.AssembleBlockRequest{ diff --git a/turbo/engineapi/engine_types/jsonrpc.go b/turbo/engineapi/engine_types/jsonrpc.go index db006884c4c..af76e4197b4 100644 --- a/turbo/engineapi/engine_types/jsonrpc.go +++ b/turbo/engineapi/engine_types/jsonrpc.go @@ -4,6 +4,7 @@ import ( "encoding/binary" "encoding/json" "errors" + "math/big" "github.com/ledgerwatch/erigon-lib/common/hexutil" @@ -155,9 +156,13 @@ func ConvertRpcBlockToExecutionPayload(payload *execution.Block) *ExecutionPaylo return res } -func ConvertPayloadFromRpc(payload *types2.ExecutionPayload) *ExecutionPayload { +func ConvertPayloadFromRpc(payload *types2.ExecutionPayload, isBobaLegacyBlock bool) *ExecutionPayload { var bloom types.Bloom = gointerfaces.ConvertH2048ToBloom(payload.LogsBloom) - baseFee := gointerfaces.ConvertH256ToUint256Int(payload.BaseFeePerGas).ToBig() + + var baseFee *big.Int + if !isBobaLegacyBlock { + baseFee = gointerfaces.ConvertH256ToUint256Int(payload.BaseFeePerGas).ToBig() + } // Convert slice of hexutility.Bytes to a slice of slice of bytes transactions := make([]hexutility.Bytes, len(payload.Transactions)) diff --git a/turbo/execution/eth1/block_building.go b/turbo/execution/eth1/block_building.go index c82b301696a..6aacb5cd088 100644 --- a/turbo/execution/eth1/block_building.go +++ b/turbo/execution/eth1/block_building.go @@ -129,8 +129,15 @@ func (e *EthereumExecutionModule) GetAssembledBlock(ctx context.Context, req *ex block := blockWithReceipts.Block header := block.Header() - baseFee := new(uint256.Int) - baseFee.SetFromBig(header.BaseFee) + var ( + baseFee *uint256.Int + baseFeePerGas *types2.H256 + ) + if !e.config.IsBobaLegacyBlock(block.NumberU64()) { + baseFee := new(uint256.Int) + baseFee.SetFromBig(header.BaseFee) + baseFeePerGas = gointerfaces.ConvertUint256IntToH256(baseFee) + } encodedTransactions, err := types.MarshalTransactionsBinary(block.Transactions()) if err != nil { @@ -150,7 +157,7 @@ func (e *EthereumExecutionModule) GetAssembledBlock(ctx context.Context, req *ex GasUsed: block.GasUsed(), BlockNumber: block.NumberU64(), ExtraData: block.Extra(), - BaseFeePerGas: gointerfaces.ConvertUint256IntToH256(baseFee), + BaseFeePerGas: baseFeePerGas, BlockHash: gointerfaces.ConvertHashToH256(block.Hash()), Transactions: encodedTransactions, } @@ -165,7 +172,13 @@ func (e *EthereumExecutionModule) GetAssembledBlock(ctx context.Context, req *ex payload.ExcessBlobGas = header.ExcessBlobGas } - blockValue := blockValue(blockWithReceipts, baseFee) + var rBlockValue *uint256.Int + if e.config.IsBobaLegacyBlock(block.NumberU64()) { + payload.BaseFeePerGas = nil + rBlockValue = blockValue(blockWithReceipts, uint256.NewInt(0)) + } else { + rBlockValue = blockValue(blockWithReceipts, baseFee) + } blobsBundle := &types2.BlobsBundleV1{} for i, tx := range block.Transactions() { @@ -202,7 +215,7 @@ func (e *EthereumExecutionModule) GetAssembledBlock(ctx context.Context, req *ex return &execution.GetAssembledBlockResponse{ Data: &execution.AssembledBlockData{ ExecutionPayload: payload, - BlockValue: gointerfaces.ConvertUint256IntToH256(blockValue), + BlockValue: gointerfaces.ConvertUint256IntToH256(rBlockValue), BlobsBundle: blobsBundle, }, Busy: false, diff --git a/turbo/jsonrpc/eth_call.go b/turbo/jsonrpc/eth_call.go index 734c0b2ab8f..2ac2215e52e 100644 --- a/turbo/jsonrpc/eth_call.go +++ b/turbo/jsonrpc/eth_call.go @@ -4,9 +4,10 @@ import ( "context" "errors" "fmt" - "github.com/ledgerwatch/erigon-lib/common/hexutil" "math/big" + "github.com/ledgerwatch/erigon-lib/common/hexutil" + "github.com/holiman/uint256" "github.com/ledgerwatch/erigon-lib/kv/membatchwithdb" "github.com/ledgerwatch/log/v3" diff --git a/turbo/jsonrpc/eth_receipts.go b/turbo/jsonrpc/eth_receipts.go index 51b85a28b6c..bc6b8764692 100644 --- a/turbo/jsonrpc/eth_receipts.go +++ b/turbo/jsonrpc/eth_receipts.go @@ -44,6 +44,7 @@ func (api *BaseAPI) getReceipts(ctx context.Context, tx kv.Tx, chainConfig *chai if cached := rawdb.ReadReceipts(chainConfig, tx, block, senders); cached != nil { return cached, nil } + engine := api.engine() _, _, _, ibs, _, err := transactions.ComputeTxEnv(ctx, engine, block, chainConfig, api._blockReader, tx, 0, api.historyV3(tx)) @@ -69,7 +70,7 @@ func (api *BaseAPI) getReceipts(ctx context.Context, tx kv.Tx, chainConfig *chai header := block.Header() for i, txn := range block.Transactions() { ibs.SetTxContext(txn.Hash(), block.Hash(), i) - receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, noopWriter, header, txn, usedGas, usedBlobGas, vm.Config{}) + receipt, _, err := core.ApplyTransaction(chainConfig, core.GetHashFn(header, getHeader), engine, nil, gp, ibs, noopWriter, header, txn, usedGas, usedBlobGas, vm.Config{}, nil, nil) log.Debug("Computed receipt for tx", "txhash", txn.Hash(), "l1Fee", receipt.L1Fee) if err != nil { return nil, err @@ -786,7 +787,7 @@ func marshalReceipt(receipt *types.Receipt, txn types.Transaction, chainConfig * } if !chainConfig.IsLondon(header.Number.Uint64()) { fields["effectiveGasPrice"] = hexutil.Uint64(txn.GetPrice().Uint64()) - } else { + } else if header.BaseFee != nil { baseFee, _ := uint256.FromBig(header.BaseFee) gasPrice := new(big.Int).Add(header.BaseFee, txn.GetEffectiveGasTip(baseFee).ToBig()) fields["effectiveGasPrice"] = hexutil.Uint64(gasPrice.Uint64()) diff --git a/turbo/stages/mock/mock_sentry.go b/turbo/stages/mock/mock_sentry.go index fc92b99ec5c..eac628a4163 100644 --- a/turbo/stages/mock/mock_sentry.go +++ b/turbo/stages/mock/mock_sentry.go @@ -414,10 +414,10 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK stagedsync.MiningStages(mock.Ctx, stagedsync.StageMiningCreateBlockCfg(mock.DB, miningStatePos, *mock.ChainConfig, mock.Engine, mock.txPoolDB, param, tmpdir, mock.BlockReader), stagedsync.StageBorHeimdallCfg(mock.DB, snapDb, miningStatePos, *mock.ChainConfig, nil, mock.BlockReader, nil, nil, recents, signatures), - stagedsync.StageMiningExecCfg(mock.DB, miningStatePos, mock.Notifications.Events, *mock.ChainConfig, mock.Engine, &vm.Config{}, tmpdir, interrupt, param.PayloadId, mock.TxPool, mock.txPoolDB, mock.BlockReader), + stagedsync.StageMiningExecCfg(mock.DB, miningStatePos, mock.Notifications.Events, *mock.ChainConfig, mock.Engine, &vm.Config{}, tmpdir, interrupt, param.PayloadId, mock.TxPool, mock.txPoolDB, mock.BlockReader, nil, nil), stagedsync.StageHashStateCfg(mock.DB, dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(mock.DB, false, true, true, tmpdir, mock.BlockReader, nil, histV3, mock.agg), - stagedsync.StageMiningFinishCfg(mock.DB, *mock.ChainConfig, mock.Engine, miningStatePos, nil, mock.BlockReader, latestBlockBuiltStore), + stagedsync.StageMiningFinishCfg(mock.DB, *mock.ChainConfig, mock.Engine, miningStatePos, nil, mock.BlockReader, latestBlockBuiltStore, nil, nil), ), stagedsync.MiningUnwindOrder, stagedsync.MiningPruneOrder, logger) // We start the mining step @@ -456,6 +456,8 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK ethconfig.Defaults.Sync, mock.agg, nil, + cfg.RollupHistoricalRPC, + cfg.RollupHistoricalRPCTimeout, ), stagedsync.StageHashStateCfg(mock.DB, mock.Dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(mock.DB, checkStateRoot, true, false, dirs.Tmp, mock.BlockReader, mock.sentriesClient.Hd, cfg.HistoryV3, mock.agg), @@ -497,10 +499,10 @@ func MockWithEverything(tb testing.TB, gspec *types.Genesis, key *ecdsa.PrivateK stagedsync.MiningStages(mock.Ctx, stagedsync.StageMiningCreateBlockCfg(mock.DB, miner, *mock.ChainConfig, mock.Engine, nil, nil, dirs.Tmp, mock.BlockReader), stagedsync.StageBorHeimdallCfg(mock.DB, snapDb, miner, *mock.ChainConfig, nil /*heimdallClient*/, mock.BlockReader, nil, nil, recents, signatures), - stagedsync.StageMiningExecCfg(mock.DB, miner, nil, *mock.ChainConfig, mock.Engine, &vm.Config{}, dirs.Tmp, nil, 0, mock.TxPool, nil, mock.BlockReader), + stagedsync.StageMiningExecCfg(mock.DB, miner, nil, *mock.ChainConfig, mock.Engine, &vm.Config{}, dirs.Tmp, nil, 0, mock.TxPool, nil, mock.BlockReader, nil, nil), stagedsync.StageHashStateCfg(mock.DB, dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(mock.DB, false, true, false, dirs.Tmp, mock.BlockReader, mock.sentriesClient.Hd, cfg.HistoryV3, mock.agg), - stagedsync.StageMiningFinishCfg(mock.DB, *mock.ChainConfig, mock.Engine, miner, miningCancel, mock.BlockReader, latestBlockBuiltStore), + stagedsync.StageMiningFinishCfg(mock.DB, *mock.ChainConfig, mock.Engine, miner, miningCancel, mock.BlockReader, latestBlockBuiltStore, nil, nil), ), stagedsync.MiningUnwindOrder, stagedsync.MiningPruneOrder, diff --git a/turbo/stages/stageloop.go b/turbo/stages/stageloop.go index a69008c260b..79457452f9d 100644 --- a/turbo/stages/stageloop.go +++ b/turbo/stages/stageloop.go @@ -509,6 +509,8 @@ func NewDefaultStages(ctx context.Context, cfg.Sync, agg, silkwormForExecutionStage(silkworm, cfg), + cfg.RollupHistoricalRPC, + cfg.RollupHistoricalRPCTimeout, ), stagedsync.StageHashStateCfg(db, dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(db, true, true, false, dirs.Tmp, blockReader, controlServer.Hd, cfg.HistoryV3, agg), @@ -564,6 +566,8 @@ func NewPipelineStages(ctx context.Context, cfg.Sync, agg, silkwormForExecutionStage(silkworm, cfg), + cfg.RollupHistoricalRPC, + cfg.RollupHistoricalRPCTimeout, ), stagedsync.StageHashStateCfg(db, dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(db, checkStateRoot, true, false, dirs.Tmp, blockReader, controlServer.Hd, cfg.HistoryV3, agg), @@ -603,6 +607,8 @@ func NewInMemoryExecution(ctx context.Context, db kv.RwDB, cfg *ethconfig.Config cfg.Sync, agg, silkwormForExecutionStage(silkworm, cfg), + cfg.RollupHistoricalRPC, + cfg.RollupHistoricalRPCTimeout, ), stagedsync.StageHashStateCfg(db, dirs, cfg.HistoryV3), stagedsync.StageTrieCfg(db, true, true, true, dirs.Tmp, blockReader, controlServer.Hd, cfg.HistoryV3, agg)),