Skip to content

Commit 7789060

Browse files
committed
refactor: reduce delta from main
1 parent 74dc312 commit 7789060

File tree

5 files changed

+123
-103
lines changed

5 files changed

+123
-103
lines changed

triedb/database.go

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,17 @@ import (
2727
"github.com/ava-labs/libevm/trie/triestate"
2828
"github.com/ava-labs/libevm/triedb/database"
2929
"github.com/ava-labs/libevm/triedb/hashdb"
30+
"github.com/ava-labs/libevm/triedb/pathdb"
3031
)
3132

3233
// Config defines all necessary options for database.
3334
type Config struct {
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
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
39+
40+
DBOverride BackendConstructor // Injects an arbitrary backend implementation
3841
}
3942

4043
// HashDefaults represents a config for using hash-based scheme with
@@ -44,15 +47,6 @@ var HashDefaults = &Config{
4447
HashDB: hashdb.Defaults,
4548
}
4649

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-
5650
// backend defines the methods needed to access/update trie nodes in different
5751
// state scheme.
5852
type backend interface {
@@ -84,10 +78,6 @@ type backend interface {
8478

8579
// Close closes the trie database backend and releases all held resources.
8680
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)
9181
}
9282

9383
// Database is the wrapper of the underlying backend which is shared by different
@@ -120,7 +110,7 @@ func NewDatabase(diskdb ethdb.Database, config *Config) *Database {
120110
log.Crit("Both 'hash' and 'path' mode are configured")
121111
}
122112
if config.PathDB != nil {
123-
db.backend = config.PathDB.New(diskdb)
113+
db.backend = pathdb.New(diskdb, config.PathDB)
124114
} else {
125115
var resolver hashdb.ChildResolver
126116
if config.IsVerkle {
@@ -129,19 +119,24 @@ func NewDatabase(diskdb ethdb.Database, config *Config) *Database {
129119
} else {
130120
resolver = trie.MerkleResolver{}
131121
}
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)
122+
db.backend = hashdb.New(diskdb, config.HashDB, resolver)
137123
}
124+
db.overrideBackend(diskdb, config)
138125
return db
139126
}
140127

141128
// Reader returns a reader for accessing all trie nodes with provided state root.
142129
// An error will be returned if the requested state is not available.
143130
func (db *Database) Reader(blockRoot common.Hash) (database.Reader, error) {
144-
return db.backend.Reader(blockRoot)
131+
switch b := db.backend.(type) {
132+
case ReaderProvider:
133+
return b.Reader(blockRoot)
134+
case *hashdb.Database:
135+
return b.Reader(blockRoot)
136+
case *pathdb.Database:
137+
return b.Reader(blockRoot)
138+
}
139+
return nil, errors.New("unknown backend")
145140
}
146141

147142
// Update performs a state transition by committing dirty nodes contained in the
@@ -231,7 +226,7 @@ func (db *Database) InsertPreimage(preimages map[common.Hash][]byte) {
231226
//
232227
// It's only supported by hash-based database and will return an error for others.
233228
func (db *Database) Cap(limit common.StorageSize) error {
234-
hdb, ok := db.backend.(database.HashBackend)
229+
hdb, ok := db.backend.(HashBackend)
235230
if !ok {
236231
return errors.New("not supported")
237232
}
@@ -247,7 +242,7 @@ func (db *Database) Cap(limit common.StorageSize) error {
247242
//
248243
// It's only supported by hash-based database and will return an error for others.
249244
func (db *Database) Reference(root common.Hash, parent common.Hash) error {
250-
hdb, ok := db.backend.(database.HashBackend)
245+
hdb, ok := db.backend.(HashBackend)
251246
if !ok {
252247
return errors.New("not supported")
253248
}
@@ -258,7 +253,7 @@ func (db *Database) Reference(root common.Hash, parent common.Hash) error {
258253
// Dereference removes an existing reference from a root node. It's only
259254
// supported by hash-based database and will return an error for others.
260255
func (db *Database) Dereference(root common.Hash) error {
261-
hdb, ok := db.backend.(database.HashBackend)
256+
hdb, ok := db.backend.(HashBackend)
262257
if !ok {
263258
return errors.New("not supported")
264259
}
@@ -271,7 +266,7 @@ func (db *Database) Dereference(root common.Hash) error {
271266
// corresponding trie histories are existent. It's only supported by path-based
272267
// database and will return an error for others.
273268
func (db *Database) Recover(target common.Hash) error {
274-
pdb, ok := db.backend.(database.PathBackend)
269+
pdb, ok := db.backend.(PathBackend)
275270
if !ok {
276271
return errors.New("not supported")
277272
}
@@ -289,7 +284,7 @@ func (db *Database) Recover(target common.Hash) error {
289284
// recovered. It's only supported by path-based database and will return an
290285
// error for others.
291286
func (db *Database) Recoverable(root common.Hash) (bool, error) {
292-
pdb, ok := db.backend.(database.PathBackend)
287+
pdb, ok := db.backend.(PathBackend)
293288
if !ok {
294289
return false, errors.New("not supported")
295290
}
@@ -302,7 +297,7 @@ func (db *Database) Recoverable(root common.Hash) (bool, error) {
302297
//
303298
// It's only supported by path-based database and will return an error for others.
304299
func (db *Database) Disable() error {
305-
pdb, ok := db.backend.(database.PathBackend)
300+
pdb, ok := db.backend.(PathBackend)
306301
if !ok {
307302
return errors.New("not supported")
308303
}
@@ -312,7 +307,7 @@ func (db *Database) Disable() error {
312307
// Enable activates database and resets the state tree with the provided persistent
313308
// state root once the state sync is finished.
314309
func (db *Database) Enable(root common.Hash) error {
315-
pdb, ok := db.backend.(database.PathBackend)
310+
pdb, ok := db.backend.(PathBackend)
316311
if !ok {
317312
return errors.New("not supported")
318313
}
@@ -324,7 +319,7 @@ func (db *Database) Enable(root common.Hash) error {
324319
// flattening everything down (bad for reorgs). It's only supported by path-based
325320
// database and will return an error for others.
326321
func (db *Database) Journal(root common.Hash) error {
327-
pdb, ok := db.backend.(database.PathBackend)
322+
pdb, ok := db.backend.(PathBackend)
328323
if !ok {
329324
return errors.New("not supported")
330325
}
@@ -335,7 +330,7 @@ func (db *Database) Journal(root common.Hash) error {
335330
// It's only supported by path-based database and will return an error for
336331
// others.
337332
func (db *Database) SetBufferSize(size int) error {
338-
pdb, ok := db.backend.(database.PathBackend)
333+
pdb, ok := db.backend.(PathBackend)
339334
if !ok {
340335
return errors.New("not supported")
341336
}

triedb/database.libevm.go

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
// Copyright 2024 the libevm authors.
2+
//
3+
// The libevm additions to go-ethereum are free software: you can redistribute
4+
// them and/or modify them under the terms of the GNU Lesser General Public License
5+
// as published by the Free Software Foundation, either version 3 of the License,
6+
// or (at your option) any later version.
7+
//
8+
// The libevm additions are distributed in the hope that they will be useful,
9+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
10+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
11+
// General Public License for more details.
12+
//
13+
// You should have received a copy of the GNU Lesser General Public License
14+
// along with the go-ethereum library. If not, see
15+
// <http://www.gnu.org/licenses/>.
16+
17+
package triedb
18+
19+
import (
20+
"github.com/ava-labs/libevm/common"
21+
"github.com/ava-labs/libevm/ethdb"
22+
"github.com/ava-labs/libevm/log"
23+
"github.com/ava-labs/libevm/trie/triestate"
24+
"github.com/ava-labs/libevm/triedb/database"
25+
"github.com/ava-labs/libevm/triedb/hashdb"
26+
"github.com/ava-labs/libevm/triedb/pathdb"
27+
)
28+
29+
// Backend defines the intersection of methods shared by [hashdb.Database] and
30+
// [pathdb.Database].
31+
type Backend backend
32+
33+
// A ReaderProvider exposes its underlying Reader as an interface. Both
34+
// [hashdb.Database] and [pathdb.Database] return concrete types so Go's lack of
35+
// support for [covariant types] means that this method can't be defined on
36+
// [Backend].
37+
//
38+
// [covariant types]: https://go.dev/doc/faq#covariant_types
39+
type ReaderProvider interface {
40+
Reader(common.Hash) (database.Reader, error)
41+
}
42+
43+
// A BackendConstructor constructs alternative backend implements. The returned
44+
// type MUST be either a [HashBackend] or a [PathBackend].
45+
type BackendConstructor func(ethdb.Database, *Config) interface {
46+
Backend
47+
ReaderProvider
48+
}
49+
50+
func (db *Database) overrideBackend(diskdb ethdb.Database, config *Config) {
51+
if config.DBOverride == nil {
52+
return
53+
}
54+
if config.HashDB != nil || config.PathDB != nil {
55+
log.Crit("Database override provided when 'hash' or 'path' mode are configured")
56+
}
57+
db.backend.Close() //nolint:gsec // geth defaults to hashdb instances, which always return nil from Close()
58+
59+
db.backend = config.DBOverride(diskdb, config)
60+
switch db.backend.(type) {
61+
case HashBackend:
62+
case PathBackend:
63+
default:
64+
log.Crit("Database override is neither hash- nor path-based")
65+
}
66+
}
67+
68+
var (
69+
// If either of these break then the respective interface SHOULD be updated.
70+
_ HashBackend = (*hashdb.Database)(nil)
71+
_ PathBackend = (*pathdb.Database)(nil)
72+
)
73+
74+
// A HashBackend mirrors the functionality of a [hashdb.Database].
75+
type HashBackend interface {
76+
Backend
77+
78+
Cap(limit common.StorageSize) error
79+
Reference(root common.Hash, parent common.Hash)
80+
Dereference(root common.Hash)
81+
}
82+
83+
// A PathBackend mirrors the functionality of a [pathdb.Database].
84+
type PathBackend interface {
85+
Backend
86+
87+
Recover(root common.Hash, loader triestate.TrieLoader) error
88+
Recoverable(root common.Hash) bool
89+
Disable() error
90+
Enable(root common.Hash) error
91+
Journal(root common.Hash) error
92+
SetBufferSize(size int) error
93+
}

triedb/database/database.go

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

1919
import (
2020
"github.com/ava-labs/libevm/common"
21-
"github.com/ava-labs/libevm/trie/trienode"
22-
"github.com/ava-labs/libevm/trie/triestate"
2321
)
2422

2523
// Reader wraps the Node method of a backing trie reader.
@@ -48,59 +46,3 @@ type Database interface {
4846
// An error will be returned if the specified state is not available.
4947
Reader(stateRoot common.Hash) (Reader, error)
5048
}
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: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import (
3333
"github.com/ava-labs/libevm/rlp"
3434
"github.com/ava-labs/libevm/trie/trienode"
3535
"github.com/ava-labs/libevm/trie/triestate"
36-
"github.com/ava-labs/libevm/triedb/database"
3736
)
3837

3938
var (
@@ -80,10 +79,6 @@ var Defaults = &Config{
8079
CleanCacheSize: 0,
8180
}
8281

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

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

triedb/pathdb/database.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
"github.com/ava-labs/libevm/params"
3232
"github.com/ava-labs/libevm/trie/trienode"
3333
"github.com/ava-labs/libevm/trie/triestate"
34-
"github.com/ava-labs/libevm/triedb/database"
3534
)
3635

3736
const (
@@ -93,10 +92,6 @@ type Config struct {
9392
ReadOnly bool // Flag whether the database is opened in read only mode.
9493
}
9594

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

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

0 commit comments

Comments
 (0)