diff --git a/CHANGELOG.md b/CHANGELOG.md index 06a5b4824..438d42811 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,8 @@ ### BUG FIXES - [\#965](https://github.com/cosmos/evm/pull/965) Fix gas double charging on EVM calls in IBCOnTimeoutPacketCallback. +- [\#1032](https://github.com/cosmos/evm/issues/1032) Resolve EthTxIndex -1 sentinel before uint cast in ReceiptsFromCometBlock, preventing transactionIndex overflow to MaxUint64. +- [\#965](https://github.com/cosmos/evm/pull/965) Fix gas double charging on EVM calls in IBCOnTimeoutPacketCallback. - [\#869](https://github.com/cosmos/evm/pull/869) Fix erc20 IBC callbacks to check for native token transfer before parsing recipient. - [\#860](https://github.com/cosmos/evm/pull/860) Fix EIP-712 signature verification to use configured EVM chain ID instead of parsing cosmos chain ID string and replace legacytx.StdSignBytes with the aminojson sign mode handler. - [\#794](https://github.com/cosmos/evm/pull/794) Fix mempool.max-txs flag not using desired default of 0 diff --git a/rpc/backend/comet_to_eth.go b/rpc/backend/comet_to_eth.go index cb63feca1..b4065988d 100644 --- a/rpc/backend/comet_to_eth.go +++ b/rpc/backend/comet_to_eth.go @@ -275,6 +275,13 @@ func (b *Backend) ReceiptsFromCometBlock( return nil, fmt.Errorf("tx not found: hash=%s, error=%s", ethMsg.Hash(), err.Error()) } + // Resolve -1 sentinel: indexer hasn't assigned EthTxIndex yet. + // Use the loop index as the correct eth tx position, + // matching the existing fallback in GetTransactionByHash (tx_info.go). + if txResult.EthTxIndex == -1 { + txResult.EthTxIndex = int32(i) //#nosec G115 -- checked for int overflow already + } + cumulatedGasUsed += txResult.GasUsed var effectiveGasPrice *big.Int diff --git a/rpc/backend/tx_info_test.go b/rpc/backend/tx_info_test.go index 3f1dfae16..d715866f5 100644 --- a/rpc/backend/tx_info_test.go +++ b/rpc/backend/tx_info_test.go @@ -464,11 +464,12 @@ func TestReceiptsFromCometBlock(t *testing.T) { TxsResults: []*abcitypes.ExecTxResult{{Code: 0, Data: encodedData}}, } tcs := []struct { - name string - ethTxIndex int32 + name string + ethTxIndex int32 + expectedTxIndex uint }{ - {"tx_with_index_5", 5}, - {"tx_with_index_10", 10}, + {"tx_with_valid_index", 5, 5}, + {"tx_with_sentinel_index", -1, 0}, // -1 sentinel resolved to loop index } for _, tc := range tcs { t.Run(tc.name, func(t *testing.T) { @@ -492,9 +493,7 @@ func TestReceiptsFromCometBlock(t *testing.T) { receipts, err := backend.ReceiptsFromCometBlock(rpctypes.NewContextWithHeight(1), resBlock, blockRes, msgs) require.NoError(t, err) require.Len(t, receipts, 1) - actualTxIndex := receipts[0].TransactionIndex - require.NotEqual(t, uint(0), actualTxIndex) - require.Equal(t, uint(tc.ethTxIndex), actualTxIndex) // #nosec G115 + require.Equal(t, tc.expectedTxIndex, receipts[0].TransactionIndex) require.Equal(t, msgs[0].Hash(), receipts[0].TxHash) require.Equal(t, big.NewInt(height), receipts[0].BlockNumber) require.Equal(t, ethtypes.ReceiptStatusSuccessful, receipts[0].Status)