Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
feat: add config to enable block database
  • Loading branch information
DracoLi committed Dec 14, 2025
commit f3bf7e550049ff5a979ac4d40a30fcd4950e69a8
6 changes: 5 additions & 1 deletion graft/coreth/plugin/evm/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,11 @@ type Config struct {
StateSyncRequestSize uint16 `json:"state-sync-request-size"`

// Database Settings
InspectDatabase bool `json:"inspect-database"` // Inspects the database on startup if enabled.
InspectDatabase bool `json:"inspect-database"` // Inspects the database on startup if enabled.
BlockDatabaseEnabled bool `json:"block-database-enabled"` // Use block database for storing block data
// SkipBlockDatabaseAutoMigrate skips auto-migrating block data from key-value
// database to the block database. Only new blocks will be stored in the block database.
SkipBlockDatabaseAutoMigrate bool `json:"skip-block-database-auto-migrate"`

// SkipUpgradeCheck disables checking that upgrades must take place before the last
// accepted block. Skipping this check is useful when a node operator does not update
Expand Down
5 changes: 4 additions & 1 deletion graft/coreth/plugin/evm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ var (
metadataPrefix = []byte("metadata")
warpPrefix = []byte("warp")
ethDBPrefix = []byte("ethdb")
blockDBPrefix = []byte("blockdb")
)

var (
Expand Down Expand Up @@ -312,7 +313,9 @@ func (vm *VM) Initialize(
}

// Initialize the database
vm.initializeDBs(db)
if err := vm.initializeDBs(db); err != nil {
return err
}
if vm.config.InspectDatabase {
if err := vm.inspectDatabases(); err != nil {
return err
Expand Down
60 changes: 59 additions & 1 deletion graft/coreth/plugin/evm/vm_database.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
package evm

import (
"context"
"errors"
"path/filepath"
"strconv"
"time"

"github.com/ava-labs/libevm/common"
Expand All @@ -13,13 +17,15 @@ import (
"github.com/ava-labs/avalanchego/database/prefixdb"
"github.com/ava-labs/avalanchego/database/versiondb"
"github.com/ava-labs/avalanchego/vms/evm/database"
"github.com/ava-labs/avalanchego/vms/evm/database/blockdb"

avalanchedatabase "github.com/ava-labs/avalanchego/database"
heightindexdb "github.com/ava-labs/avalanchego/x/blockdb"
)

// initializeDBs initializes the databases used by the VM.
// coreth always uses the avalanchego provided database.
func (vm *VM) initializeDBs(db avalanchedatabase.Database) {
func (vm *VM) initializeDBs(db avalanchedatabase.Database) error {
// Use NewNested rather than New so that the structure of the database
// remains the same regardless of the provided baseDB type.
vm.chaindb = rawdb.NewDatabase(database.New(prefixdb.NewNested(ethDBPrefix, db)))
Expand All @@ -30,6 +36,13 @@ func (vm *VM) initializeDBs(db avalanchedatabase.Database) {
// that warp signatures are committed to the database atomically with
// the last accepted block.
vm.warpDB = prefixdb.New(warpPrefix, db)

// initBlockDB must be called after acceptedBlockDB and chaindb are initialized
// because it uses them.
if err := vm.initBlockDB(db); err != nil {
return err
}
return nil
}

func (vm *VM) inspectDatabases() error {
Expand Down Expand Up @@ -80,3 +93,48 @@ func inspectDB(db avalanchedatabase.Database, label string) error {
log.Info("Database statistics", "label", label, "total", total.String(), "count", count)
return nil
}

// initBlockDB wraps the chaindb with a blockdb.Database that
// stores blocks data in separate databases when enabled.
func (vm *VM) initBlockDB(db avalanchedatabase.Database) error {
// Error if block database has been enabled and then disabled
metaDB := prefixdb.New(blockDBPrefix, db)
enabled, err := blockdb.IsEnabled(metaDB)
if err != nil {
return err
}
if !vm.config.BlockDatabaseEnabled {
if enabled {
return errors.New("block database should not be disabled after it has been enabled")
}
return nil
}

version := strconv.FormatUint(heightindexdb.IndexFileVersion, 10)
path := filepath.Join(vm.ctx.ChainDataDir, "blockdb", version)
_, height, err := vm.ReadLastAccepted()
if err != nil {
return err
}
ssEnabled := vm.stateSyncEnabled(height)
cfg := heightindexdb.DefaultConfig().WithSyncToDisk(false)
bdb, initialized, err := blockdb.New(
metaDB,
vm.chaindb,
path,
ssEnabled,
cfg,
vm.ctx.Log,
vm.sdkMetrics,
)
if err != nil {
return err
}
if initialized && !vm.config.SkipBlockDatabaseAutoMigrate {
if err := bdb.StartMigration(context.Background()); err != nil {
return err
}
}
vm.chaindb = bdb
return nil
}
2 changes: 1 addition & 1 deletion graft/coreth/plugin/evm/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2206,6 +2206,6 @@ func TestInspectDatabases(t *testing.T) {
db = memdb.New()
)

vm.initializeDBs(db)
require.NoError(t, vm.initializeDBs(db))
require.NoError(t, vm.inspectDatabases())
}
15 changes: 15 additions & 0 deletions graft/coreth/sync/blocksync/syncer.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/ava-labs/libevm/ethdb"
"github.com/ava-labs/libevm/log"

"github.com/ava-labs/avalanchego/vms/evm/database/blockdb"

syncpkg "github.com/ava-labs/avalanchego/graft/coreth/sync"
statesyncclient "github.com/ava-labs/avalanchego/graft/coreth/sync/client"
)
Expand Down Expand Up @@ -75,6 +77,19 @@ func (s *BlockSyncer) Sync(ctx context.Context) error {
nextHeight := s.fromHeight
blocksToFetch := s.blocksToFetch

// Init blockdb with the first block we will be fetching
firstBlockToFetch := nextHeight - blocksToFetch + 1
if db, ok := s.db.(*blockdb.Database); ok {
log.Info(
"Initializing block databases on block syncer",
"nextHeight", nextHeight,
"minHeight", firstBlockToFetch,
)
if err := db.InitBlockDBs(firstBlockToFetch); err != nil {
return err
}
}

// first, check for blocks already available on disk so we don't
// request them from peers.
for blocksToFetch > 0 {
Expand Down