Skip to content

Conversation

almk-dev
Copy link
Member

@almk-dev almk-dev commented Aug 12, 2025

Description

Remove static chain configs from EVM

Currently we have the configuration for chains held in .go files that are compiled into the binary. This logic and struct is duplicated throughout the codebase, making it very complicated to think about testing and spinning up nodes.

Cosmos apps already come with an app.toml which is already used for some of our EVM configuration. We should just move all of this logic to a config file so that it is simple to work with in testing and for users

STACK-1409
EVM-176

Please review that all chain config redundancy has been removed and that all tests and functionality is working exactly the same as before.

Author Checklist

I have...

  • tackled an existing issue or discussed with a team member
  • left instructions on how to review the changes
  • targeted the main branch

Copy link

linear bot commented Aug 12, 2025

@aljo242 aljo242 added the v0.5.x targeting v0.5.x label Aug 14, 2025
@aljo242 aljo242 self-requested a review August 14, 2025 21:26
@almk-dev almk-dev force-pushed the stack-1409-clean-up-chain-config branch from 1f0d4d4 to cda76f9 Compare August 15, 2025 15:28
@almk-dev almk-dev changed the title Stack 1409 clean up chain config fix: consolidate and clean up chain config Aug 18, 2025
@almk-dev almk-dev marked this pull request as ready for review August 19, 2025 16:13
@almk-dev almk-dev requested review from a team as code owners August 19, 2025 16:13
@aljo242 aljo242 self-assigned this Aug 19, 2025
@aljo242 aljo242 requested a review from technicallyty August 25, 2025 15:58
@@ -92,6 +93,7 @@ type EVMAppConfig struct {
EVM cosmosevmserverconfig.EVMConfig
JSONRPC cosmosevmserverconfig.JSONRPCConfig
TLS cosmosevmserverconfig.TLSConfig
Chain evmtypes.EvmCoinInfo
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels confusing that all of the other configs are defined in cosmosevmserverconfig but this one comes from another package (evmtypes). Then below, the DefaultEvmCoinInfo function actually does come from the cosmosevmserverconfig package

Comment on lines 117 to 119
###############################################################################
### Chain Configuration ###
###############################################################################
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Folks generate this toml when they run appd init so this would be run at whatever initial version they are using. So if i was on v0.4 when i ran appd init i would not have this section in my config. What would happen in that scenario?

Decimals: evmtypes.EighteenDecimals,
},
// GetEvmCoinInfo returns appropriate EvmCoinInfo for evmd based on chainID.
func GetEvmCoinInfo(chainID uint64) evmtypes.EvmCoinInfo {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we just export something like this once from the library instead of here and how it is duplicated in testutil?

@@ -328,6 +328,24 @@ certificate-path = ""
# Key path defines the key.pem file path for the TLS configuration.
key-path = ""

###############################################################################
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this file?

@@ -0,0 +1,119 @@
# Chain Configuration Migration Guide
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The title of this file is pretty generic. How are we pointing people to this file?

Feels like it needs to be linked in the changelog or in an overall "migration guide"

we have stuff here for previous releases

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should definitely put what versions this is relevant for here

Comment on lines 102 to 104
// Deprecated: Use testutil/config.CreateEvmCoinInfoFromDynamicConfig() instead.
// This function is kept for backward compatibility but should be replaced
// with dynamic configuration generation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we are deprecating this and keeping it for compatibility, then why not just keep the global map type?

Folks will be broken because we've changed the API

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would also make the diff much smaller

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree here, it seems counter intuitive to break something and immediately deprecate it. its also still used extensively throughout the code. should that be updated to the non-deprecated version?

@@ -11,6 +11,7 @@ import (
"fmt"

"github.com/ethereum/go-ethereum/core/vm"
"github.com/ethereum/go-ethereum/log"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does this file need to be behind test build flags?

@technicallyty
Copy link
Contributor

i think the PR title should be "refactor!" since it is a breaking change and a restructure of how users will interact with the software

Copy link
Contributor

@technicallyty technicallyty left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mostly questions on stuff. am a little confused about the map -> function changes. it kinda blew up the diff and its unclear to me if it was necessary for this refactor

CHANGELOG.md Outdated
@@ -14,6 +14,7 @@
- [\#467](https://github.com/cosmos/evm/pull/467) Replace GlobalEVMMempool by passing to JSONRPC on initiate.
- [\#352](https://github.com/cosmos/evm/pull/352) Remove the creation of a Geth EVM instance, stateDB during the AnteHandler balance check.
- [\#496](https://github.com/cosmos/evm/pull/496) Simplify mempool instantiation by using configs instead of objects.
- [\#436](https://github.com/cosmos/evm/pull/436) Consolidate and clean up chain config
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this feels a bit too ambiguous for the change being made. if i was an evm user, i wouldn't really know what needs to be actionized from this.

Comment on lines 35 to 38
default:
// Default fallback - return the default configuration
return *config.DefaultEvmCoinInfo()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems like it could be a potential footgun. what types of issues could cascade from this?

Comment on lines 117 to 119
###############################################################################
### Chain Configuration ###
###############################################################################
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we can automate the updating of their app.toml in an upgrade handler, we should definitely do that. im still going through the PR as i write this comment so i'm not sure what is possible yet.

@@ -0,0 +1,119 @@
# Chain Configuration Migration Guide
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should definitely put what versions this is relevant for here

}
```

## Dynamic Configuration for Tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems a bit confusing to me. is there a reason we have all this dynamic stuff -- it seems like you could just skirt all this and directly construct an EvmCoinInfo type, no?

Comment on lines 102 to 104
// Deprecated: Use testutil/config.CreateEvmCoinInfoFromDynamicConfig() instead.
// This function is kept for backward compatibility but should be replaced
// with dynamic configuration generation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

agree here, it seems counter intuitive to break something and immediately deprecate it. its also still used extensively throughout the code. should that be updated to the non-deprecated version?

@@ -118,14 +118,7 @@ type ConfigOption func(*Config)
// WithChainID sets a custom chainID for the network. Changing the chainID
// change automatically also the EVM coin used. It panics if the chainID is invalid.
func WithChainID(chainID testconstants.ChainID) ConfigOption {
evmCoinInfo, found := testconstants.ExampleChainCoinInfo[chainID]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

regarding the change of maps to functions for the coin info, the map version did have the benefit of giving the user a presence check for free. with the function as is, it doesnt seem like there is a way for the user to check that the thing they were looking for is actually there. but, im not too sure how important that is.

@almk-dev almk-dev changed the title fix: consolidate and clean up chain config refactor: consolidate and clean up chain config Aug 26, 2025
@technicallyty technicallyty changed the title refactor: consolidate and clean up chain config refactor!: consolidate and clean up chain config Aug 26, 2025
// Call the configurator to set the EVM coin required for the
// function to be tested.
configurator := evmtypes.NewEVMConfigurator()
configurator.ResetTestConfig()
s.Require().NoError(configurator.WithEVMCoinInfo(testconstants.ExampleChainCoinInfo[chainID]).Configure())
s.Require().NoError(configurator.WithEVMCoinInfo(chainConfig.CoinInfo).Configure())

Check warning

Code scanning / CodeQL

Unreachable statement Warning test

This statement is unreachable.

Copilot Autofix

AI 5 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

@@ -500,8 +500,8 @@
func FuzzBurnCoins(f *testing.F) {
configurator := evmtypes.NewEVMConfigurator()
configurator.ResetTestConfig()
configurator.WithEVMCoinInfo(testconstants.ExampleChainCoinInfo[testconstants.SixDecimalsChainID])
err := configurator.Configure()
coinInfo := testconfig.SixDecimalsChainConfig.CoinInfo

Check warning

Code scanning / CodeQL

Unreachable statement Warning test

This statement is unreachable.

Copilot Autofix

AI 5 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

@@ -417,8 +417,7 @@
func FuzzMintCoins(f *testing.F) {
configurator := evmtypes.NewEVMConfigurator()
configurator.ResetTestConfig()
configurator.WithEVMCoinInfo(testconstants.ExampleChainCoinInfo[testconstants.SixDecimalsChainID])
err := configurator.Configure()
err := configurator.WithEVMCoinInfo(testconfig.SixDecimalsChainConfig.CoinInfo).Configure()

Check warning

Code scanning / CodeQL

Unreachable statement Warning test

This statement is unreachable.

Copilot Autofix

AI 5 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

@@ -798,8 +798,7 @@
func FuzzSendCoins(f *testing.F) {
configurator := evmtypes.NewEVMConfigurator()
configurator.ResetTestConfig()
configurator.WithEVMCoinInfo(testconstants.ExampleChainCoinInfo[testconstants.SixDecimalsChainID])
err := configurator.Configure()
err := configurator.WithEVMCoinInfo(testconfig.SixDecimalsChainConfig.CoinInfo).Configure()

Check warning

Code scanning / CodeQL

Unreachable statement Warning test

This statement is unreachable.

Copilot Autofix

AI 5 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.

@@ -105,17 +105,18 @@
extendedDenom := evmtypes.GetEVMCoinExtendedDenom()
displayDenom := evmtypes.GetEVMCoinDisplayDenom()
decimals := evmtypes.GetEVMCoinDecimals()
coinInfo := evmtypes.EvmCoinInfo{

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This definition of coinInfo is never used.
@@ -1605,9 +1605,10 @@

configurator := types.NewEVMConfigurator()
configurator.ResetTestConfig()
coinInfo := testconfig.DefaultChainConfig.CoinInfo

Check warning

Code scanning / CodeQL

Unreachable statement Warning test

This statement is unreachable.

Copilot Autofix

AI 5 days ago

Copilot could not generate an autofix suggestion

Copilot could not generate an autofix suggestion for this alert. Try pushing a new commit or if the problem persists contact support.


// If the base denom has different decimals, we need to create it properly
denom := evmtypes.CreateDenomStr(defaultDecimals, defaultDisplayDenom)
if defaultDecimals == evmtypes.EighteenDecimals {

Check warning

Code scanning / CodeQL

Comparison of identical values Warning

This expression compares an
expression
to itself.

Copilot Autofix

AI 6 days ago

To fix the issue, we need to remove the unnecessary comparison between two identical values. Since defaultDecimals is set unconditionally to evmtypes.Decimals(18), which is in all likelihood equal to evmtypes.EighteenDecimals, the conditional on line 160 will always execute. The ramifications are that the nominal else block (base and extended denom creation) is never used, and the denom/extendedDenom are both simply set to the default string. The fix should be either to use the default values unconditionally, or (if conditional behaviour is needed) to ensure the comparison actually checks for something meaningful. If the intent was to allow variable decimal configurations, defaultDecimals should be set from configuration rather than hardcoded. For now, the best minimal fix is to remove the condition and set denom and extendedDenom to the default values unconditionally, and remove the dead code.

Suggested changeset 1
evmd/cmd/evmd/config/loader.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/evmd/cmd/evmd/config/loader.go b/evmd/cmd/evmd/config/loader.go
--- a/evmd/cmd/evmd/config/loader.go
+++ b/evmd/cmd/evmd/config/loader.go
@@ -152,17 +152,10 @@
 	defaultDisplayDenom := "test"
 	defaultDecimals := evmtypes.Decimals(18)
 
-	// Create extended denom (atto version for 18-decimal representation)
-	extendedDenom := evmtypes.CreateDenomStr(defaultDecimals, defaultDisplayDenom)
+	// For 18 decimals, base and extended are the same
+	denom := defaultDenom
+	extendedDenom := defaultDenom
 
-	// If the base denom has different decimals, we need to create it properly
-	denom := evmtypes.CreateDenomStr(defaultDecimals, defaultDisplayDenom)
-	if defaultDecimals == evmtypes.EighteenDecimals {
-		// For 18 decimals, base and extended are the same
-		denom = defaultDenom
-		extendedDenom = defaultDenom
-	}
-
 	coinInfo = evmtypes.EvmCoinInfo{
 		Denom:         denom,
 		ExtendedDenom: extendedDenom,
EOF
@@ -152,17 +152,10 @@
defaultDisplayDenom := "test"
defaultDecimals := evmtypes.Decimals(18)

// Create extended denom (atto version for 18-decimal representation)
extendedDenom := evmtypes.CreateDenomStr(defaultDecimals, defaultDisplayDenom)
// For 18 decimals, base and extended are the same
denom := defaultDenom
extendedDenom := defaultDenom

// If the base denom has different decimals, we need to create it properly
denom := evmtypes.CreateDenomStr(defaultDecimals, defaultDisplayDenom)
if defaultDecimals == evmtypes.EighteenDecimals {
// For 18 decimals, base and extended are the same
denom = defaultDenom
extendedDenom = defaultDenom
}

coinInfo = evmtypes.EvmCoinInfo{
Denom: denom,
ExtendedDenom: extendedDenom,
Copilot is powered by AI and may make mistakes. Always verify output.
// testEvmAppOptions creates an EvmAppOptions function for testing
func testEvmAppOptions(evmChainID uint64) error {
// Use default chain configuration for testing
chainConfig := testconfig.DefaultChainConfig

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This definition of chainConfig is never used.

Copilot Autofix

AI 6 days ago

The best way to fix the problem is to remove the unnecessary assignment to the local variable chainConfig in the function testEvmAppOptions. Instead, access testconfig.DefaultChainConfig.CoinInfo directly when calling WithEVMCoinInfo. No other changes are needed as the rest of the code already works with this direct access. Edits should be made in evmd/test_helpers.go, lines 55–58.

Suggested changeset 1
evmd/test_helpers.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/evmd/test_helpers.go b/evmd/test_helpers.go
--- a/evmd/test_helpers.go
+++ b/evmd/test_helpers.go
@@ -52,10 +52,9 @@
 // testEvmAppOptions creates an EvmAppOptions function for testing
 func testEvmAppOptions(evmChainID uint64) error {
 	// Use default chain configuration for testing
-	chainConfig := testconfig.DefaultChainConfig
 	configurator := evmtypes.NewEVMConfigurator()
 	configurator.ResetTestConfig()
-	return configurator.WithEVMCoinInfo(chainConfig.CoinInfo).Configure()
+	return configurator.WithEVMCoinInfo(testconfig.DefaultChainConfig.CoinInfo).Configure()
 }
 
 func setup(withGenesis bool, invCheckPeriod uint, chainID string, evmChainID uint64) (*EVMD, GenesisState) {
EOF
@@ -52,10 +52,9 @@
// testEvmAppOptions creates an EvmAppOptions function for testing
func testEvmAppOptions(evmChainID uint64) error {
// Use default chain configuration for testing
chainConfig := testconfig.DefaultChainConfig
configurator := evmtypes.NewEVMConfigurator()
configurator.ResetTestConfig()
return configurator.WithEVMCoinInfo(chainConfig.CoinInfo).Configure()
return configurator.WithEVMCoinInfo(testconfig.DefaultChainConfig.CoinInfo).Configure()
}

func setup(withGenesis bool, invCheckPeriod uint, chainID string, evmChainID uint64) (*EVMD, GenesisState) {
Copilot is powered by AI and may make mistakes. Always verify output.
// testEvmAppOptionsWithReset creates an EvmAppOptions function for testing with reset
func testEvmAppOptionsWithReset(evmChainID uint64) error {
// Use default chain configuration for testing
chainConfig := testconfig.DefaultChainConfig

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This definition of chainConfig is never used.

Copilot Autofix

AI 6 days ago

The best fix is to remove the definition of the local variable chainConfig, and replace its usage with a direct reference to testconfig.DefaultChainConfig.CoinInfo. Specifically, in testEvmAppOptionsWithReset (lines 26 and 29), delete the assignment to chainConfig and change the argument passed to WithEVMCoinInfo from chainConfig.CoinInfo to testconfig.DefaultChainConfig.CoinInfo. No imports or definitions are required beyond this local change. This removes the useless assignment, improving clarity without altering functionality.

Suggested changeset 1
evmd/tests/integration/create_app.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/evmd/tests/integration/create_app.go b/evmd/tests/integration/create_app.go
--- a/evmd/tests/integration/create_app.go
+++ b/evmd/tests/integration/create_app.go
@@ -23,10 +23,9 @@
 // testEvmAppOptionsWithReset creates an EvmAppOptions function for testing with reset
 func testEvmAppOptionsWithReset(evmChainID uint64) error {
 	// Use default chain configuration for testing
-	chainConfig := testconfig.DefaultChainConfig
 	configurator := evmtypes.NewEVMConfigurator()
 	configurator.ResetTestConfig()
-	return configurator.WithEVMCoinInfo(chainConfig.CoinInfo).Configure()
+	return configurator.WithEVMCoinInfo(testconfig.DefaultChainConfig.CoinInfo).Configure()
 }
 
 // CreateEvmd creates an evm app for regular integration tests (non-mempool)
EOF
@@ -23,10 +23,9 @@
// testEvmAppOptionsWithReset creates an EvmAppOptions function for testing with reset
func testEvmAppOptionsWithReset(evmChainID uint64) error {
// Use default chain configuration for testing
chainConfig := testconfig.DefaultChainConfig
configurator := evmtypes.NewEVMConfigurator()
configurator.ResetTestConfig()
return configurator.WithEVMCoinInfo(chainConfig.CoinInfo).Configure()
return configurator.WithEVMCoinInfo(testconfig.DefaultChainConfig.CoinInfo).Configure()
}

// CreateEvmd creates an evm app for regular integration tests (non-mempool)
Copilot is powered by AI and may make mistakes. Always verify output.
// testEvmAppOptions creates an EvmAppOptions function for testing
func testEvmAppOptions(evmChainID uint64) error {
// Use default chain configuration for testing
chainConfig := testconfig.DefaultChainConfig

Check warning

Code scanning / CodeQL

Useless assignment to local variable Warning test

This definition of chainConfig is never used.

Copilot Autofix

AI 5 days ago

To fix this problem, we should remove the unnecessary assignment of chainConfig to testconfig.DefaultChainConfig on line 106, since it is only used to access its CoinInfo field. Instead, we should directly use testconfig.DefaultChainConfig.CoinInfo in the call to configurator.WithEVMCoinInfo. This applies only to the region inside testEvmAppOptions. No other code or functionality will be affected, as the assignment is not used elsewhere.

Suggested changeset 1
evmd/tests/network/network.go

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/evmd/tests/network/network.go b/evmd/tests/network/network.go
--- a/evmd/tests/network/network.go
+++ b/evmd/tests/network/network.go
@@ -103,10 +103,9 @@
 // testEvmAppOptions creates an EvmAppOptions function for testing
 func testEvmAppOptions(evmChainID uint64) error {
 	// Use default chain configuration for testing
-	chainConfig := testconfig.DefaultChainConfig
 	configurator := evmtypes.NewEVMConfigurator()
 	configurator.ResetTestConfig()
-	return configurator.WithEVMCoinInfo(chainConfig.CoinInfo).Configure()
+	return configurator.WithEVMCoinInfo(testconfig.DefaultChainConfig.CoinInfo).Configure()
 }
 
 // DefaultConfig returns a sane default configuration suitable for nearly all
EOF
@@ -103,10 +103,9 @@
// testEvmAppOptions creates an EvmAppOptions function for testing
func testEvmAppOptions(evmChainID uint64) error {
// Use default chain configuration for testing
chainConfig := testconfig.DefaultChainConfig
configurator := evmtypes.NewEVMConfigurator()
configurator.ResetTestConfig()
return configurator.WithEVMCoinInfo(chainConfig.CoinInfo).Configure()
return configurator.WithEVMCoinInfo(testconfig.DefaultChainConfig.CoinInfo).Configure()
}

// DefaultConfig returns a sane default configuration suitable for nearly all
Copilot is powered by AI and may make mistakes. Always verify output.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
v0.5.x targeting v0.5.x
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants