github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/apps/29-fee/keeper/msg_server.go (about) 1 package keeper 2 3 import ( 4 "context" 5 6 sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types" 7 sdkerrors "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types/errors" 8 "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/29-fee/types" 9 channeltypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types" 10 ) 11 12 var _ types.MsgServer = Keeper{} 13 14 // RegisterPayee defines a rpc handler method for MsgRegisterPayee 15 // RegisterPayee is called by the relayer on each channelEnd and allows them to set an optional 16 // payee to which reverse and timeout relayer packet fees will be paid out. The payee should be registered on 17 // the source chain from which packets originate as this is where fee distribution takes place. This function may be 18 // called more than once by a relayer, in which case, the latest payee is always used. 19 func (k Keeper) RegisterPayee(goCtx context.Context, msg *types.MsgRegisterPayee) (*types.MsgRegisterPayeeResponse, error) { 20 ctx := sdk.UnwrapSDKContext(goCtx) 21 22 payee, err := sdk.AccAddressFromBech32(msg.Payee) 23 if err != nil { 24 return nil, err 25 } 26 27 if k.bankKeeper.BlockedAddr(payee) { 28 return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not authorized to be a payee", payee) 29 } 30 31 // only register payee address if the channel exists and is fee enabled 32 if _, found := k.channelKeeper.GetChannel(ctx, msg.PortId, msg.ChannelId); !found { 33 return nil, channeltypes.ErrChannelNotFound 34 } 35 36 if !k.IsFeeEnabled(ctx, msg.PortId, msg.ChannelId) { 37 return nil, types.ErrFeeNotEnabled 38 } 39 40 k.SetPayeeAddress(ctx, msg.Relayer, msg.Payee, msg.ChannelId) 41 42 k.Logger(ctx).Info("registering payee address for relayer", "relayer", msg.Relayer, "payee", msg.Payee, "channel", msg.ChannelId) 43 44 EmitRegisterPayeeEvent(ctx, msg.Relayer, msg.Payee, msg.ChannelId) 45 46 return &types.MsgRegisterPayeeResponse{}, nil 47 } 48 49 // RegisterCounterpartyPayee defines a rpc handler method for MsgRegisterCounterpartyPayee 50 // RegisterCounterpartyPayee is called by the relayer on each channelEnd and allows them to specify the counterparty 51 // payee address before relaying. This ensures they will be properly compensated for forward relaying since 52 // the destination chain must include the registered counterparty payee address in the acknowledgement. This function 53 // may be called more than once by a relayer, in which case, the latest counterparty payee address is always used. 54 func (k Keeper) RegisterCounterpartyPayee(goCtx context.Context, msg *types.MsgRegisterCounterpartyPayee) (*types.MsgRegisterCounterpartyPayeeResponse, error) { 55 ctx := sdk.UnwrapSDKContext(goCtx) 56 57 // only register counterparty payee if the channel exists and is fee enabled 58 if _, found := k.channelKeeper.GetChannel(ctx, msg.PortId, msg.ChannelId); !found { 59 return nil, channeltypes.ErrChannelNotFound 60 } 61 62 if !k.IsFeeEnabled(ctx, msg.PortId, msg.ChannelId) { 63 return nil, types.ErrFeeNotEnabled 64 } 65 66 k.SetCounterpartyPayeeAddress(ctx, msg.Relayer, msg.CounterpartyPayee, msg.ChannelId) 67 68 k.Logger(ctx).Info("registering counterparty payee for relayer", "relayer", msg.Relayer, "counterparty payee", msg.CounterpartyPayee, "channel", msg.ChannelId) 69 70 EmitRegisterCounterpartyPayeeEvent(ctx, msg.Relayer, msg.CounterpartyPayee, msg.ChannelId) 71 72 return &types.MsgRegisterCounterpartyPayeeResponse{}, nil 73 } 74 75 // PayPacketFee defines a rpc handler method for MsgPayPacketFee 76 // PayPacketFee is an open callback that may be called by any module/user that wishes to escrow funds in order to relay the packet with the next sequence 77 func (k Keeper) PayPacketFee(goCtx context.Context, msg *types.MsgPayPacketFee) (*types.MsgPayPacketFeeResponse, error) { 78 ctx := sdk.UnwrapSDKContext(goCtx) 79 80 if !k.IsFeeEnabled(ctx, msg.SourcePortId, msg.SourceChannelId) { 81 // users may not escrow fees on this channel. Must send packets without a fee message 82 return nil, types.ErrFeeNotEnabled 83 } 84 85 if k.IsLocked(ctx) { 86 return nil, types.ErrFeeModuleLocked 87 } 88 89 refundAcc, err := sdk.AccAddressFromBech32(msg.Signer) 90 if err != nil { 91 return nil, err 92 } 93 94 if k.bankKeeper.BlockedAddr(refundAcc) { 95 return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to escrow fees", refundAcc) 96 } 97 98 // get the next sequence 99 sequence, found := k.GetNextSequenceSend(ctx, msg.SourcePortId, msg.SourceChannelId) 100 if !found { 101 return nil, channeltypes.ErrSequenceSendNotFound 102 } 103 104 packetID := channeltypes.NewPacketId(msg.SourcePortId, msg.SourceChannelId, sequence) 105 packetFee := types.NewPacketFee(msg.Fee, msg.Signer, msg.Relayers) 106 107 if err := k.escrowPacketFee(ctx, packetID, packetFee); err != nil { 108 return nil, err 109 } 110 111 return &types.MsgPayPacketFeeResponse{}, nil 112 } 113 114 // PayPacketFee defines a rpc handler method for MsgPayPacketFee 115 // PayPacketFee is an open callback that may be called by any module/user that wishes to escrow funds in order to 116 // incentivize the relaying of a known packet. Only packets which have been sent and have not gone through the 117 // packet life cycle may be incentivized. 118 func (k Keeper) PayPacketFeeAsync(goCtx context.Context, msg *types.MsgPayPacketFeeAsync) (*types.MsgPayPacketFeeAsyncResponse, error) { 119 ctx := sdk.UnwrapSDKContext(goCtx) 120 if !k.IsFeeEnabled(ctx, msg.PacketId.PortId, msg.PacketId.ChannelId) { 121 // users may not escrow fees on this channel. Must send packets without a fee message 122 return nil, types.ErrFeeNotEnabled 123 } 124 if k.IsLocked(ctx) { 125 return nil, types.ErrFeeModuleLocked 126 } 127 128 refundAcc, err := sdk.AccAddressFromBech32(msg.PacketFee.RefundAddress) 129 if err != nil { 130 return nil, err 131 } 132 133 if k.bankKeeper.BlockedAddr(refundAcc) { 134 return nil, sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "%s is not allowed to escrow fees", refundAcc) 135 } 136 137 nextSeqSend, found := k.GetNextSequenceSend(ctx, msg.PacketId.PortId, msg.PacketId.ChannelId) 138 if !found { 139 return nil, sdkerrors.Wrapf(channeltypes.ErrSequenceSendNotFound, "channel does not exist, portID: %s, channelID: %s", msg.PacketId.PortId, msg.PacketId.ChannelId) 140 } 141 142 // only allow incentivizing of packets which have been sent 143 if msg.PacketId.Sequence >= nextSeqSend { 144 return nil, channeltypes.ErrPacketNotSent 145 } 146 147 // only allow incentivizng of packets which have not completed the packet life cycle 148 if bz := k.GetPacketCommitment(ctx, msg.PacketId.PortId, msg.PacketId.ChannelId, msg.PacketId.Sequence); len(bz) == 0 { 149 return nil, sdkerrors.Wrapf(channeltypes.ErrPacketCommitmentNotFound, "packet has already been acknowledged or timed out") 150 } 151 152 if err := k.escrowPacketFee(ctx, msg.PacketId, msg.PacketFee); err != nil { 153 return nil, err 154 } 155 156 return &types.MsgPayPacketFeeAsyncResponse{}, nil 157 }