cosmos-sdk/cmd/commands/query.go

234 lines
5.0 KiB
Go
Raw Normal View History

package commands
2017-01-29 18:41:37 -08:00
import (
"encoding/hex"
"encoding/json"
2017-01-29 18:41:37 -08:00
"fmt"
"strconv"
2017-04-15 09:07:27 -07:00
"github.com/pkg/errors"
"github.com/spf13/cobra"
2017-01-29 18:41:37 -08:00
"github.com/tendermint/go-wire"
2017-04-25 22:20:29 -07:00
"github.com/tendermint/merkleeyes/iavl"
2017-05-21 19:22:58 -07:00
"github.com/tendermint/tendermint/rpc/client"
2017-01-29 18:41:37 -08:00
tmtypes "github.com/tendermint/tendermint/types"
)
//commands
var (
QueryCmd = &cobra.Command{
Use: "query [key]",
Short: "Query the merkle tree",
2017-04-15 09:07:27 -07:00
RunE: queryCmd,
}
AccountCmd = &cobra.Command{
Use: "account [address]",
Short: "Get details of an account",
2017-04-15 09:07:27 -07:00
RunE: accountCmd,
}
BlockCmd = &cobra.Command{
Use: "block [height]",
Short: "Get the header and commit of a block",
2017-04-15 09:07:27 -07:00
RunE: blockCmd,
}
VerifyCmd = &cobra.Command{
Use: "verify",
Short: "Verify the IAVL proof",
2017-04-15 09:07:27 -07:00
RunE: verifyCmd,
}
)
//flags
var (
nodeFlag string
proofFlag string
keyFlag string
valueFlag string
rootFlag string
)
func init() {
commonFlags := []Flag2Register{
{&nodeFlag, "node", "tcp://localhost:46657", "Tendermint RPC address"},
}
verifyFlags := []Flag2Register{
{&proofFlag, "proof", "", "hex-encoded IAVL proof"},
{&keyFlag, "key", "", "key to the IAVL tree"},
{&valueFlag, "value", "", "value in the IAVL tree"},
{&rootFlag, "root", "", "root hash of the IAVL tree"},
}
RegisterFlags(QueryCmd, commonFlags)
RegisterFlags(AccountCmd, commonFlags)
RegisterFlags(BlockCmd, commonFlags)
RegisterFlags(VerifyCmd, verifyFlags)
2017-02-09 16:46:50 -08:00
}
2017-04-15 09:07:27 -07:00
func queryCmd(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
2017-04-15 09:07:27 -07:00
return fmt.Errorf("query command requires an argument ([key])") //never stack trace
2017-01-29 18:41:37 -08:00
}
keyString := args[0]
2017-01-29 18:41:37 -08:00
key := []byte(keyString)
if isHex(keyString) {
// convert key to bytes
var err error
2017-01-30 08:16:00 -08:00
key, err = hex.DecodeString(StripHex(keyString))
2017-01-29 18:41:37 -08:00
if err != nil {
2017-04-15 09:07:27 -07:00
return errors.Errorf("Query key (%v) is invalid hex: %v\n", keyString, err)
2017-01-29 18:41:37 -08:00
}
}
resp, err := Query(nodeFlag, key)
2017-01-29 18:41:37 -08:00
if err != nil {
2017-04-15 09:07:27 -07:00
return errors.Errorf("Query returns error: %v\n", err)
2017-01-29 18:41:37 -08:00
}
if !resp.Code.IsOK() {
2017-04-15 09:07:27 -07:00
return errors.Errorf("Query for key (%v) returned non-zero code (%v): %v", keyString, resp.Code, resp.Log)
2017-01-29 18:41:37 -08:00
}
val := resp.Value
proof := resp.Proof
height := resp.Height
out, err := json.Marshal(struct {
2017-01-29 18:41:37 -08:00
Value []byte `json:"value"`
Proof []byte `json:"proof"`
Height uint64 `json:"height"`
}{val, proof, height})
if err != nil {
return err
}
fmt.Println(string(out))
2017-04-15 09:07:27 -07:00
return nil
2017-01-29 18:41:37 -08:00
}
2017-04-15 09:07:27 -07:00
func accountCmd(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
2017-04-15 09:07:27 -07:00
return fmt.Errorf("account command requires an argument ([address])") //never stack trace
2017-01-29 18:41:37 -08:00
}
addrHex := StripHex(args[0])
2017-01-29 18:41:37 -08:00
// convert destination address to bytes
addr, err := hex.DecodeString(addrHex)
if err != nil {
2017-04-15 09:07:27 -07:00
return errors.Errorf("Account address (%v) is invalid hex: %v\n", addrHex, err)
2017-01-29 18:41:37 -08:00
}
2017-05-21 19:22:58 -07:00
httpClient := client.NewHTTP(nodeFlag, "/websocket")
acc, err := getAccWithClient(httpClient, addr)
2017-01-29 18:41:37 -08:00
if err != nil {
2017-04-15 09:07:27 -07:00
return err
2017-01-29 18:41:37 -08:00
}
out, err := json.Marshal(acc)
if err != nil {
return err
}
fmt.Println(string(out))
2017-04-15 09:07:27 -07:00
return nil
2017-01-29 18:41:37 -08:00
}
2017-04-15 09:07:27 -07:00
func blockCmd(cmd *cobra.Command, args []string) error {
if len(args) != 1 {
2017-04-15 09:07:27 -07:00
return fmt.Errorf("block command requires an argument ([height])") //never stack trace
2017-01-29 18:41:37 -08:00
}
heightString := args[0]
2017-01-29 18:41:37 -08:00
height, err := strconv.Atoi(heightString)
if err != nil {
2017-04-15 09:07:27 -07:00
return errors.Errorf("Height must be an int, got %v: %v\n", heightString, err)
2017-01-29 18:41:37 -08:00
}
header, commit, err := getHeaderAndCommit(nodeFlag, height)
2017-01-29 18:41:37 -08:00
if err != nil {
2017-04-15 09:07:27 -07:00
return err
2017-01-29 18:41:37 -08:00
}
out, err := json.Marshal(struct {
2017-01-29 18:41:37 -08:00
Hex BlockHex `json:"hex"`
JSON BlockJSON `json:"json"`
}{
BlockHex{
2017-02-13 20:22:31 -08:00
Header: wire.BinaryBytes(header),
Commit: wire.BinaryBytes(commit),
2017-01-29 18:41:37 -08:00
},
BlockJSON{
2017-02-13 20:22:31 -08:00
Header: header,
Commit: commit,
2017-01-29 18:41:37 -08:00
},
})
if err != nil {
return err
}
fmt.Println(string(out))
2017-04-15 09:07:27 -07:00
return nil
2017-01-29 18:41:37 -08:00
}
type BlockHex struct {
Header []byte `json:"header"`
Commit []byte `json:"commit"`
}
type BlockJSON struct {
Header *tmtypes.Header `json:"header"`
Commit *tmtypes.Commit `json:"commit"`
}
2017-01-29 19:45:21 -08:00
2017-04-15 09:07:27 -07:00
func verifyCmd(cmd *cobra.Command, args []string) error {
keyString, valueString := keyFlag, valueFlag
2017-01-29 19:45:21 -08:00
var err error
key := []byte(keyString)
if isHex(keyString) {
2017-01-30 08:16:00 -08:00
key, err = hex.DecodeString(StripHex(keyString))
2017-01-29 19:45:21 -08:00
if err != nil {
2017-04-15 09:07:27 -07:00
return errors.Errorf("Key (%v) is invalid hex: %v\n", keyString, err)
2017-01-29 19:45:21 -08:00
}
}
value := []byte(valueString)
if isHex(valueString) {
2017-01-30 08:16:00 -08:00
value, err = hex.DecodeString(StripHex(valueString))
2017-01-29 19:45:21 -08:00
if err != nil {
2017-04-15 09:07:27 -07:00
return errors.Errorf("Value (%v) is invalid hex: %v\n", valueString, err)
2017-01-29 19:45:21 -08:00
}
}
root, err := hex.DecodeString(StripHex(rootFlag))
2017-01-29 19:45:21 -08:00
if err != nil {
2017-04-15 09:07:27 -07:00
return errors.Errorf("Root (%v) is invalid hex: %v\n", rootFlag, err)
2017-01-29 19:45:21 -08:00
}
proofBytes, err := hex.DecodeString(StripHex(proofFlag))
2017-04-17 18:28:03 -07:00
if err != nil {
2017-04-17 23:50:23 -07:00
return errors.Errorf("Proof (%v) is invalid hex: %v\n", proofFlag, err)
2017-04-17 18:28:03 -07:00
}
2017-01-29 19:45:21 -08:00
2017-04-25 22:20:29 -07:00
proof, err := iavl.ReadProof(proofBytes)
2017-01-29 19:45:21 -08:00
if err != nil {
2017-04-15 09:07:27 -07:00
return errors.Errorf("Error unmarshalling proof: %v\n", err)
2017-01-29 19:45:21 -08:00
}
if proof.Verify(key, value, root) {
fmt.Println("OK")
} else {
2017-04-15 09:07:27 -07:00
return errors.New("Proof does not verify")
2017-01-29 19:45:21 -08:00
}
2017-04-15 09:07:27 -07:00
return nil
2017-01-29 19:45:21 -08:00
}