Skip to content
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
- [\#1061](https://github.com/cosmos/evm/pull/1061) Block nested ICS20 forwarding in source callbacks.
- [\#1050](https://github.com/cosmos/evm/pull/1050) Align precompile gas calculation with expected EVM gas semantics.
- [\#1107](https://github.com/cosmos/evm/pull/1107) Skip StateDB commit error transactions during receipt conversion to prevent `invalid message index` errors in block RPCs.
- [\#1183](https://github.com/cosmos/evm/pull/1183) Align eth_call's KV gas accounting with deliverTx so it stops rejecting valid estimateGas results for native precompile txs.


## v0.6.0
Expand Down
35 changes: 35 additions & 0 deletions tests/integration/x/vm/test_grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import (
"github.com/holiman/uint256"
"github.com/stretchr/testify/require"

bankprecompile "github.com/cosmos/evm/precompiles/bank"
"github.com/cosmos/evm/server/config"
testconstants "github.com/cosmos/evm/testutil/constants"
"github.com/cosmos/evm/testutil/integration/evm/factory"
Expand Down Expand Up @@ -2211,6 +2212,40 @@ func (s *KeeperTestSuite) TestEthCall() {
}
}

// TestEthCallGasMatchesDeliverTxForNativePrecompile asserts that EthCall and
// a broadcasted tx report the same GasUsed when targeting a native precompile,
// covering the BuildEvmExecutionCtx call added to EthCall.
func (s *KeeperTestSuite) TestEthCallGasMatchesDeliverTxForNativePrecompile() {
s.SetupTest()

sender := s.Keyring.GetKey(0)
to := common.HexToAddress(types.BankPrecompileAddress)
data, err := bankprecompile.ABI.Pack(bankprecompile.BalancesMethod, sender.Addr)
s.Require().NoError(err)

gas := hexutil.Uint64(500_000)
args, err := json.Marshal(&types.TransactionArgs{
From: &sender.Addr, To: &to, Data: (*hexutil.Bytes)(&data), Gas: &gas,
})
s.Require().NoError(err)

callRes, err := s.Network.GetEvmClient().EthCall(s.Network.GetContext(), &types.EthCallRequest{
Args: args, GasCap: config.DefaultGasCap,
})
s.Require().NoError(err)
s.Require().Empty(callRes.VmError)

txRes, err := s.Factory.ExecuteEthTx(sender.Priv, types.EvmTxArgs{
To: &to, GasLimit: uint64(gas), Input: data,
})
s.Require().NoError(err)
deliverRes, err := types.DecodeTxResponse(txRes.Data)
s.Require().NoError(err)
s.Require().Empty(deliverRes.VmError)

s.Require().Equal(deliverRes.GasUsed, callRes.GasUsed)
}

func (s *KeeperTestSuite) TestBalance() {
testCases := []struct {
name string
Expand Down
6 changes: 6 additions & 0 deletions x/vm/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,12 @@ func (k Keeper) EthCall(c context.Context, req *types.EthCallRequest) (_ *types.
}
}

// Align eth_call's KV gas accounting with deliverTx: clear KV/transient gas
// configs so EVM-internal cosmos-sdk store ops (e.g. precompile.FlushToCacheCtx)
// don't charge gas. Otherwise eth_call would report a stricter floor than
// real broadcast for txs reaching native precompiles.
ctx = evmante.BuildEvmExecutionCtx(ctx)

var args types.TransactionArgs
err = json.Unmarshal(req.Args, &args)
if err != nil {
Expand Down
24 changes: 24 additions & 0 deletions x/vm/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package keeper

import (
"testing"

"github.com/stretchr/testify/require"

storetypes "github.com/cosmos/cosmos-sdk/store/v2/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)

// buildTraceCtx must zero KV gas configs so simulation matches deliverTx
// (whose ante also zeroes KV via BuildEvmExecutionCtx). SLOAD/SSTORE gas
// accounting then remains opcode-driven and does not consume KV gas, and
// pre-precompile cosmos-sdk store ops (e.g. stateDB.FlushToCacheCtx) are
// free — same as on real chain.
func TestBuildTraceCtxZeroesKVGasConfig(t *testing.T) {
parent := sdk.Context{}.
WithKVGasConfig(storetypes.KVGasConfig()).
WithTransientKVGasConfig(storetypes.TransientGasConfig())
traceCtx := buildTraceCtx(parent, 1_000_000)
require.Equal(t, storetypes.GasConfig{}, traceCtx.KVGasConfig())
require.Equal(t, storetypes.GasConfig{}, traceCtx.TransientKVGasConfig())
}
Loading