Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: grpc query total timeout fees #1033

Merged
merged 12 commits into from
Mar 2, 2022
66 changes: 66 additions & 0 deletions docs/ibc/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,12 @@
- [QueryIncentivizedPacketResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketResponse)
- [QueryIncentivizedPacketsRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketsRequest)
- [QueryIncentivizedPacketsResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketsResponse)
- [QueryTotalAckFeesRequest](#ibc.applications.fee.v1.QueryTotalAckFeesRequest)
- [QueryTotalAckFeesResponse](#ibc.applications.fee.v1.QueryTotalAckFeesResponse)
- [QueryTotalRecvFeesRequest](#ibc.applications.fee.v1.QueryTotalRecvFeesRequest)
- [QueryTotalRecvFeesResponse](#ibc.applications.fee.v1.QueryTotalRecvFeesResponse)
- [QueryTotalTimeoutFeesRequest](#ibc.applications.fee.v1.QueryTotalTimeoutFeesRequest)
- [QueryTotalTimeoutFeesResponse](#ibc.applications.fee.v1.QueryTotalTimeoutFeesResponse)

- [Query](#ibc.applications.fee.v1.Query)

Expand Down Expand Up @@ -986,6 +990,36 @@ QueryIncentivizedPacketsResponse is the response type for the incentivized packe



<a name="ibc.applications.fee.v1.QueryTotalAckFeesRequest"></a>

### QueryTotalAckFeesRequest
QueryTotalAckFeesRequest defines the request type for the TotalAckFees rpc


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | the packet identifier for the associated fees |






<a name="ibc.applications.fee.v1.QueryTotalAckFeesResponse"></a>

### QueryTotalAckFeesResponse
QueryTotalAckFeesResponse defines the response type for the TotalAckFees rpc


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `ack_fees` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | the total packet acknowledgement fees |






<a name="ibc.applications.fee.v1.QueryTotalRecvFeesRequest"></a>

### QueryTotalRecvFeesRequest
Expand Down Expand Up @@ -1015,6 +1049,36 @@ QueryTotalRecvFeesResponse defines the response type for the TotalRecvFees rpc




<a name="ibc.applications.fee.v1.QueryTotalTimeoutFeesRequest"></a>

### QueryTotalTimeoutFeesRequest
QueryTotalTimeoutFeesRequest defines the request type for the TotalTimeoutFees rpc


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `packet_id` | [ibc.core.channel.v1.PacketId](#ibc.core.channel.v1.PacketId) | | the packet identifier for the associated fees |






<a name="ibc.applications.fee.v1.QueryTotalTimeoutFeesResponse"></a>

### QueryTotalTimeoutFeesResponse
QueryTotalTimeoutFeesResponse defines the response type for the TotalTimeoutFees rpc


| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| `timeout_fees` | [cosmos.base.v1beta1.Coin](#cosmos.base.v1beta1.Coin) | repeated | the total packet timeout fees |





<!-- end messages -->

<!-- end enums -->
Expand All @@ -1032,6 +1096,8 @@ Query provides defines the gRPC querier service.
| `IncentivizedPackets` | [QueryIncentivizedPacketsRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketsRequest) | [QueryIncentivizedPacketsResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketsResponse) | Gets all incentivized packets | GET|/ibc/apps/fee/v1/incentivized_packets|
| `IncentivizedPacket` | [QueryIncentivizedPacketRequest](#ibc.applications.fee.v1.QueryIncentivizedPacketRequest) | [QueryIncentivizedPacketResponse](#ibc.applications.fee.v1.QueryIncentivizedPacketResponse) | Gets the fees expected for submitting the ReceivePacket, AcknowledgementPacket, and TimeoutPacket messages for the given packet | GET|/ibc/apps/fee/v1/incentivized_packet/port/{packet_id.port_id}/channel/{packet_id.channel_id}/sequence/{packet_id.sequence}|
| `TotalRecvFees` | [QueryTotalRecvFeesRequest](#ibc.applications.fee.v1.QueryTotalRecvFeesRequest) | [QueryTotalRecvFeesResponse](#ibc.applications.fee.v1.QueryTotalRecvFeesResponse) | TotalRecvFees returns the total receive fees for a packet given its identifier | GET|/ibc/apps/fee/v1/total_recv_fees/port/{packet_id.port_id}/channel/{packet_id.channel_id}/sequence/{packet_id.sequence}|
| `TotalAckFees` | [QueryTotalAckFeesRequest](#ibc.applications.fee.v1.QueryTotalAckFeesRequest) | [QueryTotalAckFeesResponse](#ibc.applications.fee.v1.QueryTotalAckFeesResponse) | TotalAckFees returns the total acknowledgement fees for a packet given its identifier | GET|/ibc/apps/fee/v1/total_ack_fees/port/{packet_id.port_id}/channel/{packet_id.channel_id}/sequence/{packet_id.sequence}|
| `TotalTimeoutFees` | [QueryTotalTimeoutFeesRequest](#ibc.applications.fee.v1.QueryTotalTimeoutFeesRequest) | [QueryTotalTimeoutFeesResponse](#ibc.applications.fee.v1.QueryTotalTimeoutFeesResponse) | TotalTimeoutFees returns the total timeout fees for a packet given its identifier | GET|/ibc/apps/fee/v1/total_timeout_fees/port/{packet_id.port_id}/channel/{packet_id.channel_id}/sequence/{packet_id.sequence}|

<!-- end services -->

Expand Down
52 changes: 52 additions & 0 deletions modules/apps/29-fee/keeper/grpc_query.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,3 +91,55 @@ func (k Keeper) TotalRecvFees(goCtx context.Context, req *types.QueryTotalRecvFe
RecvFees: recvFees,
}, nil
}

// TotalAckFees implements the Query/TotalAckFees gRPC method
func (k Keeper) TotalAckFees(goCtx context.Context, req *types.QueryTotalAckFeesRequest) (*types.QueryTotalAckFeesResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}

ctx := sdk.UnwrapSDKContext(goCtx)

feesInEscrow, found := k.GetFeesInEscrow(ctx, req.PacketId)
if !found {
return nil, status.Errorf(
codes.NotFound,
sdkerrors.Wrapf(types.ErrFeeNotFound, "channel: %s, port: %s, sequence: %d", req.PacketId.ChannelId, req.PacketId.PortId, req.PacketId.Sequence).Error(),
)
}

var ackFees sdk.Coins
for _, packetFee := range feesInEscrow.PacketFees {
ackFees = ackFees.Add(packetFee.Fee.AckFee...)
}

return &types.QueryTotalAckFeesResponse{
AckFees: ackFees,
}, nil
}

// TotalTimeoutFees implements the Query/TotalTimeoutFees gRPC method
func (k Keeper) TotalTimeoutFees(goCtx context.Context, req *types.QueryTotalTimeoutFeesRequest) (*types.QueryTotalTimeoutFeesResponse, error) {
if req == nil {
return nil, status.Error(codes.InvalidArgument, "empty request")
}

ctx := sdk.UnwrapSDKContext(goCtx)

feesInEscrow, found := k.GetFeesInEscrow(ctx, req.PacketId)
if !found {
return nil, status.Errorf(
codes.NotFound,
sdkerrors.Wrapf(types.ErrFeeNotFound, "channel: %s, port: %s, sequence: %d", req.PacketId.ChannelId, req.PacketId.PortId, req.PacketId.Sequence).Error(),
)
}

var timeoutFees sdk.Coins
for _, packetFee := range feesInEscrow.PacketFees {
timeoutFees = timeoutFees.Add(packetFee.Fee.TimeoutFee...)
}

return &types.QueryTotalTimeoutFeesResponse{
TimeoutFees: timeoutFees,
}, nil
}
128 changes: 128 additions & 0 deletions modules/apps/29-fee/keeper/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,131 @@ func (suite *KeeperTestSuite) TestQueryTotalRecvFees() {
})
}
}

func (suite *KeeperTestSuite) TestQueryTotalAckFees() {
var (
req *types.QueryTotalAckFeesRequest
)

testCases := []struct {
name string
malleate func()
expPass bool
}{
{
"success",
func() {},
true,
},
{
"packet not found",
func() {
req.PacketId = channeltypes.NewPacketId(ibctesting.FirstChannelID, ibctesting.MockFeePort, 100)
},
false,
},
}

for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.SetupTest() // reset

suite.chainA.GetSimApp().IBCFeeKeeper.SetFeeEnabled(suite.chainA.GetContext(), ibctesting.MockFeePort, ibctesting.FirstChannelID)

packetID := channeltypes.NewPacketId(ibctesting.FirstChannelID, ibctesting.MockFeePort, 1)

fee := types.NewFee(defaultReceiveFee, defaultAckFee, defaultTimeoutFee)
packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount.GetAddress().String(), []string(nil))

for i := 0; i < 3; i++ {
// escrow three packet fees for the same packet
err := suite.chainA.GetSimApp().IBCFeeKeeper.EscrowPacketFee(suite.chainA.GetContext(), packetID, packetFee)
suite.Require().NoError(err)
}

req = &types.QueryTotalAckFeesRequest{
PacketId: packetID,
}

tc.malleate()

ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.queryClient.TotalAckFees(ctx, req)

if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)

// expected total is three times the default acknowledgement fee
expectedFees := defaultAckFee.Add(defaultAckFee...).Add(defaultAckFee...)
suite.Require().Equal(expectedFees, res.AckFees)
} else {
suite.Require().Error(err)
}
})
}
}

func (suite *KeeperTestSuite) TestQueryTotalTimeoutFees() {
var (
req *types.QueryTotalTimeoutFeesRequest
)

testCases := []struct {
name string
malleate func()
expPass bool
}{
{
"success",
func() {},
true,
},
{
"packet not found",
func() {
req.PacketId = channeltypes.NewPacketId(ibctesting.FirstChannelID, ibctesting.MockFeePort, 100)
},
false,
},
}

for _, tc := range testCases {
suite.Run(tc.name, func() {
suite.SetupTest() // reset

suite.chainA.GetSimApp().IBCFeeKeeper.SetFeeEnabled(suite.chainA.GetContext(), ibctesting.MockFeePort, ibctesting.FirstChannelID)

packetID := channeltypes.NewPacketId(ibctesting.FirstChannelID, ibctesting.MockFeePort, 1)

fee := types.NewFee(defaultReceiveFee, defaultAckFee, defaultTimeoutFee)
packetFee := types.NewPacketFee(fee, suite.chainA.SenderAccount.GetAddress().String(), []string(nil))

for i := 0; i < 3; i++ {
// escrow three packet fees for the same packet
err := suite.chainA.GetSimApp().IBCFeeKeeper.EscrowPacketFee(suite.chainA.GetContext(), packetID, packetFee)
suite.Require().NoError(err)
}

req = &types.QueryTotalTimeoutFeesRequest{
PacketId: packetID,
}

tc.malleate()

ctx := sdk.WrapSDKContext(suite.chainA.GetContext())
res, err := suite.queryClient.TotalTimeoutFees(ctx, req)

if tc.expPass {
suite.Require().NoError(err)
suite.Require().NotNil(res)

// expected total is three times the default acknowledgement fee
expectedFees := defaultTimeoutFee.Add(defaultTimeoutFee...).Add(defaultTimeoutFee...)
suite.Require().Equal(expectedFees, res.TimeoutFees)
} else {
suite.Require().Error(err)
}
})
}
}
Loading