Add ibc query commands
This commit is contained in:
parent
374f078b79
commit
746ae28eaa
|
@ -19,6 +19,7 @@ import (
|
||||||
basecmd "github.com/tendermint/basecoin/modules/base/commands"
|
basecmd "github.com/tendermint/basecoin/modules/base/commands"
|
||||||
coincmd "github.com/tendermint/basecoin/modules/coin/commands"
|
coincmd "github.com/tendermint/basecoin/modules/coin/commands"
|
||||||
feecmd "github.com/tendermint/basecoin/modules/fee/commands"
|
feecmd "github.com/tendermint/basecoin/modules/fee/commands"
|
||||||
|
ibccmd "github.com/tendermint/basecoin/modules/ibc/commands"
|
||||||
noncecmd "github.com/tendermint/basecoin/modules/nonce/commands"
|
noncecmd "github.com/tendermint/basecoin/modules/nonce/commands"
|
||||||
rolecmd "github.com/tendermint/basecoin/modules/roles/commands"
|
rolecmd "github.com/tendermint/basecoin/modules/roles/commands"
|
||||||
)
|
)
|
||||||
|
@ -46,6 +47,7 @@ func main() {
|
||||||
coincmd.AccountQueryCmd,
|
coincmd.AccountQueryCmd,
|
||||||
noncecmd.NonceQueryCmd,
|
noncecmd.NonceQueryCmd,
|
||||||
rolecmd.RoleQueryCmd,
|
rolecmd.RoleQueryCmd,
|
||||||
|
ibccmd.IBCQueryCmd,
|
||||||
)
|
)
|
||||||
proofs.TxPresenters.Register("base", txcmd.BaseTxPresenter{})
|
proofs.TxPresenters.Register("base", txcmd.BaseTxPresenter{})
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,10 @@ import (
|
||||||
"github.com/tendermint/basecoin/stack"
|
"github.com/tendermint/basecoin/stack"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO: other test making sure tx is output on send, balance is updated
|
||||||
|
|
||||||
|
// This makes sure we respond properly to posttx
|
||||||
|
// TODO: set credit limit
|
||||||
func TestIBCPostPacket(t *testing.T) {
|
func TestIBCPostPacket(t *testing.T) {
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
|
|
|
@ -0,0 +1,185 @@
|
||||||
|
package commands
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
|
proofcmd "github.com/tendermint/basecoin/client/commands/proofs"
|
||||||
|
"github.com/tendermint/basecoin/modules/ibc"
|
||||||
|
"github.com/tendermint/basecoin/stack"
|
||||||
|
)
|
||||||
|
|
||||||
|
// IBCQueryCmd - parent command to query ibc info
|
||||||
|
var IBCQueryCmd = &cobra.Command{
|
||||||
|
Use: "ibc",
|
||||||
|
Short: "Get information about IBC",
|
||||||
|
RunE: commands.RequireInit(ibcQueryCmd),
|
||||||
|
// HandlerInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainsQueryCmd - get a list of all registered chains
|
||||||
|
var ChainsQueryCmd = &cobra.Command{
|
||||||
|
Use: "chains",
|
||||||
|
Short: "Get a list of all registered chains",
|
||||||
|
RunE: commands.RequireInit(chainsQueryCmd),
|
||||||
|
// ChainSet ([]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainQueryCmd - get details on one registered chain
|
||||||
|
var ChainQueryCmd = &cobra.Command{
|
||||||
|
Use: "chain [id]",
|
||||||
|
Short: "Get details on one registered chain",
|
||||||
|
RunE: commands.RequireInit(chainQueryCmd),
|
||||||
|
// ChainInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
// PacketsQueryCmd - get latest packet in a queue
|
||||||
|
var PacketsQueryCmd = &cobra.Command{
|
||||||
|
Use: "packets",
|
||||||
|
Short: "Get latest packet in a queue",
|
||||||
|
RunE: commands.RequireInit(packetsQueryCmd),
|
||||||
|
// uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
// PacketQueryCmd - get the names packet (by queue and sequence)
|
||||||
|
var PacketQueryCmd = &cobra.Command{
|
||||||
|
Use: "packet",
|
||||||
|
Short: "Get packet with given sequence from the named queue",
|
||||||
|
RunE: commands.RequireInit(packetQueryCmd),
|
||||||
|
// Packet
|
||||||
|
}
|
||||||
|
|
||||||
|
//nolint
|
||||||
|
const (
|
||||||
|
FlagFromChain = "from"
|
||||||
|
FlagToChain = "to"
|
||||||
|
FlagSequence = "sequence"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
IBCQueryCmd.AddCommand(
|
||||||
|
ChainQueryCmd,
|
||||||
|
ChainsQueryCmd,
|
||||||
|
PacketQueryCmd,
|
||||||
|
PacketsQueryCmd,
|
||||||
|
)
|
||||||
|
|
||||||
|
fs1 := PacketsQueryCmd.Flags()
|
||||||
|
fs1.String(FlagFromChain, "", "Name of the input chain (where packets came from)")
|
||||||
|
fs1.String(FlagToChain, "", "Name of the output chain (where packets go to)")
|
||||||
|
|
||||||
|
fs2 := PacketQueryCmd.Flags()
|
||||||
|
fs2.String(FlagFromChain, "", "Name of the input chain (where packets came from)")
|
||||||
|
fs2.String(FlagToChain, "", "Name of the output chain (where packets go to)")
|
||||||
|
fs2.Int(FlagSequence, -1, "Name of the output chain (where packets go to)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func ibcQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
var res ibc.HandlerInfo
|
||||||
|
key := stack.PrefixedKey(ibc.NameIBC, ibc.HandlerKey())
|
||||||
|
proof, err := proofcmd.GetAndParseAppProof(key, &res)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return proofcmd.OutputProof(res, proof.BlockHeight())
|
||||||
|
}
|
||||||
|
|
||||||
|
func chainsQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
list := [][]byte{}
|
||||||
|
key := stack.PrefixedKey(ibc.NameIBC, ibc.HandlerKey())
|
||||||
|
proof, err := proofcmd.GetAndParseAppProof(key, &list)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert these names to strings for better output
|
||||||
|
res := make([]string, len(list))
|
||||||
|
for i := range list {
|
||||||
|
res[i] = string(list[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
return proofcmd.OutputProof(res, proof.BlockHeight())
|
||||||
|
}
|
||||||
|
|
||||||
|
func chainQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
arg, err := commands.GetOneArg(args, "id")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var res ibc.ChainInfo
|
||||||
|
key := stack.PrefixedKey(ibc.NameIBC, ibc.ChainKey(arg))
|
||||||
|
proof, err := proofcmd.GetAndParseAppProof(key, &res)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return proofcmd.OutputProof(res, proof.BlockHeight())
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertOne(from, to string) error {
|
||||||
|
if from == "" && to == "" {
|
||||||
|
return errors.Errorf("You must specify either --%s or --%s",
|
||||||
|
FlagFromChain, FlagToChain)
|
||||||
|
}
|
||||||
|
if from != "" && to != "" {
|
||||||
|
return errors.Errorf("You can only specify one of --%s or --%s",
|
||||||
|
FlagFromChain, FlagToChain)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func packetsQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
from := viper.GetString(FlagFromChain)
|
||||||
|
to := viper.GetString(FlagToChain)
|
||||||
|
err := assertOne(from, to)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var key []byte
|
||||||
|
if from != "" {
|
||||||
|
key = stack.PrefixedKey(ibc.NameIBC, ibc.QueueInKey(from))
|
||||||
|
} else {
|
||||||
|
key = stack.PrefixedKey(ibc.NameIBC, ibc.QueueOutKey(to))
|
||||||
|
}
|
||||||
|
|
||||||
|
var res uint64
|
||||||
|
proof, err := proofcmd.GetAndParseAppProof(key, &res)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return proofcmd.OutputProof(res, proof.BlockHeight())
|
||||||
|
}
|
||||||
|
|
||||||
|
func packetQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
from := viper.GetString(FlagFromChain)
|
||||||
|
to := viper.GetString(FlagToChain)
|
||||||
|
err := assertOne(from, to)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
seq := viper.GetInt(FlagSequence)
|
||||||
|
if seq < 0 {
|
||||||
|
return errors.Errorf("--%s must be a non-negative number", FlagSequence)
|
||||||
|
}
|
||||||
|
|
||||||
|
var key []byte
|
||||||
|
if from != "" {
|
||||||
|
key = stack.PrefixedKey(ibc.NameIBC, ibc.QueueInPacketKey(from, uint64(seq)))
|
||||||
|
} else {
|
||||||
|
key = stack.PrefixedKey(ibc.NameIBC, ibc.QueueOutPacketKey(to, uint64(seq)))
|
||||||
|
}
|
||||||
|
|
||||||
|
var res ibc.Packet
|
||||||
|
proof, err := proofcmd.GetAndParseAppProof(key, &res)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return proofcmd.OutputProof(res, proof.BlockHeight())
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package ibc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/tendermint/basecoin/stack"
|
||||||
|
"github.com/tendermint/basecoin/state"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// this is the prefix for the list of chains
|
||||||
|
// we otherwise use the chainid as prefix, so this must not be an
|
||||||
|
// alpha-numeric byte
|
||||||
|
prefixChains = "**"
|
||||||
|
|
||||||
|
prefixInput = "i"
|
||||||
|
prefixOutput = "o"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HandlerKey is used for the global permission info
|
||||||
|
func HandlerKey() []byte {
|
||||||
|
return []byte{0x2}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainsKey is the key to get info on all chains
|
||||||
|
func ChainsKey() []byte {
|
||||||
|
return stack.PrefixedKey(prefixChains, state.SetKey())
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChainKey is the key to get info on one chain
|
||||||
|
func ChainKey(chainID string) []byte {
|
||||||
|
bkey := state.MakeBKey([]byte(chainID))
|
||||||
|
return stack.PrefixedKey(prefixChains, bkey)
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueueInKey is the key to get newest of the input queue from this chain
|
||||||
|
func QueueInKey(chainID string) []byte {
|
||||||
|
return stack.PrefixedKey(chainID,
|
||||||
|
stack.PrefixedKey(prefixInput,
|
||||||
|
state.QueueTailKey()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueueOutKey is the key to get v of the output queue from this chain
|
||||||
|
func QueueOutKey(chainID string) []byte {
|
||||||
|
return stack.PrefixedKey(chainID,
|
||||||
|
stack.PrefixedKey(prefixOutput,
|
||||||
|
state.QueueTailKey()))
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueueInPacketKey is the key to get given packet from this chain's input queue
|
||||||
|
func QueueInPacketKey(chainID string, seq uint64) []byte {
|
||||||
|
return stack.PrefixedKey(chainID,
|
||||||
|
stack.PrefixedKey(prefixInput,
|
||||||
|
state.QueueItemKey(seq)))
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueueOutPacketKey is the key to get given packet from this chain's output queue
|
||||||
|
func QueueOutPacketKey(chainID string, seq uint64) []byte {
|
||||||
|
return stack.PrefixedKey(chainID,
|
||||||
|
stack.PrefixedKey(prefixOutput,
|
||||||
|
state.QueueItemKey(seq)))
|
||||||
|
}
|
|
@ -7,21 +7,6 @@ import (
|
||||||
wire "github.com/tendermint/go-wire"
|
wire "github.com/tendermint/go-wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
// this is the prefix for the list of chains
|
|
||||||
// we otherwise use the chainid as prefix, so this must not be an
|
|
||||||
// alpha-numeric byte
|
|
||||||
prefixChains = "**"
|
|
||||||
|
|
||||||
prefixInput = "i"
|
|
||||||
prefixOutput = "o"
|
|
||||||
)
|
|
||||||
|
|
||||||
// this is used for the global handler info
|
|
||||||
var (
|
|
||||||
handlerKey = []byte{0x2}
|
|
||||||
)
|
|
||||||
|
|
||||||
// HandlerInfo is the global state of the ibc.Handler
|
// HandlerInfo is the global state of the ibc.Handler
|
||||||
type HandlerInfo struct {
|
type HandlerInfo struct {
|
||||||
Registrar basecoin.Actor `json:"registrar"`
|
Registrar basecoin.Actor `json:"registrar"`
|
||||||
|
@ -30,12 +15,12 @@ type HandlerInfo struct {
|
||||||
// Save the HandlerInfo to the store
|
// Save the HandlerInfo to the store
|
||||||
func (h HandlerInfo) Save(store state.KVStore) {
|
func (h HandlerInfo) Save(store state.KVStore) {
|
||||||
b := wire.BinaryBytes(h)
|
b := wire.BinaryBytes(h)
|
||||||
store.Set(handlerKey, b)
|
store.Set(HandlerKey(), b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadInfo loads the HandlerInfo from the data store
|
// LoadInfo loads the HandlerInfo from the data store
|
||||||
func LoadInfo(store state.KVStore) (h HandlerInfo) {
|
func LoadInfo(store state.KVStore) (h HandlerInfo) {
|
||||||
b := store.Get(handlerKey)
|
b := store.Get(HandlerKey())
|
||||||
if len(b) > 0 {
|
if len(b) > 0 {
|
||||||
wire.ReadBinaryBytes(b, &h)
|
wire.ReadBinaryBytes(b, &h)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
lcmd "github.com/tendermint/basecoin/client/commands"
|
"github.com/tendermint/basecoin/client/commands"
|
||||||
proofcmd "github.com/tendermint/basecoin/client/commands/proofs"
|
proofcmd "github.com/tendermint/basecoin/client/commands/proofs"
|
||||||
"github.com/tendermint/basecoin/modules/roles"
|
"github.com/tendermint/basecoin/modules/roles"
|
||||||
"github.com/tendermint/basecoin/stack"
|
"github.com/tendermint/basecoin/stack"
|
||||||
|
@ -14,17 +13,15 @@ import (
|
||||||
var RoleQueryCmd = &cobra.Command{
|
var RoleQueryCmd = &cobra.Command{
|
||||||
Use: "role [name]",
|
Use: "role [name]",
|
||||||
Short: "Get details of a role, with proof",
|
Short: "Get details of a role, with proof",
|
||||||
RunE: lcmd.RequireInit(roleQueryCmd),
|
RunE: commands.RequireInit(roleQueryCmd),
|
||||||
}
|
}
|
||||||
|
|
||||||
func roleQueryCmd(cmd *cobra.Command, args []string) error {
|
func roleQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
if len(args) == 0 {
|
arg, err := commands.GetOneArg(args, "name")
|
||||||
return errors.New("Missing required argument [name]")
|
if err != nil {
|
||||||
} else if len(args) > 1 {
|
return err
|
||||||
return errors.New("Command only supports one name")
|
|
||||||
}
|
}
|
||||||
|
role, err := parseRole(arg)
|
||||||
role, err := parseRole(args[0])
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,21 @@ var (
|
||||||
dataKey = []byte("d")
|
dataKey = []byte("d")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// QueueHeadKey gives us the key for the height at head of the queue
|
||||||
|
func QueueHeadKey() []byte {
|
||||||
|
return headKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueueTailKey gives us the key for the height at tail of the queue
|
||||||
|
func QueueTailKey() []byte {
|
||||||
|
return tailKey
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueueItemKey gives us the key to look up one item by sequence
|
||||||
|
func QueueItemKey(i uint64) []byte {
|
||||||
|
return makeKey(i)
|
||||||
|
}
|
||||||
|
|
||||||
// Queue allows us to fill up a range of the db, and grab from either end
|
// Queue allows us to fill up a range of the db, and grab from either end
|
||||||
type Queue struct {
|
type Queue struct {
|
||||||
store KVStore
|
store KVStore
|
||||||
|
|
13
state/set.go
13
state/set.go
|
@ -7,6 +7,11 @@ import (
|
||||||
wire "github.com/tendermint/go-wire"
|
wire "github.com/tendermint/go-wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// SetKey returns the key to get all members of this set
|
||||||
|
func SetKey() []byte {
|
||||||
|
return keys
|
||||||
|
}
|
||||||
|
|
||||||
// Set allows us to add arbitrary k-v pairs, check existence,
|
// Set allows us to add arbitrary k-v pairs, check existence,
|
||||||
// as well as iterate through the set (always in key order)
|
// as well as iterate through the set (always in key order)
|
||||||
//
|
//
|
||||||
|
@ -29,7 +34,7 @@ func NewSet(store KVStore) *Set {
|
||||||
// Set puts a value at a given height.
|
// Set puts a value at a given height.
|
||||||
// If the value is nil, or an empty slice, remove the key from the list
|
// If the value is nil, or an empty slice, remove the key from the list
|
||||||
func (s *Set) Set(key []byte, value []byte) {
|
func (s *Set) Set(key []byte, value []byte) {
|
||||||
s.store.Set(makeBKey(key), value)
|
s.store.Set(MakeBKey(key), value)
|
||||||
if len(value) > 0 {
|
if len(value) > 0 {
|
||||||
s.addKey(key)
|
s.addKey(key)
|
||||||
} else {
|
} else {
|
||||||
|
@ -40,7 +45,7 @@ func (s *Set) Set(key []byte, value []byte) {
|
||||||
|
|
||||||
// Get returns the element with a key if it exists
|
// Get returns the element with a key if it exists
|
||||||
func (s *Set) Get(key []byte) []byte {
|
func (s *Set) Get(key []byte) []byte {
|
||||||
return s.store.Get(makeBKey(key))
|
return s.store.Get(MakeBKey(key))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove deletes this key from the set (same as setting value = nil)
|
// Remove deletes this key from the set (same as setting value = nil)
|
||||||
|
@ -122,8 +127,8 @@ func (s *Set) storeKeys() {
|
||||||
s.store.Set(keys, b)
|
s.store.Set(keys, b)
|
||||||
}
|
}
|
||||||
|
|
||||||
// makeBKey prefixes the byte slice for the storage key
|
// MakeBKey prefixes the byte slice for the storage key
|
||||||
func makeBKey(key []byte) []byte {
|
func MakeBKey(key []byte) []byte {
|
||||||
return append(dataKey, key...)
|
return append(dataKey, key...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue