174 lines
6.1 KiB
Go
174 lines
6.1 KiB
Go
package keeper
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"fmt"
|
|
|
|
"github.com/tendermint/tendermint/libs/log"
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/cosmos/cosmos-sdk/x/capability"
|
|
"github.com/cosmos/cosmos-sdk/x/ibc/04-channel/types"
|
|
ibctypes "github.com/cosmos/cosmos-sdk/x/ibc/types"
|
|
)
|
|
|
|
// Keeper defines the IBC channel keeper
|
|
type Keeper struct {
|
|
storeKey sdk.StoreKey
|
|
cdc *codec.Codec
|
|
clientKeeper types.ClientKeeper
|
|
connectionKeeper types.ConnectionKeeper
|
|
portKeeper types.PortKeeper
|
|
scopedKeeper capability.ScopedKeeper
|
|
}
|
|
|
|
// NewKeeper creates a new IBC channel Keeper instance
|
|
func NewKeeper(
|
|
cdc *codec.Codec, key sdk.StoreKey,
|
|
clientKeeper types.ClientKeeper, connectionKeeper types.ConnectionKeeper,
|
|
portKeeper types.PortKeeper, scopedKeeper capability.ScopedKeeper,
|
|
) Keeper {
|
|
return Keeper{
|
|
storeKey: key,
|
|
cdc: cdc,
|
|
clientKeeper: clientKeeper,
|
|
connectionKeeper: connectionKeeper,
|
|
portKeeper: portKeeper,
|
|
scopedKeeper: scopedKeeper,
|
|
}
|
|
}
|
|
|
|
// Logger returns a module-specific logger.
|
|
func (k Keeper) Logger(ctx sdk.Context) log.Logger {
|
|
return ctx.Logger().With("module", fmt.Sprintf("x/%s/%s", ibctypes.ModuleName, types.SubModuleName))
|
|
}
|
|
|
|
// GetChannel returns a channel with a particular identifier binded to a specific port
|
|
func (k Keeper) GetChannel(ctx sdk.Context, portID, channelID string) (types.Channel, bool) {
|
|
store := ctx.KVStore(k.storeKey)
|
|
bz := store.Get(ibctypes.KeyChannel(portID, channelID))
|
|
if bz == nil {
|
|
return types.Channel{}, false
|
|
}
|
|
|
|
var channel types.Channel
|
|
k.cdc.MustUnmarshalBinaryBare(bz, &channel)
|
|
return channel, true
|
|
}
|
|
|
|
// SetChannel sets a channel to the store
|
|
func (k Keeper) SetChannel(ctx sdk.Context, portID, channelID string, channel types.Channel) {
|
|
store := ctx.KVStore(k.storeKey)
|
|
bz := k.cdc.MustMarshalBinaryBare(channel)
|
|
store.Set(ibctypes.KeyChannel(portID, channelID), bz)
|
|
}
|
|
|
|
// GetNextSequenceSend gets a channel's next send sequence from the store
|
|
func (k Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) {
|
|
store := ctx.KVStore(k.storeKey)
|
|
bz := store.Get(ibctypes.KeyNextSequenceSend(portID, channelID))
|
|
if bz == nil {
|
|
return 0, false
|
|
}
|
|
|
|
return binary.BigEndian.Uint64(bz), true
|
|
}
|
|
|
|
// SetNextSequenceSend sets a channel's next send sequence to the store
|
|
func (k Keeper) SetNextSequenceSend(ctx sdk.Context, portID, channelID string, sequence uint64) {
|
|
store := ctx.KVStore(k.storeKey)
|
|
bz := sdk.Uint64ToBigEndian(sequence)
|
|
store.Set(ibctypes.KeyNextSequenceSend(portID, channelID), bz)
|
|
}
|
|
|
|
// GetNextSequenceRecv gets a channel's next receive sequence from the store
|
|
func (k Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) (uint64, bool) {
|
|
store := ctx.KVStore(k.storeKey)
|
|
bz := store.Get(ibctypes.KeyNextSequenceRecv(portID, channelID))
|
|
if bz == nil {
|
|
return 0, false
|
|
}
|
|
|
|
return binary.BigEndian.Uint64(bz), true
|
|
}
|
|
|
|
// SetNextSequenceRecv sets a channel's next receive sequence to the store
|
|
func (k Keeper) SetNextSequenceRecv(ctx sdk.Context, portID, channelID string, sequence uint64) {
|
|
store := ctx.KVStore(k.storeKey)
|
|
bz := sdk.Uint64ToBigEndian(sequence)
|
|
store.Set(ibctypes.KeyNextSequenceRecv(portID, channelID), bz)
|
|
}
|
|
|
|
// GetPacketCommitment gets the packet commitment hash from the store
|
|
func (k Keeper) GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte {
|
|
store := ctx.KVStore(k.storeKey)
|
|
bz := store.Get(ibctypes.KeyPacketCommitment(portID, channelID, sequence))
|
|
return bz
|
|
}
|
|
|
|
// SetPacketCommitment sets the packet commitment hash to the store
|
|
func (k Keeper) SetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64, commitmentHash []byte) {
|
|
store := ctx.KVStore(k.storeKey)
|
|
store.Set(ibctypes.KeyPacketCommitment(portID, channelID, sequence), commitmentHash)
|
|
}
|
|
|
|
func (k Keeper) deletePacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) {
|
|
store := ctx.KVStore(k.storeKey)
|
|
store.Delete(ibctypes.KeyPacketCommitment(portID, channelID, sequence))
|
|
}
|
|
|
|
// SetPacketAcknowledgement sets the packet ack hash to the store
|
|
func (k Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64, ackHash []byte) {
|
|
store := ctx.KVStore(k.storeKey)
|
|
store.Set(ibctypes.KeyPacketAcknowledgement(portID, channelID, sequence), ackHash)
|
|
}
|
|
|
|
// GetPacketAcknowledgement gets the packet ack hash from the store
|
|
func (k Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) {
|
|
store := ctx.KVStore(k.storeKey)
|
|
bz := store.Get(ibctypes.KeyPacketAcknowledgement(portID, channelID, sequence))
|
|
if bz == nil {
|
|
return nil, false
|
|
}
|
|
return bz, true
|
|
}
|
|
|
|
// IterateChannels provides an iterator over all Channel objects. For each
|
|
// Channel, cb will be called. If the cb returns true, the iterator will close
|
|
// and stop.
|
|
func (k Keeper) IterateChannels(ctx sdk.Context, cb func(types.IdentifiedChannel) bool) {
|
|
store := ctx.KVStore(k.storeKey)
|
|
iterator := sdk.KVStorePrefixIterator(store, []byte(ibctypes.KeyChannelPrefix))
|
|
|
|
defer iterator.Close()
|
|
for ; iterator.Valid(); iterator.Next() {
|
|
var channel types.Channel
|
|
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &channel)
|
|
portID, channelID := ibctypes.MustParseChannelPath(string(iterator.Key()))
|
|
|
|
if cb(types.IdentifiedChannel{Channel: channel, PortIdentifier: portID, ChannelIdentifier: channelID}) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetAllChannels returns all stored Channel objects.
|
|
func (k Keeper) GetAllChannels(ctx sdk.Context) (channels []types.IdentifiedChannel) {
|
|
k.IterateChannels(ctx, func(channel types.IdentifiedChannel) bool {
|
|
channels = append(channels, channel)
|
|
return false
|
|
})
|
|
return channels
|
|
}
|
|
|
|
// LookupModuleByChannel will return the IBCModule along with the capability associated with a given channel defined by its portID and channelID
|
|
func (k Keeper) LookupModuleByChannel(ctx sdk.Context, portID, channelID string) (string, *capability.Capability, bool) {
|
|
modules, cap, ok := k.scopedKeeper.LookupModules(ctx, ibctypes.ChannelCapabilityPath(portID, channelID))
|
|
if !ok {
|
|
return "", nil, false
|
|
}
|
|
|
|
return ibctypes.GetModuleOwner(modules), cap, true
|
|
}
|