Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add standalone dbs and configs #1354

Merged
merged 17 commits into from
Oct 21, 2024
Merged
5 changes: 2 additions & 3 deletions plugin/evm/block_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,8 @@ func TestHandlePrecompileAccept(t *testing.T) {

db := rawdb.NewMemoryDatabase()
vm := &VM{
chaindb: db,
chainConfig: params.TestChainConfig,
skipStandaloneDB: true,
chaindb: db,
chainConfig: params.TestChainConfig,
}

precompileAddr := common.Address{0x05}
Expand Down
8 changes: 2 additions & 6 deletions plugin/evm/syncervm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,7 @@ func TestStateSyncToggleEnabledToDisabled(t *testing.T) {
test.responseIntercept = nil
test.expectedErr = nil

syncDisabledVM := &VM{
skipStandaloneDB: true,
}
syncDisabledVM := &VM{}
appSender := &enginetest.Sender{T: t}
appSender.SendAppGossipF = func(context.Context, commonEng.SendConfig, []byte) error { return nil }
appSender.SendAppRequestF = func(ctx context.Context, nodeSet set.Set[ids.NodeID], requestID uint32, request []byte) error {
Expand Down Expand Up @@ -197,9 +195,7 @@ func TestStateSyncToggleEnabledToDisabled(t *testing.T) {
syncDisabledVM.blockChain.DrainAcceptorQueue()

// Create a new VM from the same database with state sync enabled.
syncReEnabledVM := &VM{
skipStandaloneDB: true,
}
syncReEnabledVM := &VM{}
// Enable state sync in configJSON
configJSON := fmt.Sprintf(
`{"state-sync-enabled":true, "state-sync-min-blocks":%d}`,
Expand Down
5 changes: 1 addition & 4 deletions plugin/evm/tx_gossip_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ func TestEthTxGossip(t *testing.T) {
SentAppResponse: make(chan []byte, 1),
}
vm := &VM{
p2pSender: responseSender,
skipStandaloneDB: true,
p2pSender: responseSender,
}

require.NoError(vm.Initialize(
Expand Down Expand Up @@ -170,7 +169,6 @@ func TestEthTxPushGossipOutbound(t *testing.T) {

vm := &VM{
ethTxPullGossiper: gossip.NoOpGossiper{},
skipStandaloneDB: true,
}

require.NoError(vm.Initialize(
Expand Down Expand Up @@ -224,7 +222,6 @@ func TestEthTxPushGossipInbound(t *testing.T) {
sender := &enginetest.Sender{}
vm := &VM{
ethTxPullGossiper: gossip.NoOpGossiper{},
skipStandaloneDB: true,
}

require.NoError(vm.Initialize(
Expand Down
63 changes: 35 additions & 28 deletions plugin/evm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,6 @@ type VM struct {
ethTxPushGossiper avalancheUtils.Atomic[*gossip.PushGossiper[*GossipEthTx]]
ethTxPullGossiper gossip.Gossiper

skipStandaloneDB bool

chainAlias string
}

Expand Down Expand Up @@ -1190,21 +1188,22 @@ func attachEthService(handler *rpc.Server, apis []rpc.API, names []string) error
func (vm *VM) useStandaloneDatabase(acceptedDB database.Database) (bool, error) {
// no config provided, use default
standaloneDBFlag := vm.config.UseStandaloneDatabase
if standaloneDBFlag == nil {
// check if the chain can use a standalone database
_, lastAcceptedErr := acceptedDB.Get(lastAcceptedKey)
if lastAcceptedErr == database.ErrNotFound {
// If there is nothing in the database, we can use the standalone database
return true, nil
} else {
return false, lastAcceptedErr
}
if standaloneDBFlag != nil {
return standaloneDBFlag.Bool(), nil
}

// check if the chain can use a standalone database
_, err := acceptedDB.Get(lastAcceptedKey)
if err == database.ErrNotFound {
// If there is nothing in the database, we can use the standalone database
return true, nil
} else {
ceyonur marked this conversation as resolved.
Show resolved Hide resolved
return false, err
}
return standaloneDBFlag.Bool(), nil
}

// getDatabaseConfig returns the database configuration for the chain
// to be used by sepearate, standalone database.
// to be used by separate, standalone database.
func getDatabaseConfig(config Config, chainDataDir string) (avalancheNode.DatabaseConfig, error) {
var (
configBytes []byte
Expand Down Expand Up @@ -1241,25 +1240,33 @@ func getDatabaseConfig(config Config, chainDataDir string) (avalancheNode.Databa
// If [useStandaloneDB] is true, the chain will use a standalone database for its state.
// Otherwise, the chain will use the provided [avaDB] for its state.
func (vm *VM) initializeDBs(avaDB database.Database) error {
// first initialize the accepted block database to check if we need to use a standalone database
verDB := versiondb.New(avaDB)
acceptedDB := prefixdb.New(acceptedPrefix, verDB)
useStandAloneDB, err := vm.useStandaloneDatabase(acceptedDB)
if err != nil {
return err
}
db := avaDB
if useStandAloneDB && !vm.skipStandaloneDB {
// If we are using a standalone database, we need to create a new database
// for the chain state.
dbConfig, err := getDatabaseConfig(vm.config, vm.ctx.ChainDataDir)
var isMemDB bool
switch avaDB.(type) {
case *memdb.Database:
isMemDB = true
}
// skip standalone database initialization if we are running memdb
if !isMemDB {
// first initialize the accepted block database to check if we need to use a standalone database
verDB := versiondb.New(avaDB)
acceptedDB := prefixdb.New(acceptedPrefix, verDB)
useStandAloneDB, err := vm.useStandaloneDatabase(acceptedDB)
if err != nil {
return err
}
log.Info("Using standalone database for the chain state", "DatabaseConfig", dbConfig)
db, err = vm.createDatabase(dbConfig)
if err != nil {
return err
if useStandAloneDB {
// If we are using a standalone database, we need to create a new database
// for the chain state.
dbConfig, err := getDatabaseConfig(vm.config, vm.ctx.ChainDataDir)
if err != nil {
return err
}
log.Info("Using standalone database for the chain state", "DatabaseConfig", dbConfig)
db, err = vm.createDatabase(dbConfig)
if err != nil {
return err
}
}
}
// Use NewNested rather than New so that the structure of the database
Expand Down
31 changes: 8 additions & 23 deletions plugin/evm/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,8 @@ func setupGenesis(
genesisBytes := buildGenesisTest(t, genesisJSON)
ctx := NewContext()

baseDB := memdb.New()

// initialize the atomic memory
atomicMemory := atomic.NewMemory(prefixdb.New([]byte{0}, baseDB))
atomicMemory := atomic.NewMemory(prefixdb.New([]byte{0}, memdb.New()))
ceyonur marked this conversation as resolved.
Show resolved Hide resolved
ctx.SharedMemory = atomicMemory.NewSharedMemory(ctx.ChainID)

// NB: this lock is intentionally left locked when this function returns.
Expand All @@ -206,8 +204,7 @@ func setupGenesis(
ctx.Keystore = userKeystore.NewBlockchainKeyStore(ctx.ChainID)

issuer := make(chan commonEng.Message, 1)
prefixedDB := prefixdb.New([]byte{1}, baseDB)
return ctx, prefixedDB, genesisBytes, issuer, atomicMemory
return ctx, memdb.New(), genesisBytes, issuer, atomicMemory
}

// GenesisVM creates a VM instance with the genesis test bytes and returns
Expand All @@ -225,9 +222,7 @@ func GenesisVM(t *testing.T,
database.Database,
*enginetest.Sender,
) {
vm := &VM{
skipStandaloneDB: true,
}
vm := &VM{}
ctx, dbManager, genesisBytes, issuer, _ := setupGenesis(t, genesisJSON)
appSender := &enginetest.Sender{T: t}
appSender.CantSendAppGossip = true
Expand Down Expand Up @@ -490,9 +485,7 @@ func TestBuildEthTxBlock(t *testing.T) {
t.Fatalf("Found unexpected blkID for parent of blk2")
}

restartedVM := &VM{
skipStandaloneDB: true,
}
restartedVM := &VM{}
genesisBytes := buildGenesisTest(t, genesisJSONSubnetEVM)

if err := restartedVM.Initialize(
Expand Down Expand Up @@ -1936,9 +1929,7 @@ func TestConfigureLogLevel(t *testing.T) {
}
for _, test := range configTests {
t.Run(test.name, func(t *testing.T) {
vm := &VM{
skipStandaloneDB: true,
}
vm := &VM{}
ctx, dbManager, genesisBytes, issuer, _ := setupGenesis(t, test.genesisJSON)
appSender := &enginetest.Sender{T: t}
appSender.CantSendAppGossip = true
Expand Down Expand Up @@ -2307,9 +2298,7 @@ func TestVerifyManagerConfig(t *testing.T) {
genesisJSON, err := genesis.MarshalJSON()
require.NoError(t, err)

vm := &VM{
skipStandaloneDB: true,
}
vm := &VM{}
ctx, dbManager, genesisBytes, issuer, _ := setupGenesis(t, string(genesisJSON))
err = vm.Initialize(
context.Background(),
Expand Down Expand Up @@ -2340,9 +2329,7 @@ func TestVerifyManagerConfig(t *testing.T) {
upgradeBytesJSON, err := json.Marshal(upgradeConfig)
require.NoError(t, err)

vm = &VM{
skipStandaloneDB: true,
}
vm = &VM{}
ctx, dbManager, genesisBytes, issuer, _ = setupGenesis(t, string(genesisJSON))
err = vm.Initialize(
context.Background(),
Expand Down Expand Up @@ -3035,9 +3022,7 @@ func TestSkipChainConfigCheckCompatible(t *testing.T) {
t.Fatalf("Expected new block to match")
}

reinitVM := &VM{
skipStandaloneDB: true,
}
reinitVM := &VM{}
// use the block's timestamp instead of 0 since rewind to genesis
// is hardcoded to be allowed in core/genesis.go.
genesisWithUpgrade := &core.Genesis{}
Expand Down
4 changes: 1 addition & 3 deletions plugin/evm/vm_upgrade_bytes_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,9 +181,7 @@ func TestNetworkUpgradesOverriden(t *testing.T) {
}
}`

vm := &VM{
skipStandaloneDB: true,
}
vm := &VM{}
ctx, dbManager, genesisBytes, issuer, _ := setupGenesis(t, string(genesisBytes))
appSender := &enginetest.Sender{T: t}
appSender.CantSendAppGossip = true
Expand Down
3 changes: 2 additions & 1 deletion utils/snow.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/ava-labs/avalanchego/snow"
"github.com/ava-labs/avalanchego/snow/validators/validatorstest"
"github.com/ava-labs/avalanchego/upgrade/upgradetest"
"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/avalanchego/utils/crypto/bls"
"github.com/ava-labs/avalanchego/utils/logging"
)
Expand All @@ -20,7 +21,7 @@ func TestSnowContext() *snow.Context {
}
pk := bls.PublicFromSecretKey(sk)
return &snow.Context{
NetworkID: 0,
NetworkID: constants.UnitTestID,
SubnetID: ids.Empty,
ChainID: ids.Empty,
NodeID: ids.EmptyNodeID,
Expand Down
Loading