github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/ibc-go/modules/apps/27-interchain-accounts/controller/keeper/keeper.go (about)

     1  package keeper
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  
     7  	"github.com/fibonacci-chain/fbc/libs/tendermint/libs/log"
     8  
     9  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/baseapp"
    10  	"github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec"
    11  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
    12  	capabilitykeeper "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/keeper"
    13  	capabilitytypes "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/x/capability/types"
    14  	"github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/27-interchain-accounts/controller/types"
    15  	icatypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/apps/27-interchain-accounts/types"
    16  	channeltypes "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/04-channel/types"
    17  	host "github.com/fibonacci-chain/fbc/libs/ibc-go/modules/core/24-host"
    18  	paramtypes "github.com/fibonacci-chain/fbc/x/params"
    19  )
    20  
    21  // Keeper defines the IBC interchain accounts controller keeper
    22  type Keeper struct {
    23  	storeKey   sdk.StoreKey
    24  	cdc        *codec.CodecProxy
    25  	paramSpace paramtypes.Subspace
    26  
    27  	ics4Wrapper   icatypes.ICS4Wrapper
    28  	channelKeeper icatypes.ChannelKeeper
    29  	portKeeper    icatypes.PortKeeper
    30  
    31  	scopedKeeper capabilitykeeper.ScopedKeeper
    32  
    33  	msgRouter *baseapp.MsgServiceRouter
    34  }
    35  
    36  // NewKeeper creates a new interchain accounts controller Keeper instance
    37  func NewKeeper(
    38  	cdc *codec.CodecProxy, key sdk.StoreKey, paramSpace paramtypes.Subspace,
    39  	ics4Wrapper icatypes.ICS4Wrapper, channelKeeper icatypes.ChannelKeeper, portKeeper icatypes.PortKeeper,
    40  	scopedKeeper capabilitykeeper.ScopedKeeper, msgRouter *baseapp.MsgServiceRouter,
    41  ) Keeper {
    42  	// set KeyTable if it has not already been set
    43  	if !paramSpace.HasKeyTable() {
    44  		paramSpace = paramSpace.WithKeyTable(types.ParamKeyTable())
    45  	}
    46  
    47  	return Keeper{
    48  		storeKey:      key,
    49  		cdc:           cdc,
    50  		paramSpace:    paramSpace,
    51  		ics4Wrapper:   ics4Wrapper,
    52  		channelKeeper: channelKeeper,
    53  		portKeeper:    portKeeper,
    54  		scopedKeeper:  scopedKeeper,
    55  		msgRouter:     msgRouter,
    56  	}
    57  }
    58  
    59  // Logger returns the application logger, scoped to the associated module
    60  func (k Keeper) Logger(ctx sdk.Context) log.Logger {
    61  	return ctx.Logger().With("module", fmt.Sprintf("x/%s-%s", host.ModuleName, icatypes.ModuleName))
    62  }
    63  
    64  // GetAllPorts returns all ports to which the interchain accounts controller module is bound. Used in ExportGenesis
    65  func (k Keeper) GetAllPorts(ctx sdk.Context) []string {
    66  	store := ctx.KVStore(k.storeKey)
    67  	iterator := sdk.KVStorePrefixIterator(store, []byte(icatypes.PortKeyPrefix))
    68  	defer iterator.Close()
    69  
    70  	var ports []string
    71  	for ; iterator.Valid(); iterator.Next() {
    72  		keySplit := strings.Split(string(iterator.Key()), "/")
    73  
    74  		ports = append(ports, keySplit[1])
    75  	}
    76  
    77  	return ports
    78  }
    79  
    80  // BindPort stores the provided portID and binds to it, returning the associated capability
    81  func (k Keeper) BindPort(ctx sdk.Context, portID string) *capabilitytypes.Capability {
    82  	store := ctx.KVStore(k.storeKey)
    83  	store.Set(icatypes.KeyPort(portID), []byte{0x01})
    84  
    85  	return k.portKeeper.BindPort(ctx, portID)
    86  }
    87  
    88  // IsBound checks if the interchain account controller module is already bound to the desired port
    89  func (k Keeper) IsBound(ctx sdk.Context, portID string) bool {
    90  	_, ok := k.scopedKeeper.GetCapability(ctx, host.PortPath(portID))
    91  	return ok
    92  }
    93  
    94  // AuthenticateCapability wraps the scopedKeeper's AuthenticateCapability function
    95  func (k Keeper) AuthenticateCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) bool {
    96  	return k.scopedKeeper.AuthenticateCapability(ctx, cap, name)
    97  }
    98  
    99  // ClaimCapability wraps the scopedKeeper's ClaimCapability function
   100  func (k Keeper) ClaimCapability(ctx sdk.Context, cap *capabilitytypes.Capability, name string) error {
   101  	return k.scopedKeeper.ClaimCapability(ctx, cap, name)
   102  }
   103  
   104  // GetAppVersion calls the ICS4Wrapper GetAppVersion function.
   105  func (k Keeper) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) {
   106  	return k.ics4Wrapper.GetAppVersion(ctx, portID, channelID)
   107  }
   108  
   109  // GetActiveChannelID retrieves the active channelID from the store, keyed by the provided connectionID and portID
   110  func (k Keeper) GetActiveChannelID(ctx sdk.Context, connectionID, portID string) (string, bool) {
   111  	store := ctx.KVStore(k.storeKey)
   112  	key := icatypes.KeyActiveChannel(portID, connectionID)
   113  
   114  	if !store.Has(key) {
   115  		return "", false
   116  	}
   117  
   118  	return string(store.Get(key)), true
   119  }
   120  
   121  // GetOpenActiveChannel retrieves the active channelID from the store, keyed by the provided connectionID and portID & checks if the channel in question is in state OPEN
   122  func (k Keeper) GetOpenActiveChannel(ctx sdk.Context, connectionID, portID string) (string, bool) {
   123  	channelID, found := k.GetActiveChannelID(ctx, connectionID, portID)
   124  	if !found {
   125  		return "", false
   126  	}
   127  
   128  	channel, found := k.channelKeeper.GetChannel(ctx, portID, channelID)
   129  
   130  	if found && channel.State == channeltypes.OPEN {
   131  		return channelID, true
   132  	}
   133  
   134  	return "", false
   135  }
   136  
   137  // GetAllActiveChannels returns a list of all active interchain accounts controller channels and their associated connection and port identifiers
   138  func (k Keeper) GetAllActiveChannels(ctx sdk.Context) []icatypes.ActiveChannel {
   139  	store := ctx.KVStore(k.storeKey)
   140  	iterator := sdk.KVStorePrefixIterator(store, []byte(icatypes.ActiveChannelKeyPrefix))
   141  	defer iterator.Close()
   142  
   143  	var activeChannels []icatypes.ActiveChannel
   144  	for ; iterator.Valid(); iterator.Next() {
   145  		keySplit := strings.Split(string(iterator.Key()), "/")
   146  
   147  		ch := icatypes.ActiveChannel{
   148  			ConnectionId: keySplit[2],
   149  			PortId:       keySplit[1],
   150  			ChannelId:    string(iterator.Value()),
   151  		}
   152  
   153  		activeChannels = append(activeChannels, ch)
   154  	}
   155  
   156  	return activeChannels
   157  }
   158  
   159  // SetActiveChannelID stores the active channelID, keyed by the provided connectionID and portID
   160  func (k Keeper) SetActiveChannelID(ctx sdk.Context, connectionID, portID, channelID string) {
   161  	store := ctx.KVStore(k.storeKey)
   162  	store.Set(icatypes.KeyActiveChannel(portID, connectionID), []byte(channelID))
   163  }
   164  
   165  // IsActiveChannel returns true if there exists an active channel for the provided connectionID and portID, otherwise false
   166  func (k Keeper) IsActiveChannel(ctx sdk.Context, connectionID, portID string) bool {
   167  	_, ok := k.GetActiveChannelID(ctx, connectionID, portID)
   168  	return ok
   169  }
   170  
   171  // GetInterchainAccountAddress retrieves the InterchainAccount address from the store associated with the provided connectionID and portID
   172  func (k Keeper) GetInterchainAccountAddress(ctx sdk.Context, connectionID, portID string) (string, bool) {
   173  	store := ctx.KVStore(k.storeKey)
   174  	key := icatypes.KeyOwnerAccount(portID, connectionID)
   175  
   176  	if !store.Has(key) {
   177  		return "", false
   178  	}
   179  
   180  	return string(store.Get(key)), true
   181  }
   182  
   183  // GetAllInterchainAccounts returns a list of all registered interchain account addresses and their associated connection and controller port identifiers
   184  func (k Keeper) GetAllInterchainAccounts(ctx sdk.Context) []icatypes.RegisteredInterchainAccount {
   185  	store := ctx.KVStore(k.storeKey)
   186  	iterator := sdk.KVStorePrefixIterator(store, []byte(icatypes.OwnerKeyPrefix))
   187  
   188  	var interchainAccounts []icatypes.RegisteredInterchainAccount
   189  	for ; iterator.Valid(); iterator.Next() {
   190  		keySplit := strings.Split(string(iterator.Key()), "/")
   191  
   192  		acc := icatypes.RegisteredInterchainAccount{
   193  			ConnectionId:   keySplit[2],
   194  			PortId:         keySplit[1],
   195  			AccountAddress: string(iterator.Value()),
   196  		}
   197  
   198  		interchainAccounts = append(interchainAccounts, acc)
   199  	}
   200  
   201  	return interchainAccounts
   202  }
   203  
   204  // SetInterchainAccountAddress stores the InterchainAccount address, keyed by the associated connectionID and portID
   205  func (k Keeper) SetInterchainAccountAddress(ctx sdk.Context, connectionID, portID, address string) {
   206  	store := ctx.KVStore(k.storeKey)
   207  	store.Set(icatypes.KeyOwnerAccount(portID, connectionID), []byte(address))
   208  }