From ffa8b5f6204964d622eb7fddf1a40eb5f44b6f83 Mon Sep 17 00:00:00 2001 From: Zach Ramsay Date: Wed, 6 Jun 2018 10:38:34 -0400 Subject: [PATCH] oomph --- docs/using-tendermint.md | 402 +++++++++++++++++++++++++++++++++ docs/using-tendermint.rst | 463 -------------------------------------- 2 files changed, 402 insertions(+), 463 deletions(-) create mode 100644 docs/using-tendermint.md delete mode 100644 docs/using-tendermint.rst diff --git a/docs/using-tendermint.md b/docs/using-tendermint.md new file mode 100644 index 000000000..a7fb4c792 --- /dev/null +++ b/docs/using-tendermint.md @@ -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. diff --git a/docs/using-tendermint.rst b/docs/using-tendermint.rst deleted file mode 100644 index 56790feae..000000000 --- a/docs/using-tendermint.rst +++ /dev/null @@ -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 `__. 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 `__ tool written by `@hxzqlh `__ if -you are keen to preserve the state of your chain when upgrading to newer versions.