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

all: recommit genesis state for 0 rewinding target #24450

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 1 addition & 1 deletion accounts/abi/bind/backends/simulated.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ type SimulatedBackend struct {
func NewSimulatedBackendWithDatabase(database ethdb.Database, alloc core.GenesisAlloc, gasLimit uint64) *SimulatedBackend {
genesis := core.Genesis{Config: params.AllEthashProtocolChanges, GasLimit: gasLimit, Alloc: alloc}
genesis.MustCommit(database)
blockchain, _ := core.NewBlockChain(database, nil, genesis.Config, ethash.NewFaker(), vm.Config{}, nil, nil)
blockchain, _ := core.NewBlockChain(database, &genesis, nil, genesis.Config, ethash.NewFaker(), vm.Config{}, nil, nil)

backend := &SimulatedBackend{
database: database,
Expand Down
14 changes: 7 additions & 7 deletions cmd/devp2p/internal/ethtest/snap.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,8 @@ func (s *Suite) TestSnapTrieNodes(t *utesting.T) {
{
root: s.chain.RootAt(999),
paths: []snap.TrieNodePathSet{
snap.TrieNodePathSet{}, // zero-length pathset should 'abort' and kick us off
snap.TrieNodePathSet{[]byte{0}},
{}, // zero-length pathset should 'abort' and kick us off
{[]byte{0}},
},
nBytes: 5000,
expHashes: []common.Hash{},
Expand All @@ -382,8 +382,8 @@ func (s *Suite) TestSnapTrieNodes(t *utesting.T) {
{
root: s.chain.RootAt(999),
paths: []snap.TrieNodePathSet{
snap.TrieNodePathSet{[]byte{0}},
snap.TrieNodePathSet{[]byte{1}, []byte{0}},
{[]byte{0}},
{[]byte{1}, []byte{0}},
},
nBytes: 5000,
//0x6b3724a41b8c38b46d4d02fba2bb2074c47a507eb16a9a4b978f91d32e406faf
Expand All @@ -392,7 +392,7 @@ func (s *Suite) TestSnapTrieNodes(t *utesting.T) {
{ // nonsensically long path
root: s.chain.RootAt(999),
paths: []snap.TrieNodePathSet{
snap.TrieNodePathSet{[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8,
{[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8,
0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8, 0, 1, 2, 3, 4, 5, 6, 7, 8}},
},
nBytes: 5000,
Expand All @@ -401,8 +401,8 @@ func (s *Suite) TestSnapTrieNodes(t *utesting.T) {
{
root: s.chain.RootAt(0),
paths: []snap.TrieNodePathSet{
snap.TrieNodePathSet{[]byte{0}},
snap.TrieNodePathSet{[]byte{1}, []byte{0}},
{[]byte{0}},
{[]byte{1}, []byte{0}},
},
nBytes: 5000,
expHashes: []common.Hash{},
Expand Down
2 changes: 1 addition & 1 deletion cmd/geth/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ func initGenesis(ctx *cli.Context) error {
if err != nil {
utils.Fatalf("Failed to open database: %v", err)
}
_, hash, err := core.SetupGenesisBlock(chaindb, genesis)
_, _, hash, err := core.SetupGenesisBlock(chaindb, genesis)
if err != nil {
utils.Fatalf("Failed to write genesis block: %v", err)
}
Expand Down
4 changes: 2 additions & 2 deletions cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -1881,7 +1881,7 @@ func MakeGenesis(ctx *cli.Context) *core.Genesis {
func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chainDb ethdb.Database) {
var err error
chainDb = MakeChainDatabase(ctx, stack, false) // TODO(rjl493456442) support read-only database
config, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx))
config, genesis, _, err := core.SetupGenesisBlock(chainDb, MakeGenesis(ctx))
if err != nil {
Fatalf("%v", err)
}
Expand Down Expand Up @@ -1932,7 +1932,7 @@ func MakeChain(ctx *cli.Context, stack *node.Node) (chain *core.BlockChain, chai

// TODO(rjl493456442) disable snapshot generation/wiping if the chain is read only.
// Disable transaction indexing/unindexing by default.
chain, err = core.NewBlockChain(chainDb, cache, config, engine, vmcfg, nil, nil)
chain, err = core.NewBlockChain(chainDb, genesis, cache, config, engine, vmcfg, nil, nil)
if err != nil {
Fatalf("Can't create BlockChain: %v", err)
}
Expand Down
6 changes: 3 additions & 3 deletions consensus/clique/clique_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ func TestReimportMirroredState(t *testing.T) {
genesis := genspec.MustCommit(db)

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

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

chain, _ = core.NewBlockChain(db, nil, params.AllCliqueProtocolChanges, engine, vm.Config{}, nil, nil)
chain, _ = core.NewBlockChain(db, genspec, nil, params.AllCliqueProtocolChanges, engine, vm.Config{}, nil, nil)
defer chain.Stop()

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

if _, err := chain.InsertChain(blocks[2:]); err != nil {
Expand Down
2 changes: 1 addition & 1 deletion consensus/clique/snapshot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ func TestClique(t *testing.T) {
batches[len(batches)-1] = append(batches[len(batches)-1], block)
}
// Pass all the headers through clique and ensure tallying succeeds
chain, err := core.NewBlockChain(db, nil, &config, engine, vm.Config{}, nil, nil)
chain, err := core.NewBlockChain(db, genesis, nil, &config, engine, vm.Config{}, nil, nil)
if err != nil {
t.Errorf("test %d: failed to create test chain: %v", i, err)
continue
Expand Down
5 changes: 3 additions & 2 deletions core/bench_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ 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{}, nil, nil)
chainman, _ := NewBlockChain(db, &gspec, nil, gspec.Config, ethash.NewFaker(), vm.Config{}, nil, nil)

defer chainman.Stop()
b.ReportAllocs()
b.ResetTimer()
Expand Down Expand Up @@ -316,7 +317,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, &cacheConfig, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
chain, err := NewBlockChain(db, nil, &cacheConfig, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
if err != nil {
b.Fatalf("error creating chain: %v", err)
}
Expand Down
17 changes: 9 additions & 8 deletions core/block_validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,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, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
chain, _ := NewBlockChain(testdb, gspec, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
defer chain.Stop()

for i := 0; i < len(blocks); i++ {
Expand Down Expand Up @@ -94,6 +94,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
postBlocks []*types.Block
runEngine consensus.Engine
chainConfig *params.ChainConfig
genspec *Genesis
merger = consensus.NewMerger(rawdb.NewMemoryDatabase())
)
if isClique {
Expand All @@ -102,7 +103,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
addr = crypto.PubkeyToAddress(key.PublicKey)
engine = clique.New(params.AllCliqueProtocolChanges.Clique, testdb)
)
genspec := &Genesis{
genspec = &Genesis{
ExtraData: make([]byte, 32+common.AddressLength+crypto.SignatureLength),
Alloc: map[common.Address]GenesisAccount{
addr: {Balance: big.NewInt(1)},
Expand Down Expand Up @@ -135,8 +136,8 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
chainConfig = &config
runEngine = beacon.New(engine)
} else {
gspec := &Genesis{Config: params.TestChainConfig}
genesis := gspec.MustCommit(testdb)
genspec = &Genesis{Config: params.TestChainConfig}
genesis := genspec.MustCommit(testdb)
genEngine := beacon.New(ethash.NewFaker())

preBlocks, _ = GenerateChain(params.TestChainConfig, genesis, genEngine, testdb, 8, nil)
Expand Down Expand Up @@ -168,7 +169,7 @@ func testHeaderVerificationForMerging(t *testing.T, isClique bool) {
t.Logf("Log header after the merging %d: %v", block.NumberU64(), string(blob))
}
// Run the header checker for blocks one-by-one, checking for both valid and invalid nonces
chain, _ := NewBlockChain(testdb, nil, chainConfig, runEngine, vm.Config{}, nil, nil)
chain, _ := NewBlockChain(testdb, genspec, nil, chainConfig, runEngine, vm.Config{}, nil, nil)
defer chain.Stop()

// Verify the blocks before the merging
Expand Down Expand Up @@ -279,11 +280,11 @@ func testHeaderConcurrentVerification(t *testing.T, threads int) {
var results <-chan error

if valid {
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
chain, _ := NewBlockChain(testdb, gspec, nil, params.TestChainConfig, ethash.NewFaker(), vm.Config{}, nil, nil)
_, results = chain.engine.VerifyHeaders(chain, headers, seals)
chain.Stop()
} else {
chain, _ := NewBlockChain(testdb, nil, params.TestChainConfig, ethash.NewFakeFailer(uint64(len(headers)-1)), vm.Config{}, nil, nil)
chain, _ := NewBlockChain(testdb, gspec, nil, params.TestChainConfig, ethash.NewFakeFailer(uint64(len(headers)-1)), vm.Config{}, nil, nil)
_, results = chain.engine.VerifyHeaders(chain, headers, seals)
chain.Stop()
}
Expand Down Expand Up @@ -346,7 +347,7 @@ func testHeaderConcurrentAbortion(t *testing.T, threads int) {
defer runtime.GOMAXPROCS(old)

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

abort, results := chain.engine.VerifyHeaders(chain, headers, seals)
Expand Down
21 changes: 19 additions & 2 deletions core/blockchain.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,12 @@ type BlockChain struct {
logsFeed event.Feed
blockProcFeed event.Feed
scope event.SubscriptionScope
genesisBlock *types.Block

// The earliest block and the corresponding state.
// Once the historical chain pruning is enabled, it
// should be replaced with tail block and tail state.
genesisBlock *types.Block
genesis *Genesis

// This mutex synchronizes chain write operations.
// Readers don't need to take it, they can just read the database.
Expand Down Expand Up @@ -214,7 +219,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, shouldPreserve func(header *types.Header) bool, txLookupLimit *uint64) (*BlockChain, error) {
func NewBlockChain(db ethdb.Database, genesis *Genesis, cacheConfig *CacheConfig, chainConfig *params.ChainConfig, engine consensus.Engine, vmConfig vm.Config, shouldPreserve func(header *types.Header) bool, txLookupLimit *uint64) (*BlockChain, error) {
if cacheConfig == nil {
cacheConfig = defaultCacheConfig
}
Expand All @@ -229,6 +234,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, chainConfig *par
chainConfig: chainConfig,
cacheConfig: cacheConfig,
db: db,
genesis: genesis,
triegc: prque.New(nil),
stateCache: state.NewDatabaseWithConfig(db, &trie.Config{
Cache: cacheConfig.TrieCleanLimit,
Expand Down Expand Up @@ -542,6 +548,17 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, root common.Hash, repair bo
}
}
if beyondRoot || newHeadBlock.NumberU64() == 0 {
// Recommit the genesis state into disk in case the rewinding destination
// is genesis. In the future this rewinding destination can be the earliest
// block stored in the chain if the historical chain pruning is enabled.
// In that case the logic needs to be improved here.
if newHeadBlock.NumberU64() == 0 {
if bc.genesis == nil {
log.Crit("Genesis is not existent, no complete state to rewind")
}
bc.genesis.ToBlock(bc.db)
log.Debug("Recommitted genesis state to disk")
}
log.Debug("Rewound to block with state", "number", newHeadBlock.NumberU64(), "hash", newHeadBlock.Hash())
break
}
Expand Down
14 changes: 8 additions & 6 deletions core/blockchain_repair_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1770,7 +1770,8 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {

// Initialize a fresh chain
var (
genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
gspec = &Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}
genesis = gspec.MustCommit(db)
engine = ethash.NewFullFaker()
config = &CacheConfig{
TrieCleanLimit: 256,
Expand All @@ -1784,7 +1785,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
config.SnapshotLimit = 256
config.SnapshotWait = true
}
chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
chain, err := NewBlockChain(db, gspec, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
if err != nil {
t.Fatalf("Failed to create chain: %v", err)
}
Expand Down Expand Up @@ -1837,7 +1838,7 @@ func testRepair(t *testing.T, tt *rewindTest, snapshots bool) {
}
defer db.Close()

newChain, err := NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
newChain, err := NewBlockChain(db, gspec, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
Expand Down Expand Up @@ -1898,7 +1899,8 @@ func TestIssue23496(t *testing.T) {

// Initialize a fresh chain
var (
genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
gspec = &Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}
genesis = gspec.MustCommit(db)
engine = ethash.NewFullFaker()
config = &CacheConfig{
TrieCleanLimit: 256,
Expand All @@ -1908,7 +1910,7 @@ func TestIssue23496(t *testing.T) {
SnapshotWait: true,
}
)
chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
chain, err := NewBlockChain(db, gspec, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
if err != nil {
t.Fatalf("Failed to create chain: %v", err)
}
Expand Down Expand Up @@ -1952,7 +1954,7 @@ func TestIssue23496(t *testing.T) {
}
defer db.Close()

chain, err = NewBlockChain(db, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
chain, err = NewBlockChain(db, gspec, nil, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
if err != nil {
t.Fatalf("Failed to recreate chain: %v", err)
}
Expand Down
5 changes: 3 additions & 2 deletions core/blockchain_sethead_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1969,7 +1969,8 @@ func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) {

// Initialize a fresh chain
var (
genesis = (&Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}).MustCommit(db)
gspec = &Genesis{BaseFee: big.NewInt(params.InitialBaseFee)}
genesis = gspec.MustCommit(db)
engine = ethash.NewFullFaker()
config = &CacheConfig{
TrieCleanLimit: 256,
Expand All @@ -1982,7 +1983,7 @@ func testSetHead(t *testing.T, tt *rewindTest, snapshots bool) {
config.SnapshotLimit = 256
config.SnapshotWait = true
}
chain, err := NewBlockChain(db, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
chain, err := NewBlockChain(db, gspec, config, params.AllEthashProtocolChanges, engine, vm.Config{}, nil, nil)
if err != nil {
t.Fatalf("Failed to create chain: %v", err)
}
Expand Down
Loading