mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-06-19 13:21:37 +00:00
Reorder initialization in eth.New so the effective chain config is resolved and persisted via core.SetupGenesisBlock before creating the consensus engine. Background: - On first sync from genesis, LoadChainConfig could return a stored/incomplete config (notably with XDPoS.V2 unset in legacy testnet setups). - Creating XDPoS before finalizing genesis config could trigger mainnet V2 fallback and log/behavior mismatches around SwitchBlock. What changed: - Replace early LoadChainConfig usage with SetupGenesisBlock in eth.New. - Keep ConfigCompatError semantics consistent with core/blockchain initialization: fail only on non-compat errors. - Initialize consensus engine after finalized chainConfig is available. Result: - Consensus engine now starts with finalized network config on first boot. - Avoids incorrect V2 fallback parameters (e.g. wrong SwitchBlock) during initial testnet sync. Tests: - Added regression tests in eth/backend_test.go to cover legacy missing-V2 repair and SetupGenesisBlock idempotency.
This commit is contained in:
parent
13548d5d9e
commit
3a505d50b0
2 changed files with 71 additions and 6 deletions
|
|
@ -129,11 +129,11 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Here we determine genesis hash and active ChainConfig.
|
||||
// We need these to figure out the consensus parameters and to set up history pruning.
|
||||
chainConfig, _, err := core.LoadChainConfig(chainDb, config.Genesis)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
// Resolve the effective chain config (and persist it when compatible)
|
||||
// before constructing the consensus engine so it initializes with final network settings.
|
||||
chainConfig, _, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis)
|
||||
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
|
||||
return nil, genesisErr
|
||||
}
|
||||
|
||||
// Set networkID to chainID by default.
|
||||
|
|
@ -142,6 +142,7 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
|
|||
networkID = chainConfig.ChainID.Uint64()
|
||||
}
|
||||
common.CopyConstants(networkID)
|
||||
engine := CreateConsensusEngine(stack, chainConfig, chainDb)
|
||||
|
||||
// Assemble the Ethereum object.
|
||||
eth := &Ethereum{
|
||||
|
|
@ -149,7 +150,7 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
|
|||
chainDb: chainDb,
|
||||
eventMux: stack.EventMux(),
|
||||
accountManager: stack.AccountManager(),
|
||||
engine: CreateConsensusEngine(stack, chainConfig, chainDb),
|
||||
engine: engine,
|
||||
shutdownChan: make(chan bool),
|
||||
networkId: networkID,
|
||||
gasPrice: config.Miner.GasPrice,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import (
|
|||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/XinFinOrg/XDPoSChain/core"
|
||||
"github.com/XinFinOrg/XDPoSChain/core/rawdb"
|
||||
"github.com/XinFinOrg/XDPoSChain/eth/util"
|
||||
"github.com/XinFinOrg/XDPoSChain/params"
|
||||
)
|
||||
|
|
@ -27,3 +29,65 @@ func TestRewardInflation(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetupGenesisBlockRepairsMissingV2Config(t *testing.T) {
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
|
||||
legacyGenesis := legacyTestnetGenesisWithoutV2()
|
||||
legacyGenesis.MustCommit(db)
|
||||
|
||||
loadedCfg, _, err := core.LoadChainConfig(db, core.DefaultTestnetGenesisBlock())
|
||||
if err != nil {
|
||||
t.Fatalf("LoadChainConfig failed: %v", err)
|
||||
}
|
||||
if loadedCfg.XDPoS == nil {
|
||||
t.Fatal("expected XDPoS config in loaded chain config")
|
||||
}
|
||||
if loadedCfg.XDPoS.V2 != nil {
|
||||
t.Fatal("expected stored legacy chain config to have nil XDPoS.V2 before setup")
|
||||
}
|
||||
|
||||
finalCfg, _, err := core.SetupGenesisBlock(db, core.DefaultTestnetGenesisBlock())
|
||||
if err != nil {
|
||||
t.Fatalf("SetupGenesisBlock failed: %v", err)
|
||||
}
|
||||
if finalCfg.XDPoS == nil || finalCfg.XDPoS.V2 == nil {
|
||||
t.Fatal("expected SetupGenesisBlock to return a config with XDPoS.V2")
|
||||
}
|
||||
if finalCfg.XDPoS.V2.SwitchBlock.Cmp(params.TestnetChainConfig.XDPoS.V2.SwitchBlock) != 0 {
|
||||
t.Fatalf("unexpected switch block after setup: have %v want %v", finalCfg.XDPoS.V2.SwitchBlock, params.TestnetChainConfig.XDPoS.V2.SwitchBlock)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetupGenesisBlockIsIdempotentForTestnet(t *testing.T) {
|
||||
db := rawdb.NewMemoryDatabase()
|
||||
genesis := core.DefaultTestnetGenesisBlock()
|
||||
|
||||
cfg1, hash1, err := core.SetupGenesisBlock(db, genesis)
|
||||
if err != nil {
|
||||
t.Fatalf("first SetupGenesisBlock failed: %v", err)
|
||||
}
|
||||
cfg2, hash2, err := core.SetupGenesisBlock(db, genesis)
|
||||
if err != nil {
|
||||
t.Fatalf("second SetupGenesisBlock failed: %v", err)
|
||||
}
|
||||
if hash1 != hash2 {
|
||||
t.Fatalf("genesis hash changed across SetupGenesisBlock calls: first %v second %v", hash1, hash2)
|
||||
}
|
||||
if cfg1.XDPoS == nil || cfg2.XDPoS == nil || cfg1.XDPoS.V2 == nil || cfg2.XDPoS.V2 == nil {
|
||||
t.Fatal("expected both returned configs to include XDPoS.V2")
|
||||
}
|
||||
if cfg1.XDPoS.V2.SwitchBlock.Cmp(cfg2.XDPoS.V2.SwitchBlock) != 0 {
|
||||
t.Fatalf("switch block changed across SetupGenesisBlock calls: first %v second %v", cfg1.XDPoS.V2.SwitchBlock, cfg2.XDPoS.V2.SwitchBlock)
|
||||
}
|
||||
}
|
||||
|
||||
func legacyTestnetGenesisWithoutV2() *core.Genesis {
|
||||
legacyGenesis := *core.DefaultTestnetGenesisBlock()
|
||||
legacyChainConfig := *params.TestnetChainConfig
|
||||
legacyXDPoS := *params.TestnetChainConfig.XDPoS
|
||||
legacyXDPoS.V2 = nil
|
||||
legacyChainConfig.XDPoS = &legacyXDPoS
|
||||
legacyGenesis.Config = &legacyChainConfig
|
||||
return &legacyGenesis
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue