diff --git a/.editorconfig b/.editorconfig index d587999e..82f77436 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,3 +13,7 @@ indent_style = tab [*.sh] indent_style = tab + +[*.proto] +indent_style = space +indent_size = 2 diff --git a/.gitignore b/.gitignore index 62f28681..ea27eda1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ vendor .glide +types/types.pb.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cd5046c..64c0cbce 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,31 @@ # Changelog +## 0.8.0 (December 6, 2017) + +BREAKING CHANGES: + - [client] all XxxSync methods now return (ResponseXxx, error) + - [types] all methods on Application interface now take RequestXxx and return (ResponseXxx, error). + - Except `CheckTx`/`DeliverTx`, which takes a `tx []byte` argument. + - Except `Commit`, which takes no arguments. + - [types] removed Result and ResultQuery + - [types] removed CodeType - only `0 == OK` is defined here, everything else is left to convention at the application level + - [types] switched to using `gogo/protobuf` for code generation + - [types] use `customtype` feature of `gogo/protobuf` to replace `[]byte` with `data.Bytes` in all generated types :) + - this eliminates the need for additional types like ResultQuery + - [types] `pubKey` -> `pub_key` + - [types] `uint64` -> `int32` for `Header.num_txs` and `PartSetHeader.total` + - [types] `uint64` -> `int64` for everything else + - [types] ResponseSetOption includes error code + - [abci-cli] codes are printed as their number instead of a message, except for `code == 0`, which is still printed as `OK` + +FEATURES: + - [types] ResponseDeliverTx: added `tags` field + - [types] ResponseCheckTx: added `gas` and `fee` fields + - [types] RequestBeginBlock: added `absent_validators` and `byzantine_validators` fields + - [dummy] DeliverTx returns an owner tag and a key tag + - [abci-cli] added `log_level` flag to control the logger + - [abci-cli] introduce `abci-cli test` command for simple testing of ABCI server implementations via Counter application + ## 0.7.1 (November 14, 2017) IMPROVEMENTS: diff --git a/Dockerfile.develop b/Dockerfile.develop new file mode 100644 index 00000000..d4643155 --- /dev/null +++ b/Dockerfile.develop @@ -0,0 +1,21 @@ +FROM golang:latest + +RUN mkdir -p /go/src/github.com/tendermint/abci +WORKDIR /go/src/github.com/tendermint/abci + +COPY Makefile /go/src/github.com/tendermint/abci/ + +# see make protoc for details on ldconfig +RUN make install_protoc && ldconfig + +# killall is used in tests +RUN apt-get update && apt-get install -y \ + psmisc \ + && rm -rf /var/lib/apt/lists/* + +COPY glide.yaml /go/src/github.com/tendermint/abci/ +COPY glide.lock /go/src/github.com/tendermint/abci/ + +RUN make get_vendor_deps + +COPY . /go/src/github.com/tendermint/abci diff --git a/Makefile b/Makefile index 6c99e363..d5fe913b 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,33 @@ GOTOOLS = \ github.com/mitchellh/gox \ github.com/Masterminds/glide \ - github.com/alecthomas/gometalinter + github.com/alecthomas/gometalinter \ + github.com/ckaznocha/protoc-gen-lint \ + github.com/gogo/protobuf/protoc-gen-gogo \ + github.com/gogo/protobuf/gogoproto -all: protoc install test +INCLUDE = -I=. -I=${GOPATH}/src -I=${GOPATH}/src/github.com/gogo/protobuf/protobuf + +all: install test PACKAGES=$(shell go list ./... | grep -v '/vendor/') -install-protoc: - # Download: https://github.com/google/protobuf/releases - go get github.com/golang/protobuf/protoc-gen-go +install_protoc: + # https://github.com/google/protobuf/releases + curl -L https://github.com/google/protobuf/releases/download/v3.4.1/protobuf-cpp-3.4.1.tar.gz | tar xvz && \ + cd protobuf-3.4.1 && \ + DIST_LANG=cpp ./configure && \ + make && \ + make install && \ + cd .. && \ + rm -rf protobuf-3.4.1 protoc: - @ protoc --go_out=plugins=grpc:. types/*.proto + ## Note to self: + ## On "error while loading shared libraries: libprotobuf.so.14: cannot open shared object file: No such file or directory" + ## ldconfig (may require sudo) + ## https://stackoverflow.com/a/25518702 + protoc $(INCLUDE) --gogo_out=plugins=grpc:. --lint_out=. types/*.proto install: @ go install ./cmd/... @@ -24,37 +39,45 @@ dist: @ bash scripts/dist.sh @ bash scripts/publish.sh -# test.sh requires that we run the installed cmds, must not be out of date -test: install - find . -path ./vendor -prune -o -name *.sock -exec rm {} \; +test: + @ find . -path ./vendor -prune -o -name "*.sock" -exec rm {} \; + @ echo "==> Running linter" + @ make metalinter_test + @ echo "==> Running go test" @ go test $(PACKAGES) - @ bash tests/test.sh + +test_race: + @ find . -path ./vendor -prune -o -name "*.sock" -exec rm {} \; + @ echo "==> Running go test --race" + @go test -v -race $(PACKAGES) + +test_integrations: + @ bash test.sh fmt: @ go fmt ./... -test_integrations: get_vendor_deps install test - get_deps: @ go get -d $(PACKAGES) -tools: +ensure_tools: go get -u -v $(GOTOOLS) + @gometalinter --install -get_vendor_deps: - @ go get github.com/Masterminds/glide +get_vendor_deps: ensure_tools + @rm -rf vendor/ + @echo "--> Running glide install" @ glide install -metalinter: tools - @gometalinter --install +metalinter: + protoc $(INCLUDE) --lint_out=. types/*.proto gometalinter --vendor --deadline=600s --enable-all --disable=lll ./... -metalinter_test: tools - @gometalinter --install +metalinter_test: + protoc $(INCLUDE) --lint_out=. types/*.proto gometalinter --vendor --deadline=600s --disable-all \ --enable=maligned \ --enable=deadcode \ - --enable=gas \ --enable=goconst \ --enable=goimports \ --enable=gosimple \ @@ -70,6 +93,7 @@ metalinter_test: tools --enable=vetshadow \ ./... + #--enable=gas \ #--enable=dupl \ #--enable=errcheck \ #--enable=gocyclo \ @@ -79,4 +103,10 @@ metalinter_test: tools #--enable=unparam \ #--enable=vet \ -.PHONY: all build test fmt get_deps tools +build-docker: + docker build -t "tendermint/abci-dev" -f Dockerfile.develop . + +run-docker: + docker run -it --rm -v "$PWD:/go/src/github.com/tendermint/abci" -w "/go/src/github.com/tendermint/abci" "tendermint/abci-dev" /bin/bash + +.PHONY: all build test fmt get_deps ensure_tools protoc install_protoc build-docker run-docker diff --git a/README.md b/README.md index aedebee6..46abcc4f 100644 --- a/README.md +++ b/README.md @@ -2,21 +2,12 @@ [![CircleCI](https://circleci.com/gh/tendermint/abci.svg?style=svg)](https://circleci.com/gh/tendermint/abci) -Blockchains are a system for multi-master state machine replication. +Blockchains are systems for multi-master state machine replication. **ABCI** is an interface that defines the boundary between the replication engine (the blockchain), and the state machine (the application). By using a socket protocol, we enable a consensus engine running in one process to manage an application state running in another. -## Install - -``` -go get github.com/tendermint/abci -cd $GOPATH/src/github.com/tendermint/abci -make get_vendor_deps -make install -``` - For background information on ABCI, motivations, and tendermint, please visit [the documentation](http://tendermint.readthedocs.io/en/master/). The two guides to focus on are the `Application Development Guide` and `Using ABCI-CLI`. @@ -28,11 +19,19 @@ The community has provided a number of addtional implementations, see the `Tende We provide three implementations of the ABCI in Go: +- Golang in-process - ABCI-socket - GRPC -- Golang in-process -### Socket +Note the GRPC version is maintained primarily to simplify onboarding and prototyping and is not receiving the same +attention to security and performance as the others. + +### In Process + +The simplest implementation just uses function calls within Go. +This means ABCI applications written in Golang can be compiled with TendermintCore and run as a single binary. + +### Socket (TSP) ABCI is best implemented as a streaming protocol. The socket implementation provides for asynchronous, ordered message passing over unix or tcp. @@ -45,25 +44,33 @@ For example, if the Protobuf3 encoded ABCI message is `0xDEADBEEF` (4 bytes), th GRPC is an rpc framework native to Protocol Buffers with support in many languages. Implementing the ABCI using GRPC can allow for faster prototyping, but is expected to be much slower than -the ordered, asynchronous socket protocol. +the ordered, asynchronous socket protocol. The implementation has also not received as much testing or review. Note the length-prefixing used in the socket implementation does not apply for GRPC. -### In Process +## Tools -The simplest implementation just uses function calls within Go. -This means ABCI applications written in Golang can be compiled with TendermintCore and run as a single binary. - -## Example Apps - -The `abci-cli` tool wraps any ABCI client and can be used for probing/testing an ABCI application. +The `abci-cli` tool wraps an ABCI client and can be used for probing/testing an ABCI server. +For instance, `abci-cli test` will run a test sequence against a listening server running the Counter application (see below). +It can also be used to run some example applications. See [the documentation](http://tendermint.readthedocs.io/en/master/) for more details. +### Example Apps + Multiple example apps are included: - the `abci-cli counter` application, which illustrates nonce checking in txs - the `abci-cli dummy` application, which illustrates a simple key-value merkle tree - the `abci-cli dummy --persistent` application, which augments the dummy with persistence and validator set changes +### Install + +``` +go get github.com/tendermint/abci +cd $GOPATH/src/github.com/tendermint/abci +make get_vendor_deps +make install +``` + ## Specification The [primary specification](https://github.com/tendermint/abci/blob/master/types/types.proto) is made using Protocol Buffers. @@ -91,6 +98,7 @@ Here, we describe the requests and responses as function arguments and return va * `Code (uint32)`: Response code * `Data ([]byte)`: Result bytes, if any * `Log (string)`: Debug or error message + * `Tags ([]*KVPair)`: Optional tags for indexing * __Usage__:
Append and run a transaction. If the transaction is valid, returns CodeType.OK @@ -101,6 +109,8 @@ Here, we describe the requests and responses as function arguments and return va * `Code (uint32)`: Response code * `Data ([]byte)`: Result bytes, if any * `Log (string)`: Debug or error message + * `Gas (int64)`: Amount of gas consumed by transaction + * `Fee (int64)`: Fee paid by transaction * __Usage__:
Validate a mempool transaction, prior to broadcasting or proposing. This message should not mutate the main state, but application developers may want to keep a separate CheckTx state that gets reset upon Commit. @@ -124,14 +134,14 @@ Here, we describe the requests and responses as function arguments and return va * `Path (string)`: Path of request, like an HTTP GET path. Can be used with or in liue of Data. * Apps MUST interpret '/store' as a query by key on the underlying store. The key SHOULD be specified in the Data field. * Apps SHOULD allow queries over specific types like '/accounts/...' or '/votes/...' - * `Height (uint64)`: The block height for which you want the query (default=0 returns data for the latest committed block). Note that this is the height of the block containing the application's Merkle root hash, which represents the state as it was after committing the block at Height-1 + * `Height (int64)`: The block height for which you want the query (default=0 returns data for the latest committed block). Note that this is the height of the block containing the application's Merkle root hash, which represents the state as it was after committing the block at Height-1 * `Prove (bool)`: Return Merkle proof with response if possible * __Returns__: * `Code (uint32)`: Response code * `Key ([]byte)`: The key of the matching data * `Value ([]byte)`: The value of the matching data * `Proof ([]byte)`: Proof for the data, if requested - * `Height (uint64)`: The block height from which data was derived. Note that this is the height of the block containing the application's Merkle root hash, which represents the state as it was after committing the block at Height-1 + * `Height (int64)`: The block height from which data was derived. Note that this is the height of the block containing the application's Merkle root hash, which represents the state as it was after committing the block at Height-1 * `Log (string)`: Debug or error message *Please note* The current implementation of go-merkle doesn't support querying proofs from past blocks, so for the present moment, any height other than 0 will return an error (recall height=0 defaults to latest block). Hopefully this will be improved soon(ish) @@ -139,7 +149,7 @@ Here, we describe the requests and responses as function arguments and return va * __Returns__: * `Data (string)`: Some arbitrary information * `Version (Version)`: Version information - * `LastBlockHeight (uint64)`: Latest block for which the app has called Commit + * `LastBlockHeight (int64)`: Latest block for which the app has called Commit * `LastBlockAppHash ([]byte)`: Latest result of Commit * __Usage__:
@@ -150,6 +160,7 @@ Here, we describe the requests and responses as function arguments and return va * `Key (string)`: Key to set * `Value (string)`: Value to set for key * __Returns__: + * `Code (uint32)`: Response code * `Log (string)`: Debug or error message * __Usage__:
Set application options. E.g. Key="mode", Value="mempool" for a mempool connection, or Key="mode", Value="consensus" for a consensus connection. @@ -165,12 +176,14 @@ Here, we describe the requests and responses as function arguments and return va * __Arguments__: * `Hash ([]byte)`: The block's hash. This can be derived from the block header. * `Header (struct{})`: The block header + * `AbsentValidators ([]int32)`: List of indices of validators not included in the LastCommit + * `ByzantineValidators ([]Evidence)`: List of evidence of validators that acted maliciously * __Usage__:
- Signals the beginning of a new block. Called prior to any DeliverTxs. The header is expected to at least contain the Height. + Signals the beginning of a new block. Called prior to any DeliverTxs. The header is expected to at least contain the Height. The `AbsentValidators` and `ByzantineValidators` can be used to determine rewards and punishments for the validators. #### EndBlock * __Arguments__: - * `Height (uint64)`: The block height that ended + * `Height (int64)`: The block height that ended * __Returns__: * `Diffs ([]Validator)`: Changed validators with new voting powers (0 to remove) * __Usage__:
@@ -187,3 +200,4 @@ Here, we describe the requests and responses as function arguments and return va #### Flush * __Usage__:
* Signals that messages queued on the client should be flushed to the server. It is called periodically by the client implementation to ensure asynchronous requests are actually sent, and is called immediately to make a synchronous request, which returns when the Flush response comes back. + diff --git a/circle.yml b/circle.yml index daa4218e..7d4545e5 100644 --- a/circle.yml +++ b/circle.yml @@ -12,11 +12,11 @@ checkout: - rm -rf $REPO - mkdir -p $HOME/.go_workspace/src/github.com/$CIRCLE_PROJECT_USERNAME - mv $HOME/$CIRCLE_PROJECT_REPONAME $REPO - # - git submodule sync - # - git submodule update --init # use submodules + - go version test: override: - - "go version" - - "cd $REPO && make get_vendor_deps && make metalinter_test" - - "cd $REPO && make test_integrations" + - cd $REPO && make get_vendor_deps && make test_integrations + post: + - cd "$REPO" && bash <(curl -s https://codecov.io/bash) -f coverage.txt + - cd "$REPO" && mv coverage.txt "${CIRCLE_ARTIFACTS}" diff --git a/client/client.go b/client/client.go index 51d04124..ad0e5a7a 100644 --- a/client/client.go +++ b/client/client.go @@ -8,6 +8,16 @@ import ( cmn "github.com/tendermint/tmlibs/common" ) +const ( + dialRetryIntervalSeconds = 3 + echoRetryIntervalSeconds = 1 +) + +// Client defines an interface for an ABCI client. +// All `Async` methods return a `ReqRes` object. +// All `Sync` methods return the appropriate protobuf ResponseXxx struct and an error. +// Note these are client errors, eg. ABCI socket connectivity issues. +// Application-related errors are reflected in response via ABCI error codes and logs. type Client interface { cmn.Service @@ -17,28 +27,26 @@ type Client interface { FlushAsync() *ReqRes EchoAsync(msg string) *ReqRes InfoAsync(types.RequestInfo) *ReqRes - SetOptionAsync(key string, value string) *ReqRes + SetOptionAsync(types.RequestSetOption) *ReqRes DeliverTxAsync(tx []byte) *ReqRes CheckTxAsync(tx []byte) *ReqRes QueryAsync(types.RequestQuery) *ReqRes CommitAsync() *ReqRes - - FlushSync() error - EchoSync(msg string) (res types.Result) - InfoSync(types.RequestInfo) (resInfo types.ResponseInfo, err error) - SetOptionSync(key string, value string) (res types.Result) - DeliverTxSync(tx []byte) (res types.Result) - CheckTxSync(tx []byte) (res types.Result) - QuerySync(types.RequestQuery) (resQuery types.ResponseQuery, err error) - CommitSync() (res types.Result) - InitChainAsync(types.RequestInitChain) *ReqRes BeginBlockAsync(types.RequestBeginBlock) *ReqRes - EndBlockAsync(height uint64) *ReqRes + EndBlockAsync(types.RequestEndBlock) *ReqRes - InitChainSync(types.RequestInitChain) (err error) - BeginBlockSync(types.RequestBeginBlock) (err error) - EndBlockSync(height uint64) (resEndBlock types.ResponseEndBlock, err error) + FlushSync() error + EchoSync(msg string) (*types.ResponseEcho, error) + InfoSync(types.RequestInfo) (*types.ResponseInfo, error) + SetOptionSync(types.RequestSetOption) (*types.ResponseSetOption, error) + DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) + CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) + QuerySync(types.RequestQuery) (*types.ResponseQuery, error) + CommitSync() (*types.ResponseCommit, error) + InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) + BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error) + EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error) } //---------------------------------------- diff --git a/client/grpc_client.go b/client/grpc_client.go index 30f5d088..f277e1d7 100644 --- a/client/grpc_client.go +++ b/client/grpc_client.go @@ -6,6 +6,7 @@ import ( "sync" "time" + "github.com/pkg/errors" context "golang.org/x/net/context" grpc "google.golang.org/grpc" @@ -13,6 +14,8 @@ import ( cmn "github.com/tendermint/tmlibs/common" ) +var _ Client = (*grpcClient)(nil) + // A stripped copy of the remoteClient that makes // synchronous calls using grpc type grpcClient struct { @@ -45,7 +48,6 @@ func (cli *grpcClient) OnStart() error { return err } RETRY_LOOP: - for { conn, err := grpc.Dial(cli.addr, grpc.WithInsecure(), grpc.WithDialer(dialerFunc)) if err != nil { @@ -53,10 +55,11 @@ RETRY_LOOP: return err } cli.Logger.Error(fmt.Sprintf("abci.grpcClient failed to connect to %v. Retrying...\n", cli.addr)) - time.Sleep(time.Second * 3) + time.Sleep(time.Second * dialRetryIntervalSeconds) continue RETRY_LOOP } + cli.Logger.Info("Dialed server. Waiting for echo.", "addr", cli.addr) client := types.NewABCIApplicationClient(conn) ENSURE_CONNECTED: @@ -65,7 +68,8 @@ RETRY_LOOP: if err == nil { break ENSURE_CONNECTED } - time.Sleep(time.Second) + cli.Logger.Error("Echo failed", "err", err) + time.Sleep(time.Second * echoRetryIntervalSeconds) } cli.client = client @@ -78,8 +82,8 @@ func (cli *grpcClient) OnStop() { cli.mtx.Lock() defer cli.mtx.Unlock() // TODO: how to close conn? its not a net.Conn and grpc doesn't expose a Close() - /*if cli.conn != nil { - cli.conn.Close() + /*if cli.client.conn != nil { + cli.client.conn.Close() }*/ } @@ -101,7 +105,7 @@ func (cli *grpcClient) StopForError(err error) { func (cli *grpcClient) Error() error { cli.mtx.Lock() defer cli.mtx.Unlock() - return cli.err + return errors.Wrap(cli.err, "grpc client error") } // Set listener for all responses @@ -147,8 +151,8 @@ func (cli *grpcClient) InfoAsync(params types.RequestInfo) *ReqRes { return cli.finishAsyncCall(req, &types.Response{&types.Response_Info{res}}) } -func (cli *grpcClient) SetOptionAsync(key string, value string) *ReqRes { - req := types.ToRequestSetOption(key, value) +func (cli *grpcClient) SetOptionAsync(params types.RequestSetOption) *ReqRes { + req := types.ToRequestSetOption(params) res, err := cli.client.SetOption(context.Background(), req.GetSetOption(), grpc.FailFast(true)) if err != nil { cli.StopForError(err) @@ -210,8 +214,8 @@ func (cli *grpcClient) BeginBlockAsync(params types.RequestBeginBlock) *ReqRes { return cli.finishAsyncCall(req, &types.Response{&types.Response_BeginBlock{res}}) } -func (cli *grpcClient) EndBlockAsync(height uint64) *ReqRes { - req := types.ToRequestEndBlock(height) +func (cli *grpcClient) EndBlockAsync(params types.RequestEndBlock) *ReqRes { + req := types.ToRequestEndBlock(params) res, err := cli.client.EndBlock(context.Background(), req.GetEndBlock(), grpc.FailFast(true)) if err != nil { cli.StopForError(err) @@ -240,104 +244,59 @@ func (cli *grpcClient) finishAsyncCall(req *types.Request, res *types.Response) return reqres } -func (cli *grpcClient) checkErrGetResult() types.Result { - if err := cli.Error(); err != nil { - // StopForError should already have been called if error is set - return types.ErrInternalError.SetLog(err.Error()) - } - return types.Result{} -} - //---------------------------------------- -func (cli *grpcClient) EchoSync(msg string) (res types.Result) { - reqres := cli.EchoAsync(msg) - if res := cli.checkErrGetResult(); res.IsErr() { - return res - } - resp := reqres.Response.GetEcho() - return types.NewResultOK([]byte(resp.Message), "") -} - func (cli *grpcClient) FlushSync() error { return nil } -func (cli *grpcClient) InfoSync(req types.RequestInfo) (resInfo types.ResponseInfo, err error) { +func (cli *grpcClient) EchoSync(msg string) (*types.ResponseEcho, error) { + reqres := cli.EchoAsync(msg) + // StopForError should already have been called if error is set + return reqres.Response.GetEcho(), cli.Error() +} + +func (cli *grpcClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { reqres := cli.InfoAsync(req) - if err = cli.Error(); err != nil { - return resInfo, err - } - if info := reqres.Response.GetInfo(); info != nil { - return *info, nil - } - return resInfo, nil + return reqres.Response.GetInfo(), cli.Error() } -func (cli *grpcClient) SetOptionSync(key string, value string) (res types.Result) { - reqres := cli.SetOptionAsync(key, value) - if res := cli.checkErrGetResult(); res.IsErr() { - return res - } - resp := reqres.Response.GetSetOption() - return types.Result{Code: OK, Data: nil, Log: resp.Log} +func (cli *grpcClient) SetOptionSync(req types.RequestSetOption) (*types.ResponseSetOption, error) { + reqres := cli.SetOptionAsync(req) + return reqres.Response.GetSetOption(), cli.Error() } -func (cli *grpcClient) DeliverTxSync(tx []byte) (res types.Result) { +func (cli *grpcClient) DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) { reqres := cli.DeliverTxAsync(tx) - if res := cli.checkErrGetResult(); res.IsErr() { - return res - } - resp := reqres.Response.GetDeliverTx() - return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log} + return reqres.Response.GetDeliverTx(), cli.Error() } -func (cli *grpcClient) CheckTxSync(tx []byte) (res types.Result) { +func (cli *grpcClient) CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) { reqres := cli.CheckTxAsync(tx) - if res := cli.checkErrGetResult(); res.IsErr() { - return res - } - resp := reqres.Response.GetCheckTx() - return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log} + return reqres.Response.GetCheckTx(), cli.Error() } -func (cli *grpcClient) QuerySync(reqQuery types.RequestQuery) (resQuery types.ResponseQuery, err error) { - reqres := cli.QueryAsync(reqQuery) - if err = cli.Error(); err != nil { - return resQuery, err - } - if resQuery_ := reqres.Response.GetQuery(); resQuery_ != nil { - return *resQuery_, nil - } - return resQuery, nil +func (cli *grpcClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { + reqres := cli.QueryAsync(req) + return reqres.Response.GetQuery(), cli.Error() } -func (cli *grpcClient) CommitSync() (res types.Result) { +func (cli *grpcClient) CommitSync() (*types.ResponseCommit, error) { reqres := cli.CommitAsync() - if res := cli.checkErrGetResult(); res.IsErr() { - return res - } - resp := reqres.Response.GetCommit() - return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log} + return reqres.Response.GetCommit(), cli.Error() } -func (cli *grpcClient) InitChainSync(params types.RequestInitChain) (err error) { - cli.InitChainAsync(params) - return cli.Error() +func (cli *grpcClient) InitChainSync(params types.RequestInitChain) (*types.ResponseInitChain, error) { + reqres := cli.InitChainAsync(params) + return reqres.Response.GetInitChain(), cli.Error() } -func (cli *grpcClient) BeginBlockSync(params types.RequestBeginBlock) (err error) { - cli.BeginBlockAsync(params) - return cli.Error() +func (cli *grpcClient) BeginBlockSync(params types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { + reqres := cli.BeginBlockAsync(params) + return reqres.Response.GetBeginBlock(), cli.Error() } -func (cli *grpcClient) EndBlockSync(height uint64) (resEndBlock types.ResponseEndBlock, err error) { - reqres := cli.EndBlockAsync(height) - if err := cli.Error(); err != nil { - return resEndBlock, err - } - if blk := reqres.Response.GetEndBlock(); blk != nil { - return *blk, nil - } - return resEndBlock, nil +func (cli *grpcClient) EndBlockSync(params types.RequestEndBlock) (*types.ResponseEndBlock, error) { + reqres := cli.EndBlockAsync(params) + return reqres.Response.GetEndBlock(), cli.Error() } diff --git a/client/local_client.go b/client/local_client.go index 8494a468..64bf5fe0 100644 --- a/client/local_client.go +++ b/client/local_client.go @@ -7,6 +7,8 @@ import ( cmn "github.com/tendermint/tmlibs/common" ) +var _ Client = (*localClient)(nil) + type localClient struct { cmn.BaseService mtx *sync.Mutex @@ -51,21 +53,21 @@ func (app *localClient) EchoAsync(msg string) *ReqRes { func (app *localClient) InfoAsync(req types.RequestInfo) *ReqRes { app.mtx.Lock() - resInfo := app.Application.Info(req) + res := app.Application.Info(req) app.mtx.Unlock() return app.callback( types.ToRequestInfo(req), - types.ToResponseInfo(resInfo), + types.ToResponseInfo(res), ) } -func (app *localClient) SetOptionAsync(key string, value string) *ReqRes { +func (app *localClient) SetOptionAsync(req types.RequestSetOption) *ReqRes { app.mtx.Lock() - log := app.Application.SetOption(key, value) + res := app.Application.SetOption(req) app.mtx.Unlock() return app.callback( - types.ToRequestSetOption(key, value), - types.ToResponseSetOption(log), + types.ToRequestSetOption(req), + types.ToResponseSetOption(res), ) } @@ -75,7 +77,7 @@ func (app *localClient) DeliverTxAsync(tx []byte) *ReqRes { app.mtx.Unlock() return app.callback( types.ToRequestDeliverTx(tx), - types.ToResponseDeliverTx(res.Code, res.Data, res.Log), + types.ToResponseDeliverTx(res), ) } @@ -85,17 +87,17 @@ func (app *localClient) CheckTxAsync(tx []byte) *ReqRes { app.mtx.Unlock() return app.callback( types.ToRequestCheckTx(tx), - types.ToResponseCheckTx(res.Code, res.Data, res.Log), + types.ToResponseCheckTx(res), ) } -func (app *localClient) QueryAsync(reqQuery types.RequestQuery) *ReqRes { +func (app *localClient) QueryAsync(req types.RequestQuery) *ReqRes { app.mtx.Lock() - resQuery := app.Application.Query(reqQuery) + res := app.Application.Query(req) app.mtx.Unlock() return app.callback( - types.ToRequestQuery(reqQuery), - types.ToResponseQuery(resQuery), + types.ToRequestQuery(req), + types.ToResponseQuery(res), ) } @@ -105,38 +107,38 @@ func (app *localClient) CommitAsync() *ReqRes { app.mtx.Unlock() return app.callback( types.ToRequestCommit(), - types.ToResponseCommit(res.Code, res.Data, res.Log), + types.ToResponseCommit(res), ) } -func (app *localClient) InitChainAsync(params types.RequestInitChain) *ReqRes { +func (app *localClient) InitChainAsync(req types.RequestInitChain) *ReqRes { app.mtx.Lock() - app.Application.InitChain(params) + res := app.Application.InitChain(req) reqRes := app.callback( - types.ToRequestInitChain(params), - types.ToResponseInitChain(), + types.ToRequestInitChain(req), + types.ToResponseInitChain(res), ) app.mtx.Unlock() return reqRes } -func (app *localClient) BeginBlockAsync(params types.RequestBeginBlock) *ReqRes { +func (app *localClient) BeginBlockAsync(req types.RequestBeginBlock) *ReqRes { app.mtx.Lock() - app.Application.BeginBlock(params) + res := app.Application.BeginBlock(req) app.mtx.Unlock() return app.callback( - types.ToRequestBeginBlock(params), - types.ToResponseBeginBlock(), + types.ToRequestBeginBlock(req), + types.ToResponseBeginBlock(res), ) } -func (app *localClient) EndBlockAsync(height uint64) *ReqRes { +func (app *localClient) EndBlockAsync(req types.RequestEndBlock) *ReqRes { app.mtx.Lock() - resEndBlock := app.Application.EndBlock(height) + res := app.Application.EndBlock(req) app.mtx.Unlock() return app.callback( - types.ToRequestEndBlock(height), - types.ToResponseEndBlock(resEndBlock), + types.ToRequestEndBlock(req), + types.ToResponseEndBlock(res), ) } @@ -146,71 +148,71 @@ func (app *localClient) FlushSync() error { return nil } -func (app *localClient) EchoSync(msg string) (res types.Result) { - return types.OK.SetData([]byte(msg)) +func (app *localClient) EchoSync(msg string) (*types.ResponseEcho, error) { + return &types.ResponseEcho{msg}, nil } -func (app *localClient) InfoSync(req types.RequestInfo) (resInfo types.ResponseInfo, err error) { +func (app *localClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { app.mtx.Lock() - defer app.mtx.Unlock() - resInfo = app.Application.Info(req) - return resInfo, nil -} - -func (app *localClient) SetOptionSync(key string, value string) (res types.Result) { - app.mtx.Lock() - log := app.Application.SetOption(key, value) + res := app.Application.Info(req) app.mtx.Unlock() - return types.OK.SetLog(log) + return &res, nil } -func (app *localClient) DeliverTxSync(tx []byte) (res types.Result) { +func (app *localClient) SetOptionSync(req types.RequestSetOption) (*types.ResponseSetOption, error) { app.mtx.Lock() - res = app.Application.DeliverTx(tx) + res := app.Application.SetOption(req) app.mtx.Unlock() - return res + return &res, nil } -func (app *localClient) CheckTxSync(tx []byte) (res types.Result) { +func (app *localClient) DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) { app.mtx.Lock() - res = app.Application.CheckTx(tx) + res := app.Application.DeliverTx(tx) app.mtx.Unlock() - return res + return &res, nil } -func (app *localClient) QuerySync(reqQuery types.RequestQuery) (resQuery types.ResponseQuery, err error) { +func (app *localClient) CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) { app.mtx.Lock() - resQuery = app.Application.Query(reqQuery) + res := app.Application.CheckTx(tx) app.mtx.Unlock() - return resQuery, nil + return &res, nil } -func (app *localClient) CommitSync() (res types.Result) { +func (app *localClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { app.mtx.Lock() - res = app.Application.Commit() + res := app.Application.Query(req) app.mtx.Unlock() - return res + return &res, nil } -func (app *localClient) InitChainSync(params types.RequestInitChain) (err error) { +func (app *localClient) CommitSync() (*types.ResponseCommit, error) { app.mtx.Lock() - app.Application.InitChain(params) + res := app.Application.Commit() app.mtx.Unlock() - return nil + return &res, nil } -func (app *localClient) BeginBlockSync(params types.RequestBeginBlock) (err error) { +func (app *localClient) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) { app.mtx.Lock() - app.Application.BeginBlock(params) + res := app.Application.InitChain(req) app.mtx.Unlock() - return nil + return &res, nil } -func (app *localClient) EndBlockSync(height uint64) (resEndBlock types.ResponseEndBlock, err error) { +func (app *localClient) BeginBlockSync(req types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { app.mtx.Lock() - resEndBlock = app.Application.EndBlock(height) + res := app.Application.BeginBlock(req) app.mtx.Unlock() - return resEndBlock, nil + return &res, nil +} + +func (app *localClient) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { + app.mtx.Lock() + res := app.Application.EndBlock(req) + app.mtx.Unlock() + return &res, nil } //------------------------------------------------------- diff --git a/client/socket_client.go b/client/socket_client.go index 1045dea7..ecdc3694 100644 --- a/client/socket_client.go +++ b/client/socket_client.go @@ -3,26 +3,23 @@ package abcicli import ( "bufio" "container/list" - "errors" "fmt" "net" "reflect" "sync" "time" + "github.com/pkg/errors" "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" ) -const ( - OK = types.CodeType_OK - LOG = "" -) - const reqQueueSize = 256 // TODO make configurable // const maxResponseSize = 1048576 // 1MB TODO make configurable const flushThrottleMS = 20 // Don't wait longer than... +var _ Client = (*socketClient)(nil) + // This is goroutine-safe, but users should beware that // the application in general is not meant to be interfaced // with concurrent callers. @@ -71,7 +68,7 @@ RETRY_LOOP: return err } cli.Logger.Error(fmt.Sprintf("abci.socketClient failed to connect to %v. Retrying...", cli.addr)) - time.Sleep(time.Second * 3) + time.Sleep(time.Second * dialRetryIntervalSeconds) continue RETRY_LOOP } cli.conn = conn @@ -114,7 +111,7 @@ func (cli *socketClient) StopForError(err error) { func (cli *socketClient) Error() error { cli.mtx.Lock() defer cli.mtx.Unlock() - return cli.err + return errors.Wrap(cli.err, "socket client error") } // Set listener for all responses @@ -237,8 +234,8 @@ func (cli *socketClient) InfoAsync(req types.RequestInfo) *ReqRes { return cli.queueRequest(types.ToRequestInfo(req)) } -func (cli *socketClient) SetOptionAsync(key string, value string) *ReqRes { - return cli.queueRequest(types.ToRequestSetOption(key, value)) +func (cli *socketClient) SetOptionAsync(req types.RequestSetOption) *ReqRes { + return cli.queueRequest(types.ToRequestSetOption(req)) } func (cli *socketClient) DeliverTxAsync(tx []byte) *ReqRes { @@ -249,133 +246,95 @@ func (cli *socketClient) CheckTxAsync(tx []byte) *ReqRes { return cli.queueRequest(types.ToRequestCheckTx(tx)) } -func (cli *socketClient) QueryAsync(reqQuery types.RequestQuery) *ReqRes { - return cli.queueRequest(types.ToRequestQuery(reqQuery)) +func (cli *socketClient) QueryAsync(req types.RequestQuery) *ReqRes { + return cli.queueRequest(types.ToRequestQuery(req)) } func (cli *socketClient) CommitAsync() *ReqRes { return cli.queueRequest(types.ToRequestCommit()) } -func (cli *socketClient) InitChainAsync(params types.RequestInitChain) *ReqRes { - return cli.queueRequest(types.ToRequestInitChain(params)) +func (cli *socketClient) InitChainAsync(req types.RequestInitChain) *ReqRes { + return cli.queueRequest(types.ToRequestInitChain(req)) } -func (cli *socketClient) BeginBlockAsync(params types.RequestBeginBlock) *ReqRes { - return cli.queueRequest(types.ToRequestBeginBlock(params)) +func (cli *socketClient) BeginBlockAsync(req types.RequestBeginBlock) *ReqRes { + return cli.queueRequest(types.ToRequestBeginBlock(req)) } -func (cli *socketClient) EndBlockAsync(height uint64) *ReqRes { - return cli.queueRequest(types.ToRequestEndBlock(height)) +func (cli *socketClient) EndBlockAsync(req types.RequestEndBlock) *ReqRes { + return cli.queueRequest(types.ToRequestEndBlock(req)) } //---------------------------------------- -func (cli *socketClient) EchoSync(msg string) (res types.Result) { - reqres := cli.queueRequest(types.ToRequestEcho(msg)) - cli.FlushSync() - if err := cli.Error(); err != nil { - return types.ErrInternalError.SetLog(err.Error()) - } - resp := reqres.Response.GetEcho() - return types.Result{Code: OK, Data: []byte(resp.Message)} -} - func (cli *socketClient) FlushSync() error { reqRes := cli.queueRequest(types.ToRequestFlush()) if err := cli.Error(); err != nil { - return types.ErrInternalError.SetLog(err.Error()) + return err } reqRes.Wait() // NOTE: if we don't flush the queue, its possible to get stuck here return cli.Error() } -func (cli *socketClient) InfoSync(req types.RequestInfo) (resInfo types.ResponseInfo, err error) { +func (cli *socketClient) EchoSync(msg string) (*types.ResponseEcho, error) { + reqres := cli.queueRequest(types.ToRequestEcho(msg)) + cli.FlushSync() + return reqres.Response.GetEcho(), cli.Error() +} + +func (cli *socketClient) InfoSync(req types.RequestInfo) (*types.ResponseInfo, error) { reqres := cli.queueRequest(types.ToRequestInfo(req)) cli.FlushSync() - if err := cli.Error(); err != nil { - return resInfo, err - } - if resInfo_ := reqres.Response.GetInfo(); resInfo_ != nil { - return *resInfo_, nil - } - return resInfo, nil + return reqres.Response.GetInfo(), cli.Error() } -func (cli *socketClient) SetOptionSync(key string, value string) (res types.Result) { - reqres := cli.queueRequest(types.ToRequestSetOption(key, value)) +func (cli *socketClient) SetOptionSync(req types.RequestSetOption) (*types.ResponseSetOption, error) { + reqres := cli.queueRequest(types.ToRequestSetOption(req)) cli.FlushSync() - if err := cli.Error(); err != nil { - return types.ErrInternalError.SetLog(err.Error()) - } - resp := reqres.Response.GetSetOption() - return types.Result{Code: OK, Data: nil, Log: resp.Log} + return reqres.Response.GetSetOption(), cli.Error() } -func (cli *socketClient) DeliverTxSync(tx []byte) (res types.Result) { +func (cli *socketClient) DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) { reqres := cli.queueRequest(types.ToRequestDeliverTx(tx)) cli.FlushSync() - if err := cli.Error(); err != nil { - return types.ErrInternalError.SetLog(err.Error()) - } - resp := reqres.Response.GetDeliverTx() - return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log} + return reqres.Response.GetDeliverTx(), cli.Error() } -func (cli *socketClient) CheckTxSync(tx []byte) (res types.Result) { +func (cli *socketClient) CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) { reqres := cli.queueRequest(types.ToRequestCheckTx(tx)) cli.FlushSync() - if err := cli.Error(); err != nil { - return types.ErrInternalError.SetLog(err.Error()) - } - resp := reqres.Response.GetCheckTx() - return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log} + return reqres.Response.GetCheckTx(), cli.Error() } -func (cli *socketClient) QuerySync(reqQuery types.RequestQuery) (resQuery types.ResponseQuery, err error) { - reqres := cli.queueRequest(types.ToRequestQuery(reqQuery)) +func (cli *socketClient) QuerySync(req types.RequestQuery) (*types.ResponseQuery, error) { + reqres := cli.queueRequest(types.ToRequestQuery(req)) cli.FlushSync() - if err := cli.Error(); err != nil { - return resQuery, err - } - if resQuery_ := reqres.Response.GetQuery(); resQuery_ != nil { - return *resQuery_, nil - } - return resQuery, nil + return reqres.Response.GetQuery(), cli.Error() } -func (cli *socketClient) CommitSync() (res types.Result) { +func (cli *socketClient) CommitSync() (*types.ResponseCommit, error) { reqres := cli.queueRequest(types.ToRequestCommit()) cli.FlushSync() - if err := cli.Error(); err != nil { - return types.ErrInternalError.SetLog(err.Error()) - } - resp := reqres.Response.GetCommit() - return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log} + return reqres.Response.GetCommit(), cli.Error() } -func (cli *socketClient) InitChainSync(params types.RequestInitChain) (err error) { - cli.queueRequest(types.ToRequestInitChain(params)) +func (cli *socketClient) InitChainSync(req types.RequestInitChain) (*types.ResponseInitChain, error) { + reqres := cli.queueRequest(types.ToRequestInitChain(req)) cli.FlushSync() - return cli.Error() + return reqres.Response.GetInitChain(), cli.Error() } -func (cli *socketClient) BeginBlockSync(params types.RequestBeginBlock) (err error) { - cli.queueRequest(types.ToRequestBeginBlock(params)) +func (cli *socketClient) BeginBlockSync(req types.RequestBeginBlock) (*types.ResponseBeginBlock, error) { + reqres := cli.queueRequest(types.ToRequestBeginBlock(req)) cli.FlushSync() - return cli.Error() + return reqres.Response.GetBeginBlock(), cli.Error() } -func (cli *socketClient) EndBlockSync(height uint64) (resEndBlock types.ResponseEndBlock, err error) { - reqres := cli.queueRequest(types.ToRequestEndBlock(height)) +func (cli *socketClient) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { + reqres := cli.queueRequest(types.ToRequestEndBlock(req)) cli.FlushSync() - if err := cli.Error(); err != nil { - return resEndBlock, err - } - if blk := reqres.Response.GetEndBlock(); blk != nil { - return *blk, nil - } - return resEndBlock, nil + return reqres.Response.GetEndBlock(), cli.Error() } //---------------------------------------- diff --git a/cmd/abci-cli/abci-cli.go b/cmd/abci-cli/abci-cli.go index 9962380b..18437ff7 100644 --- a/cmd/abci-cli/abci-cli.go +++ b/cmd/abci-cli/abci-cli.go @@ -10,59 +10,47 @@ import ( "os/exec" "strings" - abcicli "github.com/tendermint/abci/client" - "github.com/tendermint/abci/example/counter" - "github.com/tendermint/abci/example/dummy" - "github.com/tendermint/abci/server" - "github.com/tendermint/abci/types" - "github.com/tendermint/abci/version" + "github.com/spf13/cobra" + cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/tmlibs/log" - "github.com/spf13/cobra" + abcicli "github.com/tendermint/abci/client" + "github.com/tendermint/abci/example/code" + "github.com/tendermint/abci/example/counter" + "github.com/tendermint/abci/example/dummy" + "github.com/tendermint/abci/server" + servertest "github.com/tendermint/abci/tests/server" + "github.com/tendermint/abci/types" + "github.com/tendermint/abci/version" ) -// Structure for data passed to print response. -type response struct { - // generic abci response - Data []byte - Code types.CodeType - Log string - - Query *queryResponse -} - -type queryResponse struct { - Key []byte - Value []byte - Height uint64 - Proof []byte -} - // client is a global variable so it can be reused by the console -var client abcicli.Client - -var logger log.Logger +var ( + client abcicli.Client + logger log.Logger +) // flags var ( // global - address string - abci string - verbose bool + flagAddress string + flagAbci string + flagVerbose bool // for the println output + flagLogLevel string // for the logger // query - path string - height int - prove bool + flagPath string + flagHeight int + flagProve bool // counter - addrC string - serial bool + flagAddrC string + flagSerial bool // dummy - addrD string - persist string + flagAddrD string + flagPersist string ) var RootCmd = &cobra.Command{ @@ -79,16 +67,20 @@ var RootCmd = &cobra.Command{ } if logger == nil { - logger = log.NewFilter(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), log.AllowError()) + allowLevel, err := log.AllowLevel(flagLogLevel) + if err != nil { + return err + } + logger = log.NewFilter(log.NewTMLogger(log.NewSyncWriter(os.Stdout)), allowLevel) } if client == nil { var err error - client, err = abcicli.NewClient(address, abci, false) + client, err = abcicli.NewClient(flagAddress, flagAbci, false) if err != nil { return err } client.SetLogger(logger.With("module", "abci-client")) - if _, err := client.Start(); err != nil { + if err := client.Start(); err != nil { return err } } @@ -96,32 +88,50 @@ var RootCmd = &cobra.Command{ }, } -func Execute() { +// Structure for data passed to print response. +type response struct { + // generic abci response + Data []byte + Code uint32 + Log string + + Query *queryResponse +} + +type queryResponse struct { + Key []byte + Value []byte + Height int64 + Proof []byte +} + +func Execute() error { addGlobalFlags() addCommands() - RootCmd.Execute() + return RootCmd.Execute() } func addGlobalFlags() { - RootCmd.PersistentFlags().StringVarP(&address, "address", "", "tcp://127.0.0.1:46658", "Address of application socket") - RootCmd.PersistentFlags().StringVarP(&abci, "abci", "", "socket", "Either socket or grpc") - RootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Print the command and results as if it were a console session") + RootCmd.PersistentFlags().StringVarP(&flagAddress, "address", "", "tcp://0.0.0.0:46658", "Address of application socket") + RootCmd.PersistentFlags().StringVarP(&flagAbci, "abci", "", "socket", "Either socket or grpc") + RootCmd.PersistentFlags().BoolVarP(&flagVerbose, "verbose", "v", false, "Print the command and results as if it were a console session") + RootCmd.PersistentFlags().StringVarP(&flagLogLevel, "log_level", "", "debug", "Set the logger level") } func addQueryFlags() { - queryCmd.PersistentFlags().StringVarP(&path, "path", "", "/store", "Path to prefix query with") - queryCmd.PersistentFlags().IntVarP(&height, "height", "", 0, "Height to query the blockchain at") - queryCmd.PersistentFlags().BoolVarP(&prove, "prove", "", false, "Whether or not to return a merkle proof of the query result") + queryCmd.PersistentFlags().StringVarP(&flagPath, "path", "", "/store", "Path to prefix query with") + queryCmd.PersistentFlags().IntVarP(&flagHeight, "height", "", 0, "Height to query the blockchain at") + queryCmd.PersistentFlags().BoolVarP(&flagProve, "prove", "", false, "Whether or not to return a merkle proof of the query result") } func addCounterFlags() { - counterCmd.PersistentFlags().StringVarP(&addrC, "addr", "", "tcp://0.0.0.0:46658", "Listen address") - counterCmd.PersistentFlags().BoolVarP(&serial, "serial", "", false, "Enforce incrementing (serial) transactions") + counterCmd.PersistentFlags().StringVarP(&flagAddrC, "addr", "", "tcp://0.0.0.0:46658", "Listen address") + counterCmd.PersistentFlags().BoolVarP(&flagSerial, "serial", "", false, "Enforce incrementing (serial) transactions") } func addDummyFlags() { - dummyCmd.PersistentFlags().StringVarP(&addrD, "addr", "", "tcp://0.0.0.0:46658", "Listen address") - dummyCmd.PersistentFlags().StringVarP(&persist, "persist", "", "", "Directory to use for a database") + dummyCmd.PersistentFlags().StringVarP(&flagAddrD, "addr", "", "tcp://0.0.0.0:46658", "Listen address") + dummyCmd.PersistentFlags().StringVarP(&flagPersist, "persist", "", "", "Directory to use for a database") } func addCommands() { RootCmd.AddCommand(batchCmd) @@ -133,6 +143,7 @@ func addCommands() { RootCmd.AddCommand(checkTxCmd) RootCmd.AddCommand(commitCmd) RootCmd.AddCommand(versionCmd) + RootCmd.AddCommand(testCmd) addQueryFlags() RootCmd.AddCommand(queryCmd) @@ -263,6 +274,16 @@ var dummyCmd = &cobra.Command{ }, } +var testCmd = &cobra.Command{ + Use: "test", + Short: "Run integration tests", + Long: "", + Args: cobra.ExactArgs(0), + RunE: func(cmd *cobra.Command, args []string) error { + return cmdTest(cmd, args) + }, +} + // Generates new Args array based off of previous call args to maintain flag persistence func persistentArgs(line []byte) []string { @@ -279,6 +300,53 @@ func persistentArgs(line []byte) []string { //-------------------------------------------------------------------------------- +func or(err1 error, err2 error) error { + if err1 == nil { + return err2 + } else { + return err1 + } +} + +func cmdTest(cmd *cobra.Command, args []string) error { + fmt.Println("Running tests") + + var err error + + err = servertest.InitChain(client) + fmt.Println("") + err = or(err, servertest.SetOption(client, "serial", "on")) + fmt.Println("") + err = or(err, servertest.Commit(client, nil)) + fmt.Println("") + err = or(err, servertest.DeliverTx(client, []byte("abc"), code.CodeTypeBadNonce, nil)) + fmt.Println("") + err = or(err, servertest.Commit(client, nil)) + fmt.Println("") + err = or(err, servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeOK, nil)) + fmt.Println("") + err = or(err, servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 1})) + fmt.Println("") + err = or(err, servertest.DeliverTx(client, []byte{0x00}, code.CodeTypeBadNonce, nil)) + fmt.Println("") + err = or(err, servertest.DeliverTx(client, []byte{0x01}, code.CodeTypeOK, nil)) + fmt.Println("") + err = or(err, servertest.DeliverTx(client, []byte{0x00, 0x02}, code.CodeTypeOK, nil)) + fmt.Println("") + err = or(err, servertest.DeliverTx(client, []byte{0x00, 0x03}, code.CodeTypeOK, nil)) + fmt.Println("") + err = or(err, servertest.DeliverTx(client, []byte{0x00, 0x00, 0x04}, code.CodeTypeOK, nil)) + fmt.Println("") + err = or(err, servertest.DeliverTx(client, []byte{0x00, 0x00, 0x06}, code.CodeTypeBadNonce, nil)) + fmt.Println("") + err = or(err, servertest.Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 5})) + + if err != nil { + return errors.New("Some checks didn't pass, please inspect stdout to see the exact failures.") + } + return nil +} + func cmdBatch(cmd *cobra.Command, args []string) error { bufReader := bufio.NewReader(os.Stdin) for { @@ -294,7 +362,7 @@ func cmdBatch(cmd *cobra.Command, args []string) error { } pArgs := persistentArgs(line) - out, err := exec.Command(pArgs[0], pArgs[1:]...).Output() + out, err := exec.Command(pArgs[0], pArgs[1:]...).Output() // nolint: gas if err != nil { return err } @@ -316,7 +384,7 @@ func cmdConsole(cmd *cobra.Command, args []string) error { } pArgs := persistentArgs(line) - out, err := exec.Command(pArgs[0], pArgs[1:]...).Output() + out, err := exec.Command(pArgs[0], pArgs[1:]...).Output() // nolint: gas if err != nil { return err } @@ -327,9 +395,12 @@ func cmdConsole(cmd *cobra.Command, args []string) error { // Have the application echo a message func cmdEcho(cmd *cobra.Command, args []string) error { - resEcho := client.EchoSync(args[0]) + res, err := client.EchoSync(args[0]) + if err != nil { + return err + } printResponse(cmd, args, response{ - Data: resEcho.Data, + Data: []byte(res.Message), }) return nil } @@ -340,21 +411,26 @@ func cmdInfo(cmd *cobra.Command, args []string) error { if len(args) == 1 { version = args[0] } - resInfo, err := client.InfoSync(types.RequestInfo{version}) + res, err := client.InfoSync(types.RequestInfo{version}) if err != nil { return err } printResponse(cmd, args, response{ - Data: []byte(resInfo.Data), + Data: []byte(res.Data), }) return nil } // Set an option on the application func cmdSetOption(cmd *cobra.Command, args []string) error { - resSetOption := client.SetOptionSync(args[0], args[1]) + key, val := args[0], args[1] + res, err := client.SetOptionSync(types.RequestSetOption{key, val}) + if err != nil { + return err + } printResponse(cmd, args, response{ - Log: resSetOption.Log, + Code: res.Code, + Log: res.Log, }) return nil } @@ -365,7 +441,10 @@ func cmdDeliverTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - res := client.DeliverTxSync(txBytes) + res, err := client.DeliverTxSync(txBytes) + if err != nil { + return err + } printResponse(cmd, args, response{ Code: res.Code, Data: res.Data, @@ -380,7 +459,10 @@ func cmdCheckTx(cmd *cobra.Command, args []string) error { if err != nil { return err } - res := client.CheckTxSync(txBytes) + res, err := client.CheckTxSync(txBytes) + if err != nil { + return err + } printResponse(cmd, args, response{ Code: res.Code, Data: res.Data, @@ -391,7 +473,10 @@ func cmdCheckTx(cmd *cobra.Command, args []string) error { // Get application Merkle root hash func cmdCommit(cmd *cobra.Command, args []string) error { - res := client.CommitSync() + res, err := client.CommitSync() + if err != nil { + return err + } printResponse(cmd, args, response{ Code: res.Code, Data: res.Data, @@ -409,9 +494,9 @@ func cmdQuery(cmd *cobra.Command, args []string) error { resQuery, err := client.QuerySync(types.RequestQuery{ Data: queryBytes, - Path: path, - Height: uint64(height), - Prove: prove, + Path: flagPath, + Height: int64(flagHeight), + Prove: flagProve, }) if err != nil { return err @@ -431,17 +516,17 @@ func cmdQuery(cmd *cobra.Command, args []string) error { func cmdCounter(cmd *cobra.Command, args []string) error { - app := counter.NewCounterApplication(serial) + app := counter.NewCounterApplication(flagSerial) logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) // Start the listener - srv, err := server.NewServer(addrC, abci, app) + srv, err := server.NewServer(flagAddrC, flagAbci, app) if err != nil { return err } srv.SetLogger(logger.With("module", "abci-server")) - if _, err := srv.Start(); err != nil { + if err := srv.Start(); err != nil { return err } @@ -458,20 +543,20 @@ func cmdDummy(cmd *cobra.Command, args []string) error { // Create the application - in memory or persisted to disk var app types.Application - if persist == "" { + if flagPersist == "" { app = dummy.NewDummyApplication() } else { - app = dummy.NewPersistentDummyApplication(persist) + app = dummy.NewPersistentDummyApplication(flagPersist) app.(*dummy.PersistentDummyApplication).SetLogger(logger.With("module", "dummy")) } // Start the listener - srv, err := server.NewServer(addrD, abci, app) + srv, err := server.NewServer(flagAddrD, flagAbci, app) if err != nil { return err } srv.SetLogger(logger.With("module", "abci-server")) - if _, err := srv.Start(); err != nil { + if err := srv.Start(); err != nil { return err } @@ -487,12 +572,17 @@ func cmdDummy(cmd *cobra.Command, args []string) error { func printResponse(cmd *cobra.Command, args []string, rsp response) { - if verbose { + if flagVerbose { fmt.Println(">", cmd.Use, strings.Join(args, " ")) } // Always print the status code. - fmt.Printf("-> code: %s\n", rsp.Code.String()) + if rsp.Code == types.CodeTypeOK { + fmt.Printf("-> code: OK\n") + } else { + fmt.Printf("-> code: %d\n", rsp.Code) + + } if len(rsp.Data) != 0 { // Do no print this line when using the commit command diff --git a/cmd/abci-cli/main.go b/cmd/abci-cli/main.go index 736ef310..a927e7ed 100644 --- a/cmd/abci-cli/main.go +++ b/cmd/abci-cli/main.go @@ -1,5 +1,14 @@ package main +import ( + "fmt" + "os" +) + func main() { - Execute() + err := Execute() + if err != nil { + fmt.Print(err) + os.Exit(1) + } } diff --git a/example/block_aware/block_aware_app.go b/example/block_aware/block_aware_app.go deleted file mode 100644 index 8a031da2..00000000 --- a/example/block_aware/block_aware_app.go +++ /dev/null @@ -1,65 +0,0 @@ -package main - -import ( - "flag" - "os" - - "github.com/tendermint/abci/server" - "github.com/tendermint/abci/types" - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" -) - -func main() { - - addrPtr := flag.String("addr", "tcp://0.0.0.0:46658", "Listen address") - abciPtr := flag.String("abci", "socket", "socket | grpc") - flag.Parse() - - logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) - - // Start the listener - srv, err := server.NewServer(*addrPtr, *abciPtr, NewChainAwareApplication()) - if err != nil { - logger.Error(err.Error()) - os.Exit(1) - } - srv.SetLogger(logger.With("module", "abci-server")) - if _, err := srv.Start(); err != nil { - logger.Error(err.Error()) - os.Exit(1) - } - - // Wait forever - cmn.TrapSignal(func() { - // Cleanup - srv.Stop() - }) - -} - -type ChainAwareApplication struct { - types.BaseApplication - - beginCount int - endCount int -} - -func NewChainAwareApplication() *ChainAwareApplication { - return &ChainAwareApplication{} -} - -func (app *ChainAwareApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) { - return types.ResponseQuery{ - Value: []byte(cmn.Fmt("%d,%d", app.beginCount, app.endCount)), - } -} - -func (app *ChainAwareApplication) BeginBlock(reqBeginBlock types.RequestBeginBlock) { - app.beginCount++ -} - -func (app *ChainAwareApplication) EndBlock(height uint64) (resEndBlock types.ResponseEndBlock) { - app.endCount++ - return -} diff --git a/example/block_aware/block_aware_test.go b/example/block_aware/block_aware_test.go deleted file mode 100644 index 2777ce1a..00000000 --- a/example/block_aware/block_aware_test.go +++ /dev/null @@ -1,57 +0,0 @@ -package main - -import ( - "strconv" - "strings" - "testing" - - abcicli "github.com/tendermint/abci/client" - "github.com/tendermint/abci/server" - "github.com/tendermint/abci/types" - "github.com/tendermint/tmlibs/log" -) - -func TestChainAware(t *testing.T) { - app := NewChainAwareApplication() - - // Start the listener - srv, err := server.NewServer("unix://test.sock", "socket", app) - if err != nil { - t.Fatal(err) - } - srv.SetLogger(log.TestingLogger().With("module", "abci-server")) - if _, err := srv.Start(); err != nil { - t.Fatal(err.Error()) - } - defer srv.Stop() - - // Connect to the socket - client := abcicli.NewSocketClient("unix://test.sock", false) - client.SetLogger(log.TestingLogger().With("module", "abci-client")) - if _, err := client.Start(); err != nil { - t.Fatalf("Error starting socket client: %v", err.Error()) - } - defer client.Stop() - - n := uint64(5) - hash := []byte("fake block hash") - header := &types.Header{} - for i := uint64(0); i < n; i++ { - client.BeginBlockSync(types.RequestBeginBlock{hash, header}) - client.EndBlockSync(i) - client.CommitSync() - } - - r := app.Query(types.RequestQuery{}) - spl := strings.Split(string(r.Value), ",") - if len(spl) != 2 { - t.Fatal("expected %d,%d ; got %s", n, n, string(r.Value)) - } - beginCount, _ := strconv.Atoi(spl[0]) - endCount, _ := strconv.Atoi(spl[1]) - if uint64(beginCount) != n { - t.Fatalf("expected beginCount of %d, got %d", n, beginCount) - } else if uint64(endCount) != n { - t.Fatalf("expected endCount of %d, got %d", n, endCount) - } -} diff --git a/example/code/code.go b/example/code/code.go new file mode 100644 index 00000000..b7e37d36 --- /dev/null +++ b/example/code/code.go @@ -0,0 +1,11 @@ +package code + +// Return codes for the examples +const ( + CodeTypeOK uint32 = 0 + CodeTypeEncodingError uint32 = 1 + CodeTypeBadNonce uint32 = 2 + CodeTypeUnauthorized uint32 = 3 + + CodeTypeBadOption uint32 = 101 +) diff --git a/example/counter/counter.go b/example/counter/counter.go index d2478ae2..abd7bb18 100644 --- a/example/counter/counter.go +++ b/example/counter/counter.go @@ -2,7 +2,9 @@ package counter import ( "encoding/binary" + "fmt" + "github.com/tendermint/abci/example/code" "github.com/tendermint/abci/types" cmn "github.com/tendermint/tmlibs/common" ) @@ -23,52 +25,69 @@ func (app *CounterApplication) Info(req types.RequestInfo) types.ResponseInfo { return types.ResponseInfo{Data: cmn.Fmt("{\"hashes\":%v,\"txs\":%v}", app.hashCount, app.txCount)} } -func (app *CounterApplication) SetOption(key string, value string) (log string) { +func (app *CounterApplication) SetOption(req types.RequestSetOption) types.ResponseSetOption { + key, value := req.Key, req.Value if key == "serial" && value == "on" { app.serial = true + } else { + return types.ResponseSetOption{ + Code: code.CodeTypeBadOption, + Log: cmn.Fmt("Unknown key (%s) or value (%s)", key, value), + } + } + + return types.ResponseSetOption{ + Code: code.CodeTypeOK, } - return "" } -func (app *CounterApplication) DeliverTx(tx []byte) types.Result { +func (app *CounterApplication) DeliverTx(tx []byte) types.ResponseDeliverTx { if app.serial { if len(tx) > 8 { - return types.ErrEncodingError.SetLog(cmn.Fmt("Max tx size is 8 bytes, got %d", len(tx))) + return types.ResponseDeliverTx{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("Max tx size is 8 bytes, got %d", len(tx))} } tx8 := make([]byte, 8) copy(tx8[len(tx8)-len(tx):], tx) txValue := binary.BigEndian.Uint64(tx8) if txValue != uint64(app.txCount) { - return types.ErrBadNonce.SetLog(cmn.Fmt("Invalid nonce. Expected %v, got %v", app.txCount, txValue)) + return types.ResponseDeliverTx{ + Code: code.CodeTypeBadNonce, + Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.txCount, txValue)} } } app.txCount++ - return types.OK + return types.ResponseDeliverTx{Code: code.CodeTypeOK} } -func (app *CounterApplication) CheckTx(tx []byte) types.Result { +func (app *CounterApplication) CheckTx(tx []byte) types.ResponseCheckTx { if app.serial { if len(tx) > 8 { - return types.ErrEncodingError.SetLog(cmn.Fmt("Max tx size is 8 bytes, got %d", len(tx))) + return types.ResponseCheckTx{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("Max tx size is 8 bytes, got %d", len(tx))} } tx8 := make([]byte, 8) copy(tx8[len(tx8)-len(tx):], tx) txValue := binary.BigEndian.Uint64(tx8) if txValue < uint64(app.txCount) { - return types.ErrBadNonce.SetLog(cmn.Fmt("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue)) + return types.ResponseCheckTx{ + Code: code.CodeTypeBadNonce, + Log: fmt.Sprintf("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue)} } } - return types.OK + return types.ResponseCheckTx{Code: code.CodeTypeOK} } -func (app *CounterApplication) Commit() types.Result { +func (app *CounterApplication) Commit() (resp types.ResponseCommit) { app.hashCount++ if app.txCount == 0 { - return types.OK + return types.ResponseCommit{Code: code.CodeTypeOK} } hash := make([]byte, 8) binary.BigEndian.PutUint64(hash, uint64(app.txCount)) - return types.NewResultOK(hash, "") + return types.ResponseCommit{Code: code.CodeTypeOK, Data: hash} } func (app *CounterApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery { diff --git a/example/dummy/dummy.go b/example/dummy/dummy.go index 7e95c859..fdb4851c 100644 --- a/example/dummy/dummy.go +++ b/example/dummy/dummy.go @@ -1,15 +1,18 @@ package dummy import ( - "strings" + "bytes" + "fmt" + "github.com/tendermint/abci/example/code" "github.com/tendermint/abci/types" wire "github.com/tendermint/go-wire" "github.com/tendermint/iavl" - cmn "github.com/tendermint/tmlibs/common" dbm "github.com/tendermint/tmlibs/db" ) +var _ types.Application = (*DummyApplication)(nil) + type DummyApplication struct { types.BaseApplication @@ -22,25 +25,32 @@ func NewDummyApplication() *DummyApplication { } func (app *DummyApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) { - return types.ResponseInfo{Data: cmn.Fmt("{\"size\":%v}", app.state.Size())} + return types.ResponseInfo{Data: fmt.Sprintf("{\"size\":%v}", app.state.Size())} } // tx is either "key=value" or just arbitrary bytes -func (app *DummyApplication) DeliverTx(tx []byte) types.Result { - parts := strings.Split(string(tx), "=") +func (app *DummyApplication) DeliverTx(tx []byte) types.ResponseDeliverTx { + var key, value []byte + parts := bytes.Split(tx, []byte("=")) if len(parts) == 2 { - app.state.Set([]byte(parts[0]), []byte(parts[1])) + key, value = parts[0], parts[1] } else { - app.state.Set(tx, tx) + key, value = tx, tx } - return types.OK + app.state.Set(key, value) + + tags := []*types.KVPair{ + {Key: "app.creator", ValueType: types.KVPair_STRING, ValueString: "jae"}, + {Key: "app.key", ValueType: types.KVPair_STRING, ValueString: string(key)}, + } + return types.ResponseDeliverTx{Code: code.CodeTypeOK, Tags: tags} } -func (app *DummyApplication) CheckTx(tx []byte) types.Result { - return types.OK +func (app *DummyApplication) CheckTx(tx []byte) types.ResponseCheckTx { + return types.ResponseCheckTx{Code: code.CodeTypeOK} } -func (app *DummyApplication) Commit() types.Result { +func (app *DummyApplication) Commit() types.ResponseCommit { // Save a new version var hash []byte var err error @@ -55,7 +65,7 @@ func (app *DummyApplication) Commit() types.Result { } } - return types.NewResultOK(hash, "") + return types.ResponseCommit{Code: code.CodeTypeOK, Data: hash} } func (app *DummyApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) { diff --git a/example/dummy/dummy_test.go b/example/dummy/dummy_test.go index efbc5af7..bfe9ef7a 100644 --- a/example/dummy/dummy_test.go +++ b/example/dummy/dummy_test.go @@ -7,12 +7,15 @@ import ( "testing" "github.com/stretchr/testify/require" - abcicli "github.com/tendermint/abci/client" - abciserver "github.com/tendermint/abci/server" - "github.com/tendermint/abci/types" + "github.com/tendermint/iavl" cmn "github.com/tendermint/tmlibs/common" "github.com/tendermint/tmlibs/log" + + abcicli "github.com/tendermint/abci/client" + "github.com/tendermint/abci/example/code" + abciserver "github.com/tendermint/abci/server" + "github.com/tendermint/abci/types" ) func testDummy(t *testing.T, app types.Application, tx []byte, key, value string) { @@ -27,7 +30,7 @@ func testDummy(t *testing.T, app types.Application, tx []byte, key, value string Path: "/store", Data: []byte(key), }) - require.Equal(t, types.CodeType_OK, resQuery.Code) + require.Equal(t, code.CodeTypeOK, resQuery.Code) require.Equal(t, value, string(resQuery.Value)) // make sure proof is fine @@ -36,7 +39,7 @@ func testDummy(t *testing.T, app types.Application, tx []byte, key, value string Data: []byte(key), Prove: true, }) - require.Equal(t, types.CodeType_OK, resQuery.Code) + require.EqualValues(t, code.CodeTypeOK, resQuery.Code) require.Equal(t, value, string(resQuery.Value)) proof, err := iavl.ReadKeyExistsProof(resQuery.Proof) require.Nil(t, err) @@ -79,7 +82,7 @@ func TestPersistentDummyInfo(t *testing.T) { } dummy := NewPersistentDummyApplication(dir) InitDummy(dummy) - height := uint64(0) + height := int64(0) resInfo := dummy.Info(types.RequestInfo{}) if resInfo.LastBlockHeight != height { @@ -87,13 +90,13 @@ func TestPersistentDummyInfo(t *testing.T) { } // make and apply block - height = uint64(1) + height = int64(1) hash := []byte("foo") header := &types.Header{ - Height: uint64(height), + Height: int64(height), } - dummy.BeginBlock(types.RequestBeginBlock{hash, header}) - dummy.EndBlock(height) + dummy.BeginBlock(types.RequestBeginBlock{hash, header, nil, nil}) + dummy.EndBlock(types.RequestEndBlock{header.Height}) dummy.Commit() resInfo = dummy.Info(types.RequestInfo{}) @@ -170,19 +173,19 @@ func TestValSetChanges(t *testing.T) { func makeApplyBlock(t *testing.T, dummy types.Application, heightInt int, diff []*types.Validator, txs ...[]byte) { // make and apply block - height := uint64(heightInt) + height := int64(heightInt) hash := []byte("foo") header := &types.Header{ Height: height, } - dummy.BeginBlock(types.RequestBeginBlock{hash, header}) + dummy.BeginBlock(types.RequestBeginBlock{hash, header, nil, nil}) for _, tx := range txs { if r := dummy.DeliverTx(tx); r.IsErr() { t.Fatal(r) } } - resEndBlock := dummy.EndBlock(height) + resEndBlock := dummy.EndBlock(types.RequestEndBlock{header.Height}) dummy.Commit() valsEqual(t, diff, resEndBlock.Diffs) @@ -212,14 +215,14 @@ func makeSocketClientServer(app types.Application, name string) (abcicli.Client, server := abciserver.NewSocketServer(socket, app) server.SetLogger(logger.With("module", "abci-server")) - if _, err := server.Start(); err != nil { + if err := server.Start(); err != nil { return nil, nil, err } // Connect to the socket client := abcicli.NewSocketClient(socket, false) client.SetLogger(logger.With("module", "abci-client")) - if _, err := client.Start(); err != nil { + if err := client.Start(); err != nil { server.Stop() return nil, nil, err } @@ -235,13 +238,13 @@ func makeGRPCClientServer(app types.Application, name string) (abcicli.Client, c gapp := types.NewGRPCApplication(app) server := abciserver.NewGRPCServer(socket, gapp) server.SetLogger(logger.With("module", "abci-server")) - if _, err := server.Start(); err != nil { + if err := server.Start(); err != nil { return nil, nil, err } client := abcicli.NewGRPCClient(socket, true) client.SetLogger(logger.With("module", "abci-client")) - if _, err := client.Start(); err != nil { + if err := client.Start(); err != nil { server.Stop() return nil, nil, err } @@ -281,10 +284,12 @@ func runClientTests(t *testing.T, client abcicli.Client) { } func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) { - ar := app.DeliverTxSync(tx) + ar, err := app.DeliverTxSync(tx) + require.NoError(t, err) require.False(t, ar.IsErr(), ar) // repeating tx doesn't raise error - ar = app.DeliverTxSync(tx) + ar, err = app.DeliverTxSync(tx) + require.NoError(t, err) require.False(t, ar.IsErr(), ar) // make sure query is fine @@ -293,7 +298,7 @@ func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) Data: []byte(key), }) require.Nil(t, err) - require.Equal(t, types.CodeType_OK, resQuery.Code) + require.Equal(t, code.CodeTypeOK, resQuery.Code) require.Equal(t, value, string(resQuery.Value)) // make sure proof is fine @@ -303,7 +308,7 @@ func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) Prove: true, }) require.Nil(t, err) - require.Equal(t, types.CodeType_OK, resQuery.Code) + require.Equal(t, code.CodeTypeOK, resQuery.Code) require.Equal(t, value, string(resQuery.Value)) proof, err := iavl.ReadKeyExistsProof(resQuery.Proof) require.Nil(t, err) diff --git a/example/dummy/helpers.go b/example/dummy/helpers.go index 55c464de..d6b4338c 100644 --- a/example/dummy/helpers.go +++ b/example/dummy/helpers.go @@ -11,7 +11,7 @@ import ( func RandVal(i int) *types.Validator { pubkey := crypto.GenPrivKeyEd25519FromSecret([]byte(cmn.Fmt("test%d", i))).PubKey().Bytes() power := cmn.RandUint16() + 1 - return &types.Validator{pubkey, uint64(power)} + return &types.Validator{pubkey, int64(power)} } // RandVals returns a list of cnt validators for initializing diff --git a/example/dummy/persistent_dummy.go b/example/dummy/persistent_dummy.go index 4c480175..6f389c50 100644 --- a/example/dummy/persistent_dummy.go +++ b/example/dummy/persistent_dummy.go @@ -3,9 +3,11 @@ package dummy import ( "bytes" "encoding/hex" + "fmt" "strconv" "strings" + "github.com/tendermint/abci/example/code" "github.com/tendermint/abci/types" crypto "github.com/tendermint/go-crypto" "github.com/tendermint/iavl" @@ -20,6 +22,8 @@ const ( //----------------------------------------- +var _ types.Application = (*PersistentDummyApplication)(nil) + type PersistentDummyApplication struct { app *DummyApplication @@ -49,19 +53,20 @@ func (app *PersistentDummyApplication) SetLogger(l log.Logger) { app.logger = l } -func (app *PersistentDummyApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) { - resInfo = app.app.Info(req) - resInfo.LastBlockHeight = app.app.state.LatestVersion() - resInfo.LastBlockAppHash = app.app.state.Hash() - return resInfo +func (app *PersistentDummyApplication) Info(req types.RequestInfo) types.ResponseInfo { + res := app.app.Info(req) + var latestVersion uint64 = app.app.state.LatestVersion() // TODO: change to int64 + res.LastBlockHeight = int64(latestVersion) + res.LastBlockAppHash = app.app.state.Hash() + return res } -func (app *PersistentDummyApplication) SetOption(key string, value string) (log string) { - return app.app.SetOption(key, value) +func (app *PersistentDummyApplication) SetOption(req types.RequestSetOption) types.ResponseSetOption { + return app.app.SetOption(req) } // tx is either "val:pubkey/power" or "key=value" or just arbitrary bytes -func (app *PersistentDummyApplication) DeliverTx(tx []byte) types.Result { +func (app *PersistentDummyApplication) DeliverTx(tx []byte) types.ResponseDeliverTx { // if it starts with "val:", update the validator set // format is "val:pubkey/power" if isValidatorTx(tx) { @@ -74,12 +79,12 @@ func (app *PersistentDummyApplication) DeliverTx(tx []byte) types.Result { return app.app.DeliverTx(tx) } -func (app *PersistentDummyApplication) CheckTx(tx []byte) types.Result { +func (app *PersistentDummyApplication) CheckTx(tx []byte) types.ResponseCheckTx { return app.app.CheckTx(tx) } // Commit will panic if InitChain was not called -func (app *PersistentDummyApplication) Commit() types.Result { +func (app *PersistentDummyApplication) Commit() types.ResponseCommit { // Save a new version for next height height := app.app.state.LatestVersion() + 1 @@ -93,7 +98,7 @@ func (app *PersistentDummyApplication) Commit() types.Result { } app.logger.Info("Commit block", "height", height, "root", appHash) - return types.NewResultOK(appHash, "") + return types.ResponseCommit{Code: code.CodeTypeOK, Data: appHash} } func (app *PersistentDummyApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery { @@ -101,23 +106,25 @@ func (app *PersistentDummyApplication) Query(reqQuery types.RequestQuery) types. } // Save the validators in the merkle tree -func (app *PersistentDummyApplication) InitChain(params types.RequestInitChain) { - for _, v := range params.Validators { +func (app *PersistentDummyApplication) InitChain(req types.RequestInitChain) types.ResponseInitChain { + for _, v := range req.Validators { r := app.updateValidator(v) if r.IsErr() { app.logger.Error("Error updating validators", "r", r) } } + return types.ResponseInitChain{} } // Track the block hash and header information -func (app *PersistentDummyApplication) BeginBlock(params types.RequestBeginBlock) { +func (app *PersistentDummyApplication) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock { // reset valset changes app.changes = make([]*types.Validator, 0) + return types.ResponseBeginBlock{} } // Update the validator set -func (app *PersistentDummyApplication) EndBlock(height uint64) (resEndBlock types.ResponseEndBlock) { +func (app *PersistentDummyApplication) EndBlock(req types.RequestEndBlock) types.ResponseEndBlock { return types.ResponseEndBlock{Diffs: app.changes} } @@ -139,7 +146,7 @@ func (app *PersistentDummyApplication) Validators() (validators []*types.Validat return } -func MakeValSetChangeTx(pubkey []byte, power uint64) []byte { +func MakeValSetChangeTx(pubkey []byte, power int64) []byte { return []byte(cmn.Fmt("val:%X/%d", pubkey, power)) } @@ -148,50 +155,62 @@ func isValidatorTx(tx []byte) bool { } // format is "val:pubkey1/power1,addr2/power2,addr3/power3"tx -func (app *PersistentDummyApplication) execValidatorTx(tx []byte) types.Result { +func (app *PersistentDummyApplication) execValidatorTx(tx []byte) types.ResponseDeliverTx { tx = tx[len(ValidatorSetChangePrefix):] //get the pubkey and power pubKeyAndPower := strings.Split(string(tx), "/") if len(pubKeyAndPower) != 2 { - return types.ErrEncodingError.SetLog(cmn.Fmt("Expected 'pubkey/power'. Got %v", pubKeyAndPower)) + return types.ResponseDeliverTx{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("Expected 'pubkey/power'. Got %v", pubKeyAndPower)} } pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1] // decode the pubkey, ensuring its go-crypto encoded pubkey, err := hex.DecodeString(pubkeyS) if err != nil { - return types.ErrEncodingError.SetLog(cmn.Fmt("Pubkey (%s) is invalid hex", pubkeyS)) + return types.ResponseDeliverTx{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("Pubkey (%s) is invalid hex", pubkeyS)} } _, err = crypto.PubKeyFromBytes(pubkey) if err != nil { - return types.ErrEncodingError.SetLog(cmn.Fmt("Pubkey (%X) is invalid go-crypto encoded", pubkey)) + return types.ResponseDeliverTx{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("Pubkey (%X) is invalid go-crypto encoded", pubkey)} } // decode the power - power, err := strconv.Atoi(powerS) + power, err := strconv.ParseInt(powerS, 10, 64) if err != nil { - return types.ErrEncodingError.SetLog(cmn.Fmt("Power (%s) is not an int", powerS)) + return types.ResponseDeliverTx{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("Power (%s) is not an int", powerS)} } // update - return app.updateValidator(&types.Validator{pubkey, uint64(power)}) + return app.updateValidator(&types.Validator{pubkey, power}) } // add, update, or remove a validator -func (app *PersistentDummyApplication) updateValidator(v *types.Validator) types.Result { +func (app *PersistentDummyApplication) updateValidator(v *types.Validator) types.ResponseDeliverTx { key := []byte("val:" + string(v.PubKey)) if v.Power == 0 { // remove validator if !app.app.state.Has(key) { - return types.ErrUnauthorized.SetLog(cmn.Fmt("Cannot remove non-existent validator %X", key)) + return types.ResponseDeliverTx{ + Code: code.CodeTypeUnauthorized, + Log: fmt.Sprintf("Cannot remove non-existent validator %X", key)} } app.app.state.Remove(key) } else { // add or update validator value := bytes.NewBuffer(make([]byte, 0)) if err := types.WriteMessage(v, value); err != nil { - return types.ErrInternalError.SetLog(cmn.Fmt("Error encoding validator: %v", err)) + return types.ResponseDeliverTx{ + Code: code.CodeTypeEncodingError, + Log: fmt.Sprintf("Error encoding validator: %v", err)} } app.app.state.Set(key, value.Bytes()) } @@ -199,5 +218,5 @@ func (app *PersistentDummyApplication) updateValidator(v *types.Validator) types // we only update the changes array if we successfully updated the tree app.changes = append(app.changes, v) - return types.OK + return types.ResponseDeliverTx{Code: code.CodeTypeOK} } diff --git a/example/example_test.go b/example/example_test.go index 496ed3d3..dfa38a39 100644 --- a/example/example_test.go +++ b/example/example_test.go @@ -11,12 +11,14 @@ import ( "golang.org/x/net/context" + cmn "github.com/tendermint/tmlibs/common" + "github.com/tendermint/tmlibs/log" + abcicli "github.com/tendermint/abci/client" + "github.com/tendermint/abci/example/code" "github.com/tendermint/abci/example/dummy" abciserver "github.com/tendermint/abci/server" "github.com/tendermint/abci/types" - cmn "github.com/tendermint/tmlibs/common" - "github.com/tendermint/tmlibs/log" ) func TestDummy(t *testing.T) { @@ -40,7 +42,7 @@ func testStream(t *testing.T, app types.Application) { // Start the listener server := abciserver.NewSocketServer("unix://test.sock", app) server.SetLogger(log.TestingLogger().With("module", "abci-server")) - if _, err := server.Start(); err != nil { + if err := server.Start(); err != nil { t.Fatalf("Error starting socket server: %v", err.Error()) } defer server.Stop() @@ -48,7 +50,7 @@ func testStream(t *testing.T, app types.Application) { // Connect to the socket client := abcicli.NewSocketClient("unix://test.sock", false) client.SetLogger(log.TestingLogger().With("module", "abci-client")) - if _, err := client.Start(); err != nil { + if err := client.Start(); err != nil { t.Fatalf("Error starting socket client: %v", err.Error()) } defer client.Stop() @@ -60,7 +62,7 @@ func testStream(t *testing.T, app types.Application) { switch r := res.Value.(type) { case *types.Response_DeliverTx: counter++ - if r.DeliverTx.Code != types.CodeType_OK { + if r.DeliverTx.Code != code.CodeTypeOK { t.Error("DeliverTx failed with ret_code", r.DeliverTx.Code) } if counter > numDeliverTxs { @@ -113,7 +115,7 @@ func testGRPCSync(t *testing.T, app *types.GRPCApplication) { // Start the listener server := abciserver.NewGRPCServer("unix://test.sock", app) server.SetLogger(log.TestingLogger().With("module", "abci-server")) - if _, err := server.Start(); err != nil { + if err := server.Start(); err != nil { t.Fatalf("Error starting GRPC server: %v", err.Error()) } defer server.Stop() @@ -135,7 +137,7 @@ func testGRPCSync(t *testing.T, app *types.GRPCApplication) { t.Fatalf("Error in GRPC DeliverTx: %v", err.Error()) } counter++ - if response.Code != types.CodeType_OK { + if response.Code != code.CodeTypeOK { t.Error("DeliverTx failed with ret_code", response.Code) } if counter > numDeliverTxs { diff --git a/glide.lock b/glide.lock index 80dbc483..f96fd1c0 100644 --- a/glide.lock +++ b/glide.lock @@ -1,14 +1,12 @@ -hash: 5501ab3d7136aa8fb425c995d45221849b33aefab76c5d2c192e721dad28da38 -updated: 2017-11-14T18:23:41.2024073Z +hash: 6cb2c869c8ce7d9e43b1e8930b9b1bc974ebb3d36d4b704fc78b77efba956a13 +updated: 2017-11-30T17:08:29.176515576-05:00 imports: - name: github.com/btcsuite/btcd - version: b8df516b4b267acf2de46be593a9d948d1d2c420 + version: 2e60448ffcc6bf78332d1fe590260095f554dd78 subpackages: - btcec -- name: github.com/btcsuite/fastsha256 - version: 637e656429416087660c84436a2a035d69d54e2e - name: github.com/go-kit/kit - version: d67bb4c202e3b91377d1079b110a6c9ce23ab2f8 + version: e3b2152e0063c5f05efea89ecbe297852af2a92d subpackages: - log - log/level @@ -16,15 +14,21 @@ imports: - name: github.com/go-logfmt/logfmt version: 390ab7935ee28ec6b286364bba9b4dd6410cb3d5 - name: github.com/go-playground/locales - version: 1e5f1161c6416a5ff48840eb8724a394e48cc534 + version: e4cbcb5d0652150d40ad0646651076b6bd2be4f6 subpackages: - currency - name: github.com/go-playground/universal-translator version: 71201497bace774495daed26a3874fd339e0b538 - name: github.com/go-stack/stack - version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82 + version: 259ab82a6cad3992b4e21ff5cac294ccb06474bc +- name: github.com/gogo/protobuf + version: 342cbe0a04158f6dcb03ca0079991a51a4248c02 + subpackages: + - gogoproto + - proto + - protoc-gen-gogo/descriptor - name: github.com/golang/protobuf - version: 1643683e1b54a9e88ad26d98f81400c8c9d9f4f9 + version: 1e59b77b52bf8e4b449a57e6f79f21226d571845 subpackages: - proto - ptypes @@ -40,13 +44,13 @@ imports: - name: github.com/kr/logfmt version: b84e30acd515aadc4b783ad4ff83aff3299bdfe0 - name: github.com/pkg/errors - version: 645ef00459ed84a119197bfb8d8205042c6df63d + version: f15c970de5b76fac0b59abb32d62c17cc7bed265 - name: github.com/spf13/cobra version: 7b2c5ac9fc04fc5efafb60700713d4fa609b777b - name: github.com/spf13/pflag - version: 80fe0fb4eba54167e2ccae1c6c950e72abf61b73 + version: 4c012f6dcd9546820e378d0bdda4d8fc772cdfea - name: github.com/syndtr/goleveldb - version: 8c81ea47d4c41a385645e133e15510fc6a2a74b4 + version: adf24ef3f94bd13ec4163060b21a5678f22b429b subpackages: - leveldb - leveldb/cache @@ -61,27 +65,27 @@ imports: - leveldb/table - leveldb/util - name: github.com/tendermint/ed25519 - version: 1f52c6f8b8a5c7908aff4497c186af344b428925 + version: d8387025d2b9d158cf4efb07e7ebf814bcce2057 subpackages: - edwards25519 - extra25519 - name: github.com/tendermint/go-crypto version: b4f04f196cd719660e43b91202cd60d9a95b1837 - name: github.com/tendermint/go-wire - version: 1c96861c03231361546944d883d99593b2e6b408 + version: 5ab49b4c6ad674da6b81442911cf713ef0afb544 subpackages: - data - name: github.com/tendermint/iavl version: 595f3dcd5b6cd4a292e90757ae6d367fd7a6e653 - name: github.com/tendermint/tmlibs - version: 2442a0a698d271d5cf5d6a8e7c1db20335e959c1 + version: 21fb7819891997c96838308b4eba5a50b07ff03f subpackages: - common - db - log - process - name: golang.org/x/crypto - version: c7af5bf2638a1164f2eb5467c39c6cffbd13a02e + version: 94eea52f7b742c7cbe0b03b22f0c4c8631ece122 subpackages: - nacl/secretbox - openpgp/armor @@ -90,7 +94,7 @@ imports: - ripemd160 - salsa20/salsa - name: golang.org/x/net - version: cd69bc3fc700721b709c3a59e16e24c67b58f6ff + version: a8b9294777976932365dabb6640cf1468d95c70f subpackages: - context - http2 @@ -100,18 +104,18 @@ imports: - lex/httplex - trace - name: golang.org/x/text - version: 470f45bf29f4147d6fbd7dfd0a02a848e49f5bf4 + version: 75cc3cad82b5f47d3fb229ddda8c5167da14f294 subpackages: - secure/bidirule - transform - unicode/bidi - unicode/norm - name: google.golang.org/genproto - version: f676e0f3ac6395ff1a529ae59a6670878a8371a6 + version: 7f0da29060c682909f650ad8ed4e515bd74fa12a subpackages: - googleapis/rpc/status - name: google.golang.org/grpc - version: f7bf885db0b7479a537ec317c6e48ce53145f3db + version: 401e0e00e4bb830a10496d64cd95e068c5bf50de subpackages: - balancer - codes @@ -130,10 +134,10 @@ imports: - tap - transport - name: gopkg.in/go-playground/validator.v9 - version: 6d8c18553ea1ac493d049edd6f102f52e618f085 + version: 61caf9d3038e1af346dbf5c2e16f6678e1548364 testImports: - name: github.com/davecgh/go-spew - version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9 + version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9 subpackages: - spew - name: github.com/pmezard/go-difflib @@ -141,7 +145,7 @@ testImports: subpackages: - difflib - name: github.com/stretchr/testify - version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0 + version: 2aa2c176b9dab406a6970f6a55f513e8a8c8b18f subpackages: - assert - require diff --git a/glide.yaml b/glide.yaml index ce805723..88f49dde 100644 --- a/glide.yaml +++ b/glide.yaml @@ -1,9 +1,11 @@ package: github.com/tendermint/abci import: -- package: github.com/golang/protobuf +- package: github.com/gogo/protobuf + version: v0.5 subpackages: - proto - package: github.com/spf13/cobra + version: v0.0.1 - package: github.com/tendermint/go-crypto version: develop - package: github.com/tendermint/go-wire @@ -23,6 +25,7 @@ import: subpackages: - context - package: google.golang.org/grpc + version: v1.7.3 testImport: - package: github.com/stretchr/testify subpackages: diff --git a/server/grpc_server.go b/server/grpc_server.go index 077f0e52..e7dad15c 100644 --- a/server/grpc_server.go +++ b/server/grpc_server.go @@ -42,6 +42,7 @@ func (s *GRPCServer) OnStart() error { if err != nil { return err } + s.Logger.Info("Listening", "proto", s.proto, "addr", s.addr) s.listener = ln s.server = grpc.NewServer() types.RegisterABCIApplicationServer(s.server, s.app) diff --git a/server/socket_server.go b/server/socket_server.go index 2396c556..eb26dc35 100644 --- a/server/socket_server.go +++ b/server/socket_server.go @@ -56,13 +56,17 @@ func (s *SocketServer) OnStart() error { func (s *SocketServer) OnStop() { s.BaseService.OnStop() - s.listener.Close() + if err := s.listener.Close(); err != nil { + s.Logger.Error("Error closing listener", "err", err) + } s.connsMtx.Lock() defer s.connsMtx.Unlock() for id, conn := range s.conns { delete(s.conns, id) - conn.Close() + if err := conn.Close(); err != nil { + s.Logger.Error("Error closing connection", "id", id, "conn", conn, "err", err) + } } } @@ -168,33 +172,32 @@ func (s *SocketServer) handleRequest(req *types.Request, responses chan<- *types case *types.Request_Flush: responses <- types.ToResponseFlush() case *types.Request_Info: - resInfo := s.app.Info(*r.Info) - responses <- types.ToResponseInfo(resInfo) + res := s.app.Info(*r.Info) + responses <- types.ToResponseInfo(res) case *types.Request_SetOption: - so := r.SetOption - logStr := s.app.SetOption(so.Key, so.Value) - responses <- types.ToResponseSetOption(logStr) + res := s.app.SetOption(*r.SetOption) + responses <- types.ToResponseSetOption(res) case *types.Request_DeliverTx: res := s.app.DeliverTx(r.DeliverTx.Tx) - responses <- types.ToResponseDeliverTx(res.Code, res.Data, res.Log) + responses <- types.ToResponseDeliverTx(res) case *types.Request_CheckTx: res := s.app.CheckTx(r.CheckTx.Tx) - responses <- types.ToResponseCheckTx(res.Code, res.Data, res.Log) + responses <- types.ToResponseCheckTx(res) case *types.Request_Commit: res := s.app.Commit() - responses <- types.ToResponseCommit(res.Code, res.Data, res.Log) + responses <- types.ToResponseCommit(res) case *types.Request_Query: - resQuery := s.app.Query(*r.Query) - responses <- types.ToResponseQuery(resQuery) + res := s.app.Query(*r.Query) + responses <- types.ToResponseQuery(res) case *types.Request_InitChain: - s.app.InitChain(*r.InitChain) - responses <- types.ToResponseInitChain() + res := s.app.InitChain(*r.InitChain) + responses <- types.ToResponseInitChain(res) case *types.Request_BeginBlock: - s.app.BeginBlock(*r.BeginBlock) - responses <- types.ToResponseBeginBlock() + res := s.app.BeginBlock(*r.BeginBlock) + responses <- types.ToResponseBeginBlock(res) case *types.Request_EndBlock: - resEndBlock := s.app.EndBlock(r.EndBlock.Height) - responses <- types.ToResponseEndBlock(resEndBlock) + res := s.app.EndBlock(*r.EndBlock) + responses <- types.ToResponseEndBlock(res) default: responses <- types.ToResponseException("Unknown request") } diff --git a/test.sh b/test.sh new file mode 100755 index 00000000..978b26e1 --- /dev/null +++ b/test.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -e +echo "" > coverage.txt + +echo "==> Running unit tests" +for d in $(go list ./... | grep -v vendor); do + go test -race -coverprofile=profile.out -covermode=atomic "$d" + if [ -f profile.out ]; then + cat profile.out >> coverage.txt + rm profile.out + fi +done + +echo "==> Running integration tests (./tests)" +find . -path ./vendor -prune -o -name "*.sock" -exec rm {} \; +# tests/test.sh requires that we run the installed cmds, must not be out of date +make install +bash tests/test.sh diff --git a/tests/client_server_test.go b/tests/client_server_test.go index cc946fce..3d74478b 100644 --- a/tests/client_server_test.go +++ b/tests/client_server_test.go @@ -1,4 +1,4 @@ -package main +package tests import ( "testing" @@ -17,11 +17,11 @@ func TestClientServerNoAddrPrefix(t *testing.T) { server, err := abciserver.NewServer(addr, transport, app) assert.NoError(t, err, "expected no error on NewServer") - _, err = server.Start() + err = server.Start() assert.NoError(t, err, "expected no error on server.Start") client, err := abciclient.NewClient(addr, transport, true) assert.NoError(t, err, "expected no error on NewClient") - _, err = client.Start() + err = client.Start() assert.NoError(t, err, "expected no error on client.Start") } diff --git a/tests/server/client.go b/tests/server/client.go new file mode 100644 index 00000000..f1757fe1 --- /dev/null +++ b/tests/server/client.go @@ -0,0 +1,98 @@ +package testsuite + +import ( + "bytes" + "errors" + "fmt" + + abcicli "github.com/tendermint/abci/client" + "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + cmn "github.com/tendermint/tmlibs/common" +) + +func InitChain(client abcicli.Client) error { + total := 10 + vals := make([]*types.Validator, total) + for i := 0; i < total; i++ { + pubkey := crypto.GenPrivKeyEd25519FromSecret([]byte(cmn.Fmt("test%d", i))).PubKey().Bytes() + power := cmn.RandInt() + vals[i] = &types.Validator{pubkey, int64(power)} + } + _, err := client.InitChainSync(types.RequestInitChain{Validators: vals}) + if err != nil { + fmt.Println("Failed test: InitChain - %v", err) + return err + } + fmt.Println("Passed test: InitChain") + return nil +} + +func SetOption(client abcicli.Client, key, value string) error { + res, err := client.SetOptionSync(types.RequestSetOption{Key: key, Value: value}) + log := res.GetLog() + if err != nil { + fmt.Println("Failed test: SetOption") + fmt.Printf("setting %v=%v: \nlog: %v", key, value, log) + fmt.Println("Failed test: SetOption") + return err + } + fmt.Println("Passed test: SetOption") + return nil +} + +func Commit(client abcicli.Client, hashExp []byte) error { + res, err := client.CommitSync() + _, data := res.Code, res.Data + if err != nil { + fmt.Println("Failed test: Commit") + fmt.Printf("committing %v\nlog: %v", res.GetLog()) + return err + } + if !bytes.Equal(data, hashExp) { + fmt.Println("Failed test: Commit") + fmt.Printf("Commit hash was unexpected. Got %X expected %X", + data.Bytes(), hashExp) + return errors.New("CommitTx failed") + } + fmt.Println("Passed test: Commit") + return nil +} + +func DeliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { + res, _ := client.DeliverTxSync(txBytes) + code, data, log := res.Code, res.Data, res.Log + if code != codeExp { + fmt.Println("Failed test: DeliverTx") + fmt.Printf("DeliverTx response code was unexpected. Got %v expected %v. Log: %v", + code, codeExp, log) + return errors.New("DeliverTx error") + } + if !bytes.Equal(data, dataExp) { + fmt.Println("Failed test: DeliverTx") + fmt.Printf("DeliverTx response data was unexpected. Got %X expected %X", + data, dataExp) + return errors.New("DeliverTx error") + } + fmt.Println("Passed test: DeliverTx") + return nil +} + +func CheckTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { + res, _ := client.CheckTxSync(txBytes) + code, data, log := res.Code, res.Data, res.Log + if code != codeExp { + fmt.Println("Failed test: CheckTx") + fmt.Printf("CheckTx response code was unexpected. Got %v expected %v. Log: %v", + code, codeExp, log) + return errors.New("CheckTx") + } + if !bytes.Equal(data, dataExp) { + fmt.Println("Failed test: CheckTx") + fmt.Printf("CheckTx response data was unexpected. Got %X expected %X", + data, dataExp) + return errors.New("CheckTx") + } + fmt.Println("Passed test: CheckTx") + return nil +} diff --git a/tests/test.sh b/tests/test.sh index 4087cdce..c005c0de 100755 --- a/tests/test.sh +++ b/tests/test.sh @@ -1,4 +1,5 @@ #! /bin/bash +set -e # test the counter using a go test script bash tests/test_app/test.sh diff --git a/tests/test_app/app.go b/tests/test_app/app.go index 127ba78f..f0403621 100644 --- a/tests/test_app/app.go +++ b/tests/test_app/app.go @@ -4,34 +4,12 @@ import ( "bytes" "fmt" "os" - "time" abcicli "github.com/tendermint/abci/client" "github.com/tendermint/abci/types" "github.com/tendermint/tmlibs/log" - "github.com/tendermint/tmlibs/process" ) -func startApp(abciApp string) *process.Process { - // Start the app - //outBuf := NewBufferCloser(nil) - proc, err := process.StartProcess("abci_app", - "", - "bash", - []string{"-c", fmt.Sprintf("abci-cli %s", abciApp)}, - nil, - os.Stdout, - ) - if err != nil { - panic("running abci_app: " + err.Error()) - } - - // TODO a better way to handle this? - time.Sleep(time.Second) - - return proc -} - func startClient(abciType string) abcicli.Client { // Start client client, err := abcicli.NewClient("tcp://127.0.0.1:46658", abciType, true) @@ -40,58 +18,64 @@ func startClient(abciType string) abcicli.Client { } logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout)) client.SetLogger(logger.With("module", "abcicli")) - if _, err := client.Start(); err != nil { - panic("connecting to abci_app: " + err.Error()) + if err := client.Start(); err != nil { + panicf("connecting to abci_app: %v", err.Error()) } return client } func setOption(client abcicli.Client, key, value string) { - res := client.SetOptionSync(key, value) - _, _, log := res.Code, res.Data, res.Log - if res.IsErr() { - panic(fmt.Sprintf("setting %v=%v: \nlog: %v", key, value, log)) + _, err := client.SetOptionSync(types.RequestSetOption{key, value}) + if err != nil { + panicf("setting %v=%v: \nerr: %v", key, value, err) } } func commit(client abcicli.Client, hashExp []byte) { - res := client.CommitSync() - _, data, _ := res.Code, res.Data, res.Log + res, err := client.CommitSync() + if err != nil { + panicf("client error: %v", err) + } if res.IsErr() { - panic(fmt.Sprintf("committing err %v\n", res)) + panicf("committing err %v\n", res) } if !bytes.Equal(res.Data, hashExp) { - panic(fmt.Sprintf("Commit hash was unexpected. Got %X expected %X", - data, hashExp)) + panicf("Commit hash was unexpected. Got %X expected %X", res.Data, hashExp) } } -func deliverTx(client abcicli.Client, txBytes []byte, codeExp types.CodeType, dataExp []byte) { - res := client.DeliverTxSync(txBytes) - code, data, log := res.Code, res.Data, res.Log - if code != codeExp { - panic(fmt.Sprintf("DeliverTx response code was unexpected. Got %v expected %v. Log: %v", - code, codeExp, log)) +func deliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) { + res, err := client.DeliverTxSync(txBytes) + if err != nil { + panicf("client error: %v", err) } - if !bytes.Equal(data, dataExp) { - panic(fmt.Sprintf("DeliverTx response data was unexpected. Got %X expected %X", - data, dataExp)) + if res.Code != codeExp { + panicf("DeliverTx response code was unexpected. Got %v expected %v. Log: %v", res.Code, codeExp, res.Log) + } + if !bytes.Equal(res.Data, dataExp) { + panicf("DeliverTx response data was unexpected. Got %X expected %X", res.Data, dataExp) } } -/*func checkTx(client abcicli.Client, txBytes []byte, codeExp types.CodeType, dataExp []byte) { - res := client.CheckTxSync(txBytes) - code, data, log := res.Code, res.Data, res.Log +/*func checkTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) { + res, err := client.CheckTxSync(txBytes) + if err != nil { + panicf("client error: %v", err) + } if res.IsErr() { - panic(fmt.Sprintf("checking tx %X: %v\nlog: %v", txBytes, log)) + panicf("checking tx %X: %v\nlog: %v", txBytes, res.Log) } - if code != codeExp { - panic(fmt.Sprintf("CheckTx response code was unexpected. Got %v expected %v. Log: %v", - code, codeExp, log)) + if res.Code != codeExp { + panicf("CheckTx response code was unexpected. Got %v expected %v. Log: %v", + res.Code, codeExp, res.Log) } - if !bytes.Equal(data, dataExp) { - panic(fmt.Sprintf("CheckTx response data was unexpected. Got %X expected %X", - data, dataExp)) + if !bytes.Equal(res.Data, dataExp) { + panicf("CheckTx response data was unexpected. Got %X expected %X", + res.Data, dataExp) } }*/ + +func panicf(format string, a ...interface{}) { + panic(fmt.Sprintf(format, a...)) +} diff --git a/tests/test_app/main.go b/tests/test_app/main.go index 376c02fe..95a7515d 100644 --- a/tests/test_app/main.go +++ b/tests/test_app/main.go @@ -2,8 +2,12 @@ package main import ( "fmt" + "log" "os" + "os/exec" + "time" + "github.com/tendermint/abci/example/code" "github.com/tendermint/abci/types" ) @@ -20,6 +24,28 @@ func main() { testCounter() } +const ( + maxABCIConnectTries = 10 +) + +func ensureABCIIsUp(typ string, n int) error { + var err error + cmdString := "abci-cli echo hello" + if typ == "grpc" { + cmdString = "abci-cli --abci grpc echo hello" + } + + for i := 0; i < n; i++ { + cmd := exec.Command("bash", "-c", cmdString) // nolint: gas + _, err = cmd.CombinedOutput() + if err == nil { + break + } + <-time.After(500 * time.Millisecond) + } + return err +} + func testCounter() { abciApp := os.Getenv("ABCI_APP") if abciApp == "" { @@ -27,22 +53,32 @@ func testCounter() { } fmt.Printf("Running %s test with abci=%s\n", abciApp, abciType) - appProc := startApp(abciApp) - defer appProc.StopProcess(true) + cmd := exec.Command("bash", "-c", fmt.Sprintf("abci-cli %s", abciApp)) // nolint: gas + cmd.Stdout = os.Stdout + if err := cmd.Start(); err != nil { + log.Fatalf("starting %q err: %v", abciApp, err) + } + defer cmd.Wait() + defer cmd.Process.Kill() + + if err := ensureABCIIsUp(abciType, maxABCIConnectTries); err != nil { + log.Fatalf("echo failed: %v", err) + } + client := startClient(abciType) defer client.Stop() setOption(client, "serial", "on") commit(client, nil) - deliverTx(client, []byte("abc"), types.CodeType_BadNonce, nil) + deliverTx(client, []byte("abc"), code.CodeTypeBadNonce, nil) commit(client, nil) - deliverTx(client, []byte{0x00}, types.CodeType_OK, nil) + deliverTx(client, []byte{0x00}, types.CodeTypeOK, nil) commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 1}) - deliverTx(client, []byte{0x00}, types.CodeType_BadNonce, nil) - deliverTx(client, []byte{0x01}, types.CodeType_OK, nil) - deliverTx(client, []byte{0x00, 0x02}, types.CodeType_OK, nil) - deliverTx(client, []byte{0x00, 0x03}, types.CodeType_OK, nil) - deliverTx(client, []byte{0x00, 0x00, 0x04}, types.CodeType_OK, nil) - deliverTx(client, []byte{0x00, 0x00, 0x06}, types.CodeType_BadNonce, nil) + deliverTx(client, []byte{0x00}, code.CodeTypeBadNonce, nil) + deliverTx(client, []byte{0x01}, types.CodeTypeOK, nil) + deliverTx(client, []byte{0x00, 0x02}, types.CodeTypeOK, nil) + deliverTx(client, []byte{0x00, 0x03}, types.CodeTypeOK, nil) + deliverTx(client, []byte{0x00, 0x00, 0x04}, types.CodeTypeOK, nil) + deliverTx(client, []byte{0x00, 0x00, 0x06}, code.CodeTypeBadNonce, nil) commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 5}) } diff --git a/tests/test_app/test.sh b/tests/test_app/test.sh index 5b523fef..230c9416 100755 --- a/tests/test_app/test.sh +++ b/tests/test_app/test.sh @@ -11,11 +11,16 @@ DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )" # Change into that dir because we expect that. cd "$DIR" +echo "RUN COUNTER OVER SOCKET" # test golang counter ABCI_APP="counter" go run ./*.go +echo "----------------------" + +echo "RUN COUNTER OVER GRPC" # test golang counter via grpc ABCI_APP="counter --abci=grpc" ABCI="grpc" go run ./*.go +echo "----------------------" # test nodejs counter # TODO: fix node app diff --git a/tests/test_cli/ex2.abci.out b/tests/test_cli/ex2.abci.out index 40e10f83..741dd7b7 100644 --- a/tests/test_cli/ex2.abci.out +++ b/tests/test_cli/ex2.abci.out @@ -11,14 +11,14 @@ -> code: OK > check_tx 0x00 --> code: BadNonce +-> code: 2 -> log: Invalid nonce. Expected >= 1, got 0 > deliver_tx 0x01 -> code: OK > deliver_tx 0x04 --> code: BadNonce +-> code: 2 -> log: Invalid nonce. Expected 2, got 4 > info diff --git a/tests/test_cli/test.sh b/tests/test_cli/test.sh old mode 100644 new mode 100755 index ea4ea4fa..ed00b9d7 --- a/tests/test_cli/test.sh +++ b/tests/test_cli/test.sh @@ -1,4 +1,5 @@ #! /bin/bash +set -e # Get the root directory. SOURCE="${BASH_SOURCE[0]}" @@ -9,29 +10,29 @@ DIR="$( cd -P "$( dirname "$SOURCE" )/../.." && pwd )" cd "$DIR" || exit function testExample() { - N=$1 - INPUT=$2 - APP="$3 $4" + N=$1 + INPUT=$2 + APP="$3 $4" - echo "Example $N: $APP" - $APP &> /dev/null & - sleep 2 - abci-cli --verbose batch < "$INPUT" > "${INPUT}.out.new" - killall "$3" + echo "Example $N: $APP" + $APP &> /dev/null & + sleep 2 + abci-cli --log_level=error --verbose batch < "$INPUT" > "${INPUT}.out.new" + killall "$3" - pre=$(shasum < "${INPUT}.out") - post=$(shasum < "${INPUT}.out.new") + pre=$(shasum < "${INPUT}.out") + post=$(shasum < "${INPUT}.out.new") - if [[ "$pre" != "$post" ]]; then - echo "You broke the tutorial" - echo "Got:" - cat "${INPUT}.out.new" - echo "Expected:" - cat "${INPUT}.out" - exit 1 - fi + if [[ "$pre" != "$post" ]]; then + echo "You broke the tutorial" + echo "Got:" + cat "${INPUT}.out.new" + echo "Expected:" + cat "${INPUT}.out" + exit 1 + fi - rm "${INPUT}".out.new + rm "${INPUT}".out.new } testExample 1 tests/test_cli/ex1.abci abci-cli dummy diff --git a/tests/tests.go b/tests/tests.go new file mode 100644 index 00000000..ca8701d2 --- /dev/null +++ b/tests/tests.go @@ -0,0 +1 @@ +package tests diff --git a/types/application.go b/types/application.go index 3d9716b7..c8ea19c3 100644 --- a/types/application.go +++ b/types/application.go @@ -5,25 +5,75 @@ import ( ) // Application is an interface that enables any finite, deterministic state machine -// to be driven by a blockchain-based replication engine via the ABCI +// to be driven by a blockchain-based replication engine via the ABCI. +// All methods take a RequestXxx argument and return a ResponseXxx argument, +// except CheckTx/DeliverTx, which take `tx []byte`, and `Commit`, which takes nothing. type Application interface { // Info/Query Connection - Info(RequestInfo) ResponseInfo // Return application info - SetOption(key string, value string) (log string) // Set application option - Query(RequestQuery) ResponseQuery // Query for state + Info(RequestInfo) ResponseInfo // Return application info + SetOption(RequestSetOption) ResponseSetOption // Set application option + Query(RequestQuery) ResponseQuery // Query for state // Mempool Connection - CheckTx(tx []byte) Result // Validate a tx for the mempool + CheckTx(tx []byte) ResponseCheckTx // Validate a tx for the mempool // Consensus Connection - InitChain(RequestInitChain) // Initialize blockchain with validators and other info from TendermintCore - BeginBlock(RequestBeginBlock) // Signals the beginning of a block - DeliverTx(tx []byte) Result // Deliver a tx for full processing - EndBlock(height uint64) ResponseEndBlock // Signals the end of a block, returns changes to the validator set - Commit() Result // Commit the state and return the application Merkle root hash + InitChain(RequestInitChain) ResponseInitChain // Initialize blockchain with validators and other info from TendermintCore + BeginBlock(RequestBeginBlock) ResponseBeginBlock // Signals the beginning of a block + DeliverTx(tx []byte) ResponseDeliverTx // Deliver a tx for full processing + EndBlock(RequestEndBlock) ResponseEndBlock // Signals the end of a block, returns changes to the validator set + Commit() ResponseCommit // Commit the state and return the application Merkle root hash } -//------------------------------------ +//------------------------------------------------------- +// BaseApplication is a base form of Application + +var _ Application = (*BaseApplication)(nil) + +type BaseApplication struct { +} + +func NewBaseApplication() *BaseApplication { + return &BaseApplication{} +} + +func (BaseApplication) Info(req RequestInfo) ResponseInfo { + return ResponseInfo{} +} + +func (BaseApplication) SetOption(req RequestSetOption) ResponseSetOption { + return ResponseSetOption{Code: CodeTypeOK} +} + +func (BaseApplication) DeliverTx(tx []byte) ResponseDeliverTx { + return ResponseDeliverTx{Code: CodeTypeOK} +} + +func (BaseApplication) CheckTx(tx []byte) ResponseCheckTx { + return ResponseCheckTx{Code: CodeTypeOK} +} + +func (BaseApplication) Commit() ResponseCommit { + return ResponseCommit{Code: CodeTypeOK} +} + +func (BaseApplication) Query(req RequestQuery) ResponseQuery { + return ResponseQuery{Code: CodeTypeOK} +} + +func (BaseApplication) InitChain(req RequestInitChain) ResponseInitChain { + return ResponseInitChain{} +} + +func (BaseApplication) BeginBlock(req RequestBeginBlock) ResponseBeginBlock { + return ResponseBeginBlock{} +} + +func (BaseApplication) EndBlock(req RequestEndBlock) ResponseEndBlock { + return ResponseEndBlock{} +} + +//------------------------------------------------------- // GRPCApplication is a GRPC wrapper for Application type GRPCApplication struct { @@ -43,45 +93,46 @@ func (app *GRPCApplication) Flush(ctx context.Context, req *RequestFlush) (*Resp } func (app *GRPCApplication) Info(ctx context.Context, req *RequestInfo) (*ResponseInfo, error) { - resInfo := app.app.Info(*req) - return &resInfo, nil + res := app.app.Info(*req) + return &res, nil } func (app *GRPCApplication) SetOption(ctx context.Context, req *RequestSetOption) (*ResponseSetOption, error) { - return &ResponseSetOption{app.app.SetOption(req.Key, req.Value)}, nil + res := app.app.SetOption(*req) + return &res, nil } func (app *GRPCApplication) DeliverTx(ctx context.Context, req *RequestDeliverTx) (*ResponseDeliverTx, error) { - r := app.app.DeliverTx(req.Tx) - return &ResponseDeliverTx{r.Code, r.Data, r.Log}, nil + res := app.app.DeliverTx(req.Tx) + return &res, nil } func (app *GRPCApplication) CheckTx(ctx context.Context, req *RequestCheckTx) (*ResponseCheckTx, error) { - r := app.app.CheckTx(req.Tx) - return &ResponseCheckTx{r.Code, r.Data, r.Log}, nil + res := app.app.CheckTx(req.Tx) + return &res, nil } func (app *GRPCApplication) Query(ctx context.Context, req *RequestQuery) (*ResponseQuery, error) { - resQuery := app.app.Query(*req) - return &resQuery, nil + res := app.app.Query(*req) + return &res, nil } func (app *GRPCApplication) Commit(ctx context.Context, req *RequestCommit) (*ResponseCommit, error) { - r := app.app.Commit() - return &ResponseCommit{r.Code, r.Data, r.Log}, nil + res := app.app.Commit() + return &res, nil } func (app *GRPCApplication) InitChain(ctx context.Context, req *RequestInitChain) (*ResponseInitChain, error) { - app.app.InitChain(*req) - return &ResponseInitChain{}, nil // NOTE: empty return + res := app.app.InitChain(*req) + return &res, nil } func (app *GRPCApplication) BeginBlock(ctx context.Context, req *RequestBeginBlock) (*ResponseBeginBlock, error) { - app.app.BeginBlock(*req) - return &ResponseBeginBlock{}, nil // NOTE: empty return + res := app.app.BeginBlock(*req) + return &res, nil } func (app *GRPCApplication) EndBlock(ctx context.Context, req *RequestEndBlock) (*ResponseEndBlock, error) { - resEndBlock := app.app.EndBlock(req.Height) - return &resEndBlock, nil + res := app.app.EndBlock(*req) + return &res, nil } diff --git a/types/base_app.go b/types/base_app.go deleted file mode 100644 index 94607e9a..00000000 --- a/types/base_app.go +++ /dev/null @@ -1,42 +0,0 @@ -package types - -type BaseApplication struct { -} - -func NewBaseApplication() *BaseApplication { - return &BaseApplication{} -} - -func (app *BaseApplication) Info(req RequestInfo) (resInfo ResponseInfo) { - return -} - -func (app *BaseApplication) SetOption(key string, value string) (log string) { - return "" -} - -func (app *BaseApplication) DeliverTx(tx []byte) Result { - return NewResultOK(nil, "") -} - -func (app *BaseApplication) CheckTx(tx []byte) Result { - return NewResultOK(nil, "") -} - -func (app *BaseApplication) Commit() Result { - return NewResultOK([]byte("nil"), "") -} - -func (app *BaseApplication) Query(req RequestQuery) (resQuery ResponseQuery) { - return -} - -func (app *BaseApplication) InitChain(req RequestInitChain) { -} - -func (app *BaseApplication) BeginBlock(req RequestBeginBlock) { -} - -func (app *BaseApplication) EndBlock(height uint64) (resEndBlock ResponseEndBlock) { - return -} diff --git a/types/code.go b/types/code.go deleted file mode 100644 index c99a0bbe..00000000 --- a/types/code.go +++ /dev/null @@ -1,3 +0,0 @@ -package types - -func (c CodeType) IsOK() bool { return c == CodeType_OK } diff --git a/types/errors.go b/types/errors.go deleted file mode 100644 index 7fa1f009..00000000 --- a/types/errors.go +++ /dev/null @@ -1,26 +0,0 @@ -package types - -var ( - OK = NewResultOK(nil, "") - - ErrInternalError = NewError(CodeType_InternalError, "Internal error") - ErrEncodingError = NewError(CodeType_EncodingError, "Encoding error") - ErrBadNonce = NewError(CodeType_BadNonce, "Error bad nonce") - ErrUnauthorized = NewError(CodeType_Unauthorized, "Unauthorized") - ErrInsufficientFunds = NewError(CodeType_InsufficientFunds, "Insufficient funds") - ErrUnknownRequest = NewError(CodeType_UnknownRequest, "Unknown request") - - ErrBaseDuplicateAddress = NewError(CodeType_BaseDuplicateAddress, "Error (base) duplicate address") - ErrBaseEncodingError = NewError(CodeType_BaseEncodingError, "Error (base) encoding error") - ErrBaseInsufficientFees = NewError(CodeType_BaseInsufficientFees, "Error (base) insufficient fees") - ErrBaseInsufficientFunds = NewError(CodeType_BaseInsufficientFunds, "Error (base) insufficient funds") - ErrBaseInsufficientGasPrice = NewError(CodeType_BaseInsufficientGasPrice, "Error (base) insufficient gas price") - ErrBaseInvalidInput = NewError(CodeType_BaseInvalidInput, "Error (base) invalid input") - ErrBaseInvalidOutput = NewError(CodeType_BaseInvalidOutput, "Error (base) invalid output") - ErrBaseInvalidPubKey = NewError(CodeType_BaseInvalidPubKey, "Error (base) invalid pubkey") - ErrBaseInvalidSequence = NewError(CodeType_BaseInvalidSequence, "Error (base) invalid sequence") - ErrBaseInvalidSignature = NewError(CodeType_BaseInvalidSignature, "Error (base) invalid signature") - ErrBaseUnknownAddress = NewError(CodeType_BaseUnknownAddress, "Error (base) unknown address") - ErrBaseUnknownPlugin = NewError(CodeType_BaseUnknownPlugin, "Error (base) unknown plugin") - ErrBaseUnknownPubKey = NewError(CodeType_BaseUnknownPubKey, "Error (base) unknown pubkey") -) diff --git a/types/messages.go b/types/messages.go index be272c38..5ce234cf 100644 --- a/types/messages.go +++ b/types/messages.go @@ -3,10 +3,35 @@ package types import ( "io" - "github.com/golang/protobuf/proto" - "github.com/tendermint/go-wire" + "github.com/gogo/protobuf/proto" + wire "github.com/tendermint/go-wire" ) +// WriteMessage writes a length-delimited protobuf message. +func WriteMessage(msg proto.Message, w io.Writer) error { + bz, err := proto.Marshal(msg) + if err != nil { + return err + } + var n int + wire.WriteByteSlice(bz, w, &n, &err) + return err +} + +// ReadMessage reads a length delimited protobuf message. +func ReadMessage(r io.Reader, msg proto.Message) error { + var n int + var err error + bz := wire.ReadByteSlice(r, 0, &n, &err) //XXX: no max + if err != nil { + return err + } + err = proto.Unmarshal(bz, msg) + return err +} + +//---------------------------------------- + func ToRequestEcho(message string) *Request { return &Request{ Value: &Request_Echo{&RequestEcho{message}}, @@ -25,21 +50,21 @@ func ToRequestInfo(req RequestInfo) *Request { } } -func ToRequestSetOption(key string, value string) *Request { +func ToRequestSetOption(req RequestSetOption) *Request { return &Request{ - Value: &Request_SetOption{&RequestSetOption{key, value}}, + Value: &Request_SetOption{&req}, } } -func ToRequestDeliverTx(txBytes []byte) *Request { +func ToRequestDeliverTx(tx []byte) *Request { return &Request{ - Value: &Request_DeliverTx{&RequestDeliverTx{txBytes}}, + Value: &Request_DeliverTx{&RequestDeliverTx{tx}}, } } -func ToRequestCheckTx(txBytes []byte) *Request { +func ToRequestCheckTx(tx []byte) *Request { return &Request{ - Value: &Request_CheckTx{&RequestCheckTx{txBytes}}, + Value: &Request_CheckTx{&RequestCheckTx{tx}}, } } @@ -67,9 +92,9 @@ func ToRequestBeginBlock(req RequestBeginBlock) *Request { } } -func ToRequestEndBlock(height uint64) *Request { +func ToRequestEndBlock(req RequestEndBlock) *Request { return &Request{ - Value: &Request_EndBlock{&RequestEndBlock{height}}, + Value: &Request_EndBlock{&req}, } } @@ -93,81 +118,56 @@ func ToResponseFlush() *Response { } } -func ToResponseInfo(resInfo ResponseInfo) *Response { +func ToResponseInfo(res ResponseInfo) *Response { return &Response{ - Value: &Response_Info{&resInfo}, + Value: &Response_Info{&res}, } } -func ToResponseSetOption(log string) *Response { +func ToResponseSetOption(res ResponseSetOption) *Response { return &Response{ - Value: &Response_SetOption{&ResponseSetOption{log}}, + Value: &Response_SetOption{&res}, } } -func ToResponseDeliverTx(code CodeType, data []byte, log string) *Response { +func ToResponseDeliverTx(res ResponseDeliverTx) *Response { return &Response{ - Value: &Response_DeliverTx{&ResponseDeliverTx{code, data, log}}, + Value: &Response_DeliverTx{&res}, } } -func ToResponseCheckTx(code CodeType, data []byte, log string) *Response { +func ToResponseCheckTx(res ResponseCheckTx) *Response { return &Response{ - Value: &Response_CheckTx{&ResponseCheckTx{code, data, log}}, + Value: &Response_CheckTx{&res}, } } -func ToResponseCommit(code CodeType, data []byte, log string) *Response { +func ToResponseCommit(res ResponseCommit) *Response { return &Response{ - Value: &Response_Commit{&ResponseCommit{code, data, log}}, + Value: &Response_Commit{&res}, } } -func ToResponseQuery(resQuery ResponseQuery) *Response { +func ToResponseQuery(res ResponseQuery) *Response { return &Response{ - Value: &Response_Query{&resQuery}, + Value: &Response_Query{&res}, } } -func ToResponseInitChain() *Response { +func ToResponseInitChain(res ResponseInitChain) *Response { return &Response{ - Value: &Response_InitChain{&ResponseInitChain{}}, + Value: &Response_InitChain{&res}, } } -func ToResponseBeginBlock() *Response { +func ToResponseBeginBlock(res ResponseBeginBlock) *Response { return &Response{ - Value: &Response_BeginBlock{&ResponseBeginBlock{}}, + Value: &Response_BeginBlock{&res}, } } -func ToResponseEndBlock(resEndBlock ResponseEndBlock) *Response { +func ToResponseEndBlock(res ResponseEndBlock) *Response { return &Response{ - Value: &Response_EndBlock{&resEndBlock}, + Value: &Response_EndBlock{&res}, } } - -//---------------------------------------- - -// Write proto message, length delimited -func WriteMessage(msg proto.Message, w io.Writer) error { - bz, err := proto.Marshal(msg) - if err != nil { - return err - } - var n int - wire.WriteByteSlice(bz, w, &n, &err) - return err -} - -// Read proto message, length delimited -func ReadMessage(r io.Reader, msg proto.Message) error { - var n int - var err error - bz := wire.ReadByteSlice(r, 0, &n, &err) - if err != nil { - return err - } - err = proto.Unmarshal(bz, msg) - return err -} diff --git a/types/messages_test.go b/types/messages_test.go new file mode 100644 index 00000000..32f09623 --- /dev/null +++ b/types/messages_test.go @@ -0,0 +1,38 @@ +package types + +import ( + "bytes" + "encoding/json" + "strings" + "testing" + + "github.com/gogo/protobuf/proto" + "github.com/stretchr/testify/assert" +) + +func TestMarshalJSON(t *testing.T) { + b, err := json.Marshal(&ResponseDeliverTx{}) + assert.Nil(t, err) + assert.True(t, strings.Contains(string(b), "code")) +} + +func TestWriteReadMessage(t *testing.T) { + cases := []proto.Message{ + &Header{ + NumTxs: 4, + }, + // TODO: add the rest + } + + for _, c := range cases { + buf := new(bytes.Buffer) + err := WriteMessage(c, buf) + assert.Nil(t, err) + + msg := new(Header) + err = ReadMessage(buf, msg) + assert.Nil(t, err) + + assert.Equal(t, c, msg) + } +} diff --git a/types/protoreplace/protoreplace.go b/types/protoreplace/protoreplace.go new file mode 100644 index 00000000..c859098f --- /dev/null +++ b/types/protoreplace/protoreplace.go @@ -0,0 +1,55 @@ +package main + +// +build ignore + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "os/exec" + "regexp" + "strings" +) + +// This script replaces most `[]byte` with `data.Bytes` in a `.pb.go` file. +// It was written before we realized we could use `gogo/protobuf` to achieve +// this more natively. So it's here for safe keeping in case we ever need to +// abandon `gogo/protobuf`. + +func main() { + bytePattern := regexp.MustCompile("[[][]]byte") + const oldPath = "types/types.pb.go" + const tmpPath = "types/types.pb.new" + content, err := ioutil.ReadFile(oldPath) + if err != nil { + panic("cannot read " + oldPath) + os.Exit(1) + } + lines := bytes.Split(content, []byte("\n")) + outFile, _ := os.Create(tmpPath) + wroteImport := false + for _, line_bytes := range lines { + line := string(line_bytes) + gotPackageLine := strings.HasPrefix(line, "package ") + writeImportTime := strings.HasPrefix(line, "import ") + containsDescriptor := strings.Contains(line, "Descriptor") + containsByteArray := strings.Contains(line, "[]byte") + if containsByteArray && !containsDescriptor { + line = string(bytePattern.ReplaceAll([]byte(line), []byte("data.Bytes"))) + } + if writeImportTime && !wroteImport { + wroteImport = true + fmt.Fprintf(outFile, "import \"github.com/tendermint/go-wire/data\"\n") + + } + if gotPackageLine { + fmt.Fprintf(outFile, "%s\n", "//nolint: gas") + } + fmt.Fprintf(outFile, "%s\n", line) + } + outFile.Close() + os.Remove(oldPath) + os.Rename(tmpPath, oldPath) + exec.Command("goimports", "-w", oldPath) +} diff --git a/types/result.go b/types/result.go index abf1e964..1963520d 100644 --- a/types/result.go +++ b/types/result.go @@ -3,135 +3,106 @@ package types import ( "fmt" - "github.com/tendermint/go-wire/data" + "github.com/gogo/protobuf/jsonpb" ) -// Result is a common result object for ABCI calls. -// CONTRACT: a zero Result is OK. -type Result struct { - Code CodeType `json:"code"` - Data data.Bytes `json:"data"` - Log string `json:"log"` // Can be non-deterministic +const ( + CodeTypeOK uint32 = 0 +) + +// IsOK returns true if Code is OK. +func (r ResponseCheckTx) IsOK() bool { + return r.Code == CodeTypeOK } -func NewResult(code CodeType, data []byte, log string) Result { - return Result{ - Code: code, - Data: data, - Log: log, - } +// IsErr returns true if Code is something other than OK. +func (r ResponseCheckTx) IsErr() bool { + return r.Code != CodeTypeOK } -func (res Result) IsOK() bool { - return res.Code == CodeType_OK +// Error implements error interface by formatting response as string. +func (r ResponseCheckTx) Error() string { + return fmtError(r.Code, r.Log) } -func (res Result) IsErr() bool { - return res.Code != CodeType_OK +// IsOK returns true if Code is OK. +func (r ResponseDeliverTx) IsOK() bool { + return r.Code == CodeTypeOK } -func (res Result) IsSameCode(compare Result) bool { - return res.Code == compare.Code +// IsErr returns true if Code is something other than OK. +func (r ResponseDeliverTx) IsErr() bool { + return r.Code != CodeTypeOK } -func (res Result) Error() string { - return fmt.Sprintf("ABCI{code:%v, data:%X, log:%v}", res.Code, res.Data, res.Log) +// Error implements error interface by formatting response as string. +func (r ResponseDeliverTx) Error() string { + return fmtError(r.Code, r.Log) } -func (res Result) String() string { - return fmt.Sprintf("ABCI{code:%v, data:%X, log:%v}", res.Code, res.Data, res.Log) +// IsOK returns true if Code is OK. +func (r ResponseCommit) IsOK() bool { + return r.Code == CodeTypeOK } -func (res Result) PrependLog(log string) Result { - return Result{ - Code: res.Code, - Data: res.Data, - Log: log + ";" + res.Log, - } +// IsErr returns true if Code is something other than OK. +func (r ResponseCommit) IsErr() bool { + return r.Code != CodeTypeOK } -func (res Result) AppendLog(log string) Result { - return Result{ - Code: res.Code, - Data: res.Data, - Log: res.Log + ";" + log, - } +// Error implements error interface by formatting response as string. +func (r ResponseCommit) Error() string { + return fmtError(r.Code, r.Log) } -func (res Result) SetLog(log string) Result { - return Result{ - Code: res.Code, - Data: res.Data, - Log: log, - } +// IsOK returns true if Code is OK. +func (r ResponseQuery) IsOK() bool { + return r.Code == CodeTypeOK } -func (res Result) SetData(data []byte) Result { - return Result{ - Code: res.Code, - Data: data, - Log: res.Log, - } +// IsErr returns true if Code is something other than OK. +func (r ResponseQuery) IsErr() bool { + return r.Code != CodeTypeOK } -//---------------------------------------- - -// NOTE: if data == nil and log == "", same as zero Result. -func NewResultOK(data []byte, log string) Result { - return Result{ - Code: CodeType_OK, - Data: data, - Log: log, - } +// Error implements error interface by formatting response as string. +func (r ResponseQuery) Error() string { + return fmtError(r.Code, r.Log) } -func NewError(code CodeType, log string) Result { - return Result{ - Code: code, - Log: log, - } +func fmtError(code uint32, log string) string { + return fmt.Sprintf("Error code (%d): %s", code, log) } -//---------------------------------------- -// Convenience methods for turning the -// pb type into one using data.Bytes +//--------------------------------------------------------------------------- +// override JSON marshalling so we dont emit defaults (ie. disable omitempty) -// Convert ResponseCheckTx to standard Result -func (r *ResponseCheckTx) Result() Result { - return Result{ - Code: r.Code, - Data: r.Data, - Log: r.Log, - } +func (r *ResponseSetOption) MarshalJSON() ([]byte, error) { + m := jsonpb.Marshaler{EmitDefaults: true} + s, err := m.MarshalToString(r) + return []byte(s), err } -// Convert ResponseDeliverTx to standard Result -func (r *ResponseDeliverTx) Result() Result { - return Result{ - Code: r.Code, - Data: r.Data, - Log: r.Log, - } +func (r *ResponseCheckTx) MarshalJSON() ([]byte, error) { + m := jsonpb.Marshaler{EmitDefaults: true} + s, err := m.MarshalToString(r) + return []byte(s), err } -type ResultQuery struct { - Code CodeType `json:"code"` - Index int64 `json:"index"` - Key data.Bytes `json:"key"` - Value data.Bytes `json:"value"` - Proof data.Bytes `json:"proof"` - Height uint64 `json:"height"` - Log string `json:"log"` +func (r *ResponseDeliverTx) MarshalJSON() ([]byte, error) { + m := jsonpb.Marshaler{EmitDefaults: true} + s, err := m.MarshalToString(r) + return []byte(s), err } -func (r *ResponseQuery) Result() *ResultQuery { - return &ResultQuery{ - Code: r.Code, - Index: r.Index, - Key: r.Key, - Value: r.Value, - Proof: r.Proof, - Height: r.Height, - Log: r.Log, - } +func (r *ResponseQuery) MarshalJSON() ([]byte, error) { + m := jsonpb.Marshaler{EmitDefaults: true} + s, err := m.MarshalToString(r) + return []byte(s), err +} + +func (r *ResponseCommit) MarshalJSON() ([]byte, error) { + m := jsonpb.Marshaler{EmitDefaults: true} + s, err := m.MarshalToString(r) + return []byte(s), err } diff --git a/types/result_test.go b/types/result_test.go new file mode 100644 index 00000000..b7da838c --- /dev/null +++ b/types/result_test.go @@ -0,0 +1,74 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestResponseQuery(t *testing.T) { + res := ResponseQuery{ + Code: CodeTypeOK, + Index: 0, + Key: []byte("hello"), + Value: []byte("world"), + Height: 1, + } + assert.False(t, res.IsErr()) + + res = ResponseQuery{ + Code: 1, + Index: 0, + Key: []byte("hello"), + Value: []byte("world"), + Height: 1, + Log: "bad", + } + assert.True(t, res.IsErr()) + assert.Equal(t, "Error code (1): bad", res.Error()) +} + +func TestResponseDeliverTx(t *testing.T) { + res := ResponseDeliverTx{ + Code: CodeTypeOK, + Data: []byte("Victor Mancha"), + } + assert.False(t, res.IsErr()) + + res = ResponseDeliverTx{ + Code: 1, + Log: "bad", + } + assert.True(t, res.IsErr()) + assert.Equal(t, "Error code (1): bad", res.Error()) +} + +func TestResponseCheckTx(t *testing.T) { + res := ResponseCheckTx{ + Code: CodeTypeOK, + Data: []byte("Talos"), + } + assert.False(t, res.IsErr()) + + res = ResponseCheckTx{ + Code: 1, + Log: "bad", + } + assert.True(t, res.IsErr()) + assert.Equal(t, "Error code (1): bad", res.Error()) +} + +func TestResponseCommit(t *testing.T) { + res := ResponseCommit{ + Code: CodeTypeOK, + Data: []byte("Old Lace"), + } + assert.False(t, res.IsErr()) + + res = ResponseCommit{ + Code: 1, + Log: "bad", + } + assert.True(t, res.IsErr()) + assert.Equal(t, "Error code (1): bad", res.Error()) +} diff --git a/types/types.pb.go b/types/types.pb.go index 4ca304ac..69777d6d 100644 --- a/types/types.pb.go +++ b/types/types.pb.go @@ -1,6 +1,5 @@ -// Code generated by protoc-gen-go. +// Code generated by protoc-gen-gogo. DO NOT EDIT. // source: types/types.proto -// DO NOT EDIT! /* Package types is a generated protocol buffer package. @@ -38,17 +37,20 @@ It has these top-level messages: BlockID PartSetHeader Validator + Evidence + KVPair */ package types -import proto "github.com/golang/protobuf/proto" +import proto "github.com/gogo/protobuf/proto" import fmt "fmt" import math "math" +import _ "github.com/gogo/protobuf/gogoproto" -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) +import github_com_tendermint_go_wire_data "github.com/tendermint/go-wire/data" + +import context "golang.org/x/net/context" +import grpc "google.golang.org/grpc" // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal @@ -59,115 +61,28 @@ var _ = math.Inf // is compatible with the proto package it is being compiled against. // A compilation error at this line likely means your copy of the // proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package +const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package -type CodeType int32 +type KVPair_Type int32 const ( - CodeType_OK CodeType = 0 - // General response codes, 0 ~ 99 - CodeType_InternalError CodeType = 1 - CodeType_EncodingError CodeType = 2 - CodeType_BadNonce CodeType = 3 - CodeType_Unauthorized CodeType = 4 - CodeType_InsufficientFunds CodeType = 5 - CodeType_UnknownRequest CodeType = 6 - // Reserved for basecoin, 100 ~ 199 - CodeType_BaseDuplicateAddress CodeType = 101 - CodeType_BaseEncodingError CodeType = 102 - CodeType_BaseInsufficientFees CodeType = 103 - CodeType_BaseInsufficientFunds CodeType = 104 - CodeType_BaseInsufficientGasPrice CodeType = 105 - CodeType_BaseInvalidInput CodeType = 106 - CodeType_BaseInvalidOutput CodeType = 107 - CodeType_BaseInvalidPubKey CodeType = 108 - CodeType_BaseInvalidSequence CodeType = 109 - CodeType_BaseInvalidSignature CodeType = 110 - CodeType_BaseUnknownAddress CodeType = 111 - CodeType_BaseUnknownPubKey CodeType = 112 - CodeType_BaseUnknownPlugin CodeType = 113 - // Reserved for governance, 200 ~ 299 - CodeType_GovUnknownEntity CodeType = 201 - CodeType_GovUnknownGroup CodeType = 202 - CodeType_GovUnknownProposal CodeType = 203 - CodeType_GovDuplicateGroup CodeType = 204 - CodeType_GovDuplicateMember CodeType = 205 - CodeType_GovDuplicateProposal CodeType = 206 - CodeType_GovDuplicateVote CodeType = 207 - CodeType_GovInvalidMember CodeType = 208 - CodeType_GovInvalidVote CodeType = 209 - CodeType_GovInvalidVotingPower CodeType = 210 + KVPair_STRING KVPair_Type = 0 + KVPair_INT KVPair_Type = 1 ) -var CodeType_name = map[int32]string{ - 0: "OK", - 1: "InternalError", - 2: "EncodingError", - 3: "BadNonce", - 4: "Unauthorized", - 5: "InsufficientFunds", - 6: "UnknownRequest", - 101: "BaseDuplicateAddress", - 102: "BaseEncodingError", - 103: "BaseInsufficientFees", - 104: "BaseInsufficientFunds", - 105: "BaseInsufficientGasPrice", - 106: "BaseInvalidInput", - 107: "BaseInvalidOutput", - 108: "BaseInvalidPubKey", - 109: "BaseInvalidSequence", - 110: "BaseInvalidSignature", - 111: "BaseUnknownAddress", - 112: "BaseUnknownPubKey", - 113: "BaseUnknownPlugin", - 201: "GovUnknownEntity", - 202: "GovUnknownGroup", - 203: "GovUnknownProposal", - 204: "GovDuplicateGroup", - 205: "GovDuplicateMember", - 206: "GovDuplicateProposal", - 207: "GovDuplicateVote", - 208: "GovInvalidMember", - 209: "GovInvalidVote", - 210: "GovInvalidVotingPower", +var KVPair_Type_name = map[int32]string{ + 0: "STRING", + 1: "INT", } -var CodeType_value = map[string]int32{ - "OK": 0, - "InternalError": 1, - "EncodingError": 2, - "BadNonce": 3, - "Unauthorized": 4, - "InsufficientFunds": 5, - "UnknownRequest": 6, - "BaseDuplicateAddress": 101, - "BaseEncodingError": 102, - "BaseInsufficientFees": 103, - "BaseInsufficientFunds": 104, - "BaseInsufficientGasPrice": 105, - "BaseInvalidInput": 106, - "BaseInvalidOutput": 107, - "BaseInvalidPubKey": 108, - "BaseInvalidSequence": 109, - "BaseInvalidSignature": 110, - "BaseUnknownAddress": 111, - "BaseUnknownPubKey": 112, - "BaseUnknownPlugin": 113, - "GovUnknownEntity": 201, - "GovUnknownGroup": 202, - "GovUnknownProposal": 203, - "GovDuplicateGroup": 204, - "GovDuplicateMember": 205, - "GovDuplicateProposal": 206, - "GovDuplicateVote": 207, - "GovInvalidMember": 208, - "GovInvalidVote": 209, - "GovInvalidVotingPower": 210, +var KVPair_Type_value = map[string]int32{ + "STRING": 0, + "INT": 1, } -func (x CodeType) String() string { - return proto.EnumName(CodeType_name, int32(x)) +func (x KVPair_Type) String() string { + return proto.EnumName(KVPair_Type_name, int32(x)) } -func (CodeType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +func (KVPair_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30, 0} } type Request struct { // Types that are valid to be assigned to Value: @@ -188,7 +103,7 @@ type Request struct { func (m *Request) Reset() { *m = Request{} } func (m *Request) String() string { return proto.CompactTextString(m) } func (*Request) ProtoMessage() {} -func (*Request) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } +func (*Request) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{0} } type isRequest_Value interface { isRequest_Value() @@ -346,57 +261,57 @@ func _Request_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { // value switch x := m.Value.(type) { case *Request_Echo: - b.EncodeVarint(1<<3 | proto.WireBytes) + _ = b.EncodeVarint(1<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Echo); err != nil { return err } case *Request_Flush: - b.EncodeVarint(2<<3 | proto.WireBytes) + _ = b.EncodeVarint(2<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Flush); err != nil { return err } case *Request_Info: - b.EncodeVarint(3<<3 | proto.WireBytes) + _ = b.EncodeVarint(3<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Info); err != nil { return err } case *Request_SetOption: - b.EncodeVarint(4<<3 | proto.WireBytes) + _ = b.EncodeVarint(4<<3 | proto.WireBytes) if err := b.EncodeMessage(x.SetOption); err != nil { return err } case *Request_DeliverTx: - b.EncodeVarint(5<<3 | proto.WireBytes) + _ = b.EncodeVarint(5<<3 | proto.WireBytes) if err := b.EncodeMessage(x.DeliverTx); err != nil { return err } case *Request_CheckTx: - b.EncodeVarint(6<<3 | proto.WireBytes) + _ = b.EncodeVarint(6<<3 | proto.WireBytes) if err := b.EncodeMessage(x.CheckTx); err != nil { return err } case *Request_Commit: - b.EncodeVarint(7<<3 | proto.WireBytes) + _ = b.EncodeVarint(7<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Commit); err != nil { return err } case *Request_Query: - b.EncodeVarint(8<<3 | proto.WireBytes) + _ = b.EncodeVarint(8<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Query); err != nil { return err } case *Request_InitChain: - b.EncodeVarint(9<<3 | proto.WireBytes) + _ = b.EncodeVarint(9<<3 | proto.WireBytes) if err := b.EncodeMessage(x.InitChain); err != nil { return err } case *Request_BeginBlock: - b.EncodeVarint(10<<3 | proto.WireBytes) + _ = b.EncodeVarint(10<<3 | proto.WireBytes) if err := b.EncodeMessage(x.BeginBlock); err != nil { return err } case *Request_EndBlock: - b.EncodeVarint(11<<3 | proto.WireBytes) + _ = b.EncodeVarint(11<<3 | proto.WireBytes) if err := b.EncodeMessage(x.EndBlock); err != nil { return err } @@ -570,13 +485,13 @@ func _Request_OneofSizer(msg proto.Message) (n int) { } type RequestEcho struct { - Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` } func (m *RequestEcho) Reset() { *m = RequestEcho{} } func (m *RequestEcho) String() string { return proto.CompactTextString(m) } func (*RequestEcho) ProtoMessage() {} -func (*RequestEcho) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } +func (*RequestEcho) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{1} } func (m *RequestEcho) GetMessage() string { if m != nil { @@ -591,16 +506,16 @@ type RequestFlush struct { func (m *RequestFlush) Reset() { *m = RequestFlush{} } func (m *RequestFlush) String() string { return proto.CompactTextString(m) } func (*RequestFlush) ProtoMessage() {} -func (*RequestFlush) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } +func (*RequestFlush) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{2} } type RequestInfo struct { - Version string `protobuf:"bytes,1,opt,name=version" json:"version,omitempty"` + Version string `protobuf:"bytes,1,opt,name=version,proto3" json:"version,omitempty"` } func (m *RequestInfo) Reset() { *m = RequestInfo{} } func (m *RequestInfo) String() string { return proto.CompactTextString(m) } func (*RequestInfo) ProtoMessage() {} -func (*RequestInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } +func (*RequestInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{3} } func (m *RequestInfo) GetVersion() string { if m != nil { @@ -610,14 +525,14 @@ func (m *RequestInfo) GetVersion() string { } type RequestSetOption struct { - Key string `protobuf:"bytes,1,opt,name=key" json:"key,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` } func (m *RequestSetOption) Reset() { *m = RequestSetOption{} } func (m *RequestSetOption) String() string { return proto.CompactTextString(m) } func (*RequestSetOption) ProtoMessage() {} -func (*RequestSetOption) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } +func (*RequestSetOption) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{4} } func (m *RequestSetOption) GetKey() string { if m != nil { @@ -640,7 +555,7 @@ type RequestDeliverTx struct { func (m *RequestDeliverTx) Reset() { *m = RequestDeliverTx{} } func (m *RequestDeliverTx) String() string { return proto.CompactTextString(m) } func (*RequestDeliverTx) ProtoMessage() {} -func (*RequestDeliverTx) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } +func (*RequestDeliverTx) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{5} } func (m *RequestDeliverTx) GetTx() []byte { if m != nil { @@ -656,7 +571,7 @@ type RequestCheckTx struct { func (m *RequestCheckTx) Reset() { *m = RequestCheckTx{} } func (m *RequestCheckTx) String() string { return proto.CompactTextString(m) } func (*RequestCheckTx) ProtoMessage() {} -func (*RequestCheckTx) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } +func (*RequestCheckTx) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{6} } func (m *RequestCheckTx) GetTx() []byte { if m != nil { @@ -667,15 +582,15 @@ func (m *RequestCheckTx) GetTx() []byte { type RequestQuery struct { Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` - Path string `protobuf:"bytes,2,opt,name=path" json:"path,omitempty"` - Height uint64 `protobuf:"varint,3,opt,name=height" json:"height,omitempty"` - Prove bool `protobuf:"varint,4,opt,name=prove" json:"prove,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + Height int64 `protobuf:"varint,3,opt,name=height,proto3" json:"height,omitempty"` + Prove bool `protobuf:"varint,4,opt,name=prove,proto3" json:"prove,omitempty"` } func (m *RequestQuery) Reset() { *m = RequestQuery{} } func (m *RequestQuery) String() string { return proto.CompactTextString(m) } func (*RequestQuery) ProtoMessage() {} -func (*RequestQuery) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } +func (*RequestQuery) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{7} } func (m *RequestQuery) GetData() []byte { if m != nil { @@ -691,7 +606,7 @@ func (m *RequestQuery) GetPath() string { return "" } -func (m *RequestQuery) GetHeight() uint64 { +func (m *RequestQuery) GetHeight() int64 { if m != nil { return m.Height } @@ -711,7 +626,7 @@ type RequestCommit struct { func (m *RequestCommit) Reset() { *m = RequestCommit{} } func (m *RequestCommit) String() string { return proto.CompactTextString(m) } func (*RequestCommit) ProtoMessage() {} -func (*RequestCommit) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } +func (*RequestCommit) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{8} } type RequestInitChain struct { Validators []*Validator `protobuf:"bytes,1,rep,name=validators" json:"validators,omitempty"` @@ -720,7 +635,7 @@ type RequestInitChain struct { func (m *RequestInitChain) Reset() { *m = RequestInitChain{} } func (m *RequestInitChain) String() string { return proto.CompactTextString(m) } func (*RequestInitChain) ProtoMessage() {} -func (*RequestInitChain) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } +func (*RequestInitChain) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{9} } func (m *RequestInitChain) GetValidators() []*Validator { if m != nil { @@ -730,14 +645,16 @@ func (m *RequestInitChain) GetValidators() []*Validator { } type RequestBeginBlock struct { - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` - Header *Header `protobuf:"bytes,2,opt,name=header" json:"header,omitempty"` + Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + Header *Header `protobuf:"bytes,2,opt,name=header" json:"header,omitempty"` + AbsentValidators []int32 `protobuf:"varint,3,rep,packed,name=absent_validators,json=absentValidators" json:"absent_validators,omitempty"` + ByzantineValidators []*Evidence `protobuf:"bytes,4,rep,name=byzantine_validators,json=byzantineValidators" json:"byzantine_validators,omitempty"` } func (m *RequestBeginBlock) Reset() { *m = RequestBeginBlock{} } func (m *RequestBeginBlock) String() string { return proto.CompactTextString(m) } func (*RequestBeginBlock) ProtoMessage() {} -func (*RequestBeginBlock) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } +func (*RequestBeginBlock) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{10} } func (m *RequestBeginBlock) GetHash() []byte { if m != nil { @@ -753,16 +670,30 @@ func (m *RequestBeginBlock) GetHeader() *Header { return nil } +func (m *RequestBeginBlock) GetAbsentValidators() []int32 { + if m != nil { + return m.AbsentValidators + } + return nil +} + +func (m *RequestBeginBlock) GetByzantineValidators() []*Evidence { + if m != nil { + return m.ByzantineValidators + } + return nil +} + type RequestEndBlock struct { - Height uint64 `protobuf:"varint,1,opt,name=height" json:"height,omitempty"` + Height int64 `protobuf:"varint,1,opt,name=height,proto3" json:"height,omitempty"` } func (m *RequestEndBlock) Reset() { *m = RequestEndBlock{} } func (m *RequestEndBlock) String() string { return proto.CompactTextString(m) } func (*RequestEndBlock) ProtoMessage() {} -func (*RequestEndBlock) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } +func (*RequestEndBlock) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{11} } -func (m *RequestEndBlock) GetHeight() uint64 { +func (m *RequestEndBlock) GetHeight() int64 { if m != nil { return m.Height } @@ -789,7 +720,7 @@ type Response struct { func (m *Response) Reset() { *m = Response{} } func (m *Response) String() string { return proto.CompactTextString(m) } func (*Response) ProtoMessage() {} -func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } +func (*Response) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{12} } type isResponse_Value interface { isResponse_Value() @@ -959,62 +890,62 @@ func _Response_OneofMarshaler(msg proto.Message, b *proto.Buffer) error { // value switch x := m.Value.(type) { case *Response_Exception: - b.EncodeVarint(1<<3 | proto.WireBytes) + _ = b.EncodeVarint(1<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Exception); err != nil { return err } case *Response_Echo: - b.EncodeVarint(2<<3 | proto.WireBytes) + _ = b.EncodeVarint(2<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Echo); err != nil { return err } case *Response_Flush: - b.EncodeVarint(3<<3 | proto.WireBytes) + _ = b.EncodeVarint(3<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Flush); err != nil { return err } case *Response_Info: - b.EncodeVarint(4<<3 | proto.WireBytes) + _ = b.EncodeVarint(4<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Info); err != nil { return err } case *Response_SetOption: - b.EncodeVarint(5<<3 | proto.WireBytes) + _ = b.EncodeVarint(5<<3 | proto.WireBytes) if err := b.EncodeMessage(x.SetOption); err != nil { return err } case *Response_DeliverTx: - b.EncodeVarint(6<<3 | proto.WireBytes) + _ = b.EncodeVarint(6<<3 | proto.WireBytes) if err := b.EncodeMessage(x.DeliverTx); err != nil { return err } case *Response_CheckTx: - b.EncodeVarint(7<<3 | proto.WireBytes) + _ = b.EncodeVarint(7<<3 | proto.WireBytes) if err := b.EncodeMessage(x.CheckTx); err != nil { return err } case *Response_Commit: - b.EncodeVarint(8<<3 | proto.WireBytes) + _ = b.EncodeVarint(8<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Commit); err != nil { return err } case *Response_Query: - b.EncodeVarint(9<<3 | proto.WireBytes) + _ = b.EncodeVarint(9<<3 | proto.WireBytes) if err := b.EncodeMessage(x.Query); err != nil { return err } case *Response_InitChain: - b.EncodeVarint(10<<3 | proto.WireBytes) + _ = b.EncodeVarint(10<<3 | proto.WireBytes) if err := b.EncodeMessage(x.InitChain); err != nil { return err } case *Response_BeginBlock: - b.EncodeVarint(11<<3 | proto.WireBytes) + _ = b.EncodeVarint(11<<3 | proto.WireBytes) if err := b.EncodeMessage(x.BeginBlock); err != nil { return err } case *Response_EndBlock: - b.EncodeVarint(12<<3 | proto.WireBytes) + _ = b.EncodeVarint(12<<3 | proto.WireBytes) if err := b.EncodeMessage(x.EndBlock); err != nil { return err } @@ -1201,13 +1132,13 @@ func _Response_OneofSizer(msg proto.Message) (n int) { } type ResponseException struct { - Error string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"` + Error string `protobuf:"bytes,1,opt,name=error,proto3" json:"error,omitempty"` } func (m *ResponseException) Reset() { *m = ResponseException{} } func (m *ResponseException) String() string { return proto.CompactTextString(m) } func (*ResponseException) ProtoMessage() {} -func (*ResponseException) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } +func (*ResponseException) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{13} } func (m *ResponseException) GetError() string { if m != nil { @@ -1217,13 +1148,13 @@ func (m *ResponseException) GetError() string { } type ResponseEcho struct { - Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` + Message string `protobuf:"bytes,1,opt,name=message,proto3" json:"message,omitempty"` } func (m *ResponseEcho) Reset() { *m = ResponseEcho{} } func (m *ResponseEcho) String() string { return proto.CompactTextString(m) } func (*ResponseEcho) ProtoMessage() {} -func (*ResponseEcho) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } +func (*ResponseEcho) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{14} } func (m *ResponseEcho) GetMessage() string { if m != nil { @@ -1238,19 +1169,19 @@ type ResponseFlush struct { func (m *ResponseFlush) Reset() { *m = ResponseFlush{} } func (m *ResponseFlush) String() string { return proto.CompactTextString(m) } func (*ResponseFlush) ProtoMessage() {} -func (*ResponseFlush) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } +func (*ResponseFlush) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{15} } type ResponseInfo struct { - Data string `protobuf:"bytes,1,opt,name=data" json:"data,omitempty"` - Version string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"` - LastBlockHeight uint64 `protobuf:"varint,3,opt,name=last_block_height,json=lastBlockHeight" json:"last_block_height,omitempty"` + Data string `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + LastBlockHeight int64 `protobuf:"varint,3,opt,name=last_block_height,json=lastBlockHeight,proto3" json:"last_block_height,omitempty"` LastBlockAppHash []byte `protobuf:"bytes,4,opt,name=last_block_app_hash,json=lastBlockAppHash,proto3" json:"last_block_app_hash,omitempty"` } func (m *ResponseInfo) Reset() { *m = ResponseInfo{} } func (m *ResponseInfo) String() string { return proto.CompactTextString(m) } func (*ResponseInfo) ProtoMessage() {} -func (*ResponseInfo) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } +func (*ResponseInfo) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{16} } func (m *ResponseInfo) GetData() string { if m != nil { @@ -1266,7 +1197,7 @@ func (m *ResponseInfo) GetVersion() string { return "" } -func (m *ResponseInfo) GetLastBlockHeight() uint64 { +func (m *ResponseInfo) GetLastBlockHeight() int64 { if m != nil { return m.LastBlockHeight } @@ -1281,13 +1212,21 @@ func (m *ResponseInfo) GetLastBlockAppHash() []byte { } type ResponseSetOption struct { - Log string `protobuf:"bytes,1,opt,name=log" json:"log,omitempty"` + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Log string `protobuf:"bytes,2,opt,name=log,proto3" json:"log,omitempty"` } func (m *ResponseSetOption) Reset() { *m = ResponseSetOption{} } func (m *ResponseSetOption) String() string { return proto.CompactTextString(m) } func (*ResponseSetOption) ProtoMessage() {} -func (*ResponseSetOption) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } +func (*ResponseSetOption) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{17} } + +func (m *ResponseSetOption) GetCode() uint32 { + if m != nil { + return m.Code + } + return 0 +} func (m *ResponseSetOption) GetLog() string { if m != nil { @@ -1297,28 +1236,22 @@ func (m *ResponseSetOption) GetLog() string { } type ResponseDeliverTx struct { - Code CodeType `protobuf:"varint,1,opt,name=code,enum=types.CodeType" json:"code,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - Log string `protobuf:"bytes,3,opt,name=log" json:"log,omitempty"` + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Data github_com_tendermint_go_wire_data.Bytes `protobuf:"bytes,2,opt,name=data,proto3,customtype=github.com/tendermint/go-wire/data.Bytes" json:"data"` + Log string `protobuf:"bytes,3,opt,name=log,proto3" json:"log,omitempty"` + Tags []*KVPair `protobuf:"bytes,4,rep,name=tags" json:"tags,omitempty"` } func (m *ResponseDeliverTx) Reset() { *m = ResponseDeliverTx{} } func (m *ResponseDeliverTx) String() string { return proto.CompactTextString(m) } func (*ResponseDeliverTx) ProtoMessage() {} -func (*ResponseDeliverTx) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } +func (*ResponseDeliverTx) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{18} } -func (m *ResponseDeliverTx) GetCode() CodeType { +func (m *ResponseDeliverTx) GetCode() uint32 { if m != nil { return m.Code } - return CodeType_OK -} - -func (m *ResponseDeliverTx) GetData() []byte { - if m != nil { - return m.Data - } - return nil + return 0 } func (m *ResponseDeliverTx) GetLog() string { @@ -1328,29 +1261,31 @@ func (m *ResponseDeliverTx) GetLog() string { return "" } +func (m *ResponseDeliverTx) GetTags() []*KVPair { + if m != nil { + return m.Tags + } + return nil +} + type ResponseCheckTx struct { - Code CodeType `protobuf:"varint,1,opt,name=code,enum=types.CodeType" json:"code,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - Log string `protobuf:"bytes,3,opt,name=log" json:"log,omitempty"` + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Data github_com_tendermint_go_wire_data.Bytes `protobuf:"bytes,2,opt,name=data,proto3,customtype=github.com/tendermint/go-wire/data.Bytes" json:"data"` + Log string `protobuf:"bytes,3,opt,name=log,proto3" json:"log,omitempty"` + Gas int64 `protobuf:"varint,4,opt,name=gas,proto3" json:"gas,omitempty"` + Fee int64 `protobuf:"varint,5,opt,name=fee,proto3" json:"fee,omitempty"` } func (m *ResponseCheckTx) Reset() { *m = ResponseCheckTx{} } func (m *ResponseCheckTx) String() string { return proto.CompactTextString(m) } func (*ResponseCheckTx) ProtoMessage() {} -func (*ResponseCheckTx) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } +func (*ResponseCheckTx) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{19} } -func (m *ResponseCheckTx) GetCode() CodeType { +func (m *ResponseCheckTx) GetCode() uint32 { if m != nil { return m.Code } - return CodeType_OK -} - -func (m *ResponseCheckTx) GetData() []byte { - if m != nil { - return m.Data - } - return nil + return 0 } func (m *ResponseCheckTx) GetLog() string { @@ -1360,26 +1295,40 @@ func (m *ResponseCheckTx) GetLog() string { return "" } +func (m *ResponseCheckTx) GetGas() int64 { + if m != nil { + return m.Gas + } + return 0 +} + +func (m *ResponseCheckTx) GetFee() int64 { + if m != nil { + return m.Fee + } + return 0 +} + type ResponseQuery struct { - Code CodeType `protobuf:"varint,1,opt,name=code,enum=types.CodeType" json:"code,omitempty"` - Index int64 `protobuf:"varint,2,opt,name=index" json:"index,omitempty"` - Key []byte `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` - Value []byte `protobuf:"bytes,4,opt,name=value,proto3" json:"value,omitempty"` - Proof []byte `protobuf:"bytes,5,opt,name=proof,proto3" json:"proof,omitempty"` - Height uint64 `protobuf:"varint,6,opt,name=height" json:"height,omitempty"` - Log string `protobuf:"bytes,7,opt,name=log" json:"log,omitempty"` + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Index int64 `protobuf:"varint,2,opt,name=index,proto3" json:"index,omitempty"` + Key github_com_tendermint_go_wire_data.Bytes `protobuf:"bytes,3,opt,name=key,proto3,customtype=github.com/tendermint/go-wire/data.Bytes" json:"key"` + Value github_com_tendermint_go_wire_data.Bytes `protobuf:"bytes,4,opt,name=value,proto3,customtype=github.com/tendermint/go-wire/data.Bytes" json:"value"` + Proof github_com_tendermint_go_wire_data.Bytes `protobuf:"bytes,5,opt,name=proof,proto3,customtype=github.com/tendermint/go-wire/data.Bytes" json:"proof"` + Height int64 `protobuf:"varint,6,opt,name=height,proto3" json:"height,omitempty"` + Log string `protobuf:"bytes,7,opt,name=log,proto3" json:"log,omitempty"` } func (m *ResponseQuery) Reset() { *m = ResponseQuery{} } func (m *ResponseQuery) String() string { return proto.CompactTextString(m) } func (*ResponseQuery) ProtoMessage() {} -func (*ResponseQuery) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } +func (*ResponseQuery) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{20} } -func (m *ResponseQuery) GetCode() CodeType { +func (m *ResponseQuery) GetCode() uint32 { if m != nil { return m.Code } - return CodeType_OK + return 0 } func (m *ResponseQuery) GetIndex() int64 { @@ -1389,28 +1338,7 @@ func (m *ResponseQuery) GetIndex() int64 { return 0 } -func (m *ResponseQuery) GetKey() []byte { - if m != nil { - return m.Key - } - return nil -} - -func (m *ResponseQuery) GetValue() []byte { - if m != nil { - return m.Value - } - return nil -} - -func (m *ResponseQuery) GetProof() []byte { - if m != nil { - return m.Proof - } - return nil -} - -func (m *ResponseQuery) GetHeight() uint64 { +func (m *ResponseQuery) GetHeight() int64 { if m != nil { return m.Height } @@ -1425,28 +1353,21 @@ func (m *ResponseQuery) GetLog() string { } type ResponseCommit struct { - Code CodeType `protobuf:"varint,1,opt,name=code,enum=types.CodeType" json:"code,omitempty"` - Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` - Log string `protobuf:"bytes,3,opt,name=log" json:"log,omitempty"` + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Data github_com_tendermint_go_wire_data.Bytes `protobuf:"bytes,2,opt,name=data,proto3,customtype=github.com/tendermint/go-wire/data.Bytes" json:"data"` + Log string `protobuf:"bytes,3,opt,name=log,proto3" json:"log,omitempty"` } func (m *ResponseCommit) Reset() { *m = ResponseCommit{} } func (m *ResponseCommit) String() string { return proto.CompactTextString(m) } func (*ResponseCommit) ProtoMessage() {} -func (*ResponseCommit) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } +func (*ResponseCommit) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{21} } -func (m *ResponseCommit) GetCode() CodeType { +func (m *ResponseCommit) GetCode() uint32 { if m != nil { return m.Code } - return CodeType_OK -} - -func (m *ResponseCommit) GetData() []byte { - if m != nil { - return m.Data - } - return nil + return 0 } func (m *ResponseCommit) GetLog() string { @@ -1462,7 +1383,7 @@ type ResponseInitChain struct { func (m *ResponseInitChain) Reset() { *m = ResponseInitChain{} } func (m *ResponseInitChain) String() string { return proto.CompactTextString(m) } func (*ResponseInitChain) ProtoMessage() {} -func (*ResponseInitChain) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } +func (*ResponseInitChain) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{22} } type ResponseBeginBlock struct { } @@ -1470,7 +1391,7 @@ type ResponseBeginBlock struct { func (m *ResponseBeginBlock) Reset() { *m = ResponseBeginBlock{} } func (m *ResponseBeginBlock) String() string { return proto.CompactTextString(m) } func (*ResponseBeginBlock) ProtoMessage() {} -func (*ResponseBeginBlock) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } +func (*ResponseBeginBlock) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{23} } type ResponseEndBlock struct { Diffs []*Validator `protobuf:"bytes,1,rep,name=diffs" json:"diffs,omitempty"` @@ -1479,7 +1400,7 @@ type ResponseEndBlock struct { func (m *ResponseEndBlock) Reset() { *m = ResponseEndBlock{} } func (m *ResponseEndBlock) String() string { return proto.CompactTextString(m) } func (*ResponseEndBlock) ProtoMessage() {} -func (*ResponseEndBlock) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } +func (*ResponseEndBlock) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{24} } func (m *ResponseEndBlock) GetDiffs() []*Validator { if m != nil { @@ -1489,10 +1410,10 @@ func (m *ResponseEndBlock) GetDiffs() []*Validator { } type Header struct { - ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId" json:"chain_id,omitempty"` - Height uint64 `protobuf:"varint,2,opt,name=height" json:"height,omitempty"` - Time uint64 `protobuf:"varint,3,opt,name=time" json:"time,omitempty"` - NumTxs uint64 `protobuf:"varint,4,opt,name=num_txs,json=numTxs" json:"num_txs,omitempty"` + ChainId string `protobuf:"bytes,1,opt,name=chain_id,json=chainId,proto3" json:"chain_id,omitempty"` + Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` + Time int64 `protobuf:"varint,3,opt,name=time,proto3" json:"time,omitempty"` + NumTxs int32 `protobuf:"varint,4,opt,name=num_txs,json=numTxs,proto3" json:"num_txs,omitempty"` LastBlockId *BlockID `protobuf:"bytes,5,opt,name=last_block_id,json=lastBlockId" json:"last_block_id,omitempty"` LastCommitHash []byte `protobuf:"bytes,6,opt,name=last_commit_hash,json=lastCommitHash,proto3" json:"last_commit_hash,omitempty"` DataHash []byte `protobuf:"bytes,7,opt,name=data_hash,json=dataHash,proto3" json:"data_hash,omitempty"` @@ -1503,7 +1424,7 @@ type Header struct { func (m *Header) Reset() { *m = Header{} } func (m *Header) String() string { return proto.CompactTextString(m) } func (*Header) ProtoMessage() {} -func (*Header) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } +func (*Header) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{25} } func (m *Header) GetChainId() string { if m != nil { @@ -1512,21 +1433,21 @@ func (m *Header) GetChainId() string { return "" } -func (m *Header) GetHeight() uint64 { +func (m *Header) GetHeight() int64 { if m != nil { return m.Height } return 0 } -func (m *Header) GetTime() uint64 { +func (m *Header) GetTime() int64 { if m != nil { return m.Time } return 0 } -func (m *Header) GetNumTxs() uint64 { +func (m *Header) GetNumTxs() int32 { if m != nil { return m.NumTxs } @@ -1576,7 +1497,7 @@ type BlockID struct { func (m *BlockID) Reset() { *m = BlockID{} } func (m *BlockID) String() string { return proto.CompactTextString(m) } func (*BlockID) ProtoMessage() {} -func (*BlockID) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } +func (*BlockID) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{26} } func (m *BlockID) GetHash() []byte { if m != nil { @@ -1593,16 +1514,16 @@ func (m *BlockID) GetParts() *PartSetHeader { } type PartSetHeader struct { - Total uint64 `protobuf:"varint,1,opt,name=total" json:"total,omitempty"` + Total int32 `protobuf:"varint,1,opt,name=total,proto3" json:"total,omitempty"` Hash []byte `protobuf:"bytes,2,opt,name=hash,proto3" json:"hash,omitempty"` } func (m *PartSetHeader) Reset() { *m = PartSetHeader{} } func (m *PartSetHeader) String() string { return proto.CompactTextString(m) } func (*PartSetHeader) ProtoMessage() {} -func (*PartSetHeader) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } +func (*PartSetHeader) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{27} } -func (m *PartSetHeader) GetTotal() uint64 { +func (m *PartSetHeader) GetTotal() int32 { if m != nil { return m.Total } @@ -1617,14 +1538,14 @@ func (m *PartSetHeader) GetHash() []byte { } type Validator struct { - PubKey []byte `protobuf:"bytes,1,opt,name=pubKey,proto3" json:"pubKey,omitempty"` - Power uint64 `protobuf:"varint,2,opt,name=power" json:"power,omitempty"` + PubKey []byte `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty"` + Power int64 `protobuf:"varint,2,opt,name=power,proto3" json:"power,omitempty"` } func (m *Validator) Reset() { *m = Validator{} } func (m *Validator) String() string { return proto.CompactTextString(m) } func (*Validator) ProtoMessage() {} -func (*Validator) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } +func (*Validator) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{28} } func (m *Validator) GetPubKey() []byte { if m != nil { @@ -1633,13 +1554,77 @@ func (m *Validator) GetPubKey() []byte { return nil } -func (m *Validator) GetPower() uint64 { +func (m *Validator) GetPower() int64 { if m != nil { return m.Power } return 0 } +type Evidence struct { + PubKey []byte `protobuf:"bytes,1,opt,name=pub_key,json=pubKey,proto3" json:"pub_key,omitempty"` + Height int64 `protobuf:"varint,2,opt,name=height,proto3" json:"height,omitempty"` +} + +func (m *Evidence) Reset() { *m = Evidence{} } +func (m *Evidence) String() string { return proto.CompactTextString(m) } +func (*Evidence) ProtoMessage() {} +func (*Evidence) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{29} } + +func (m *Evidence) GetPubKey() []byte { + if m != nil { + return m.PubKey + } + return nil +} + +func (m *Evidence) GetHeight() int64 { + if m != nil { + return m.Height + } + return 0 +} + +type KVPair struct { + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` + ValueType KVPair_Type `protobuf:"varint,2,opt,name=value_type,json=valueType,proto3,enum=types.KVPair_Type" json:"value_type,omitempty"` + ValueString string `protobuf:"bytes,3,opt,name=value_string,json=valueString,proto3" json:"value_string,omitempty"` + ValueInt int64 `protobuf:"varint,4,opt,name=value_int,json=valueInt,proto3" json:"value_int,omitempty"` +} + +func (m *KVPair) Reset() { *m = KVPair{} } +func (m *KVPair) String() string { return proto.CompactTextString(m) } +func (*KVPair) ProtoMessage() {} +func (*KVPair) Descriptor() ([]byte, []int) { return fileDescriptorTypes, []int{30} } + +func (m *KVPair) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +func (m *KVPair) GetValueType() KVPair_Type { + if m != nil { + return m.ValueType + } + return KVPair_STRING +} + +func (m *KVPair) GetValueString() string { + if m != nil { + return m.ValueString + } + return "" +} + +func (m *KVPair) GetValueInt() int64 { + if m != nil { + return m.ValueInt + } + return 0 +} + func init() { proto.RegisterType((*Request)(nil), "types.Request") proto.RegisterType((*RequestEcho)(nil), "types.RequestEcho") @@ -1670,7 +1655,9 @@ func init() { proto.RegisterType((*BlockID)(nil), "types.BlockID") proto.RegisterType((*PartSetHeader)(nil), "types.PartSetHeader") proto.RegisterType((*Validator)(nil), "types.Validator") - proto.RegisterEnum("types.CodeType", CodeType_name, CodeType_value) + proto.RegisterType((*Evidence)(nil), "types.Evidence") + proto.RegisterType((*KVPair)(nil), "types.KVPair") + proto.RegisterEnum("types.KVPair_Type", KVPair_Type_name, KVPair_Type_value) } // Reference imports to suppress errors if they are not otherwise used. @@ -2075,110 +2062,106 @@ var _ABCIApplication_serviceDesc = grpc.ServiceDesc{ Metadata: "types/types.proto", } -func init() { proto.RegisterFile("types/types.proto", fileDescriptor0) } +func init() { proto.RegisterFile("types/types.proto", fileDescriptorTypes) } -var fileDescriptor0 = []byte{ - // 1625 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0x59, 0x6f, 0xdb, 0xc6, - 0x16, 0x36, 0xb5, 0xeb, 0xd8, 0x96, 0xe9, 0xb1, 0x6c, 0xcb, 0xba, 0xf7, 0x21, 0xe0, 0x45, 0x6e, - 0xec, 0xdc, 0xdc, 0xa4, 0x70, 0x90, 0x22, 0x6e, 0x8a, 0x02, 0xde, 0x62, 0x0b, 0x41, 0x13, 0x97, - 0x59, 0x5e, 0x5a, 0x54, 0xa0, 0xc9, 0x91, 0xc4, 0x5a, 0x9a, 0x61, 0xc8, 0xa1, 0x23, 0xf7, 0x37, - 0xe4, 0xbd, 0x3f, 0xa1, 0xef, 0x05, 0xfa, 0x17, 0x0a, 0x74, 0x5f, 0x7e, 0x51, 0x31, 0x0b, 0x57, - 0x93, 0x41, 0x1f, 0xf2, 0x22, 0xf0, 0x6c, 0x33, 0x73, 0xce, 0x9c, 0xf3, 0x9d, 0x33, 0x82, 0x55, - 0x76, 0xe5, 0xe1, 0xe0, 0x9e, 0xf8, 0xbd, 0xeb, 0xf9, 0x94, 0x51, 0x54, 0x17, 0x84, 0xf1, 0x43, - 0x0d, 0x9a, 0x26, 0x7e, 0x1d, 0xe2, 0x80, 0xa1, 0x6d, 0xa8, 0x61, 0x7b, 0x42, 0x7b, 0xda, 0x0d, - 0x6d, 0x7b, 0x71, 0x17, 0xdd, 0x95, 0xea, 0x4a, 0x7a, 0x6c, 0x4f, 0xe8, 0xe9, 0x82, 0x29, 0x34, - 0xd0, 0xff, 0xa0, 0x3e, 0x9a, 0x86, 0xc1, 0xa4, 0x57, 0x11, 0xaa, 0x6b, 0x59, 0xd5, 0xc7, 0x5c, - 0x74, 0xba, 0x60, 0x4a, 0x1d, 0xbe, 0xac, 0x4b, 0x46, 0xb4, 0x57, 0x2d, 0x5a, 0x76, 0x40, 0x46, - 0x62, 0x59, 0xae, 0x81, 0x1e, 0x02, 0x04, 0x98, 0x0d, 0xa9, 0xc7, 0x5c, 0x4a, 0x7a, 0x35, 0xa1, - 0xbf, 0x99, 0xd5, 0x7f, 0x8e, 0xd9, 0x33, 0x21, 0x3e, 0x5d, 0x30, 0xdb, 0x41, 0x44, 0x70, 0x4b, - 0x07, 0x4f, 0xdd, 0x4b, 0xec, 0x0f, 0xd9, 0xbc, 0x57, 0x2f, 0xb2, 0x3c, 0x92, 0xf2, 0x17, 0x73, - 0x6e, 0xe9, 0x44, 0x04, 0xda, 0x85, 0x96, 0x3d, 0xc1, 0xf6, 0x05, 0xb7, 0x6b, 0x08, 0xbb, 0xf5, - 0xac, 0xdd, 0x21, 0x97, 0x0a, 0xab, 0xa6, 0x2d, 0x3f, 0xd1, 0x5d, 0x68, 0xd8, 0x74, 0x36, 0x73, - 0x59, 0xaf, 0x29, 0x2c, 0xba, 0x39, 0x0b, 0x21, 0x3b, 0x5d, 0x30, 0x95, 0x16, 0x0f, 0xd7, 0xeb, - 0x10, 0xfb, 0x57, 0xbd, 0x56, 0x51, 0xb8, 0x3e, 0xe3, 0x22, 0x1e, 0x2e, 0xa1, 0xc3, 0x5d, 0x71, - 0x89, 0xcb, 0x86, 0xf6, 0xc4, 0x72, 0x49, 0xaf, 0x5d, 0xe4, 0xca, 0x80, 0xb8, 0xec, 0x90, 0x8b, - 0xb9, 0x2b, 0x6e, 0x44, 0xa0, 0x47, 0xb0, 0x78, 0x8e, 0xc7, 0x2e, 0x19, 0x9e, 0x4f, 0xa9, 0x7d, - 0xd1, 0x03, 0x61, 0xda, 0xcb, 0x9a, 0x1e, 0x70, 0x85, 0x03, 0x2e, 0x3f, 0x5d, 0x30, 0xe1, 0x3c, - 0xa6, 0xd0, 0x03, 0x68, 0x63, 0xe2, 0x28, 0xd3, 0x45, 0x61, 0xba, 0x91, 0xcb, 0x00, 0xe2, 0x44, - 0x86, 0x2d, 0xac, 0xbe, 0x0f, 0x9a, 0x50, 0xbf, 0xb4, 0xa6, 0x21, 0x36, 0x6e, 0xc1, 0x62, 0x2a, - 0x53, 0x50, 0x0f, 0x9a, 0x33, 0x1c, 0x04, 0xd6, 0x18, 0x8b, 0x74, 0x6a, 0x9b, 0x11, 0x69, 0x74, - 0x60, 0x29, 0x9d, 0x27, 0x29, 0x43, 0x9e, 0x0b, 0xdc, 0xf0, 0x12, 0xfb, 0x01, 0x4f, 0x00, 0x65, - 0xa8, 0x48, 0xe3, 0x23, 0xd0, 0xf3, 0x49, 0x80, 0x74, 0xa8, 0x5e, 0xe0, 0x2b, 0xa5, 0xc9, 0x3f, - 0x51, 0x57, 0x1d, 0x48, 0xa4, 0x66, 0xdb, 0x54, 0xa7, 0x33, 0x62, 0xdb, 0x38, 0x0d, 0x50, 0x07, - 0x2a, 0x6c, 0x2e, 0x4c, 0x97, 0xcc, 0x0a, 0x9b, 0x1b, 0x37, 0xa0, 0x93, 0xbd, 0xf2, 0x6b, 0x1a, - 0x4e, 0x7c, 0x74, 0x71, 0x67, 0x08, 0x41, 0xcd, 0xb1, 0x98, 0xa5, 0x34, 0xc4, 0x37, 0xe7, 0x79, - 0x16, 0x9b, 0xa8, 0xed, 0xc5, 0x37, 0xda, 0x80, 0xc6, 0x04, 0xbb, 0xe3, 0x09, 0x13, 0x35, 0x50, - 0x33, 0x15, 0xc5, 0xcf, 0xea, 0xf9, 0xf4, 0x12, 0x8b, 0x54, 0x6f, 0x99, 0x92, 0x30, 0x56, 0x60, - 0x39, 0x93, 0x48, 0xc6, 0x51, 0x7c, 0xf8, 0xf8, 0xe2, 0xd1, 0x07, 0x00, 0x97, 0xd6, 0xd4, 0x75, - 0x2c, 0x46, 0xfd, 0xa0, 0xa7, 0xdd, 0xa8, 0x6e, 0x2f, 0xee, 0xea, 0xea, 0xbe, 0x5e, 0x45, 0x02, - 0x33, 0xa5, 0x63, 0x3c, 0x85, 0xd5, 0x6b, 0x39, 0xc0, 0x4f, 0x3b, 0xb1, 0x82, 0x49, 0xe4, 0x01, - 0xff, 0x46, 0x37, 0xf9, 0x69, 0x2d, 0x07, 0xfb, 0xaa, 0xba, 0x97, 0xd5, 0xb2, 0xa7, 0x82, 0x69, - 0x2a, 0xa1, 0xb1, 0x03, 0x2b, 0xb9, 0xc4, 0x48, 0xf9, 0xa9, 0xa5, 0xfd, 0x34, 0xde, 0xd6, 0xa1, - 0x65, 0xe2, 0xc0, 0xa3, 0x24, 0xc0, 0xe8, 0x21, 0xb4, 0xf1, 0xdc, 0xc6, 0xb2, 0xc6, 0xb5, 0x5c, - 0x8e, 0x4a, 0x9d, 0xe3, 0x48, 0xce, 0xf3, 0x3b, 0x56, 0x46, 0x3b, 0x0a, 0x9f, 0xf2, 0xa0, 0xa3, - 0x8c, 0xd2, 0x00, 0x75, 0x27, 0x02, 0xa8, 0x6a, 0xae, 0x40, 0xa5, 0x6e, 0x0e, 0xa1, 0x76, 0x14, - 0x42, 0xd5, 0x0a, 0x17, 0xce, 0x40, 0xd4, 0x5e, 0x06, 0xa2, 0xea, 0x85, 0xc7, 0x2f, 0xc1, 0xa8, - 0xbd, 0x0c, 0x46, 0x35, 0x0a, 0x4d, 0x4b, 0x40, 0xea, 0x7e, 0x0a, 0xa4, 0x9a, 0xb9, 0xda, 0x94, - 0x86, 0x05, 0x28, 0x75, 0x2f, 0x46, 0xa9, 0x56, 0x0e, 0xd7, 0x94, 0x49, 0x1e, 0xa6, 0xee, 0x44, - 0x30, 0xd5, 0x2e, 0x0c, 0x5a, 0x0e, 0xa7, 0xf6, 0x32, 0x38, 0x05, 0x85, 0xee, 0x94, 0x00, 0xd5, - 0xc7, 0x59, 0xa0, 0x92, 0x68, 0xb3, 0x95, 0xb3, 0x2d, 0x45, 0xaa, 0x0f, 0xd3, 0x48, 0xb5, 0x94, - 0xc3, 0x47, 0x95, 0x0b, 0xef, 0x84, 0xaa, 0x1d, 0x5e, 0x09, 0xb9, 0x4c, 0xe3, 0xb5, 0x88, 0x7d, - 0x9f, 0xfa, 0x0a, 0x4b, 0x24, 0x61, 0x6c, 0xf3, 0x8a, 0x4f, 0xf2, 0xeb, 0x1d, 0xb0, 0x26, 0xaa, - 0x36, 0x95, 0x5d, 0xc6, 0x37, 0x5a, 0x62, 0x2b, 0x90, 0x2d, 0x8d, 0x16, 0x6d, 0x85, 0x16, 0x29, - 0xb4, 0xab, 0x64, 0xd0, 0x0e, 0xdd, 0x86, 0xd5, 0xa9, 0x15, 0x30, 0xe9, 0xe6, 0x30, 0x03, 0x1f, - 0x2b, 0x5c, 0x20, 0xfd, 0x93, 0x38, 0xf2, 0x7f, 0x58, 0x4b, 0xe9, 0x5a, 0x9e, 0x37, 0x14, 0x45, - 0x5d, 0x13, 0x45, 0xad, 0xc7, 0xda, 0xfb, 0x9e, 0x77, 0x6a, 0x05, 0x13, 0xe3, 0x66, 0xe2, 0x7f, - 0x06, 0x49, 0xa7, 0x74, 0x1c, 0x21, 0xe9, 0x94, 0x8e, 0x8d, 0x2f, 0x13, 0xb5, 0x04, 0x34, 0xff, - 0x03, 0x35, 0x9b, 0x3a, 0xd2, 0xfb, 0xce, 0xee, 0x8a, 0x8a, 0xfb, 0x21, 0x75, 0xf0, 0x8b, 0x2b, - 0x0f, 0x9b, 0x42, 0x18, 0x7b, 0x5a, 0x49, 0xe1, 0xa2, 0x5a, 0xbf, 0x9a, 0xac, 0xff, 0x05, 0x07, - 0x90, 0x4c, 0xf6, 0xbe, 0xcf, 0xd5, 0xbf, 0xd3, 0x92, 0x0b, 0x91, 0x68, 0xfd, 0x8f, 0x16, 0xef, - 0x42, 0xdd, 0x25, 0x0e, 0x9e, 0x8b, 0xd5, 0xab, 0xa6, 0x24, 0xa2, 0x36, 0x53, 0x15, 0x3b, 0x66, - 0xdb, 0x8c, 0x0c, 0xb2, 0x24, 0x14, 0xa0, 0xd3, 0x91, 0x00, 0x86, 0x25, 0x53, 0x12, 0x29, 0x58, - 0x6c, 0x64, 0xe0, 0x5f, 0x1d, 0xba, 0x99, 0x1c, 0xfa, 0x73, 0xde, 0x82, 0xd2, 0xd5, 0xf9, 0x3e, - 0x23, 0xb2, 0x96, 0xdc, 0x67, 0x5c, 0x97, 0x46, 0x17, 0xd0, 0xf5, 0x82, 0x93, 0xad, 0x36, 0x5b, - 0x4a, 0xe8, 0xbf, 0x50, 0x77, 0xdc, 0xd1, 0xa8, 0xbc, 0xd9, 0x48, 0xb1, 0xf1, 0x6d, 0x05, 0x1a, - 0xb2, 0x55, 0xa0, 0x2d, 0x0e, 0x5b, 0x96, 0x4b, 0x86, 0xae, 0x13, 0x95, 0x8b, 0xa0, 0x07, 0x4e, - 0x2a, 0x26, 0x95, 0x4c, 0x4c, 0x10, 0xd4, 0x98, 0x3b, 0xc3, 0x2a, 0xd3, 0xc5, 0x37, 0xda, 0x84, - 0x26, 0x09, 0x67, 0x43, 0x36, 0x0f, 0x44, 0xb4, 0x6b, 0x66, 0x83, 0x84, 0xb3, 0x17, 0xf3, 0x00, - 0xed, 0xc2, 0x72, 0x2a, 0xef, 0x5d, 0x47, 0xe1, 0x71, 0x47, 0x1d, 0x4d, 0x9c, 0x7b, 0x70, 0x64, - 0x2e, 0xc6, 0x15, 0x30, 0x70, 0xd0, 0x36, 0x88, 0x82, 0x18, 0x4a, 0xcc, 0x93, 0x85, 0xd2, 0x10, - 0x71, 0xeb, 0x70, 0xbe, 0x02, 0x45, 0xde, 0x07, 0xff, 0x05, 0x6d, 0x1e, 0x49, 0xa9, 0xd2, 0x14, - 0x2a, 0x2d, 0xce, 0x10, 0xc2, 0x5b, 0xb0, 0x92, 0xf4, 0x56, 0xa9, 0xd2, 0x92, 0xab, 0x24, 0x6c, - 0xa1, 0xb8, 0x05, 0xad, 0xb8, 0x20, 0xdb, 0x42, 0xa3, 0x69, 0xa9, 0x3a, 0x1c, 0x40, 0x53, 0x1d, - 0xb1, 0xb0, 0x0f, 0xdf, 0x86, 0xba, 0x67, 0xf9, 0x2c, 0x50, 0xfd, 0x2e, 0x82, 0xe3, 0x33, 0xcb, - 0xe7, 0x03, 0x90, 0xea, 0xc6, 0x52, 0xc5, 0xd8, 0x83, 0xe5, 0x0c, 0x9f, 0x67, 0x22, 0xa3, 0xcc, - 0x9a, 0xaa, 0x4e, 0x2c, 0x89, 0x78, 0x9b, 0x4a, 0xb2, 0x8d, 0xb1, 0x07, 0xed, 0xf8, 0x0e, 0xf9, - 0xb5, 0x78, 0xe1, 0xf9, 0x13, 0x35, 0x52, 0x2d, 0x99, 0x8a, 0x12, 0x89, 0x4d, 0xdf, 0xa8, 0x91, - 0xa0, 0x66, 0x4a, 0xe2, 0xf6, 0xf7, 0x75, 0x68, 0x45, 0xa9, 0x88, 0x1a, 0x50, 0x79, 0xf6, 0x44, - 0x5f, 0x40, 0xab, 0xb0, 0x3c, 0x20, 0x0c, 0xfb, 0xc4, 0x9a, 0x1e, 0x73, 0x0c, 0xd5, 0x35, 0xce, - 0x3a, 0x26, 0x36, 0x75, 0x5c, 0x32, 0x96, 0xac, 0x0a, 0x5a, 0x82, 0xd6, 0x81, 0xe5, 0x3c, 0xa5, - 0xc4, 0xc6, 0x7a, 0x15, 0xe9, 0xb0, 0xf4, 0x92, 0x58, 0x21, 0x9b, 0x50, 0xdf, 0xfd, 0x1a, 0x3b, - 0x7a, 0x0d, 0xad, 0xc3, 0xea, 0x80, 0x04, 0xe1, 0x68, 0xe4, 0xda, 0x2e, 0x26, 0xec, 0x71, 0x48, - 0x9c, 0x40, 0xaf, 0x23, 0x04, 0x9d, 0x97, 0xe4, 0x82, 0xd0, 0x37, 0x44, 0xcd, 0x1e, 0x7a, 0x03, - 0xf5, 0xa0, 0x7b, 0x60, 0x05, 0xf8, 0x28, 0xf4, 0xa6, 0xae, 0x6d, 0x31, 0xbc, 0xef, 0x38, 0x3e, - 0x0e, 0x02, 0x1d, 0xf3, 0x45, 0xb8, 0x24, 0xbb, 0xf7, 0x28, 0x32, 0xc8, 0xac, 0x8f, 0x71, 0xa0, - 0x8f, 0xd1, 0x16, 0xac, 0x5f, 0x93, 0x88, 0x9d, 0x27, 0xe8, 0xdf, 0xd0, 0xcb, 0x8b, 0x4e, 0xac, - 0xe0, 0xcc, 0x77, 0x6d, 0xac, 0xbb, 0xa8, 0x0b, 0xba, 0x94, 0x8a, 0xdb, 0x1f, 0x10, 0x2f, 0x64, - 0xfa, 0x57, 0xd1, 0xfe, 0x8a, 0xfb, 0x2c, 0x64, 0x9c, 0x7d, 0x91, 0x63, 0x9f, 0x89, 0x08, 0xeb, - 0x53, 0xb4, 0x09, 0x6b, 0x29, 0xf6, 0x73, 0xee, 0x1f, 0x8f, 0xce, 0x2c, 0x39, 0xaf, 0x14, 0xb8, - 0x63, 0x62, 0xb1, 0xd0, 0xc7, 0x3a, 0x41, 0x1b, 0x80, 0xb8, 0x44, 0x85, 0x24, 0x72, 0x9c, 0x46, - 0x3b, 0x28, 0xbe, 0xda, 0xc1, 0xcb, 0xb3, 0xa7, 0xe1, 0xd8, 0x25, 0xfa, 0x6b, 0xb4, 0x0e, 0xfa, - 0x09, 0xbd, 0x54, 0xdc, 0x63, 0xc2, 0x5c, 0x76, 0xa5, 0xff, 0xa8, 0xa1, 0x2e, 0xac, 0x24, 0xec, - 0x13, 0x9f, 0x86, 0x9e, 0xfe, 0x93, 0x86, 0x36, 0x01, 0x25, 0xdc, 0x33, 0x9f, 0x7a, 0x34, 0xb0, - 0xa6, 0xfa, 0xcf, 0x1a, 0xda, 0x80, 0xd5, 0x13, 0x7a, 0x19, 0xdf, 0x82, 0x34, 0xf8, 0x25, 0x32, - 0x88, 0xf9, 0x9f, 0xe2, 0xd9, 0x39, 0xf6, 0xf5, 0x5f, 0x35, 0xb4, 0x05, 0xdd, 0xb4, 0x20, 0x5e, - 0xeb, 0x37, 0x4d, 0x9d, 0x28, 0x16, 0xbd, 0xa2, 0x0c, 0xeb, 0xbf, 0x47, 0x6c, 0x15, 0x07, 0xb5, - 0xd0, 0x1f, 0x1a, 0x5a, 0x83, 0x4e, 0xc2, 0x16, 0xba, 0x7f, 0x6a, 0xa8, 0x0f, 0xeb, 0x19, 0xa6, - 0x4b, 0xc6, 0x67, 0x3c, 0x69, 0xf5, 0xbf, 0xb4, 0xdd, 0xb7, 0x75, 0x58, 0xd9, 0x3f, 0x38, 0x1c, - 0xec, 0x7b, 0x72, 0x03, 0xde, 0xff, 0xee, 0x41, 0x4d, 0x74, 0xf8, 0x82, 0x67, 0x6f, 0xbf, 0x68, - 0xd4, 0x44, 0xbb, 0x50, 0x17, 0x8d, 0x1e, 0x15, 0xbd, 0x7e, 0xfb, 0x85, 0x13, 0x27, 0xdf, 0x44, - 0x8e, 0x02, 0xd7, 0x1f, 0xc1, 0xfd, 0xa2, 0xb1, 0x13, 0x7d, 0x02, 0xed, 0xa4, 0x45, 0x97, 0x3d, - 0x85, 0xfb, 0xa5, 0x03, 0x28, 0xb7, 0x4f, 0x7a, 0x77, 0xd9, 0x83, 0xb8, 0x5f, 0x3a, 0x85, 0xa2, - 0x87, 0xd0, 0x8c, 0x7a, 0x73, 0xf1, 0xb3, 0xb8, 0x5f, 0x32, 0x88, 0xf2, 0xf0, 0xc8, 0xb6, 0x5b, - 0xf4, 0xda, 0xed, 0x17, 0xce, 0x96, 0xe8, 0x01, 0x34, 0x54, 0xdb, 0x2b, 0x7c, 0x51, 0xf7, 0x8b, - 0x27, 0x58, 0xee, 0x64, 0xf2, 0x30, 0x2a, 0x7b, 0x2a, 0xf7, 0x4b, 0x67, 0x53, 0xb4, 0x0f, 0x90, - 0x7a, 0x12, 0x95, 0x3e, 0x98, 0xfb, 0xe5, 0x13, 0x2a, 0x7a, 0x04, 0xad, 0xe4, 0x15, 0x54, 0xfc, - 0x6c, 0xee, 0x97, 0x0d, 0xa9, 0xe7, 0x0d, 0xf1, 0x8f, 0xcc, 0xfd, 0xbf, 0x03, 0x00, 0x00, 0xff, - 0xff, 0xbd, 0xb6, 0xa5, 0xad, 0xa6, 0x11, 0x00, 0x00, +var fileDescriptorTypes = []byte{ + // 1554 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xbc, 0x98, 0xcb, 0x6e, 0xdb, 0x46, + 0x17, 0xc7, 0x2d, 0x51, 0xd4, 0xe5, 0xf8, 0x26, 0x8f, 0xfd, 0x25, 0x8a, 0xb2, 0x88, 0x43, 0xe0, + 0x6b, 0xe4, 0x5c, 0xac, 0xd4, 0x41, 0x8a, 0x38, 0x29, 0x0a, 0x58, 0x71, 0x52, 0x09, 0x01, 0xd2, + 0x74, 0x62, 0x64, 0x2b, 0x50, 0xe2, 0x48, 0x22, 0x22, 0x91, 0x0c, 0x39, 0x72, 0xe4, 0xa2, 0x8f, + 0x90, 0x7d, 0xd7, 0xed, 0xa6, 0x40, 0x5f, 0xa0, 0xcb, 0xee, 0x8a, 0x3e, 0x43, 0x17, 0x79, 0x96, + 0x62, 0xce, 0x0c, 0xaf, 0x26, 0xb3, 0xc8, 0x22, 0x1b, 0x63, 0x2e, 0xe7, 0x3f, 0x3a, 0x33, 0x3c, + 0xf3, 0x3b, 0x67, 0x0c, 0x3b, 0xfc, 0xc2, 0x63, 0x41, 0x17, 0xff, 0x1e, 0x7a, 0xbe, 0xcb, 0x5d, + 0xa2, 0x63, 0xa7, 0x7d, 0x6f, 0x6a, 0xf3, 0xd9, 0x72, 0x74, 0x38, 0x76, 0x17, 0xdd, 0xa9, 0x3b, + 0x75, 0xbb, 0x38, 0x3b, 0x5a, 0x4e, 0xb0, 0x87, 0x1d, 0x6c, 0x49, 0x95, 0xf1, 0x77, 0x05, 0x6a, + 0x94, 0xbd, 0x5b, 0xb2, 0x80, 0x93, 0x0e, 0x54, 0xd8, 0x78, 0xe6, 0xb6, 0x4a, 0xfb, 0xa5, 0xce, + 0xfa, 0x11, 0x39, 0x94, 0xab, 0xab, 0xd9, 0x67, 0xe3, 0x99, 0xdb, 0x5f, 0xa3, 0x68, 0x41, 0xee, + 0x80, 0x3e, 0x99, 0x2f, 0x83, 0x59, 0xab, 0x8c, 0xa6, 0xbb, 0x69, 0xd3, 0xe7, 0x62, 0xaa, 0xbf, + 0x46, 0xa5, 0x8d, 0x58, 0xd6, 0x76, 0x26, 0x6e, 0x4b, 0xcb, 0x5b, 0x76, 0xe0, 0x4c, 0x70, 0x59, + 0x61, 0x41, 0x1e, 0x01, 0x04, 0x8c, 0x0f, 0x5d, 0x8f, 0xdb, 0xae, 0xd3, 0xaa, 0xa0, 0xfd, 0xd5, + 0xb4, 0xfd, 0x6b, 0xc6, 0x7f, 0xc0, 0xe9, 0xfe, 0x1a, 0x6d, 0x04, 0x61, 0x47, 0x28, 0x2d, 0x36, + 0xb7, 0xcf, 0x99, 0x3f, 0xe4, 0xab, 0x96, 0x9e, 0xa7, 0x3c, 0x95, 0xf3, 0x67, 0x2b, 0xa1, 0xb4, + 0xc2, 0x0e, 0x39, 0x82, 0xfa, 0x78, 0xc6, 0xc6, 0x6f, 0x85, 0xae, 0x8a, 0xba, 0xff, 0xa5, 0x75, + 0x4f, 0xc5, 0x2c, 0xaa, 0x6a, 0x63, 0xd9, 0x24, 0x87, 0x50, 0x1d, 0xbb, 0x8b, 0x85, 0xcd, 0x5b, + 0x35, 0x54, 0xec, 0x65, 0x14, 0x38, 0xd7, 0x5f, 0xa3, 0xca, 0x4a, 0x1c, 0xd7, 0xbb, 0x25, 0xf3, + 0x2f, 0x5a, 0xf5, 0xbc, 0xe3, 0xfa, 0x51, 0x4c, 0x89, 0xe3, 0x42, 0x1b, 0xb1, 0x15, 0xdb, 0xb1, + 0xf9, 0x70, 0x3c, 0x33, 0x6d, 0xa7, 0xd5, 0xc8, 0xdb, 0xca, 0xc0, 0xb1, 0xf9, 0x53, 0x31, 0x2d, + 0xb6, 0x62, 0x87, 0x1d, 0xf2, 0x04, 0xd6, 0x47, 0x6c, 0x6a, 0x3b, 0xc3, 0xd1, 0xdc, 0x1d, 0xbf, + 0x6d, 0x01, 0x4a, 0x5b, 0x69, 0x69, 0x4f, 0x18, 0xf4, 0xc4, 0x7c, 0x7f, 0x8d, 0xc2, 0x28, 0xea, + 0x91, 0x87, 0xd0, 0x60, 0x8e, 0xa5, 0xa4, 0xeb, 0x28, 0xbd, 0x92, 0x89, 0x00, 0xc7, 0x0a, 0x85, + 0x75, 0xa6, 0xda, 0xbd, 0x1a, 0xe8, 0xe7, 0xe6, 0x7c, 0xc9, 0x8c, 0x5b, 0xb0, 0x9e, 0x88, 0x14, + 0xd2, 0x82, 0xda, 0x82, 0x05, 0x81, 0x39, 0x65, 0x18, 0x4e, 0x0d, 0x1a, 0x76, 0x8d, 0x2d, 0xd8, + 0x48, 0xc6, 0x49, 0x42, 0x28, 0x62, 0x41, 0x08, 0xcf, 0x99, 0x1f, 0x88, 0x00, 0x50, 0x42, 0xd5, + 0x35, 0x1e, 0x43, 0x33, 0x1b, 0x04, 0xa4, 0x09, 0xda, 0x5b, 0x76, 0xa1, 0x2c, 0x45, 0x93, 0xec, + 0x29, 0x87, 0x30, 0x34, 0x1b, 0x54, 0x79, 0x67, 0x44, 0xda, 0x28, 0x0c, 0xc8, 0x16, 0x94, 0xf9, + 0x0a, 0xa5, 0x1b, 0xb4, 0xcc, 0x57, 0xc6, 0x3e, 0x6c, 0xa5, 0x3f, 0xf9, 0x25, 0x0b, 0x2b, 0x72, + 0x1d, 0xbf, 0x19, 0x21, 0x50, 0xb1, 0x4c, 0x6e, 0x2a, 0x0b, 0x6c, 0x8b, 0x31, 0xcf, 0xe4, 0x33, + 0xf5, 0xf3, 0xd8, 0x26, 0x57, 0xa0, 0x3a, 0x63, 0xf6, 0x74, 0xc6, 0xf1, 0x0e, 0x68, 0x54, 0xf5, + 0x84, 0xaf, 0x9e, 0xef, 0x9e, 0x33, 0x0c, 0xf5, 0x3a, 0x95, 0x1d, 0x63, 0x1b, 0x36, 0x53, 0x81, + 0x64, 0x9c, 0x46, 0xce, 0x47, 0x1f, 0x9e, 0xdc, 0x07, 0x38, 0x37, 0xe7, 0xb6, 0x65, 0x72, 0xd7, + 0x0f, 0x5a, 0xa5, 0x7d, 0xad, 0xb3, 0x7e, 0xd4, 0x54, 0xdf, 0xeb, 0x4d, 0x38, 0x41, 0x13, 0x36, + 0xc6, 0x5f, 0x25, 0xd8, 0xb9, 0x14, 0x04, 0xc2, 0xdd, 0x99, 0x19, 0xcc, 0xc2, 0x2d, 0x88, 0x36, + 0xf9, 0xbf, 0x70, 0xd7, 0xb4, 0x98, 0xaf, 0xae, 0xf7, 0xa6, 0x5a, 0xb7, 0x8f, 0x83, 0x54, 0x4d, + 0x92, 0x3b, 0xb0, 0x63, 0x8e, 0x02, 0xe6, 0xf0, 0x61, 0xc2, 0x13, 0x6d, 0x5f, 0xeb, 0xe8, 0xb4, + 0x29, 0x27, 0x22, 0x47, 0x02, 0xd2, 0x83, 0xbd, 0xd1, 0xc5, 0x4f, 0xa6, 0xc3, 0x6d, 0x87, 0x25, + 0xed, 0x2b, 0xe8, 0xf9, 0xb6, 0xfa, 0x85, 0x67, 0xe7, 0xb6, 0xc5, 0x9c, 0x31, 0xa3, 0xbb, 0x91, + 0x71, 0xbc, 0x86, 0x71, 0x00, 0xdb, 0x99, 0x50, 0x4c, 0x9c, 0x6c, 0x29, 0x79, 0xb2, 0xc6, 0x07, + 0x1d, 0xea, 0x94, 0x05, 0x9e, 0xeb, 0x04, 0x8c, 0x3c, 0x82, 0x06, 0x5b, 0x8d, 0x99, 0xa4, 0x4a, + 0x29, 0x73, 0x2b, 0xa4, 0xcd, 0xb3, 0x70, 0x5e, 0xdc, 0xa8, 0xc8, 0x98, 0x1c, 0x28, 0x22, 0x66, + 0x31, 0xa7, 0x44, 0x49, 0x24, 0xde, 0x0d, 0x91, 0xa8, 0x65, 0x90, 0x20, 0x6d, 0x33, 0x4c, 0x3c, + 0x50, 0x4c, 0xac, 0xe4, 0x2e, 0x9c, 0x82, 0xe2, 0x71, 0x0a, 0x8a, 0x7a, 0xae, 0xfb, 0x05, 0x54, + 0x3c, 0x4e, 0x51, 0xb1, 0x9a, 0x2b, 0x2d, 0xc0, 0xe2, 0x83, 0x04, 0x16, 0x6b, 0x19, 0x1a, 0x48, + 0x61, 0x0e, 0x17, 0xbb, 0x11, 0x17, 0xeb, 0x19, 0x92, 0x2a, 0x49, 0x16, 0x8c, 0x77, 0x43, 0x30, + 0x36, 0x72, 0x0f, 0x2d, 0x43, 0xc6, 0xe3, 0x14, 0x19, 0x21, 0x77, 0x3b, 0x05, 0x68, 0xfc, 0x36, + 0x8d, 0x46, 0xc9, 0xb7, 0x6b, 0x19, 0x6d, 0x21, 0x1b, 0xbf, 0x49, 0xb2, 0x71, 0x23, 0x43, 0x64, + 0x15, 0x0b, 0x9f, 0x84, 0xe3, 0x81, 0xb8, 0x7a, 0x99, 0x48, 0x13, 0xb7, 0x9f, 0xf9, 0xbe, 0xeb, + 0x2b, 0x7a, 0xc9, 0x8e, 0xd1, 0x11, 0x8c, 0x89, 0xe3, 0xeb, 0x13, 0x20, 0x45, 0x4e, 0x24, 0xa2, + 0xcb, 0xf8, 0xa5, 0x14, 0x6b, 0x91, 0xa5, 0x49, 0x3e, 0x35, 0x14, 0x9f, 0x12, 0x7c, 0x2d, 0xa7, + 0xf8, 0x4a, 0x6e, 0xc3, 0xce, 0xdc, 0x0c, 0xb8, 0xdc, 0xe6, 0x30, 0x05, 0xac, 0x6d, 0x31, 0x21, + 0xf7, 0x27, 0xc9, 0x75, 0x0f, 0x76, 0x13, 0xb6, 0xa6, 0xe7, 0x0d, 0x91, 0x22, 0x15, 0xa4, 0x48, + 0x33, 0xb2, 0x3e, 0xf1, 0xbc, 0xbe, 0x19, 0xcc, 0x8c, 0xe3, 0x78, 0xff, 0x31, 0xbb, 0x09, 0x54, + 0xc6, 0xae, 0x25, 0xb7, 0xb5, 0x49, 0xb1, 0x2d, 0x78, 0x3e, 0x77, 0xa7, 0xca, 0x33, 0xd1, 0x34, + 0x7e, 0x2b, 0xc5, 0xda, 0x98, 0xdd, 0x79, 0xda, 0x53, 0xb5, 0x5b, 0x21, 0xde, 0xe8, 0xdd, 0xff, + 0xe7, 0xe3, 0x8d, 0xb5, 0x7f, 0x3f, 0xde, 0xe8, 0x24, 0xea, 0x21, 0xce, 0x1c, 0x8b, 0xf9, 0x0b, + 0xdb, 0xe1, 0xdd, 0xa9, 0x7b, 0xef, 0xbd, 0xed, 0xb3, 0xae, 0x50, 0x1c, 0xf6, 0x2e, 0x38, 0x0b, + 0xd4, 0xf9, 0x28, 0x0f, 0xb4, 0xc8, 0x03, 0x72, 0x13, 0x2a, 0xdc, 0x9c, 0x86, 0xa8, 0x0a, 0x61, + 0xf8, 0xe2, 0xcd, 0x2b, 0xd3, 0xf6, 0x29, 0x4e, 0x19, 0xbf, 0x96, 0x04, 0x9a, 0x52, 0xf7, 0xe2, + 0x8b, 0xba, 0xd8, 0x04, 0x6d, 0x6a, 0x06, 0x78, 0xfc, 0x1a, 0x15, 0x4d, 0x31, 0x32, 0x61, 0x0c, + 0x71, 0xa1, 0x51, 0xd1, 0x34, 0xfe, 0x2c, 0xc7, 0xf1, 0x12, 0xa5, 0xaf, 0x4b, 0x1e, 0xee, 0x81, + 0x6e, 0x3b, 0x16, 0x5b, 0xa1, 0x8b, 0x1a, 0x95, 0x1d, 0xd2, 0x93, 0x69, 0x56, 0xfb, 0x4c, 0xb7, + 0x31, 0x31, 0x3f, 0x0f, 0x13, 0x73, 0xe5, 0x33, 0x57, 0x91, 0x72, 0xb1, 0x8e, 0xe7, 0xbb, 0xee, + 0x04, 0xf7, 0xf6, 0x59, 0xeb, 0xa0, 0x3c, 0x91, 0x3a, 0xaa, 0xa9, 0xa4, 0xac, 0x4e, 0xb7, 0x16, + 0x87, 0xe0, 0xcf, 0xa2, 0x30, 0x48, 0x12, 0xec, 0x4b, 0x7e, 0x5b, 0x63, 0x37, 0x8e, 0xff, 0x08, + 0x6e, 0xc6, 0x1e, 0x90, 0xcb, 0xd4, 0x92, 0x15, 0x52, 0x9a, 0x47, 0xe4, 0x2b, 0xd0, 0x2d, 0x7b, + 0x32, 0x29, 0xae, 0x11, 0xe4, 0xb4, 0xf1, 0x7b, 0x19, 0xaa, 0x32, 0xc1, 0x93, 0x6b, 0x82, 0xfd, + 0xa6, 0xed, 0x0c, 0x6d, 0x2b, 0x64, 0x0e, 0xf6, 0x07, 0x56, 0xe2, 0xd0, 0xca, 0xa9, 0x43, 0x23, + 0x50, 0xe1, 0xf6, 0x82, 0x29, 0x5c, 0x60, 0x9b, 0x5c, 0x85, 0x9a, 0xb3, 0x5c, 0x0c, 0xf9, 0x4a, + 0x06, 0xa6, 0x4e, 0xab, 0xce, 0x72, 0x71, 0xb6, 0x0a, 0xc8, 0x11, 0x6c, 0x26, 0xe0, 0x61, 0x5b, + 0x2a, 0xa9, 0x6d, 0x29, 0xd7, 0xd0, 0xef, 0xc1, 0x29, 0x5d, 0x8f, 0x30, 0x32, 0xb0, 0x48, 0x07, + 0x90, 0x2a, 0x43, 0x99, 0x38, 0x24, 0x6d, 0xaa, 0x48, 0x9b, 0x2d, 0x31, 0xae, 0x32, 0x8b, 0xa8, + 0x5e, 0xae, 0x43, 0x43, 0x9c, 0xa4, 0x34, 0xa9, 0xa1, 0x49, 0x5d, 0x0c, 0xe0, 0xe4, 0x2d, 0xd8, + 0x8e, 0x8b, 0x0f, 0x69, 0x52, 0x97, 0xab, 0xc4, 0xc3, 0x68, 0x78, 0x0d, 0xea, 0x11, 0xd5, 0x1a, + 0x68, 0x51, 0x33, 0x15, 0xcc, 0x06, 0x50, 0x53, 0x2e, 0xe6, 0x56, 0x4f, 0xb7, 0x41, 0xf7, 0x4c, + 0x9f, 0x07, 0xaa, 0x68, 0x08, 0x73, 0xda, 0x2b, 0xd3, 0x17, 0x75, 0xab, 0xaa, 0xa1, 0xa4, 0x89, + 0x71, 0x0c, 0x9b, 0xa9, 0x71, 0x71, 0xfd, 0xb8, 0xcb, 0xcd, 0x39, 0xae, 0xa8, 0x53, 0xd9, 0x89, + 0x7e, 0xa6, 0x1c, 0xff, 0x8c, 0xf1, 0x18, 0x1a, 0xd1, 0x37, 0x14, 0x47, 0xed, 0x2d, 0x47, 0xc3, + 0xb0, 0x14, 0xde, 0xa0, 0x55, 0x6f, 0x39, 0x7a, 0x21, 0xab, 0x61, 0xcf, 0x7d, 0xaf, 0x2a, 0x39, + 0x8d, 0xca, 0x8e, 0xf1, 0x04, 0xea, 0x61, 0xa5, 0x55, 0x2c, 0x2d, 0xf8, 0xd4, 0xc6, 0x1f, 0x25, + 0xa8, 0x4a, 0xf8, 0xe5, 0x54, 0xdf, 0x5f, 0x63, 0x59, 0xba, 0x64, 0x43, 0xb1, 0x69, 0x14, 0x6e, + 0x45, 0x2f, 0x3e, 0x29, 0x3a, 0x3c, 0xbb, 0xf0, 0x18, 0x6d, 0xa0, 0x95, 0x68, 0x92, 0x9b, 0xb0, + 0x21, 0x25, 0x01, 0xf7, 0x6d, 0x27, 0x0c, 0xfd, 0x75, 0x1c, 0x7b, 0x8d, 0x43, 0xe2, 0x93, 0x4a, + 0x13, 0xdb, 0xe1, 0x0a, 0x72, 0x75, 0x1c, 0x18, 0x38, 0xdc, 0xb8, 0x0e, 0x15, 0x5c, 0x07, 0xa0, + 0xfa, 0xfa, 0x8c, 0x0e, 0x5e, 0x7e, 0xdf, 0x5c, 0x23, 0x35, 0xd0, 0x06, 0x2f, 0xcf, 0x9a, 0xa5, + 0xa3, 0x0f, 0x3a, 0x6c, 0x9f, 0xf4, 0x9e, 0x0e, 0x4e, 0x3c, 0x6f, 0x6e, 0x8f, 0x4d, 0xcc, 0x3b, + 0x5d, 0xa8, 0x60, 0x66, 0xcd, 0x79, 0xe0, 0xb6, 0xf3, 0x4a, 0x3c, 0x72, 0x04, 0x3a, 0x26, 0x58, + 0x92, 0xf7, 0xce, 0x6d, 0xe7, 0x56, 0x7a, 0xe2, 0x47, 0x64, 0x0a, 0xbe, 0xfc, 0xdc, 0x6d, 0xe7, + 0x95, 0x7b, 0xe4, 0x3b, 0x68, 0xc4, 0xa9, 0xb1, 0xe8, 0xd1, 0xdb, 0x2e, 0x2c, 0xfc, 0x84, 0x3e, + 0x4e, 0x8f, 0x45, 0x4f, 0xdf, 0x76, 0x61, 0xf5, 0x47, 0x1e, 0x41, 0x2d, 0xcc, 0x5c, 0xf9, 0x0f, + 0xe0, 0x76, 0x41, 0x01, 0x28, 0x8e, 0x47, 0xe6, 0x93, 0xbc, 0x77, 0x6d, 0x3b, 0xb7, 0xa6, 0x23, + 0x0f, 0xa1, 0xaa, 0x50, 0x9a, 0xfb, 0x76, 0x6e, 0xe7, 0x57, 0x8e, 0x62, 0x93, 0xf1, 0x13, 0xa8, + 0xe8, 0x51, 0xdc, 0x2e, 0xac, 0x09, 0xc9, 0x09, 0x40, 0xe2, 0xed, 0x53, 0xf8, 0x34, 0x6e, 0x17, + 0x57, 0x86, 0x44, 0xdc, 0x9d, 0xe8, 0xf5, 0x91, 0xff, 0x40, 0x6e, 0x17, 0x15, 0x87, 0xa3, 0x2a, + 0xfe, 0xd3, 0xe5, 0xc1, 0x7f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x00, 0x4d, 0x6a, 0x92, 0xbf, 0x11, + 0x00, 0x00, } diff --git a/types/types.proto b/types/types.proto index 802d8fc5..516cca15 100644 --- a/types/types.proto +++ b/types/types.proto @@ -1,115 +1,77 @@ syntax = "proto3"; package types; +import "github.com/gogo/protobuf/gogoproto/gogo.proto"; + + // This file is copied from http://github.com/tendermint/abci -//---------------------------------------- -// Code types - -enum CodeType { - OK = 0; - - // General response codes, 0 ~ 99 - InternalError = 1; - EncodingError = 2; - BadNonce = 3; - Unauthorized = 4; - InsufficientFunds = 5; - UnknownRequest = 6; - - // Reserved for basecoin, 100 ~ 199 - BaseDuplicateAddress = 101; - BaseEncodingError = 102; - BaseInsufficientFees = 103; - BaseInsufficientFunds = 104; - BaseInsufficientGasPrice = 105; - BaseInvalidInput = 106; - BaseInvalidOutput = 107; - BaseInvalidPubKey = 108; - BaseInvalidSequence = 109; - BaseInvalidSignature = 110; - BaseUnknownAddress = 111; - BaseUnknownPubKey = 112; - BaseUnknownPlugin = 113; - - // Reserved for governance, 200 ~ 299 - GovUnknownEntity = 201; - GovUnknownGroup = 202; - GovUnknownProposal = 203; - GovDuplicateGroup = 204; - GovDuplicateMember = 205; - GovDuplicateProposal = 206; - GovDuplicateVote = 207; - GovInvalidMember = 208; - GovInvalidVote = 209; - GovInvalidVotingPower = 210; - -} - //---------------------------------------- // Request types message Request { - oneof value{ - RequestEcho echo = 1; - RequestFlush flush = 2; - RequestInfo info = 3; - RequestSetOption set_option = 4; - RequestDeliverTx deliver_tx = 5; - RequestCheckTx check_tx = 6; - RequestCommit commit = 7; - RequestQuery query = 8; - RequestInitChain init_chain = 9; - RequestBeginBlock begin_block = 10; - RequestEndBlock end_block = 11; - } + oneof value{ + RequestEcho echo = 1; + RequestFlush flush = 2; + RequestInfo info = 3; + RequestSetOption set_option = 4; + RequestDeliverTx deliver_tx = 5; + RequestCheckTx check_tx = 6; + RequestCommit commit = 7; + RequestQuery query = 8; + RequestInitChain init_chain = 9; + RequestBeginBlock begin_block = 10; + RequestEndBlock end_block = 11; + } } message RequestEcho { - string message = 1; + string message = 1; } message RequestFlush { } message RequestInfo { - string version = 1; + string version = 1; } message RequestSetOption{ - string key = 1; - string value = 2; + string key = 1; + string value = 2; } message RequestDeliverTx{ - bytes tx = 1; + bytes tx = 1; } message RequestCheckTx{ - bytes tx = 1; + bytes tx = 1; } message RequestQuery{ - bytes data = 1; - string path = 2; - uint64 height = 3; - bool prove = 4; + bytes data = 1; + string path = 2; + int64 height = 3; + bool prove = 4; } message RequestCommit{ } message RequestInitChain{ - repeated Validator validators = 1; + repeated Validator validators = 1; } message RequestBeginBlock{ - bytes hash = 1; - Header header = 2; + bytes hash = 1; + Header header = 2; + repeated int32 absent_validators = 3; + repeated Evidence byzantine_validators = 4; } message RequestEndBlock{ - uint64 height = 1; + int64 height = 1; } //---------------------------------------- @@ -117,70 +79,74 @@ message RequestEndBlock{ message Response { - oneof value{ - ResponseException exception = 1; - ResponseEcho echo = 2; - ResponseFlush flush = 3; - ResponseInfo info = 4; - ResponseSetOption set_option = 5; - ResponseDeliverTx deliver_tx = 6; - ResponseCheckTx check_tx = 7; - ResponseCommit commit = 8; - ResponseQuery query = 9; - ResponseInitChain init_chain = 10; - ResponseBeginBlock begin_block = 11; - ResponseEndBlock end_block = 12; - } + oneof value{ + ResponseException exception = 1; + ResponseEcho echo = 2; + ResponseFlush flush = 3; + ResponseInfo info = 4; + ResponseSetOption set_option = 5; + ResponseDeliverTx deliver_tx = 6; + ResponseCheckTx check_tx = 7; + ResponseCommit commit = 8; + ResponseQuery query = 9; + ResponseInitChain init_chain = 10; + ResponseBeginBlock begin_block = 11; + ResponseEndBlock end_block = 12; + } } message ResponseException{ - string error = 1; + string error = 1; } message ResponseEcho { - string message = 1; + string message = 1; } message ResponseFlush{ } message ResponseInfo { - string data = 1; - string version = 2; - uint64 last_block_height = 3; - bytes last_block_app_hash = 4; + string data = 1; + string version = 2; + int64 last_block_height = 3; + bytes last_block_app_hash = 4; } message ResponseSetOption{ - string log = 1; + uint32 code = 1; + string log = 2; } message ResponseDeliverTx{ - CodeType code = 1; - bytes data = 2; - string log = 3; + uint32 code = 1; + bytes data = 2 [(gogoproto.customtype) = "github.com/tendermint/go-wire/data.Bytes", (gogoproto.nullable) = false]; + string log = 3; + repeated KVPair tags = 4; } message ResponseCheckTx{ - CodeType code = 1; - bytes data = 2; - string log = 3; + uint32 code = 1; + bytes data = 2 [(gogoproto.customtype) = "github.com/tendermint/go-wire/data.Bytes", (gogoproto.nullable) = false]; + string log = 3; + int64 gas = 4; + int64 fee = 5; } message ResponseQuery{ - CodeType code = 1; - int64 index = 2; - bytes key = 3; - bytes value = 4; - bytes proof = 5; - uint64 height = 6; - string log = 7; + uint32 code = 1; + int64 index = 2; + bytes key = 3 [(gogoproto.customtype) = "github.com/tendermint/go-wire/data.Bytes", (gogoproto.nullable) = false]; + bytes value = 4 [(gogoproto.customtype) = "github.com/tendermint/go-wire/data.Bytes", (gogoproto.nullable) = false]; + bytes proof = 5 [(gogoproto.customtype) = "github.com/tendermint/go-wire/data.Bytes", (gogoproto.nullable) = false]; + int64 height = 6; + string log = 7; } message ResponseCommit{ - CodeType code = 1; - bytes data = 2; - string log = 3; + uint32 code = 1; + bytes data = 2 [(gogoproto.customtype) = "github.com/tendermint/go-wire/data.Bytes", (gogoproto.nullable) = false]; + string log = 3; } @@ -191,52 +157,71 @@ message ResponseBeginBlock{ } message ResponseEndBlock{ - repeated Validator diffs = 1; + repeated Validator diffs = 1; } //---------------------------------------- // Blockchain Types message Header { - string chain_id = 1; - uint64 height = 2; - uint64 time = 3; - uint64 num_txs = 4; - BlockID last_block_id = 5; - bytes last_commit_hash = 6; - bytes data_hash = 7; - bytes validators_hash = 8; - bytes app_hash = 9; + string chain_id = 1; + int64 height = 2; + int64 time = 3; + int32 num_txs = 4; + BlockID last_block_id = 5; + bytes last_commit_hash = 6; + bytes data_hash = 7; + bytes validators_hash = 8; + bytes app_hash = 9; } message BlockID { - bytes hash = 1; - PartSetHeader parts = 2; + bytes hash = 1; + PartSetHeader parts = 2; } message PartSetHeader { - uint64 total = 1; - bytes hash = 2; + int32 total = 1; + bytes hash = 2; } message Validator { - bytes pubKey = 1; - uint64 power = 2; + bytes pub_key = 1; + int64 power = 2; +} + +message Evidence { + bytes pub_key = 1; + int64 height = 2; +} + +//---------------------------------------- +// Abstract types + +message KVPair { + string key = 1; + enum Type { + STRING = 0; + INT = 1; + } + Type value_type = 2; + string value_string = 3; + int64 value_int = 4; } //---------------------------------------- // Service Definition service ABCIApplication { - rpc Echo(RequestEcho) returns (ResponseEcho) ; - rpc Flush(RequestFlush) returns (ResponseFlush); - rpc Info(RequestInfo) returns (ResponseInfo); - rpc SetOption(RequestSetOption) returns (ResponseSetOption); - rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx); - rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); - rpc Query(RequestQuery) returns (ResponseQuery); - rpc Commit(RequestCommit) returns (ResponseCommit); - rpc InitChain(RequestInitChain) returns (ResponseInitChain); - rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock); - rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock); + rpc Echo(RequestEcho) returns (ResponseEcho) ; + rpc Flush(RequestFlush) returns (ResponseFlush); + rpc Info(RequestInfo) returns (ResponseInfo); + rpc SetOption(RequestSetOption) returns (ResponseSetOption); + rpc DeliverTx(RequestDeliverTx) returns (ResponseDeliverTx); + rpc CheckTx(RequestCheckTx) returns (ResponseCheckTx); + rpc Query(RequestQuery) returns (ResponseQuery); + rpc Commit(RequestCommit) returns (ResponseCommit); + rpc InitChain(RequestInitChain) returns (ResponseInitChain); + rpc BeginBlock(RequestBeginBlock) returns (ResponseBeginBlock); + rpc EndBlock(RequestEndBlock) returns (ResponseEndBlock); } diff --git a/types/validators.go b/types/util.go similarity index 53% rename from types/validators.go rename to types/util.go index 95258aa2..17c53f65 100644 --- a/types/validators.go +++ b/types/util.go @@ -8,8 +8,9 @@ import ( cmn "github.com/tendermint/tmlibs/common" ) -// validators implements sort +//------------------------------------------------------------------------------ +// Validators is a list of validators that implements the Sort interface type Validators []*Validator func (v Validators) Len() int { @@ -27,13 +28,6 @@ func (v Validators) Swap(i, j int) { v[j] = v1 } -//------------------------------------- - -type validatorPretty struct { - PubKey data.Bytes `json:"pub_key"` - Power uint64 `json:"power"` -} - func ValidatorsString(vs Validators) string { s := make([]validatorPretty, len(vs)) for i, v := range vs { @@ -45,3 +39,28 @@ func ValidatorsString(vs Validators) string { } return string(b) } + +type validatorPretty struct { + PubKey data.Bytes `json:"pub_key"` + Power int64 `json:"power"` +} + +//------------------------------------------------------------------------------ + +// KVPairInt is a helper method to build KV pair with an integer value. +func KVPairInt(key string, val int64) *KVPair { + return &KVPair{ + Key: key, + ValueInt: val, + ValueType: KVPair_INT, + } +} + +// KVPairString is a helper method to build KV pair with a string value. +func KVPairString(key, val string) *KVPair { + return &KVPair{ + Key: key, + ValueString: val, + ValueType: KVPair_STRING, + } +} diff --git a/types/util_test.go b/types/util_test.go new file mode 100644 index 00000000..d006d56b --- /dev/null +++ b/types/util_test.go @@ -0,0 +1,15 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestKVPairInt(t *testing.T) { + assert.Equal(t, KVPairInt("a", 1), &KVPair{Key: "a", ValueType: KVPair_INT, ValueInt: 1}) +} + +func TestKVPairString(t *testing.T) { + assert.Equal(t, KVPairString("a", "b"), &KVPair{Key: "a", ValueType: KVPair_STRING, ValueString: "b"}) +} diff --git a/version/version.go b/version/version.go index e02653d8..c0699526 100644 --- a/version/version.go +++ b/version/version.go @@ -3,7 +3,7 @@ package version // NOTE: we should probably be versioning the ABCI and the abci-cli separately const Maj = "0" -const Min = "7" -const Fix = "1" +const Min = "8" +const Fix = "0" -const Version = "0.7.1" +const Version = "0.8.0"