mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-01 23:51:21 +00:00
commit
1236e8fb6e
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,3 +1,4 @@
|
||||
*.swp
|
||||
*.swo
|
||||
*.pyc
|
||||
vendor
|
||||
|
171
CHANGELOG.md
Normal file
171
CHANGELOG.md
Normal file
@ -0,0 +1,171 @@
|
||||
# Changelog
|
||||
|
||||
## 0.4.0 (March 6, 2017)
|
||||
|
||||
BREAKING CHANGES:
|
||||
|
||||
- Query takes RequestQuery and returns ResponseQuery. The request is split into `data` and `path`,
|
||||
can specify a height to query the state from, and whether or not the response should come with a proof.
|
||||
The response returns the corresponding key-value pair, with proof if requested.
|
||||
|
||||
```
|
||||
message RequestQuery{
|
||||
bytes data = 1;
|
||||
string path = 2;
|
||||
uint64 height = 3;
|
||||
bool prove = 4;
|
||||
}
|
||||
|
||||
message ResponseQuery{
|
||||
CodeType code = 1;
|
||||
int64 index = 2;
|
||||
bytes key = 3;
|
||||
bytes value = 4;
|
||||
bytes proof = 5;
|
||||
uint64 height = 6;
|
||||
string log = 7;
|
||||
}
|
||||
```
|
||||
|
||||
IMPROVEMENTS:
|
||||
|
||||
- Updates to Makefile
|
||||
- Various cleanup
|
||||
- BaseApplication can be embedded by new apps to avoid implementing empty methods
|
||||
- Drop BlockchainAware and make BeginBlock/EndBlock part of the `type Application interface`
|
||||
|
||||
## 0.3.0 (January 12, 2017)
|
||||
|
||||
BREAKING CHANGES:
|
||||
|
||||
- TMSP is now ABCI (Application/Asynchronous/A BlockChain Interface or Atomic BroadCast Interface)
|
||||
- AppendTx is now DeliverTx (conforms to the literature)
|
||||
- BeginBlock takes a Header:
|
||||
|
||||
```
|
||||
message RequestBeginBlock{
|
||||
bytes hash = 1;
|
||||
Header header = 2;
|
||||
}
|
||||
```
|
||||
|
||||
- Info returns a ResponseInfo, containing last block height and app hash:
|
||||
|
||||
```
|
||||
message ResponseInfo {
|
||||
string data = 1;
|
||||
string version = 2;
|
||||
uint64 last_block_height = 3;
|
||||
bytes last_block_app_hash = 4;
|
||||
}
|
||||
```
|
||||
|
||||
- EndBlock returns a ResponseEndBlock, containing the changed validators:
|
||||
|
||||
```
|
||||
message ResponseEndBlock{
|
||||
repeated Validator diffs = 4;
|
||||
}
|
||||
```
|
||||
|
||||
- Hex strings are 0x-prefixed in the CLI
|
||||
- Query on the Dummy app now uses hex-strings
|
||||
|
||||
FEATURES:
|
||||
|
||||
- New app, PersistentDummy, uses Info/BeginBlock to recover from failures and supports validator set changes
|
||||
- New message types for blockchain data:
|
||||
|
||||
```
|
||||
//----------------------------------------
|
||||
// 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;
|
||||
}
|
||||
|
||||
message BlockID {
|
||||
bytes hash = 1;
|
||||
PartSetHeader parts = 2;
|
||||
}
|
||||
|
||||
message PartSetHeader {
|
||||
uint64 total = 1;
|
||||
bytes hash = 2;
|
||||
}
|
||||
|
||||
message Validator {
|
||||
bytes pubKey = 1;
|
||||
uint64 power = 2;
|
||||
}
|
||||
```
|
||||
|
||||
- Add support for Query to Counter app
|
||||
|
||||
IMPROVEMENT:
|
||||
|
||||
- Don't exit the tmsp-cli console on bad args
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
- Fix parsing in the Counter app to handle invalid transactions
|
||||
|
||||
|
||||
## 0.2.1 (September 12, 2016)
|
||||
|
||||
IMPROVEMENTS
|
||||
|
||||
- Better error handling in console
|
||||
|
||||
|
||||
## 0.2.0 (July 23, 2016)
|
||||
|
||||
BREAKING CHANGES:
|
||||
|
||||
- Use `oneof` types in protobuf
|
||||
|
||||
FEATURES:
|
||||
|
||||
- GRPC support
|
||||
|
||||
|
||||
## PreHistory
|
||||
|
||||
##### Mar 26h, 2016
|
||||
* Introduce BeginBlock
|
||||
|
||||
##### Mar 6th, 2016
|
||||
|
||||
* Added InitChain, EndBlock
|
||||
|
||||
##### Feb 14th, 2016
|
||||
|
||||
* s/GetHash/Commit/g
|
||||
* Document Protobuf request/response fields
|
||||
|
||||
##### Jan 23th, 2016
|
||||
|
||||
* Added CheckTx/Query ABCI message types
|
||||
* Added Result/Log fields to DeliverTx/CheckTx/SetOption
|
||||
* Removed Listener messages
|
||||
* Removed Code from ResponseSetOption and ResponseGetHash
|
||||
* Made examples BigEndian
|
||||
|
||||
##### Jan 12th, 2016
|
||||
|
||||
* Added "RetCodeBadNonce = 0x06" return code
|
||||
|
||||
##### Jan 8th, 2016
|
||||
|
||||
* Tendermint/ABCI now comes to consensus on the order first before DeliverTx.
|
||||
|
||||
|
||||
|
36
Makefile
36
Makefile
@ -1,24 +1,42 @@
|
||||
.PHONY: all test get_deps
|
||||
.PHONY: all build test fmt lint get_deps
|
||||
|
||||
all: protoc install test
|
||||
|
||||
NOVENDOR = go list github.com/tendermint/abci/... | grep -v /vendor/
|
||||
|
||||
install-protoc:
|
||||
# Download: https://github.com/google/protobuf/releases
|
||||
go get github.com/golang/protobuf/protoc-gen-go
|
||||
|
||||
protoc:
|
||||
protoc --go_out=plugins=grpc:. types/*.proto
|
||||
@ protoc --go_out=plugins=grpc:. types/*.proto
|
||||
|
||||
install:
|
||||
go install github.com/tendermint/abci/cmd/...
|
||||
@ go install github.com/tendermint/abci/cmd/...
|
||||
|
||||
test:
|
||||
go test `${NOVENDOR}`
|
||||
bash tests/test.sh
|
||||
build:
|
||||
@ go build -i github.com/tendermint/abci/cmd/...
|
||||
|
||||
# test.sh requires that we run the installed cmds, must not be out of date
|
||||
test: install
|
||||
find . -name test.sock -exec rm {} \;
|
||||
@ go test -p 1 `${NOVENDOR}`
|
||||
@ bash tests/test.sh
|
||||
|
||||
fmt:
|
||||
@ go fmt ./...
|
||||
|
||||
lint:
|
||||
@ go get -u github.com/golang/lint/golint
|
||||
@ for file in $$(find "." -name '*.go' | grep -v '/vendor/' | grep -v '\.pb\.go'); do \
|
||||
golint -set_exit_status $${file}; \
|
||||
done;
|
||||
|
||||
test_integrations: get_vendor_deps install test
|
||||
|
||||
get_deps:
|
||||
go get -d `${NOVENDOR}`
|
||||
@ go get -d `${NOVENDOR}`
|
||||
|
||||
get_vendor_deps:
|
||||
go get github.com/Masterminds/glide
|
||||
glide install
|
||||
@ go get github.com/Masterminds/glide
|
||||
@ glide install
|
||||
|
29
README.md
29
README.md
@ -22,8 +22,14 @@ Other implementations:
|
||||
|
||||
The [primary specification](https://github.com/tendermint/abci/blob/master/types/types.proto) is made using Protocol Buffers.
|
||||
|
||||
As a [Go interface](https://github.com/tendermint/abci/blob/master/types/application.go), it might look like:
|
||||
- The Protobuf file defining ABCI message types, and the optional GRPC interface. To build, run `make protoc`
|
||||
- See `protoc --help` and [the GRPC docs](https://www.grpc.io/docs) for examples and details of other languages.
|
||||
|
||||
TendermintCore runs a client, and the ABCI application runs a server. There are three Golang implementation of ABCI client and server.
|
||||
|
||||
1. ABCI-socket: Asynchronous, ordered message passing over Unix or TCP sockets. Messages are serialized using Protobuf and length prefixed.
|
||||
2. GRPC: Synchronous (slow) implementation using GRPC.
|
||||
3. Golang in-process: If the ABCI appliation is written in Golang, it is possible to compile both TendermintCore and the application as one binary.
|
||||
|
||||
```golang
|
||||
// Applications
|
||||
@ -66,7 +72,7 @@ type ResponseEndBlock struct {
|
||||
Diffs []*Validator
|
||||
}
|
||||
|
||||
```
|
||||
_TODO: merge information from https://tendermint.com/blog/tendermint-0-8-release_
|
||||
|
||||
## Message Types
|
||||
|
||||
@ -93,13 +99,13 @@ ABCI requests/responses are simple Protobuf messages. Check out the [schema fil
|
||||
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.
|
||||
|
||||
CheckTx can happen interspersed with DeliverTx, but they happen on different connections - CheckTx from the mempool connection, and DeliverTx from the consensus connection. During Commit, the mempool is locked, so you can reset the mempool state to the latest state after running all those delivertxs, and then the mempool will re run whatever txs it has against that latest mempool stte
|
||||
CheckTx can happen interspersed with DeliverTx, but they happen on different connections - CheckTx from the mempool connection, and DeliverTx from the consensus connection. During Commit, the mempool is locked, so you can reset the mempool state to the latest state after running all those delivertxs, and then the mempool will re-run whatever txs it has against that latest mempool state.
|
||||
|
||||
Transactions are first run through CheckTx before broadcast to peers in the mempool layer.
|
||||
You can make CheckTx semi-stateful and clear the state upon `Commit` or `BeginBlock`,
|
||||
to allow for dependent sequences of transactions in the same block.
|
||||
|
||||
#### Commit
|
||||
#### Commit
|
||||
* __Returns__:
|
||||
* `Data ([]byte)`: The Merkle root hash
|
||||
* `Log (string)`: Debug or error message
|
||||
@ -108,11 +114,20 @@ ABCI requests/responses are simple Protobuf messages. Check out the [schema fil
|
||||
|
||||
#### Query
|
||||
* __Arguments__:
|
||||
* `Data ([]byte)`: The query request bytes
|
||||
* `Data ([]byte)`: Raw query bytes. Can be used with or in lieu of Path.
|
||||
* `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
|
||||
* `Prove (bool)`: Return Merkle proof with response if possible
|
||||
* __Returns__:
|
||||
* `Code (uint32)`: Response code
|
||||
* `Data ([]byte)`: The query response bytes
|
||||
* `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
|
||||
* `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)
|
||||
|
||||
#### Info
|
||||
* __Returns__:
|
||||
@ -142,7 +157,7 @@ ABCI requests/responses are simple Protobuf messages. Check out the [schema fil
|
||||
|
||||
#### BeginBlock
|
||||
* __Arguments__:
|
||||
* `Hash ([]byte)`: The block height that is starting
|
||||
* `Hash ([]byte)`: The block's hash. This can be derived from the block header.
|
||||
* `Header (struct{})`: The block header
|
||||
* __Usage__:<br/>
|
||||
Signals the beginning of a new block. Called prior to any DeliverTxs. The header is expected to at least contain the Height.
|
||||
|
@ -4,12 +4,12 @@ import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
type Client interface {
|
||||
Service
|
||||
cmn.Service
|
||||
|
||||
SetResponseCallback(Callback)
|
||||
Error() error
|
||||
@ -20,7 +20,7 @@ type Client interface {
|
||||
SetOptionAsync(key string, value string) *ReqRes
|
||||
DeliverTxAsync(tx []byte) *ReqRes
|
||||
CheckTxAsync(tx []byte) *ReqRes
|
||||
QueryAsync(tx []byte) *ReqRes
|
||||
QueryAsync(reqQuery types.RequestQuery) *ReqRes
|
||||
CommitAsync() *ReqRes
|
||||
|
||||
FlushSync() error
|
||||
@ -29,7 +29,7 @@ type Client interface {
|
||||
SetOptionSync(key string, value string) (res types.Result)
|
||||
DeliverTxSync(tx []byte) (res types.Result)
|
||||
CheckTxSync(tx []byte) (res types.Result)
|
||||
QuerySync(tx []byte) (res types.Result)
|
||||
QuerySync(reqQuery types.RequestQuery) (resQuery types.ResponseQuery, err error)
|
||||
CommitSync() (res types.Result)
|
||||
|
||||
InitChainAsync(validators []*types.Validator) *ReqRes
|
||||
|
@ -1,6 +1,7 @@
|
||||
package abcicli
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
@ -8,14 +9,14 @@ import (
|
||||
context "golang.org/x/net/context"
|
||||
grpc "google.golang.org/grpc"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
// A stripped copy of the remoteClient that makes
|
||||
// synchronous calls using grpc
|
||||
type grpcClient struct {
|
||||
BaseService
|
||||
cmn.BaseService
|
||||
mustConnect bool
|
||||
|
||||
client types.ABCIApplicationClient
|
||||
@ -31,13 +32,13 @@ func NewGRPCClient(addr string, mustConnect bool) (*grpcClient, error) {
|
||||
addr: addr,
|
||||
mustConnect: mustConnect,
|
||||
}
|
||||
cli.BaseService = *NewBaseService(nil, "grpcClient", cli)
|
||||
cli.BaseService = *cmn.NewBaseService(nil, "grpcClient", cli)
|
||||
_, err := cli.Start() // Just start it, it's confusing for callers to remember to start.
|
||||
return cli, err
|
||||
}
|
||||
|
||||
func dialerFunc(addr string, timeout time.Duration) (net.Conn, error) {
|
||||
return Connect(addr)
|
||||
return cmn.Connect(addr)
|
||||
}
|
||||
|
||||
func (cli *grpcClient) OnStart() error {
|
||||
@ -49,11 +50,10 @@ RETRY_LOOP:
|
||||
if err != nil {
|
||||
if cli.mustConnect {
|
||||
return err
|
||||
} else {
|
||||
log.Warn(Fmt("abci.grpcClient failed to connect to %v. Retrying...\n", cli.addr))
|
||||
time.Sleep(time.Second * 3)
|
||||
continue RETRY_LOOP
|
||||
}
|
||||
log.Warn(fmt.Sprintf("abci.grpcClient failed to connect to %v. Retrying...\n", cli.addr))
|
||||
time.Sleep(time.Second * 3)
|
||||
continue RETRY_LOOP
|
||||
}
|
||||
|
||||
client := types.NewABCIApplicationClient(conn)
|
||||
@ -93,7 +93,7 @@ func (cli *grpcClient) StopForError(err error) {
|
||||
}
|
||||
cli.mtx.Unlock()
|
||||
|
||||
log.Warn(Fmt("Stopping abci.grpcClient for error: %v", err.Error()))
|
||||
log.Warn(fmt.Sprintf("Stopping abci.grpcClient for error: %v", err.Error()))
|
||||
cli.Stop()
|
||||
}
|
||||
|
||||
@ -173,8 +173,8 @@ func (cli *grpcClient) CheckTxAsync(tx []byte) *ReqRes {
|
||||
return cli.finishAsyncCall(req, &types.Response{&types.Response_CheckTx{res}})
|
||||
}
|
||||
|
||||
func (cli *grpcClient) QueryAsync(query []byte) *ReqRes {
|
||||
req := types.ToRequestQuery(query)
|
||||
func (cli *grpcClient) QueryAsync(reqQuery types.RequestQuery) *ReqRes {
|
||||
req := types.ToRequestQuery(reqQuery)
|
||||
res, err := cli.client.Query(context.Background(), req.GetQuery(), grpc.FailFast(true))
|
||||
if err != nil {
|
||||
cli.StopForError(err)
|
||||
@ -255,7 +255,7 @@ func (cli *grpcClient) EchoSync(msg string) (res types.Result) {
|
||||
return res
|
||||
}
|
||||
resp := reqres.Response.GetEcho()
|
||||
return types.NewResultOK([]byte(resp.Message), LOG)
|
||||
return types.NewResultOK([]byte(resp.Message), "")
|
||||
}
|
||||
|
||||
func (cli *grpcClient) FlushSync() error {
|
||||
@ -267,11 +267,10 @@ func (cli *grpcClient) InfoSync() (resInfo types.ResponseInfo, err error) {
|
||||
if err = cli.Error(); err != nil {
|
||||
return resInfo, err
|
||||
}
|
||||
if resInfo_ := reqres.Response.GetInfo(); resInfo_ != nil {
|
||||
return *resInfo_, nil
|
||||
} else {
|
||||
return resInfo, nil
|
||||
if info := reqres.Response.GetInfo(); info != nil {
|
||||
return *info, nil
|
||||
}
|
||||
return resInfo, nil
|
||||
}
|
||||
|
||||
func (cli *grpcClient) SetOptionSync(key string, value string) (res types.Result) {
|
||||
@ -301,13 +300,15 @@ func (cli *grpcClient) CheckTxSync(tx []byte) (res types.Result) {
|
||||
return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log}
|
||||
}
|
||||
|
||||
func (cli *grpcClient) QuerySync(query []byte) (res types.Result) {
|
||||
reqres := cli.QueryAsync(query)
|
||||
if res := cli.checkErrGetResult(); res.IsErr() {
|
||||
return res
|
||||
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
|
||||
}
|
||||
resp := reqres.Response.GetQuery()
|
||||
return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log}
|
||||
if resQuery_ := reqres.Response.GetQuery(); resQuery_ != nil {
|
||||
return *resQuery_, nil
|
||||
}
|
||||
return resQuery, nil
|
||||
}
|
||||
|
||||
func (cli *grpcClient) CommitSync() (res types.Result) {
|
||||
@ -334,9 +335,8 @@ func (cli *grpcClient) EndBlockSync(height uint64) (resEndBlock types.ResponseEn
|
||||
if err := cli.Error(); err != nil {
|
||||
return resEndBlock, err
|
||||
}
|
||||
if resEndBlock_ := reqres.Response.GetEndBlock(); resEndBlock_ != nil {
|
||||
return *resEndBlock_, nil
|
||||
} else {
|
||||
return resEndBlock, nil
|
||||
if blk := reqres.Response.GetEndBlock(); blk != nil {
|
||||
return *blk, nil
|
||||
}
|
||||
return resEndBlock, nil
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ package abcicli
|
||||
import (
|
||||
"sync"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
types "github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
type localClient struct {
|
||||
BaseService
|
||||
cmn.BaseService
|
||||
mtx *sync.Mutex
|
||||
types.Application
|
||||
Callback
|
||||
@ -22,7 +22,7 @@ func NewLocalClient(mtx *sync.Mutex, app types.Application) *localClient {
|
||||
mtx: mtx,
|
||||
Application: app,
|
||||
}
|
||||
cli.BaseService = *NewBaseService(log, "localClient", cli)
|
||||
cli.BaseService = *cmn.NewBaseService(log, "localClient", cli)
|
||||
return cli
|
||||
}
|
||||
|
||||
@ -89,13 +89,13 @@ func (app *localClient) CheckTxAsync(tx []byte) *ReqRes {
|
||||
)
|
||||
}
|
||||
|
||||
func (app *localClient) QueryAsync(tx []byte) *ReqRes {
|
||||
func (app *localClient) QueryAsync(reqQuery types.RequestQuery) *ReqRes {
|
||||
app.mtx.Lock()
|
||||
res := app.Application.Query(tx)
|
||||
resQuery := app.Application.Query(reqQuery)
|
||||
app.mtx.Unlock()
|
||||
return app.callback(
|
||||
types.ToRequestQuery(tx),
|
||||
types.ToResponseQuery(res.Code, res.Data, res.Log),
|
||||
types.ToRequestQuery(reqQuery),
|
||||
types.ToResponseQuery(resQuery),
|
||||
)
|
||||
}
|
||||
|
||||
@ -111,9 +111,7 @@ func (app *localClient) CommitAsync() *ReqRes {
|
||||
|
||||
func (app *localClient) InitChainAsync(validators []*types.Validator) *ReqRes {
|
||||
app.mtx.Lock()
|
||||
if bcApp, ok := app.Application.(types.BlockchainAware); ok {
|
||||
bcApp.InitChain(validators)
|
||||
}
|
||||
app.Application.InitChain(validators)
|
||||
reqRes := app.callback(
|
||||
types.ToRequestInitChain(validators),
|
||||
types.ToResponseInitChain(),
|
||||
@ -124,9 +122,7 @@ func (app *localClient) InitChainAsync(validators []*types.Validator) *ReqRes {
|
||||
|
||||
func (app *localClient) BeginBlockAsync(hash []byte, header *types.Header) *ReqRes {
|
||||
app.mtx.Lock()
|
||||
if bcApp, ok := app.Application.(types.BlockchainAware); ok {
|
||||
bcApp.BeginBlock(hash, header)
|
||||
}
|
||||
app.Application.BeginBlock(hash, header)
|
||||
app.mtx.Unlock()
|
||||
return app.callback(
|
||||
types.ToRequestBeginBlock(hash, header),
|
||||
@ -136,10 +132,7 @@ func (app *localClient) BeginBlockAsync(hash []byte, header *types.Header) *ReqR
|
||||
|
||||
func (app *localClient) EndBlockAsync(height uint64) *ReqRes {
|
||||
app.mtx.Lock()
|
||||
var resEndBlock types.ResponseEndBlock
|
||||
if bcApp, ok := app.Application.(types.BlockchainAware); ok {
|
||||
resEndBlock = bcApp.EndBlock(height)
|
||||
}
|
||||
resEndBlock := app.Application.EndBlock(height)
|
||||
app.mtx.Unlock()
|
||||
return app.callback(
|
||||
types.ToRequestEndBlock(height),
|
||||
@ -185,11 +178,11 @@ func (app *localClient) CheckTxSync(tx []byte) (res types.Result) {
|
||||
return res
|
||||
}
|
||||
|
||||
func (app *localClient) QuerySync(query []byte) (res types.Result) {
|
||||
func (app *localClient) QuerySync(reqQuery types.RequestQuery) (resQuery types.ResponseQuery, err error) {
|
||||
app.mtx.Lock()
|
||||
res = app.Application.Query(query)
|
||||
resQuery = app.Application.Query(reqQuery)
|
||||
app.mtx.Unlock()
|
||||
return res
|
||||
return resQuery, nil
|
||||
}
|
||||
|
||||
func (app *localClient) CommitSync() (res types.Result) {
|
||||
@ -201,27 +194,21 @@ func (app *localClient) CommitSync() (res types.Result) {
|
||||
|
||||
func (app *localClient) InitChainSync(validators []*types.Validator) (err error) {
|
||||
app.mtx.Lock()
|
||||
if bcApp, ok := app.Application.(types.BlockchainAware); ok {
|
||||
bcApp.InitChain(validators)
|
||||
}
|
||||
app.Application.InitChain(validators)
|
||||
app.mtx.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *localClient) BeginBlockSync(hash []byte, header *types.Header) (err error) {
|
||||
app.mtx.Lock()
|
||||
if bcApp, ok := app.Application.(types.BlockchainAware); ok {
|
||||
bcApp.BeginBlock(hash, header)
|
||||
}
|
||||
app.Application.BeginBlock(hash, header)
|
||||
app.mtx.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *localClient) EndBlockSync(height uint64) (resEndBlock types.ResponseEndBlock, err error) {
|
||||
app.mtx.Lock()
|
||||
if bcApp, ok := app.Application.(types.BlockchainAware); ok {
|
||||
resEndBlock = bcApp.EndBlock(height)
|
||||
}
|
||||
resEndBlock = app.Application.EndBlock(height)
|
||||
app.mtx.Unlock()
|
||||
return resEndBlock, nil
|
||||
}
|
||||
|
@ -10,8 +10,8 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -27,10 +27,10 @@ const flushThrottleMS = 20 // Don't wait longer than...
|
||||
// the application in general is not meant to be interfaced
|
||||
// with concurrent callers.
|
||||
type socketClient struct {
|
||||
BaseService
|
||||
cmn.BaseService
|
||||
|
||||
reqQueue chan *ReqRes
|
||||
flushTimer *ThrottleTimer
|
||||
flushTimer *cmn.ThrottleTimer
|
||||
mustConnect bool
|
||||
|
||||
mtx sync.Mutex
|
||||
@ -45,14 +45,14 @@ type socketClient struct {
|
||||
func NewSocketClient(addr string, mustConnect bool) (*socketClient, error) {
|
||||
cli := &socketClient{
|
||||
reqQueue: make(chan *ReqRes, reqQueueSize),
|
||||
flushTimer: NewThrottleTimer("socketClient", flushThrottleMS),
|
||||
flushTimer: cmn.NewThrottleTimer("socketClient", flushThrottleMS),
|
||||
mustConnect: mustConnect,
|
||||
|
||||
addr: addr,
|
||||
reqSent: list.New(),
|
||||
resCb: nil,
|
||||
}
|
||||
cli.BaseService = *NewBaseService(nil, "socketClient", cli)
|
||||
cli.BaseService = *cmn.NewBaseService(nil, "socketClient", cli)
|
||||
|
||||
_, err := cli.Start() // Just start it, it's confusing for callers to remember to start.
|
||||
return cli, err
|
||||
@ -65,15 +65,14 @@ func (cli *socketClient) OnStart() error {
|
||||
var conn net.Conn
|
||||
RETRY_LOOP:
|
||||
for {
|
||||
conn, err = Connect(cli.addr)
|
||||
conn, err = cmn.Connect(cli.addr)
|
||||
if err != nil {
|
||||
if cli.mustConnect {
|
||||
return err
|
||||
} else {
|
||||
log.Warn(Fmt("abci.socketClient failed to connect to %v. Retrying...", cli.addr))
|
||||
time.Sleep(time.Second * 3)
|
||||
continue RETRY_LOOP
|
||||
}
|
||||
log.Warn(fmt.Sprintf("abci.socketClient failed to connect to %v. Retrying...", cli.addr))
|
||||
time.Sleep(time.Second * 3)
|
||||
continue RETRY_LOOP
|
||||
}
|
||||
cli.conn = conn
|
||||
|
||||
@ -82,7 +81,6 @@ RETRY_LOOP:
|
||||
|
||||
return nil
|
||||
}
|
||||
return nil // never happens
|
||||
}
|
||||
|
||||
func (cli *socketClient) OnStop() {
|
||||
@ -109,7 +107,7 @@ func (cli *socketClient) StopForError(err error) {
|
||||
}
|
||||
cli.mtx.Unlock()
|
||||
|
||||
log.Warn(Fmt("Stopping abci.socketClient for error: %v", err.Error()))
|
||||
log.Warn(fmt.Sprintf("Stopping abci.socketClient for error: %v", err.Error()))
|
||||
cli.Stop()
|
||||
}
|
||||
|
||||
@ -251,8 +249,8 @@ func (cli *socketClient) CheckTxAsync(tx []byte) *ReqRes {
|
||||
return cli.queueRequest(types.ToRequestCheckTx(tx))
|
||||
}
|
||||
|
||||
func (cli *socketClient) QueryAsync(query []byte) *ReqRes {
|
||||
return cli.queueRequest(types.ToRequestQuery(query))
|
||||
func (cli *socketClient) QueryAsync(reqQuery types.RequestQuery) *ReqRes {
|
||||
return cli.queueRequest(types.ToRequestQuery(reqQuery))
|
||||
}
|
||||
|
||||
func (cli *socketClient) CommitAsync() *ReqRes {
|
||||
@ -280,7 +278,7 @@ func (cli *socketClient) EchoSync(msg string) (res types.Result) {
|
||||
return types.ErrInternalError.SetLog(err.Error())
|
||||
}
|
||||
resp := reqres.Response.GetEcho()
|
||||
return types.Result{Code: OK, Data: []byte(resp.Message), Log: LOG}
|
||||
return types.Result{Code: OK, Data: []byte(resp.Message)}
|
||||
}
|
||||
|
||||
func (cli *socketClient) FlushSync() error {
|
||||
@ -300,9 +298,8 @@ func (cli *socketClient) InfoSync() (resInfo types.ResponseInfo, err error) {
|
||||
}
|
||||
if resInfo_ := reqres.Response.GetInfo(); resInfo_ != nil {
|
||||
return *resInfo_, nil
|
||||
} else {
|
||||
return resInfo, nil
|
||||
}
|
||||
return resInfo, nil
|
||||
}
|
||||
|
||||
func (cli *socketClient) SetOptionSync(key string, value string) (res types.Result) {
|
||||
@ -335,14 +332,16 @@ func (cli *socketClient) CheckTxSync(tx []byte) (res types.Result) {
|
||||
return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log}
|
||||
}
|
||||
|
||||
func (cli *socketClient) QuerySync(query []byte) (res types.Result) {
|
||||
reqres := cli.queueRequest(types.ToRequestQuery(query))
|
||||
func (cli *socketClient) QuerySync(reqQuery types.RequestQuery) (resQuery types.ResponseQuery, err error) {
|
||||
reqres := cli.queueRequest(types.ToRequestQuery(reqQuery))
|
||||
cli.FlushSync()
|
||||
if err := cli.Error(); err != nil {
|
||||
return types.ErrInternalError.SetLog(err.Error())
|
||||
return resQuery, err
|
||||
}
|
||||
resp := reqres.Response.GetQuery()
|
||||
return types.Result{Code: resp.Code, Data: resp.Data, Log: resp.Log}
|
||||
if resQuery_ := reqres.Response.GetQuery(); resQuery_ != nil {
|
||||
return *resQuery_, nil
|
||||
}
|
||||
return resQuery, nil
|
||||
}
|
||||
|
||||
func (cli *socketClient) CommitSync() (res types.Result) {
|
||||
@ -379,11 +378,10 @@ func (cli *socketClient) EndBlockSync(height uint64) (resEndBlock types.Response
|
||||
if err := cli.Error(); err != nil {
|
||||
return resEndBlock, err
|
||||
}
|
||||
if resEndBlock_ := reqres.Response.GetEndBlock(); resEndBlock_ != nil {
|
||||
return *resEndBlock_, nil
|
||||
} else {
|
||||
return resEndBlock, nil
|
||||
if blk := reqres.Response.GetEndBlock(); blk != nil {
|
||||
return *blk, nil
|
||||
}
|
||||
return resEndBlock, nil
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
@ -6,37 +6,31 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/tendermint/abci/client"
|
||||
"github.com/tendermint/abci/types"
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/version"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
//structure for data passed to print response
|
||||
// variables must be exposed for JSON to read
|
||||
// Structure for data passed to print response.
|
||||
type response struct {
|
||||
Res types.Result
|
||||
Data string
|
||||
PrintCode bool
|
||||
Code string
|
||||
// generic abci response
|
||||
Data []byte
|
||||
Code types.CodeType
|
||||
Log string
|
||||
|
||||
Query *queryResponse
|
||||
}
|
||||
|
||||
func newResponse(res types.Result, data string, printCode bool) *response {
|
||||
rsp := &response{
|
||||
Res: res,
|
||||
Data: data,
|
||||
PrintCode: printCode,
|
||||
Code: "",
|
||||
}
|
||||
|
||||
if printCode {
|
||||
rsp.Code = res.Code.String()
|
||||
}
|
||||
|
||||
return rsp
|
||||
type queryResponse struct {
|
||||
Key []byte
|
||||
Value []byte
|
||||
Height uint64
|
||||
Proof []byte
|
||||
}
|
||||
|
||||
// client is a global variable so it can be reused by the console
|
||||
@ -50,7 +44,7 @@ func main() {
|
||||
app := cli.NewApp()
|
||||
app.Name = "abci-cli"
|
||||
app.Usage = "abci-cli [command] [args...]"
|
||||
app.Version = "0.3.0" // hex handling
|
||||
app.Version = version.Version
|
||||
app.Flags = []cli.Flag{
|
||||
cli.StringFlag{
|
||||
Name: "address",
|
||||
@ -135,7 +129,7 @@ func main() {
|
||||
app.Before = before
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
}
|
||||
@ -145,7 +139,7 @@ func before(c *cli.Context) error {
|
||||
var err error
|
||||
client, err = abcicli.NewClient(c.GlobalString("address"), c.GlobalString("abci"), false)
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@ -220,9 +214,10 @@ func cmdEcho(c *cli.Context) error {
|
||||
if len(args) != 1 {
|
||||
return errors.New("Command echo takes 1 argument")
|
||||
}
|
||||
res := client.EchoSync(args[0])
|
||||
rsp := newResponse(res, string(res.Data), false)
|
||||
printResponse(c, rsp)
|
||||
resEcho := client.EchoSync(args[0])
|
||||
printResponse(c, response{
|
||||
Data: resEcho.Data,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -232,8 +227,9 @@ func cmdInfo(c *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rsp := newResponse(types.Result{}, string(resInfo.Data), false)
|
||||
printResponse(c, rsp)
|
||||
printResponse(c, response{
|
||||
Data: []byte(resInfo.Data),
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -243,9 +239,10 @@ func cmdSetOption(c *cli.Context) error {
|
||||
if len(args) != 2 {
|
||||
return errors.New("Command set_option takes 2 arguments (key, value)")
|
||||
}
|
||||
res := client.SetOptionSync(args[0], args[1])
|
||||
rsp := newResponse(res, Fmt("%s=%s", args[0], args[1]), false)
|
||||
printResponse(c, rsp)
|
||||
resSetOption := client.SetOptionSync(args[0], args[1])
|
||||
printResponse(c, response{
|
||||
Log: resSetOption.Log,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -260,8 +257,11 @@ func cmdDeliverTx(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
res := client.DeliverTxSync(txBytes)
|
||||
rsp := newResponse(res, string(res.Data), true)
|
||||
printResponse(c, rsp)
|
||||
printResponse(c, response{
|
||||
Code: res.Code,
|
||||
Data: res.Data,
|
||||
Log: res.Log,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -276,20 +276,27 @@ func cmdCheckTx(c *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
res := client.CheckTxSync(txBytes)
|
||||
rsp := newResponse(res, string(res.Data), true)
|
||||
printResponse(c, rsp)
|
||||
printResponse(c, response{
|
||||
Code: res.Code,
|
||||
Data: res.Data,
|
||||
Log: res.Log,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Get application Merkle root hash
|
||||
func cmdCommit(c *cli.Context) error {
|
||||
res := client.CommitSync()
|
||||
rsp := newResponse(res, Fmt("0x%X", res.Data), false)
|
||||
printResponse(c, rsp)
|
||||
printResponse(c, response{
|
||||
Code: res.Code,
|
||||
Data: res.Data,
|
||||
Log: res.Log,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// Query application state
|
||||
// TODO: Make request and response support all fields.
|
||||
func cmdQuery(c *cli.Context) error {
|
||||
args := c.Args()
|
||||
if len(args) != 1 {
|
||||
@ -299,15 +306,31 @@ func cmdQuery(c *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res := client.QuerySync(queryBytes)
|
||||
rsp := newResponse(res, string(res.Data), true)
|
||||
printResponse(c, rsp)
|
||||
resQuery, err := client.QuerySync(types.RequestQuery{
|
||||
Data: queryBytes,
|
||||
Path: "/store", // TOOD expose
|
||||
Height: 0, // TODO expose
|
||||
//Prove: true, // TODO expose
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printResponse(c, response{
|
||||
Code: resQuery.Code,
|
||||
Log: resQuery.Log,
|
||||
Query: &queryResponse{
|
||||
Key: resQuery.Key,
|
||||
Value: resQuery.Value,
|
||||
Height: resQuery.Height,
|
||||
Proof: resQuery.Proof,
|
||||
},
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
func printResponse(c *cli.Context, rsp *response) {
|
||||
func printResponse(c *cli.Context, rsp response) {
|
||||
|
||||
verbose := c.GlobalBool("verbose")
|
||||
|
||||
@ -315,19 +338,30 @@ func printResponse(c *cli.Context, rsp *response) {
|
||||
fmt.Println(">", c.Command.Name, strings.Join(c.Args(), " "))
|
||||
}
|
||||
|
||||
if rsp.PrintCode {
|
||||
fmt.Printf("-> code: %s\n", rsp.Code)
|
||||
if !rsp.Code.IsOK() {
|
||||
fmt.Printf("-> code: %s\n", rsp.Code.String())
|
||||
}
|
||||
|
||||
//if pr.res.Error != "" {
|
||||
// fmt.Printf("-> error: %s\n", pr.res.Error)
|
||||
//}
|
||||
|
||||
if rsp.Data != "" {
|
||||
if len(rsp.Data) != 0 {
|
||||
fmt.Printf("-> data: %s\n", rsp.Data)
|
||||
fmt.Printf("-> data.hex: %X\n", rsp.Data)
|
||||
}
|
||||
if rsp.Res.Log != "" {
|
||||
fmt.Printf("-> log: %s\n", rsp.Res.Log)
|
||||
if rsp.Log != "" {
|
||||
fmt.Printf("-> log: %s\n", rsp.Log)
|
||||
}
|
||||
|
||||
if rsp.Query != nil {
|
||||
fmt.Printf("-> height: %d\n", rsp.Query.Height)
|
||||
if rsp.Query.Key != nil {
|
||||
fmt.Printf("-> key: %s\n", rsp.Query.Key)
|
||||
fmt.Printf("-> key.hex: %X\n", rsp.Query.Key)
|
||||
}
|
||||
if rsp.Query.Value != nil {
|
||||
fmt.Printf("-> value: %s\n", rsp.Query.Value)
|
||||
fmt.Printf("-> value.hex: %X\n", rsp.Query.Value)
|
||||
}
|
||||
if rsp.Query.Proof != nil {
|
||||
fmt.Printf("-> proof: %X\n", rsp.Query.Proof)
|
||||
}
|
||||
}
|
||||
|
||||
if verbose {
|
@ -2,10 +2,11 @@ package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/example/counter"
|
||||
"github.com/tendermint/abci/server"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -19,11 +20,11 @@ func main() {
|
||||
// Start the listener
|
||||
srv, err := server.NewServer(*addrPtr, *abciPtr, app)
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
// Wait forever
|
||||
TrapSignal(func() {
|
||||
cmn.TrapSignal(func() {
|
||||
// Cleanup
|
||||
srv.Stop()
|
||||
})
|
||||
|
@ -2,11 +2,12 @@ package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/example/dummy"
|
||||
"github.com/tendermint/abci/server"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
func main() {
|
||||
@ -27,11 +28,11 @@ func main() {
|
||||
// Start the listener
|
||||
srv, err := server.NewServer(*addrPtr, *abciPtr, app)
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
// Wait forever
|
||||
TrapSignal(func() {
|
||||
cmn.TrapSignal(func() {
|
||||
// Cleanup
|
||||
srv.Stop()
|
||||
})
|
||||
|
57
example/block_aware/block_aware_app.go
Normal file
57
example/block_aware/block_aware_app.go
Normal file
@ -0,0 +1,57 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
|
||||
"github.com/tendermint/abci/server"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
addrPtr := flag.String("addr", "tcp://0.0.0.0:46658", "Listen address")
|
||||
abciPtr := flag.String("abci", "socket", "socket | grpc")
|
||||
flag.Parse()
|
||||
|
||||
// Start the listener
|
||||
srv, err := server.NewServer(*addrPtr, *abciPtr, NewChainAwareApplication())
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
// 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(hash []byte, header *types.Header) {
|
||||
app.beginCount++
|
||||
return
|
||||
}
|
||||
|
||||
func (app *ChainAwareApplication) EndBlock(height uint64) (resEndBlock types.ResponseEndBlock) {
|
||||
app.endCount++
|
||||
return
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/client"
|
||||
"github.com/tendermint/abci/server"
|
||||
"github.com/tendermint/abci/types"
|
||||
@ -25,7 +26,7 @@ func TestChainAware(t *testing.T) {
|
||||
// Connect to the socket
|
||||
client, err := abcicli.NewSocketClient("unix://test.sock", false)
|
||||
if err != nil {
|
||||
Exit(Fmt("Error starting socket client: %v", err.Error()))
|
||||
log.Fatal(fmt.Sprintf("Error starting socket client: %v", err.Error()))
|
||||
}
|
||||
client.Start()
|
||||
defer client.Stop()
|
||||
@ -39,10 +40,10 @@ func TestChainAware(t *testing.T) {
|
||||
client.CommitSync()
|
||||
}
|
||||
|
||||
r := app.Query(nil)
|
||||
spl := strings.Split(string(r.Data), ",")
|
||||
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.Data))
|
||||
t.Fatal("expected %d,%d ; got %s", n, n, string(r.Value))
|
||||
}
|
||||
beginCount, _ := strconv.Atoi(spl[0])
|
||||
endCount, _ := strconv.Atoi(spl[1])
|
@ -1,76 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/server"
|
||||
"github.com/tendermint/abci/types"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
addrPtr := flag.String("addr", "tcp://0.0.0.0:46658", "Listen address")
|
||||
abciPtr := flag.String("abci", "socket", "socket | grpc")
|
||||
flag.Parse()
|
||||
|
||||
// Start the listener
|
||||
srv, err := server.NewServer(*addrPtr, *abciPtr, NewChainAwareApplication())
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
}
|
||||
|
||||
// Wait forever
|
||||
TrapSignal(func() {
|
||||
// Cleanup
|
||||
srv.Stop()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
type ChainAwareApplication struct {
|
||||
beginCount int
|
||||
endCount int
|
||||
}
|
||||
|
||||
func NewChainAwareApplication() *ChainAwareApplication {
|
||||
return &ChainAwareApplication{}
|
||||
}
|
||||
|
||||
func (app *ChainAwareApplication) Info() types.ResponseInfo {
|
||||
return types.ResponseInfo{}
|
||||
}
|
||||
|
||||
func (app *ChainAwareApplication) SetOption(key string, value string) (log string) {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (app *ChainAwareApplication) DeliverTx(tx []byte) types.Result {
|
||||
return types.NewResultOK(nil, "")
|
||||
}
|
||||
|
||||
func (app *ChainAwareApplication) CheckTx(tx []byte) types.Result {
|
||||
return types.NewResultOK(nil, "")
|
||||
}
|
||||
|
||||
func (app *ChainAwareApplication) Commit() types.Result {
|
||||
return types.NewResultOK([]byte("nil"), "")
|
||||
}
|
||||
|
||||
func (app *ChainAwareApplication) Query(query []byte) types.Result {
|
||||
return types.NewResultOK([]byte(Fmt("%d,%d", app.beginCount, app.endCount)), "")
|
||||
}
|
||||
|
||||
func (app *ChainAwareApplication) BeginBlock(hash []byte, header *types.Header) {
|
||||
app.beginCount += 1
|
||||
return
|
||||
}
|
||||
|
||||
func (app *ChainAwareApplication) EndBlock(height uint64) (resEndBlock types.ResponseEndBlock) {
|
||||
app.endCount += 1
|
||||
return
|
||||
}
|
||||
|
||||
func (app *ChainAwareApplication) InitChain(vals []*types.Validator) {
|
||||
return
|
||||
}
|
@ -3,11 +3,13 @@ package counter
|
||||
import (
|
||||
"encoding/binary"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
type CounterApplication struct {
|
||||
types.BaseApplication
|
||||
|
||||
hashCount int
|
||||
txCount int
|
||||
serial bool
|
||||
@ -18,7 +20,7 @@ func NewCounterApplication(serial bool) *CounterApplication {
|
||||
}
|
||||
|
||||
func (app *CounterApplication) Info() types.ResponseInfo {
|
||||
return types.ResponseInfo{Data: Fmt("{\"hashes\":%v,\"txs\":%v}", app.hashCount, app.txCount)}
|
||||
return types.ResponseInfo{Data: cmn.Fmt("{\"hashes\":%v,\"txs\":%v}", app.hashCount, app.txCount)}
|
||||
}
|
||||
|
||||
func (app *CounterApplication) SetOption(key string, value string) (log string) {
|
||||
@ -31,55 +33,51 @@ func (app *CounterApplication) SetOption(key string, value string) (log string)
|
||||
func (app *CounterApplication) DeliverTx(tx []byte) types.Result {
|
||||
if app.serial {
|
||||
if len(tx) > 8 {
|
||||
return types.ErrEncodingError.SetLog(Fmt("Max tx size is 8 bytes, got %d", len(tx)))
|
||||
return types.ErrEncodingError.SetLog(cmn.Fmt("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(Fmt("Invalid nonce. Expected %v, got %v", app.txCount, txValue))
|
||||
return types.ErrBadNonce.SetLog(cmn.Fmt("Invalid nonce. Expected %v, got %v", app.txCount, txValue))
|
||||
}
|
||||
}
|
||||
app.txCount += 1
|
||||
app.txCount++
|
||||
return types.OK
|
||||
}
|
||||
|
||||
func (app *CounterApplication) CheckTx(tx []byte) types.Result {
|
||||
if app.serial {
|
||||
if len(tx) > 8 {
|
||||
return types.ErrEncodingError.SetLog(Fmt("Max tx size is 8 bytes, got %d", len(tx)))
|
||||
return types.ErrEncodingError.SetLog(cmn.Fmt("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(Fmt("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue))
|
||||
return types.ErrBadNonce.SetLog(cmn.Fmt("Invalid nonce. Expected >= %v, got %v", app.txCount, txValue))
|
||||
}
|
||||
}
|
||||
return types.OK
|
||||
}
|
||||
|
||||
func (app *CounterApplication) Commit() types.Result {
|
||||
app.hashCount += 1
|
||||
|
||||
app.hashCount++
|
||||
if app.txCount == 0 {
|
||||
return types.OK
|
||||
} else {
|
||||
hash := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(hash, uint64(app.txCount))
|
||||
return types.NewResultOK(hash, "")
|
||||
}
|
||||
hash := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(hash, uint64(app.txCount))
|
||||
return types.NewResultOK(hash, "")
|
||||
}
|
||||
|
||||
func (app *CounterApplication) Query(query []byte) types.Result {
|
||||
queryStr := string(query)
|
||||
|
||||
switch queryStr {
|
||||
func (app *CounterApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery {
|
||||
switch reqQuery.Path {
|
||||
case "hash":
|
||||
return types.NewResultOK(nil, Fmt("%v", app.hashCount))
|
||||
return types.ResponseQuery{Value: []byte(cmn.Fmt("%v", app.hashCount))}
|
||||
case "tx":
|
||||
return types.NewResultOK(nil, Fmt("%v", app.txCount))
|
||||
return types.ResponseQuery{Value: []byte(cmn.Fmt("%v", app.txCount))}
|
||||
default:
|
||||
return types.ResponseQuery{Log: cmn.Fmt("Invalid query path. Expected hash or tx, got %v", reqQuery.Path)}
|
||||
}
|
||||
|
||||
return types.ErrUnknownRequest.SetLog(Fmt("Invalid nonce. Expected hash or tx, got %v", queryStr))
|
||||
}
|
||||
|
@ -1,16 +1,16 @@
|
||||
package dummy
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
|
||||
"github.com/tendermint/abci/types"
|
||||
. "github.com/tendermint/go-common"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/go-merkle"
|
||||
"github.com/tendermint/go-wire"
|
||||
)
|
||||
|
||||
type DummyApplication struct {
|
||||
types.BaseApplication
|
||||
|
||||
state merkle.Tree
|
||||
}
|
||||
|
||||
@ -20,11 +20,7 @@ func NewDummyApplication() *DummyApplication {
|
||||
}
|
||||
|
||||
func (app *DummyApplication) Info() (resInfo types.ResponseInfo) {
|
||||
return types.ResponseInfo{Data: Fmt("{\"size\":%v}", app.state.Size())}
|
||||
}
|
||||
|
||||
func (app *DummyApplication) SetOption(key string, value string) (log string) {
|
||||
return ""
|
||||
return types.ResponseInfo{Data: cmn.Fmt("{\"size\":%v}", app.state.Size())}
|
||||
}
|
||||
|
||||
// tx is either "key=value" or just arbitrary bytes
|
||||
@ -47,15 +43,28 @@ func (app *DummyApplication) Commit() types.Result {
|
||||
return types.NewResultOK(hash, "")
|
||||
}
|
||||
|
||||
func (app *DummyApplication) Query(query []byte) types.Result {
|
||||
index, value, exists := app.state.Get(query)
|
||||
queryResult := QueryResult{index, string(value), hex.EncodeToString(value), exists}
|
||||
return types.NewResultOK(wire.JSONBytes(queryResult), "")
|
||||
}
|
||||
|
||||
type QueryResult struct {
|
||||
Index int `json:"index"`
|
||||
Value string `json:"value"`
|
||||
ValueHex string `json:"valueHex"`
|
||||
Exists bool `json:"exists"`
|
||||
func (app *DummyApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {
|
||||
if reqQuery.Prove {
|
||||
value, proof, exists := app.state.Proof(reqQuery.Data)
|
||||
resQuery.Index = -1 // TODO make Proof return index
|
||||
resQuery.Key = reqQuery.Data
|
||||
resQuery.Value = value
|
||||
resQuery.Proof = proof
|
||||
if exists {
|
||||
resQuery.Log = "exists"
|
||||
} else {
|
||||
resQuery.Log = "does not exist"
|
||||
}
|
||||
return
|
||||
} else {
|
||||
index, value, exists := app.state.Get(reqQuery.Data)
|
||||
resQuery.Index = int64(index)
|
||||
resQuery.Value = value
|
||||
if exists {
|
||||
resQuery.Log = "exists"
|
||||
} else {
|
||||
resQuery.Log = "does not exist"
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@ -6,34 +6,41 @@ import (
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/stretchr/testify/require"
|
||||
abcicli "github.com/tendermint/abci/client"
|
||||
"github.com/tendermint/abci/server"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-merkle"
|
||||
)
|
||||
|
||||
func testDummy(t *testing.T, dummy types.Application, tx []byte, key, value string) {
|
||||
if r := dummy.DeliverTx(tx); r.IsErr() {
|
||||
t.Fatal(r)
|
||||
}
|
||||
if r := dummy.DeliverTx(tx); r.IsErr() {
|
||||
t.Fatal(r)
|
||||
}
|
||||
func testDummy(t *testing.T, app types.Application, tx []byte, key, value string) {
|
||||
ar := app.DeliverTx(tx)
|
||||
require.False(t, ar.IsErr(), ar)
|
||||
// repeating tx doesn't raise error
|
||||
ar = app.DeliverTx(tx)
|
||||
require.False(t, ar.IsErr(), ar)
|
||||
|
||||
r := dummy.Query([]byte(key))
|
||||
if r.IsErr() {
|
||||
t.Fatal(r)
|
||||
}
|
||||
|
||||
q := new(QueryResult)
|
||||
if err := wire.ReadJSONBytes(r.Data, q); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if q.Value != value {
|
||||
t.Fatalf("Got %s, expected %s", q.Value, value)
|
||||
}
|
||||
// make sure query is fine
|
||||
resQuery := app.Query(types.RequestQuery{
|
||||
Path: "/store",
|
||||
Data: []byte(key),
|
||||
})
|
||||
require.Equal(t, types.CodeType_OK, resQuery.Code)
|
||||
require.Equal(t, value, string(resQuery.Value))
|
||||
|
||||
// make sure proof is fine
|
||||
resQuery = app.Query(types.RequestQuery{
|
||||
Path: "/store",
|
||||
Data: []byte(key),
|
||||
Prove: true,
|
||||
})
|
||||
require.Equal(t, types.CodeType_OK, resQuery.Code)
|
||||
require.Equal(t, value, string(resQuery.Value))
|
||||
proof, err := merkle.ReadProof(resQuery.Proof)
|
||||
require.Nil(t, err)
|
||||
require.True(t, proof.Verify([]byte(key), resQuery.Value, proof.RootHash)) // NOTE: we have no way to verify the RootHash
|
||||
}
|
||||
|
||||
func TestDummyKV(t *testing.T) {
|
||||
@ -107,8 +114,8 @@ func TestValSetChanges(t *testing.T) {
|
||||
nInit := 5
|
||||
vals := make([]*types.Validator, total)
|
||||
for i := 0; i < total; i++ {
|
||||
pubkey := crypto.GenPrivKeyEd25519FromSecret([]byte(Fmt("test%d", i))).PubKey().Bytes()
|
||||
power := RandInt()
|
||||
pubkey := crypto.GenPrivKeyEd25519FromSecret([]byte(cmn.Fmt("test%d", i))).PubKey().Bytes()
|
||||
power := cmn.RandInt()
|
||||
vals[i] = &types.Validator{pubkey, uint64(power)}
|
||||
}
|
||||
// iniitalize with the first nInit
|
||||
@ -172,14 +179,13 @@ func makeApplyBlock(t *testing.T, dummy types.Application, heightInt int, diff [
|
||||
Height: height,
|
||||
}
|
||||
|
||||
dummyChain := dummy.(types.BlockchainAware) // hmm...
|
||||
dummyChain.BeginBlock(hash, header)
|
||||
dummy.BeginBlock(hash, header)
|
||||
for _, tx := range txs {
|
||||
if r := dummy.DeliverTx(tx); r.IsErr() {
|
||||
t.Fatal(r)
|
||||
}
|
||||
}
|
||||
resEndBlock := dummyChain.EndBlock(height)
|
||||
resEndBlock := dummy.EndBlock(height)
|
||||
dummy.Commit()
|
||||
|
||||
valsEqual(t, diff, resEndBlock.Diffs)
|
||||
@ -201,3 +207,102 @@ func valsEqual(t *testing.T, vals1, vals2 []*types.Validator) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func makeSocketClientServer(app types.Application, name string) (abcicli.Client, cmn.Service, error) {
|
||||
// Start the listener
|
||||
socket := cmn.Fmt("unix://%s.sock", name)
|
||||
server, err := server.NewSocketServer(socket, app)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
// Connect to the socket
|
||||
client, err := abcicli.NewSocketClient(socket, false)
|
||||
if err != nil {
|
||||
server.Stop()
|
||||
return nil, nil, err
|
||||
}
|
||||
client.Start()
|
||||
|
||||
return client, server, err
|
||||
}
|
||||
|
||||
func makeGRPCClientServer(app types.Application, name string) (abcicli.Client, cmn.Service, error) {
|
||||
// Start the listener
|
||||
socket := cmn.Fmt("unix://%s.sock", name)
|
||||
|
||||
gapp := types.NewGRPCApplication(app)
|
||||
server, err := server.NewGRPCServer(socket, gapp)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
client, err := abcicli.NewGRPCClient(socket, true)
|
||||
if err != nil {
|
||||
server.Stop()
|
||||
return nil, nil, err
|
||||
}
|
||||
return client, server, err
|
||||
}
|
||||
|
||||
func TestClientServer(t *testing.T) {
|
||||
// set up socket app
|
||||
dummy := NewDummyApplication()
|
||||
client, server, err := makeSocketClientServer(dummy, "dummy-socket")
|
||||
require.Nil(t, err)
|
||||
defer server.Stop()
|
||||
defer client.Stop()
|
||||
|
||||
runClientTests(t, client)
|
||||
|
||||
// set up grpc app
|
||||
dummy = NewDummyApplication()
|
||||
gclient, gserver, err := makeGRPCClientServer(dummy, "dummy-grpc")
|
||||
require.Nil(t, err)
|
||||
defer gserver.Stop()
|
||||
defer gclient.Stop()
|
||||
|
||||
runClientTests(t, gclient)
|
||||
}
|
||||
|
||||
func runClientTests(t *testing.T, client abcicli.Client) {
|
||||
// run some tests....
|
||||
key := "abc"
|
||||
value := key
|
||||
tx := []byte(key)
|
||||
testClient(t, client, tx, key, value)
|
||||
|
||||
value = "def"
|
||||
tx = []byte(key + "=" + value)
|
||||
testClient(t, client, tx, key, value)
|
||||
}
|
||||
|
||||
func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) {
|
||||
ar := app.DeliverTxSync(tx)
|
||||
require.False(t, ar.IsErr(), ar)
|
||||
// repeating tx doesn't raise error
|
||||
ar = app.DeliverTxSync(tx)
|
||||
require.False(t, ar.IsErr(), ar)
|
||||
|
||||
// make sure query is fine
|
||||
resQuery, err := app.QuerySync(types.RequestQuery{
|
||||
Path: "/store",
|
||||
Data: []byte(key),
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, types.CodeType_OK, resQuery.Code)
|
||||
require.Equal(t, value, string(resQuery.Value))
|
||||
|
||||
// make sure proof is fine
|
||||
resQuery, err = app.QuerySync(types.RequestQuery{
|
||||
Path: "/store",
|
||||
Data: []byte(key),
|
||||
Prove: true,
|
||||
})
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, types.CodeType_OK, resQuery.Code)
|
||||
require.Equal(t, value, string(resQuery.Value))
|
||||
proof, err := merkle.ReadProof(resQuery.Proof)
|
||||
require.Nil(t, err)
|
||||
require.True(t, proof.Verify([]byte(key), resQuery.Value, proof.RootHash)) // NOTE: we have no way to verify the RootHash
|
||||
}
|
||||
|
@ -6,11 +6,11 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
dbm "github.com/tendermint/go-db"
|
||||
"github.com/tendermint/go-merkle"
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/abci/types"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -89,8 +89,8 @@ func (app *PersistentDummyApplication) Commit() types.Result {
|
||||
return types.NewResultOK(appHash, "")
|
||||
}
|
||||
|
||||
func (app *PersistentDummyApplication) Query(query []byte) types.Result {
|
||||
return app.app.Query(query)
|
||||
func (app *PersistentDummyApplication) Query(reqQuery types.RequestQuery) types.ResponseQuery {
|
||||
return app.app.Query(reqQuery)
|
||||
}
|
||||
|
||||
// Save the validators in the merkle tree
|
||||
@ -135,7 +135,7 @@ func LoadLastBlock(db dbm.DB) (lastBlock LastBlockInfo) {
|
||||
wire.ReadBinaryPtr(&lastBlock, r, 0, n, err)
|
||||
if *err != nil {
|
||||
// DATA HAS BEEN CORRUPTED OR THE SPEC HAS CHANGED
|
||||
Exit(Fmt("Data has been corrupted or its spec has changed: %v\n", *err))
|
||||
log.Crit(cmn.Fmt("Data has been corrupted or its spec has changed: %v\n", *err))
|
||||
}
|
||||
// TODO: ensure that buf is completely read.
|
||||
}
|
||||
@ -149,7 +149,7 @@ func SaveLastBlock(db dbm.DB, lastBlock LastBlockInfo) {
|
||||
wire.WriteBinary(lastBlock, buf, n, err)
|
||||
if *err != nil {
|
||||
// TODO
|
||||
PanicCrisis(*err)
|
||||
cmn.PanicCrisis(*err)
|
||||
}
|
||||
db.Set(lastBlockKey, buf.Bytes())
|
||||
}
|
||||
@ -173,7 +173,7 @@ func (app *PersistentDummyApplication) Validators() (validators []*types.Validat
|
||||
}
|
||||
|
||||
func MakeValSetChangeTx(pubkey []byte, power uint64) []byte {
|
||||
return []byte(Fmt("val:%X/%d", pubkey, power))
|
||||
return []byte(cmn.Fmt("val:%X/%d", pubkey, power))
|
||||
}
|
||||
|
||||
func isValidatorTx(tx []byte) bool {
|
||||
@ -188,16 +188,16 @@ func (app *PersistentDummyApplication) execValidatorTx(tx []byte) types.Result {
|
||||
tx = tx[len(ValidatorSetChangePrefix):]
|
||||
pubKeyAndPower := strings.Split(string(tx), "/")
|
||||
if len(pubKeyAndPower) != 2 {
|
||||
return types.ErrEncodingError.SetLog(Fmt("Expected 'pubkey/power'. Got %v", pubKeyAndPower))
|
||||
return types.ErrEncodingError.SetLog(cmn.Fmt("Expected 'pubkey/power'. Got %v", pubKeyAndPower))
|
||||
}
|
||||
pubkeyS, powerS := pubKeyAndPower[0], pubKeyAndPower[1]
|
||||
pubkey, err := hex.DecodeString(pubkeyS)
|
||||
if err != nil {
|
||||
return types.ErrEncodingError.SetLog(Fmt("Pubkey (%s) is invalid hex", pubkeyS))
|
||||
return types.ErrEncodingError.SetLog(cmn.Fmt("Pubkey (%s) is invalid hex", pubkeyS))
|
||||
}
|
||||
power, err := strconv.Atoi(powerS)
|
||||
if err != nil {
|
||||
return types.ErrEncodingError.SetLog(Fmt("Power (%s) is not an int", powerS))
|
||||
return types.ErrEncodingError.SetLog(cmn.Fmt("Power (%s) is not an int", powerS))
|
||||
}
|
||||
|
||||
// update
|
||||
@ -210,14 +210,14 @@ func (app *PersistentDummyApplication) updateValidator(v *types.Validator) types
|
||||
if v.Power == 0 {
|
||||
// remove validator
|
||||
if !app.app.state.Has(key) {
|
||||
return types.ErrUnauthorized.SetLog(Fmt("Cannot remove non-existent validator %X", key))
|
||||
return types.ErrUnauthorized.SetLog(cmn.Fmt("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(Fmt("Error encoding validator: %v", err))
|
||||
return types.ErrInternalError.SetLog(cmn.Fmt("Error encoding validator: %v", err))
|
||||
}
|
||||
app.app.state.Set(key, value.Bytes())
|
||||
}
|
||||
|
@ -2,20 +2,21 @@ package example
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"github.com/tendermint/abci/client"
|
||||
"github.com/tendermint/abci/example/dummy"
|
||||
nilapp "github.com/tendermint/abci/example/nil"
|
||||
"github.com/tendermint/abci/server"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
func TestDummy(t *testing.T) {
|
||||
@ -23,14 +24,14 @@ func TestDummy(t *testing.T) {
|
||||
testStream(t, dummy.NewDummyApplication())
|
||||
}
|
||||
|
||||
func TestNilApp(t *testing.T) {
|
||||
fmt.Println("### Testing NilApp")
|
||||
testStream(t, nilapp.NewNilApplication())
|
||||
func TestBaseApp(t *testing.T) {
|
||||
fmt.Println("### Testing BaseApp")
|
||||
testStream(t, types.NewBaseApplication())
|
||||
}
|
||||
|
||||
func TestGRPC(t *testing.T) {
|
||||
fmt.Println("### Testing GRPC")
|
||||
testGRPCSync(t, types.NewGRPCApplication(nilapp.NewNilApplication()))
|
||||
testGRPCSync(t, types.NewGRPCApplication(types.NewBaseApplication()))
|
||||
}
|
||||
|
||||
func testStream(t *testing.T, app types.Application) {
|
||||
@ -40,14 +41,14 @@ func testStream(t *testing.T, app types.Application) {
|
||||
// Start the listener
|
||||
server, err := server.NewSocketServer("unix://test.sock", app)
|
||||
if err != nil {
|
||||
Exit(Fmt("Error starting socket server: %v", err.Error()))
|
||||
log.Fatal(cmn.Fmt("Error starting socket server: %v", err.Error()))
|
||||
}
|
||||
defer server.Stop()
|
||||
|
||||
// Connect to the socket
|
||||
client, err := abcicli.NewSocketClient("unix://test.sock", false)
|
||||
if err != nil {
|
||||
Exit(Fmt("Error starting socket client: %v", err.Error()))
|
||||
log.Fatal(cmn.Fmt("Error starting socket client: %v", err.Error()))
|
||||
}
|
||||
client.Start()
|
||||
defer client.Stop()
|
||||
@ -58,7 +59,7 @@ func testStream(t *testing.T, app types.Application) {
|
||||
// Process response
|
||||
switch r := res.Value.(type) {
|
||||
case *types.Response_DeliverTx:
|
||||
counter += 1
|
||||
counter++
|
||||
if r.DeliverTx.Code != types.CodeType_OK {
|
||||
t.Error("DeliverTx failed with ret_code", r.DeliverTx.Code)
|
||||
}
|
||||
@ -103,7 +104,7 @@ func testStream(t *testing.T, app types.Application) {
|
||||
// test grpc
|
||||
|
||||
func dialerFunc(addr string, timeout time.Duration) (net.Conn, error) {
|
||||
return Connect(addr)
|
||||
return cmn.Connect(addr)
|
||||
}
|
||||
|
||||
func testGRPCSync(t *testing.T, app *types.GRPCApplication) {
|
||||
@ -113,14 +114,14 @@ func testGRPCSync(t *testing.T, app *types.GRPCApplication) {
|
||||
// Start the listener
|
||||
server, err := server.NewGRPCServer("unix://test.sock", app)
|
||||
if err != nil {
|
||||
Exit(Fmt("Error starting GRPC server: %v", err.Error()))
|
||||
log.Fatal(cmn.Fmt("Error starting GRPC server: %v", err.Error()))
|
||||
}
|
||||
defer server.Stop()
|
||||
|
||||
// Connect to the socket
|
||||
conn, err := grpc.Dial("unix://test.sock", grpc.WithInsecure(), grpc.WithDialer(dialerFunc))
|
||||
if err != nil {
|
||||
Exit(Fmt("Error dialing GRPC server: %v", err.Error()))
|
||||
log.Fatal(cmn.Fmt("Error dialing GRPC server: %v", err.Error()))
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
@ -133,7 +134,7 @@ func testGRPCSync(t *testing.T, app *types.GRPCApplication) {
|
||||
if err != nil {
|
||||
t.Fatalf("Error in GRPC DeliverTx: %v", err.Error())
|
||||
}
|
||||
counter += 1
|
||||
counter++
|
||||
if response.Code != types.CodeType_OK {
|
||||
t.Error("DeliverTx failed with ret_code", response.Code)
|
||||
}
|
||||
|
@ -1,36 +0,0 @@
|
||||
package nilapp
|
||||
|
||||
import (
|
||||
"github.com/tendermint/abci/types"
|
||||
)
|
||||
|
||||
type NilApplication struct {
|
||||
}
|
||||
|
||||
func NewNilApplication() *NilApplication {
|
||||
return &NilApplication{}
|
||||
}
|
||||
|
||||
func (app *NilApplication) Info() (resInfo types.ResponseInfo) {
|
||||
return
|
||||
}
|
||||
|
||||
func (app *NilApplication) SetOption(key string, value string) (log string) {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (app *NilApplication) DeliverTx(tx []byte) types.Result {
|
||||
return types.NewResultOK(nil, "")
|
||||
}
|
||||
|
||||
func (app *NilApplication) CheckTx(tx []byte) types.Result {
|
||||
return types.NewResultOK(nil, "")
|
||||
}
|
||||
|
||||
func (app *NilApplication) Commit() types.Result {
|
||||
return types.NewResultOK([]byte("nil"), "")
|
||||
}
|
||||
|
||||
func (app *NilApplication) Query(query []byte) types.Result {
|
||||
return types.NewResultOK(nil, "")
|
||||
}
|
50
glide.lock
generated
50
glide.lock
generated
@ -1,8 +1,8 @@
|
||||
hash: febff7f2646081f635b5dc2a0a672d9b8e42eb59241269e6658eec916cd2a5a4
|
||||
updated: 2017-01-13T00:24:02.377918976-05:00
|
||||
hash: 54e49c7cb920a3390f631de12e38226494920bbc5e0c369514df18fe0ab5b693
|
||||
updated: 2017-02-14T16:51:55.592202262-05:00
|
||||
imports:
|
||||
- name: github.com/btcsuite/btcd
|
||||
version: 153dca5c1e4b5d1ea1523592495e5bedfa503391
|
||||
version: d06c0bb181529331be8f8d9350288c420d9e60e4
|
||||
subpackages:
|
||||
- btcec
|
||||
- name: github.com/go-stack/stack
|
||||
@ -12,13 +12,18 @@ imports:
|
||||
subpackages:
|
||||
- proto
|
||||
- name: github.com/golang/snappy
|
||||
version: d9eb7a3d35ec988b8585d4a0068e462c27d28380
|
||||
version: 7db9049039a047d955fe8c19b83c8ff5abd765c7
|
||||
- name: github.com/jmhodges/levigo
|
||||
version: c42d9e0ca023e2198120196f842701bb4c55d7b9
|
||||
- name: github.com/mattn/go-colorable
|
||||
version: d228849504861217f796da67fae4f6e347643f15
|
||||
version: 5411d3eea5978e6cdc258b30de592b60df6aba96
|
||||
- name: github.com/mattn/go-isatty
|
||||
version: 30a891c33c7cde7b02a981314b4228ec99380cca
|
||||
version: 281032e84ae07510239465db46bf442aa44b953a
|
||||
- name: github.com/stretchr/testify
|
||||
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
|
||||
subpackages:
|
||||
- assert
|
||||
- require
|
||||
- name: github.com/syndtr/goleveldb
|
||||
version: 23851d93a2292dcc56e71a18ec9e0624d84a0f65
|
||||
subpackages:
|
||||
@ -40,7 +45,7 @@ imports:
|
||||
- edwards25519
|
||||
- extra25519
|
||||
- name: github.com/tendermint/go-common
|
||||
version: e289af53b6bf6af28da129d9ef64389a4cf7987f
|
||||
version: 339e135776142939d82bc8e699db0bf391fd938d
|
||||
- name: github.com/tendermint/go-crypto
|
||||
version: 4b11d62bdb324027ea01554e5767b71174680ba0
|
||||
- name: github.com/tendermint/go-db
|
||||
@ -48,19 +53,19 @@ imports:
|
||||
- name: github.com/tendermint/go-logger
|
||||
version: cefb3a45c0bf3c493a04e9bcd9b1540528be59f2
|
||||
- name: github.com/tendermint/go-merkle
|
||||
version: 7a86b4486f2cd84ac885c5bbc609fdee2905f5d1
|
||||
version: 9f20e80cb188d07860caa70196dd7700659ec4a4
|
||||
- name: github.com/tendermint/go-process
|
||||
version: b27edfd189b1a01a0b099f7e9f8263589cf04909
|
||||
- name: github.com/tendermint/go-wire
|
||||
version: 2f3b7aafe21c80b19b6ee3210ecb3e3d07c7a471
|
||||
version: 3216ec9d47bbdf8d4fc27d22169ea86a6688bc15
|
||||
- name: github.com/tendermint/log15
|
||||
version: ae0f3d6450da9eac7074b439c8e1c3cabf0d5ce6
|
||||
subpackages:
|
||||
- term
|
||||
- name: github.com/urfave/cli
|
||||
version: 8ef3805c9de2519805c3f060524b695bba2cd715
|
||||
version: 347a9884a87374d000eec7e6445a34487c1f4a2b
|
||||
- name: golang.org/x/crypto
|
||||
version: 7c6cc321c680f03b9ef0764448e780704f486b51
|
||||
version: 453249f01cfeb54c3d549ddb75ff152ca243f9d8
|
||||
subpackages:
|
||||
- nacl/secretbox
|
||||
- openpgp/armor
|
||||
@ -69,7 +74,7 @@ imports:
|
||||
- ripemd160
|
||||
- salsa20/salsa
|
||||
- name: golang.org/x/net
|
||||
version: 60c41d1de8da134c05b7b40154a9a82bf5b7edb9
|
||||
version: 61557ac0112b576429a0df080e1c2cef5dfbb642
|
||||
subpackages:
|
||||
- context
|
||||
- http2
|
||||
@ -79,18 +84,11 @@ imports:
|
||||
- lex/httplex
|
||||
- trace
|
||||
- name: golang.org/x/sys
|
||||
version: d75a52659825e75fff6158388dddc6a5b04f9ba5
|
||||
version: e24f485414aeafb646f6fca458b0bf869c0880a1
|
||||
subpackages:
|
||||
- unix
|
||||
- name: golang.org/x/text
|
||||
version: 44f4f658a783b0cee41fe0a23b8fc91d9c120558
|
||||
subpackages:
|
||||
- secure/bidirule
|
||||
- transform
|
||||
- unicode/bidi
|
||||
- unicode/norm
|
||||
- name: google.golang.org/grpc
|
||||
version: 50955793b0183f9de69bd78e2ec251cf20aab121
|
||||
version: cbcceb2942a489498cf22b2f918536e819d33f0a
|
||||
subpackages:
|
||||
- codes
|
||||
- credentials
|
||||
@ -102,4 +100,12 @@ imports:
|
||||
- stats
|
||||
- tap
|
||||
- transport
|
||||
testImports: []
|
||||
testImports:
|
||||
- name: github.com/davecgh/go-spew
|
||||
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
|
||||
subpackages:
|
||||
- spew
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
- difflib
|
||||
|
@ -4,10 +4,13 @@ import:
|
||||
subpackages:
|
||||
- proto
|
||||
- package: github.com/tendermint/go-common
|
||||
version: develop
|
||||
- package: github.com/tendermint/go-crypto
|
||||
version: develop
|
||||
- package: github.com/tendermint/go-logger
|
||||
- package: github.com/tendermint/go-db
|
||||
- package: github.com/tendermint/go-merkle
|
||||
version: develop
|
||||
- package: github.com/tendermint/go-process
|
||||
- package: github.com/tendermint/go-wire
|
||||
- package: github.com/urfave/cli
|
||||
@ -15,3 +18,7 @@ import:
|
||||
subpackages:
|
||||
- context
|
||||
- package: google.golang.org/grpc
|
||||
- package: github.com/stretchr/testify
|
||||
version: ^1.1.4
|
||||
subpackages:
|
||||
- require
|
||||
|
@ -6,14 +6,14 @@ import (
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
// var maxNumberConnections = 2
|
||||
|
||||
type GRPCServer struct {
|
||||
BaseService
|
||||
cmn.BaseService
|
||||
|
||||
proto string
|
||||
addr string
|
||||
@ -23,7 +23,7 @@ type GRPCServer struct {
|
||||
app types.ABCIApplicationServer
|
||||
}
|
||||
|
||||
func NewGRPCServer(protoAddr string, app types.ABCIApplicationServer) (Service, error) {
|
||||
func NewGRPCServer(protoAddr string, app types.ABCIApplicationServer) (cmn.Service, error) {
|
||||
parts := strings.SplitN(protoAddr, "://", 2)
|
||||
proto, addr := parts[0], parts[1]
|
||||
s := &GRPCServer{
|
||||
@ -32,7 +32,7 @@ func NewGRPCServer(protoAddr string, app types.ABCIApplicationServer) (Service,
|
||||
listener: nil,
|
||||
app: app,
|
||||
}
|
||||
s.BaseService = *NewBaseService(nil, "ABCIServer", s)
|
||||
s.BaseService = *cmn.NewBaseService(nil, "ABCIServer", s)
|
||||
_, err := s.Start() // Just start it
|
||||
return s, err
|
||||
}
|
||||
|
@ -3,12 +3,12 @@ package server
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
func NewServer(protoAddr, transport string, app types.Application) (Service, error) {
|
||||
var s Service
|
||||
func NewServer(protoAddr, transport string, app types.Application) (cmn.Service, error) {
|
||||
var s cmn.Service
|
||||
var err error
|
||||
switch transport {
|
||||
case "socket":
|
||||
|
@ -8,14 +8,14 @@ import (
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
// var maxNumberConnections = 2
|
||||
|
||||
type SocketServer struct {
|
||||
BaseService
|
||||
cmn.BaseService
|
||||
|
||||
proto string
|
||||
addr string
|
||||
@ -29,7 +29,7 @@ type SocketServer struct {
|
||||
app types.Application
|
||||
}
|
||||
|
||||
func NewSocketServer(protoAddr string, app types.Application) (Service, error) {
|
||||
func NewSocketServer(protoAddr string, app types.Application) (cmn.Service, error) {
|
||||
parts := strings.SplitN(protoAddr, "://", 2)
|
||||
proto, addr := parts[0], parts[1]
|
||||
s := &SocketServer{
|
||||
@ -39,7 +39,7 @@ func NewSocketServer(protoAddr string, app types.Application) (Service, error) {
|
||||
app: app,
|
||||
conns: make(map[int]net.Conn),
|
||||
}
|
||||
s.BaseService = *NewBaseService(nil, "ABCIServer", s)
|
||||
s.BaseService = *cmn.NewBaseService(nil, "ABCIServer", s)
|
||||
_, err := s.Start() // Just start it
|
||||
return s, err
|
||||
}
|
||||
@ -72,7 +72,7 @@ func (s *SocketServer) addConn(conn net.Conn) int {
|
||||
defer s.connsMtx.Unlock()
|
||||
|
||||
connID := s.nextConnID
|
||||
s.nextConnID += 1
|
||||
s.nextConnID++
|
||||
s.conns[connID] = conn
|
||||
|
||||
return connID
|
||||
@ -100,7 +100,7 @@ func (s *SocketServer) acceptConnectionsRoutine() {
|
||||
if !s.IsRunning() {
|
||||
return // Ignore error from listener closing.
|
||||
}
|
||||
Exit("Failed to accept connection: " + err.Error())
|
||||
log.Crit("Failed to accept connection: " + err.Error())
|
||||
} else {
|
||||
log.Notice("Accepted a new connection")
|
||||
}
|
||||
@ -184,25 +184,17 @@ func (s *SocketServer) handleRequest(req *types.Request, responses chan<- *types
|
||||
res := s.app.Commit()
|
||||
responses <- types.ToResponseCommit(res.Code, res.Data, res.Log)
|
||||
case *types.Request_Query:
|
||||
res := s.app.Query(r.Query.Query)
|
||||
responses <- types.ToResponseQuery(res.Code, res.Data, res.Log)
|
||||
resQuery := s.app.Query(*r.Query)
|
||||
responses <- types.ToResponseQuery(resQuery)
|
||||
case *types.Request_InitChain:
|
||||
if app, ok := s.app.(types.BlockchainAware); ok {
|
||||
app.InitChain(r.InitChain.Validators)
|
||||
}
|
||||
s.app.InitChain(r.InitChain.Validators)
|
||||
responses <- types.ToResponseInitChain()
|
||||
case *types.Request_BeginBlock:
|
||||
if app, ok := s.app.(types.BlockchainAware); ok {
|
||||
app.BeginBlock(r.BeginBlock.Hash, r.BeginBlock.Header)
|
||||
}
|
||||
s.app.BeginBlock(r.BeginBlock.Hash, r.BeginBlock.Header)
|
||||
responses <- types.ToResponseBeginBlock()
|
||||
case *types.Request_EndBlock:
|
||||
if app, ok := s.app.(types.BlockchainAware); ok {
|
||||
resEndBlock := app.EndBlock(r.EndBlock.Height)
|
||||
responses <- types.ToResponseEndBlock(resEndBlock)
|
||||
} else {
|
||||
responses <- types.ToResponseEndBlock(types.ResponseEndBlock{})
|
||||
}
|
||||
resEndBlock := s.app.EndBlock(r.EndBlock.Height)
|
||||
responses <- types.ToResponseEndBlock(resEndBlock)
|
||||
default:
|
||||
responses <- types.ToResponseException("Unknown request")
|
||||
}
|
||||
|
@ -3,17 +3,17 @@ package main
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
//"encoding/hex"
|
||||
"log"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
conn, err := Connect("unix://test.sock")
|
||||
conn, err := cmn.Connect("unix://test.sock")
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
// Read a bunch of responses
|
||||
@ -23,9 +23,9 @@ func main() {
|
||||
var res = &types.Response{}
|
||||
err := types.ReadMessage(conn, res)
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
counter += 1
|
||||
counter++
|
||||
if counter%1000 == 0 {
|
||||
fmt.Println("Read", counter)
|
||||
}
|
||||
@ -40,14 +40,14 @@ func main() {
|
||||
|
||||
err := types.WriteMessage(req, bufWriter)
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
err = bufWriter.Flush()
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
counter += 1
|
||||
counter++
|
||||
if counter%1000 == 0 {
|
||||
fmt.Println("Write", counter)
|
||||
}
|
||||
|
@ -2,21 +2,20 @@ package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"reflect"
|
||||
//"encoding/hex"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/go-common"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
conn, err := Connect("unix://test.sock")
|
||||
conn, err := cmn.Connect("unix://test.sock")
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
// Make a bunch of requests
|
||||
@ -25,9 +24,9 @@ func main() {
|
||||
req := types.ToRequestEcho("foobar")
|
||||
_, err := makeRequest(conn, req)
|
||||
if err != nil {
|
||||
Exit(err.Error())
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
counter += 1
|
||||
counter++
|
||||
if counter%1000 == 0 {
|
||||
fmt.Println(counter)
|
||||
}
|
||||
@ -63,7 +62,7 @@ func makeRequest(conn net.Conn, req *types.Request) (*types.Response, error) {
|
||||
return nil, err
|
||||
}
|
||||
if _, ok := resFlush.Value.(*types.Response_Flush); !ok {
|
||||
return nil, errors.New(Fmt("Expected flush response but got something else: %v", reflect.TypeOf(resFlush)))
|
||||
return nil, fmt.Errorf("Expected flush response but got something else: %v", reflect.TypeOf(resFlush))
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
@ -2,18 +2,16 @@ package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
. "github.com/tendermint/go-common"
|
||||
"github.com/tendermint/go-process"
|
||||
"github.com/tendermint/abci/client"
|
||||
"github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/go-process"
|
||||
)
|
||||
|
||||
//----------------------------------------
|
||||
|
||||
func StartApp(abciApp string) *process.Process {
|
||||
func startApp(abciApp string) *process.Process {
|
||||
// Start the app
|
||||
//outBuf := NewBufferCloser(nil)
|
||||
proc, err := process.StartProcess("abci_app",
|
||||
@ -33,7 +31,7 @@ func StartApp(abciApp string) *process.Process {
|
||||
return proc
|
||||
}
|
||||
|
||||
func StartClient(abciType string) abcicli.Client {
|
||||
func startClient(abciType string) abcicli.Client {
|
||||
// Start client
|
||||
client, err := abcicli.NewClient("tcp://127.0.0.1:46658", abciType, true)
|
||||
if err != nil {
|
||||
@ -42,51 +40,51 @@ func StartClient(abciType string) abcicli.Client {
|
||||
return client
|
||||
}
|
||||
|
||||
func SetOption(client abcicli.Client, key, value string) {
|
||||
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("setting %v=%v: \nlog: %v", key, value, log))
|
||||
panic(fmt.Sprintf("setting %v=%v: \nlog: %v", key, value, log))
|
||||
}
|
||||
}
|
||||
|
||||
func Commit(client abcicli.Client, hashExp []byte) {
|
||||
func commit(client abcicli.Client, hashExp []byte) {
|
||||
res := client.CommitSync()
|
||||
_, data, log := res.Code, res.Data, res.Log
|
||||
if res.IsErr() {
|
||||
panic(Fmt("committing %v\nlog: %v", log))
|
||||
panic(fmt.Sprintf("committing %v\nlog: %v", log))
|
||||
}
|
||||
if !bytes.Equal(res.Data, hashExp) {
|
||||
panic(Fmt("Commit hash was unexpected. Got %X expected %X",
|
||||
panic(fmt.Sprintf("Commit hash was unexpected. Got %X expected %X",
|
||||
data, hashExp))
|
||||
}
|
||||
}
|
||||
|
||||
func DeliverTx(client abcicli.Client, txBytes []byte, codeExp types.CodeType, dataExp []byte) {
|
||||
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("DeliverTx response code was unexpected. Got %v expected %v. Log: %v",
|
||||
panic(fmt.Sprintf("DeliverTx response code was unexpected. Got %v expected %v. Log: %v",
|
||||
code, codeExp, log))
|
||||
}
|
||||
if !bytes.Equal(data, dataExp) {
|
||||
panic(Fmt("DeliverTx response data was unexpected. Got %X expected %X",
|
||||
panic(fmt.Sprintf("DeliverTx response data was unexpected. Got %X expected %X",
|
||||
data, dataExp))
|
||||
}
|
||||
}
|
||||
|
||||
func CheckTx(client abcicli.Client, txBytes []byte, codeExp types.CodeType, dataExp []byte) {
|
||||
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
|
||||
if res.IsErr() {
|
||||
panic(Fmt("checking tx %X: %v\nlog: %v", txBytes, log))
|
||||
panic(fmt.Sprintf("checking tx %X: %v\nlog: %v", txBytes, log))
|
||||
}
|
||||
if code != codeExp {
|
||||
panic(Fmt("CheckTx response code was unexpected. Got %v expected %v. Log: %v",
|
||||
panic(fmt.Sprintf("CheckTx response code was unexpected. Got %v expected %v. Log: %v",
|
||||
code, codeExp, log))
|
||||
}
|
||||
if !bytes.Equal(data, dataExp) {
|
||||
panic(Fmt("CheckTx response data was unexpected. Got %X expected %X",
|
||||
panic(fmt.Sprintf("CheckTx response data was unexpected. Got %X expected %X",
|
||||
data, dataExp))
|
||||
}
|
||||
}
|
||||
|
@ -27,22 +27,22 @@ func testCounter() {
|
||||
}
|
||||
|
||||
fmt.Printf("Running %s test with abci=%s\n", abciApp, abciType)
|
||||
appProc := StartApp(abciApp)
|
||||
appProc := startApp(abciApp)
|
||||
defer appProc.StopProcess(true)
|
||||
client := StartClient(abciType)
|
||||
client := startClient(abciType)
|
||||
defer client.Stop()
|
||||
|
||||
SetOption(client, "serial", "on")
|
||||
Commit(client, nil)
|
||||
DeliverTx(client, []byte("abc"), types.CodeType_BadNonce, nil)
|
||||
Commit(client, nil)
|
||||
DeliverTx(client, []byte{0x00}, types.CodeType_OK, 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)
|
||||
Commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 5})
|
||||
setOption(client, "serial", "on")
|
||||
commit(client, nil)
|
||||
deliverTx(client, []byte("abc"), types.CodeType_BadNonce, nil)
|
||||
commit(client, nil)
|
||||
deliverTx(client, []byte{0x00}, types.CodeType_OK, 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)
|
||||
commit(client, []byte{0, 0, 0, 0, 0, 0, 0, 5})
|
||||
}
|
||||
|
@ -1,32 +1,38 @@
|
||||
> echo hello
|
||||
-> data: hello
|
||||
-> data.hex: 68656C6C6F
|
||||
|
||||
> info
|
||||
-> data: {"size":0}
|
||||
-> data.hex: 7B2273697A65223A307D
|
||||
|
||||
> commit
|
||||
-> data: 0x
|
||||
|
||||
> deliver_tx "abc"
|
||||
-> code: OK
|
||||
|
||||
> info
|
||||
-> data: {"size":1}
|
||||
-> data.hex: 7B2273697A65223A317D
|
||||
|
||||
> commit
|
||||
-> data: 0x750502FC7E84BBD788ED589624F06CFA871845D1
|
||||
-> data: uü~„»×ˆíX–$ðlú‡EÑ
|
||||
-> data.hex: 750502FC7E84BBD788ED589624F06CFA871845D1
|
||||
|
||||
> query "abc"
|
||||
-> code: OK
|
||||
-> data: {"index":0,"value":"abc","valueHex":"616263","exists":true}
|
||||
-> log: exists
|
||||
-> height: 0
|
||||
-> value: abc
|
||||
-> value.hex: 616263
|
||||
|
||||
> deliver_tx "def=xyz"
|
||||
-> code: OK
|
||||
|
||||
> commit
|
||||
-> data: 0x76393B8A182E450286B0694C629ECB51B286EFD5
|
||||
-> data: v9;Š.E†°iLbžËQ²†ïÕ
|
||||
-> data.hex: 76393B8A182E450286B0694C629ECB51B286EFD5
|
||||
|
||||
> query "def"
|
||||
-> code: OK
|
||||
-> data: {"index":1,"value":"xyz","valueHex":"78797a","exists":true}
|
||||
-> log: exists
|
||||
-> height: 0
|
||||
-> value: xyz
|
||||
-> value.hex: 78797A
|
||||
|
||||
|
@ -1,21 +1,16 @@
|
||||
> set_option serial on
|
||||
-> data: serial=on
|
||||
|
||||
> check_tx 0x00
|
||||
-> code: OK
|
||||
|
||||
> check_tx 0xff
|
||||
-> code: OK
|
||||
|
||||
> deliver_tx 0x00
|
||||
-> code: OK
|
||||
|
||||
> check_tx 0x00
|
||||
-> code: BadNonce
|
||||
-> log: Invalid nonce. Expected >= 1, got 0
|
||||
|
||||
> deliver_tx 0x01
|
||||
-> code: OK
|
||||
|
||||
> deliver_tx 0x04
|
||||
-> code: BadNonce
|
||||
@ -23,4 +18,5 @@
|
||||
|
||||
> info
|
||||
-> data: {"hashes":0,"txs":2}
|
||||
-> data.hex: 7B22686173686573223A302C22747873223A327D
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
package testutil
|
||||
|
||||
import (
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/go-crypto"
|
||||
)
|
||||
|
||||
//----------------------------------------
|
||||
|
@ -6,42 +6,25 @@ import (
|
||||
|
||||
// Applications
|
||||
type Application interface {
|
||||
// Info/Query Connection
|
||||
Info() ResponseInfo // Return application info
|
||||
SetOption(key string, value string) (log string) // Set application option
|
||||
Query(reqQuery RequestQuery) ResponseQuery // Query for state
|
||||
|
||||
// Return application info
|
||||
Info() ResponseInfo
|
||||
// Mempool Connection
|
||||
CheckTx(tx []byte) Result // Validate a tx for the mempool
|
||||
|
||||
// Set application option (e.g. mode=mempool, mode=consensus)
|
||||
SetOption(key string, value string) (log string)
|
||||
|
||||
// Deliver a tx
|
||||
DeliverTx(tx []byte) Result
|
||||
|
||||
// Validate a tx for the mempool
|
||||
CheckTx(tx []byte) Result
|
||||
|
||||
// Query for state
|
||||
Query(query []byte) Result
|
||||
|
||||
// Return the application Merkle root hash
|
||||
Commit() Result
|
||||
}
|
||||
|
||||
// Some applications can choose to implement BlockchainAware
|
||||
type BlockchainAware interface {
|
||||
|
||||
// Initialize blockchain
|
||||
// validators: genesis validators from TendermintCore
|
||||
InitChain(validators []*Validator)
|
||||
|
||||
// Signals the beginning of a block
|
||||
BeginBlock(hash []byte, header *Header)
|
||||
|
||||
// Signals the end of a block
|
||||
// diffs: changed validators from app to TendermintCore
|
||||
EndBlock(height uint64) ResponseEndBlock
|
||||
// Consensus Connection
|
||||
InitChain(validators []*Validator) // Initialize blockchain with validators from TendermintCore
|
||||
BeginBlock(hash []byte, header *Header) // 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
|
||||
}
|
||||
|
||||
//------------------------------------
|
||||
|
||||
// GRPC wrapper for application
|
||||
type GRPCApplication struct {
|
||||
app Application
|
||||
}
|
||||
@ -78,8 +61,8 @@ func (app *GRPCApplication) CheckTx(ctx context.Context, req *RequestCheckTx) (*
|
||||
}
|
||||
|
||||
func (app *GRPCApplication) Query(ctx context.Context, req *RequestQuery) (*ResponseQuery, error) {
|
||||
r := app.app.Query(req.Query)
|
||||
return &ResponseQuery{r.Code, r.Data, r.Log}, nil
|
||||
resQuery := app.app.Query(*req)
|
||||
return &resQuery, nil
|
||||
}
|
||||
|
||||
func (app *GRPCApplication) Commit(ctx context.Context, req *RequestCommit) (*ResponseCommit, error) {
|
||||
@ -88,23 +71,16 @@ func (app *GRPCApplication) Commit(ctx context.Context, req *RequestCommit) (*Re
|
||||
}
|
||||
|
||||
func (app *GRPCApplication) InitChain(ctx context.Context, req *RequestInitChain) (*ResponseInitChain, error) {
|
||||
if chainAware, ok := app.app.(BlockchainAware); ok {
|
||||
chainAware.InitChain(req.Validators)
|
||||
}
|
||||
return &ResponseInitChain{}, nil
|
||||
app.app.InitChain(req.Validators)
|
||||
return &ResponseInitChain{}, nil // NOTE: empty return
|
||||
}
|
||||
|
||||
func (app *GRPCApplication) BeginBlock(ctx context.Context, req *RequestBeginBlock) (*ResponseBeginBlock, error) {
|
||||
if chainAware, ok := app.app.(BlockchainAware); ok {
|
||||
chainAware.BeginBlock(req.Hash, req.Header)
|
||||
}
|
||||
return &ResponseBeginBlock{}, nil
|
||||
app.app.BeginBlock(req.Hash, req.Header)
|
||||
return &ResponseBeginBlock{}, nil // NOTE: empty return
|
||||
}
|
||||
|
||||
func (app *GRPCApplication) EndBlock(ctx context.Context, req *RequestEndBlock) (*ResponseEndBlock, error) {
|
||||
if chainAware, ok := app.app.(BlockchainAware); ok {
|
||||
resEndBlock := chainAware.EndBlock(req.Height)
|
||||
return &resEndBlock, nil
|
||||
}
|
||||
return &ResponseEndBlock{}, nil
|
||||
resEndBlock := app.app.EndBlock(req.Height)
|
||||
return &resEndBlock, nil
|
||||
}
|
||||
|
42
types/base_app.go
Normal file
42
types/base_app.go
Normal file
@ -0,0 +1,42 @@
|
||||
package types
|
||||
|
||||
type BaseApplication struct {
|
||||
}
|
||||
|
||||
func NewBaseApplication() *BaseApplication {
|
||||
return &BaseApplication{}
|
||||
}
|
||||
|
||||
func (app *BaseApplication) Info() (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(reqQuery RequestQuery) (resQuery ResponseQuery) {
|
||||
return
|
||||
}
|
||||
|
||||
func (app *BaseApplication) InitChain(validators []*Validator) {
|
||||
}
|
||||
|
||||
func (app *BaseApplication) BeginBlock(hash []byte, header *Header) {
|
||||
}
|
||||
|
||||
func (app *BaseApplication) EndBlock(height uint64) (resEndBlock ResponseEndBlock) {
|
||||
return
|
||||
}
|
3
types/code.go
Normal file
3
types/code.go
Normal file
@ -0,0 +1,3 @@
|
||||
package types
|
||||
|
||||
func (c CodeType) IsOK() bool { return c == CodeType_OK }
|
@ -49,9 +49,9 @@ func ToRequestCommit() *Request {
|
||||
}
|
||||
}
|
||||
|
||||
func ToRequestQuery(queryBytes []byte) *Request {
|
||||
func ToRequestQuery(reqQuery RequestQuery) *Request {
|
||||
return &Request{
|
||||
Value: &Request_Query{&RequestQuery{queryBytes}},
|
||||
Value: &Request_Query{&reqQuery},
|
||||
}
|
||||
}
|
||||
|
||||
@ -123,9 +123,9 @@ func ToResponseCommit(code CodeType, data []byte, log string) *Response {
|
||||
}
|
||||
}
|
||||
|
||||
func ToResponseQuery(code CodeType, data []byte, log string) *Response {
|
||||
func ToResponseQuery(resQuery ResponseQuery) *Response {
|
||||
return &Response{
|
||||
Value: &Response_Query{&ResponseQuery{code, data, log}},
|
||||
Value: &Response_Query{&resQuery},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -716,7 +716,10 @@ func (m *RequestCheckTx) GetTx() []byte {
|
||||
}
|
||||
|
||||
type RequestQuery struct {
|
||||
Query []byte `protobuf:"bytes,1,opt,name=query,proto3" json:"query,omitempty"`
|
||||
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"`
|
||||
}
|
||||
|
||||
func (m *RequestQuery) Reset() { *m = RequestQuery{} }
|
||||
@ -724,13 +727,34 @@ func (m *RequestQuery) String() string { return proto.CompactTextStri
|
||||
func (*RequestQuery) ProtoMessage() {}
|
||||
func (*RequestQuery) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
|
||||
|
||||
func (m *RequestQuery) GetQuery() []byte {
|
||||
func (m *RequestQuery) GetData() []byte {
|
||||
if m != nil {
|
||||
return m.Query
|
||||
return m.Data
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *RequestQuery) GetPath() string {
|
||||
if m != nil {
|
||||
return m.Path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *RequestQuery) GetHeight() uint64 {
|
||||
if m != nil {
|
||||
return m.Height
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *RequestQuery) GetProve() bool {
|
||||
if m != nil {
|
||||
return m.Prove
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
type RequestCommit struct {
|
||||
}
|
||||
|
||||
@ -1387,9 +1411,13 @@ func (m *ResponseCheckTx) GetLog() string {
|
||||
}
|
||||
|
||||
type ResponseQuery 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 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"`
|
||||
}
|
||||
|
||||
func (m *ResponseQuery) Reset() { *m = ResponseQuery{} }
|
||||
@ -1404,13 +1432,41 @@ func (m *ResponseQuery) GetCode() CodeType {
|
||||
return CodeType_OK
|
||||
}
|
||||
|
||||
func (m *ResponseQuery) GetData() []byte {
|
||||
func (m *ResponseQuery) GetIndex() int64 {
|
||||
if m != nil {
|
||||
return m.Data
|
||||
return m.Index
|
||||
}
|
||||
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 {
|
||||
if m != nil {
|
||||
return m.Height
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (m *ResponseQuery) GetLog() string {
|
||||
if m != nil {
|
||||
return m.Log
|
||||
@ -2073,108 +2129,112 @@ var _ABCIApplication_serviceDesc = grpc.ServiceDesc{
|
||||
func init() { proto.RegisterFile("types/types.proto", fileDescriptor0) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
// 1642 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x58, 0xc9, 0x6e, 0xdb, 0xdc,
|
||||
0x15, 0x36, 0x35, 0xeb, 0xc8, 0x96, 0xae, 0x8f, 0x65, 0x5b, 0x56, 0xbb, 0x08, 0xd8, 0xa6, 0xb1,
|
||||
0xdd, 0x34, 0x29, 0x1c, 0xa4, 0x88, 0x9b, 0xa2, 0x80, 0xa7, 0xd8, 0x42, 0x90, 0xc4, 0x65, 0x86,
|
||||
0x45, 0x5b, 0x54, 0xa0, 0xc5, 0x2b, 0x89, 0x35, 0x45, 0x32, 0x1c, 0x1c, 0xbb, 0xcf, 0x90, 0x7d,
|
||||
0x1f, 0xa1, 0x4f, 0xd0, 0xd5, 0xbf, 0xff, 0x81, 0x7f, 0x1e, 0x9e, 0xe8, 0xc7, 0x1d, 0x38, 0x9a,
|
||||
0xcc, 0x2a, 0x1b, 0x81, 0x67, 0xbc, 0xd3, 0x77, 0xbe, 0x7b, 0xae, 0x60, 0x35, 0xb8, 0x71, 0xa9,
|
||||
0xff, 0x90, 0xff, 0x3e, 0x70, 0x3d, 0x27, 0x70, 0xb0, 0xce, 0x05, 0xf5, 0xcb, 0x1a, 0x34, 0x35,
|
||||
0xfa, 0x3e, 0xa4, 0x7e, 0x80, 0xdb, 0x50, 0xa3, 0x93, 0xb9, 0x33, 0x50, 0xee, 0x28, 0xdb, 0x9d,
|
||||
0x3d, 0x7c, 0x20, 0xdc, 0xa5, 0xf5, 0x64, 0x32, 0x77, 0xce, 0x96, 0x34, 0xee, 0x81, 0xbf, 0x87,
|
||||
0xfa, 0xd4, 0x0a, 0xfd, 0xf9, 0xa0, 0xc2, 0x5d, 0xd7, 0xb2, 0xae, 0xcf, 0x98, 0xe9, 0x6c, 0x49,
|
||||
0x13, 0x3e, 0x2c, 0xad, 0x69, 0x4f, 0x9d, 0x41, 0xb5, 0x28, 0xed, 0xc8, 0x9e, 0xf2, 0xb4, 0xcc,
|
||||
0x03, 0x9f, 0x00, 0xf8, 0x34, 0x18, 0x3b, 0x6e, 0x60, 0x3a, 0xf6, 0xa0, 0xc6, 0xfd, 0x37, 0xb3,
|
||||
0xfe, 0xaf, 0x69, 0xf0, 0x8a, 0x9b, 0xcf, 0x96, 0xb4, 0xb6, 0x1f, 0x09, 0x2c, 0xd2, 0xa0, 0x96,
|
||||
0x79, 0x45, 0xbd, 0x71, 0x70, 0x3d, 0xa8, 0x17, 0x45, 0x1e, 0x0b, 0xfb, 0x9b, 0x6b, 0x16, 0x69,
|
||||
0x44, 0x02, 0xee, 0x41, 0x6b, 0x32, 0xa7, 0x93, 0x4b, 0x16, 0xd7, 0xe0, 0x71, 0xeb, 0xd9, 0xb8,
|
||||
0x23, 0x66, 0xe5, 0x51, 0xcd, 0x89, 0xf8, 0xc4, 0x07, 0xd0, 0x98, 0x38, 0x8b, 0x85, 0x19, 0x0c,
|
||||
0x9a, 0x3c, 0xa2, 0x9f, 0x8b, 0xe0, 0xb6, 0xb3, 0x25, 0x4d, 0x7a, 0xb1, 0xed, 0x7a, 0x1f, 0x52,
|
||||
0xef, 0x66, 0xd0, 0x2a, 0xda, 0xae, 0xbf, 0x31, 0x13, 0xdb, 0x2e, 0xee, 0xc3, 0x96, 0x62, 0xda,
|
||||
0x66, 0x30, 0x9e, 0xcc, 0x75, 0xd3, 0x1e, 0xb4, 0x8b, 0x96, 0x32, 0xb2, 0xcd, 0xe0, 0x88, 0x99,
|
||||
0xd9, 0x52, 0xcc, 0x48, 0xc0, 0xa7, 0xd0, 0xb9, 0xa0, 0x33, 0xd3, 0x1e, 0x5f, 0x58, 0xce, 0xe4,
|
||||
0x72, 0x00, 0x3c, 0x74, 0x90, 0x0d, 0x3d, 0x64, 0x0e, 0x87, 0xcc, 0x7e, 0xb6, 0xa4, 0xc1, 0x45,
|
||||
0x2c, 0xe1, 0x63, 0x68, 0x53, 0xdb, 0x90, 0xa1, 0x1d, 0x1e, 0xba, 0x91, 0x43, 0x80, 0x6d, 0x44,
|
||||
0x81, 0x2d, 0x2a, 0xbf, 0x0f, 0x9b, 0x50, 0xbf, 0xd2, 0xad, 0x90, 0xaa, 0xf7, 0xa0, 0x93, 0x42,
|
||||
0x0a, 0x0e, 0xa0, 0xb9, 0xa0, 0xbe, 0xaf, 0xcf, 0x28, 0x87, 0x53, 0x5b, 0x8b, 0x44, 0xb5, 0x0b,
|
||||
0xcb, 0x69, 0x9c, 0xa8, 0x2b, 0x71, 0x20, 0xc3, 0x82, 0xfa, 0x67, 0x20, 0xf9, 0xa3, 0x46, 0x02,
|
||||
0xd5, 0x4b, 0x7a, 0x23, 0x13, 0xb1, 0x4f, 0xec, 0xcb, 0x61, 0x39, 0x00, 0xdb, 0x9a, 0x9c, 0x83,
|
||||
0x1a, 0xc7, 0xc6, 0x87, 0x8d, 0x5d, 0xa8, 0x04, 0xd7, 0x3c, 0x74, 0x59, 0xab, 0x04, 0xd7, 0xea,
|
||||
0x1d, 0xe8, 0x66, 0x0f, 0xf6, 0x96, 0xc7, 0x6f, 0xe3, 0x09, 0xf2, 0x93, 0x61, 0x63, 0x89, 0xd3,
|
||||
0x13, 0x2e, 0x42, 0x50, 0x7b, 0xb0, 0x92, 0x39, 0x6e, 0xf5, 0x38, 0x1e, 0x3c, 0x3e, 0x1e, 0xfc,
|
||||
0x23, 0xc0, 0x95, 0x6e, 0x99, 0x86, 0x1e, 0x38, 0x9e, 0x3f, 0x50, 0xee, 0x54, 0xb7, 0x3b, 0x7b,
|
||||
0x44, 0xee, 0xea, 0xbb, 0xc8, 0xa0, 0xa5, 0x7c, 0xd4, 0x97, 0xb0, 0x7a, 0xeb, 0xa4, 0x10, 0xa1,
|
||||
0x36, 0xd7, 0xfd, 0xb9, 0x9c, 0x00, 0xff, 0xc6, 0xbb, 0xd0, 0x98, 0x53, 0xdd, 0xa0, 0x9e, 0xac,
|
||||
0xc1, 0x15, 0x99, 0xf6, 0x8c, 0x2b, 0x35, 0x69, 0x54, 0x77, 0xa0, 0x97, 0x3b, 0x3e, 0xdc, 0x60,
|
||||
0x91, 0xe6, 0x6c, 0x1e, 0xf0, 0x7c, 0x35, 0x4d, 0x4a, 0xea, 0xc7, 0x3a, 0xb4, 0x34, 0xea, 0xbb,
|
||||
0x8e, 0xed, 0x53, 0x7c, 0x02, 0x6d, 0x7a, 0x3d, 0xa1, 0xa2, 0x12, 0x95, 0x1c, 0x92, 0x84, 0xcf,
|
||||
0x49, 0x64, 0x67, 0x28, 0x8c, 0x9d, 0x71, 0x47, 0xb2, 0x48, 0x9e, 0x1a, 0x64, 0x50, 0x9a, 0x46,
|
||||
0xee, 0x47, 0x34, 0x52, 0xcd, 0x95, 0x91, 0xf0, 0xcd, 0xf1, 0xc8, 0x8e, 0xe4, 0x91, 0x5a, 0x61,
|
||||
0xe2, 0x0c, 0x91, 0xec, 0x67, 0x88, 0xa4, 0x5e, 0x38, 0xfd, 0x12, 0x26, 0xd9, 0xcf, 0x30, 0x49,
|
||||
0xa3, 0x30, 0xb4, 0x84, 0x4a, 0x1e, 0xa5, 0xa8, 0xa4, 0x99, 0xab, 0x20, 0x11, 0x58, 0xc0, 0x25,
|
||||
0x0f, 0x63, 0x2e, 0x69, 0xe5, 0xd8, 0x47, 0x86, 0xe4, 0xc9, 0xe4, 0x7e, 0x04, 0xc7, 0x76, 0xe1,
|
||||
0xa6, 0xe5, 0xd8, 0x64, 0x3f, 0xc3, 0x26, 0x50, 0xb8, 0x9c, 0x12, 0x3a, 0xf9, 0x4b, 0x96, 0x4e,
|
||||
0x04, 0x27, 0x6c, 0xe5, 0x62, 0x4b, 0xf9, 0xe4, 0x4f, 0x69, 0x3e, 0x59, 0xce, 0xb1, 0x98, 0xc4,
|
||||
0xc2, 0x27, 0x09, 0x65, 0x87, 0x55, 0x42, 0x0e, 0x69, 0xac, 0x16, 0xa9, 0xe7, 0x39, 0x9e, 0xe4,
|
||||
0x02, 0x21, 0xa8, 0xdb, 0xac, 0x62, 0x13, 0x7c, 0x7d, 0x82, 0x7c, 0x78, 0xd5, 0xa6, 0xd0, 0xa5,
|
||||
0xfe, 0x57, 0x49, 0x62, 0x19, 0x84, 0x58, 0xad, 0x19, 0x7a, 0xa0, 0xcb, 0x40, 0xfe, 0xcd, 0xf2,
|
||||
0x5d, 0x51, 0xcf, 0x67, 0x58, 0x12, 0x7c, 0x13, 0x89, 0xb8, 0x0b, 0xab, 0x96, 0xee, 0x07, 0x62,
|
||||
0x99, 0x63, 0x59, 0x56, 0x55, 0x5e, 0x56, 0x3d, 0x66, 0x10, 0xeb, 0xe3, 0x6a, 0xfc, 0x03, 0xac,
|
||||
0xa5, 0x7c, 0x75, 0xd7, 0x1d, 0xf3, 0xa2, 0xae, 0xf1, 0xa2, 0x26, 0xb1, 0xf7, 0x81, 0xeb, 0x9e,
|
||||
0xe9, 0xfe, 0x5c, 0xbd, 0x9b, 0xac, 0x3f, 0xc3, 0x84, 0x96, 0x33, 0x8b, 0x98, 0xd0, 0x72, 0x66,
|
||||
0xea, 0xbf, 0x12, 0xb7, 0x84, 0xf4, 0x7e, 0x03, 0xb5, 0x89, 0x63, 0x88, 0xd5, 0x77, 0xf7, 0x7a,
|
||||
0x72, 0xdf, 0x8f, 0x1c, 0x83, 0xbe, 0xb9, 0x71, 0xa9, 0xc6, 0x8d, 0xf1, 0x4a, 0x2b, 0x82, 0x55,
|
||||
0xf8, 0x4a, 0x65, 0xfe, 0x6a, 0x92, 0xff, 0x9f, 0x8c, 0x40, 0x32, 0xe8, 0xfd, 0x9c, 0xd9, 0xff,
|
||||
0x9e, 0x9c, 0x87, 0x20, 0xdb, 0xcf, 0x98, 0xfb, 0x1f, 0x8c, 0xe9, 0xd3, 0x45, 0xf4, 0x39, 0x93,
|
||||
0xaf, 0x25, 0xdb, 0x1e, 0x97, 0x8f, 0xda, 0x07, 0xbc, 0x5d, 0x17, 0xe2, 0x46, 0xcb, 0x22, 0x1e,
|
||||
0x7f, 0x07, 0x75, 0xc3, 0x9c, 0x4e, 0xfd, 0x41, 0xad, 0xe4, 0x4e, 0x10, 0x66, 0xf5, 0x7f, 0x15,
|
||||
0x68, 0x08, 0x46, 0xc7, 0x2d, 0xc6, 0x2e, 0xba, 0x69, 0x8f, 0x4d, 0x23, 0x42, 0x35, 0x97, 0x47,
|
||||
0x46, 0x8a, 0xd1, 0x2b, 0x69, 0x46, 0x67, 0x4b, 0x09, 0xcc, 0x05, 0x95, 0x80, 0xe4, 0xdf, 0xb8,
|
||||
0x09, 0x4d, 0x3b, 0x5c, 0x8c, 0x83, 0x6b, 0x9f, 0x23, 0xaf, 0xa6, 0x35, 0xec, 0x70, 0xf1, 0xe6,
|
||||
0xda, 0xc7, 0x3d, 0x58, 0x49, 0xc1, 0xd3, 0x34, 0x24, 0x6d, 0x76, 0xe5, 0xd4, 0xf8, 0xbc, 0x47,
|
||||
0xc7, 0x5a, 0x27, 0x06, 0xea, 0xc8, 0xc0, 0x6d, 0xe0, 0xb8, 0x1d, 0x0b, 0x6a, 0x12, 0x78, 0x6e,
|
||||
0xf0, 0x7d, 0xeb, 0x32, 0xbd, 0xe4, 0x2e, 0x76, 0x5d, 0xfd, 0x0a, 0xda, 0x6c, 0x27, 0x85, 0x4b,
|
||||
0x93, 0xbb, 0xb4, 0x98, 0x82, 0x1b, 0xef, 0x41, 0x2f, 0xb9, 0x02, 0x85, 0x4b, 0x4b, 0x64, 0x49,
|
||||
0xd4, 0xdc, 0x71, 0x0b, 0x5a, 0x71, 0xdd, 0xb4, 0xb9, 0x47, 0x53, 0x97, 0xe5, 0x32, 0x82, 0xa6,
|
||||
0x9c, 0x62, 0xe1, 0x75, 0xb9, 0x0b, 0x75, 0x57, 0xf7, 0x02, 0x5f, 0x5e, 0x4b, 0x11, 0x6b, 0x9e,
|
||||
0xeb, 0x1e, 0xeb, 0x33, 0xe4, 0xa5, 0x29, 0x5c, 0xd4, 0x7d, 0x58, 0xc9, 0xe8, 0x19, 0xeb, 0x04,
|
||||
0x4e, 0xa0, 0x5b, 0xf2, 0xc2, 0x14, 0x42, 0x3c, 0x4c, 0x25, 0x19, 0x46, 0xdd, 0x87, 0x76, 0x7c,
|
||||
0x86, 0xec, 0x58, 0xdc, 0xf0, 0xe2, 0x39, 0x8d, 0x3a, 0x07, 0x29, 0xb1, 0x74, 0xae, 0xf3, 0x41,
|
||||
0xde, 0xdc, 0x35, 0x4d, 0x08, 0xbb, 0x5f, 0x28, 0xd0, 0x79, 0x21, 0x68, 0x8a, 0xa1, 0x11, 0x7b,
|
||||
0xd0, 0x79, 0x19, 0x5a, 0x96, 0x54, 0x91, 0x25, 0x6c, 0x41, 0x8d, 0xb1, 0x1b, 0x51, 0xb0, 0x0d,
|
||||
0x75, 0xce, 0x5e, 0xa4, 0xc2, 0x94, 0x8c, 0xb6, 0x48, 0x15, 0x57, 0xa0, 0x1d, 0xf3, 0x04, 0xa9,
|
||||
0x31, 0x31, 0xa6, 0x4d, 0x52, 0x67, 0x62, 0x4c, 0x0f, 0x64, 0x15, 0x3b, 0xd0, 0x94, 0xd5, 0x4c,
|
||||
0x10, 0x01, 0x1a, 0xe2, 0xa4, 0xc8, 0x1a, 0x4b, 0xcd, 0x0b, 0x91, 0xf4, 0x59, 0x48, 0x0c, 0x6d,
|
||||
0xb2, 0x8e, 0x5d, 0x80, 0x04, 0xd4, 0x64, 0x03, 0x97, 0xa1, 0x15, 0xc1, 0x99, 0x6c, 0xee, 0xfe,
|
||||
0xbf, 0x0e, 0xad, 0xa8, 0x90, 0xb0, 0x01, 0x95, 0x57, 0xcf, 0xc9, 0x12, 0xae, 0xc2, 0xca, 0xc8,
|
||||
0x0e, 0xa8, 0x67, 0xeb, 0xd6, 0x09, 0x23, 0x6a, 0xa2, 0x30, 0xd5, 0x89, 0x3d, 0x71, 0x0c, 0xd3,
|
||||
0x9e, 0x09, 0x55, 0x85, 0x25, 0x3a, 0xd4, 0x8d, 0x97, 0x8e, 0x3d, 0xa1, 0xa4, 0x8a, 0x04, 0x96,
|
||||
0xdf, 0xda, 0x7a, 0x18, 0xcc, 0x1d, 0xcf, 0xfc, 0x0f, 0x35, 0x48, 0x0d, 0xd7, 0x61, 0x75, 0x64,
|
||||
0xfb, 0xe1, 0x74, 0x6a, 0x4e, 0x4c, 0x6a, 0x07, 0xcf, 0x42, 0xdb, 0xf0, 0x49, 0x1d, 0x11, 0xba,
|
||||
0x6f, 0xed, 0x4b, 0xdb, 0xf9, 0x60, 0xcb, 0x06, 0x87, 0x34, 0x70, 0x00, 0xfd, 0x43, 0xdd, 0xa7,
|
||||
0xc7, 0xa1, 0x6b, 0x99, 0x13, 0x3d, 0xa0, 0x07, 0x86, 0xe1, 0x51, 0xdf, 0x27, 0x94, 0x25, 0x61,
|
||||
0x96, 0xec, 0xd8, 0xd3, 0x28, 0x20, 0x93, 0x9f, 0x52, 0x9f, 0xcc, 0x70, 0x0b, 0xd6, 0x6f, 0x59,
|
||||
0xf8, 0xc8, 0x73, 0xfc, 0x35, 0x0c, 0xf2, 0xa6, 0x53, 0xdd, 0x3f, 0xf7, 0xcc, 0x09, 0x25, 0x26,
|
||||
0xf6, 0x81, 0x08, 0x2b, 0xc7, 0xee, 0xc8, 0x76, 0xc3, 0x80, 0xfc, 0x3b, 0x1a, 0x5f, 0x6a, 0x5f,
|
||||
0x85, 0x01, 0x53, 0x5f, 0xe6, 0xd4, 0xe7, 0x1c, 0x1f, 0xc4, 0xc2, 0x4d, 0x58, 0x4b, 0xa9, 0x5f,
|
||||
0xb3, 0xf5, 0xb1, 0xdd, 0x59, 0x24, 0xf3, 0x15, 0x06, 0x73, 0x66, 0xeb, 0x41, 0xe8, 0x51, 0x62,
|
||||
0xe3, 0x06, 0x20, 0xb3, 0xc8, 0x2d, 0x89, 0x16, 0xee, 0x44, 0x23, 0x48, 0xbd, 0x1c, 0xc1, 0xcd,
|
||||
0xab, 0xad, 0x70, 0x66, 0xda, 0xe4, 0x3d, 0xae, 0x03, 0x39, 0x75, 0xae, 0xa4, 0xf6, 0xc4, 0x0e,
|
||||
0xcc, 0xe0, 0x86, 0x7c, 0xa5, 0x60, 0x1f, 0x7a, 0x89, 0xfa, 0xd4, 0x73, 0x42, 0x97, 0x7c, 0xad,
|
||||
0xe0, 0x26, 0x60, 0xa2, 0x3d, 0xf7, 0x1c, 0xd7, 0xf1, 0x75, 0x8b, 0x7c, 0xa3, 0xe0, 0x06, 0xac,
|
||||
0x9e, 0x3a, 0x57, 0xf1, 0x29, 0x88, 0x80, 0x6f, 0xa3, 0x80, 0x58, 0xff, 0x82, 0x2e, 0x2e, 0xa8,
|
||||
0x47, 0xbe, 0x53, 0x70, 0x0b, 0xfa, 0x69, 0x43, 0x9c, 0xeb, 0x7b, 0x45, 0xce, 0x28, 0x36, 0xbd,
|
||||
0x73, 0x02, 0x4a, 0x7e, 0x88, 0xd4, 0x72, 0x1f, 0x64, 0xa2, 0x1f, 0x15, 0x5c, 0x83, 0x6e, 0xa2,
|
||||
0xe6, 0xbe, 0x3f, 0x29, 0x38, 0x84, 0xf5, 0x8c, 0xd2, 0xb4, 0x67, 0xe7, 0xac, 0xe4, 0xc8, 0xcf,
|
||||
0xca, 0xde, 0xc7, 0x3a, 0xf4, 0x0e, 0x0e, 0x8f, 0x46, 0x07, 0xae, 0x18, 0x80, 0x5d, 0xb2, 0x0f,
|
||||
0x45, 0xa1, 0x61, 0xc1, 0x0b, 0x78, 0x58, 0xd4, 0xcf, 0xe2, 0x9e, 0xac, 0x47, 0x2c, 0x7a, 0x08,
|
||||
0x0f, 0x0b, 0xdb, 0x5a, 0x36, 0x88, 0xe8, 0x37, 0x6e, 0xbf, 0x87, 0x87, 0x45, 0xbd, 0x2d, 0xfe,
|
||||
0x35, 0x55, 0xdf, 0x58, 0xf6, 0x2a, 0x1e, 0x96, 0x76, 0xb9, 0x2c, 0x3e, 0x69, 0x10, 0xca, 0xde,
|
||||
0xc6, 0xc3, 0xd2, 0x56, 0x17, 0x9f, 0xc4, 0x94, 0x81, 0xc5, 0x2f, 0xe4, 0x61, 0x49, 0xb7, 0xcb,
|
||||
0xb6, 0x47, 0x5c, 0xee, 0x45, 0x0f, 0xdf, 0x61, 0x61, 0x03, 0x8b, 0x8f, 0x23, 0x4e, 0xc2, 0xc2,
|
||||
0xc7, 0xf5, 0xb0, 0xb8, 0x4d, 0x66, 0x8b, 0x4c, 0x5e, 0x5f, 0x65, 0xaf, 0xe6, 0x61, 0x69, 0x03,
|
||||
0x8c, 0x07, 0x69, 0x92, 0xc3, 0xd2, 0xb7, 0xf3, 0xb0, 0xbc, 0x0d, 0xc6, 0xa7, 0x09, 0x2f, 0x62,
|
||||
0xc9, 0x0b, 0x7a, 0x58, 0xd6, 0x09, 0x5f, 0x34, 0xf8, 0x9f, 0x33, 0x8f, 0x7e, 0x09, 0x00, 0x00,
|
||||
0xff, 0xff, 0x84, 0x7d, 0xd1, 0x2f, 0xb1, 0x11, 0x00, 0x00,
|
||||
// 1697 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xac, 0x58, 0x4b, 0x6f, 0x1b, 0x47,
|
||||
0x12, 0xf6, 0xf0, 0xcd, 0xa6, 0x44, 0xb6, 0x5a, 0x92, 0x4d, 0x73, 0xf7, 0x60, 0xcc, 0xc2, 0x6b,
|
||||
0x49, 0xeb, 0xb5, 0x17, 0x32, 0x76, 0xb1, 0x5a, 0x2f, 0x02, 0x48, 0xb2, 0x6c, 0x13, 0x86, 0x6d,
|
||||
0x65, 0xfc, 0xb8, 0x24, 0x08, 0x31, 0xe2, 0x34, 0xc5, 0x89, 0xa8, 0x99, 0xf1, 0x3c, 0x64, 0x29,
|
||||
0xbf, 0x21, 0xf7, 0xfc, 0x84, 0xdc, 0x03, 0xe4, 0x94, 0x7b, 0x80, 0xbc, 0x1f, 0xbf, 0x28, 0x55,
|
||||
0xdd, 0x3d, 0x4f, 0xcd, 0x18, 0x39, 0xf8, 0x42, 0x4c, 0x3d, 0xbb, 0xab, 0xab, 0xea, 0xeb, 0x6a,
|
||||
0x92, 0x95, 0xf0, 0xc2, 0xe3, 0xc1, 0x5d, 0xf1, 0x7b, 0xc7, 0xf3, 0xdd, 0xd0, 0x65, 0x4d, 0x41,
|
||||
0xe8, 0xdf, 0x36, 0x48, 0xdb, 0xe0, 0x6f, 0x22, 0x1e, 0x84, 0x6c, 0x83, 0x34, 0xf8, 0x74, 0xee,
|
||||
0x0e, 0xb5, 0x1b, 0xda, 0x46, 0x6f, 0x9b, 0xdd, 0x91, 0xea, 0x4a, 0x7a, 0x00, 0x92, 0xc7, 0x57,
|
||||
0x0c, 0xa1, 0xc1, 0xfe, 0x41, 0x9a, 0xb3, 0x45, 0x14, 0xcc, 0x87, 0x35, 0xa1, 0xba, 0x9a, 0x57,
|
||||
0x7d, 0x88, 0x22, 0xd0, 0x95, 0x3a, 0xe8, 0xd6, 0x76, 0x66, 0xee, 0xb0, 0x5e, 0xe6, 0x76, 0x0c,
|
||||
0x12, 0x74, 0x8b, 0x1a, 0xec, 0xbf, 0x84, 0x04, 0x3c, 0x9c, 0xb8, 0x5e, 0x68, 0xbb, 0xce, 0xb0,
|
||||
0x21, 0xf4, 0xaf, 0xe5, 0xf5, 0x5f, 0xf0, 0xf0, 0xb9, 0x10, 0x83, 0x51, 0x37, 0x88, 0x09, 0xb4,
|
||||
0xb4, 0xf8, 0xc2, 0x3e, 0xe3, 0xfe, 0x24, 0x3c, 0x1f, 0x36, 0xcb, 0x2c, 0x1f, 0x48, 0xf9, 0xcb,
|
||||
0x73, 0xb4, 0xb4, 0x62, 0x82, 0x6d, 0x93, 0xce, 0x74, 0xce, 0xa7, 0x27, 0x68, 0xd7, 0x12, 0x76,
|
||||
0xeb, 0x79, 0xbb, 0x7d, 0x94, 0x0a, 0xab, 0xf6, 0x54, 0x7e, 0xb2, 0x3b, 0xa4, 0x35, 0x75, 0x4f,
|
||||
0x4f, 0xed, 0x70, 0xd8, 0x16, 0x16, 0x6b, 0x05, 0x0b, 0x21, 0x03, 0x03, 0xa5, 0x85, 0xc7, 0x05,
|
||||
0x02, 0xff, 0x62, 0xd8, 0x29, 0x3b, 0xae, 0x0f, 0x51, 0x84, 0xc7, 0x25, 0x74, 0x30, 0x14, 0xdb,
|
||||
0xb1, 0xc3, 0xc9, 0x74, 0x6e, 0xda, 0xce, 0xb0, 0x5b, 0x16, 0xca, 0x18, 0xe4, 0xfb, 0x28, 0xc6,
|
||||
0x50, 0xec, 0x98, 0x60, 0xf7, 0x49, 0xef, 0x88, 0x1f, 0xdb, 0xce, 0xe4, 0x68, 0xe1, 0x4e, 0x4f,
|
||||
0x86, 0x44, 0x98, 0x0e, 0xf3, 0xa6, 0x7b, 0xa8, 0xb0, 0x87, 0x72, 0xb0, 0x25, 0x47, 0x09, 0xc5,
|
||||
0xfe, 0x4d, 0xba, 0xdc, 0xb1, 0x94, 0x69, 0x4f, 0x98, 0x5e, 0x2d, 0x54, 0x80, 0x63, 0xc5, 0x86,
|
||||
0x1d, 0xae, 0xbe, 0xf7, 0xda, 0xa4, 0x79, 0x66, 0x2e, 0x22, 0xae, 0xdf, 0x22, 0xbd, 0x4c, 0xa5,
|
||||
0xb0, 0x21, 0x69, 0x9f, 0xf2, 0x20, 0x30, 0x8f, 0xb9, 0x28, 0xa7, 0xae, 0x11, 0x93, 0x7a, 0x9f,
|
||||
0x2c, 0x65, 0xeb, 0x44, 0x5f, 0x4e, 0x0c, 0xb1, 0x16, 0xf4, 0xff, 0x11, 0x5a, 0x4c, 0x35, 0xa3,
|
||||
0xa4, 0x7e, 0xc2, 0x2f, 0x94, 0x23, 0xfc, 0x64, 0x6b, 0x6a, 0x59, 0x51, 0x80, 0x5d, 0x43, 0xed,
|
||||
0x41, 0x4f, 0x6c, 0x93, 0x64, 0xb3, 0x3e, 0xa9, 0x41, 0x66, 0xd1, 0x74, 0xc9, 0x80, 0x2f, 0xfd,
|
||||
0x06, 0xe9, 0xe7, 0x13, 0x7b, 0x49, 0xc3, 0x4a, 0x36, 0x28, 0x32, 0xc3, 0x18, 0x69, 0x58, 0x66,
|
||||
0x68, 0x2a, 0x0d, 0xf1, 0x8d, 0x3c, 0xcf, 0x0c, 0xe7, 0x6a, 0x79, 0xf1, 0xcd, 0xae, 0x92, 0xd6,
|
||||
0x9c, 0xdb, 0xc7, 0xf3, 0x50, 0x54, 0x7a, 0xc3, 0x50, 0x14, 0xee, 0x15, 0x5a, 0xee, 0x8c, 0x8b,
|
||||
0x82, 0xee, 0x18, 0x92, 0xd0, 0x07, 0x64, 0x39, 0x57, 0x2e, 0xfa, 0x83, 0x64, 0xf3, 0x49, 0x7a,
|
||||
0xd9, 0xbf, 0x08, 0x81, 0xc8, 0x6c, 0x58, 0xd2, 0xf5, 0x03, 0xd8, 0x40, 0x1d, 0xb2, 0x42, 0x55,
|
||||
0x56, 0x5e, 0xc7, 0x02, 0x23, 0xa3, 0xa3, 0x3f, 0x23, 0x2b, 0x97, 0x32, 0x8d, 0xbb, 0x9d, 0x9b,
|
||||
0xd0, 0xad, 0x2a, 0x02, 0xfc, 0x66, 0x37, 0x71, 0xb7, 0xa6, 0xc5, 0x7d, 0xd5, 0xc3, 0xcb, 0xca,
|
||||
0xed, 0x63, 0xc1, 0x34, 0x94, 0x50, 0xdf, 0x24, 0x83, 0x42, 0xfa, 0x33, 0x71, 0x6a, 0xd9, 0x38,
|
||||
0xf5, 0xcf, 0x9b, 0xa4, 0x63, 0xf0, 0xc0, 0x73, 0x9d, 0x80, 0x43, 0x15, 0x77, 0xf9, 0xf9, 0x94,
|
||||
0xcb, 0x4e, 0xd6, 0x0a, 0x95, 0x28, 0x75, 0x0e, 0x62, 0x39, 0x56, 0x71, 0xa2, 0xcc, 0x36, 0x15,
|
||||
0x0a, 0x15, 0xa1, 0x45, 0x19, 0x65, 0x61, 0xe8, 0x76, 0x0c, 0x43, 0xf5, 0x42, 0x1b, 0x4a, 0xdd,
|
||||
0x02, 0x0e, 0x6d, 0x2a, 0x1c, 0x6a, 0x94, 0x3a, 0xce, 0x01, 0xd1, 0x4e, 0x0e, 0x88, 0x9a, 0xa5,
|
||||
0xdb, 0xaf, 0x40, 0xa2, 0x9d, 0x1c, 0x12, 0xb5, 0x4a, 0x4d, 0x2b, 0xa0, 0xe8, 0x5e, 0x06, 0x8a,
|
||||
0xda, 0x85, 0x0e, 0x94, 0x86, 0x25, 0x58, 0x74, 0x37, 0xc1, 0xa2, 0x4e, 0x01, 0xbd, 0x94, 0x49,
|
||||
0x11, 0x8c, 0x6e, 0xc7, 0x60, 0xd4, 0x2d, 0x3d, 0xb4, 0x02, 0x1a, 0xed, 0xe4, 0xd0, 0x88, 0x94,
|
||||
0x86, 0x53, 0x01, 0x47, 0xff, 0xcf, 0xc3, 0x91, 0xc4, 0x94, 0xeb, 0x05, 0xdb, 0x4a, 0x3c, 0xfa,
|
||||
0x4f, 0x16, 0x8f, 0x96, 0x0a, 0x28, 0xa8, 0x6a, 0xe1, 0x9d, 0x80, 0xb4, 0x89, 0x9d, 0x50, 0xa8,
|
||||
0x34, 0xec, 0x45, 0xee, 0xfb, 0xae, 0xaf, 0xb0, 0x44, 0x12, 0xfa, 0x06, 0x76, 0x7c, 0x5a, 0x5f,
|
||||
0xef, 0x00, 0x2f, 0xd1, 0xb5, 0x99, 0xea, 0xd2, 0xbf, 0xd0, 0x52, 0x5b, 0x2c, 0xa1, 0x1c, 0x5a,
|
||||
0x74, 0x15, 0x5a, 0x80, 0x3f, 0xc8, 0x70, 0x80, 0xb5, 0x24, 0x01, 0x23, 0x26, 0xd9, 0x16, 0x59,
|
||||
0x59, 0x98, 0x41, 0x28, 0xc3, 0x9c, 0xe4, 0xe0, 0x63, 0x80, 0x02, 0x19, 0x9f, 0xc4, 0x91, 0x7f,
|
||||
0x92, 0xd5, 0x8c, 0xae, 0xe9, 0x79, 0x13, 0xd1, 0xd4, 0x0d, 0xd1, 0xd4, 0x34, 0xd1, 0xde, 0xf5,
|
||||
0xbc, 0xc7, 0xc0, 0xd7, 0x6f, 0xa6, 0xf1, 0xe7, 0x90, 0x74, 0xe1, 0x1e, 0xc7, 0x48, 0x0a, 0x9f,
|
||||
0xfa, 0x27, 0xa9, 0x5a, 0x0a, 0x9a, 0x7f, 0x23, 0x8d, 0xa9, 0x6b, 0xc9, 0xe8, 0xfb, 0xdb, 0x03,
|
||||
0x75, 0xee, 0xfb, 0xc0, 0x7a, 0x09, 0x5f, 0x86, 0x10, 0x26, 0x91, 0xd6, 0x32, 0xb8, 0xa8, 0xfc,
|
||||
0xd7, 0x53, 0xff, 0x1f, 0x23, 0x80, 0xe4, 0xaa, 0xf7, 0x7d, 0x7a, 0xff, 0x4a, 0x4b, 0x13, 0x22,
|
||||
0xd1, 0xfa, 0x4f, 0x39, 0x87, 0x32, 0xb0, 0x1d, 0x8b, 0x9f, 0x0b, 0xef, 0x75, 0x43, 0x12, 0xf1,
|
||||
0x35, 0x53, 0x17, 0x2b, 0xe6, 0xaf, 0x19, 0x79, 0xc8, 0x92, 0x50, 0x80, 0xee, 0xce, 0x04, 0x30,
|
||||
0x2c, 0x19, 0x92, 0xc8, 0xc0, 0x62, 0x2b, 0x07, 0xff, 0x6a, 0xd3, 0xed, 0x74, 0xd3, 0x1f, 0xe1,
|
||||
0x15, 0x94, 0xed, 0xce, 0xf7, 0x79, 0x22, 0xab, 0x69, 0x3e, 0x93, 0xbe, 0xd4, 0xd7, 0x08, 0xbb,
|
||||
0xdc, 0x70, 0xf2, 0xaa, 0xcd, 0xb7, 0x12, 0xfb, 0x3b, 0x69, 0x5a, 0xf6, 0x6c, 0x16, 0x40, 0xc4,
|
||||
0xe5, 0x97, 0x8d, 0x14, 0xeb, 0x5f, 0xd6, 0x48, 0x4b, 0x5e, 0x15, 0xec, 0x3a, 0xc2, 0x16, 0xac,
|
||||
0x32, 0xb1, 0xad, 0xb8, 0x5d, 0x04, 0x3d, 0xb6, 0x32, 0x67, 0x52, 0xcb, 0x9d, 0x09, 0x84, 0x12,
|
||||
0xda, 0xa7, 0x5c, 0x55, 0xba, 0xf8, 0x66, 0xd7, 0x48, 0xdb, 0x89, 0x4e, 0x01, 0xfb, 0x02, 0x71,
|
||||
0xda, 0xa0, 0x0c, 0xe4, 0xcb, 0xf3, 0x00, 0x26, 0xb4, 0xe5, 0x4c, 0xdd, 0xc3, 0x22, 0x12, 0x8f,
|
||||
0xfb, 0x6a, 0x6b, 0x62, 0xdf, 0xe3, 0x07, 0x46, 0x2f, 0xe9, 0x00, 0x58, 0x78, 0x83, 0x88, 0x86,
|
||||
0x98, 0x48, 0xcc, 0x93, 0x8d, 0xd2, 0x12, 0xe7, 0xd6, 0x47, 0xbe, 0x02, 0x45, 0xbc, 0x07, 0xff,
|
||||
0x42, 0xba, 0x78, 0x92, 0x52, 0xa5, 0x2d, 0x54, 0x3a, 0xc8, 0x10, 0xc2, 0x5b, 0x64, 0x90, 0xde,
|
||||
0xad, 0x52, 0xa5, 0x23, 0xbd, 0xa4, 0x6c, 0xa1, 0x08, 0x67, 0x90, 0x34, 0x64, 0x57, 0x68, 0xb4,
|
||||
0x4d, 0xd5, 0x87, 0x63, 0xd2, 0x56, 0x5b, 0x2c, 0xbd, 0x87, 0xb7, 0xa0, 0x98, 0x4c, 0x3f, 0x0c,
|
||||
0xd4, 0x7d, 0x17, 0xc3, 0xf1, 0x21, 0xf0, 0xa0, 0x6d, 0xd5, 0x6d, 0x2c, 0x55, 0xf4, 0x1d, 0xb2,
|
||||
0x9c, 0xe3, 0x63, 0x25, 0x86, 0x6e, 0x68, 0x2e, 0xd4, 0x4d, 0x2c, 0x89, 0x64, 0x99, 0x5a, 0xba,
|
||||
0x0c, 0x98, 0x76, 0x93, 0x1c, 0x62, 0x5a, 0xbc, 0xe8, 0xe8, 0x89, 0x1a, 0xa9, 0x96, 0x0c, 0x45,
|
||||
0x89, 0xc2, 0x76, 0xdf, 0xaa, 0x91, 0x00, 0xdc, 0x09, 0x62, 0xeb, 0x1b, 0x8d, 0xf4, 0x9e, 0x4a,
|
||||
0xfc, 0xc3, 0x6a, 0x64, 0x03, 0xd2, 0x7b, 0x16, 0x2d, 0x16, 0x8a, 0x45, 0xaf, 0xb0, 0x0e, 0x69,
|
||||
0x20, 0x6c, 0x52, 0x8d, 0x75, 0x49, 0x53, 0xc0, 0x22, 0xad, 0x21, 0x13, 0xf1, 0x90, 0xd6, 0xd9,
|
||||
0x32, 0xe9, 0x26, 0x00, 0x44, 0x1b, 0x48, 0x26, 0x78, 0x4c, 0x9b, 0x48, 0x26, 0xb8, 0x43, 0x57,
|
||||
0x58, 0x8f, 0xb4, 0x15, 0x4c, 0x50, 0x88, 0x83, 0xb4, 0x64, 0xa6, 0xe8, 0x2a, 0xba, 0x16, 0x0d,
|
||||
0x4e, 0xd7, 0xd0, 0x24, 0x29, 0x6d, 0xba, 0x0e, 0xf3, 0x1b, 0x49, 0x8b, 0x9a, 0x5e, 0x65, 0x4b,
|
||||
0xa4, 0x13, 0x97, 0x33, 0xbd, 0xb6, 0xf5, 0x35, 0x4c, 0x25, 0x71, 0x23, 0xb1, 0x16, 0xa9, 0x3d,
|
||||
0x7f, 0x02, 0x3b, 0x5e, 0x21, 0xcb, 0x63, 0x27, 0xe4, 0xbe, 0x63, 0x2e, 0x0e, 0xf0, 0x06, 0x80,
|
||||
0xad, 0x03, 0xeb, 0xc0, 0x81, 0x3e, 0xb3, 0x9d, 0x63, 0xc9, 0xaa, 0xa1, 0xa3, 0x3d, 0xd3, 0x7a,
|
||||
0xe6, 0x3a, 0x53, 0x0e, 0x61, 0x50, 0xb2, 0xf4, 0xca, 0x31, 0xa3, 0x70, 0xee, 0xfa, 0xf6, 0x67,
|
||||
0xdc, 0x82, 0x48, 0xd6, 0xc9, 0xca, 0xd8, 0x09, 0xa2, 0xd9, 0xcc, 0x9e, 0xda, 0xdc, 0x09, 0x1f,
|
||||
0x46, 0x8e, 0x15, 0x40, 0x44, 0x8c, 0xf4, 0x5f, 0x39, 0x27, 0x8e, 0xfb, 0xd6, 0x51, 0x93, 0x13,
|
||||
0x6d, 0xc1, 0x0d, 0xb0, 0xb6, 0x67, 0x02, 0xc2, 0x46, 0xde, 0xc2, 0x9e, 0x9a, 0x21, 0xdf, 0xb5,
|
||||
0x2c, 0x1f, 0xce, 0x8f, 0x72, 0x74, 0x82, 0x92, 0xfc, 0xda, 0xb3, 0xd8, 0x20, 0xe7, 0x9f, 0xf3,
|
||||
0x80, 0x1e, 0x43, 0xa9, 0xad, 0x5f, 0x92, 0x88, 0x95, 0xe7, 0xec, 0xaf, 0x64, 0x58, 0x14, 0x3d,
|
||||
0x32, 0x83, 0x43, 0xdf, 0x86, 0x00, 0x6c, 0xc8, 0x2e, 0x95, 0x52, 0x51, 0xbb, 0x63, 0xc7, 0x8b,
|
||||
0x42, 0xfa, 0x69, 0xbc, 0xbe, 0xe2, 0x3e, 0x8f, 0x42, 0x64, 0x9f, 0x14, 0xd8, 0x87, 0xa2, 0x3e,
|
||||
0xe8, 0x02, 0x9a, 0x74, 0x35, 0xc3, 0x7e, 0x81, 0xf1, 0xe1, 0xe9, 0x9c, 0xa6, 0xfb, 0x95, 0x02,
|
||||
0xfb, 0xd8, 0x31, 0xc3, 0xc8, 0xe7, 0xd4, 0x81, 0x62, 0x63, 0x28, 0x51, 0x47, 0x12, 0x07, 0xee,
|
||||
0xc6, 0x2b, 0x28, 0xbe, 0x5a, 0xc1, 0x2b, 0xb2, 0x17, 0x11, 0x64, 0x96, 0xbe, 0x01, 0x36, 0x7d,
|
||||
0xe4, 0x9e, 0x29, 0xee, 0x81, 0x13, 0xda, 0xe1, 0x05, 0xfd, 0x4e, 0x83, 0x98, 0x06, 0x29, 0xfb,
|
||||
0x91, 0xef, 0x46, 0x1e, 0xfd, 0x5e, 0x83, 0x5d, 0xb2, 0x94, 0x7b, 0xe8, 0xbb, 0x9e, 0x1b, 0x98,
|
||||
0x0b, 0xfa, 0x83, 0x06, 0x7b, 0x59, 0x01, 0x41, 0x92, 0x05, 0x69, 0xf0, 0x63, 0x6c, 0x90, 0xf0,
|
||||
0x9f, 0xf2, 0xd3, 0x23, 0xee, 0xd3, 0x9f, 0x34, 0x38, 0xec, 0xb5, 0xac, 0x20, 0xf1, 0xf5, 0xb3,
|
||||
0xa6, 0x76, 0x94, 0x88, 0x5e, 0xbb, 0x21, 0xa7, 0xbf, 0xc4, 0x6c, 0x75, 0x0e, 0xca, 0xd1, 0xaf,
|
||||
0x1a, 0x5b, 0x25, 0xfd, 0x94, 0x2d, 0x74, 0x7f, 0xd3, 0xd8, 0x88, 0xac, 0xe7, 0x98, 0x90, 0xff,
|
||||
0x43, 0x6c, 0x39, 0xfa, 0xbb, 0xb6, 0x0d, 0xd3, 0xf4, 0x60, 0x77, 0x6f, 0x7f, 0x0c, 0xd7, 0xb9,
|
||||
0x58, 0x00, 0x6f, 0xef, 0xbb, 0xb2, 0xd1, 0x58, 0xc9, 0xd3, 0x7c, 0x54, 0x36, 0x28, 0x03, 0x74,
|
||||
0xca, 0x7e, 0x64, 0x65, 0x2f, 0xf4, 0x51, 0xe9, 0xbc, 0x8c, 0x8b, 0xc8, 0x41, 0xe6, 0xf2, 0x43,
|
||||
0x7d, 0x54, 0x36, 0x34, 0xb3, 0x0f, 0x32, 0xfd, 0xcd, 0xaa, 0x9e, 0xeb, 0xa3, 0xca, 0xf1, 0x19,
|
||||
0xed, 0xd3, 0xc9, 0xa3, 0xea, 0xd1, 0x3e, 0xaa, 0x9c, 0xa1, 0xe1, 0xa9, 0x11, 0x43, 0x06, 0x2b,
|
||||
0x7f, 0xba, 0x8f, 0x2a, 0xc6, 0x68, 0x3c, 0x1e, 0x39, 0x34, 0x94, 0xbd, 0xc8, 0x47, 0xa5, 0x93,
|
||||
0x31, 0xbc, 0x93, 0x15, 0x26, 0xb1, 0xd2, 0x57, 0xff, 0xa8, 0x7c, 0xfe, 0xc6, 0x20, 0xd3, 0x67,
|
||||
0x5d, 0xd5, 0x73, 0x7e, 0x54, 0x39, 0x59, 0xb3, 0xdd, 0x2c, 0xc8, 0xb1, 0xca, 0x47, 0xfd, 0xa8,
|
||||
0x7a, 0xbe, 0x66, 0xf7, 0x53, 0x5c, 0x64, 0x15, 0x4f, 0xfb, 0x51, 0xd5, 0x88, 0x7d, 0xd4, 0x12,
|
||||
0xff, 0x1a, 0xdd, 0xfb, 0x23, 0x00, 0x00, 0xff, 0xff, 0x73, 0x34, 0x90, 0x2d, 0x4a, 0x12, 0x00,
|
||||
0x00,
|
||||
}
|
||||
|
@ -6,67 +6,67 @@ package types;
|
||||
//----------------------------------------
|
||||
// Message types
|
||||
|
||||
// Not being used
|
||||
// Not being used
|
||||
// Could be added to request/response
|
||||
// so we don't have to type switch
|
||||
// (would be twice as fast, but we're talking about 15ns)
|
||||
enum MessageType {
|
||||
NullMessage = 0x00;
|
||||
NullMessage = 0x00;
|
||||
|
||||
Echo = 0x01;
|
||||
Flush = 0x02;
|
||||
Info = 0x03;
|
||||
SetOption = 0x04;
|
||||
Exception = 0x05;
|
||||
DeliverTx = 0x11;
|
||||
CheckTx = 0x12;
|
||||
Commit = 0x13;
|
||||
Query = 0x14;
|
||||
InitChain = 0x15;
|
||||
BeginBlock = 0x16;
|
||||
EndBlock = 0x17;
|
||||
Echo = 0x01;
|
||||
Flush = 0x02;
|
||||
Info = 0x03;
|
||||
SetOption = 0x04;
|
||||
Exception = 0x05;
|
||||
DeliverTx = 0x11;
|
||||
CheckTx = 0x12;
|
||||
Commit = 0x13;
|
||||
Query = 0x14;
|
||||
InitChain = 0x15;
|
||||
BeginBlock = 0x16;
|
||||
EndBlock = 0x17;
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
// Code types
|
||||
|
||||
enum CodeType {
|
||||
OK = 0;
|
||||
OK = 0;
|
||||
|
||||
// General response codes, 0 ~ 99
|
||||
InternalError = 1;
|
||||
EncodingError = 2;
|
||||
BadNonce = 3;
|
||||
Unauthorized = 4;
|
||||
InsufficientFunds = 5;
|
||||
UnknownRequest = 6;
|
||||
// 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 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;
|
||||
// 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;
|
||||
|
||||
}
|
||||
|
||||
@ -105,15 +105,18 @@ message RequestSetOption{
|
||||
}
|
||||
|
||||
message RequestDeliverTx{
|
||||
bytes tx = 1;
|
||||
bytes tx = 1;
|
||||
}
|
||||
|
||||
message RequestCheckTx{
|
||||
bytes tx = 1;
|
||||
bytes tx = 1;
|
||||
}
|
||||
|
||||
message RequestQuery{
|
||||
bytes query = 1;
|
||||
bytes data = 1;
|
||||
string path = 2;
|
||||
uint64 height = 3;
|
||||
bool prove = 4;
|
||||
}
|
||||
|
||||
message RequestCommit{
|
||||
@ -189,8 +192,12 @@ message ResponseCheckTx{
|
||||
|
||||
message ResponseQuery{
|
||||
CodeType code = 1;
|
||||
bytes data = 2;
|
||||
string log = 3;
|
||||
int64 index = 2;
|
||||
bytes key = 3;
|
||||
bytes value = 4;
|
||||
bytes proof = 5;
|
||||
uint64 height = 6;
|
||||
string log = 7;
|
||||
}
|
||||
|
||||
message ResponseCommit{
|
||||
@ -207,7 +214,7 @@ message ResponseBeginBlock{
|
||||
}
|
||||
|
||||
message ResponseEndBlock{
|
||||
repeated Validator diffs = 4;
|
||||
repeated Validator diffs = 1;
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
@ -222,7 +229,7 @@ message Header {
|
||||
bytes last_commit_hash = 6;
|
||||
bytes data_hash = 7;
|
||||
bytes validators_hash = 8;
|
||||
bytes app_hash = 9;
|
||||
bytes app_hash = 9;
|
||||
}
|
||||
|
||||
message BlockID {
|
||||
@ -236,8 +243,8 @@ message PartSetHeader {
|
||||
}
|
||||
|
||||
message Validator {
|
||||
bytes pubKey = 1;
|
||||
uint64 power = 2;
|
||||
bytes pubKey = 1;
|
||||
uint64 power = 2;
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
|
9
version/version.go
Normal file
9
version/version.go
Normal file
@ -0,0 +1,9 @@
|
||||
package version
|
||||
|
||||
// NOTE: we should probably be versioning the ABCI and the abci-cli separately
|
||||
|
||||
const Maj = "0"
|
||||
const Min = "4"
|
||||
const Fix = "0"
|
||||
|
||||
const Version = "0.4.0" // new Query args and response (with proof!)
|
Loading…
x
Reference in New Issue
Block a user