Skip to content

Commit

Permalink
refactor: Split config package so it doesn't import core, core/vm (#734)
Browse files Browse the repository at this point in the history
Co-authored-by: Quentin McGaw <[email protected]>
  • Loading branch information
darioush and qdm12 authored Jan 7, 2025
1 parent e19a2f7 commit 14e9d30
Show file tree
Hide file tree
Showing 5 changed files with 118 additions and 18 deletions.
21 changes: 21 additions & 0 deletions plugin/evm/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// (c) 2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm

import (
"github.com/ava-labs/coreth/core/txpool/legacypool"
"github.com/ava-labs/coreth/plugin/evm/config"
)

// defaultTxPoolConfig uses [legacypool.DefaultConfig] to make a [config.TxPoolConfig]
// that can be passed to [config.Config.SetDefaults].
var defaultTxPoolConfig = config.TxPoolConfig{
PriceLimit: legacypool.DefaultConfig.PriceLimit,
PriceBump: legacypool.DefaultConfig.PriceBump,
AccountSlots: legacypool.DefaultConfig.AccountSlots,
GlobalSlots: legacypool.DefaultConfig.GlobalSlots,
AccountQueue: legacypool.DefaultConfig.AccountQueue,
GlobalQueue: legacypool.DefaultConfig.GlobalQueue,
Lifetime: legacypool.DefaultConfig.Lifetime,
}
35 changes: 21 additions & 14 deletions plugin/evm/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import (
"time"

"github.com/ava-labs/avalanchego/utils/constants"
"github.com/ava-labs/coreth/core/txpool/legacypool"
"github.com/ava-labs/coreth/eth"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/spf13/cast"
Expand Down Expand Up @@ -224,28 +222,37 @@ type Config struct {
HttpBodyLimit uint64 `json:"http-body-limit"`
}

// TxPoolConfig contains the transaction pool config to be passed
// to [Config.SetDefaults].
type TxPoolConfig struct {
PriceLimit uint64
PriceBump uint64
AccountSlots uint64
GlobalSlots uint64
AccountQueue uint64
GlobalQueue uint64
Lifetime time.Duration
}

// EthAPIs returns an array of strings representing the Eth APIs that should be enabled
func (c Config) EthAPIs() []string {
return c.EnabledEthAPIs
}

func (c Config) EthBackendSettings() eth.Settings {
return eth.Settings{MaxBlocksPerRequest: c.MaxBlocksPerRequest}
}

func (c *Config) SetDefaults() {
func (c *Config) SetDefaults(txPoolConfig TxPoolConfig) {
c.EnabledEthAPIs = defaultEnabledAPIs
c.RPCGasCap = defaultRpcGasCap
c.RPCTxFeeCap = defaultRpcTxFeeCap
c.MetricsExpensiveEnabled = defaultMetricsExpensiveEnabled

c.TxPoolPriceLimit = legacypool.DefaultConfig.PriceLimit
c.TxPoolPriceBump = legacypool.DefaultConfig.PriceBump
c.TxPoolAccountSlots = legacypool.DefaultConfig.AccountSlots
c.TxPoolGlobalSlots = legacypool.DefaultConfig.GlobalSlots
c.TxPoolAccountQueue = legacypool.DefaultConfig.AccountQueue
c.TxPoolGlobalQueue = legacypool.DefaultConfig.GlobalQueue
c.TxPoolLifetime.Duration = legacypool.DefaultConfig.Lifetime
// TxPool settings
c.TxPoolPriceLimit = txPoolConfig.PriceLimit
c.TxPoolPriceBump = txPoolConfig.PriceBump
c.TxPoolAccountSlots = txPoolConfig.AccountSlots
c.TxPoolGlobalSlots = txPoolConfig.GlobalSlots
c.TxPoolAccountQueue = txPoolConfig.AccountQueue
c.TxPoolGlobalQueue = txPoolConfig.GlobalQueue
c.TxPoolLifetime.Duration = txPoolConfig.Lifetime

c.APIMaxDuration.Duration = defaultApiMaxDuration
c.WSCPURefillRate.Duration = defaultWsCpuRefillRate
Expand Down
72 changes: 72 additions & 0 deletions plugin/evm/imports_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// (c) 2025, Ava Labs, Inc. All rights reserved.
// See the file LICENSE for licensing terms.

package evm

import (
"fmt"
"testing"

"github.com/stretchr/testify/require"
"golang.org/x/tools/go/packages"
)

// getDependencies takes a fully qualified package name and returns a map of all
// its recursive package imports (including itself) in the same format.
func getDependencies(packageName string) (map[string]struct{}, error) {
// Configure the load mode to include dependencies
cfg := &packages.Config{Mode: packages.NeedDeps | packages.NeedImports | packages.NeedName | packages.NeedModule}
pkgs, err := packages.Load(cfg, packageName)
if err != nil {
return nil, fmt.Errorf("failed to load package: %v", err)
}

if len(pkgs) == 0 || pkgs[0].Errors != nil {
return nil, fmt.Errorf("failed to load package %s", packageName)
}

deps := make(map[string]struct{})
var collectDeps func(pkg *packages.Package)
collectDeps = func(pkg *packages.Package) {
if _, ok := deps[pkg.PkgPath]; ok {
return // Avoid re-processing the same dependency
}
deps[pkg.PkgPath] = struct{}{}
for _, dep := range pkg.Imports {
collectDeps(dep)
}
}

// Start collecting dependencies
collectDeps(pkgs[0])
return deps, nil
}

func TestMustNotImport(t *testing.T) {
withRepo := func(pkg string) string {
const repo = "github.com/ava-labs/coreth"
return fmt.Sprintf("%s/%s", repo, pkg)
}
mustNotImport := map[string][]string{
// The following sub-packages of plugin/evm must not import core, core/vm
// so clients (e.g., wallets, e2e tests) can import them without pulling in
// the entire VM logic.
// Importing these packages configures libevm globally and it is not
// possible to do so for both coreth and subnet-evm, where the client may
// wish to connect to multiple chains.
"plugin/evm/atomic": {"core", "core/vm"},
"plugin/evm/client": {"core", "core/vm"},
"plugin/evm/config": {"core", "core/vm"},
}

for packageName, forbiddenImports := range mustNotImport {
imports, err := getDependencies(withRepo(packageName))
require.NoError(t, err)

for _, forbiddenImport := range forbiddenImports {
fullForbiddenImport := withRepo(forbiddenImport)
_, found := imports[fullForbiddenImport]
require.False(t, found, "package %s must not import %s, check output of go list -f '{{ .Deps }}' \"%s\" ", packageName, fullForbiddenImport, withRepo(packageName))
}
}
}
4 changes: 2 additions & 2 deletions plugin/evm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ func (vm *VM) Initialize(
fxs []*commonEng.Fx,
appSender commonEng.AppSender,
) error {
vm.config.SetDefaults()
vm.config.SetDefaults(defaultTxPoolConfig)
if len(configBytes) > 0 {
if err := json.Unmarshal(configBytes, &vm.config); err != nil {
return fmt.Errorf("failed to unmarshal config %s: %w", string(configBytes), err)
Expand Down Expand Up @@ -660,7 +660,7 @@ func (vm *VM) initializeChain(lastAcceptedHash common.Hash) error {
&vm.ethConfig,
&EthPushGossiper{vm: vm},
vm.chaindb,
vm.config.EthBackendSettings(),
eth.Settings{MaxBlocksPerRequest: vm.config.MaxBlocksPerRequest},
lastAcceptedHash,
dummy.NewFakerWithClock(callbacks, &vm.clock),
&vm.clock,
Expand Down
4 changes: 2 additions & 2 deletions plugin/evm/vm_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ func TestVMConfigDefaults(t *testing.T) {
_, vm, _, _, _ := GenesisVM(t, false, "", configJSON, "")

var vmConfig config.Config
vmConfig.SetDefaults()
vmConfig.SetDefaults(defaultTxPoolConfig)
vmConfig.RPCTxFeeCap = txFeeCap
vmConfig.EnabledEthAPIs = enabledEthAPIs
require.Equal(t, vmConfig, vm.config, "VM Config should match default with overrides")
Expand All @@ -414,7 +414,7 @@ func TestVMNilConfig(t *testing.T) {

// VM Config should match defaults if no config is passed in
var vmConfig config.Config
vmConfig.SetDefaults()
vmConfig.SetDefaults(defaultTxPoolConfig)
require.Equal(t, vmConfig, vm.config, "VM Config should match default config")
require.NoError(t, vm.Shutdown(context.Background()))
}
Expand Down

0 comments on commit 14e9d30

Please sign in to comment.