Some checks failed
CodeQL / Analyze (push) Waiting to run
Docker Build & Push Simapp (main) / docker-build (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
Deploy to GitHub Pages / Deploy to GitHub Pages (push) Has been cancelled
Buf-Push / push (push) Has been cancelled
586 lines
21 KiB
Go
586 lines
21 KiB
Go
package keeper
|
|
|
|
import (
|
|
"errors"
|
|
"strconv"
|
|
"strings"
|
|
|
|
db "github.com/cosmos/cosmos-db"
|
|
|
|
corestore "cosmossdk.io/core/store"
|
|
errorsmod "cosmossdk.io/errors"
|
|
"cosmossdk.io/log"
|
|
storetypes "cosmossdk.io/store/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
"github.com/cosmos/cosmos-sdk/runtime"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
|
|
clienttypes "github.com/cosmos/ibc-go/v10/modules/core/02-client/types"
|
|
connectiontypes "github.com/cosmos/ibc-go/v10/modules/core/03-connection/types"
|
|
"github.com/cosmos/ibc-go/v10/modules/core/04-channel/types"
|
|
porttypes "github.com/cosmos/ibc-go/v10/modules/core/05-port/types"
|
|
host "github.com/cosmos/ibc-go/v10/modules/core/24-host"
|
|
"github.com/cosmos/ibc-go/v10/modules/core/exported"
|
|
)
|
|
|
|
var _ porttypes.ICS4Wrapper = (*Keeper)(nil)
|
|
|
|
// Keeper defines the IBC channel keeper
|
|
type Keeper struct {
|
|
// implements gRPC QueryServer interface
|
|
types.QueryServer
|
|
|
|
storeService corestore.KVStoreService
|
|
cdc codec.BinaryCodec
|
|
clientKeeper types.ClientKeeper
|
|
connectionKeeper types.ConnectionKeeper
|
|
}
|
|
|
|
// NewKeeper creates a new IBC channel Keeper instance
|
|
func NewKeeper(
|
|
cdc codec.BinaryCodec,
|
|
storeService corestore.KVStoreService,
|
|
clientKeeper types.ClientKeeper,
|
|
connectionKeeper types.ConnectionKeeper,
|
|
) *Keeper {
|
|
return &Keeper{
|
|
storeService: storeService,
|
|
cdc: cdc,
|
|
clientKeeper: clientKeeper,
|
|
connectionKeeper: connectionKeeper,
|
|
}
|
|
}
|
|
|
|
// Logger returns a module-specific logger.
|
|
func (Keeper) Logger(ctx sdk.Context) log.Logger {
|
|
return ctx.Logger().With("module", "x/"+exported.ModuleName+"/"+types.SubModuleName)
|
|
}
|
|
|
|
// GenerateChannelIdentifier returns the next channel identifier.
|
|
func (k *Keeper) GenerateChannelIdentifier(ctx sdk.Context) string {
|
|
nextChannelSeq := k.GetNextChannelSequence(ctx)
|
|
channelID := types.FormatChannelIdentifier(nextChannelSeq)
|
|
|
|
nextChannelSeq++
|
|
k.SetNextChannelSequence(ctx, nextChannelSeq)
|
|
return channelID
|
|
}
|
|
|
|
// HasChannel true if the channel with the given identifiers exists in state.
|
|
func (k *Keeper) HasChannel(ctx sdk.Context, portID, channelID string) bool {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
has, err := store.Has(host.ChannelKey(portID, channelID))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return has
|
|
}
|
|
|
|
// 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 := k.storeService.OpenKVStore(ctx)
|
|
bz, err := store.Get(host.ChannelKey(portID, channelID))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if len(bz) == 0 {
|
|
return types.Channel{}, false
|
|
}
|
|
|
|
var channel types.Channel
|
|
k.cdc.MustUnmarshal(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 := k.storeService.OpenKVStore(ctx)
|
|
bz := k.cdc.MustMarshal(&channel)
|
|
if err := store.Set(host.ChannelKey(portID, channelID), bz); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// GetAppVersion gets the version for the specified channel.
|
|
func (k *Keeper) GetAppVersion(ctx sdk.Context, portID, channelID string) (string, bool) {
|
|
channel, found := k.GetChannel(ctx, portID, channelID)
|
|
if !found {
|
|
return "", false
|
|
}
|
|
|
|
return channel.Version, true
|
|
}
|
|
|
|
// GetNextChannelSequence gets the next channel sequence from the store.
|
|
func (k *Keeper) GetNextChannelSequence(ctx sdk.Context) uint64 {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
bz, err := store.Get([]byte(types.KeyNextChannelSequence))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if len(bz) == 0 {
|
|
panic(errors.New("next channel sequence is nil"))
|
|
}
|
|
|
|
return sdk.BigEndianToUint64(bz)
|
|
}
|
|
|
|
// SetNextChannelSequence sets the next channel sequence to the store.
|
|
func (k *Keeper) SetNextChannelSequence(ctx sdk.Context, sequence uint64) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
bz := sdk.Uint64ToBigEndian(sequence)
|
|
if err := store.Set([]byte(types.KeyNextChannelSequence), bz); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// GetNextSequenceSend gets a channel's next send sequence from the store
|
|
func (k *Keeper) GetNextSequenceSend(ctx sdk.Context, portID, channelID string) (uint64, bool) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
bz, err := store.Get(host.NextSequenceSendKey(portID, channelID))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if len(bz) == 0 {
|
|
return 0, false
|
|
}
|
|
|
|
return sdk.BigEndianToUint64(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 := k.storeService.OpenKVStore(ctx)
|
|
bz := sdk.Uint64ToBigEndian(sequence)
|
|
if err := store.Set(host.NextSequenceSendKey(portID, channelID), bz); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// GetNextSequenceRecv gets a channel's next receive sequence from the store
|
|
func (k *Keeper) GetNextSequenceRecv(ctx sdk.Context, portID, channelID string) (uint64, bool) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
bz, err := store.Get(host.NextSequenceRecvKey(portID, channelID))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
if len(bz) == 0 {
|
|
return 0, false
|
|
}
|
|
|
|
return sdk.BigEndianToUint64(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 := k.storeService.OpenKVStore(ctx)
|
|
bz := sdk.Uint64ToBigEndian(sequence)
|
|
if err := store.Set(host.NextSequenceRecvKey(portID, channelID), bz); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// GetNextSequenceAck gets a channel's next ack sequence from the store
|
|
func (k *Keeper) GetNextSequenceAck(ctx sdk.Context, portID, channelID string) (uint64, bool) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
bz, err := store.Get(host.NextSequenceAckKey(portID, channelID))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if len(bz) == 0 {
|
|
return 0, false
|
|
}
|
|
|
|
return sdk.BigEndianToUint64(bz), true
|
|
}
|
|
|
|
// SetNextSequenceAck sets a channel's next ack sequence to the store
|
|
func (k *Keeper) SetNextSequenceAck(ctx sdk.Context, portID, channelID string, sequence uint64) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
bz := sdk.Uint64ToBigEndian(sequence)
|
|
if err := store.Set(host.NextSequenceAckKey(portID, channelID), bz); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// GetPacketReceipt gets a packet receipt from the store
|
|
func (k *Keeper) GetPacketReceipt(ctx sdk.Context, portID, channelID string, sequence uint64) (string, bool) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
bz, err := store.Get(host.PacketReceiptKey(portID, channelID, sequence))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if len(bz) == 0 {
|
|
return "", false
|
|
}
|
|
|
|
return string(bz), true
|
|
}
|
|
|
|
// SetPacketReceipt sets an empty packet receipt to the store
|
|
func (k *Keeper) SetPacketReceipt(ctx sdk.Context, portID, channelID string, sequence uint64) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
if err := store.Set(host.PacketReceiptKey(portID, channelID, sequence), []byte{byte(1)}); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// GetPacketCommitment gets the packet commitment hash from the store
|
|
func (k *Keeper) GetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) []byte {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
bz, err := store.Get(host.PacketCommitmentKey(portID, channelID, sequence))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return bz
|
|
}
|
|
|
|
// HasPacketCommitment returns true if the packet commitment exists
|
|
func (k *Keeper) HasPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) bool {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
has, err := store.Has(host.PacketCommitmentKey(portID, channelID, sequence))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return has
|
|
}
|
|
|
|
// SetPacketCommitment sets the packet commitment hash to the store
|
|
func (k *Keeper) SetPacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64, commitmentHash []byte) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
if err := store.Set(host.PacketCommitmentKey(portID, channelID, sequence), commitmentHash); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
func (k *Keeper) deletePacketCommitment(ctx sdk.Context, portID, channelID string, sequence uint64) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
if err := store.Delete(host.PacketCommitmentKey(portID, channelID, sequence)); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// SetPacketAcknowledgement sets the packet ack hash to the store
|
|
func (k *Keeper) SetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64, ackHash []byte) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
if err := store.Set(host.PacketAcknowledgementKey(portID, channelID, sequence), ackHash); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// GetPacketAcknowledgement gets the packet ack hash from the store
|
|
func (k *Keeper) GetPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) ([]byte, bool) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
bz, err := store.Get(host.PacketAcknowledgementKey(portID, channelID, sequence))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if len(bz) == 0 {
|
|
return nil, false
|
|
}
|
|
|
|
return bz, true
|
|
}
|
|
|
|
// HasPacketAcknowledgement check if the packet ack hash is already on the store
|
|
func (k *Keeper) HasPacketAcknowledgement(ctx sdk.Context, portID, channelID string, sequence uint64) bool {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
has, err := store.Has(host.PacketAcknowledgementKey(portID, channelID, sequence))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return has
|
|
}
|
|
|
|
// IteratePacketSequence provides an iterator over all send, receive or ack sequences.
|
|
// For each sequence, cb will be called. If the cb returns true, the iterator
|
|
// will close and stop.
|
|
func (k *Keeper) IteratePacketSequence(ctx sdk.Context, iterator db.Iterator, cb func(portID, channelID string, sequence uint64) bool) {
|
|
defer sdk.LogDeferred(k.Logger(ctx), func() error { return iterator.Close() })
|
|
for ; iterator.Valid(); iterator.Next() {
|
|
portID, channelID, err := host.ParseChannelPath(string(iterator.Key()))
|
|
if err != nil {
|
|
// return if the key is not a channel key
|
|
return
|
|
}
|
|
|
|
sequence := sdk.BigEndianToUint64(iterator.Value())
|
|
|
|
if cb(portID, channelID, sequence) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetAllPacketSendSeqs returns all stored next send sequences.
|
|
func (k *Keeper) GetAllPacketSendSeqs(ctx sdk.Context) (seqs []types.PacketSequence) {
|
|
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
|
iterator := storetypes.KVStorePrefixIterator(store, []byte(host.KeyNextSeqSendPrefix))
|
|
k.IteratePacketSequence(ctx, iterator, func(portID, channelID string, nextSendSeq uint64) bool {
|
|
ps := types.NewPacketSequence(portID, channelID, nextSendSeq)
|
|
seqs = append(seqs, ps)
|
|
return false
|
|
})
|
|
return seqs
|
|
}
|
|
|
|
// GetAllPacketRecvSeqs returns all stored next recv sequences.
|
|
func (k *Keeper) GetAllPacketRecvSeqs(ctx sdk.Context) (seqs []types.PacketSequence) {
|
|
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
|
iterator := storetypes.KVStorePrefixIterator(store, []byte(host.KeyNextSeqRecvPrefix))
|
|
k.IteratePacketSequence(ctx, iterator, func(portID, channelID string, nextRecvSeq uint64) bool {
|
|
ps := types.NewPacketSequence(portID, channelID, nextRecvSeq)
|
|
seqs = append(seqs, ps)
|
|
return false
|
|
})
|
|
return seqs
|
|
}
|
|
|
|
// GetAllPacketAckSeqs returns all stored next acknowledgements sequences.
|
|
func (k *Keeper) GetAllPacketAckSeqs(ctx sdk.Context) (seqs []types.PacketSequence) {
|
|
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
|
iterator := storetypes.KVStorePrefixIterator(store, []byte(host.KeyNextSeqAckPrefix))
|
|
k.IteratePacketSequence(ctx, iterator, func(portID, channelID string, nextAckSeq uint64) bool {
|
|
ps := types.NewPacketSequence(portID, channelID, nextAckSeq)
|
|
seqs = append(seqs, ps)
|
|
return false
|
|
})
|
|
return seqs
|
|
}
|
|
|
|
// IteratePacketCommitment provides an iterator over all PacketCommitment objects. For each
|
|
// packet commitment, cb will be called. If the cb returns true, the iterator will close
|
|
// and stop.
|
|
func (k *Keeper) IteratePacketCommitment(ctx sdk.Context, cb func(portID, channelID string, sequence uint64, hash []byte) bool) {
|
|
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
|
iterator := storetypes.KVStorePrefixIterator(store, []byte(host.KeyPacketCommitmentPrefix))
|
|
k.iterateHashes(ctx, iterator, cb)
|
|
}
|
|
|
|
// GetAllPacketCommitments returns all stored PacketCommitments objects.
|
|
func (k *Keeper) GetAllPacketCommitments(ctx sdk.Context) (commitments []types.PacketState) {
|
|
k.IteratePacketCommitment(ctx, func(portID, channelID string, sequence uint64, hash []byte) bool {
|
|
pc := types.NewPacketState(portID, channelID, sequence, hash)
|
|
commitments = append(commitments, pc)
|
|
return false
|
|
})
|
|
return commitments
|
|
}
|
|
|
|
// IteratePacketCommitmentAtChannel provides an iterator over all PacketCommitment objects
|
|
// at a specified channel. For each packet commitment, cb will be called. If the cb returns
|
|
// true, the iterator will close and stop.
|
|
func (k *Keeper) IteratePacketCommitmentAtChannel(ctx sdk.Context, portID, channelID string, cb func(_, _ string, sequence uint64, hash []byte) bool) {
|
|
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
|
iterator := storetypes.KVStorePrefixIterator(store, host.PacketCommitmentPrefixKey(portID, channelID))
|
|
k.iterateHashes(ctx, iterator, cb)
|
|
}
|
|
|
|
// GetAllPacketCommitmentsAtChannel returns all stored PacketCommitments objects for a specified
|
|
// port ID and channel ID.
|
|
func (k *Keeper) GetAllPacketCommitmentsAtChannel(ctx sdk.Context, portID, channelID string) (commitments []types.PacketState) {
|
|
k.IteratePacketCommitmentAtChannel(ctx, portID, channelID, func(_, _ string, sequence uint64, hash []byte) bool {
|
|
pc := types.NewPacketState(portID, channelID, sequence, hash)
|
|
commitments = append(commitments, pc)
|
|
return false
|
|
})
|
|
return commitments
|
|
}
|
|
|
|
// IteratePacketReceipt provides an iterator over all PacketReceipt objects. For each
|
|
// receipt, cb will be called. If the cb returns true, the iterator will close
|
|
// and stop.
|
|
func (k *Keeper) IteratePacketReceipt(ctx sdk.Context, cb func(portID, channelID string, sequence uint64, receipt []byte) bool) {
|
|
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
|
iterator := storetypes.KVStorePrefixIterator(store, []byte(host.KeyPacketReceiptPrefix))
|
|
k.iterateHashes(ctx, iterator, cb)
|
|
}
|
|
|
|
// GetAllPacketReceipts returns all stored PacketReceipt objects.
|
|
func (k *Keeper) GetAllPacketReceipts(ctx sdk.Context) (receipts []types.PacketState) {
|
|
k.IteratePacketReceipt(ctx, func(portID, channelID string, sequence uint64, receipt []byte) bool {
|
|
packetReceipt := types.NewPacketState(portID, channelID, sequence, receipt)
|
|
receipts = append(receipts, packetReceipt)
|
|
return false
|
|
})
|
|
return receipts
|
|
}
|
|
|
|
// IteratePacketAcknowledgement provides an iterator over all PacketAcknowledgement objects. For each
|
|
// acknowledgement, cb will be called. If the cb returns true, the iterator will close
|
|
// and stop.
|
|
func (k *Keeper) IteratePacketAcknowledgement(ctx sdk.Context, cb func(portID, channelID string, sequence uint64, hash []byte) bool) {
|
|
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
|
iterator := storetypes.KVStorePrefixIterator(store, []byte(host.KeyPacketAckPrefix))
|
|
k.iterateHashes(ctx, iterator, cb)
|
|
}
|
|
|
|
// GetAllPacketAcks returns all stored PacketAcknowledgements objects.
|
|
func (k *Keeper) GetAllPacketAcks(ctx sdk.Context) (acks []types.PacketState) {
|
|
k.IteratePacketAcknowledgement(ctx, func(portID, channelID string, sequence uint64, ack []byte) bool {
|
|
packetAck := types.NewPacketState(portID, channelID, sequence, ack)
|
|
acks = append(acks, packetAck)
|
|
return false
|
|
})
|
|
return acks
|
|
}
|
|
|
|
// 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 := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
|
iterator := storetypes.KVStorePrefixIterator(store, []byte(host.KeyChannelEndPrefix))
|
|
|
|
defer sdk.LogDeferred(k.Logger(ctx), func() error { return iterator.Close() })
|
|
for ; iterator.Valid(); iterator.Next() {
|
|
var channel types.Channel
|
|
k.cdc.MustUnmarshal(iterator.Value(), &channel)
|
|
|
|
portID, channelID := host.MustParseChannelPath(string(iterator.Key()))
|
|
identifiedChannel := types.NewIdentifiedChannel(portID, channelID, channel)
|
|
if cb(identifiedChannel) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// GetAllChannelsWithPortPrefix returns all channels with the specified port prefix. If an empty prefix is provided
|
|
// all channels will be returned.
|
|
func (k *Keeper) GetAllChannelsWithPortPrefix(ctx sdk.Context, portPrefix string) []types.IdentifiedChannel {
|
|
if strings.TrimSpace(portPrefix) == "" {
|
|
return k.GetAllChannels(ctx)
|
|
}
|
|
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
|
iterator := storetypes.KVStorePrefixIterator(store, types.FilteredPortPrefix(portPrefix))
|
|
defer sdk.LogDeferred(k.Logger(ctx), func() error { return iterator.Close() })
|
|
|
|
var filteredChannels []types.IdentifiedChannel
|
|
for ; iterator.Valid(); iterator.Next() {
|
|
var channel types.Channel
|
|
k.cdc.MustUnmarshal(iterator.Value(), &channel)
|
|
|
|
portID, channelID := host.MustParseChannelPath(string(iterator.Key()))
|
|
identifiedChannel := types.NewIdentifiedChannel(portID, channelID, channel)
|
|
filteredChannels = append(filteredChannels, identifiedChannel)
|
|
}
|
|
return filteredChannels
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// GetChannelClientState returns the associated client state with its ID, from a port and channel identifier.
|
|
func (k *Keeper) GetChannelClientState(ctx sdk.Context, portID, channelID string) (string, exported.ClientState, error) {
|
|
channel, found := k.GetChannel(ctx, portID, channelID)
|
|
if !found {
|
|
return "", nil, errorsmod.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id: %s", portID, channelID)
|
|
}
|
|
|
|
connection, found := k.connectionKeeper.GetConnection(ctx, channel.ConnectionHops[0])
|
|
if !found {
|
|
return "", nil, errorsmod.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", channel.ConnectionHops[0])
|
|
}
|
|
|
|
clientState, found := k.clientKeeper.GetClientState(ctx, connection.ClientId)
|
|
if !found {
|
|
return "", nil, errorsmod.Wrapf(clienttypes.ErrClientNotFound, "client-id: %s", connection.ClientId)
|
|
}
|
|
|
|
return connection.ClientId, clientState, nil
|
|
}
|
|
|
|
// GetConnection wraps the connection keeper's GetConnection function.
|
|
func (k *Keeper) GetConnection(ctx sdk.Context, connectionID string) (connectiontypes.ConnectionEnd, error) {
|
|
connection, found := k.connectionKeeper.GetConnection(ctx, connectionID)
|
|
if !found {
|
|
return connectiontypes.ConnectionEnd{}, errorsmod.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", connectionID)
|
|
}
|
|
|
|
return connection, nil
|
|
}
|
|
|
|
// GetChannelConnection returns the connection ID and state associated with the given port and channel identifier.
|
|
func (k *Keeper) GetChannelConnection(ctx sdk.Context, portID, channelID string) (string, connectiontypes.ConnectionEnd, error) {
|
|
channel, found := k.GetChannel(ctx, portID, channelID)
|
|
if !found {
|
|
return "", connectiontypes.ConnectionEnd{}, errorsmod.Wrapf(types.ErrChannelNotFound, "port-id: %s, channel-id: %s", portID, channelID)
|
|
}
|
|
|
|
connectionID := channel.ConnectionHops[0]
|
|
|
|
connection, found := k.connectionKeeper.GetConnection(ctx, connectionID)
|
|
if !found {
|
|
return "", connectiontypes.ConnectionEnd{}, errorsmod.Wrapf(connectiontypes.ErrConnectionNotFound, "connection-id: %s", connectionID)
|
|
}
|
|
|
|
return connectionID, connection, nil
|
|
}
|
|
|
|
// common functionality for IteratePacketCommitment and IteratePacketAcknowledgement
|
|
func (k *Keeper) iterateHashes(ctx sdk.Context, iterator db.Iterator, cb func(portID, channelID string, sequence uint64, hash []byte) bool) {
|
|
defer sdk.LogDeferred(k.Logger(ctx), func() error { return iterator.Close() })
|
|
|
|
for ; iterator.Valid(); iterator.Next() {
|
|
keySplit := strings.Split(string(iterator.Key()), "/")
|
|
portID := keySplit[2]
|
|
channelID := keySplit[4]
|
|
|
|
sequence, err := strconv.ParseUint(keySplit[len(keySplit)-1], 10, 64)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if cb(portID, channelID, sequence, iterator.Value()) {
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
// HasInflightPackets returns true if there are packet commitments stored at the specified
|
|
// port and channel, and false otherwise.
|
|
func (k *Keeper) HasInflightPackets(ctx sdk.Context, portID, channelID string) bool {
|
|
store := runtime.KVStoreAdapter(k.storeService.OpenKVStore(ctx))
|
|
iterator := storetypes.KVStorePrefixIterator(store, host.PacketCommitmentPrefixKey(portID, channelID))
|
|
defer sdk.LogDeferred(k.Logger(ctx), func() error { return iterator.Close() })
|
|
|
|
return iterator.Valid()
|
|
}
|
|
|
|
// setRecvStartSequence sets the channel's recv start sequence to the store.
|
|
func (k *Keeper) setRecvStartSequence(ctx sdk.Context, portID, channelID string, sequence uint64) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
bz := sdk.Uint64ToBigEndian(sequence)
|
|
if err := store.Set(host.RecvStartSequenceKey(portID, channelID), bz); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// GetRecvStartSequence gets a channel's recv start sequence from the store.
|
|
// The recv start sequence will be set to the counterparty's next sequence send
|
|
// upon a successful channel upgrade. It will be used for replay protection of
|
|
// historical packets and as the upper bound for pruning stale packet receives.
|
|
func (k *Keeper) GetRecvStartSequence(ctx sdk.Context, portID, channelID string) (uint64, bool) {
|
|
store := k.storeService.OpenKVStore(ctx)
|
|
bz, err := store.Get(host.RecvStartSequenceKey(portID, channelID))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if len(bz) == 0 {
|
|
return 0, false
|
|
}
|
|
|
|
return sdk.BigEndianToUint64(bz), true
|
|
}
|