mirror of
https://github.com/tendermint/tendermint.git
synced 2026-08-22 07:06:14 +00:00
lint: add markdown linter (#5254)
This commit is contained in:
@@ -0,0 +1,32 @@
|
|||||||
|
name: Lint
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths:
|
||||||
|
- "**.md"
|
||||||
|
- "**.yml"
|
||||||
|
- "**.yaml"
|
||||||
|
pull_request:
|
||||||
|
branches: [master]
|
||||||
|
paths:
|
||||||
|
- "**.md"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Super linter
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
- name: Lint Code Base
|
||||||
|
uses: docker://github/super-linter:v3
|
||||||
|
env:
|
||||||
|
LINTER_RULES_PATH: .
|
||||||
|
VALIDATE_ALL_CODEBASE: true
|
||||||
|
DEFAULT_BRANCH: master
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
VALIDATE_MD: true
|
||||||
|
MARKDOWN_CONFIG_FILE: .markdownlint.yml
|
||||||
|
VALIDATE_OPAENAPI: true
|
||||||
|
VALIDATE_YAML: true
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
default: true,
|
||||||
|
MD007: { "indent": 4 }
|
||||||
|
MD013: false
|
||||||
|
MD024: { siblings_only: true }
|
||||||
|
MD025: false
|
||||||
|
MD033: { no-inline-html: false }
|
||||||
|
no-hard-tabs: false
|
||||||
|
whitespace: false
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
docs/node_modules
|
||||||
|
CHANGELOG.md
|
||||||
|
docs/architecture/*
|
||||||
|
crypto/secp256k1/internal/secp256k1/*
|
||||||
|
scripts/*
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
## v0.34.0-rc4
|
# v0.34.0-rc4
|
||||||
|
|
||||||
Special thanks to external contributors on this release:
|
Special thanks to external contributors on this release:
|
||||||
|
|
||||||
Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermint).
|
Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermint).
|
||||||
|
|
||||||
### BREAKING CHANGES:
|
## BREAKING CHANGES
|
||||||
|
|
||||||
### FEATURES:
|
## FEATURES
|
||||||
|
|
||||||
- [privval] \#5239 Add `chainID` to requests from client.
|
- [privval] \#5239 Add `chainID` to requests from client.
|
||||||
|
|
||||||
### IMPROVEMENTS:
|
## IMPROVEMENTS
|
||||||
|
|
||||||
### BUG FIXES:
|
## BUG FIXES
|
||||||
|
|
||||||
- [blockchain] \#5249 Fix fast sync halt with initial height > 1 (@erikgrinaker)
|
- [blockchain] \#5249 Fix fast sync halt with initial height > 1 (@erikgrinaker)
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
# The Tendermint Code of Conduct
|
# The Tendermint Code of Conduct
|
||||||
|
|
||||||
This code of conduct applies to all projects run by the Tendermint/COSMOS team and hence to tendermint.
|
This code of conduct applies to all projects run by the Tendermint/COSMOS team and hence to tendermint.
|
||||||
|
|
||||||
|
|
||||||
@@ -6,6 +7,7 @@ This code of conduct applies to all projects run by the Tendermint/COSMOS team a
|
|||||||
|
|
||||||
|
|
||||||
# Conduct
|
# Conduct
|
||||||
|
|
||||||
## Contact: conduct@tendermint.com
|
## Contact: conduct@tendermint.com
|
||||||
|
|
||||||
* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic.
|
* We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic.
|
||||||
@@ -29,6 +31,7 @@ This code of conduct applies to all projects run by the Tendermint/COSMOS team a
|
|||||||
|
|
||||||
|
|
||||||
# Moderation
|
# Moderation
|
||||||
|
|
||||||
These are the policies for upholding our community’s standards of conduct. If you feel that a thread needs moderation, please contact the above mentioned person.
|
These are the policies for upholding our community’s standards of conduct. If you feel that a thread needs moderation, please contact the above mentioned person.
|
||||||
|
|
||||||
1. Remarks that violate the Tendermint/COSMOS standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.)
|
1. Remarks that violate the Tendermint/COSMOS standards of conduct, including hateful, hurtful, oppressive, or exclusionary remarks, are not allowed. (Cursing is allowed, but never targeting another user, and never in a hateful manner.)
|
||||||
|
|||||||
+8
-8
@@ -115,14 +115,14 @@ There are two ways to generate your proto stubs.
|
|||||||
|
|
||||||
### Installation Instructions
|
### Installation Instructions
|
||||||
|
|
||||||
To install `protoc`, download an appropriate release (https://github.com/protocolbuffers/protobuf) and then move the provided binaries into your PATH (follow instructions in README included with the download).
|
To install `protoc`, download an appropriate release (<https://github.com/protocolbuffers/protobuf>) and then move the provided binaries into your PATH (follow instructions in README included with the download).
|
||||||
|
|
||||||
To install `gogoproto`, do the following:
|
To install `gogoproto`, do the following:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
$ go get github.com/gogo/protobuf/gogoproto
|
go get github.com/gogo/protobuf/gogoproto
|
||||||
$ cd $GOPATH/pkg/mod/github.com/gogo/protobuf@v1.3.1 # or wherever go get installs things
|
cd $GOPATH/pkg/mod/github.com/gogo/protobuf@v1.3.1 # or wherever go get installs things
|
||||||
$ make install
|
make install
|
||||||
```
|
```
|
||||||
|
|
||||||
You should now be able to run `make proto-gen` from inside the root Tendermint directory to generate new files from proto files.
|
You should now be able to run `make proto-gen` from inside the root Tendermint directory to generate new files from proto files.
|
||||||
@@ -135,7 +135,7 @@ hacking Tendermint with the commands below.
|
|||||||
NOTE: In case you installed Vagrant in 2017, you might need to run
|
NOTE: In case you installed Vagrant in 2017, you might need to run
|
||||||
`vagrant box update` to upgrade to the latest `ubuntu/xenial64`.
|
`vagrant box update` to upgrade to the latest `ubuntu/xenial64`.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
vagrant up
|
vagrant up
|
||||||
vagrant ssh
|
vagrant ssh
|
||||||
make test
|
make test
|
||||||
@@ -218,7 +218,7 @@ If your change should be included in a minor release, please also open a PR agai
|
|||||||
|
|
||||||
You can do this by cherry-picking your commit off master:
|
You can do this by cherry-picking your commit off master:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
$ git checkout rc1/v0.33.5
|
$ git checkout rc1/v0.33.5
|
||||||
$ git checkout -b {new branch name}
|
$ git checkout -b {new branch name}
|
||||||
$ git cherry-pick {commit SHA from master}
|
$ git cherry-pick {commit SHA from master}
|
||||||
@@ -232,7 +232,7 @@ After this, you can open a PR. Please note in the PR body if there were merge co
|
|||||||
|
|
||||||
We follow the [Go style guide on commit messages](https://tip.golang.org/doc/contribute.html#commit_messages). Write concise commits that start with the package name and have a description that finishes the sentence "This change modifies Tendermint to...". For example,
|
We follow the [Go style guide on commit messages](https://tip.golang.org/doc/contribute.html#commit_messages). Write concise commits that start with the package name and have a description that finishes the sentence "This change modifies Tendermint to...". For example,
|
||||||
|
|
||||||
```
|
```sh
|
||||||
cmd/debug: execute p.Signal only when p is not nil
|
cmd/debug: execute p.Signal only when p is not nil
|
||||||
|
|
||||||
[potentially longer description in the body]
|
[potentially longer description in the body]
|
||||||
|
|||||||
+3
-3
@@ -8,12 +8,12 @@ Official releases can be found [here](https://github.com/tendermint/tendermint/r
|
|||||||
|
|
||||||
The Dockerfile for tendermint is not expected to change in the near future. The master file used for all builds can be found [here](https://raw.githubusercontent.com/tendermint/tendermint/master/DOCKER/Dockerfile).
|
The Dockerfile for tendermint is not expected to change in the near future. The master file used for all builds can be found [here](https://raw.githubusercontent.com/tendermint/tendermint/master/DOCKER/Dockerfile).
|
||||||
|
|
||||||
Respective versioned files can be found https://raw.githubusercontent.com/tendermint/tendermint/vX.XX.XX/DOCKER/Dockerfile (replace the Xs with the version number).
|
Respective versioned files can be found <https://raw.githubusercontent.com/tendermint/tendermint/vX.XX.XX/DOCKER/Dockerfile> (replace the Xs with the version number).
|
||||||
|
|
||||||
## Quick reference
|
## Quick reference
|
||||||
|
|
||||||
- **Where to get help:** https://tendermint.com/
|
- **Where to get help:** <https://tendermint.com/>
|
||||||
- **Where to file issues:** https://github.com/tendermint/tendermint/issues
|
- **Where to file issues:** <https://github.com/tendermint/tendermint/issues>
|
||||||
- **Supported Docker versions:** [the latest release](https://github.com/moby/moby/releases) (down to 1.6 on a best-effort basis)
|
- **Supported Docker versions:** [the latest release](https://github.com/moby/moby/releases) (down to 1.6 on a best-effort basis)
|
||||||
|
|
||||||
## Tendermint
|
## Tendermint
|
||||||
|
|||||||
+21
-21
@@ -1,16 +1,16 @@
|
|||||||
## Design goals
|
# Design goals
|
||||||
|
|
||||||
The design goals for Tendermint (and the SDK and related libraries) are:
|
The design goals for Tendermint (and the SDK and related libraries) are:
|
||||||
|
|
||||||
* Simplicity and Legibility
|
* Simplicity and Legibility
|
||||||
* Parallel performance, namely ability to utilize multicore architecture
|
* Parallel performance, namely ability to utilize multicore architecture
|
||||||
* Ability to evolve the codebase bug-free
|
* Ability to evolve the codebase bug-free
|
||||||
* Debuggability
|
* Debuggability
|
||||||
* Complete correctness that considers all edge cases, esp in concurrency
|
* Complete correctness that considers all edge cases, esp in concurrency
|
||||||
* Future-proof modular architecture, message protocol, APIs, and encapsulation
|
* Future-proof modular architecture, message protocol, APIs, and encapsulation
|
||||||
|
|
||||||
|
|
||||||
### Justification
|
## Justification
|
||||||
|
|
||||||
Legibility is key to maintaining bug-free software as it evolves toward more
|
Legibility is key to maintaining bug-free software as it evolves toward more
|
||||||
optimizations, more ease of debugging, and additional features.
|
optimizations, more ease of debugging, and additional features.
|
||||||
@@ -44,7 +44,7 @@ become more complicated over time, and it becomes more and more difficult to
|
|||||||
assess the correctness of such a for-loop by visual inspection.
|
assess the correctness of such a for-loop by visual inspection.
|
||||||
|
|
||||||
|
|
||||||
### On performance
|
## On performance
|
||||||
|
|
||||||
It doesn't matter whether there are alternative implementations that are 2x or
|
It doesn't matter whether there are alternative implementations that are 2x or
|
||||||
3x more performant, when the software doesn't work, deadlocks, or if bugs
|
3x more performant, when the software doesn't work, deadlocks, or if bugs
|
||||||
@@ -74,7 +74,7 @@ that works well enough, can be debugged and maintained, and can serve as a spec
|
|||||||
for future implementations.
|
for future implementations.
|
||||||
|
|
||||||
|
|
||||||
### On encapsulation
|
## On encapsulation
|
||||||
|
|
||||||
In order to create maintainable, forward-optimizable software, it is critical
|
In order to create maintainable, forward-optimizable software, it is critical
|
||||||
to develop well-encapsulated objects that have well understood properties, and
|
to develop well-encapsulated objects that have well understood properties, and
|
||||||
@@ -92,12 +92,12 @@ and the rand.Rand struct. It's one single struct declaration that can be used
|
|||||||
in both concurrent and non-concurrent logic, and due to its well encapsulation,
|
in both concurrent and non-concurrent logic, and due to its well encapsulation,
|
||||||
it's easy to get the usage of the mutex right.
|
it's easy to get the usage of the mutex right.
|
||||||
|
|
||||||
#### example: rand.Rand:
|
### example: rand.Rand
|
||||||
|
|
||||||
`The default Source is safe for concurrent use by multiple goroutines, but
|
`The default Source is safe for concurrent use by multiple goroutines, but
|
||||||
Sources created by NewSource are not`. The reason why the default
|
Sources created by NewSource are not`. The reason why the default
|
||||||
package-level source is safe for concurrent use is because it is protected (see
|
package-level source is safe for concurrent use is because it is protected (see
|
||||||
`lockedSource` in https://golang.org/src/math/rand/rand.go).
|
`lockedSource` in <https://golang.org/src/math/rand/rand.go>).
|
||||||
|
|
||||||
But we shouldn't rely on the global source, we should be creating our own
|
But we shouldn't rely on the global source, we should be creating our own
|
||||||
Rand/Source instances and using them, especially for determinism in testing.
|
Rand/Source instances and using them, especially for determinism in testing.
|
||||||
@@ -120,7 +120,7 @@ clear what methods have what side effects, then there is something wrong about
|
|||||||
the design of abstractions that should be revisited.
|
the design of abstractions that should be revisited.
|
||||||
|
|
||||||
|
|
||||||
### On concurrency
|
## On concurrency
|
||||||
|
|
||||||
In order for Tendermint to remain relevant in the years to come, it is vital
|
In order for Tendermint to remain relevant in the years to come, it is vital
|
||||||
for Tendermint to take advantage of multicore architectures. Due to the nature
|
for Tendermint to take advantage of multicore architectures. Due to the nature
|
||||||
@@ -131,24 +131,24 @@ design, especially when it comes to the reactor design, and also for RPC
|
|||||||
request handling.
|
request handling.
|
||||||
|
|
||||||
|
|
||||||
## Guidelines
|
# Guidelines
|
||||||
|
|
||||||
Here are some guidelines for designing for (sufficient) performance and concurrency:
|
Here are some guidelines for designing for (sufficient) performance and concurrency:
|
||||||
|
|
||||||
* Mutex locks are cheap enough when there isn't contention.
|
* Mutex locks are cheap enough when there isn't contention.
|
||||||
* Do not optimize code without analytical or observed proof that it is in a hot path.
|
* Do not optimize code without analytical or observed proof that it is in a hot path.
|
||||||
* Don't over-use channels when mutex locks w/ encapsulation are sufficient.
|
* Don't over-use channels when mutex locks w/ encapsulation are sufficient.
|
||||||
* The need to drain channels are often a hint of unconsidered edge cases.
|
* The need to drain channels are often a hint of unconsidered edge cases.
|
||||||
* The creation of O(N) one-off goroutines is generally technical debt that
|
* The creation of O(N) one-off goroutines is generally technical debt that
|
||||||
needs to get addressed sooner than later. Avoid creating too many
|
needs to get addressed sooner than later. Avoid creating too many
|
||||||
goroutines as a patch around incomplete concurrency design, or at least be
|
goroutines as a patch around incomplete concurrency design, or at least be
|
||||||
aware of the debt and do not invest in the debt. On the other hand, Tendermint
|
aware of the debt and do not invest in the debt. On the other hand, Tendermint
|
||||||
is designed to have a limited number of peers (e.g. 10 or 20), so the creation
|
is designed to have a limited number of peers (e.g. 10 or 20), so the creation
|
||||||
of O(C) goroutines per O(P) peers is still O(C\*P=constant).
|
of O(C) goroutines per O(P) peers is still O(C\*P=constant).
|
||||||
* Use defer statements to unlock as much as possible. If you want to unlock sooner,
|
* Use defer statements to unlock as much as possible. If you want to unlock sooner,
|
||||||
try to create more modular functions that do make use of defer statements.
|
try to create more modular functions that do make use of defer statements.
|
||||||
|
|
||||||
## Matras
|
# Mantras
|
||||||
|
|
||||||
* Premature optimization kills
|
* Premature optimization kills
|
||||||
* Readability is paramount
|
* Readability is paramount
|
||||||
|
|||||||
@@ -11,12 +11,12 @@ Or [Blockchain](<https://en.wikipedia.org/wiki/Blockchain_(database)>), for shor
|
|||||||
[](https://github.com/moovweb/gvm)
|
[](https://github.com/moovweb/gvm)
|
||||||
[](https://discord.gg/AzefAFd)
|
[](https://discord.gg/AzefAFd)
|
||||||
[](https://github.com/tendermint/tendermint/blob/master/LICENSE)
|
[](https://github.com/tendermint/tendermint/blob/master/LICENSE)
|
||||||
[](https://github.com/tendermint/tendermint)
|
[](https://github.com/tendermint/tendermint)
|
||||||
[](https://sourcegraph.com/github.com/tendermint/tendermint?badge)
|
[](https://sourcegraph.com/github.com/tendermint/tendermint?badge)
|
||||||
|
|
||||||
| Branch | Tests | Coverage | Linting |
|
| Branch | Tests | Coverage | Linting |
|
||||||
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
|
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
|
||||||
| master | [](https://circleci.com/gh/tendermint/tendermint/tree/master) <br />  | [](https://codecov.io/gh/tendermint/tendermint) |  |
|
| master | [](https://circleci.com/gh/tendermint/tendermint/tree/master) </br>  | [](https://codecov.io/gh/tendermint/tendermint) |  |
|
||||||
|
|
||||||
Tendermint Core is Byzantine Fault Tolerant (BFT) middleware that takes a state transition machine - written in any programming language -
|
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.
|
and securely replicates it on many machines.
|
||||||
@@ -101,11 +101,11 @@ CHANGELOG even if they don't lead to MINOR version bumps:
|
|||||||
- config
|
- config
|
||||||
- node
|
- node
|
||||||
- libs
|
- libs
|
||||||
- bech32
|
- bech32
|
||||||
- common
|
- common
|
||||||
- db
|
- db
|
||||||
- errors
|
- errors
|
||||||
- log
|
- log
|
||||||
|
|
||||||
Exported objects in these packages that are not covered by the versioning scheme
|
Exported objects in these packages that are not covered by the versioning scheme
|
||||||
are explicitly marked by `// UNSTABLE` in their go doc comment and may change at any
|
are explicitly marked by `// UNSTABLE` in their go doc comment and may change at any
|
||||||
@@ -139,7 +139,7 @@ For details about the blockchain data structures and the p2p protocols, see the
|
|||||||
[Tendermint specification](https://docs.tendermint.com/master/spec/).
|
[Tendermint specification](https://docs.tendermint.com/master/spec/).
|
||||||
|
|
||||||
For details on using the software, see the [documentation](/docs/) which is also
|
For details on using the software, see the [documentation](/docs/) which is also
|
||||||
hosted at: https://docs.tendermint.com/master/
|
hosted at: <https://docs.tendermint.com/master/>
|
||||||
|
|
||||||
### Tools
|
### Tools
|
||||||
|
|
||||||
|
|||||||
+9
-3
@@ -1,6 +1,7 @@
|
|||||||
# Security
|
# Security
|
||||||
|
|
||||||
## Reporting a Bug
|
## Reporting a Bug
|
||||||
|
|
||||||
As part of our [Coordinated Vulnerability Disclosure
|
As part of our [Coordinated Vulnerability Disclosure
|
||||||
Policy](https://tendermint.com/security), we operate a [bug
|
Policy](https://tendermint.com/security), we operate a [bug
|
||||||
bounty](https://hackerone.com/tendermint).
|
bounty](https://hackerone.com/tendermint).
|
||||||
@@ -21,6 +22,7 @@ If you follow these guidelines when reporting an issue to us, we commit to:
|
|||||||
* Work with you to understand, resolve and ultimately disclose the issue in a timely fashion
|
* Work with you to understand, resolve and ultimately disclose the issue in a timely fashion
|
||||||
|
|
||||||
## Disclosure Process
|
## Disclosure Process
|
||||||
|
|
||||||
Tendermint Core uses the following disclosure process:
|
Tendermint Core uses the following disclosure process:
|
||||||
|
|
||||||
1. Once a security report is received, the Tendermint Core team works to verify the issue and confirm its severity level using CVSS.
|
1. Once a security report is received, the Tendermint Core team works to verify the issue and confirm its severity level using CVSS.
|
||||||
@@ -37,6 +39,7 @@ Tendermint Core uses the following disclosure process:
|
|||||||
This process can take some time. Every effort will be made to handle the bug in as timely a manner as possible, however it's important that we follow the process described above to ensure that disclosures are handled consistently and to keep Tendermint Core and its downstream dependent projects--including but not limited to Gaia and the Cosmos Hub--as secure as possible.
|
This process can take some time. Every effort will be made to handle the bug in as timely a manner as possible, however it's important that we follow the process described above to ensure that disclosures are handled consistently and to keep Tendermint Core and its downstream dependent projects--including but not limited to Gaia and the Cosmos Hub--as secure as possible.
|
||||||
|
|
||||||
### Example Timeline
|
### Example Timeline
|
||||||
|
|
||||||
The following is an example timeline for the triage and response. The required roles and team members are described in parentheses after each task; however, multiple people can play each role and each person may play multiple roles.
|
The following is an example timeline for the triage and response. The required roles and team members are described in parentheses after each task; however, multiple people can play each role and each person may play multiple roles.
|
||||||
|
|
||||||
#### > 24 Hours Before Release Time
|
#### > 24 Hours Before Release Time
|
||||||
@@ -54,6 +57,7 @@ The following is an example timeline for the triage and response. The required r
|
|||||||
4. Send emails to validators or other users (PARTNERSHIPS LEAD)
|
4. Send emails to validators or other users (PARTNERSHIPS LEAD)
|
||||||
|
|
||||||
#### Release Time
|
#### Release Time
|
||||||
|
|
||||||
1. Cut Tendermint releases for eligible versions (TENDERMINT ENG, TENDERMINT LEAD)
|
1. Cut Tendermint releases for eligible versions (TENDERMINT ENG, TENDERMINT LEAD)
|
||||||
2. Cut Cosmos SDK release for eligible versions (COSMOS ENG)
|
2. Cut Cosmos SDK release for eligible versions (COSMOS ENG)
|
||||||
3. Cut Gaia release for eligible versions (GAIA ENG)
|
3. Cut Gaia release for eligible versions (GAIA ENG)
|
||||||
@@ -64,19 +68,23 @@ The following is an example timeline for the triage and response. The required r
|
|||||||
8. Publish Security Advisory and CVE, if CVE has no sensitive information (ADMIN)
|
8. Publish Security Advisory and CVE, if CVE has no sensitive information (ADMIN)
|
||||||
|
|
||||||
#### After Release Time
|
#### After Release Time
|
||||||
|
|
||||||
1. Write forum post with exploit details (TENDERMINT LEAD)
|
1. Write forum post with exploit details (TENDERMINT LEAD)
|
||||||
2. Approve pay-out on HackerOne for submitter (ADMIN)
|
2. Approve pay-out on HackerOne for submitter (ADMIN)
|
||||||
|
|
||||||
#### 7 Days After Release Time
|
#### 7 Days After Release Time
|
||||||
|
|
||||||
1. Publish CVE if it has not yet been published (ADMIN)
|
1. Publish CVE if it has not yet been published (ADMIN)
|
||||||
2. Publish forum post with exploit details (TENDERMINT ENG, TENDERMINT LEAD)
|
2. Publish forum post with exploit details (TENDERMINT ENG, TENDERMINT LEAD)
|
||||||
|
|
||||||
## Supported Releases
|
## Supported Releases
|
||||||
|
|
||||||
The Tendermint Core team commits to releasing security patch releases for both the latest minor release as well for the major/minor release that the Cosmos Hub is running.
|
The Tendermint Core team commits to releasing security patch releases for both the latest minor release as well for the major/minor release that the Cosmos Hub is running.
|
||||||
|
|
||||||
If you are running older versions of Tendermint Core, we encourage you to upgrade at your earliest opportunity so that you can receive security patches directly from the Tendermint repo. While you are welcome to backport security patches to older versions for your own use, we will not publish or promote these backports.
|
If you are running older versions of Tendermint Core, we encourage you to upgrade at your earliest opportunity so that you can receive security patches directly from the Tendermint repo. While you are welcome to backport security patches to older versions for your own use, we will not publish or promote these backports.
|
||||||
|
|
||||||
## Scope
|
## Scope
|
||||||
|
|
||||||
The full scope of our bug bounty program is outlined on our [Hacker One program page](https://hackerone.com/tendermint). Please also note that, in the interest of the safety of our users and staff, a few things are explicitly excluded from scope:
|
The full scope of our bug bounty program is outlined on our [Hacker One program page](https://hackerone.com/tendermint). Please also note that, in the interest of the safety of our users and staff, a few things are explicitly excluded from scope:
|
||||||
|
|
||||||
* Any third-party services
|
* Any third-party services
|
||||||
@@ -84,6 +92,7 @@ The full scope of our bug bounty program is outlined on our [Hacker One program
|
|||||||
* Findings derived from social engineering (e.g., phishing)
|
* Findings derived from social engineering (e.g., phishing)
|
||||||
|
|
||||||
## Example Vulnerabilities
|
## Example Vulnerabilities
|
||||||
|
|
||||||
The following is a list of examples of the kinds of vulnerabilities that we’re most interested in. It is not exhaustive: there are other kinds of issues we may also be interested in!
|
The following is a list of examples of the kinds of vulnerabilities that we’re most interested in. It is not exhaustive: there are other kinds of issues we may also be interested in!
|
||||||
|
|
||||||
### Specification
|
### Specification
|
||||||
@@ -143,6 +152,3 @@ Attacks may come through the P2P network or the RPC layer:
|
|||||||
|
|
||||||
* Core verification
|
* Core verification
|
||||||
* Bisection/sequential algorithms
|
* Bisection/sequential algorithms
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+60
-57
@@ -15,6 +15,7 @@ We expect all contributors to be familiar with [Effective Go](https://golang.org
|
|||||||
Perhaps more key for code readability than good commenting is having the right structure. As a rule of thumb, try to write
|
Perhaps more key for code readability than good commenting is having the right structure. As a rule of thumb, try to write
|
||||||
in a logical order of importance, taking a little time to think how to order and divide the code such that someone could
|
in a logical order of importance, taking a little time to think how to order and divide the code such that someone could
|
||||||
scroll down and understand the functionality of it just as well as you do. A loose example of such order would be:
|
scroll down and understand the functionality of it just as well as you do. A loose example of such order would be:
|
||||||
|
|
||||||
* Constants, global and package-level variables
|
* Constants, global and package-level variables
|
||||||
* Main Struct
|
* Main Struct
|
||||||
* Options (only if they are seen as critical to the struct else they should be placed in another file)
|
* Options (only if they are seen as critical to the struct else they should be placed in another file)
|
||||||
@@ -26,113 +27,115 @@ scroll down and understand the functionality of it just as well as you do. A loo
|
|||||||
|
|
||||||
## General
|
## General
|
||||||
|
|
||||||
* Use `gofmt` (or `goimport`) to format all code upon saving it. (If you use VIM, check out vim-go).
|
* Use `gofmt` (or `goimport`) to format all code upon saving it. (If you use VIM, check out vim-go).
|
||||||
* Use a linter (see below) and generally try to keep the linter happy (where it makes sense).
|
* Use a linter (see below) and generally try to keep the linter happy (where it makes sense).
|
||||||
* Think about documentation, and try to leave godoc comments, when it will help new developers.
|
* Think about documentation, and try to leave godoc comments, when it will help new developers.
|
||||||
* Every package should have a high level doc.go file to describe the purpose of that package, its main functions, and any other relevant information.
|
* Every package should have a high level doc.go file to describe the purpose of that package, its main functions, and any other relevant information.
|
||||||
* `TODO` should not be used. If important enough should be recorded as an issue.
|
* `TODO` should not be used. If important enough should be recorded as an issue.
|
||||||
* `BUG` / `FIXME` should be used sparingly to guide future developers on some of the vulnerabilities of the code.
|
* `BUG` / `FIXME` should be used sparingly to guide future developers on some of the vulnerabilities of the code.
|
||||||
* `XXX` can be used in work-in-progress (prefixed with "WIP:" on github) branches but they must be removed before approving a PR.
|
* `XXX` can be used in work-in-progress (prefixed with "WIP:" on github) branches but they must be removed before approving a PR.
|
||||||
* Applications (e.g. clis/servers) *should* panic on unexpected unrecoverable errors and print a stack trace.
|
* Applications (e.g. clis/servers) *should* panic on unexpected unrecoverable errors and print a stack trace.
|
||||||
|
|
||||||
## Comments
|
## Comments
|
||||||
|
|
||||||
* Use a space after comment deliminter (ex. `// your comment`).
|
* Use a space after comment deliminter (ex. `// your comment`).
|
||||||
* Many comments are not sentences. These should begin with a lower case letter and end without a period.
|
* Many comments are not sentences. These should begin with a lower case letter and end without a period.
|
||||||
* Conversely, sentences in comments should be sentenced-cased and end with a period.
|
* Conversely, sentences in comments should be sentenced-cased and end with a period.
|
||||||
|
|
||||||
## Linters
|
## Linters
|
||||||
|
|
||||||
These must be applied to all (Go) repos.
|
These must be applied to all (Go) repos.
|
||||||
|
|
||||||
* [shellcheck](https://github.com/koalaman/shellcheck)
|
* [shellcheck](https://github.com/koalaman/shellcheck)
|
||||||
* [golangci-lint](https://github.com/golangci/golangci-lint) (covers all important linters)
|
* [golangci-lint](https://github.com/golangci/golangci-lint) (covers all important linters)
|
||||||
- See the `.golangci.yml` file in each repo for linter configuration.
|
* See the `.golangci.yml` file in each repo for linter configuration.
|
||||||
|
|
||||||
## Various
|
## Various
|
||||||
|
|
||||||
* Reserve "Save" and "Load" for long-running persistence operations. When parsing bytes, use "Encode" or "Decode".
|
* Reserve "Save" and "Load" for long-running persistence operations. When parsing bytes, use "Encode" or "Decode".
|
||||||
* Maintain consistency across the codebase.
|
* Maintain consistency across the codebase.
|
||||||
* Functions that return functions should have the suffix `Fn`
|
* Functions that return functions should have the suffix `Fn`
|
||||||
* Names should not [stutter](https://blog.golang.org/package-names). For example, a struct generally shouldn’t have
|
* Names should not [stutter](https://blog.golang.org/package-names). For example, a struct generally shouldn’t have
|
||||||
a field named after itself; e.g., this shouldn't occur:
|
a field named after itself; e.g., this shouldn't occur:
|
||||||
|
|
||||||
``` golang
|
``` golang
|
||||||
type middleware struct {
|
type middleware struct {
|
||||||
middleware Middleware
|
middleware Middleware
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
* In comments, use "iff" to mean, "if and only if".
|
|
||||||
* Product names are capitalized, like "Tendermint", "Basecoin", "Protobuf", etc except in command lines: `tendermint --help`
|
* In comments, use "iff" to mean, "if and only if".
|
||||||
* Acronyms are all capitalized, like "RPC", "gRPC", "API". "MyID", rather than "MyId".
|
* Product names are capitalized, like "Tendermint", "Basecoin", "Protobuf", etc except in command lines: `tendermint --help`
|
||||||
* Prefer errors.New() instead of fmt.Errorf() unless you're actually using the format feature with arguments.
|
* Acronyms are all capitalized, like "RPC", "gRPC", "API". "MyID", rather than "MyId".
|
||||||
|
* Prefer errors.New() instead of fmt.Errorf() unless you're actually using the format feature with arguments.
|
||||||
|
|
||||||
## Importing Libraries
|
## Importing Libraries
|
||||||
|
|
||||||
Sometimes it's necessary to rename libraries to avoid naming collisions or ambiguity.
|
Sometimes it's necessary to rename libraries to avoid naming collisions or ambiguity.
|
||||||
|
|
||||||
* Use [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports)
|
* Use [goimports](https://godoc.org/golang.org/x/tools/cmd/goimports)
|
||||||
* Separate imports into blocks - one for the standard lib, one for external libs and one for application libs.
|
* Separate imports into blocks - one for the standard lib, one for external libs and one for application libs.
|
||||||
* Here are some common library labels for consistency:
|
* Here are some common library labels for consistency:
|
||||||
- dbm "github.com/tendermint/tm-db"
|
* dbm "github.com/tendermint/tm-db"
|
||||||
- tmcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
* tmcmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
|
||||||
- tmcfg "github.com/tendermint/tendermint/config/tendermint"
|
* tmcfg "github.com/tendermint/tendermint/config/tendermint"
|
||||||
- tmtypes "github.com/tendermint/tendermint/types"
|
* tmtypes "github.com/tendermint/tendermint/types"
|
||||||
* Never use anonymous imports (the `.`), for example, `tmlibs/common` or anything else.
|
* Never use anonymous imports (the `.`), for example, `tmlibs/common` or anything else.
|
||||||
* When importing a pkg from the `tendermint/libs` directory, prefix the pkg alias with tm.
|
* When importing a pkg from the `tendermint/libs` directory, prefix the pkg alias with tm.
|
||||||
- tmbits "github.com/tendermint/tendermint/libs/bits"
|
* tmbits "github.com/tendermint/tendermint/libs/bits"
|
||||||
* tip: Use the `_` library import to import a library for initialization effects (side effects)
|
* tip: Use the `_` library import to import a library for initialization effects (side effects)
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
|
|
||||||
* Dependencies should be pinned by a release tag, or specific commit, to avoid breaking `go get` when external dependencies are updated.
|
* Dependencies should be pinned by a release tag, or specific commit, to avoid breaking `go get` when external dependencies are updated.
|
||||||
* Refer to the [contributing](CONTRIBUTING.md) document for more details
|
* Refer to the [contributing](CONTRIBUTING.md) document for more details
|
||||||
|
|
||||||
## Testing
|
## Testing
|
||||||
|
|
||||||
* The first rule of testing is: we add tests to our code
|
* The first rule of testing is: we add tests to our code
|
||||||
* The second rule of testing is: we add tests to our code
|
* The second rule of testing is: we add tests to our code
|
||||||
* For Golang testing:
|
* For Golang testing:
|
||||||
* Make use of table driven testing where possible and not-cumbersome
|
* Make use of table driven testing where possible and not-cumbersome
|
||||||
- [Inspiration](https://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go)
|
* [Inspiration](https://dave.cheney.net/2013/06/09/writing-table-driven-tests-in-go)
|
||||||
* Make use of [assert](https://godoc.org/github.com/stretchr/testify/assert) and [require](https://godoc.org/github.com/stretchr/testify/require)
|
* Make use of [assert](https://godoc.org/github.com/stretchr/testify/assert) and [require](https://godoc.org/github.com/stretchr/testify/require)
|
||||||
* When using mocks, it is recommended to use Testify [mock] (https://pkg.go.dev/github.com/stretchr/testify/mock
|
* When using mocks, it is recommended to use Testify [mock] (<https://pkg.go.dev/github.com/stretchr/testify/mock>
|
||||||
) along with [Mockery](https://github.com/vektra/mockery) for autogeneration
|
) along with [Mockery](https://github.com/vektra/mockery) for autogeneration
|
||||||
|
|
||||||
## Errors
|
## Errors
|
||||||
|
|
||||||
* Ensure that errors are concise, clear and traceable.
|
* Ensure that errors are concise, clear and traceable.
|
||||||
* Use stdlib errors package.
|
* Use stdlib errors package.
|
||||||
* For wrapping errors, use `fmt.Errorf()` with `%w`.
|
* For wrapping errors, use `fmt.Errorf()` with `%w`.
|
||||||
* Panic is appropriate when an internal invariant of a system is broken, while all other cases (in particular,
|
* Panic is appropriate when an internal invariant of a system is broken, while all other cases (in particular,
|
||||||
incorrect or invalid usage) should return errors.
|
incorrect or invalid usage) should return errors.
|
||||||
|
|
||||||
## Config
|
## Config
|
||||||
|
|
||||||
* Currently the TOML filetype is being used for config files
|
* Currently the TOML filetype is being used for config files
|
||||||
* A good practice is to store per-user config files under `~/.[yourAppName]/config.toml`
|
* A good practice is to store per-user config files under `~/.[yourAppName]/config.toml`
|
||||||
|
|
||||||
## CLI
|
## CLI
|
||||||
|
|
||||||
* When implementing a CLI use [Cobra](https://github.com/spf13/cobra) and [Viper](https://github.com/spf13/viper).
|
* When implementing a CLI use [Cobra](https://github.com/spf13/cobra) and [Viper](https://github.com/spf13/viper).
|
||||||
* Helper messages for commands and flags must be all lowercase.
|
* Helper messages for commands and flags must be all lowercase.
|
||||||
* Instead of using pointer flags (eg. `FlagSet().StringVar`) use Viper to retrieve flag values (eg. `viper.GetString`)
|
* Instead of using pointer flags (eg. `FlagSet().StringVar`) use Viper to retrieve flag values (eg. `viper.GetString`)
|
||||||
- The flag key used when setting and getting the flag should always be stored in a
|
* The flag key used when setting and getting the flag should always be stored in a
|
||||||
variable taking the form `FlagXxx` or `flagXxx`.
|
variable taking the form `FlagXxx` or `flagXxx`.
|
||||||
- Flag short variable descriptions should always start with a lower case character as to remain consistent with
|
* Flag short variable descriptions should always start with a lower case character as to remain consistent with
|
||||||
the description provided in the default `--help` flag.
|
the description provided in the default `--help` flag.
|
||||||
|
|
||||||
## Version
|
## Version
|
||||||
|
|
||||||
* Every repo should have a version/version.go file that mimics the Tendermint Core repo
|
* Every repo should have a version/version.go file that mimics the Tendermint Core repo
|
||||||
* We read the value of the constant version in our build scripts and hence it has to be a string
|
* We read the value of the constant version in our build scripts and hence it has to be a string
|
||||||
|
|
||||||
## Non-Go Code
|
## Non-Go Code
|
||||||
|
|
||||||
* All non-Go code (`*.proto`, `Makefile`, `*.sh`), where there is no common
|
* All non-Go code (`*.proto`, `Makefile`, `*.sh`), where there is no common
|
||||||
agreement on style, should be formatted according to
|
agreement on style, should be formatted according to
|
||||||
[EditorConfig](http://editorconfig.org/) config:
|
[EditorConfig](http://editorconfig.org/) config:
|
||||||
|
|
||||||
```
|
```toml
|
||||||
# top-most EditorConfig file
|
# top-most EditorConfig file
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
|
|||||||
+20
-22
@@ -30,11 +30,9 @@ evidence types.
|
|||||||
|
|
||||||
### P2P Protocol
|
### P2P Protocol
|
||||||
|
|
||||||
The default codec is now proto3, not amino. Check out the [TODO]() for
|
The default codec is now proto3, not amino. The schema files can be found in the `/proto`
|
||||||
motivation behind this change. The schema files can be found in the `/proto`
|
|
||||||
directory. In the future we're considering using gRPC for the remote private
|
directory. In the future we're considering using gRPC for the remote private
|
||||||
validator and ABCI
|
validator and ABCI ( [#4698](https://github.com/tendermint/tendermint/issues/4698) ).
|
||||||
([\#4698](https://github.com/tendermint/tendermint/issues/4698)).
|
|
||||||
|
|
||||||
### Blockchain Protocol
|
### Blockchain Protocol
|
||||||
|
|
||||||
@@ -77,7 +75,7 @@ With this release we are happy to announce the full protobuf migration of the Te
|
|||||||
- All proto files have been moved under one directory, `/proto`. This is in line with the recommended file layout by [buf](https://buf.build), you can read more about it [here](https://buf.build/docs/lint-checkers#file_layout)
|
- All proto files have been moved under one directory, `/proto`. This is in line with the recommended file layout by [buf](https://buf.build), you can read more about it [here](https://buf.build/docs/lint-checkers#file_layout)
|
||||||
- We use the generated protobuf types for only on disk and over the wire serialization. This means that these changes should not effect you as user of Tendermint.
|
- We use the generated protobuf types for only on disk and over the wire serialization. This means that these changes should not effect you as user of Tendermint.
|
||||||
- A few notable changes in the abci:
|
- A few notable changes in the abci:
|
||||||
- In `ValidatorUpdates` the public key type has been migrated to a protobuf `oneof` type. Since Tendermint only supports ed25519 validator keys this is the only available key in the oneof.
|
- In `ValidatorUpdates` the public key type has been migrated to a protobuf `oneof` type. Since Tendermint only supports ed25519 validator keys this is the only available key in the oneof.
|
||||||
|
|
||||||
### Consensus Params
|
### Consensus Params
|
||||||
|
|
||||||
@@ -125,7 +123,7 @@ article](https://medium.com/tendermint/everything-you-need-to-know-about-the-ten
|
|||||||
if you want to learn why the rewrite was needed and what comprise the new light
|
if you want to learn why the rewrite was needed and what comprise the new light
|
||||||
client.
|
client.
|
||||||
|
|
||||||
Doc: https://pkg.go.dev/github.com/tendermint/tendermint/lite2?tab=doc
|
Doc: <https://pkg.go.dev/github.com/tendermint/tendermint/lite2?tab=doc>
|
||||||
|
|
||||||
`Verifier` was broken up in two pieces: core verification logic (pure `VerifyX`
|
`Verifier` was broken up in two pieces: core verification logic (pure `VerifyX`
|
||||||
functions) and `Client` object, which represents the complete light client.
|
functions) and `Client` object, which represents the complete light client.
|
||||||
@@ -216,18 +214,18 @@ keys are called
|
|||||||
|
|
||||||
Evidence Params has been changed to include duration.
|
Evidence Params has been changed to include duration.
|
||||||
|
|
||||||
- `consensus_params.evidence.max_age_duration`.
|
- `consensus_params.evidence.max_age_duration`.
|
||||||
- Renamed `consensus_params.evidence.max_age` to `max_age_num_blocks`.
|
- Renamed `consensus_params.evidence.max_age` to `max_age_num_blocks`.
|
||||||
|
|
||||||
### Go API
|
### Go API
|
||||||
|
|
||||||
- `libs/common` has been removed in favor of specific pkgs.
|
- `libs/common` has been removed in favor of specific pkgs.
|
||||||
- `async`
|
- `async`
|
||||||
- `service`
|
- `service`
|
||||||
- `rand`
|
- `rand`
|
||||||
- `net`
|
- `net`
|
||||||
- `strings`
|
- `strings`
|
||||||
- `cmap`
|
- `cmap`
|
||||||
- removal of `errors` pkg
|
- removal of `errors` pkg
|
||||||
|
|
||||||
### RPC Changes
|
### RPC Changes
|
||||||
@@ -352,7 +350,7 @@ the compilation tag:
|
|||||||
|
|
||||||
Use `cleveldb` tag instead of `gcc` to compile Tendermint with CLevelDB or
|
Use `cleveldb` tag instead of `gcc` to compile Tendermint with CLevelDB or
|
||||||
use `make build_c` / `make install_c` (full instructions can be found at
|
use `make build_c` / `make install_c` (full instructions can be found at
|
||||||
https://tendermint.com/docs/introduction/install.html#compile-with-cleveldb-support)
|
<https://tendermint.com/docs/introduction/install.html#compile-with-cleveldb-support>)
|
||||||
|
|
||||||
## v0.31.0
|
## v0.31.0
|
||||||
|
|
||||||
@@ -470,7 +468,7 @@ To upgrade manually, use the provided `privValUpgrade.go` script, with exact pat
|
|||||||
to use the default paths, of `config/priv_validator_key.json` and
|
to use the default paths, of `config/priv_validator_key.json` and
|
||||||
`data/priv_validator_state.json`, respectively:
|
`data/priv_validator_state.json`, respectively:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
go run scripts/privValUpgrade.go <old-path> <new-key-path> <new-state-path>
|
go run scripts/privValUpgrade.go <old-path> <new-key-path> <new-state-path>
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -540,8 +538,8 @@ old data to be compatible with the new version.
|
|||||||
|
|
||||||
To reset the state do:
|
To reset the state do:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
$ tendermint unsafe_reset_all
|
tendermint unsafe_reset_all
|
||||||
```
|
```
|
||||||
|
|
||||||
Here we summarize some other notable changes to be mindful of.
|
Here we summarize some other notable changes to be mindful of.
|
||||||
@@ -578,7 +576,7 @@ the root of another. If you don't need this functionality, and you used to
|
|||||||
return `<proof bytes>` here, you should instead return a single `ProofOp` with
|
return `<proof bytes>` here, you should instead return a single `ProofOp` with
|
||||||
just the `Data` field set:
|
just the `Data` field set:
|
||||||
|
|
||||||
```
|
```go
|
||||||
[]ProofOp{
|
[]ProofOp{
|
||||||
ProofOp{
|
ProofOp{
|
||||||
Data: <proof bytes>,
|
Data: <proof bytes>,
|
||||||
@@ -626,8 +624,8 @@ old data to be compatible with the new version.
|
|||||||
|
|
||||||
To reset the state do:
|
To reset the state do:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
$ tendermint unsafe_reset_all
|
tendermint unsafe_reset_all
|
||||||
```
|
```
|
||||||
|
|
||||||
Here we summarize some other notable changes to be mindful of.
|
Here we summarize some other notable changes to be mindful of.
|
||||||
@@ -637,7 +635,7 @@ Here we summarize some other notable changes to be mindful of.
|
|||||||
`p2p.max_num_peers` was removed in favor of `p2p.max_num_inbound_peers` and
|
`p2p.max_num_peers` was removed in favor of `p2p.max_num_inbound_peers` and
|
||||||
`p2p.max_num_outbound_peers`.
|
`p2p.max_num_outbound_peers`.
|
||||||
|
|
||||||
```
|
```toml
|
||||||
# Maximum number of inbound peers
|
# Maximum number of inbound peers
|
||||||
max_num_inbound_peers = 40
|
max_num_inbound_peers = 40
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -27,11 +27,10 @@ A detailed description of the ABCI methods and message types is contained in:
|
|||||||
|
|
||||||
To compile the protobuf file, run (from the root of the repo):
|
To compile the protobuf file, run (from the root of the repo):
|
||||||
|
|
||||||
```
|
```sh
|
||||||
make protoc_abci
|
make protoc_abci
|
||||||
```
|
```
|
||||||
|
|
||||||
See `protoc --help` and [the Protocol Buffers site](https://developers.google.com/protocol-buffers)
|
See `protoc --help` and [the Protocol Buffers site](https://developers.google.com/protocol-buffers)
|
||||||
for details on compiling for other languages. Note we also include a [GRPC](https://www.grpc.io/docs)
|
for details on compiling for other languages. Note we also include a [GRPC](https://www.grpc.io/docs)
|
||||||
service definition.
|
service definition.
|
||||||
|
|
||||||
|
|||||||
@@ -21,11 +21,10 @@ The state is persisted in leveldb along with the last block committed,
|
|||||||
and the Handshake allows any necessary blocks to be replayed.
|
and the Handshake allows any necessary blocks to be replayed.
|
||||||
Validator set changes are effected using the following transaction format:
|
Validator set changes are effected using the following transaction format:
|
||||||
|
|
||||||
```
|
```md
|
||||||
"val:pubkey1!power1,pubkey2!power2,pubkey3!power3"
|
"val:pubkey1!power1,pubkey2!power2,pubkey3!power3"
|
||||||
```
|
```
|
||||||
|
|
||||||
where `pubkeyN` is a base64-encoded 32-byte ed25519 key and `powerN` is a new voting power for the validator with `pubkeyN` (possibly a new one).
|
where `pubkeyN` is a base64-encoded 32-byte ed25519 key and `powerN` is a new voting power for the validator with `pubkeyN` (possibly a new one).
|
||||||
To remove a validator from the validator set, set power to `0`.
|
To remove a validator from the validator set, set power to `0`.
|
||||||
There is no sybil protection against new validators joining.
|
There is no sybil protection against new validators joining.
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1,3 @@
|
|||||||
|
# Consensus
|
||||||
|
|
||||||
See the [consensus spec](https://github.com/tendermint/spec/tree/master/spec/consensus) and the [reactor consensus spec](https://github.com/tendermint/spec/tree/master/spec/reactors/consensus) for more information.
|
See the [consensus spec](https://github.com/tendermint/spec/tree/master/spec/consensus) and the [reactor consensus spec](https://github.com/tendermint/spec/tree/master/spec/reactors/consensus) for more information.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
## Simple Merkle Tree
|
# Merkle Tree
|
||||||
|
|
||||||
For smaller static data structures that don't require immutable snapshots or mutability;
|
For smaller static data structures that don't require immutable snapshots or mutability;
|
||||||
for instance the transactions and validation signatures of a block can be hashed using this simple merkle tree logic.
|
for instance the transactions and validation signatures of a block can be hashed using this simple merkle tree logic.
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
The documentation for Tendermint Core is hosted at:
|
The documentation for Tendermint Core is hosted at:
|
||||||
|
|
||||||
- https://docs.tendermint.com/master/
|
- <https://docs.tendermint.com/master/>
|
||||||
|
|
||||||
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) respectively.
|
[master](https://github.com/tendermint/tendermint/tree/master/docs) respectively.
|
||||||
@@ -79,7 +79,7 @@ npm run serve
|
|||||||
|
|
||||||
<!-- markdown-link-check-disable -->
|
<!-- markdown-link-check-disable -->
|
||||||
|
|
||||||
Run `pre` and `post` hooks and start a hot-reloading web-server. See output of this command for the URL (it is often https://localhost:8080).
|
Run `pre` and `post` hooks and start a hot-reloading web-server. See output of this command for the URL (it is often <https://localhost:8080>).
|
||||||
|
|
||||||
<!-- markdown-link-check-enable -->
|
<!-- markdown-link-check-enable -->
|
||||||
|
|
||||||
|
|||||||
+12
-12
@@ -14,7 +14,7 @@ Make sure you [have Go installed](https://golang.org/doc/install).
|
|||||||
|
|
||||||
Next, install the `abci-cli` tool and example applications:
|
Next, install the `abci-cli` tool and example applications:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
mkdir -p $GOPATH/src/github.com/tendermint
|
mkdir -p $GOPATH/src/github.com/tendermint
|
||||||
cd $GOPATH/src/github.com/tendermint
|
cd $GOPATH/src/github.com/tendermint
|
||||||
git clone https://github.com/tendermint/tendermint.git
|
git clone https://github.com/tendermint/tendermint.git
|
||||||
@@ -25,7 +25,7 @@ make install_abci
|
|||||||
|
|
||||||
Now run `abci-cli` to see the list of commands:
|
Now run `abci-cli` to see the list of commands:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
Usage:
|
Usage:
|
||||||
abci-cli [command]
|
abci-cli [command]
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ Its code can be found
|
|||||||
[here](https://github.com/tendermint/tendermint/blob/master/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:
|
||||||
|
|
||||||
```
|
```go
|
||||||
func cmdKVStore(cmd *cobra.Command, args []string) error {
|
func cmdKVStore(cmd *cobra.Command, args []string) error {
|
||||||
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
logger := log.NewTMLogger(log.NewSyncWriter(os.Stdout))
|
||||||
|
|
||||||
@@ -105,27 +105,27 @@ func cmdKVStore(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
Start by running:
|
Start by running:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
abci-cli kvstore
|
abci-cli kvstore
|
||||||
```
|
```
|
||||||
|
|
||||||
And in another terminal, run
|
And in another terminal, run
|
||||||
|
|
||||||
```
|
```sh
|
||||||
abci-cli echo hello
|
abci-cli echo hello
|
||||||
abci-cli info
|
abci-cli info
|
||||||
```
|
```
|
||||||
|
|
||||||
You'll see something like:
|
You'll see something like:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
-> data: hello
|
-> data: hello
|
||||||
-> data.hex: 68656C6C6F
|
-> data.hex: 68656C6C6F
|
||||||
```
|
```
|
||||||
|
|
||||||
and:
|
and:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
-> data: {"size":0}
|
-> data: {"size":0}
|
||||||
-> data.hex: 7B2273697A65223A307D
|
-> data.hex: 7B2273697A65223A307D
|
||||||
```
|
```
|
||||||
@@ -162,7 +162,7 @@ speaking ABCI messages to your application.
|
|||||||
|
|
||||||
Try running these commands:
|
Try running these commands:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
> echo hello
|
> echo hello
|
||||||
-> code: OK
|
-> code: OK
|
||||||
-> data: hello
|
-> data: hello
|
||||||
@@ -226,7 +226,7 @@ Like the kvstore app, its code can be found
|
|||||||
[here](https://github.com/tendermint/tendermint/blob/master/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:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
func cmdCounter(cmd *cobra.Command, args []string) error {
|
func cmdCounter(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
app := counter.NewCounterApplication(flagSerial)
|
app := counter.NewCounterApplication(flagSerial)
|
||||||
@@ -280,13 +280,13 @@ whose integer is greater than the last committed one.
|
|||||||
Let's kill the console and the kvstore application, and start the
|
Let's kill the console and the kvstore application, and start the
|
||||||
counter app:
|
counter app:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
abci-cli counter
|
abci-cli counter
|
||||||
```
|
```
|
||||||
|
|
||||||
In another window, start the `abci-cli console`:
|
In another window, start the `abci-cli console`:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
> set_option serial on
|
> set_option serial on
|
||||||
-> code: OK
|
-> code: OK
|
||||||
-> log: OK (SetOption doesn't return anything.)
|
-> log: OK (SetOption doesn't return anything.)
|
||||||
@@ -332,7 +332,7 @@ example directory](https://github.com/tendermint/tendermint/tree/master/abci/exa
|
|||||||
|
|
||||||
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):
|
||||||
|
|
||||||
```
|
```sh
|
||||||
git clone https://github.com/tendermint/js-abci.git
|
git clone https://github.com/tendermint/js-abci.git
|
||||||
cd js-abci
|
cd js-abci
|
||||||
npm install abci
|
npm install abci
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Tendermint blockchain application.
|
|||||||
|
|
||||||
The following diagram provides a superb example:
|
The following diagram provides a superb example:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
We distinguish here between two forms of "application". The first is the
|
We distinguish here between two forms of "application". The first is the
|
||||||
end-user application, like a desktop-based wallet app that a user downloads,
|
end-user application, like a desktop-based wallet app that a user downloads,
|
||||||
|
|||||||
@@ -26,25 +26,25 @@ committed in hash-linked blocks.
|
|||||||
The ABCI design has a few distinct components:
|
The ABCI design has a few distinct components:
|
||||||
|
|
||||||
- message protocol
|
- message protocol
|
||||||
- pairs of request and response messages
|
- pairs of request and response messages
|
||||||
- consensus makes requests, application responds
|
- consensus makes requests, application responds
|
||||||
- defined using protobuf
|
- defined using protobuf
|
||||||
- server/client
|
- server/client
|
||||||
- consensus engine runs the client
|
- consensus engine runs the client
|
||||||
- application runs the server
|
- application runs the server
|
||||||
- two implementations:
|
- two implementations:
|
||||||
- async raw bytes
|
- async raw bytes
|
||||||
- grpc
|
- grpc
|
||||||
- blockchain protocol
|
- blockchain protocol
|
||||||
- abci is connection oriented
|
- abci is connection oriented
|
||||||
- Tendermint Core maintains three connections:
|
- Tendermint Core maintains three connections:
|
||||||
- [mempool connection](#mempool-connection): for checking if
|
- [mempool connection](#mempool-connection): for checking if
|
||||||
transactions should be relayed before they are committed;
|
transactions should be relayed before they are committed;
|
||||||
only uses `CheckTx`
|
only uses `CheckTx`
|
||||||
- [consensus connection](#consensus-connection): for executing
|
- [consensus connection](#consensus-connection): for executing
|
||||||
transactions that have been committed. Message sequence is
|
transactions that have been committed. Message sequence is
|
||||||
-for every block -`BeginBlock, [DeliverTx, ...], EndBlock, Commit`
|
-for every block -`BeginBlock, [DeliverTx, ...], EndBlock, Commit`
|
||||||
- [query connection](#query-connection): for querying the
|
- [query connection](#query-connection): for querying the
|
||||||
application state; only uses Query and Info
|
application state; only uses Query and Info
|
||||||
|
|
||||||
The mempool and consensus logic act as clients, and each maintains an
|
The mempool and consensus logic act as clients, and each maintains an
|
||||||
@@ -104,7 +104,7 @@ mempool state (this behaviour can be turned off with
|
|||||||
|
|
||||||
In go:
|
In go:
|
||||||
|
|
||||||
```
|
```go
|
||||||
func (app *KVStoreApplication) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx {
|
func (app *KVStoreApplication) CheckTx(req types.RequestCheckTx) types.ResponseCheckTx {
|
||||||
return types.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1}
|
return types.ResponseCheckTx{Code: code.CodeTypeOK, GasWanted: 1}
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,7 @@ func (app *KVStoreApplication) CheckTx(req types.RequestCheckTx) types.ResponseC
|
|||||||
|
|
||||||
In Java:
|
In Java:
|
||||||
|
|
||||||
```
|
```java
|
||||||
ResponseCheckTx requestCheckTx(RequestCheckTx req) {
|
ResponseCheckTx requestCheckTx(RequestCheckTx req) {
|
||||||
byte[] transaction = req.getTx().toByteArray();
|
byte[] transaction = req.getTx().toByteArray();
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ merkle root of the data returned by the DeliverTx requests, or both.
|
|||||||
|
|
||||||
In go:
|
In go:
|
||||||
|
|
||||||
```
|
```go
|
||||||
// tx is either "key=value" or just arbitrary bytes
|
// tx is either "key=value" or just arbitrary bytes
|
||||||
func (app *KVStoreApplication) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx {
|
func (app *KVStoreApplication) DeliverTx(req types.RequestDeliverTx) types.ResponseDeliverTx {
|
||||||
var key, value []byte
|
var key, value []byte
|
||||||
@@ -200,7 +200,7 @@ func (app *KVStoreApplication) DeliverTx(req types.RequestDeliverTx) types.Respo
|
|||||||
|
|
||||||
In Java:
|
In Java:
|
||||||
|
|
||||||
```
|
```java
|
||||||
/**
|
/**
|
||||||
* Using Protobuf types from the protoc compiler, we always start with a byte[]
|
* Using Protobuf types from the protoc compiler, we always start with a byte[]
|
||||||
*/
|
*/
|
||||||
@@ -241,7 +241,7 @@ job of the [Handshake](#handshake).
|
|||||||
|
|
||||||
In go:
|
In go:
|
||||||
|
|
||||||
```
|
```go
|
||||||
func (app *KVStoreApplication) Commit() types.ResponseCommit {
|
func (app *KVStoreApplication) Commit() types.ResponseCommit {
|
||||||
// Using a memdb - just return the big endian size of the db
|
// Using a memdb - just return the big endian size of the db
|
||||||
appHash := make([]byte, 8)
|
appHash := make([]byte, 8)
|
||||||
@@ -255,7 +255,7 @@ func (app *KVStoreApplication) Commit() types.ResponseCommit {
|
|||||||
|
|
||||||
In Java:
|
In Java:
|
||||||
|
|
||||||
```
|
```java
|
||||||
ResponseCommit requestCommit(RequestCommit requestCommit) {
|
ResponseCommit requestCommit(RequestCommit requestCommit) {
|
||||||
|
|
||||||
// update the internal app-state
|
// update the internal app-state
|
||||||
@@ -278,7 +278,7 @@ pick up from when it restarts. See information on the Handshake, below.
|
|||||||
|
|
||||||
In go:
|
In go:
|
||||||
|
|
||||||
```
|
```go
|
||||||
// Track the block hash and header information
|
// Track the block hash and header information
|
||||||
func (app *PersistentKVStoreApplication) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock {
|
func (app *PersistentKVStoreApplication) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock {
|
||||||
// reset valset changes
|
// reset valset changes
|
||||||
@@ -289,7 +289,7 @@ func (app *PersistentKVStoreApplication) BeginBlock(req types.RequestBeginBlock)
|
|||||||
|
|
||||||
In Java:
|
In Java:
|
||||||
|
|
||||||
```
|
```java
|
||||||
/*
|
/*
|
||||||
* all types come from protobuf definition
|
* all types come from protobuf definition
|
||||||
*/
|
*/
|
||||||
@@ -321,7 +321,7 @@ for details on how it tracks validators.
|
|||||||
|
|
||||||
In go:
|
In go:
|
||||||
|
|
||||||
```
|
```go
|
||||||
// Update the validator set
|
// Update the validator set
|
||||||
func (app *PersistentKVStoreApplication) EndBlock(req types.RequestEndBlock) types.ResponseEndBlock {
|
func (app *PersistentKVStoreApplication) EndBlock(req types.RequestEndBlock) types.ResponseEndBlock {
|
||||||
return types.ResponseEndBlock{ValidatorUpdates: app.ValUpdates}
|
return types.ResponseEndBlock{ValidatorUpdates: app.ValUpdates}
|
||||||
@@ -330,7 +330,7 @@ func (app *PersistentKVStoreApplication) EndBlock(req types.RequestEndBlock) typ
|
|||||||
|
|
||||||
In Java:
|
In Java:
|
||||||
|
|
||||||
```
|
```java
|
||||||
/*
|
/*
|
||||||
* Assume that one validator changes. The new validator has a power of 10
|
* Assume that one validator changes. The new validator has a power of 10
|
||||||
*/
|
*/
|
||||||
@@ -367,7 +367,7 @@ Note: these query formats are subject to change!
|
|||||||
|
|
||||||
In go:
|
In go:
|
||||||
|
|
||||||
```
|
```go
|
||||||
func (app *KVStoreApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {
|
func (app *KVStoreApplication) Query(reqQuery types.RequestQuery) (resQuery types.ResponseQuery) {
|
||||||
if reqQuery.Prove {
|
if reqQuery.Prove {
|
||||||
value := app.state.db.Get(prefixKey(reqQuery.Data))
|
value := app.state.db.Get(prefixKey(reqQuery.Data))
|
||||||
@@ -396,7 +396,7 @@ func (app *KVStoreApplication) Query(reqQuery types.RequestQuery) (resQuery type
|
|||||||
|
|
||||||
In Java:
|
In Java:
|
||||||
|
|
||||||
```
|
```java
|
||||||
ResponseQuery requestQuery(RequestQuery req) {
|
ResponseQuery requestQuery(RequestQuery req) {
|
||||||
final boolean isProveQuery = req.getProve();
|
final boolean isProveQuery = req.getProve();
|
||||||
final ResponseQuery.Builder responseBuilder = ResponseQuery.newBuilder();
|
final ResponseQuery.Builder responseBuilder = ResponseQuery.newBuilder();
|
||||||
@@ -444,7 +444,7 @@ all blocks.
|
|||||||
|
|
||||||
In go:
|
In go:
|
||||||
|
|
||||||
```
|
```go
|
||||||
func (app *KVStoreApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) {
|
func (app *KVStoreApplication) Info(req types.RequestInfo) (resInfo types.ResponseInfo) {
|
||||||
return types.ResponseInfo{
|
return types.ResponseInfo{
|
||||||
Data: fmt.Sprintf("{\"size\":%v}", app.state.Size),
|
Data: fmt.Sprintf("{\"size\":%v}", app.state.Size),
|
||||||
@@ -456,7 +456,7 @@ func (app *KVStoreApplication) Info(req types.RequestInfo) (resInfo types.Respon
|
|||||||
|
|
||||||
In Java:
|
In Java:
|
||||||
|
|
||||||
```
|
```java
|
||||||
ResponseInfo requestInfo(RequestInfo req) {
|
ResponseInfo requestInfo(RequestInfo req) {
|
||||||
final byte[] lastAppHash = getLastAppHash();
|
final byte[] lastAppHash = getLastAppHash();
|
||||||
final long lastHeight = getLastHeight();
|
final long lastHeight = getLastHeight();
|
||||||
@@ -472,7 +472,7 @@ consensus params.
|
|||||||
|
|
||||||
In go:
|
In go:
|
||||||
|
|
||||||
```
|
```go
|
||||||
// Save the validators in the merkle tree
|
// Save the validators in the merkle tree
|
||||||
func (app *PersistentKVStoreApplication) InitChain(req types.RequestInitChain) types.ResponseInitChain {
|
func (app *PersistentKVStoreApplication) InitChain(req types.RequestInitChain) types.ResponseInitChain {
|
||||||
for _, v := range req.Validators {
|
for _, v := range req.Validators {
|
||||||
@@ -487,7 +487,7 @@ func (app *PersistentKVStoreApplication) InitChain(req types.RequestInitChain) t
|
|||||||
|
|
||||||
In Java:
|
In Java:
|
||||||
|
|
||||||
```
|
```java
|
||||||
/*
|
/*
|
||||||
* all types come from protobuf definition
|
* all types come from protobuf definition
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ echo export GO111MODULE=on >> ~/.bash_profile
|
|||||||
|
|
||||||
Then run
|
Then run
|
||||||
|
|
||||||
```
|
```sh
|
||||||
go get github.com/tendermint/tendermint
|
go get github.com/tendermint/tendermint
|
||||||
cd $GOPATH/src/github.com/tendermint/tendermint
|
cd $GOPATH/src/github.com/tendermint/tendermint
|
||||||
make tools
|
make tools
|
||||||
@@ -55,7 +55,7 @@ full transaction bytes are stored as the key and the value.
|
|||||||
|
|
||||||
Let's start a kvstore application.
|
Let's start a kvstore application.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
abci-cli kvstore
|
abci-cli kvstore
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ Tendermint binary installed. If not, follow the steps from
|
|||||||
[here](../introduction/install.md). If you have never run Tendermint
|
[here](../introduction/install.md). If you have never run Tendermint
|
||||||
before, use:
|
before, use:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
tendermint init
|
tendermint init
|
||||||
tendermint node
|
tendermint node
|
||||||
```
|
```
|
||||||
@@ -77,7 +77,7 @@ details, see [the guide on using Tendermint](../tendermint-core/using-tendermint
|
|||||||
You should see Tendermint making blocks! We can get the status of our
|
You should see Tendermint making blocks! We can get the status of our
|
||||||
Tendermint node as follows:
|
Tendermint node as follows:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -s localhost:26657/status
|
curl -s localhost:26657/status
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -86,7 +86,7 @@ tool like [jq](https://stedolan.github.io/jq/) or `json_pp`.
|
|||||||
|
|
||||||
Now let's send some transactions to the kvstore.
|
Now let's send some transactions to the kvstore.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -s 'localhost:26657/broadcast_tx_commit?tx="abcd"'
|
curl -s 'localhost:26657/broadcast_tx_commit?tx="abcd"'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -96,7 +96,7 @@ transaction with bytes `abcd`, so `abcd` will be stored as both the key
|
|||||||
and the value in the Merkle tree. The response should look something
|
and the value in the Merkle tree. The response should look something
|
||||||
like:
|
like:
|
||||||
|
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"id": "",
|
"id": "",
|
||||||
@@ -123,13 +123,13 @@ like:
|
|||||||
We can confirm that our transaction worked and the value got stored by
|
We can confirm that our transaction worked and the value got stored by
|
||||||
querying the app:
|
querying the app:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -s 'localhost:26657/abci_query?data="abcd"'
|
curl -s 'localhost:26657/abci_query?data="abcd"'
|
||||||
```
|
```
|
||||||
|
|
||||||
The result should look like:
|
The result should look like:
|
||||||
|
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"id": "",
|
"id": "",
|
||||||
@@ -153,14 +153,14 @@ human-readable](https://github.com/tendermint/tendermint/issues/1794).
|
|||||||
|
|
||||||
Now let's try setting a different key and value:
|
Now let's try setting a different key and value:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -s 'localhost:26657/broadcast_tx_commit?tx="name=satoshi"'
|
curl -s 'localhost:26657/broadcast_tx_commit?tx="name=satoshi"'
|
||||||
```
|
```
|
||||||
|
|
||||||
Now if we query for `name`, we should get `satoshi`, or `c2F0b3NoaQ==`
|
Now if we query for `name`, we should get `satoshi`, or `c2F0b3NoaQ==`
|
||||||
in base64:
|
in base64:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -s 'localhost:26657/abci_query?data="name"'
|
curl -s 'localhost:26657/abci_query?data="name"'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -196,13 +196,13 @@ Let's kill the previous instance of `tendermint` and the `kvstore`
|
|||||||
application, and start the counter app. We can enable `serial=on` with a
|
application, and start the counter app. We can enable `serial=on` with a
|
||||||
flag:
|
flag:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
abci-cli counter --serial
|
abci-cli counter --serial
|
||||||
```
|
```
|
||||||
|
|
||||||
In another window, reset then start Tendermint:
|
In another window, reset then start Tendermint:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
tendermint unsafe_reset_all
|
tendermint unsafe_reset_all
|
||||||
tendermint node
|
tendermint node
|
||||||
```
|
```
|
||||||
@@ -211,14 +211,14 @@ Once again, you can see the blocks streaming by. Let's send some
|
|||||||
transactions. Since we have set `serial=on`, the first transaction must
|
transactions. Since we have set `serial=on`, the first transaction must
|
||||||
be the number `0`:
|
be the number `0`:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl localhost:26657/broadcast_tx_commit?tx=0x00
|
curl localhost:26657/broadcast_tx_commit?tx=0x00
|
||||||
```
|
```
|
||||||
|
|
||||||
Note the empty (hence successful) response. The next transaction must be
|
Note the empty (hence successful) response. The next transaction must be
|
||||||
the number `1`. If instead, we try to send a `5`, we get an error:
|
the number `1`. If instead, we try to send a `5`, we get an error:
|
||||||
|
|
||||||
```
|
```json
|
||||||
> curl localhost:26657/broadcast_tx_commit?tx=0x05
|
> curl localhost:26657/broadcast_tx_commit?tx=0x05
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
@@ -237,7 +237,7 @@ the number `1`. If instead, we try to send a `5`, we get an error:
|
|||||||
|
|
||||||
But if we send a `1`, it works again:
|
But if we send a `1`, it works again:
|
||||||
|
|
||||||
```
|
```json
|
||||||
> curl localhost:26657/broadcast_tx_commit?tx=0x01
|
> curl localhost:26657/broadcast_tx_commit?tx=0x01
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
@@ -263,7 +263,7 @@ to [install node](https://nodejs.org/en/download/).
|
|||||||
You'll also need to fetch the relevant repository, from
|
You'll also need to fetch the relevant repository, from
|
||||||
[here](https://github.com/tendermint/js-abci), then install it:
|
[here](https://github.com/tendermint/js-abci), then install it:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
git clone https://github.com/tendermint/js-abci.git
|
git clone https://github.com/tendermint/js-abci.git
|
||||||
cd js-abci
|
cd js-abci
|
||||||
npm install abci
|
npm install abci
|
||||||
@@ -271,13 +271,13 @@ npm install abci
|
|||||||
|
|
||||||
Kill the previous `counter` and `tendermint` processes. Now run the app:
|
Kill the previous `counter` and `tendermint` processes. Now run the app:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
node example/counter.js
|
node example/counter.js
|
||||||
```
|
```
|
||||||
|
|
||||||
In another window, reset and start `tendermint`:
|
In another window, reset and start `tendermint`:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
tendermint unsafe_reset_all
|
tendermint unsafe_reset_all
|
||||||
tendermint node
|
tendermint node
|
||||||
```
|
```
|
||||||
@@ -286,7 +286,7 @@ Once again, you should see blocks streaming by - but now, our
|
|||||||
application is written in Javascript! Try sending some transactions, and
|
application is written in Javascript! Try sending some transactions, and
|
||||||
like before - the results should be the same:
|
like before - the results should be the same:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
# ok
|
# ok
|
||||||
curl localhost:26657/broadcast_tx_commit?tx=0x00
|
curl localhost:26657/broadcast_tx_commit?tx=0x00
|
||||||
# invalid nonce
|
# invalid nonce
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ type, only the key-value pairs defined in `EndBlock` are used.
|
|||||||
Each event contains a type and a list of attributes, which are key-value pairs
|
Each event contains a type and a list of attributes, which are key-value pairs
|
||||||
denoting something about what happened during the method's execution. For more
|
denoting something about what happened during the method's execution. For more
|
||||||
details on `Events`, see the
|
details on `Events`, see the
|
||||||
[ABCI]https://github.com/tendermint/spec/blob/master/spec/abci/abci.md#events)
|
[ABCI](https://github.com/tendermint/spec/blob/master/spec/abci/abci.md#events)
|
||||||
documentation.
|
documentation.
|
||||||
|
|
||||||
An Event has a composite key associated with it. A `compositeKey` is
|
An Event has a composite key associated with it. A `compositeKey` is
|
||||||
|
|||||||
@@ -13,14 +13,14 @@ for third-party applications (for analysis) or for inspecting state.
|
|||||||
To connect to a node via websocket from the CLI, you can use a tool such as
|
To connect to a node via websocket from the CLI, you can use a tool such as
|
||||||
[wscat](https://github.com/websockets/wscat) and run:
|
[wscat](https://github.com/websockets/wscat) and run:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
wscat ws://127.0.0.1:26657/websocket
|
wscat ws://127.0.0.1:26657/websocket
|
||||||
```
|
```
|
||||||
|
|
||||||
You can subscribe to any of the events above by calling the `subscribe` RPC
|
You can subscribe to any of the events above by calling the `subscribe` RPC
|
||||||
method via Websocket along with a valid query.
|
method via Websocket along with a valid query.
|
||||||
|
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"method": "subscribe",
|
"method": "subscribe",
|
||||||
@@ -38,7 +38,7 @@ You can also use tags, given you had included them into DeliverTx
|
|||||||
response, to query transaction results. See [Indexing
|
response, to query transaction results. See [Indexing
|
||||||
transactions](./indexing-transactions.md) for details.
|
transactions](./indexing-transactions.md) for details.
|
||||||
|
|
||||||
### ValidatorSetUpdates
|
## ValidatorSetUpdates
|
||||||
|
|
||||||
When validator set changes, ValidatorSetUpdates event is published. The
|
When validator set changes, ValidatorSetUpdates event is published. The
|
||||||
event carries a list of pubkey/power pairs. The list is the same
|
event carries a list of pubkey/power pairs. The list is the same
|
||||||
@@ -48,7 +48,7 @@ the ABCI spec).
|
|||||||
|
|
||||||
Response:
|
Response:
|
||||||
|
|
||||||
```
|
```json
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"id": 0,
|
"id": 0,
|
||||||
|
|||||||
@@ -55,8 +55,8 @@ $ echo $GOPATH
|
|||||||
We'll start by creating a new Go project.
|
We'll start by creating a new Go project.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ mkdir kvstore
|
mkdir kvstore
|
||||||
$ cd kvstore
|
cd kvstore
|
||||||
```
|
```
|
||||||
|
|
||||||
Inside the example directory create a `main.go` file with the following content:
|
Inside the example directory create a `main.go` file with the following content:
|
||||||
@@ -230,7 +230,7 @@ application in 3 parts: `BeginBlock`, one `DeliverTx` per transaction and
|
|||||||
`EndBlock` in the end. DeliverTx are being transfered asynchronously, but the
|
`EndBlock` in the end. DeliverTx are being transfered asynchronously, but the
|
||||||
responses are expected to come in order.
|
responses are expected to come in order.
|
||||||
|
|
||||||
```
|
```go
|
||||||
func (app *KVStoreApplication) BeginBlock(req abcitypes.RequestBeginBlock) abcitypes.ResponseBeginBlock {
|
func (app *KVStoreApplication) BeginBlock(req abcitypes.RequestBeginBlock) abcitypes.ResponseBeginBlock {
|
||||||
app.currentBatch = app.db.NewTransaction(true)
|
app.currentBatch = app.db.NewTransaction(true)
|
||||||
return abcitypes.ResponseBeginBlock{}
|
return abcitypes.ResponseBeginBlock{}
|
||||||
@@ -569,8 +569,8 @@ We are going to use [Go modules](https://github.com/golang/go/wiki/Modules) for
|
|||||||
dependency management.
|
dependency management.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ go mod init github.com/me/example
|
go mod init github.com/me/example
|
||||||
$ go build
|
go build
|
||||||
```
|
```
|
||||||
|
|
||||||
This should build the binary.
|
This should build the binary.
|
||||||
@@ -625,7 +625,7 @@ Response should contain the height where this transaction was committed.
|
|||||||
|
|
||||||
Now let's check if the given key now exists and its value:
|
Now let's check if the given key now exists and its value:
|
||||||
|
|
||||||
```
|
```json
|
||||||
$ curl -s 'localhost:26657/abci_query?data="tendermint"'
|
$ curl -s 'localhost:26657/abci_query?data="tendermint"'
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
|
|||||||
+18
-18
@@ -49,7 +49,7 @@ go version go1.14.x darwin/amd64
|
|||||||
Make sure you have `$GOPATH` environment variable set:
|
Make sure you have `$GOPATH` environment variable set:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ echo $GOPATH
|
echo $GOPATH
|
||||||
/Users/melekes/go
|
/Users/melekes/go
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -58,8 +58,8 @@ $ echo $GOPATH
|
|||||||
We'll start by creating a new Go project.
|
We'll start by creating a new Go project.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ mkdir kvstore
|
mkdir kvstore
|
||||||
$ cd kvstore
|
cd kvstore
|
||||||
```
|
```
|
||||||
|
|
||||||
Inside the example directory create a `main.go` file with the following content:
|
Inside the example directory create a `main.go` file with the following content:
|
||||||
@@ -79,7 +79,7 @@ func main() {
|
|||||||
When run, this should print "Hello, Tendermint Core" to the standard output.
|
When run, this should print "Hello, Tendermint Core" to the standard output.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ go run main.go
|
go run main.go
|
||||||
Hello, Tendermint Core
|
Hello, Tendermint Core
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -233,7 +233,7 @@ application in 3 parts: `BeginBlock`, one `DeliverTx` per transaction and
|
|||||||
`EndBlock` in the end. DeliverTx are being transferred asynchronously, but the
|
`EndBlock` in the end. DeliverTx are being transferred asynchronously, but the
|
||||||
responses are expected to come in order.
|
responses are expected to come in order.
|
||||||
|
|
||||||
```
|
```go
|
||||||
func (app *KVStoreApplication) BeginBlock(req abcitypes.RequestBeginBlock) abcitypes.ResponseBeginBlock {
|
func (app *KVStoreApplication) BeginBlock(req abcitypes.RequestBeginBlock) abcitypes.ResponseBeginBlock {
|
||||||
app.currentBatch = app.db.NewTransaction(true)
|
app.currentBatch = app.db.NewTransaction(true)
|
||||||
return abcitypes.ResponseBeginBlock{}
|
return abcitypes.ResponseBeginBlock{}
|
||||||
@@ -426,9 +426,9 @@ We are going to use [Go modules](https://github.com/golang/go/wiki/Modules) for
|
|||||||
dependency management.
|
dependency management.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ export GO111MODULE=on
|
export GO111MODULE=on
|
||||||
$ go mod init github.com/me/example
|
go mod init github.com/me/example
|
||||||
$ go build
|
go build
|
||||||
```
|
```
|
||||||
|
|
||||||
This should build the binary.
|
This should build the binary.
|
||||||
@@ -440,8 +440,8 @@ guide](https://docs.tendermint.com/master/introduction/install.html). If you're
|
|||||||
installing from source, don't forget to checkout the latest release (`git checkout vX.Y.Z`).
|
installing from source, don't forget to checkout the latest release (`git checkout vX.Y.Z`).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ rm -rf /tmp/example
|
rm -rf /tmp/example
|
||||||
$ TMHOME="/tmp/example" tendermint init
|
TMHOME="/tmp/example" tendermint init
|
||||||
|
|
||||||
I[2019-07-16|18:20:36.480] Generated private validator module=main keyFile=/tmp/example/config/priv_validator_key.json stateFile=/tmp/example2/data/priv_validator_state.json
|
I[2019-07-16|18:20:36.480] Generated private validator module=main keyFile=/tmp/example/config/priv_validator_key.json stateFile=/tmp/example2/data/priv_validator_state.json
|
||||||
I[2019-07-16|18:20:36.481] Generated node key module=main path=/tmp/example/config/node_key.json
|
I[2019-07-16|18:20:36.481] Generated node key module=main path=/tmp/example/config/node_key.json
|
||||||
@@ -455,8 +455,8 @@ Feel free to explore the generated files, which can be found at
|
|||||||
We are ready to start our application:
|
We are ready to start our application:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ rm example.sock
|
rm example.sock
|
||||||
$ ./example
|
./example
|
||||||
|
|
||||||
badger 2019/07/16 18:25:11 INFO: All 0 tables opened in 0s
|
badger 2019/07/16 18:25:11 INFO: All 0 tables opened in 0s
|
||||||
badger 2019/07/16 18:25:11 INFO: Replaying file id: 0 at offset: 0
|
badger 2019/07/16 18:25:11 INFO: Replaying file id: 0 at offset: 0
|
||||||
@@ -468,7 +468,7 @@ Then we need to start Tendermint Core and point it to our application. Staying
|
|||||||
within the application directory execute:
|
within the application directory execute:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ TMHOME="/tmp/example" tendermint node --proxy_app=unix://example.sock
|
TMHOME="/tmp/example" tendermint node --proxy_app=unix://example.sock
|
||||||
|
|
||||||
I[2019-07-16|18:26:20.362] Version info module=main software=0.32.1 block=10 p2p=7
|
I[2019-07-16|18:26:20.362] Version info module=main software=0.32.1 block=10 p2p=7
|
||||||
I[2019-07-16|18:26:20.383] Starting Node module=main impl=Node
|
I[2019-07-16|18:26:20.383] Starting Node module=main impl=Node
|
||||||
@@ -480,7 +480,7 @@ I[2019-07-16|18:26:21.446] Committed state module=s
|
|||||||
|
|
||||||
This should start the full node and connect to our ABCI application.
|
This should start the full node and connect to our ABCI application.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
I[2019-07-16|18:25:11.525] Waiting for new connection...
|
I[2019-07-16|18:25:11.525] Waiting for new connection...
|
||||||
I[2019-07-16|18:26:20.329] Accepted a new connection
|
I[2019-07-16|18:26:20.329] Accepted a new connection
|
||||||
I[2019-07-16|18:26:20.329] Waiting for new connection...
|
I[2019-07-16|18:26:20.329] Waiting for new connection...
|
||||||
@@ -491,8 +491,8 @@ I[2019-07-16|18:26:20.330] Accepted a new connection
|
|||||||
|
|
||||||
Now open another tab in your terminal and try sending a transaction:
|
Now open another tab in your terminal and try sending a transaction:
|
||||||
|
|
||||||
```bash
|
```json
|
||||||
$ curl -s 'localhost:26657/broadcast_tx_commit?tx="tendermint=rocks"'
|
curl -s 'localhost:26657/broadcast_tx_commit?tx="tendermint=rocks"'
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"id": "",
|
"id": "",
|
||||||
@@ -510,8 +510,8 @@ Response should contain the height where this transaction was committed.
|
|||||||
|
|
||||||
Now let's check if the given key now exists and its value:
|
Now let's check if the given key now exists and its value:
|
||||||
|
|
||||||
```
|
```json
|
||||||
$ curl -s 'localhost:26657/abci_query?data="tendermint"'
|
curl -s 'localhost:26657/abci_query?data="tendermint"'
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"id": "",
|
"id": "",
|
||||||
|
|||||||
+3
-3
@@ -64,9 +64,9 @@ For Gradle installation, please refer to [their official guide](https://gradle.o
|
|||||||
We'll start by creating a new Gradle project.
|
We'll start by creating a new Gradle project.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ export KVSTORE_HOME=~/kvstore
|
export KVSTORE_HOME=~/kvstore
|
||||||
$ mkdir $KVSTORE_HOME
|
mkdir $KVSTORE_HOME
|
||||||
$ cd $KVSTORE_HOME
|
cd $KVSTORE_HOME
|
||||||
```
|
```
|
||||||
|
|
||||||
Inside the example directory run:
|
Inside the example directory run:
|
||||||
|
|||||||
+15
-15
@@ -41,7 +41,7 @@ Please refer to [the Oracle's guide for installing JDK](https://www.oracle.com/t
|
|||||||
Verify that you have installed Java successfully:
|
Verify that you have installed Java successfully:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ java -version
|
java -version
|
||||||
java version "1.8.0_162"
|
java version "1.8.0_162"
|
||||||
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
|
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
|
||||||
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
|
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)
|
||||||
@@ -53,7 +53,7 @@ In my case it is Java SE Development Kit 8.
|
|||||||
Make sure you have `$JAVA_HOME` environment variable set:
|
Make sure you have `$JAVA_HOME` environment variable set:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ echo $JAVA_HOME
|
echo $JAVA_HOME
|
||||||
/Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home
|
/Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -64,9 +64,9 @@ For Gradle installation, please refer to [their official guide](https://gradle.o
|
|||||||
We'll start by creating a new Gradle project.
|
We'll start by creating a new Gradle project.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ export KVSTORE_HOME=~/kvstore
|
export KVSTORE_HOME=~/kvstore
|
||||||
$ mkdir $KVSTORE_HOME
|
mkdir $KVSTORE_HOME
|
||||||
$ cd $KVSTORE_HOME
|
cd $KVSTORE_HOME
|
||||||
```
|
```
|
||||||
|
|
||||||
Inside the example directory run:
|
Inside the example directory run:
|
||||||
@@ -78,7 +78,7 @@ gradle init --dsl groovy --package io.example --project-name example --type kotl
|
|||||||
This will create a new project for you. The tree of files should look like:
|
This will create a new project for you. The tree of files should look like:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ tree
|
tree
|
||||||
.
|
.
|
||||||
|-- build.gradle
|
|-- build.gradle
|
||||||
|-- gradle
|
|-- gradle
|
||||||
@@ -106,7 +106,7 @@ $ tree
|
|||||||
When run, this should print "Hello world." to the standard output.
|
When run, this should print "Hello world." to the standard output.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ ./gradlew run
|
./gradlew run
|
||||||
> Task :run
|
> Task :run
|
||||||
Hello world.
|
Hello world.
|
||||||
```
|
```
|
||||||
@@ -214,7 +214,7 @@ To generate all protobuf-type classes run:
|
|||||||
To verify that everything went smoothly, you can inspect the `build/generated/` directory:
|
To verify that everything went smoothly, you can inspect the `build/generated/` directory:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ tree build/generated/
|
tree build/generated/
|
||||||
build/generated/
|
build/generated/
|
||||||
`-- source
|
`-- source
|
||||||
`-- proto
|
`-- proto
|
||||||
@@ -521,10 +521,10 @@ execute `tendermint init`. But before we do that, we will need to install
|
|||||||
Tendermint Core.
|
Tendermint Core.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ rm -rf /tmp/example
|
rm -rf /tmp/example
|
||||||
$ cd $GOPATH/src/github.com/tendermint/tendermint
|
cd $GOPATH/src/github.com/tendermint/tendermint
|
||||||
$ make install
|
make install
|
||||||
$ TMHOME="/tmp/example" tendermint init
|
TMHOME="/tmp/example" tendermint init
|
||||||
|
|
||||||
I[2019-07-16|18:20:36.480] Generated private validator module=main keyFile=/tmp/example/config/priv_validator_key.json stateFile=/tmp/example2/data/priv_validator_state.json
|
I[2019-07-16|18:20:36.480] Generated private validator module=main keyFile=/tmp/example/config/priv_validator_key.json stateFile=/tmp/example2/data/priv_validator_state.json
|
||||||
I[2019-07-16|18:20:36.481] Generated node key module=main path=/tmp/example/config/node_key.json
|
I[2019-07-16|18:20:36.481] Generated node key module=main path=/tmp/example/config/node_key.json
|
||||||
@@ -547,7 +547,7 @@ Then we need to start Tendermint Core and point it to our application. Staying
|
|||||||
within the application directory execute:
|
within the application directory execute:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ TMHOME="/tmp/example" tendermint node --abci grpc --proxy_app tcp://127.0.0.1:26658
|
TMHOME="/tmp/example" tendermint node --abci grpc --proxy_app tcp://127.0.0.1:26658
|
||||||
|
|
||||||
I[2019-07-28|15:44:53.632] Version info module=main software=0.32.1 block=10 p2p=7
|
I[2019-07-28|15:44:53.632] Version info module=main software=0.32.1 block=10 p2p=7
|
||||||
I[2019-07-28|15:44:53.677] Starting Node module=main impl=Node
|
I[2019-07-28|15:44:53.677] Starting Node module=main impl=Node
|
||||||
@@ -559,7 +559,7 @@ I[2019-07-28|15:44:54.814] Committed state module=s
|
|||||||
Now open another tab in your terminal and try sending a transaction:
|
Now open another tab in your terminal and try sending a transaction:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ curl -s 'localhost:26657/broadcast_tx_commit?tx="tendermint=rocks"'
|
curl -s 'localhost:26657/broadcast_tx_commit?tx="tendermint=rocks"'
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"id": "",
|
"id": "",
|
||||||
@@ -578,7 +578,7 @@ Response should contain the height where this transaction was committed.
|
|||||||
Now let's check if the given key now exists and its value:
|
Now let's check if the given key now exists and its value:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
$ curl -s 'localhost:26657/abci_query?data="tendermint"'
|
curl -s 'localhost:26657/abci_query?data="tendermint"'
|
||||||
{
|
{
|
||||||
"jsonrpc": "2.0",
|
"jsonrpc": "2.0",
|
||||||
"id": "",
|
"id": "",
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ is inspired by Raft, is that it's simpler so normal engineers could understand.
|
|||||||
|
|
||||||
**CC**: Can you expand on the termination requirement?
|
**CC**: Can you expand on the termination requirement?
|
||||||
|
|
||||||
_Important point about Liveness in Tendermint_
|
> **Important point about Liveness in Tendermint**
|
||||||
|
|
||||||
**ZM**: In Tendermint, we are saying, for termination, we are making assumption
|
**ZM**: In Tendermint, we are saying, for termination, we are making assumption
|
||||||
that the system is partially synchronous. And in a partially synchronous system
|
that the system is partially synchronous. And in a partially synchronous system
|
||||||
|
|||||||
@@ -15,6 +15,6 @@ Get Tendermint up-and-running quickly with the [quick-start guide](./quick-start
|
|||||||
|
|
||||||
Detailed [installation instructions](./install.md).
|
Detailed [installation instructions](./install.md).
|
||||||
|
|
||||||
## What is Tendermint?
|
## What is Tendermint
|
||||||
|
|
||||||
Dive into [what Tendermint is and why](./what-is-tendermint.md)!
|
Dive into [what Tendermint is and why](./what-is-tendermint.md)!
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
# Tendermint Architectural Overview
|
# Tendermint Architectural Overview
|
||||||
_November 2019_
|
|
||||||
|
> **November 2019**
|
||||||
|
|
||||||
Over the next few weeks, @brapse, @marbar3778 and I (@tessr) are having a series of meetings to go over the architecture of Tendermint Core. These are my notes from these meetings, which will either serve as an artifact for onboarding future engineers; or will provide the basis for such a document.
|
Over the next few weeks, @brapse, @marbar3778 and I (@tessr) are having a series of meetings to go over the architecture of Tendermint Core. These are my notes from these meetings, which will either serve as an artifact for onboarding future engineers; or will provide the basis for such a document.
|
||||||
|
|
||||||
## Communication
|
## Communication
|
||||||
|
|
||||||
There are three forms of communication (e.g., requests, responses, connections) that can happen in Tendermint Core: *internode communication*, *intranode communication*, and *client communication*.
|
There are three forms of communication (e.g., requests, responses, connections) that can happen in Tendermint Core: *internode communication*, *intranode communication*, and *client communication*.
|
||||||
|
|
||||||
- Internode communication: Happens between a node and other peers. This kind of communication happens over TCP or HTTP. More on this below.
|
- Internode communication: Happens between a node and other peers. This kind of communication happens over TCP or HTTP. More on this below.
|
||||||
- Intranode communication: Happens within the node itself (i.e., between reactors or other components). These are typically function or method calls, or occasionally happen through an event bus.
|
- Intranode communication: Happens within the node itself (i.e., between reactors or other components). These are typically function or method calls, or occasionally happen through an event bus.
|
||||||
- Client communiation: Happens between a client (like a wallet or a browser) and a node on the network.
|
- Client communiation: Happens between a client (like a wallet or a browser) and a node on the network.
|
||||||
@@ -13,6 +15,7 @@ There are three forms of communication (e.g., requests, responses, connections)
|
|||||||
### Internode Communication
|
### Internode Communication
|
||||||
|
|
||||||
Internode communication can happen in two ways:
|
Internode communication can happen in two ways:
|
||||||
|
|
||||||
1. TCP connections through the p2p package
|
1. TCP connections through the p2p package
|
||||||
- Most common form of internode communication
|
- Most common form of internode communication
|
||||||
- Connections between nodes are persisted and shared across reactors, facilitated by the switch. (More on the switch below.)
|
- Connections between nodes are persisted and shared across reactors, facilitated by the switch. (More on the switch below.)
|
||||||
@@ -24,10 +27,12 @@ Internode communication can happen in two ways:
|
|||||||
### P2P Business (the Switch, the PEX, and the Address Book)
|
### P2P Business (the Switch, the PEX, and the Address Book)
|
||||||
|
|
||||||
When writing a p2p service, there are two primary responsibilities:
|
When writing a p2p service, there are two primary responsibilities:
|
||||||
|
|
||||||
1. Routing: Who gets which messages?
|
1. Routing: Who gets which messages?
|
||||||
2. Peer management: Who can you talk to? What is their state? And how can you do peer discovery?
|
2. Peer management: Who can you talk to? What is their state? And how can you do peer discovery?
|
||||||
|
|
||||||
The first responsibility is handled by the Switch:
|
The first responsibility is handled by the Switch:
|
||||||
|
|
||||||
- Responsible for routing connections between peers
|
- Responsible for routing connections between peers
|
||||||
- Notably _only handles TCP connections_; RPC/HTTP is separate
|
- Notably _only handles TCP connections_; RPC/HTTP is separate
|
||||||
- Is a dependency for every reactor; all reactors expose a function `setSwitch`
|
- Is a dependency for every reactor; all reactors expose a function `setSwitch`
|
||||||
@@ -42,12 +47,14 @@ The second responsibility is handled by a combination of the PEX and the Address
|
|||||||
TODO: What is the PEX and the Address Book?
|
TODO: What is the PEX and the Address Book?
|
||||||
|
|
||||||
#### The Nature of TCP, and Introduction to the `mconnection`
|
#### The Nature of TCP, and Introduction to the `mconnection`
|
||||||
Here are some relevant facts about TCP:
|
|
||||||
1. All TCP connections have a "frame window size" which represents the packet size to the "confidence;" i.e., if you are sending packets along a new connection, you must start out with small packets. As the packets are received successfully, you can start to send larger and larger packets. (This curve is illustrated below.) This means that TCP connections are slow to spin up.
|
|
||||||
3. The syn/ack process also means that there's a high overhead for small, frequent messages
|
|
||||||
4. Sockets are represented by file descriptors.
|
|
||||||
|
|
||||||

|
Here are some relevant facts about TCP:
|
||||||
|
|
||||||
|
1. All TCP connections have a "frame window size" which represents the packet size to the "confidence;" i.e., if you are sending packets along a new connection, you must start out with small packets. As the packets are received successfully, you can start to send larger and larger packets. (This curve is illustrated below.) This means that TCP connections are slow to spin up.
|
||||||
|
2. The syn/ack process also means that there's a high overhead for small, frequent messages
|
||||||
|
3. Sockets are represented by file descriptors.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
In order to have performant TCP connections under the conditions created in Tendermint, we've created the `mconnection`, or the multiplexing connection. It is our own protocol built on top of TCP. It lets us reuse TCP connections to minimize overhead, and it keeps the window size high by sending auxiliary messages when necessary.
|
In order to have performant TCP connections under the conditions created in Tendermint, we've created the `mconnection`, or the multiplexing connection. It is our own protocol built on top of TCP. It lets us reuse TCP connections to minimize overhead, and it keeps the window size high by sending auxiliary messages when necessary.
|
||||||
|
|
||||||
@@ -57,22 +64,25 @@ The `mconnection` has two methods: `send`, which takes a raw handle to the socke
|
|||||||
|
|
||||||
The `mconnection` is owned by a peer, which is owned (potentially with many other peers) by a (global) transport, which is owned by the (global) switch:
|
The `mconnection` is owned by a peer, which is owned (potentially with many other peers) by a (global) transport, which is owned by the (global) switch:
|
||||||
|
|
||||||
|
<!-- markdownlint-disable -->
|
||||||
```
|
```
|
||||||
switch
|
switch
|
||||||
transport
|
transport
|
||||||
peer
|
peer
|
||||||
mconnection
|
mconnection
|
||||||
peer
|
peer
|
||||||
mconnection
|
mconnection
|
||||||
peer
|
peer
|
||||||
mconnection
|
mconnection
|
||||||
```
|
```
|
||||||
|
<!-- markdownlint-restore -->
|
||||||
|
|
||||||
## node.go
|
## node.go
|
||||||
|
|
||||||
node.go is the entrypoint for running a node. It sets up reactors, sets up the switch, and registers all the RPC endpoints for a node.
|
node.go is the entrypoint for running a node. It sets up reactors, sets up the switch, and registers all the RPC endpoints for a node.
|
||||||
|
|
||||||
## Types of Nodes
|
## Types of Nodes
|
||||||
|
|
||||||
1. Validator Node:
|
1. Validator Node:
|
||||||
2. Full Node:
|
2. Full Node:
|
||||||
3. Seed Node:
|
3. Seed Node:
|
||||||
@@ -82,6 +92,7 @@ TODO: Flesh out the differences between the types of nodes and how they're confi
|
|||||||
## Reactors
|
## Reactors
|
||||||
|
|
||||||
Here are some Reactor Facts:
|
Here are some Reactor Facts:
|
||||||
|
|
||||||
- Every reactor holds a pointer to the global switch (set through `SetSwitch()`)
|
- Every reactor holds a pointer to the global switch (set through `SetSwitch()`)
|
||||||
- The switch holds a pointer to every reactor (`addReactor()`)
|
- The switch holds a pointer to every reactor (`addReactor()`)
|
||||||
- Every reactor gets set up in node.go (and if you are using custom reactors, this is where you specify that)
|
- Every reactor gets set up in node.go (and if you are using custom reactors, this is where you specify that)
|
||||||
@@ -90,6 +101,7 @@ Here are some Reactor Facts:
|
|||||||
- Sometimes reactors talk to each other by fetching references to one another via the switch (which maintains a pointer to each reactor). **Question: Can reactors talk to each other in any other way?**
|
- Sometimes reactors talk to each other by fetching references to one another via the switch (which maintains a pointer to each reactor). **Question: Can reactors talk to each other in any other way?**
|
||||||
|
|
||||||
Furthermore, all reactors expose:
|
Furthermore, all reactors expose:
|
||||||
|
|
||||||
1. A TCP channel
|
1. A TCP channel
|
||||||
2. A `receive` method
|
2. A `receive` method
|
||||||
3. An `addReactor` call
|
3. An `addReactor` call
|
||||||
@@ -99,6 +111,7 @@ The `receive` method can be called many times by the mconnection. It has the sam
|
|||||||
The `addReactor` call does a for loop over all the channels on the reactor and creates a map of channel IDs->reactors. The switch holds onto this map, and passes it to the _transport_, a thin wrapper around TCP connections.
|
The `addReactor` call does a for loop over all the channels on the reactor and creates a map of channel IDs->reactors. The switch holds onto this map, and passes it to the _transport_, a thin wrapper around TCP connections.
|
||||||
|
|
||||||
The following is an exhaustive (?) list of reactors:
|
The following is an exhaustive (?) list of reactors:
|
||||||
|
|
||||||
- Blockchain Reactor
|
- Blockchain Reactor
|
||||||
- Consensus Reactor
|
- Consensus Reactor
|
||||||
- Evidence Reactor
|
- Evidence Reactor
|
||||||
@@ -108,6 +121,8 @@ The following is an exhaustive (?) list of reactors:
|
|||||||
Each of these will be discussed in more detail later.
|
Each of these will be discussed in more detail later.
|
||||||
|
|
||||||
### Blockchain Reactor
|
### Blockchain Reactor
|
||||||
|
|
||||||
The blockchain reactor has two responsibilities:
|
The blockchain reactor has two responsibilities:
|
||||||
|
|
||||||
1. Serve blocks at the request of peers
|
1. Serve blocks at the request of peers
|
||||||
2. TODO: learn about the second responsibility of the blockchain reactor
|
2. TODO: learn about the second responsibility of the blockchain reactor
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ echo export GO111MODULE=on >> ~/.bash_profile
|
|||||||
|
|
||||||
### Get Source Code
|
### Get Source Code
|
||||||
|
|
||||||
```
|
```sh
|
||||||
mkdir -p $GOPATH/src/github.com/tendermint
|
mkdir -p $GOPATH/src/github.com/tendermint
|
||||||
cd $GOPATH/src/github.com/tendermint
|
cd $GOPATH/src/github.com/tendermint
|
||||||
git clone https://github.com/tendermint/tendermint.git
|
git clone https://github.com/tendermint/tendermint.git
|
||||||
@@ -30,19 +30,19 @@ cd tendermint
|
|||||||
|
|
||||||
### Get Tools & Dependencies
|
### Get Tools & Dependencies
|
||||||
|
|
||||||
```
|
```sh
|
||||||
make tools
|
make tools
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compile
|
### Compile
|
||||||
|
|
||||||
```
|
```sh
|
||||||
make install
|
make install
|
||||||
```
|
```
|
||||||
|
|
||||||
to put the binary in `$GOPATH/bin` or use:
|
to put the binary in `$GOPATH/bin` or use:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
make build
|
make build
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ file.
|
|||||||
The latest tendermint is now installed. You can verify the installation by
|
The latest tendermint is now installed. You can verify the installation by
|
||||||
running:
|
running:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
tendermint version
|
tendermint version
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ tendermint version
|
|||||||
|
|
||||||
To start a one-node blockchain with a simple in-process application:
|
To start a one-node blockchain with a simple in-process application:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
tendermint init
|
tendermint init
|
||||||
tendermint node --proxy_app=kvstore
|
tendermint node --proxy_app=kvstore
|
||||||
```
|
```
|
||||||
@@ -73,14 +73,14 @@ tendermint node --proxy_app=kvstore
|
|||||||
|
|
||||||
If you already have Tendermint installed, and you make updates, simply
|
If you already have Tendermint installed, and you make updates, simply
|
||||||
|
|
||||||
```
|
```sh
|
||||||
cd $GOPATH/src/github.com/tendermint/tendermint
|
cd $GOPATH/src/github.com/tendermint/tendermint
|
||||||
make install
|
make install
|
||||||
```
|
```
|
||||||
|
|
||||||
To upgrade, run
|
To upgrade, run
|
||||||
|
|
||||||
```
|
```sh
|
||||||
cd $GOPATH/src/github.com/tendermint/tendermint
|
cd $GOPATH/src/github.com/tendermint/tendermint
|
||||||
git pull origin master
|
git pull origin master
|
||||||
make install
|
make install
|
||||||
@@ -92,7 +92,7 @@ Install [LevelDB](https://github.com/google/leveldb) (minimum version is 1.7).
|
|||||||
|
|
||||||
Install LevelDB with snappy (optionally). Below are commands for Ubuntu:
|
Install LevelDB with snappy (optionally). Below are commands for Ubuntu:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt install build-essential
|
sudo apt install build-essential
|
||||||
|
|
||||||
@@ -111,20 +111,20 @@ wget https://github.com/google/leveldb/archive/v1.20.tar.gz && \
|
|||||||
|
|
||||||
Set a database backend to `cleveldb`:
|
Set a database backend to `cleveldb`:
|
||||||
|
|
||||||
```
|
```toml
|
||||||
# config/config.toml
|
# config/config.toml
|
||||||
db_backend = "cleveldb"
|
db_backend = "cleveldb"
|
||||||
```
|
```
|
||||||
|
|
||||||
To install Tendermint, run:
|
To install Tendermint, run:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
CGO_LDFLAGS="-lsnappy" make install TENDERMINT_BUILD_OPTIONS=cleveldb
|
CGO_LDFLAGS="-lsnappy" make install TENDERMINT_BUILD_OPTIONS=cleveldb
|
||||||
```
|
```
|
||||||
|
|
||||||
or run:
|
or run:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
CGO_LDFLAGS="-lsnappy" make build TENDERMINT_BUILD_OPTIONS=cleveldb
|
CGO_LDFLAGS="-lsnappy" make build TENDERMINT_BUILD_OPTIONS=cleveldb
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ order: 2
|
|||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
This is a quick start guide. If you have a vague idea about how <df value="tendermint">Tendermint</df>
|
This is a quick start guide. If you have a vague idea about how Tendermint
|
||||||
works and want to get started right away, continue.
|
works and want to get started right away, continue.
|
||||||
|
|
||||||
## Install
|
## Install
|
||||||
@@ -18,7 +18,7 @@ Ubuntu 16.04 machine, use [this script](https://git.io/fFfOR).
|
|||||||
|
|
||||||
WARNING: do not run this on your local machine.
|
WARNING: do not run this on your local machine.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -L https://git.io/fFfOR | bash
|
curl -L https://git.io/fFfOR | bash
|
||||||
source ~/.profile
|
source ~/.profile
|
||||||
```
|
```
|
||||||
@@ -33,7 +33,7 @@ For manual installation, see the [install instructions](install.md)
|
|||||||
|
|
||||||
Running:
|
Running:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
tendermint init
|
tendermint init
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ will create the required files for a single, local node.
|
|||||||
|
|
||||||
These files are found in `$HOME/.tendermint`:
|
These files are found in `$HOME/.tendermint`:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
$ ls $HOME/.tendermint
|
$ ls $HOME/.tendermint
|
||||||
|
|
||||||
config data
|
config data
|
||||||
@@ -58,46 +58,46 @@ Configuring a cluster is covered further below.
|
|||||||
|
|
||||||
Start tendermint with a simple in-process application:
|
Start tendermint with a simple in-process application:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
tendermint node --proxy_app=kvstore
|
tendermint node --proxy_app=kvstore
|
||||||
```
|
```
|
||||||
|
|
||||||
and blocks will start to stream in:
|
and blocks will start to stream in:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
I[01-06|01:45:15.592] Executed block module=state height=1 validTxs=0 invalidTxs=0
|
I[01-06|01:45:15.592] Executed block module=state height=1 validTxs=0 invalidTxs=0
|
||||||
I[01-06|01:45:15.624] Committed state module=state height=1 txs=0 appHash=
|
I[01-06|01:45:15.624] Committed state module=state height=1 txs=0 appHash=
|
||||||
```
|
```
|
||||||
|
|
||||||
Check the status with:
|
Check the status with:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -s localhost:26657/status
|
curl -s localhost:26657/status
|
||||||
```
|
```
|
||||||
|
|
||||||
### Sending Transactions
|
### Sending Transactions
|
||||||
|
|
||||||
With the kvstore app running, we can send transactions:
|
With the KVstore app running, we can send transactions:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -s 'localhost:26657/broadcast_tx_commit?tx="abcd"'
|
curl -s 'localhost:26657/broadcast_tx_commit?tx="abcd"'
|
||||||
```
|
```
|
||||||
|
|
||||||
and check that it worked with:
|
and check that it worked with:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -s 'localhost:26657/abci_query?data="abcd"'
|
curl -s 'localhost:26657/abci_query?data="abcd"'
|
||||||
```
|
```
|
||||||
|
|
||||||
We can send transactions with a key and value too:
|
We can send transactions with a key and value too:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -s 'localhost:26657/broadcast_tx_commit?tx="name=satoshi"'
|
curl -s 'localhost:26657/broadcast_tx_commit?tx="name=satoshi"'
|
||||||
```
|
```
|
||||||
|
|
||||||
and query the key:
|
and query the key:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -s 'localhost:26657/abci_query?data="name"'
|
curl -s 'localhost:26657/abci_query?data="name"'
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ addresses below as IP1, IP2, IP3, IP4.
|
|||||||
|
|
||||||
Then, `ssh` into each machine, and execute [this script](https://git.io/fFfOR):
|
Then, `ssh` into each machine, and execute [this script](https://git.io/fFfOR):
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl -L https://git.io/fFfOR | bash
|
curl -L https://git.io/fFfOR | bash
|
||||||
source ~/.profile
|
source ~/.profile
|
||||||
```
|
```
|
||||||
@@ -122,7 +122,7 @@ Next, use the `tendermint testnet` command to create four directories of config
|
|||||||
|
|
||||||
Before you can start the network, you'll need peers identifiers (IPs are not enough and can change). We'll refer to them as ID1, ID2, ID3, ID4.
|
Before you can start the network, you'll need peers identifiers (IPs are not enough and can change). We'll refer to them as ID1, ID2, ID3, ID4.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
tendermint show_node_id --home ./mytestnet/node0
|
tendermint show_node_id --home ./mytestnet/node0
|
||||||
tendermint show_node_id --home ./mytestnet/node1
|
tendermint show_node_id --home ./mytestnet/node1
|
||||||
tendermint show_node_id --home ./mytestnet/node2
|
tendermint show_node_id --home ./mytestnet/node2
|
||||||
@@ -131,7 +131,7 @@ tendermint show_node_id --home ./mytestnet/node3
|
|||||||
|
|
||||||
Finally, from each machine, run:
|
Finally, from each machine, run:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
tendermint node --home ./mytestnet/node0 --proxy_app=kvstore --p2p.persistent_peers="ID1@IP1:26656,ID2@IP2:26656,ID3@IP3:26656,ID4@IP4:26656"
|
tendermint node --home ./mytestnet/node0 --proxy_app=kvstore --p2p.persistent_peers="ID1@IP1:26656,ID2@IP2:26656,ID3@IP3:26656,ID4@IP4:26656"
|
||||||
tendermint node --home ./mytestnet/node1 --proxy_app=kvstore --p2p.persistent_peers="ID1@IP1:26656,ID2@IP2:26656,ID3@IP3:26656,ID4@IP4:26656"
|
tendermint node --home ./mytestnet/node1 --proxy_app=kvstore --p2p.persistent_peers="ID1@IP1:26656,ID2@IP2:26656,ID3@IP3:26656,ID4@IP4:26656"
|
||||||
tendermint node --home ./mytestnet/node2 --proxy_app=kvstore --p2p.persistent_peers="ID1@IP1:26656,ID2@IP2:26656,ID3@IP3:26656,ID4@IP4:26656"
|
tendermint node --home ./mytestnet/node2 --proxy_app=kvstore --p2p.persistent_peers="ID1@IP1:26656,ID2@IP2:26656,ID3@IP3:26656,ID4@IP4:26656"
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
order: 4
|
order: 4
|
||||||
---
|
---
|
||||||
|
|
||||||
# What is Tendermint?
|
# What is Tendermint
|
||||||
|
|
||||||
Tendermint is software for securely and consistently replicating an
|
Tendermint is software for securely and consistently replicating an
|
||||||
application on many machines. By securely, we mean that Tendermint works
|
application on many machines. By securely, we mean that Tendermint works
|
||||||
@@ -74,7 +74,7 @@ Tendermint is in essence similar software, but with two key differences:
|
|||||||
the application logic that's right for them, from key-value store to
|
the application logic that's right for them, from key-value store to
|
||||||
cryptocurrency to e-voting platform and beyond.
|
cryptocurrency to e-voting platform and beyond.
|
||||||
|
|
||||||
### Bitcoin, Ethereum, etc.
|
### Bitcoin, Ethereum, etc
|
||||||
|
|
||||||
Tendermint emerged in the tradition of cryptocurrencies like Bitcoin,
|
Tendermint emerged in the tradition of cryptocurrencies like Bitcoin,
|
||||||
Ethereum, etc. with the goal of providing a more efficient and secure
|
Ethereum, etc. with the goal of providing a more efficient and secure
|
||||||
@@ -227,7 +227,7 @@ design their message handlers to create a blockchain that does anything
|
|||||||
useful but this architecture provides a place to start. The diagram
|
useful but this architecture provides a place to start. The diagram
|
||||||
below illustrates the flow of messages via ABCI.
|
below illustrates the flow of messages via ABCI.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## A Note on Determinism
|
## A Note on Determinism
|
||||||
|
|
||||||
@@ -263,7 +263,7 @@ Tendermint is an easy-to-understand, mostly asynchronous, BFT consensus
|
|||||||
protocol. The protocol follows a simple state machine that looks like
|
protocol. The protocol follows a simple state machine that looks like
|
||||||
this:
|
this:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
Participants in the protocol are called **validators**; they take turns
|
Participants in the protocol are called **validators**; they take turns
|
||||||
proposing blocks of transactions and voting on them. Blocks are
|
proposing blocks of transactions and voting on them. Blocks are
|
||||||
@@ -329,4 +329,4 @@ The following diagram is Tendermint in a (technical) nutshell. [See here
|
|||||||
for high resolution
|
for high resolution
|
||||||
version](https://github.com/mobfoundry/hackatom/blob/master/tminfo.pdf).
|
version](https://github.com/mobfoundry/hackatom/blob/master/tminfo.pdf).
|
||||||
|
|
||||||

|

|
||||||
|
|||||||
@@ -61,7 +61,7 @@ the binary and config files to the container.
|
|||||||
|
|
||||||
To change the number of validators / non-validators change the `localnet-start` Makefile target [here](../../makefile):
|
To change the number of validators / non-validators change the `localnet-start` Makefile target [here](../../makefile):
|
||||||
|
|
||||||
```sh
|
```makefile
|
||||||
localnet-start: localnet-stop
|
localnet-start: localnet-stop
|
||||||
@if ! [ -f build/node0/config/genesis.json ]; then docker run --rm -v $(CURDIR)/build:/tendermint:Z tendermint/localnode testnet --v 5 --n 3 --o . --populate-persistent-peers --starting-ip-address 192.167.10.2 ; fi
|
@if ! [ -f build/node0/config/genesis.json ]; then docker run --rm -v $(CURDIR)/build:/tendermint:Z tendermint/localnode testnet --v 5 --n 3 --o . --populate-persistent-peers --starting-ip-address 192.167.10.2 ; fi
|
||||||
docker-compose up
|
docker-compose up
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ node testnet. The script more or less does everything described below.
|
|||||||
- Create SSH keys (`ssh-keygen`)
|
- Create SSH keys (`ssh-keygen`)
|
||||||
- Set environment variables:
|
- Set environment variables:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
export DO_API_TOKEN="abcdef01234567890abcdef01234567890"
|
export DO_API_TOKEN="abcdef01234567890abcdef01234567890"
|
||||||
export SSH_KEY_FILE="$HOME/.ssh/id_rsa.pub"
|
export SSH_KEY_FILE="$HOME/.ssh/id_rsa.pub"
|
||||||
```
|
```
|
||||||
@@ -40,13 +40,13 @@ These will be used by both `terraform` and `ansible`.
|
|||||||
This step will create four Digital Ocean droplets. First, go to the
|
This step will create four Digital Ocean droplets. First, go to the
|
||||||
correct directory:
|
correct directory:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
cd $GOPATH/src/github.com/tendermint/tendermint/networks/remote/terraform
|
cd $GOPATH/src/github.com/tendermint/tendermint/networks/remote/terraform
|
||||||
```
|
```
|
||||||
|
|
||||||
then:
|
then:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
terraform init
|
terraform init
|
||||||
terraform apply -var DO_API_TOKEN="$DO_API_TOKEN" -var SSH_KEY_FILE="$SSH_KEY_FILE"
|
terraform apply -var DO_API_TOKEN="$DO_API_TOKEN" -var SSH_KEY_FILE="$SSH_KEY_FILE"
|
||||||
```
|
```
|
||||||
@@ -72,13 +72,13 @@ number of droplets created).
|
|||||||
|
|
||||||
To create the node files run:
|
To create the node files run:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
tendermint testnet
|
tendermint testnet
|
||||||
```
|
```
|
||||||
|
|
||||||
Then, to configure our droplets run:
|
Then, to configure our droplets run:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
ansible-playbook -i inventory/digital_ocean.py -l sentrynet config.yml -e BINARY=$GOPATH/src/github.com/tendermint/tendermint/build/tendermint -e CONFIGDIR=$GOPATH/src/github.com/tendermint/tendermint/networks/remote/ansible/mytestnet
|
ansible-playbook -i inventory/digital_ocean.py -l sentrynet config.yml -e BINARY=$GOPATH/src/github.com/tendermint/tendermint/build/tendermint -e CONFIGDIR=$GOPATH/src/github.com/tendermint/tendermint/networks/remote/ansible/mytestnet
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -87,7 +87,7 @@ configuration files to run a testnet.
|
|||||||
|
|
||||||
Next, we run the install role:
|
Next, we run the install role:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
ansible-playbook -i inventory/digital_ocean.py -l sentrynet install.yml
|
ansible-playbook -i inventory/digital_ocean.py -l sentrynet install.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -104,14 +104,14 @@ increasing).
|
|||||||
Next, open `roles/install/templates/systemd.service.j2` and look for the
|
Next, open `roles/install/templates/systemd.service.j2` and look for the
|
||||||
line `ExecStart` which should look something like:
|
line `ExecStart` which should look something like:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
ExecStart=/usr/bin/tendermint node --proxy_app=kvstore
|
ExecStart=/usr/bin/tendermint node --proxy_app=kvstore
|
||||||
```
|
```
|
||||||
|
|
||||||
and add the `--p2p.persistent_peers` flag with the relevant information
|
and add the `--p2p.persistent_peers` flag with the relevant information
|
||||||
for each node. The resulting file should look something like:
|
for each node. The resulting file should look something like:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
[Unit]
|
[Unit]
|
||||||
Description={{service}}
|
Description={{service}}
|
||||||
Requires=network-online.target
|
Requires=network-online.target
|
||||||
@@ -132,13 +132,13 @@ WantedBy=multi-user.target
|
|||||||
|
|
||||||
Then, stop the nodes:
|
Then, stop the nodes:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
ansible-playbook -i inventory/digital_ocean.py -l sentrynet stop.yml
|
ansible-playbook -i inventory/digital_ocean.py -l sentrynet stop.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
Finally, we run the install role again:
|
Finally, we run the install role again:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
ansible-playbook -i inventory/digital_ocean.py -l sentrynet install.yml
|
ansible-playbook -i inventory/digital_ocean.py -l sentrynet install.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ increasing. Your testnet is now up and running :)
|
|||||||
|
|
||||||
Peek at the logs with the status role:
|
Peek at the logs with the status role:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
ansible-playbook -i inventory/digital_ocean.py -l sentrynet status.yml
|
ansible-playbook -i inventory/digital_ocean.py -l sentrynet status.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ service provider. You can set up your nodes to log there automatically.
|
|||||||
Create an account and get your API key from the notes on [this
|
Create an account and get your API key from the notes on [this
|
||||||
page](https://app.logz.io/#/dashboard/data-sources/Filebeat), then:
|
page](https://app.logz.io/#/dashboard/data-sources/Filebeat), then:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
yum install systemd-devel || echo "This will only work on RHEL-based systems."
|
yum install systemd-devel || echo "This will only work on RHEL-based systems."
|
||||||
apt-get install libsystemd-dev || echo "This will only work on Debian-based systems."
|
apt-get install libsystemd-dev || echo "This will only work on Debian-based systems."
|
||||||
|
|
||||||
@@ -172,6 +172,6 @@ ansible-playbook -i inventory/digital_ocean.py -l sentrynet logzio.yml -e LOGZIO
|
|||||||
|
|
||||||
To remove your droplets, run:
|
To remove your droplets, run:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
terraform destroy -var DO_API_TOKEN="$DO_API_TOKEN" -var SSH_KEY_FILE="$SSH_KEY_FILE"
|
terraform destroy -var DO_API_TOKEN="$DO_API_TOKEN" -var SSH_KEY_FILE="$SSH_KEY_FILE"
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ the parameters set with their default values. It will look something
|
|||||||
like the file below, however, double check by inspecting the
|
like the file below, however, double check by inspecting the
|
||||||
`config.toml` created with your version of `tendermint` installed:
|
`config.toml` created with your version of `tendermint` installed:
|
||||||
|
|
||||||
```
|
```toml
|
||||||
# This is a TOML config file.
|
# This is a TOML config file.
|
||||||
# For more information, see https://github.com/toml-lang/toml
|
# For more information, see https://github.com/toml-lang/toml
|
||||||
|
|
||||||
@@ -351,13 +351,13 @@ namespace = "tendermint"
|
|||||||
|
|
||||||
## Empty blocks VS no empty blocks
|
## Empty blocks VS no empty blocks
|
||||||
|
|
||||||
**create_empty_blocks = true**
|
### create_empty_blocks = true
|
||||||
|
|
||||||
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 = "10s"` should result in ~ 10 second blocks.
|
the delay between blocks by changing the `timeout_commit`. E.g. `timeout_commit = "10s"` should result in ~ 10 second blocks.
|
||||||
|
|
||||||
**create_empty_blocks = false**
|
### create_empty_blocks = false
|
||||||
|
|
||||||
In this setting, blocks are created when transactions received.
|
In this setting, blocks are created when transactions received.
|
||||||
|
|
||||||
@@ -386,7 +386,7 @@ 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).
|
||||||
|
|
||||||
```
|
```toml
|
||||||
[consensus]
|
[consensus]
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ order: 7
|
|||||||
We first create three connections (mempool, consensus and query) to the
|
We first create three connections (mempool, consensus and query) to the
|
||||||
application (running `kvstore` locally in this case).
|
application (running `kvstore` locally in this case).
|
||||||
|
|
||||||
```
|
```sh
|
||||||
I[10-04|13:54:27.364] Starting multiAppConn module=proxy impl=multiAppConn
|
I[10-04|13:54:27.364] Starting multiAppConn module=proxy impl=multiAppConn
|
||||||
I[10-04|13:54:27.366] Starting localClient module=abci-client connection=query impl=localClient
|
I[10-04|13:54:27.366] Starting localClient module=abci-client connection=query impl=localClient
|
||||||
I[10-04|13:54:27.366] Starting localClient module=abci-client connection=mempool impl=localClient
|
I[10-04|13:54:27.366] Starting localClient module=abci-client connection=mempool impl=localClient
|
||||||
@@ -18,7 +18,7 @@ I[10-04|13:54:27.367] Starting localClient module=abci-c
|
|||||||
|
|
||||||
Then Tendermint Core and the application perform a handshake.
|
Then Tendermint Core and the application perform a handshake.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
I[10-04|13:54:27.367] ABCI Handshake module=consensus appHeight=90 appHash=E0FBAFBF6FCED8B9786DDFEB1A0D4FA2501BADAD
|
I[10-04|13:54:27.367] ABCI Handshake module=consensus appHeight=90 appHash=E0FBAFBF6FCED8B9786DDFEB1A0D4FA2501BADAD
|
||||||
I[10-04|13:54:27.368] ABCI Replay Blocks module=consensus appHeight=90 storeHeight=90 stateHeight=90
|
I[10-04|13:54:27.368] ABCI Replay Blocks module=consensus appHeight=90 storeHeight=90 stateHeight=90
|
||||||
I[10-04|13:54:27.368] Completed ABCI Handshake - Tendermint and App are synced module=consensus appHeight=90 appHash=E0FBAFBF6FCED8B9786DDFEB1A0D4FA2501BADAD
|
I[10-04|13:54:27.368] Completed ABCI Handshake - Tendermint and App are synced module=consensus appHeight=90 appHash=E0FBAFBF6FCED8B9786DDFEB1A0D4FA2501BADAD
|
||||||
@@ -27,7 +27,7 @@ I[10-04|13:54:27.368] Completed ABCI Handshake - Tendermint and App are synced m
|
|||||||
After that, we start a few more things like the event switch, reactors,
|
After that, we start a few more things like the event switch, reactors,
|
||||||
and perform UPNP discover in order to detect the IP address.
|
and perform UPNP discover in order to detect the IP address.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
I[10-04|13:54:27.374] Starting EventSwitch module=types impl=EventSwitch
|
I[10-04|13:54:27.374] Starting EventSwitch module=types impl=EventSwitch
|
||||||
I[10-04|13:54:27.375] This node is a validator module=consensus
|
I[10-04|13:54:27.375] This node is a validator module=consensus
|
||||||
I[10-04|13:54:27.379] Starting Node module=main impl=Node
|
I[10-04|13:54:27.379] Starting Node module=main impl=Node
|
||||||
@@ -50,7 +50,7 @@ validator". It also could be just an observer (regular node).
|
|||||||
|
|
||||||
Next we replay all the messages from the WAL.
|
Next we replay all the messages from the WAL.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
I[10-04|13:54:30.390] Catchup by replaying consensus messages module=consensus height=91
|
I[10-04|13:54:30.390] Catchup by replaying consensus messages module=consensus height=91
|
||||||
I[10-04|13:54:30.390] Replay: New Step module=consensus height=91 round=0 step=RoundStepNewHeight
|
I[10-04|13:54:30.390] Replay: New Step module=consensus height=91 round=0 step=RoundStepNewHeight
|
||||||
I[10-04|13:54:30.390] Replay: Done module=consensus
|
I[10-04|13:54:30.390] Replay: Done module=consensus
|
||||||
@@ -58,7 +58,7 @@ I[10-04|13:54:30.390] Replay: Done module=consen
|
|||||||
|
|
||||||
"Started node" message signals that everything is ready for work.
|
"Started node" message signals that everything is ready for work.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
I[10-04|13:54:30.391] Starting RPC HTTP server on tcp socket 0.0.0.0:26657 module=rpc-server
|
I[10-04|13:54:30.391] Starting RPC HTTP server on tcp socket 0.0.0.0:26657 module=rpc-server
|
||||||
I[10-04|13:54:30.392] Started node module=main nodeInfo="NodeInfo{id: DF22D7C92C91082324A1312F092AA1DA197FA598DBBFB6526E, moniker: anonymous, network: test-chain-3MNw2N [remote , listen 10.0.2.15:26656], version: 0.11.0-10f361fc ([wire_version=0.6.2 p2p_version=0.5.0 consensus_version=v1/0.2.2 rpc_version=0.7.0/3 tx_index=on rpc_addr=tcp://0.0.0.0:26657])}"
|
I[10-04|13:54:30.392] Started node module=main nodeInfo="NodeInfo{id: DF22D7C92C91082324A1312F092AA1DA197FA598DBBFB6526E, moniker: anonymous, network: test-chain-3MNw2N [remote , listen 10.0.2.15:26656], version: 0.11.0-10f361fc ([wire_version=0.6.2 p2p_version=0.5.0 consensus_version=v1/0.2.2 rpc_version=0.7.0/3 tx_index=on rpc_addr=tcp://0.0.0.0:26657])}"
|
||||||
```
|
```
|
||||||
@@ -69,7 +69,7 @@ precommits and finally have a chance to commit a block. For details,
|
|||||||
please refer to [Byzantine Consensus
|
please refer to [Byzantine Consensus
|
||||||
Algorithm](https://github.com/tendermint/spec/blob/master/spec/consensus/consensus.md).
|
Algorithm](https://github.com/tendermint/spec/blob/master/spec/consensus/consensus.md).
|
||||||
|
|
||||||
```
|
```sh
|
||||||
I[10-04|13:54:30.393] enterNewRound(91/0). Current: 91/0/RoundStepNewHeight module=consensus
|
I[10-04|13:54:30.393] enterNewRound(91/0). Current: 91/0/RoundStepNewHeight module=consensus
|
||||||
I[10-04|13:54:30.393] enterPropose(91/0). Current: 91/0/RoundStepNewRound module=consensus
|
I[10-04|13:54:30.393] enterPropose(91/0). Current: 91/0/RoundStepNewRound module=consensus
|
||||||
I[10-04|13:54:30.393] enterPropose: Our turn to propose module=consensus proposer=125B0E3C5512F5C2B0E1109E31885C4511570C42 privValidator="PrivValidator{125B0E3C5512F5C2B0E1109E31885C4511570C42 LH:90, LR:0, LS:3}"
|
I[10-04|13:54:30.393] enterPropose: Our turn to propose module=consensus proposer=125B0E3C5512F5C2B0E1109E31885C4511570C42 privValidator="PrivValidator{125B0E3C5512F5C2B0E1109E31885C4511570C42 LH:90, LR:0, LS:3}"
|
||||||
|
|||||||
@@ -31,9 +31,9 @@ proofs](https://github.com/tendermint/spec/blob/953523c3cb99fdb8c8f7a2d21e3a9909
|
|||||||
name-registry without worrying about fork censorship attacks, without posting
|
name-registry without worrying about fork censorship attacks, without posting
|
||||||
a commit and waiting for confirmations. It's fast, secure, and free!
|
a commit and waiting for confirmations. It's fast, secure, and free!
|
||||||
|
|
||||||
## Where to obtain trusted height & hash?
|
## Where to obtain trusted height & hash
|
||||||
|
|
||||||
https://pkg.go.dev/github.com/tendermint/tendermint/light?tab=doc#TrustOptions
|
<https://pkg.go.dev/github.com/tendermint/tendermint/light?tab=doc#TrustOptions>
|
||||||
|
|
||||||
One way to obtain semi-trusted hash & height is to query multiple full nodes
|
One way to obtain semi-trusted hash & height is to query multiple full nodes
|
||||||
and compare their hashes:
|
and compare their hashes:
|
||||||
|
|||||||
@@ -12,31 +12,34 @@ arrived (via RPC or from other nodes).
|
|||||||
So the only way to specify the order is to send them to a single node.
|
So the only way to specify the order is to send them to a single node.
|
||||||
|
|
||||||
valA:
|
valA:
|
||||||
- tx1
|
|
||||||
- tx2
|
- tx1
|
||||||
- tx3
|
- tx2
|
||||||
|
- tx3
|
||||||
|
|
||||||
If the transactions are split up across different nodes, there's no way to
|
If the transactions are split up across different nodes, there's no way to
|
||||||
ensure they are processed in the expected order.
|
ensure they are processed in the expected order.
|
||||||
|
|
||||||
valA:
|
valA:
|
||||||
- tx1
|
|
||||||
- tx2
|
- tx1
|
||||||
|
- tx2
|
||||||
|
|
||||||
valB:
|
valB:
|
||||||
- tx3
|
|
||||||
|
- tx3
|
||||||
|
|
||||||
If valB is the proposer, the order might be:
|
If valB is the proposer, the order might be:
|
||||||
|
|
||||||
- tx3
|
- tx3
|
||||||
- tx1
|
- tx1
|
||||||
- tx2
|
- tx2
|
||||||
|
|
||||||
If valA is the proposer, the order might be:
|
If valA is the proposer, the order might be:
|
||||||
|
|
||||||
- tx1
|
- tx1
|
||||||
- tx2
|
- tx2
|
||||||
- tx3
|
- tx3
|
||||||
|
|
||||||
That said, if the transactions contain some internal value, like an
|
That said, if the transactions contain some internal value, like an
|
||||||
order/nonce/sequence number, the application can reject transactions that are
|
order/nonce/sequence number, the application can reject transactions that are
|
||||||
|
|||||||
@@ -54,6 +54,6 @@ The following metrics are available:
|
|||||||
|
|
||||||
Percentage of missing + byzantine validators:
|
Percentage of missing + byzantine validators:
|
||||||
|
|
||||||
```
|
```md
|
||||||
((consensus\_byzantine\_validators\_power + consensus\_missing\_validators\_power) / consensus\_validators\_power) * 100
|
((consensus\_byzantine\_validators\_power + consensus\_missing\_validators\_power) / consensus\_validators\_power) * 100
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ Tendermint also can report and serve Prometheus metrics. See
|
|||||||
information into an archive. See [Debugging](../tools/debugging.md) for more
|
information into an archive. See [Debugging](../tools/debugging.md) for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
## What happens when my app dies?
|
## What happens when my app dies
|
||||||
|
|
||||||
You are supposed to run Tendermint under a [process
|
You are supposed to run Tendermint under a [process
|
||||||
supervisor](https://en.wikipedia.org/wiki/Process_supervision) (like
|
supervisor](https://en.wikipedia.org/wiki/Process_supervision) (like
|
||||||
@@ -180,7 +180,7 @@ order of restart does not matter for it.
|
|||||||
## Signal handling
|
## Signal handling
|
||||||
|
|
||||||
We catch SIGINT and SIGTERM and try to clean up nicely. For other
|
We catch SIGINT and SIGTERM and try to clean up nicely. For other
|
||||||
signals we use the default behaviour in Go: [Default behavior of signals
|
signals we use the default behavior in Go: [Default behavior of signals
|
||||||
in Go
|
in Go
|
||||||
programs](https://golang.org/pkg/os/signal/#hdr-Default_behavior_of_signals_in_Go_programs).
|
programs](https://golang.org/pkg/os/signal/#hdr-Default_behavior_of_signals_in_Go_programs).
|
||||||
|
|
||||||
@@ -206,11 +206,11 @@ Other causes can be:
|
|||||||
- Operating system bugs
|
- Operating system bugs
|
||||||
- Admin error (e.g., directly modifying Tendermint data-directory contents)
|
- Admin error (e.g., directly modifying Tendermint data-directory contents)
|
||||||
|
|
||||||
(Source: https://wiki.postgresql.org/wiki/Corruption)
|
(Source: <https://wiki.postgresql.org/wiki/Corruption>)
|
||||||
|
|
||||||
### WAL Corruption
|
### WAL Corruption
|
||||||
|
|
||||||
If consensus WAL is corrupted at the lastest height and you are trying to start
|
If consensus WAL is corrupted at the latest height and you are trying to start
|
||||||
Tendermint, replay will fail with panic.
|
Tendermint, replay will fail with panic.
|
||||||
|
|
||||||
Recovering from data corruption can be hard and time-consuming. Here are two approaches you can take:
|
Recovering from data corruption can be hard and time-consuming. Here are two approaches you can take:
|
||||||
@@ -220,33 +220,33 @@ Recovering from data corruption can be hard and time-consuming. Here are two app
|
|||||||
|
|
||||||
1) Create a backup of the corrupted WAL file:
|
1) Create a backup of the corrupted WAL file:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
cp "$TMHOME/data/cs.wal/wal" > /tmp/corrupted_wal_backup
|
cp "$TMHOME/data/cs.wal/wal" > /tmp/corrupted_wal_backup
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Use `./scripts/wal2json` to create a human-readable version
|
2) Use `./scripts/wal2json` to create a human-readable version:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
./scripts/wal2json/wal2json "$TMHOME/data/cs.wal/wal" > /tmp/corrupted_wal
|
./scripts/wal2json/wal2json "$TMHOME/data/cs.wal/wal" > /tmp/corrupted_wal
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Search for a "CORRUPTED MESSAGE" line.
|
3) Search for a "CORRUPTED MESSAGE" line.
|
||||||
4. By looking at the previous message and the message after the corrupted one
|
4) By looking at the previous message and the message after the corrupted one
|
||||||
and looking at the logs, try to rebuild the message. If the consequent
|
and looking at the logs, try to rebuild the message. If the consequent
|
||||||
messages are marked as corrupted too (this may happen if length header
|
messages are marked as corrupted too (this may happen if length header
|
||||||
got corrupted or some writes did not make it to the WAL ~ truncation),
|
got corrupted or some writes did not make it to the WAL ~ truncation),
|
||||||
then remove all the lines starting from the corrupted one and restart
|
then remove all the lines starting from the corrupted one and restart
|
||||||
Tendermint.
|
Tendermint.
|
||||||
|
|
||||||
```
|
```sh
|
||||||
$EDITOR /tmp/corrupted_wal
|
$EDITOR /tmp/corrupted_wal
|
||||||
```
|
```
|
||||||
|
|
||||||
5. After editing, convert this file back into binary form by running:
|
5) After editing, convert this file back into binary form by running:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
./scripts/json2wal/json2wal /tmp/corrupted_wal $TMHOME/data/cs.wal/wal
|
./scripts/json2wal/json2wal /tmp/corrupted_wal $TMHOME/data/cs.wal/wal
|
||||||
```
|
```
|
||||||
|
|
||||||
## Hardware
|
## Hardware
|
||||||
|
|
||||||
@@ -313,7 +313,7 @@ If you are going to use Tendermint in a private domain and you have a
|
|||||||
private high-speed network among your peers, it makes sense to lower
|
private high-speed network among your peers, it makes sense to lower
|
||||||
flush throttle timeout and increase other params.
|
flush throttle timeout and increase other params.
|
||||||
|
|
||||||
```
|
```toml
|
||||||
[p2p]
|
[p2p]
|
||||||
|
|
||||||
send_rate=20000000 # 2MB/s
|
send_rate=20000000 # 2MB/s
|
||||||
@@ -380,7 +380,7 @@ The process file limits must also be increased, e.g. via `ulimit -n 8192`.
|
|||||||
|
|
||||||
...for N connections, such as 50k:
|
...for N connections, such as 50k:
|
||||||
|
|
||||||
```
|
```md
|
||||||
kern.maxfiles=10000+2*N # BSD
|
kern.maxfiles=10000+2*N # BSD
|
||||||
kern.maxfilesperproc=100+2*N # BSD
|
kern.maxfilesperproc=100+2*N # BSD
|
||||||
kern.ipc.maxsockets=10000+2*N # BSD
|
kern.ipc.maxsockets=10000+2*N # BSD
|
||||||
|
|||||||
@@ -48,43 +48,43 @@ definition](https://github.com/tendermint/tendermint/blob/master/types/genesis.g
|
|||||||
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` [spec](https://github.com/tendermint/spec/blob/master/spec/core/state.md#consensusparams)
|
- `consensus_params` [spec](https://github.com/tendermint/spec/blob/master/spec/core/state.md#consensusparams)
|
||||||
- `block`
|
- `block`
|
||||||
- `max_bytes`: Max block size, in bytes.
|
- `max_bytes`: Max block size, in bytes.
|
||||||
- `max_gas`: Max gas per block.
|
- `max_gas`: Max gas per block.
|
||||||
- `time_iota_ms`: Minimum time increment between consecutive blocks (in
|
- `time_iota_ms`: Minimum time increment between consecutive blocks (in
|
||||||
milliseconds). If the block header timestamp is ahead of the system clock,
|
milliseconds). If the block header timestamp is ahead of the system clock,
|
||||||
decrease this value.
|
decrease this value.
|
||||||
- `evidence`
|
- `evidence`
|
||||||
- `max_age_num_blocks`: Max age of evidence, in blocks. The basic formula
|
- `max_age_num_blocks`: Max age of evidence, in blocks. The basic formula
|
||||||
for calculating this is: MaxAgeDuration / {average block time}.
|
for calculating this is: MaxAgeDuration / {average block time}.
|
||||||
- `max_age_duration`: Max age of evidence, in time. It should correspond
|
- `max_age_duration`: Max age of evidence, in time. It should correspond
|
||||||
with an app's "unbonding period" or other similar mechanism for handling
|
with an app's "unbonding period" or other similar mechanism for handling
|
||||||
[Nothing-At-Stake
|
[Nothing-At-Stake
|
||||||
attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed).
|
attacks](https://github.com/ethereum/wiki/wiki/Proof-of-Stake-FAQ#what-is-the-nothing-at-stake-problem-and-how-can-it-be-fixed).
|
||||||
- `max_num`: This sets the maximum number of evidence that can be committed
|
- `max_num`: This sets the maximum number of evidence that can be committed
|
||||||
in a single block. and should fall comfortably under the max block
|
in a single block. and should fall comfortably under the max block
|
||||||
bytes when we consider the size of each evidence.
|
bytes when we consider the size of each evidence.
|
||||||
- `proof_trial_period`: Proof trial period dictates the time given for
|
- `proof_trial_period`: Proof trial period dictates the time given for
|
||||||
nodes accused of amnesia evidence, incorrectly voting twice in two
|
nodes accused of amnesia evidence, incorrectly voting twice in two
|
||||||
different rounds to respond with their respective proofs.
|
different rounds to respond with their respective proofs.
|
||||||
- `validator`
|
- `validator`
|
||||||
- `pub_key_types`: Public key types validators can use.
|
- `pub_key_types`: Public key types validators can use.
|
||||||
- `version`
|
- `version`
|
||||||
- `app_version`: ABCI application version.
|
- `app_version`: ABCI application version.
|
||||||
- `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.
|
||||||
- `pub_key`: The first element specifies the `pub_key` type. 1
|
- `pub_key`: The first element specifies the `pub_key` type. 1
|
||||||
== Ed25519. The second element are the pubkey bytes.
|
== Ed25519. The second element are the pubkey bytes.
|
||||||
- `power`: The validator's voting power.
|
- `power`: The validator's voting power.
|
||||||
- `name`: Name of the validator (optional).
|
- `name`: Name of the validator (optional).
|
||||||
- `app_hash`: The expected application hash (as returned by the
|
- `app_hash`: The expected application hash (as returned by the
|
||||||
`ResponseInfo` ABCI message) upon genesis. If the app's hash does
|
`ResponseInfo` ABCI message) upon genesis. If the app's hash does
|
||||||
not match, Tendermint will panic.
|
not match, Tendermint will panic.
|
||||||
- `app_state`: The application state (e.g. initial distribution
|
- `app_state`: The application state (e.g. initial distribution
|
||||||
of tokens).
|
of tokens).
|
||||||
|
|
||||||
**WARNING: ChainID must be unique to every blockchain. Reusing old chainID can cause issues**
|
> :warning: **ChainID must be unique to every blockchain. Reusing old chainID can cause issues**
|
||||||
|
|
||||||
#### Sample genesis.json
|
#### Sample genesis.json
|
||||||
|
|
||||||
@@ -179,7 +179,7 @@ curl http://localhost:26657/status | json_pp | grep latest_app_hash
|
|||||||
|
|
||||||
<!-- markdown-link-check-disable -->
|
<!-- markdown-link-check-disable -->
|
||||||
|
|
||||||
Visit http://localhost:26657 in your browser to see the list of other
|
Visit <http://localhost:26657> in your browser to see the list of other
|
||||||
endpoints. Some take no arguments (like `/status`), while others specify
|
endpoints. Some take no arguments (like `/status`), while others specify
|
||||||
the argument name and use `_` as a placeholder.
|
the argument name and use `_` as a placeholder.
|
||||||
|
|
||||||
|
|||||||
@@ -86,8 +86,8 @@ The sentry nodes should be able to talk to the entire network hence why `pex=tru
|
|||||||
|
|
||||||
More Information can be found at these links:
|
More Information can be found at these links:
|
||||||
|
|
||||||
- https://kb.certus.one/
|
- <https://kb.certus.one/>
|
||||||
- https://forum.cosmos.network/t/sentry-node-architecture-overview/454
|
- <https://forum.cosmos.network/t/sentry-node-architecture-overview/454>
|
||||||
|
|
||||||
### Validator keys
|
### Validator keys
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ Currently Tendermint uses [Ed25519](https://ed25519.cr.yp.to/) keys which are wi
|
|||||||
|
|
||||||
## Committing a Block
|
## Committing a Block
|
||||||
|
|
||||||
_+2/3 is short for "more than 2/3"_
|
> **+2/3 is short for "more than 2/3"**
|
||||||
|
|
||||||
A block is committed when +2/3 of the validator set sign [precommit
|
A block is committed when +2/3 of the validator set sign [precommit
|
||||||
votes](https://github.com/tendermint/spec/blob/953523c3cb99fdb8c8f7a2d21e3a99094279e9de/spec/blockchain/blockchain.md#vote) for that block at the same `round`.
|
votes](https://github.com/tendermint/spec/blob/953523c3cb99fdb8c8f7a2d21e3a99094279e9de/spec/blockchain/blockchain.md#vote) for that block at the same `round`.
|
||||||
|
|||||||
@@ -16,14 +16,14 @@ Tendermint has some tools that are associated with it for:
|
|||||||
|
|
||||||
## Benchmarking
|
## Benchmarking
|
||||||
|
|
||||||
- https://github.com/informalsystems/tm-load-test
|
- <https://github.com/informalsystems/tm-load-test>
|
||||||
|
|
||||||
`tm-load-test` is a distributed load testing tool (and framework) for load
|
`tm-load-test` is a distributed load testing tool (and framework) for load
|
||||||
testing Tendermint networks.
|
testing Tendermint networks.
|
||||||
|
|
||||||
## Testnets
|
## Testnets
|
||||||
|
|
||||||
- https://github.com/informalsystems/testnets
|
- <https://github.com/informalsystems/testnets>
|
||||||
|
|
||||||
This repository contains various different configurations of test networks for,
|
This repository contains various different configurations of test networks for,
|
||||||
and relating to, Tendermint.
|
and relating to, Tendermint.
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ tendermint debug kill <pid> </path/to/out.zip> --home=</path/to/app.d>
|
|||||||
will write debug info into a compressed archive. The archive will contain the
|
will write debug info into a compressed archive. The archive will contain the
|
||||||
following:
|
following:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
├── config.toml
|
├── config.toml
|
||||||
├── consensus_state.json
|
├── consensus_state.json
|
||||||
├── net_info.json
|
├── net_info.json
|
||||||
@@ -29,7 +29,7 @@ Under the hood, `debug kill` fetches info from `/status`, `/net_info`, and
|
|||||||
`/dump_consensus_state` HTTP endpoints, and kills the process with `-6`, which
|
`/dump_consensus_state` HTTP endpoints, and kills the process with `-6`, which
|
||||||
catches the go-routine dump.
|
catches the go-routine dump.
|
||||||
|
|
||||||
## tendermint debug dump
|
## Tendermint debug dump
|
||||||
|
|
||||||
Also, the `debug dump` sub-command allows you to dump debugging data into
|
Also, the `debug dump` sub-command allows you to dump debugging data into
|
||||||
compressed archives at a regular interval. These archives contain the goroutine
|
compressed archives at a regular interval. These archives contain the goroutine
|
||||||
@@ -44,7 +44,7 @@ will perform similarly to `kill` except it only polls the node and
|
|||||||
dumps debugging data every frequency seconds to a compressed archive under a
|
dumps debugging data every frequency seconds to a compressed archive under a
|
||||||
given destination directory. Each archive will contain:
|
given destination directory. Each archive will contain:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
├── consensus_state.json
|
├── consensus_state.json
|
||||||
├── goroutine.out
|
├── goroutine.out
|
||||||
├── heap.out
|
├── heap.out
|
||||||
|
|||||||
@@ -21,10 +21,12 @@ When executed, `tm-signer-harness`:
|
|||||||
error.
|
error.
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
Requires the same prerequisites as for building
|
Requires the same prerequisites as for building
|
||||||
[Tendermint](https://github.com/tendermint/tendermint).
|
[Tendermint](https://github.com/tendermint/tendermint).
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
From the `tools/tm-signer-harness` directory in your Tendermint source
|
From the `tools/tm-signer-harness` directory in your Tendermint source
|
||||||
repository, simply run:
|
repository, simply run:
|
||||||
|
|
||||||
@@ -36,6 +38,7 @@ make install
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Docker Image
|
## Docker Image
|
||||||
|
|
||||||
To build a Docker image containing the `tm-signer-harness`, also from the
|
To build a Docker image containing the `tm-signer-harness`, also from the
|
||||||
`tools/tm-signer-harness` directory of your Tendermint source repo, simply run:
|
`tools/tm-signer-harness` directory of your Tendermint source repo, simply run:
|
||||||
|
|
||||||
@@ -44,6 +47,7 @@ make docker-image
|
|||||||
```
|
```
|
||||||
|
|
||||||
## Running against KMS
|
## Running against KMS
|
||||||
|
|
||||||
As an example of how to use `tm-signer-harness`, the following instructions show
|
As an example of how to use `tm-signer-harness`, the following instructions show
|
||||||
you how to execute its tests against [KMS](https://github.com/tendermint/kms).
|
you how to execute its tests against [KMS](https://github.com/tendermint/kms).
|
||||||
For this example, we will make use of the **software signing module in KMS**, as
|
For this example, we will make use of the **software signing module in KMS**, as
|
||||||
@@ -51,6 +55,7 @@ the hardware signing module requires a physical
|
|||||||
[YubiHSM](https://www.yubico.com/products/yubihsm/) device.
|
[YubiHSM](https://www.yubico.com/products/yubihsm/) device.
|
||||||
|
|
||||||
### Step 1: Install KMS on your local machine
|
### Step 1: Install KMS on your local machine
|
||||||
|
|
||||||
See the [KMS repo](https://github.com/tendermint/kms) for details on how to set
|
See the [KMS repo](https://github.com/tendermint/kms) for details on how to set
|
||||||
KMS up on your local machine.
|
KMS up on your local machine.
|
||||||
|
|
||||||
@@ -62,6 +67,7 @@ cargo install tmkms
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Step 2: Make keys for KMS
|
### Step 2: Make keys for KMS
|
||||||
|
|
||||||
The KMS software signing module needs a key with which to sign messages. In our
|
The KMS software signing module needs a key with which to sign messages. In our
|
||||||
example, we will simply export a signing key from our local Tendermint instance.
|
example, we will simply export a signing key from our local Tendermint instance.
|
||||||
|
|
||||||
@@ -85,6 +91,7 @@ tmkms keygen secret_connection.key
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Configure and run KMS
|
### Step 3: Configure and run KMS
|
||||||
|
|
||||||
KMS needs some configuration to tell it to use the softer signing module as well
|
KMS needs some configuration to tell it to use the softer signing module as well
|
||||||
as the `signing.key` file we just generated. Save the following to a file called
|
as the `signing.key` file we just generated. Save the following to a file called
|
||||||
`tmkms.toml`:
|
`tmkms.toml`:
|
||||||
@@ -111,6 +118,7 @@ This will start KMS, which will repeatedly try to connect to
|
|||||||
`tcp://127.0.0.1:61219` until it is successful.
|
`tcp://127.0.0.1:61219` until it is successful.
|
||||||
|
|
||||||
### Step 4: Run tm-signer-harness
|
### Step 4: Run tm-signer-harness
|
||||||
|
|
||||||
Now we get to run the signer test harness:
|
Now we get to run the signer test harness:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -124,10 +132,12 @@ should now exit with a 0 exit code. If they are somehow not compatible, it
|
|||||||
should exit with a meaningful non-zero exit code (see the exit codes below).
|
should exit with a meaningful non-zero exit code (see the exit codes below).
|
||||||
|
|
||||||
### Step 5: Shut down KMS
|
### Step 5: Shut down KMS
|
||||||
|
|
||||||
Simply hit Ctrl+Break on your KMS instance (or use the `kill` command in Linux)
|
Simply hit Ctrl+Break on your KMS instance (or use the `kill` command in Linux)
|
||||||
to terminate it gracefully.
|
to terminate it gracefully.
|
||||||
|
|
||||||
## Exit Code Meanings
|
## Exit Code Meanings
|
||||||
|
|
||||||
The following list shows the various exit codes from `tm-signer-harness` and
|
The following list shows the various exit codes from `tm-signer-harness` and
|
||||||
their meanings:
|
their meanings:
|
||||||
|
|
||||||
|
|||||||
+37
-19
@@ -1,31 +1,32 @@
|
|||||||
|
|
||||||
|
|
||||||
# events
|
# events
|
||||||
|
|
||||||
`import "github.com/tendermint/tendermint/libs/events"`
|
`import "github.com/tendermint/tendermint/libs/events"`
|
||||||
|
|
||||||
* [Overview](#pkg-overview)
|
* [Overview](#pkg-overview)
|
||||||
* [Index](#pkg-index)
|
* [Index](#pkg-index)
|
||||||
|
|
||||||
## <a name="pkg-overview">Overview</a>
|
## Overview
|
||||||
|
|
||||||
Pub-Sub in go with event caching
|
Pub-Sub in go with event caching
|
||||||
|
|
||||||
|
## Index
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## <a name="pkg-index">Index</a>
|
|
||||||
* [type EventCache](#EventCache)
|
* [type EventCache](#EventCache)
|
||||||
* [func NewEventCache(evsw Fireable) *EventCache](#NewEventCache)
|
* [func NewEventCache(evsw Fireable) *EventCache](#NewEventCache)
|
||||||
* [func (evc *EventCache) FireEvent(event string, data EventData)](#EventCache.FireEvent)
|
* [func (evc *EventCache) FireEvent(event string, data EventData)](#EventCache.FireEvent)
|
||||||
* [func (evc *EventCache) Flush()](#EventCache.Flush)
|
* [func (evc *EventCache) Flush()](#EventCache.Flush)
|
||||||
* [type EventCallback](#EventCallback)
|
* [type EventCallback](#EventCallback)
|
||||||
* [type EventData](#EventData)
|
* [type EventData](#EventData)
|
||||||
* [type EventSwitch](#EventSwitch)
|
* [type EventSwitch](#EventSwitch)
|
||||||
* [func NewEventSwitch() EventSwitch](#NewEventSwitch)
|
* [func NewEventSwitch() EventSwitch](#NewEventSwitch)
|
||||||
* [type Eventable](#Eventable)
|
* [type Eventable](#Eventable)
|
||||||
* [type Fireable](#Fireable)
|
* [type Fireable](#Fireable)
|
||||||
|
|
||||||
|
|
||||||
#### <a name="pkg-files">Package files</a>
|
### Package files
|
||||||
|
|
||||||
[event_cache.go](/src/github.com/tendermint/tendermint/libs/events/event_cache.go) [events.go](/src/github.com/tendermint/tendermint/libs/events/events.go)
|
[event_cache.go](/src/github.com/tendermint/tendermint/libs/events/event_cache.go) [events.go](/src/github.com/tendermint/tendermint/libs/events/events.go)
|
||||||
|
|
||||||
|
|
||||||
@@ -33,12 +34,14 @@ Pub-Sub in go with event caching
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## <a name="EventCache">type</a> [EventCache](/src/target/event_cache.go?s=116:179#L5)
|
## Type [EventCache](/src/target/event_cache.go?s=116:179#L5)
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
type EventCache struct {
|
type EventCache struct {
|
||||||
// contains filtered or unexported fields
|
// contains filtered or unexported fields
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
An EventCache buffers events for a Fireable
|
An EventCache buffers events for a Fireable
|
||||||
All events are cached. Filtering happens on Flush
|
All events are cached. Filtering happens on Flush
|
||||||
|
|
||||||
@@ -48,36 +51,43 @@ All events are cached. Filtering happens on Flush
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <a name="NewEventCache">func</a> [NewEventCache](/src/target/event_cache.go?s=239:284#L11)
|
### func [NewEventCache](/src/target/event_cache.go?s=239:284#L11)
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
func NewEventCache(evsw Fireable) *EventCache
|
func NewEventCache(evsw Fireable) *EventCache
|
||||||
```
|
```
|
||||||
|
|
||||||
Create a new EventCache with an EventSwitch as backend
|
Create a new EventCache with an EventSwitch as backend
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <a name="EventCache.FireEvent">func</a> (\*EventCache) [FireEvent](/src/target/event_cache.go?s=449:511#L24)
|
### func (\*EventCache) [FireEvent](/src/target/event_cache.go?s=449:511#L24)
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
func (evc *EventCache) FireEvent(event string, data EventData)
|
func (evc *EventCache) FireEvent(event string, data EventData)
|
||||||
```
|
```
|
||||||
|
|
||||||
Cache an event to be fired upon finality.
|
Cache an event to be fired upon finality.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <a name="EventCache.Flush">func</a> (\*EventCache) [Flush](/src/target/event_cache.go?s=735:765#L31)
|
### func (\*EventCache) [Flush](/src/target/event_cache.go?s=735:765#L31)
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
func (evc *EventCache) Flush()
|
func (evc *EventCache) Flush()
|
||||||
```
|
```
|
||||||
|
|
||||||
Fire events by running evsw.FireEvent on all cached events. Blocks.
|
Fire events by running evsw.FireEvent on all cached events. Blocks.
|
||||||
Clears cached events
|
Clears cached events
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## <a name="EventCallback">type</a> [EventCallback](/src/target/events.go?s=4201:4240#L185)
|
## Type [EventCallback](/src/target/events.go?s=4201:4240#L185)
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
type EventCallback func(data EventData)
|
type EventCallback func(data EventData)
|
||||||
```
|
```
|
||||||
@@ -90,11 +100,13 @@ type EventCallback func(data EventData)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## <a name="EventData">type</a> [EventData](/src/target/events.go?s=243:294#L14)
|
## Type [EventData](/src/target/events.go?s=243:294#L14)
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
type EventData interface {
|
type EventData interface {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Generic event data can be typed and registered with tendermint/go-amino
|
Generic event data can be typed and registered with tendermint/go-amino
|
||||||
via concrete implementation of this interface
|
via concrete implementation of this interface
|
||||||
|
|
||||||
@@ -107,7 +119,8 @@ via concrete implementation of this interface
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## <a name="EventSwitch">type</a> [EventSwitch](/src/target/events.go?s=560:771#L29)
|
## Type [EventSwitch](/src/target/events.go?s=560:771#L29)
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
type EventSwitch interface {
|
type EventSwitch interface {
|
||||||
service.Service
|
service.Service
|
||||||
@@ -124,7 +137,8 @@ type EventSwitch interface {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### <a name="NewEventSwitch">func</a> [NewEventSwitch](/src/target/events.go?s=917:950#L46)
|
### func [NewEventSwitch](/src/target/events.go?s=917:950#L46)
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
func NewEventSwitch() EventSwitch
|
func NewEventSwitch() EventSwitch
|
||||||
```
|
```
|
||||||
@@ -132,12 +146,14 @@ func NewEventSwitch() EventSwitch
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## <a name="Eventable">type</a> [Eventable](/src/target/events.go?s=378:440#L20)
|
## Type [Eventable](/src/target/events.go?s=378:440#L20)
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
type Eventable interface {
|
type Eventable interface {
|
||||||
SetEventSwitch(evsw EventSwitch)
|
SetEventSwitch(evsw EventSwitch)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
reactors and other modules should export
|
reactors and other modules should export
|
||||||
this interface to become eventable
|
this interface to become eventable
|
||||||
|
|
||||||
@@ -150,12 +166,14 @@ this interface to become eventable
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## <a name="Fireable">type</a> [Fireable](/src/target/events.go?s=490:558#L25)
|
## Type [Fireable](/src/target/events.go?s=490:558#L25)
|
||||||
|
|
||||||
``` go
|
``` go
|
||||||
type Fireable interface {
|
type Fireable interface {
|
||||||
FireEvent(event string, data EventData)
|
FireEvent(event string, data EventData)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
an event switch or cache implements fireable
|
an event switch or cache implements fireable
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,4 +7,4 @@ go get github.com/mxk/go-flowrate/flowrate
|
|||||||
|
|
||||||
The documentation is available at:
|
The documentation is available at:
|
||||||
|
|
||||||
http://godoc.org/github.com/mxk/go-flowrate/flowrate
|
<http://godoc.org/github.com/mxk/go-flowrate/flowrate>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
## Swagger docs
|
# Swagger docs
|
||||||
|
|
||||||
Do not forget to update ../swagger/swagger.yaml if making changes to any
|
Do not forget to update ../swagger/swagger.yaml if making changes to any
|
||||||
endpoint.
|
endpoint.
|
||||||
|
|||||||
@@ -62,4 +62,3 @@ By default, the command will upload the file `/tmp/workspace/tendermint_${CIRCLE
|
|||||||
|
|
||||||
## github-publish.py
|
## github-publish.py
|
||||||
Publish a GitHub release. The release is defined by the mandatory `--id` (release ID) input parameter.
|
Publish a GitHub release. The release is defined by the mandatory `--id` (release ID) input parameter.
|
||||||
|
|
||||||
|
|||||||
+9
-9
@@ -7,15 +7,15 @@ Running the integrations test will build a docker container with local version o
|
|||||||
and run the following tests in docker containers:
|
and run the following tests in docker containers:
|
||||||
|
|
||||||
- go tests, with --race
|
- go tests, with --race
|
||||||
- includes test coverage
|
- includes test coverage
|
||||||
- app tests
|
- app tests
|
||||||
- kvstore app over socket
|
- kvstore app over socket
|
||||||
- counter app over socket
|
- counter app over socket
|
||||||
- counter app over grpc
|
- counter app over grpc
|
||||||
- persistence tests
|
- persistence tests
|
||||||
- crash tendermint at each of many predefined points, restart, and ensure it syncs properly with the app
|
- crash tendermint at each of many predefined points, restart, and ensure it syncs properly with the app
|
||||||
- p2p tests
|
- p2p tests
|
||||||
- start a local kvstore app testnet on a docker network (requires docker version 1.10+)
|
- start a local kvstore app testnet on a docker network (requires docker version 1.10+)
|
||||||
- send a tx on each node and ensure the state root is updated on all of them
|
- send a tx on each node and ensure the state root is updated on all of them
|
||||||
- crash and restart nodes one at a time and ensure they can sync back up (via fastsync)
|
- crash and restart nodes one at a time and ensure they can sync back up (via fastsync)
|
||||||
- crash and restart all nodes at once and ensure they can sync back up
|
- crash and restart all nodes at once and ensure they can sync back up
|
||||||
|
|||||||
+6
-6
@@ -8,13 +8,13 @@ For consistency, we assume all commands are run from the Tendermint repository r
|
|||||||
|
|
||||||
First, build the docker image:
|
First, build the docker image:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
docker build -t tendermint_tester -f ./test/docker/Dockerfile .
|
docker build -t tendermint_tester -f ./test/docker/Dockerfile .
|
||||||
```
|
```
|
||||||
|
|
||||||
Now create the docker network:
|
Now create the docker network:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
docker network create --driver bridge --subnet 172.57.0.0/16 my_testnet
|
docker network create --driver bridge --subnet 172.57.0.0/16 my_testnet
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -23,14 +23,14 @@ Peers on the network can have any IP address in this range.
|
|||||||
For our four node network, let's pick `172.57.0.101 - 172.57.0.104`.
|
For our four node network, let's pick `172.57.0.101 - 172.57.0.104`.
|
||||||
Since we use Tendermint's default listening port of 26656, our list of seed nodes will look like:
|
Since we use Tendermint's default listening port of 26656, our list of seed nodes will look like:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
172.57.0.101:26656,172.57.0.102:26656,172.57.0.103:26656,172.57.0.104:26656
|
172.57.0.101:26656,172.57.0.102:26656,172.57.0.103:26656,172.57.0.104:26656
|
||||||
```
|
```
|
||||||
|
|
||||||
Now we can start up the peers. We already have config files setup in `test/p2p/data/`.
|
Now we can start up the peers. We already have config files setup in `test/p2p/data/`.
|
||||||
Let's use a for-loop to start our peers:
|
Let's use a for-loop to start our peers:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
for i in $(seq 1 4); do
|
for i in $(seq 1 4); do
|
||||||
docker run -d \
|
docker run -d \
|
||||||
--net=my_testnet\
|
--net=my_testnet\
|
||||||
@@ -46,7 +46,7 @@ If you now run `docker ps`, you'll see your containers!
|
|||||||
|
|
||||||
We can confirm they are making blocks by checking the `/status` message using `curl` and `jq` to pretty print the output json:
|
We can confirm they are making blocks by checking the `/status` message using `curl` and `jq` to pretty print the output json:
|
||||||
|
|
||||||
```
|
```sh
|
||||||
curl 172.57.0.101:26657/status | jq .
|
curl 172.57.0.101:26657/status | jq .
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -63,4 +63,4 @@ IPv6 tests require a Docker daemon with IPv6 enabled, by setting the following i
|
|||||||
|
|
||||||
In Docker for Mac, this is done via Preferences → Docker Engine.
|
In Docker for Mac, this is done via Preferences → Docker Engine.
|
||||||
|
|
||||||
Once set, run IPv6 tests via `make test_p2p_ipv6`.
|
Once set, run IPv6 tests via `make test_p2p_ipv6`.
|
||||||
|
|||||||
Reference in New Issue
Block a user