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
253 lines
8.3 KiB
Go
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, ¶ms)
|
|
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(¶ms)
|
|
if err := store.Set([]byte(types.ParamsKey), bz); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|