Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

core: LoadChainConfig return the predefined config for built-in networks firstly #2078

Merged
merged 4 commits into from
Dec 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions cmd/geth/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,9 @@ func loadBaseConfig(ctx *cli.Context) gethConfig {
if !utils.ValidateStateScheme(cfg.Eth.StateScheme) {
utils.Fatalf("invalid state scheme param in config: %s", cfg.Eth.StateScheme)
}
if cfg.Eth.Genesis != nil && cfg.Eth.Genesis.Config != nil {
log.Warn("Chain config in the configuration file is ignored!")
}

// Apply flags.
utils.SetNodeConfig(ctx, &cfg.Node)
Expand Down
1 change: 1 addition & 0 deletions consensus/parlia/parlia.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,7 @@ func New(
) *Parlia {
// get parlia config
parliaConfig := chainConfig.Parlia
log.Info("Parlia", "chainConfig", chainConfig)

// Set any missing consensus parameters to their defaults
if parliaConfig != nil && parliaConfig.Epoch == 0 {
Expand Down
83 changes: 13 additions & 70 deletions core/genesis.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ import (
"errors"
"fmt"
"math/big"
"reflect"
"regexp"
"strings"

"github.com/ethereum/go-ethereum/common"
Expand Down Expand Up @@ -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
Expand All @@ -432,75 +435,15 @@ 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
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
default:
if g != nil {
// it could be a custom config for QA test, just return
return g.Config
}
defaultConfig = params.AllEthashProtocolChanges
conf := params.GetBuiltInChainConfig(ghash)
if conf != nil {
return conf
}
if g == nil || g.Config == nil {
return defaultConfig
if g != nil {
return g.Config // it could be a custom config for QA test, just return
}

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
return params.AllEthashProtocolChanges
}

// ToBlock returns the genesis block according to genesis specification.
Expand Down
42 changes: 3 additions & 39 deletions core/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -258,42 +258,6 @@ func TestConfigOrDefault(t *testing.T) {
}
}

func TestSetDefaultHardforkValues(t *testing.T) {
genesis := &Genesis{Config: &params.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
Expand Down
4 changes: 4 additions & 0 deletions core/systemcontracts/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
24 changes: 24 additions & 0 deletions params/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,21 @@ var (
TestRules = TestChainConfig.Rules(new(big.Int), false, 0)
)

func GetBuiltInChainConfig(ghash common.Hash) *ChainConfig {
switch ghash {
case MainnetGenesisHash:
return MainnetChainConfig
case BSCGenesisHash:
return BSCChainConfig
case ChapelGenesisHash:
return ChapelChainConfig
case 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",
Expand Down Expand Up @@ -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)
Expand Down