Zach Ramsay 7 years ago
parent
commit
350d584af8
6 changed files with 47 additions and 74 deletions
  1. +19
    -29
      docs/getting-started/#02-first-app.md
  2. +1
    -1
      docs/getting-started/#04-next-steps.md
  3. +2
    -3
      docs/guides/abci-cli.md
  4. +8
    -14
      docs/guides/app-architecture.md
  5. +3
    -5
      docs/guides/app-development.md
  6. +14
    -22
      docs/guides/using-tendermint.md

+ 19
- 29
docs/getting-started/#02-first-app.md View File

@ -8,6 +8,8 @@ and just forwards transactions to the application when they need to be validated
In this guide, we show you some examples of how to run an application using Tendermint.
**Note:** It is highly recommended to read the [Using Tendermint Guide](/docs/guides/using-tendermint) prior to working through this tutorial.
## Install
First, make sure you have [installed Tendermint](/download).
@ -21,7 +23,7 @@ Then run
go get -u github.com/tendermint/abci/cmd/...
```
If there is an error, download the `glide` tool to pin the dependencies:
If there is an error, install and run the `glide` tool to pin the dependencies:
```
go get github.com/Masterminds/glide
@ -30,27 +32,16 @@ glide install
go install ./cmd/...
```
Now you should have two apps installed:
Now you should have the `abci-cli` plus two apps installed:
```
dummy --help
counter --help
```
Both of these applications are in Go.
But we also want to run an application in another language -
in this case, we'll run a Javascript version of the `counter`.
To run it, you'll need to [install node](https://nodejs.org/en/download/).
These binaries are installed on `$GOPATH/bin` and all come from within the `./cmd/...` directory of the abci repository.
You'll also need to fetch the relevant repository, from https://github.com/tendermint/js-abci.
Since I keep all my code under the `$GOPATH`, I just `go get github.com/tendermint/js-abci &> /dev/null`.
Then `cd` into the `example` directory within that repository and run `npm install`.
For instance, if you used `go get`,
```
cd $GOPATH/src/github.com/tendermint/js-abci/example
npm install
```
Both of these example applications are in Go. See below for an application written in Javascript.
Now, let's run some apps!
@ -61,7 +52,7 @@ If the transaction contains an `=`, eg. `key=value`,
then the `value` is stored under the `key` in the Merkle tree.
Otherwise, the full transaction bytes are stored as the key and the value.
Let's start a dummy application.
Let's start a dummy application.
```
dummy
@ -159,14 +150,14 @@ before they are stored in memory or gossipped to other peers.
In this instance of the counter app, with `serial=on`, `CheckTx` only allows transactions whose integer is greater than the last committed one.
Let's kill the previous instance of tendermint and the dummy application, and start the counter app.
Let's kill the previous instance of `tendermint` and the `dummy` application, and start the counter app.
We can enable `serial=on` with a flag:
```
counter --serial
```
In another window, reset and start Tendermint:
In another window, reset then start Tendermint:
```
tendermint unsafe_reset_all
@ -180,7 +171,7 @@ Since we have set `serial=on`, the first transaction must be the number `0`:
curl localhost:46657/broadcast_tx_commit?tx=0x00
```
Note the empty, hence successful, response.
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:
```
@ -200,19 +191,19 @@ see [the guide on using Tendermint](/docs/guides/using-tendermint).
## Example in Another Language - CounterJS
The ultimate flexibility in Tendermint comes from being able to easily write the application in any language.
While we already used the implementation written in Go,
let's now try the Counter application written in Javascript!
We also want to run applications in another language - in this case, we'll run a Javascript version of the `counter`.
To run it, you'll need to [install node](https://nodejs.org/en/download/).
Kill the previous `counter` and `tendermint` processes.
Change directory to the location of the `github.com/tendermint/js-abci`.
If you fetched the repository with `go get`, it would be
You'll also need to fetch the relevant repository, from https://github.com/tendermint/js-abci then install it.
As go devs, we keep all our code under the `$GOPATH`, so run:
```
cd $GOPATH/src/github.com/tendermint/js-abci
go get github.com/tendermint/js-abci &> /dev/null
cd $GOPATH/src/github.com/tendermint/js-abci/example
npm install
```
Now run the app:
Kill the previous `counter` and `tendermint` processes. Now run the app:
```
node example/app.js
@ -226,7 +217,7 @@ tendermint node
```
Once again, you should see blocks streaming by - but now, our application is written in javascript!
Try sending some transasctions, like before - the results should be the same:
Try sending some transactions, and like before - the results should be the same:
```
curl localhost:46657/broadcast_tx_commit?tx=0x00 # ok
@ -245,7 +236,6 @@ Unlike the `dummy` and `counter`, which are strictly for example purposes,
The default `basecoin` application is a multi-asset cryptocurrency that supports inter-blockchain communication.
For more details on how basecoin works and how to use it, see our [basecoin guide](https://github.com/tendermint/basecoin/blob/develop/docs/guide/basecoin-basics.md)
## Next Step
In this tutorial you learned how to run applications using Tendermint on a single node.


+ 1
- 1
docs/getting-started/#04-next-steps.md View File

@ -6,7 +6,7 @@ and on a remote Tendermint cluster.
To learn more about building ABCI applications and integrating with Tendermint, see the [Developer Guides](/docs/guides/app-development).
To learn more about running the Tendermint software, see the [Using Tendermint Guide](/docs/guides/using-tendermint).
To learn more about Tendermint's various pieces, checkout the [Documentation](/docs).
To learn more about Tendermint's various pieces, check out the [Documentation](/docs).
For a deeper dive, see [this thesis](https://atrium.lib.uoguelph.ca/xmlui/handle/10214/9769).
There is also the [original whitepaper](/static/docs/tendermint.pdf), though it is now quite outdated.


+ 2
- 3
docs/guides/abci-cli.md View File

@ -49,7 +49,7 @@ The `abci-cli` tool lets us send ABCI messages to our application, to help build
The most important messages are `deliver_tx`, `check_tx`, and `commit`,
but there are others for convenience, configuration, and information purposes.
Let's start a dummy application. The dummy just stores transactions in a merkle tree:
Let's start a dummy application, which was installed at the same time as `abci-cli` above. The dummy just stores transactions in a merkle tree:
```
dummy
@ -190,7 +190,7 @@ In another window, start the `abci-cli console`:
```
This is a very simple application, but between `counter` and `dummy`, its easy to see how you can build out arbitrary application states on top of the ABCI.
In the near future, `erisdb` of Eris Industries will also run atop ABCI, bringing with it Ethereum-like accounts, the Ethereum virtual-machine, Eris's permissioning scheme, and native contracts extensions.
[Hyperledger's Burrow](https://github.com/hyperledger/burrow) also runs atop ABCI, bringing with it Ethereum-like accounts, the Ethereum virtual-machine, Monax's permissioning scheme, and native contracts extensions.
But the ultimate flexibility comes from being able to write the application easily in any language.
@ -217,4 +217,3 @@ each with its own pattern of messages.
For more information, see the [application developers guide](/docs/guides/app-development).
For examples of running an ABCI app with Tendermint, see the [introductory guide](/docs/getting-started/first-abci-app).

+ 8
- 14
docs/guides/app-architecture.md View File

@ -2,13 +2,13 @@
## Overview
A blockchain application is more than the consensus engine and the transaction logic (eg. smart contracts, business logic) as implemented in the ABCI app. There are also (mobile, web, desktop) clients that will need to connect and make use of the app. We will assume for now that you have a well designed transactions and database model, but maybe this will be the topic of another article. This article is more interested in various ways of setting up the "plumbing" and connecting these pieces, and demonstrating some evolving best practices.
A blockchain application is more than the consensus engine and the transaction logic (eg. smart contracts, business logic) as implemented in the ABCI app. There are also (mobile, web, desktop) clients that will need to connect and make use of the app. We will assume for now that you have a well designed transactions and database model, but maybe this will be the topic of another article. This article is more interested in various ways of setting up the "plumbing" and connecting these pieces, and demonstrating some evolving best practices.
## Security
A very important aspect when constructing a blockchain is security. The consensus model can be DoSed (no consensus possible) by corrupting 1/3 of the validators and exploited (writing arbitrary blocks) by corrupting 2/3 of the validators. So, while the security is not that of the "weakest link", you should take care that the "average link" is sufficiently hardened.
A very important aspect when constructing a blockchain is security. The consensus model can be DoSed (no consensus possible) by corrupting 1/3 of the validators and exploited (writing arbitrary blocks) by corrupting 2/3 of the validators. So, while the security is not that of the "weakest link", you should take care that the "average link" is sufficiently hardened.
One big attack surface on the validators is the communication between the ABCI app and the tendermint core. This should be highly protected. Ideally, the app and the core are running on the same machine, so no external agent can target the communication channel. You can use unix sockets (with permissions preventing access from other users), or even compile the two apps into one binary if the ABCI app is also writen in go (@ebuchman says this is possible). If you are unable to do that due to language support, then the ABCI app should bind a TCP connection to localhost (127.0.0.1), which is less efficient and secure, but still not reachable from outside. If you must run the ABCI app and tendermint core on separate machines, make sure you have a secure communication channel (ssh tunnel?)
One big attack surface on the validators is the communication between the ABCI app and the tendermint core. This should be highly protected. Ideally, the app and the core are running on the same machine, so no external agent can target the communication channel. You can use unix sockets (with permissions preventing access from other users), or even compile the two apps into one binary if the ABCI app is also writen in go. If you are unable to do that due to language support, then the ABCI app should bind a TCP connection to localhost (127.0.0.1), which is less efficient and secure, but still not reachable from outside. If you must run the ABCI app and tendermint core on separate machines, make sure you have a secure communication channel (ssh tunnel?)
Now assuming, you have linked together your app and the core securely, you must also make sure no one can get on the machine it is hosted on. At this point it is basic network security. Run on a secure operating system (SELinux?). Limit who has access to the machine (user accounts, but also where the physical machine is hosted). Turn off all services except for ssh, which should only be accessible by some well-guarded public/private key pairs (no password). And maybe even firewall off access to the ports used by the validators, so only known validators can connect.
@ -18,7 +18,7 @@ There was also a suggestion on slack from @jhon about compiling everything toget
### Tendermint Core RPC
I believe this was the original design from @ebuchman. The concept is that the ABCI app is completely hidden from the outside world and only communicated through a tested and secured [interface exposed by the tendermint core](/docs/specs/rpc). This interface exposes a lot of data on the block header and consensus process, which is quite useful for externally verifying the system. It also includes 3(!) methods to broadcast a transaction (propose it for the blockchain, and possibly await a response). And one method to query app-specific data from the ABCI application.
The concept is that the ABCI app is completely hidden from the outside world and only communicated through a tested and secured [interface exposed by the tendermint core](/docs/specs/rpc). This interface exposes a lot of data on the block header and consensus process, which is quite useful for externally verifying the system. It also includes 3(!) methods to broadcast a transaction (propose it for the blockchain, and possibly await a response). And one method to query app-specific data from the ABCI application.
Pros:
* Server code already written
@ -26,11 +26,11 @@ Pros:
* Basic read/write functionality is supported
Cons:
* Limited interface to app. All queries must be serialized into []byte (less expressive than JSON over HTTP) and there is no way to push data from ABCI app to the client (eg. notify me if account X receives a transaction)
* Limited interface to app. All queries must be serialized into []byte (less expressive than JSON over HTTP) and there is no way to push data from ABCI app to the client (eg. notify me if account X receives a transaction)
### Custom ABCI server
This was proposed by @wolfposd on slack and demonstrated by [TMChat](https://github.com/wolfposd/TMChat), a sample app. The concept is to write a custom server for your app (with typical REST API/websockets/etc for easy use by a mobile app). This custom server is in the same binary as the ABCI app and data store, so can easily react to complex events there that involve understanding the data format (send a message if my balance drops below 500). All "writes" sent to this server are proxied via websocket/JSON-RPC to tendermint core. When they come back as deliver_tx over ABCI, they will be written to the data store. For "reads", we can do any queries we wish that are supported by our architecture, using any web technology that is useful. The general architecture is shown in the following diagram:
This was proposed by @wolfposd on slack and demonstrated by [TMChat](https://github.com/wolfposd/TMChat), a sample app. The concept is to write a custom server for your app (with typical REST API/websockets/etc for easy use by a mobile app). This custom server is in the same binary as the ABCI app and data store, so can easily react to complex events there that involve understanding the data format (send a message if my balance drops below 500). All "writes" sent to this server are proxied via websocket/JSON-RPC to tendermint core. When they come back as deliver_tx over ABCI, they will be written to the data store. For "reads", we can do any queries we wish that are supported by our architecture, using any web technology that is useful. The general architecture is shown in the following diagram:
<img alt="Application Architecture" src="../assets/images/tm-app-example.png">
@ -46,7 +46,7 @@ Cons:
### Hybrid solutions
Likely the least secure but most versatile. The client can access both the tendermint node for all blockchain info, as well as a custom app server, for complex queries and pub-sub on the abci app.
Likely the least secure but most versatile. The client can access both the tendermint node for all blockchain info, as well as a custom app server, for complex queries and pub-sub on the abci app.
Pros:
* All from both above solutions
@ -57,14 +57,8 @@ Cons:
## Scalability
Read replica using non-validating nodes? They could forward transactions to the validators (fewer connections, more security), and locally allow all queries in any of the above configurations. Thus, while transaction-processing speed is limited by the speed of the abci app and the number of validators, one should be able to scale our read performance to quite an extent (until the replication process drains too many resources from the validator nodes).
Read replica using non-validating nodes? They could forward transactions to the validators (fewer connections, more security), and locally allow all queries in any of the above configurations. Thus, while transaction-processing speed is limited by the speed of the abci app and the number of validators, one should be able to scale our read performance to quite an extent (until the replication process drains too many resources from the validator nodes).
## Example Code
* [TMChat](https://github.com/wolfposd/TMChat)
TODO: more!
## Contributions
Many thanks to Ethan Frey for writing this page.

+ 3
- 5
docs/guides/app-development.md View File

@ -19,9 +19,9 @@ The ABCI design has a few distinct components:
- blockchain protocol
- abci is connection oriented
- Tendermint Core maintains three connections:
- [mempool connection](#mempool-connection): for checking if transactions should be relayed before they are committed. only uses `CheckTx`
- [consensus connection](#consensus-connection): for executing transactions that have been committed. Message sequence is, for every block, `BeginBlock, [DeliverTx, ...], EndBlock, Commit`
- [query connection](#query-connection): for querying the application state. only uses Query and Info
- [mempool connection](#mempool-connection): for checking if transactions should be relayed before they are committed; only uses `CheckTx`
- [consensus connection](#consensus-connection): for executing transactions that have been committed. Message sequence is - for every block - `BeginBlock, [DeliverTx, ...], EndBlock, Commit`
- [query connection](#query-connection): for querying the application state; only uses Query and Info
<img src="../assets/images/abci.png">
@ -153,5 +153,3 @@ Using this information, Tendermint will determine what needs to be replayed, if
to ensure both Tendermint and the app are synced to the latest block height.
If the app returns a LastBlockHeight of 0, Tendermint will just replay all blocks.
Note this functionality is only available in v0.8.0 and up.

+ 14
- 22
docs/guides/using-tendermint.md View File

@ -21,8 +21,7 @@ tendermint init
This will create a new private key (`priv_validator.json`), and a genesis file (`genesis.json`) containing the associated public key.
This is all that's necessary to run a local testnet with one validator.
For more elaborate initialization, see our quick and dirty deployment tool, [mintnet](https://github.com/tendermint/mintnet).
For more elaborate initialization, see our [testnet deployment tool](https://github.com/tendermint/tools/tree/master/mintnet-kubernetes).
## Run
@ -42,7 +41,7 @@ tendermint node --proxy_app=dummy
After a few seconds you should see blocks start streaming in.
Note that blocks are produced regularly, even if there are no transactions.
Hopefully we will change this.
This changes [with this pull request](https://github.com/tendermint/tendermint/pull/584).
Tendermint supports in-process versions of the dummy, counter, and nil apps that ship as examples in the [ABCI repository](https://github.com/tendermint/abci).
It's easy to compile your own app in-process with tendermint if it's written in Go.
@ -54,7 +53,6 @@ and use the `--proxy_app` flag to specify the address of the socket it is listen
tendermint node --proxy_app=/var/run/abci.sock
```
## Transactions
To send a transaction, use `curl` to make requests to the Tendermint RPC server:
@ -63,7 +61,7 @@ To send a transaction, use `curl` to make requests to the Tendermint RPC server:
curl http://localhost:46657/broadcast_tx_commit?tx=\"abcd\"
```
For handling responses, we recommend you [install the `jsonpp` tool](http://jmhodges.github.io/jsonpp/) to pretty print the JSON
For handling responses, we recommend you [install the jsonpp tool](http://jmhodges.github.io/jsonpp/) to pretty print the JSON.
We can see the chain's status at the `/status` end-point:
@ -82,7 +80,7 @@ Some take no arguments (like `/status`), while others specify the argument name
## Reset
WARNING: UNSAFE. Only do this in development and only if you can afford to lose all blockchain data!
**WARNING: UNSAFE** Only do this in development and only if you can afford to lose all blockchain data!
To reset a blockchain, stop the node, remove the `~/.tendermint/data` directory and run
@ -93,7 +91,7 @@ tendermint unsafe_reset_priv_validator
This final step is necessary to reset the `priv_validator.json`,
which otherwise prevents you from making conflicting votes in the consensus
(something that could get you in trouble if you do it on a real blockchain).
If you don't reset the priv_validator, your fresh new blockchain will not make any blocks.
If you don't reset the `priv_validator.json`, your fresh new blockchain will not make any blocks.
## Configuration
@ -129,13 +127,9 @@ but will return right away if the transaction does not pass `CheckTx`.
The return value for `broadcast_tx_commit` includes two fields, `check_tx` and `deliver_tx`, pertaining to the result of running
the transaction through those ABCI messages.
The benefit of using `broadcast_tx_commit` is that the request returns after the transaction is committed (ie. included in a block),
but that can take on the order of a second.
For a quick result, use `broadcast_tx_sync`,
The benefit of using `broadcast_tx_commit` is that the request returns after the transaction is committed (ie. included in a block), but that can take on the order of a second. For a quick result, use `broadcast_tx_sync`,
but the transaction will not be committed until later, and by that point its effect on the state may change.
We are working to improve the API and add more ways to track the status of a transaction and get its results.
## Tendermint Networks
When `tendermint init` is run, both a `genesis.json` and `priv_validator.json` are created in `~/.tendermint`.
@ -180,15 +174,15 @@ And the `priv_validator.json`:
}
```
The `priv_validator.json` actually contains a private key, and should be kept absolutely secret,
but for now we work with the plain text.
Note the `last_` fields, which prevent us from signing conflicting messages.
The `priv_validator.json` actually contains a private key, and should thus be kept absolutely secret;
for now we work with the plain text.
Note the `last_` fields, which are used to prevent us from signing conflicting messages.
Note also that the `pub_key` (the public key) in the `priv_validator.json` is also present in the `genesis.json`.
The genesis file contains the list of public keys which may participate in the consensus,
and their corresponding voting power.
More than 2/3 of the voting power must be active (ie. the corresponding private keys must be producing signatures)
Greater than 2/3 of the voting power must be active (ie. the corresponding private keys must be producing signatures)
for the consensus to make progress.
In our case, the genesis file contains the public key of our `priv_validator.json`,
so a tendermint node started with the default root directory will be able to make new blocks,
@ -217,10 +211,9 @@ curl --data-urlencode "seeds=[\"1.2.3.4:46656\",\"5.6.7.8:46656\"]" localhost:46
```
Additionally, the peer-exchange protocol can be enabled using the `--pex` flag,
though this feature is still under development (beware of dragons!).
though this feature is [still under development](https://github.com/tendermint/tendermint/issues/598)
If `--pex` is enabled, peers will gossip about known peers and form a more resilient network.
### Adding a Non-Validator
Adding a non-validator is simple. Just copy the original `genesis.json` to `~/.tendermint` on the new machine
@ -292,11 +285,11 @@ Update the `genesis.json` in `~/.tendermint`. Copy the genesis file and the new
to the `~/.tendermint` on a new machine.
Now run `tendermint node` on both machines, and use either `--p2p.seeds` or the `/dial_seeds` to get them to peer up.
They should start making blocks, and will only continue to do so so long as both of them are online.
They should start making blocks, and will only continue to do so as long as both of them are online.
To make a Tendermint network that can tolerate one of the validators failing, you need at least four validator nodes.
To make a Tendermint network that can tolerate one of the validators failing, you need at least four validator nodes (> 2/3).
Updating validators in a live network is supported as of v0.8, but it must be explicitly programmed by the application developer.
Updating validators in a live network is supported but must be explicitly programmed by the application developer.
See the [application developers guide](/docs/guides/app-development#Handshake) for more details.
### Local Network
@ -311,4 +304,3 @@ otherwise Tendermint's p2p library will deny making connections to peers with th
Got a couple nodes talking to each other using the dummy app?
Try a more sophisticated app like [Ethermint](https://github.com/tendermint/ethermint),
or learn more about building your own in the [Application Developer's Guide](/docs/guides/app-development).

Loading…
Cancel
Save