Merge pull request #3807 from tendermint/release/v0.32.1

Release/v0.32.1
This commit is contained in:
Ethan Buchman 2019-07-15 12:25:35 -04:00 committed by GitHub
commit dbf4062acd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
89 changed files with 1730 additions and 1369 deletions

View File

@ -331,6 +331,34 @@ jobs:
docker push "tendermint/tendermint" docker push "tendermint/tendermint"
docker logout docker logout
reproducible_builds:
<<: *defaults
steps:
- attach_workspace:
at: /tmp/workspace
- checkout
- setup_remote_docker:
docker_layer_caching: true
- run:
name: Build tendermint
no_output_timeout: 20m
command: |
sudo apt-get install -y ruby
bash -x ./scripts/gitian-build.sh all
for os in darwin linux windows; do
cp gitian-build-${os}/result/tendermint-${os}-res.yml .
cp gitian-build-${os}/build/out/tendermint-*.tar.gz .
rm -rf gitian-build-${os}/
done
- store_artifacts:
path: /go/src/github.com/tendermint/tendermint/tendermint-darwin-res.yml
- store_artifacts:
path: /go/src/github.com/tendermint/tendermint/tendermint-linux-res.yml
- store_artifacts:
path: /go/src/github.com/tendermint/tendermint/tendermint-windows-res.yml
- store_artifacts:
path: /go/src/github.com/tendermint/tendermint/tendermint-*.tar.gz
workflows: workflows:
version: 2 version: 2
test-suite: test-suite:
@ -340,7 +368,6 @@ workflows:
branches: branches:
only: only:
- master - master
- develop
- setup_dependencies - setup_dependencies
- test_abci_apps: - test_abci_apps:
requires: requires:
@ -364,6 +391,12 @@ workflows:
- upload_coverage: - upload_coverage:
requires: requires:
- test_cover - test_cover
- reproducible_builds:
filters:
branches:
only:
- master
- /v[0-9]+\.[0-9]+/
release: release:
jobs: jobs:
- prepare_build - prepare_build

View File

@ -1,5 +1,49 @@
# Changelog # Changelog
## v0.32.1
*July 15, 2019*
Special thanks to external contributors on this release:
@ParthDesai, @climber73, @jim380, @ashleyvega
This release contains a minor enhancement to the ABCI and some breaking changes to our libs folder, namely:
- CheckTx requests include a `CheckTxType` enum that can be set to `Recheck` to indicate to the application that this transaction was already checked/validated and certain expensive operations (like checking signatures) can be skipped
- Removed various functions from `libs` pkgs
Friendly reminder, we have a [bug bounty
program](https://hackerone.com/tendermint).
### BREAKING CHANGES:
- Go API
- [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127) The CheckTx and DeliverTx methods in the ABCI `Application` interface now take structs as arguments (RequestCheckTx and RequestDeliverTx, respectively), instead of just the raw tx bytes. This allows more information to be passed to these methods, for instance, indicating whether a tx has already been checked.
- [libs] Remove unused `db/debugDB` and `common/colors.go` & `errors/errors.go` files (@marbar3778)
- [libs] [\#2432](https://github.com/tendermint/tendermint/issues/2432) Remove unused `common/heap.go` file (@marbar3778)
- [libs] Remove unused `date.go`, `io.go`. Remove `GoPath()`, `Prompt()` and `IsDirEmpty()` functions from `os.go` (@marbar3778)
- [libs] Remove unused `FailRand()` func and minor clean up to `fail.go`(@marbar3778)
### FEATURES:
- [node] Add variadic argument to `NewNode` to support functional options, allowing the Node to be more easily customized.
- [node][\#3730](https://github.com/tendermint/tendermint/pull/3730) Add `CustomReactors` option to `NewNode` allowing caller to pass
custom reactors to run inside Tendermint node (@ParthDesai)
- [abci] [\#2127](https://github.com/tendermint/tendermint/issues/2127)RequestCheckTx has a new field, `CheckTxType`, which can take values of `CheckTxType_New` and `CheckTxType_Recheck`, indicating whether this is a new tx being checked for the first time or whether this tx is being rechecked after a block commit. This allows applications to skip certain expensive operations, like signature checking, if they've already been done once. see [docs](https://github.com/tendermint/tendermint/blob/eddb433d7c082efbeaf8974413a36641519ee895/docs/spec/abci/apps.md#mempool-connection)
### IMPROVEMENTS:
- [rpc] [\#3700](https://github.com/tendermint/tendermint/issues/3700) Make possible to set absolute paths for TLS cert and key (@climber73)
- [abci] [\#3513](https://github.com/tendermint/tendermint/issues/3513) Call the reqRes callback after the resCb so they always happen in the same order
### BUG FIXES:
- [p2p] [\#3338](https://github.com/tendermint/tendermint/issues/3338) Prevent "sent next PEX request too soon" errors by not calling
ensurePeers outside of ensurePeersRoutine
- [behaviour] [\3772](https://github.com/tendermint/tendermint/pull/3772) Return correct reason in MessageOutOfOrder (@jim380)
- [config] [\#3723](https://github.com/tendermint/tendermint/issues/3723) Add consensus_params to testnet config generation; document time_iota_ms (@ashleyvega)
## v0.32.0 ## v0.32.0
*June 25, 2019* *June 25, 2019*
@ -21,29 +65,29 @@ program](https://hackerone.com/tendermint).
### BREAKING CHANGES: ### BREAKING CHANGES:
* CLI/RPC/Config * CLI/RPC/Config
- [cli] \#3613 Switch from golang/dep to Go Modules to resolve dependencies: - [cli] [\#3613](https://github.com/tendermint/tendermint/issues/3613) Switch from golang/dep to Go Modules to resolve dependencies:
It is recommended to switch to Go Modules if your project has tendermint as It is recommended to switch to Go Modules if your project has tendermint as
a dependency. Read more on Modules here: a dependency. Read more on Modules here:
https://github.com/golang/go/wiki/Modules https://github.com/golang/go/wiki/Modules
- [config] [\#3632](https://github.com/tendermint/tendermint/pull/3632) Removed `leveldb` as generic - [config] [\#3632](https://github.com/tendermint/tendermint/pull/3632) Removed `leveldb` as generic
option for `db_backend`. Must be `goleveldb` or `cleveldb`. option for `db_backend`. Must be `goleveldb` or `cleveldb`.
- [rpc] \#3616 Fix field names for `/block_results` response (eg. `results.DeliverTx` - [rpc] [\#3616](https://github.com/tendermint/tendermint/issues/3616) Fix field names for `/block_results` response (eg. `results.DeliverTx`
-> `results.deliver_tx`). See docs for details. -> `results.deliver_tx`). See docs for details.
- [rpc] \#3724 RPC now binds to `127.0.0.1` by default instead of `0.0.0.0` - [rpc] [\#3724](https://github.com/tendermint/tendermint/issues/3724) RPC now binds to `127.0.0.1` by default instead of `0.0.0.0`
* Apps * Apps
- [abci] \#1859 `ResponseCheckTx`, `ResponseDeliverTx`, `ResponseBeginBlock`, - [abci] [\#1859](https://github.com/tendermint/tendermint/issues/1859) `ResponseCheckTx`, `ResponseDeliverTx`, `ResponseBeginBlock`,
and `ResponseEndBlock` now include `Events` instead of `Tags`. Each `Event` and `ResponseEndBlock` now include `Events` instead of `Tags`. Each `Event`
contains a `type` and a list of `attributes` (list of key-value pairs) contains a `type` and a list of `attributes` (list of key-value pairs)
allowing for inclusion of multiple distinct events in each response. allowing for inclusion of multiple distinct events in each response.
* Go API * Go API
- [abci] \#3193 Use RequestDeliverTx and RequestCheckTx in the ABCI - [abci] [\#3193](https://github.com/tendermint/tendermint/issues/3193) Use RequestDeliverTx and RequestCheckTx in the ABCI
Application interface Application interface
- [libs/db] [\#3632](https://github.com/tendermint/tendermint/pull/3632) Removed deprecated `LevelDBBackend` const - [libs/db] [\#3632](https://github.com/tendermint/tendermint/pull/3632) Removed deprecated `LevelDBBackend` const
If you have `db_backend` set to `leveldb` in your config file, please If you have `db_backend` set to `leveldb` in your config file, please
change it to `goleveldb` or `cleveldb`. change it to `goleveldb` or `cleveldb`.
- [p2p] \#3521 Remove NewNetAddressStringWithOptionalID - [p2p] [\#3521](https://github.com/tendermint/tendermint/issues/3521) Remove NewNetAddressStringWithOptionalID
* Blockchain Protocol * Blockchain Protocol
@ -52,16 +96,16 @@ program](https://hackerone.com/tendermint).
### FEATURES: ### FEATURES:
### IMPROVEMENTS: ### IMPROVEMENTS:
- [abci/examples] \#3659 Change validator update tx format in the `persistent_kvstore` to use base64 for pubkeys instead of hex (@needkane) - [abci/examples] [\#3659](https://github.com/tendermint/tendermint/issues/3659) Change validator update tx format in the `persistent_kvstore` to use base64 for pubkeys instead of hex (@needkane)
- [consensus] \#3656 Exit if SwitchToConsensus fails - [consensus] [\#3656](https://github.com/tendermint/tendermint/issues/3656) Exit if SwitchToConsensus fails
- [p2p] \#3666 Add per channel telemetry to improve reactor observability - [p2p] [\#3666](https://github.com/tendermint/tendermint/issues/3666) Add per channel telemetry to improve reactor observability
- [rpc] [\#3686](https://github.com/tendermint/tendermint/pull/3686) `HTTPClient#Call` returns wrapped errors, so a caller could use `errors.Cause` to retrieve an error code. (@wooparadog) - [rpc] [\#3686](https://github.com/tendermint/tendermint/pull/3686) `HTTPClient#Call` returns wrapped errors, so a caller could use `errors.Cause` to retrieve an error code. (@wooparadog)
### BUG FIXES: ### BUG FIXES:
- [libs/db] \#3717 Fixed the BoltDB backend's Batch.Delete implementation (@Yawning) - [libs/db] [\#3717](https://github.com/tendermint/tendermint/issues/3717) Fixed the BoltDB backend's Batch.Delete implementation (@Yawning)
- [libs/db] \#3718 Fixed the BoltDB backend's Get and Iterator implementation (@Yawning) - [libs/db] [\#3718](https://github.com/tendermint/tendermint/issues/3718) Fixed the BoltDB backend's Get and Iterator implementation (@Yawning)
- [node] \#3716 Fix a bug where `nil` is recorded as node's address - [node] [\#3716](https://github.com/tendermint/tendermint/issues/3716) Fix a bug where `nil` is recorded as node's address
- [node] \#3741 Fix profiler blocking the entire node - [node] [\#3741](https://github.com/tendermint/tendermint/issues/3741) Fix profiler blocking the entire node
## v0.31.7 ## v0.31.7
@ -72,11 +116,11 @@ The regression caused the invalid committed txs to be proposed in blocks over an
over again. over again.
### BUG FIXES: ### BUG FIXES:
- [mempool] \#3699 Remove all committed txs from the mempool. - [mempool] [\#3699](https://github.com/tendermint/tendermint/issues/3699) Remove all committed txs from the mempool.
This reverts the change from v0.31.6 where we only remove valid txs from the mempool. This reverts the change from v0.31.6 where we only remove valid txs from the mempool.
Note this means malicious proposals can cause txs to be dropped from the Note this means malicious proposals can cause txs to be dropped from the
mempools of other nodes by including them in blocks before they are valid. mempools of other nodes by including them in blocks before they are valid.
See \#3322. See [\#3322](https://github.com/tendermint/tendermint/issues/3322).
## v0.31.6 ## v0.31.6

View File

@ -1,6 +1,6 @@
## v0.32.1 ## v0.32.2
** \*\*
Special thanks to external contributors on this release: Special thanks to external contributors on this release:
@ -9,15 +9,11 @@ program](https://hackerone.com/tendermint).
### BREAKING CHANGES: ### BREAKING CHANGES:
* CLI/RPC/Config - CLI/RPC/Config
* Apps - Apps
* Go API - Go API
* Blockchain Protocol
* P2P Protocol
### FEATURES: ### FEATURES:

View File

@ -13,7 +13,9 @@ to write a more detailed design document in the form of an
Architectural Decision Record (ie. see [here](./docs/architecture/)) before submitting code Architectural Decision Record (ie. see [here](./docs/architecture/)) before submitting code
changes. changes.
Please make sure to use `gofmt` before every commit - the easiest way to do this is have your editor run it for you upon saving a file. Please open a [Draft PR](https://github.blog/2019-02-14-introducing-draft-pull-requests/), even if your contribution is incomplete, this inidicates to the community you're working on something and allows them to provide comments early in the development process. When the code is complete it can be marked as ready-for-review.
Please make sure to use `gofmt` before every commit - the easiest way to do this is have your editor run it for you upon saving a file. Additionally please ensure that your code is lint compliant by running `make lint`
## Forking ## Forking
@ -39,8 +41,6 @@ To pull in updates from the origin repo, run
* `git fetch upstream` * `git fetch upstream`
* `git rebase upstream/master` (or whatever branch you want) * `git rebase upstream/master` (or whatever branch you want)
Please don't make Pull Requests to `master`.
## Dependencies ## Dependencies
We use [go modules](https://github.com/golang/go/wiki/Modules) to manage dependencies. We use [go modules](https://github.com/golang/go/wiki/Modules) to manage dependencies.

View File

@ -1,34 +0,0 @@
FROM alpine:3.7
ENV DATA_ROOT /tendermint
ENV TMHOME $DATA_ROOT
RUN addgroup tmuser && \
adduser -S -G tmuser tmuser
RUN mkdir -p $DATA_ROOT && \
chown -R tmuser:tmuser $DATA_ROOT
RUN apk add --no-cache bash curl jq
ENV GOPATH /go
ENV PATH "$PATH:/go/bin"
RUN mkdir -p /go/src/github.com/tendermint/tendermint && \
apk add --no-cache go build-base git && \
cd /go/src/github.com/tendermint/tendermint && \
git clone https://github.com/tendermint/tendermint . && \
git checkout develop && \
make get_tools && \
make install && \
cd - && \
rm -rf /go/src/github.com/tendermint/tendermint && \
apk del go build-base git
VOLUME $DATA_ROOT
EXPOSE 26656
EXPOSE 26657
ENTRYPOINT ["tendermint"]
CMD ["node", "--moniker=`hostname`", "--proxy_app=kvstore"]

View File

@ -12,28 +12,25 @@
- `0.9.1`, `0.9`, [(Dockerfile)](https://github.com/tendermint/tendermint/blob/809e0e8c5933604ba8b2d096803ada7c5ec4dfd3/DOCKER/Dockerfile) - `0.9.1`, `0.9`, [(Dockerfile)](https://github.com/tendermint/tendermint/blob/809e0e8c5933604ba8b2d096803ada7c5ec4dfd3/DOCKER/Dockerfile)
- `0.9.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/d474baeeea6c22b289e7402449572f7c89ee21da/DOCKER/Dockerfile) - `0.9.0` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/d474baeeea6c22b289e7402449572f7c89ee21da/DOCKER/Dockerfile)
- `0.8.0`, `0.8` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/bf64dd21fdb193e54d8addaaaa2ecf7ac371de8c/DOCKER/Dockerfile) - `0.8.0`, `0.8` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/bf64dd21fdb193e54d8addaaaa2ecf7ac371de8c/DOCKER/Dockerfile)
- `develop` [(Dockerfile)](https://github.com/tendermint/tendermint/blob/master/DOCKER/Dockerfile.develop)
`develop` tag points to the [develop](https://github.com/tendermint/tendermint/tree/develop) branch.
## Quick reference ## Quick reference
* **Where to get help:** - **Where to get help:**
https://cosmos.network/community [cosmos.network/ecosystem](https://cosmos.network/ecosystem)
* **Where to file issues:** - **Where to file issues:**
https://github.com/tendermint/tendermint/issues [Tendermint Issues](https://github.com/tendermint/tendermint/issues)
* **Supported Docker versions:** - **Supported Docker versions:**
[the latest release](https://github.com/moby/moby/releases) (down to 1.6 on a best-effort basis) [the latest release](https://github.com/moby/moby/releases) (down to 1.6 on a best-effort basis)
## Tendermint ## Tendermint
Tendermint Core is Byzantine Fault Tolerant (BFT) middleware that takes a state transition machine, written in any programming language, and securely replicates it on many machines. Tendermint Core is Byzantine Fault Tolerant (BFT) middleware that takes a state transition machine, written in any programming language, and securely replicates it on many machines.
For more background, see the [introduction](https://tendermint.readthedocs.io/en/master/introduction.html). For more background, see the [the docs](https://tendermint.com/docs/introduction/#quick-start).
To get started developing applications, see the [application developers guide](https://tendermint.readthedocs.io/en/master/getting-started.html). To get started developing applications, see the [application developers guide](https://tendermint.com/docs/introduction/quick-start.html).
## How to use this image ## How to use this image
@ -48,7 +45,7 @@ docker run -it --rm -v "/tmp:/tendermint" tendermint/tendermint node --proxy_app
## Local cluster ## Local cluster
To run a 4-node network, see the `Makefile` in the root of [the repo](https://github.com/tendermint/tendermint/master/Makefile) and run: To run a 4-node network, see the `Makefile` in the root of [the repo](https://github.com/tendermint/tendermint/blob/master/Makefile) and run:
``` ```
make build-linux make build-linux
@ -60,7 +57,7 @@ Note that this will build and use a different image than the ones provided here.
## License ## License
- Tendermint's license is [Apache 2.0](https://github.com/tendermint/tendermint/master/LICENSE). - Tendermint's license is [Apache 2.0](https://github.com/tendermint/tendermint/blob/master/LICENSE).
## Contributing ## Contributing

View File

@ -1,4 +1,5 @@
# Tendermint # Tendermint
![banner](docs/tendermint-core-image.jpg)
[Byzantine-Fault Tolerant](https://en.wikipedia.org/wiki/Byzantine_fault_tolerance) [Byzantine-Fault Tolerant](https://en.wikipedia.org/wiki/Byzantine_fault_tolerance)
[State Machines](https://en.wikipedia.org/wiki/State_machine_replication). [State Machines](https://en.wikipedia.org/wiki/State_machine_replication).

View File

@ -28,8 +28,8 @@ type Client interface {
EchoAsync(msg string) *ReqRes EchoAsync(msg string) *ReqRes
InfoAsync(types.RequestInfo) *ReqRes InfoAsync(types.RequestInfo) *ReqRes
SetOptionAsync(types.RequestSetOption) *ReqRes SetOptionAsync(types.RequestSetOption) *ReqRes
DeliverTxAsync(tx []byte) *ReqRes DeliverTxAsync(types.RequestDeliverTx) *ReqRes
CheckTxAsync(tx []byte) *ReqRes CheckTxAsync(types.RequestCheckTx) *ReqRes
QueryAsync(types.RequestQuery) *ReqRes QueryAsync(types.RequestQuery) *ReqRes
CommitAsync() *ReqRes CommitAsync() *ReqRes
InitChainAsync(types.RequestInitChain) *ReqRes InitChainAsync(types.RequestInitChain) *ReqRes
@ -40,8 +40,8 @@ type Client interface {
EchoSync(msg string) (*types.ResponseEcho, error) EchoSync(msg string) (*types.ResponseEcho, error)
InfoSync(types.RequestInfo) (*types.ResponseInfo, error) InfoSync(types.RequestInfo) (*types.ResponseInfo, error)
SetOptionSync(types.RequestSetOption) (*types.ResponseSetOption, error) SetOptionSync(types.RequestSetOption) (*types.ResponseSetOption, error)
DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) DeliverTxSync(types.RequestDeliverTx) (*types.ResponseDeliverTx, error)
CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) CheckTxSync(types.RequestCheckTx) (*types.ResponseCheckTx, error)
QuerySync(types.RequestQuery) (*types.ResponseQuery, error) QuerySync(types.RequestQuery) (*types.ResponseQuery, error)
CommitSync() (*types.ResponseCommit, error) CommitSync() (*types.ResponseCommit, error)
InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error)

View File

@ -159,8 +159,8 @@ func (cli *grpcClient) SetOptionAsync(params types.RequestSetOption) *ReqRes {
return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_SetOption{SetOption: res}}) return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_SetOption{SetOption: res}})
} }
func (cli *grpcClient) DeliverTxAsync(tx []byte) *ReqRes { func (cli *grpcClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes {
req := types.ToRequestDeliverTx(tx) req := types.ToRequestDeliverTx(params)
res, err := cli.client.DeliverTx(context.Background(), req.GetDeliverTx(), grpc.FailFast(true)) res, err := cli.client.DeliverTx(context.Background(), req.GetDeliverTx(), grpc.FailFast(true))
if err != nil { if err != nil {
cli.StopForError(err) cli.StopForError(err)
@ -168,8 +168,8 @@ func (cli *grpcClient) DeliverTxAsync(tx []byte) *ReqRes {
return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_DeliverTx{DeliverTx: res}}) return cli.finishAsyncCall(req, &types.Response{Value: &types.Response_DeliverTx{DeliverTx: res}})
} }
func (cli *grpcClient) CheckTxAsync(tx []byte) *ReqRes { func (cli *grpcClient) CheckTxAsync(params types.RequestCheckTx) *ReqRes {
req := types.ToRequestCheckTx(tx) req := types.ToRequestCheckTx(params)
res, err := cli.client.CheckTx(context.Background(), req.GetCheckTx(), grpc.FailFast(true)) res, err := cli.client.CheckTx(context.Background(), req.GetCheckTx(), grpc.FailFast(true))
if err != nil { if err != nil {
cli.StopForError(err) cli.StopForError(err)
@ -265,13 +265,13 @@ func (cli *grpcClient) SetOptionSync(req types.RequestSetOption) (*types.Respons
return reqres.Response.GetSetOption(), cli.Error() return reqres.Response.GetSetOption(), cli.Error()
} }
func (cli *grpcClient) DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) { func (cli *grpcClient) DeliverTxSync(params types.RequestDeliverTx) (*types.ResponseDeliverTx, error) {
reqres := cli.DeliverTxAsync(tx) reqres := cli.DeliverTxAsync(params)
return reqres.Response.GetDeliverTx(), cli.Error() return reqres.Response.GetDeliverTx(), cli.Error()
} }
func (cli *grpcClient) CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) { func (cli *grpcClient) CheckTxSync(params types.RequestCheckTx) (*types.ResponseCheckTx, error) {
reqres := cli.CheckTxAsync(tx) reqres := cli.CheckTxAsync(params)
return reqres.Response.GetCheckTx(), cli.Error() return reqres.Response.GetCheckTx(), cli.Error()
} }

View File

@ -81,24 +81,24 @@ func (app *localClient) SetOptionAsync(req types.RequestSetOption) *ReqRes {
) )
} }
func (app *localClient) DeliverTxAsync(tx []byte) *ReqRes { func (app *localClient) DeliverTxAsync(params types.RequestDeliverTx) *ReqRes {
app.mtx.Lock() app.mtx.Lock()
defer app.mtx.Unlock() defer app.mtx.Unlock()
res := app.Application.DeliverTx(types.RequestDeliverTx{Tx: tx}) res := app.Application.DeliverTx(params)
return app.callback( return app.callback(
types.ToRequestDeliverTx(tx), types.ToRequestDeliverTx(params),
types.ToResponseDeliverTx(res), types.ToResponseDeliverTx(res),
) )
} }
func (app *localClient) CheckTxAsync(tx []byte) *ReqRes { func (app *localClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes {
app.mtx.Lock() app.mtx.Lock()
defer app.mtx.Unlock() defer app.mtx.Unlock()
res := app.Application.CheckTx(types.RequestCheckTx{Tx: tx}) res := app.Application.CheckTx(req)
return app.callback( return app.callback(
types.ToRequestCheckTx(tx), types.ToRequestCheckTx(req),
types.ToResponseCheckTx(res), types.ToResponseCheckTx(res),
) )
} }
@ -184,19 +184,19 @@ func (app *localClient) SetOptionSync(req types.RequestSetOption) (*types.Respon
return &res, nil return &res, nil
} }
func (app *localClient) DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) { func (app *localClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) {
app.mtx.Lock() app.mtx.Lock()
defer app.mtx.Unlock() defer app.mtx.Unlock()
res := app.Application.DeliverTx(types.RequestDeliverTx{Tx: tx}) res := app.Application.DeliverTx(req)
return &res, nil return &res, nil
} }
func (app *localClient) CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) { func (app *localClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) {
app.mtx.Lock() app.mtx.Lock()
defer app.mtx.Unlock() defer app.mtx.Unlock()
res := app.Application.CheckTx(types.RequestCheckTx{Tx: tx}) res := app.Application.CheckTx(req)
return &res, nil return &res, nil
} }

View File

@ -55,10 +55,6 @@ func NewSocketClient(addr string, mustConnect bool) *socketClient {
} }
func (cli *socketClient) OnStart() error { func (cli *socketClient) OnStart() error {
if err := cli.BaseService.OnStart(); err != nil {
return err
}
var err error var err error
var conn net.Conn var conn net.Conn
RETRY_LOOP: RETRY_LOOP:
@ -82,15 +78,12 @@ RETRY_LOOP:
} }
func (cli *socketClient) OnStop() { func (cli *socketClient) OnStop() {
cli.BaseService.OnStop()
cli.mtx.Lock()
defer cli.mtx.Unlock()
if cli.conn != nil { if cli.conn != nil {
// does this really need a mutex?
cli.conn.Close() cli.conn.Close()
} }
cli.mtx.Lock()
defer cli.mtx.Unlock()
cli.flushQueue() cli.flushQueue()
} }
@ -209,19 +202,18 @@ func (cli *socketClient) didRecvResponse(res *types.Response) error {
reqres.Done() // Release waiters reqres.Done() // Release waiters
cli.reqSent.Remove(next) // Pop first item from linked list cli.reqSent.Remove(next) // Pop first item from linked list
// Notify reqRes listener if set (request specific callback).
// NOTE: it is possible this callback isn't set on the reqres object.
// at this point, in which case it will be called after, when it is set.
// TODO: should we move this after the resCb call so the order is always consistent?
if cb := reqres.GetCallback(); cb != nil {
cb(res)
}
// Notify client listener if set (global callback). // Notify client listener if set (global callback).
if cli.resCb != nil { if cli.resCb != nil {
cli.resCb(reqres.Request, res) cli.resCb(reqres.Request, res)
} }
// Notify reqRes listener if set (request specific callback).
// NOTE: it is possible this callback isn't set on the reqres object.
// at this point, in which case it will be called after, when it is set.
if cb := reqres.GetCallback(); cb != nil {
cb(res)
}
return nil return nil
} }
@ -243,12 +235,12 @@ func (cli *socketClient) SetOptionAsync(req types.RequestSetOption) *ReqRes {
return cli.queueRequest(types.ToRequestSetOption(req)) return cli.queueRequest(types.ToRequestSetOption(req))
} }
func (cli *socketClient) DeliverTxAsync(tx []byte) *ReqRes { func (cli *socketClient) DeliverTxAsync(req types.RequestDeliverTx) *ReqRes {
return cli.queueRequest(types.ToRequestDeliverTx(tx)) return cli.queueRequest(types.ToRequestDeliverTx(req))
} }
func (cli *socketClient) CheckTxAsync(tx []byte) *ReqRes { func (cli *socketClient) CheckTxAsync(req types.RequestCheckTx) *ReqRes {
return cli.queueRequest(types.ToRequestCheckTx(tx)) return cli.queueRequest(types.ToRequestCheckTx(req))
} }
func (cli *socketClient) QueryAsync(req types.RequestQuery) *ReqRes { func (cli *socketClient) QueryAsync(req types.RequestQuery) *ReqRes {
@ -300,14 +292,14 @@ func (cli *socketClient) SetOptionSync(req types.RequestSetOption) (*types.Respo
return reqres.Response.GetSetOption(), cli.Error() return reqres.Response.GetSetOption(), cli.Error()
} }
func (cli *socketClient) DeliverTxSync(tx []byte) (*types.ResponseDeliverTx, error) { func (cli *socketClient) DeliverTxSync(req types.RequestDeliverTx) (*types.ResponseDeliverTx, error) {
reqres := cli.queueRequest(types.ToRequestDeliverTx(tx)) reqres := cli.queueRequest(types.ToRequestDeliverTx(req))
cli.FlushSync() cli.FlushSync()
return reqres.Response.GetDeliverTx(), cli.Error() return reqres.Response.GetDeliverTx(), cli.Error()
} }
func (cli *socketClient) CheckTxSync(tx []byte) (*types.ResponseCheckTx, error) { func (cli *socketClient) CheckTxSync(req types.RequestCheckTx) (*types.ResponseCheckTx, error) {
reqres := cli.queueRequest(types.ToRequestCheckTx(tx)) reqres := cli.queueRequest(types.ToRequestCheckTx(req))
cli.FlushSync() cli.FlushSync()
return reqres.Response.GetCheckTx(), cli.Error() return reqres.Response.GetCheckTx(), cli.Error()
} }

View File

@ -546,7 +546,7 @@ func cmdDeliverTx(cmd *cobra.Command, args []string) error {
if err != nil { if err != nil {
return err return err
} }
res, err := client.DeliverTxSync(txBytes) res, err := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes})
if err != nil { if err != nil {
return err return err
} }
@ -572,7 +572,7 @@ func cmdCheckTx(cmd *cobra.Command, args []string) error {
if err != nil { if err != nil {
return err return err
} }
res, err := client.CheckTxSync(txBytes) res, err := client.CheckTxSync(types.RequestCheckTx{Tx: txBytes})
if err != nil { if err != nil {
return err return err
} }

View File

@ -87,7 +87,7 @@ func testStream(t *testing.T, app types.Application) {
// Write requests // Write requests
for counter := 0; counter < numDeliverTxs; counter++ { for counter := 0; counter < numDeliverTxs; counter++ {
// Send request // Send request
reqRes := client.DeliverTxAsync([]byte("test")) reqRes := client.DeliverTxAsync(types.RequestDeliverTx{Tx: []byte("test")})
_ = reqRes _ = reqRes
// check err ? // check err ?

View File

@ -283,11 +283,11 @@ func runClientTests(t *testing.T, client abcicli.Client) {
} }
func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) { func testClient(t *testing.T, app abcicli.Client, tx []byte, key, value string) {
ar, err := app.DeliverTxSync(tx) ar, err := app.DeliverTxSync(types.RequestDeliverTx{Tx: tx})
require.NoError(t, err) require.NoError(t, err)
require.False(t, ar.IsErr(), ar) require.False(t, ar.IsErr(), ar)
// repeating tx doesn't raise error // repeating tx doesn't raise error
ar, err = app.DeliverTxSync(tx) ar, err = app.DeliverTxSync(types.RequestDeliverTx{Tx: tx})
require.NoError(t, err) require.NoError(t, err)
require.False(t, ar.IsErr(), ar) require.False(t, ar.IsErr(), ar)

View File

@ -58,7 +58,7 @@ func Commit(client abcicli.Client, hashExp []byte) error {
} }
func DeliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { func DeliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error {
res, _ := client.DeliverTxSync(txBytes) res, _ := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes})
code, data, log := res.Code, res.Data, res.Log code, data, log := res.Code, res.Data, res.Log
if code != codeExp { if code != codeExp {
fmt.Println("Failed test: DeliverTx") fmt.Println("Failed test: DeliverTx")
@ -77,7 +77,7 @@ func DeliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []
} }
func CheckTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error { func CheckTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) error {
res, _ := client.CheckTxSync(txBytes) res, _ := client.CheckTxSync(types.RequestCheckTx{Tx: txBytes})
code, data, log := res.Code, res.Data, res.Log code, data, log := res.Code, res.Data, res.Log
if code != codeExp { if code != codeExp {
fmt.Println("Failed test: CheckTx") fmt.Println("Failed test: CheckTx")

View File

@ -43,7 +43,7 @@ func commit(client abcicli.Client, hashExp []byte) {
} }
func deliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) { func deliverTx(client abcicli.Client, txBytes []byte, codeExp uint32, dataExp []byte) {
res, err := client.DeliverTxSync(txBytes) res, err := client.DeliverTxSync(types.RequestDeliverTx{Tx: txBytes})
if err != nil { if err != nil {
panicf("client error: %v", err) panicf("client error: %v", err)
} }

View File

@ -93,15 +93,15 @@ func ToRequestSetOption(req RequestSetOption) *Request {
} }
} }
func ToRequestDeliverTx(tx []byte) *Request { func ToRequestDeliverTx(req RequestDeliverTx) *Request {
return &Request{ return &Request{
Value: &Request_DeliverTx{&RequestDeliverTx{Tx: tx}}, Value: &Request_DeliverTx{&req},
} }
} }
func ToRequestCheckTx(tx []byte) *Request { func ToRequestCheckTx(req RequestCheckTx) *Request {
return &Request{ return &Request{
Value: &Request_CheckTx{&RequestCheckTx{Tx: tx}}, Value: &Request_CheckTx{&req},
} }
} }

View File

@ -38,6 +38,29 @@ var _ = time.Kitchen
// proto package needs to be updated. // proto package needs to be updated.
const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
type CheckTxType int32
const (
CheckTxType_New CheckTxType = 0
CheckTxType_Recheck CheckTxType = 1
)
var CheckTxType_name = map[int32]string{
0: "New",
1: "Recheck",
}
var CheckTxType_value = map[string]int32{
"New": 0,
"Recheck": 1,
}
func (x CheckTxType) String() string {
return proto.EnumName(CheckTxType_name, int32(x))
}
func (CheckTxType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_types_30d8160a6576aafe, []int{0}
}
type Request struct { type Request struct {
// Types that are valid to be assigned to Value: // Types that are valid to be assigned to Value:
// *Request_Echo // *Request_Echo
@ -61,7 +84,7 @@ func (m *Request) Reset() { *m = Request{} }
func (m *Request) String() string { return proto.CompactTextString(m) } func (m *Request) String() string { return proto.CompactTextString(m) }
func (*Request) ProtoMessage() {} func (*Request) ProtoMessage() {}
func (*Request) Descriptor() ([]byte, []int) { func (*Request) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{0} return fileDescriptor_types_30d8160a6576aafe, []int{0}
} }
func (m *Request) XXX_Unmarshal(b []byte) error { func (m *Request) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -483,7 +506,7 @@ func (m *RequestEcho) Reset() { *m = RequestEcho{} }
func (m *RequestEcho) String() string { return proto.CompactTextString(m) } func (m *RequestEcho) String() string { return proto.CompactTextString(m) }
func (*RequestEcho) ProtoMessage() {} func (*RequestEcho) ProtoMessage() {}
func (*RequestEcho) Descriptor() ([]byte, []int) { func (*RequestEcho) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{1} return fileDescriptor_types_30d8160a6576aafe, []int{1}
} }
func (m *RequestEcho) XXX_Unmarshal(b []byte) error { func (m *RequestEcho) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -529,7 +552,7 @@ func (m *RequestFlush) Reset() { *m = RequestFlush{} }
func (m *RequestFlush) String() string { return proto.CompactTextString(m) } func (m *RequestFlush) String() string { return proto.CompactTextString(m) }
func (*RequestFlush) ProtoMessage() {} func (*RequestFlush) ProtoMessage() {}
func (*RequestFlush) Descriptor() ([]byte, []int) { func (*RequestFlush) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{2} return fileDescriptor_types_30d8160a6576aafe, []int{2}
} }
func (m *RequestFlush) XXX_Unmarshal(b []byte) error { func (m *RequestFlush) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -571,7 +594,7 @@ func (m *RequestInfo) Reset() { *m = RequestInfo{} }
func (m *RequestInfo) String() string { return proto.CompactTextString(m) } func (m *RequestInfo) String() string { return proto.CompactTextString(m) }
func (*RequestInfo) ProtoMessage() {} func (*RequestInfo) ProtoMessage() {}
func (*RequestInfo) Descriptor() ([]byte, []int) { func (*RequestInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{3} return fileDescriptor_types_30d8160a6576aafe, []int{3}
} }
func (m *RequestInfo) XXX_Unmarshal(b []byte) error { func (m *RequestInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -634,7 +657,7 @@ func (m *RequestSetOption) Reset() { *m = RequestSetOption{} }
func (m *RequestSetOption) String() string { return proto.CompactTextString(m) } func (m *RequestSetOption) String() string { return proto.CompactTextString(m) }
func (*RequestSetOption) ProtoMessage() {} func (*RequestSetOption) ProtoMessage() {}
func (*RequestSetOption) Descriptor() ([]byte, []int) { func (*RequestSetOption) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{4} return fileDescriptor_types_30d8160a6576aafe, []int{4}
} }
func (m *RequestSetOption) XXX_Unmarshal(b []byte) error { func (m *RequestSetOption) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -692,7 +715,7 @@ func (m *RequestInitChain) Reset() { *m = RequestInitChain{} }
func (m *RequestInitChain) String() string { return proto.CompactTextString(m) } func (m *RequestInitChain) String() string { return proto.CompactTextString(m) }
func (*RequestInitChain) ProtoMessage() {} func (*RequestInitChain) ProtoMessage() {}
func (*RequestInitChain) Descriptor() ([]byte, []int) { func (*RequestInitChain) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{5} return fileDescriptor_types_30d8160a6576aafe, []int{5}
} }
func (m *RequestInitChain) XXX_Unmarshal(b []byte) error { func (m *RequestInitChain) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -770,7 +793,7 @@ func (m *RequestQuery) Reset() { *m = RequestQuery{} }
func (m *RequestQuery) String() string { return proto.CompactTextString(m) } func (m *RequestQuery) String() string { return proto.CompactTextString(m) }
func (*RequestQuery) ProtoMessage() {} func (*RequestQuery) ProtoMessage() {}
func (*RequestQuery) Descriptor() ([]byte, []int) { func (*RequestQuery) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{6} return fileDescriptor_types_30d8160a6576aafe, []int{6}
} }
func (m *RequestQuery) XXX_Unmarshal(b []byte) error { func (m *RequestQuery) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -841,7 +864,7 @@ func (m *RequestBeginBlock) Reset() { *m = RequestBeginBlock{} }
func (m *RequestBeginBlock) String() string { return proto.CompactTextString(m) } func (m *RequestBeginBlock) String() string { return proto.CompactTextString(m) }
func (*RequestBeginBlock) ProtoMessage() {} func (*RequestBeginBlock) ProtoMessage() {}
func (*RequestBeginBlock) Descriptor() ([]byte, []int) { func (*RequestBeginBlock) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{7} return fileDescriptor_types_30d8160a6576aafe, []int{7}
} }
func (m *RequestBeginBlock) XXX_Unmarshal(b []byte) error { func (m *RequestBeginBlock) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -900,6 +923,7 @@ func (m *RequestBeginBlock) GetByzantineValidators() []Evidence {
type RequestCheckTx struct { type RequestCheckTx struct {
Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"`
Type CheckTxType `protobuf:"varint,2,opt,name=type,proto3,enum=types.CheckTxType" json:"type,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
@ -909,7 +933,7 @@ func (m *RequestCheckTx) Reset() { *m = RequestCheckTx{} }
func (m *RequestCheckTx) String() string { return proto.CompactTextString(m) } func (m *RequestCheckTx) String() string { return proto.CompactTextString(m) }
func (*RequestCheckTx) ProtoMessage() {} func (*RequestCheckTx) ProtoMessage() {}
func (*RequestCheckTx) Descriptor() ([]byte, []int) { func (*RequestCheckTx) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{8} return fileDescriptor_types_30d8160a6576aafe, []int{8}
} }
func (m *RequestCheckTx) XXX_Unmarshal(b []byte) error { func (m *RequestCheckTx) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -945,6 +969,13 @@ func (m *RequestCheckTx) GetTx() []byte {
return nil return nil
} }
func (m *RequestCheckTx) GetType() CheckTxType {
if m != nil {
return m.Type
}
return CheckTxType_New
}
type RequestDeliverTx struct { type RequestDeliverTx struct {
Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"` Tx []byte `protobuf:"bytes,1,opt,name=tx,proto3" json:"tx,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
@ -956,7 +987,7 @@ func (m *RequestDeliverTx) Reset() { *m = RequestDeliverTx{} }
func (m *RequestDeliverTx) String() string { return proto.CompactTextString(m) } func (m *RequestDeliverTx) String() string { return proto.CompactTextString(m) }
func (*RequestDeliverTx) ProtoMessage() {} func (*RequestDeliverTx) ProtoMessage() {}
func (*RequestDeliverTx) Descriptor() ([]byte, []int) { func (*RequestDeliverTx) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{9} return fileDescriptor_types_30d8160a6576aafe, []int{9}
} }
func (m *RequestDeliverTx) XXX_Unmarshal(b []byte) error { func (m *RequestDeliverTx) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1003,7 +1034,7 @@ func (m *RequestEndBlock) Reset() { *m = RequestEndBlock{} }
func (m *RequestEndBlock) String() string { return proto.CompactTextString(m) } func (m *RequestEndBlock) String() string { return proto.CompactTextString(m) }
func (*RequestEndBlock) ProtoMessage() {} func (*RequestEndBlock) ProtoMessage() {}
func (*RequestEndBlock) Descriptor() ([]byte, []int) { func (*RequestEndBlock) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{10} return fileDescriptor_types_30d8160a6576aafe, []int{10}
} }
func (m *RequestEndBlock) XXX_Unmarshal(b []byte) error { func (m *RequestEndBlock) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1049,7 +1080,7 @@ func (m *RequestCommit) Reset() { *m = RequestCommit{} }
func (m *RequestCommit) String() string { return proto.CompactTextString(m) } func (m *RequestCommit) String() string { return proto.CompactTextString(m) }
func (*RequestCommit) ProtoMessage() {} func (*RequestCommit) ProtoMessage() {}
func (*RequestCommit) Descriptor() ([]byte, []int) { func (*RequestCommit) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{11} return fileDescriptor_types_30d8160a6576aafe, []int{11}
} }
func (m *RequestCommit) XXX_Unmarshal(b []byte) error { func (m *RequestCommit) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1102,7 +1133,7 @@ func (m *Response) Reset() { *m = Response{} }
func (m *Response) String() string { return proto.CompactTextString(m) } func (m *Response) String() string { return proto.CompactTextString(m) }
func (*Response) ProtoMessage() {} func (*Response) ProtoMessage() {}
func (*Response) Descriptor() ([]byte, []int) { func (*Response) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{12} return fileDescriptor_types_30d8160a6576aafe, []int{12}
} }
func (m *Response) XXX_Unmarshal(b []byte) error { func (m *Response) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1555,7 +1586,7 @@ func (m *ResponseException) Reset() { *m = ResponseException{} }
func (m *ResponseException) String() string { return proto.CompactTextString(m) } func (m *ResponseException) String() string { return proto.CompactTextString(m) }
func (*ResponseException) ProtoMessage() {} func (*ResponseException) ProtoMessage() {}
func (*ResponseException) Descriptor() ([]byte, []int) { func (*ResponseException) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{13} return fileDescriptor_types_30d8160a6576aafe, []int{13}
} }
func (m *ResponseException) XXX_Unmarshal(b []byte) error { func (m *ResponseException) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1602,7 +1633,7 @@ func (m *ResponseEcho) Reset() { *m = ResponseEcho{} }
func (m *ResponseEcho) String() string { return proto.CompactTextString(m) } func (m *ResponseEcho) String() string { return proto.CompactTextString(m) }
func (*ResponseEcho) ProtoMessage() {} func (*ResponseEcho) ProtoMessage() {}
func (*ResponseEcho) Descriptor() ([]byte, []int) { func (*ResponseEcho) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{14} return fileDescriptor_types_30d8160a6576aafe, []int{14}
} }
func (m *ResponseEcho) XXX_Unmarshal(b []byte) error { func (m *ResponseEcho) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1648,7 +1679,7 @@ func (m *ResponseFlush) Reset() { *m = ResponseFlush{} }
func (m *ResponseFlush) String() string { return proto.CompactTextString(m) } func (m *ResponseFlush) String() string { return proto.CompactTextString(m) }
func (*ResponseFlush) ProtoMessage() {} func (*ResponseFlush) ProtoMessage() {}
func (*ResponseFlush) Descriptor() ([]byte, []int) { func (*ResponseFlush) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{15} return fileDescriptor_types_30d8160a6576aafe, []int{15}
} }
func (m *ResponseFlush) XXX_Unmarshal(b []byte) error { func (m *ResponseFlush) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1692,7 +1723,7 @@ func (m *ResponseInfo) Reset() { *m = ResponseInfo{} }
func (m *ResponseInfo) String() string { return proto.CompactTextString(m) } func (m *ResponseInfo) String() string { return proto.CompactTextString(m) }
func (*ResponseInfo) ProtoMessage() {} func (*ResponseInfo) ProtoMessage() {}
func (*ResponseInfo) Descriptor() ([]byte, []int) { func (*ResponseInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{16} return fileDescriptor_types_30d8160a6576aafe, []int{16}
} }
func (m *ResponseInfo) XXX_Unmarshal(b []byte) error { func (m *ResponseInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1771,7 +1802,7 @@ func (m *ResponseSetOption) Reset() { *m = ResponseSetOption{} }
func (m *ResponseSetOption) String() string { return proto.CompactTextString(m) } func (m *ResponseSetOption) String() string { return proto.CompactTextString(m) }
func (*ResponseSetOption) ProtoMessage() {} func (*ResponseSetOption) ProtoMessage() {}
func (*ResponseSetOption) Descriptor() ([]byte, []int) { func (*ResponseSetOption) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{17} return fileDescriptor_types_30d8160a6576aafe, []int{17}
} }
func (m *ResponseSetOption) XXX_Unmarshal(b []byte) error { func (m *ResponseSetOption) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1833,7 +1864,7 @@ func (m *ResponseInitChain) Reset() { *m = ResponseInitChain{} }
func (m *ResponseInitChain) String() string { return proto.CompactTextString(m) } func (m *ResponseInitChain) String() string { return proto.CompactTextString(m) }
func (*ResponseInitChain) ProtoMessage() {} func (*ResponseInitChain) ProtoMessage() {}
func (*ResponseInitChain) Descriptor() ([]byte, []int) { func (*ResponseInitChain) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{18} return fileDescriptor_types_30d8160a6576aafe, []int{18}
} }
func (m *ResponseInitChain) XXX_Unmarshal(b []byte) error { func (m *ResponseInitChain) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1896,7 +1927,7 @@ func (m *ResponseQuery) Reset() { *m = ResponseQuery{} }
func (m *ResponseQuery) String() string { return proto.CompactTextString(m) } func (m *ResponseQuery) String() string { return proto.CompactTextString(m) }
func (*ResponseQuery) ProtoMessage() {} func (*ResponseQuery) ProtoMessage() {}
func (*ResponseQuery) Descriptor() ([]byte, []int) { func (*ResponseQuery) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{19} return fileDescriptor_types_30d8160a6576aafe, []int{19}
} }
func (m *ResponseQuery) XXX_Unmarshal(b []byte) error { func (m *ResponseQuery) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -1999,7 +2030,7 @@ func (m *ResponseBeginBlock) Reset() { *m = ResponseBeginBlock{} }
func (m *ResponseBeginBlock) String() string { return proto.CompactTextString(m) } func (m *ResponseBeginBlock) String() string { return proto.CompactTextString(m) }
func (*ResponseBeginBlock) ProtoMessage() {} func (*ResponseBeginBlock) ProtoMessage() {}
func (*ResponseBeginBlock) Descriptor() ([]byte, []int) { func (*ResponseBeginBlock) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{20} return fileDescriptor_types_30d8160a6576aafe, []int{20}
} }
func (m *ResponseBeginBlock) XXX_Unmarshal(b []byte) error { func (m *ResponseBeginBlock) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2053,7 +2084,7 @@ func (m *ResponseCheckTx) Reset() { *m = ResponseCheckTx{} }
func (m *ResponseCheckTx) String() string { return proto.CompactTextString(m) } func (m *ResponseCheckTx) String() string { return proto.CompactTextString(m) }
func (*ResponseCheckTx) ProtoMessage() {} func (*ResponseCheckTx) ProtoMessage() {}
func (*ResponseCheckTx) Descriptor() ([]byte, []int) { func (*ResponseCheckTx) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{21} return fileDescriptor_types_30d8160a6576aafe, []int{21}
} }
func (m *ResponseCheckTx) XXX_Unmarshal(b []byte) error { func (m *ResponseCheckTx) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2156,7 +2187,7 @@ func (m *ResponseDeliverTx) Reset() { *m = ResponseDeliverTx{} }
func (m *ResponseDeliverTx) String() string { return proto.CompactTextString(m) } func (m *ResponseDeliverTx) String() string { return proto.CompactTextString(m) }
func (*ResponseDeliverTx) ProtoMessage() {} func (*ResponseDeliverTx) ProtoMessage() {}
func (*ResponseDeliverTx) Descriptor() ([]byte, []int) { func (*ResponseDeliverTx) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{22} return fileDescriptor_types_30d8160a6576aafe, []int{22}
} }
func (m *ResponseDeliverTx) XXX_Unmarshal(b []byte) error { func (m *ResponseDeliverTx) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2254,7 +2285,7 @@ func (m *ResponseEndBlock) Reset() { *m = ResponseEndBlock{} }
func (m *ResponseEndBlock) String() string { return proto.CompactTextString(m) } func (m *ResponseEndBlock) String() string { return proto.CompactTextString(m) }
func (*ResponseEndBlock) ProtoMessage() {} func (*ResponseEndBlock) ProtoMessage() {}
func (*ResponseEndBlock) Descriptor() ([]byte, []int) { func (*ResponseEndBlock) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{23} return fileDescriptor_types_30d8160a6576aafe, []int{23}
} }
func (m *ResponseEndBlock) XXX_Unmarshal(b []byte) error { func (m *ResponseEndBlock) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2316,7 +2347,7 @@ func (m *ResponseCommit) Reset() { *m = ResponseCommit{} }
func (m *ResponseCommit) String() string { return proto.CompactTextString(m) } func (m *ResponseCommit) String() string { return proto.CompactTextString(m) }
func (*ResponseCommit) ProtoMessage() {} func (*ResponseCommit) ProtoMessage() {}
func (*ResponseCommit) Descriptor() ([]byte, []int) { func (*ResponseCommit) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{24} return fileDescriptor_types_30d8160a6576aafe, []int{24}
} }
func (m *ResponseCommit) XXX_Unmarshal(b []byte) error { func (m *ResponseCommit) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2367,7 +2398,7 @@ func (m *ConsensusParams) Reset() { *m = ConsensusParams{} }
func (m *ConsensusParams) String() string { return proto.CompactTextString(m) } func (m *ConsensusParams) String() string { return proto.CompactTextString(m) }
func (*ConsensusParams) ProtoMessage() {} func (*ConsensusParams) ProtoMessage() {}
func (*ConsensusParams) Descriptor() ([]byte, []int) { func (*ConsensusParams) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{25} return fileDescriptor_types_30d8160a6576aafe, []int{25}
} }
func (m *ConsensusParams) XXX_Unmarshal(b []byte) error { func (m *ConsensusParams) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2417,7 +2448,7 @@ func (m *ConsensusParams) GetValidator() *ValidatorParams {
return nil return nil
} }
// BlockParams contains limits on the block size and timestamp. // BlockParams contains limits on the block size.
type BlockParams struct { type BlockParams struct {
// Note: must be greater than 0 // Note: must be greater than 0
MaxBytes int64 `protobuf:"varint,1,opt,name=max_bytes,json=maxBytes,proto3" json:"max_bytes,omitempty"` MaxBytes int64 `protobuf:"varint,1,opt,name=max_bytes,json=maxBytes,proto3" json:"max_bytes,omitempty"`
@ -2432,7 +2463,7 @@ func (m *BlockParams) Reset() { *m = BlockParams{} }
func (m *BlockParams) String() string { return proto.CompactTextString(m) } func (m *BlockParams) String() string { return proto.CompactTextString(m) }
func (*BlockParams) ProtoMessage() {} func (*BlockParams) ProtoMessage() {}
func (*BlockParams) Descriptor() ([]byte, []int) { func (*BlockParams) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{26} return fileDescriptor_types_30d8160a6576aafe, []int{26}
} }
func (m *BlockParams) XXX_Unmarshal(b []byte) error { func (m *BlockParams) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2488,7 +2519,7 @@ func (m *EvidenceParams) Reset() { *m = EvidenceParams{} }
func (m *EvidenceParams) String() string { return proto.CompactTextString(m) } func (m *EvidenceParams) String() string { return proto.CompactTextString(m) }
func (*EvidenceParams) ProtoMessage() {} func (*EvidenceParams) ProtoMessage() {}
func (*EvidenceParams) Descriptor() ([]byte, []int) { func (*EvidenceParams) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{27} return fileDescriptor_types_30d8160a6576aafe, []int{27}
} }
func (m *EvidenceParams) XXX_Unmarshal(b []byte) error { func (m *EvidenceParams) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2536,7 +2567,7 @@ func (m *ValidatorParams) Reset() { *m = ValidatorParams{} }
func (m *ValidatorParams) String() string { return proto.CompactTextString(m) } func (m *ValidatorParams) String() string { return proto.CompactTextString(m) }
func (*ValidatorParams) ProtoMessage() {} func (*ValidatorParams) ProtoMessage() {}
func (*ValidatorParams) Descriptor() ([]byte, []int) { func (*ValidatorParams) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{28} return fileDescriptor_types_30d8160a6576aafe, []int{28}
} }
func (m *ValidatorParams) XXX_Unmarshal(b []byte) error { func (m *ValidatorParams) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2584,7 +2615,7 @@ func (m *LastCommitInfo) Reset() { *m = LastCommitInfo{} }
func (m *LastCommitInfo) String() string { return proto.CompactTextString(m) } func (m *LastCommitInfo) String() string { return proto.CompactTextString(m) }
func (*LastCommitInfo) ProtoMessage() {} func (*LastCommitInfo) ProtoMessage() {}
func (*LastCommitInfo) Descriptor() ([]byte, []int) { func (*LastCommitInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{29} return fileDescriptor_types_30d8160a6576aafe, []int{29}
} }
func (m *LastCommitInfo) XXX_Unmarshal(b []byte) error { func (m *LastCommitInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2639,7 +2670,7 @@ func (m *Event) Reset() { *m = Event{} }
func (m *Event) String() string { return proto.CompactTextString(m) } func (m *Event) String() string { return proto.CompactTextString(m) }
func (*Event) ProtoMessage() {} func (*Event) ProtoMessage() {}
func (*Event) Descriptor() ([]byte, []int) { func (*Event) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{30} return fileDescriptor_types_30d8160a6576aafe, []int{30}
} }
func (m *Event) XXX_Unmarshal(b []byte) error { func (m *Event) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2713,7 +2744,7 @@ func (m *Header) Reset() { *m = Header{} }
func (m *Header) String() string { return proto.CompactTextString(m) } func (m *Header) String() string { return proto.CompactTextString(m) }
func (*Header) ProtoMessage() {} func (*Header) ProtoMessage() {}
func (*Header) Descriptor() ([]byte, []int) { func (*Header) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{31} return fileDescriptor_types_30d8160a6576aafe, []int{31}
} }
func (m *Header) XXX_Unmarshal(b []byte) error { func (m *Header) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2866,7 +2897,7 @@ func (m *Version) Reset() { *m = Version{} }
func (m *Version) String() string { return proto.CompactTextString(m) } func (m *Version) String() string { return proto.CompactTextString(m) }
func (*Version) ProtoMessage() {} func (*Version) ProtoMessage() {}
func (*Version) Descriptor() ([]byte, []int) { func (*Version) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{32} return fileDescriptor_types_30d8160a6576aafe, []int{32}
} }
func (m *Version) XXX_Unmarshal(b []byte) error { func (m *Version) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2921,7 +2952,7 @@ func (m *BlockID) Reset() { *m = BlockID{} }
func (m *BlockID) String() string { return proto.CompactTextString(m) } func (m *BlockID) String() string { return proto.CompactTextString(m) }
func (*BlockID) ProtoMessage() {} func (*BlockID) ProtoMessage() {}
func (*BlockID) Descriptor() ([]byte, []int) { func (*BlockID) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{33} return fileDescriptor_types_30d8160a6576aafe, []int{33}
} }
func (m *BlockID) XXX_Unmarshal(b []byte) error { func (m *BlockID) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -2976,7 +3007,7 @@ func (m *PartSetHeader) Reset() { *m = PartSetHeader{} }
func (m *PartSetHeader) String() string { return proto.CompactTextString(m) } func (m *PartSetHeader) String() string { return proto.CompactTextString(m) }
func (*PartSetHeader) ProtoMessage() {} func (*PartSetHeader) ProtoMessage() {}
func (*PartSetHeader) Descriptor() ([]byte, []int) { func (*PartSetHeader) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{34} return fileDescriptor_types_30d8160a6576aafe, []int{34}
} }
func (m *PartSetHeader) XXX_Unmarshal(b []byte) error { func (m *PartSetHeader) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -3033,7 +3064,7 @@ func (m *Validator) Reset() { *m = Validator{} }
func (m *Validator) String() string { return proto.CompactTextString(m) } func (m *Validator) String() string { return proto.CompactTextString(m) }
func (*Validator) ProtoMessage() {} func (*Validator) ProtoMessage() {}
func (*Validator) Descriptor() ([]byte, []int) { func (*Validator) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{35} return fileDescriptor_types_30d8160a6576aafe, []int{35}
} }
func (m *Validator) XXX_Unmarshal(b []byte) error { func (m *Validator) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -3089,7 +3120,7 @@ func (m *ValidatorUpdate) Reset() { *m = ValidatorUpdate{} }
func (m *ValidatorUpdate) String() string { return proto.CompactTextString(m) } func (m *ValidatorUpdate) String() string { return proto.CompactTextString(m) }
func (*ValidatorUpdate) ProtoMessage() {} func (*ValidatorUpdate) ProtoMessage() {}
func (*ValidatorUpdate) Descriptor() ([]byte, []int) { func (*ValidatorUpdate) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{36} return fileDescriptor_types_30d8160a6576aafe, []int{36}
} }
func (m *ValidatorUpdate) XXX_Unmarshal(b []byte) error { func (m *ValidatorUpdate) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -3145,7 +3176,7 @@ func (m *VoteInfo) Reset() { *m = VoteInfo{} }
func (m *VoteInfo) String() string { return proto.CompactTextString(m) } func (m *VoteInfo) String() string { return proto.CompactTextString(m) }
func (*VoteInfo) ProtoMessage() {} func (*VoteInfo) ProtoMessage() {}
func (*VoteInfo) Descriptor() ([]byte, []int) { func (*VoteInfo) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{37} return fileDescriptor_types_30d8160a6576aafe, []int{37}
} }
func (m *VoteInfo) XXX_Unmarshal(b []byte) error { func (m *VoteInfo) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -3200,7 +3231,7 @@ func (m *PubKey) Reset() { *m = PubKey{} }
func (m *PubKey) String() string { return proto.CompactTextString(m) } func (m *PubKey) String() string { return proto.CompactTextString(m) }
func (*PubKey) ProtoMessage() {} func (*PubKey) ProtoMessage() {}
func (*PubKey) Descriptor() ([]byte, []int) { func (*PubKey) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{38} return fileDescriptor_types_30d8160a6576aafe, []int{38}
} }
func (m *PubKey) XXX_Unmarshal(b []byte) error { func (m *PubKey) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -3258,7 +3289,7 @@ func (m *Evidence) Reset() { *m = Evidence{} }
func (m *Evidence) String() string { return proto.CompactTextString(m) } func (m *Evidence) String() string { return proto.CompactTextString(m) }
func (*Evidence) ProtoMessage() {} func (*Evidence) ProtoMessage() {}
func (*Evidence) Descriptor() ([]byte, []int) { func (*Evidence) Descriptor() ([]byte, []int) {
return fileDescriptor_types_62f0c59aeb977f78, []int{39} return fileDescriptor_types_30d8160a6576aafe, []int{39}
} }
func (m *Evidence) XXX_Unmarshal(b []byte) error { func (m *Evidence) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b) return m.Unmarshal(b)
@ -3403,6 +3434,8 @@ func init() {
golang_proto.RegisterType((*PubKey)(nil), "types.PubKey") golang_proto.RegisterType((*PubKey)(nil), "types.PubKey")
proto.RegisterType((*Evidence)(nil), "types.Evidence") proto.RegisterType((*Evidence)(nil), "types.Evidence")
golang_proto.RegisterType((*Evidence)(nil), "types.Evidence") golang_proto.RegisterType((*Evidence)(nil), "types.Evidence")
proto.RegisterEnum("types.CheckTxType", CheckTxType_name, CheckTxType_value)
golang_proto.RegisterEnum("types.CheckTxType", CheckTxType_name, CheckTxType_value)
} }
func (this *Request) Equal(that interface{}) bool { func (this *Request) Equal(that interface{}) bool {
if that == nil { if that == nil {
@ -3958,6 +3991,9 @@ func (this *RequestCheckTx) Equal(that interface{}) bool {
if !bytes.Equal(this.Tx, that1.Tx) { if !bytes.Equal(this.Tx, that1.Tx) {
return false return false
} }
if this.Type != that1.Type {
return false
}
if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
return false return false
} }
@ -6211,6 +6247,11 @@ func (m *RequestCheckTx) MarshalTo(dAtA []byte) (int, error) {
i = encodeVarintTypes(dAtA, i, uint64(len(m.Tx))) i = encodeVarintTypes(dAtA, i, uint64(len(m.Tx)))
i += copy(dAtA[i:], m.Tx) i += copy(dAtA[i:], m.Tx)
} }
if m.Type != 0 {
dAtA[i] = 0x10
i++
i = encodeVarintTypes(dAtA, i, uint64(m.Type))
}
if m.XXX_unrecognized != nil { if m.XXX_unrecognized != nil {
i += copy(dAtA[i:], m.XXX_unrecognized) i += copy(dAtA[i:], m.XXX_unrecognized)
} }
@ -7872,8 +7913,9 @@ func NewPopulatedRequestCheckTx(r randyTypes, easy bool) *RequestCheckTx {
for i := 0; i < v11; i++ { for i := 0; i < v11; i++ {
this.Tx[i] = byte(r.Intn(256)) this.Tx[i] = byte(r.Intn(256))
} }
this.Type = CheckTxType([]int32{0, 1}[r.Intn(2)])
if !easy && r.Intn(10) != 0 { if !easy && r.Intn(10) != 0 {
this.XXX_unrecognized = randUnrecognizedTypes(r, 2) this.XXX_unrecognized = randUnrecognizedTypes(r, 3)
} }
return this return this
} }
@ -8906,6 +8948,9 @@ func (m *RequestCheckTx) Size() (n int) {
if l > 0 { if l > 0 {
n += 1 + l + sovTypes(uint64(l)) n += 1 + l + sovTypes(uint64(l))
} }
if m.Type != 0 {
n += 1 + sovTypes(uint64(m.Type))
}
if m.XXX_unrecognized != nil { if m.XXX_unrecognized != nil {
n += len(m.XXX_unrecognized) n += len(m.XXX_unrecognized)
} }
@ -11127,6 +11172,25 @@ func (m *RequestCheckTx) Unmarshal(dAtA []byte) error {
m.Tx = []byte{} m.Tx = []byte{}
} }
iNdEx = postIndex iNdEx = postIndex
case 2:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType)
}
m.Type = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowTypes
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.Type |= (CheckTxType(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipTypes(dAtA[iNdEx:]) skippy, err := skipTypes(dAtA[iNdEx:])
@ -15638,152 +15702,154 @@ var (
ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow") ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow")
) )
func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_62f0c59aeb977f78) } func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_30d8160a6576aafe) }
func init() { func init() {
golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_62f0c59aeb977f78) golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_30d8160a6576aafe)
} }
var fileDescriptor_types_62f0c59aeb977f78 = []byte{ var fileDescriptor_types_30d8160a6576aafe = []byte{
// 2241 bytes of a gzipped FileDescriptorProto // 2282 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0x4b, 0x73, 0x1c, 0x49, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x58, 0xcd, 0x73, 0x1c, 0x47,
0xf1, 0x57, 0xcf, 0xbb, 0x73, 0x34, 0x0f, 0x97, 0x65, 0x7b, 0x3c, 0x7f, 0xff, 0x25, 0x47, 0x1b, 0x15, 0xd7, 0xec, 0xf7, 0xbc, 0xd5, 0x7e, 0xb8, 0x2d, 0xdb, 0xeb, 0xc5, 0x48, 0xae, 0x31, 0x38,
0x76, 0x25, 0xd6, 0x3b, 0xda, 0xd5, 0x62, 0x42, 0xc6, 0xcb, 0x46, 0x68, 0x6c, 0x83, 0x14, 0x6b, 0x52, 0xe2, 0xac, 0x12, 0x05, 0x53, 0x32, 0x0e, 0xa9, 0xd2, 0xda, 0x06, 0xa9, 0x62, 0x82, 0x18,
0x40, 0xb4, 0x6d, 0x71, 0x21, 0xa2, 0xa3, 0x66, 0xba, 0x3c, 0xd3, 0xe1, 0x99, 0xee, 0xde, 0xee, 0xdb, 0xe2, 0x42, 0xd5, 0x54, 0xef, 0x4e, 0x7b, 0x77, 0xca, 0xbb, 0x33, 0x93, 0x99, 0x5e, 0x79,
0x9a, 0xd9, 0x11, 0x47, 0xce, 0x7b, 0xd8, 0x03, 0x1f, 0x81, 0x03, 0x1f, 0x61, 0x8f, 0x9c, 0x88, 0xc5, 0x91, 0x73, 0x0e, 0x39, 0xf0, 0x27, 0x70, 0xe0, 0x4f, 0xc8, 0x91, 0x13, 0x95, 0x23, 0x07,
0x3d, 0x72, 0xe0, 0x6c, 0x40, 0x04, 0x17, 0x22, 0x38, 0x03, 0x37, 0xa2, 0xb2, 0xaa, 0x9f, 0xea, 0xce, 0x06, 0x44, 0x71, 0xa1, 0x8a, 0x33, 0x70, 0xa3, 0xfa, 0x75, 0xcf, 0xa7, 0x66, 0x4d, 0x62,
0x31, 0xbb, 0x86, 0x1b, 0x17, 0xa9, 0xab, 0xf2, 0x97, 0xf5, 0xc8, 0xc9, 0xcc, 0x5f, 0x66, 0xc1, 0xb8, 0xe5, 0xb2, 0x3b, 0xdd, 0xef, 0xf7, 0x7a, 0xba, 0xdf, 0xbc, 0xf7, 0x7e, 0xef, 0x35, 0x5c,
0x75, 0x3a, 0x1a, 0x3b, 0xfb, 0xfc, 0xdc, 0x67, 0xa1, 0xfc, 0x3b, 0xf0, 0x03, 0x8f, 0x7b, 0xa4, 0xa5, 0xa3, 0xb1, 0xb3, 0xcb, 0xcf, 0x7c, 0x16, 0xca, 0xdf, 0x81, 0x1f, 0x78, 0xdc, 0x23, 0x55,
0x8a, 0x83, 0xfe, 0xbb, 0x13, 0x87, 0x4f, 0x17, 0xa3, 0xc1, 0xd8, 0x9b, 0xef, 0x4f, 0xbc, 0x89, 0x1c, 0xf4, 0xdf, 0x9d, 0x38, 0x7c, 0xba, 0x18, 0x0d, 0xc6, 0xde, 0x7c, 0x77, 0xe2, 0x4d, 0xbc,
0xb7, 0x8f, 0xd2, 0xd1, 0xe2, 0x05, 0x8e, 0x70, 0x80, 0x5f, 0x52, 0xab, 0xff, 0x20, 0x05, 0xe7, 0x5d, 0x94, 0x8e, 0x16, 0xcf, 0x71, 0x84, 0x03, 0x7c, 0x92, 0x5a, 0xfd, 0xfb, 0x29, 0x38, 0x67,
0xcc, 0xb5, 0x59, 0x30, 0x77, 0x5c, 0x9e, 0xfe, 0x1c, 0x07, 0xe7, 0x3e, 0xf7, 0xf6, 0xe7, 0x2c, 0xae, 0xcd, 0x82, 0xb9, 0xe3, 0xf2, 0xf4, 0xe3, 0x38, 0x38, 0xf3, 0xb9, 0xb7, 0x3b, 0x67, 0xc1,
0x78, 0x39, 0x63, 0xea, 0x9f, 0x52, 0x3e, 0xfc, 0xb7, 0xca, 0x33, 0x67, 0x14, 0xee, 0x8f, 0xbd, 0x8b, 0x19, 0x53, 0x7f, 0x4a, 0x79, 0xff, 0xbf, 0x2a, 0xcf, 0x9c, 0x51, 0xb8, 0x3b, 0xf6, 0xe6,
0xf9, 0xdc, 0x73, 0xd3, 0x87, 0xed, 0xef, 0x4c, 0x3c, 0x6f, 0x32, 0x63, 0xc9, 0xe1, 0xb8, 0x33, 0x73, 0xcf, 0x4d, 0x6f, 0xb6, 0xbf, 0x35, 0xf1, 0xbc, 0xc9, 0x8c, 0x25, 0x9b, 0xe3, 0xce, 0x9c,
0x67, 0x21, 0xa7, 0x73, 0x5f, 0x02, 0x8c, 0xdf, 0x56, 0xa0, 0x6e, 0xb2, 0x4f, 0x16, 0x2c, 0xe4, 0x85, 0x9c, 0xce, 0x7d, 0x09, 0x30, 0x7e, 0x5f, 0x81, 0xba, 0xc9, 0x3e, 0x5d, 0xb0, 0x90, 0x93,
0x64, 0x17, 0x2a, 0x6c, 0x3c, 0xf5, 0x7a, 0xa5, 0xdb, 0xda, 0x6e, 0xf3, 0x80, 0x0c, 0xe4, 0x42, 0x6d, 0xa8, 0xb0, 0xf1, 0xd4, 0xeb, 0x95, 0x6e, 0x6a, 0xdb, 0xcd, 0x3d, 0x32, 0x90, 0x0b, 0x29,
0x4a, 0xfa, 0x78, 0x3c, 0xf5, 0x8e, 0x37, 0x4c, 0x44, 0x90, 0x77, 0xa0, 0xfa, 0x62, 0xb6, 0x08, 0xe9, 0xa3, 0xf1, 0xd4, 0x3b, 0x5c, 0x33, 0x11, 0x41, 0xde, 0x81, 0xea, 0xf3, 0xd9, 0x22, 0x9c,
0xa7, 0xbd, 0x32, 0x42, 0xaf, 0x66, 0xa1, 0xdf, 0x17, 0xa2, 0xe3, 0x0d, 0x53, 0x62, 0xc4, 0xb2, 0xf6, 0xca, 0x08, 0xbd, 0x9c, 0x85, 0xfe, 0x48, 0x88, 0x0e, 0xd7, 0x4c, 0x89, 0x11, 0xcb, 0x3a,
0x8e, 0xfb, 0xc2, 0xeb, 0x55, 0x8a, 0x96, 0x3d, 0x71, 0x5f, 0xe0, 0xb2, 0x02, 0x41, 0x0e, 0x01, 0xee, 0x73, 0xaf, 0x57, 0x29, 0x5a, 0xf6, 0xc8, 0x7d, 0x8e, 0xcb, 0x0a, 0x04, 0xd9, 0x07, 0x08,
0x42, 0xc6, 0x2d, 0xcf, 0xe7, 0x8e, 0xe7, 0xf6, 0xaa, 0x88, 0xbf, 0x91, 0xc5, 0x3f, 0x65, 0xfc, 0x19, 0xb7, 0x3c, 0x9f, 0x3b, 0x9e, 0xdb, 0xab, 0x22, 0xfe, 0x5a, 0x16, 0xff, 0x84, 0xf1, 0x9f,
0xc7, 0x28, 0x3e, 0xde, 0x30, 0xf5, 0x30, 0x1a, 0x08, 0x4d, 0xc7, 0x75, 0xb8, 0x35, 0x9e, 0x52, 0xa2, 0xf8, 0x70, 0xcd, 0xd4, 0xc3, 0x68, 0x20, 0x34, 0x1d, 0xd7, 0xe1, 0xd6, 0x78, 0x4a, 0x1d,
0xc7, 0xed, 0xd5, 0x8a, 0x34, 0x4f, 0x5c, 0x87, 0x3f, 0x14, 0x62, 0xa1, 0xe9, 0x44, 0x03, 0x71, 0xb7, 0x57, 0x2b, 0xd2, 0x3c, 0x72, 0x1d, 0xfe, 0x40, 0x88, 0x85, 0xa6, 0x13, 0x0d, 0xc4, 0x51,
0x95, 0x4f, 0x16, 0x2c, 0x38, 0xef, 0xd5, 0x8b, 0xae, 0xf2, 0x13, 0x21, 0x12, 0x57, 0x41, 0x0c, 0x3e, 0x5d, 0xb0, 0xe0, 0xac, 0x57, 0x2f, 0x3a, 0xca, 0xcf, 0x84, 0x48, 0x1c, 0x05, 0x31, 0xe4,
0x79, 0x00, 0xcd, 0x11, 0x9b, 0x38, 0xae, 0x35, 0x9a, 0x79, 0xe3, 0x97, 0xbd, 0x06, 0xaa, 0xf4, 0x3e, 0x34, 0x47, 0x6c, 0xe2, 0xb8, 0xd6, 0x68, 0xe6, 0x8d, 0x5f, 0xf4, 0x1a, 0xa8, 0xd2, 0xcb,
0xb2, 0x2a, 0x43, 0x01, 0x18, 0x0a, 0xf9, 0xf1, 0x86, 0x09, 0xa3, 0x78, 0x44, 0x0e, 0xa0, 0x31, 0xaa, 0x0c, 0x05, 0x60, 0x28, 0xe4, 0x87, 0x6b, 0x26, 0x8c, 0xe2, 0x11, 0xd9, 0x83, 0xc6, 0x78,
0x9e, 0xb2, 0xf1, 0x4b, 0x8b, 0xaf, 0x7a, 0x3a, 0x6a, 0x5e, 0xcb, 0x6a, 0x3e, 0x14, 0xd2, 0x67, 0xca, 0xc6, 0x2f, 0x2c, 0xbe, 0xec, 0xe9, 0xa8, 0x79, 0x25, 0xab, 0xf9, 0x40, 0x48, 0x9f, 0x2e,
0xab, 0xe3, 0x0d, 0xb3, 0x3e, 0x96, 0x9f, 0xe4, 0x1e, 0xe8, 0xcc, 0xb5, 0xd5, 0x76, 0x4d, 0x54, 0x0f, 0xd7, 0xcc, 0xfa, 0x58, 0x3e, 0x92, 0xbb, 0xa0, 0x33, 0xd7, 0x56, 0xaf, 0x6b, 0xa2, 0xd2,
0xba, 0x9e, 0xfb, 0x5d, 0x5c, 0x3b, 0xda, 0xac, 0xc1, 0xd4, 0x37, 0x19, 0x40, 0x4d, 0x38, 0x83, 0xd5, 0xdc, 0x77, 0x71, 0xed, 0xe8, 0x65, 0x0d, 0xa6, 0x9e, 0xc9, 0x00, 0x6a, 0xc2, 0x19, 0x1c,
0xc3, 0x7b, 0x9b, 0xa8, 0xb3, 0x95, 0xdb, 0x08, 0x65, 0xc7, 0x1b, 0xa6, 0x42, 0x09, 0xf3, 0xd9, 0xde, 0x5b, 0x47, 0x9d, 0x8d, 0xdc, 0x8b, 0x50, 0x76, 0xb8, 0x66, 0x2a, 0x94, 0x30, 0x9f, 0xcd,
0x6c, 0xe6, 0x2c, 0x59, 0x20, 0x0e, 0x77, 0xb5, 0xc8, 0x7c, 0x8f, 0xa4, 0x1c, 0x8f, 0xa7, 0xdb, 0x66, 0xce, 0x29, 0x0b, 0xc4, 0xe6, 0x2e, 0x17, 0x99, 0xef, 0xa1, 0x94, 0xe3, 0xf6, 0x74, 0x3b,
0xd1, 0x60, 0x58, 0x87, 0xea, 0x92, 0xce, 0x16, 0xcc, 0x78, 0x1b, 0x9a, 0x29, 0x4f, 0x21, 0x3d, 0x1a, 0x0c, 0xeb, 0x50, 0x3d, 0xa5, 0xb3, 0x05, 0x33, 0xde, 0x82, 0x66, 0xca, 0x53, 0x48, 0x0f,
0xa8, 0xcf, 0x59, 0x18, 0xd2, 0x09, 0xeb, 0x69, 0xb7, 0xb5, 0x5d, 0xdd, 0x8c, 0x86, 0x46, 0x1b, 0xea, 0x73, 0x16, 0x86, 0x74, 0xc2, 0x7a, 0xda, 0x4d, 0x6d, 0x5b, 0x37, 0xa3, 0xa1, 0xd1, 0x86,
0x36, 0xd3, 0x7e, 0x62, 0xcc, 0x63, 0x45, 0xe1, 0x0b, 0x42, 0x71, 0xc9, 0x82, 0x50, 0x38, 0x80, 0xf5, 0xb4, 0x9f, 0x18, 0xf3, 0x58, 0x51, 0xf8, 0x82, 0x50, 0x3c, 0x65, 0x41, 0x28, 0x1c, 0x40,
0x52, 0x54, 0x43, 0x72, 0x07, 0x5a, 0x68, 0x07, 0x2b, 0x92, 0x0b, 0x3f, 0xad, 0x98, 0x9b, 0x38, 0x29, 0xaa, 0x21, 0xb9, 0x05, 0x2d, 0xb4, 0x83, 0x15, 0xc9, 0x85, 0x9f, 0x56, 0xcc, 0x75, 0x9c,
0x79, 0xa6, 0x40, 0x3b, 0xd0, 0xf4, 0x0f, 0xfc, 0x18, 0x52, 0x46, 0x08, 0xf8, 0x07, 0xbe, 0x02, 0x3c, 0x51, 0xa0, 0x2d, 0x68, 0xfa, 0x7b, 0x7e, 0x0c, 0x29, 0x23, 0x04, 0xfc, 0x3d, 0x5f, 0x01,
0x18, 0xdf, 0x85, 0x6e, 0xde, 0x95, 0x48, 0x17, 0xca, 0x2f, 0xd9, 0xb9, 0xda, 0x4f, 0x7c, 0x92, 0x8c, 0x1f, 0x40, 0x37, 0xef, 0x4a, 0xa4, 0x0b, 0xe5, 0x17, 0xec, 0x4c, 0xbd, 0x4f, 0x3c, 0x92,
0x2d, 0x75, 0x2d, 0xdc, 0x43, 0x37, 0xd5, 0x1d, 0x3f, 0x2f, 0xc5, 0xca, 0xb1, 0x37, 0x91, 0x43, 0x0d, 0x75, 0x2c, 0x7c, 0x87, 0x6e, 0xaa, 0x33, 0x7e, 0x5e, 0x8a, 0x95, 0x63, 0x6f, 0x22, 0xfb,
0xa8, 0x88, 0xa0, 0x42, 0xed, 0xe6, 0x41, 0x7f, 0x20, 0x23, 0x6e, 0x10, 0x45, 0xdc, 0xe0, 0x59, 0x50, 0x11, 0x41, 0x85, 0xda, 0xcd, 0xbd, 0xfe, 0x40, 0x46, 0xdc, 0x20, 0x8a, 0xb8, 0xc1, 0xd3,
0x14, 0x71, 0xc3, 0xc6, 0x97, 0xaf, 0x76, 0x36, 0x3e, 0xff, 0xc3, 0x8e, 0x66, 0xa2, 0x06, 0xb9, 0x28, 0xe2, 0x86, 0x8d, 0x2f, 0x5f, 0x6d, 0xad, 0x7d, 0xfe, 0xa7, 0x2d, 0xcd, 0x44, 0x0d, 0x72,
0x29, 0x1c, 0x82, 0x3a, 0xae, 0xe5, 0xd8, 0x6a, 0x9f, 0x3a, 0x8e, 0x4f, 0x6c, 0x72, 0x04, 0xdd, 0x5d, 0x38, 0x04, 0x75, 0x5c, 0xcb, 0xb1, 0xd5, 0x7b, 0xea, 0x38, 0x3e, 0xb2, 0xc9, 0x01, 0x74,
0xb1, 0xe7, 0x86, 0xcc, 0x0d, 0x17, 0xa1, 0xe5, 0xd3, 0x80, 0xce, 0x43, 0x15, 0x6b, 0xd1, 0xcf, 0xc7, 0x9e, 0x1b, 0x32, 0x37, 0x5c, 0x84, 0x96, 0x4f, 0x03, 0x3a, 0x0f, 0x55, 0xac, 0x45, 0x9f,
0xff, 0x30, 0x12, 0x9f, 0xa2, 0xd4, 0xec, 0x8c, 0xb3, 0x13, 0xe4, 0x43, 0x80, 0x25, 0x9d, 0x39, 0xff, 0x41, 0x24, 0x3e, 0x46, 0xa9, 0xd9, 0x19, 0x67, 0x27, 0xc8, 0x87, 0x00, 0xa7, 0x74, 0xe6,
0x36, 0xe5, 0x5e, 0x10, 0xf6, 0x2a, 0xb7, 0xcb, 0x29, 0xe5, 0xb3, 0x48, 0xf0, 0xdc, 0xb7, 0x29, 0xd8, 0x94, 0x7b, 0x41, 0xd8, 0xab, 0xdc, 0x2c, 0xa7, 0x94, 0x4f, 0x22, 0xc1, 0x33, 0xdf, 0xa6,
0x67, 0xc3, 0x8a, 0x38, 0x99, 0x99, 0xc2, 0x93, 0xb7, 0xa0, 0x43, 0x7d, 0xdf, 0x0a, 0x39, 0xe5, 0x9c, 0x0d, 0x2b, 0x62, 0x67, 0x66, 0x0a, 0x4f, 0x6e, 0x43, 0x87, 0xfa, 0xbe, 0x15, 0x72, 0xca,
0xcc, 0x1a, 0x9d, 0x73, 0x16, 0x62, 0x3c, 0x6e, 0x9a, 0x2d, 0xea, 0xfb, 0x4f, 0xc5, 0xec, 0x50, 0x99, 0x35, 0x3a, 0xe3, 0x2c, 0xc4, 0x78, 0x5c, 0x37, 0x5b, 0xd4, 0xf7, 0x9f, 0x88, 0xd9, 0xa1,
0x4c, 0x1a, 0x76, 0xfc, 0x6b, 0x62, 0xa8, 0x10, 0x02, 0x15, 0x9b, 0x72, 0x8a, 0xd6, 0xd8, 0x34, 0x98, 0x34, 0xec, 0xf8, 0x6b, 0x62, 0xa8, 0x10, 0x02, 0x15, 0x9b, 0x72, 0x8a, 0xd6, 0x58, 0x37,
0xf1, 0x5b, 0xcc, 0xf9, 0x94, 0x4f, 0xd5, 0x1d, 0xf1, 0x9b, 0x5c, 0x87, 0xda, 0x94, 0x39, 0x93, 0xf1, 0x59, 0xcc, 0xf9, 0x94, 0x4f, 0xd5, 0x19, 0xf1, 0x99, 0x5c, 0x85, 0xda, 0x94, 0x39, 0x93,
0x29, 0xc7, 0x6b, 0x95, 0x4d, 0x35, 0x12, 0x86, 0xf7, 0x03, 0x6f, 0xc9, 0x30, 0x5b, 0x34, 0x4c, 0x29, 0xc7, 0x63, 0x95, 0x4d, 0x35, 0x12, 0x86, 0xf7, 0x03, 0xef, 0x94, 0x61, 0xb6, 0x68, 0x98,
0x39, 0x30, 0xfe, 0xa2, 0xc1, 0x95, 0x4b, 0xe1, 0x25, 0xd6, 0x9d, 0xd2, 0x70, 0x1a, 0xed, 0x25, 0x72, 0x60, 0xfc, 0x4d, 0x83, 0x4b, 0x17, 0xc2, 0x4b, 0xac, 0x3b, 0xa5, 0xe1, 0x34, 0x7a, 0x97,
0xbe, 0xc9, 0x3b, 0x62, 0x5d, 0x6a, 0xb3, 0x40, 0x65, 0xb1, 0x96, 0xba, 0xf1, 0x31, 0x4e, 0xaa, 0x78, 0x26, 0xef, 0x88, 0x75, 0xa9, 0xcd, 0x02, 0x95, 0xc5, 0x5a, 0xea, 0xc4, 0x87, 0x38, 0xa9,
0x8b, 0x2a, 0x08, 0x79, 0x0c, 0xdd, 0x19, 0x0d, 0xb9, 0x25, 0xa3, 0xc0, 0xc2, 0x2c, 0x55, 0xce, 0x0e, 0xaa, 0x20, 0xe4, 0x11, 0x74, 0x67, 0x34, 0xe4, 0x96, 0x8c, 0x02, 0x0b, 0xb3, 0x54, 0x39,
0x44, 0xe6, 0x13, 0x1a, 0x45, 0x8b, 0x70, 0x4e, 0xa5, 0xde, 0x9e, 0x65, 0x66, 0xc9, 0x31, 0x6c, 0x13, 0x99, 0x8f, 0x69, 0x14, 0x2d, 0xc2, 0x39, 0x95, 0x7a, 0x7b, 0x96, 0x99, 0x25, 0x87, 0xb0,
0x8d, 0xce, 0x7f, 0x4e, 0x5d, 0xee, 0xb8, 0xcc, 0xba, 0x64, 0xf3, 0x8e, 0x5a, 0xea, 0xf1, 0xd2, 0x31, 0x3a, 0xfb, 0x25, 0x75, 0xb9, 0xe3, 0x32, 0xeb, 0x82, 0xcd, 0x3b, 0x6a, 0xa9, 0x47, 0xa7,
0xb1, 0x99, 0x3b, 0x8e, 0x8c, 0x7d, 0x35, 0x56, 0x89, 0x7f, 0x8c, 0xd0, 0xb8, 0x0d, 0xed, 0x6c, 0x8e, 0xcd, 0xdc, 0x71, 0x64, 0xec, 0xcb, 0xb1, 0x4a, 0xfc, 0x31, 0x42, 0xe3, 0x10, 0xda, 0xd9,
0x2e, 0x20, 0x6d, 0x28, 0xf1, 0x95, 0xba, 0x61, 0x89, 0xaf, 0x0c, 0x23, 0xf6, 0xc0, 0x38, 0x20, 0x5c, 0x40, 0xda, 0x50, 0xe2, 0x4b, 0x75, 0xc2, 0x12, 0x5f, 0x92, 0xdb, 0x50, 0x11, 0xcb, 0xe1,
0x2f, 0x61, 0xf6, 0xa0, 0x93, 0x4b, 0x0e, 0x29, 0x73, 0x6b, 0x69, 0x73, 0x1b, 0x1d, 0x68, 0x65, 0xe9, 0xda, 0x71, 0x32, 0x55, 0xe8, 0xa7, 0x67, 0x3e, 0x33, 0x51, 0x6e, 0x18, 0xb1, 0xa7, 0xc6,
0x72, 0x82, 0xf1, 0x59, 0x15, 0x1a, 0x26, 0x0b, 0x7d, 0xe1, 0x4c, 0xe4, 0x10, 0x74, 0xb6, 0x1a, 0x81, 0x9b, 0x5f, 0xcb, 0xd8, 0x81, 0x4e, 0x2e, 0x89, 0xa4, 0x3e, 0x8b, 0x96, 0xfe, 0x2c, 0x46,
0x33, 0x99, 0x8e, 0xb5, 0x5c, 0xb2, 0x93, 0x98, 0xc7, 0x91, 0x5c, 0xa4, 0x85, 0x18, 0x4c, 0xf6, 0x07, 0x5a, 0x99, 0xdc, 0x61, 0x7c, 0x56, 0x85, 0x86, 0xc9, 0x42, 0x5f, 0x38, 0x1d, 0xd9, 0x07,
0x32, 0x54, 0x72, 0x35, 0xaf, 0x94, 0xe6, 0x92, 0xbb, 0x59, 0x2e, 0xd9, 0xca, 0x61, 0x73, 0x64, 0x9d, 0x2d, 0xc7, 0x4c, 0xa6, 0x6d, 0x2d, 0x97, 0x14, 0x25, 0xe6, 0x51, 0x24, 0x17, 0xe9, 0x23,
0xb2, 0x97, 0x21, 0x93, 0xfc, 0xc2, 0x19, 0x36, 0xb9, 0x5f, 0xc0, 0x26, 0xf9, 0xe3, 0xaf, 0xa1, 0x06, 0x93, 0x9d, 0x0c, 0xe5, 0x5c, 0xce, 0x2b, 0xa5, 0x39, 0xe7, 0x4e, 0x96, 0x73, 0x36, 0x72,
0x93, 0xfb, 0x05, 0x74, 0xd2, 0xbb, 0xb4, 0x57, 0x21, 0x9f, 0xdc, 0xcd, 0xf2, 0x49, 0xfe, 0x3a, 0xd8, 0x1c, 0xe9, 0xec, 0x64, 0x48, 0x27, 0xbf, 0x70, 0x86, 0x75, 0xee, 0x15, 0xb0, 0x4e, 0x7e,
0x39, 0x42, 0xf9, 0xb0, 0x88, 0x50, 0x6e, 0xe6, 0x74, 0xd6, 0x32, 0xca, 0x07, 0x97, 0x18, 0xe5, 0xfb, 0x2b, 0x68, 0xe7, 0x5e, 0x01, 0xed, 0xf4, 0x2e, 0xbc, 0xab, 0x90, 0x77, 0xee, 0x64, 0x79,
0x7a, 0x4e, 0xb5, 0x80, 0x52, 0xee, 0x67, 0x72, 0x3d, 0x14, 0xde, 0xad, 0x38, 0xd9, 0x93, 0xef, 0x27, 0x7f, 0x9c, 0x1c, 0xf1, 0x7c, 0x58, 0x44, 0x3c, 0xd7, 0x73, 0x3a, 0x2b, 0x99, 0xe7, 0x83,
0x5c, 0x66, 0xa3, 0x1b, 0xf9, 0x9f, 0xb6, 0x88, 0x8e, 0xf6, 0x73, 0x74, 0x74, 0x2d, 0x7f, 0xca, 0x0b, 0xcc, 0x73, 0x35, 0xa7, 0x5a, 0x40, 0x3d, 0xf7, 0x32, 0x9c, 0x00, 0x85, 0x67, 0x2b, 0x26,
0x1c, 0x1f, 0x25, 0xac, 0xb2, 0x27, 0xe2, 0x3e, 0xe7, 0x69, 0x22, 0x47, 0xb0, 0x20, 0xf0, 0x02, 0x05, 0xf2, 0xfd, 0x8b, 0xac, 0x75, 0x2d, 0xff, 0x69, 0x8b, 0x68, 0x6b, 0x37, 0x47, 0x5b, 0x57,
0x95, 0xb0, 0xe5, 0xc0, 0xd8, 0x15, 0x99, 0x28, 0xf1, 0xaf, 0xd7, 0x30, 0x10, 0x3a, 0x7d, 0xca, 0xf2, 0xbb, 0xcc, 0xf1, 0x56, 0xc2, 0x3e, 0x3b, 0x22, 0x3f, 0xe4, 0x3c, 0x4d, 0xe4, 0x12, 0x16,
0xbb, 0x8c, 0x2f, 0xb4, 0x44, 0x17, 0x23, 0x3a, 0x9d, 0xc5, 0x74, 0x95, 0xc5, 0x52, 0xc4, 0x54, 0x04, 0x5e, 0xa0, 0x12, 0xbb, 0x1c, 0x18, 0xdb, 0x22, 0x63, 0x25, 0xfe, 0xf5, 0x1a, 0xa6, 0x42,
0xca, 0x12, 0xd3, 0x0e, 0x34, 0x45, 0xae, 0xcc, 0x71, 0x0e, 0xf5, 0x23, 0xce, 0x21, 0xdf, 0x82, 0xa7, 0x4f, 0x79, 0x97, 0xf1, 0x85, 0x96, 0xe8, 0x62, 0xe4, 0xa7, 0xb3, 0x9d, 0xae, 0xb2, 0x5d,
0x2b, 0x98, 0x67, 0x24, 0x7d, 0xa9, 0x40, 0xac, 0x60, 0x20, 0x76, 0x84, 0x40, 0x5a, 0x4c, 0x26, 0x8a, 0xc0, 0x4a, 0x59, 0x02, 0xdb, 0x82, 0xa6, 0xc8, 0xa9, 0x39, 0x6e, 0xa2, 0x7e, 0xc4, 0x4d,
0xc0, 0x77, 0xe1, 0x6a, 0x0a, 0x2b, 0xd6, 0xc5, 0x1c, 0x27, 0x93, 0x6f, 0x37, 0x46, 0x1f, 0xf9, 0xe4, 0x6d, 0xb8, 0x84, 0xf9, 0x48, 0xd2, 0x9c, 0x0a, 0xc4, 0x0a, 0x06, 0x62, 0x47, 0x08, 0xa4,
0xfe, 0x31, 0x0d, 0xa7, 0xc6, 0x0f, 0x13, 0x03, 0x25, 0x7c, 0x46, 0xa0, 0x32, 0xf6, 0x6c, 0x79, 0xc5, 0x64, 0xa2, 0x7c, 0x17, 0x2e, 0xa7, 0xb0, 0x62, 0x5d, 0xcc, 0x85, 0x32, 0x49, 0x77, 0x63,
0xef, 0x96, 0x89, 0xdf, 0x82, 0xe3, 0x66, 0xde, 0x04, 0x0f, 0xa7, 0x9b, 0xe2, 0x53, 0xa0, 0xe2, 0xf4, 0x81, 0xef, 0x1f, 0xd2, 0x70, 0x6a, 0xfc, 0x24, 0x31, 0x50, 0xc2, 0x7b, 0x04, 0x2a, 0x63,
0x50, 0xd2, 0x65, 0xcc, 0x18, 0xbf, 0xd4, 0x92, 0xf5, 0x12, 0x8a, 0x2b, 0x62, 0x23, 0xed, 0x3f, 0xcf, 0x96, 0xe7, 0x6e, 0x99, 0xf8, 0x2c, 0xb8, 0x70, 0xe6, 0x4d, 0x70, 0x73, 0xba, 0x29, 0x1e,
0x61, 0xa3, 0xd2, 0xd7, 0x63, 0x23, 0xe3, 0x42, 0x4b, 0x7e, 0xb2, 0x98, 0x67, 0xde, 0xec, 0x8a, 0x05, 0x2a, 0x0e, 0x25, 0x5d, 0xc6, 0x8c, 0xf1, 0x6b, 0x2d, 0x59, 0x2f, 0xa1, 0xc2, 0x22, 0xd6,
0xc2, 0x7b, 0x1c, 0xd7, 0x66, 0x2b, 0x34, 0x69, 0xd9, 0x94, 0x83, 0xa8, 0x04, 0xa8, 0xa1, 0x99, 0xd2, 0xfe, 0x17, 0xd6, 0x2a, 0x7d, 0x3d, 0xd6, 0x32, 0xce, 0xb5, 0xe4, 0x93, 0xc5, 0x7c, 0xf4,
0xb3, 0x25, 0x40, 0x1d, 0xe7, 0xe4, 0x80, 0xdc, 0x41, 0x7e, 0xf2, 0x5e, 0xa8, 0x50, 0x6d, 0x0d, 0x66, 0x47, 0x14, 0xde, 0xe3, 0xb8, 0x36, 0x5b, 0xa2, 0x49, 0xcb, 0xa6, 0x1c, 0x44, 0xa5, 0x42,
0x54, 0xa1, 0x7e, 0x2a, 0x26, 0x4d, 0x29, 0x4b, 0x65, 0x5b, 0x3d, 0x43, 0x6e, 0xb7, 0x40, 0x17, 0x0d, 0xcd, 0x9c, 0x2d, 0x15, 0xea, 0x38, 0x27, 0x07, 0xe4, 0x16, 0xf2, 0x98, 0xf7, 0x5c, 0x85,
0x07, 0x0d, 0x7d, 0x3a, 0x66, 0x18, 0x79, 0xba, 0x99, 0x4c, 0x18, 0xcf, 0x80, 0x5c, 0x8e, 0x78, 0x6a, 0x6b, 0xa0, 0x0a, 0xfa, 0x63, 0x31, 0x69, 0x4a, 0x59, 0x2a, 0xdb, 0xea, 0x19, 0x12, 0xbc,
0xf2, 0x11, 0xd4, 0xd8, 0x92, 0xb9, 0x5c, 0x58, 0x5c, 0x18, 0x6d, 0x33, 0xa6, 0x13, 0xe6, 0xf2, 0x01, 0xba, 0xd8, 0x68, 0xe8, 0xd3, 0x31, 0xc3, 0xc8, 0xd3, 0xcd, 0x64, 0xc2, 0x78, 0x0a, 0xe4,
0x61, 0x4f, 0x98, 0xea, 0xaf, 0xaf, 0x76, 0xba, 0x12, 0x73, 0xd7, 0x9b, 0x3b, 0x9c, 0xcd, 0x7d, 0x62, 0xc4, 0x93, 0x8f, 0xa0, 0xc6, 0x4e, 0x99, 0xcb, 0x85, 0xc5, 0x85, 0xd1, 0xd6, 0x63, 0xda,
0x7e, 0x6e, 0x2a, 0x2d, 0xe3, 0xef, 0x9a, 0x60, 0x83, 0x4c, 0x36, 0x28, 0x34, 0x5e, 0xe4, 0xf2, 0x61, 0x2e, 0x1f, 0xf6, 0x84, 0xa9, 0xfe, 0xfe, 0x6a, 0xab, 0x2b, 0x31, 0x77, 0xbc, 0xb9, 0xc3,
0xa5, 0x14, 0x71, 0x7f, 0x35, 0x83, 0xfe, 0x3f, 0xc0, 0x84, 0x86, 0xd6, 0xa7, 0xd4, 0xe5, 0xcc, 0xd9, 0xdc, 0xe7, 0x67, 0xa6, 0xd2, 0x32, 0xfe, 0xa9, 0x09, 0x36, 0xc8, 0x64, 0x83, 0x42, 0xe3,
0x56, 0x56, 0xd5, 0x27, 0x34, 0xfc, 0x29, 0x4e, 0x88, 0x2a, 0x47, 0x88, 0x17, 0x21, 0xb3, 0xd1, 0x45, 0x2e, 0x5f, 0x4a, 0x11, 0xfc, 0x57, 0x33, 0xe8, 0xb7, 0x01, 0x26, 0x34, 0xb4, 0x5e, 0x52,
0xbc, 0x65, 0xb3, 0x3e, 0xa1, 0xe1, 0xf3, 0x90, 0xd9, 0xa9, 0xbb, 0xd5, 0xdf, 0xe4, 0x6e, 0x59, 0x97, 0x33, 0x5b, 0x59, 0x55, 0x9f, 0xd0, 0xf0, 0xe7, 0x38, 0x21, 0xaa, 0x21, 0x21, 0x5e, 0x84,
0x7b, 0x36, 0xf2, 0xf6, 0xfc, 0x67, 0xca, 0x97, 0x13, 0xb2, 0xfc, 0xdf, 0xb8, 0xfb, 0xdf, 0x34, 0xcc, 0x46, 0xf3, 0x96, 0xcd, 0xfa, 0x84, 0x86, 0xcf, 0x42, 0x66, 0xa7, 0xce, 0x56, 0x7f, 0x93,
0x51, 0x27, 0x64, 0x53, 0x32, 0x39, 0x81, 0x2b, 0x71, 0x4c, 0x59, 0x0b, 0x8c, 0xb5, 0xc8, 0xab, 0xb3, 0x65, 0xed, 0xd9, 0xc8, 0xdb, 0xf3, 0xdf, 0x29, 0x5f, 0x4e, 0xc8, 0xf2, 0x9b, 0x71, 0xf6,
0x5e, 0x1f, 0x8a, 0xdd, 0x65, 0x76, 0x3a, 0x24, 0x3f, 0x82, 0x1b, 0xb9, 0x8c, 0x10, 0x2f, 0x58, 0x7f, 0x68, 0xa2, 0x4e, 0xc8, 0xa6, 0x64, 0x72, 0x04, 0x97, 0xe2, 0x98, 0xb2, 0x16, 0x18, 0x6b,
0x7a, 0x6d, 0x62, 0xb8, 0x96, 0x4d, 0x0c, 0xd1, 0x7a, 0x89, 0x35, 0xca, 0x6f, 0xe4, 0xe5, 0xdf, 0x91, 0x57, 0xbd, 0x3e, 0x14, 0xbb, 0xa7, 0xd9, 0xe9, 0x90, 0x7c, 0x02, 0xd7, 0x72, 0x19, 0x21,
0x10, 0x85, 0x53, 0x9a, 0x4c, 0x8a, 0x7e, 0x53, 0xe3, 0x57, 0x1a, 0x74, 0x72, 0x07, 0x22, 0xbb, 0x5e, 0xb0, 0xf4, 0xda, 0xc4, 0x70, 0x25, 0x9b, 0x18, 0xa2, 0xf5, 0x12, 0x6b, 0x94, 0xdf, 0xc8,
0x50, 0x95, 0x7c, 0xa6, 0x65, 0xda, 0x53, 0xb4, 0x98, 0x3a, 0xb3, 0x04, 0x90, 0xf7, 0xa1, 0xc1, 0xcb, 0xbf, 0x23, 0x0a, 0xac, 0x34, 0x99, 0x14, 0x7d, 0x53, 0xe3, 0x37, 0x1a, 0x74, 0x72, 0x1b,
0x54, 0x0d, 0xa7, 0x2e, 0x79, 0x2d, 0x57, 0xda, 0x29, 0x7c, 0x0c, 0x23, 0xdf, 0x06, 0x3d, 0x36, 0x22, 0xdb, 0x50, 0x95, 0x7c, 0xa6, 0x65, 0xda, 0x58, 0xb4, 0x98, 0xda, 0xb3, 0x04, 0x90, 0xf7,
0x5d, 0xae, 0x7e, 0x8f, 0x2d, 0xad, 0x94, 0x12, 0xa0, 0xf1, 0x10, 0x9a, 0xa9, 0xed, 0xc9, 0xff, 0xa1, 0xc1, 0x54, 0xad, 0xa7, 0x0e, 0x79, 0x25, 0x57, 0x02, 0x2a, 0x7c, 0x0c, 0x23, 0xdf, 0x03,
0x81, 0x3e, 0xa7, 0x2b, 0x55, 0x84, 0xcb, 0xf2, 0xad, 0x31, 0xa7, 0x2b, 0xac, 0xbf, 0xc9, 0x0d, 0x3d, 0x36, 0x5d, 0xae, 0xce, 0x8f, 0x2d, 0xad, 0x94, 0x12, 0xa0, 0xf1, 0x00, 0x9a, 0xa9, 0xd7,
0xa8, 0x0b, 0xe1, 0x84, 0x4a, 0xc3, 0x97, 0xcd, 0xda, 0x9c, 0xae, 0x7e, 0x40, 0x43, 0x63, 0x0f, 0x93, 0x6f, 0x81, 0x3e, 0xa7, 0x4b, 0x55, 0xac, 0xcb, 0xf2, 0xad, 0x31, 0xa7, 0x4b, 0xac, 0xd3,
0xda, 0xd9, 0x63, 0x45, 0xd0, 0x88, 0x10, 0x25, 0xf4, 0x68, 0xc2, 0x8c, 0x7b, 0xd0, 0xc9, 0x9d, 0xc9, 0x35, 0xa8, 0x0b, 0xe1, 0x84, 0x4a, 0xc3, 0x97, 0xcd, 0xda, 0x9c, 0x2e, 0x7f, 0x4c, 0x43,
0x86, 0x18, 0xd0, 0xf2, 0x17, 0x23, 0xeb, 0x25, 0x3b, 0xb7, 0xf0, 0xb8, 0xe8, 0x26, 0xba, 0xd9, 0x63, 0x07, 0xda, 0xd9, 0x6d, 0x45, 0xd0, 0x88, 0x10, 0x25, 0xf4, 0x60, 0xc2, 0x8c, 0xbb, 0xd0,
0xf4, 0x17, 0xa3, 0x8f, 0xd9, 0xf9, 0x33, 0x31, 0x65, 0x3c, 0x85, 0x76, 0xb6, 0x3c, 0x16, 0x29, 0xc9, 0xed, 0x86, 0x18, 0xd0, 0xf2, 0x17, 0x23, 0xeb, 0x05, 0x3b, 0xb3, 0x70, 0xbb, 0xe8, 0x26,
0x33, 0xf0, 0x16, 0xae, 0x8d, 0xeb, 0x57, 0x4d, 0x39, 0x10, 0x1d, 0xf6, 0xd2, 0x93, 0x9e, 0x91, 0xba, 0xd9, 0xf4, 0x17, 0xa3, 0x8f, 0xd9, 0x99, 0xa8, 0x47, 0x43, 0xe3, 0x09, 0xb4, 0xb3, 0x65,
0xae, 0x87, 0xcf, 0x3c, 0xce, 0x52, 0x45, 0xb5, 0xc4, 0x18, 0x0e, 0x54, 0xf1, 0x37, 0x17, 0xbf, 0xb4, 0x48, 0x99, 0x81, 0xb7, 0x70, 0x6d, 0x5c, 0xbf, 0x6a, 0xca, 0x81, 0xe8, 0xc4, 0x4f, 0x3d,
0x9f, 0xc0, 0x45, 0x14, 0x2c, 0xbe, 0xc9, 0x13, 0x00, 0xca, 0x79, 0xe0, 0x8c, 0x16, 0xc9, 0x72, 0xe9, 0x19, 0xe9, 0xba, 0xf9, 0xc4, 0xe3, 0x2c, 0x55, 0x7c, 0x4b, 0x8c, 0xe1, 0x40, 0x15, 0xbf,
0xed, 0x81, 0x7c, 0xf6, 0x18, 0x7c, 0x7c, 0x76, 0x4a, 0x9d, 0x60, 0x78, 0x4b, 0xf9, 0xca, 0x56, 0xb9, 0xf8, 0x7e, 0x58, 0x10, 0x2b, 0x0a, 0x16, 0xcf, 0xe4, 0x31, 0x00, 0xe5, 0x3c, 0x70, 0x46,
0x82, 0x4c, 0xf9, 0x4b, 0x4a, 0xdf, 0xf8, 0x45, 0x15, 0x6a, 0xb2, 0x2d, 0x20, 0x83, 0x6c, 0xd3, 0x8b, 0x64, 0xb9, 0xf6, 0x40, 0x5e, 0x8f, 0x0c, 0x3e, 0x3e, 0x39, 0xa6, 0x4e, 0x30, 0xbc, 0xa1,
0x29, 0x56, 0x55, 0x87, 0x94, 0xb3, 0xea, 0x8c, 0x31, 0xe3, 0xbf, 0x95, 0xef, 0xdc, 0x86, 0xcd, 0x7c, 0x65, 0x23, 0x41, 0xa6, 0xfc, 0x25, 0xa5, 0x6f, 0xfc, 0xaa, 0x0a, 0x35, 0xd9, 0x3e, 0x90,
0x8b, 0x57, 0x3b, 0x75, 0x64, 0xcb, 0x93, 0x47, 0x49, 0x1b, 0xb7, 0xae, 0xcb, 0x89, 0x7a, 0xc6, 0x41, 0xb6, 0x39, 0x15, 0xab, 0xaa, 0x4d, 0xca, 0x59, 0xb5, 0xc7, 0x98, 0xf1, 0x6f, 0xe7, 0x3b,
0xca, 0xd7, 0xee, 0x19, 0x6f, 0x40, 0xdd, 0x5d, 0xcc, 0x2d, 0xbe, 0x0a, 0x55, 0xb6, 0xa9, 0xb9, 0xbc, 0x61, 0xf3, 0xfc, 0xd5, 0x56, 0x1d, 0xd9, 0xf2, 0xe8, 0x61, 0xd2, 0xee, 0xad, 0xea, 0x86,
0x8b, 0xf9, 0xb3, 0x15, 0x7a, 0x09, 0xf7, 0x38, 0x9d, 0xa1, 0x48, 0xe6, 0x9a, 0x06, 0x4e, 0x08, 0xa2, 0xde, 0xb2, 0xf2, 0xb5, 0x7b, 0xcb, 0x6b, 0x50, 0x77, 0x17, 0x73, 0x8b, 0x2f, 0x43, 0x95,
0xe1, 0x21, 0xb4, 0x52, 0x45, 0x85, 0x63, 0xab, 0xe2, 0xb4, 0x9d, 0x76, 0xf6, 0x93, 0x47, 0xea, 0x6d, 0x6a, 0xee, 0x62, 0xfe, 0x74, 0x89, 0x5e, 0xc2, 0x3d, 0x4e, 0x67, 0x28, 0x92, 0xb9, 0xa6,
0x96, 0xcd, 0xb8, 0xc8, 0x38, 0xb1, 0xc9, 0x6e, 0xb6, 0x45, 0xc2, 0x5a, 0xa4, 0x81, 0x21, 0x95, 0x81, 0x13, 0x42, 0xb8, 0x0f, 0xad, 0x54, 0x51, 0xe1, 0xd8, 0xaa, 0x38, 0x6d, 0xa7, 0x9d, 0xfd,
0xea, 0x82, 0x44, 0x25, 0x22, 0x0e, 0x20, 0x82, 0x4c, 0x42, 0x74, 0x84, 0x34, 0xc4, 0x04, 0x0a, 0xe8, 0xa1, 0x3a, 0x65, 0x33, 0x2e, 0x32, 0x8e, 0x6c, 0xb2, 0x9d, 0x6d, 0xa5, 0xb0, 0x16, 0x69,
0xdf, 0x86, 0x4e, 0x42, 0xe7, 0x12, 0x02, 0x72, 0x95, 0x64, 0x1a, 0x81, 0xef, 0xc1, 0x96, 0xcb, 0x60, 0x48, 0xa5, 0xba, 0x25, 0x51, 0x89, 0x88, 0x0d, 0x88, 0x20, 0x93, 0x10, 0x1d, 0x21, 0x0d,
0x56, 0xdc, 0xca, 0xa3, 0x9b, 0x88, 0x26, 0x42, 0x76, 0x96, 0xd5, 0xf8, 0x26, 0xb4, 0x93, 0x54, 0x31, 0x81, 0xc2, 0xb7, 0xa0, 0x93, 0xd0, 0xb9, 0x84, 0x80, 0x5c, 0x25, 0x99, 0x46, 0xe0, 0x7b,
0x84, 0xd8, 0x4d, 0xd9, 0xa8, 0xc6, 0xb3, 0x08, 0xbb, 0x09, 0x8d, 0xb8, 0x98, 0x6a, 0x21, 0xa0, 0xb0, 0xe1, 0xb2, 0x25, 0xb7, 0xf2, 0xe8, 0x26, 0xa2, 0x89, 0x90, 0x9d, 0x64, 0x35, 0xbe, 0x0b,
0x4e, 0x65, 0x0d, 0x15, 0x97, 0x67, 0x01, 0x0b, 0x17, 0x33, 0xae, 0x16, 0x69, 0x23, 0x06, 0xcb, 0xed, 0x24, 0x15, 0x21, 0x76, 0x5d, 0x36, 0xb4, 0xf1, 0x2c, 0xc2, 0xae, 0x43, 0x23, 0x2e, 0xa6,
0x33, 0x53, 0xce, 0x23, 0xf6, 0x0e, 0xb4, 0xa2, 0xe8, 0x96, 0xb8, 0x0e, 0xe2, 0x36, 0xa3, 0x49, 0x5a, 0x08, 0xa8, 0x53, 0x59, 0x43, 0xc5, 0xe5, 0x59, 0xc0, 0xc2, 0xc5, 0x8c, 0xab, 0x45, 0xda,
0x04, 0xed, 0x41, 0xd7, 0x0f, 0x3c, 0xdf, 0x0b, 0x59, 0x60, 0x51, 0xdb, 0x0e, 0x58, 0x18, 0xf6, 0x88, 0xc1, 0xf2, 0xcc, 0x94, 0xf3, 0x88, 0xbd, 0x05, 0xad, 0x28, 0xba, 0x25, 0xae, 0x83, 0xb8,
0xba, 0x72, 0xbd, 0x68, 0xfe, 0x48, 0x4e, 0x1b, 0xef, 0x43, 0x3d, 0xaa, 0x12, 0xb7, 0xa0, 0x3a, 0xf5, 0x68, 0x12, 0x41, 0x3b, 0xd0, 0xf5, 0x03, 0xcf, 0xf7, 0x42, 0x16, 0x58, 0xd4, 0xb6, 0x03,
0x8c, 0x33, 0x51, 0xc5, 0x94, 0x03, 0xc1, 0x43, 0x47, 0xbe, 0xaf, 0xde, 0x3a, 0xc4, 0xa7, 0xf1, 0x16, 0x86, 0xbd, 0xae, 0x5c, 0x2f, 0x9a, 0x3f, 0x90, 0xd3, 0xc6, 0xfb, 0x50, 0x8f, 0xaa, 0xc4,
0x33, 0xa8, 0xab, 0x1f, 0xac, 0xb0, 0x03, 0xfe, 0x1e, 0x6c, 0xfa, 0x34, 0x10, 0xd7, 0x48, 0xf7, 0x0d, 0xa8, 0x0e, 0xe3, 0x4c, 0x54, 0x31, 0xe5, 0x40, 0xf0, 0xd0, 0x81, 0xef, 0xab, 0x3b, 0x11,
0xc1, 0x51, 0x1f, 0x72, 0x4a, 0x03, 0xfe, 0x94, 0xf1, 0x4c, 0x3b, 0xdc, 0x44, 0xbc, 0x9c, 0x32, 0xf1, 0x68, 0xfc, 0x02, 0xea, 0xea, 0x83, 0x15, 0x76, 0xca, 0x3f, 0x84, 0x75, 0x9f, 0x06, 0xe2,
0xee, 0x43, 0x2b, 0x83, 0x11, 0xc7, 0x42, 0x3f, 0x8a, 0x82, 0x1a, 0x07, 0xf1, 0xce, 0xa5, 0x64, 0x18, 0xe9, 0x7e, 0x39, 0xea, 0x43, 0x8e, 0x69, 0xc0, 0x9f, 0x30, 0x9e, 0x69, 0x9b, 0x9b, 0x88,
0x67, 0xe3, 0x01, 0xe8, 0xf1, 0x6f, 0x23, 0xca, 0xe5, 0xe8, 0xea, 0x9a, 0x32, 0xb7, 0x1c, 0x62, 0x97, 0x53, 0xc6, 0x3d, 0x68, 0x65, 0x30, 0x62, 0x5b, 0xe8, 0x47, 0x51, 0x50, 0xe3, 0x20, 0x7e,
0x8b, 0xef, 0x7d, 0xca, 0x02, 0x15, 0x13, 0x72, 0x60, 0x3c, 0x4f, 0x25, 0x21, 0xc9, 0x0a, 0xe4, 0x73, 0x29, 0x79, 0xb3, 0x71, 0x1f, 0xf4, 0xf8, 0xdb, 0x88, 0x72, 0x39, 0x3a, 0xba, 0xa6, 0xcc,
0x2e, 0xd4, 0x55, 0x12, 0x52, 0x51, 0x19, 0x35, 0xf3, 0xa7, 0x98, 0x85, 0xa2, 0x66, 0x5e, 0xe6, 0x2d, 0x87, 0x78, 0x15, 0xe0, 0xbd, 0x64, 0x81, 0x8a, 0x09, 0x39, 0x30, 0x9e, 0xa5, 0x92, 0x90,
0xa4, 0x64, 0xd9, 0x52, 0x7a, 0xd9, 0x19, 0x34, 0xa2, 0x44, 0x93, 0xcd, 0xc6, 0x72, 0xc5, 0x6e, 0x64, 0x05, 0x72, 0x07, 0xea, 0x2a, 0x09, 0xa9, 0xa8, 0x8c, 0x9a, 0xfe, 0x63, 0xcc, 0x42, 0x51,
0x3e, 0x1b, 0xab, 0x45, 0x13, 0xa0, 0xf0, 0x8e, 0xd0, 0x99, 0xb8, 0xcc, 0xb6, 0x92, 0x10, 0xc2, 0xd3, 0x2f, 0x73, 0x52, 0xb2, 0x6c, 0x29, 0xbd, 0xec, 0x0c, 0x1a, 0x51, 0xa2, 0xc9, 0x66, 0x63,
0x3d, 0x1a, 0x66, 0x47, 0x0a, 0x9e, 0x44, 0xf1, 0x62, 0xbc, 0x07, 0x35, 0x79, 0xb6, 0xc2, 0xf4, 0xb9, 0x62, 0x37, 0x9f, 0x8d, 0xd5, 0xa2, 0x09, 0x50, 0x78, 0x47, 0xe8, 0x4c, 0x5c, 0x66, 0x5b,
0x55, 0x44, 0x49, 0xbf, 0xd7, 0xa0, 0x11, 0xe5, 0xe9, 0x42, 0xa5, 0xcc, 0xa1, 0x4b, 0x5f, 0xf5, 0x49, 0x08, 0xe1, 0x3b, 0x1a, 0x66, 0x47, 0x0a, 0x1e, 0x47, 0xf1, 0x62, 0xbc, 0x07, 0x35, 0xb9,
0xd0, 0xff, 0xfd, 0xc4, 0x73, 0x17, 0x88, 0xcc, 0x2f, 0x4b, 0x8f, 0x3b, 0xee, 0xc4, 0x92, 0xb6, 0xb7, 0xc2, 0xf4, 0x55, 0x44, 0x49, 0x7f, 0xd4, 0xa0, 0x11, 0xe5, 0xe9, 0x42, 0xa5, 0xcc, 0xa6,
0x96, 0x39, 0xa8, 0x8b, 0x92, 0x33, 0x14, 0x9c, 0x8a, 0xf9, 0x83, 0xcf, 0xaa, 0xd0, 0x39, 0x1a, 0x4b, 0x5f, 0x75, 0xd3, 0xff, 0xff, 0xc4, 0x73, 0x07, 0x88, 0xcc, 0x2f, 0xa7, 0x1e, 0x77, 0xdc,
0x3e, 0x3c, 0x39, 0xf2, 0xfd, 0x99, 0x33, 0xa6, 0xd8, 0x95, 0xec, 0x43, 0x05, 0x1b, 0xb3, 0x82, 0x89, 0x25, 0x6d, 0x2d, 0x73, 0x50, 0x17, 0x25, 0x27, 0x28, 0x38, 0x16, 0xf3, 0x6f, 0xdf, 0x82,
0x87, 0xe5, 0x7e, 0xd1, 0x0b, 0x01, 0x39, 0x80, 0x2a, 0xf6, 0x67, 0xa4, 0xe8, 0x7d, 0xb9, 0x5f, 0x66, 0xea, 0xee, 0x82, 0xd4, 0xa1, 0xfc, 0x09, 0x7b, 0xd9, 0x5d, 0x23, 0x4d, 0xa8, 0x9b, 0x0c,
0xf8, 0x50, 0x20, 0x36, 0x91, 0x1d, 0xdc, 0xe5, 0x67, 0xe6, 0x7e, 0xd1, 0x6b, 0x01, 0xf9, 0x08, 0x3b, 0xd1, 0xae, 0xb6, 0xf7, 0x59, 0x15, 0x3a, 0x07, 0xc3, 0x07, 0x47, 0x07, 0xbe, 0x3f, 0x73,
0xf4, 0xa4, 0x71, 0x5a, 0xf7, 0xd8, 0xdc, 0x5f, 0xfb, 0x6e, 0x20, 0xf4, 0x93, 0xe2, 0x72, 0xdd, 0xc6, 0x14, 0x5b, 0x97, 0x5d, 0xa8, 0x60, 0xf7, 0x56, 0x70, 0x4b, 0xdd, 0x2f, 0xba, 0x46, 0x20,
0x9b, 0x69, 0x7f, 0x6d, 0x83, 0x4d, 0x0e, 0xa1, 0x1e, 0x95, 0xe5, 0xc5, 0xcf, 0xc1, 0xfd, 0x35, 0x7b, 0x50, 0xc5, 0x26, 0x8e, 0x14, 0x5d, 0x56, 0xf7, 0x0b, 0x6f, 0x13, 0xc4, 0x4b, 0x64, 0x9b,
0x3d, 0xbd, 0x30, 0x8f, 0xec, 0x85, 0x8a, 0xde, 0xac, 0xfb, 0x85, 0x0f, 0x0f, 0xe4, 0x1e, 0xd4, 0x77, 0xf1, 0xce, 0xba, 0x5f, 0x74, 0xa5, 0x40, 0x3e, 0x02, 0x3d, 0xe9, 0xae, 0x56, 0xdd, 0x5c,
0x54, 0x7d, 0x54, 0xf8, 0x24, 0xdc, 0x2f, 0xee, 0xcc, 0xc5, 0x25, 0x93, 0x6e, 0x70, 0xdd, 0xbb, 0xf7, 0x57, 0x5e, 0x2e, 0x08, 0xfd, 0xa4, 0x02, 0x5d, 0x75, 0x01, 0xdb, 0x5f, 0xd9, 0x85, 0x93,
0x7a, 0x7f, 0xed, 0x0b, 0x09, 0x39, 0x02, 0x48, 0xb5, 0x34, 0x6b, 0x1f, 0xcc, 0xfb, 0xeb, 0x5f, 0x7d, 0xa8, 0x47, 0xb5, 0x7b, 0xf1, 0xdd, 0x72, 0x7f, 0x45, 0xe3, 0x2f, 0xcc, 0x23, 0x1b, 0xa6,
0x3e, 0xc8, 0x03, 0x68, 0x24, 0xaf, 0x59, 0xc5, 0x4f, 0xe0, 0xfd, 0x75, 0x8f, 0x11, 0xc3, 0x5b, 0xa2, 0x0b, 0xf0, 0x7e, 0xe1, 0xed, 0x04, 0xb9, 0x0b, 0x35, 0x55, 0x44, 0x15, 0xde, 0x2f, 0xf7,
0xff, 0xf8, 0xd3, 0xb6, 0xf6, 0xeb, 0x8b, 0x6d, 0xed, 0x8b, 0x8b, 0x6d, 0xed, 0xcb, 0x8b, 0x6d, 0x8b, 0xdb, 0x77, 0x71, 0xc8, 0xa4, 0x65, 0x5c, 0x75, 0x49, 0xdf, 0x5f, 0x79, 0x8d, 0x42, 0x0e,
0xed, 0x77, 0x17, 0xdb, 0xda, 0x1f, 0x2f, 0xb6, 0xb5, 0xdf, 0xfc, 0x79, 0x5b, 0x1b, 0xd5, 0xd0, 0x00, 0x52, 0x7d, 0xcf, 0xca, 0xdb, 0xf7, 0xfe, 0xea, 0xeb, 0x11, 0x72, 0x1f, 0x1a, 0xc9, 0x95,
0xfd, 0x3f, 0xf8, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, 0x3e, 0x33, 0xc0, 0x3b, 0xf2, 0x19, 0x00, 0x57, 0xf1, 0x7d, 0x7a, 0x7f, 0xd5, 0x8d, 0xc5, 0xf0, 0xc6, 0xbf, 0xfe, 0xb2, 0xa9, 0xfd, 0xf6,
0x00, 0x7c, 0x53, 0xfb, 0xe2, 0x7c, 0x53, 0xfb, 0xf2, 0x7c, 0x53, 0xfb, 0xc3, 0xf9, 0xa6, 0xf6, 0xe7,
0xf3, 0x4d, 0xed, 0x77, 0x7f, 0xdd, 0xd4, 0x46, 0x35, 0x8c, 0x91, 0x0f, 0xfe, 0x13, 0x00, 0x00,
0xff, 0xff, 0x92, 0xed, 0x9f, 0xca, 0x3f, 0x1a, 0x00, 0x00,
} }

View File

@ -81,8 +81,14 @@ message RequestBeginBlock {
repeated Evidence byzantine_validators = 4 [(gogoproto.nullable)=false]; repeated Evidence byzantine_validators = 4 [(gogoproto.nullable)=false];
} }
enum CheckTxType {
New = 0;
Recheck = 1;
}
message RequestCheckTx { message RequestCheckTx {
bytes tx = 1; bytes tx = 1;
CheckTxType type = 2;
} }
message RequestDeliverTx { message RequestDeliverTx {

View File

@ -27,7 +27,7 @@ type messageOutOfOrder struct {
// MessageOutOfOrder returns a messagOutOfOrder PeerBehaviour. // MessageOutOfOrder returns a messagOutOfOrder PeerBehaviour.
func MessageOutOfOrder(peerID p2p.ID, explanation string) PeerBehaviour { func MessageOutOfOrder(peerID p2p.ID, explanation string) PeerBehaviour {
return PeerBehaviour{peerID: peerID, reason: badMessage{explanation}} return PeerBehaviour{peerID: peerID, reason: messageOutOfOrder{explanation}}
} }
type consensusVote struct { type consensusVote struct {

View File

@ -161,8 +161,9 @@ func testnetFiles(cmd *cobra.Command, args []string) error {
// Generate genesis doc from generated validators // Generate genesis doc from generated validators
genDoc := &types.GenesisDoc{ genDoc := &types.GenesisDoc{
GenesisTime: tmtime.Now(),
ChainID: "chain-" + cmn.RandStr(6), ChainID: "chain-" + cmn.RandStr(6),
ConsensusParams: types.DefaultConsensusParams(),
GenesisTime: tmtime.Now(),
Validators: genVals, Validators: genVals,
} }

View File

@ -351,7 +351,8 @@ type RPCConfig struct {
// See https://github.com/tendermint/tendermint/issues/3435 // See https://github.com/tendermint/tendermint/issues/3435
TimeoutBroadcastTxCommit time.Duration `mapstructure:"timeout_broadcast_tx_commit"` TimeoutBroadcastTxCommit time.Duration `mapstructure:"timeout_broadcast_tx_commit"`
// The name of a file containing certificate that is used to create the HTTPS server. // The path to a file containing certificate that is used to create the HTTPS server.
// Migth be either absolute path or path related to tendermint's config directory.
// //
// If the certificate is signed by a certificate authority, // If the certificate is signed by a certificate authority,
// the certFile should be the concatenation of the server's certificate, any intermediates, // the certFile should be the concatenation of the server's certificate, any intermediates,
@ -360,7 +361,8 @@ type RPCConfig struct {
// NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run.
TLSCertFile string `mapstructure:"tls_cert_file"` TLSCertFile string `mapstructure:"tls_cert_file"`
// The name of a file containing matching private key that is used to create the HTTPS server. // The path to a file containing matching private key that is used to create the HTTPS server.
// Migth be either absolute path or path related to tendermint's config directory.
// //
// NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. // NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run.
TLSKeyFile string `mapstructure:"tls_key_file"` TLSKeyFile string `mapstructure:"tls_key_file"`
@ -424,11 +426,19 @@ func (cfg *RPCConfig) IsCorsEnabled() bool {
} }
func (cfg RPCConfig) KeyFile() string { func (cfg RPCConfig) KeyFile() string {
return rootify(filepath.Join(defaultConfigDir, cfg.TLSKeyFile), cfg.RootDir) path := cfg.TLSKeyFile
if filepath.IsAbs(path) {
return path
}
return rootify(filepath.Join(defaultConfigDir, path), cfg.RootDir)
} }
func (cfg RPCConfig) CertFile() string { func (cfg RPCConfig) CertFile() string {
return rootify(filepath.Join(defaultConfigDir, cfg.TLSCertFile), cfg.RootDir) path := cfg.TLSCertFile
if filepath.IsAbs(path) {
return path
}
return rootify(filepath.Join(defaultConfigDir, path), cfg.RootDir)
} }
func (cfg RPCConfig) IsTLSEnabled() bool { func (cfg RPCConfig) IsTLSEnabled() bool {

View File

@ -36,3 +36,19 @@ func TestConfigValidateBasic(t *testing.T) {
cfg.Consensus.TimeoutPropose = -10 * time.Second cfg.Consensus.TimeoutPropose = -10 * time.Second
assert.Error(t, cfg.ValidateBasic()) assert.Error(t, cfg.ValidateBasic())
} }
func TestTLSConfiguration(t *testing.T) {
assert := assert.New(t)
cfg := DefaultConfig()
cfg.SetRoot("/home/user")
cfg.RPC.TLSCertFile = "file.crt"
assert.Equal("/home/user/config/file.crt", cfg.RPC.CertFile())
cfg.RPC.TLSKeyFile = "file.key"
assert.Equal("/home/user/config/file.key", cfg.RPC.KeyFile())
cfg.RPC.TLSCertFile = "/abs/path/to/file.crt"
assert.Equal("/abs/path/to/file.crt", cfg.RPC.CertFile())
cfg.RPC.TLSKeyFile = "/abs/path/to/file.key"
assert.Equal("/abs/path/to/file.key", cfg.RPC.KeyFile())
}

View File

@ -192,14 +192,16 @@ max_subscriptions_per_client = {{ .RPC.MaxSubscriptionsPerClient }}
# See https://github.com/tendermint/tendermint/issues/3435 # See https://github.com/tendermint/tendermint/issues/3435
timeout_broadcast_tx_commit = "{{ .RPC.TimeoutBroadcastTxCommit }}" timeout_broadcast_tx_commit = "{{ .RPC.TimeoutBroadcastTxCommit }}"
# The name of a file containing certificate that is used to create the HTTPS server. # The path to a file containing certificate that is used to create the HTTPS server.
# Migth be either absolute path or path related to tendermint's config directory.
# If the certificate is signed by a certificate authority, # If the certificate is signed by a certificate authority,
# the certFile should be the concatenation of the server's certificate, any intermediates, # the certFile should be the concatenation of the server's certificate, any intermediates,
# and the CA's certificate. # and the CA's certificate.
# NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run.
tls_cert_file = "{{ .RPC.TLSCertFile }}" tls_cert_file = "{{ .RPC.TLSCertFile }}"
# The name of a file containing matching private key that is used to create the HTTPS server. # The path to a file containing matching private key that is used to create the HTTPS server.
# Migth be either absolute path or path related to tendermint's config directory.
# NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run.
tls_key_file = "{{ .RPC.TLSKeyFile }}" tls_key_file = "{{ .RPC.TLSKeyFile }}"

View File

@ -565,7 +565,7 @@ func TestMockProxyApp(t *testing.T) {
mock.SetResponseCallback(proxyCb) mock.SetResponseCallback(proxyCb)
someTx := []byte("tx") someTx := []byte("tx")
mock.DeliverTxAsync(someTx) mock.DeliverTxAsync(abci.RequestDeliverTx{Tx: someTx})
}) })
assert.True(t, validTxs == 1) assert.True(t, validTxs == 1)
assert.True(t, invalidTxs == 0) assert.True(t, invalidTxs == 0)

View File

@ -6,14 +6,12 @@ The documentation for Tendermint Core is hosted at:
- https://tendermint-staging.interblock.io/docs/ - https://tendermint-staging.interblock.io/docs/
built from the files in this (`/docs`) directory for built from the files in this (`/docs`) directory for
[master](https://github.com/tendermint/tendermint/tree/master/docs) [master](https://github.com/tendermint/tendermint/tree/master/docs) respectively.
and [develop](https://github.com/tendermint/tendermint/tree/develop/docs),
respectively.
## How It Works ## How It Works
There is a CircleCI job listening for changes in the `/docs` directory, on both There is a CircleCI job listening for changes in the `/docs` directory, on both
the `master` and `develop` branches. Any updates to files in this directory the `master` branch. Any updates to files in this directory
on those branches will automatically trigger a website deployment. Under the hood, on those branches will automatically trigger a website deployment. Under the hood,
the private website repository has a `make build-docs` target consumed by a CircleCI job in that repo. the private website repository has a `make build-docs` target consumed by a CircleCI job in that repo.
@ -35,7 +33,7 @@ of the sidebar.
**NOTE:** Strongly consider the existing links - both within this directory **NOTE:** Strongly consider the existing links - both within this directory
and to the website docs - when moving or deleting files. and to the website docs - when moving or deleting files.
Links to directories *MUST* end in a `/`. Links to directories _MUST_ end in a `/`.
Relative links should be used nearly everywhere, having discovered and weighed the following: Relative links should be used nearly everywhere, having discovered and weighed the following:
@ -101,4 +99,4 @@ We are using [Algolia](https://www.algolia.com) to power full-text search. This
## Consistency ## Consistency
Because the build processes are identical (as is the information contained herein), this file should be kept in sync as Because the build processes are identical (as is the information contained herein), this file should be kept in sync as
much as possible with its [counterpart in the Cosmos SDK repo](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/DOCS_README.md). much as possible with its [counterpart in the Cosmos SDK repo](https://github.com/cosmos/cosmos-sdk/blob/master/docs/DOCS_README.md).

View File

@ -62,7 +62,7 @@ as `abci-cli` above. The kvstore just stores transactions in a merkle
tree. tree.
Its code can be found Its code can be found
[here](https://github.com/tendermint/tendermint/blob/develop/abci/cmd/abci-cli/abci-cli.go) [here](https://github.com/tendermint/tendermint/blob/master/abci/cmd/abci-cli/abci-cli.go)
and looks like: and looks like:
``` ```
@ -137,7 +137,7 @@ response.
The server may be generic for a particular language, and we provide a The server may be generic for a particular language, and we provide a
[reference implementation in [reference implementation in
Golang](https://github.com/tendermint/tendermint/tree/develop/abci/server). See the Golang](https://github.com/tendermint/tendermint/tree/master/abci/server). See the
[list of other ABCI implementations](./ecosystem.md) for servers in [list of other ABCI implementations](./ecosystem.md) for servers in
other languages. other languages.
@ -324,7 +324,7 @@ But the ultimate flexibility comes from being able to write the
application easily in any language. application easily in any language.
We have implemented the counter in a number of languages [see the We have implemented the counter in a number of languages [see the
example directory](https://github.com/tendermint/tendermint/tree/develop/abci/example). example directory](https://github.com/tendermint/tendermint/tree/master/abci/example).
To run the Node.js version, fist download & install [the Javascript ABCI server](https://github.com/tendermint/js-abci): To run the Node.js version, fist download & install [the Javascript ABCI server](https://github.com/tendermint/js-abci):

View File

@ -48,9 +48,9 @@ open ABCI connection with the application, which hosts an ABCI server.
Shown are the request and response types sent on each connection. Shown are the request and response types sent on each connection.
Most of the examples below are from [kvstore Most of the examples below are from [kvstore
application](https://github.com/tendermint/tendermint/blob/develop/abci/example/kvstore/kvstore.go), application](https://github.com/tendermint/tendermint/blob/master/abci/example/kvstore/kvstore.go),
which is a part of the abci repo. [persistent_kvstore which is a part of the abci repo. [persistent_kvstore
application](https://github.com/tendermint/tendermint/blob/develop/abci/example/kvstore/persistent_kvstore.go) application](https://github.com/tendermint/tendermint/blob/master/abci/example/kvstore/persistent_kvstore.go)
is used to show `BeginBlock`, `EndBlock` and `InitChain` example is used to show `BeginBlock`, `EndBlock` and `InitChain` example
implementations. implementations.

View File

@ -2,10 +2,7 @@
## Changelog ## Changelog
016-08-2018: Follow up from review: 016-08-2018: Follow up from review: - Revert changes to commit round - Remind about justification for removing pubkey - Update pros/cons
- Revert changes to commit round
- Remind about justification for removing pubkey
- Update pros/cons
05-08-2018: Initial draft 05-08-2018: Initial draft
## Context ## Context
@ -35,11 +32,11 @@ message ValidatorUpdate {
} }
``` ```
As noted in ADR-009[https://github.com/tendermint/tendermint/blob/develop/docs/architecture/adr-009-ABCI-design.md], As noted in ADR-009[https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-009-ABCI-design.md],
the `Validator` does not contain a pubkey because quantum public keys are the `Validator` does not contain a pubkey because quantum public keys are
quite large and it would be wasteful to send them all over ABCI with every block. quite large and it would be wasteful to send them all over ABCI with every block.
Thus, applications that want to take advantage of the information in BeginBlock Thus, applications that want to take advantage of the information in BeginBlock
are *required* to store pubkeys in state (or use much less efficient lazy means are _required_ to store pubkeys in state (or use much less efficient lazy means
of verifying BeginBlock data). of verifying BeginBlock data).
### RequestBeginBlock ### RequestBeginBlock

View File

@ -0,0 +1,391 @@
# ADR 043: Blockhchain Reactor Riri-Org
## Changelog
* 18-06-2019: Initial draft
* 08-07-2019: Reviewed
## Context
The blockchain reactor is responsible for two high level processes:sending/receiving blocks from peers and FastSync-ing blocks to catch upnode who is far behind. The goal of [ADR-40](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-040-blockchain-reactor-refactor.md) was to refactor these two processes by separating business logic currently wrapped up in go-channels into pure `handle*` functions. While the ADR specified what the final form of the reactor might look like it lacked guidance on intermediary steps to get there.
The following diagram illustrates the state of the [blockchain-reorg](https://github.com/tendermint/tendermint/pull/35610) reactor which will be referred to as `v1`.
![v1 Blockchain Reactor Architecture
Diagram](https://github.com/tendermint/tendermint/blob/f9e556481654a24aeb689bdadaf5eab3ccd66829/docs/architecture/img/blockchain-reactor-v1.png)
While `v1` of the blockchain reactor has shown significant improvements in terms of simplifying the concurrency model, the current PR has run into few roadblocks.
* The current PR large and difficult to review.
* Block gossiping and fast sync processes are highly coupled to the shared `Pool` data structure.
* Peer communication is spread over multiple components creating complex dependency graph which must be mocked out during testing.
* Timeouts modeled as stateful tickers introduce non-determinism in tests
This ADR is meant to specify the missing components and control necessary to achieve [ADR-40](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-040-blockchain-reactor-refactor.md).
## Decision
Partition the responsibilities of the blockchain reactor into a set of components which communicate exclusively with events. Events will contain timestamps allowing each component to track time as internal state. The internal state will be mutated by a set of `handle*` which will produce event(s). The integration between components will happen in the reactor and reactor tests will then become integration tests between components. This design will be known as `v2`.
![v2 Blockchain Reactor Architecture
Diagram](https://github.com/tendermint/tendermint/blob/f9e556481654a24aeb689bdadaf5eab3ccd66829/docs/architecture/img/blockchain-reactor-v2.png)
### Reactor changes in detail
The reactor will include a demultiplexing routine which will send each message to each sub routine for independent processing. Each sub routine will then select the messages it's interested in and call the handle specific function specified in [ADR-40](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-040-blockchain-reactor-refactor.md). The demuxRoutine acts as "pacemaker" setting the time in which events are expected to be handled.
```go
func demuxRoutine(msgs, scheduleMsgs, processorMsgs, ioMsgs) {
timer := time.NewTicker(interval)
for {
select {
case <-timer.C:
now := evTimeCheck{time.Now()}
schedulerMsgs <- now
processorMsgs <- now
ioMsgs <- now
case msg:= <- msgs:
msg.time = time.Now()
// These channels should produce backpressure before
// being full to avoid starving each other
schedulerMsgs <- msg
processorMsgs <- msg
ioMesgs <- msg
if msg == stop {
break;
}
}
}
}
func processRoutine(input chan Message, output chan Message) {
processor := NewProcessor(..)
for {
msg := <- input
switch msg := msg.(type) {
case bcBlockRequestMessage:
output <- processor.handleBlockRequest(msg))
...
case stop:
processor.stop()
break;
}
}
func scheduleRoutine(input chan Message, output chan Message) {
schelduer = NewScheduler(...)
for {
msg := <-msgs
switch msg := input.(type) {
case bcBlockResponseMessage:
output <- scheduler.handleBlockResponse(msg)
...
case stop:
schedule.stop()
break;
}
}
}
```
## Lifecycle management
A set of routines for individual processes allow processes to run in parallel with clear lifecycle management. `Start`, `Stop`, and `AddPeer` hooks currently present in the reactor will delegate to the sub-routines allowing them to manage internal state independent without further coupling to the reactor.
```go
func (r *BlockChainReactor) Start() {
r.msgs := make(chan Message, maxInFlight)
schedulerMsgs := make(chan Message)
processorMsgs := make(chan Message)
ioMsgs := make(chan Message)
go processorRoutine(processorMsgs, r.msgs)
go scheduleRoutine(schedulerMsgs, r.msgs)
go ioRoutine(ioMsgs, r.msgs)
...
}
func (bcR *BlockchainReactor) Receive(...) {
...
r.msgs <- msg
...
}
func (r *BlockchainReactor) Stop() {
...
r.msgs <- stop
...
}
...
func (r *BlockchainReactor) Stop() {
...
r.msgs <- stop
...
}
...
func (r *BlockchainReactor) AddPeer(peer p2p.Peer) {
...
r.msgs <- bcAddPeerEv{peer.ID}
...
}
```
## IO handling
An io handling routine within the reactor will isolate peer communication. Message going through the ioRoutine will usually be one way, using `p2p` APIs. In the case in which the `p2p` API such as `trySend` return errors, the ioRoutine can funnel those message back to the demuxRoutine for distribution to the other routines. For instance errors from the ioRoutine can be consumed by the scheduler to inform better peer selection implementations.
```go
func (r *BlockchainReacor) ioRoutine(ioMesgs chan Message, outMsgs chan Message) {
...
for {
msg := <-ioMsgs
switch msg := msg.(type) {
case scBlockRequestMessage:
queued := r.sendBlockRequestToPeer(...)
if queued {
outMsgs <- ioSendQueued{...}
}
case scStatusRequestMessage
r.sendStatusRequestToPeer(...)
case bcPeerError
r.Swtich.StopPeerForError(msg.src)
...
...
case bcFinished
break;
}
}
}
```
### Processor Internals
The processor is responsible for ordering, verifying and executing blocks. The Processor will maintain an internal cursor `height` refering to the last processed block. As a set of blocks arrive unordered, the Processor will check if it has `height+1` necessary to process the next block. The processor also maintains the map `blockPeers` of peers to height, to keep track of which peer provided the block at `height`. `blockPeers` can be used in`handleRemovePeer(...)` to reschedule all unprocessed blocks provided by a peer who has errored.
```go
type Processor struct {
height int64 // the height cursor
state ...
blocks [height]*Block // keep a set of blocks in memory until they are processed
blockPeers [height]PeerID // keep track of which heights came from which peerID
lastTouch timestamp
}
func (proc *Processor) handleBlockResponse(peerID, block) {
if block.height <= height || block[block.height] {
} else if blocks[block.height] {
return errDuplicateBlock{}
} else {
blocks[block.height] = block
}
if blocks[height] && blocks[height+1] {
... = state.Validators.VerifyCommit(...)
... = store.SaveBlock(...)
state, err = blockExec.ApplyBlock(...)
...
if err == nil {
delete blocks[height]
height++
lastTouch = msg.time
return pcBlockProcessed{height-1}
} else {
... // Delete all unprocessed block from the peer
return pcBlockProcessError{peerID, height}
}
}
}
func (proc *Processor) handleRemovePeer(peerID) {
events = []
// Delete all unprocessed blocks from peerID
for i = height; i < len(blocks); i++ {
if blockPeers[i] == peerID {
events = append(events, pcBlockReschedule{height})
delete block[height]
}
}
return events
}
func handleTimeCheckEv(time) {
if time - lastTouch > timeout {
// Timeout the processor
...
}
}
```
## Schedule
The Schedule maintains the internal state used for scheduling blockRequestMessages based on some scheduling algorithm. The schedule needs to maintain state on:
* The state `blockState` of every block seem up to height of maxHeight
* The set of peers and their peer state `peerState`
* which peers have which blocks
* which blocks have been requested from which peers
```go
type blockState int
const (
blockStateNew = iota
blockStatePending,
blockStateReceived,
blockStateProcessed
)
type schedule {
// a list of blocks in which blockState
blockStates map[height]blockState
// a map of which blocks are available from which peers
blockPeers map[height]map[p2p.ID]scPeer
// a map of peerID to schedule specific peer struct `scPeer`
peers map[p2p.ID]scPeer
// a map of heights to the peer we are waiting for a response from
pending map[height]scPeer
targetPending int // the number of blocks we want in blockStatePending
targetReceived int // the number of blocks we want in blockStateReceived
peerTimeout int
peerMinSpeed int
}
func (sc *schedule) numBlockInState(state blockState) uint32 {
num := 0
for i := sc.minHeight(); i <= sc.maxHeight(); i++ {
if sc.blockState[i] == state {
num++
}
}
return num
}
func (sc *schedule) popSchedule(maxRequest int) []scBlockRequestMessage {
// We only want to schedule requests such that we have less than sc.targetPending and sc.targetReceived
// This ensures we don't saturate the network or flood the processor with unprocessed blocks
todo := min(sc.targetPending - sc.numBlockInState(blockStatePending), sc.numBlockInState(blockStateReceived))
events := []scBlockRequestMessage{}
for i := sc.minHeight(); i < sc.maxMaxHeight(); i++ {
if todo == 0 {
break
}
if blockStates[i] == blockStateNew {
peer = sc.selectPeer(blockPeers[i])
sc.blockStates[i] = blockStatePending
sc.pending[i] = peer
events = append(events, scBlockRequestMessage{peerID: peer.peerID, height: i})
todo--
}
}
return events
}
...
type scPeer struct {
peerID p2p.ID
numOustandingRequest int
lastTouched time.Time
monitor flow.Monitor
}
```
# Scheduler
The scheduler is configured to maintain a target `n` of in flight
messages and will use feedback from `_blockResponseMessage`,
`_statusResponseMessage` and `_peerError` produce an optimal assignment
of scBlockRequestMessage at each `timeCheckEv`.
```
func handleStatusResponse(peerID, height, time) {
schedule.touchPeer(peerID, time)
schedule.setPeerHeight(peerID, height)
}
func handleBlockResponseMessage(peerID, height, block, time) {
schedule.touchPeer(peerID, time)
schedule.markReceived(peerID, height, size(block))
}
func handleNoBlockResponseMessage(peerID, height, time) {
schedule.touchPeer(peerID, time)
// reschedule that block, punish peer...
...
}
func handlePeerError(peerID) {
// Remove the peer, reschedule the requests
...
}
func handleTimeCheckEv(time) {
// clean peer list
events = []
for peerID := range schedule.peersNotTouchedSince(time) {
pending = schedule.pendingFrom(peerID)
schedule.setPeerState(peerID, timedout)
schedule.resetBlocks(pending)
events = append(events, peerTimeout{peerID})
}
events = append(events, schedule.popSchedule())
return events
}
```
## Peer
The Peer Stores per peer state based on messages received by the scheduler.
```go
type Peer struct {
lastTouched timestamp
lastDownloaded timestamp
pending map[height]struct{}
height height // max height for the peer
state {
pending, // we know the peer but not the height
active, // we know the height
timeout // the peer has timed out
}
}
```
## Status
Work in progress
## Consequences
### Positive
* Test become deterministic
* Simulation becomes a-termporal: no need wait for a wall-time timeout
* Peer Selection can be independently tested/simulated
* Develop a general approach to refactoring reactors
### Negative
### Neutral
### Implementation Path
* Implement the scheduler, test the scheduler, review the rescheduler
* Implement the processor, test the processor, review the processor
* Implement the demuxer, write integration test, review integration tests
## References
* [ADR-40](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-040-blockchain-reactor-refactor.md): The original blockchain reactor re-org proposal
* [Blockchain re-org](https://github.com/tendermint/tendermint/pull/3561): The current blockchain reactor re-org implementation (v1)

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

View File

@ -1,9 +1,9 @@
# Install Tendermint # Install Tendermint
The fastest and easiest way to install the `tendermint` binary The fastest and easiest way to install the `tendermint` binary
is to run [this script](https://github.com/tendermint/tendermint/blob/develop/scripts/install/install_tendermint_ubuntu.sh) on is to run [this script](https://github.com/tendermint/tendermint/blob/master/scripts/install/install_tendermint_ubuntu.sh) on
a fresh Ubuntu instance, a fresh Ubuntu instance,
or [this script](https://github.com/tendermint/tendermint/blob/develop/scripts/install/install_tendermint_bsd.sh) or [this script](https://github.com/tendermint/tendermint/blob/master/scripts/install/install_tendermint_bsd.sh)
on a fresh FreeBSD instance. Read the comments / instructions carefully (i.e., reset your terminal after running the script, on a fresh FreeBSD instance. Read the comments / instructions carefully (i.e., reset your terminal after running the script,
make sure you are okay with the network connections being made). make sure you are okay with the network connections being made).

View File

@ -122,7 +122,7 @@ consensus engine, and provides a particular application state.
## ABCI Overview ## ABCI Overview
The [Application BlockChain Interface The [Application BlockChain Interface
(ABCI)](https://github.com/tendermint/tendermint/tree/develop/abci) (ABCI)](https://github.com/tendermint/tendermint/tree/master/abci)
allows for Byzantine Fault Tolerant replication of applications allows for Byzantine Fault Tolerant replication of applications
written in any programming language. written in any programming language.
@ -190,7 +190,7 @@ core to the application. The application replies with corresponding
response messages. response messages.
The messages are specified here: [ABCI Message The messages are specified here: [ABCI Message
Types](https://github.com/tendermint/tendermint/blob/develop/abci/README.md#message-types). Types](https://github.com/tendermint/tendermint/blob/master/abci/README.md#message-types).
The **DeliverTx** message is the work horse of the application. Each The **DeliverTx** message is the work horse of the application. Each
transaction in the blockchain is delivered with this message. The transaction in the blockchain is delivered with this message. The

View File

@ -116,7 +116,7 @@ consensus engine, and provides a particular application state.
## ABCI Overview ## ABCI Overview
The [Application BlockChain Interface The [Application BlockChain Interface
(ABCI)](https://github.com/tendermint/tendermint/tree/develop/abci) (ABCI)](https://github.com/tendermint/tendermint/tree/master/abci)
allows for Byzantine Fault Tolerant replication of applications allows for Byzantine Fault Tolerant replication of applications
written in any programming language. written in any programming language.
@ -184,7 +184,7 @@ core to the application. The application replies with corresponding
response messages. response messages.
The messages are specified here: [ABCI Message The messages are specified here: [ABCI Message
Types](https://github.com/tendermint/tendermint/blob/develop/abci/README.md#message-types). Types](https://github.com/tendermint/tendermint/blob/master/abci/README.md#message-types).
The **DeliverTx** message is the work horse of the application. Each The **DeliverTx** message is the work horse of the application. Each
transaction in the blockchain is delivered with this message. The transaction in the blockchain is delivered with this message. The

View File

@ -80,7 +80,7 @@ rm -rf ./build/node*
## Configuring abci containers ## Configuring abci containers
To use your own abci applications with 4-node setup edit the [docker-compose.yaml](https://github.com/tendermint/tendermint/blob/develop/docker-compose.yml) file and add image to your abci application. To use your own abci applications with 4-node setup edit the [docker-compose.yaml](https://github.com/tendermint/tendermint/blob/master/docker-compose.yml) file and add image to your abci application.
``` ```
abci0: abci0:

View File

@ -8,7 +8,7 @@ testnets on those servers.
## Install ## Install
NOTE: see the [integration bash NOTE: see the [integration bash
script](https://github.com/tendermint/tendermint/blob/develop/networks/remote/integration.sh) script](https://github.com/tendermint/tendermint/blob/master/networks/remote/integration.sh)
that can be run on a fresh DO droplet and will automatically spin up a 4 that can be run on a fresh DO droplet and will automatically spin up a 4
node testnet. The script more or less does everything described below. node testnet. The script more or less does everything described below.

View File

@ -2,11 +2,11 @@
ABCI is the interface between Tendermint (a state-machine replication engine) ABCI is the interface between Tendermint (a state-machine replication engine)
and your application (the actual state machine). It consists of a set of and your application (the actual state machine). It consists of a set of
*methods*, where each method has a corresponding `Request` and `Response` _methods_, where each method has a corresponding `Request` and `Response`
message type. Tendermint calls the ABCI methods on the ABCI application by sending the `Request*` message type. Tendermint calls the ABCI methods on the ABCI application by sending the `Request*`
messages and receiving the `Response*` messages in return. messages and receiving the `Response*` messages in return.
All message types are defined in a [protobuf file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto). All message types are defined in a [protobuf file](https://github.com/tendermint/tendermint/blob/master/abci/types/types.proto).
This allows Tendermint to run applications written in any programming language. This allows Tendermint to run applications written in any programming language.
This specification is split as follows: This specification is split as follows:

View File

@ -3,9 +3,9 @@
## Overview ## Overview
The ABCI message types are defined in a [protobuf The ABCI message types are defined in a [protobuf
file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto). file](https://github.com/tendermint/tendermint/blob/master/abci/types/types.proto).
ABCI methods are split across 3 separate ABCI *connections*: ABCI methods are split across 3 separate ABCI _connections_:
- `Consensus Connection`: `InitChain, BeginBlock, DeliverTx, EndBlock, Commit` - `Consensus Connection`: `InitChain, BeginBlock, DeliverTx, EndBlock, Commit`
- `Mempool Connection`: `CheckTx` - `Mempool Connection`: `CheckTx`
@ -296,6 +296,10 @@ Commit are included in the header of the next block.
- **Request**: - **Request**:
- `Tx ([]byte)`: The request transaction bytes - `Tx ([]byte)`: The request transaction bytes
- `Type (CheckTxType)`: What type of `CheckTx` request is this? At present,
there are two possible values: `CheckTx_New` (the default, which says
that a full check is required), and `CheckTx_Recheck` (when the mempool is
initiating a normal recheck of a transaction).
- **Response**: - **Response**:
- `Code (uint32)`: Response code - `Code (uint32)`: Response code
- `Data ([]byte)`: Result bytes, if any. - `Data ([]byte)`: Result bytes, if any.
@ -526,4 +530,3 @@ Commit are included in the header of the next block.
- `Type (string)`: Type of Merkle proof and how it's encoded. - `Type (string)`: Type of Merkle proof and how it's encoded.
- `Key ([]byte)`: Key in the Merkle tree that this proof is for. - `Key ([]byte)`: Key in the Merkle tree that this proof is for.
- `Data ([]byte)`: Encoded Merkle proof for the key. - `Data ([]byte)`: Encoded Merkle proof for the key.

View File

@ -65,7 +65,10 @@ begin.
After `Commit`, CheckTx is run again on all transactions that remain in the After `Commit`, CheckTx is run again on all transactions that remain in the
node's local mempool after filtering those included in the block. To prevent the node's local mempool after filtering those included in the block. To prevent the
mempool from rechecking all transactions every time a block is committed, set mempool from rechecking all transactions every time a block is committed, set
the configuration option `mempool.recheck=false`. the configuration option `mempool.recheck=false`. As of Tendermint v0.32.1,
an additional `Type` parameter is made available to the CheckTx function that
indicates whether an incoming transaction is new (`CheckTxType_New`), or a
recheck (`CheckTxType_Recheck`).
Finally, the mempool will unlock and new transactions can be processed through CheckTx again. Finally, the mempool will unlock and new transactions can be processed through CheckTx again.

View File

@ -9,7 +9,7 @@ Applications](./apps.md).
## Message Protocol ## Message Protocol
The message protocol consists of pairs of requests and responses defined in the The message protocol consists of pairs of requests and responses defined in the
[protobuf file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto). [protobuf file](https://github.com/tendermint/tendermint/blob/master/abci/types/types.proto).
Some messages have no fields, while others may include byte-arrays, strings, integers, Some messages have no fields, while others may include byte-arrays, strings, integers,
or custom protobuf types. or custom protobuf types.
@ -33,9 +33,9 @@ The latter two can be tested using the `abci-cli` by setting the `--abci` flag
appropriately (ie. to `socket` or `grpc`). appropriately (ie. to `socket` or `grpc`).
See examples, in various stages of maintenance, in See examples, in various stages of maintenance, in
[Go](https://github.com/tendermint/tendermint/tree/develop/abci/server), [Go](https://github.com/tendermint/tendermint/tree/master/abci/server),
[JavaScript](https://github.com/tendermint/js-abci), [JavaScript](https://github.com/tendermint/js-abci),
[Python](https://github.com/tendermint/tendermint/tree/develop/abci/example/python3/abci), [Python](https://github.com/tendermint/tendermint/tree/master/abci/example/python3/abci),
[C++](https://github.com/mdyring/cpp-tmsp), and [C++](https://github.com/mdyring/cpp-tmsp), and
[Java](https://github.com/jTendermint/jabci). [Java](https://github.com/jTendermint/jabci).
@ -44,14 +44,13 @@ See examples, in various stages of maintenance, in
The simplest implementation uses function calls within Golang. The simplest implementation uses function calls within Golang.
This means ABCI applications written in Golang can be compiled with TendermintCore and run as a single binary. This means ABCI applications written in Golang can be compiled with TendermintCore and run as a single binary.
### GRPC ### GRPC
If GRPC is available in your language, this is the easiest approach, If GRPC is available in your language, this is the easiest approach,
though it will have significant performance overhead. though it will have significant performance overhead.
To get started with GRPC, copy in the [protobuf To get started with GRPC, copy in the [protobuf
file](https://github.com/tendermint/tendermint/blob/develop/abci/types/types.proto) file](https://github.com/tendermint/tendermint/blob/master/abci/types/types.proto)
and compile it using the GRPC plugin for your language. For instance, and compile it using the GRPC plugin for your language. For instance,
for golang, the command is `protoc --go_out=plugins=grpc:. types.proto`. for golang, the command is `protoc --go_out=plugins=grpc:. types.proto`.
See the [grpc documentation for more details](http://www.grpc.io/docs/). See the [grpc documentation for more details](http://www.grpc.io/docs/).
@ -107,4 +106,4 @@ received or a block is committed.
It is unlikely that you will need to implement a client. For details of It is unlikely that you will need to implement a client. For details of
our client, see our client, see
[here](https://github.com/tendermint/tendermint/tree/develop/abci/client). [here](https://github.com/tendermint/tendermint/tree/master/abci/client).

View File

@ -60,7 +60,7 @@ You can simply use below table and concatenate Prefix || Length (of raw bytes) |
( while || stands for byte concatenation here). ( while || stands for byte concatenation here).
| Type | Name | Prefix | Length | Notes | | Type | Name | Prefix | Length | Notes |
| ------------------ | ----------------------------- | ---------- | -------- | ----- | | ----------------------- | ---------------------------------- | ---------- | -------- | ----- |
| PubKeyEd25519 | tendermint/PubKeyEd25519 | 0x1624DE64 | 0x20 | | | PubKeyEd25519 | tendermint/PubKeyEd25519 | 0x1624DE64 | 0x20 | |
| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | | | PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | |
| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | | | PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | |
@ -170,11 +170,11 @@ We use the RFC 6962 specification of a merkle tree, with sha256 as the hash func
Merkle trees are used throughout Tendermint to compute a cryptographic digest of a data structure. Merkle trees are used throughout Tendermint to compute a cryptographic digest of a data structure.
The differences between RFC 6962 and the simplest form a merkle tree are that: The differences between RFC 6962 and the simplest form a merkle tree are that:
1) leaf nodes and inner nodes have different hashes. 1. leaf nodes and inner nodes have different hashes.
This is for "second pre-image resistance", to prevent the proof to an inner node being valid as the proof of a leaf. This is for "second pre-image resistance", to prevent the proof to an inner node being valid as the proof of a leaf.
The leaf nodes are `SHA256(0x00 || leaf_data)`, and inner nodes are `SHA256(0x01 || left_hash || right_hash)`. The leaf nodes are `SHA256(0x00 || leaf_data)`, and inner nodes are `SHA256(0x01 || left_hash || right_hash)`.
2) When the number of items isn't a power of two, the left half of the tree is as big as it could be. 2. When the number of items isn't a power of two, the left half of the tree is as big as it could be.
(The largest power of two less than the number of items) This allows new leaves to be added with less (The largest power of two less than the number of items) This allows new leaves to be added with less
recomputation. For example: recomputation. For example:
@ -290,7 +290,7 @@ func computeHashFromAunts(index, total int, leafHash []byte, innerHashes [][]byt
### IAVL+ Tree ### IAVL+ Tree
Because Tendermint only uses a Simple Merkle Tree, application developers are expect to use their own Merkle tree in their applications. For example, the IAVL+ Tree - an immutable self-balancing binary tree for persisting application state is used by the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/blob/develop/docs/sdk/core/multistore.md) Because Tendermint only uses a Simple Merkle Tree, application developers are expect to use their own Merkle tree in their applications. For example, the IAVL+ Tree - an immutable self-balancing binary tree for persisting application state is used by the [Cosmos SDK](https://github.com/cosmos/cosmos-sdk/blob/master/docs/clients/lite/specification.md)
## JSON ## JSON

View File

@ -120,7 +120,7 @@ A proposal is signed and published by the designated proposer at each
round. The proposer is chosen by a deterministic and non-choking round round. The proposer is chosen by a deterministic and non-choking round
robin selection algorithm that selects proposers in proportion to their robin selection algorithm that selects proposers in proportion to their
voting power (see voting power (see
[implementation](https://github.com/tendermint/tendermint/blob/develop/types/validator_set.go)). [implementation](https://github.com/tendermint/tendermint/blob/master/types/validator_set.go)).
A proposal at `(H,R)` is composed of a block and an optional latest A proposal at `(H,R)` is composed of a block and an optional latest
`PoLC-Round < R` which is included iff the proposer knows of one. This `PoLC-Round < R` which is included iff the proposer knows of one. This

View File

@ -7,7 +7,7 @@ See [this issue](https://github.com/tendermint/tendermint/issues/1503)
Mempool maintains a cache of the last 10000 transactions to prevent Mempool maintains a cache of the last 10000 transactions to prevent
replaying old transactions (plus transactions coming from other replaying old transactions (plus transactions coming from other
validators, who are continually exchanging transactions). Read [Replay validators, who are continually exchanging transactions). Read [Replay
Protection](../../../../app-development.md#replay-protection) Protection](../../../app-dev/app-development.md#replay-protection)
for details. for details.
Sending incorrectly encoded data or data exceeding `maxMsgSize` will result Sending incorrectly encoded data or data exceeding `maxMsgSize` will result

View File

@ -28,5 +28,5 @@ WAL. Then it will go to precommit, and that time it will work because the
private validator contains the `LastSignBytes` and then well replay the private validator contains the `LastSignBytes` and then well replay the
precommit from the WAL. precommit from the WAL.
Make sure to read about [WAL corruption](../../../tendermint-core/running-in-production.md#wal-corruption) Make sure to read about [WAL corruption](../../tendermint-core/running-in-production.md#wal-corruption)
and recovery strategies. and recovery strategies.

BIN
docs/tendermint-core-image.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

View File

@ -138,14 +138,16 @@ max_subscriptions_per_client = 5
# See https://github.com/tendermint/tendermint/issues/3435 # See https://github.com/tendermint/tendermint/issues/3435
timeout_broadcast_tx_commit = "10s" timeout_broadcast_tx_commit = "10s"
# The name of a file containing certificate that is used to create the HTTPS server. # The path to a file containing certificate that is used to create the HTTPS server.
# Migth be either absolute path or path related to tendermint's config directory.
# If the certificate is signed by a certificate authority, # If the certificate is signed by a certificate authority,
# the certFile should be the concatenation of the server's certificate, any intermediates, # the certFile should be the concatenation of the server's certificate, any intermediates,
# and the CA's certificate. # and the CA's certificate.
# NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run.
tls_cert_file = "" tls_cert_file = ""
# The name of a file containing matching private key that is used to create the HTTPS server. # The path to a file containing matching private key that is used to create the HTTPS server.
# Migth be either absolute path or path related to tendermint's config directory.
# NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run. # NOTE: both tls_cert_file and tls_key_file must be present for Tendermint to create HTTPS server. Otherwise, HTTP server is run.
tls_key_file = "" tls_key_file = ""
@ -313,8 +315,7 @@ namespace = "tendermint"
If `create_empty_blocks` is set to `true` in your config, blocks will be If `create_empty_blocks` is set to `true` in your config, blocks will be
created ~ every second (with default consensus parameters). You can regulate created ~ every second (with default consensus parameters). You can regulate
the delay between blocks by changing the `timeout_commit`. E.g. `timeout_commit the delay between blocks by changing the `timeout_commit`. E.g. `timeout_commit = "10s"` should result in ~ 10 second blocks.
= "10s"` should result in ~ 10 second blocks.
**create_empty_blocks = false** **create_empty_blocks = false**
@ -340,7 +341,7 @@ Tendermint will only create blocks if there are transactions, or after waiting
## Consensus timeouts explained ## Consensus timeouts explained
There's a variety of information about timeouts in [Running in There's a variety of information about timeouts in [Running in
production](./running-in-production.html) production](./running-in-production.md)
You can also find more detailed technical explanation in the spec: [The latest You can also find more detailed technical explanation in the spec: [The latest
gossip on BFT consensus](https://arxiv.org/abs/1807.04938). gossip on BFT consensus](https://arxiv.org/abs/1807.04938).

View File

@ -115,7 +115,7 @@ little overview what they do.
- `abci-client` As mentioned in [Application Development Guide](../app-dev/app-development.md), Tendermint acts as an ABCI - `abci-client` As mentioned in [Application Development Guide](../app-dev/app-development.md), Tendermint acts as an ABCI
client with respect to the application and maintains 3 connections: client with respect to the application and maintains 3 connections:
mempool, consensus and query. The code used by Tendermint Core can mempool, consensus and query. The code used by Tendermint Core can
be found [here](https://github.com/tendermint/tendermint/tree/develop/abci/client). be found [here](https://github.com/tendermint/tendermint/tree/master/abci/client).
- `blockchain` Provides storage, pool (a group of peers), and reactor - `blockchain` Provides storage, pool (a group of peers), and reactor
for both storing and exchanging blocks between peers. for both storing and exchanging blocks between peers.
- `consensus` The heart of Tendermint core, which is the - `consensus` The heart of Tendermint core, which is the

View File

@ -4,4 +4,4 @@ The RPC documentation is hosted here:
- [https://tendermint.com/rpc/](https://tendermint.com/rpc/) - [https://tendermint.com/rpc/](https://tendermint.com/rpc/)
To update the documentation, edit the relevant `godoc` comments in the [rpc/core directory](https://github.com/tendermint/tendermint/tree/develop/rpc/core). To update the documentation, edit the relevant `godoc` comments in the [rpc/core directory](https://github.com/tendermint/tendermint/tree/master/rpc/core).

View File

@ -20,7 +20,7 @@ Initialize the root directory by running:
tendermint init tendermint init
``` ```
This will create a new private key (`priv_validator.json`), and a This will create a new private key (`priv_validator_key.json`), and a
genesis file (`genesis.json`) containing the associated public key, in genesis file (`genesis.json`) containing the associated public key, in
`$TMHOME/config`. This is all that's necessary to run a local testnet `$TMHOME/config`. This is all that's necessary to run a local testnet
with one validator. with one validator.
@ -43,6 +43,11 @@ definition](https://github.com/tendermint/tendermint/blob/master/types/genesis.g
- `chain_id`: ID of the blockchain. This must be unique for - `chain_id`: ID of the blockchain. This must be unique for
every blockchain. If your testnet blockchains do not have unique every blockchain. If your testnet blockchains do not have unique
chain IDs, you will have a bad time. The ChainID must be less than 50 symbols. chain IDs, you will have a bad time. The ChainID must be less than 50 symbols.
- `consensus_params`
- `block`
- `time_iota_ms`: Minimum time increment between consecutive blocks (in
milliseconds). If the block header timestamp is ahead of the system clock,
decrease this value.
- `validators`: List of initial validators. Note this may be overridden entirely by the - `validators`: List of initial validators. Note this may be overridden entirely by the
application, and may be left empty to make explicit that the application, and may be left empty to make explicit that the
application will initialize the validator set with ResponseInitChain. application will initialize the validator set with ResponseInitChain.
@ -63,9 +68,10 @@ definition](https://github.com/tendermint/tendermint/blob/master/types/genesis.g
"genesis_time": "2018-11-13T18:11:50.277637Z", "genesis_time": "2018-11-13T18:11:50.277637Z",
"chain_id": "test-chain-s4ui7D", "chain_id": "test-chain-s4ui7D",
"consensus_params": { "consensus_params": {
"block_size": { "block": {
"max_bytes": "22020096", "max_bytes": "22020096",
"max_gas": "-1" "max_gas": "-1",
"time_iota_ms": "1000"
}, },
"evidence": { "evidence": {
"max_age": "100000" "max_age": "100000"
@ -308,7 +314,7 @@ write-ahead-log](../tendermint-core/running-in-production.md#mempool-wal)
## Tendermint Networks ## Tendermint Networks
When `tendermint init` is run, both a `genesis.json` and When `tendermint init` is run, both a `genesis.json` and
`priv_validator.json` are created in `~/.tendermint/config`. The `priv_validator_key.json` are created in `~/.tendermint/config`. The
`genesis.json` might look like: `genesis.json` might look like:
``` ```
@ -329,7 +335,7 @@ When `tendermint init` is run, both a `genesis.json` and
} }
``` ```
And the `priv_validator.json`: And the `priv_validator_key.json`:
``` ```
{ {
@ -348,20 +354,20 @@ And the `priv_validator.json`:
} }
``` ```
The `priv_validator.json` actually contains a private key, and should The `priv_validator_key.json` actually contains a private key, and should
thus be kept absolutely secret; for now we work with the plain text. thus be kept absolutely secret; for now we work with the plain text.
Note the `last_` fields, which are used to prevent us from signing Note the `last_` fields, which are used to prevent us from signing
conflicting messages. conflicting messages.
Note also that the `pub_key` (the public key) in the Note also that the `pub_key` (the public key) in the
`priv_validator.json` is also present in the `genesis.json`. `priv_validator_key.json` is also present in the `genesis.json`.
The genesis file contains the list of public keys which may participate The genesis file contains the list of public keys which may participate
in the consensus, and their corresponding voting power. Greater than 2/3 in the consensus, and their corresponding voting power. Greater than 2/3
of the voting power must be active (i.e. the corresponding private keys of the voting power must be active (i.e. the corresponding private keys
must be producing signatures) for the consensus to make progress. In our must be producing signatures) for the consensus to make progress. In our
case, the genesis file contains the public key of our case, the genesis file contains the public key of our
`priv_validator.json`, so a Tendermint node started with the default `priv_validator_key.json`, so a Tendermint node started with the default
root directory will be able to make progress. Voting power uses an int64 root directory will be able to make progress. Voting power uses an int64
but must be positive, thus the range is: 0 through 9223372036854775807. but must be positive, thus the range is: 0 through 9223372036854775807.
Because of how the current proposer selection algorithm works, we do not Because of how the current proposer selection algorithm works, we do not
@ -447,16 +453,16 @@ not connected to the other peer.
The easiest way to add new validators is to do it in the `genesis.json`, The easiest way to add new validators is to do it in the `genesis.json`,
before starting the network. For instance, we could make a new before starting the network. For instance, we could make a new
`priv_validator.json`, and copy it's `pub_key` into the above genesis. `priv_validator_key.json`, and copy it's `pub_key` into the above genesis.
We can generate a new `priv_validator.json` with the command: We can generate a new `priv_validator_key.json` with the command:
``` ```
tendermint gen_validator tendermint gen_validator
``` ```
Now we can update our genesis file. For instance, if the new Now we can update our genesis file. For instance, if the new
`priv_validator.json` looks like: `priv_validator_key.json` looks like:
``` ```
{ {
@ -504,7 +510,7 @@ then the new `genesis.json` will be:
``` ```
Update the `genesis.json` in `~/.tendermint/config`. Copy the genesis Update the `genesis.json` in `~/.tendermint/config`. Copy the genesis
file and the new `priv_validator.json` to the `~/.tendermint/config` on file and the new `priv_validator_key.json` to the `~/.tendermint/config` on
a new machine. a new machine.
Now run `tendermint node` on both machines, and use either Now run `tendermint node` on both machines, and use either

3
go.mod
View File

@ -16,7 +16,6 @@ require (
github.com/gogo/protobuf v1.2.1 github.com/gogo/protobuf v1.2.1
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
github.com/golang/protobuf v1.3.0 github.com/golang/protobuf v1.3.0
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db // indirect
github.com/google/gofuzz v1.0.0 // indirect github.com/google/gofuzz v1.0.0 // indirect
github.com/gorilla/websocket v1.2.0 github.com/gorilla/websocket v1.2.0
github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect
@ -41,7 +40,7 @@ require (
github.com/spf13/pflag v1.0.3 // indirect github.com/spf13/pflag v1.0.3 // indirect
github.com/spf13/viper v1.0.0 github.com/spf13/viper v1.0.0
github.com/stretchr/testify v1.2.2 github.com/stretchr/testify v1.2.2
github.com/syndtr/goleveldb v0.0.0-20181012014443-6b91fda63f2e github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965
github.com/tendermint/go-amino v0.14.1 github.com/tendermint/go-amino v0.14.1
go.etcd.io/bbolt v1.3.3 // indirect go.etcd.io/bbolt v1.3.3 // indirect
golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25 golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25

5
go.sum
View File

@ -39,6 +39,8 @@ github.com/golang/protobuf v1.3.0 h1:kbxbvI4Un1LUWKxufD+BiE6AEExYYgkQLQmLFqA1LFk
github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db h1:woRePGFeVFfLKN/pOkfl+p/TAqKOfFu+7KPlMVpok/w=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ= github.com/gorilla/websocket v1.2.0 h1:VJtLvh6VQym50czpZzx07z/kw9EgAxI3x1ZB8taTMQQ=
@ -103,6 +105,9 @@ github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/syndtr/goleveldb v0.0.0-20181012014443-6b91fda63f2e h1:91EeXI4y4ShkyzkMqZ7QP/ZTIqwXp3RuDu5WFzxcFAs= github.com/syndtr/goleveldb v0.0.0-20181012014443-6b91fda63f2e h1:91EeXI4y4ShkyzkMqZ7QP/ZTIqwXp3RuDu5WFzxcFAs=
github.com/syndtr/goleveldb v0.0.0-20181012014443-6b91fda63f2e/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0= github.com/syndtr/goleveldb v0.0.0-20181012014443-6b91fda63f2e/go.mod h1:Z4AUp2Km+PwemOoO/VB5AOx9XSsIItzFjoJlOSiYmn0=
github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE=
github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965 h1:1oFLiOyVl+W7bnBzGhf7BbIv9loSFQcieWWYIjLqcAw=
github.com/syndtr/goleveldb v1.0.1-0.20190318030020-c3a204f8e965/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA=
github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6offJMk= github.com/tendermint/go-amino v0.14.1 h1:o2WudxNfdLNBwMyl2dqOJxiro5rfrEaU0Ugs6offJMk=
github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso= github.com/tendermint/go-amino v0.14.1/go.mod h1:i/UKE5Uocn+argJJBb12qTZsCDBcAYMbR92AaJVmKso=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=

View File

@ -1,21 +0,0 @@
machine:
environment:
GOPATH: "${HOME}/.go_workspace"
PROJECT_PARENT_PATH: "$GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME"
PROJECT_PATH: $GOPATH/src/github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME
hosts:
localhost: 127.0.0.1
dependencies:
override:
- mkdir -p "$PROJECT_PARENT_PATH"
- ln -sf "$HOME/$CIRCLE_PROJECT_REPONAME/" "$PROJECT_PATH"
post:
- go version
test:
override:
- cd $PROJECT_PATH && make get_tools && bash ./test.sh
post:
- cd "$PROJECT_PATH" && bash <(curl -s https://codecov.io/bash) -f coverage.txt
- cd "$PROJECT_PATH" && mv coverage.txt "${CIRCLE_ARTIFACTS}"

View File

@ -1,95 +0,0 @@
package common
import (
"fmt"
"strings"
)
const (
ANSIReset = "\x1b[0m"
ANSIBright = "\x1b[1m"
ANSIDim = "\x1b[2m"
ANSIUnderscore = "\x1b[4m"
ANSIBlink = "\x1b[5m"
ANSIReverse = "\x1b[7m"
ANSIHidden = "\x1b[8m"
ANSIFgBlack = "\x1b[30m"
ANSIFgRed = "\x1b[31m"
ANSIFgGreen = "\x1b[32m"
ANSIFgYellow = "\x1b[33m"
ANSIFgBlue = "\x1b[34m"
ANSIFgMagenta = "\x1b[35m"
ANSIFgCyan = "\x1b[36m"
ANSIFgWhite = "\x1b[37m"
ANSIBgBlack = "\x1b[40m"
ANSIBgRed = "\x1b[41m"
ANSIBgGreen = "\x1b[42m"
ANSIBgYellow = "\x1b[43m"
ANSIBgBlue = "\x1b[44m"
ANSIBgMagenta = "\x1b[45m"
ANSIBgCyan = "\x1b[46m"
ANSIBgWhite = "\x1b[47m"
)
// color the string s with color 'color'
// unless s is already colored
func treat(s string, color string) string {
if len(s) > 2 && s[:2] == "\x1b[" {
return s
}
return color + s + ANSIReset
}
func treatAll(color string, args ...interface{}) string {
parts := make([]string, 0, len(args))
for _, arg := range args {
parts = append(parts, treat(fmt.Sprintf("%v", arg), color))
}
return strings.Join(parts, "")
}
func Black(args ...interface{}) string {
return treatAll(ANSIFgBlack, args...)
}
func Red(args ...interface{}) string {
return treatAll(ANSIFgRed, args...)
}
func Green(args ...interface{}) string {
return treatAll(ANSIFgGreen, args...)
}
func Yellow(args ...interface{}) string {
return treatAll(ANSIFgYellow, args...)
}
func Blue(args ...interface{}) string {
return treatAll(ANSIFgBlue, args...)
}
func Magenta(args ...interface{}) string {
return treatAll(ANSIFgMagenta, args...)
}
func Cyan(args ...interface{}) string {
return treatAll(ANSIFgCyan, args...)
}
func White(args ...interface{}) string {
return treatAll(ANSIFgWhite, args...)
}
func ColoredBytes(data []byte, textColor, bytesColor func(...interface{}) string) string {
s := ""
for _, b := range data {
if 0x21 <= b && b < 0x7F {
s += textColor(string(b))
} else {
s += bytesColor(fmt.Sprintf("%02X", b))
}
}
return s
}

View File

@ -1,43 +0,0 @@
package common
import (
"strings"
"time"
"github.com/pkg/errors"
)
// TimeLayout helps to parse a date string of the format YYYY-MM-DD
// Intended to be used with the following function:
// time.Parse(TimeLayout, date)
var TimeLayout = "2006-01-02" //this represents YYYY-MM-DD
// ParseDateRange parses a date range string of the format start:end
// where the start and end date are of the format YYYY-MM-DD.
// The parsed dates are time.Time and will return the zero time for
// unbounded dates, ex:
// unbounded start: :2000-12-31
// unbounded end: 2000-12-31:
func ParseDateRange(dateRange string) (startDate, endDate time.Time, err error) {
dates := strings.Split(dateRange, ":")
if len(dates) != 2 {
err = errors.New("bad date range, must be in format date:date")
return
}
parseDate := func(date string) (out time.Time, err error) {
if len(date) == 0 {
return
}
out, err = time.Parse(TimeLayout, date)
return
}
startDate, err = parseDate(dates[0])
if err != nil {
return
}
endDate, err = parseDate(dates[1])
if err != nil {
return
}
return
}

View File

@ -1,46 +0,0 @@
package common
import (
"testing"
"time"
"github.com/stretchr/testify/assert"
)
var (
date = time.Date(2015, time.Month(12), 31, 0, 0, 0, 0, time.UTC)
date2 = time.Date(2016, time.Month(12), 31, 0, 0, 0, 0, time.UTC)
zero time.Time
)
func TestParseDateRange(t *testing.T) {
assert := assert.New(t)
var testDates = []struct {
dateStr string
start time.Time
end time.Time
errNil bool
}{
{"2015-12-31:2016-12-31", date, date2, true},
{"2015-12-31:", date, zero, true},
{":2016-12-31", zero, date2, true},
{"2016-12-31", zero, zero, false},
{"2016-31-12:", zero, zero, false},
{":2016-31-12", zero, zero, false},
}
for _, test := range testDates {
start, end, err := ParseDateRange(test.dateStr)
if test.errNil {
assert.Nil(err)
testPtr := func(want, have time.Time) {
assert.True(have.Equal(want))
}
testPtr(test.start, start)
testPtr(test.end, end)
} else {
assert.NotNil(err)
}
}
}

View File

@ -1,125 +0,0 @@
package common
import (
"bytes"
"container/heap"
)
/*
Example usage:
```
h := NewHeap()
h.Push("msg1", 1)
h.Push("msg3", 3)
h.Push("msg2", 2)
fmt.Println(h.Pop()) // msg1
fmt.Println(h.Pop()) // msg2
fmt.Println(h.Pop()) // msg3
```
*/
type Heap struct {
pq priorityQueue
}
func NewHeap() *Heap {
return &Heap{pq: make([]*pqItem, 0)}
}
func (h *Heap) Len() int64 {
return int64(len(h.pq))
}
func (h *Heap) Push(value interface{}, priority int) {
heap.Push(&h.pq, &pqItem{value: value, priority: cmpInt(priority)})
}
func (h *Heap) PushBytes(value interface{}, priority []byte) {
heap.Push(&h.pq, &pqItem{value: value, priority: cmpBytes(priority)})
}
func (h *Heap) PushComparable(value interface{}, priority Comparable) {
heap.Push(&h.pq, &pqItem{value: value, priority: priority})
}
func (h *Heap) Peek() interface{} {
if len(h.pq) == 0 {
return nil
}
return h.pq[0].value
}
func (h *Heap) Update(value interface{}, priority Comparable) {
h.pq.Update(h.pq[0], value, priority)
}
func (h *Heap) Pop() interface{} {
item := heap.Pop(&h.pq).(*pqItem)
return item.value
}
//-----------------------------------------------------------------------------
// From: http://golang.org/pkg/container/heap/#example__priorityQueue
type pqItem struct {
value interface{}
priority Comparable
index int
}
type priorityQueue []*pqItem
func (pq priorityQueue) Len() int { return len(pq) }
func (pq priorityQueue) Less(i, j int) bool {
return pq[i].priority.Less(pq[j].priority)
}
func (pq priorityQueue) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
pq[i].index = i
pq[j].index = j
}
func (pq *priorityQueue) Push(x interface{}) {
n := len(*pq)
item := x.(*pqItem)
item.index = n
*pq = append(*pq, item)
}
func (pq *priorityQueue) Pop() interface{} {
old := *pq
n := len(old)
item := old[n-1]
item.index = -1 // for safety
*pq = old[0 : n-1]
return item
}
func (pq *priorityQueue) Update(item *pqItem, value interface{}, priority Comparable) {
item.value = value
item.priority = priority
heap.Fix(pq, item.index)
}
//--------------------------------------------------------------------------------
// Comparable
type Comparable interface {
Less(o interface{}) bool
}
type cmpInt int
func (i cmpInt) Less(o interface{}) bool {
return int(i) < int(o.(cmpInt))
}
type cmpBytes []byte
func (bz cmpBytes) Less(o interface{}) bool {
return bytes.Compare([]byte(bz), []byte(o.(cmpBytes))) < 0
}

View File

@ -1,74 +0,0 @@
package common
import (
"bytes"
"errors"
"io"
)
type PrefixedReader struct {
Prefix []byte
reader io.Reader
}
func NewPrefixedReader(prefix []byte, reader io.Reader) *PrefixedReader {
return &PrefixedReader{prefix, reader}
}
func (pr *PrefixedReader) Read(p []byte) (n int, err error) {
if len(pr.Prefix) > 0 {
read := copy(p, pr.Prefix)
pr.Prefix = pr.Prefix[read:]
return read, nil
}
return pr.reader.Read(p)
}
// NOTE: Not goroutine safe
type BufferCloser struct {
bytes.Buffer
Closed bool
}
func NewBufferCloser(buf []byte) *BufferCloser {
return &BufferCloser{
*bytes.NewBuffer(buf),
false,
}
}
func (bc *BufferCloser) Close() error {
if bc.Closed {
return errors.New("BufferCloser already closed")
}
bc.Closed = true
return nil
}
func (bc *BufferCloser) Write(p []byte) (n int, err error) {
if bc.Closed {
return 0, errors.New("Cannot write to closed BufferCloser")
}
return bc.Buffer.Write(p)
}
func (bc *BufferCloser) WriteByte(c byte) error {
if bc.Closed {
return errors.New("Cannot write to closed BufferCloser")
}
return bc.Buffer.WriteByte(c)
}
func (bc *BufferCloser) WriteRune(r rune) (n int, err error) {
if bc.Closed {
return 0, errors.New("Cannot write to closed BufferCloser")
}
return bc.Buffer.WriteRune(r)
}
func (bc *BufferCloser) WriteString(s string) (n int, err error) {
if bc.Closed {
return 0, errors.New("Cannot write to closed BufferCloser")
}
return bc.Buffer.WriteString(s)
}

View File

@ -1,39 +1,13 @@
package common package common
import ( import (
"bufio"
"fmt" "fmt"
"io"
"io/ioutil" "io/ioutil"
"os" "os"
"os/exec"
"os/signal" "os/signal"
"strings"
"syscall" "syscall"
) )
var gopath string
// GoPath returns GOPATH env variable value. If it is not set, this function
// will try to call `go env GOPATH` subcommand.
func GoPath() string {
if gopath != "" {
return gopath
}
path := os.Getenv("GOPATH")
if len(path) == 0 {
goCmd := exec.Command("go", "env", "GOPATH")
out, err := goCmd.Output()
if err != nil {
panic(fmt.Sprintf("failed to determine gopath: %v", err))
}
path = string(out)
}
gopath = path
return path
}
type logger interface { type logger interface {
Info(msg string, keyvals ...interface{}) Info(msg string, keyvals ...interface{})
} }
@ -78,25 +52,6 @@ func EnsureDir(dir string, mode os.FileMode) error {
return nil return nil
} }
func IsDirEmpty(name string) (bool, error) {
f, err := os.Open(name)
if err != nil {
if os.IsNotExist(err) {
return true, err
}
// Otherwise perhaps a permission
// error or some other error.
return false, err
}
defer f.Close()
_, err = f.Readdirnames(1) // Or f.Readdir(1)
if err == io.EOF {
return true, nil
}
return false, err // Either not empty or error, suits both cases
}
func FileExists(filePath string) bool { func FileExists(filePath string) bool {
_, err := os.Stat(filePath) _, err := os.Stat(filePath)
return !os.IsNotExist(err) return !os.IsNotExist(err)
@ -125,19 +80,3 @@ func MustWriteFile(filePath string, contents []byte, mode os.FileMode) {
Exit(fmt.Sprintf("MustWriteFile failed: %v", err)) Exit(fmt.Sprintf("MustWriteFile failed: %v", err))
} }
} }
//--------------------------------------------------------------------------------
func Prompt(prompt string, defaultValue string) (string, error) {
fmt.Print(prompt)
reader := bufio.NewReader(os.Stdin)
line, err := reader.ReadString('\n')
if err != nil {
return defaultValue, err
}
line = strings.TrimSpace(line)
if line == "" {
return defaultValue, nil
}
return line, nil
}

View File

@ -1,46 +0,0 @@
package common
import (
"os"
"testing"
)
func TestOSGoPath(t *testing.T) {
// restore original gopath upon exit
path := os.Getenv("GOPATH")
defer func() {
_ = os.Setenv("GOPATH", path)
}()
err := os.Setenv("GOPATH", "~/testgopath")
if err != nil {
t.Fatal(err)
}
path = GoPath()
if path != "~/testgopath" {
t.Fatalf("should get GOPATH env var value, got %v", path)
}
os.Unsetenv("GOPATH")
path = GoPath()
if path != "~/testgopath" {
t.Fatalf("subsequent calls should return the same value, got %v", path)
}
}
func TestOSGoPathWithoutEnvVar(t *testing.T) {
// restore original gopath upon exit
path := os.Getenv("GOPATH")
defer func() {
_ = os.Setenv("GOPATH", path)
}()
os.Unsetenv("GOPATH")
// reset cache
gopath = ""
path = GoPath()
if path == "" || path == "~/testgopath" {
t.Fatalf("should get nonempty result of calling go env GOPATH, got %v", path)
}
}

View File

@ -182,8 +182,7 @@ func TestDBBatchWrite(t *testing.T) {
for i, tc := range testCases { for i, tc := range testCases {
mdb := newMockDB() mdb := newMockDB()
ddb := NewDebugDB(t.Name(), mdb) batch := mdb.NewBatch()
batch := ddb.NewBatch()
tc.modify(batch) tc.modify(batch)

View File

@ -1,257 +0,0 @@
package db
import (
"fmt"
"sync"
cmn "github.com/tendermint/tendermint/libs/common"
)
//----------------------------------------
// debugDB
type debugDB struct {
label string
db DB
}
// For printing all operationgs to the console for debugging.
func NewDebugDB(label string, db DB) debugDB {
return debugDB{
label: label,
db: db,
}
}
// Implements atomicSetDeleter.
func (ddb debugDB) Mutex() *sync.Mutex { return nil }
// Implements DB.
func (ddb debugDB) Get(key []byte) (value []byte) {
defer func() {
fmt.Printf("%v.Get(%v) %v\n", ddb.label,
cmn.ColoredBytes(key, cmn.Cyan, cmn.Blue),
cmn.ColoredBytes(value, cmn.Green, cmn.Blue))
}()
value = ddb.db.Get(key)
return
}
// Implements DB.
func (ddb debugDB) Has(key []byte) (has bool) {
defer func() {
fmt.Printf("%v.Has(%v) %v\n", ddb.label,
cmn.ColoredBytes(key, cmn.Cyan, cmn.Blue), has)
}()
return ddb.db.Has(key)
}
// Implements DB.
func (ddb debugDB) Set(key []byte, value []byte) {
fmt.Printf("%v.Set(%v, %v)\n", ddb.label,
cmn.ColoredBytes(key, cmn.Yellow, cmn.Blue),
cmn.ColoredBytes(value, cmn.Green, cmn.Blue))
ddb.db.Set(key, value)
}
// Implements DB.
func (ddb debugDB) SetSync(key []byte, value []byte) {
fmt.Printf("%v.SetSync(%v, %v)\n", ddb.label,
cmn.ColoredBytes(key, cmn.Yellow, cmn.Blue),
cmn.ColoredBytes(value, cmn.Green, cmn.Blue))
ddb.db.SetSync(key, value)
}
// Implements atomicSetDeleter.
func (ddb debugDB) SetNoLock(key []byte, value []byte) {
fmt.Printf("%v.SetNoLock(%v, %v)\n", ddb.label,
cmn.ColoredBytes(key, cmn.Yellow, cmn.Blue),
cmn.ColoredBytes(value, cmn.Green, cmn.Blue))
ddb.db.(atomicSetDeleter).SetNoLock(key, value)
}
// Implements atomicSetDeleter.
func (ddb debugDB) SetNoLockSync(key []byte, value []byte) {
fmt.Printf("%v.SetNoLockSync(%v, %v)\n", ddb.label,
cmn.ColoredBytes(key, cmn.Yellow, cmn.Blue),
cmn.ColoredBytes(value, cmn.Green, cmn.Blue))
ddb.db.(atomicSetDeleter).SetNoLockSync(key, value)
}
// Implements DB.
func (ddb debugDB) Delete(key []byte) {
fmt.Printf("%v.Delete(%v)\n", ddb.label,
cmn.ColoredBytes(key, cmn.Red, cmn.Yellow))
ddb.db.Delete(key)
}
// Implements DB.
func (ddb debugDB) DeleteSync(key []byte) {
fmt.Printf("%v.DeleteSync(%v)\n", ddb.label,
cmn.ColoredBytes(key, cmn.Red, cmn.Yellow))
ddb.db.DeleteSync(key)
}
// Implements atomicSetDeleter.
func (ddb debugDB) DeleteNoLock(key []byte) {
fmt.Printf("%v.DeleteNoLock(%v)\n", ddb.label,
cmn.ColoredBytes(key, cmn.Red, cmn.Yellow))
ddb.db.(atomicSetDeleter).DeleteNoLock(key)
}
// Implements atomicSetDeleter.
func (ddb debugDB) DeleteNoLockSync(key []byte) {
fmt.Printf("%v.DeleteNoLockSync(%v)\n", ddb.label,
cmn.ColoredBytes(key, cmn.Red, cmn.Yellow))
ddb.db.(atomicSetDeleter).DeleteNoLockSync(key)
}
// Implements DB.
func (ddb debugDB) Iterator(start, end []byte) Iterator {
fmt.Printf("%v.Iterator(%v, %v)\n", ddb.label,
cmn.ColoredBytes(start, cmn.Cyan, cmn.Blue),
cmn.ColoredBytes(end, cmn.Cyan, cmn.Blue))
return NewDebugIterator(ddb.label, ddb.db.Iterator(start, end))
}
// Implements DB.
func (ddb debugDB) ReverseIterator(start, end []byte) Iterator {
fmt.Printf("%v.ReverseIterator(%v, %v)\n", ddb.label,
cmn.ColoredBytes(start, cmn.Cyan, cmn.Blue),
cmn.ColoredBytes(end, cmn.Cyan, cmn.Blue))
return NewDebugIterator(ddb.label, ddb.db.ReverseIterator(start, end))
}
// Implements DB.
// Panics if the underlying db is not an
// atomicSetDeleter.
func (ddb debugDB) NewBatch() Batch {
fmt.Printf("%v.NewBatch()\n", ddb.label)
return NewDebugBatch(ddb.label, ddb.db.NewBatch())
}
// Implements DB.
func (ddb debugDB) Close() {
fmt.Printf("%v.Close()\n", ddb.label)
ddb.db.Close()
}
// Implements DB.
func (ddb debugDB) Print() {
ddb.db.Print()
}
// Implements DB.
func (ddb debugDB) Stats() map[string]string {
return ddb.db.Stats()
}
//----------------------------------------
// debugIterator
type debugIterator struct {
label string
itr Iterator
}
// For printing all operationgs to the console for debugging.
func NewDebugIterator(label string, itr Iterator) debugIterator {
return debugIterator{
label: label,
itr: itr,
}
}
// Implements Iterator.
func (ditr debugIterator) Domain() (start []byte, end []byte) {
defer func() {
fmt.Printf("%v.itr.Domain() (%X,%X)\n", ditr.label, start, end)
}()
start, end = ditr.itr.Domain()
return
}
// Implements Iterator.
func (ditr debugIterator) Valid() (ok bool) {
defer func() {
fmt.Printf("%v.itr.Valid() %v\n", ditr.label, ok)
}()
ok = ditr.itr.Valid()
return
}
// Implements Iterator.
func (ditr debugIterator) Next() {
fmt.Printf("%v.itr.Next()\n", ditr.label)
ditr.itr.Next()
}
// Implements Iterator.
func (ditr debugIterator) Key() (key []byte) {
key = ditr.itr.Key()
fmt.Printf("%v.itr.Key() %v\n", ditr.label,
cmn.ColoredBytes(key, cmn.Cyan, cmn.Blue))
return
}
// Implements Iterator.
func (ditr debugIterator) Value() (value []byte) {
value = ditr.itr.Value()
fmt.Printf("%v.itr.Value() %v\n", ditr.label,
cmn.ColoredBytes(value, cmn.Green, cmn.Blue))
return
}
// Implements Iterator.
func (ditr debugIterator) Close() {
fmt.Printf("%v.itr.Close()\n", ditr.label)
ditr.itr.Close()
}
//----------------------------------------
// debugBatch
type debugBatch struct {
label string
bch Batch
}
// For printing all operationgs to the console for debugging.
func NewDebugBatch(label string, bch Batch) debugBatch {
return debugBatch{
label: label,
bch: bch,
}
}
// Implements Batch.
func (dbch debugBatch) Set(key, value []byte) {
fmt.Printf("%v.batch.Set(%v, %v)\n", dbch.label,
cmn.ColoredBytes(key, cmn.Yellow, cmn.Blue),
cmn.ColoredBytes(value, cmn.Green, cmn.Blue))
dbch.bch.Set(key, value)
}
// Implements Batch.
func (dbch debugBatch) Delete(key []byte) {
fmt.Printf("%v.batch.Delete(%v)\n", dbch.label,
cmn.ColoredBytes(key, cmn.Red, cmn.Yellow))
dbch.bch.Delete(key)
}
// Implements Batch.
func (dbch debugBatch) Write() {
fmt.Printf("%v.batch.Write()\n", dbch.label)
dbch.bch.Write()
}
// Implements Batch.
func (dbch debugBatch) WriteSync() {
fmt.Printf("%v.batch.WriteSync()\n", dbch.label)
dbch.bch.WriteSync()
}
// Implements Batch.
func (dbch debugBatch) Close() {
dbch.bch.Close()
}

View File

@ -1,21 +0,0 @@
// Package errors contains errors that are thrown across packages.
package errors
// // ErrPermissionsChanged occurs if the file permission have changed since the file was created.
// type ErrPermissionsChanged struct {
// name string
// got, want os.FileMode
// }
// func NewErrPermissionsChanged(name string, got, want os.FileMode) *ErrPermissionsChanged {
// return &ErrPermissionsChanged{name: name, got: got, want: want}
// }
// func (e ErrPermissionsChanged) Error() string {
// return fmt.Sprintf(
// "file: [%v]\nexpected file permissions: %v, got: %v",
// e.name,
// e.want,
// e.got,
// )
// }

View File

@ -2,36 +2,30 @@ package fail
import ( import (
"fmt" "fmt"
"math/rand"
"os" "os"
"strconv" "strconv"
) )
var callIndexToFail int func envSet() int {
func init() {
callIndexToFailS := os.Getenv("FAIL_TEST_INDEX") callIndexToFailS := os.Getenv("FAIL_TEST_INDEX")
if callIndexToFailS == "" { if callIndexToFailS == "" {
callIndexToFail = -1 return -1
} else { } else {
var err error var err error
callIndexToFail, err = strconv.Atoi(callIndexToFailS) callIndexToFail, err := strconv.Atoi(callIndexToFailS)
if err != nil { if err != nil {
callIndexToFail = -1 return -1
} }
return callIndexToFail
} }
} }
// Fail when FAIL_TEST_INDEX == callIndex // Fail when FAIL_TEST_INDEX == callIndex
var ( var callIndex int //indexes Fail calls
callIndex int //indexes Fail calls
callRandIndex int // indexes a run of FailRand calls
callRandIndexToFail = -1 // the callRandIndex to fail on in FailRand
)
func Fail() { func Fail() {
callIndexToFail := envSet()
if callIndexToFail < 0 { if callIndexToFail < 0 {
return return
} }
@ -43,33 +37,6 @@ func Fail() {
callIndex += 1 callIndex += 1
} }
// FailRand should be called n successive times.
// It will fail on a random one of those calls
// n must be greater than 0
func FailRand(n int) {
if callIndexToFail < 0 {
return
}
if callRandIndexToFail < 0 {
// first call in the loop, pick a random index to fail at
callRandIndexToFail = rand.Intn(n)
callRandIndex = 0
}
if callIndex == callIndexToFail {
if callRandIndex == callRandIndexToFail {
Exit()
}
}
callRandIndex += 1
if callRandIndex == n {
callIndex += 1
}
}
func Exit() { func Exit() {
fmt.Printf("*** fail-test %d ***\n", callIndex) fmt.Printf("*** fail-test %d ***\n", callIndex)
os.Exit(1) os.Exit(1)

View File

@ -1,14 +0,0 @@
package test
import (
"testing"
)
func AssertPanics(t *testing.T, msg string, f func()) {
defer func() {
if err := recover(); err == nil {
t.Errorf("Should have panic'd, but didn't: %v", msg)
}
}()
f()
}

View File

@ -1,3 +0,0 @@
package version
const Version = "0.9.0"

View File

@ -279,7 +279,7 @@ func (mem *CListMempool) CheckTxWithInfo(tx types.Tx, cb func(*abci.Response), t
return err return err
} }
reqRes := mem.proxyAppConn.CheckTxAsync(tx) reqRes := mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{Tx: tx})
reqRes.SetCallback(mem.reqResCb(tx, txInfo.SenderID, cb)) reqRes.SetCallback(mem.reqResCb(tx, txInfo.SenderID, cb))
return nil return nil
@ -591,7 +591,10 @@ func (mem *CListMempool) recheckTxs() {
// NOTE: globalCb may be called concurrently. // NOTE: globalCb may be called concurrently.
for e := mem.txs.Front(); e != nil; e = e.Next() { for e := mem.txs.Front(); e != nil; e = e.Next() {
memTx := e.Value.(*mempoolTx) memTx := e.Value.(*mempoolTx)
mem.proxyAppConn.CheckTxAsync(memTx.tx) mem.proxyAppConn.CheckTxAsync(abci.RequestCheckTx{
Tx: memTx.tx,
Type: abci.CheckTxType_Recheck,
})
} }
mem.proxyAppConn.FlushAsync() mem.proxyAppConn.FlushAsync()

View File

@ -314,7 +314,7 @@ func TestSerialReap(t *testing.T) {
for i := start; i < end; i++ { for i := start; i < end; i++ {
txBytes := make([]byte, 8) txBytes := make([]byte, 8)
binary.BigEndian.PutUint64(txBytes, uint64(i)) binary.BigEndian.PutUint64(txBytes, uint64(i))
res, err := appConnCon.DeliverTxSync(txBytes) res, err := appConnCon.DeliverTxSync(abci.RequestDeliverTx{Tx: txBytes})
if err != nil { if err != nil {
t.Errorf("Client error committing tx: %v", err) t.Errorf("Client error committing tx: %v", err)
} }
@ -522,7 +522,7 @@ func TestMempoolTxsBytes(t *testing.T) {
err = appConnCon.Start() err = appConnCon.Start()
require.Nil(t, err) require.Nil(t, err)
defer appConnCon.Stop() defer appConnCon.Stop()
res, err := appConnCon.DeliverTxSync(txBytes) res, err := appConnCon.DeliverTxSync(abci.RequestDeliverTx{Tx: txBytes})
require.NoError(t, err) require.NoError(t, err)
require.EqualValues(t, 0, res.Code) require.EqualValues(t, 0, res.Code)
res2, err := appConnCon.CommitSync() res2, err := appConnCon.CommitSync()

View File

@ -47,6 +47,10 @@ import (
"github.com/tendermint/tendermint/version" "github.com/tendermint/tendermint/version"
) )
// CustomReactorNamePrefix is a prefix for all custom reactors to prevent
// clashes with built-in reactors.
const CustomReactorNamePrefix = "CUSTOM_"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// DBContext specifies config information for loading a new DB. // DBContext specifies config information for loading a new DB.
@ -136,6 +140,18 @@ func DefaultMetricsProvider(config *cfg.InstrumentationConfig) MetricsProvider {
} }
} }
// Option sets a parameter for the node.
type Option func(*Node)
// CustomReactors allows you to add custom reactors to the node's Switch.
func CustomReactors(reactors map[string]p2p.Reactor) Option {
return func(n *Node) {
for name, reactor := range reactors {
n.sw.AddReactor(CustomReactorNamePrefix+name, reactor)
}
}
}
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Node is the highest level interface to a full Tendermint node. // Node is the highest level interface to a full Tendermint node.
@ -433,6 +449,7 @@ func createSwitch(config *cfg.Config,
sw.AddReactor("BLOCKCHAIN", bcReactor) sw.AddReactor("BLOCKCHAIN", bcReactor)
sw.AddReactor("CONSENSUS", consensusReactor) sw.AddReactor("CONSENSUS", consensusReactor)
sw.AddReactor("EVIDENCE", evidenceReactor) sw.AddReactor("EVIDENCE", evidenceReactor)
sw.SetNodeInfo(nodeInfo) sw.SetNodeInfo(nodeInfo)
sw.SetNodeKey(nodeKey) sw.SetNodeKey(nodeKey)
@ -495,7 +512,8 @@ func NewNode(config *cfg.Config,
genesisDocProvider GenesisDocProvider, genesisDocProvider GenesisDocProvider,
dbProvider DBProvider, dbProvider DBProvider,
metricsProvider MetricsProvider, metricsProvider MetricsProvider,
logger log.Logger) (*Node, error) { logger log.Logger,
options ...Option) (*Node, error) {
blockStore, stateDB, err := initDBs(config, dbProvider) blockStore, stateDB, err := initDBs(config, dbProvider)
if err != nil { if err != nil {
@ -661,6 +679,11 @@ func NewNode(config *cfg.Config,
eventBus: eventBus, eventBus: eventBus,
} }
node.BaseService = *cmn.NewBaseService(logger, "Node", node) node.BaseService = *cmn.NewBaseService(logger, "Node", node)
for _, option := range options {
option(node)
}
return node, nil return node, nil
} }

View File

@ -21,6 +21,7 @@ import (
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
mempl "github.com/tendermint/tendermint/mempool" mempl "github.com/tendermint/tendermint/mempool"
"github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/p2p"
p2pmock "github.com/tendermint/tendermint/p2p/mock"
"github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/privval"
"github.com/tendermint/tendermint/proxy" "github.com/tendermint/tendermint/proxy"
sm "github.com/tendermint/tendermint/state" sm "github.com/tendermint/tendermint/state"
@ -100,7 +101,10 @@ func TestNodeDelayedStart(t *testing.T) {
n.GenesisDoc().GenesisTime = now.Add(2 * time.Second) n.GenesisDoc().GenesisTime = now.Add(2 * time.Second)
require.NoError(t, err) require.NoError(t, err)
n.Start() err = n.Start()
require.NoError(t, err)
defer n.Stop()
startTime := tmtime.Now() startTime := tmtime.Now()
assert.Equal(t, true, startTime.After(n.GenesisDoc().GenesisTime)) assert.Equal(t, true, startTime.After(n.GenesisDoc().GenesisTime))
} }
@ -279,6 +283,34 @@ func TestCreateProposalBlock(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
} }
func TestNodeNewNodeCustomReactors(t *testing.T) {
config := cfg.ResetTestRoot("node_new_node_custom_reactors_test")
defer os.RemoveAll(config.RootDir)
cr := p2pmock.NewReactor()
nodeKey, err := p2p.LoadOrGenNodeKey(config.NodeKeyFile())
require.NoError(t, err)
n, err := NewNode(config,
privval.LoadOrGenFilePV(config.PrivValidatorKeyFile(), config.PrivValidatorStateFile()),
nodeKey,
proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()),
DefaultGenesisDocProviderFunc(config),
DefaultDBProvider,
DefaultMetricsProvider(config.Instrumentation),
log.TestingLogger(),
CustomReactors(map[string]p2p.Reactor{"FOO": cr}),
)
require.NoError(t, err)
err = n.Start()
require.NoError(t, err)
defer n.Stop()
assert.True(t, cr.IsRunning())
}
func state(nVals int, height int64) (sm.State, dbm.DB) { func state(nVals int, height int64) (sm.State, dbm.DB) {
vals := make([]types.GenesisValidator, nVals) vals := make([]types.GenesisValidator, nVals)
for i := 0; i < nVals; i++ { for i := 0; i < nVals; i++ {

23
p2p/mock/reactor.go Normal file
View File

@ -0,0 +1,23 @@
package mock
import (
"github.com/tendermint/tendermint/libs/log"
"github.com/tendermint/tendermint/p2p"
"github.com/tendermint/tendermint/p2p/conn"
)
type Reactor struct {
p2p.BaseReactor
}
func NewReactor() *Reactor {
r := &Reactor{}
r.BaseReactor = *p2p.NewBaseReactor("Reactor", r)
r.SetLogger(log.TestingLogger())
return r
}
func (r *Reactor) GetChannels() []*conn.ChannelDescriptor { return []*conn.ChannelDescriptor{} }
func (r *Reactor) AddPeer(peer p2p.Peer) {}
func (r *Reactor) RemovePeer(peer p2p.Peer, reason interface{}) {}
func (r *Reactor) Receive(chID byte, peer p2p.Peer, msgBytes []byte) {}

View File

@ -13,7 +13,7 @@ import (
"strings" "strings"
"time" "time"
"errors" "github.com/pkg/errors"
) )
// NetAddress defines information about a peer on the network // NetAddress defines information about a peer on the network
@ -40,7 +40,7 @@ func IDAddressString(id ID, protocolHostPort string) string {
// NewNetAddress returns a new NetAddress using the provided TCP // NewNetAddress returns a new NetAddress using the provided TCP
// address. When testing, other net.Addr (except TCP) will result in // address. When testing, other net.Addr (except TCP) will result in
// using 0.0.0.0:0. When normal run, other net.Addr (except TCP) will // using 0.0.0.0:0. When normal run, other net.Addr (except TCP) will
// panic. // panic. Panics if ID is invalid.
// TODO: socks proxies? // TODO: socks proxies?
func NewNetAddress(id ID, addr net.Addr) *NetAddress { func NewNetAddress(id ID, addr net.Addr) *NetAddress {
tcpAddr, ok := addr.(*net.TCPAddr) tcpAddr, ok := addr.(*net.TCPAddr)
@ -53,6 +53,11 @@ func NewNetAddress(id ID, addr net.Addr) *NetAddress {
return netAddr return netAddr
} }
} }
if err := validateID(id); err != nil {
panic(fmt.Sprintf("Invalid ID %v: %v (addr: %v)", id, err, addr))
}
ip := tcpAddr.IP ip := tcpAddr.IP
port := uint16(tcpAddr.Port) port := uint16(tcpAddr.Port)
na := NewNetAddressIPPort(ip, port) na := NewNetAddressIPPort(ip, port)
@ -72,18 +77,11 @@ func NewNetAddressString(addr string) (*NetAddress, error) {
} }
// get ID // get ID
idStr := spl[0] if err := validateID(ID(spl[0])); err != nil {
idBytes, err := hex.DecodeString(idStr)
if err != nil {
return nil, ErrNetAddressInvalid{addrWithoutProtocol, err} return nil, ErrNetAddressInvalid{addrWithoutProtocol, err}
} }
if len(idBytes) != IDByteLength {
return nil, ErrNetAddressInvalid{
addrWithoutProtocol,
fmt.Errorf("invalid hex length - got %d, expected %d", len(idBytes), IDByteLength)}
}
var id ID var id ID
id, addrWithoutProtocol = ID(idStr), spl[1] id, addrWithoutProtocol = ID(spl[0]), spl[1]
// get host and port // get host and port
host, portStr, err := net.SplitHostPort(addrWithoutProtocol) host, portStr, err := net.SplitHostPort(addrWithoutProtocol)
@ -207,22 +205,28 @@ func (na *NetAddress) DialTimeout(timeout time.Duration) (net.Conn, error) {
// Routable returns true if the address is routable. // Routable returns true if the address is routable.
func (na *NetAddress) Routable() bool { func (na *NetAddress) Routable() bool {
if err := na.Valid(); err != nil {
return false
}
// TODO(oga) bitcoind doesn't include RFC3849 here, but should we? // TODO(oga) bitcoind doesn't include RFC3849 here, but should we?
return na.Valid() && !(na.RFC1918() || na.RFC3927() || na.RFC4862() || return !(na.RFC1918() || na.RFC3927() || na.RFC4862() ||
na.RFC4193() || na.RFC4843() || na.Local()) na.RFC4193() || na.RFC4843() || na.Local())
} }
// For IPv4 these are either a 0 or all bits set address. For IPv6 a zero // For IPv4 these are either a 0 or all bits set address. For IPv6 a zero
// address or one that matches the RFC3849 documentation address format. // address or one that matches the RFC3849 documentation address format.
func (na *NetAddress) Valid() bool { func (na *NetAddress) Valid() error {
if string(na.ID) != "" { if err := validateID(na.ID); err != nil {
data, err := hex.DecodeString(string(na.ID)) return errors.Wrap(err, "invalid ID")
if err != nil || len(data) != IDByteLength {
return false
} }
if na.IP == nil {
return errors.New("no IP")
} }
return na.IP != nil && !(na.IP.IsUnspecified() || na.RFC3849() || if na.IP.IsUnspecified() || na.RFC3849() || na.IP.Equal(net.IPv4bcast) {
na.IP.Equal(net.IPv4bcast)) return errors.New("invalid IP")
}
return nil
} }
// HasID returns true if the address has an ID. // HasID returns true if the address has an ID.
@ -329,3 +333,17 @@ func removeProtocolIfDefined(addr string) string {
return addr return addr
} }
func validateID(id ID) error {
if len(id) == 0 {
return errors.New("no ID")
}
idBytes, err := hex.DecodeString(string(id))
if err != nil {
return err
}
if len(idBytes) != IDByteLength {
return fmt.Errorf("invalid hex length - got %d, expected %d", len(idBytes), IDByteLength)
}
return nil
}

View File

@ -11,9 +11,13 @@ import (
func TestNewNetAddress(t *testing.T) { func TestNewNetAddress(t *testing.T) {
tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:8080") tcpAddr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:8080")
require.Nil(t, err) require.Nil(t, err)
addr := NewNetAddress("", tcpAddr)
assert.Equal(t, "127.0.0.1:8080", addr.String()) assert.Panics(t, func() {
NewNetAddress("", tcpAddr)
})
addr := NewNetAddress("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef", tcpAddr)
assert.Equal(t, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef@127.0.0.1:8080", addr.String())
assert.NotPanics(t, func() { assert.NotPanics(t, func() {
NewNetAddress("", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8000}) NewNetAddress("", &net.UDPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8000})
@ -106,7 +110,12 @@ func TestNetAddressProperties(t *testing.T) {
addr, err := NewNetAddressString(tc.addr) addr, err := NewNetAddressString(tc.addr)
require.Nil(t, err) require.Nil(t, err)
assert.Equal(t, tc.valid, addr.Valid()) err = addr.Valid()
if tc.valid {
assert.NoError(t, err)
} else {
assert.Error(t, err)
}
assert.Equal(t, tc.local, addr.Local()) assert.Equal(t, tc.local, addr.Local())
assert.Equal(t, tc.routable, addr.Routable()) assert.Equal(t, tc.routable, addr.Routable())
} }

View File

@ -586,8 +586,8 @@ func (a *addrBook) addAddress(addr, src *p2p.NetAddress) error {
return ErrAddrBookNilAddr{addr, src} return ErrAddrBookNilAddr{addr, src}
} }
if !addr.HasID() { if err := addr.Valid(); err != nil {
return ErrAddrBookInvalidAddrNoID{addr} return ErrAddrBookInvalidAddr{Addr: addr, AddrErr: err}
} }
if _, ok := a.privateIDs[addr.ID]; ok { if _, ok := a.privateIDs[addr.ID]; ok {
@ -607,10 +607,6 @@ func (a *addrBook) addAddress(addr, src *p2p.NetAddress) error {
return ErrAddrBookNonRoutable{addr} return ErrAddrBookNonRoutable{addr}
} }
if !addr.Valid() {
return ErrAddrBookInvalidAddr{addr}
}
ka := a.addrLookup[addr.ID] ka := a.addrLookup[addr.ID]
if ka != nil { if ka != nil {
// If its already old and the addr is the same, ignore it. // If its already old and the addr is the same, ignore it.

View File

@ -57,16 +57,9 @@ func (err ErrAddrBookNilAddr) Error() string {
type ErrAddrBookInvalidAddr struct { type ErrAddrBookInvalidAddr struct {
Addr *p2p.NetAddress Addr *p2p.NetAddress
AddrErr error
} }
func (err ErrAddrBookInvalidAddr) Error() string { func (err ErrAddrBookInvalidAddr) Error() string {
return fmt.Sprintf("Cannot add invalid address %v", err.Addr) return fmt.Sprintf("Cannot add invalid address %v: %v", err.Addr, err.AddrErr)
}
type ErrAddrBookInvalidAddrNoID struct {
Addr *p2p.NetAddress
}
func (err ErrAddrBookInvalidAddrNoID) Error() string {
return fmt.Sprintf("Cannot add address with no ID %v", err.Addr)
} }

View File

@ -340,23 +340,18 @@ func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error {
if err != nil { if err != nil {
return err return err
} }
for _, netAddr := range addrs {
// Validate netAddr. Disconnect from a peer if it sends us invalid data. srcIsSeed := false
if netAddr == nil { for _, seedAddr := range r.seedAddrs {
return errors.New("nil address in pexAddrsMessage") if seedAddr.Equals(srcAddr) {
srcIsSeed = true
break
} }
// TODO: extract validating logic from NewNetAddressString
// and put it in netAddr#Valid (#2722)
na, err := p2p.NewNetAddressString(netAddr.String())
if err != nil {
return fmt.Errorf("%s address in pexAddrsMessage is invalid: %v",
netAddr.String(),
err,
)
} }
for _, netAddr := range addrs {
// NOTE: we check netAddr validity and routability in book#AddAddress. // NOTE: we check netAddr validity and routability in book#AddAddress.
err = r.book.AddAddress(na, srcAddr) err = r.book.AddAddress(netAddr, srcAddr)
if err != nil { if err != nil {
r.logErrAddrBook(err) r.logErrAddrBook(err)
// XXX: should we be strict about incoming data and disconnect from a // XXX: should we be strict about incoming data and disconnect from a
@ -365,13 +360,23 @@ func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error {
} }
// If this address came from a seed node, try to connect to it without // If this address came from a seed node, try to connect to it without
// waiting. // waiting (#2093)
for _, seedAddr := range r.seedAddrs { if srcIsSeed {
if seedAddr.Equals(srcAddr) { r.Logger.Info("Will dial address, which came from seed", "addr", netAddr, "seed", srcAddr)
r.ensurePeers() go func(addr *p2p.NetAddress) {
err := r.dialPeer(addr)
if err != nil {
switch err.(type) {
case errMaxAttemptsToDial, errTooEarlyToDial:
r.Logger.Debug(err.Error(), "addr", addr)
default:
r.Logger.Error(err.Error(), "addr", addr)
} }
} }
}(netAddr)
} }
}
return nil return nil
} }

View File

@ -15,7 +15,7 @@ type AppConnConsensus interface {
InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error) InitChainSync(types.RequestInitChain) (*types.ResponseInitChain, error)
BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error) BeginBlockSync(types.RequestBeginBlock) (*types.ResponseBeginBlock, error)
DeliverTxAsync(tx []byte) *abcicli.ReqRes DeliverTxAsync(types.RequestDeliverTx) *abcicli.ReqRes
EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error) EndBlockSync(types.RequestEndBlock) (*types.ResponseEndBlock, error)
CommitSync() (*types.ResponseCommit, error) CommitSync() (*types.ResponseCommit, error)
} }
@ -24,7 +24,7 @@ type AppConnMempool interface {
SetResponseCallback(abcicli.Callback) SetResponseCallback(abcicli.Callback)
Error() error Error() error
CheckTxAsync(tx []byte) *abcicli.ReqRes CheckTxAsync(types.RequestCheckTx) *abcicli.ReqRes
FlushAsync() *abcicli.ReqRes FlushAsync() *abcicli.ReqRes
FlushSync() error FlushSync() error
@ -69,8 +69,8 @@ func (app *appConnConsensus) BeginBlockSync(req types.RequestBeginBlock) (*types
return app.appConn.BeginBlockSync(req) return app.appConn.BeginBlockSync(req)
} }
func (app *appConnConsensus) DeliverTxAsync(tx []byte) *abcicli.ReqRes { func (app *appConnConsensus) DeliverTxAsync(req types.RequestDeliverTx) *abcicli.ReqRes {
return app.appConn.DeliverTxAsync(tx) return app.appConn.DeliverTxAsync(req)
} }
func (app *appConnConsensus) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) { func (app *appConnConsensus) EndBlockSync(req types.RequestEndBlock) (*types.ResponseEndBlock, error) {
@ -110,8 +110,8 @@ func (app *appConnMempool) FlushSync() error {
return app.appConn.FlushSync() return app.appConn.FlushSync()
} }
func (app *appConnMempool) CheckTxAsync(tx []byte) *abcicli.ReqRes { func (app *appConnMempool) CheckTxAsync(req types.RequestCheckTx) *abcicli.ReqRes {
return app.appConn.CheckTxAsync(tx) return app.appConn.CheckTxAsync(req)
} }
//------------------------------------------------ //------------------------------------------------

201
scripts/gitian-build.sh Executable file
View File

@ -0,0 +1,201 @@
#!/bin/bash
# symbol prefixes:
# g_ -> global
# l_ - local variable
# f_ -> function
set -euo pipefail
GITIAN_CACHE_DIRNAME='.gitian-builder-cache'
GO_DEBIAN_RELEASE='1.12.5-1'
GO_TARBALL="golang-debian-${GO_DEBIAN_RELEASE}.tar.gz"
GO_TARBALL_URL="https://salsa.debian.org/go-team/compiler/golang/-/archive/debian/${GO_DEBIAN_RELEASE}/${GO_TARBALL}"
# Defaults
DEFAULT_SIGN_COMMAND='gpg --detach-sign'
DEFAULT_TENDERMINT_SIGS=${TENDERMINT_SIGS:-'tendermint.sigs'}
DEFAULT_GITIAN_REPO='https://github.com/devrandom/gitian-builder'
DEFAULT_GBUILD_FLAGS=''
DEFAULT_SIGS_REPO='https://github.com/tendermint/tendermint.sigs'
# Overrides
SIGN_COMMAND=${SIGN_COMMAND:-${DEFAULT_SIGN_COMMAND}}
GITIAN_REPO=${GITIAN_REPO:-${DEFAULT_GITIAN_REPO}}
GBUILD_FLAGS=${GBUILD_FLAGS:-${DEFAULT_GBUILD_FLAGS}}
# Globals
g_workdir=''
g_gitian_cache=''
g_cached_gitian=''
g_cached_go_tarball=''
g_sign_identity=''
g_sigs_dir=''
g_flag_commit=''
f_help() {
cat >&2 <<EOF
Usage: $(basename $0) [-h] PLATFORM
Launch a gitian build from the current source directory for the given PLATFORM.
The following platforms are supported:
darwin
linux
windows
all
Options:
-h display this help and exit
-c clone the signatures repository and commit signatures;
ignored if sign identity is not supplied
-s IDENTITY sign build as IDENTITY
If a GPG identity is supplied via the -s flag, the build will be signed and verified.
The signature will be saved in '${DEFAULT_TENDERMINT_SIGS}/'. An alternative output directory
for signatures can be supplied via the environment variable \$TENDERMINT_SIGS.
The default signing command used to sign the build is '$DEFAULT_SIGN_COMMAND'.
An alternative signing command can be supplied via the environment
variable \$SIGN_COMMAND.
EOF
}
f_builddir() {
printf '%s' "${g_workdir}/gitian-build-$1"
}
f_prep_build() {
local l_platforms \
l_os \
l_builddir
l_platforms="$1"
if [ -n "${g_flag_commit}" -a ! -d "${g_sigs_dir}" ]; then
git clone ${DEFAULT_SIGS_REPO} "${g_sigs_dir}"
fi
for l_os in ${l_platforms}; do
l_builddir="$(f_builddir ${l_os})"
f_echo_stderr "Preparing build directory $(basename ${l_builddir}), restoring files from cache"
cp -ar "${g_cached_gitian}" "${l_builddir}" >&2
mkdir "${l_builddir}/inputs/"
cp -v "${g_cached_go_tarball}" "${l_builddir}/inputs/"
done
}
f_build() {
local l_descriptor
l_descriptor=$1
bin/gbuild --commit tendermint="$g_commit" ${GBUILD_FLAGS} "$l_descriptor"
libexec/stop-target || f_echo_stderr "warning: couldn't stop target"
}
f_sign_verify() {
local l_descriptor
l_descriptor=$1
bin/gsign -p "${SIGN_COMMAND}" -s "${g_sign_identity}" --destination="${g_sigs_dir}" --release=${g_release} ${l_descriptor}
bin/gverify --destination="${g_sigs_dir}" --release="${g_release}" ${l_descriptor}
}
f_commit_sig() {
local l_release_name
l_release_name=$1
pushd "${g_sigs_dir}"
git add . || echo "git add failed" >&2
git commit -m "Add ${l_release_name} reproducible build" || echo "git commit failed" >&2
popd
}
f_prep_docker_image() {
pushd $1
bin/make-base-vm --docker --suite bionic --arch amd64
popd
}
f_ensure_cache() {
g_gitian_cache="${g_workdir}/${GITIAN_CACHE_DIRNAME}"
[ -d "${g_gitian_cache}" ] || mkdir "${g_gitian_cache}"
g_cached_go_tarball="${g_gitian_cache}/${GO_TARBALL}"
if [ ! -f "${g_cached_go_tarball}" ]; then
f_echo_stderr "${g_cached_go_tarball}: cache miss, caching..."
curl -L "${GO_TARBALL_URL}" --output "${g_cached_go_tarball}"
fi
g_cached_gitian="${g_gitian_cache}/gitian-builder"
if [ ! -d "${g_cached_gitian}" ]; then
f_echo_stderr "${g_cached_gitian}: cache miss, caching..."
git clone ${GITIAN_REPO} "${g_cached_gitian}"
fi
}
f_demangle_platforms() {
case "${1}" in
all)
printf '%s' 'darwin linux windows' ;;
linux|darwin|windows)
printf '%s' "${1}" ;;
*)
echo "invalid platform -- ${1}"
exit 1
esac
}
f_echo_stderr() {
echo $@ >&2
}
while getopts ":cs:h" opt; do
case "${opt}" in
h) f_help ; exit 0 ;;
c) g_flag_commit=y ;;
s) g_sign_identity="${OPTARG}" ;;
esac
done
shift "$((OPTIND-1))"
g_platforms=$(f_demangle_platforms "${1}")
g_workdir="$(pwd)"
g_commit="$(git rev-parse HEAD)"
g_sigs_dir=${TENDERMINT_SIGS:-"${g_workdir}/${DEFAULT_TENDERMINT_SIGS}"}
f_ensure_cache
f_prep_docker_image "${g_cached_gitian}"
f_prep_build "${g_platforms}"
export USE_DOCKER=1
for g_os in ${g_platforms}; do
g_release="$(git describe --tags --abbrev=9 | sed 's/^v//')-${g_os}"
g_descriptor="${g_workdir}/scripts/gitian-descriptors/gitian-${g_os}.yml"
[ -f ${g_descriptor} ]
g_builddir="$(f_builddir ${g_os})"
pushd "${g_builddir}"
f_build "${g_descriptor}"
if [ -n "${g_sign_identity}" ]; then
f_sign_verify "${g_descriptor}"
fi
popd
if [ -n "${g_sign_identity}" -a -n "${g_flag_commit}" ]; then
[ -d "${g_sigs_dir}/.git/" ] && f_commit_sig ${g_release} || f_echo_stderr "couldn't commit, ${g_sigs_dir} is not a git clone"
fi
done
exit 0

View File

@ -0,0 +1,111 @@
---
name: "tendermint-darwin"
enable_cache: true
distro: "ubuntu"
suites:
- "bionic"
architectures:
- "amd64"
packages:
- "bsdmainutils"
- "build-essential"
- "ca-certificates"
- "curl"
- "debhelper"
- "dpkg-dev"
- "devscripts"
- "fakeroot"
- "git"
- "golang-any"
- "xxd"
- "quilt"
remotes:
- "url": "https://github.com/tendermint/tendermint.git"
"dir": "tendermint"
files:
- "golang-debian-1.12.5-1.tar.gz"
script: |
set -e -o pipefail
GO_SRC_RELEASE=golang-debian-1.12.5-1
GO_SRC_TARBALL="${GO_SRC_RELEASE}.tar.gz"
# Compile go and configure the environment
export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
export BUILD_DIR=`pwd`
tar xf "${GO_SRC_TARBALL}"
rm -f "${GO_SRC_TARBALL}"
[ -d "${GO_SRC_RELEASE}/" ]
mv "${GO_SRC_RELEASE}/" go/
pushd go/
QUILT_PATCHES=debian/patches quilt push -a
fakeroot debian/rules build RUN_TESTS=false GOCACHE=/tmp/go-cache
popd
export GOOS=darwin
export GOROOT=${BUILD_DIR}/go
export GOPATH=${BUILD_DIR}/gopath
mkdir -p ${GOPATH}/bin
export PATH_orig=${PATH}
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
export ARCHS='386 amd64'
export GO111MODULE=on
# Make release tarball
pushd tendermint
VERSION=$(git describe --tags | sed 's/^v//')
COMMIT=$(git rev-parse --short=8 HEAD)
DISTNAME=tendermint-${VERSION}
git archive --format tar.gz --prefix ${DISTNAME}/ -o ${DISTNAME}.tar.gz HEAD
SOURCEDIST=`pwd`/`echo tendermint-*.tar.gz`
popd
# Correct tar file order
mkdir -p temp
pushd temp
tar xf $SOURCEDIST
rm $SOURCEDIST
find tendermint-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > $SOURCEDIST
popd
# Prepare GOPATH and install deps
distsrc=${GOPATH}/src/github.com/tendermint/tendermint
mkdir -p ${distsrc}
pushd ${distsrc}
tar --strip-components=1 -xf $SOURCEDIST
go mod download
popd
# Configure LDFLAGS for reproducible builds
LDFLAGS="-extldflags=-static -buildid=${VERSION} -s -w \
-X github.com/tendermint/tendermint/version.GitCommit=${COMMIT}"
# Extract release tarball and build
for arch in ${ARCHS}; do
INSTALLPATH=`pwd`/installed/${DISTNAME}-${arch}
mkdir -p ${INSTALLPATH}
# Build tendermint binary
pushd ${distsrc}
GOARCH=${arch} GOROOT_FINAL=${GOROOT} go build -a \
-gcflags=all=-trimpath=${GOPATH} \
-asmflags=all=-trimpath=${GOPATH} \
-mod=readonly -tags "tendermint" \
-ldflags="${LDFLAGS}" \
-o ${INSTALLPATH}/tendermint ./cmd/tendermint/
popd # ${distsrc}
pushd ${INSTALLPATH}
find -type f | sort | tar \
--no-recursion --mode='u+rw,go+r-w,a+X' \
--numeric-owner --sort=name \
--owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-darwin-${arch}.tar.gz
popd # installed
done
rm -rf ${distsrc}
mkdir -p $OUTDIR/src
mv $SOURCEDIST $OUTDIR/src

View File

@ -0,0 +1,110 @@
---
name: "tendermint-linux"
enable_cache: true
distro: "ubuntu"
suites:
- "bionic"
architectures:
- "amd64"
packages:
- "bsdmainutils"
- "build-essential"
- "ca-certificates"
- "curl"
- "debhelper"
- "dpkg-dev"
- "devscripts"
- "fakeroot"
- "git"
- "golang-any"
- "xxd"
- "quilt"
remotes:
- "url": "https://github.com/tendermint/tendermint.git"
"dir": "tendermint"
files:
- "golang-debian-1.12.5-1.tar.gz"
script: |
set -e -o pipefail
GO_SRC_RELEASE=golang-debian-1.12.5-1
GO_SRC_TARBALL="${GO_SRC_RELEASE}.tar.gz"
# Compile go and configure the environment
export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
export BUILD_DIR=`pwd`
tar xf "${GO_SRC_TARBALL}"
rm -f "${GO_SRC_TARBALL}"
[ -d "${GO_SRC_RELEASE}/" ]
mv "${GO_SRC_RELEASE}/" go/
pushd go/
QUILT_PATCHES=debian/patches quilt push -a
fakeroot debian/rules build RUN_TESTS=false GOCACHE=/tmp/go-cache
popd
export GOROOT=${BUILD_DIR}/go
export GOPATH=${BUILD_DIR}/gopath
mkdir -p ${GOPATH}/bin
export PATH_orig=${PATH}
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
export ARCHS='386 amd64 arm arm64'
export GO111MODULE=on
# Make release tarball
pushd tendermint
VERSION=$(git describe --tags | sed 's/^v//')
COMMIT=$(git rev-parse --short=8 HEAD)
DISTNAME=tendermint-${VERSION}
git archive --format tar.gz --prefix ${DISTNAME}/ -o ${DISTNAME}.tar.gz HEAD
SOURCEDIST=`pwd`/`echo tendermint-*.tar.gz`
popd
# Correct tar file order
mkdir -p temp
pushd temp
tar xf $SOURCEDIST
rm $SOURCEDIST
find tendermint-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > $SOURCEDIST
popd
# Prepare GOPATH and install deps
distsrc=${GOPATH}/src/github.com/tendermint/tendermint
mkdir -p ${distsrc}
pushd ${distsrc}
tar --strip-components=1 -xf $SOURCEDIST
go mod download
popd
# Configure LDFLAGS for reproducible builds
LDFLAGS="-extldflags=-static -buildid=${VERSION} -s -w \
-X github.com/tendermint/tendermint/version.GitCommit=${COMMIT}"
# Extract release tarball and build
for arch in ${ARCHS}; do
INSTALLPATH=`pwd`/installed/${DISTNAME}-${arch}
mkdir -p ${INSTALLPATH}
# Build tendermint binary
pushd ${distsrc}
GOARCH=${arch} GOROOT_FINAL=${GOROOT} go build -a \
-gcflags=all=-trimpath=${GOPATH} \
-asmflags=all=-trimpath=${GOPATH} \
-mod=readonly -tags "tendermint" \
-ldflags="${LDFLAGS}" \
-o ${INSTALLPATH}/tendermint ./cmd/tendermint/
popd # ${distsrc}
pushd ${INSTALLPATH}
find -type f | sort | tar \
--no-recursion --mode='u+rw,go+r-w,a+X' \
--numeric-owner --sort=name \
--owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-linux-${arch}.tar.gz
popd # installed
done
rm -rf ${distsrc}
mkdir -p $OUTDIR/src
mv $SOURCEDIST $OUTDIR/src

View File

@ -0,0 +1,111 @@
---
name: "tendermint-windows"
enable_cache: true
distro: "ubuntu"
suites:
- "bionic"
architectures:
- "amd64"
packages:
- "bsdmainutils"
- "build-essential"
- "ca-certificates"
- "curl"
- "debhelper"
- "dpkg-dev"
- "devscripts"
- "fakeroot"
- "git"
- "golang-any"
- "xxd"
- "quilt"
remotes:
- "url": "https://github.com/tendermint/tendermint.git"
"dir": "tendermint"
files:
- "golang-debian-1.12.5-1.tar.gz"
script: |
set -e -o pipefail
GO_SRC_RELEASE=golang-debian-1.12.5-1
GO_SRC_TARBALL="${GO_SRC_RELEASE}.tar.gz"
# Compile go and configure the environment
export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME""
export BUILD_DIR=`pwd`
tar xf "${GO_SRC_TARBALL}"
rm -f "${GO_SRC_TARBALL}"
[ -d "${GO_SRC_RELEASE}/" ]
mv "${GO_SRC_RELEASE}/" go/
pushd go/
QUILT_PATCHES=debian/patches quilt push -a
fakeroot debian/rules build RUN_TESTS=false GOCACHE=/tmp/go-cache
popd
export GOOS=windows
export GOROOT=${BUILD_DIR}/go
export GOPATH=${BUILD_DIR}/gopath
mkdir -p ${GOPATH}/bin
export PATH_orig=${PATH}
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
export ARCHS='386 amd64'
export GO111MODULE=on
# Make release tarball
pushd tendermint
VERSION=$(git describe --tags | sed 's/^v//')
COMMIT=$(git rev-parse --short=8 HEAD)
DISTNAME=tendermint-${VERSION}
git archive --format tar.gz --prefix ${DISTNAME}/ -o ${DISTNAME}.tar.gz HEAD
SOURCEDIST=`pwd`/`echo tendermint-*.tar.gz`
popd
# Correct tar file order
mkdir -p temp
pushd temp
tar xf $SOURCEDIST
rm $SOURCEDIST
find tendermint-* | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > $SOURCEDIST
popd
# Prepare GOPATH and install deps
distsrc=${GOPATH}/src/github.com/tendermint/tendermint
mkdir -p ${distsrc}
pushd ${distsrc}
tar --strip-components=1 -xf $SOURCEDIST
go mod download
popd
# Configure LDFLAGS for reproducible builds
LDFLAGS="-extldflags=-static -buildid=${VERSION} -s -w \
-X github.com/tendermint/tendermint/version.GitCommit=${COMMIT}"
# Extract release tarball and build
for arch in ${ARCHS}; do
INSTALLPATH=`pwd`/installed/${DISTNAME}-${arch}
mkdir -p ${INSTALLPATH}
# Build tendermint binary
pushd ${distsrc}
GOARCH=${arch} GOROOT_FINAL=${GOROOT} go build -a \
-gcflags=all=-trimpath=${GOPATH} \
-asmflags=all=-trimpath=${GOPATH} \
-mod=readonly -tags "tendermint" \
-ldflags="${LDFLAGS}" \
-o ${INSTALLPATH}/tendermint.exe ./cmd/tendermint/
popd # ${distsrc}
pushd ${INSTALLPATH}
find -type f | sort | tar \
--no-recursion --mode='u+rw,go+r-w,a+X' \
--numeric-owner --sort=name \
--owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-windows-${arch}.tar.gz
popd # installed
done
rm -rf ${distsrc}
mkdir -p $OUTDIR/src
mv $SOURCEDIST $OUTDIR/src

View File

@ -0,0 +1,29 @@
## PGP keys of Gitian builders and Tendermint Developers
The file `keys.txt` contains fingerprints of the public keys of Gitian builders
and active developers.
The associated keys are mainly used to sign git commits or the build results
of Gitian builds.
The most recent version of each pgp key can be found on most PGP key servers.
Fetch the latest version from the key server to see if any key was revoked in
the meantime.
To fetch the latest version of all pgp keys in your gpg homedir,
```sh
gpg --refresh-keys
```
To fetch keys of Gitian builders and active core developers, feed the list of
fingerprints of the primary keys into gpg:
```sh
while read fingerprint keyholder_name; \
do gpg --keyserver hkp://subset.pool.sks-keyservers.net \
--recv-keys ${fingerprint}; done < ./keys.txt
```
Add your key to the list if you are a Tendermint core developer or you have
provided Gitian signatures for two major or minor releases of Tendermint.

View File

@ -0,0 +1 @@
04160004A8276E40BB9890FBE8A48AE5311D765A Alessio Treglia

View File

@ -284,7 +284,7 @@ func execBlockOnProxyApp(
// Run txs of block. // Run txs of block.
for _, tx := range block.Txs { for _, tx := range block.Txs {
proxyAppConn.DeliverTxAsync(tx) proxyAppConn.DeliverTxAsync(abci.RequestDeliverTx{Tx: tx})
if err := proxyAppConn.Error(); err != nil { if err := proxyAppConn.Error(); err != nil {
return nil, err return nil, err
} }

View File

@ -36,7 +36,7 @@ dist: build-all
build-docker: build-docker:
rm -f ./tm-monitor rm -f ./tm-monitor
docker run -it --rm -v "$(PWD)/../../:/go/src/github.com/tendermint/tendermint" -w "/go/src/github.com/tendermint/tendermint/tools/tm-monitor" -e "CGO_ENABLED=0" golang:alpine go build -ldflags "-s -w" -o tm-monitor docker run -it --rm -v "$(PWD)/../../:/go/src/github.com/tendermint/tendermint" -w "/go/src/github.com/tendermint/tendermint/tools/tm-monitor" -e "GO111MODULE=on" -e "CGO_ENABLED=0" golang:1.12 go build -ldflags "-s -w" -o tm-monitor
docker build -t "tendermint/monitor" . docker build -t "tendermint/monitor" .
clean: clean:

View File

@ -5,9 +5,11 @@ import (
"net" "net"
"net/http" "net/http"
rpctypes "github.com/tendermint/tendermint/rpc/lib/types"
"github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/libs/log"
rpc "github.com/tendermint/tendermint/rpc/lib/server" rpc "github.com/tendermint/tendermint/rpc/lib/server"
monitor "github.com/tendermint/tendermint/tools/tm-monitor/monitor" "github.com/tendermint/tendermint/tools/tm-monitor/monitor"
) )
func startRPC(listenAddr string, m *monitor.Monitor, logger log.Logger) net.Listener { func startRPC(listenAddr string, m *monitor.Monitor, logger log.Logger) net.Listener {
@ -41,33 +43,33 @@ func routes(m *monitor.Monitor) map[string]*rpc.RPCFunc {
} }
// RPCStatus returns common statistics for the network and statistics per node. // RPCStatus returns common statistics for the network and statistics per node.
func RPCStatus(m *monitor.Monitor) interface{} { func RPCStatus(m *monitor.Monitor) func(*rpctypes.Context) (networkAndNodes, error) {
return func() (networkAndNodes, error) { return func(_ *rpctypes.Context) (networkAndNodes, error) {
return networkAndNodes{m.Network, m.Nodes}, nil return networkAndNodes{m.Network, m.Nodes}, nil
} }
} }
// RPCNetworkStatus returns common statistics for the network. // RPCNetworkStatus returns common statistics for the network.
func RPCNetworkStatus(m *monitor.Monitor) interface{} { func RPCNetworkStatus(m *monitor.Monitor) func(*rpctypes.Context) (*monitor.Network, error) {
return func() (*monitor.Network, error) { return func(_ *rpctypes.Context) (*monitor.Network, error) {
return m.Network, nil return m.Network, nil
} }
} }
// RPCNodeStatus returns statistics for the given node. // RPCNodeStatus returns statistics for the given node.
func RPCNodeStatus(m *monitor.Monitor) interface{} { func RPCNodeStatus(m *monitor.Monitor) func(*rpctypes.Context, string) (*monitor.Node, error) {
return func(name string) (*monitor.Node, error) { return func(_ *rpctypes.Context, name string) (*monitor.Node, error) {
if i, n := m.NodeByName(name); i != -1 { if i, n := m.NodeByName(name); i != -1 {
return n, nil return n, nil
} }
return nil, errors.New("Cannot find node with that name") return nil, errors.New("cannot find node with that name")
} }
} }
// RPCMonitor allows to dynamically add a endpoint to under the monitor. Safe // RPCMonitor allows to dynamically add a endpoint to under the monitor. Safe
// to call multiple times. // to call multiple times.
func RPCMonitor(m *monitor.Monitor) interface{} { func RPCMonitor(m *monitor.Monitor) func(*rpctypes.Context, string) (*monitor.Node, error) {
return func(endpoint string) (*monitor.Node, error) { return func(_ *rpctypes.Context, endpoint string) (*monitor.Node, error) {
i, n := m.NodeByName(endpoint) i, n := m.NodeByName(endpoint)
if i == -1 { if i == -1 {
n = monitor.NewNode(endpoint) n = monitor.NewNode(endpoint)
@ -80,13 +82,13 @@ func RPCMonitor(m *monitor.Monitor) interface{} {
} }
// RPCUnmonitor removes the given endpoint from under the monitor. // RPCUnmonitor removes the given endpoint from under the monitor.
func RPCUnmonitor(m *monitor.Monitor) interface{} { func RPCUnmonitor(m *monitor.Monitor) func(*rpctypes.Context, string) (bool, error) {
return func(endpoint string) (bool, error) { return func(_ *rpctypes.Context, endpoint string) (bool, error) {
if i, n := m.NodeByName(endpoint); i != -1 { if i, n := m.NodeByName(endpoint); i != -1 {
m.Unmonitor(n) m.Unmonitor(n)
return true, nil return true, nil
} }
return false, errors.New("Cannot find node with that name") return false, errors.New("cannot find node with that name")
} }
} }

View File

@ -4,9 +4,10 @@ import (
"bytes" "bytes"
"testing" "testing"
"github.com/stretchr/testify/assert"
"github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto"
cmn "github.com/tendermint/tendermint/libs/common" cmn "github.com/tendermint/tendermint/libs/common"
tst "github.com/tendermint/tendermint/libs/test"
tmtime "github.com/tendermint/tendermint/types/time" tmtime "github.com/tendermint/tendermint/types/time"
) )
@ -490,7 +491,7 @@ func TestMakeCommit(t *testing.T) {
} }
// MakeCommit should fail. // MakeCommit should fail.
tst.AssertPanics(t, "Doesn't have +2/3 majority", func() { voteSet.MakeCommit() }) assert.Panics(t, func() { voteSet.MakeCommit() }, "Doesn't have +2/3 majority")
// 7th voted for some other block. // 7th voted for some other block.
{ {

View File

@ -7,6 +7,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
amino "github.com/tendermint/go-amino" amino "github.com/tendermint/go-amino"
"github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto"
"github.com/tendermint/tendermint/crypto/ed25519" "github.com/tendermint/tendermint/crypto/ed25519"

View File

@ -20,10 +20,10 @@ const (
// Must be a string because scripts like dist.sh read this file. // Must be a string because scripts like dist.sh read this file.
// XXX: Don't change the name of this variable or you will break // XXX: Don't change the name of this variable or you will break
// automation :) // automation :)
TMCoreSemVer = "0.32.0" TMCoreSemVer = "0.32.1"
// ABCISemVer is the semantic version of the ABCI library // ABCISemVer is the semantic version of the ABCI library
ABCISemVer = "0.16.0" ABCISemVer = "0.16.1"
ABCIVersion = ABCISemVer ABCIVersion = ABCISemVer
) )