mirror of
https://github.com/fluencelabs/tendermint
synced 2025-04-25 14:52:17 +00:00
Merge pull request #3807 from tendermint/release/v0.32.1
Release/v0.32.1
This commit is contained in:
commit
dbf4062acd
@ -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
|
||||||
|
74
CHANGELOG.md
74
CHANGELOG.md
@ -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
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
@ -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"]
|
|
@ -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
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
# Tendermint
|
# Tendermint
|
||||||
|

|
||||||
|
|
||||||
[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).
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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 ?
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
|
||||||
|
@ -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")
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
|
@ -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},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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())
|
||||||
|
}
|
||||||
|
@ -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 }}"
|
||||||
|
|
||||||
|
@ -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)
|
||||||
|
@ -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).
|
||||||
|
@ -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):
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
391
docs/architecture/adr-043-blockchain-riri-org.md
Normal file
391
docs/architecture/adr-043-blockchain-riri-org.md
Normal 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`.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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`.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 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)
|
BIN
docs/architecture/img/blockchain-reactor-v1.png
Normal file
BIN
docs/architecture/img/blockchain-reactor-v1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 121 KiB |
BIN
docs/architecture/img/blockchain-reactor-v2.png
Normal file
BIN
docs/architecture/img/blockchain-reactor-v2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 118 KiB |
@ -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).
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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:
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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).
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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 we’ll replay the
|
private validator contains the `LastSignBytes` and then we’ll 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
BIN
docs/tendermint-core-image.jpg
Executable file
Binary file not shown.
After Width: | Height: | Size: 123 KiB |
@ -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).
|
||||||
|
@ -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
|
||||||
|
@ -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).
|
||||||
|
@ -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
3
go.mod
@ -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
5
go.sum
@ -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=
|
||||||
|
@ -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}"
|
|
@ -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
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
@ -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)
|
|
||||||
}
|
|
@ -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
|
|
||||||
}
|
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -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)
|
||||||
|
|
||||||
|
@ -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()
|
|
||||||
}
|
|
@ -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,
|
|
||||||
// )
|
|
||||||
// }
|
|
@ -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)
|
||||||
|
@ -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()
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
package version
|
|
||||||
|
|
||||||
const Version = "0.9.0"
|
|
@ -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()
|
||||||
|
@ -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()
|
||||||
|
25
node/node.go
25
node/node.go
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
23
p2p/mock/reactor.go
Normal 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) {}
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
201
scripts/gitian-build.sh
Executable 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
|
111
scripts/gitian-descriptors/gitian-darwin.yml
Normal file
111
scripts/gitian-descriptors/gitian-darwin.yml
Normal 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
|
110
scripts/gitian-descriptors/gitian-linux.yml
Normal file
110
scripts/gitian-descriptors/gitian-linux.yml
Normal 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
|
111
scripts/gitian-descriptors/gitian-windows.yml
Normal file
111
scripts/gitian-descriptors/gitian-windows.yml
Normal 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
|
29
scripts/gitian-keys/README.md
Normal file
29
scripts/gitian-keys/README.md
Normal 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.
|
1
scripts/gitian-keys/keys.txt
Normal file
1
scripts/gitian-keys/keys.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
04160004A8276E40BB9890FBE8A48AE5311D765A Alessio Treglia
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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:
|
||||||
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
||||||
{
|
{
|
||||||
|
@ -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"
|
||||||
|
@ -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
|
||||||
)
|
)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user