Skip to content

Commit

Permalink
refactor: support statestore reader
Browse files Browse the repository at this point in the history
  • Loading branch information
flywukong committed Mar 6, 2024
1 parent 79acc1d commit a44dc79
Show file tree
Hide file tree
Showing 11 changed files with 41 additions and 62 deletions.
2 changes: 1 addition & 1 deletion cmd/geth/chaincmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ func initGenesis(ctx *cli.Context) error {

// if the trie data dir has been set, new trie db with a new state database
if ctx.IsSet(utils.SeparateDBFlag.Name) {
statediskdb, dbErr := stack.OpenDatabaseWithFreezer(name, 0, 0, "", "", false, false, false, false, true)
statediskdb, dbErr := stack.OpenDatabaseWithFreezer(name+"/state", 0, 0, "", "", false, false, false, false, true)
if dbErr != nil {
utils.Fatalf("Failed to open separate trie database: %v", dbErr)
}
Expand Down
7 changes: 1 addition & 6 deletions cmd/geth/dbcmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -420,12 +420,7 @@ func inspectTrie(ctx *cli.Context) error {
}
fmt.Printf("ReadBlockHeader, root: %v, blocknum: %v\n", trieRootHash, blockNumber)

var dbScheme string
if db.StateStore() != nil {
dbScheme = rawdb.ReadStateSchemeByStateDB(db, db.StateStore())
} else {
dbScheme = rawdb.ReadStateScheme(db)
}
dbScheme := rawdb.ReadStateScheme(db)
var config *trie.Config
if dbScheme == rawdb.PathScheme {
config = &trie.Config{
Expand Down
10 changes: 2 additions & 8 deletions cmd/geth/snapshot.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,14 +441,8 @@ func pruneState(ctx *cli.Context) error {
BloomSize: ctx.Uint64(utils.BloomFilterSizeFlag.Name),
}

if chaindb.StateStore() != nil {
if rawdb.ReadStateSchemeByStateDB(chaindb, chaindb.StateStore()) != rawdb.HashScheme {
log.Crit("Offline pruning is not required for path scheme")
}
} else {
if rawdb.ReadStateScheme(chaindb) != rawdb.HashScheme {
log.Crit("Offline pruning is not required for path scheme")
}
if rawdb.ReadStateScheme(chaindb) != rawdb.HashScheme {
log.Crit("Offline pruning is not required for path scheme")
}

pruner, err := pruner.NewPruner(chaindb, prunerconfig, ctx.Uint64(utils.TriesInMemoryFlag.Name))
Expand Down
35 changes: 4 additions & 31 deletions core/rawdb/accessors_trie.go
Original file line number Diff line number Diff line change
Expand Up @@ -288,13 +288,13 @@ func DeleteTrieNode(db ethdb.KeyValueWriter, owner common.Hash, path []byte, has
// if the state is not present in database.
func ReadStateScheme(db ethdb.Reader) string {
// Check if state in path-based scheme is present
blob, _ := ReadAccountTrieNode(db, nil)
blob, _ := ReadAccountTrieNode(db.StateStoreReader(), nil)
if len(blob) != 0 {
return PathScheme
}
// The root node might be deleted during the initial snap sync, check
// the persistent state id then.
if id := ReadPersistentStateID(db); id != 0 {
if id := ReadPersistentStateID(db.StateStoreReader()); id != 0 {
return PathScheme
}
// In a hash-based scheme, the genesis state is consistently stored
Expand All @@ -304,29 +304,7 @@ func ReadStateScheme(db ethdb.Reader) string {
if header == nil {
return "" // empty datadir
}
blob = ReadLegacyTrieNode(db, header.Root)
if len(blob) == 0 {
return "" // no state in disk
}
return HashScheme
}

// ReadStateSchemeByStateDB reads the state scheme of persistent state from state disk db, or none
// if the state is not present in database
func ReadStateSchemeByStateDB(db, statediskdb ethdb.Reader) string {
// Check if state in path-based scheme is present
blob, _ := ReadAccountTrieNode(statediskdb, nil)
if len(blob) != 0 {
return PathScheme
}
// In a hash-based scheme, the genesis state is consistently stored
// on the disk. To assess the scheme of the persistent state, it
// suffices to inspect the scheme of the genesis state.
header := ReadHeader(db, ReadCanonicalHash(db, 0), 0)
if header == nil {
return "" // empty datadir
}
blob = ReadLegacyTrieNode(statediskdb, header.Root)
blob = ReadLegacyTrieNode(db.StateStoreReader(), header.Root)
if len(blob) == 0 {
return "" // no state in disk
}
Expand Down Expand Up @@ -357,12 +335,7 @@ func ParseStateScheme(provided string, disk ethdb.Database) (string, error) {
// If state scheme is not specified, use the scheme consistent
// with persistent state, or fallback to hash mode if database
// is empty.
var stored string
if disk != nil && disk.StateStore() != nil {
stored = ReadStateSchemeByStateDB(disk, disk.StateStore())
} else {
stored = ReadStateScheme(disk)
}
stored := ReadStateScheme(disk)
if provided == "" {
if stored == "" {
// use default scheme for empty database, flip it when
Expand Down
3 changes: 2 additions & 1 deletion core/rawdb/ancient_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,8 @@ func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) {
infos = append(infos, info)

case StateFreezerName:
if ReadStateScheme(db) != PathScheme {
if

Check failure on line 94 in core/rawdb/ancient_utils.go

View workflow job for this annotation

GitHub Actions / golang-lint (1.21.x, ubuntu-latest)

File is not `goimports`-ed (goimports)
ReadStateScheme(db) != PathScheme {
continue
}
datadir, err := db.AncientDatadir()
Expand Down
14 changes: 14 additions & 0 deletions core/rawdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ type freezerdb struct {
stateStore ethdb.Database
}

func (frdb *freezerdb) StateStoreReader() ethdb.Reader {
if frdb.stateStore == nil {
return frdb
}
return frdb.stateStore
}

// AncientDatadir returns the path of root ancient directory.
func (frdb *freezerdb) AncientDatadir() (string, error) {
return frdb.ancientRoot, nil
Expand Down Expand Up @@ -196,6 +203,13 @@ func (db *nofreezedb) SetStateStore(state ethdb.Database) {
db.stateStore = state
}

func (db *nofreezedb) StateStoreReader() ethdb.Reader {
if db.stateStore != nil {
return db.stateStore
}
return db
}

func (db *nofreezedb) ReadAncients(fn func(reader ethdb.AncientReaderOp) error) (err error) {
// Unlike other ancient-related methods, this method does not return
// errNotSupported when invoked.
Expand Down
4 changes: 4 additions & 0 deletions core/rawdb/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,10 @@ func (t *table) SetStateStore(state ethdb.Database) {
panic("not implement")
}

func (t *table) StateStoreReader() ethdb.Reader {
return nil
}

// NewBatchWithSize creates a write-only database batch with pre-allocated buffer.
func (t *table) NewBatchWithSize(size int) ethdb.Batch {
return &tableBatch{t.db.NewBatchWithSize(size), t.prefix}
Expand Down
5 changes: 5 additions & 0 deletions ethdb/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,11 +155,16 @@ type AncientStater interface {
AncientDatadir() (string, error)
}

type StateStoreReader interface {
StateStoreReader() Reader
}

// Reader contains the methods required to read data from both key-value as well as
// immutable ancient data.
type Reader interface {
KeyValueReader
AncientReader
StateStoreReader
}

// Writer contains the methods required to write data to both key-value as well as
Expand Down
4 changes: 4 additions & 0 deletions ethdb/remotedb/remotedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ func (db *Database) SetStateStore(state ethdb.Database) {
panic("not supported")
}

func (db *Database) StateStoreReader() ethdb.Reader {
return db
}

func (db *Database) ReadAncients(fn func(op ethdb.AncientReaderOp) error) (err error) {
return fn(db)
}
Expand Down
14 changes: 3 additions & 11 deletions node/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -789,7 +789,7 @@ func (n *Node) OpenAndMergeDatabase(name string, cache, handles int, freezer, di
// Open the separated state database if the state directory exists
if n.HasSeparateTrieDir() {
// Allocate half of the handles and cache to this separate state data database
statediskdb, err = n.OpenDatabaseWithFreezer(name, cache/2, chainDataHandles/2, "", "eth/db/statedata/", readonly, false, false, pruneAncientData, true)
statediskdb, err = n.OpenDatabaseWithFreezer(name+"/state", cache/2, chainDataHandles/2, "", "eth/db/statedata/", readonly, false, false, pruneAncientData, true)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -838,18 +838,10 @@ func (n *Node) OpenDatabaseWithFreezer(name string, cache, handles int, ancient,
}
db = rawdb.NewMemoryDatabase()
} else {
var dirName, ancientDirName string
if isSeparateStateDB {
dirName = filepath.Join(n.ResolvePath(name), "state")
ancientDirName = filepath.Join(dirName, "ancient")
} else {
dirName = n.ResolvePath(name)
ancientDirName = n.ResolveAncient(name, ancient)
}
db, err = rawdb.Open(rawdb.OpenOptions{
Type: n.config.DBEngine,
Directory: dirName,
AncientsDirectory: ancientDirName,
Directory: n.ResolvePath(name),
AncientsDirectory: n.ResolveAncient(name, ancient),
Namespace: namespace,
Cache: cache,
Handles: handles,
Expand Down
5 changes: 1 addition & 4 deletions trie/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,13 @@ type Database struct {
// the legacy hash-based scheme is used by default.
func NewDatabase(diskdb ethdb.Database, config *Config) *Database {
// Sanitize the config and use the default one if it's not specified.
var dbScheme string
var triediskdb ethdb.Database
if diskdb != nil && diskdb.StateStore() != nil {
dbScheme = rawdb.ReadStateSchemeByStateDB(diskdb, diskdb.StateStore())
triediskdb = diskdb.StateStore()
} else {
dbScheme = rawdb.ReadStateScheme(diskdb)
triediskdb = diskdb
}

dbScheme := rawdb.ReadStateScheme(diskdb)
if config == nil {
if dbScheme == rawdb.PathScheme {
config = &Config{
Expand Down

0 comments on commit a44dc79

Please sign in to comment.