mukan-ibc/modules/core/03-connection/keeper/keeper.go
Mukan Erkin Törük 88dd97a9f8
Some checks failed
CodeQL / Analyze (push) Waiting to run
golangci-lint / lint (push) Waiting to run
Tests / Code Coverage / build (amd64) (push) Waiting to run
Tests / Code Coverage / build (arm64) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[additional-args:-tags="test_e2e" name:e2e path:./e2e]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:08-wasm path:./modules/light-clients/08-wasm]) (push) Waiting to run
Tests / Code Coverage / unit-tests (map[name:ibc-go path:.]) (push) Waiting to run
Docker Build & Push Simapp (main) / docker-build (push) Has been cancelled
refactor: replace all github.com upstream refs with git.cw.tr/mukan-network
2026-05-11 03:36:22 +03:00

253 lines
8.3 KiB
Go

package keeper
import (
"errors"
corestore "cosmossdk.io/core/store"
errorsmod "cosmossdk.io/errors"
"cosmossdk.io/log"
storetypes "cosmossdk.io/store/types"
"git.cw.tr/mukan-network/mukan-sdk/codec"
"git.cw.tr/mukan-network/mukan-sdk/runtime"
sdk "git.cw.tr/mukan-network/mukan-sdk/types"
clienttypes "git.cw.tr/mukan-network/mukan-ibc/modules/core/02-client/types"
"git.cw.tr/mukan-network/mukan-ibc/modules/core/03-connection/types"
commitmenttypes "git.cw.tr/mukan-network/mukan-ibc/modules/core/23-commitment/types"
host "git.cw.tr/mukan-network/mukan-ibc/modules/core/24-host"
"git.cw.tr/mukan-network/mukan-ibc/modules/core/exported"
)
// Keeper defines the IBC connection keeper
type Keeper struct {
// implements gRPC QueryServer interface
types.QueryServer
storeService corestore.KVStoreService
legacySubspace types.ParamSubspace
cdc codec.BinaryCodec
clientKeeper types.ClientKeeper
}
// NewKeeper creates a new IBC connection Keeper instance
func NewKeeper(cdc codec.BinaryCodec, storeService corestore.KVStoreService, legacySubspace types.ParamSubspace, ck types.ClientKeeper) *Keeper {
return &Keeper{
storeService: storeService,
cdc: cdc,
legacySubspace: legacySubspace,
clientKeeper: ck,
}
}
// Logger returns a module-specific logger.
func (Keeper) Logger(ctx sdk.Context) log.Logger {
return ctx.Logger().With("module", "x/"+exported.ModuleName+"/"+types.SubModuleName)
}
// GetCommitmentPrefix returns the IBC connection store prefix as a commitment
// Prefix
func (*Keeper) GetCommitmentPrefix() exported.Prefix {
return commitmenttypes.NewMerklePrefix([]byte(exported.StoreKey))
}
// GenerateConnectionIdentifier returns the next connection identifier.
func (k *Keeper) GenerateConnectionIdentifier(ctx sdk.Context) string {
nextConnSeq := k.GetNextConnectionSequence(ctx)
connectionID := types.FormatConnectionIdentifier(nextConnSeq)
nextConnSeq++
k.SetNextConnectionSequence(ctx, nextConnSeq)
return connectionID
}
// GetConnection returns a connection with a particular identifier
func (k *Keeper) GetConnection(ctx sdk.Context, connectionID string) (types.ConnectionEnd, bool) {
store := k.storeService.OpenKVStore(ctx)
bz, err := store.Get(host.ConnectionKey(connectionID))
if err != nil {
panic(err)
}
if len(bz) == 0 {
return types.ConnectionEnd{}, false
}
var connection types.ConnectionEnd
k.cdc.MustUnmarshal(bz, &connection)
return connection, true
}
// HasConnection returns a true if the connection with the given identifier
// exists in the store.
func (k *Keeper) HasConnection(ctx sdk.Context, connectionID string) bool {
store := k.storeService.OpenKVStore(ctx)
has, err := store.Has(host.ConnectionKey(connectionID))
if err != nil {
return false
}
return has
}
// SetConnection sets a connection to the store
func (k *Keeper) SetConnection(ctx sdk.Context, connectionID string, connection types.ConnectionEnd) {
store := k.storeService.OpenKVStore(ctx)
bz := k.cdc.MustMarshal(&connection)
if err := store.Set(host.ConnectionKey(connectionID), bz); err != nil {
panic(err)
}
}
// GetClientConnectionPaths returns all the connection paths stored under a
// particular client
func (k *Keeper) GetClientConnectionPaths(ctx sdk.Context, clientID string) ([]string, bool) {
store := k.storeService.OpenKVStore(ctx)
bz, err := store.Get(host.ClientConnectionsKey(clientID))
if err != nil {
panic(err)
}
if len(bz) == 0 {
return nil, false
}
var clientPaths types.ClientPaths
k.cdc.MustUnmarshal(bz, &clientPaths)
return clientPaths.Paths, true
}
// SetClientConnectionPaths sets the connections paths for client
func (k *Keeper) SetClientConnectionPaths(ctx sdk.Context, clientID string, paths []string) {
store := k.storeService.OpenKVStore(ctx)
clientPaths := types.ClientPaths{Paths: paths}
bz := k.cdc.MustMarshal(&clientPaths)
if err := store.Set(host.ClientConnectionsKey(clientID), bz); err != nil {
panic(err)
}
}
// GetNextConnectionSequence gets the next connection sequence from the store.
func (k *Keeper) GetNextConnectionSequence(ctx sdk.Context) uint64 {
store := k.storeService.OpenKVStore(ctx)
bz, err := store.Get([]byte(types.KeyNextConnectionSequence))
if err != nil {
panic(err)
}
if len(bz) == 0 {
panic(errors.New("next connection sequence is nil"))
}
return sdk.BigEndianToUint64(bz)
}
// SetNextConnectionSequence sets the next connection sequence to the store.
func (k *Keeper) SetNextConnectionSequence(ctx sdk.Context, sequence uint64) {
store := k.storeService.OpenKVStore(ctx)
bz := sdk.Uint64ToBigEndian(sequence)
if err := store.Set([]byte(types.KeyNextConnectionSequence), bz); err != nil {
panic(err)
}
}
// GetAllClientConnectionPaths returns all stored clients connection id paths. It
// will ignore the clients that haven't initialized a connection handshake since
// no paths are stored.
func (k *Keeper) GetAllClientConnectionPaths(ctx sdk.Context) []types.ConnectionPaths {
var allConnectionPaths []types.ConnectionPaths
k.clientKeeper.IterateClientStates(ctx, nil, func(clientID string, cs exported.ClientState) bool {
paths, found := k.GetClientConnectionPaths(ctx, clientID)
if !found {
// continue when connection handshake is not initialized
return false
}
connPaths := types.NewConnectionPaths(clientID, paths)
allConnectionPaths = append(allConnectionPaths, connPaths)
return false
})
return allConnectionPaths
}
// IterateConnections provides an iterator over all ConnectionEnd objects.
// For each ConnectionEnd, cb will be called. If the cb returns true, the
// iterator will close and stop.
func (k *Keeper) IterateConnections(ctx sdk.Context, cb func(types.IdentifiedConnection) bool) {
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
iterator := storetypes.KVStorePrefixIterator(store, []byte(host.KeyConnectionPrefix))
defer sdk.LogDeferred(k.Logger(ctx), func() error { return iterator.Close() })
for ; iterator.Valid(); iterator.Next() {
var connection types.ConnectionEnd
k.cdc.MustUnmarshal(iterator.Value(), &connection)
connectionID := host.MustParseConnectionPath(string(iterator.Key()))
identifiedConnection := types.NewIdentifiedConnection(connectionID, connection)
if cb(identifiedConnection) {
break
}
}
}
// GetAllConnections returns all stored ConnectionEnd objects.
func (k *Keeper) GetAllConnections(ctx sdk.Context) (connections []types.IdentifiedConnection) {
k.IterateConnections(ctx, func(connection types.IdentifiedConnection) bool {
connections = append(connections, connection)
return false
})
return connections
}
// CreateSentinelLocalhostConnection creates and sets the sentinel localhost connection end in the IBC store.
func (k *Keeper) CreateSentinelLocalhostConnection(ctx sdk.Context) {
counterparty := types.NewCounterparty(exported.LocalhostClientID, exported.LocalhostConnectionID, commitmenttypes.NewMerklePrefix(k.GetCommitmentPrefix().Bytes()))
connectionEnd := types.NewConnectionEnd(types.OPEN, exported.LocalhostClientID, counterparty, types.GetCompatibleVersions(), 0)
k.SetConnection(ctx, exported.LocalhostConnectionID, connectionEnd)
}
// addConnectionToClient is used to add a connection identifier to the set of
// connections associated with a client.
func (k *Keeper) addConnectionToClient(ctx sdk.Context, clientID, connectionID string) error {
_, found := k.clientKeeper.GetClientState(ctx, clientID)
if !found {
return errorsmod.Wrap(clienttypes.ErrClientNotFound, clientID)
}
conns, found := k.GetClientConnectionPaths(ctx, clientID)
if !found {
conns = []string{}
}
conns = append(conns, connectionID)
k.SetClientConnectionPaths(ctx, clientID, conns)
return nil
}
// GetParams returns the total set of ibc-connection parameters.
func (k *Keeper) GetParams(ctx sdk.Context) types.Params {
store := k.storeService.OpenKVStore(ctx)
bz, err := store.Get([]byte(types.ParamsKey))
if err != nil {
panic(err)
}
if bz == nil { // only panic on unset params and not on empty params
panic(errors.New("connection params are not set in store"))
}
var params types.Params
k.cdc.MustUnmarshal(bz, &params)
return params
}
// SetParams sets the total set of ibc-connection parameters.
func (k *Keeper) SetParams(ctx sdk.Context, params types.Params) {
store := k.storeService.OpenKVStore(ctx)
bz := k.cdc.MustMarshal(&params)
if err := store.Set([]byte(types.ParamsKey), bz); err != nil {
panic(err)
}
}