Browse Source

Begin adding proof calls

pull/1780/head
Ethan Frey 8 years ago
parent
commit
58ea995032
14 changed files with 131 additions and 2 deletions
  1. +2
    -0
      client/client.go
  2. +18
    -0
      client/grpc_client.go
  3. +17
    -0
      client/local_client.go
  4. +15
    -0
      client/socket_client.go
  5. +19
    -0
      cmd/abci-cli/tmsp-cli.go
  6. +4
    -0
      example/chain_aware/chain_aware_app.go
  7. +4
    -0
      example/counter/counter.go
  8. +4
    -0
      example/dummy/dummy.go
  9. +4
    -0
      example/dummy/persistent_dummy.go
  10. +4
    -0
      example/nil/nil_app.go
  11. +3
    -0
      server/socket_server.go
  12. +8
    -0
      types/application.go
  13. +12
    -0
      types/messages.go
  14. +17
    -2
      types/types.proto

+ 2
- 0
client/client.go View File

@ -21,6 +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
CommitAsync() *ReqRes CommitAsync() *ReqRes
FlushSync() error FlushSync() error
@ -30,6 +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)
CommitSync() (res types.Result) CommitSync() (res types.Result)
InitChainAsync(validators []*types.Validator) *ReqRes InitChainAsync(validators []*types.Validator) *ReqRes


+ 18
- 0
client/grpc_client.go View File

@ -182,6 +182,15 @@ 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 {
req := types.ToRequestProof(key)
res, err := cli.client.Proof(context.Background(), req.GetProof(), grpc.FailFast(true))
if err != nil {
cli.StopForError(err)
}
return cli.finishAsyncCall(req, &types.Response{&types.Response_Proof{res}})
}
func (cli *grpcClient) CommitAsync() *ReqRes { func (cli *grpcClient) CommitAsync() *ReqRes {
req := types.ToRequestCommit() req := types.ToRequestCommit()
res, err := cli.client.Commit(context.Background(), req.GetCommit(), grpc.FailFast(true)) res, err := cli.client.Commit(context.Background(), req.GetCommit(), grpc.FailFast(true))
@ -301,6 +310,15 @@ 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) {
reqres := cli.ProofAsync(key)
if res := cli.checkErrGetResult(); res.IsErr() {
return res
}
resp := reqres.Response.GetProof()
return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log}
}
func (cli *grpcClient) QuerySync(query []byte) (res types.Result) { func (cli *grpcClient) QuerySync(query []byte) (res types.Result) {
reqres := cli.QueryAsync(query) reqres := cli.QueryAsync(query)
if res := cli.checkErrGetResult(); res.IsErr() { if res := cli.checkErrGetResult(); res.IsErr() {


+ 17
- 0
client/local_client.go View File

@ -99,6 +99,16 @@ func (app *localClient) QueryAsync(tx []byte) *ReqRes {
) )
} }
func (app *localClient) ProofAsync(key []byte) *ReqRes {
app.mtx.Lock()
res := app.Application.Proof(key)
app.mtx.Unlock()
return app.callback(
types.ToRequestProof(key),
types.ToResponseQuery(res.Code, res.Data, res.Log),
)
}
func (app *localClient) CommitAsync() *ReqRes { func (app *localClient) CommitAsync() *ReqRes {
app.mtx.Lock() app.mtx.Lock()
res := app.Application.Commit() res := app.Application.Commit()
@ -192,6 +202,13 @@ func (app *localClient) QuerySync(query []byte) (res types.Result) {
return res return res
} }
func (app *localClient) ProofSync(key []byte) (res types.Result) {
app.mtx.Lock()
res = app.Application.Proof(key)
app.mtx.Unlock()
return res
}
func (app *localClient) CommitSync() (res types.Result) { func (app *localClient) CommitSync() (res types.Result) {
app.mtx.Lock() app.mtx.Lock()
res = app.Application.Commit() res = app.Application.Commit()


+ 15
- 0
client/socket_client.go View File

@ -255,6 +255,10 @@ 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 {
return cli.queueRequest(types.ToRequestProof(key))
}
func (cli *socketClient) CommitAsync() *ReqRes { func (cli *socketClient) CommitAsync() *ReqRes {
return cli.queueRequest(types.ToRequestCommit()) return cli.queueRequest(types.ToRequestCommit())
} }
@ -345,6 +349,15 @@ 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) {
reqres := cli.queueRequest(types.ToRequestProof(key))
cli.FlushSync()
if err := cli.Error(); err != nil {
return types.ErrInternalError.SetLog(err.Error())
}
resp := reqres.Response.GetProof()
return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log}
}
func (cli *socketClient) CommitSync() (res types.Result) { func (cli *socketClient) CommitSync() (res types.Result) {
reqres := cli.queueRequest(types.ToRequestCommit()) reqres := cli.queueRequest(types.ToRequestCommit())
cli.FlushSync() cli.FlushSync()
@ -437,6 +450,8 @@ func resMatchesReq(req *types.Request, res *types.Response) (ok bool) {
_, ok = res.Value.(*types.Response_Commit) _, ok = res.Value.(*types.Response_Commit)
case *types.Request_Query: case *types.Request_Query:
_, ok = res.Value.(*types.Response_Query) _, ok = res.Value.(*types.Response_Query)
case *types.Request_Proof:
_, ok = res.Value.(*types.Response_Proof)
case *types.Request_InitChain: case *types.Request_InitChain:
_, ok = res.Value.(*types.Response_InitChain) _, ok = res.Value.(*types.Response_InitChain)
case *types.Request_BeginBlock: case *types.Request_BeginBlock:


+ 19
- 0
cmd/abci-cli/tmsp-cli.go View File

@ -131,6 +131,13 @@ func main() {
return cmdQuery(c) return cmdQuery(c)
}, },
}, },
{
Name: "proof",
Usage: "Get proof for a key",
Action: func(c *cli.Context) error {
return cmdProof(c)
},
},
} }
app.Before = before app.Before = before
err := app.Run(os.Args) err := app.Run(os.Args)
@ -305,6 +312,18 @@ func cmdQuery(c *cli.Context) error {
return nil return nil
} }
// Prove application state
func cmdProof(c *cli.Context) error {
args := c.Args()
if len(args) != 1 {
return errors.New("Command proof takes 1 argument")
}
keyBytes := stringOrHexToBytes(c.Args()[0])
res := client.ProofSync(keyBytes)
printResponse(c, res, string(res.Data), true)
return nil
}
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
func printResponse(c *cli.Context, rsp *response) { func printResponse(c *cli.Context, rsp *response) {


+ 4
- 0
example/chain_aware/chain_aware_app.go View File

@ -61,6 +61,10 @@ func (app *ChainAwareApplication) Query(query []byte) types.Result {
return types.NewResultOK([]byte(Fmt("%d,%d", app.beginCount, app.endCount)), "") return types.NewResultOK([]byte(Fmt("%d,%d", app.beginCount, app.endCount)), "")
} }
func (app *ChainAwareApplication) Proof(key []byte) types.Result {
return types.NewResultOK(nil, Fmt("Proof is not supported"))
}
func (app *ChainAwareApplication) BeginBlock(hash []byte, header *types.Header) { func (app *ChainAwareApplication) BeginBlock(hash []byte, header *types.Header) {
app.beginCount += 1 app.beginCount += 1
return return


+ 4
- 0
example/counter/counter.go View File

@ -83,3 +83,7 @@ func (app *CounterApplication) Query(query []byte) types.Result {
return types.ErrUnknownRequest.SetLog(Fmt("Invalid nonce. Expected hash or tx, got %v", queryStr)) return types.ErrUnknownRequest.SetLog(Fmt("Invalid nonce. Expected hash or tx, got %v", queryStr))
} }
func (app *CounterApplication) Proof(key []byte) types.Result {
return types.NewResultOK(nil, Fmt("Proof is not supported"))
}

+ 4
- 0
example/dummy/dummy.go View File

@ -53,6 +53,10 @@ func (app *DummyApplication) Query(query []byte) types.Result {
return types.NewResultOK(wire.JSONBytes(queryResult), "") return types.NewResultOK(wire.JSONBytes(queryResult), "")
} }
func (app *DummyApplication) Proof(key []byte) types.Result {
return types.NewResultOK(nil, Fmt("TODO: support proof!"))
}
type QueryResult struct { type QueryResult struct {
Index int `json:"index"` Index int `json:"index"`
Value string `json:"value"` Value string `json:"value"`


+ 4
- 0
example/dummy/persistent_dummy.go View File

@ -93,6 +93,10 @@ func (app *PersistentDummyApplication) Query(query []byte) types.Result {
return app.app.Query(query) return app.app.Query(query)
} }
func (app *PersistentDummyApplication) Proof(key []byte) types.Result {
return types.NewResultOK(nil, Fmt("TODO: support proof!"))
}
// Save the validators in the merkle tree // Save the validators in the merkle tree
func (app *PersistentDummyApplication) InitChain(validators []*types.Validator) { func (app *PersistentDummyApplication) InitChain(validators []*types.Validator) {
for _, v := range validators { for _, v := range validators {


+ 4
- 0
example/nil/nil_app.go View File

@ -34,3 +34,7 @@ func (app *NilApplication) Commit() types.Result {
func (app *NilApplication) Query(query []byte) types.Result { func (app *NilApplication) Query(query []byte) types.Result {
return types.NewResultOK(nil, "") return types.NewResultOK(nil, "")
} }
func (app *NilApplication) Proof(key []byte) types.Result {
return types.NewResultOK(nil, "")
}

+ 3
- 0
server/socket_server.go View File

@ -186,6 +186,9 @@ func (s *SocketServer) handleRequest(req *types.Request, responses chan<- *types
case *types.Request_Query: case *types.Request_Query:
res := s.app.Query(r.Query.Query) res := s.app.Query(r.Query.Query)
responses <- types.ToResponseQuery(res.Code, res.Data, res.Log) responses <- types.ToResponseQuery(res.Code, res.Data, res.Log)
case *types.Request_Proof:
res := s.app.Proof(r.Proof.Key, r.Proof.Height)
responses <- types.ToResponseProof(res.Code, res.Data, res.Log)
case *types.Request_InitChain: case *types.Request_InitChain:
if app, ok := s.app.(types.BlockchainAware); ok { if app, ok := s.app.(types.BlockchainAware); ok {
app.InitChain(r.InitChain.Validators) app.InitChain(r.InitChain.Validators)


+ 8
- 0
types/application.go View File

@ -22,6 +22,9 @@ type Application interface {
// Query for state // Query for state
Query(query []byte) Result Query(query []byte) Result
// Get proof for state
Proof(key []byte, blockHeight int) Result
// Return the application Merkle root hash // Return the application Merkle root hash
Commit() Result Commit() Result
} }
@ -82,6 +85,11 @@ func (app *GRPCApplication) Query(ctx context.Context, req *RequestQuery) (*Resp
return &ResponseQuery{r.Code, r.Data, r.Log}, nil return &ResponseQuery{r.Code, r.Data, r.Log}, nil
} }
func (app *GRPCApplication) Proof(ctx context.Context, req *RequestProof) (*ResponseQuery, error) {
r := app.app.Proof(req.Key, req.Height)
return &ResponseProof{r.Code, r.Data, r.Log}, nil
}
func (app *GRPCApplication) Commit(ctx context.Context, req *RequestCommit) (*ResponseCommit, error) { func (app *GRPCApplication) Commit(ctx context.Context, req *RequestCommit) (*ResponseCommit, error) {
r := app.app.Commit() r := app.app.Commit()
return &ResponseCommit{r.Code, r.Data, r.Log}, nil return &ResponseCommit{r.Code, r.Data, r.Log}, nil


+ 12
- 0
types/messages.go View File

@ -55,6 +55,12 @@ func ToRequestQuery(queryBytes []byte) *Request {
} }
} }
func ToRequestProof(key []byte, blockHeight int) *Request {
return &Request{
Value: &Request_Proof{&RequestProof{key, blockHeight}},
}
}
func ToRequestInitChain(validators []*Validator) *Request { func ToRequestInitChain(validators []*Validator) *Request {
return &Request{ return &Request{
Value: &Request_InitChain{&RequestInitChain{validators}}, Value: &Request_InitChain{&RequestInitChain{validators}},
@ -129,6 +135,12 @@ func ToResponseQuery(code CodeType, data []byte, log string) *Response {
} }
} }
func ToResponseProof(code CodeType, data []byte, log string) *Response {
return &Response{
Value: &Response_Proof{&ResponseProof{code, data, log}},
}
}
func ToResponseInitChain() *Response { func ToResponseInitChain() *Response {
return &Response{ return &Response{
Value: &Response_InitChain{&ResponseInitChain{}}, Value: &Response_InitChain{&ResponseInitChain{}},


+ 17
- 2
types/types.proto View File

@ -6,7 +6,7 @@ package types;
//---------------------------------------- //----------------------------------------
// Message types // Message types
// Not being used
// Not being used
// Could be added to request/response // Could be added to request/response
// so we don't have to type switch // so we don't have to type switch
// (would be twice as fast, but we're talking about 15ns) // (would be twice as fast, but we're talking about 15ns)
@ -25,6 +25,7 @@ enum MessageType {
InitChain = 0x15; InitChain = 0x15;
BeginBlock = 0x16; BeginBlock = 0x16;
EndBlock = 0x17; EndBlock = 0x17;
Proof = 0x18;
} }
//---------------------------------------- //----------------------------------------
@ -116,6 +117,12 @@ message RequestQuery{
bytes query = 1; bytes query = 1;
} }
message RequestProof{
bytes key = 1;
int64 height = 2;
}
message RequestCommit{ message RequestCommit{
} }
@ -150,6 +157,7 @@ message Response {
ResponseInitChain init_chain = 10; ResponseInitChain init_chain = 10;
ResponseBeginBlock begin_block = 11; ResponseBeginBlock begin_block = 11;
ResponseEndBlock end_block = 12; ResponseEndBlock end_block = 12;
ResponseProof proof = 13;
} }
} }
@ -193,6 +201,12 @@ message ResponseQuery{
string log = 3; string log = 3;
} }
message ResponseProof{
CodeType code = 1;
bytes data = 2;
string log = 3;
}
message ResponseCommit{ message ResponseCommit{
CodeType code = 1; CodeType code = 1;
bytes data = 2; bytes data = 2;
@ -222,7 +236,7 @@ message Header {
bytes last_commit_hash = 6; bytes last_commit_hash = 6;
bytes data_hash = 7; bytes data_hash = 7;
bytes validators_hash = 8; bytes validators_hash = 8;
bytes app_hash = 9;
bytes app_hash = 9;
} }
message BlockID { message BlockID {
@ -251,6 +265,7 @@ service ABCIApplication {
rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx); rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx);
rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx);
rpc Query(RequestQuery) returns (ResponseQuery); rpc Query(RequestQuery) returns (ResponseQuery);
rpc Proof(RequestProof) returns (ResponseProof);
rpc Commit(RequestCommit) returns (ResponseCommit); rpc Commit(RequestCommit) returns (ResponseCommit);
rpc InitChain(RequestInitChain) returns (ResponseInitChain); rpc InitChain(RequestInitChain) returns (ResponseInitChain);
rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock); rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock);


Loading…
Cancel
Save