Expose height flag in all queries
This commit is contained in:
parent
3b7020520c
commit
c4ead8b8a3
|
@ -146,11 +146,12 @@ func (app *StoreApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQu
|
||||||
// we must retrun most recent, even if apphash
|
// we must retrun most recent, even if apphash
|
||||||
// is not yet in the blockchain
|
// is not yet in the blockchain
|
||||||
|
|
||||||
// if tree.Tree.VersionExists(app.height - 1) {
|
withProof := app.CommittedHeight() - 1
|
||||||
// height = app.height - 1
|
if tree.Tree.VersionExists(withProof) {
|
||||||
// } else {
|
height = withProof
|
||||||
|
} else {
|
||||||
height = app.CommittedHeight()
|
height = app.CommittedHeight()
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
resQuery.Height = height
|
resQuery.Height = height
|
||||||
|
|
||||||
|
|
|
@ -25,8 +25,8 @@ import (
|
||||||
// It will try to get the proof for the given key. If it is successful,
|
// It will try to get the proof for the given key. If it is successful,
|
||||||
// it will return the height and also unserialize proof.Data into the data
|
// it will return the height and also unserialize proof.Data into the data
|
||||||
// argument (so pass in a pointer to the appropriate struct)
|
// argument (so pass in a pointer to the appropriate struct)
|
||||||
func GetParsed(key []byte, data interface{}, prove bool) (uint64, error) {
|
func GetParsed(key []byte, data interface{}, height int, prove bool) (uint64, error) {
|
||||||
bs, h, err := Get(key, prove)
|
bs, h, err := Get(key, height, prove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
@ -45,27 +45,31 @@ func GetParsed(key []byte, data interface{}, prove bool) (uint64, error) {
|
||||||
// we just repeat whatever any (potentially malicious) node gives us.
|
// we just repeat whatever any (potentially malicious) node gives us.
|
||||||
// Only use that if you are running the full node yourself,
|
// Only use that if you are running the full node yourself,
|
||||||
// and it is localhost or you have a secure connection (not HTTP)
|
// and it is localhost or you have a secure connection (not HTTP)
|
||||||
func Get(key []byte, prove bool) (data.Bytes, uint64, error) {
|
func Get(key []byte, height int, prove bool) (data.Bytes, uint64, error) {
|
||||||
|
if height < 0 {
|
||||||
|
return nil, 0, fmt.Errorf("Height cannot be negative")
|
||||||
|
}
|
||||||
|
|
||||||
if !prove {
|
if !prove {
|
||||||
node := commands.GetNode()
|
node := commands.GetNode()
|
||||||
resp, err := node.ABCIQueryWithOptions("/key", key,
|
resp, err := node.ABCIQueryWithOptions("/key", key,
|
||||||
rpcclient.ABCIQueryOptions{Trusted: true})
|
rpcclient.ABCIQueryOptions{Trusted: true, Height: uint64(height)})
|
||||||
return data.Bytes(resp.Value), resp.Height, err
|
return data.Bytes(resp.Value), resp.Height, err
|
||||||
}
|
}
|
||||||
val, h, _, err := GetWithProof(key)
|
val, h, _, err := GetWithProof(key, height)
|
||||||
return val, h, err
|
return val, h, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWithProof returns the values stored under a given key at the named
|
// GetWithProof returns the values stored under a given key at the named
|
||||||
// height as in Get. Additionally, it will return a validated merkle
|
// height as in Get. Additionally, it will return a validated merkle
|
||||||
// proof for the key-value pair if it exists, and all checks pass.
|
// proof for the key-value pair if it exists, and all checks pass.
|
||||||
func GetWithProof(key []byte) (data.Bytes, uint64, iavl.KeyProof, error) {
|
func GetWithProof(key []byte, height int) (data.Bytes, uint64, iavl.KeyProof, error) {
|
||||||
node := commands.GetNode()
|
node := commands.GetNode()
|
||||||
cert, err := commands.GetCertifier()
|
cert, err := commands.GetCertifier()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, 0, nil, err
|
return nil, 0, nil, err
|
||||||
}
|
}
|
||||||
return client.GetWithProof(key, node, cert)
|
return client.GetWithProof(key, height, node, cert)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ParseHexKey parses the key flag as hex and converts to bytes or returns error
|
// ParseHexKey parses the key flag as hex and converts to bytes or returns error
|
||||||
|
|
|
@ -28,7 +28,7 @@ func keyQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
|
|
||||||
val, h, err := Get(key, prove)
|
val, h, err := Get(key, GetHeight(), prove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,17 @@ import (
|
||||||
// If there is any error in checking, returns an error.
|
// If there is any error in checking, returns an error.
|
||||||
// If val is non-empty, proof should be KeyExistsProof
|
// If val is non-empty, proof should be KeyExistsProof
|
||||||
// If val is empty, proof should be KeyMissingProof
|
// If val is empty, proof should be KeyMissingProof
|
||||||
func GetWithProof(key []byte, node client.Client, cert certifiers.Certifier) (
|
func GetWithProof(key []byte, reqHeight int, node client.Client,
|
||||||
|
cert certifiers.Certifier) (
|
||||||
val data.Bytes, height uint64, proof iavl.KeyProof, err error) {
|
val data.Bytes, height uint64, proof iavl.KeyProof, err error) {
|
||||||
|
|
||||||
resp, err := node.ABCIQuery("/key", key)
|
if reqHeight < 0 {
|
||||||
|
err = errors.Errorf("Height cannot be negative")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := node.ABCIQueryWithOptions("/key", key,
|
||||||
|
client.ABCIQueryOptions{Height: uint64(reqHeight)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,7 @@ func TestAppProofs(t *testing.T) {
|
||||||
require.NoError(err, "%+v", err)
|
require.NoError(err, "%+v", err)
|
||||||
require.EqualValues(0, br.CheckTx.Code, "%#v", br.CheckTx)
|
require.EqualValues(0, br.CheckTx.Code, "%#v", br.CheckTx)
|
||||||
require.EqualValues(0, br.DeliverTx.Code)
|
require.EqualValues(0, br.DeliverTx.Code)
|
||||||
|
brh := br.Height
|
||||||
|
|
||||||
// This sets up our trust on the node based on some past point.
|
// This sets up our trust on the node based on some past point.
|
||||||
source := certclient.New(cl)
|
source := certclient.New(cl)
|
||||||
|
@ -71,7 +72,14 @@ func TestAppProofs(t *testing.T) {
|
||||||
// Test existing key.
|
// Test existing key.
|
||||||
var data eyes.Data
|
var data eyes.Data
|
||||||
|
|
||||||
bs, height, proof, err := GetWithProof(k, cl, cert)
|
// verify a query before the tx block has no data (and valid non-exist proof)
|
||||||
|
bs, height, proof, err := GetWithProof(k, brh-1, cl, cert)
|
||||||
|
require.NotNil(err)
|
||||||
|
require.True(lc.IsNoDataErr(err))
|
||||||
|
require.Nil(bs)
|
||||||
|
|
||||||
|
// but given that block it is good
|
||||||
|
bs, height, proof, err = GetWithProof(k, brh, cl, cert)
|
||||||
require.NoError(err, "%+v", err)
|
require.NoError(err, "%+v", err)
|
||||||
require.NotNil(proof)
|
require.NotNil(proof)
|
||||||
require.True(height >= uint64(latest.Header.Height))
|
require.True(height >= uint64(latest.Header.Height))
|
||||||
|
@ -89,7 +97,7 @@ func TestAppProofs(t *testing.T) {
|
||||||
|
|
||||||
// Test non-existing key.
|
// Test non-existing key.
|
||||||
missing := []byte("my-missing-key")
|
missing := []byte("my-missing-key")
|
||||||
bs, _, proof, err = GetWithProof(missing, cl, cert)
|
bs, _, proof, err = GetWithProof(missing, 0, cl, cert)
|
||||||
require.True(lc.IsNoDataErr(err))
|
require.True(lc.IsNoDataErr(err))
|
||||||
require.Nil(bs)
|
require.Nil(bs)
|
||||||
require.NotNil(proof)
|
require.NotNil(proof)
|
||||||
|
|
|
@ -23,7 +23,7 @@ func counterQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
key := stack.PrefixedKey(counter.NameCounter, counter.StateKey())
|
key := stack.PrefixedKey(counter.NameCounter, counter.StateKey())
|
||||||
h, err := query.GetParsed(key, &cp, prove)
|
h, err := query.GetParsed(key, &cp, query.GetHeight(), prove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@ func accountQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
acc := coin.Account{}
|
acc := coin.Account{}
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
height, err := query.GetParsed(key, &acc, prove)
|
height, err := query.GetParsed(key, &acc, query.GetHeight(), prove)
|
||||||
if lc.IsNoDataErr(err) {
|
if lc.IsNoDataErr(err) {
|
||||||
return errors.Errorf("Account bytes are empty for address %s ", addr)
|
return errors.Errorf("Account bytes are empty for address %s ", addr)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
|
|
@ -3,6 +3,7 @@ package rest
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
@ -45,11 +46,22 @@ func doQueryAccount(w http.ResponseWriter, r *http.Request) {
|
||||||
common.WriteError(w, err)
|
common.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var h int
|
||||||
|
qHeight := args["height"]
|
||||||
|
if qHeight != "" {
|
||||||
|
h, err = strconv.Atoi(qHeight)
|
||||||
|
if err != nil {
|
||||||
|
common.WriteError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
actor = coin.ChainAddr(actor)
|
actor = coin.ChainAddr(actor)
|
||||||
key := stack.PrefixedKey(coin.NameCoin, actor.Bytes())
|
key := stack.PrefixedKey(coin.NameCoin, actor.Bytes())
|
||||||
account := new(coin.Account)
|
account := new(coin.Account)
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
height, err := query.GetParsed(key, account, prove)
|
height, err := query.GetParsed(key, account, h, prove)
|
||||||
if lightclient.IsNoDataErr(err) {
|
if lightclient.IsNoDataErr(err) {
|
||||||
err := fmt.Errorf("account bytes are empty for address: %q", signature)
|
err := fmt.Errorf("account bytes are empty for address: %q", signature)
|
||||||
common.WriteError(w, err)
|
common.WriteError(w, err)
|
||||||
|
@ -152,4 +164,3 @@ func RegisterAll(r *mux.Router) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// End of mux.Router registrars
|
// End of mux.Router registrars
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ func eyesQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
key = stack.PrefixedKey(eyes.Name, key)
|
key = stack.PrefixedKey(eyes.Name, key)
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
height, err := query.GetParsed(key, &res, prove)
|
height, err := query.GetParsed(key, &res, query.GetHeight(), prove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ func ibcQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
var res ibc.HandlerInfo
|
var res ibc.HandlerInfo
|
||||||
key := stack.PrefixedKey(ibc.NameIBC, ibc.HandlerKey())
|
key := stack.PrefixedKey(ibc.NameIBC, ibc.HandlerKey())
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
h, err := query.GetParsed(key, &res, prove)
|
h, err := query.GetParsed(key, &res, query.GetHeight(), prove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ func chainsQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
list := [][]byte{}
|
list := [][]byte{}
|
||||||
key := stack.PrefixedKey(ibc.NameIBC, ibc.ChainsKey())
|
key := stack.PrefixedKey(ibc.NameIBC, ibc.ChainsKey())
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
h, err := query.GetParsed(key, &list, prove)
|
h, err := query.GetParsed(key, &list, query.GetHeight(), prove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -121,7 +121,7 @@ func chainQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
var res ibc.ChainInfo
|
var res ibc.ChainInfo
|
||||||
key := stack.PrefixedKey(ibc.NameIBC, ibc.ChainKey(arg))
|
key := stack.PrefixedKey(ibc.NameIBC, ibc.ChainKey(arg))
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
h, err := query.GetParsed(key, &res, prove)
|
h, err := query.GetParsed(key, &res, query.GetHeight(), prove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ func packetsQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
var res uint64
|
var res uint64
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
h, err := query.GetParsed(key, &res, prove)
|
h, err := query.GetParsed(key, &res, query.GetHeight(), prove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -190,7 +190,7 @@ func packetQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
// Input queue just display the results
|
// Input queue just display the results
|
||||||
var packet ibc.Packet
|
var packet ibc.Packet
|
||||||
if from != "" {
|
if from != "" {
|
||||||
h, err := query.GetParsed(key, &packet, prove)
|
h, err := query.GetParsed(key, &packet, query.GetHeight(), prove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ func packetQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// output queue, create a post packet
|
// output queue, create a post packet
|
||||||
bs, height, proof, err := query.GetWithProof(key)
|
bs, height, proof, err := query.GetWithProof(key, query.GetHeight())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ func nonceQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
func doNonceQuery(signers []sdk.Actor) (sequence uint32, height uint64, err error) {
|
func doNonceQuery(signers []sdk.Actor) (sequence uint32, height uint64, err error) {
|
||||||
key := stack.PrefixedKey(nonce.NameNonce, nonce.GetSeqKey(signers))
|
key := stack.PrefixedKey(nonce.NameNonce, nonce.GetSeqKey(signers))
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
height, err = query.GetParsed(key, &sequence, prove)
|
height, err = query.GetParsed(key, &sequence, query.GetHeight(), prove)
|
||||||
if lc.IsNoDataErr(err) {
|
if lc.IsNoDataErr(err) {
|
||||||
// no data, return sequence 0
|
// no data, return sequence 0
|
||||||
return 0, 0, nil
|
return 0, 0, nil
|
||||||
|
|
|
@ -3,6 +3,7 @@ package rest
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
|
@ -28,6 +29,17 @@ func doQueryNonce(w http.ResponseWriter, r *http.Request) {
|
||||||
common.WriteError(w, err)
|
common.WriteError(w, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var h int
|
||||||
|
qHeight := args["height"]
|
||||||
|
if qHeight != "" {
|
||||||
|
h, err = strconv.Atoi(qHeight)
|
||||||
|
if err != nil {
|
||||||
|
common.WriteError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
actor = coin.ChainAddr(actor)
|
actor = coin.ChainAddr(actor)
|
||||||
key := nonce.GetSeqKey([]sdk.Actor{actor})
|
key := nonce.GetSeqKey([]sdk.Actor{actor})
|
||||||
key = stack.PrefixedKey(nonce.NameNonce, key)
|
key = stack.PrefixedKey(nonce.NameNonce, key)
|
||||||
|
@ -35,7 +47,7 @@ func doQueryNonce(w http.ResponseWriter, r *http.Request) {
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
|
|
||||||
// query sequence number
|
// query sequence number
|
||||||
data, height, err := query.Get(key, prove)
|
data, height, err := query.Get(key, h, prove)
|
||||||
if lightclient.IsNoDataErr(err) {
|
if lightclient.IsNoDataErr(err) {
|
||||||
err = fmt.Errorf("nonce empty for address: %q", signature)
|
err = fmt.Errorf("nonce empty for address: %q", signature)
|
||||||
common.WriteError(w, err)
|
common.WriteError(w, err)
|
||||||
|
|
|
@ -30,7 +30,7 @@ func roleQueryCmd(cmd *cobra.Command, args []string) error {
|
||||||
var res roles.Role
|
var res roles.Role
|
||||||
key := stack.PrefixedKey(roles.NameRole, role)
|
key := stack.PrefixedKey(roles.NameRole, role)
|
||||||
prove := !viper.GetBool(commands.FlagTrustNode)
|
prove := !viper.GetBool(commands.FlagTrustNode)
|
||||||
height, err := query.GetParsed(key, &res, prove)
|
height, err := query.GetParsed(key, &res, query.GetHeight(), prove)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue