|
9 | 9 | "github.com/cosmos/ibc-go/modules/apps/29-fee/types"
|
10 | 10 | channeltypes "github.com/cosmos/ibc-go/modules/core/04-channel/types"
|
11 | 11 | porttypes "github.com/cosmos/ibc-go/modules/core/05-port/types"
|
12 |
| - ibcexported "github.com/cosmos/ibc-go/modules/core/exported" |
| 12 | + "github.com/cosmos/ibc-go/modules/core/exported" |
13 | 13 | )
|
14 | 14 |
|
15 | 15 | // IBCModule implements the ICS26 callbacks for the fee middleware given the fee keeper and the underlying application.
|
@@ -171,32 +171,105 @@ func (im IBCModule) OnChanCloseConfirm(
|
171 | 171 | }
|
172 | 172 |
|
173 | 173 | // OnRecvPacket implements the IBCModule interface.
|
| 174 | +// If fees are not enabled, this callback will default to the ibc-core packet callback |
174 | 175 | func (im IBCModule) OnRecvPacket(
|
175 | 176 | ctx sdk.Context,
|
176 | 177 | packet channeltypes.Packet,
|
177 | 178 | relayer sdk.AccAddress,
|
178 |
| -) ibcexported.Acknowledgement { |
179 |
| - // TODO: Implement fee specific logic if fee is enabled for the given channel |
180 |
| - return im.app.OnRecvPacket(ctx, packet, relayer) |
| 179 | +) exported.Acknowledgement { |
| 180 | + if !im.keeper.IsFeeEnabled(ctx, packet.DestinationPort, packet.DestinationChannel) { |
| 181 | + return im.app.OnRecvPacket(ctx, packet, relayer) |
| 182 | + } |
| 183 | + |
| 184 | + ack := im.app.OnRecvPacket(ctx, packet, relayer) |
| 185 | + |
| 186 | + forwardRelayer, found := im.keeper.GetCounterpartyAddress(ctx, relayer.String()) |
| 187 | + if !found { |
| 188 | + forwardRelayer = "" |
| 189 | + } |
| 190 | + |
| 191 | + return types.IncentivizedAcknowledgement{ |
| 192 | + Result: ack.Acknowledgement(), |
| 193 | + ForwardRelayerAddress: forwardRelayer, |
| 194 | + } |
181 | 195 | }
|
182 | 196 |
|
183 | 197 | // OnAcknowledgementPacket implements the IBCModule interface
|
| 198 | +// If fees are not enabled, this callback will default to the ibc-core packet callback |
184 | 199 | func (im IBCModule) OnAcknowledgementPacket(
|
185 | 200 | ctx sdk.Context,
|
186 | 201 | packet channeltypes.Packet,
|
187 | 202 | acknowledgement []byte,
|
188 | 203 | relayer sdk.AccAddress,
|
189 | 204 | ) error {
|
190 |
| - // TODO: Implement fee specific logic if fee is enabled for the given channel |
191 |
| - return im.app.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) |
| 205 | + if !im.keeper.IsFeeEnabled(ctx, packet.SourcePort, packet.SourceChannel) { |
| 206 | + return im.app.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) |
| 207 | + } |
| 208 | + |
| 209 | + ack := new(types.IncentivizedAcknowledgement) |
| 210 | + if err := types.ModuleCdc.UnmarshalJSON(acknowledgement, ack); err != nil { |
| 211 | + return sdkerrors.Wrapf(err, "cannot unmarshal ICS-29 incentivized packet acknowledgement: %v", ack) |
| 212 | + } |
| 213 | + |
| 214 | + packetId := channeltypes.NewPacketId(packet.SourceChannel, packet.SourcePort, packet.Sequence) |
| 215 | + identifiedPacketFee, found := im.keeper.GetFeeInEscrow(ctx, packetId) |
| 216 | + |
| 217 | + if !found { |
| 218 | + // return underlying callback if no fee found for given packetID |
| 219 | + return im.app.OnAcknowledgementPacket(ctx, packet, ack.Result, relayer) |
| 220 | + } |
| 221 | + |
| 222 | + // cache context before trying to distribute the fee |
| 223 | + cacheCtx, writeFn := ctx.CacheContext() |
| 224 | + |
| 225 | + forwardRelayer, _ := sdk.AccAddressFromBech32(ack.ForwardRelayerAddress) |
| 226 | + refundAcc, _ := sdk.AccAddressFromBech32(identifiedPacketFee.RefundAddress) |
| 227 | + |
| 228 | + err := im.keeper.DistributeFee(cacheCtx, refundAcc, forwardRelayer, relayer, packetId) |
| 229 | + |
| 230 | + if err == nil { |
| 231 | + // write the cache and then call underlying callback |
| 232 | + writeFn() |
| 233 | + // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. |
| 234 | + ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) |
| 235 | + } |
| 236 | + // otherwise discard cache and call underlying callback |
| 237 | + return im.app.OnAcknowledgementPacket(ctx, packet, ack.Result, relayer) |
192 | 238 | }
|
193 | 239 |
|
194 | 240 | // OnTimeoutPacket implements the IBCModule interface
|
| 241 | +// If fees are not enabled, this callback will default to the ibc-core packet callback |
195 | 242 | func (im IBCModule) OnTimeoutPacket(
|
196 | 243 | ctx sdk.Context,
|
197 | 244 | packet channeltypes.Packet,
|
198 | 245 | relayer sdk.AccAddress,
|
199 | 246 | ) error {
|
200 |
| - // TODO: Implement fee specific logic if fee is enabled for the given channel |
| 247 | + if !im.keeper.IsFeeEnabled(ctx, packet.SourcePort, packet.SourceChannel) { |
| 248 | + return im.app.OnTimeoutPacket(ctx, packet, relayer) |
| 249 | + } |
| 250 | + |
| 251 | + packetId := channeltypes.NewPacketId(packet.SourceChannel, packet.SourcePort, packet.Sequence) |
| 252 | + |
| 253 | + identifiedPacketFee, found := im.keeper.GetFeeInEscrow(ctx, packetId) |
| 254 | + |
| 255 | + if !found { |
| 256 | + // return underlying callback if fee not found for given packetID |
| 257 | + return im.app.OnTimeoutPacket(ctx, packet, relayer) |
| 258 | + } |
| 259 | + |
| 260 | + // cache context before trying to distribute the fee |
| 261 | + cacheCtx, writeFn := ctx.CacheContext() |
| 262 | + |
| 263 | + refundAcc, _ := sdk.AccAddressFromBech32(identifiedPacketFee.RefundAddress) |
| 264 | + err := im.keeper.DistributeFeeTimeout(cacheCtx, refundAcc, relayer, packetId) |
| 265 | + |
| 266 | + if err == nil { |
| 267 | + // write the cache and then call underlying callback |
| 268 | + writeFn() |
| 269 | + // NOTE: The context returned by CacheContext() refers to a new EventManager, so it needs to explicitly set events to the original context. |
| 270 | + ctx.EventManager().EmitEvents(cacheCtx.EventManager().Events()) |
| 271 | + } |
| 272 | + |
| 273 | + // otherwise discard cache and call underlying callback |
201 | 274 | return im.app.OnTimeoutPacket(ctx, packet, relayer)
|
202 | 275 | }
|
0 commit comments