Skip to content

Commit 6cf5169

Browse files
committed
feat: add version scheme for startup
1 parent 7f3aac3 commit 6cf5169

File tree

4 files changed

+55
-44
lines changed

4 files changed

+55
-44
lines changed

cmd/utils/flags.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,7 @@ var (
353353
}
354354
StateSchemeFlag = &cli.StringFlag{
355355
Name: "state.scheme",
356-
Usage: "Scheme to use for storing ethereum state ('hash' or 'path')",
356+
Usage: "Scheme to use for storing ethereum state ('hash', 'path', 'version')",
357357
Category: flags.StateCategory,
358358
}
359359
PathDBSyncFlag = &cli.BoolFlag{
@@ -1953,11 +1953,16 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) {
19531953
if ctx.IsSet(StateHistoryFlag.Name) {
19541954
cfg.StateHistory = ctx.Uint64(StateHistoryFlag.Name)
19551955
}
1956-
scheme, err := ParseCLIAndConfigStateScheme(ctx.String(StateSchemeFlag.Name), cfg.StateScheme)
1957-
if err != nil {
1958-
Fatalf("%v", err)
1956+
if ctx.String(StateSchemeFlag.Name) != rawdb.VersionScheme {
1957+
scheme, err := ParseCLIAndConfigStateScheme(ctx.String(StateSchemeFlag.Name), cfg.StateScheme)
1958+
if err != nil {
1959+
Fatalf("%v", err)
1960+
}
1961+
cfg.StateScheme = scheme
1962+
} else {
1963+
cfg.StateScheme = rawdb.VersionScheme
19591964
}
1960-
cfg.StateScheme = scheme
1965+
19611966
// Parse transaction history flag, if user is still using legacy config
19621967
// file with 'TxLookupLimit' configured, copy the value to 'TransactionHistory'.
19631968
if cfg.TransactionHistory == ethconfig.Defaults.TransactionHistory && cfg.TxLookupLimit != ethconfig.Defaults.TxLookupLimit {

core/blockchain.go

Lines changed: 43 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,6 +1169,9 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha
11691169
// SnapSyncCommitHead sets the current head block to the one defined by the hash
11701170
// irrelevant what the chain contents were prior.
11711171
func (bc *BlockChain) SnapSyncCommitHead(hash common.Hash) error {
1172+
if bc.triedb.Scheme() == rawdb.VersionScheme {
1173+
panic("version db not support snap sync")
1174+
}
11721175
// Make sure that both the block as well at its state trie exists
11731176
block := bc.GetBlockByHash(hash)
11741177
if block == nil {
@@ -1380,48 +1383,50 @@ func (bc *BlockChain) Stop() {
13801383
}
13811384
bc.snaps.Release()
13821385
}
1383-
if bc.triedb.Scheme() == rawdb.PathScheme {
1384-
// Ensure that the in-memory trie nodes are journaled to disk properly.
1385-
if err := bc.triedb.Journal(bc.CurrentBlock().Root); err != nil {
1386-
log.Info("Failed to journal in-memory trie nodes", "err", err)
1387-
}
1388-
} else {
1389-
// Ensure the state of a recent block is also stored to disk before exiting.
1390-
// We're writing three different states to catch different restart scenarios:
1391-
// - HEAD: So we don't need to reprocess any blocks in the general case
1392-
// - HEAD-1: So we don't do large reorgs if our HEAD becomes an uncle
1393-
// - HEAD-127: So we have a hard limit on the number of blocks reexecuted
1394-
if !bc.cacheConfig.TrieDirtyDisabled {
1395-
triedb := bc.triedb
1396-
var once sync.Once
1397-
for _, offset := range []uint64{0, 1, TriesInMemory - 1} {
1398-
if number := bc.CurrentBlock().Number.Uint64(); number > offset {
1399-
recent := bc.GetBlockByNumber(number - offset)
1400-
log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
1401-
if err := triedb.Commit(recent.Root(), true); err != nil {
1386+
if bc.triedb.Scheme() != rawdb.VersionScheme {
1387+
if bc.triedb.Scheme() == rawdb.PathScheme {
1388+
// Ensure that the in-memory trie nodes are journaled to disk properly.
1389+
if err := bc.triedb.Journal(bc.CurrentBlock().Root); err != nil {
1390+
log.Info("Failed to journal in-memory trie nodes", "err", err)
1391+
}
1392+
} else {
1393+
// Ensure the state of a recent block is also stored to disk before exiting.
1394+
// We're writing three different states to catch different restart scenarios:
1395+
// - HEAD: So we don't need to reprocess any blocks in the general case
1396+
// - HEAD-1: So we don't do large reorgs if our HEAD becomes an uncle
1397+
// - HEAD-127: So we have a hard limit on the number of blocks reexecuted
1398+
if !bc.cacheConfig.TrieDirtyDisabled {
1399+
triedb := bc.triedb
1400+
var once sync.Once
1401+
for _, offset := range []uint64{0, 1, TriesInMemory - 1} {
1402+
if number := bc.CurrentBlock().Number.Uint64(); number > offset {
1403+
recent := bc.GetBlockByNumber(number - offset)
1404+
log.Info("Writing cached state to disk", "block", recent.Number(), "hash", recent.Hash(), "root", recent.Root())
1405+
if err := triedb.Commit(recent.Root(), true); err != nil {
1406+
log.Error("Failed to commit recent state trie", "err", err)
1407+
} else {
1408+
rawdb.WriteSafePointBlockNumber(bc.db, recent.NumberU64())
1409+
once.Do(func() {
1410+
rawdb.WriteHeadBlockHash(bc.db.BlockStore(), recent.Hash())
1411+
})
1412+
}
1413+
}
1414+
}
1415+
1416+
if snapBase != (common.Hash{}) {
1417+
log.Info("Writing snapshot state to disk", "root", snapBase)
1418+
if err := triedb.Commit(snapBase, true); err != nil {
14021419
log.Error("Failed to commit recent state trie", "err", err)
14031420
} else {
1404-
rawdb.WriteSafePointBlockNumber(bc.db, recent.NumberU64())
1405-
once.Do(func() {
1406-
rawdb.WriteHeadBlockHash(bc.db.BlockStore(), recent.Hash())
1407-
})
1421+
rawdb.WriteSafePointBlockNumber(bc.db, bc.CurrentBlock().Number.Uint64())
14081422
}
14091423
}
1410-
}
1411-
1412-
if snapBase != (common.Hash{}) {
1413-
log.Info("Writing snapshot state to disk", "root", snapBase)
1414-
if err := triedb.Commit(snapBase, true); err != nil {
1415-
log.Error("Failed to commit recent state trie", "err", err)
1416-
} else {
1417-
rawdb.WriteSafePointBlockNumber(bc.db, bc.CurrentBlock().Number.Uint64())
1424+
for !bc.triegc.Empty() {
1425+
triedb.Dereference(bc.triegc.PopItem())
1426+
}
1427+
if _, size, _, _ := triedb.Size(); size != 0 {
1428+
log.Error("Dangling trie nodes after full cleanup")
14181429
}
1419-
}
1420-
for !bc.triegc.Empty() {
1421-
triedb.Dereference(bc.triegc.PopItem())
1422-
}
1423-
if _, size, _, _ := triedb.Size(); size != 0 {
1424-
log.Error("Dangling trie nodes after full cleanup")
14251430
}
14261431
}
14271432
}
@@ -1817,7 +1822,7 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types.
18171822

18181823
// If node is running in path mode, skip explicit gc operation
18191824
// which is unnecessary in this mode.
1820-
if bc.triedb.Scheme() == rawdb.PathScheme {
1825+
if bc.triedb.Scheme() != rawdb.HashScheme {
18211826
return nil
18221827
}
18231828

core/rawdb/accessors_trie.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ func ReadStateScheme(db ethdb.Reader) string {
316316
// ValidateStateScheme used to check state scheme whether is valid.
317317
// Valid state scheme: hash and path.
318318
func ValidateStateScheme(stateScheme string) bool {
319-
if stateScheme == HashScheme || stateScheme == PathScheme {
319+
if stateScheme == HashScheme || stateScheme == PathScheme || stateScheme == VersionScheme {
320320
return true
321321
}
322322
return false

core/state/statedb.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ func New(root common.Hash, db Database, snaps *snapshot.Tree) (*StateDB, error)
175175
if db.Scheme() == rawdb.VersionScheme && snaps != nil {
176176
panic("statedb snapshot must be nil in version db.")
177177
}
178+
log.Info("new statedb with type", "scheme", db.Scheme())
178179
// clean up previous traces
179180
db.Reset()
180181

0 commit comments

Comments
 (0)