diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a2e33f1c88d..262057c189a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: go-version: '1.22' - name: Release - uses: goreleaser/goreleaser-action@v5 + uses: goreleaser/goreleaser-action@v6 if: startsWith(github.ref, 'refs/tags/') with: version: latest diff --git a/e2e/go.mod b/e2e/go.mod index 95715c11a86..787bdd1a019 100644 --- a/e2e/go.mod +++ b/e2e/go.mod @@ -19,7 +19,7 @@ require ( github.com/strangelove-ventures/interchaintest/v8 v8.2.1-0.20240419152858-c8b741617cd8 github.com/stretchr/testify v1.9.0 go.uber.org/zap v1.27.0 - golang.org/x/mod v0.17.0 + golang.org/x/mod v0.18.0 google.golang.org/grpc v1.64.0 gopkg.in/yaml.v2 v2.4.0 ) diff --git a/e2e/go.sum b/e2e/go.sum index d14f64a0d75..53cb6a3a4b7 100644 --- a/e2e/go.sum +++ b/e2e/go.sum @@ -1211,8 +1211,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= -golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= +golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/modules/apps/transfer/ibc_module_test.go b/modules/apps/transfer/ibc_module_test.go index 43fae9a3d2b..9ec0430be5f 100644 --- a/modules/apps/transfer/ibc_module_test.go +++ b/modules/apps/transfer/ibc_module_test.go @@ -4,6 +4,8 @@ import ( "errors" "math" + sdkmath "cosmossdk.io/math" + "github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1" sdk "github.com/cosmos/cosmos-sdk/types" @@ -14,6 +16,7 @@ import ( channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" porttypes "github.com/cosmos/ibc-go/v8/modules/core/05-port/types" host "github.com/cosmos/ibc-go/v8/modules/core/24-host" + ibcerrors "github.com/cosmos/ibc-go/v8/modules/core/errors" ibctesting "github.com/cosmos/ibc-go/v8/testing" ) @@ -230,9 +233,11 @@ func (suite *TransferTestSuite) TestOnChanOpenAck() { "success", func() {}, nil, }, { - "invalid counterparty version", func() { + "invalid counterparty version", + func() { counterpartyVersion = "version" - }, types.ErrInvalidVersion, + }, + types.ErrInvalidVersion, }, } @@ -268,6 +273,99 @@ func (suite *TransferTestSuite) TestOnChanOpenAck() { } } +func (suite *TransferTestSuite) TestOnTimeoutPacket() { + var path *ibctesting.Path + var packet channeltypes.Packet + + testCases := []struct { + name string + malleate func() + expError error + }{ + { + "success", + func() {}, + nil, + }, + { + "non-existent channel", + func() { + packet.SourceChannel = "channel-100" + }, + ibcerrors.ErrNotFound, + }, + { + "invalid packet data", + func() { + packet.Data = []byte("invalid data") + }, + ibcerrors.ErrInvalidType, + }, + { + "already timed-out packet", + func() { + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.TransferPort) + suite.Require().NoError(err) + + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + + suite.Require().NoError(cbs.OnTimeoutPacket(suite.chainA.GetContext(), packet, suite.chainA.SenderAccount.GetAddress())) + }, + errors.New("unable to unescrow tokens"), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.SetupTest() // reset + + path = ibctesting.NewTransferPath(suite.chainA, suite.chainB) + path.Setup() + + coinToSendToB := sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(42)) + timeoutHeight := suite.chainA.GetTimeoutHeight() + msg := types.NewMsgTransfer( + path.EndpointA.ChannelConfig.PortID, + path.EndpointA.ChannelID, + sdk.NewCoins(coinToSendToB), + suite.chainA.SenderAccount.GetAddress().String(), + suite.chainB.SenderAccount.GetAddress().String(), + timeoutHeight, + 0, + "") + res, err := suite.chainA.SendMsgs(msg) + suite.Require().NoError(err) // message committed + + packet, err = ibctesting.ParsePacketFromEvents(res.Events) + suite.Require().NoError(err) + + module, _, err := suite.chainA.App.GetIBCKeeper().PortKeeper.LookupModuleByPort(suite.chainA.GetContext(), ibctesting.TransferPort) + suite.Require().NoError(err) + + cbs, ok := suite.chainA.App.GetIBCKeeper().PortKeeper.Route(module) + suite.Require().True(ok) + + tc.malleate() // change fields in packet + + err = cbs.OnTimeoutPacket(suite.chainA.GetContext(), packet, suite.chainA.SenderAccount.GetAddress()) + + expPass := tc.expError == nil + if expPass { + suite.Require().NoError(err) + + escrowAddress := types.GetEscrowAddress(packet.GetSourcePort(), packet.GetSourceChannel()) + escrowBalanceAfter := suite.chainA.GetSimApp().BankKeeper.GetBalance(suite.chainA.GetContext(), escrowAddress, sdk.DefaultBondDenom) + suite.Require().Equal(sdkmath.NewInt(0), escrowBalanceAfter.Amount) + } else { + suite.Require().Error(err) + suite.Require().Contains(err.Error(), tc.expError.Error()) + } + }) + } +} + func (suite *TransferTestSuite) TestOnChanUpgradeInit() { var path *ibctesting.Path diff --git a/modules/apps/transfer/internal/telemetry/telemetry.go b/modules/apps/transfer/internal/telemetry/telemetry.go new file mode 100644 index 00000000000..c031f3f8b10 --- /dev/null +++ b/modules/apps/transfer/internal/telemetry/telemetry.go @@ -0,0 +1,47 @@ +package telemetry + +import ( + "github.com/hashicorp/go-metrics" + + sdkmath "cosmossdk.io/math" + + "github.com/cosmos/cosmos-sdk/telemetry" + + "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" + coretypes "github.com/cosmos/ibc-go/v8/modules/core/types" +) + +func ReportTransferTelemetry(tokens types.Tokens, labels []metrics.Label) { + for _, token := range tokens { + amount, ok := sdkmath.NewIntFromString(token.Amount) + if ok && amount.IsInt64() { + telemetry.SetGaugeWithLabels( + []string{"tx", "msg", "ibc", "transfer"}, + float32(amount.Int64()), + []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, token.Denom.Path())}, + ) + } + } + + telemetry.IncrCounterWithLabels( + []string{"ibc", types.ModuleName, "send"}, + 1, + labels, + ) +} + +func ReportOnRecvPacketTelemetry(transferAmount sdkmath.Int, denomPath string, labels []metrics.Label) { + if transferAmount.IsInt64() { + telemetry.SetGaugeWithLabels( + []string{"ibc", types.ModuleName, "packet", "receive"}, + float32(transferAmount.Int64()), + []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, denomPath)}, + ) + } + + telemetry.IncrCounterWithLabels( + []string{"ibc", types.ModuleName, "receive"}, + 1, + labels, + ) +} diff --git a/modules/apps/transfer/keeper/relay.go b/modules/apps/transfer/keeper/relay.go index a9d57e66084..3b3d3fca1aa 100644 --- a/modules/apps/transfer/keeper/relay.go +++ b/modules/apps/transfer/keeper/relay.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - metrics "github.com/hashicorp/go-metrics" + "github.com/hashicorp/go-metrics" errorsmod "cosmossdk.io/errors" sdkmath "cosmossdk.io/math" @@ -13,6 +13,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/internal/events" + internaltelemetry "github.com/cosmos/ibc-go/v8/modules/apps/transfer/internal/telemetry" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" clienttypes "github.com/cosmos/ibc-go/v8/modules/core/02-client/types" channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" @@ -147,24 +148,7 @@ func (k Keeper) sendTransfer( events.EmitTransferEvent(ctx, sender.String(), receiver, tokens, memo) - defer func() { - for _, token := range tokens { - amount, ok := sdkmath.NewIntFromString(token.Amount) - if ok && amount.IsInt64() { - telemetry.SetGaugeWithLabels( - []string{"tx", "msg", "ibc", "transfer"}, - float32(amount.Int64()), - []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, token.Denom.Path())}, - ) - } - } - - telemetry.IncrCounterWithLabels( - []string{"ibc", types.ModuleName, "send"}, - 1, - labels, - ) - }() + defer internaltelemetry.ReportTransferTelemetry(tokens, labels) return sequence, nil } @@ -227,23 +211,8 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t } denomPath := token.Denom.Path() - defer func() { - if transferAmount.IsInt64() { - telemetry.SetGaugeWithLabels( - []string{"ibc", types.ModuleName, "packet", "receive"}, - float32(transferAmount.Int64()), - []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, denomPath)}, - ) - } - - telemetry.IncrCounterWithLabels( - []string{"ibc", types.ModuleName, "receive"}, - 1, - append( - labels, telemetry.NewLabel(coretypes.LabelSource, "true"), - ), - ) - }() + labels = append(labels, telemetry.NewLabel(coretypes.LabelSource, "true")) + defer internaltelemetry.ReportOnRecvPacketTelemetry(transferAmount, denomPath, labels) // Continue processing rest of tokens in packet data. continue @@ -283,23 +252,8 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t } denomPath := token.Denom.Path() - defer func() { - if transferAmount.IsInt64() { - telemetry.SetGaugeWithLabels( - []string{"ibc", types.ModuleName, "packet", "receive"}, - float32(transferAmount.Int64()), - []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, denomPath)}, - ) - } - - telemetry.IncrCounterWithLabels( - []string{"ibc", types.ModuleName, "receive"}, - 1, - append( - labels, telemetry.NewLabel(coretypes.LabelSource, "false"), - ), - ) - }() + labels = append(labels, telemetry.NewLabel(coretypes.LabelSource, "false")) + defer internaltelemetry.ReportOnRecvPacketTelemetry(transferAmount, denomPath, labels) } return nil