diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index 14401d0f9..6dab3bfb4 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -237,7 +237,7 @@ func Main(ctx *cli.Context) error { prestate.Env.Random = nil } - if chainConfig.IsShanghai(prestate.Env.Timestamp) && prestate.Env.Withdrawals == nil { + if chainConfig.IsShanghai(prestate.Env.Number, prestate.Env.Timestamp) && prestate.Env.Withdrawals == nil { return NewError(ErrorVMConfig, errors.New("Shanghai config but missing 'withdrawals' in env section")) } diff --git a/consensus/merge/merge.go b/consensus/merge/merge.go index 6d5cf111b..667d4b96a 100644 --- a/consensus/merge/merge.go +++ b/consensus/merge/merge.go @@ -234,7 +234,7 @@ func (s *Merge) verifyHeader(chain consensus.ChainHeaderReader, header, parent * } // Verify existence / non-existence of withdrawalsHash - shanghai := chain.Config().IsShanghai(header.Time) + shanghai := chain.Config().IsShanghai(header.Number.Uint64(), header.Time) if shanghai && header.WithdrawalsHash == nil { return fmt.Errorf("missing withdrawalsHash") } diff --git a/core/genesis_write.go b/core/genesis_write.go index d152eb381..a79b33d90 100644 --- a/core/genesis_write.go +++ b/core/genesis_write.go @@ -567,7 +567,7 @@ func GenesisToBlock(g *types.Genesis, tmpDir string, logger log.Logger) (*types. } var withdrawals []*types.Withdrawal - if g.Config != nil && g.Config.IsShanghai(g.Timestamp) { + if g.Config != nil && g.Config.IsShanghai(g.Number, g.Timestamp) { withdrawals = []*types.Withdrawal{} } diff --git a/erigon-lib/chain/chain_config.go b/erigon-lib/chain/chain_config.go index 0fe1dadd3..2133a79c9 100644 --- a/erigon-lib/chain/chain_config.go +++ b/erigon-lib/chain/chain_config.go @@ -210,7 +210,12 @@ func (c *Config) IsGrayGlacier(num uint64) bool { } // IsShanghai returns whether time is either equal to the Shanghai fork time or greater. -func (c *Config) IsShanghai(time uint64) bool { +func (c *Config) IsShanghai(num uint64, time uint64) bool { + if c.PrimordialPulseAhead(num) { + // If the PrimordialPulse fork is ahead, + // compare with the Ethereum Mainnet Shanghai time. + return 1681338455 <= time + } return isForked(c.ShanghaiTime, time) } @@ -238,14 +243,14 @@ func (c *Config) IsPrague(time uint64) bool { } // IsPrimordialPulseBlock returns whether or not the given block is the primordial pulse block. -func (c *Config) IsPrimordialPulseBlock(number uint64) bool { - return c.PrimordialPulseBlock != nil && c.PrimordialPulseBlock.Uint64() == number +func (c *Config) IsPrimordialPulseBlock(num uint64) bool { + return c.PrimordialPulseBlock != nil && c.PrimordialPulseBlock.Uint64() == num } // PrimordialPulseAhead Returns true if there is a PrimordialPulse block in the future, indicating this chain // should still be evaluated using the ethash consensus engine and with mainnet ChainID. -func (c *Config) PrimordialPulseAhead(number uint64) bool { - return c.PrimordialPulseBlock != nil && c.PrimordialPulseBlock.Uint64() > number +func (c *Config) PrimordialPulseAhead(num uint64) bool { + return c.PrimordialPulseBlock != nil && c.PrimordialPulseBlock.Uint64() > num } func (c *Config) GetBurntContract(num uint64) *common.Address { @@ -527,12 +532,6 @@ func (c *Config) Rules(num uint64, time uint64) *Rules { if chainID == nil { chainID = new(big.Int) } - isShanghai := c.IsShanghai(time) - if c.PrimordialPulseAhead(num) { - // If the PrimordialPulse fork is ahead, derive the `isShanghai` rule - // from the Ethereum Mainnet Shanghai timestamp. - isShanghai = time >= 1681338455 - } return &Rules{ ChainID: new(big.Int).Set(chainID), @@ -545,7 +544,7 @@ func (c *Config) Rules(num uint64, time uint64) *Rules { IsIstanbul: c.IsIstanbul(num), IsBerlin: c.IsBerlin(num), IsLondon: c.IsLondon(num), - IsShanghai: isShanghai || c.IsAgra(num), + IsShanghai: c.IsShanghai(num, time) || c.IsAgra(num), IsCancun: c.IsCancun(time), IsNapoli: c.IsNapoli(num), IsPrague: c.IsPrague(time), diff --git a/turbo/engineapi/engine_server.go b/turbo/engineapi/engine_server.go index c302139d9..e076d3681 100644 --- a/turbo/engineapi/engine_server.go +++ b/turbo/engineapi/engine_server.go @@ -103,11 +103,12 @@ func (e *EngineServer) Start(httpConfig *httpcfg.HttpCfg, db kv.RoDB, blockReade } } -func (s *EngineServer) checkWithdrawalsPresence(time uint64, withdrawals []*types.Withdrawal) error { - if !s.config.IsShanghai(time) && withdrawals != nil { +func (s *EngineServer) checkWithdrawalsPresence(num uint64, time uint64, withdrawals []*types.Withdrawal) error { + shanghai := s.config.IsShanghai(num, time) + if !shanghai && withdrawals != nil { return &rpc.InvalidParamsError{Message: "withdrawals before shanghai"} } - if s.config.IsShanghai(time) && withdrawals == nil { + if shanghai && withdrawals == nil { return &rpc.InvalidParamsError{Message: "missing withdrawals list"} } return nil @@ -186,7 +187,7 @@ func (s *EngineServer) newPayload(ctx context.Context, req *engine_types.Executi header.WithdrawalsHash = &wh } - if err := s.checkWithdrawalsPresence(header.Time, withdrawals); err != nil { + if err := s.checkWithdrawalsPresence(header.Number.Uint64(), header.Time, withdrawals); err != nil { return nil, err } diff --git a/turbo/execution/eth1/block_building.go b/turbo/execution/eth1/block_building.go index 6e8174e78..3ea632a67 100644 --- a/turbo/execution/eth1/block_building.go +++ b/turbo/execution/eth1/block_building.go @@ -13,6 +13,7 @@ import ( types2 "github.com/ledgerwatch/erigon-lib/gointerfaces/types" "github.com/ledgerwatch/erigon/core" + "github.com/ledgerwatch/erigon/core/rawdb" "github.com/ledgerwatch/erigon/core/types" "github.com/ledgerwatch/erigon/rpc" "github.com/ledgerwatch/erigon/turbo/builder" @@ -20,11 +21,12 @@ import ( "github.com/ledgerwatch/erigon/turbo/execution/eth1/eth1_utils" ) -func (e *EthereumExecutionModule) checkWithdrawalsPresence(time uint64, withdrawals []*types.Withdrawal) error { - if !e.config.IsShanghai(time) && withdrawals != nil { +func (e *EthereumExecutionModule) checkWithdrawalsPresence(num uint64, time uint64, withdrawals []*types.Withdrawal) error { + shanghai := e.config.IsShanghai(num, time) + if !shanghai && withdrawals != nil { return &rpc.InvalidParamsError{Message: "withdrawals before shanghai"} } - if e.config.IsShanghai(time) && withdrawals == nil { + if shanghai && withdrawals == nil { return &rpc.InvalidParamsError{Message: "missing withdrawals list"} } return nil @@ -56,7 +58,16 @@ func (e *EthereumExecutionModule) AssembleBlock(ctx context.Context, req *execut Withdrawals: eth1_utils.ConvertWithdrawalsFromRpc(req.Withdrawals), } - if err := e.checkWithdrawalsPresence(param.Timestamp, param.Withdrawals); err != nil { + tx, err := e.db.BeginRo(ctx) + if err != nil { + return nil, err + } + parentNum := rawdb.ReadHeaderNumber(tx, param.ParentHash) + tx.Rollback() + if parentNum == nil { + return nil, fmt.Errorf("unknown parent: %x", param.ParentHash) + } + if err := e.checkWithdrawalsPresence(*parentNum+1, param.Timestamp, param.Withdrawals); err != nil { return nil, err }