Skip to content
This repository was archived by the owner on Nov 25, 2025. It is now read-only.
Merged
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
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
Loading