Skip to content
This repository was archived by the owner on Nov 25, 2025. It is now read-only.

Commit 43080d2

Browse files
authored
chore(core/rawdb): InspectDatabase uses libevm (8) (#791)
- Part of the core/rawdb migration to use libevm - Using libevm `InspectDatabase` - Define options passed to libevm `InspectDatabase`
1 parent a4abc14 commit 43080d2

File tree

2 files changed

+53
-181
lines changed

2 files changed

+53
-181
lines changed

core/rawdb/database.go

Lines changed: 52 additions & 180 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,14 @@ import (
3131
"fmt"
3232
"os"
3333
"path/filepath"
34-
"time"
3534

3635
"github.com/ava-labs/libevm/common"
36+
ethrawdb "github.com/ava-labs/libevm/core/rawdb"
3737
"github.com/ava-labs/libevm/ethdb"
3838
"github.com/ava-labs/libevm/ethdb/leveldb"
3939
"github.com/ava-labs/libevm/ethdb/memorydb"
4040
"github.com/ava-labs/libevm/ethdb/pebble"
4141
"github.com/ava-labs/libevm/log"
42-
"github.com/olekukonko/tablewriter"
4342
)
4443

4544
// nofreezedb is a database wrapper that disables freezer data retrievals.
@@ -242,192 +241,65 @@ func Open(o OpenOptions) (ethdb.Database, error) {
242241
return kvdb, nil
243242
}
244243

245-
type counter uint64
246-
247-
func (c counter) String() string {
248-
return fmt.Sprintf("%d", c)
249-
}
250-
251-
func (c counter) Percentage(current uint64) string {
252-
return fmt.Sprintf("%d", current*100/uint64(c))
253-
}
254-
255-
// stat stores sizes and count for a parameter
256-
type stat struct {
257-
size common.StorageSize
258-
count counter
259-
}
260-
261-
// Add size to the stat and increase the counter by 1
262-
func (s *stat) Add(size common.StorageSize) {
263-
s.size += size
264-
s.count++
265-
}
266-
267-
func (s *stat) Size() string {
268-
return s.size.String()
269-
}
270-
271-
func (s *stat) Count() string {
272-
return s.count.String()
273-
}
274-
275244
// InspectDatabase traverses the entire database and checks the size
276245
// of all different categories of data.
277246
func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error {
278-
it := db.NewIterator(keyPrefix, keyStart)
279-
defer it.Release()
280-
281247
var (
282-
count int64
283-
start = time.Now()
284-
logged = time.Now()
285-
286-
// Key-value store statistics
287-
headers stat
288-
bodies stat
289-
receipts stat
290-
numHashPairings stat
291-
hashNumPairings stat
292-
legacyTries stat
293-
stateLookups stat
294-
accountTries stat
295-
storageTries stat
296-
codes stat
297-
txLookups stat
298-
accountSnaps stat
299-
storageSnaps stat
300-
preimages stat
301-
bloomBits stat
302-
cliqueSnaps stat
303-
304-
// State sync statistics
305-
codeToFetch stat
306-
syncProgress stat
307-
syncSegments stat
308-
syncPerformed stat
309-
310-
// Les statistic
311-
chtTrieNodes stat
312-
bloomTrieNodes stat
313-
314-
// Meta- and unaccounted data
315-
metadata stat
316-
unaccounted stat
317-
318-
// Totals
319-
total common.StorageSize
248+
codeToFetch ethrawdb.DatabaseStat
249+
syncPerformed ethrawdb.DatabaseStat
250+
syncProgress ethrawdb.DatabaseStat
251+
syncSegments ethrawdb.DatabaseStat
320252
)
321-
// Inspect key-value database first.
322-
for it.Next() {
323-
var (
324-
key = it.Key()
325-
size = common.StorageSize(len(key) + len(it.Value()))
326-
)
327-
total += size
328-
switch {
329-
case bytes.HasPrefix(key, headerPrefix) && len(key) == (len(headerPrefix)+8+common.HashLength):
330-
headers.Add(size)
331-
case bytes.HasPrefix(key, blockBodyPrefix) && len(key) == (len(blockBodyPrefix)+8+common.HashLength):
332-
bodies.Add(size)
333-
case bytes.HasPrefix(key, blockReceiptsPrefix) && len(key) == (len(blockReceiptsPrefix)+8+common.HashLength):
334-
receipts.Add(size)
335-
case bytes.HasPrefix(key, headerPrefix) && bytes.HasSuffix(key, headerHashSuffix):
336-
numHashPairings.Add(size)
337-
case bytes.HasPrefix(key, headerNumberPrefix) && len(key) == (len(headerNumberPrefix)+common.HashLength):
338-
hashNumPairings.Add(size)
339-
case IsLegacyTrieNode(key, it.Value()):
340-
legacyTries.Add(size)
341-
case bytes.HasPrefix(key, stateIDPrefix) && len(key) == len(stateIDPrefix)+common.HashLength:
342-
stateLookups.Add(size)
343-
case IsAccountTrieNode(key):
344-
accountTries.Add(size)
345-
case IsStorageTrieNode(key):
346-
storageTries.Add(size)
347-
case bytes.HasPrefix(key, CodePrefix) && len(key) == len(CodePrefix)+common.HashLength:
348-
codes.Add(size)
349-
case bytes.HasPrefix(key, txLookupPrefix) && len(key) == (len(txLookupPrefix)+common.HashLength):
350-
txLookups.Add(size)
351-
case bytes.HasPrefix(key, SnapshotAccountPrefix) && len(key) == (len(SnapshotAccountPrefix)+common.HashLength):
352-
accountSnaps.Add(size)
353-
case bytes.HasPrefix(key, SnapshotStoragePrefix) && len(key) == (len(SnapshotStoragePrefix)+2*common.HashLength):
354-
storageSnaps.Add(size)
355-
case bytes.HasPrefix(key, PreimagePrefix) && len(key) == (len(PreimagePrefix)+common.HashLength):
356-
preimages.Add(size)
357-
case bytes.HasPrefix(key, configPrefix) && len(key) == (len(configPrefix)+common.HashLength):
358-
metadata.Add(size)
359-
case bytes.HasPrefix(key, bloomBitsPrefix) && len(key) == (len(bloomBitsPrefix)+10+common.HashLength):
360-
bloomBits.Add(size)
361-
case bytes.HasPrefix(key, BloomBitsIndexPrefix):
362-
bloomBits.Add(size)
363-
case bytes.HasPrefix(key, syncStorageTriesPrefix) && len(key) == syncStorageTriesKeyLength:
364-
syncProgress.Add(size)
365-
case bytes.HasPrefix(key, syncSegmentsPrefix) && len(key) == syncSegmentsKeyLength:
366-
syncSegments.Add(size)
367-
case bytes.HasPrefix(key, CodeToFetchPrefix) && len(key) == codeToFetchKeyLength:
368-
codeToFetch.Add(size)
369-
case bytes.HasPrefix(key, syncPerformedPrefix) && len(key) == syncPerformedKeyLength:
370-
syncPerformed.Add(size)
371-
default:
372-
var accounted bool
373-
for _, meta := range [][]byte{
374-
databaseVersionKey, headHeaderKey, headBlockKey,
375-
snapshotRootKey, snapshotBlockHashKey, snapshotGeneratorKey,
376-
uncleanShutdownKey, syncRootKey, txIndexTailKey,
377-
persistentStateIDKey, trieJournalKey,
378-
} {
379-
if bytes.Equal(key, meta) {
380-
metadata.Add(size)
381-
accounted = true
382-
break
383-
}
253+
254+
options := []ethrawdb.InspectDatabaseOption{
255+
ethrawdb.WithDatabaseMetadataKeys(func(key []byte) bool {
256+
return bytes.Equal(key, snapshotBlockHashKey) ||
257+
bytes.Equal(key, syncRootKey)
258+
}),
259+
ethrawdb.WithDatabaseStatRecorder(func(key []byte, size common.StorageSize) bool {
260+
switch {
261+
case bytes.HasPrefix(key, syncSegmentsPrefix) && len(key) == syncSegmentsKeyLength:
262+
syncSegments.Add(size)
263+
return true
264+
case bytes.HasPrefix(key, syncStorageTriesPrefix) && len(key) == syncStorageTriesKeyLength:
265+
syncProgress.Add(size)
266+
return true
267+
case bytes.HasPrefix(key, CodeToFetchPrefix) && len(key) == codeToFetchKeyLength:
268+
codeToFetch.Add(size)
269+
return true
270+
case bytes.HasPrefix(key, syncPerformedPrefix) && len(key) == syncPerformedKeyLength:
271+
syncPerformed.Add(size)
272+
return true
273+
default:
274+
return false
384275
}
385-
if !accounted {
386-
unaccounted.Add(size)
276+
}),
277+
ethrawdb.WithDatabaseStatsTransformer(func(rows [][]string) [][]string {
278+
newRows := make([][]string, 0, len(rows))
279+
for _, row := range rows {
280+
database := row[0]
281+
category := row[1]
282+
switch {
283+
case database == "Key-Value store" && category == "Difficulties",
284+
database == "Key-Value store" && category == "Beacon sync headers",
285+
database == "Ancient store (Chain)":
286+
// Discard rows specific to libevm (geth) but irrelevant to coreth.
287+
continue
288+
}
289+
newRows = append(newRows, row)
387290
}
388-
}
389-
count++
390-
if count%1000 == 0 && time.Since(logged) > 8*time.Second {
391-
log.Info("Inspecting database", "count", count, "elapsed", common.PrettyDuration(time.Since(start)))
392-
logged = time.Now()
393-
}
394-
}
395-
// Display the database statistic.
396-
stats := [][]string{
397-
{"Key-Value store", "Headers", headers.Size(), headers.Count()},
398-
{"Key-Value store", "Bodies", bodies.Size(), bodies.Count()},
399-
{"Key-Value store", "Receipt lists", receipts.Size(), receipts.Count()},
400-
{"Key-Value store", "Block number->hash", numHashPairings.Size(), numHashPairings.Count()},
401-
{"Key-Value store", "Block hash->number", hashNumPairings.Size(), hashNumPairings.Count()},
402-
{"Key-Value store", "Transaction index", txLookups.Size(), txLookups.Count()},
403-
{"Key-Value store", "Bloombit index", bloomBits.Size(), bloomBits.Count()},
404-
{"Key-Value store", "Contract codes", codes.Size(), codes.Count()},
405-
{"Key-Value store", "Hash trie nodes", legacyTries.Size(), legacyTries.Count()},
406-
{"Key-Value store", "Path trie state lookups", stateLookups.Size(), stateLookups.Count()},
407-
{"Key-Value store", "Path trie account nodes", accountTries.Size(), accountTries.Count()},
408-
{"Key-Value store", "Path trie storage nodes", storageTries.Size(), storageTries.Count()},
409-
{"Key-Value store", "Trie preimages", preimages.Size(), preimages.Count()},
410-
{"Key-Value store", "Account snapshot", accountSnaps.Size(), accountSnaps.Count()},
411-
{"Key-Value store", "Storage snapshot", storageSnaps.Size(), storageSnaps.Count()},
412-
{"Key-Value store", "Clique snapshots", cliqueSnaps.Size(), cliqueSnaps.Count()},
413-
{"Key-Value store", "Singleton metadata", metadata.Size(), metadata.Count()},
414-
{"Light client", "CHT trie nodes", chtTrieNodes.Size(), chtTrieNodes.Count()},
415-
{"Light client", "Bloom trie nodes", bloomTrieNodes.Size(), bloomTrieNodes.Count()},
416-
{"State sync", "Trie segments", syncSegments.Size(), syncSegments.Count()},
417-
{"State sync", "Storage tries to fetch", syncProgress.Size(), syncProgress.Count()},
418-
{"State sync", "Code to fetch", codeToFetch.Size(), codeToFetch.Count()},
419-
{"State sync", "Block numbers synced to", syncPerformed.Size(), syncPerformed.Count()},
420-
}
421-
table := tablewriter.NewWriter(os.Stdout)
422-
table.SetHeader([]string{"Database", "Category", "Size", "Items"})
423-
table.SetFooter([]string{"", "Total", total.String(), " "})
424-
table.AppendBulk(stats)
425-
table.Render()
426-
427-
if unaccounted.size > 0 {
428-
log.Error("Database contains unaccounted data", "size", unaccounted.size, "count", unaccounted.count)
291+
292+
return append(
293+
newRows,
294+
[]string{"State sync", "Trie segments", syncSegments.Size(), syncSegments.Count()},
295+
[]string{"State sync", "Storage tries to fetch", syncProgress.Size(), syncProgress.Count()},
296+
[]string{"State sync", "Code to fetch", codeToFetch.Size(), codeToFetch.Count()},
297+
[]string{"State sync", "Block numbers synced to", syncPerformed.Size(), syncPerformed.Count()},
298+
)
299+
}),
429300
}
430-
return nil
301+
302+
return ethrawdb.InspectDatabase(db, keyPrefix, keyStart, options...)
431303
}
432304

433305
// ClearPrefix removes all keys in db that begin with prefix and match an

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ require (
1919
github.com/holiman/uint256 v1.2.4
2020
github.com/mattn/go-colorable v0.1.13
2121
github.com/mattn/go-isatty v0.0.17
22-
github.com/olekukonko/tablewriter v0.0.5
2322
github.com/prometheus/client_golang v1.16.0
2423
github.com/prometheus/client_model v0.3.0
2524
github.com/spf13/cast v1.5.0
@@ -91,6 +90,7 @@ require (
9190
github.com/mitchellh/pointerstructure v1.2.0 // indirect
9291
github.com/mmcloughlin/addchain v0.4.0 // indirect
9392
github.com/mr-tron/base58 v1.2.0 // indirect
93+
github.com/olekukonko/tablewriter v0.0.5 // indirect
9494
github.com/pelletier/go-toml v1.9.5 // indirect
9595
github.com/pelletier/go-toml/v2 v2.0.5 // indirect
9696
github.com/pkg/errors v0.9.1 // indirect

0 commit comments

Comments
 (0)