From 3421e4dcd7c6937e9ae8f72af17b38840840a781 Mon Sep 17 00:00:00 2001 From: zjubfd Date: Sun, 3 Mar 2019 05:36:52 +0800 Subject: [PATCH] make lightd availbe (#3364) 1."abci_query": rpcserver.NewRPCFunc(c.ABCIQuery, "path,data,prove") "validators": rpcserver.NewRPCFunc(c.Validators, "height"), the parameters and function do not match, cause index out of range error. 2. the prove of query is forced to be true, while default option is false. 3. fix the wrong key of merkle --- cmd/tendermint/commands/lite.go | 6 +++--- lite/proxy/proxy.go | 4 ++-- lite/proxy/query.go | 34 +++++++++++++++++++++++++++------ lite/proxy/wrapper.go | 4 ++++ 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/cmd/tendermint/commands/lite.go b/cmd/tendermint/commands/lite.go index 94259cb0b..d3a4ac53e 100644 --- a/cmd/tendermint/commands/lite.go +++ b/cmd/tendermint/commands/lite.go @@ -43,7 +43,7 @@ func init() { LiteCmd.Flags().IntVar(&cacheSize, "cache-size", 10, "Specify the memory trust store cache size") } -func ensureAddrHasSchemeOrDefaultToTCP(addr string) (string, error) { +func EnsureAddrHasSchemeOrDefaultToTCP(addr string) (string, error) { u, err := url.Parse(addr) if err != nil { return "", err @@ -64,11 +64,11 @@ func runProxy(cmd *cobra.Command, args []string) error { // TODO: close up shop }) - nodeAddr, err := ensureAddrHasSchemeOrDefaultToTCP(nodeAddr) + nodeAddr, err := EnsureAddrHasSchemeOrDefaultToTCP(nodeAddr) if err != nil { return err } - listenAddr, err := ensureAddrHasSchemeOrDefaultToTCP(listenAddr) + listenAddr, err := EnsureAddrHasSchemeOrDefaultToTCP(listenAddr) if err != nil { return err } diff --git a/lite/proxy/proxy.go b/lite/proxy/proxy.go index d7ffb27d0..39baf5a48 100644 --- a/lite/proxy/proxy.go +++ b/lite/proxy/proxy.go @@ -66,7 +66,7 @@ func RPCRoutes(c rpcclient.Client) map[string]*rpcserver.RPCFunc { "block": rpcserver.NewRPCFunc(c.Block, "height"), "commit": rpcserver.NewRPCFunc(c.Commit, "height"), "tx": rpcserver.NewRPCFunc(c.Tx, "hash,prove"), - "validators": rpcserver.NewRPCFunc(c.Validators, ""), + "validators": rpcserver.NewRPCFunc(c.Validators, "height"), // broadcast API "broadcast_tx_commit": rpcserver.NewRPCFunc(c.BroadcastTxCommit, "tx"), @@ -74,7 +74,7 @@ func RPCRoutes(c rpcclient.Client) map[string]*rpcserver.RPCFunc { "broadcast_tx_async": rpcserver.NewRPCFunc(c.BroadcastTxAsync, "tx"), // abci API - "abci_query": rpcserver.NewRPCFunc(c.ABCIQuery, "path,data,prove"), + "abci_query": rpcserver.NewRPCFunc(c.ABCIQuery, "path,data"), "abci_info": rpcserver.NewRPCFunc(c.ABCIInfo, ""), } } diff --git a/lite/proxy/query.go b/lite/proxy/query.go index 3acf826b8..fd10e0bb6 100644 --- a/lite/proxy/query.go +++ b/lite/proxy/query.go @@ -2,6 +2,7 @@ package proxy import ( "fmt" + "strings" cmn "github.com/tendermint/tendermint/libs/common" @@ -43,11 +44,7 @@ func GetWithProof(prt *merkle.ProofRuntime, key []byte, reqHeight int64, node rp func GetWithProofOptions(prt *merkle.ProofRuntime, path string, key []byte, opts rpcclient.ABCIQueryOptions, node rpcclient.Client, cert lite.Verifier) ( *ctypes.ResultABCIQuery, error) { - - if !opts.Prove { - return nil, cmn.NewError("require ABCIQueryOptions.Prove to be true") - } - + opts.Prove = true res, err := node.ABCIQueryWithOptions(path, key, opts) if err != nil { return nil, err @@ -77,7 +74,14 @@ func GetWithProofOptions(prt *merkle.ProofRuntime, path string, key []byte, opts if resp.Value != nil { // Value exists // XXX How do we encode the key into a string... - err = prt.VerifyValue(resp.Proof, signedHeader.AppHash, string(resp.Key), resp.Value) + storeName, err := parseQueryStorePath(path) + if err != nil { + return nil, err + } + kp := merkle.KeyPath{} + kp = kp.AppendKey([]byte(storeName), merkle.KeyEncodingURL) + kp = kp.AppendKey(resp.Key, merkle.KeyEncodingURL) + err = prt.VerifyValue(resp.Proof, signedHeader.AppHash, kp.String(), resp.Value) if err != nil { return nil, cmn.ErrorWrap(err, "Couldn't verify value proof") } @@ -94,6 +98,24 @@ func GetWithProofOptions(prt *merkle.ProofRuntime, path string, key []byte, opts } } +func parseQueryStorePath(path string) (storeName string, err error) { + if !strings.HasPrefix(path, "/") { + return "", fmt.Errorf("expected path to start with /") + } + + paths := strings.SplitN(path[1:], "/", 3) + switch { + case len(paths) != 3: + return "", fmt.Errorf("expected format like /store//key") + case paths[0] != "store": + return "", fmt.Errorf("expected format like /store//key") + case paths[2] != "key": + return "", fmt.Errorf("expected format like /store//key") + } + + return paths[1], nil +} + // GetCertifiedCommit gets the signed header for a given height and certifies // it. Returns error if unable to get a proven header. func GetCertifiedCommit(h int64, client rpcclient.Client, cert lite.Verifier) (types.SignedHeader, error) { diff --git a/lite/proxy/wrapper.go b/lite/proxy/wrapper.go index 7ddb3b8ad..c90cdb275 100644 --- a/lite/proxy/wrapper.go +++ b/lite/proxy/wrapper.go @@ -145,6 +145,10 @@ func (w Wrapper) Commit(height *int64) (*ctypes.ResultCommit, error) { return res, err } +func (w Wrapper) RegisterOpDecoder(typ string, dec merkle.OpDecoder) { + w.prt.RegisterOpDecoder(typ, dec) +} + // // WrappedSwitch creates a websocket connection that auto-verifies any info // // coming through before passing it along. // //