Skip to content

Migrate to Cosmos EVM and XRPLEVM v9#5

Open
JordiParraCrespo wants to merge 4 commits intoxrplevm:chains/exrp/devnetfrom
JordiParraCrespo:chore/migrate-evmos-to-cosmos-evm
Open

Migrate to Cosmos EVM and XRPLEVM v9#5
JordiParraCrespo wants to merge 4 commits intoxrplevm:chains/exrp/devnetfrom
JordiParraCrespo:chore/migrate-evmos-to-cosmos-evm

Conversation

@JordiParraCrespo
Copy link

Description

This update migrates callisto from xrplevm/node/v6 to xrplevm/node/v9. The core change in the xrplevm ecosystem is the move from the evmos EVM stack (github.com/evmos/evmos/v20) to the new modular cosmos/evm library (github.com/cosmos/evm), along with a Cosmos SDK bump from v0.50.x to v0.53.x.

Main changes

Go Version

Before After
go 1.22.7 + toolchain go1.22.9 go 1.23.8 (no toolchain directive)

Direct Dependencies

Old New
github.com/xrplevm/node/v6 v6.0.0 github.com/xrplevm/node/v9 v9.0.0
github.com/evmos/evmos/v20 v20.0.0 github.com/cosmos/evm v0.4.0
github.com/cosmos/cosmos-sdk v0.50.11 github.com/cosmos/cosmos-sdk v0.53.4
github.com/cometbft/cometbft v0.38.15 github.com/cometbft/cometbft v0.38.21
cosmossdk.io/math v1.4.0 cosmossdk.io/math v1.5.3
cosmossdk.io/store v1.1.1 cosmossdk.io/store v1.1.2
cosmossdk.io/log v1.4.1 cosmossdk.io/log v1.6.1

Replace Directives

Old New
cosmossdk.io/core => cosmossdk.io/core v0.11.0 cosmossdk.io/core => cosmossdk.io/core v0.11.3
cosmossdk.io/store => github.com/evmos/cosmos-sdk/store v0.0.0-... github.com/cosmos/cosmos-sdk/store => cosmossdk.io/store v1.1.2
github.com/cosmos/cosmos-sdk => github.com/evmos/cosmos-sdk v0.50.9-evmos github.com/cosmos/cosmos-sdk => github.com/xrplevm/cosmos-sdk v0.53.4-xrplevm.2
github.com/ethereum/go-ethereum => github.com/evmos/go-ethereum v1.10.26-evmos-rc4 github.com/ethereum/go-ethereum => github.com/cosmos/go-ethereum v0.0.0-20250806193535-2fc7571efa91
github.com/evmos/evmos/v20 => github.com/xrplevm/evmos/v20 v20.0.0-exrp.4 github.com/cosmos/evm => github.com/xrplevm/evm v0.4.2-xrplevm.2

Copilot AI review requested due to automatic review settings February 11, 2026 16:30
@JordiParraCrespo JordiParraCrespo force-pushed the chore/migrate-evmos-to-cosmos-evm branch from f3afbf1 to 89b7577 Compare February 11, 2026 16:30
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates Callisto to the XRPL EVM v9 stack by moving from the Evmos-based EVM integration to github.com/cosmos/evm and upgrading core Cosmos SDK dependencies, while also updating local dev tooling and configuration to support the new EVM requirements.

Changes:

  • Upgrade core dependencies (XRPL EVM node v9, Cosmos SDK v0.53, CometBFT) and switch EVM integration from Evmos to cosmos/evm.
  • Introduce an EVM chain_id config loader and wire it into codec initialization.
  • Update local development setup (docker/hasura settings, Makefile targets) and add ready-to-use mainnet/testnet configs.

Reviewed changes

Copilot reviewed 12 out of 16 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
utils/codec.go Switches codec/module registration to cosmos/evm and initializes encoding config with configured EVM ChainID.
types/evm_config/evm_config.go Adds EVM config parsing/loading for evm.chain_id from config.yaml.
types/evm_config/evm_config_test.go Adds unit tests for the new EVM config loader/parser.
cmd/callisto/main.go Loads EVM config at startup and sets the global ChainID used by codec initialization.
go.mod Bumps Go/Cosmos dependencies and updates replace directives for the new EVM stack and forks.
modules/gov/utils_events_test.go Updates expectations to match updated vote-option parsing output type.
configs/mainnet-config.yaml Adds a preconfigured mainnet config including evm.chain_id.
configs/testnet-config.yaml Adds a preconfigured testnet config including evm.chain_id.
docker-compose.yml Makes Hasura image arch-selectable via env and updates actions base URL to host.docker.internal.
hasura/config.yaml Updates actions handler base URL to host.docker.internal.
Makefile Adds dev convenience targets (start/start-clean, schema management, env setup).
README.md Major rewrite with quickstart, make targets, and service/docs layout.
.gitignore Ignores .env used by docker-compose/Makefile flow.
cmd/parse/slashing/cmd.go, cmd/parse/slashing/params.go Removes trailing whitespace.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 67 to 78
tempFile, err := os.CreateTemp("", "config-*.yaml")
require.NoError(t, err)
defer os.Remove(tempFile.Name())

invalidYaml := []byte(`invalid: yaml: content`)
_, err = tempFile.Write(invalidYaml)
require.NoError(t, err)
require.NoError(t, tempFile.Close())

t.Setenv("JUNO_CONFIG", tempFile.Name())

cfg := ReadConfigFromFile()
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

TestGetConfig/Missing Config File doesn't set config.HomePath to the temp dir, so it can accidentally read a real config.yaml from the developer's environment and become flaky. Set config.HomePath = tempDir (and restore it) and avoid creating/setting unrelated JUNO_CONFIG state if it isn't used by GetConfig.

Suggested change
tempFile, err := os.CreateTemp("", "config-*.yaml")
require.NoError(t, err)
defer os.Remove(tempFile.Name())
invalidYaml := []byte(`invalid: yaml: content`)
_, err = tempFile.Write(invalidYaml)
require.NoError(t, err)
require.NoError(t, tempFile.Close())
t.Setenv("JUNO_CONFIG", tempFile.Name())
cfg := ReadConfigFromFile()
originalHomePath := config.HomePath
config.HomePath = tempDir
defer func() { config.HomePath = originalHomePath }()
cfg, err := GetConfig()
require.NoError(t, err)

Copilot uses AI. Check for mistakes.
Comment on lines +166 to +173
start: setup-env update-config build
@echo "Starting database services..."
@docker compose up -d
@echo "Waiting for database to be ready..."
@sleep 3
@echo "Starting callisto..."
@./build/callisto start
.PHONY: start
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The start/start-clean targets always invoke update-config, but update-config will fail with a cryptic cp error when CONFIG is not set (e.g., make start). Consider adding a guard that errors with a clear message when CONFIG is empty, or set a sensible default.

Copilot uses AI. Check for mistakes.
Comment on lines 41 to 47
if _, err := os.Stat(file); os.IsNotExist(err) {
return Config{}, fmt.Errorf("config file does not exist")
}

bz, err := os.ReadFile(file)
if err != nil {
return Config{}, fmt.Errorf("error while reading config file: %s", err)
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The errors returned by GetConfig are hard to diagnose because they omit the file path and don't wrap the underlying error. Consider including the resolved file path in the message and using %w when returning the read/stat errors so callers can inspect the cause.

Suggested change
if _, err := os.Stat(file); os.IsNotExist(err) {
return Config{}, fmt.Errorf("config file does not exist")
}
bz, err := os.ReadFile(file)
if err != nil {
return Config{}, fmt.Errorf("error while reading config file: %s", err)
if _, err := os.Stat(file); err != nil {
if os.IsNotExist(err) {
return Config{}, fmt.Errorf("config file %q does not exist: %w", file, err)
}
return Config{}, fmt.Errorf("failed to stat config file %q: %w", file, err)
}
bz, err := os.ReadFile(file)
if err != nil {
return Config{}, fmt.Errorf("error while reading config file %q: %w", file, err)

Copilot uses AI. Check for mistakes.
README.md Outdated
migrations_directory: migrations
actions:
kind: synchronous
handler_webhook_baseurl: http://localhost:3000
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

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

The Hasura config example still shows handler_webhook_baseurl: http://localhost:3000, but the repository configuration now uses http://host.docker.internal:3000. Update this snippet so it matches the actual hasura/config.yaml behavior when running Hasura in Docker.

Suggested change
handler_webhook_baseurl: http://localhost:3000
handler_webhook_baseurl: http://host.docker.internal:3000

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants