Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
timeout-minutes: 240
strategy:
matrix:
tests: [unmarked, ibc, ibc_rly_evm, ibc_rly_gas, ibc_timeout, ibc_update_client, ica, gov, upgrade, slow, gas, mint]
tests: [unmarked, ibc, ibc_rly_evm, ibc_rly_gas, ibc_timeout, ibc_update_client, ica, gov, upgrade, slow, gas, mint, evm]
env:
TESTS_TO_RUN: ${{ matrix.tests }}
steps:
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
* [#1875](https://github.com/crypto-org-chain/cronos/pull/1875) Support for preinstalls
* [#1882](https://github.com/crypto-org-chain/cronos/pull/1882) Support for eip2935
* [#1880](https://github.com/crypto-org-chain/cronos/pull/1880) Move module from v2 to v1 to follow semver convention
* [#1933](https://github.com/crypto-org-chain/cronos/pull/1933) Chore: add validation for HeaderHashNum and HistoryServeWindow in evm params

*Dec 4, 2025*

Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ require (
github.com/hashicorp/go-metrics v0.5.4
github.com/linxGnu/grocksdb v1.9.10-0.20250331012329-9d5f074653d1
github.com/spf13/cast v1.10.0
github.com/spf13/cobra v1.10.1
github.com/spf13/cobra v1.10.2
github.com/spf13/pflag v1.0.10
github.com/spf13/viper v1.21.0
github.com/stretchr/testify v1.11.1
Expand Down Expand Up @@ -303,7 +303,7 @@ replace (
// release/v1.15
github.com/ethereum/go-ethereum => github.com/crypto-org-chain/go-ethereum v1.10.20-0.20250815065500-a4fbafcae0dd
// develop
github.com/evmos/ethermint => github.com/crypto-org-chain/ethermint v0.22.1-0.20251204034614-3b1542d755b6
github.com/evmos/ethermint => github.com/randy-cro/ethermint v0.0.0-20251208045921-6a15b6334ab2
// Fix upstream GHSA-h395-qcrw-5vmq and GHSA-3vp4-m3rf-835h vulnerabilities.
// TODO Remove it: https://github.com/cosmos/cosmos-sdk/issues/10409
github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.9.0
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -911,8 +911,6 @@ github.com/crypto-org-chain/cosmos-sdk/store v0.0.0-20241217090828-cfbca9fe8254
github.com/crypto-org-chain/cosmos-sdk/store v0.0.0-20241217090828-cfbca9fe8254/go.mod h1:8DwVTz83/2PSI366FERGbWSH7hL6sB7HbYp8bqksNwM=
github.com/crypto-org-chain/cosmos-sdk/x/tx v0.0.0-20241217090828-cfbca9fe8254 h1:JzLOFRiKsDtLJt5h0M0jkEIPDKvFFyja7VEp7gG6O9U=
github.com/crypto-org-chain/cosmos-sdk/x/tx v0.0.0-20241217090828-cfbca9fe8254/go.mod h1:V6DImnwJMTq5qFjeGWpXNiT/fjgE4HtmclRmTqRVM3w=
github.com/crypto-org-chain/ethermint v0.22.1-0.20251204034614-3b1542d755b6 h1:PGpc3xvGh+vCwi+0MVgdLlMWYPfR+ATD46QHcIqfoAI=
github.com/crypto-org-chain/ethermint v0.22.1-0.20251204034614-3b1542d755b6/go.mod h1:avrVK14+Kwx8rn4B2uzkOVc/TLYPeLcf19dbAII+7lM=
github.com/crypto-org-chain/go-block-stm v0.0.0-20241213061541-7afe924fb4a6 h1:6KPEi8dWkDSBddQb4NAvEXmNnTXymF3yVeTaT4Hz1iU=
github.com/crypto-org-chain/go-block-stm v0.0.0-20241213061541-7afe924fb4a6/go.mod h1:iwQTX9xMX8NV9k3o2BiWXA0SswpsZrDk5q3gA7nWYiE=
github.com/crypto-org-chain/go-ethereum v1.10.20-0.20250815065500-a4fbafcae0dd h1:ebSnzvM9yKVGFjvoGly7LFQQCS2HuOWMCvQyByJ52Gs=
Expand Down Expand Up @@ -1610,6 +1608,8 @@ github.com/prometheus/procfs v0.3.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/randy-cro/ethermint v0.0.0-20251208045921-6a15b6334ab2 h1:bOBFJLwwT19gdT515OH2dN+rs7xXRlKWACytAL8yABE=
github.com/randy-cro/ethermint v0.0.0-20251208045921-6a15b6334ab2/go.mod h1:bfcBQITxYzsbXuF+VWOtL3EhBi9mEIOzsFT0UvB+mso=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM=
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
Expand Down Expand Up @@ -1666,8 +1666,8 @@ github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
Expand Down
10 changes: 5 additions & 5 deletions gomod2nix.toml
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,9 @@ schema = 3
version = "v0.2.2"
hash = "sha256-0MLfSJKdeK3Z7tWAXTdzwB4091dmyxIX38S5SKH5QAw="
[mod."github.com/evmos/ethermint"]
version = "v0.22.1-0.20251204034614-3b1542d755b6"
hash = "sha256-POcEnzlcWj4YdwdbekPlFzC9FehRJ4nYo4kyvqsUJDA="
replaced = "github.com/crypto-org-chain/ethermint"
version = "v0.0.0-20251208045921-6a15b6334ab2"
hash = "sha256-hB9qvklny56AP8MltiAQGhSx79SI68dj3l0ITXulSt0="
replaced = "github.com/randy-cro/ethermint"
[mod."github.com/fatih/color"]
version = "v1.17.0"
hash = "sha256-QsKMy3MsvjbYNcA9jP8w6c3wpmWDZ0079bybAEzmXR0="
Expand Down Expand Up @@ -625,8 +625,8 @@ schema = 3
version = "v1.10.0"
hash = "sha256-dQ6Qqf26IZsa6XsGKP7GDuCj+WmSsBmkBwGTDfue/rk="
[mod."github.com/spf13/cobra"]
version = "v1.10.1"
hash = "sha256-OP6wdqk4dvBD8U5aicTkySHZ2s0LWnBo2TST2SmgcpM="
version = "v1.10.2"
hash = "sha256-nbRCTFiDCC2jKK7AHi79n7urYCMP5yDZnWtNVJrDi+k="
[mod."github.com/spf13/pflag"]
version = "v1.0.10"
hash = "sha256-uDPnWjHpSrzXr17KEYEA1yAbizfcsfo5AyztY2tS6ZU="
Expand Down
262 changes: 262 additions & 0 deletions integration_tests/test_evm_params_int_64_overflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
"""
Integration tests for EVM module int64 overflow parameter validation.

This test suite validates that the EVM module properly handles different values
of the header_hash_num and history_serve_window parameters, including edge cases
that could cause int64 overflow.

Test scenarios (both parameters tested together):
1. value = 0 (valid, should succeed - no minimum check in ValidateInt64Overflow)
2. value = 100 (valid, should succeed)
3. value = MaxInt64 (valid, should succeed)
4. value = MaxInt64 + 1 (overflow case, should be rejected)
5. value = 2^64-1 (UINT64_MAX, overflow case, should be rejected)
"""

import pytest

from .cosmoscli import module_address
from .utils import submit_gov_proposal, wait_for_new_blocks

pytestmark = pytest.mark.evm

MAX_INT64 = (1 << 63) - 1 # 9223372036854775807
UINT64_MAX = (1 << 64) - 1 # 18446744073709551615


def get_evm_params(cli):
"""Query current EVM module parameters."""
params = cli.query_params("evm")
return params


def submit_evm_param_update(cronos, params):
"""
Submit a governance proposal to update EVM module parameters.

Args:
cronos: Cronos cluster instance
params: Complete params dict with updated values

Returns:
True if proposal passes, False if it fails
"""
authority = module_address("gov")
msg = "/ethermint.evm.v1.MsgUpdateParams"

try:
submit_gov_proposal(
cronos,
msg,
messages=[
{
"@type": msg,
"authority": authority,
"params": params,
}
],
)
return True
except (AssertionError, Exception) as e:
print(f"Proposal failed as expected: {e}")
return False


def prepare_evm_params(cli, header_hash_num, history_serve_window):
"""
Prepare EVM params for update by querying current params and applying updates.

Args:
cli: Cosmos CLI instance
header_hash_num: Value to set for header_hash_num
history_serve_window: Value to set for history_serve_window

Returns:
Updated params dict
"""
params = get_evm_params(cli)
params["header_hash_num"] = str(header_hash_num)
params["history_serve_window"] = str(history_serve_window)
return params


def test_evm_params_zero(cronos):
"""
Test that header_hash_num = 0 and history_serve_window = 0 are valid.

Zero is a valid value as ValidateInt64Overflow only checks for values
exceeding MaxInt64.
"""
cli = cronos.cosmos_cli()

# Get initial params
initial_params = get_evm_params(cli)
initial_header_hash_num = initial_params["header_hash_num"]
initial_history_serve_window = initial_params["history_serve_window"]
print(f"Initial header_hash_num: {initial_header_hash_num}")
print(f"Initial history_serve_window: {initial_history_serve_window}")

test_value = 0
print(f"Attempting to set both params to {test_value}")

params = prepare_evm_params(cli, test_value, test_value)
success = submit_evm_param_update(cronos, params)

# Should succeed (0 is valid)
assert success, f"Proposal should succeed for value = {test_value}"

wait_for_new_blocks(cli, 2)
updated_params = get_evm_params(cli)
print(f"Updated header_hash_num: {updated_params['header_hash_num']}")
print(f"Updated history_serve_window: {updated_params['history_serve_window']}")

assert updated_params["header_hash_num"] == str(
test_value
), f"header_hash_num should be {test_value}"
assert updated_params["history_serve_window"] == str(
test_value
), f"history_serve_window should be {test_value}"

# Verify chain continues to produce blocks
wait_for_new_blocks(cli, 3)
print(f"Chain continues to produce blocks with both params = {test_value}")


def test_evm_params_valid(cronos):
"""
Test that valid values (100) work correctly for both parameters.

This verifies that the parameter update mechanism works for valid values.
"""
cli = cronos.cosmos_cli()

# Get initial params
initial_params = get_evm_params(cli)
print(f"Initial header_hash_num: {initial_params['header_hash_num']}")
print(f"Initial history_serve_window: {initial_params['history_serve_window']}")

test_value = 100
print(f"Attempting to set both params to {test_value}")

params = prepare_evm_params(cli, test_value, test_value)
success = submit_evm_param_update(cronos, params)

assert success, f"Valid proposal should succeed with value {test_value}"

wait_for_new_blocks(cli, 2)
updated_params = get_evm_params(cli)
print(f"Updated header_hash_num: {updated_params['header_hash_num']}")
print(f"Updated history_serve_window: {updated_params['history_serve_window']}")

assert updated_params["header_hash_num"] == str(
test_value
), f"header_hash_num should be {test_value}"
assert updated_params["history_serve_window"] == str(
test_value
), f"history_serve_window should be {test_value}"

# Verify chain continues to produce blocks
wait_for_new_blocks(cli, 3)
print(f"Chain continues to produce blocks with both params = {test_value}")


def test_evm_params_max_int64_boundary(cronos):
"""
Test the boundary case: both params = MaxInt64.

This value should be valid as it's the maximum positive value
that fits in an int64.
"""
cli = cronos.cosmos_cli()

# Get initial params
initial_params = get_evm_params(cli)
print(f"Initial header_hash_num: {initial_params['header_hash_num']}")
print(f"Initial history_serve_window: {initial_params['history_serve_window']}")

test_value = MAX_INT64
print(f"Attempting to set both params to {test_value} (MaxInt64)")

params = prepare_evm_params(cli, test_value, test_value)
success = submit_evm_param_update(cronos, params)

assert success, f"Proposal should succeed with value = {test_value}"

wait_for_new_blocks(cli, 2)
updated_params = get_evm_params(cli)
print(f"Updated header_hash_num: {updated_params['header_hash_num']}")
print(f"Updated history_serve_window: {updated_params['history_serve_window']}")

assert updated_params["header_hash_num"] == str(
test_value
), f"header_hash_num should be {test_value}"
assert updated_params["history_serve_window"] == str(
test_value
), f"history_serve_window should be {test_value}"

wait_for_new_blocks(cli, 3)
print(f"Chain continues to produce blocks with both params = {test_value}")


def test_evm_params_just_over_max_int64(cronos):
"""
Test the edge case: both params = MaxInt64 + 1.

This is the smallest value that would overflow int64 and should be rejected.
"""
cli = cronos.cosmos_cli()

# Get initial params
initial_params = get_evm_params(cli)
initial_header_hash_num = initial_params["header_hash_num"]
initial_history_serve_window = initial_params["history_serve_window"]
print(f"Initial header_hash_num: {initial_header_hash_num}")
print(f"Initial history_serve_window: {initial_history_serve_window}")

overflow_value = MAX_INT64 + 1
print(f"Attempting to set both params to {overflow_value}")

params = prepare_evm_params(cli, overflow_value, overflow_value)
success = submit_evm_param_update(cronos, params)

assert not success, f"Proposal should fail for value = {overflow_value}"

wait_for_new_blocks(cli, 1)
current_params = get_evm_params(cli)
assert (
current_params["header_hash_num"] == initial_header_hash_num
), "header_hash_num should not change"
assert (
current_params["history_serve_window"] == initial_history_serve_window
), "history_serve_window should not change"


def test_evm_params_uint64_max(cronos):
"""
Test that both params = 2^64-1 (UINT64_MAX) is properly rejected.
"""
cli = cronos.cosmos_cli()

# Get initial params
initial_params = get_evm_params(cli)
initial_header_hash_num = initial_params["header_hash_num"]
initial_history_serve_window = initial_params["history_serve_window"]
print(f"Initial header_hash_num: {initial_header_hash_num}")
print(f"Initial history_serve_window: {initial_history_serve_window}")

overflow_value = UINT64_MAX
print(f"Attempting to set both params to {overflow_value} (2^64 - 1)")

params = prepare_evm_params(cli, overflow_value, overflow_value)
success = submit_evm_param_update(cronos, params)

assert not success, f"Proposal should fail for value = {overflow_value}"

wait_for_new_blocks(cli, 1)
current_params = get_evm_params(cli)
assert (
current_params["header_hash_num"] == initial_header_hash_num
), "header_hash_num should not change"
assert (
current_params["history_serve_window"] == initial_history_serve_window
), "history_serve_window should not change"
Loading