Skip to content

Commit ec7eda1

Browse files
author
Darioush Jalali
committed
make backends configurable
1 parent e0fbaa5 commit ec7eda1

File tree

4 files changed

+103
-25
lines changed

4 files changed

+103
-25
lines changed

triedb/database.go

Lines changed: 33 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,14 @@ import (
2727
"github.com/ethereum/go-ethereum/trie/triestate"
2828
"github.com/ethereum/go-ethereum/triedb/database"
2929
"github.com/ethereum/go-ethereum/triedb/hashdb"
30-
"github.com/ethereum/go-ethereum/triedb/pathdb"
3130
)
3231

3332
// Config defines all necessary options for database.
3433
type Config struct {
35-
Preimages bool // Flag whether the preimage of node key is recorded
36-
IsVerkle bool // Flag whether the db is holding a verkle tree
37-
HashDB *hashdb.Config // Configs for hash-based scheme
38-
PathDB *pathdb.Config // Configs for experimental path-based scheme
34+
Preimages bool // Flag whether the preimage of node key is recorded
35+
IsVerkle bool // Flag whether the db is holding a verkle tree
36+
HashDB hashBackender // Configs for hash-based scheme
37+
PathDB pathBackender // Configs for experimental path-based scheme
3938
}
4039

4140
// HashDefaults represents a config for using hash-based scheme with
@@ -45,6 +44,15 @@ var HashDefaults = &Config{
4544
HashDB: hashdb.Defaults,
4645
}
4746

47+
type Backend backend
48+
49+
type hashBackender interface {
50+
New(diskdb ethdb.Database, resolver hashdb.ChildResolver) database.HashBackend
51+
}
52+
type pathBackender interface {
53+
New(diskdb ethdb.Database) database.PathBackend
54+
}
55+
4856
// backend defines the methods needed to access/update trie nodes in different
4957
// state scheme.
5058
type backend interface {
@@ -76,6 +84,10 @@ type backend interface {
7684

7785
// Close closes the trie database backend and releases all held resources.
7886
Close() error
87+
88+
// Reader returns a node reader associated with the specific state.
89+
// An error will be returned if the specified state is not available.
90+
Reader(stateRoot common.Hash) (database.Reader, error)
7991
}
8092

8193
// Database is the wrapper of the underlying backend which is shared by different
@@ -108,7 +120,7 @@ func NewDatabase(diskdb ethdb.Database, config *Config) *Database {
108120
log.Crit("Both 'hash' and 'path' mode are configured")
109121
}
110122
if config.PathDB != nil {
111-
db.backend = pathdb.New(diskdb, config.PathDB)
123+
db.backend = config.PathDB.New(diskdb)
112124
} else {
113125
var resolver hashdb.ChildResolver
114126
if config.IsVerkle {
@@ -117,21 +129,19 @@ func NewDatabase(diskdb ethdb.Database, config *Config) *Database {
117129
} else {
118130
resolver = trie.MerkleResolver{}
119131
}
120-
db.backend = hashdb.New(diskdb, config.HashDB, resolver)
132+
if config.HashDB == nil {
133+
// some tests don't set this yet pass a non-nil config
134+
config.HashDB = hashdb.Defaults
135+
}
136+
db.backend = config.HashDB.New(diskdb, resolver)
121137
}
122138
return db
123139
}
124140

125141
// Reader returns a reader for accessing all trie nodes with provided state root.
126142
// An error will be returned if the requested state is not available.
127143
func (db *Database) Reader(blockRoot common.Hash) (database.Reader, error) {
128-
switch b := db.backend.(type) {
129-
case *hashdb.Database:
130-
return b.Reader(blockRoot)
131-
case *pathdb.Database:
132-
return b.Reader(blockRoot)
133-
}
134-
return nil, errors.New("unknown backend")
144+
return db.backend.Reader(blockRoot)
135145
}
136146

137147
// Update performs a state transition by committing dirty nodes contained in the
@@ -221,7 +231,7 @@ func (db *Database) InsertPreimage(preimages map[common.Hash][]byte) {
221231
//
222232
// It's only supported by hash-based database and will return an error for others.
223233
func (db *Database) Cap(limit common.StorageSize) error {
224-
hdb, ok := db.backend.(*hashdb.Database)
234+
hdb, ok := db.backend.(database.HashBackend)
225235
if !ok {
226236
return errors.New("not supported")
227237
}
@@ -237,7 +247,7 @@ func (db *Database) Cap(limit common.StorageSize) error {
237247
//
238248
// It's only supported by hash-based database and will return an error for others.
239249
func (db *Database) Reference(root common.Hash, parent common.Hash) error {
240-
hdb, ok := db.backend.(*hashdb.Database)
250+
hdb, ok := db.backend.(database.HashBackend)
241251
if !ok {
242252
return errors.New("not supported")
243253
}
@@ -248,7 +258,7 @@ func (db *Database) Reference(root common.Hash, parent common.Hash) error {
248258
// Dereference removes an existing reference from a root node. It's only
249259
// supported by hash-based database and will return an error for others.
250260
func (db *Database) Dereference(root common.Hash) error {
251-
hdb, ok := db.backend.(*hashdb.Database)
261+
hdb, ok := db.backend.(database.HashBackend)
252262
if !ok {
253263
return errors.New("not supported")
254264
}
@@ -261,7 +271,7 @@ func (db *Database) Dereference(root common.Hash) error {
261271
// corresponding trie histories are existent. It's only supported by path-based
262272
// database and will return an error for others.
263273
func (db *Database) Recover(target common.Hash) error {
264-
pdb, ok := db.backend.(*pathdb.Database)
274+
pdb, ok := db.backend.(database.PathBackend)
265275
if !ok {
266276
return errors.New("not supported")
267277
}
@@ -279,7 +289,7 @@ func (db *Database) Recover(target common.Hash) error {
279289
// recovered. It's only supported by path-based database and will return an
280290
// error for others.
281291
func (db *Database) Recoverable(root common.Hash) (bool, error) {
282-
pdb, ok := db.backend.(*pathdb.Database)
292+
pdb, ok := db.backend.(database.PathBackend)
283293
if !ok {
284294
return false, errors.New("not supported")
285295
}
@@ -292,7 +302,7 @@ func (db *Database) Recoverable(root common.Hash) (bool, error) {
292302
//
293303
// It's only supported by path-based database and will return an error for others.
294304
func (db *Database) Disable() error {
295-
pdb, ok := db.backend.(*pathdb.Database)
305+
pdb, ok := db.backend.(database.PathBackend)
296306
if !ok {
297307
return errors.New("not supported")
298308
}
@@ -302,7 +312,7 @@ func (db *Database) Disable() error {
302312
// Enable activates database and resets the state tree with the provided persistent
303313
// state root once the state sync is finished.
304314
func (db *Database) Enable(root common.Hash) error {
305-
pdb, ok := db.backend.(*pathdb.Database)
315+
pdb, ok := db.backend.(database.PathBackend)
306316
if !ok {
307317
return errors.New("not supported")
308318
}
@@ -314,7 +324,7 @@ func (db *Database) Enable(root common.Hash) error {
314324
// flattening everything down (bad for reorgs). It's only supported by path-based
315325
// database and will return an error for others.
316326
func (db *Database) Journal(root common.Hash) error {
317-
pdb, ok := db.backend.(*pathdb.Database)
327+
pdb, ok := db.backend.(database.PathBackend)
318328
if !ok {
319329
return errors.New("not supported")
320330
}
@@ -325,7 +335,7 @@ func (db *Database) Journal(root common.Hash) error {
325335
// It's only supported by path-based database and will return an error for
326336
// others.
327337
func (db *Database) SetBufferSize(size int) error {
328-
pdb, ok := db.backend.(*pathdb.Database)
338+
pdb, ok := db.backend.(database.PathBackend)
329339
if !ok {
330340
return errors.New("not supported")
331341
}

triedb/database/database.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ package database
1818

1919
import (
2020
"github.com/ethereum/go-ethereum/common"
21+
"github.com/ethereum/go-ethereum/trie/trienode"
22+
"github.com/ethereum/go-ethereum/trie/triestate"
2123
)
2224

2325
// Reader wraps the Node method of a backing trie reader.
@@ -46,3 +48,59 @@ type Database interface {
4648
// An error will be returned if the specified state is not available.
4749
Reader(stateRoot common.Hash) (Reader, error)
4850
}
51+
52+
// Backend defines the methods needed to access/update trie nodes in different
53+
// state scheme.
54+
type Backend interface {
55+
// Scheme returns the identifier of used storage scheme.
56+
Scheme() string
57+
58+
// Initialized returns an indicator if the state data is already initialized
59+
// according to the state scheme.
60+
Initialized(genesisRoot common.Hash) bool
61+
62+
// Size returns the current storage size of the diff layers on top of the
63+
// disk layer and the storage size of the nodes cached in the disk layer.
64+
//
65+
// For hash scheme, there is no differentiation between diff layer nodes
66+
// and dirty disk layer nodes, so both are merged into the second return.
67+
Size() (common.StorageSize, common.StorageSize)
68+
69+
// Update performs a state transition by committing dirty nodes contained
70+
// in the given set in order to update state from the specified parent to
71+
// the specified root.
72+
//
73+
// The passed in maps(nodes, states) will be retained to avoid copying
74+
// everything. Therefore, these maps must not be changed afterwards.
75+
Update(root common.Hash, parent common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *triestate.Set) error
76+
77+
// Commit writes all relevant trie nodes belonging to the specified state
78+
// to disk. Report specifies whether logs will be displayed in info level.
79+
Commit(root common.Hash, report bool) error
80+
81+
// Close closes the trie database backend and releases all held resources.
82+
Close() error
83+
84+
// Reader returns a node reader associated with the specific state.
85+
// An error will be returned if the specified state is not available.
86+
Reader(stateRoot common.Hash) (Reader, error)
87+
}
88+
89+
type HashBackend interface {
90+
Backend
91+
92+
Cap(limit common.StorageSize) error
93+
Reference(root common.Hash, parent common.Hash)
94+
Dereference(root common.Hash)
95+
}
96+
97+
type PathBackend interface {
98+
Backend
99+
100+
Recover(root common.Hash, loader triestate.TrieLoader) error
101+
Recoverable(root common.Hash) bool
102+
Disable() error
103+
Enable(root common.Hash) error
104+
Journal(root common.Hash) error
105+
SetBufferSize(size int) error
106+
}

triedb/hashdb/database.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"github.com/ethereum/go-ethereum/rlp"
3434
"github.com/ethereum/go-ethereum/trie/trienode"
3535
"github.com/ethereum/go-ethereum/trie/triestate"
36+
"github.com/ethereum/go-ethereum/triedb/database"
3637
)
3738

3839
var (
@@ -79,6 +80,10 @@ var Defaults = &Config{
7980
CleanCacheSize: 0,
8081
}
8182

83+
func (c *Config) New(diskdb ethdb.Database, resolver ChildResolver) database.HashBackend {
84+
return New(diskdb, c, resolver)
85+
}
86+
8287
// Database is an intermediate write layer between the trie data structures and
8388
// the disk database. The aim is to accumulate trie writes in-memory and only
8489
// periodically flush a couple tries to disk, garbage collecting the remainder.
@@ -631,7 +636,7 @@ func (db *Database) Scheme() string {
631636

632637
// Reader retrieves a node reader belonging to the given state root.
633638
// An error will be returned if the requested state is not available.
634-
func (db *Database) Reader(root common.Hash) (*reader, error) {
639+
func (db *Database) Reader(root common.Hash) (database.Reader, error) {
635640
if _, err := db.node(root); err != nil {
636641
return nil, fmt.Errorf("state %#x is not available, %v", root, err)
637642
}

triedb/pathdb/database.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"github.com/ethereum/go-ethereum/params"
3232
"github.com/ethereum/go-ethereum/trie/trienode"
3333
"github.com/ethereum/go-ethereum/trie/triestate"
34+
"github.com/ethereum/go-ethereum/triedb/database"
3435
)
3536

3637
const (
@@ -92,6 +93,10 @@ type Config struct {
9293
ReadOnly bool // Flag whether the database is opened in read only mode.
9394
}
9495

96+
func (c *Config) New(diskdb ethdb.Database) database.PathBackend {
97+
return New(diskdb, c)
98+
}
99+
95100
// sanitize checks the provided user configurations and changes anything that's
96101
// unreasonable or unworkable.
97102
func (c *Config) sanitize() *Config {
@@ -208,7 +213,7 @@ func New(diskdb ethdb.Database, config *Config) *Database {
208213
}
209214

210215
// Reader retrieves a layer belonging to the given state root.
211-
func (db *Database) Reader(root common.Hash) (layer, error) {
216+
func (db *Database) Reader(root common.Hash) (database.Reader, error) {
212217
l := db.tree.get(root)
213218
if l == nil {
214219
return nil, fmt.Errorf("state %#x is not available", root)

0 commit comments

Comments
 (0)