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  }