diff --git a/consensus/parlia/parlia.go b/consensus/parlia/parlia.go index a8643cc732..a508bb5b40 100644 --- a/consensus/parlia/parlia.go +++ b/consensus/parlia/parlia.go @@ -241,6 +241,7 @@ func New( ) *Parlia { // get parlia config parliaConfig := chainConfig.Parlia + log.Debug("Parlia", "chainConfig", chainConfig) // Set any missing consensus parameters to their defaults if parliaConfig != nil && parliaConfig.Epoch == 0 { diff --git a/core/genesis.go b/core/genesis.go index 93a653250e..768a228796 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -23,8 +23,6 @@ import ( "errors" "fmt" "math/big" - "reflect" - "regexp" "strings" "github.com/ethereum/go-ethereum/common" @@ -399,14 +397,19 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *trie.Database, gen return newcfg, stored, nil } -// LoadChainConfig loads the stored chain config if it is already present in -// database, otherwise, return the config in the provided genesis specification. +// LoadChainConfig retrieves the predefined chain configuration for the built-in network. +// For non-built-in networks, it first attempts to load the stored chain configuration from the database. +// If the configuration is not present, it returns the configuration specified in the provided genesis specification. func LoadChainConfig(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { // Load the stored chain config from the database. It can be nil // in case the database is empty. Notably, we only care about the // chain config corresponds to the canonical chain. stored := rawdb.ReadCanonicalHash(db, 0) if stored != (common.Hash{}) { + builtInConf := params.GetBuiltInChainConfig(stored) + if builtInConf != nil { + return builtInConf, stored, nil + } storedcfg := rawdb.ReadChainConfig(db, stored) if storedcfg != nil { return storedcfg, stored, nil @@ -432,75 +435,16 @@ func LoadChainConfig(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, return params.BSCChainConfig, params.BSCGenesisHash, nil } -// For any block or time in g.Config which is nil but the same field in defaultConfig is not -// set the field in genesis config to the field in defaultConfig. -// Reflection is used to avoid a long series of if statements with hardcoded block names. -func (g *Genesis) setDefaultHardforkValues(defaultConfig *params.ChainConfig) { - // Regex to match Block names or Time names - hardforkPattern := []string{`.*Block$`, `.*Time$`} - - for _, pat := range hardforkPattern { - hardforkRegex := regexp.MustCompile(pat) - - // Get reflect values - gConfigElem := reflect.ValueOf(g.Config).Elem() - defaultConfigElem := reflect.ValueOf(defaultConfig).Elem() - - // Iterate over fields in config - for i := 0; i < gConfigElem.NumField(); i++ { - gConfigField := gConfigElem.Field(i) - defaultConfigField := defaultConfigElem.Field(i) - fieldName := gConfigElem.Type().Field(i).Name - - // Use the regex to check if the field is a Block or Time field - if gConfigField.Kind() == reflect.Ptr && hardforkRegex.MatchString(fieldName) { - if gConfigField.IsNil() { - gConfigField.Set(defaultConfigField) - } - } - } - } -} - -// Hard fork field specified in config.toml has higher priority, but -// if it is not specified in config.toml, use the default height in code. func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { - var defaultConfig *params.ChainConfig + conf := params.GetBuiltInChainConfig(ghash) switch { - case ghash == params.MainnetGenesisHash: - defaultConfig = params.MainnetChainConfig - case ghash == params.BSCGenesisHash: - defaultConfig = params.BSCChainConfig - case ghash == params.ChapelGenesisHash: - defaultConfig = params.ChapelChainConfig - case ghash == params.RialtoGenesisHash: - defaultConfig = params.RialtoChainConfig + case conf != nil: + return conf + case g != nil: + return g.Config // it could be a custom config for QA test, just return default: - if g != nil { - // it could be a custom config for QA test, just return - return g.Config - } - defaultConfig = params.AllEthashProtocolChanges - } - if g == nil || g.Config == nil { - return defaultConfig + return params.AllEthashProtocolChanges } - - g.setDefaultHardforkValues(defaultConfig) - - // BSC Parlia set up - if g.Config.Parlia == nil { - g.Config.Parlia = defaultConfig.Parlia - } else { - if g.Config.Parlia.Period == 0 { - g.Config.Parlia.Period = defaultConfig.Parlia.Period - } - if g.Config.Parlia.Epoch == 0 { - g.Config.Parlia.Epoch = defaultConfig.Parlia.Epoch - } - } - - return g.Config } // ToBlock returns the genesis block according to genesis specification. diff --git a/core/genesis_test.go b/core/genesis_test.go index 082d88ba30..815ab5d020 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -241,12 +241,12 @@ func TestConfigOrDefault(t *testing.T) { gHash := params.BSCGenesisHash config := defaultGenesis.configOrDefault(gHash) - if config.ChainID.Cmp(params.MainnetChainConfig.ChainID) != 0 { + if config.ChainID.Cmp(params.BSCChainConfig.ChainID) != 0 { t.Errorf("ChainID of resulting config should be %v, but is %v instead", params.BSCChainConfig.ChainID, config.ChainID) } - if config.HomesteadBlock.Cmp(params.MainnetChainConfig.HomesteadBlock) != 0 { - t.Errorf("resulting config should have HomesteadBlock = %v, but instead is %v", params.MainnetChainConfig, config.HomesteadBlock) + if config.HomesteadBlock.Cmp(params.BSCChainConfig.HomesteadBlock) != 0 { + t.Errorf("resulting config should have HomesteadBlock = %v, but instead is %v", params.BSCChainConfig, config.HomesteadBlock) } if config.PlanckBlock == nil { @@ -258,42 +258,6 @@ func TestConfigOrDefault(t *testing.T) { } } -func TestSetDefaultHardforkValues(t *testing.T) { - genesis := &Genesis{Config: ¶ms.ChainConfig{ChainID: big.NewInt(66), HomesteadBlock: big.NewInt(11)}} - genesis.setDefaultHardforkValues(params.BSCChainConfig) - - // Make sure the non-nil block was not modified - if genesis.Config.HomesteadBlock.Cmp(big.NewInt(11)) != 0 { - t.Errorf("Homestead block should not have been modified. HomesteadBlock = %v", genesis.Config.HomesteadBlock) - } - - // Spot check a few blocks - if genesis.Config.NielsBlock.Cmp(params.BSCChainConfig.NielsBlock) != 0 { - t.Errorf("Niels block not matching: in genesis = %v , in defaultConfig = %v", genesis.Config.NielsBlock, params.BSCChainConfig.NielsBlock) - } - - if genesis.Config.NanoBlock.Cmp(params.BSCChainConfig.NanoBlock) != 0 { - t.Errorf("Nano block not matching: in genesis = %v , in defaultConfig = %v", genesis.Config.NanoBlock, params.BSCChainConfig.NanoBlock) - } - - if genesis.Config.PlanckBlock.Cmp(params.BSCChainConfig.PlanckBlock) != 0 { - t.Errorf("Nano block not matching: in genesis = %v , in defaultConfig = %v", genesis.Config.PlanckBlock, params.BSCChainConfig.PlanckBlock) - } - - // Spot check a few times - if *genesis.Config.ShanghaiTime != *params.BSCChainConfig.ShanghaiTime { - t.Errorf("Shanghai Time not matching: in genesis = %d , in defaultConfig = %d", *genesis.Config.ShanghaiTime, *params.BSCChainConfig.ShanghaiTime) - } - if *genesis.Config.KeplerTime != *params.BSCChainConfig.KeplerTime { - t.Errorf("Kepler Time not matching: in genesis = %d , in defaultConfig = %d", *genesis.Config.KeplerTime, *params.BSCChainConfig.KeplerTime) - } - - // Lastly make sure non-block fields such as ChainID have not been modified - if genesis.Config.ChainID.Cmp(big.NewInt(66)) != 0 { - t.Errorf("ChainID should not have been modified. ChainID = %v", genesis.Config.ChainID) - } -} - func newDbConfig(scheme string) *trie.Config { if scheme == rawdb.HashScheme { return trie.HashDefaults diff --git a/core/systemcontracts/upgrade.go b/core/systemcontracts/upgrade.go index e38bd65d70..c8d50a14fe 100644 --- a/core/systemcontracts/upgrade.go +++ b/core/systemcontracts/upgrade.go @@ -823,6 +823,10 @@ func UpgradeBuildInSystemContract(config *params.ChainConfig, blockNumber *big.I applySystemContractUpgrade(platoUpgrade[network], blockNumber, statedb, logger) } + if config.IsOnShanghai(blockNumber, lastBlockTime, blockTime) { + logger.Info("Empty upgrade config for shanghai", "height", blockNumber.String()) + } + if config.IsOnKepler(blockNumber, lastBlockTime, blockTime) { applySystemContractUpgrade(keplerUpgrade[network], blockNumber, statedb, logger) } diff --git a/params/config.go b/params/config.go index 94b67eef49..df1112d7d7 100644 --- a/params/config.go +++ b/params/config.go @@ -418,6 +418,21 @@ var ( TestRules = TestChainConfig.Rules(new(big.Int), false, 0) ) +func GetBuiltInChainConfig(ghash common.Hash) *ChainConfig { + switch { + case ghash == MainnetGenesisHash: + return MainnetChainConfig + case ghash == BSCGenesisHash: + return BSCChainConfig + case ghash == ChapelGenesisHash: + return ChapelChainConfig + case ghash == RialtoGenesisHash: + return RialtoChainConfig + default: + return nil + } +} + // NetworkNames are user friendly names to use in the chain spec banner. var NetworkNames = map[string]string{ MainnetChainConfig.ChainID.String(): "mainnet", @@ -795,6 +810,15 @@ func (c *ChainConfig) IsShanghai(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.ShanghaiTime, time) } +// IsOnShanghai returns whether currentBlockTime is either equal to the shanghai fork time or greater firstly. +func (c *ChainConfig) IsOnShanghai(currentBlockNumber *big.Int, lastBlockTime uint64, currentBlockTime uint64) bool { + lastBlockNumber := new(big.Int) + if currentBlockNumber.Cmp(big.NewInt(1)) >= 0 { + lastBlockNumber.Sub(currentBlockNumber, big.NewInt(1)) + } + return !c.IsShanghai(lastBlockNumber, lastBlockTime) && c.IsShanghai(currentBlockNumber, currentBlockTime) +} + // IsKepler returns whether time is either equal to the kepler fork time or greater. func (c *ChainConfig) IsKepler(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.KeplerTime, time)