@@ -48,8 +48,12 @@ const (
4848 logFileName = "firewood.log"
4949)
5050
51- var _ triedb.DBOverride = (* Database )(nil )
51+ var (
52+ _ triedb.DBConstructor = Config {}.BackendConstructor
53+ _ triedb.DBOverride = (* Database )(nil )
54+ )
5255
56+ // A Database is an implementation of [triedb.DBOverride].
5357type Database struct {
5458 // The underlying Firewood database, used for storing proposals and revisions.
5559 // This must be exported so other packages (e.g. state sync) can access firewood-specific methods.
@@ -93,8 +97,8 @@ type proposalMeta struct {
9397
9498type Config struct {
9599 ChainDir string
96- CleanCacheSize int // Size of the clean cache in bytes
97- FreeListCacheEntries uint // Number of free list entries to cache
100+ CleanCacheSize int
101+ FreeListCacheEntries uint
98102 Revisions uint
99103 ReadCacheStrategy ffi.CacheStrategy
100104}
@@ -118,11 +122,10 @@ func (c Config) BackendConstructor(ethdb.Database) triedb.DBOverride {
118122// New creates a new Firewood database with the given disk database and configuration.
119123// Any error during creation will cause the program to exit.
120124func New (config Config ) (* Database , error ) {
121- if err := validatePath (config .ChainDir ); err != nil {
125+ if err := validateDir (config .ChainDir ); err != nil {
122126 return nil , err
123127 }
124128
125- // Start the logs prior to opening the database
126129 logPath := filepath .Join (config .ChainDir , logFileName )
127130 if err := ffi .StartLogs (& ffi.LogConfig {Path : logPath }); err != nil {
128131 // This shouldn't be a fatal error, as this can only be called once per thread.
@@ -132,7 +135,7 @@ func New(config Config) (*Database, error) {
132135
133136 dbPath := filepath .Join (config .ChainDir , dbFileName )
134137 fw , err := ffi .New (dbPath , & ffi.Config {
135- NodeCacheEntries : uint (config .CleanCacheSize ) / 256 , // TODO: estimate 256 bytes per node
138+ NodeCacheEntries : uint (config .CleanCacheSize ) / 256 , // TODO(alarso16): 256 bytes may not be accurate
136139 FreeListCacheEntries : config .FreeListCacheEntries ,
137140 Revisions : config .Revisions ,
138141 ReadCacheStrategy : config .ReadCacheStrategy ,
@@ -143,6 +146,9 @@ func New(config Config) (*Database, error) {
143146
144147 currentRoot , err := fw .Root ()
145148 if err != nil {
149+ if closeErr := fw .Close (context .Background ()); closeErr != nil {
150+ return nil , fmt .Errorf ("%w: error while closing: %w" , err , closeErr )
151+ }
146152 return nil , err
147153 }
148154
@@ -162,23 +168,22 @@ func New(config Config) (*Database, error) {
162168 }, nil
163169}
164170
165- func validatePath (dir string ) error {
171+ func validateDir (dir string ) error {
166172 if dir == "" {
167173 return errors .New ("chain data directory must be set" )
168174 }
169175
170- // Check that the directory exists
171176 switch info , err := os .Stat (dir ); {
172177 case os .IsNotExist (err ):
173178 log .Info ("Database directory not found, creating" , "path" , dir )
174179 if err := os .MkdirAll (dir , 0o755 ); err != nil {
175- return fmt .Errorf ("error creating database directory: %w " , err )
180+ return fmt .Errorf ("creating database directory: %v " , err )
176181 }
177182 return nil
178183 case err != nil :
179- return fmt .Errorf ("error checking database directory: %w " , err )
184+ return fmt .Errorf ("os.Stat() on database directory: %v " , err )
180185 case ! info .IsDir ():
181- return fmt .Errorf ("database directory path is not a directory: %s " , dir )
186+ return fmt .Errorf ("database directory path is not a directory: %q " , dir )
182187 }
183188
184189 return nil
@@ -197,14 +202,15 @@ func (*Database) Scheme() string {
197202
198203// Initialized checks whether a non-empty genesis block has been written.
199204func (db * Database ) Initialized (common.Hash ) bool {
200- rootBytes , err := db .Firewood .Root ()
205+ root , err := db .Firewood .Root ()
201206 if err != nil {
202207 log .Error ("firewood: error getting current root" , "error" , err )
203208 return false
204209 }
205- root := common .BytesToHash (rootBytes )
206- // If the current root isn't empty, then unless the database is empty, we have a genesis block recorded.
207- return root != types .EmptyRootHash
210+
211+ // If the current root isn't empty, then unless the genesis block is empty,
212+ // the database is initialized.
213+ return ! bytes .Equal (root , types .EmptyRootHash [:])
208214}
209215
210216// Size returns the storage size of diff layer nodes above the persistent disk
@@ -216,11 +222,9 @@ func (*Database) Size() (common.StorageSize, common.StorageSize) {
216222 return 0 , 0
217223}
218224
219- // This isn't called anywhere in coreth
220225func (* Database ) Reference (common.Hash , common.Hash ) {}
221226
222- // Dereference drops a proposal from the database.
223- // This function is no-op because unused proposals are dereferenced when no longer valid.
227+ // Dereference is no-op because unused proposals are dereferenced when no longer valid.
224228// We cannot dereference at this call. Consider the following case:
225229// Chain 1 has root A and root C
226230// Chain 2 has root B and root C
@@ -229,7 +233,7 @@ func (*Database) Reference(common.Hash, common.Hash) {}
229233// Thus, we recognize the single root C as the only proposal, and dereference it.
230234func (* Database ) Dereference (common.Hash ) {}
231235
232- // Firewood does not support this .
236+ // Cap is a no-op because it isn't supported by Firewood .
233237func (* Database ) Cap (common.StorageSize ) error {
234238 return nil
235239}
0 commit comments