Everything compiles, test proof in dummy app

This commit is contained in:
Ethan Frey
2017-01-10 17:06:51 +01:00
parent 7cd39dafea
commit cfc3f24751
8 changed files with 63 additions and 22 deletions

View File

@ -21,7 +21,7 @@ type Client interface {
DeliverTxAsync(tx []byte) *ReqRes DeliverTxAsync(tx []byte) *ReqRes
CheckTxAsync(tx []byte) *ReqRes CheckTxAsync(tx []byte) *ReqRes
QueryAsync(tx []byte) *ReqRes QueryAsync(tx []byte) *ReqRes
ProofAsync(tx []byte) *ReqRes ProofAsync(key []byte, blockHeight int64) *ReqRes
CommitAsync() *ReqRes CommitAsync() *ReqRes
FlushSync() error FlushSync() error
@ -31,7 +31,7 @@ type Client interface {
DeliverTxSync(tx []byte) (res types.Result) DeliverTxSync(tx []byte) (res types.Result)
CheckTxSync(tx []byte) (res types.Result) CheckTxSync(tx []byte) (res types.Result)
QuerySync(tx []byte) (res types.Result) QuerySync(tx []byte) (res types.Result)
ProofSync(tx []byte) (res types.Result) ProofSync(key []byte, blockHeight int64) (res types.Result)
CommitSync() (res types.Result) CommitSync() (res types.Result)
InitChainAsync(validators []*types.Validator) *ReqRes InitChainAsync(validators []*types.Validator) *ReqRes

View File

@ -182,8 +182,8 @@ func (cli *grpcClient) QueryAsync(query []byte) *ReqRes {
return cli.finishAsyncCall(req, &types.Response{&types.Response_Query{res}}) return cli.finishAsyncCall(req, &types.Response{&types.Response_Query{res}})
} }
func (cli *grpcClient) ProofAsync(key []byte) *ReqRes { func (cli *grpcClient) ProofAsync(key []byte, blockHeight int64) *ReqRes {
req := types.ToRequestProof(key) req := types.ToRequestProof(key, blockHeight)
res, err := cli.client.Proof(context.Background(), req.GetProof(), grpc.FailFast(true)) res, err := cli.client.Proof(context.Background(), req.GetProof(), grpc.FailFast(true))
if err != nil { if err != nil {
cli.StopForError(err) cli.StopForError(err)
@ -310,8 +310,8 @@ func (cli *grpcClient) CheckTxSync(tx []byte) (res types.Result) {
return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log} return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log}
} }
func (cli *grpcClient) ProofSync(key []byte) (res types.Result) { func (cli *grpcClient) ProofSync(key []byte, blockHeight int64) (res types.Result) {
reqres := cli.ProofAsync(key) reqres := cli.ProofAsync(key, blockHeight)
if res := cli.checkErrGetResult(); res.IsErr() { if res := cli.checkErrGetResult(); res.IsErr() {
return res return res
} }

View File

@ -99,12 +99,12 @@ func (app *localClient) QueryAsync(tx []byte) *ReqRes {
) )
} }
func (app *localClient) ProofAsync(key []byte) *ReqRes { func (app *localClient) ProofAsync(key []byte, blockHeight int64) *ReqRes {
app.mtx.Lock() app.mtx.Lock()
res := app.Application.Proof(key) res := app.Application.Proof(key, blockHeight)
app.mtx.Unlock() app.mtx.Unlock()
return app.callback( return app.callback(
types.ToRequestProof(key), types.ToRequestProof(key, blockHeight),
types.ToResponseQuery(res.Code, res.Data, res.Log), types.ToResponseQuery(res.Code, res.Data, res.Log),
) )
} }
@ -202,9 +202,9 @@ func (app *localClient) QuerySync(query []byte) (res types.Result) {
return res return res
} }
func (app *localClient) ProofSync(key []byte) (res types.Result) { func (app *localClient) ProofSync(key []byte, blockHeight int64) (res types.Result) {
app.mtx.Lock() app.mtx.Lock()
res = app.Application.Proof(key) res = app.Application.Proof(key, blockHeight)
app.mtx.Unlock() app.mtx.Unlock()
return res return res
} }

View File

@ -255,8 +255,8 @@ func (cli *socketClient) QueryAsync(query []byte) *ReqRes {
return cli.queueRequest(types.ToRequestQuery(query)) return cli.queueRequest(types.ToRequestQuery(query))
} }
func (cli *socketClient) ProofAsync(key []byte) *ReqRes { func (cli *socketClient) ProofAsync(key []byte, blockHeight int64) *ReqRes {
return cli.queueRequest(types.ToRequestProof(key)) return cli.queueRequest(types.ToRequestProof(key, blockHeight))
} }
func (cli *socketClient) CommitAsync() *ReqRes { func (cli *socketClient) CommitAsync() *ReqRes {
@ -349,8 +349,8 @@ func (cli *socketClient) QuerySync(query []byte) (res types.Result) {
return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log} return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log}
} }
func (cli *socketClient) ProofSync(key []byte) (res types.Result) { func (cli *socketClient) ProofSync(key []byte, blockHeight int64) (res types.Result) {
reqres := cli.queueRequest(types.ToRequestProof(key)) reqres := cli.queueRequest(types.ToRequestProof(key, blockHeight))
cli.FlushSync() cli.FlushSync()
if err := cli.Error(); err != nil { if err := cli.Error(); err != nil {
return types.ErrInternalError.SetLog(err.Error()) return types.ErrInternalError.SetLog(err.Error())

View File

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"io" "io"
"os" "os"
"strconv"
"strings" "strings"
"github.com/tendermint/abci/client" "github.com/tendermint/abci/client"
@ -315,12 +316,21 @@ func cmdQuery(c *cli.Context) error {
// Prove application state // Prove application state
func cmdProof(c *cli.Context) error { func cmdProof(c *cli.Context) error {
args := c.Args() args := c.Args()
if len(args) != 1 { if len(args) < 1 {
return errors.New("Command proof takes 1 argument") return errors.New("Command proof takes 1 or 2 arguments")
} }
keyBytes := stringOrHexToBytes(c.Args()[0]) keyBytes, err := stringOrHexToBytes(c.Args()[0])
res := client.ProofSync(keyBytes) if err != nil {
printResponse(c, res, string(res.Data), true) return err
}
var height int64
if len(args) == 2 {
height, _ = strconv.ParseInt(args[1], 10, 0)
}
res := client.ProofSync(keyBytes, height)
rsp := newResponse(res, string(res.Data), true)
printResponse(c, rsp)
return nil return nil
} }

View File

@ -2,6 +2,7 @@ package dummy
import ( import (
"encoding/hex" "encoding/hex"
"fmt"
"strings" "strings"
"github.com/tendermint/abci/types" "github.com/tendermint/abci/types"
@ -54,7 +55,15 @@ func (app *DummyApplication) Query(query []byte) types.Result {
} }
func (app *DummyApplication) Proof(key []byte, blockHeight int64) types.Result { func (app *DummyApplication) Proof(key []byte, blockHeight int64) types.Result {
return types.NewResultOK(nil, Fmt("TODO: support proof!")) if blockHeight != 0 {
return types.ErrUnknownRequest
}
proof, exists := app.state.Proof(key)
if !exists {
fmt.Println("Didn't find nothing")
return types.NewResultOK(nil, "")
}
return types.NewResultOK(proof, "Found the key")
} }
type QueryResult struct { type QueryResult struct {

View File

@ -8,6 +8,7 @@ import (
. "github.com/tendermint/go-common" . "github.com/tendermint/go-common"
"github.com/tendermint/go-crypto" "github.com/tendermint/go-crypto"
merkle "github.com/tendermint/go-merkle"
"github.com/tendermint/go-wire" "github.com/tendermint/go-wire"
"github.com/tendermint/abci/types" "github.com/tendermint/abci/types"
) )
@ -34,6 +35,27 @@ func testDummy(t *testing.T, dummy types.Application, tx []byte, key, value stri
t.Fatalf("Got %s, expected %s", q.Value, value) t.Fatalf("Got %s, expected %s", q.Value, value)
} }
rp := dummy.Proof([]byte(key), 0)
if rp.IsErr() {
t.Fatal(rp)
}
p, err := merkle.LoadProof(rp.Data)
if err != nil {
t.Fatal(err)
}
if !p.Valid() {
t.Fatal("Invalid proof")
}
if !bytes.Equal([]byte(key), p.Key()) {
t.Fatalf("Invalid key: %s", p.Key())
}
if !bytes.Equal([]byte(value), p.Value()) {
t.Fatalf("Invalid key: %s", p.Value())
}
} }
func TestDummyKV(t *testing.T) { func TestDummyKV(t *testing.T) {

View File

@ -94,7 +94,7 @@ func (app *PersistentDummyApplication) Query(query []byte) types.Result {
} }
func (app *PersistentDummyApplication) Proof(key []byte, blockHeight int64) types.Result { func (app *PersistentDummyApplication) Proof(key []byte, blockHeight int64) types.Result {
return types.NewResultOK(nil, Fmt("TODO: support proof!")) return app.app.Proof(key, blockHeight)
} }
// Save the validators in the merkle tree // Save the validators in the merkle tree