refactor(all): move genesis initialization to blockchain #25523 (#2018)

This commit is contained in:
Daniel Liu 2026-02-10 19:26:34 +08:00 committed by GitHub
parent 35d5bbd240
commit 85f2bebfd1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 178 additions and 96 deletions

View file

@ -143,7 +143,7 @@ func NewXDCSimulatedBackend(alloc types.GenesisAlloc, gasLimit uint64, chainConf
TrieTimeLimit: 5 * time.Minute,
Preimages: true,
}
blockchain, _ := core.NewBlockChain(database, cacheConfig, genesis.Config, consensus, vm.Config{})
blockchain, _ := core.NewBlockChain(database, cacheConfig, &genesis, consensus, vm.Config{})
backend := &SimulatedBackend{
database: database,
@ -171,7 +171,7 @@ func NewSimulatedBackend(alloc types.GenesisAlloc, gasLimit uint64) *SimulatedBa
database := rawdb.NewMemoryDatabase()
genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc}
genesis.MustCommit(database)
blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{})
blockchain, _ := core.NewBlockChain(database, nil, &genesis, ethash.NewFaker(), vm.Config{})
backend := &SimulatedBackend{
database: database,

View file

@ -128,8 +128,12 @@ func testDAOForkBlockNewChain(t *testing.T, test int, genesis string, expectBloc
}
config, err := rawdb.ReadChainConfig(db, genesisHash)
if err != nil {
t.Errorf("test %d: failed to retrieve chain config: %v", test, err)
return // we want to return here, the other checks can't make it past this point (nil panic).
t.Errorf("test %d: failed to read chain config: %v", test, err)
return
}
if config == nil {
t.Errorf("test %d: failed to retrieve chain config", test)
return
}
// Validate the DAO hard-fork block number against the expected value
if config.DAOForkBlock == nil {

View file

@ -1762,11 +1762,12 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
}
// MakeChain creates a chain manager from set command line flags.
func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (chain *core.BlockChain, chainDb ethdb.Database) {
var err error
chainDb = MakeChainDatabase(ctx, stack, readonly)
config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx))
func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockChain, ethdb.Database) {
var (
gspec = MakeGenesis(ctx)
chainDb = MakeChainDatabase(ctx, stack, readonly)
)
config, _, err := core.LoadChainConfig(chainDb, gspec)
if err != nil {
Fatalf("%v", err)
}
@ -1809,7 +1810,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (chain *core.B
}
}
// Disable transaction indexing/unindexing by default.
chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg)
chain, err := core.NewBlockChain(chainDb, cache, gspec, engine, vmcfg)
if err != nil {
Fatalf("Can't create BlockChain: %v", err)
}

View file

@ -170,7 +170,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
// Time the insertion of the new chain.
// State and blocks are stored in the same DB.
chainman, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
chainman, _ := NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
defer chainman.Stop()
b.ReportAllocs()
b.ResetTimer()
@ -236,6 +236,11 @@ func makeChainForBench(db ethdb.Database, full bool, count uint64) {
rawdb.WriteCanonicalHash(db, hash, n)
rawdb.WriteTd(db, hash, n, big.NewInt(int64(n+1)))
if n == 0 {
rawdb.WriteChainConfig(db, hash, params.TestChainConfig)
}
rawdb.WriteHeadHeaderHash(db, hash)
if full || n == 0 {
block := types.NewBlockWithHeader(header)
rawdb.WriteBody(db, hash, n, block.Body())
@ -273,7 +278,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
if err != nil {
b.Fatalf("error opening database at %v: %v", dir, err)
}
chain, err := NewBlockChain(db, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{})
chain, err := NewBlockChain(db, nil, nil, ethash.NewFaker(), vm.Config{})
if err != nil {
b.Fatalf("error creating chain: %v", err)
}

View file

@ -41,7 +41,7 @@ func TestHeaderVerification(t *testing.T) {
headers[i] = block.Header()
}
// Run the header checker for blocks one-by-one, checking for both valid and invalid nonces
chain, err := NewBlockChain(testdb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
chain, err := NewBlockChain(testdb, nil, gspec, ethash.NewFaker(), vm.Config{})
defer chain.Stop()
if err != nil {
t.Fatal(err)

View file

@ -22,6 +22,7 @@ import (
"fmt"
"io"
"math/big"
"strings"
"sync"
"sync/atomic"
"time"
@ -230,7 +231,7 @@ type BlockChain struct {
// NewBlockChain returns a fully initialised block chain using information
// available in the database. It initialises the default Ethereum Validator and
// Processor.
func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) {
func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) {
if cacheConfig == nil {
cacheConfig = &CacheConfig{
TrieCleanLimit: 256,
@ -239,6 +240,19 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
}
}
// Setup the genesis block, commit the provided genesis specification
// to database if the genesis block is not present yet, or load the
// stored one from database.
chainConfig, genesisHash, genesisErr := SetupGenesisBlock(db, genesis)
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
return nil, genesisErr
}
log.Info(strings.Repeat("-", 153))
for line := range strings.SplitSeq(chainConfig.Description(), "\n") {
log.Info(line)
}
log.Info(strings.Repeat("-", 153))
// Open trie database with provided config
triedb := trie.NewDatabaseWithConfig(db, &trie.Config{
Cache: cacheConfig.TrieCleanLimit,
@ -334,6 +348,13 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
}
}
// Rewind the chain in case of an incompatible config upgrade.
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
bc.SetHead(compat.RewindTo)
rawdb.WriteChainConfig(db, genesisHash, chainConfig)
}
// Start future block processor.
bc.wg.Go(bc.futureBlocksLoop)
@ -341,8 +362,8 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
}
// NewBlockChainEx extend old blockchain, add order state db
func NewBlockChainEx(db ethdb.Database, XDCxDb ethdb.XDCxDatabase, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) {
blockchain, err := NewBlockChain(db, cacheConfig, chainConfig, engine, vmConfig)
func NewBlockChainEx(db ethdb.Database, XDCxDb ethdb.XDCxDatabase, cacheConfig *CacheConfig, genesis *Genesis, engine consensus.Engine, vmConfig vm.Config) (*BlockChain, error) {
blockchain, err := NewBlockChain(db, cacheConfig, genesis, engine, vmConfig)
if err != nil {
return nil, err
}

View file

@ -44,16 +44,16 @@ import (
// are also returned in case more test blocks are needed later.
func newCanonical(engine consensus.Engine, n int, full bool) (ethdb.Database, *BlockChain, error) {
var (
db = rawdb.NewMemoryDatabase()
gspec = &Genesis{
BaseFee: big.NewInt(params.InitialBaseFee),
Config: params.AllEthashProtocolChanges,
}
genesis = gspec.MustCommit(db)
)
db := rawdb.NewMemoryDatabase()
genesis := gspec.MustCommit(db)
// Initialize a fresh chain with only a genesis block
blockchain, _ := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{})
blockchain, _ := NewBlockChain(db, nil, gspec, engine, vm.Config{})
// Create and inject the requested chain
if n == 0 {
@ -517,7 +517,11 @@ func testReorgBadHashes(t *testing.T, full bool) {
blockchain.Stop()
// Create a new BlockChain and check that it rolled back the state.
ncm, err := NewBlockChain(blockchain.db, nil, blockchain.chainConfig, ethash.NewFaker(), vm.Config{})
gspec := &Genesis{
BaseFee: big.NewInt(params.InitialBaseFee),
Config: params.AllEthashProtocolChanges,
}
ncm, err := NewBlockChain(blockchain.db, nil, gspec, ethash.NewFaker(), vm.Config{})
if err != nil {
t.Fatalf("failed to create new chain manager: %v", err)
}
@ -620,7 +624,7 @@ func TestFastVsFullChains(t *testing.T) {
// Import the chain as an archive node for the comparison baseline
archiveDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(archiveDb)
archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
archive, _ := NewBlockChain(archiveDb, nil, gspec, ethash.NewFaker(), vm.Config{})
defer archive.Stop()
if n, err := archive.InsertChain(blocks); err != nil {
@ -629,7 +633,7 @@ func TestFastVsFullChains(t *testing.T) {
// Fast import the chain as a non-archive node to test
fastDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(fastDb)
fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
fast, _ := NewBlockChain(fastDb, nil, gspec, ethash.NewFaker(), vm.Config{})
defer fast.Stop()
headers := make([]*types.Header, len(blocks))
@ -711,7 +715,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
archiveDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(archiveDb)
archive, _ := NewBlockChain(archiveDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
archive, _ := NewBlockChain(archiveDb, nil, gspec, ethash.NewFaker(), vm.Config{})
if n, err := archive.InsertChain(blocks); err != nil {
t.Fatalf("failed to process block %d: %v", n, err)
}
@ -724,7 +728,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
// Import the chain as a non-archive node and ensure all pointers are updated
fastDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(fastDb)
fast, _ := NewBlockChain(fastDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
fast, _ := NewBlockChain(fastDb, nil, gspec, ethash.NewFaker(), vm.Config{})
defer fast.Stop()
headers := make([]*types.Header, len(blocks))
@ -745,7 +749,7 @@ func TestLightVsFastVsFullChainHeads(t *testing.T) {
lightDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(lightDb)
light, _ := NewBlockChain(lightDb, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
light, _ := NewBlockChain(lightDb, nil, gspec, ethash.NewFaker(), vm.Config{})
if n, err := light.InsertHeaderChain(headers, 1); err != nil {
t.Fatalf("failed to insert header %d: %v", n, err)
}
@ -814,7 +818,7 @@ func TestChainTxReorgs(t *testing.T) {
}
})
// Import the chain. This runs all block validation rules.
blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
blockchain, _ := NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
if i, err := blockchain.InsertChain(chain); err != nil {
t.Fatalf("failed to insert original chain[%d]: %v", i, err)
}
@ -887,7 +891,7 @@ func TestLogReorgs(t *testing.T) {
signer = types.LatestSigner(gspec.Config)
)
blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
blockchain, _ := NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
defer blockchain.Stop()
rmLogsCh := make(chan RemovedLogsEvent)
@ -1066,7 +1070,7 @@ func TestEIP155Transition(t *testing.T) {
genesis = gspec.MustCommit(db)
)
blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
blockchain, _ := NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
defer blockchain.Stop()
blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 4, func(i int, block *BlockGen) {
@ -1173,7 +1177,7 @@ func TestEIP161AccountRemoval(t *testing.T) {
}
genesis = gspec.MustCommit(db)
)
blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
blockchain, _ := NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
defer blockchain.Stop()
blocks, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 3, func(i int, block *BlockGen) {
@ -1252,7 +1256,7 @@ func TestBlockchainHeaderchainReorgConsistency(t *testing.T) {
diskdb := rawdb.NewMemoryDatabase()
gspec.MustCommit(diskdb)
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
chain, err := NewBlockChain(diskdb, nil, gspec, engine, vm.Config{})
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1300,7 +1304,7 @@ func TestTrieForkGC(t *testing.T) {
diskdb := rawdb.NewMemoryDatabase()
gspec.MustCommit(diskdb)
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
chain, err := NewBlockChain(diskdb, nil, gspec, engine, vm.Config{})
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1327,12 +1331,12 @@ func TestTrieForkGC(t *testing.T) {
func TestLargeReorgTrieGC(t *testing.T) {
// Generate the original common chain segment and the two competing forks
engine := ethash.NewFaker()
db := rawdb.NewMemoryDatabase()
gspec := &Genesis{
BaseFee: big.NewInt(params.InitialBaseFee),
Config: params.TestChainConfig,
}
db := rawdb.NewMemoryDatabase()
genesis := gspec.MustCommit(db)
shared, _ := GenerateChain(gspec.Config, genesis, engine, db, 64, func(i int, b *BlockGen) { b.SetCoinbase(common.Address{1}) })
@ -1343,7 +1347,7 @@ func TestLargeReorgTrieGC(t *testing.T) {
diskdb := rawdb.NewMemoryDatabase()
gspec.MustCommit(diskdb)
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
chain, err := NewBlockChain(diskdb, nil, gspec, engine, vm.Config{})
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1425,7 +1429,7 @@ func benchmarkLargeNumberOfValueToNonexisting(b *testing.B, numTxs, numBlocks in
diskdb := rawdb.NewMemoryDatabase()
gspec.MustCommit(diskdb)
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
chain, err := NewBlockChain(diskdb, nil, gspec, engine, vm.Config{})
if err != nil {
b.Fatalf("failed to create tester chain: %v", err)
}
@ -1652,7 +1656,7 @@ func TestEIP2718Transition(t *testing.T) {
diskdb := rawdb.NewMemoryDatabase()
gspec.MustCommit(diskdb)
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
chain, err := NewBlockChain(diskdb, nil, gspec, engine, vm.Config{})
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1747,7 +1751,7 @@ func TestTransientStorageReset(t *testing.T) {
gspec.MustCommit(diskdb)
// Initialize the blockchain with 1153 enabled.
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vmConfig)
chain, err := NewBlockChain(diskdb, nil, gspec, engine, vmConfig)
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1842,7 +1846,7 @@ func TestEIP3651(t *testing.T) {
diskdb := rawdb.NewMemoryDatabase()
gspec.MustCommit(diskdb)
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
chain, err := NewBlockChain(diskdb, nil, gspec, engine, vm.Config{})
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}
@ -1945,7 +1949,7 @@ func TestDeleteCreateRevert(t *testing.T) {
diskdb := rawdb.NewMemoryDatabase()
gspec.MustCommit(diskdb)
chain, err := NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
chain, err := NewBlockChain(diskdb, nil, gspec, engine, vm.Config{})
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}

View file

@ -78,7 +78,7 @@ func ExampleGenerateChain() {
})
// Import the chain. This runs all block validation rules.
blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
blockchain, _ := NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
defer blockchain.Stop()
if i, err := blockchain.InsertChain(chain); err != nil {

View file

@ -32,29 +32,39 @@ func TestDAOForkRangeExtradata(t *testing.T) {
forkBlock := big.NewInt(32)
// Generate a common prefix for both pro-forkers and non-forkers
db := rawdb.NewMemoryDatabase()
gspec := &Genesis{
BaseFee: big.NewInt(params.InitialBaseFee),
Config: params.TestChainConfig,
}
db := rawdb.NewMemoryDatabase()
genesis := gspec.MustCommit(db)
prefix, _ := GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, int(forkBlock.Int64()-1), func(i int, gen *BlockGen) {})
// Create the concurrent, conflicting two nodes
proDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(proDb)
proConf := *params.TestChainConfig
proConf.DAOForkBlock = forkBlock
proConf.DAOForkSupport = true
proBc, _ := NewBlockChain(proDb, nil, &proConf, ethash.NewFaker(), vm.Config{})
progspec := &Genesis{
BaseFee: big.NewInt(params.InitialBaseFee),
Config: &proConf,
}
gspec.MustCommit(proDb)
proBc, _ := NewBlockChain(proDb, nil, progspec, ethash.NewFaker(), vm.Config{})
defer proBc.Stop()
conDb := rawdb.NewMemoryDatabase()
gspec.MustCommit(conDb)
conConf := *params.TestChainConfig
conConf.DAOForkBlock = forkBlock
conConf.DAOForkSupport = false
conBc, _ := NewBlockChain(conDb, nil, &conConf, ethash.NewFaker(), vm.Config{})
congspec := &Genesis{
BaseFee: big.NewInt(params.InitialBaseFee),
Config: &conConf,
}
gspec.MustCommit(conDb)
conBc, _ := NewBlockChain(conDb, nil, congspec, ethash.NewFaker(), vm.Config{})
defer conBc.Stop()
if _, err := proBc.InsertChain(prefix); err != nil {
@ -67,8 +77,8 @@ func TestDAOForkRangeExtradata(t *testing.T) {
for i := int64(0); i < params.DAOForkExtraRange.Int64(); i++ {
// Create a pro-fork block, and try to feed into the no-fork chain
db = rawdb.NewMemoryDatabase()
gspec.MustCommit(db)
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
congspec.MustCommit(db)
bc, _ := NewBlockChain(db, nil, congspec, ethash.NewFaker(), vm.Config{})
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().Number.Uint64()))
for j := 0; j < len(blocks)/2; j++ {
@ -92,8 +102,8 @@ func TestDAOForkRangeExtradata(t *testing.T) {
}
// Create a no-fork block, and try to feed into the pro-fork chain
db = rawdb.NewMemoryDatabase()
gspec.MustCommit(db)
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
progspec.MustCommit(db)
bc, _ = NewBlockChain(db, nil, progspec, ethash.NewFaker(), vm.Config{})
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().Number.Uint64()))
for j := 0; j < len(blocks)/2; j++ {
@ -118,8 +128,8 @@ func TestDAOForkRangeExtradata(t *testing.T) {
}
// Verify that contra-forkers accept pro-fork extra-datas after forking finishes
db = rawdb.NewMemoryDatabase()
gspec.MustCommit(db)
bc, _ := NewBlockChain(db, nil, &conConf, ethash.NewFaker(), vm.Config{})
congspec.MustCommit(db)
bc, _ := NewBlockChain(db, nil, congspec, ethash.NewFaker(), vm.Config{})
defer bc.Stop()
blocks := conBc.GetBlocksFromHash(conBc.CurrentBlock().Hash(), int(conBc.CurrentBlock().Number.Uint64()))
@ -138,8 +148,8 @@ func TestDAOForkRangeExtradata(t *testing.T) {
}
// Verify that pro-forkers accept contra-fork extra-datas after forking finishes
db = rawdb.NewMemoryDatabase()
gspec.MustCommit(db)
bc, _ = NewBlockChain(db, nil, &proConf, ethash.NewFaker(), vm.Config{})
progspec.MustCommit(db)
bc, _ = NewBlockChain(db, nil, progspec, ethash.NewFaker(), vm.Config{})
defer bc.Stop()
blocks = proBc.GetBlocksFromHash(proBc.CurrentBlock().Hash(), int(proBc.CurrentBlock().Number.Uint64()))

View file

@ -246,7 +246,10 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
// Get the existing chain configuration.
newcfg := genesis.configOrDefault(stored)
storedcfg, _ := rawdb.ReadChainConfig(db, stored)
storedcfg, err := rawdb.ReadChainConfig(db, stored)
if err != nil {
return nil, common.Hash{}, err
}
if storedcfg == nil {
log.Warn("Found genesis block without chain config")
rawdb.WriteChainConfig(db, stored, newcfg)
@ -285,6 +288,43 @@ func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig
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.
func LoadChainConfig(db ethdb.Database, genesis *Genesis) (cfg *params.ChainConfig, ghash common.Hash, err 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{}) {
storedcfg, err := rawdb.ReadChainConfig(db, stored)
if err != nil {
return nil, common.Hash{}, err
}
if storedcfg != nil {
return storedcfg, stored, nil
}
}
// Load the config from the provided genesis specification
if genesis != nil {
// Reject invalid genesis spec without valid chain config
if genesis.Config == nil {
return nil, common.Hash{}, errGenesisNoConfig
}
// If the canonical genesis header is present, but the chain
// config is missing(initialize the empty leveldb with an
// external ancient chain segment), ensure the provided genesis
// is matched.
ghash := genesis.ToBlock().Hash()
if stored != (common.Hash{}) && ghash != stored {
return nil, ghash, &GenesisMismatchError{stored, ghash}
}
return genesis.Config, ghash, nil
}
// There is no stored chain config and no new config provided,
// In this case the default chain config(mainnet) will be used
return params.XDCMainnetChainConfig, params.MainnetGenesisHash, nil
}
func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
switch {
case g != nil:

View file

@ -167,7 +167,7 @@ func TestSetupGenesis(t *testing.T) {
// Advance to block #4, past the homestead transition block of customg.
genesis := oldcustomg.MustCommit(db)
bc, _ := NewBlockChain(db, nil, oldcustomg.Config, ethash.NewFullFaker(), vm.Config{})
bc, _ := NewBlockChain(db, nil, &oldcustomg, ethash.NewFullFaker(), vm.Config{})
defer bc.Stop()
blocks, _ := GenerateChain(oldcustomg.Config, genesis, ethash.NewFaker(), db, 4, nil)

View file

@ -123,7 +123,7 @@ func TestStateProcessorErrors(t *testing.T) {
},
}
genesis = gspec.MustCommit(db)
blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
blockchain, _ = NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
tooBigInitCode = [params.MaxInitCodeSize + 1]byte{}
)
@ -284,7 +284,7 @@ func TestStateProcessorErrors(t *testing.T) {
},
}
genesis = gspec.MustCommit(db)
blockchain, _ = NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
blockchain, _ = NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
)
defer blockchain.Stop()
for i, tt := range []struct {
@ -415,7 +415,7 @@ func TestApplyTransactionWithEVMTracer(t *testing.T) {
},
}
genesis := gspec.MustCommit(db)
blockchain, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
blockchain, _ := NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
defer blockchain.Stop()
// Create state database

View file

@ -23,7 +23,6 @@ import (
"fmt"
"math/big"
"runtime"
"strings"
"sync"
"sync/atomic"
@ -109,6 +108,7 @@ type Ethereum struct {
// New creates a new Ethereum object (including the
// initialisation of the common Ethereum object)
func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendingServ *XDCxlending.Lending) (*Ethereum, error) {
// Ensure configuration values are compatible and sane
if config.SyncMode == downloader.LightSync {
return nil, errors.New("can't run eth.Ethereum in light sync mode, light mode has been deprecated")
}
@ -116,28 +116,25 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode)
}
// Assemble the Ethereum object
chainDb, err := stack.OpenDatabase("chaindata", config.DatabaseCache, config.DatabaseHandles, "eth/db/chaindata/", false)
if err != nil {
return nil, err
}
chainConfig, genesisHash, genesisErr := core.SetupGenesisBlock(chainDb, config.Genesis)
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
return nil, genesisErr
// 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
}
// Set networkID to chainID by default.
networkID := config.NetworkId
if networkID == 0 {
networkID = chainConfig.ChainID.Uint64()
}
common.CopyConstants(networkID)
log.Info(strings.Repeat("-", 153))
for line := range strings.SplitSeq(chainConfig.Description(), "\n") {
log.Info(line)
}
log.Info(strings.Repeat("-", 153))
// Assemble the Ethereum object.
eth := &Ethereum{
config: config,
chainDb: chainDb,
@ -168,6 +165,7 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
}
log.Info("Initialising Ethereum protocol", "versions", ProtocolVersions, "network", networkID, "dbversion", dbVer)
// Create BlockChain object.
if !config.SkipBcVersionCheck {
if bcVersion != nil && *bcVersion > core.BlockChainVersion {
return nil, fmt.Errorf("database version is v%d, XDC %s only supports v%d", *bcVersion, version.WithMeta, core.BlockChainVersion)
@ -224,7 +222,7 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
return eth.Lending
}
}
eth.blockchain, err = core.NewBlockChainEx(chainDb, XDCXServ.GetLevelDB(), cacheConfig, eth.chainConfig, eth.engine, vmConfig)
eth.blockchain, err = core.NewBlockChainEx(chainDb, XDCXServ.GetLevelDB(), cacheConfig, config.Genesis, eth.engine, vmConfig)
if err != nil {
return nil, err
}
@ -256,14 +254,9 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
}
}
// Rewind the chain in case of an incompatible config upgrade.
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
eth.blockchain.SetHead(compat.RewindTo)
rawdb.WriteChainConfig(chainDb, genesisHash, chainConfig)
}
eth.bloomIndexer.Start(eth.blockchain)
// TxPool
if config.TxPool.Journal != "" {
config.TxPool.Journal = stack.ResolvePath(config.TxPool.Journal)
}
@ -274,13 +267,13 @@ func New(stack *node.Node, config *ethconfig.Config, XDCXServ *XDCx.XDCX, lendin
return nil, err
}
eth.orderPool = legacypool.NewOrderPool(eth.chainConfig, eth.blockchain)
eth.lendingPool = legacypool.NewLendingPool(eth.chainConfig, eth.blockchain)
eth.orderPool = legacypool.NewOrderPool(eth.blockchain.Config(), eth.blockchain)
eth.lendingPool = legacypool.NewLendingPool(eth.blockchain.Config(), eth.blockchain)
if eth.protocolManager, err = NewProtocolManagerEx(eth.chainConfig, config.SyncMode, networkID, eth.eventMux, eth.txPool, eth.orderPool, eth.lendingPool, eth.engine, eth.blockchain, chainDb); err != nil {
if eth.protocolManager, err = NewProtocolManagerEx(eth.blockchain.Config(), config.SyncMode, networkID, eth.eventMux, eth.txPool, eth.orderPool, eth.lendingPool, eth.engine, eth.blockchain, chainDb); err != nil {
return nil, err
}
eth.miner = miner.New(eth, eth.chainConfig, eth.EventMux(), eth.engine, stack.Config().AnnounceTxs)
eth.miner = miner.New(eth, eth.blockchain.Config(), eth.EventMux(), eth.engine, stack.Config().AnnounceTxs)
eth.miner.SetExtra(makeExtraData(config.ExtraData))
var xdPoS *XDPoS.XDPoS = nil

View file

@ -382,7 +382,7 @@ func TestInvalidGetLogsRequest(t *testing.T) {
)
// Insert the blocks into the chain so filter can look them up
blockchain, err := core.NewBlockChain(db, nil, genesis.Config, ethash.NewFaker(), vm.Config{})
blockchain, err := core.NewBlockChain(db, nil, genesis, ethash.NewFaker(), vm.Config{})
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}

View file

@ -246,7 +246,7 @@ func TestFilters(t *testing.T) {
}
})
bc, err := core.NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
bc, err := core.NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
if err != nil {
t.Fatal(err)
}
@ -372,7 +372,7 @@ func TestRangeLimit(t *testing.T) {
}
genesis := gspec.MustCommit(db)
chain, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {})
bc, err := core.NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{})
bc, err := core.NewBlockChain(db, nil, gspec, ethash.NewFaker(), vm.Config{})
if err != nil {
t.Fatal(err)
}

View file

@ -154,7 +154,7 @@ func newTestBackend(t *testing.T, eip1559Block *big.Int, pending bool) *testBack
// Construct testing chain
diskdb := rawdb.NewMemoryDatabase()
gspec.MustCommit(diskdb)
chain, err := core.NewBlockChain(diskdb, nil, gspec.Config, engine, vm.Config{})
chain, err := core.NewBlockChain(diskdb, nil, gspec, engine, vm.Config{})
if err != nil {
t.Fatalf("Failed to create local chain, %v", err)
}

View file

@ -469,15 +469,19 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
}
// Create a DAO aware protocol manager
var (
evmux = new(event.TypeMux)
pow = ethash.NewFaker()
db = rawdb.NewMemoryDatabase()
config = &params.ChainConfig{DAOForkBlock: big.NewInt(1), DAOForkSupport: localForked}
gspec = &core.Genesis{Config: config}
evmux = new(event.TypeMux)
pow = ethash.NewFaker()
db = rawdb.NewMemoryDatabase()
gspec = &core.Genesis{
Config: &params.ChainConfig{
DAOForkBlock: big.NewInt(1),
DAOForkSupport: localForked,
},
}
genesis = gspec.MustCommit(db)
blockchain, _ = core.NewBlockChain(db, nil, config, pow, vm.Config{})
blockchain, _ = core.NewBlockChain(db, nil, gspec, pow, vm.Config{})
)
pm, err := NewProtocolManager(config, downloader.FullSync, ethconfig.Defaults.NetworkId, evmux, new(testTxPool), pow, blockchain, db)
pm, err := NewProtocolManager(gspec.Config, downloader.FullSync, ethconfig.Defaults.NetworkId, evmux, new(testTxPool), pow, blockchain, db)
if err != nil {
t.Fatalf("failed to start test protocol manager: %v", err)
}
@ -489,7 +493,7 @@ func testDAOChallenge(t *testing.T, localForked, remoteForked bool, timeout bool
defer peer.close()
challenge := &getBlockHeadersData{
Origin: hashOrNumber{Number: config.DAOForkBlock.Uint64()},
Origin: hashOrNumber{Number: gspec.Config.DAOForkBlock.Uint64()},
Amount: 1,
Skip: 0,
Reverse: false,

View file

@ -62,7 +62,7 @@ func newTestProtocolManager(mode downloader.SyncMode, blocks int, generator func
Config: params.TestChainConfig,
}
genesis = gspec.MustCommit(db)
blockchain, _ = core.NewBlockChain(db, nil, gspec.Config, engine, vm.Config{})
blockchain, _ = core.NewBlockChain(db, nil, gspec, engine, vm.Config{})
)
chain, _ := core.GenerateChain(gspec.Config, genesis, ethash.NewFaker(), db, blocks, generator)
if _, err := blockchain.InsertChain(chain); err != nil {

View file

@ -81,7 +81,7 @@ func newTestBackend(t *testing.T, n int, gspec *core.Genesis, generator func(i i
TrieTimeLimit: 5 * time.Minute,
TrieDirtyDisabled: true, // Archive mode
}
chain, err := core.NewBlockChain(backend.chaindb, cacheConfig, backend.chainConfig, backend.engine, vm.Config{})
chain, err := core.NewBlockChain(backend.chaindb, cacheConfig, gspec, backend.engine, vm.Config{})
if err != nil {
t.Fatalf("failed to create tester chain: %v", err)
}

View file

@ -249,7 +249,7 @@ var (
},
}
// MainnetChainConfig is the chain parameters to run a node on the main network.
// MainnetChainConfig is the chain parameters to run a node on the ethereum main network.
MainnetChainConfig = &ChainConfig{
ChainID: big.NewInt(1),
HomesteadBlock: big.NewInt(1150000),

View file

@ -112,7 +112,7 @@ func (t *BlockTest) Run() error {
return fmt.Errorf("genesis block state root does not match test: computed=%x, test=%x", gblock.Root().Bytes(), t.json.Genesis.StateRoot)
}
chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieCleanLimit: 0}, config, ethash.NewFaker(), vm.Config{})
chain, err := core.NewBlockChain(db, &core.CacheConfig{TrieCleanLimit: 0}, gspec, ethash.NewFaker(), vm.Config{})
if err != nil {
return err
}