Skip to content

Commit 3d9e219

Browse files
rjl493456442jagdeep sidhu
authored andcommitted
all: move genesis initialization to blockchain (ethereum#25523)
1 parent be36c61 commit 3d9e219

35 files changed

+406
-245
lines changed

accounts/abi/bind/backends/simulated.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ type SimulatedBackend struct {
8080
func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
8181
genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc}
8282
genesis.MustCommit(database)
83-
blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
83+
blockchain, _ := core.NewBlockChain(database, nil, &genesis, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
8484

8585
backend := &SimulatedBackend{
8686
database: database,

cmd/utils/flags.go

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import (
3333
"github.com/ethereum/go-ethereum/accounts/keystore"
3434
"github.com/ethereum/go-ethereum/common"
3535
"github.com/ethereum/go-ethereum/common/fdlimit"
36-
"github.com/ethereum/go-ethereum/consensus"
3736
"github.com/ethereum/go-ethereum/consensus/ethash"
3837
"github.com/ethereum/go-ethereum/core"
3938
"github.com/ethereum/go-ethereum/core/rawdb"
@@ -2216,20 +2215,20 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
22162215
}
22172216

22182217
// MakeChain creates a chain manager from set command line flags.
2219-
func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chainDb ethdb.Database) {
2220-
var err error
2221-
chainDb = MakeChainDatabase(ctx, stack, false) // TODO(rjl493456442) support read-only database
2222-
config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx))
2218+
func MakeChain(ctx *cli.Context, stack *node.Node) (*core.BlockChain, ethdb.Database) {
2219+
var (
2220+
gspec = MakeGenesis(ctx)
2221+
chainDb = MakeChainDatabase(ctx, stack, false) // TODO(rjl493456442) support read-only database
2222+
)
2223+
cliqueConfig, err := core.LoadCliqueConfig(chainDb, gspec)
22232224
if err != nil {
22242225
Fatalf("%v", err)
22252226
}
2226-
2227-
var engine consensus.Engine
2228-
ethashConf := ethconfig.Defaults.Ethash
2227+
ethashConfig := ethconfig.Defaults.Ethash
22292228
if ctx.Bool(FakePoWFlag.Name) {
2230-
ethashConf.PowMode = ethash.ModeFake
2229+
ethashConfig.PowMode = ethash.ModeFake
22312230
}
2232-
engine = ethconfig.CreateConsensusEngine(stack, config, &ethashConf, nil, false, chainDb)
2231+
engine := ethconfig.CreateConsensusEngine(stack, &ethashConfig, cliqueConfig, nil, false, chainDb)
22332232
if gcmode := ctx.String(GCModeFlag.Name); gcmode != "full" && gcmode != "archive" {
22342233
Fatalf("--%s must be either 'full' or 'archive'", GCModeFlag.Name)
22352234
}
@@ -2259,7 +2258,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai
22592258

22602259
// TODO(rjl493456442) disable snapshot generation/wiping if the chain is read only.
22612260
// Disable transaction indexing/unindexing by default.
2262-
chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil, nil)
2261+
chain, err := core.NewBlockChain(chainDb, cache, gspec, nil, engine, vmcfg, nil, nil)
22632262
if err != nil {
22642263
Fatalf("Can't create BlockChain: %v", err)
22652264
}

consensus/clique/clique_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func TestReimportMirroredState(t *testing.T) {
4545
signer = new(types.HomesteadSigner)
4646
)
4747
genspec := &core.Genesis{
48+
Config: params.AllCliqueProtocolChanges,
4849
ExtraData: make([]byte, extraVanity+common.AddressLength+extraSeal),
4950
Alloc: map[common.Address]core.GenesisAccount{
5051
addr: {Balance: big.NewInt(10000000000000000)},
@@ -55,7 +56,7 @@ func TestReimportMirroredState(t *testing.T) {
5556
genesis := genspec.MustCommit(db)
5657

5758
// Generate a batch of blocks, each properly signed
58-
chain, _ := core.NewBlockChain(db, nil, params.AllCliqueProtocolChanges, engine, vm.Config{}, nil, nil)
59+
chain, _ := core.NewBlockChain(db, nil, genspec, nil, engine, vm.Config{}, nil, nil)
5960
defer chain.Stop()
6061

6162
blocks, _ := core.GenerateChain(params.AllCliqueProtocolChanges, genesis, engine, db, 3, func(i int, block *core.BlockGen) {
@@ -89,7 +90,7 @@ func TestReimportMirroredState(t *testing.T) {
8990
db = rawdb.NewMemoryDatabase()
9091
genspec.MustCommit(db)
9192

92-
chain, _ = core.NewBlockChain(db, nil, params.AllCliqueProtocolChanges, engine, vm.Config{}, nil, nil)
93+
chain, _ = core.NewBlockChain(db, nil, genspec, nil, engine, vm.Config{}, nil, nil)
9394
defer chain.Stop()
9495

9596
if _, err := chain.InsertChain(blocks[:2]); err != nil {
@@ -102,7 +103,7 @@ func TestReimportMirroredState(t *testing.T) {
102103
// Simulate a crash by creating a new chain on top of the database, without
103104
// flushing the dirty states out. Insert the last block, triggering a sidechain
104105
// reimport.
105-
chain, _ = core.NewBlockChain(db, nil, params.AllCliqueProtocolChanges, engine, vm.Config{}, nil, nil)
106+
chain, _ = core.NewBlockChain(db, nil, genspec, nil, engine, vm.Config{}, nil, nil)
106107
defer chain.Stop()
107108

108109
if _, err := chain.InsertChain(blocks[2:]); err != nil {

consensus/clique/snapshot_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ func TestClique(t *testing.T) {
411411
Period: 1,
412412
Epoch: tt.epoch,
413413
}
414+
genesis.Config = &config
414415
engine := New(config.Clique, db)
415416
engine.fakeDiff = true
416417

@@ -450,7 +451,7 @@ func TestClique(t *testing.T) {
450451
batches[len(batches)-1] = append(batches[len(batches)-1], block)
451452
}
452453
// Pass all the headers through clique and ensure tallying succeeds
453-
chain, err := core.NewBlockChain(db, nil, &config, engine, vm.Config{}, nil, nil)
454+
chain, err := core.NewBlockChain(db, nil, genesis, nil, engine, vm.Config{}, nil, nil)
454455
if err != nil {
455456
t.Errorf("test %d: failed to create test chain: %v", i, err)
456457
continue

core/bench_test.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ func benchInsertChain(b *testing.B, disk bool, gen func(int, *BlockGen)) {
196196

197197
// Time the insertion of the new chain.
198198
// State and blocks are stored in the same DB.
199-
chainman, _ := NewBlockChain(db, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
199+
chainman, _ := NewBlockChain(db, nil, &gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
200200
defer chainman.Stop()
201201
b.ReportAllocs()
202202
b.ResetTimer()
@@ -262,6 +262,11 @@ func makeChainForBench(db ethdb.Database, full bool, count uint64) {
262262
rawdb.WriteCanonicalHash(db, hash, n)
263263
rawdb.WriteTd(db, hash, n, big.NewInt(int64(n+1)))
264264

265+
if n == 0 {
266+
rawdb.WriteChainConfig(db, hash, params.AllEthashProtocolChanges)
267+
}
268+
rawdb.WriteHeadHeaderHash(db, hash)
269+
265270
if full || n == 0 {
266271
block := types.NewBlockWithHeader(header)
267272
rawdb.WriteBody(db, hash, n, block.Body())
@@ -303,7 +308,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) {
303308
if err != nil {
304309
b.Fatalf("error opening database at %v: %v", dir, err)
305310
}
306-
chain, err := NewBlockChain(db, &cacheConfig, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
311+
chain, err := NewBlockChain(db, &cacheConfig, nil, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
307312
if err != nil {
308313
b.Fatalf("error creating chain: %v", err)
309314
}

core/block_validator_test.go

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ func TestHeaderVerification(t *testing.T) {
4949
headers[i] = block.Header()
5050
}
5151
// Run the header checker for blocks one-by-one, checking for both valid and invalid nonces
52-
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
52+
chain, _ := NewBlockChain(testdb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
5353
defer chain.Stop()
5454

5555
for i := 0; i < len(blocks); i++ {
@@ -89,20 +89,21 @@ func TestHeaderVerificationForMergingEthash(t *testing.T) { testHeaderVerificati
8989
// Tests the verification for eth1/2 merging, including pre-merge and post-merge
9090
func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
9191
var (
92-
testdb = rawdb.NewMemoryDatabase()
93-
preBlocks []*types.Block
94-
postBlocks []*types.Block
95-
runEngine consensus.Engine
96-
chainConfig *params.ChainConfig
97-
merger = consensus.NewMerger(rawdb.NewMemoryDatabase())
92+
testdb = rawdb.NewMemoryDatabase()
93+
preBlocks []*types.Block
94+
postBlocks []*types.Block
95+
runEngine consensus.Engine
96+
genspec *Genesis
97+
merger = consensus.NewMerger(rawdb.NewMemoryDatabase())
9898
)
9999
if isClique {
100100
var (
101101
key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
102102
addr = crypto.PubkeyToAddress(key.PublicKey)
103103
engine = clique.New(params.AllCliqueProtocolChanges.Clique, testdb)
104104
)
105-
genspec := &Genesis{
105+
genspec = &Genesis{
106+
Config: params.AllCliqueProtocolChanges,
106107
ExtraData: make([]byte, 32+common.AddressLength+crypto.SignatureLength),
107108
Alloc: map[common.Address]GenesisAccount{
108109
addr: {Balance: big.NewInt(1)},
@@ -133,11 +134,11 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
133134
config := *params.AllCliqueProtocolChanges
134135
config.TerminalTotalDifficulty = big.NewInt(int64(td))
135136
postBlocks, _ = GenerateChain(&config, preBlocks[len(preBlocks)-1], genEngine, testdb, 8, nil)
136-
chainConfig = &config
137137
runEngine = beacon.New(engine)
138+
genspec.Config = &config
138139
} else {
139-
gspec := &Genesis{Config: params.TestChainConfig}
140-
genesis := gspec.MustCommit(testdb)
140+
genspec = &Genesis{Config: params.TestChainConfig}
141+
genesis := genspec.MustCommit(testdb)
141142
genEngine := beacon.New(ethash.NewFaker())
142143

143144
preBlocks, _ = GenerateChain(params.TestChainConfig, genesis, genEngine, testdb, 8, nil)
@@ -150,8 +151,8 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
150151
config.TerminalTotalDifficulty = big.NewInt(int64(td))
151152
postBlocks, _ = GenerateChain(params.TestChainConfig, preBlocks[len(preBlocks)-1], genEngine, testdb, 8, nil)
152153

153-
chainConfig = &config
154154
runEngine = beacon.New(ethash.NewFaker())
155+
genspec.Config = &config
155156
}
156157

157158
preHeaders := make([]*types.Header, len(preBlocks))
@@ -169,7 +170,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
169170
t.Logf("Log header after the merging %d: %v", block.NumberU64(), string(blob))
170171
}
171172
// Run the header checker for blocks one-by-one, checking for both valid and invalid nonces
172-
chain, _ := NewBlockChain(testdb, nil, chainConfig, runEngine, vm.Config{}, nil, nil)
173+
chain, _ := NewBlockChain(testdb, nil, genspec, nil, runEngine, vm.Config{}, nil, nil)
173174
defer chain.Stop()
174175

175176
// Verify the blocks before the merging
@@ -280,11 +281,11 @@ func testHeaderConcurrentVerification(t *testing.T, threads int) {
280281
var results <-chan error
281282

282283
if valid {
283-
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
284+
chain, _ := NewBlockChain(testdb, nil, gspec, nil, ethash.NewFaker(), vm.Config{}, nil, nil)
284285
_, results = chain.engine.VerifyHeaders(chain, headers, seals)
285286
chain.Stop()
286287
} else {
287-
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeFailer(uint64(len(headers)-1)), vm.Config{}, nil, nil)
288+
chain, _ := NewBlockChain(testdb, nil, gspec, nil, ethash.NewFakeFailer(uint64(len(headers)-1)), vm.Config{}, nil, nil)
288289
_, results = chain.engine.VerifyHeaders(chain, headers, seals)
289290
chain.Stop()
290291
}
@@ -347,7 +348,7 @@ func testHeaderConcurrentAbortion(t *testing.T, threads int) {
347348
defer runtime.GOMAXPROCS(old)
348349

349350
// Start the verifications and immediately abort
350-
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeDelayer(time.Millisecond), vm.Config{}, nil, nil)
351+
chain, _ := NewBlockChain(testdb, nil, gspec, nil, ethash.NewFakeDelayer(time.Millisecond), vm.Config{}, nil, nil)
351352
defer chain.Stop()
352353

353354
abort, results := chain.engine.VerifyHeaders(chain, headers, seals)

core/blockchain.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"io"
2424
"math/big"
2525
"sort"
26+
"strings"
2627
"sync"
2728
"sync/atomic"
2829
"time"
@@ -219,7 +220,7 @@ type BlockChain struct {
219220
// NewBlockChain returns a fully initialised block chain using information
220221
// available in the database. It initialises the default Ethereum Validator
221222
// and Processor.
222-
func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(header *types.Header) bool, txLookupLimit *uint64) (*BlockChain, error) {
223+
func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis, overrides *ChainOverrides, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(header *types.Header) bool, txLookupLimit *uint64) (*BlockChain, error) {
223224
if cacheConfig == nil {
224225
cacheConfig = defaultCacheConfig
225226
}
@@ -230,6 +231,21 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
230231
txLookupCache, _ := lru.New(txLookupCacheLimit)
231232
futureBlocks, _ := lru.New(maxFutureBlocks)
232233

234+
// Setup the genesis block, commit the provided genesis specification
235+
// to database if the genesis block is not present yet, or load the
236+
// stored one from database.
237+
chainConfig, genesisHash, genesisErr := SetupGenesisBlockWithOverride(db, genesis, overrides)
238+
if _, ok := genesisErr.(*params.ConfigCompatError); genesisErr != nil && !ok {
239+
return nil, genesisErr
240+
}
241+
log.Info("")
242+
log.Info(strings.Repeat("-", 153))
243+
for _, line := range strings.Split(chainConfig.String(), "\n") {
244+
log.Info(line)
245+
}
246+
log.Info(strings.Repeat("-", 153))
247+
log.Info("")
248+
233249
bc := &BlockChain{
234250
chainConfig: chainConfig,
235251
cacheConfig: cacheConfig,
@@ -410,6 +426,12 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
410426
triedb.SaveCachePeriodically(bc.cacheConfig.TrieCleanJournal, bc.cacheConfig.TrieCleanRejournal, bc.quit)
411427
}()
412428
}
429+
// Rewind the chain in case of an incompatible config upgrade.
430+
if compat, ok := genesisErr.(*params.ConfigCompatError); ok {
431+
log.Warn("Rewinding chain to upgrade configuration", "err", compat)
432+
bc.SetHead(compat.RewindTo)
433+
rawdb.WriteChainConfig(db, genesisHash, chainConfig)
434+
}
413435
return bc, nil
414436
}
415437

core/blockchain_repair_test.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,7 +1764,11 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
17641764

17651765
// Initialize a fresh chain
17661766
var (
1767-
genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
1767+
gspec = &Genesis{
1768+
BaseFee: big.NewInt(params.InitialBaseFee),
1769+
Config: params.AllEthashProtocolChanges,
1770+
}
1771+
genesis = gspec.MustCommit(db)
17681772
engine = ethash.NewFullFaker()
17691773
config = &CacheConfig{
17701774
TrieCleanLimit: 256,
@@ -1778,7 +1782,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
17781782
config.SnapshotLimit = 256
17791783
config.SnapshotWait = true
17801784
}
1781-
chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
1785+
chain, err := NewBlockChain(db, config, gspec, nil, engine, vm.Config{}, nil, nil)
17821786
if err != nil {
17831787
t.Fatalf("Failed to create chain: %v", err)
17841788
}
@@ -1831,7 +1835,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
18311835
}
18321836
defer db.Close()
18331837

1834-
newChain, err := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
1838+
newChain, err := NewBlockChain(db, nil, gspec, nil, engine, vm.Config{}, nil, nil)
18351839
if err != nil {
18361840
t.Fatalf("Failed to recreate chain: %v", err)
18371841
}
@@ -1888,7 +1892,11 @@ func TestIssue23496(t *testing.T) {
18881892

18891893
// Initialize a fresh chain
18901894
var (
1891-
genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
1895+
gspec = &Genesis{
1896+
Config: params.TestChainConfig,
1897+
BaseFee: big.NewInt(params.InitialBaseFee),
1898+
}
1899+
genesis = gspec.MustCommit(db)
18921900
engine = ethash.NewFullFaker()
18931901
config = &CacheConfig{
18941902
TrieCleanLimit: 256,
@@ -1898,7 +1906,7 @@ func TestIssue23496(t *testing.T) {
18981906
SnapshotWait: true,
18991907
}
19001908
)
1901-
chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
1909+
chain, err := NewBlockChain(db, config, gspec, nil, engine, vm.Config{}, nil, nil)
19021910
if err != nil {
19031911
t.Fatalf("Failed to create chain: %v", err)
19041912
}
@@ -1942,7 +1950,7 @@ func TestIssue23496(t *testing.T) {
19421950
}
19431951
defer db.Close()
19441952

1945-
chain, err = NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
1953+
chain, err = NewBlockChain(db, nil, gspec, nil, engine, vm.Config{}, nil, nil)
19461954
if err != nil {
19471955
t.Fatalf("Failed to recreate chain: %v", err)
19481956
}

core/blockchain_sethead_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1964,7 +1964,11 @@ func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) {
19641964

19651965
// Initialize a fresh chain
19661966
var (
1967-
genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
1967+
gspec = &Genesis{
1968+
BaseFee: big.NewInt(params.InitialBaseFee),
1969+
Config: params.AllEthashProtocolChanges,
1970+
}
1971+
genesis = gspec.MustCommit(db)
19681972
engine = ethash.NewFullFaker()
19691973
config = &CacheConfig{
19701974
TrieCleanLimit: 256,
@@ -1977,7 +1981,7 @@ func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) {
19771981
config.SnapshotLimit = 256
19781982
config.SnapshotWait = true
19791983
}
1980-
chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
1984+
chain, err := NewBlockChain(db, config, gspec, nil, engine, vm.Config{}, nil, nil)
19811985
if err != nil {
19821986
t.Fatalf("Failed to create chain: %v", err)
19831987
}

0 commit comments

Comments
 (0)