From 85a4b82b3373fc5f3fa8b7c68061c55b0db0e9b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 19 May 2023 11:27:19 +0300 Subject: [PATCH] all: tie timestamp based forks to the passage of London (#27279) --- cmd/evm/internal/t8ntool/transaction.go | 4 ++-- cmd/evm/internal/t8ntool/transition.go | 2 +- consensus/beacon/consensus.go | 6 +++--- consensus/clique/clique.go | 4 ++-- consensus/ethash/consensus.go | 4 ++-- core/genesis.go | 2 +- core/state_processor.go | 2 +- core/state_processor_test.go | 4 ++-- core/txpool/txpool.go | 2 +- core/types/transaction_signing.go | 2 +- eth/catalyst/api.go | 7 ++++--- light/txpool.go | 2 +- params/config.go | 18 +++++++++--------- params/config_test.go | 1 + 14 files changed, 31 insertions(+), 29 deletions(-) diff --git a/cmd/evm/internal/t8ntool/transaction.go b/cmd/evm/internal/t8ntool/transaction.go index b1f65815b..03a2e2eb9 100644 --- a/cmd/evm/internal/t8ntool/transaction.go +++ b/cmd/evm/internal/t8ntool/transaction.go @@ -140,7 +140,7 @@ func Transaction(ctx *cli.Context) error { } // Check intrinsic gas if gas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.To() == nil, - chainConfig.IsHomestead(new(big.Int)), chainConfig.IsIstanbul(new(big.Int)), chainConfig.IsShanghai(0)); err != nil { + chainConfig.IsHomestead(new(big.Int)), chainConfig.IsIstanbul(new(big.Int)), chainConfig.IsShanghai(new(big.Int), 0)); err != nil { r.Error = err results = append(results, r) continue @@ -172,7 +172,7 @@ func Transaction(ctx *cli.Context) error { r.Error = errors.New("gas * maxFeePerGas exceeds 256 bits") } // Check whether the init code size has been exceeded. - if chainConfig.IsShanghai(0) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize { + if chainConfig.IsShanghai(new(big.Int), 0) && tx.To() == nil && len(tx.Data()) > params.MaxInitCodeSize { r.Error = errors.New("max initcode size exceeded") } results = append(results, r) diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index a5d061292..ce7197d10 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -261,7 +261,7 @@ func Transition(ctx *cli.Context) error { return NewError(ErrorConfig, errors.New("EIP-1559 config but missing 'currentBaseFee' in env section")) } } - if chainConfig.IsShanghai(prestate.Env.Number) && prestate.Env.Withdrawals == nil { + if chainConfig.IsShanghai(big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp) && prestate.Env.Withdrawals == nil { return NewError(ErrorConfig, errors.New("Shanghai config but missing 'withdrawals' in env section")) } isMerged := chainConfig.TerminalTotalDifficulty != nil && chainConfig.TerminalTotalDifficulty.BitLen() == 0 diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index 284477b27..75f1b65ef 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -261,7 +261,7 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa return err } // Verify existence / non-existence of withdrawalsHash. - shanghai := chain.Config().IsShanghai(header.Time) + shanghai := chain.Config().IsShanghai(header.Number, header.Time) if shanghai && header.WithdrawalsHash == nil { return errors.New("missing withdrawalsHash") } @@ -269,7 +269,7 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa return fmt.Errorf("invalid withdrawalsHash: have %x, expected nil", header.WithdrawalsHash) } // Verify the existence / non-existence of excessDataGas - cancun := chain.Config().IsCancun(header.Time) + cancun := chain.Config().IsCancun(header.Number, header.Time) if cancun && header.ExcessDataGas == nil { return errors.New("missing excessDataGas") } @@ -356,7 +356,7 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea if !beacon.IsPoSHeader(header) { return beacon.ethone.FinalizeAndAssemble(chain, header, state, txs, uncles, receipts, nil) } - shanghai := chain.Config().IsShanghai(header.Time) + shanghai := chain.Config().IsShanghai(header.Number, header.Time) if shanghai { // All blocks after Shanghai must include a withdrawals root. if withdrawals == nil { diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index 535cbeb26..01d27482d 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -298,10 +298,10 @@ func (c *Clique) verifyHeader(chain consensus.ChainHeaderReader, header *types.H if header.GasLimit > params.MaxGasLimit { return fmt.Errorf("invalid gasLimit: have %v, max %v", header.GasLimit, params.MaxGasLimit) } - if chain.Config().IsShanghai(header.Time) { + if chain.Config().IsShanghai(header.Number, header.Time) { return fmt.Errorf("clique does not support shanghai fork") } - if chain.Config().IsCancun(header.Time) { + if chain.Config().IsCancun(header.Number, header.Time) { return fmt.Errorf("clique does not support cancun fork") } // All basic checks passed, verify cascading fields diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index b912fb513..b36637c5b 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -262,10 +262,10 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa if diff := new(big.Int).Sub(header.Number, parent.Number); diff.Cmp(big.NewInt(1)) != 0 { return consensus.ErrInvalidNumber } - if chain.Config().IsShanghai(header.Time) { + if chain.Config().IsShanghai(header.Number, header.Time) { return fmt.Errorf("ethash does not support shanghai fork") } - if chain.Config().IsCancun(header.Time) { + if chain.Config().IsCancun(header.Number, header.Time) { return fmt.Errorf("ethash does not support cancun fork") } // Add some fake checks for tests diff --git a/core/genesis.go b/core/genesis.go index 26f31c086..68eeec216 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -463,7 +463,7 @@ func (g *Genesis) ToBlock() *types.Block { } } var withdrawals []*types.Withdrawal - if g.Config != nil && g.Config.IsShanghai(g.Timestamp) { + if g.Config != nil && g.Config.IsShanghai(big.NewInt(int64(g.Number)), g.Timestamp) { head.WithdrawalsHash = &types.EmptyWithdrawalsHash withdrawals = make([]*types.Withdrawal, 0) } diff --git a/core/state_processor.go b/core/state_processor.go index 25266f13b..03de673e1 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -91,7 +91,7 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } // Fail if Shanghai not enabled and len(withdrawals) is non-zero. withdrawals := block.Withdrawals() - if len(withdrawals) > 0 && !p.config.IsShanghai(block.Time()) { + if len(withdrawals) > 0 && !p.config.IsShanghai(block.Number(), block.Time()) { return nil, nil, 0, fmt.Errorf("withdrawals before shanghai") } // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) diff --git a/core/state_processor_test.go b/core/state_processor_test.go index 59391fa86..5dbeed97a 100644 --- a/core/state_processor_test.go +++ b/core/state_processor_test.go @@ -403,7 +403,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr if config.IsLondon(header.Number) { header.BaseFee = misc.CalcBaseFee(config, parent.Header()) } - if config.IsShanghai(header.Time) { + if config.IsShanghai(header.Number, header.Time) { header.WithdrawalsHash = &types.EmptyWithdrawalsHash } var receipts []*types.Receipt @@ -423,7 +423,7 @@ func GenerateBadBlock(parent *types.Block, engine consensus.Engine, txs types.Tr } header.Root = common.BytesToHash(hasher.Sum(nil)) // Assemble and return the final block for sealing - if config.IsShanghai(header.Time) { + if config.IsShanghai(header.Number, header.Time) { return types.NewBlockWithWithdrawals(header, txs, nil, receipts, []*types.Withdrawal{}, trie.NewStackTrie(nil)) } return types.NewBlock(header, txs, nil, receipts, trie.NewStackTrie(nil)) diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index 056b1ebe8..cbb8cc287 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -1397,7 +1397,7 @@ func (pool *TxPool) reset(oldHead, newHead *types.Header) { pool.istanbul.Store(pool.chainconfig.IsIstanbul(next)) pool.eip2718.Store(pool.chainconfig.IsBerlin(next)) pool.eip1559.Store(pool.chainconfig.IsLondon(next)) - pool.shanghai.Store(pool.chainconfig.IsShanghai(uint64(time.Now().Unix()))) + pool.shanghai.Store(pool.chainconfig.IsShanghai(next, uint64(time.Now().Unix()))) } // promoteExecutables moves transactions that have become processable from the diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index d7c162898..59dd2e76e 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -40,7 +40,7 @@ type sigCache struct { func MakeSigner(config *params.ChainConfig, blockNumber *big.Int, blockTime uint64) Signer { var signer Signer switch { - case config.IsCancun(blockTime): + case config.IsCancun(blockNumber, blockTime): signer = NewCancunSigner(config.ChainID) case config.IsLondon(blockNumber): signer = NewLondonSigner(config.ChainID) diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 1fe984247..58681df2e 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -20,6 +20,7 @@ package catalyst import ( "errors" "fmt" + "math/big" "sync" "time" @@ -167,7 +168,7 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV1(update engine.ForkchoiceStateV1, pa if payloadAttributes.Withdrawals != nil { return engine.STATUS_INVALID, engine.InvalidParams.With(fmt.Errorf("withdrawals not supported in V1")) } - if api.eth.BlockChain().Config().IsShanghai(payloadAttributes.Timestamp) { + if api.eth.BlockChain().Config().IsShanghai(api.eth.BlockChain().Config().LondonBlock, payloadAttributes.Timestamp) { return engine.STATUS_INVALID, engine.InvalidParams.With(fmt.Errorf("forkChoiceUpdateV1 called post-shanghai")) } } @@ -185,7 +186,7 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV2(update engine.ForkchoiceStateV1, pa } func (api *ConsensusAPI) verifyPayloadAttributes(attr *engine.PayloadAttributes) error { - if !api.eth.BlockChain().Config().IsShanghai(attr.Timestamp) { + if !api.eth.BlockChain().Config().IsShanghai(api.eth.BlockChain().Config().LondonBlock, attr.Timestamp) { // Reject payload attributes with withdrawals before shanghai if attr.Withdrawals != nil { return errors.New("withdrawals before shanghai") @@ -423,7 +424,7 @@ func (api *ConsensusAPI) NewPayloadV1(params engine.ExecutableData) (engine.Payl // NewPayloadV2 creates an Eth1 block, inserts it in the chain, and returns the status of the chain. func (api *ConsensusAPI) NewPayloadV2(params engine.ExecutableData) (engine.PayloadStatusV1, error) { - if api.eth.BlockChain().Config().IsShanghai(params.Timestamp) { + if api.eth.BlockChain().Config().IsShanghai(new(big.Int).SetUint64(params.Number), params.Timestamp) { if params.Withdrawals == nil { return engine.PayloadStatusV1{Status: engine.INVALID}, engine.InvalidParams.With(fmt.Errorf("nil withdrawals post-shanghai")) } diff --git a/light/txpool.go b/light/txpool.go index e59dc3e77..8d2a189c0 100644 --- a/light/txpool.go +++ b/light/txpool.go @@ -318,7 +318,7 @@ func (pool *TxPool) setNewHead(head *types.Header) { next := new(big.Int).Add(head.Number, big.NewInt(1)) pool.istanbul = pool.config.IsIstanbul(next) pool.eip2718 = pool.config.IsBerlin(next) - pool.shanghai = pool.config.IsShanghai(uint64(time.Now().Unix())) + pool.shanghai = pool.config.IsShanghai(next, uint64(time.Now().Unix())) } // Stop stops the light transaction pool diff --git a/params/config.go b/params/config.go index c1614bdba..08e5ea0be 100644 --- a/params/config.go +++ b/params/config.go @@ -492,18 +492,18 @@ func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *bi } // IsShanghai returns whether time is either equal to the Shanghai fork time or greater. -func (c *ChainConfig) IsShanghai(time uint64) bool { - return isTimestampForked(c.ShanghaiTime, time) +func (c *ChainConfig) IsShanghai(num *big.Int, time uint64) bool { + return c.IsLondon(num) && isTimestampForked(c.ShanghaiTime, time) } // IsCancun returns whether num is either equal to the Cancun fork time or greater. -func (c *ChainConfig) IsCancun(time uint64) bool { - return isTimestampForked(c.CancunTime, time) +func (c *ChainConfig) IsCancun(num *big.Int, time uint64) bool { + return c.IsLondon(num) && isTimestampForked(c.CancunTime, time) } // IsPrague returns whether num is either equal to the Prague fork time or greater. -func (c *ChainConfig) IsPrague(time uint64) bool { - return isTimestampForked(c.PragueTime, time) +func (c *ChainConfig) IsPrague(num *big.Int, time uint64) bool { + return c.IsLondon(num) && isTimestampForked(c.PragueTime, time) } // CheckCompatible checks whether scheduled fork transitions have been imported @@ -829,8 +829,8 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsBerlin: c.IsBerlin(num), IsLondon: c.IsLondon(num), IsMerge: isMerge, - IsShanghai: c.IsShanghai(timestamp), - IsCancun: c.IsCancun(timestamp), - IsPrague: c.IsPrague(timestamp), + IsShanghai: c.IsShanghai(num, timestamp), + IsCancun: c.IsCancun(num, timestamp), + IsPrague: c.IsPrague(num, timestamp), } } diff --git a/params/config_test.go b/params/config_test.go index 5634569e2..bf8ce2fc5 100644 --- a/params/config_test.go +++ b/params/config_test.go @@ -121,6 +121,7 @@ func TestCheckCompatible(t *testing.T) { func TestConfigRules(t *testing.T) { c := &ChainConfig{ + LondonBlock: new(big.Int), ShanghaiTime: newUint64(500), } var stamp uint64