@ -0,0 +1,402 @@ | |||||
# Using Tendermint | |||||
This is a guide to using the `tendermint` program from the command line. | |||||
It assumes only that you have the `tendermint` binary installed and have | |||||
some rudimentary idea of what Tendermint and ABCI are. | |||||
You can see the help menu with `tendermint --help`, and the version | |||||
number with `tendermint version`. | |||||
## Directory Root | |||||
The default directory for blockchain data is `~/.tendermint`. Override | |||||
this by setting the `TMHOME` environment variable. | |||||
## Initialize | |||||
Initialize the root directory by running: | |||||
tendermint init | |||||
This will create a new private key (`priv_validator.json`), and a | |||||
genesis file (`genesis.json`) containing the associated public key, in | |||||
`$TMHOME/config`. This is all that's necessary to run a local testnet | |||||
with one validator. | |||||
For more elaborate initialization, see the tesnet command: | |||||
tendermint testnet --help | |||||
## Run | |||||
To run a Tendermint node, use | |||||
tendermint node | |||||
By default, Tendermint will try to connect to an ABCI application on | |||||
[127.0.0.1:46658](127.0.0.1:46658). If you have the `kvstore` ABCI app | |||||
installed, run it in another window. If you don't, kill Tendermint and | |||||
run an in-process version of the `kvstore` app: | |||||
tendermint node --proxy_app=kvstore | |||||
After a few seconds you should see blocks start streaming in. Note that | |||||
blocks are produced regularly, even if there are no transactions. See | |||||
*No Empty Blocks*, below, to modify this setting. | |||||
Tendermint supports in-process versions of the `counter`, `kvstore` 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. If your | |||||
app is not written in Go, simply run it in another process, and use the | |||||
`--proxy_app` flag to specify the address of the socket it is listening | |||||
on, for instance: | |||||
tendermint node --proxy_app=/var/run/abci.sock | |||||
## Transactions | |||||
To send a transaction, use `curl` to make requests to the Tendermint RPC | |||||
server, for example: | |||||
curl http://localhost:46657/broadcast_tx_commit?tx=\"abcd\" | |||||
We can see the chain's status at the `/status` end-point: | |||||
curl http://localhost:46657/status | json_pp | |||||
and the `latest_app_hash` in particular: | |||||
curl http://localhost:46657/status | json_pp | grep latest_app_hash | |||||
Visit http://localhost:46657> in your browser to see the list of other | |||||
endpoints. Some take no arguments (like `/status`), while others specify | |||||
the argument name and use `_` as a placeholder. | |||||
### Formatting | |||||
The following nuances when sending/formatting transactions should be | |||||
taken into account: | |||||
With `GET`: | |||||
To send a UTF8 string byte array, quote the value of the tx pramater: | |||||
curl 'http://localhost:46657/broadcast_tx_commit?tx="hello"' | |||||
which sends a 5 byte transaction: "h e l l o" \[68 65 6c 6c 6f\]. | |||||
Note the URL must be wrapped with single quoes, else bash will ignore | |||||
the double quotes. To avoid the single quotes, escape the double quotes: | |||||
curl http://localhost:46657/broadcast_tx_commit?tx=\"hello\" | |||||
Using a special character: | |||||
curl 'http://localhost:46657/broadcast_tx_commit?tx="€5"' | |||||
sends a 4 byte transaction: "€5" (UTF8) \[e2 82 ac 35\]. | |||||
To send as raw hex, omit quotes AND prefix the hex string with `0x`: | |||||
curl http://localhost:46657/broadcast_tx_commit?tx=0x01020304 | |||||
which sends a 4 byte transaction: \[01 02 03 04\]. | |||||
With `POST` (using `json`), the raw hex must be `base64` encoded: | |||||
curl --data-binary '{"jsonrpc":"2.0","id":"anything","method":"broadcast_tx_commit","params": {"tx": "AQIDBA=="}}' -H 'content-type:text/plain;' http://localhost:46657 | |||||
which sends the same 4 byte transaction: \[01 02 03 04\]. | |||||
Note that raw hex cannot be used in `POST` transactions. | |||||
## Reset | |||||
**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 | |||||
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.json`, your fresh | |||||
new blockchain will not make any blocks. | |||||
## Configuration | |||||
Tendermint uses a `config.toml` for configuration. For details, see [the | |||||
config specification](./specification/configuration.html). | |||||
Notable options include the socket address of the application | |||||
(`proxy_app`), the listening address of the Tendermint peer | |||||
(`p2p.laddr`), and the listening address of the RPC server | |||||
(`rpc.laddr`). | |||||
Some fields from the config file can be overwritten with flags. | |||||
## No Empty Blocks | |||||
This much requested feature was implemented in version 0.10.3. While the | |||||
default behaviour of `tendermint` is still to create blocks | |||||
approximately once per second, it is possible to disable empty blocks or | |||||
set a block creation interval. In the former case, blocks will be | |||||
created when there are new transactions or when the AppHash changes. | |||||
To configure Tendermint to not produce empty blocks unless there are | |||||
transactions or the app hash changes, run Tendermint with this | |||||
additional flag: | |||||
tendermint node --consensus.create_empty_blocks=false | |||||
or set the configuration via the `config.toml` file: | |||||
[consensus] | |||||
create_empty_blocks = false | |||||
Remember: because the default is to *create empty blocks*, avoiding | |||||
empty blocks requires the config option to be set to `false`. | |||||
The block interval setting allows for a delay (in seconds) between the | |||||
creation of each new empty block. It is set via the `config.toml`: | |||||
[consensus] | |||||
create_empty_blocks_interval = 5 | |||||
With this setting, empty blocks will be produced every 5s if no block | |||||
has been produced otherwise, regardless of the value of | |||||
`create_empty_blocks`. | |||||
## Broadcast API | |||||
Earlier, we used the `broadcast_tx_commit` endpoint to send a | |||||
transaction. When a transaction is sent to a Tendermint node, it will | |||||
run via `CheckTx` against the application. If it passes `CheckTx`, it | |||||
will be included in the mempool, broadcasted to other peers, and | |||||
eventually included in a block. | |||||
Since there are multiple phases to processing a transaction, we offer | |||||
multiple endpoints to broadcast a transaction: | |||||
/broadcast_tx_async | |||||
/broadcast_tx_sync | |||||
/broadcast_tx_commit | |||||
These correspond to no-processing, processing through the mempool, and | |||||
processing through a block, respectively. That is, `broadcast_tx_async`, | |||||
will return right away without waiting to hear if the transaction is | |||||
even valid, while `broadcast_tx_sync` will return with the result of | |||||
running the transaction through `CheckTx`. Using `broadcast_tx_commit` | |||||
will wait until the transaction is committed in a block or until some | |||||
timeout is reached, 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 (i.e. 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. | |||||
Note: see the Transactions => Formatting section for details about | |||||
transaction formating. | |||||
## Tendermint Networks | |||||
When `tendermint init` is run, both a `genesis.json` and | |||||
`priv_validator.json` are created in `~/.tendermint/config`. The | |||||
`genesis.json` might look like: | |||||
{ | |||||
"validators" : [ | |||||
{ | |||||
"pub_key" : { | |||||
"value" : "h3hk+QE8c6QLTySp8TcfzclJw/BG79ziGB/pIA+DfPE=", | |||||
"type" : "AC26791624DE60" | |||||
}, | |||||
"power" : 10, | |||||
"name" : "" | |||||
} | |||||
], | |||||
"app_hash" : "", | |||||
"chain_id" : "test-chain-rDlYSN", | |||||
"genesis_time" : "0001-01-01T00:00:00Z" | |||||
} | |||||
And the `priv_validator.json`: | |||||
{ | |||||
"last_step" : 0, | |||||
"last_round" : 0, | |||||
"address" : "B788DEDE4F50AD8BC9462DE76741CCAFF87D51E2", | |||||
"pub_key" : { | |||||
"value" : "h3hk+QE8c6QLTySp8TcfzclJw/BG79ziGB/pIA+DfPE=", | |||||
"type" : "AC26791624DE60" | |||||
}, | |||||
"last_height" : 0, | |||||
"priv_key" : { | |||||
"value" : "JPivl82x+LfVkp8i3ztoTjY6c6GJ4pBxQexErOCyhwqHeGT5ATxzpAtPJKnxNx/NyUnD8Ebv3OIYH+kgD4N88Q==", | |||||
"type" : "954568A3288910" | |||||
} | |||||
} | |||||
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. Greater than 2/3 | |||||
of the voting power must be active (i.e. the corresponding private keys | |||||
must be producing signatures) for the consensus to make progress. In our | |||||
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 progress. Voting power uses an int64 | |||||
but must be positive, thus the range is: 0 through 9223372036854775807. | |||||
Because of how the current proposer selection algorithm works, we do not | |||||
recommend having voting powers greater than 10\^12 (ie. 1 trillion) (see | |||||
[Proposals section of Byzantine Consensus | |||||
Algorithm](./specification/byzantine-consensus-algorithm.html#proposals) | |||||
for details). | |||||
If we want to add more nodes to the network, we have two choices: we can | |||||
add a new validator node, who will also participate in the consensus by | |||||
proposing blocks and voting on them, or we can add a new non-validator | |||||
node, who will not participate directly, but will verify and keep up | |||||
with the consensus protocol. | |||||
### Peers | |||||
To connect to peers on start-up, specify them in the | |||||
`$TMHOME/config/config.toml` or on the command line. Use seeds to | |||||
specify seed nodes from which you can get many other peer addresses, and | |||||
`persistent_peers` to specify peers that your node will maintain | |||||
persistent connections with. | |||||
For instance, | |||||
tendermint node --p2p.seeds "f9baeaa15fedf5e1ef7448dd60f46c01f1a9e9c4@1.2.3.4:46656,0491d373a8e0fcf1023aaf18c51d6a1d0d4f31bd@5.6.7.8:46656" | |||||
Alternatively, you can use the `/dial_seeds` endpoint of the RPC to | |||||
specify seeds for a running node to connect to: | |||||
curl 'localhost:46657/dial_seeds?seeds=\["f9baeaa15fedf5e1ef7448dd60f46c01f1a9e9c4@1.2.3.4:46656","0491d373a8e0fcf1023aaf18c51d6a1d0d4f31bd@5.6.7.8:46656"\]' | |||||
Note, if the peer-exchange protocol (PEX) is enabled (default), you | |||||
should not normally need seeds after the first start. Peers will be | |||||
gossipping about known peers and forming a network, storing peer | |||||
addresses in the addrbook. | |||||
If you want Tendermint to connect to specific set of addresses and | |||||
maintain a persistent connection with each, you can use the | |||||
`--p2p.persistent_peers` flag or the corresponding setting in the | |||||
`config.toml` or the `/dial_peers` RPC endpoint to do it without | |||||
stopping Tendermint core instance. | |||||
tendermint node --p2p.persistent_peers "429fcf25974313b95673f58d77eacdd434402665@10.11.12.13:46656,96663a3dd0d7b9d17d4c8211b191af259621c693@10.11.12.14:46656" | |||||
curl 'localhost:46657/dial_peers?persistent=true&peers=\["429fcf25974313b95673f58d77eacdd434402665@10.11.12.13:46656","96663a3dd0d7b9d17d4c8211b191af259621c693@10.11.12.14:46656"\]' | |||||
### Adding a Non-Validator | |||||
Adding a non-validator is simple. Just copy the original `genesis.json` | |||||
to `~/.tendermint/config` on the new machine and start the node, | |||||
specifying seeds or persistent peers as necessary. If no seeds or | |||||
persistent peers are specified, the node won't make any blocks, because | |||||
it's not a validator, and it won't hear about any blocks, because it's | |||||
not connected to the other peer. | |||||
### Adding a Validator | |||||
The easiest way to add new validators is to do it in the `genesis.json`, | |||||
before starting the network. For instance, we could make a new | |||||
`priv_validator.json`, and copy it's `pub_key` into the above genesis. | |||||
We can generate a new `priv_validator.json` with the command: | |||||
tendermint gen_validator | |||||
Now we can update our genesis file. For instance, if the new | |||||
`priv_validator.json` looks like: | |||||
{ | |||||
"address" : "5AF49D2A2D4F5AD4C7C8C4CC2FB020131E9C4902", | |||||
"pub_key" : { | |||||
"value" : "l9X9+fjkeBzDfPGbUM7AMIRE6uJN78zN5+lk5OYotek=", | |||||
"type" : "AC26791624DE60" | |||||
}, | |||||
"priv_key" : { | |||||
"value" : "EDJY9W6zlAw+su6ITgTKg2nTZcHAH1NMTW5iwlgmNDuX1f35+OR4HMN88ZtQzsAwhETq4k3vzM3n6WTk5ii16Q==", | |||||
"type" : "954568A3288910" | |||||
}, | |||||
"last_step" : 0, | |||||
"last_round" : 0, | |||||
"last_height" : 0 | |||||
} | |||||
then the new `genesis.json` will be: | |||||
{ | |||||
"validators" : [ | |||||
{ | |||||
"pub_key" : { | |||||
"value" : "h3hk+QE8c6QLTySp8TcfzclJw/BG79ziGB/pIA+DfPE=", | |||||
"type" : "AC26791624DE60" | |||||
}, | |||||
"power" : 10, | |||||
"name" : "" | |||||
}, | |||||
{ | |||||
"pub_key" : { | |||||
"value" : "l9X9+fjkeBzDfPGbUM7AMIRE6uJN78zN5+lk5OYotek=", | |||||
"type" : "AC26791624DE60" | |||||
}, | |||||
"power" : 10, | |||||
"name" : "" | |||||
} | |||||
], | |||||
"app_hash" : "", | |||||
"chain_id" : "test-chain-rDlYSN", | |||||
"genesis_time" : "0001-01-01T00:00:00Z" | |||||
} | |||||
Update the `genesis.json` in `~/.tendermint/config`. Copy the genesis | |||||
file and the new `priv_validator.json` to the `~/.tendermint/config` on | |||||
a new machine. | |||||
Now run `tendermint node` on both machines, and use either | |||||
`--p2p.persistent_peers` or the `/dial_peers` to get them to peer up. | |||||
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 (> 2/3). | |||||
Updating validators in a live network is supported but must be | |||||
explicitly programmed by the application developer. See the [application | |||||
developers guide](./app-development.html) for more details. | |||||
### Local Network | |||||
To run a network locally, say on a single machine, you must change the | |||||
`_laddr` fields in the `config.toml` (or using the flags) so that the | |||||
listening addresses of the various sockets don't conflict. Additionally, | |||||
you must set `addrbook_strict=false` in the `config.toml`, otherwise | |||||
Tendermint's p2p library will deny making connections to peers with the | |||||
same IP address. | |||||
### Upgrading | |||||
The Tendermint development cycle currently includes a lot of breaking changes. | |||||
Upgrading from an old version to a new version usually means throwing | |||||
away the chain data. Try out the | |||||
[tm-migrate](https://github.com/hxzqlh/tm-tools) tool written by | |||||
[@hxzqlh](https://github.com/hxzqlh) if you are keen to preserve the | |||||
state of your chain when upgrading to newer versions. |
@ -1,463 +0,0 @@ | |||||
Using Tendermint | |||||
================ | |||||
This is a guide to using the ``tendermint`` program from the command | |||||
line. It assumes only that you have the ``tendermint`` binary installed | |||||
and have some rudimentary idea of what Tendermint and ABCI are. | |||||
You can see the help menu with ``tendermint --help``, and the version | |||||
number with ``tendermint version``. | |||||
Directory Root | |||||
-------------- | |||||
The default directory for blockchain data is ``~/.tendermint``. Override | |||||
this by setting the ``TMHOME`` environment variable. | |||||
Initialize | |||||
---------- | |||||
Initialize the root directory by running: | |||||
:: | |||||
tendermint init | |||||
This will create a new private key (``priv_validator.json``), and a | |||||
genesis file (``genesis.json``) containing the associated public key, | |||||
in ``$TMHOME/config``. | |||||
This is all that's necessary to run a local testnet with one validator. | |||||
For more elaborate initialization, see the `tesnet` command: | |||||
:: | |||||
tendermint testnet --help | |||||
Run | |||||
--- | |||||
To run a Tendermint node, use | |||||
:: | |||||
tendermint node | |||||
By default, Tendermint will try to connect to an ABCI application on | |||||
`127.0.0.1:46658 <127.0.0.1:46658>`__. If you have the ``kvstore`` ABCI | |||||
app installed, run it in another window. If you don't, kill Tendermint | |||||
and run an in-process version of the ``kvstore`` app: | |||||
:: | |||||
tendermint node --proxy_app=kvstore | |||||
After a few seconds you should see blocks start streaming in. Note that | |||||
blocks are produced regularly, even if there are no transactions. See *No Empty Blocks*, below, to modify this setting. | |||||
Tendermint supports in-process versions of the ``counter``, ``kvstore`` 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. If your | |||||
app is not written in Go, simply run it in another process, and use the | |||||
``--proxy_app`` flag to specify the address of the socket it is | |||||
listening on, for instance: | |||||
:: | |||||
tendermint node --proxy_app=/var/run/abci.sock | |||||
Transactions | |||||
------------ | |||||
To send a transaction, use ``curl`` to make requests to the Tendermint | |||||
RPC server, for example: | |||||
:: | |||||
curl http://localhost:46657/broadcast_tx_commit?tx=\"abcd\" | |||||
We can see the chain's status at the ``/status`` end-point: | |||||
:: | |||||
curl http://localhost:46657/status | json_pp | |||||
and the ``latest_app_hash`` in particular: | |||||
:: | |||||
curl http://localhost:46657/status | json_pp | grep latest_app_hash | |||||
Visit http://localhost:46657 in your browser to see the list of other | |||||
endpoints. Some take no arguments (like ``/status``), while others | |||||
specify the argument name and use ``_`` as a placeholder. | |||||
Formatting | |||||
~~~~~~~~~~ | |||||
The following nuances when sending/formatting transactions should | |||||
be taken into account: | |||||
With ``GET``: | |||||
To send a UTF8 string byte array, quote the value of the tx pramater: | |||||
:: | |||||
curl 'http://localhost:46657/broadcast_tx_commit?tx="hello"' | |||||
which sends a 5 byte transaction: "h e l l o" [68 65 6c 6c 6f]. | |||||
Note the URL must be wrapped with single quoes, else bash will ignore the double quotes. | |||||
To avoid the single quotes, escape the double quotes: | |||||
:: | |||||
curl http://localhost:46657/broadcast_tx_commit?tx=\"hello\" | |||||
Using a special character: | |||||
:: | |||||
curl 'http://localhost:46657/broadcast_tx_commit?tx="€5"' | |||||
sends a 4 byte transaction: "€5" (UTF8) [e2 82 ac 35]. | |||||
To send as raw hex, omit quotes AND prefix the hex string with ``0x``: | |||||
:: | |||||
curl http://localhost:46657/broadcast_tx_commit?tx=0x01020304 | |||||
which sends a 4 byte transaction: [01 02 03 04]. | |||||
With ``POST`` (using ``json``), the raw hex must be ``base64`` encoded: | |||||
:: | |||||
curl --data-binary '{"jsonrpc":"2.0","id":"anything","method":"broadcast_tx_commit","params": {"tx": "AQIDBA=="}}' -H 'content-type:text/plain;' http://localhost:46657 | |||||
which sends the same 4 byte transaction: [01 02 03 04]. | |||||
Note that raw hex cannot be used in ``POST`` transactions. | |||||
Reset | |||||
----- | |||||
**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 | |||||
:: | |||||
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.json``, your fresh | |||||
new blockchain will not make any blocks. | |||||
Configuration | |||||
------------- | |||||
Tendermint uses a ``config.toml`` for configuration. For details, see | |||||
`the config specification <./specification/configuration.html>`__. | |||||
Notable options include the socket address of the application | |||||
(``proxy_app``), the listening address of the Tendermint peer | |||||
(``p2p.laddr``), and the listening address of the RPC server | |||||
(``rpc.laddr``). | |||||
Some fields from the config file can be overwritten with flags. | |||||
No Empty Blocks | |||||
--------------- | |||||
This much requested feature was implemented in version 0.10.3. While the | |||||
default behaviour of ``tendermint`` is still to create blocks approximately | |||||
once per second, it is possible to disable empty blocks or set a block creation | |||||
interval. In the former case, blocks will be created when there are new | |||||
transactions or when the AppHash changes. | |||||
To configure Tendermint to not produce empty blocks unless there are | |||||
transactions or the app hash changes, run Tendermint with this additional flag: | |||||
:: | |||||
tendermint node --consensus.create_empty_blocks=false | |||||
or set the configuration via the ``config.toml`` file: | |||||
:: | |||||
[consensus] | |||||
create_empty_blocks = false | |||||
Remember: because the default is to *create empty blocks*, avoiding empty blocks requires the config option to be set to ``false``. | |||||
The block interval setting allows for a delay (in seconds) between the creation of each new empty block. It is set via the ``config.toml``: | |||||
:: | |||||
[consensus] | |||||
create_empty_blocks_interval = 5 | |||||
With this setting, empty blocks will be produced every 5s if no block has been produced otherwise, | |||||
regardless of the value of ``create_empty_blocks``. | |||||
Broadcast API | |||||
------------- | |||||
Earlier, we used the ``broadcast_tx_commit`` endpoint to send a | |||||
transaction. When a transaction is sent to a Tendermint node, it will | |||||
run via ``CheckTx`` against the application. If it passes ``CheckTx``, | |||||
it will be included in the mempool, broadcasted to other peers, and | |||||
eventually included in a block. | |||||
Since there are multiple phases to processing a transaction, we offer | |||||
multiple endpoints to broadcast a transaction: | |||||
:: | |||||
/broadcast_tx_async | |||||
/broadcast_tx_sync | |||||
/broadcast_tx_commit | |||||
These correspond to no-processing, processing through the mempool, and | |||||
processing through a block, respectively. That is, | |||||
``broadcast_tx_async``, will return right away without waiting to hear | |||||
if the transaction is even valid, while ``broadcast_tx_sync`` will | |||||
return with the result of running the transaction through ``CheckTx``. | |||||
Using ``broadcast_tx_commit`` will wait until the transaction is | |||||
committed in a block or until some timeout is reached, 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 (i.e. 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. | |||||
Note: see the Transactions => Formatting section for details about | |||||
transaction formating. | |||||
Tendermint Networks | |||||
------------------- | |||||
When ``tendermint init`` is run, both a ``genesis.json`` and | |||||
``priv_validator.json`` are created in ``~/.tendermint/config``. The | |||||
``genesis.json`` might look like: | |||||
:: | |||||
{ | |||||
"validators" : [ | |||||
{ | |||||
"pub_key" : { | |||||
"value" : "h3hk+QE8c6QLTySp8TcfzclJw/BG79ziGB/pIA+DfPE=", | |||||
"type" : "AC26791624DE60" | |||||
}, | |||||
"power" : 10, | |||||
"name" : "" | |||||
} | |||||
], | |||||
"app_hash" : "", | |||||
"chain_id" : "test-chain-rDlYSN", | |||||
"genesis_time" : "0001-01-01T00:00:00Z" | |||||
} | |||||
And the ``priv_validator.json``: | |||||
:: | |||||
{ | |||||
"last_step" : 0, | |||||
"last_round" : 0, | |||||
"address" : "B788DEDE4F50AD8BC9462DE76741CCAFF87D51E2", | |||||
"pub_key" : { | |||||
"value" : "h3hk+QE8c6QLTySp8TcfzclJw/BG79ziGB/pIA+DfPE=", | |||||
"type" : "AC26791624DE60" | |||||
}, | |||||
"last_height" : 0, | |||||
"priv_key" : { | |||||
"value" : "JPivl82x+LfVkp8i3ztoTjY6c6GJ4pBxQexErOCyhwqHeGT5ATxzpAtPJKnxNx/NyUnD8Ebv3OIYH+kgD4N88Q==", | |||||
"type" : "954568A3288910" | |||||
} | |||||
} | |||||
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. Greater than 2/3 of the voting | |||||
power must be active (i.e. the corresponding private keys must be producing | |||||
signatures) for the consensus to make progress. In our 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 progress. Voting | |||||
power uses an `int64` but must be positive, thus the range is: 0 through | |||||
9223372036854775807. Because of how the current proposer selection algorithm works, | |||||
we do not recommend having voting powers greater than 10^12 (ie. 1 trillion) | |||||
(see `Proposals section of Byzantine Consensus Algorithm | |||||
<./specification/byzantine-consensus-algorithm.html#proposals>`__ for details). | |||||
If we want to add more nodes to the network, we have two choices: we can | |||||
add a new validator node, who will also participate in the consensus by | |||||
proposing blocks and voting on them, or we can add a new non-validator | |||||
node, who will not participate directly, but will verify and keep up | |||||
with the consensus protocol. | |||||
Peers | |||||
~~~~~ | |||||
To connect to peers on start-up, specify them in the ``$TMHOME/config/config.toml`` or | |||||
on the command line. Use `seeds` to specify seed nodes from which you can get many other | |||||
peer addresses, and ``persistent_peers`` to specify peers that your node will maintain | |||||
persistent connections with. | |||||
For instance, | |||||
:: | |||||
tendermint node --p2p.seeds "f9baeaa15fedf5e1ef7448dd60f46c01f1a9e9c4@1.2.3.4:46656,0491d373a8e0fcf1023aaf18c51d6a1d0d4f31bd@5.6.7.8:46656" | |||||
Alternatively, you can use the ``/dial_seeds`` endpoint of the RPC to | |||||
specify seeds for a running node to connect to: | |||||
:: | |||||
curl 'localhost:46657/dial_seeds?seeds=\["f9baeaa15fedf5e1ef7448dd60f46c01f1a9e9c4@1.2.3.4:46656","0491d373a8e0fcf1023aaf18c51d6a1d0d4f31bd@5.6.7.8:46656"\]' | |||||
Note, if the peer-exchange protocol (PEX) is enabled (default), you should not | |||||
normally need seeds after the first start. Peers will be gossipping about known | |||||
peers and forming a network, storing peer addresses in the addrbook. | |||||
If you want Tendermint to connect to specific set of addresses and maintain a | |||||
persistent connection with each, you can use the ``--p2p.persistent_peers`` | |||||
flag or the corresponding setting in the ``config.toml`` or the | |||||
``/dial_peers`` RPC endpoint to do it without stopping Tendermint | |||||
core instance. | |||||
:: | |||||
tendermint node --p2p.persistent_peers "429fcf25974313b95673f58d77eacdd434402665@10.11.12.13:46656,96663a3dd0d7b9d17d4c8211b191af259621c693@10.11.12.14:46656" | |||||
curl 'localhost:46657/dial_peers?persistent=true&peers=\["429fcf25974313b95673f58d77eacdd434402665@10.11.12.13:46656","96663a3dd0d7b9d17d4c8211b191af259621c693@10.11.12.14:46656"\]' | |||||
Adding a Non-Validator | |||||
~~~~~~~~~~~~~~~~~~~~~~ | |||||
Adding a non-validator is simple. Just copy the original | |||||
``genesis.json`` to ``~/.tendermint/config`` on the new machine and start the | |||||
node, specifying seeds or persistent peers as necessary. If no seeds or persistent | |||||
peers are specified, the node won't make any blocks, because it's not a validator, | |||||
and it won't hear about any blocks, because it's not connected to the other peer. | |||||
Adding a Validator | |||||
~~~~~~~~~~~~~~~~~~ | |||||
The easiest way to add new validators is to do it in the | |||||
``genesis.json``, before starting the network. For instance, we could | |||||
make a new ``priv_validator.json``, and copy it's ``pub_key`` into the | |||||
above genesis. | |||||
We can generate a new ``priv_validator.json`` with the command: | |||||
:: | |||||
tendermint gen_validator | |||||
Now we can update our genesis file. For instance, if the new | |||||
``priv_validator.json`` looks like: | |||||
:: | |||||
{ | |||||
"address" : "5AF49D2A2D4F5AD4C7C8C4CC2FB020131E9C4902", | |||||
"pub_key" : { | |||||
"value" : "l9X9+fjkeBzDfPGbUM7AMIRE6uJN78zN5+lk5OYotek=", | |||||
"type" : "AC26791624DE60" | |||||
}, | |||||
"priv_key" : { | |||||
"value" : "EDJY9W6zlAw+su6ITgTKg2nTZcHAH1NMTW5iwlgmNDuX1f35+OR4HMN88ZtQzsAwhETq4k3vzM3n6WTk5ii16Q==", | |||||
"type" : "954568A3288910" | |||||
}, | |||||
"last_step" : 0, | |||||
"last_round" : 0, | |||||
"last_height" : 0 | |||||
} | |||||
then the new ``genesis.json`` will be: | |||||
:: | |||||
{ | |||||
"validators" : [ | |||||
{ | |||||
"pub_key" : { | |||||
"value" : "h3hk+QE8c6QLTySp8TcfzclJw/BG79ziGB/pIA+DfPE=", | |||||
"type" : "AC26791624DE60" | |||||
}, | |||||
"power" : 10, | |||||
"name" : "" | |||||
}, | |||||
{ | |||||
"pub_key" : { | |||||
"value" : "l9X9+fjkeBzDfPGbUM7AMIRE6uJN78zN5+lk5OYotek=", | |||||
"type" : "AC26791624DE60" | |||||
}, | |||||
"power" : 10, | |||||
"name" : "" | |||||
} | |||||
], | |||||
"app_hash" : "", | |||||
"chain_id" : "test-chain-rDlYSN", | |||||
"genesis_time" : "0001-01-01T00:00:00Z" | |||||
} | |||||
Update the ``genesis.json`` in ``~/.tendermint/config``. Copy the genesis file | |||||
and the new ``priv_validator.json`` to the ``~/.tendermint/config`` on a new | |||||
machine. | |||||
Now run ``tendermint node`` on both machines, and use either | |||||
``--p2p.persistent_peers`` or the ``/dial_peers`` to get them to peer up. 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 (> 2/3). | |||||
Updating validators in a live network is supported but must be | |||||
explicitly programmed by the application developer. See the `application | |||||
developers guide <./app-development.html>`__ for more | |||||
details. | |||||
Local Network | |||||
~~~~~~~~~~~~~ | |||||
To run a network locally, say on a single machine, you must change the | |||||
``_laddr`` fields in the ``config.toml`` (or using the flags) so that | |||||
the listening addresses of the various sockets don't conflict. | |||||
Additionally, you must set ``addrbook_strict=false`` in the | |||||
``config.toml``, otherwise Tendermint's p2p library will deny making | |||||
connections to peers with the same IP address. | |||||
Upgrading | |||||
~~~~~~~~~ | |||||
The Tendermint development cycle includes a lot of breaking changes. Upgrading from | |||||
an old version to a new version usually means throwing away the chain data. Try out | |||||
the `tm-migrate <https://github.com/hxzqlh/tm-tools>`__ tool written by `@hxzqlh <https://github.com/hxzqlh>`__ if | |||||
you are keen to preserve the state of your chain when upgrading to newer versions. |