diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 91d4b9f..2b91080 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -37,8 +37,9 @@ jobs: - name: Test Unit run: make test - - name: Test Integration - run: KAVA_RPC_URL=http://50.16.212.18:26658 NETWORK=kava-mainnet PORT=4000 make test-integration + # TODO(yevhenii): point KAVA_RPC_URL to running kava node and uncomment + # - name: Test Integration + # run: KAVA_RPC_URL=http://50.16.212.18:26658 NETWORK=kava-mainnet PORT=4000 make test-integration lint: name: lint @@ -50,35 +51,35 @@ jobs: with: args: --timeout 3m0s - Rosetta-Validation: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v2 - with: - go-version: 1.21 - - - name: Cache Go Modules - uses: actions/cache@v2 - with: - path: ~/go/pkg/mod - key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} - restore-keys: | - ${{ runner.os }}-go- - - - name: Start Rosetta Server - run: .github/scripts/setup.sh - shell: bash - - - name: Run Check:construction test - run: .github/scripts/construction.sh - shell: bash - - - name: Run Check:data test - run: .github/scripts/cli.sh - shell: bash - - +# TODO(yevhenii): this is deprecated and doesn't work, remove? It also depends on the http://50.16.212.18:26658 node, +# which doesn't work at the moment. +# Rosetta-Validation: +# runs-on: ubuntu-latest +# timeout-minutes: 15 +# steps: +# - uses: actions/checkout@v3 +# +# - name: Set up Go +# uses: actions/setup-go@v2 +# with: +# go-version: 1.21 +# +# - name: Cache Go Modules +# uses: actions/cache@v2 +# with: +# path: ~/go/pkg/mod +# key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} +# restore-keys: | +# ${{ runner.os }}-go- +# +# - name: Start Rosetta Server +# run: .github/scripts/setup.sh +# shell: bash +# +# - name: Run Check:construction test +# run: .github/scripts/construction.sh +# shell: bash +# +# - name: Run Check:data test +# run: .github/scripts/cli.sh +# shell: bash diff --git a/kava/client.go b/kava/client.go index 4fc2100..f3f266f 100644 --- a/kava/client.go +++ b/kava/client.go @@ -26,6 +26,10 @@ import ( "time" "github.com/coinbase/rosetta-sdk-go/types" + abci "github.com/cometbft/cometbft/abci/types" + ctypes "github.com/cometbft/cometbft/rpc/core/types" + tmrpctypes "github.com/cometbft/cometbft/rpc/jsonrpc/types" + tmtypes "github.com/cometbft/cometbft/types" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authante "github.com/cosmos/cosmos-sdk/x/auth/ante" @@ -34,10 +38,6 @@ import ( banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" kava "github.com/kava-labs/kava/app" "github.com/kava-labs/kava/app/params" - abci "github.com/cometbft/cometbft/abci/types" - ctypes "github.com/cometbft/cometbft/rpc/core/types" - tmrpctypes "github.com/cometbft/cometbft/rpc/jsonrpc/types" - tmtypes "github.com/cometbft/cometbft/types" ) var noBlockResultsForHeight = regexp.MustCompile(`could not find results for height #(\d+)`) @@ -395,7 +395,10 @@ func (c *Client) getOperationsForTransaction( if result.Codespace == sdkerrors.RootCodespace { switch result.Code { - case sdkerrors.ErrInvalidSequence.ABCICode(), sdkerrors.ErrInsufficientFee.ABCICode(), sdkerrors.ErrWrongSequence.ABCICode(): + case sdkerrors.ErrInvalidSequence.ABCICode(), + sdkerrors.ErrInsufficientFee.ABCICode(), + sdkerrors.ErrTxTimeoutHeight.ABCICode(), + sdkerrors.ErrWrongSequence.ABCICode(): feeStatus = FailureStatus // For unauthorized, insufficient funds, out of gas, we must check events in order to know if fee was paid or or not paid case sdkerrors.ErrUnauthorized.ABCICode(), sdkerrors.ErrInsufficientFunds.ABCICode(), sdkerrors.ErrOutOfGas.ABCICode(): diff --git a/kava/client_test.go b/kava/client_test.go index 8d20696..3cd7fe2 100644 --- a/kava/client_test.go +++ b/kava/client_test.go @@ -29,13 +29,6 @@ import ( sdkmath "cosmossdk.io/math" "github.com/coinbase/rosetta-sdk-go/types" - sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" - authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" - banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - app "github.com/kava-labs/kava/app" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/libs/bytes" "github.com/cometbft/cometbft/p2p" @@ -43,6 +36,14 @@ import ( tmrpctypes "github.com/cometbft/cometbft/rpc/jsonrpc/types" tmstate "github.com/cometbft/cometbft/state" tmtypes "github.com/cometbft/cometbft/types" + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/x/auth/migrations/legacytx" + authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" + app "github.com/kava-labs/kava/app" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) const ( @@ -891,6 +892,89 @@ func TestBlock_Transactions(t *testing.T) { }) } +func TestBlock_TxTimeoutHeight(t *testing.T) { + ctx := context.Background() + mockRPCClient, _, client := setupClient(t) + encodingConfig := app.MakeEncodingConfig() + + txBuilder := encodingConfig.TxConfig.NewTxBuilder() + err := txBuilder.SetMsgs(&banktypes.MsgSend{ + FromAddress: sdk.AccAddress("test from address").String(), + ToAddress: sdk.AccAddress("test to address").String(), + Amount: sdk.Coins{sdk.NewCoin("ukava", sdkmath.NewInt(100))}, + }) + require.NoError(t, err) + txBuilder.SetGasLimit(100000) + txBuilder.SetFeeAmount(sdk.Coins{sdk.Coin{Denom: "ukava", Amount: sdkmath.NewInt(5000)}}) + txBuilder.SetMemo("tx timeout height") + + var rawMockTx tmtypes.Tx + rawMockTx, err = encodingConfig.TxConfig.TxEncoder()(txBuilder.GetTx()) + require.NoError(t, err) + mockDeliverTx := &abci.ResponseDeliverTx{ + Code: sdkerrors.ErrTxTimeoutHeight.ABCICode(), + Log: sdkerrors.ErrTxTimeoutHeight.Error(), + Codespace: sdkerrors.RootCodespace, + } + + parentBlockIdentifier := &types.BlockIdentifier{ + Index: 99, + Hash: "8EA67B6F7927DB941F86501D1757AC6804C1D21B7A75B9DA3F16A3C81C397E50", + } + parentHashBytes, err := hex.DecodeString(parentBlockIdentifier.Hash) + require.NoError(t, err) + + blockIdentifier := &types.BlockIdentifier{ + Index: 100, + Hash: "D92BDF0B5EDB04434B398A59B2FD4ED3D52B4820A18DAC7311EBDF5D37467E75", + } + blockTime := time.Now() + hashBytes, err := hex.DecodeString(blockIdentifier.Hash) + require.NoError(t, err) + + mockRawTransactions := []tmtypes.Tx{rawMockTx} + mockResultBlock := &ctypes.ResultBlock{ + BlockID: tmtypes.BlockID{ + Hash: hashBytes, + }, + Block: &tmtypes.Block{ + Header: tmtypes.Header{ + Height: blockIdentifier.Index, + Time: blockTime, + LastBlockID: tmtypes.BlockID{ + Hash: parentHashBytes, + }, + }, + Data: tmtypes.Data{ + Txs: mockRawTransactions, + }, + }, + } + + mockDeliverTxs := []*abci.ResponseDeliverTx{mockDeliverTx} + mockResultBlockResults := &ctypes.ResultBlockResults{ + TxsResults: mockDeliverTxs, + BeginBlockEvents: []abci.Event{abci.Event{}}, + EndBlockEvents: []abci.Event{abci.Event{}}, + } + + mockRPCClient.On("Block", ctx, &blockIdentifier.Index).Return(mockResultBlock, nil).Once() + mockRPCClient.On("BlockResults", ctx, &blockIdentifier.Index).Return(mockResultBlockResults, nil).Once() + + blockResponse, err := client.Block(ctx, &types.PartialBlockIdentifier{Index: &blockIdentifier.Index}) + require.NoError(t, err) + require.Equal(t, 1, len(blockResponse.Block.Transactions)) + + // it should be 1 tx with 4 ops - 2 fee ops and 2 transfer ops + tx := blockResponse.Block.Transactions[0] + assert.Equal(t, len(tx.Operations), 4) + + // all 4 ops should be with failure status, because tx failed TxTimeoutHeight AnteHandler and fee is not charged in such case + for _, operation := range tx.Operations { + assert.Equal(t, kava.FailureStatus, *operation.Status) + } +} + func TestBlock_BlockResultsRetry(t *testing.T) { parentBlockIdentifier := &types.BlockIdentifier{ Index: 99,