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