cosmos-sdk/x/ibc/mapper.go

131 lines
3.5 KiB
Go

package ibc
import (
"fmt"
sdk "github.com/cosmos/cosmos-sdk/types"
wire "github.com/cosmos/cosmos-sdk/wire"
)
// IBC Mapper
type Mapper struct {
key sdk.StoreKey
cdc *wire.Codec
codespace sdk.CodespaceType
}
// XXX: The Mapper should not take a CoinKeeper. Rather have the CoinKeeper
// take an Mapper.
func NewMapper(cdc *wire.Codec, key sdk.StoreKey, codespace sdk.CodespaceType) Mapper {
// XXX: How are these codecs supposed to work?
return Mapper{
key: key,
cdc: cdc,
codespace: codespace,
}
}
// XXX: This is not the public API. This will change in MVP2 and will henceforth
// only be invoked from another module directly and not through a user
// transaction.
// TODO: Handle invalid IBC packets and return errors.
func (ibcm Mapper) PostIBCPacket(ctx sdk.Context, packet IBCPacket) sdk.Error {
// write everything into the state
store := ctx.KVStore(ibcm.key)
index := ibcm.getEgressLength(store, packet.DestChain)
bz, err := ibcm.cdc.MarshalBinary(packet)
if err != nil {
panic(err)
}
store.Set(EgressKey(packet.DestChain, index), bz)
bz, err = ibcm.cdc.MarshalBinary(int64(index + 1))
if err != nil {
panic(err)
}
store.Set(EgressLengthKey(packet.DestChain), bz)
return nil
}
// XXX: In the future every module is able to register it's own handler for
// handling it's own IBC packets. The "ibc" handler will only route the packets
// to the appropriate callbacks.
// XXX: For now this handles all interactions with the CoinKeeper.
// XXX: This needs to do some authentication checking.
func (ibcm Mapper) ReceiveIBCPacket(ctx sdk.Context, packet IBCPacket) sdk.Error {
return nil
}
// --------------------------
// Functions for accessing the underlying KVStore.
func marshalBinaryPanic(cdc *wire.Codec, value interface{}) []byte {
res, err := cdc.MarshalBinary(value)
if err != nil {
panic(err)
}
return res
}
func unmarshalBinaryPanic(cdc *wire.Codec, bz []byte, ptr interface{}) {
err := cdc.UnmarshalBinary(bz, ptr)
if err != nil {
panic(err)
}
}
// TODO add description
func (ibcm Mapper) GetIngressSequence(ctx sdk.Context, srcChain string) int64 {
store := ctx.KVStore(ibcm.key)
key := IngressSequenceKey(srcChain)
bz := store.Get(key)
if bz == nil {
zero := marshalBinaryPanic(ibcm.cdc, int64(0))
store.Set(key, zero)
return 0
}
var res int64
unmarshalBinaryPanic(ibcm.cdc, bz, &res)
return res
}
// TODO add description
func (ibcm Mapper) SetIngressSequence(ctx sdk.Context, srcChain string, sequence int64) {
store := ctx.KVStore(ibcm.key)
key := IngressSequenceKey(srcChain)
bz := marshalBinaryPanic(ibcm.cdc, sequence)
store.Set(key, bz)
}
// Retrieves the index of the currently stored outgoing IBC packets.
func (ibcm Mapper) getEgressLength(store sdk.KVStore, destChain string) int64 {
bz := store.Get(EgressLengthKey(destChain))
if bz == nil {
zero := marshalBinaryPanic(ibcm.cdc, int64(0))
store.Set(EgressLengthKey(destChain), zero)
return 0
}
var res int64
unmarshalBinaryPanic(ibcm.cdc, bz, &res)
return res
}
// Stores an outgoing IBC packet under "egress/chain_id/index".
func EgressKey(destChain string, index int64) []byte {
return []byte(fmt.Sprintf("egress/%s/%d", destChain, index))
}
// Stores the number of outgoing IBC packets under "egress/index".
func EgressLengthKey(destChain string) []byte {
return []byte(fmt.Sprintf("egress/%s", destChain))
}
// Stores the sequence number of incoming IBC packet under "ingress/index".
func IngressSequenceKey(srcChain string) []byte {
return []byte(fmt.Sprintf("ingress/%s", srcChain))
}