diff --git a/core/genesis.go b/core/genesis.go index 0a69436296..494a16f81c 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -171,6 +171,7 @@ func SetupGenesisBlock( rawdb.WriteChainConfig(db, stored, newcfg) return newcfg, stored, nil } + storedcfg.SetEthUpgrades() storedData, _ := json.Marshal(storedcfg) // Check config compatibility and write the config. Compatibility errors // are returned to the caller unless we're already at block zero. diff --git a/core/genesis_extra_test.go b/core/genesis_extra_test.go new file mode 100644 index 0000000000..25008653e0 --- /dev/null +++ b/core/genesis_extra_test.go @@ -0,0 +1,90 @@ +// (c) 2019-2021, Ava Labs, Inc. +// +// This file is a derived work, based on the go-ethereum library whose original +// notices appear below. +// +// It is distributed under a license compatible with the licensing terms of the +// original code from which it is derived. +// +// Much love to the original authors for their work. +// ********** +// Copyright 2017 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "math/big" + "testing" + "time" + + "github.com/ava-labs/coreth/core/rawdb" + "github.com/ava-labs/coreth/core/types" + "github.com/ava-labs/coreth/params" + "github.com/ava-labs/coreth/triedb" + "github.com/ava-labs/coreth/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" +) + +func TestGenesisEthUpgrades(t *testing.T) { + db := rawdb.NewMemoryDatabase() + preEthUpgrades := ¶ms.ChainConfig{ + ChainID: big.NewInt(43114), // Specifically refers to mainnet for this UT + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: false, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + NetworkUpgrades: params.NetworkUpgrades{ + ApricotPhase1BlockTimestamp: utils.NewUint64(0), + ApricotPhase2BlockTimestamp: utils.NewUint64(0), + }, + } + + tdb := triedb.NewDatabase(db, triedb.HashDefaults) + config := *preEthUpgrades + // Set this up once, just to get the genesis hash + _, genHash, err := SetupGenesisBlock(db, tdb, &Genesis{Config: &config}, common.Hash{}, false) + require.NoError(t, err) + + // Write the configuration back to the db as it would be in prior versions + rawdb.WriteChainConfig(db, genHash, preEthUpgrades) + + // Make some other block + block := types.NewBlock( + &types.Header{ + Number: big.NewInt(1640340), // Berlin activation on mainnet + Difficulty: big.NewInt(1), + ParentHash: genHash, + Time: uint64(time.Now().Unix()), + }, + nil, nil, nil, nil, + ) + rawdb.WriteBlock(db, block) + + // We should still be able to re-initialize + config = *preEthUpgrades + config.SetEthUpgrades() // New versions will set additional fields eg, LondonBlock + _, _, err = SetupGenesisBlock(db, tdb, &Genesis{Config: &config}, block.Hash(), false) + require.NoError(t, err) +} diff --git a/params/config.go b/params/config.go index 3d1af0dab8..c8211685d4 100644 --- a/params/config.go +++ b/params/config.go @@ -28,7 +28,6 @@ package params import ( "encoding/json" - "errors" "fmt" "math/big" @@ -46,8 +45,6 @@ var ( AvalancheFujiChainID = big.NewInt(43113) // AvalancheLocalChainID ... AvalancheLocalChainID = big.NewInt(43112) - - errNonGenesisForkByHeight = errors.New("coreth only supports forking by height at the genesis block") ) var ( @@ -738,9 +735,6 @@ func (c *ChainConfig) CheckConfigForkOrder() error { func checkForks(forks []fork, blockFork bool) error { lastFork := fork{} for _, cur := range forks { - if blockFork && cur.block != nil && common.Big0.Cmp(cur.block) != 0 { - return errNonGenesisForkByHeight - } if lastFork.name != "" { switch { // Non-optional forks must all be present in the chain config up to the last defined fork diff --git a/params/config_extra.go b/params/config_extra.go index 6fcf6d36c6..abe6ed7bb0 100644 --- a/params/config_extra.go +++ b/params/config_extra.go @@ -40,6 +40,24 @@ type AvalancheContext struct { // code in place of their Ethereum counterparts. The original Ethereum names // should be restored for maintainability. func (c *ChainConfig) SetEthUpgrades() { + if c.ChainID != nil && AvalancheFujiChainID.Cmp(c.ChainID) == 0 { + c.BerlinBlock = big.NewInt(184985) // https://testnet.snowtrace.io/block/184985?chainid=43113, AP2 activation block + c.LondonBlock = big.NewInt(805078) // https://testnet.snowtrace.io/block/805078?chainid=43113, AP3 activation block + } else if c.ChainID != nil && AvalancheMainnetChainID.Cmp(c.ChainID) == 0 { + c.BerlinBlock = big.NewInt(1640340) // https://snowtrace.io/block/1640340?chainid=43114, AP2 activation block + c.LondonBlock = big.NewInt(3308552) // https://snowtrace.io/block/3308552?chainid=43114, AP3 activation block + } else { + // In testing or local networks, we only support enabling Berlin and London prior + // to the initially active time. This is likely to correspond to an intended block + // number of 0 as well. + initiallyActive := uint64(upgrade.InitiallyActiveTime.Unix()) + if c.ApricotPhase2BlockTimestamp != nil && *c.ApricotPhase2BlockTimestamp <= initiallyActive && c.BerlinBlock == nil { + c.BerlinBlock = big.NewInt(0) + } + if c.ApricotPhase3BlockTimestamp != nil && *c.ApricotPhase3BlockTimestamp <= initiallyActive && c.LondonBlock == nil { + c.LondonBlock = big.NewInt(0) + } + } if c.DurangoBlockTimestamp != nil { c.ShanghaiTime = utils.NewUint64(*c.DurangoBlockTimestamp) } @@ -176,24 +194,6 @@ func GetChainConfig(agoUpgrade upgrade.Config, chainID *big.Int) *ChainConfig { MuirGlacierBlock: big.NewInt(0), NetworkUpgrades: getNetworkUpgrades(agoUpgrade), } - if AvalancheFujiChainID.Cmp(c.ChainID) == 0 { - c.BerlinBlock = big.NewInt(184985) // https://testnet.snowtrace.io/block/184985?chainid=43113, AP2 activation block - c.LondonBlock = big.NewInt(805078) // https://testnet.snowtrace.io/block/805078?chainid=43113, AP3 activation block - } else if AvalancheMainnetChainID.Cmp(c.ChainID) == 0 { - c.BerlinBlock = big.NewInt(1640340) // https://snowtrace.io/block/1640340?chainid=43114, AP2 activation block - c.LondonBlock = big.NewInt(3308552) // https://snowtrace.io/block/3308552?chainid=43114, AP3 activation block - } else { - // In testing or local networks, we only support enabling Berlin and London prior - // to the initially active time. This is likely to correspond to an intended block - // number of 0 as well. - initiallyActive := uint64(upgrade.InitiallyActiveTime.Unix()) - if c.ApricotPhase2BlockTimestamp != nil && *c.ApricotPhase2BlockTimestamp <= initiallyActive && c.BerlinBlock == nil { - c.BerlinBlock = big.NewInt(0) - } - if c.ApricotPhase3BlockTimestamp != nil && *c.ApricotPhase3BlockTimestamp <= initiallyActive && c.LondonBlock == nil { - c.LondonBlock = big.NewInt(0) - } - } return c }