Use Get/GetParsed everywhere
This commit is contained in:
parent
391380bef2
commit
831c9ae3ec
|
@ -12,59 +12,81 @@ import (
|
|||
"github.com/tendermint/go-wire/data"
|
||||
lc "github.com/tendermint/light-client"
|
||||
"github.com/tendermint/light-client/proofs"
|
||||
"github.com/tendermint/merkleeyes/iavl"
|
||||
"github.com/tendermint/tendermint/rpc/client"
|
||||
|
||||
"github.com/tendermint/basecoin/client/commands"
|
||||
)
|
||||
|
||||
// GetAndParseAppProof does most of the work of the query commands, but is quite
|
||||
// opinionated, so if you want more control, set up the items and call GetProof
|
||||
// Get does most of the work of the query commands, but is quite
|
||||
// opinionated, so if you want more control, set up the items and call Get
|
||||
// directly. Notably, it always uses go-wire.ReadBinaryBytes to deserialize,
|
||||
// and Height and Node from standard flags.
|
||||
//
|
||||
// It will try to get the proof for the given key. If it is successful,
|
||||
// it will return the proof and also unserialize proof.Data into the data
|
||||
// argument (so pass in a pointer to the appropriate struct)
|
||||
func GetAndParseAppProof(key []byte, data interface{}) (lc.Proof, error) {
|
||||
height := GetHeight()
|
||||
node := commands.GetNode()
|
||||
|
||||
prover := proofs.NewAppProver(node)
|
||||
|
||||
proof, err := GetProof(node, prover, key, height)
|
||||
func GetParsed(key []byte, data interface{}, prove bool) (uint64, error) {
|
||||
bs, h, err := Get(key, prove)
|
||||
if err != nil {
|
||||
return proof, err
|
||||
return 0, err
|
||||
}
|
||||
|
||||
err = wire.ReadBinaryBytes(proof.Data(), data)
|
||||
return proof, err
|
||||
err = wire.ReadBinaryBytes(bs, data)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return h, nil
|
||||
}
|
||||
|
||||
// GetProof performs the get command directly from the proof (not from the CLI)
|
||||
func GetProof(node client.Client, prover lc.Prover, key []byte, height int) (proof lc.Proof, err error) {
|
||||
proof, err = prover.Get(key, uint64(height))
|
||||
func Get(key []byte, prove bool) (data.Bytes, uint64, error) {
|
||||
if !prove {
|
||||
node := commands.GetNode()
|
||||
resp, err := node.ABCIQuery("/key", key, false)
|
||||
return data.Bytes(resp.Value), resp.Height, err
|
||||
}
|
||||
val, h, _, err := GetWithProof(key)
|
||||
return val, h, err
|
||||
}
|
||||
|
||||
func GetWithProof(key []byte) (data.Bytes, uint64, *iavl.KeyExistsProof, error) {
|
||||
node := commands.GetNode()
|
||||
|
||||
resp, err := node.ABCIQuery("/key", key, true)
|
||||
if err != nil {
|
||||
return
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
ph := int(resp.Height)
|
||||
|
||||
// make sure the proof is the proper height
|
||||
if !resp.Code.IsOK() {
|
||||
return nil, 0, nil, errors.Errorf("Query error %d: %s", resp.Code, resp.Code.String())
|
||||
}
|
||||
// TODO: Handle null proofs
|
||||
if len(resp.Key) == 0 || len(resp.Value) == 0 || len(resp.Proof) == 0 {
|
||||
return nil, 0, nil, lc.ErrNoData()
|
||||
}
|
||||
if ph != 0 && ph != int(resp.Height) {
|
||||
return nil, 0, nil, lc.ErrHeightMismatch(ph, int(resp.Height))
|
||||
}
|
||||
|
||||
// short-circuit with no proofs
|
||||
if viper.GetBool(commands.FlagTrustNode) {
|
||||
return proof, err
|
||||
}
|
||||
|
||||
ph := int(proof.BlockHeight())
|
||||
check, err := GetCertifiedCheckpoint(ph)
|
||||
if err != nil {
|
||||
return
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
|
||||
proof := new(iavl.KeyExistsProof)
|
||||
err = wire.ReadBinaryBytes(resp.Proof, &proof)
|
||||
if err != nil {
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
|
||||
// validate the proof against the certified header to ensure data integrity
|
||||
err = proof.Validate(check)
|
||||
err = proof.Verify(resp.Key, resp.Value, check.Header.AppHash)
|
||||
if err != nil {
|
||||
return
|
||||
return nil, 0, nil, err
|
||||
}
|
||||
|
||||
return proof, err
|
||||
return data.Bytes(resp.Value), resp.Height, proof, nil
|
||||
}
|
||||
|
||||
// GetCertifiedCheckpoint gets the signed header for a given height
|
||||
|
|
|
@ -1,15 +1,9 @@
|
|||
package proofs
|
||||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
wire "github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
lc "github.com/tendermint/light-client"
|
||||
"github.com/tendermint/merkleeyes/iavl"
|
||||
|
||||
"github.com/tendermint/basecoin/client/commands"
|
||||
)
|
||||
|
||||
|
@ -32,56 +26,11 @@ func keyQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
prove := viper.GetBool(commands.FlagTrustNode)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
|
||||
// get the proof -> this will be used by all prover commands
|
||||
node := commands.GetNode()
|
||||
|
||||
////////////////
|
||||
resp, err := node.ABCIQuery("/key", key, prove)
|
||||
val, h, err := Get(key, prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ph := int(resp.Height)
|
||||
|
||||
// short-circuit with no proofs
|
||||
if !prove {
|
||||
return OutputProof(data.Bytes(resp.Value), resp.Height)
|
||||
}
|
||||
|
||||
// make sure the proof is the proper height
|
||||
if !resp.Code.IsOK() {
|
||||
return errors.Errorf("Query error %d: %s", resp.Code, resp.Code.String())
|
||||
}
|
||||
// TODO: Handle null proofs
|
||||
if len(resp.Key) == 0 || len(resp.Value) == 0 || len(resp.Proof) == 0 {
|
||||
return lc.ErrNoData()
|
||||
}
|
||||
if ph != 0 && ph != int(resp.Height) {
|
||||
return lc.ErrHeightMismatch(ph, int(resp.Height))
|
||||
}
|
||||
|
||||
check, err := GetCertifiedCheckpoint(ph)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
proof := new(iavl.KeyExistsProof)
|
||||
err = wire.ReadBinaryBytes(resp.Proof, &proof)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// validate the proof against the certified header to ensure data integrity
|
||||
err = proof.Verify(resp.Key, resp.Value, check.Header.AppHash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// state just returns raw hex....
|
||||
info := data.Bytes(resp.Value)
|
||||
|
||||
// we can reuse this output for other commands for text/json
|
||||
// unless they do something special like store a file to disk
|
||||
return OutputProof(info, resp.Height)
|
||||
return OutputProof(val, h)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package commands
|
|||
import (
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
lc "github.com/tendermint/light-client"
|
||||
|
||||
|
@ -32,12 +33,13 @@ func accountQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
key := stack.PrefixedKey(coin.NameCoin, act.Bytes())
|
||||
|
||||
acc := coin.Account{}
|
||||
proof, err := proofcmd.GetAndParseAppProof(key, &acc)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
height, err := proofcmd.GetParsed(key, &acc, prove)
|
||||
if lc.IsNoDataErr(err) {
|
||||
return errors.Errorf("Account bytes are empty for address %s ", addr)
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return proofcmd.OutputProof(acc, proof.BlockHeight())
|
||||
return proofcmd.OutputProof(acc, height)
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/tendermint/basecoin"
|
||||
"github.com/tendermint/basecoin/client/commands"
|
||||
|
@ -47,7 +48,8 @@ func doQueryAccount(w http.ResponseWriter, r *http.Request) {
|
|||
actor = coin.ChainAddr(actor)
|
||||
key := stack.PrefixedKey(coin.NameCoin, actor.Bytes())
|
||||
account := new(coin.Account)
|
||||
proof, err := proofs.GetAndParseAppProof(key, account)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
height, err := proofs.GetParsed(key, account, prove)
|
||||
if lightclient.IsNoDataErr(err) {
|
||||
err := fmt.Errorf("account bytes are empty for address: %q", signature)
|
||||
common.WriteError(w, err)
|
||||
|
@ -57,7 +59,7 @@ func doQueryAccount(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err := proofs.FoutputProof(w, account, proof.BlockHeight()); err != nil {
|
||||
if err := proofs.FoutputProof(w, account, height); err != nil {
|
||||
common.WriteError(w, err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,6 @@ import (
|
|||
"github.com/tendermint/basecoin/modules/ibc"
|
||||
"github.com/tendermint/basecoin/stack"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
"github.com/tendermint/light-client/proofs"
|
||||
"github.com/tendermint/merkleeyes/iavl"
|
||||
)
|
||||
|
||||
// TODO: query seeds (register/update)
|
||||
|
@ -86,17 +84,19 @@ func init() {
|
|||
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)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
h, err := proofcmd.GetParsed(key, &res, prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return proofcmd.OutputProof(res, proof.BlockHeight())
|
||||
return proofcmd.OutputProof(res, h)
|
||||
}
|
||||
|
||||
func chainsQueryCmd(cmd *cobra.Command, args []string) error {
|
||||
list := [][]byte{}
|
||||
key := stack.PrefixedKey(ibc.NameIBC, ibc.ChainsKey())
|
||||
proof, err := proofcmd.GetAndParseAppProof(key, &list)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
h, err := proofcmd.GetParsed(key, &list, prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -107,7 +107,7 @@ func chainsQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
res[i] = string(list[i])
|
||||
}
|
||||
|
||||
return proofcmd.OutputProof(res, proof.BlockHeight())
|
||||
return proofcmd.OutputProof(res, h)
|
||||
}
|
||||
|
||||
func chainQueryCmd(cmd *cobra.Command, args []string) error {
|
||||
|
@ -118,12 +118,13 @@ func chainQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
|
||||
var res ibc.ChainInfo
|
||||
key := stack.PrefixedKey(ibc.NameIBC, ibc.ChainKey(arg))
|
||||
proof, err := proofcmd.GetAndParseAppProof(key, &res)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
h, err := proofcmd.GetParsed(key, &res, prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return proofcmd.OutputProof(res, proof.BlockHeight())
|
||||
return proofcmd.OutputProof(res, h)
|
||||
}
|
||||
|
||||
func assertOne(from, to string) error {
|
||||
|
@ -154,12 +155,13 @@ func packetsQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
var res uint64
|
||||
proof, err := proofcmd.GetAndParseAppProof(key, &res)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
h, err := proofcmd.GetParsed(key, &res, prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return proofcmd.OutputProof(res, proof.BlockHeight())
|
||||
return proofcmd.OutputProof(res, h)
|
||||
}
|
||||
|
||||
func packetQueryCmd(cmd *cobra.Command, args []string) error {
|
||||
|
@ -174,6 +176,7 @@ func packetQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
if seq < 0 {
|
||||
return errors.Errorf("--%s must be a non-negative number", FlagSequence)
|
||||
}
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
|
||||
var key []byte
|
||||
if from != "" {
|
||||
|
@ -185,24 +188,16 @@ func packetQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
// Input queue just display the results
|
||||
if from != "" {
|
||||
var packet ibc.Packet
|
||||
proof, err := proofcmd.GetAndParseAppProof(key, &packet)
|
||||
h, err := proofcmd.GetParsed(key, &packet, prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return proofcmd.OutputProof(packet, proof.BlockHeight())
|
||||
return proofcmd.OutputProof(packet, h)
|
||||
}
|
||||
|
||||
// output queue, create a post packet
|
||||
var packet ibc.Packet
|
||||
proof, err := proofcmd.GetAndParseAppProof(key, &packet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// TODO: oh so ugly. fix before merge!
|
||||
// wait, i want to change go-merkle too....
|
||||
appProof := proof.(proofs.AppProof)
|
||||
extractedProof, err := iavl.ReadProof(appProof.Proof)
|
||||
bs, height, proof, err := proofcmd.GetWithProof(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -210,10 +205,10 @@ func packetQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
// create the post packet here.
|
||||
post := ibc.PostPacketTx{
|
||||
FromChainID: commands.GetChainID(),
|
||||
FromChainHeight: proof.BlockHeight(),
|
||||
FromChainHeight: height,
|
||||
Key: key,
|
||||
Packet: packet,
|
||||
Proof: extractedProof,
|
||||
Proof: proof,
|
||||
}
|
||||
|
||||
// print json direct, as we don't need to wrap with the height
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
lc "github.com/tendermint/light-client"
|
||||
|
||||
|
@ -33,23 +34,21 @@ func nonceQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
seq, proof, err := doNonceQuery(signers)
|
||||
seq, height, err := doNonceQuery(signers)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return proofcmd.OutputProof(seq, proof.BlockHeight())
|
||||
return proofcmd.OutputProof(seq, height)
|
||||
}
|
||||
|
||||
func doNonceQuery(signers []basecoin.Actor) (sequence uint32, proof lc.Proof, err error) {
|
||||
|
||||
func doNonceQuery(signers []basecoin.Actor) (sequence uint32, height uint64, err error) {
|
||||
key := stack.PrefixedKey(nonce.NameNonce, nonce.GetSeqKey(signers))
|
||||
|
||||
proof, err = proofcmd.GetAndParseAppProof(key, &sequence)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
height, err = proofcmd.GetParsed(key, &sequence, prove)
|
||||
if lc.IsNoDataErr(err) {
|
||||
// no data, return sequence 0
|
||||
return 0, proof, nil
|
||||
return 0, 0, nil
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package commands
|
|||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/tendermint/basecoin/client/commands"
|
||||
proofcmd "github.com/tendermint/basecoin/client/commands/proofs"
|
||||
|
@ -28,10 +29,11 @@ func roleQueryCmd(cmd *cobra.Command, args []string) error {
|
|||
|
||||
var res roles.Role
|
||||
key := stack.PrefixedKey(roles.NameRole, role)
|
||||
proof, err := proofcmd.GetAndParseAppProof(key, &res)
|
||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||
height, err := proofcmd.GetParsed(key, &res, prove)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return proofcmd.OutputProof(res, proof.BlockHeight())
|
||||
return proofcmd.OutputProof(res, height)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue