diff --git a/.github/workflows/proto-registry.yml b/.github/workflows/proto-registry.yml index 2031be3083c..0570dd9b76f 100644 --- a/.github/workflows/proto-registry.yml +++ b/.github/workflows/proto-registry.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: bufbuild/buf-setup-action@v1.32.1 + - uses: bufbuild/buf-setup-action@v1.32.2 - uses: bufbuild/buf-push-action@v1 with: input: "proto" diff --git a/modules/apps/callbacks/ibc_middleware_test.go b/modules/apps/callbacks/ibc_middleware_test.go index 74051f3942a..98a31b79918 100644 --- a/modules/apps/callbacks/ibc_middleware_test.go +++ b/modules/apps/callbacks/ibc_middleware_test.go @@ -1007,7 +1007,7 @@ func (s *CallbacksTestSuite) TestUnmarshalPacketDataV1() { Tokens: []transfertypes.Token{ { Denom: transfertypes.Denom{ - Base: ibctesting.TestCoin.Denom, + Base: ibctesting.TestCoin.GetDenom(), Trace: nil, }, Amount: ibctesting.TestCoin.Amount.String(), @@ -1043,7 +1043,7 @@ func (s *CallbacksTestSuite) TestUnmarshalPacketDataV2() { Tokens: []transfertypes.Token{ { Denom: transfertypes.Denom{ - Base: ibctesting.TestCoin.Denom, + Base: ibctesting.TestCoin.GetDenom(), Trace: nil, }, Amount: ibctesting.TestCoin.Amount.String(), diff --git a/modules/apps/callbacks/types/callbacks_test.go b/modules/apps/callbacks/types/callbacks_test.go index be4098f9bc9..be01f892189 100644 --- a/modules/apps/callbacks/types/callbacks_test.go +++ b/modules/apps/callbacks/types/callbacks_test.go @@ -13,6 +13,7 @@ import ( transfertypes "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" + ibcexported "github.com/cosmos/ibc-go/v8/modules/core/exported" ibctesting "github.com/cosmos/ibc-go/v8/testing" ibcmock "github.com/cosmos/ibc-go/v8/testing/mock" ) @@ -250,6 +251,287 @@ func (s *CallbacksTypesTestSuite) TestGetCallbackData() { types.CallbackData{}, types.ErrCallbackAddressNotFound, }, + + { + "success: source callback", + func() { + remainingGas = 2_000_000 + packetData = transfertypes.FungibleTokenPacketData{ + Denom: ibctesting.TestCoin.Denom, + Amount: ibctesting.TestCoin.Amount.String(), + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"src_callback": {"address": "%s"}}`, sender), + } + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: sender, + ExecutionGasLimit: 1_000_000, + CommitGasLimit: 1_000_000, + }, + nil, + }, + { + "success: destination callback", + func() { + callbackKey = types.DestinationCallbackKey + + remainingGas = 2_000_000 + packetData = transfertypes.FungibleTokenPacketData{ + Denom: ibctesting.TestCoin.Denom, + Amount: ibctesting.TestCoin.Amount.String(), + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"dest_callback": {"address": "%s"}}`, sender), + } + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: "", + ExecutionGasLimit: 1_000_000, + CommitGasLimit: 1_000_000, + }, + nil, + }, + { + "success v2: destination callback with 0 user defined gas limit", + func() { + callbackKey = types.DestinationCallbackKey + + remainingGas = 2_000_000 + packetData = transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + }, + Amount: ibctesting.TestCoin.Amount.String(), + }, + }, + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"dest_callback": {"address": "%s", "gas_limit":"0"}}`, sender), + } + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: "", + ExecutionGasLimit: 1_000_000, + CommitGasLimit: 1_000_000, + }, + nil, + }, + { + "success v2: source callback with gas limit < remaining gas < max gas", + func() { + packetData = transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + }, + Amount: ibctesting.TestCoin.Amount.String(), + }, + }, + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"src_callback": {"address": "%s", "gas_limit": "50000"}}`, sender), + } + + remainingGas = 100_000 + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: sender, + ExecutionGasLimit: 50_000, + CommitGasLimit: 50_000, + }, + nil, + }, + { + "success v2: source callback with remaining gas < gas limit < max gas", + func() { + remainingGas = 100_000 + packetData = transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + }, + Amount: ibctesting.TestCoin.Amount.String(), + }, + }, + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"src_callback": {"address": "%s", "gas_limit": "200000"}}`, sender), + } + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: sender, + ExecutionGasLimit: 100_000, + CommitGasLimit: 200_000, + }, + nil, + }, + { + "success v2: source callback with remaining gas < max gas < gas limit", + func() { + remainingGas = 100_000 + packetData = transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + }, + Amount: ibctesting.TestCoin.Amount.String(), + }, + }, + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"src_callback": {"address": "%s", "gas_limit": "2000000"}}`, sender), + } + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: sender, + ExecutionGasLimit: 100_000, + CommitGasLimit: 1_000_000, + }, + nil, + }, + { + "success v2: destination callback with remaining gas < max gas < gas limit", + func() { + callbackKey = types.DestinationCallbackKey + + remainingGas = 100_000 + packetData = transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + }, + Amount: ibctesting.TestCoin.Amount.String(), + }, + }, + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"dest_callback": {"address": "%s", "gas_limit": "2000000"}}`, sender), + } + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: "", + ExecutionGasLimit: 100_000, + CommitGasLimit: 1_000_000, + }, + nil, + }, + { + "success v2: source callback with max gas < remaining gas < gas limit", + func() { + remainingGas = 2_000_000 + packetData = transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + }, + Amount: ibctesting.TestCoin.Amount.String(), + }, + }, + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"src_callback": {"address": "%s", "gas_limit": "3000000"}}`, sender), + } + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: sender, + ExecutionGasLimit: 1_000_000, + CommitGasLimit: 1_000_000, + }, + nil, + }, + { + "failure: packet data does not implement PacketDataProvider", + func() { + packetData = ibcmock.MockPacketData + }, + types.CallbackData{}, + types.ErrNotPacketDataProvider, + }, + { + "failure v2: empty memo", + func() { + packetData = transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + }, + Amount: ibctesting.TestCoin.Amount.String(), + }, + }, + Sender: sender, + Receiver: receiver, + Memo: "", + } + }, + types.CallbackData{}, + types.ErrCallbackKeyNotFound, + }, + { + "failure v2: empty address", + func() { + packetData = transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + }, + Amount: ibctesting.TestCoin.Amount.String(), + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {"address": ""}}`, + } + }, + types.CallbackData{}, + types.ErrCallbackAddressNotFound, + }, + { + "failure v2: space address", + func() { + packetData = transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + }, + Amount: ibctesting.TestCoin.Amount.String(), + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {"address": " "}}`, + } + }, + types.CallbackData{}, + types.ErrCallbackAddressNotFound, + }, } for _, tc := range testCases { @@ -277,109 +559,206 @@ func (s *CallbacksTypesTestSuite) TestGetCallbackData() { } } -func (s *CallbacksTypesTestSuite) TestGetSourceCallbackDataTransfer() { - s.SetupTest() +// bytesProvider defines an interface that both packet data types implement in order to fetch the bytes. +type bytesProvider interface { + GetBytes() []byte +} +func (s *CallbacksTypesTestSuite) TestGetSourceCallbackDataTransfer() { sender := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String() receiver := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String() - packetData := transfertypes.FungibleTokenPacketData{ - Denom: ibctesting.TestCoin.Denom, - Amount: ibctesting.TestCoin.Amount.String(), - Sender: sender, - Receiver: receiver, - Memo: fmt.Sprintf(`{"src_callback": {"address": "%s"}}`, sender), + testCases := []struct { + name string + packetData bytesProvider + expCallbackData types.CallbackData + malleate func() + }{ + { + "success: v1", + transfertypes.FungibleTokenPacketData{ + Denom: ibctesting.TestCoin.Denom, + Amount: ibctesting.TestCoin.Amount.String(), + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"src_callback": {"address": "%s"}}`, sender), + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: sender, + ExecutionGasLimit: 1_000_000, + CommitGasLimit: 1_000_000, + }, + func() { + s.path.EndpointA.ChannelConfig.Version = transfertypes.V1 + s.path.EndpointA.ChannelConfig.PortID = transfertypes.ModuleName + s.path.EndpointB.ChannelConfig.Version = transfertypes.V1 + s.path.EndpointB.ChannelConfig.PortID = transfertypes.ModuleName + }, + }, + { + "success: v2", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + }, + Amount: ibctesting.TestCoin.Amount.String(), + }, + }, + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"src_callback": {"address": "%s"}}`, sender), + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: sender, + ExecutionGasLimit: 1_000_000, + CommitGasLimit: 1_000_000, + }, + func() { + s.path.EndpointA.ChannelConfig.Version = transfertypes.V2 + s.path.EndpointA.ChannelConfig.PortID = transfertypes.ModuleName + s.path.EndpointB.ChannelConfig.Version = transfertypes.V2 + s.path.EndpointB.ChannelConfig.PortID = transfertypes.ModuleName + }, + }, } - packetDataBytes := packetData.GetBytes() - expCallbackData := types.CallbackData{ - CallbackAddress: sender, - SenderAddress: sender, - ExecutionGasLimit: 1_000_000, - CommitGasLimit: 1_000_000, - } + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + s.SetupTest() - s.path.EndpointA.ChannelConfig.Version = transfertypes.V1 - s.path.EndpointA.ChannelConfig.PortID = transfertypes.ModuleName - s.path.EndpointB.ChannelConfig.Version = transfertypes.V1 - s.path.EndpointB.ChannelConfig.PortID = transfertypes.ModuleName + tc.malleate() - transferStack, ok := s.chainA.App.GetIBCKeeper().PortKeeper.Route(transfertypes.ModuleName) - s.Require().True(ok) + packetDataBytes := tc.packetData.GetBytes() - packetUnmarshaler, ok := transferStack.(types.CallbacksCompatibleModule) - s.Require().True(ok) + transferStack, ok := s.chainA.App.GetIBCKeeper().PortKeeper.Route(transfertypes.ModuleName) + s.Require().True(ok) - s.path.Setup() + packetUnmarshaler, ok := transferStack.(types.CallbacksCompatibleModule) + s.Require().True(ok) - // Set up gas meter for context. - gasMeter := storetypes.NewGasMeter(2_000_000) - ctx := s.chainA.GetContext().WithGasMeter(gasMeter) + s.path.Setup() - packet := channeltypes.NewPacket(packetDataBytes, 0, transfertypes.PortID, s.path.EndpointA.ChannelID, transfertypes.PortID, s.path.EndpointB.ChannelID, clienttypes.ZeroHeight(), 0) - callbackData, err := types.GetSourceCallbackData(ctx, packetUnmarshaler, packet, 1_000_000) - s.Require().NoError(err) - s.Require().Equal(expCallbackData, callbackData) + gasMeter := storetypes.NewGasMeter(2_000_000) + ctx := s.chainA.GetContext().WithGasMeter(gasMeter) + packet := channeltypes.NewPacket(packetDataBytes, 0, transfertypes.PortID, s.path.EndpointA.ChannelID, transfertypes.PortID, s.path.EndpointB.ChannelID, clienttypes.ZeroHeight(), 0) + callbackData, err := types.GetSourceCallbackData(ctx, packetUnmarshaler, packet, 1_000_000) + s.Require().NoError(err) + s.Require().Equal(tc.expCallbackData, callbackData) + }) + } } func (s *CallbacksTypesTestSuite) TestGetDestCallbackDataTransfer() { - s.SetupTest() - sender := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String() receiver := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String() - packetData := transfertypes.FungibleTokenPacketData{ - Denom: ibctesting.TestCoin.Denom, - Amount: ibctesting.TestCoin.Amount.String(), - Sender: sender, - Receiver: receiver, - Memo: fmt.Sprintf(`{"dest_callback": {"address": "%s"}}`, sender), + testCases := []struct { + name string + packetData bytesProvider + expCallbackdata types.CallbackData + malleate func() + }{ + { + "success: v1", + transfertypes.FungibleTokenPacketData{ + Denom: ibctesting.TestCoin.Denom, + Amount: ibctesting.TestCoin.Amount.String(), + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"dest_callback": {"address": "%s"}}`, sender), + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: "", + ExecutionGasLimit: 1_000_000, + CommitGasLimit: 1_000_000, + }, + func() { + s.path.EndpointA.ChannelConfig.Version = transfertypes.V1 + s.path.EndpointA.ChannelConfig.PortID = transfertypes.ModuleName + s.path.EndpointB.ChannelConfig.Version = transfertypes.V1 + s.path.EndpointB.ChannelConfig.PortID = transfertypes.ModuleName + }, + }, + { + "success: v2", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + }, + Amount: ibctesting.TestCoin.Amount.String(), + }, + }, + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"dest_callback": {"address": "%s"}}`, sender), + }, + types.CallbackData{ + CallbackAddress: sender, + SenderAddress: "", + ExecutionGasLimit: 1_000_000, + CommitGasLimit: 1_000_000, + }, + func() { + s.path.EndpointA.ChannelConfig.Version = transfertypes.V2 + s.path.EndpointA.ChannelConfig.PortID = transfertypes.ModuleName + s.path.EndpointB.ChannelConfig.Version = transfertypes.V2 + s.path.EndpointB.ChannelConfig.PortID = transfertypes.ModuleName + }, + }, } - packetDataBytes := packetData.GetBytes() - expCallbackData := types.CallbackData{ - CallbackAddress: sender, - SenderAddress: "", - ExecutionGasLimit: 1_000_000, - CommitGasLimit: 1_000_000, - } + for _, tc := range testCases { + tc := tc + s.Run(tc.name, func() { + s.SetupTest() - s.path.EndpointA.ChannelConfig.Version = transfertypes.V1 - s.path.EndpointA.ChannelConfig.PortID = transfertypes.ModuleName - s.path.EndpointB.ChannelConfig.Version = transfertypes.V1 - s.path.EndpointB.ChannelConfig.PortID = transfertypes.ModuleName + tc.malleate() + + packetDataBytes := tc.packetData.GetBytes() - transferStack, ok := s.chainA.App.GetIBCKeeper().PortKeeper.Route(transfertypes.ModuleName) - s.Require().True(ok) + transferStack, ok := s.chainA.App.GetIBCKeeper().PortKeeper.Route(transfertypes.ModuleName) + s.Require().True(ok) - packetUnmarshaler, ok := transferStack.(types.CallbacksCompatibleModule) - s.Require().True(ok) + packetUnmarshaler, ok := transferStack.(types.CallbacksCompatibleModule) + s.Require().True(ok) - s.path.Setup() + s.path.Setup() - gasMeter := storetypes.NewGasMeter(2_000_000) - ctx := s.chainA.GetContext().WithGasMeter(gasMeter) - packet := channeltypes.NewPacket(packetDataBytes, 0, transfertypes.PortID, s.path.EndpointA.ChannelID, transfertypes.PortID, s.path.EndpointB.ChannelID, clienttypes.ZeroHeight(), 0) - callbackData, err := types.GetDestCallbackData(ctx, packetUnmarshaler, packet, 1_000_000) - s.Require().NoError(err) - s.Require().Equal(expCallbackData, callbackData) + gasMeter := storetypes.NewGasMeter(2_000_000) + ctx := s.chainA.GetContext().WithGasMeter(gasMeter) + packet := channeltypes.NewPacket(packetDataBytes, 0, transfertypes.PortID, s.path.EndpointA.ChannelID, transfertypes.PortID, s.path.EndpointB.ChannelID, clienttypes.ZeroHeight(), 0) + callbackData, err := types.GetDestCallbackData(ctx, packetUnmarshaler, packet, 1_000_000) + s.Require().NoError(err) + s.Require().Equal(tc.expCallbackdata, callbackData) + }) + } } func (s *CallbacksTypesTestSuite) TestGetCallbackAddress() { - denom := ibctesting.TestCoin.Denom + denom := transfertypes.Denom{Base: ibctesting.TestCoin.Denom} amount := ibctesting.TestCoin.Amount.String() sender := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String() receiver := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String() testCases := []struct { name string - packetData transfertypes.FungibleTokenPacketData + packetData ibcexported.PacketDataProvider expAddress string }{ { "success: memo has callbacks in json struct and properly formatted src_callback_address which does not match packet sender", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -390,7 +769,7 @@ func (s *CallbacksTypesTestSuite) TestGetCallbackAddress() { { "success: valid src_callback address specified in memo that matches sender", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -401,7 +780,7 @@ func (s *CallbacksTypesTestSuite) TestGetCallbackAddress() { { "failure: memo is empty", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -412,7 +791,7 @@ func (s *CallbacksTypesTestSuite) TestGetCallbackAddress() { { "failure: memo is not json string", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -423,7 +802,7 @@ func (s *CallbacksTypesTestSuite) TestGetCallbackAddress() { { "failure: memo has empty src_callback object", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -434,7 +813,7 @@ func (s *CallbacksTypesTestSuite) TestGetCallbackAddress() { { "failure: memo does not have callbacks in json struct", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -445,7 +824,7 @@ func (s *CallbacksTypesTestSuite) TestGetCallbackAddress() { { "failure: memo has src_callback in json struct but does not have address key", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -456,7 +835,7 @@ func (s *CallbacksTypesTestSuite) TestGetCallbackAddress() { { "failure: memo has src_callback in json struct but does not have string value for address key", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -464,6 +843,126 @@ func (s *CallbacksTypesTestSuite) TestGetCallbackAddress() { }, "", }, + { + "success v2: memo has callbacks in json struct and properly formatted src_callback_address which does not match packet sender", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"src_callback": {"address": "%s"}}`, receiver), + }, + receiver, + }, + { + "success v2: valid src_callback address specified in memo that matches sender", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: fmt.Sprintf(`{"src_callback": {"address": "%s"}}`, sender), + }, + sender, + }, + { + "failure v2: memo is empty", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: "", + }, + "", + }, + { + "failure v2: memo is not json string", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: "memo", + }, + "", + }, + { + "failure v2: memo has empty src_callback object", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {}}`, + }, + "", + }, + { + "failure v2: memo does not have callbacks in json struct", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"Key": 10}`, + }, + "", + }, + { + "failure v2: memo has src_callback in json struct but does not have address key", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {"Key": 10}}`, + }, + "", + }, + { + "failure v2: memo has src_callback in json struct but does not have string value for address key", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {"address": 10}}`, + }, + "", + }, } for _, tc := range testCases { @@ -477,20 +976,23 @@ func (s *CallbacksTypesTestSuite) TestGetCallbackAddress() { } func (s *CallbacksTypesTestSuite) TestUserDefinedGasLimit() { - denom := ibctesting.TestCoin.Denom + denom := transfertypes.Denom{ + Base: ibctesting.TestCoin.Denom, + Trace: nil, + } amount := ibctesting.TestCoin.Amount.String() sender := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String() receiver := sdk.AccAddress(secp256k1.GenPrivKey().PubKey().Address()).String() testCases := []struct { name string - packetData transfertypes.FungibleTokenPacketData + packetData ibcexported.PacketDataProvider expUserGas uint64 }{ { "success: memo is empty", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -501,7 +1003,7 @@ func (s *CallbacksTypesTestSuite) TestUserDefinedGasLimit() { { "success: memo has user defined gas limit", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -512,7 +1014,7 @@ func (s *CallbacksTypesTestSuite) TestUserDefinedGasLimit() { { "success: user defined gas limit is zero", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -523,7 +1025,7 @@ func (s *CallbacksTypesTestSuite) TestUserDefinedGasLimit() { { "failure: memo has empty src_callback object", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -534,7 +1036,7 @@ func (s *CallbacksTypesTestSuite) TestUserDefinedGasLimit() { { "failure: memo has user defined gas limit as json number", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -545,7 +1047,7 @@ func (s *CallbacksTypesTestSuite) TestUserDefinedGasLimit() { { "failure: memo has user defined gas limit as negative", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -556,7 +1058,7 @@ func (s *CallbacksTypesTestSuite) TestUserDefinedGasLimit() { { "failure: memo has user defined gas limit as string", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -567,7 +1069,7 @@ func (s *CallbacksTypesTestSuite) TestUserDefinedGasLimit() { { "failure: memo has user defined gas limit as empty string", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -578,7 +1080,7 @@ func (s *CallbacksTypesTestSuite) TestUserDefinedGasLimit() { { "failure: malformed memo", transfertypes.FungibleTokenPacketData{ - Denom: denom, + Denom: denom.Base, Amount: amount, Sender: sender, Receiver: receiver, @@ -586,6 +1088,141 @@ func (s *CallbacksTypesTestSuite) TestUserDefinedGasLimit() { }, 0, }, + { + "success v2: memo is empty", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: "", + }, + 0, + }, + { + "success v2: memo has user defined gas limit", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {"gas_limit": "100"}}`, + }, + 100, + }, + { + "success v2: user defined gas limit is zero", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {"gas_limit": "0"}}`, + }, + 0, + }, + { + "failure v2: memo has empty src_callback object", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {}}`, + }, + 0, + }, + { + "failure v2: memo has user defined gas limit as json number", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {"gas_limit": 100}}`, + }, + 0, + }, + { + "failure v2: memo has user defined gas limit as negative", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {"gas_limit": "-100"}}`, + }, + 0, + }, + { + "failure v2: memo has user defined gas limit as string", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {"gas_limit": "invalid"}}`, + }, + 0, + }, + { + "failure v2: memo has user defined gas limit as empty string", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `{"src_callback": {"gas_limit": ""}}`, + }, + 0, + }, + { + "failure v2: malformed memo", + transfertypes.FungibleTokenPacketDataV2{ + Tokens: transfertypes.Tokens{ + { + Denom: denom, + Amount: amount, + }, + }, + Sender: sender, + Receiver: receiver, + Memo: `invalid`, + }, + 0, + }, } for _, tc := range testCases { diff --git a/modules/apps/transfer/client/cli/cli.go b/modules/apps/transfer/client/cli/cli.go index a0fe3564b60..e07d0015b41 100644 --- a/modules/apps/transfer/client/cli/cli.go +++ b/modules/apps/transfer/client/cli/cli.go @@ -16,8 +16,8 @@ func GetQueryCmd() *cobra.Command { } queryCmd.AddCommand( - GetCmdQueryDenomTrace(), - GetCmdQueryDenomTraces(), + GetCmdQueryDenom(), + GetCmdQueryDenoms(), GetCmdParams(), GetCmdQueryEscrowAddress(), GetCmdQueryDenomHash(), diff --git a/modules/apps/transfer/client/cli/query.go b/modules/apps/transfer/client/cli/query.go index 0e07febe833..c4594f8c99a 100644 --- a/modules/apps/transfer/client/cli/query.go +++ b/modules/apps/transfer/client/cli/query.go @@ -12,26 +12,26 @@ import ( "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" ) -// GetCmdQueryDenomTrace defines the command to query a denomination trace from a given trace hash or ibc denom. -func GetCmdQueryDenomTrace() *cobra.Command { +// GetCmdQueryDenom defines the command to query a denomination from a given hash or ibc denom. +func GetCmdQueryDenom() *cobra.Command { cmd := &cobra.Command{ - Use: "denom-trace [hash/denom]", - Short: "Query the denom trace info from a given trace hash or ibc denom", - Long: "Query the denom trace info from a given trace hash or ibc denom", - Example: fmt.Sprintf("%s query ibc-transfer denom-trace 27A6394C3F9FF9C9DCF5DFFADF9BB5FE9A37C7E92B006199894CF1824DF9AC7C", version.AppName), + Use: "denom [hash/denom]", + Short: "Query the denom trace info from a given hash or ibc denom", + Long: "Query the denom trace info from a given hash or ibc denom", + Example: fmt.Sprintf("%s query ibc-transfer denom 27A6394C3F9FF9C9DCF5DFFADF9BB5FE9A37C7E92B006199894CF1824DF9AC7C", version.AppName), Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } - queryClient := types.NewQueryClient(clientCtx) + queryClient := types.NewQueryV2Client(clientCtx) - req := &types.QueryDenomTraceRequest{ + req := &types.QueryDenomRequest{ Hash: args[0], } - res, err := queryClient.DenomTrace(cmd.Context(), req) + res, err := queryClient.Denom(cmd.Context(), req) if err != nil { return err } @@ -44,32 +44,31 @@ func GetCmdQueryDenomTrace() *cobra.Command { return cmd } -// GetCmdQueryDenomTraces defines the command to query all the denomination trace infos -// that this chain maintains. -func GetCmdQueryDenomTraces() *cobra.Command { +// GetCmdQueryDenoms defines the command to query all the denominations that this chain maintains. +func GetCmdQueryDenoms() *cobra.Command { cmd := &cobra.Command{ - Use: "denom-traces", - Short: "Query the trace info for all token denominations", - Long: "Query the trace info for all token denominations", - Example: fmt.Sprintf("%s query ibc-transfer denom-traces", version.AppName), + Use: "denoms", + Short: "Query for all token denominations", + Long: "Query for all token denominations", + Example: fmt.Sprintf("%s query ibc-transfer denoms", version.AppName), Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, _ []string) error { clientCtx, err := client.GetClientQueryContext(cmd) if err != nil { return err } - queryClient := types.NewQueryClient(clientCtx) + queryClient := types.NewQueryV2Client(clientCtx) pageReq, err := client.ReadPageRequest(cmd.Flags()) if err != nil { return err } - req := &types.QueryDenomTracesRequest{ + req := &types.QueryDenomsRequest{ Pagination: pageReq, } - res, err := queryClient.DenomTraces(cmd.Context(), req) + res, err := queryClient.Denoms(cmd.Context(), req) if err != nil { return err } @@ -78,7 +77,7 @@ func GetCmdQueryDenomTraces() *cobra.Command { }, } flags.AddQueryFlagsToCmd(cmd) - flags.AddPaginationFlagsToCmd(cmd, "denominations trace") + flags.AddPaginationFlagsToCmd(cmd, "denominations") return cmd } diff --git a/modules/apps/transfer/keeper/export_test.go b/modules/apps/transfer/keeper/export_test.go new file mode 100644 index 00000000000..9183e680f1b --- /dev/null +++ b/modules/apps/transfer/keeper/export_test.go @@ -0,0 +1,28 @@ +package keeper + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + + "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" +) + +// SetDenomTraces is a wrapper around iterateDenomTraces for testing purposes. +func (k Keeper) SetDenomTrace(ctx sdk.Context, denomTrace types.DenomTrace) { + k.setDenomTrace(ctx, denomTrace) +} + +// IterateDenomTraces is a wrapper around iterateDenomTraces for testing purposes. +func (k Keeper) IterateDenomTraces(ctx sdk.Context, cb func(denomTrace types.DenomTrace) bool) { + k.iterateDenomTraces(ctx, cb) +} + +// GetAllDenomTraces returns the trace information for all the denominations. +func (k Keeper) GetAllDenomTraces(ctx sdk.Context) []types.DenomTrace { + var traces []types.DenomTrace + k.iterateDenomTraces(ctx, func(denomTrace types.DenomTrace) bool { + traces = append(traces, denomTrace) + return false + }) + + return traces +} diff --git a/modules/apps/transfer/keeper/genesis.go b/modules/apps/transfer/keeper/genesis.go index 0a98db41e2f..0901fecca64 100644 --- a/modules/apps/transfer/keeper/genesis.go +++ b/modules/apps/transfer/keeper/genesis.go @@ -12,9 +12,9 @@ import ( func (k Keeper) InitGenesis(ctx sdk.Context, state types.GenesisState) { k.SetPort(ctx, state.PortId) - for _, trace := range state.DenomTraces { - k.SetDenomTrace(ctx, trace) - k.setDenomMetadata(ctx, trace) + for _, denom := range state.Denoms { + k.SetDenom(ctx, denom) + k.setDenomMetadata(ctx, denom) } // Only try to bind to port if it is not already bound, since we may already own @@ -41,7 +41,7 @@ func (k Keeper) InitGenesis(ctx sdk.Context, state types.GenesisState) { func (k Keeper) ExportGenesis(ctx sdk.Context) *types.GenesisState { return &types.GenesisState{ PortId: k.GetPort(ctx), - DenomTraces: k.GetAllDenomTraces(ctx), + Denoms: k.GetAllDenoms(ctx), Params: k.GetParams(ctx), TotalEscrowed: k.GetAllTotalEscrowed(ctx), } diff --git a/modules/apps/transfer/keeper/genesis_test.go b/modules/apps/transfer/keeper/genesis_test.go index 39848d3f08d..4fb809e58bb 100644 --- a/modules/apps/transfer/keeper/genesis_test.go +++ b/modules/apps/transfer/keeper/genesis_test.go @@ -16,47 +16,47 @@ func (suite *KeeperTestSuite) TestGenesis() { } var ( - denomTraces types.Traces + denoms types.Denoms escrows sdk.Coins - pathsAndEscrowAmounts = []struct { - path string + traceAndEscrowAmounts = []struct { + trace []string escrow string }{ - {getTrace(0), "10"}, - {fmt.Sprintf("%s/%s", getTrace(1), getTrace(0)), "100000"}, - {fmt.Sprintf("%s/%s/%s", getTrace(2), getTrace(1), getTrace(0)), "10000000000"}, - {fmt.Sprintf("%s/%s/%s/%s", getTrace(3), getTrace(2), getTrace(1), getTrace(0)), "1000000000000000"}, - {fmt.Sprintf("%s/%s/%s/%s/%s", getTrace(4), getTrace(3), getTrace(2), getTrace(1), getTrace(0)), "100000000000000000000"}, + {[]string{getTrace(0)}, "10"}, + {[]string{getTrace(1), getTrace(0)}, "100000"}, + {[]string{getTrace(2), getTrace(1), getTrace(0)}, "10000000000"}, + {[]string{getTrace(3), getTrace(2), getTrace(1), getTrace(0)}, "1000000000000000"}, + {[]string{getTrace(4), getTrace(3), getTrace(2), getTrace(1), getTrace(0)}, "100000000000000000000"}, } ) - for _, pathAndEscrowAmount := range pathsAndEscrowAmounts { - denomTrace := types.DenomTrace{ - BaseDenom: "uatom", - Path: pathAndEscrowAmount.path, + for _, traceAndEscrowAmount := range traceAndEscrowAmounts { + denom := types.Denom{ + Base: "uatom", + Trace: traceAndEscrowAmount.trace, } - denomTraces = append(types.Traces{denomTrace}, denomTraces...) - suite.chainA.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), denomTrace) + denoms = append(denoms, denom) + suite.chainA.GetSimApp().TransferKeeper.SetDenom(suite.chainA.GetContext(), denom) - denom := denomTrace.IBCDenom() - amount, ok := sdkmath.NewIntFromString(pathAndEscrowAmount.escrow) + amount, ok := sdkmath.NewIntFromString(traceAndEscrowAmount.escrow) suite.Require().True(ok) - escrows = append(sdk.NewCoins(sdk.NewCoin(denom, amount)), escrows...) - suite.chainA.GetSimApp().TransferKeeper.SetTotalEscrowForDenom(suite.chainA.GetContext(), sdk.NewCoin(denom, amount)) + escrow := sdk.NewCoin(denom.IBCDenom(), amount) + escrows = append(escrows, escrow) + suite.chainA.GetSimApp().TransferKeeper.SetTotalEscrowForDenom(suite.chainA.GetContext(), escrow) } genesis := suite.chainA.GetSimApp().TransferKeeper.ExportGenesis(suite.chainA.GetContext()) suite.Require().Equal(types.PortID, genesis.PortId) - suite.Require().Equal(denomTraces.Sort(), genesis.DenomTraces) + suite.Require().Equal(denoms.Sort(), genesis.Denoms) suite.Require().Equal(escrows.Sort(), genesis.TotalEscrowed) suite.Require().NotPanics(func() { suite.chainA.GetSimApp().TransferKeeper.InitGenesis(suite.chainA.GetContext(), *genesis) }) - for _, denomTrace := range denomTraces { - _, found := suite.chainA.GetSimApp().BankKeeper.GetDenomMetaData(suite.chainA.GetContext(), denomTrace.IBCDenom()) + for _, denom := range denoms { + _, found := suite.chainA.GetSimApp().BankKeeper.GetDenomMetaData(suite.chainA.GetContext(), denom.IBCDenom()) suite.Require().True(found) } } diff --git a/modules/apps/transfer/keeper/grpc_query.go b/modules/apps/transfer/keeper/grpc_query.go index 0e27d2e1c48..17302fa18ff 100644 --- a/modules/apps/transfer/keeper/grpc_query.go +++ b/modules/apps/transfer/keeper/grpc_query.go @@ -19,10 +19,13 @@ import ( channeltypes "github.com/cosmos/ibc-go/v8/modules/core/04-channel/types" ) -var _ types.QueryServer = (*Keeper)(nil) +var ( + _ types.QueryServer = (*Keeper)(nil) + _ types.QueryV2Server = (*Keeper)(nil) +) -// DenomTrace implements the Query/DenomTrace gRPC method -func (k Keeper) DenomTrace(c context.Context, req *types.QueryDenomTraceRequest) (*types.QueryDenomTraceResponse, error) { +// Denom implements the Query/Denom gRPC method +func (k Keeper) Denom(c context.Context, req *types.QueryDenomRequest) (*types.QueryDenomResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") } @@ -33,46 +36,46 @@ func (k Keeper) DenomTrace(c context.Context, req *types.QueryDenomTraceRequest) } ctx := sdk.UnwrapSDKContext(c) - denomTrace, found := k.GetDenomTrace(ctx, hash) + denom, found := k.GetDenom(ctx, hash) if !found { return nil, status.Error( codes.NotFound, - errorsmod.Wrap(types.ErrTraceNotFound, req.Hash).Error(), + errorsmod.Wrap(types.ErrDenomNotFound, req.Hash).Error(), ) } - return &types.QueryDenomTraceResponse{ - DenomTrace: &denomTrace, + return &types.QueryDenomResponse{ + Denom: &denom, }, nil } -// DenomTraces implements the Query/DenomTraces gRPC method -func (k Keeper) DenomTraces(c context.Context, req *types.QueryDenomTracesRequest) (*types.QueryDenomTracesResponse, error) { +// Denoms implements the Query/Denoms gRPC method +func (k Keeper) Denoms(c context.Context, req *types.QueryDenomsRequest) (*types.QueryDenomsResponse, error) { if req == nil { return nil, status.Error(codes.InvalidArgument, "empty request") } ctx := sdk.UnwrapSDKContext(c) - var traces types.Traces - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomTraceKey) + var denoms types.Denoms + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomKey) pageRes, err := query.Paginate(store, req.Pagination, func(_, value []byte) error { - var denomTrace types.DenomTrace - if err := k.cdc.Unmarshal(value, &denomTrace); err != nil { + var denom types.Denom + if err := k.cdc.Unmarshal(value, &denom); err != nil { return err } - traces = append(traces, denomTrace) + denoms = append(denoms, denom) return nil }) if err != nil { return nil, err } - return &types.QueryDenomTracesResponse{ - DenomTraces: traces.Sort(), - Pagination: pageRes, + return &types.QueryDenomsResponse{ + Denoms: denoms.Sort(), + Pagination: pageRes, }, nil } @@ -92,7 +95,7 @@ func (k Keeper) DenomHash(c context.Context, req *types.QueryDenomHashRequest) ( return nil, status.Error(codes.InvalidArgument, "empty request") } - // Convert given request trace path to DenomTrace struct to confirm the path in a valid denom trace format + // Convert given request trace path to Denom struct to confirm the path in a valid denom trace format denomTrace := types.ParseDenomTrace(req.Trace) if err := denomTrace.Validate(); err != nil { return nil, status.Error(codes.InvalidArgument, err.Error()) @@ -100,11 +103,11 @@ func (k Keeper) DenomHash(c context.Context, req *types.QueryDenomHashRequest) ( ctx := sdk.UnwrapSDKContext(c) denomHash := denomTrace.Hash() - found := k.HasDenomTrace(ctx, denomHash) + found := k.HasDenom(ctx, denomHash) if !found { return nil, status.Error( codes.NotFound, - errorsmod.Wrap(types.ErrTraceNotFound, req.Trace).Error(), + errorsmod.Wrap(types.ErrDenomNotFound, req.Trace).Error(), ) } @@ -156,3 +159,15 @@ func (k Keeper) TotalEscrowForDenom(c context.Context, req *types.QueryTotalEscr Amount: amount, }, nil } + +// DenomTrace implements the Query/DenomTrace gRPC method +// Deprecated: Please use Denom instead. +func (Keeper) DenomTrace(c context.Context, req *types.QueryDenomTraceRequest) (*types.QueryDenomTraceResponse, error) { + return nil, status.Error(codes.Unimplemented, "unsupported rpc") +} + +// DenomTraces implements the Query/DenomTraces gRPC method +// Deprecated: Please use Denoms instead. +func (Keeper) DenomTraces(c context.Context, req *types.QueryDenomTracesRequest) (*types.QueryDenomTracesResponse, error) { + return nil, status.Error(codes.Unimplemented, "unsupported rpc") +} diff --git a/modules/apps/transfer/keeper/grpc_query_test.go b/modules/apps/transfer/keeper/grpc_query_test.go index 382372e09c1..802515e85b8 100644 --- a/modules/apps/transfer/keeper/grpc_query_test.go +++ b/modules/apps/transfer/keeper/grpc_query_test.go @@ -12,10 +12,10 @@ import ( ibctesting "github.com/cosmos/ibc-go/v8/testing" ) -func (suite *KeeperTestSuite) TestQueryDenomTrace() { +func (suite *KeeperTestSuite) TestQueryDenom() { var ( - req *types.QueryDenomTraceRequest - expTrace types.DenomTrace + req *types.QueryDenomRequest + expDenom types.Denom ) testCases := []struct { @@ -26,12 +26,14 @@ func (suite *KeeperTestSuite) TestQueryDenomTrace() { { "success: correct ibc denom", func() { - expTrace.Path = "transfer/channelToA/transfer/channelToB" //nolint:goconst - expTrace.BaseDenom = "uatom" //nolint:goconst - suite.chainA.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), expTrace) + expDenom = types.Denom{ + Base: "uatom", //nolint:goconst + Trace: []string{"transfer/channelToA", "transfer/channelToB"}, //nolint:goconst + } + suite.chainA.GetSimApp().TransferKeeper.SetDenom(suite.chainA.GetContext(), expDenom) - req = &types.QueryDenomTraceRequest{ - Hash: expTrace.IBCDenom(), + req = &types.QueryDenomRequest{ + Hash: expDenom.IBCDenom(), } }, true, @@ -39,12 +41,15 @@ func (suite *KeeperTestSuite) TestQueryDenomTrace() { { "success: correct hex hash", func() { - expTrace.Path = "transfer/channelToA/transfer/channelToB" - expTrace.BaseDenom = "uatom" - suite.chainA.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), expTrace) + expDenom = types.Denom{ + Base: "uatom", //nolint:goconst + Trace: []string{"transfer/channelToA", "transfer/channelToB"}, //nolint:goconst + } + + suite.chainA.GetSimApp().TransferKeeper.SetDenom(suite.chainA.GetContext(), expDenom) - req = &types.QueryDenomTraceRequest{ - Hash: expTrace.Hash().String(), + req = &types.QueryDenomRequest{ + Hash: expDenom.Hash().String(), } }, true, @@ -52,7 +57,7 @@ func (suite *KeeperTestSuite) TestQueryDenomTrace() { { "failure: invalid hash", func() { - req = &types.QueryDenomTraceRequest{ + req = &types.QueryDenomRequest{ Hash: "!@#!@#!", } }, @@ -61,10 +66,13 @@ func (suite *KeeperTestSuite) TestQueryDenomTrace() { { "failure: not found denom trace", func() { - expTrace.Path = "transfer/channelToA/transfer/channelToB" - expTrace.BaseDenom = "uatom" - req = &types.QueryDenomTraceRequest{ - Hash: expTrace.IBCDenom(), + expDenom = types.Denom{ + Base: "uatom", //nolint:goconst + Trace: []string{"transfer/channelToA", "transfer/channelToB"}, //nolint:goconst + } + + req = &types.QueryDenomRequest{ + Hash: expDenom.IBCDenom(), } }, false, @@ -79,12 +87,12 @@ func (suite *KeeperTestSuite) TestQueryDenomTrace() { tc.malleate() ctx := suite.chainA.GetContext() - res, err := suite.chainA.GetSimApp().TransferKeeper.DenomTrace(ctx, req) + res, err := suite.chainA.GetSimApp().TransferKeeper.Denom(ctx, req) if tc.expPass { suite.Require().NoError(err) suite.Require().NotNil(res) - suite.Require().Equal(&expTrace, res.DenomTrace) + suite.Require().Equal(&expDenom, res.Denom) } else { suite.Require().Error(err) } @@ -92,10 +100,10 @@ func (suite *KeeperTestSuite) TestQueryDenomTrace() { } } -func (suite *KeeperTestSuite) TestQueryDenomTraces() { +func (suite *KeeperTestSuite) TestQueryDenoms() { var ( - req *types.QueryDenomTracesRequest - expTraces = types.Traces(nil) + req *types.QueryDenomsRequest + expDenoms = types.Denoms(nil) ) testCases := []struct { @@ -106,22 +114,22 @@ func (suite *KeeperTestSuite) TestQueryDenomTraces() { { "empty pagination", func() { - req = &types.QueryDenomTracesRequest{} + req = &types.QueryDenomsRequest{} }, true, }, { "success", func() { - expTraces = append(expTraces, types.DenomTrace{Path: "", BaseDenom: "uatom"}) - expTraces = append(expTraces, types.DenomTrace{Path: "transfer/channelToB", BaseDenom: "uatom"}) - expTraces = append(expTraces, types.DenomTrace{Path: "transfer/channelToA/transfer/channelToB", BaseDenom: "uatom"}) + expDenoms = append(expDenoms, types.Denom{Base: "uatom"}) + expDenoms = append(expDenoms, types.Denom{Base: "uatom", Trace: []string{"transfer/channelToB"}}) + expDenoms = append(expDenoms, types.Denom{Base: "uatom", Trace: []string{"transfer/channelToA", "transfer/channelToB"}}) - for _, trace := range expTraces { - suite.chainA.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), trace) + for _, trace := range expDenoms { + suite.chainA.GetSimApp().TransferKeeper.SetDenom(suite.chainA.GetContext(), trace) } - req = &types.QueryDenomTracesRequest{ + req = &types.QueryDenomsRequest{ Pagination: &query.PageRequest{ Limit: 5, CountTotal: false, @@ -140,12 +148,12 @@ func (suite *KeeperTestSuite) TestQueryDenomTraces() { tc.malleate() ctx := suite.chainA.GetContext() - res, err := suite.chainA.GetSimApp().TransferKeeper.DenomTraces(ctx, req) + res, err := suite.chainA.GetSimApp().TransferKeeper.Denoms(ctx, req) if tc.expPass { suite.Require().NoError(err) suite.Require().NotNil(res) - suite.Require().Equal(expTraces.Sort(), res.DenomTraces) + suite.Require().Equal(expDenoms.Sort(), res.Denoms) } else { suite.Require().Error(err) } @@ -161,14 +169,14 @@ func (suite *KeeperTestSuite) TestQueryParams() { } func (suite *KeeperTestSuite) TestQueryDenomHash() { - reqTrace := types.DenomTrace{ - Path: "transfer/channelToA/transfer/channelToB", - BaseDenom: "uatom", + reqDenom := types.Denom{ + Base: "uatom", + Trace: []string{"transfer/channelToA", "transfer/channelToB"}, } var ( req *types.QueryDenomHashRequest - expHash = reqTrace.Hash().String() + expHash = reqDenom.Hash().String() ) testCases := []struct { @@ -207,9 +215,9 @@ func (suite *KeeperTestSuite) TestQueryDenomHash() { suite.SetupTest() // reset req = &types.QueryDenomHashRequest{ - Trace: reqTrace.GetFullDenomPath(), + Trace: reqDenom.FullPath(), } - suite.chainA.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), reqTrace) + suite.chainA.GetSimApp().TransferKeeper.SetDenom(suite.chainA.GetContext(), reqDenom) tc.malleate() ctx := suite.chainA.GetContext() @@ -326,12 +334,12 @@ func (suite *KeeperTestSuite) TestTotalEscrowForDenom() { { "valid ibc denom with escrow amount > 2^63", func() { - denomTrace := types.DenomTrace{ - Path: "transfer/channel-0", - BaseDenom: sdk.DefaultBondDenom, + denomTrace := types.Denom{ + Base: sdk.DefaultBondDenom, + Trace: []string{"transfer/channel-0"}, } - suite.chainA.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainA.GetContext(), denomTrace) + suite.chainA.GetSimApp().TransferKeeper.SetDenom(suite.chainA.GetContext(), denomTrace) expEscrowAmount, ok := sdkmath.NewIntFromString("100000000000000000000") suite.Require().True(ok) suite.chainA.GetSimApp().TransferKeeper.SetTotalEscrowForDenom(suite.chainA.GetContext(), sdk.NewCoin(sdk.DefaultBondDenom, expEscrowAmount)) @@ -345,9 +353,9 @@ func (suite *KeeperTestSuite) TestTotalEscrowForDenom() { { "valid ibc denom treated as native denom", func() { - denomTrace := types.DenomTrace{ - Path: "transfer/channel-0", - BaseDenom: sdk.DefaultBondDenom, + denomTrace := types.Denom{ + Base: sdk.DefaultBondDenom, + Trace: []string{"transfer/channel-0"}, } req = &types.QueryTotalEscrowForDenomRequest{ diff --git a/modules/apps/transfer/keeper/keeper.go b/modules/apps/transfer/keeper/keeper.go index 644ed0c7b6e..e110012df3d 100644 --- a/modules/apps/transfer/keeper/keeper.go +++ b/modules/apps/transfer/keeper/keeper.go @@ -144,79 +144,78 @@ func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { store.Set([]byte(types.ParamsKey), bz) } -// GetDenomTrace retrieves the full identifiers trace and base denomination from the store. -func (k Keeper) GetDenomTrace(ctx sdk.Context, denomTraceHash cmtbytes.HexBytes) (types.DenomTrace, bool) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomTraceKey) - bz := store.Get(denomTraceHash) +// GetDenom retrieves the denom from store given the hash of the denom. +func (k Keeper) GetDenom(ctx sdk.Context, denomHash cmtbytes.HexBytes) (types.Denom, bool) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomKey) + bz := store.Get(denomHash) if len(bz) == 0 { - return types.DenomTrace{}, false + return types.Denom{}, false } - var denomTrace types.DenomTrace - k.cdc.MustUnmarshal(bz, &denomTrace) + var denom types.Denom + k.cdc.MustUnmarshal(bz, &denom) - return denomTrace, true + return denom, true } -// HasDenomTrace checks if a the key with the given denomination trace hash exists on the store. -func (k Keeper) HasDenomTrace(ctx sdk.Context, denomTraceHash cmtbytes.HexBytes) bool { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomTraceKey) - return store.Has(denomTraceHash) +// HasDenom checks if a the key with the given denomination hash exists on the store. +func (k Keeper) HasDenom(ctx sdk.Context, denomHash cmtbytes.HexBytes) bool { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomKey) + return store.Has(denomHash) } -// SetDenomTrace sets a new {trace hash -> denom trace} pair to the store. -func (k Keeper) SetDenomTrace(ctx sdk.Context, denomTrace types.DenomTrace) { - store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomTraceKey) - bz := k.cdc.MustMarshal(&denomTrace) - - store.Set(denomTrace.Hash(), bz) +// SetDenom sets a new {denom hash -> denom } pair to the store. +// This allows for reverse lookup of the denom given the hash. +func (k Keeper) SetDenom(ctx sdk.Context, denom types.Denom) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomKey) + bz := k.cdc.MustMarshal(&denom) + store.Set(denom.Hash(), bz) } -// GetAllDenomTraces returns the trace information for all the denominations. -func (k Keeper) GetAllDenomTraces(ctx sdk.Context) types.Traces { - traces := types.Traces{} - k.IterateDenomTraces(ctx, func(denomTrace types.DenomTrace) bool { - traces = append(traces, denomTrace) +// GetAllDenoms returns all the denominations. +func (k Keeper) GetAllDenoms(ctx sdk.Context) types.Denoms { + denoms := types.Denoms{} + k.IterateDenoms(ctx, func(denom types.Denom) bool { + denoms = append(denoms, denom) return false }) - return traces.Sort() + return denoms.Sort() } -// IterateDenomTraces iterates over the denomination traces in the store -// and performs a callback function. -func (k Keeper) IterateDenomTraces(ctx sdk.Context, cb func(denomTrace types.DenomTrace) bool) { +// IterateDenoms iterates over the denominations in the store and performs a callback function. +func (k Keeper) IterateDenoms(ctx sdk.Context, cb func(denom types.Denom) bool) { store := ctx.KVStore(k.storeKey) - iterator := storetypes.KVStorePrefixIterator(store, types.DenomTraceKey) + iterator := storetypes.KVStorePrefixIterator(store, types.DenomKey) defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) for ; iterator.Valid(); iterator.Next() { - var denomTrace types.DenomTrace - k.cdc.MustUnmarshal(iterator.Value(), &denomTrace) + var denom types.Denom + k.cdc.MustUnmarshal(iterator.Value(), &denom) - if cb(denomTrace) { + if cb(denom) { break } } } // setDenomMetadata sets an IBC token's denomination metadata -func (k Keeper) setDenomMetadata(ctx sdk.Context, denomTrace types.DenomTrace) { +func (k Keeper) setDenomMetadata(ctx sdk.Context, denom types.Denom) { metadata := banktypes.Metadata{ - Description: fmt.Sprintf("IBC token from %s", denomTrace.GetFullDenomPath()), + Description: fmt.Sprintf("IBC token from %s", denom.FullPath()), DenomUnits: []*banktypes.DenomUnit{ { - Denom: denomTrace.BaseDenom, + Denom: denom.Base, Exponent: 0, }, }, // Setting base as IBC hash denom since bank keepers's SetDenomMetadata uses // Base as key path and the IBC hash is what gives this token uniqueness // on the executing chain - Base: denomTrace.IBCDenom(), - Display: denomTrace.GetFullDenomPath(), - Name: fmt.Sprintf("%s IBC token", denomTrace.GetFullDenomPath()), - Symbol: strings.ToUpper(denomTrace.BaseDenom), + Base: denom.IBCDenom(), + Display: denom.FullPath(), + Name: fmt.Sprintf("%s IBC token", denom.FullPath()), + Symbol: strings.ToUpper(denom.Base), } k.bankKeeper.SetDenomMetaData(ctx, metadata) diff --git a/modules/apps/transfer/keeper/keeper_test.go b/modules/apps/transfer/keeper/keeper_test.go index 0d0da50c002..f9f0e658f15 100644 --- a/modules/apps/transfer/keeper/keeper_test.go +++ b/modules/apps/transfer/keeper/keeper_test.go @@ -199,7 +199,7 @@ func (suite *KeeperTestSuite) TestGetAllDenomEscrows() { { "success", func() { - denom := "uatom" + denom := "uatom" //nolint:goconst amount := sdkmath.NewInt(100) expDenomEscrows = append(expDenomEscrows, sdk.NewCoin(denom, amount)) diff --git a/modules/apps/transfer/keeper/mbt_relay_test.go b/modules/apps/transfer/keeper/mbt_relay_test.go index 1e92262c3a5..4c11a1cb37c 100644 --- a/modules/apps/transfer/keeper/mbt_relay_test.go +++ b/modules/apps/transfer/keeper/mbt_relay_test.go @@ -320,10 +320,8 @@ func (suite *KeeperTestSuite) TestModelBasedRelay() { for i, tlaTc := range tlaTestCases { tc := OnRecvPacketTestCaseFromTla(tlaTc) registerDenomFn := func() { - denomTrace := types.ParseDenomTrace(tc.packet.Data.Tokens[0].GetFullDenomPath()) - traceHash := denomTrace.Hash() - if !suite.chainB.GetSimApp().TransferKeeper.HasDenomTrace(suite.chainB.GetContext(), traceHash) { - suite.chainB.GetSimApp().TransferKeeper.SetDenomTrace(suite.chainB.GetContext(), denomTrace) + if !suite.chainB.GetSimApp().TransferKeeper.HasDenom(suite.chainB.GetContext(), tc.packet.Data.Tokens[0].Denom.Hash()) { + suite.chainB.GetSimApp().TransferKeeper.SetDenom(suite.chainB.GetContext(), tc.packet.Data.Tokens[0].Denom) } } diff --git a/modules/apps/transfer/keeper/migrations.go b/modules/apps/transfer/keeper/migrations.go index fb738a07831..7db9ba8f4b8 100644 --- a/modules/apps/transfer/keeper/migrations.go +++ b/modules/apps/transfer/keeper/migrations.go @@ -2,8 +2,13 @@ package keeper import ( "fmt" + "strings" + + "cosmossdk.io/store/prefix" + storetypes "cosmossdk.io/store/types" sdk "github.com/cosmos/cosmos-sdk/types" + banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" ) @@ -34,7 +39,7 @@ func (m Migrator) MigrateParams(ctx sdk.Context) error { func (m Migrator) MigrateTraces(ctx sdk.Context) error { // list of traces that must replace the old traces in store var newTraces []types.DenomTrace - m.keeper.IterateDenomTraces(ctx, + m.keeper.iterateDenomTraces(ctx, func(dt types.DenomTrace) (stop bool) { // check if the new way of splitting FullDenom // is the same as the current DenomTrace. @@ -61,18 +66,18 @@ func (m Migrator) MigrateTraces(ctx sdk.Context) error { // replace the outdated traces with the new trace information for _, nt := range newTraces { - m.keeper.SetDenomTrace(ctx, nt) + m.keeper.setDenomTrace(ctx, nt) } return nil } // MigrateDenomMetadata sets token metadata for all the IBC denom traces func (m Migrator) MigrateDenomMetadata(ctx sdk.Context) error { - m.keeper.IterateDenomTraces(ctx, + m.keeper.iterateDenomTraces(ctx, func(dt types.DenomTrace) (stop bool) { // check if the metadata for the given denom trace does not already exist if !m.keeper.bankKeeper.HasDenomMetaData(ctx, dt.IBCDenom()) { - m.keeper.setDenomMetadata(ctx, dt) + m.keeper.setDenomMetadataWithDenomTrace(ctx, dt) } return false }) @@ -105,3 +110,50 @@ func (m Migrator) MigrateTotalEscrowForDenom(ctx sdk.Context) error { func equalTraces(dtA, dtB types.DenomTrace) bool { return dtA.BaseDenom == dtB.BaseDenom && dtA.Path == dtB.Path } + +// setDenomTrace sets a new {trace hash -> denom trace} pair to the store. +func (k Keeper) setDenomTrace(ctx sdk.Context, denomTrace types.DenomTrace) { + store := prefix.NewStore(ctx.KVStore(k.storeKey), types.DenomTraceKey) + bz := k.cdc.MustMarshal(&denomTrace) + + store.Set(denomTrace.Hash(), bz) +} + +// iterateDenomTraces iterates over the denomination traces in the store +// and performs a callback function. +func (k Keeper) iterateDenomTraces(ctx sdk.Context, cb func(denomTrace types.DenomTrace) bool) { + store := ctx.KVStore(k.storeKey) + iterator := storetypes.KVStorePrefixIterator(store, types.DenomTraceKey) + + defer sdk.LogDeferred(ctx.Logger(), func() error { return iterator.Close() }) + for ; iterator.Valid(); iterator.Next() { + var denomTrace types.DenomTrace + k.cdc.MustUnmarshal(iterator.Value(), &denomTrace) + + if cb(denomTrace) { + break + } + } +} + +// setDenomMetadataWithDenomTrace sets an IBC token's denomination metadata +func (k Keeper) setDenomMetadataWithDenomTrace(ctx sdk.Context, denomTrace types.DenomTrace) { + metadata := banktypes.Metadata{ + Description: fmt.Sprintf("IBC token from %s", denomTrace.GetFullDenomPath()), + DenomUnits: []*banktypes.DenomUnit{ + { + Denom: denomTrace.BaseDenom, + Exponent: 0, + }, + }, + // Setting base as IBC hash denom since bank keepers's SetDenomMetadata uses + // Base as key path and the IBC hash is what gives this token uniqueness + // on the executing chain + Base: denomTrace.IBCDenom(), + Display: denomTrace.GetFullDenomPath(), + Name: fmt.Sprintf("%s IBC token", denomTrace.GetFullDenomPath()), + Symbol: strings.ToUpper(denomTrace.BaseDenom), + } + + k.bankKeeper.SetDenomMetaData(ctx, metadata) +} diff --git a/modules/apps/transfer/keeper/migrations_test.go b/modules/apps/transfer/keeper/migrations_test.go index 8c63d3cc9d1..17e47fb797c 100644 --- a/modules/apps/transfer/keeper/migrations_test.go +++ b/modules/apps/transfer/keeper/migrations_test.go @@ -52,7 +52,7 @@ func (suite *KeeperTestSuite) TestMigratorMigrateTraces() { testCases := []struct { msg string malleate func() - expectedTraces transfertypes.Traces + expectedTraces []transfertypes.DenomTrace }{ { "success: two slashes in base denom", @@ -63,7 +63,7 @@ func (suite *KeeperTestSuite) TestMigratorMigrateTraces() { BaseDenom: "pool/1", Path: "transfer/channel-0/gamm", }) }, - transfertypes.Traces{ + []transfertypes.DenomTrace{ { BaseDenom: "gamm/pool/1", Path: "transfer/channel-0", }, @@ -78,7 +78,7 @@ func (suite *KeeperTestSuite) TestMigratorMigrateTraces() { BaseDenom: "0x85bcBCd7e79Ec36f4fBBDc54F90C643d921151AA", Path: "transfer/channel-149/erc", }) }, - transfertypes.Traces{ + []transfertypes.DenomTrace{ { BaseDenom: "erc/0x85bcBCd7e79Ec36f4fBBDc54F90C643d921151AA", Path: "transfer/channel-149", }, @@ -93,7 +93,7 @@ func (suite *KeeperTestSuite) TestMigratorMigrateTraces() { BaseDenom: "1", Path: "transfer/channel-5/gamm//pool", }) }, - transfertypes.Traces{ + []transfertypes.DenomTrace{ { BaseDenom: "gamm//pool/1", Path: "transfer/channel-5", }, @@ -108,7 +108,7 @@ func (suite *KeeperTestSuite) TestMigratorMigrateTraces() { BaseDenom: "transfer/channel-1/uatom", Path: "transfer/channel-0", }) }, - transfertypes.Traces{ + []transfertypes.DenomTrace{ { BaseDenom: "uatom", Path: "transfer/channel-0/transfer/channel-1", }, @@ -123,7 +123,7 @@ func (suite *KeeperTestSuite) TestMigratorMigrateTraces() { BaseDenom: "customport/channel-7/uatom", Path: "transfer/channel-0/transfer/channel-1", }) }, - transfertypes.Traces{ + []transfertypes.DenomTrace{ { BaseDenom: "uatom", Path: "transfer/channel-0/transfer/channel-1/customport/channel-7", }, diff --git a/modules/apps/transfer/keeper/relay.go b/modules/apps/transfer/keeper/relay.go index efe19dc85b1..ffd2bf74e87 100644 --- a/modules/apps/transfer/keeper/relay.go +++ b/modules/apps/transfer/keeper/relay.go @@ -220,35 +220,26 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t // sender chain is not the source, unescrow tokens // remove prefix added by sender chain - voucherPrefix := types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) - unprefixedDenom := fullDenomPath[len(voucherPrefix):] + token.Denom.Trace = token.Denom.Trace[1:] - // coin denomination used in sending from the escrow address - denom := unprefixedDenom - - // The denomination used to send the coins is either the native denom or the hash of the path - // if the denomination is not native. - denomTrace := types.ParseDenomTrace(unprefixedDenom) - if !denomTrace.IsNativeDenom() { - denom = denomTrace.IBCDenom() - } - token := sdk.NewCoin(denom, transferAmount) + coin := sdk.NewCoin(token.Denom.IBCDenom(), transferAmount) if k.bankKeeper.BlockedAddr(receiver) { return errorsmod.Wrapf(ibcerrors.ErrUnauthorized, "%s is not allowed to receive funds", receiver) } escrowAddress := types.GetEscrowAddress(packet.GetDestPort(), packet.GetDestChannel()) - if err := k.unescrowToken(ctx, escrowAddress, receiver, token); err != nil { + if err := k.unescrowToken(ctx, escrowAddress, receiver, coin); err != nil { return err } + unprefixedDenomPath := token.Denom.FullPath() defer func() { if transferAmount.IsInt64() { telemetry.SetGaugeWithLabels( []string{"ibc", types.ModuleName, "packet", "receive"}, float32(transferAmount.Int64()), - []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, unprefixedDenom)}, + []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, unprefixedDenomPath)}, ) } @@ -267,26 +258,23 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t // sender chain is the source, mint vouchers - // since SendPacket did not prefix the denomination, we must prefix denomination here - prefixedDenom := types.GetPrefixedDenom(packet.GetDestPort(), packet.GetDestChannel(), fullDenomPath) - - // construct the denomination trace from the full raw denomination - denomTrace := types.ParseDenomTrace(prefixedDenom) + // since SendPacket did not prefix the denomination, we must add the destination port and channel to the trace + trace := []string{fmt.Sprintf("%s/%s", packet.DestinationPort, packet.DestinationChannel)} + token.Denom.Trace = append(trace, token.Denom.Trace...) - traceHash := denomTrace.Hash() - if !k.HasDenomTrace(ctx, traceHash) { - k.SetDenomTrace(ctx, denomTrace) + if !k.HasDenom(ctx, token.Denom.Hash()) { + k.SetDenom(ctx, token.Denom) } - voucherDenom := denomTrace.IBCDenom() + voucherDenom := token.Denom.IBCDenom() if !k.bankKeeper.HasDenomMetaData(ctx, voucherDenom) { - k.setDenomMetadata(ctx, denomTrace) + k.setDenomMetadata(ctx, token.Denom) } ctx.EventManager().EmitEvent( sdk.NewEvent( types.EventTypeDenomTrace, - sdk.NewAttribute(types.AttributeKeyTraceHash, traceHash.String()), + sdk.NewAttribute(types.AttributeKeyTraceHash, token.Denom.Hash().String()), sdk.NewAttribute(types.AttributeKeyDenom, voucherDenom), ), ) @@ -306,12 +294,13 @@ func (k Keeper) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, data t return errorsmod.Wrapf(err, "failed to send coins to receiver %s", receiver.String()) } + prefixedDenomPath := token.Denom.FullPath() defer func() { if transferAmount.IsInt64() { telemetry.SetGaugeWithLabels( []string{"ibc", types.ModuleName, "packet", "receive"}, float32(transferAmount.Int64()), - []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, fullDenomPath)}, + []metrics.Label{telemetry.NewLabel(coretypes.LabelDenom, prefixedDenomPath)}, ) } @@ -440,20 +429,20 @@ func (k Keeper) unescrowToken(ctx sdk.Context, escrowAddress, receiver sdk.AccAd // DenomPathFromHash returns the full denomination path prefix from an ibc denom with a hash // component. -func (k Keeper) DenomPathFromHash(ctx sdk.Context, denom string) (string, error) { +func (k Keeper) DenomPathFromHash(ctx sdk.Context, ibcDenom string) (string, error) { // trim the denomination prefix, by default "ibc/" - hexHash := denom[len(types.DenomPrefix+"/"):] + hexHash := ibcDenom[len(types.DenomPrefix+"/"):] hash, err := types.ParseHexHash(hexHash) if err != nil { return "", errorsmod.Wrap(types.ErrInvalidDenomForTransfer, err.Error()) } - denomTrace, found := k.GetDenomTrace(ctx, hash) + denom, found := k.GetDenom(ctx, hash) if !found { - return "", errorsmod.Wrap(types.ErrTraceNotFound, hexHash) + return "", errorsmod.Wrap(types.ErrDenomNotFound, hexHash) } - fullDenomPath := denomTrace.GetFullDenomPath() + fullDenomPath := denom.FullPath() return fullDenomPath, nil } diff --git a/modules/apps/transfer/keeper/relay_test.go b/modules/apps/transfer/keeper/relay_test.go index be37669289e..ed972e559b3 100644 --- a/modules/apps/transfer/keeper/relay_test.go +++ b/modules/apps/transfer/keeper/relay_test.go @@ -96,7 +96,7 @@ func (suite *KeeperTestSuite) TestSendTransfer() { func() { coin = types.GetTransferCoin(path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, "randomdenom", coin.Amount) }, - types.ErrTraceNotFound, + types.ErrDenomNotFound, }, { "failure: bank send from module account failed, insufficient balance", @@ -1080,51 +1080,114 @@ func (suite *KeeperTestSuite) TestPacketForwardsCompatibility() { // doesn't have this field in the packet data. The module should be able to handle // this packet without any issues. + // the test also ensures that an ack is written for any malformed or bad packet data. + var packetData []byte + var path *ibctesting.Path testCases := []struct { - msg string - malleate func() - expError error + msg string + malleate func() + expError error + expAckError error }{ + { + "success: new field v2", + func() { + jsonString := fmt.Sprintf(`{"tokens":[{"denom": {"base": "atom", "trace": []},"amount":"100"}],"sender":"%s","receiver":"%s", "new_field":"value"}`, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String()) + packetData = []byte(jsonString) + }, + nil, + nil, + }, + { + "success: no new field with memo v2", + func() { + jsonString := fmt.Sprintf(`{"tokens":[{"denom": {"base": "atom", "trace": []},"amount":"100"}],"sender":"%s","receiver":"%s"}`, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String()) + packetData = []byte(jsonString) + }, + nil, + nil, + }, + { + "success: no new field without memo", + func() { + jsonString := fmt.Sprintf(`{"tokens":[{"denom": {"base": "atom", "trace": []},"amount":"100"}],"sender":"%s","receiver":"%s"}`, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String()) + packetData = []byte(jsonString) + }, + nil, + nil, + }, + { + "failure: invalid packet data v2", + func() { + packetData = []byte("invalid packet data") + }, + ibcerrors.ErrInvalidType, + ibcerrors.ErrInvalidType, + }, + { + "failure: missing field v2", + func() { + jsonString := fmt.Sprintf(`{"tokens":[{"denom": {"trace": []},"amount":"100"}],"sender":"%s","receiver":"%s"}`, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String()) + packetData = []byte(jsonString) + }, + types.ErrInvalidDenomForTransfer, + ibcerrors.ErrInvalidType, + }, { "success: new field", func() { + path.EndpointA.ChannelConfig.Version = types.V1 + path.EndpointB.ChannelConfig.Version = types.V1 jsonString := fmt.Sprintf(`{"denom":"denom","amount":"100","sender":"%s","receiver":"%s","memo":"memo","new_field":"value"}`, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String()) packetData = []byte(jsonString) }, nil, + nil, }, { "success: no new field with memo", func() { + path.EndpointA.ChannelConfig.Version = types.V1 + path.EndpointB.ChannelConfig.Version = types.V1 jsonString := fmt.Sprintf(`{"denom":"denom","amount":"100","sender":"%s","receiver":"%s","memo":"memo"}`, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String()) packetData = []byte(jsonString) }, nil, + nil, }, { "success: no new field without memo", func() { + path.EndpointA.ChannelConfig.Version = types.V1 + path.EndpointB.ChannelConfig.Version = types.V1 jsonString := fmt.Sprintf(`{"denom":"denom","amount":"100","sender":"%s","receiver":"%s"}`, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String()) packetData = []byte(jsonString) }, nil, + nil, }, { "failure: invalid packet data", func() { + path.EndpointA.ChannelConfig.Version = types.V1 + path.EndpointB.ChannelConfig.Version = types.V1 packetData = []byte("invalid packet data") }, ibcerrors.ErrInvalidType, + ibcerrors.ErrInvalidType, }, { "failure: missing field", func() { + path.EndpointA.ChannelConfig.Version = types.V1 + path.EndpointB.ChannelConfig.Version = types.V1 jsonString := fmt.Sprintf(`{"amount":"100","sender":%s","receiver":"%s"}`, suite.chainB.SenderAccount.GetAddress().String(), suite.chainA.SenderAccount.GetAddress().String()) packetData = []byte(jsonString) }, ibcerrors.ErrInvalidType, + ibcerrors.ErrInvalidType, }, } @@ -1134,13 +1197,12 @@ func (suite *KeeperTestSuite) TestPacketForwardsCompatibility() { suite.SetupTest() // reset packetData = nil - path := ibctesting.NewTransferPath(suite.chainA, suite.chainB) - path.EndpointA.ChannelConfig.Version = types.V1 - path.EndpointB.ChannelConfig.Version = types.V1 - path.Setup() + path = ibctesting.NewTransferPath(suite.chainA, suite.chainB) tc.malleate() + path.Setup() + timeoutHeight := suite.chainB.GetTimeoutHeight() seq, err := path.EndpointB.SendPacket(timeoutHeight, 0, packetData) @@ -1156,6 +1218,13 @@ func (suite *KeeperTestSuite) TestPacketForwardsCompatibility() { suite.Require().NoError(err) } else { suite.Require().ErrorContains(err, tc.expError.Error()) + ackBz, ok := path.EndpointA.Chain.GetSimApp().IBCKeeper.ChannelKeeper.GetPacketAcknowledgement(path.EndpointA.Chain.GetContext(), path.EndpointA.ChannelConfig.PortID, path.EndpointA.ChannelID, seq) + suite.Require().True(ok) + + // an ack should be written for the malformed / bad packet data. + expectedAck := channeltypes.NewErrorAcknowledgement(tc.expAckError) + expBz := channeltypes.CommitAcknowledgement(expectedAck.Acknowledgement()) + suite.Require().Equal(expBz, ackBz) } }) } diff --git a/modules/apps/transfer/simulation/genesis.go b/modules/apps/transfer/simulation/genesis.go index 6887ec48bf1..4fb8cd64871 100644 --- a/modules/apps/transfer/simulation/genesis.go +++ b/modules/apps/transfer/simulation/genesis.go @@ -41,9 +41,9 @@ func RandomizedGenState(simState *module.SimulationState) { ) transferGenesis := types.GenesisState{ - PortId: portID, - DenomTraces: types.Traces{}, - Params: types.NewParams(sendEnabled, receiveEnabled), + PortId: portID, + Denoms: types.Denoms{}, + Params: types.NewParams(sendEnabled, receiveEnabled), } bz, err := json.MarshalIndent(&transferGenesis, "", " ") diff --git a/modules/apps/transfer/simulation/genesis_test.go b/modules/apps/transfer/simulation/genesis_test.go index d5c413d135c..de63d14d730 100644 --- a/modules/apps/transfer/simulation/genesis_test.go +++ b/modules/apps/transfer/simulation/genesis_test.go @@ -47,7 +47,7 @@ func TestRandomizedGenState(t *testing.T) { require.Equal(t, "euzxpfgkqegqiqwixnku", ibcTransferGenesis.PortId) require.True(t, ibcTransferGenesis.Params.SendEnabled) require.True(t, ibcTransferGenesis.Params.ReceiveEnabled) - require.Len(t, ibcTransferGenesis.DenomTraces, 0) + require.Len(t, ibcTransferGenesis.Denoms, 0) } // TestRandomizedGenState tests abnormal scenarios of applying RandomizedGenState. diff --git a/modules/apps/transfer/transfer_test.go b/modules/apps/transfer/transfer_test.go index 1cb1261c0e3..3a0596d0bde 100644 --- a/modules/apps/transfer/transfer_test.go +++ b/modules/apps/transfer/transfer_test.go @@ -1,6 +1,7 @@ package transfer_test import ( + "fmt" "testing" testifysuite "github.com/stretchr/testify/suite" @@ -69,9 +70,12 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() { suite.Require().Equal(coinToSendToB, balance) // check that voucher exists on chain B - voucherDenomTrace := types.ParseDenomTrace(types.GetPrefixedDenom(packet.GetDestPort(), packet.GetDestChannel(), sdk.DefaultBondDenom)) - balance = suite.chainB.GetSimApp().BankKeeper.GetBalance(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), voucherDenomTrace.IBCDenom()) - coinSentFromAToB := types.GetTransferCoin(pathAtoB.EndpointB.ChannelConfig.PortID, pathAtoB.EndpointB.ChannelID, sdk.DefaultBondDenom, amount) + denom := types.Denom{ + Base: sdk.DefaultBondDenom, + Trace: []string{fmt.Sprintf("%s/%s", packet.DestinationPort, packet.DestinationChannel)}, + } + balance = suite.chainB.GetSimApp().BankKeeper.GetBalance(suite.chainB.GetContext(), suite.chainB.SenderAccount.GetAddress(), denom.IBCDenom()) + coinSentFromAToB := sdk.NewCoin(denom.IBCDenom(), amount) suite.Require().Equal(coinSentFromAToB, balance) // setup between chainB to chainC @@ -93,10 +97,11 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() { suite.Require().NoError(err) // relay committed // NOTE: fungible token is prefixed with the full trace in order to verify the packet commitment - fullDenomPath := types.GetPrefixedDenom(pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID, voucherDenomTrace.GetFullDenomPath()) + trace := []string{fmt.Sprintf("%s/%s", pathBtoC.EndpointB.ChannelConfig.PortID, pathBtoC.EndpointB.ChannelID)} + denom.Trace = append(trace, denom.Trace...) // check that the balance is updated on chainC - coinSentFromBToC := sdk.NewCoin(types.ParseDenomTrace(fullDenomPath).IBCDenom(), amount) + coinSentFromBToC := sdk.NewCoin(denom.IBCDenom(), amount) balance = suite.chainC.GetSimApp().BankKeeper.GetBalance(suite.chainC.GetContext(), suite.chainC.SenderAccount.GetAddress(), coinSentFromBToC.Denom) suite.Require().Equal(coinSentFromBToC, balance) @@ -129,7 +134,7 @@ func (suite *TransferTestSuite) TestHandleMsgTransfer() { suite.Require().Zero(balance.Amount.Int64()) // check that balance on chain C is empty - balance = suite.chainC.GetSimApp().BankKeeper.GetBalance(suite.chainC.GetContext(), suite.chainC.SenderAccount.GetAddress(), voucherDenomTrace.IBCDenom()) + balance = suite.chainC.GetSimApp().BankKeeper.GetBalance(suite.chainC.GetContext(), suite.chainC.SenderAccount.GetAddress(), denom.IBCDenom()) suite.Require().Zero(balance.Amount.Int64()) } diff --git a/modules/apps/transfer/types/coin.go b/modules/apps/transfer/types/coin.go index fad6532af81..6b935deb5b9 100644 --- a/modules/apps/transfer/types/coin.go +++ b/modules/apps/transfer/types/coin.go @@ -44,6 +44,9 @@ func GetPrefixedDenom(portID, channelID, baseDenom string) string { // GetTransferCoin creates a transfer coin with the port ID and channel ID // prefixed to the base denom. func GetTransferCoin(portID, channelID, baseDenom string, amount sdkmath.Int) sdk.Coin { - denomTrace := ParseDenomTrace(GetPrefixedDenom(portID, channelID, baseDenom)) - return sdk.NewCoin(denomTrace.IBCDenom(), amount) + denom := Denom{ + Base: baseDenom, + Trace: []string{fmt.Sprintf("%s/%s", portID, channelID)}, + } + return sdk.NewCoin(denom.IBCDenom(), amount) } diff --git a/modules/apps/transfer/types/denom.go b/modules/apps/transfer/types/denom.go new file mode 100644 index 00000000000..5b1773b89ae --- /dev/null +++ b/modules/apps/transfer/types/denom.go @@ -0,0 +1,109 @@ +package types + +import ( + "crypto/sha256" + "fmt" + "sort" + "strings" + + errorsmod "cosmossdk.io/errors" + + cmtbytes "github.com/cometbft/cometbft/libs/bytes" +) + +// Validate performs a basic validation of the Denom fields. +func (d Denom) Validate() error { + // NOTE: base denom validation cannot be performed as each chain may define + // its own base denom validation + if strings.TrimSpace(d.Base) == "" { + return fmt.Errorf("base denomination cannot be blank") + } + + if len(d.Trace) != 0 { + trace := strings.Join(d.Trace, "/") + identifiers := strings.Split(trace, "/") + + if err := validateTraceIdentifiers(identifiers); err != nil { + return err + } + } + + return nil +} + +// Hash returns the hex bytes of the SHA256 hash of the Denom fields using the following formula: +// +// hash = sha256(tracePath + "/" + baseDenom) +func (d Denom) Hash() cmtbytes.HexBytes { + hash := sha256.Sum256([]byte(d.FullPath())) + return hash[:] +} + +// IBCDenom a coin denomination for an ICS20 fungible token in the format +// 'ibc/{hash(tracePath + baseDenom)}'. If the trace is empty, it will return the base denomination. +func (d Denom) IBCDenom() string { + if d.IsNative() { + return d.Base + } + + return fmt.Sprintf("%s/%s", DenomPrefix, d.Hash()) +} + +// FullPath returns the full denomination according to the ICS20 specification: +// tracePath + "/" + baseDenom +// If there exists no trace then the base denomination is returned. +func (d Denom) FullPath() string { + if d.IsNative() { + return d.Base + } + + var sb strings.Builder + for _, t := range d.Trace { + sb.WriteString(t) // nolint:revive // no error returned by WriteString + sb.WriteByte('/') //nolint:revive // no error returned by WriteByte + } + sb.WriteString(d.Base) //nolint:revive + return sb.String() +} + +// IsNative returns true if the denomination is native, thus containing no trace history. +func (d Denom) IsNative() bool { + return len(d.Trace) == 0 +} + +// Denoms defines a wrapper type for a slice of Denom. +type Denoms []Denom + +// Validate performs a basic validation of each denomination trace info. +func (d Denoms) Validate() error { + seenDenoms := make(map[string]bool) + for i, denom := range d { + hash := denom.Hash().String() + if seenDenoms[hash] { + return fmt.Errorf("duplicated denomination with hash %s", denom.Hash()) + } + + if err := denom.Validate(); err != nil { + return errorsmod.Wrapf(err, "failed denom %d validation", i) + } + seenDenoms[hash] = true + } + return nil +} + +var _ sort.Interface = (*Denoms)(nil) + +// Len implements sort.Interface for Denoms +func (d Denoms) Len() int { return len(d) } + +// Less implements sort.Interface for Denoms +func (d Denoms) Less(i, j int) bool { return d[i].FullPath() < d[j].FullPath() } + +// Swap implements sort.Interface for Denoms +func (d Denoms) Swap(i, j int) { d[i], d[j] = d[j], d[i] } + +// Sort is a helper function to sort the set of denomination in-place +func (d Denoms) Sort() Denoms { + sort.Sort(d) + return d +} diff --git a/modules/apps/transfer/types/denom_test.go b/modules/apps/transfer/types/denom_test.go new file mode 100644 index 00000000000..785c3f2fbee --- /dev/null +++ b/modules/apps/transfer/types/denom_test.go @@ -0,0 +1,120 @@ +package types_test + +import ( + "fmt" + + "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types" +) + +func (suite *TypesTestSuite) TestDenomsValidate() { + testCases := []struct { + name string + denoms types.Denoms + expError error + }{ + { + "empty Denoms", + types.Denoms{}, + nil, + }, + { + "valid multiple trace info", + types.Denoms{ + {Base: "uatom", Trace: []string{"transfer/channel-1", "transfer/channel-2"}}, + }, + nil, + }, + { + "valid multiple trace info", + types.Denoms{ + {Base: "uatom", Trace: []string{"transfer/channel-1", "transfer/channel-2"}}, + {Base: "uatom", Trace: []string{"transfer/channel-1", "transfer/channel-2"}}, + }, + fmt.Errorf("duplicated denomination with hash"), + }, + { + "empty base denom with trace", + types.Denoms{{Base: "", Trace: []string{"transfer/channel-1"}}}, + fmt.Errorf("base denomination cannot be blank"), + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + err := tc.denoms.Validate() + if tc.expError == nil { + suite.Require().NoError(err, tc.name) + } else { + suite.Require().ErrorContains(err, tc.expError.Error()) + } + }) + } +} + +func (suite *TypesTestSuite) TestFullPath() { + testCases := []struct { + name string + denom types.Denom + expPath string + }{ + { + "empty Denom", + types.Denom{}, + "", + }, + { + "only base denom", + types.Denom{ + Base: "uatom", + }, + "uatom", + }, + { + "base with slashes", + types.Denom{ + Base: "gamm/pool/osmo", + }, + "gamm/pool/osmo", + }, + { + "1 hop denom", + types.Denom{ + Base: "uatom", + Trace: []string{"transfer/channel-0"}, + }, + "transfer/channel-0/uatom", + }, + { + "2 hop denom", + types.Denom{ + Base: "uatom", + Trace: []string{"transfer/channel-0", "transfer/channel-52"}, + }, + "transfer/channel-0/transfer/channel-52/uatom", + }, + { + "3 hop denom", + types.Denom{ + Base: "uatom", + Trace: []string{"transfer/channel-0", "transfer/channel-52", "transfer/channel-52"}, + }, + "transfer/channel-0/transfer/channel-52/transfer/channel-52/uatom", + }, + { + "4 hop denom with base denom slashes", + types.Denom{ + Base: "other-denom/", + Trace: []string{"transfer/channel-0", "transfer/channel-52", "transfer/channel-52", "transfer/channel-49"}, + }, + "transfer/channel-0/transfer/channel-52/transfer/channel-52/transfer/channel-49/other-denom/", + }, + } + + for _, tc := range testCases { + tc := tc + suite.Run(tc.name, func() { + suite.Require().Equal(tc.expPath, tc.denom.FullPath()) + }) + } +} diff --git a/modules/apps/transfer/types/errors.go b/modules/apps/transfer/types/errors.go index b3e45aa2ae2..2a7d90c0fbe 100644 --- a/modules/apps/transfer/types/errors.go +++ b/modules/apps/transfer/types/errors.go @@ -10,7 +10,7 @@ var ( ErrInvalidDenomForTransfer = errorsmod.Register(ModuleName, 3, "invalid denomination for cross-chain transfer") ErrInvalidVersion = errorsmod.Register(ModuleName, 4, "invalid ICS20 version") ErrInvalidAmount = errorsmod.Register(ModuleName, 5, "invalid token amount") - ErrTraceNotFound = errorsmod.Register(ModuleName, 6, "denomination trace not found") + ErrDenomNotFound = errorsmod.Register(ModuleName, 6, "denomination not found") ErrSendDisabled = errorsmod.Register(ModuleName, 7, "fungible token transfers from this chain are disabled") ErrReceiveDisabled = errorsmod.Register(ModuleName, 8, "fungible token transfers to this chain are disabled") ErrMaxTransferChannels = errorsmod.Register(ModuleName, 9, "max transfer channels") diff --git a/modules/apps/transfer/types/genesis.go b/modules/apps/transfer/types/genesis.go index b04cd61aeaf..fce19120997 100644 --- a/modules/apps/transfer/types/genesis.go +++ b/modules/apps/transfer/types/genesis.go @@ -7,10 +7,10 @@ import ( ) // NewGenesisState creates a new ibc-transfer GenesisState instance. -func NewGenesisState(portID string, denomTraces Traces, params Params, totalEscrowed sdk.Coins) *GenesisState { +func NewGenesisState(portID string, denoms Denoms, params Params, totalEscrowed sdk.Coins) *GenesisState { return &GenesisState{ PortId: portID, - DenomTraces: denomTraces, + Denoms: denoms, Params: params, TotalEscrowed: totalEscrowed, } @@ -20,7 +20,7 @@ func NewGenesisState(portID string, denomTraces Traces, params Params, totalEscr func DefaultGenesisState() *GenesisState { return &GenesisState{ PortId: PortID, - DenomTraces: Traces{}, + Denoms: Denoms{}, Params: DefaultParams(), TotalEscrowed: sdk.Coins{}, } @@ -32,7 +32,7 @@ func (gs GenesisState) Validate() error { if err := host.PortIdentifierValidator(gs.PortId); err != nil { return err } - if err := gs.DenomTraces.Validate(); err != nil { + if err := gs.Denoms.Validate(); err != nil { return err } return gs.TotalEscrowed.Validate() // will fail if there are duplicates for any denom diff --git a/modules/apps/transfer/types/genesis.pb.go b/modules/apps/transfer/types/genesis.pb.go index bae224a8222..af271171e3e 100644 --- a/modules/apps/transfer/types/genesis.pb.go +++ b/modules/apps/transfer/types/genesis.pb.go @@ -1,5 +1,5 @@ // Code generated by protoc-gen-gogo. DO NOT EDIT. -// source: ibc/applications/transfer/v1/genesis.proto +// source: ibc/applications/transfer/v2/genesis.proto package types @@ -27,9 +27,9 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // GenesisState defines the ibc-transfer genesis state type GenesisState struct { - PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` - DenomTraces Traces `protobuf:"bytes,2,rep,name=denom_traces,json=denomTraces,proto3,castrepeated=Traces" json:"denom_traces"` - Params Params `protobuf:"bytes,3,opt,name=params,proto3" json:"params"` + PortId string `protobuf:"bytes,1,opt,name=port_id,json=portId,proto3" json:"port_id,omitempty"` + Denoms Denoms `protobuf:"bytes,2,rep,name=denoms,proto3,castrepeated=Denoms" json:"denoms"` + Params Params `protobuf:"bytes,3,opt,name=params,proto3" json:"params"` // total_escrowed contains the total amount of tokens escrowed // by the transfer module TotalEscrowed github_com_cosmos_cosmos_sdk_types.Coins `protobuf:"bytes,4,rep,name=total_escrowed,json=totalEscrowed,proto3,castrepeated=github.com/cosmos/cosmos-sdk/types.Coins" json:"total_escrowed"` @@ -39,7 +39,7 @@ func (m *GenesisState) Reset() { *m = GenesisState{} } func (m *GenesisState) String() string { return proto.CompactTextString(m) } func (*GenesisState) ProtoMessage() {} func (*GenesisState) Descriptor() ([]byte, []int) { - return fileDescriptor_a4f788affd5bea89, []int{0} + return fileDescriptor_62efebb47a9093ed, []int{0} } func (m *GenesisState) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -75,9 +75,9 @@ func (m *GenesisState) GetPortId() string { return "" } -func (m *GenesisState) GetDenomTraces() Traces { +func (m *GenesisState) GetDenoms() Denoms { if m != nil { - return m.DenomTraces + return m.Denoms } return nil } @@ -97,39 +97,39 @@ func (m *GenesisState) GetTotalEscrowed() github_com_cosmos_cosmos_sdk_types.Coi } func init() { - proto.RegisterType((*GenesisState)(nil), "ibc.applications.transfer.v1.GenesisState") + proto.RegisterType((*GenesisState)(nil), "ibc.applications.transfer.v2.GenesisState") } func init() { - proto.RegisterFile("ibc/applications/transfer/v1/genesis.proto", fileDescriptor_a4f788affd5bea89) + proto.RegisterFile("ibc/applications/transfer/v2/genesis.proto", fileDescriptor_62efebb47a9093ed) } -var fileDescriptor_a4f788affd5bea89 = []byte{ +var fileDescriptor_62efebb47a9093ed = []byte{ // 378 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x51, 0xb1, 0x8e, 0xd3, 0x40, - 0x10, 0xb5, 0x93, 0xc8, 0x08, 0x27, 0xa4, 0xb0, 0x90, 0x30, 0x11, 0x72, 0x22, 0x44, 0x61, 0x81, - 0xb2, 0x8b, 0x43, 0x01, 0xb5, 0x01, 0x21, 0x3a, 0x30, 0x54, 0x50, 0x44, 0xeb, 0xf5, 0x62, 0x56, - 0xc4, 0x1e, 0x6b, 0x67, 0x63, 0x74, 0x7f, 0x71, 0xdf, 0x71, 0xdf, 0x70, 0x1f, 0x90, 0x32, 0xe5, - 0x55, 0x77, 0xa7, 0xe4, 0x47, 0x4e, 0x5e, 0xfb, 0xa2, 0x48, 0x27, 0xa5, 0xf2, 0x8c, 0xe7, 0xbd, - 0x37, 0xb3, 0xef, 0xb9, 0xaf, 0x65, 0xca, 0x29, 0xab, 0xaa, 0x95, 0xe4, 0x4c, 0x4b, 0x28, 0x91, - 0x6a, 0xc5, 0x4a, 0xfc, 0x23, 0x14, 0xad, 0x23, 0x9a, 0x8b, 0x52, 0xa0, 0x44, 0x52, 0x29, 0xd0, - 0xe0, 0xbd, 0x90, 0x29, 0x27, 0xc7, 0x58, 0x72, 0x8f, 0x25, 0x75, 0x34, 0x79, 0x73, 0x52, 0xe9, - 0x80, 0x34, 0x52, 0x93, 0x80, 0x03, 0x16, 0x80, 0x34, 0x65, 0x28, 0x68, 0x1d, 0xa5, 0x42, 0xb3, - 0x88, 0x72, 0x90, 0x65, 0x37, 0x7f, 0x9a, 0x43, 0x0e, 0xa6, 0xa4, 0x4d, 0xd5, 0xfe, 0x7d, 0x79, - 0xd9, 0x73, 0x47, 0x5f, 0xda, 0x93, 0x7e, 0x68, 0xa6, 0x85, 0xf7, 0xcc, 0x7d, 0x54, 0x81, 0xd2, - 0x4b, 0x99, 0xf9, 0xf6, 0xcc, 0x0e, 0x1f, 0x27, 0x4e, 0xd3, 0x7e, 0xcd, 0xbc, 0xdf, 0xee, 0x28, - 0x13, 0x25, 0x14, 0x4b, 0xad, 0x18, 0x17, 0xe8, 0xf7, 0x66, 0xfd, 0x70, 0xb8, 0x08, 0xc9, 0xa9, - 0x17, 0x90, 0x4f, 0x0d, 0xe3, 0x67, 0x43, 0x88, 0xc7, 0x9b, 0xeb, 0xa9, 0x75, 0x71, 0x33, 0x75, - 0x4c, 0x8b, 0xc9, 0x30, 0x3b, 0xcc, 0xd0, 0x8b, 0x5d, 0xa7, 0x62, 0x8a, 0x15, 0xe8, 0xf7, 0x67, - 0x76, 0x38, 0x5c, 0xbc, 0x3a, 0x2d, 0xfb, 0xcd, 0x60, 0xe3, 0x41, 0x23, 0x99, 0x74, 0x4c, 0x4f, - 0xb9, 0x63, 0x0d, 0x9a, 0xad, 0x96, 0x02, 0xb9, 0x82, 0xff, 0x22, 0xf3, 0x07, 0xe6, 0xc4, 0xe7, - 0xa4, 0x75, 0x86, 0x34, 0xce, 0x90, 0xce, 0x19, 0xf2, 0x11, 0x64, 0x19, 0xbf, 0xed, 0x6e, 0x0a, - 0x73, 0xa9, 0xff, 0xae, 0x53, 0xc2, 0xa1, 0xa0, 0x9d, 0x8d, 0xed, 0x67, 0x8e, 0xd9, 0x3f, 0xaa, - 0xcf, 0x2a, 0x81, 0x86, 0x80, 0xc9, 0x13, 0xb3, 0xe2, 0x73, 0xb7, 0x21, 0xfe, 0xbe, 0xd9, 0x05, - 0xf6, 0x76, 0x17, 0xd8, 0xb7, 0xbb, 0xc0, 0x3e, 0xdf, 0x07, 0xd6, 0x76, 0x1f, 0x58, 0x57, 0xfb, - 0xc0, 0xfa, 0xf5, 0xfe, 0xa1, 0xa4, 0x4c, 0xf9, 0x3c, 0x07, 0x5a, 0x7f, 0xa0, 0x05, 0x64, 0xeb, - 0x95, 0xc0, 0x26, 0xdb, 0xa3, 0x4c, 0xcd, 0x9e, 0xd4, 0x31, 0xc1, 0xbc, 0xbb, 0x0b, 0x00, 0x00, - 0xff, 0xff, 0xfe, 0xf0, 0xde, 0x54, 0x47, 0x02, 0x00, 0x00, + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x7c, 0x51, 0xc1, 0x4e, 0xdb, 0x40, + 0x10, 0xb5, 0x93, 0xc8, 0x55, 0x9d, 0x36, 0x07, 0xab, 0x52, 0xdd, 0xa8, 0x72, 0xa2, 0xb6, 0x07, + 0xab, 0x55, 0x76, 0x6b, 0x73, 0x80, 0xb3, 0x01, 0x21, 0xc4, 0x05, 0xcc, 0x8d, 0x4b, 0xb4, 0x5e, + 0x2f, 0x66, 0x95, 0xd8, 0x63, 0x79, 0x37, 0x46, 0xfc, 0x05, 0xdf, 0x81, 0xf8, 0x90, 0x1c, 0x73, + 0xe4, 0x04, 0x28, 0xf9, 0x11, 0xe4, 0xb5, 0x83, 0x22, 0x21, 0xf9, 0xb4, 0x33, 0xbb, 0x6f, 0xde, + 0x9b, 0x7d, 0xcf, 0xfc, 0xcb, 0x23, 0x8a, 0x49, 0x9e, 0xcf, 0x39, 0x25, 0x92, 0x43, 0x26, 0xb0, + 0x2c, 0x48, 0x26, 0xae, 0x59, 0x81, 0x4b, 0x1f, 0x27, 0x2c, 0x63, 0x82, 0x0b, 0x94, 0x17, 0x20, + 0xc1, 0xfa, 0xc9, 0x23, 0x8a, 0x76, 0xb1, 0x68, 0x8b, 0x45, 0xa5, 0x3f, 0xfc, 0xd7, 0xc2, 0xe4, + 0xbd, 0xd7, 0x35, 0xd5, 0xd0, 0x6d, 0x95, 0x95, 0x30, 0x63, 0x59, 0x83, 0x74, 0x28, 0x88, 0x14, + 0x04, 0x8e, 0x88, 0x60, 0xb8, 0xf4, 0x22, 0x26, 0x89, 0x87, 0x29, 0xf0, 0xed, 0xfb, 0xb7, 0x04, + 0x12, 0x50, 0x25, 0xae, 0xaa, 0xfa, 0xf6, 0xd7, 0x63, 0xc7, 0xfc, 0x72, 0x52, 0x2f, 0x7f, 0x29, + 0x89, 0x64, 0xd6, 0x77, 0xf3, 0x53, 0x0e, 0x85, 0x9c, 0xf2, 0xd8, 0xd6, 0xc7, 0xba, 0xfb, 0x39, + 0x34, 0xaa, 0xf6, 0x34, 0xb6, 0xce, 0x4c, 0x23, 0x66, 0x19, 0xa4, 0xc2, 0xee, 0x8c, 0xbb, 0x6e, + 0xdf, 0xff, 0x8d, 0xda, 0x7e, 0x89, 0x8e, 0x2a, 0x6c, 0x30, 0x58, 0x3e, 0x8f, 0xb4, 0x87, 0x97, + 0x91, 0xa1, 0x5a, 0x11, 0x36, 0x14, 0x56, 0x60, 0x1a, 0x39, 0x29, 0x48, 0x2a, 0xec, 0xee, 0x58, + 0x77, 0xfb, 0xfe, 0x9f, 0x36, 0x32, 0x0f, 0x9d, 0x2b, 0x6c, 0xd0, 0xab, 0xd8, 0xc2, 0x66, 0xd2, + 0x2a, 0xcc, 0x81, 0x04, 0x49, 0xe6, 0x53, 0x26, 0x68, 0x01, 0xb7, 0x2c, 0xb6, 0x7b, 0x6a, 0xb1, + 0x1f, 0xa8, 0x76, 0x02, 0x55, 0x4e, 0xa0, 0xc6, 0x09, 0x74, 0x08, 0x3c, 0x0b, 0xfe, 0x37, 0xeb, + 0xb8, 0x09, 0x97, 0x37, 0x8b, 0x08, 0x51, 0x48, 0x71, 0x63, 0x5b, 0x7d, 0x4c, 0x44, 0x3c, 0xc3, + 0xf2, 0x2e, 0x67, 0x42, 0x0d, 0x88, 0xf0, 0xab, 0x92, 0x38, 0x6e, 0x14, 0x82, 0x8b, 0xe5, 0xda, + 0xd1, 0x57, 0x6b, 0x47, 0x7f, 0x5d, 0x3b, 0xfa, 0xfd, 0xc6, 0xd1, 0x56, 0x1b, 0x47, 0x7b, 0xda, + 0x38, 0xda, 0xd5, 0xfe, 0x47, 0x4a, 0x1e, 0xd1, 0x49, 0x02, 0xb8, 0x3c, 0xc0, 0x29, 0xc4, 0x8b, + 0x39, 0x13, 0x55, 0x90, 0x3b, 0x01, 0x2a, 0x9d, 0xc8, 0x50, 0x41, 0xec, 0xbd, 0x05, 0x00, 0x00, + 0xff, 0xff, 0x98, 0x5a, 0x74, 0x43, 0x61, 0x02, 0x00, 0x00, } func (m *GenesisState) Marshal() (dAtA []byte, err error) { @@ -176,10 +176,10 @@ func (m *GenesisState) MarshalToSizedBuffer(dAtA []byte) (int, error) { } i-- dAtA[i] = 0x1a - if len(m.DenomTraces) > 0 { - for iNdEx := len(m.DenomTraces) - 1; iNdEx >= 0; iNdEx-- { + if len(m.Denoms) > 0 { + for iNdEx := len(m.Denoms) - 1; iNdEx >= 0; iNdEx-- { { - size, err := m.DenomTraces[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Denoms[iNdEx].MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -221,8 +221,8 @@ func (m *GenesisState) Size() (n int) { if l > 0 { n += 1 + l + sovGenesis(uint64(l)) } - if len(m.DenomTraces) > 0 { - for _, e := range m.DenomTraces { + if len(m.Denoms) > 0 { + for _, e := range m.Denoms { l = e.Size() n += 1 + l + sovGenesis(uint64(l)) } @@ -307,7 +307,7 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field DenomTraces", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Denoms", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -334,8 +334,8 @@ func (m *GenesisState) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.DenomTraces = append(m.DenomTraces, DenomTrace{}) - if err := m.DenomTraces[len(m.DenomTraces)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Denoms = append(m.Denoms, Denom{}) + if err := m.Denoms[len(m.Denoms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex diff --git a/modules/apps/transfer/types/keys.go b/modules/apps/transfer/types/keys.go index f8faa1336fe..6ab7fbbb3b2 100644 --- a/modules/apps/transfer/types/keys.go +++ b/modules/apps/transfer/types/keys.go @@ -53,6 +53,8 @@ var ( PortKey = []byte{0x01} // DenomTraceKey defines the key to store the denomination trace info in store DenomTraceKey = []byte{0x02} + // DenomKey defines the key to store the token denomination in store + DenomKey = []byte{0x03} // SupportedVersions defines all versions that are supported by the module SupportedVersions = []string{V2, V1} diff --git a/modules/apps/transfer/types/query.pb.go b/modules/apps/transfer/types/query.pb.go index 2f7b696daa7..0de8751b57b 100644 --- a/modules/apps/transfer/types/query.pb.go +++ b/modules/apps/transfer/types/query.pb.go @@ -176,7 +176,7 @@ func (m *QueryDenomTracesRequest) GetPagination() *query.PageRequest { // method. type QueryDenomTracesResponse struct { // denom_traces returns all denominations trace information. - DenomTraces Traces `protobuf:"bytes,1,rep,name=denom_traces,json=denomTraces,proto3,castrepeated=Traces" json:"denom_traces"` + DenomTraces []DenomTrace `protobuf:"bytes,1,rep,name=denom_traces,json=denomTraces,proto3" json:"denom_traces"` // pagination defines the pagination in the response. Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -214,7 +214,7 @@ func (m *QueryDenomTracesResponse) XXX_DiscardUnknown() { var xxx_messageInfo_QueryDenomTracesResponse proto.InternalMessageInfo -func (m *QueryDenomTracesResponse) GetDenomTraces() Traces { +func (m *QueryDenomTracesResponse) GetDenomTraces() []DenomTrace { if m != nil { return m.DenomTraces } @@ -616,59 +616,59 @@ func init() { } var fileDescriptor_a638e2800a01538c = []byte{ - // 829 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x4f, 0x4f, 0xe3, 0x46, - 0x14, 0x8f, 0x29, 0xa4, 0xcd, 0x4b, 0xe1, 0x30, 0xd0, 0x02, 0x16, 0x35, 0xc8, 0xa2, 0x2d, 0x4a, - 0xc1, 0xd3, 0x40, 0x20, 0x1c, 0xa0, 0x52, 0xa1, 0xa5, 0xa5, 0xea, 0x01, 0x02, 0xa7, 0x72, 0x88, - 0x26, 0xf6, 0xd4, 0xb1, 0x94, 0x78, 0x8c, 0xc7, 0x49, 0x85, 0x22, 0x2e, 0xfd, 0x04, 0x95, 0xf8, - 0x12, 0x55, 0xa5, 0x6a, 0xbf, 0xc2, 0x1e, 0x39, 0xa2, 0x5d, 0x69, 0xc5, 0x69, 0x77, 0x05, 0xfb, - 0x41, 0x56, 0x1e, 0x8f, 0x13, 0x7b, 0x09, 0x21, 0xd9, 0x53, 0x3c, 0xf3, 0xfe, 0xfd, 0x7e, 0xbf, - 0x37, 0xef, 0x29, 0xb0, 0xe2, 0xd4, 0x4c, 0x4c, 0x3c, 0xaf, 0xe1, 0x98, 0x24, 0x70, 0x98, 0xcb, - 0x71, 0xe0, 0x13, 0x97, 0xff, 0x49, 0x7d, 0xdc, 0x2e, 0xe2, 0xf3, 0x16, 0xf5, 0x2f, 0x0c, 0xcf, - 0x67, 0x01, 0x43, 0x0b, 0x4e, 0xcd, 0x34, 0x92, 0x9e, 0x46, 0xec, 0x69, 0xb4, 0x8b, 0xea, 0x8c, - 0xcd, 0x6c, 0x26, 0x1c, 0x71, 0xf8, 0x15, 0xc5, 0xa8, 0x9a, 0xc9, 0x78, 0x93, 0x71, 0x5c, 0x23, - 0x9c, 0xe2, 0x76, 0xb1, 0x46, 0x03, 0x52, 0xc4, 0x26, 0x73, 0x5c, 0x69, 0x2f, 0x24, 0xed, 0xa2, - 0x58, 0xd7, 0xcb, 0x23, 0xb6, 0xe3, 0x8a, 0x42, 0xd2, 0xf7, 0xbb, 0x81, 0x48, 0xbb, 0x58, 0x22, - 0xe7, 0x05, 0x9b, 0x31, 0xbb, 0x41, 0x31, 0xf1, 0x1c, 0x4c, 0x5c, 0x97, 0x05, 0x12, 0xb2, 0xb0, - 0xea, 0xab, 0xf0, 0xe5, 0x71, 0x58, 0xec, 0x27, 0xea, 0xb2, 0xe6, 0xa9, 0x4f, 0x4c, 0x5a, 0xa1, - 0xe7, 0x2d, 0xca, 0x03, 0x84, 0x60, 0xbc, 0x4e, 0x78, 0x7d, 0x4e, 0x59, 0x52, 0x56, 0x72, 0x15, - 0xf1, 0xad, 0x5b, 0x30, 0xfb, 0xc0, 0x9b, 0x7b, 0xcc, 0xe5, 0x14, 0x1d, 0x42, 0xde, 0x0a, 0x6f, - 0xab, 0x41, 0x78, 0x2d, 0xa2, 0xf2, 0xeb, 0x2b, 0xc6, 0x20, 0xa5, 0x8c, 0x44, 0x1a, 0xb0, 0xba, - 0xdf, 0x3a, 0x79, 0x50, 0x85, 0xc7, 0xa0, 0x0e, 0x00, 0x7a, 0x6a, 0xc8, 0x22, 0xdf, 0x18, 0x91, - 0x74, 0x46, 0x28, 0x9d, 0x11, 0xf5, 0x49, 0x4a, 0x67, 0x1c, 0x11, 0x3b, 0x26, 0x54, 0x49, 0x44, - 0xea, 0xcf, 0x15, 0x98, 0x7b, 0x58, 0x43, 0x52, 0x39, 0x83, 0xcf, 0x13, 0x54, 0xf8, 0x9c, 0xb2, - 0xf4, 0xc9, 0x28, 0x5c, 0xf6, 0xa6, 0xae, 0x5f, 0x2f, 0x66, 0xfe, 0x7b, 0xb3, 0x98, 0x95, 0x79, - 0xf3, 0x3d, 0x6e, 0x1c, 0xfd, 0x92, 0x62, 0x30, 0x26, 0x18, 0x7c, 0xfb, 0x24, 0x83, 0x08, 0x59, - 0x8a, 0xc2, 0x0c, 0x20, 0xc1, 0xe0, 0x88, 0xf8, 0xa4, 0x19, 0x0b, 0xa4, 0x9f, 0xc0, 0x74, 0xea, - 0x56, 0x52, 0xda, 0x81, 0xac, 0x27, 0x6e, 0xa4, 0x66, 0xcb, 0x83, 0xc9, 0xc8, 0x68, 0x19, 0xa3, - 0xaf, 0xc1, 0x17, 0x3d, 0xb1, 0x7e, 0x25, 0xbc, 0x1e, 0xb7, 0x63, 0x06, 0x26, 0x7a, 0xed, 0xce, - 0x55, 0xa2, 0x43, 0xfa, 0x4d, 0x45, 0xee, 0x12, 0x46, 0xbf, 0x37, 0x75, 0x02, 0xf3, 0xc2, 0xfb, - 0x67, 0x6e, 0xfa, 0xec, 0xaf, 0x1f, 0x2d, 0xcb, 0xa7, 0xbc, 0xdb, 0xef, 0x59, 0xf8, 0xd4, 0x63, - 0x7e, 0x50, 0x75, 0x2c, 0x19, 0x93, 0x0d, 0x8f, 0x87, 0x16, 0xfa, 0x0a, 0xc0, 0xac, 0x13, 0xd7, - 0xa5, 0x8d, 0xd0, 0x36, 0x26, 0x6c, 0x39, 0x79, 0x73, 0x68, 0xe9, 0xfb, 0xa0, 0xf6, 0x4b, 0x2a, - 0x61, 0x7c, 0x0d, 0x53, 0x54, 0x18, 0xaa, 0x24, 0xb2, 0xc8, 0xe4, 0x93, 0x34, 0xe9, 0xae, 0x97, - 0x61, 0x51, 0x24, 0x39, 0x65, 0x01, 0x69, 0x44, 0x99, 0x0e, 0x98, 0x2f, 0x58, 0x25, 0x04, 0x10, - 0xcd, 0x8d, 0x05, 0x10, 0x07, 0xfd, 0x0c, 0x96, 0x1e, 0x0f, 0x94, 0x18, 0xca, 0x90, 0x25, 0x4d, - 0xd6, 0x72, 0x03, 0xd9, 0x91, 0xf9, 0xd4, 0x1b, 0x88, 0xbb, 0xbf, 0xcf, 0x1c, 0x77, 0x6f, 0x3c, - 0x7c, 0x4f, 0x15, 0xe9, 0xbe, 0x7e, 0xfb, 0x19, 0x4c, 0x88, 0xec, 0xe8, 0x5f, 0x05, 0xf2, 0x89, - 0xf7, 0x8b, 0x36, 0x07, 0x37, 0xf5, 0x91, 0x99, 0x52, 0xb7, 0x46, 0x0d, 0x8b, 0x18, 0xe8, 0x85, - 0xbf, 0x5f, 0xbe, 0xbb, 0x1a, 0x5b, 0x46, 0x3a, 0x96, 0xeb, 0x28, 0xbd, 0x86, 0x92, 0x23, 0x84, - 0x9e, 0x29, 0x00, 0xbd, 0x1c, 0xa8, 0x34, 0x52, 0xc9, 0x18, 0xe8, 0xe6, 0x88, 0x51, 0x12, 0x67, - 0x49, 0xe0, 0x34, 0xd0, 0xea, 0xd3, 0x38, 0x71, 0x27, 0x7c, 0x92, 0xbb, 0x85, 0xc2, 0x25, 0xba, - 0x52, 0x20, 0x1b, 0x8d, 0x01, 0xfa, 0x7e, 0x88, 0xba, 0xa9, 0x29, 0x54, 0x8b, 0x23, 0x44, 0x48, - 0x94, 0xcb, 0x02, 0xa5, 0x86, 0x16, 0xfa, 0xa3, 0x8c, 0x26, 0x11, 0xfd, 0xaf, 0x40, 0xae, 0x3b, - 0x56, 0x68, 0x63, 0x58, 0x41, 0x12, 0x33, 0xab, 0x96, 0x46, 0x0b, 0x92, 0xf0, 0x36, 0x05, 0x3c, - 0x8c, 0xd6, 0x06, 0x89, 0x18, 0x8a, 0x17, 0x8a, 0x28, 0xc4, 0x14, 0x2a, 0xbe, 0x52, 0x60, 0x32, - 0x35, 0x83, 0xa8, 0x3c, 0x44, 0xf9, 0x7e, 0xab, 0x40, 0xdd, 0x1e, 0x3d, 0x50, 0x62, 0xaf, 0x08, - 0xec, 0xbf, 0xa3, 0xdf, 0xfa, 0x63, 0x97, 0x5b, 0x83, 0xe3, 0x4e, 0x6f, 0xa3, 0x5c, 0xe2, 0x70, - 0xcf, 0x70, 0xdc, 0x91, 0xdb, 0xe7, 0x12, 0xa7, 0x17, 0x06, 0x7a, 0xa1, 0xc0, 0x74, 0x9f, 0xf1, - 0x46, 0xbb, 0x43, 0xa0, 0x7c, 0x7c, 0x9f, 0xa8, 0x3f, 0x7c, 0x6c, 0xb8, 0xa4, 0xba, 0x23, 0xa8, - 0x6e, 0xa1, 0xd2, 0x80, 0x36, 0x71, 0xdc, 0x11, 0xbf, 0x61, 0x83, 0x70, 0x10, 0x26, 0xab, 0x46, - 0xe4, 0xf6, 0x8e, 0xaf, 0xef, 0x34, 0xe5, 0xe6, 0x4e, 0x53, 0xde, 0xde, 0x69, 0xca, 0x3f, 0xf7, - 0x5a, 0xe6, 0xe6, 0x5e, 0xcb, 0xdc, 0xde, 0x6b, 0x99, 0x3f, 0xca, 0xb6, 0x13, 0xd4, 0x5b, 0x35, - 0xc3, 0x64, 0x4d, 0x2c, 0xff, 0xa8, 0x38, 0x35, 0x73, 0xcd, 0x66, 0xb8, 0xbd, 0x8d, 0x9b, 0xcc, - 0x6a, 0x35, 0x28, 0xff, 0xa0, 0x5c, 0x70, 0xe1, 0x51, 0x5e, 0xcb, 0x8a, 0xbf, 0x19, 0x1b, 0xef, - 0x03, 0x00, 0x00, 0xff, 0xff, 0xb4, 0x97, 0xb6, 0x42, 0x5d, 0x09, 0x00, 0x00, + // 826 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0x4f, 0x4f, 0x1b, 0x47, + 0x14, 0xf7, 0xba, 0xe0, 0xd6, 0xcf, 0xa5, 0x87, 0x81, 0x16, 0x58, 0xd1, 0x05, 0xad, 0x68, 0x8b, + 0x28, 0xde, 0xa9, 0xf9, 0x67, 0x0e, 0x50, 0xa9, 0xd0, 0xd2, 0x52, 0xf5, 0x00, 0x86, 0x53, 0x73, + 0xb0, 0xc6, 0xbb, 0x93, 0xf5, 0x4a, 0xf6, 0xce, 0xb2, 0xb3, 0x76, 0x84, 0x2c, 0x2e, 0x39, 0xe5, + 0x18, 0x89, 0x8f, 0x11, 0xe5, 0x92, 0x43, 0x3e, 0x03, 0x47, 0x94, 0x48, 0x51, 0x4e, 0x28, 0x82, + 0x7c, 0x90, 0x68, 0x67, 0x67, 0xed, 0xdd, 0x60, 0x8c, 0x9d, 0x93, 0x77, 0x66, 0xde, 0xef, 0xbd, + 0xdf, 0xef, 0xfd, 0x93, 0x61, 0xc9, 0xa9, 0x99, 0x98, 0x78, 0x5e, 0xc3, 0x31, 0x49, 0xe0, 0x30, + 0x97, 0xe3, 0xc0, 0x27, 0x2e, 0x7f, 0x4c, 0x7d, 0xdc, 0x2e, 0xe1, 0xd3, 0x16, 0xf5, 0xcf, 0x0c, + 0xcf, 0x67, 0x01, 0x43, 0x73, 0x4e, 0xcd, 0x34, 0x92, 0x96, 0x46, 0x6c, 0x69, 0xb4, 0x4b, 0xea, + 0x94, 0xcd, 0x6c, 0x26, 0x0c, 0x71, 0xf8, 0x15, 0x61, 0x54, 0xcd, 0x64, 0xbc, 0xc9, 0x38, 0xae, + 0x11, 0x4e, 0x71, 0xbb, 0x54, 0xa3, 0x01, 0x29, 0x61, 0x93, 0x39, 0xae, 0x7c, 0xff, 0x75, 0x60, + 0xf4, 0xae, 0xff, 0xc8, 0x78, 0xce, 0x66, 0xcc, 0x6e, 0x50, 0x4c, 0x3c, 0x07, 0x13, 0xd7, 0x65, + 0x81, 0xa4, 0x11, 0xbd, 0x2e, 0x27, 0x43, 0x09, 0xde, 0xdd, 0x80, 0x1e, 0xb1, 0x1d, 0x57, 0x18, + 0x47, 0xb6, 0xfa, 0x0a, 0xfc, 0x70, 0x14, 0x5a, 0xfc, 0x49, 0x5d, 0xd6, 0x3c, 0xf1, 0x89, 0x49, + 0x2b, 0xf4, 0xb4, 0x45, 0x79, 0x80, 0x10, 0x8c, 0xd5, 0x09, 0xaf, 0xcf, 0x28, 0x0b, 0xca, 0x52, + 0xbe, 0x22, 0xbe, 0x75, 0x0b, 0xa6, 0xef, 0x58, 0x73, 0x8f, 0xb9, 0x9c, 0xa2, 0x03, 0x28, 0x58, + 0xe1, 0x6d, 0x35, 0x08, 0xaf, 0x05, 0xaa, 0xb0, 0xba, 0x64, 0x0c, 0xca, 0x94, 0x91, 0x70, 0x03, + 0x56, 0xf7, 0x5b, 0x27, 0x77, 0xa2, 0xf0, 0x98, 0xd4, 0x3e, 0x40, 0x4f, 0x82, 0x0c, 0xf2, 0xb3, + 0x11, 0xe9, 0x35, 0x42, 0xbd, 0x46, 0x54, 0x27, 0xa9, 0xd7, 0x38, 0x24, 0x76, 0x2c, 0xa8, 0x92, + 0x40, 0xea, 0xaf, 0x15, 0x98, 0xb9, 0x1b, 0x43, 0x4a, 0x39, 0x82, 0x6f, 0x13, 0x52, 0xf8, 0x8c, + 0xb2, 0xf0, 0xd5, 0x28, 0x5a, 0x76, 0xc7, 0x2e, 0xaf, 0xe7, 0x33, 0x95, 0x42, 0x4f, 0x11, 0x47, + 0x7f, 0xa7, 0x78, 0x67, 0x05, 0xef, 0x5f, 0x1e, 0xe4, 0x1d, 0xf1, 0x49, 0x11, 0x9f, 0x02, 0x24, + 0x78, 0x1f, 0x12, 0x9f, 0x34, 0xe3, 0xb4, 0xe8, 0xc7, 0x30, 0x99, 0xba, 0x95, 0x42, 0xb6, 0x21, + 0xe7, 0x89, 0x1b, 0x99, 0xa9, 0xc5, 0xc1, 0x12, 0x24, 0x5a, 0x62, 0xf4, 0x22, 0x7c, 0xdf, 0x4b, + 0xd1, 0x3f, 0x84, 0xd7, 0xe3, 0x22, 0x4c, 0xc1, 0x78, 0xaf, 0xc8, 0xf9, 0x4a, 0x74, 0x48, 0x77, + 0x52, 0x64, 0x2e, 0x69, 0xf4, 0xeb, 0xa4, 0x63, 0x98, 0x15, 0xd6, 0x7f, 0x71, 0xd3, 0x67, 0x4f, + 0xfe, 0xb0, 0x2c, 0x9f, 0xf2, 0x6e, 0x95, 0xa7, 0xe1, 0x6b, 0x8f, 0xf9, 0x41, 0xd5, 0xb1, 0x24, + 0x26, 0x17, 0x1e, 0x0f, 0x2c, 0xf4, 0x23, 0x80, 0x59, 0x27, 0xae, 0x4b, 0x1b, 0xe1, 0x5b, 0x56, + 0xbc, 0xe5, 0xe5, 0xcd, 0x81, 0xa5, 0xef, 0x81, 0xda, 0xcf, 0xa9, 0xa4, 0xf1, 0x13, 0x7c, 0x47, + 0xc5, 0x43, 0x95, 0x44, 0x2f, 0xd2, 0xf9, 0x04, 0x4d, 0x9a, 0xeb, 0x65, 0x98, 0x17, 0x4e, 0x4e, + 0x58, 0x40, 0x1a, 0x91, 0xa7, 0x7d, 0xe6, 0x0b, 0x55, 0x89, 0x04, 0x88, 0xe2, 0xc6, 0x09, 0x10, + 0x07, 0xfd, 0x11, 0x2c, 0xdc, 0x0f, 0x94, 0x1c, 0xca, 0x90, 0x23, 0x4d, 0xd6, 0x72, 0x03, 0x59, + 0x91, 0xd9, 0x54, 0x0f, 0xc4, 0xd5, 0xdf, 0x63, 0x8e, 0x2b, 0xbb, 0x48, 0x9a, 0xaf, 0x5e, 0x7f, + 0x03, 0xe3, 0xc2, 0x3b, 0x7a, 0xa1, 0x40, 0x21, 0xd1, 0xb5, 0x68, 0x63, 0x70, 0x51, 0xef, 0x99, + 0x24, 0x75, 0x73, 0x54, 0x58, 0xa4, 0x40, 0x2f, 0x3e, 0x7d, 0xfb, 0xf1, 0x22, 0xbb, 0x88, 0x74, + 0x2c, 0x17, 0x56, 0x7a, 0x51, 0x25, 0x07, 0xe7, 0x59, 0x56, 0x41, 0xaf, 0x14, 0x80, 0x9e, 0x1b, + 0xb4, 0x3e, 0x52, 0xd4, 0x98, 0xeb, 0xc6, 0x88, 0x28, 0x49, 0xb5, 0x2c, 0xa8, 0x1a, 0x68, 0xe5, + 0x61, 0xaa, 0xb8, 0x13, 0x76, 0xe5, 0xce, 0xf2, 0xf2, 0x79, 0x48, 0xfa, 0x42, 0x81, 0x5c, 0x34, + 0x0c, 0xe8, 0xb7, 0x21, 0x42, 0xa7, 0x66, 0x51, 0x2d, 0x8d, 0x80, 0x90, 0x44, 0x17, 0x05, 0x51, + 0x0d, 0xcd, 0xf5, 0x27, 0x1a, 0xcd, 0x23, 0x7a, 0xa9, 0x40, 0xbe, 0x3b, 0x5c, 0x68, 0x6d, 0xd8, + 0x9c, 0x24, 0x26, 0x57, 0x5d, 0x1f, 0x0d, 0x24, 0xe9, 0x6d, 0x08, 0x7a, 0x18, 0x15, 0x07, 0xe5, + 0x31, 0xcc, 0x5f, 0x98, 0x47, 0x91, 0xcf, 0x30, 0x91, 0xe8, 0x9d, 0x02, 0x13, 0xa9, 0x49, 0x44, + 0xe5, 0x21, 0xc2, 0xf7, 0x5b, 0x08, 0xea, 0xd6, 0xe8, 0x40, 0xc9, 0xbd, 0x22, 0xb8, 0xff, 0x87, + 0xfe, 0xed, 0xcf, 0x5d, 0xee, 0x0e, 0x8e, 0x3b, 0xbd, 0xbd, 0x72, 0x8e, 0xc3, 0x6d, 0xc3, 0x71, + 0x47, 0xee, 0xa0, 0x73, 0x9c, 0x5e, 0x1b, 0xe8, 0x8d, 0x02, 0x93, 0x7d, 0x86, 0x1c, 0xed, 0x0c, + 0xc1, 0xf2, 0xfe, 0xad, 0xa2, 0xfe, 0xfe, 0xa5, 0x70, 0x29, 0x75, 0x5b, 0x48, 0xdd, 0x44, 0xeb, + 0x03, 0xca, 0xc4, 0x71, 0x47, 0xfc, 0x86, 0x05, 0xc2, 0x41, 0xe8, 0xac, 0x1a, 0x89, 0xdb, 0x3d, + 0xba, 0xbc, 0xd1, 0x94, 0xab, 0x1b, 0x4d, 0xf9, 0x70, 0xa3, 0x29, 0xcf, 0x6f, 0xb5, 0xcc, 0xd5, + 0xad, 0x96, 0x79, 0x7f, 0xab, 0x65, 0xfe, 0x2f, 0xdb, 0x4e, 0x50, 0x6f, 0xd5, 0x0c, 0x93, 0x35, + 0xb1, 0xfc, 0x67, 0xe1, 0xd4, 0xcc, 0xa2, 0xcd, 0x70, 0x7b, 0x0b, 0x37, 0x99, 0xd5, 0x6a, 0x50, + 0xfe, 0x59, 0xb8, 0xe0, 0xcc, 0xa3, 0xbc, 0x96, 0x13, 0x7f, 0x31, 0xd6, 0x3e, 0x05, 0x00, 0x00, + 0xff, 0xff, 0x30, 0xd1, 0xf4, 0xc9, 0x59, 0x09, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -684,8 +684,10 @@ const _ = grpc.SupportPackageIsVersion4 // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. type QueryClient interface { // DenomTraces queries all denomination traces. + // Deprecated: Please use the Denoms endpoint instead. DenomTraces(ctx context.Context, in *QueryDenomTracesRequest, opts ...grpc.CallOption) (*QueryDenomTracesResponse, error) // DenomTrace queries a denomination trace information. + // Deprecated: Please se the Denom endpoint instead. DenomTrace(ctx context.Context, in *QueryDenomTraceRequest, opts ...grpc.CallOption) (*QueryDenomTraceResponse, error) // Params queries all parameters of the ibc-transfer module. Params(ctx context.Context, in *QueryParamsRequest, opts ...grpc.CallOption) (*QueryParamsResponse, error) @@ -705,6 +707,7 @@ func NewQueryClient(cc grpc1.ClientConn) QueryClient { return &queryClient{cc} } +// Deprecated: Do not use. func (c *queryClient) DenomTraces(ctx context.Context, in *QueryDenomTracesRequest, opts ...grpc.CallOption) (*QueryDenomTracesResponse, error) { out := new(QueryDenomTracesResponse) err := c.cc.Invoke(ctx, "/ibc.applications.transfer.v1.Query/DenomTraces", in, out, opts...) @@ -714,6 +717,7 @@ func (c *queryClient) DenomTraces(ctx context.Context, in *QueryDenomTracesReque return out, nil } +// Deprecated: Do not use. func (c *queryClient) DenomTrace(ctx context.Context, in *QueryDenomTraceRequest, opts ...grpc.CallOption) (*QueryDenomTraceResponse, error) { out := new(QueryDenomTraceResponse) err := c.cc.Invoke(ctx, "/ibc.applications.transfer.v1.Query/DenomTrace", in, out, opts...) @@ -762,8 +766,10 @@ func (c *queryClient) TotalEscrowForDenom(ctx context.Context, in *QueryTotalEsc // QueryServer is the server API for Query service. type QueryServer interface { // DenomTraces queries all denomination traces. + // Deprecated: Please use the Denoms endpoint instead. DenomTraces(context.Context, *QueryDenomTracesRequest) (*QueryDenomTracesResponse, error) // DenomTrace queries a denomination trace information. + // Deprecated: Please se the Denom endpoint instead. DenomTrace(context.Context, *QueryDenomTraceRequest) (*QueryDenomTraceResponse, error) // Params queries all parameters of the ibc-transfer module. Params(context.Context, *QueryParamsRequest) (*QueryParamsResponse, error) diff --git a/modules/apps/transfer/types/queryv2.pb.go b/modules/apps/transfer/types/queryv2.pb.go new file mode 100644 index 00000000000..66f03fb387e --- /dev/null +++ b/modules/apps/transfer/types/queryv2.pb.go @@ -0,0 +1,1075 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ibc/applications/transfer/v2/queryv2.proto + +package types + +import ( + context "context" + fmt "fmt" + query "github.com/cosmos/cosmos-sdk/types/query" + _ "github.com/cosmos/gogoproto/gogoproto" + grpc1 "github.com/cosmos/gogoproto/grpc" + proto "github.com/cosmos/gogoproto/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// QueryDenomRequest is the request type for the Query/Denom RPC +// method +type QueryDenomRequest struct { + // hash (in hex format) or denom (full denom with ibc prefix) of the on chain denomination. + Hash string `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` +} + +func (m *QueryDenomRequest) Reset() { *m = QueryDenomRequest{} } +func (m *QueryDenomRequest) String() string { return proto.CompactTextString(m) } +func (*QueryDenomRequest) ProtoMessage() {} +func (*QueryDenomRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_03a5118d32b8ebb9, []int{0} +} +func (m *QueryDenomRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDenomRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDenomRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryDenomRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDenomRequest.Merge(m, src) +} +func (m *QueryDenomRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryDenomRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDenomRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDenomRequest proto.InternalMessageInfo + +func (m *QueryDenomRequest) GetHash() string { + if m != nil { + return m.Hash + } + return "" +} + +// QueryDenomResponse is the response type for the Query/Denom RPC +// method. +type QueryDenomResponse struct { + // denom returns the requested denomination. + Denom *Denom `protobuf:"bytes,1,opt,name=denom,proto3" json:"denom,omitempty"` +} + +func (m *QueryDenomResponse) Reset() { *m = QueryDenomResponse{} } +func (m *QueryDenomResponse) String() string { return proto.CompactTextString(m) } +func (*QueryDenomResponse) ProtoMessage() {} +func (*QueryDenomResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_03a5118d32b8ebb9, []int{1} +} +func (m *QueryDenomResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDenomResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDenomResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryDenomResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDenomResponse.Merge(m, src) +} +func (m *QueryDenomResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryDenomResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDenomResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDenomResponse proto.InternalMessageInfo + +func (m *QueryDenomResponse) GetDenom() *Denom { + if m != nil { + return m.Denom + } + return nil +} + +// QueryDenomsRequest is the request type for the Query/Denoms RPC +// method +type QueryDenomsRequest struct { + // pagination defines an optional pagination for the request. + Pagination *query.PageRequest `protobuf:"bytes,1,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryDenomsRequest) Reset() { *m = QueryDenomsRequest{} } +func (m *QueryDenomsRequest) String() string { return proto.CompactTextString(m) } +func (*QueryDenomsRequest) ProtoMessage() {} +func (*QueryDenomsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_03a5118d32b8ebb9, []int{2} +} +func (m *QueryDenomsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDenomsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDenomsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryDenomsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDenomsRequest.Merge(m, src) +} +func (m *QueryDenomsRequest) XXX_Size() int { + return m.Size() +} +func (m *QueryDenomsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDenomsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDenomsRequest proto.InternalMessageInfo + +func (m *QueryDenomsRequest) GetPagination() *query.PageRequest { + if m != nil { + return m.Pagination + } + return nil +} + +// QueryDenomsResponse is the response type for the Query/Denoms RPC +// method. +type QueryDenomsResponse struct { + // denoms returns all denominations. + Denoms Denoms `protobuf:"bytes,1,rep,name=denoms,proto3,castrepeated=Denoms" json:"denoms"` + // pagination defines the pagination in the response. + Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` +} + +func (m *QueryDenomsResponse) Reset() { *m = QueryDenomsResponse{} } +func (m *QueryDenomsResponse) String() string { return proto.CompactTextString(m) } +func (*QueryDenomsResponse) ProtoMessage() {} +func (*QueryDenomsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_03a5118d32b8ebb9, []int{3} +} +func (m *QueryDenomsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *QueryDenomsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_QueryDenomsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *QueryDenomsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_QueryDenomsResponse.Merge(m, src) +} +func (m *QueryDenomsResponse) XXX_Size() int { + return m.Size() +} +func (m *QueryDenomsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_QueryDenomsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_QueryDenomsResponse proto.InternalMessageInfo + +func (m *QueryDenomsResponse) GetDenoms() Denoms { + if m != nil { + return m.Denoms + } + return nil +} + +func (m *QueryDenomsResponse) GetPagination() *query.PageResponse { + if m != nil { + return m.Pagination + } + return nil +} + +func init() { + proto.RegisterType((*QueryDenomRequest)(nil), "ibc.applications.transfer.v2.QueryDenomRequest") + proto.RegisterType((*QueryDenomResponse)(nil), "ibc.applications.transfer.v2.QueryDenomResponse") + proto.RegisterType((*QueryDenomsRequest)(nil), "ibc.applications.transfer.v2.QueryDenomsRequest") + proto.RegisterType((*QueryDenomsResponse)(nil), "ibc.applications.transfer.v2.QueryDenomsResponse") +} + +func init() { + proto.RegisterFile("ibc/applications/transfer/v2/queryv2.proto", fileDescriptor_03a5118d32b8ebb9) +} + +var fileDescriptor_03a5118d32b8ebb9 = []byte{ + // 464 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x93, 0xbf, 0x8a, 0x13, 0x41, + 0x1c, 0xc7, 0x33, 0xd1, 0x8b, 0x38, 0x82, 0xe0, 0x68, 0x71, 0x84, 0xb0, 0x77, 0xac, 0x72, 0x17, + 0x02, 0xce, 0xef, 0xb2, 0x16, 0x6a, 0x61, 0x73, 0x88, 0x16, 0x16, 0x7a, 0x29, 0x2c, 0xc4, 0x66, + 0x76, 0x6f, 0x9c, 0x0c, 0x26, 0xfb, 0xdb, 0xcb, 0x4c, 0x16, 0x0e, 0xb1, 0xf1, 0x09, 0x84, 0xeb, + 0x7c, 0x04, 0x7d, 0x05, 0x1f, 0xe0, 0xca, 0x80, 0x8d, 0x95, 0x4a, 0xe2, 0x83, 0xc8, 0xce, 0xce, + 0xe2, 0x46, 0x61, 0x8d, 0xdd, 0xb0, 0xfb, 0xfd, 0xf3, 0x99, 0x1f, 0xbf, 0xa1, 0x03, 0x1d, 0x27, + 0x20, 0xb2, 0x6c, 0xa2, 0x13, 0x61, 0x35, 0xa6, 0x06, 0xec, 0x4c, 0xa4, 0xe6, 0x95, 0x9c, 0x41, + 0x1e, 0xc1, 0xc9, 0x5c, 0xce, 0x4e, 0xf3, 0x88, 0x67, 0x33, 0xb4, 0xc8, 0x7a, 0x3a, 0x4e, 0x78, + 0x5d, 0xcb, 0x2b, 0x2d, 0xcf, 0xa3, 0xee, 0x0d, 0x85, 0x0a, 0x9d, 0x10, 0x8a, 0x53, 0xe9, 0xe9, + 0x0e, 0x12, 0x34, 0x53, 0x34, 0x10, 0x0b, 0x23, 0xcb, 0x38, 0xc8, 0x87, 0xb1, 0xb4, 0x62, 0x08, + 0x99, 0x50, 0x3a, 0x75, 0x41, 0x5e, 0xdb, 0x6f, 0x64, 0xb1, 0xf8, 0x5a, 0x56, 0xca, 0x9e, 0x42, + 0x54, 0x13, 0x09, 0x22, 0xd3, 0x20, 0xd2, 0x14, 0xad, 0xe7, 0x71, 0x7f, 0xc3, 0x7d, 0x7a, 0xed, + 0xa8, 0x68, 0x7a, 0x28, 0x53, 0x9c, 0x8e, 0xe4, 0xc9, 0x5c, 0x1a, 0xcb, 0x18, 0xbd, 0x38, 0x16, + 0x66, 0xbc, 0x4d, 0x76, 0x49, 0xff, 0xf2, 0xc8, 0x9d, 0xc3, 0xa7, 0x94, 0xd5, 0x85, 0x26, 0xc3, + 0xd4, 0x48, 0x76, 0x9f, 0x6e, 0x1d, 0x17, 0x1f, 0x9c, 0xf4, 0x4a, 0x74, 0x93, 0x37, 0x5d, 0x9b, + 0x97, 0xde, 0xd2, 0x11, 0xbe, 0xac, 0x07, 0x9a, 0xaa, 0xfa, 0x11, 0xa5, 0xbf, 0xef, 0xea, 0x53, + 0xf7, 0x78, 0x39, 0x18, 0x5e, 0x0c, 0x86, 0xbb, 0xc1, 0x70, 0x3f, 0x18, 0xfe, 0x4c, 0x28, 0xe9, + 0xbd, 0xa3, 0x9a, 0x33, 0xfc, 0x44, 0xe8, 0xf5, 0xb5, 0x78, 0x0f, 0xfc, 0x84, 0x76, 0x5c, 0xbd, + 0xd9, 0x26, 0xbb, 0x17, 0x36, 0x24, 0x3e, 0xbc, 0x7a, 0xfe, 0x6d, 0xa7, 0xf5, 0xf1, 0xfb, 0x4e, + 0xc7, 0x87, 0xf9, 0x08, 0xf6, 0x78, 0x0d, 0xb6, 0xed, 0x60, 0xf7, 0xff, 0x09, 0x5b, 0x92, 0xd4, + 0x69, 0xa3, 0xcf, 0x6d, 0x7a, 0xc9, 0xd1, 0x3e, 0x8f, 0xd8, 0x19, 0xa1, 0xbe, 0x87, 0x1d, 0x34, + 0xc3, 0xfd, 0x3d, 0xbe, 0xee, 0xf0, 0x3f, 0x1c, 0x25, 0x47, 0x78, 0xeb, 0xdd, 0x97, 0x9f, 0x67, + 0xed, 0x80, 0xf5, 0xc0, 0xaf, 0xd4, 0xfa, 0x2a, 0xf9, 0xab, 0x7e, 0x20, 0x74, 0xcb, 0x19, 0x19, + 0x6c, 0x5a, 0x51, 0x31, 0x1d, 0x6c, 0x6e, 0xf0, 0x48, 0xdc, 0x21, 0xf5, 0xd9, 0x5e, 0x13, 0x12, + 0xbc, 0x29, 0xf6, 0xf2, 0xc1, 0x60, 0xf0, 0xf6, 0xf0, 0xe8, 0x7c, 0x19, 0x90, 0xc5, 0x32, 0x20, + 0x3f, 0x96, 0x01, 0x79, 0xbf, 0x0a, 0x5a, 0x8b, 0x55, 0xd0, 0xfa, 0xba, 0x0a, 0x5a, 0x2f, 0xee, + 0x2a, 0x6d, 0xc7, 0xf3, 0x98, 0x27, 0x38, 0x05, 0xff, 0xba, 0x74, 0x9c, 0xdc, 0x56, 0x08, 0xf9, + 0x3d, 0x98, 0xe2, 0xf1, 0x7c, 0x22, 0xcd, 0x1f, 0x05, 0xf6, 0x34, 0x93, 0x26, 0xee, 0xb8, 0xe7, + 0x71, 0xe7, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x99, 0x73, 0xcf, 0x4d, 0xf4, 0x03, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// QueryV2Client is the client API for QueryV2 service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type QueryV2Client interface { + // Denoms queries all denominations + Denoms(ctx context.Context, in *QueryDenomsRequest, opts ...grpc.CallOption) (*QueryDenomsResponse, error) + // Denom queries a denomination + Denom(ctx context.Context, in *QueryDenomRequest, opts ...grpc.CallOption) (*QueryDenomResponse, error) +} + +type queryV2Client struct { + cc grpc1.ClientConn +} + +func NewQueryV2Client(cc grpc1.ClientConn) QueryV2Client { + return &queryV2Client{cc} +} + +func (c *queryV2Client) Denoms(ctx context.Context, in *QueryDenomsRequest, opts ...grpc.CallOption) (*QueryDenomsResponse, error) { + out := new(QueryDenomsResponse) + err := c.cc.Invoke(ctx, "/ibc.applications.transfer.v2.QueryV2/Denoms", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *queryV2Client) Denom(ctx context.Context, in *QueryDenomRequest, opts ...grpc.CallOption) (*QueryDenomResponse, error) { + out := new(QueryDenomResponse) + err := c.cc.Invoke(ctx, "/ibc.applications.transfer.v2.QueryV2/Denom", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// QueryV2Server is the server API for QueryV2 service. +type QueryV2Server interface { + // Denoms queries all denominations + Denoms(context.Context, *QueryDenomsRequest) (*QueryDenomsResponse, error) + // Denom queries a denomination + Denom(context.Context, *QueryDenomRequest) (*QueryDenomResponse, error) +} + +// UnimplementedQueryV2Server can be embedded to have forward compatible implementations. +type UnimplementedQueryV2Server struct { +} + +func (*UnimplementedQueryV2Server) Denoms(ctx context.Context, req *QueryDenomsRequest) (*QueryDenomsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Denoms not implemented") +} +func (*UnimplementedQueryV2Server) Denom(ctx context.Context, req *QueryDenomRequest) (*QueryDenomResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Denom not implemented") +} + +func RegisterQueryV2Server(s grpc1.Server, srv QueryV2Server) { + s.RegisterService(&_QueryV2_serviceDesc, srv) +} + +func _QueryV2_Denoms_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryDenomsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryV2Server).Denoms(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.applications.transfer.v2.QueryV2/Denoms", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryV2Server).Denoms(ctx, req.(*QueryDenomsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _QueryV2_Denom_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(QueryDenomRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(QueryV2Server).Denom(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/ibc.applications.transfer.v2.QueryV2/Denom", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(QueryV2Server).Denom(ctx, req.(*QueryDenomRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _QueryV2_serviceDesc = grpc.ServiceDesc{ + ServiceName: "ibc.applications.transfer.v2.QueryV2", + HandlerType: (*QueryV2Server)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Denoms", + Handler: _QueryV2_Denoms_Handler, + }, + { + MethodName: "Denom", + Handler: _QueryV2_Denom_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "ibc/applications/transfer/v2/queryv2.proto", +} + +func (m *QueryDenomRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryDenomRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDenomRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Hash) > 0 { + i -= len(m.Hash) + copy(dAtA[i:], m.Hash) + i = encodeVarintQueryv2(dAtA, i, uint64(len(m.Hash))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryDenomResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryDenomResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDenomResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Denom != nil { + { + size, err := m.Denom.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQueryv2(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryDenomsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryDenomsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDenomsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQueryv2(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *QueryDenomsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *QueryDenomsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *QueryDenomsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Pagination != nil { + { + size, err := m.Pagination.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQueryv2(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Denoms) > 0 { + for iNdEx := len(m.Denoms) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Denoms[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintQueryv2(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func encodeVarintQueryv2(dAtA []byte, offset int, v uint64) int { + offset -= sovQueryv2(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *QueryDenomRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Hash) + if l > 0 { + n += 1 + l + sovQueryv2(uint64(l)) + } + return n +} + +func (m *QueryDenomResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Denom != nil { + l = m.Denom.Size() + n += 1 + l + sovQueryv2(uint64(l)) + } + return n +} + +func (m *QueryDenomsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQueryv2(uint64(l)) + } + return n +} + +func (m *QueryDenomsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Denoms) > 0 { + for _, e := range m.Denoms { + l = e.Size() + n += 1 + l + sovQueryv2(uint64(l)) + } + } + if m.Pagination != nil { + l = m.Pagination.Size() + n += 1 + l + sovQueryv2(uint64(l)) + } + return n +} + +func sovQueryv2(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozQueryv2(x uint64) (n int) { + return sovQueryv2(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *QueryDenomRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryDenomRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDenomRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Hash", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthQueryv2 + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthQueryv2 + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Hash = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQueryv2(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQueryv2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryDenomResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryDenomResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDenomResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denom", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQueryv2 + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQueryv2 + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Denom == nil { + m.Denom = &Denom{} + } + if err := m.Denom.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQueryv2(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQueryv2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryDenomsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryDenomsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDenomsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQueryv2 + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQueryv2 + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageRequest{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQueryv2(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQueryv2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *QueryDenomsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: QueryDenomsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: QueryDenomsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Denoms", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQueryv2 + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQueryv2 + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Denoms = append(m.Denoms, Denom{}) + if err := m.Denoms[len(m.Denoms)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pagination", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthQueryv2 + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthQueryv2 + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pagination == nil { + m.Pagination = &query.PageResponse{} + } + if err := m.Pagination.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipQueryv2(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthQueryv2 + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipQueryv2(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowQueryv2 + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthQueryv2 + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupQueryv2 + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthQueryv2 + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthQueryv2 = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowQueryv2 = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupQueryv2 = fmt.Errorf("proto: unexpected end of group") +) diff --git a/modules/apps/transfer/types/queryv2.pb.gw.go b/modules/apps/transfer/types/queryv2.pb.gw.go new file mode 100644 index 00000000000..ba1dc6b7218 --- /dev/null +++ b/modules/apps/transfer/types/queryv2.pb.gw.go @@ -0,0 +1,272 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: ibc/applications/transfer/v2/queryv2.proto + +/* +Package types is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package types + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +var ( + filter_QueryV2_Denoms_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_QueryV2_Denoms_0(ctx context.Context, marshaler runtime.Marshaler, client QueryV2Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDenomsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_QueryV2_Denoms_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Denoms(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_QueryV2_Denoms_0(ctx context.Context, marshaler runtime.Marshaler, server QueryV2Server, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDenomsRequest + var metadata runtime.ServerMetadata + + if err := req.ParseForm(); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_QueryV2_Denoms_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Denoms(ctx, &protoReq) + return msg, metadata, err + +} + +func request_QueryV2_Denom_0(ctx context.Context, marshaler runtime.Marshaler, client QueryV2Client, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDenomRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["hash"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "hash") + } + + protoReq.Hash, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "hash", err) + } + + msg, err := client.Denom(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_QueryV2_Denom_0(ctx context.Context, marshaler runtime.Marshaler, server QueryV2Server, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq QueryDenomRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["hash"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "hash") + } + + protoReq.Hash, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "hash", err) + } + + msg, err := server.Denom(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterQueryV2HandlerServer registers the http handlers for service QueryV2 to "mux". +// UnaryRPC :call QueryV2Server directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterQueryV2HandlerFromEndpoint instead. +func RegisterQueryV2HandlerServer(ctx context.Context, mux *runtime.ServeMux, server QueryV2Server) error { + + mux.Handle("GET", pattern_QueryV2_Denoms_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_QueryV2_Denoms_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_QueryV2_Denoms_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_QueryV2_Denom_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_QueryV2_Denom_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_QueryV2_Denom_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterQueryV2HandlerFromEndpoint is same as RegisterQueryV2Handler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterQueryV2HandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterQueryV2Handler(ctx, mux, conn) +} + +// RegisterQueryV2Handler registers the http handlers for service QueryV2 to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterQueryV2Handler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterQueryV2HandlerClient(ctx, mux, NewQueryV2Client(conn)) +} + +// RegisterQueryV2HandlerClient registers the http handlers for service QueryV2 +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "QueryV2Client". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "QueryV2Client" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "QueryV2Client" to call the correct interceptors. +func RegisterQueryV2HandlerClient(ctx context.Context, mux *runtime.ServeMux, client QueryV2Client) error { + + mux.Handle("GET", pattern_QueryV2_Denoms_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_QueryV2_Denoms_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_QueryV2_Denoms_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_QueryV2_Denom_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_QueryV2_Denom_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_QueryV2_Denom_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_QueryV2_Denoms_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4}, []string{"ibc", "apps", "transfer", "v2", "denoms"}, "", runtime.AssumeColonVerbOpt(false))) + + pattern_QueryV2_Denom_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3, 2, 4, 3, 0, 4, 1, 5, 5}, []string{"ibc", "apps", "transfer", "v2", "denoms", "hash"}, "", runtime.AssumeColonVerbOpt(false))) +) + +var ( + forward_QueryV2_Denoms_0 = runtime.ForwardResponseMessage + + forward_QueryV2_Denom_0 = runtime.ForwardResponseMessage +) diff --git a/modules/apps/transfer/types/trace.go b/modules/apps/transfer/types/trace.go index 3287ffc1796..2d18dc0e760 100644 --- a/modules/apps/transfer/types/trace.go +++ b/modules/apps/transfer/types/trace.go @@ -4,7 +4,6 @@ import ( "crypto/sha256" "encoding/hex" "fmt" - "sort" "strings" errorsmod "cosmossdk.io/errors" @@ -77,11 +76,6 @@ func (dt DenomTrace) GetFullDenomPath() string { return dt.GetPrefix() + dt.BaseDenom } -// IsNativeDenom returns true if the denomination is native, thus containing no trace history. -func (dt DenomTrace) IsNativeDenom() bool { - return dt.Path == "" -} - // extractPathAndBaseFromFullDenom returns the trace path and the base denom from // the elements that constitute the complete denom. func extractPathAndBaseFromFullDenom(fullDenomItems []string) ([]string, string) { @@ -148,43 +142,6 @@ func (dt DenomTrace) Validate() error { return validateTraceIdentifiers(identifiers) } -// Traces defines a wrapper type for a slice of DenomTrace. -type Traces []DenomTrace - -// Validate performs a basic validation of each denomination trace info. -func (t Traces) Validate() error { - seenTraces := make(map[string]bool) - for i, trace := range t { - hash := trace.Hash().String() - if seenTraces[hash] { - return fmt.Errorf("duplicated denomination trace with hash %s", trace.Hash()) - } - - if err := trace.Validate(); err != nil { - return errorsmod.Wrapf(err, "failed denom trace %d validation", i) - } - seenTraces[hash] = true - } - return nil -} - -var _ sort.Interface = (*Traces)(nil) - -// Len implements sort.Interface for Traces -func (t Traces) Len() int { return len(t) } - -// Less implements sort.Interface for Traces -func (t Traces) Less(i, j int) bool { return t[i].GetFullDenomPath() < t[j].GetFullDenomPath() } - -// Swap implements sort.Interface for Traces -func (t Traces) Swap(i, j int) { t[i], t[j] = t[j], t[i] } - -// Sort is a helper function to sort the set of denomination traces in-place -func (t Traces) Sort() Traces { - sort.Sort(t) - return t -} - // ValidatePrefixedDenom checks that the denomination for an IBC fungible token packet denom is correctly prefixed. // The function will return no error if the given string follows one of the two formats: // diff --git a/modules/apps/transfer/types/trace_test.go b/modules/apps/transfer/types/trace_test.go index f7634a7a3b0..40ad3037586 100644 --- a/modules/apps/transfer/types/trace_test.go +++ b/modules/apps/transfer/types/trace_test.go @@ -94,37 +94,6 @@ func TestDenomTrace_Validate(t *testing.T) { } } -func TestTraces_Validate(t *testing.T) { - testCases := []struct { - name string - traces types.Traces - expError bool - }{ - {"empty Traces", types.Traces{}, false}, - {"valid multiple trace info", types.Traces{{BaseDenom: "uatom", Path: "transfer/channel-1/transfer/channel-2"}}, false}, - { - "valid multiple trace info", - types.Traces{ - {BaseDenom: "uatom", Path: "transfer/channel-1/transfer/channel-2"}, - {BaseDenom: "uatom", Path: "transfer/channel-1/transfer/channel-2"}, - }, - true, - }, - {"empty base denom with trace", types.Traces{{BaseDenom: "", Path: "transfer/channel-1"}}, true}, - } - - for _, tc := range testCases { - tc := tc - - err := tc.traces.Validate() - if tc.expError { - require.Error(t, err, tc.name) - continue - } - require.NoError(t, err, tc.name) - } -} - func TestValidatePrefixedDenom(t *testing.T) { testCases := []struct { name string diff --git a/proto/ibc/applications/transfer/v1/query.proto b/proto/ibc/applications/transfer/v1/query.proto index 788296718fe..697df1462ff 100644 --- a/proto/ibc/applications/transfer/v1/query.proto +++ b/proto/ibc/applications/transfer/v1/query.proto @@ -4,21 +4,25 @@ package ibc.applications.transfer.v1; import "gogoproto/gogo.proto"; import "cosmos/base/v1beta1/coin.proto"; -import "cosmos/base/query/v1beta1/pagination.proto"; import "ibc/applications/transfer/v1/transfer.proto"; import "google/api/annotations.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; // Query provides defines the gRPC querier service. service Query { // DenomTraces queries all denomination traces. + // Deprecated: Please use the Denoms endpoint instead. rpc DenomTraces(QueryDenomTracesRequest) returns (QueryDenomTracesResponse) { + option deprecated = true; option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces"; } // DenomTrace queries a denomination trace information. + // Deprecated: Please see the Denom endpoint instead. rpc DenomTrace(QueryDenomTraceRequest) returns (QueryDenomTraceResponse) { + option deprecated = true; option (google.api.http).get = "/ibc/apps/transfer/v1/denom_traces/{hash=**}"; } @@ -68,7 +72,7 @@ message QueryDenomTracesRequest { // method. message QueryDenomTracesResponse { // denom_traces returns all denominations trace information. - repeated DenomTrace denom_traces = 1 [(gogoproto.castrepeated) = "Traces", (gogoproto.nullable) = false]; + repeated DenomTrace denom_traces = 1 [(gogoproto.nullable) = false]; // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; } diff --git a/proto/ibc/applications/transfer/v1/genesis.proto b/proto/ibc/applications/transfer/v2/genesis.proto similarity index 62% rename from proto/ibc/applications/transfer/v1/genesis.proto rename to proto/ibc/applications/transfer/v2/genesis.proto index f7d707f6ccf..137c1a67b76 100644 --- a/proto/ibc/applications/transfer/v1/genesis.proto +++ b/proto/ibc/applications/transfer/v2/genesis.proto @@ -1,18 +1,19 @@ syntax = "proto3"; -package ibc.applications.transfer.v1; +package ibc.applications.transfer.v2; option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; import "ibc/applications/transfer/v1/transfer.proto"; +import "ibc/applications/transfer/v2/token.proto"; import "cosmos/base/v1beta1/coin.proto"; import "gogoproto/gogo.proto"; // GenesisState defines the ibc-transfer genesis state message GenesisState { - string port_id = 1; - repeated DenomTrace denom_traces = 2 [(gogoproto.castrepeated) = "Traces", (gogoproto.nullable) = false]; - Params params = 3 [(gogoproto.nullable) = false]; + string port_id = 1; + repeated Denom denoms = 2 [(gogoproto.castrepeated) = "Denoms", (gogoproto.nullable) = false]; + ibc.applications.transfer.v1.Params params = 3 [(gogoproto.nullable) = false]; // total_escrowed contains the total amount of tokens escrowed // by the transfer module repeated cosmos.base.v1beta1.Coin total_escrowed = 4 diff --git a/proto/ibc/applications/transfer/v2/queryv2.proto b/proto/ibc/applications/transfer/v2/queryv2.proto new file mode 100644 index 00000000000..be54ffb5a6a --- /dev/null +++ b/proto/ibc/applications/transfer/v2/queryv2.proto @@ -0,0 +1,53 @@ +syntax = "proto3"; + +package ibc.applications.transfer.v2; + +option go_package = "github.com/cosmos/ibc-go/v8/modules/apps/transfer/types"; + +import "gogoproto/gogo.proto"; +import "cosmos/base/query/v1beta1/pagination.proto"; +import "ibc/applications/transfer/v2/token.proto"; +import "google/api/annotations.proto"; + +// QueryV2 provides defines the gRPC querier service for ics20-v2. +service QueryV2 { + // Denoms queries all denominations + rpc Denoms(QueryDenomsRequest) returns (QueryDenomsResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v2/denoms"; + } + + // Denom queries a denomination + rpc Denom(QueryDenomRequest) returns (QueryDenomResponse) { + option (google.api.http).get = "/ibc/apps/transfer/v2/denoms/{hash=**}"; + } +} + +// QueryDenomRequest is the request type for the Query/Denom RPC +// method +message QueryDenomRequest { + // hash (in hex format) or denom (full denom with ibc prefix) of the on chain denomination. + string hash = 1; +} + +// QueryDenomResponse is the response type for the Query/Denom RPC +// method. +message QueryDenomResponse { + // denom returns the requested denomination. + Denom denom = 1; +} + +// QueryDenomsRequest is the request type for the Query/Denoms RPC +// method +message QueryDenomsRequest { + // pagination defines an optional pagination for the request. + cosmos.base.query.v1beta1.PageRequest pagination = 1; +} + +// QueryDenomsResponse is the response type for the Query/Denoms RPC +// method. +message QueryDenomsResponse { + // denoms returns all denominations. + repeated Denom denoms = 1 [(gogoproto.castrepeated) = "Denoms", (gogoproto.nullable) = false]; + // pagination defines the pagination in the response. + cosmos.base.query.v1beta1.PageResponse pagination = 2; +}