2017-07-13 10:22:05 -07:00
|
|
|
package ibc
|
2017-07-14 07:29:29 -07:00
|
|
|
|
|
|
|
import (
|
2017-07-16 13:46:21 -07:00
|
|
|
"github.com/tendermint/basecoin"
|
2017-07-14 07:29:29 -07:00
|
|
|
"github.com/tendermint/basecoin/stack"
|
|
|
|
"github.com/tendermint/basecoin/state"
|
|
|
|
wire "github.com/tendermint/go-wire"
|
|
|
|
)
|
|
|
|
|
2017-07-17 12:19:35 -07:00
|
|
|
// HandlerInfo is the global state of the ibc.Handler
|
|
|
|
type HandlerInfo struct {
|
|
|
|
Registrar basecoin.Actor `json:"registrar"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Save the HandlerInfo to the store
|
2017-07-21 10:53:52 -07:00
|
|
|
func (h HandlerInfo) Save(store state.SimpleDB) {
|
2017-07-17 12:19:35 -07:00
|
|
|
b := wire.BinaryBytes(h)
|
2017-07-21 08:15:49 -07:00
|
|
|
store.Set(HandlerKey(), b)
|
2017-07-17 12:19:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// LoadInfo loads the HandlerInfo from the data store
|
2017-07-21 10:53:52 -07:00
|
|
|
func LoadInfo(store state.SimpleDB) (h HandlerInfo) {
|
2017-07-21 08:15:49 -07:00
|
|
|
b := store.Get(HandlerKey())
|
2017-07-17 12:19:35 -07:00
|
|
|
if len(b) > 0 {
|
|
|
|
wire.ReadBinaryBytes(b, &h)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2017-07-14 07:29:29 -07:00
|
|
|
// ChainInfo is the global info we store for each registered chain,
|
|
|
|
// besides the headers, proofs, and packets
|
|
|
|
type ChainInfo struct {
|
|
|
|
RegisteredAt uint64 `json:"registered_at"`
|
|
|
|
RemoteBlock int `json:"remote_block"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// ChainSet is the set of all registered chains
|
|
|
|
type ChainSet struct {
|
|
|
|
*state.Set
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewChainSet loads or initialized the ChainSet
|
2017-07-21 10:53:52 -07:00
|
|
|
func NewChainSet(store state.SimpleDB) ChainSet {
|
2017-07-14 07:29:29 -07:00
|
|
|
space := stack.PrefixedStore(prefixChains, store)
|
|
|
|
return ChainSet{
|
|
|
|
Set: state.NewSet(space),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Register adds the named chain with some info
|
|
|
|
// returns error if already present
|
|
|
|
func (c ChainSet) Register(chainID string, ourHeight uint64, theirHeight int) error {
|
|
|
|
if c.Exists([]byte(chainID)) {
|
|
|
|
return ErrAlreadyRegistered(chainID)
|
|
|
|
}
|
|
|
|
info := ChainInfo{
|
|
|
|
RegisteredAt: ourHeight,
|
|
|
|
RemoteBlock: theirHeight,
|
|
|
|
}
|
|
|
|
data := wire.BinaryBytes(info)
|
|
|
|
c.Set.Set([]byte(chainID), data)
|
|
|
|
return nil
|
|
|
|
}
|
2017-07-16 13:46:21 -07:00
|
|
|
|
2017-07-21 09:59:11 -07:00
|
|
|
// Update sets the new tracked height on this chain
|
|
|
|
// returns error if not present
|
|
|
|
func (c ChainSet) Update(chainID string, theirHeight int) error {
|
|
|
|
d := c.Set.Get([]byte(chainID))
|
|
|
|
if len(d) == 0 {
|
|
|
|
return ErrNotRegistered(chainID)
|
|
|
|
}
|
|
|
|
// load the data
|
|
|
|
var info ChainInfo
|
|
|
|
err := wire.ReadBinaryBytes(d, &info)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// change the remote block and save it
|
|
|
|
info.RemoteBlock = theirHeight
|
|
|
|
d = wire.BinaryBytes(info)
|
|
|
|
c.Set.Set([]byte(chainID), d)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2017-07-16 13:46:21 -07:00
|
|
|
// Packet is a wrapped transaction and permission that we want to
|
|
|
|
// send off to another chain.
|
|
|
|
type Packet struct {
|
2017-07-18 05:27:53 -07:00
|
|
|
DestChain string `json:"dest_chain"`
|
|
|
|
Sequence uint64 `json:"sequence"`
|
|
|
|
Permissions basecoin.Actors `json:"permissions"`
|
|
|
|
Tx basecoin.Tx `json:"tx"`
|
2017-07-16 13:46:21 -07:00
|
|
|
}
|
|
|
|
|
2017-07-21 04:44:33 -07:00
|
|
|
// NewPacket creates a new outgoing packet
|
|
|
|
func NewPacket(tx basecoin.Tx, dest string, seq uint64, perm ...basecoin.Actor) Packet {
|
|
|
|
return Packet{
|
|
|
|
DestChain: dest,
|
|
|
|
Sequence: seq,
|
|
|
|
Permissions: perm,
|
|
|
|
Tx: tx,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-07-16 13:46:21 -07:00
|
|
|
// Bytes returns a serialization of the Packet
|
|
|
|
func (p Packet) Bytes() []byte {
|
|
|
|
return wire.BinaryBytes(p)
|
|
|
|
}
|
2017-07-17 12:28:36 -07:00
|
|
|
|
|
|
|
// InputQueue returns the queue of input packets from this chain
|
2017-07-21 10:53:52 -07:00
|
|
|
func InputQueue(store state.SimpleDB, chainID string) *state.Queue {
|
2017-07-17 12:28:36 -07:00
|
|
|
ch := stack.PrefixedStore(chainID, store)
|
|
|
|
space := stack.PrefixedStore(prefixInput, ch)
|
|
|
|
return state.NewQueue(space)
|
|
|
|
}
|
|
|
|
|
|
|
|
// OutputQueue returns the queue of output packets destined for this chain
|
2017-07-21 10:53:52 -07:00
|
|
|
func OutputQueue(store state.SimpleDB, chainID string) *state.Queue {
|
2017-07-17 12:28:36 -07:00
|
|
|
ch := stack.PrefixedStore(chainID, store)
|
|
|
|
space := stack.PrefixedStore(prefixOutput, ch)
|
|
|
|
return state.NewQueue(space)
|
|
|
|
}
|