Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

node: implement tendermint modes #6241

Merged
merged 22 commits into from Mar 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
097356a
Add Tendermint Nodes
dongsam Feb 6, 2021
46b5287
seednode automatically set seed_mode, update docs
dongsam Feb 6, 2021
8843f03
fix seednode bugs
dongsam Feb 6, 2021
5c801da
Apply suggestions from code review
dongsam Feb 10, 2021
8c250fd
fix typo
dongsam Feb 10, 2021
051f838
Merge branch 'master' into ADR-52-Tendermint-Mode-reopen-PR
dongsam Feb 10, 2021
da2b06b
Apply suggestions from code review
dongsam Feb 16, 2021
e80715b
Apply suggestions from code review
dongsam Feb 16, 2021
79fb53d
Merge branch 'master' into ADR-52-Tendermint-Mode-reopen-PR
cmwaters Mar 15, 2021
5f230f8
remove seed mode config param
cmwaters Mar 15, 2021
6226fc5
remove db's from seed nodes
cmwaters Mar 15, 2021
5d1f6b9
fix default template config
cmwaters Mar 16, 2021
22801af
adapt e2e suite to seed nodes
cmwaters Mar 16, 2021
9136ce0
Merge branch 'master' into ADR-52-Tendermint-Mode-reopen-PR
cmwaters Mar 16, 2021
8f5fb63
implement suggestions
cmwaters Mar 17, 2021
0f21867
Merge github.com:tendermint/tendermint into ADR-52-Tendermint-Mode-re…
cmwaters Mar 17, 2021
80562bd
make terminology consistent
cmwaters Mar 17, 2021
457cd5a
Merge branch 'master' into ADR-52-Tendermint-Mode-reopen-PR
cmwaters Mar 17, 2021
9e8ded8
make terminology consistent v2
cmwaters Mar 17, 2021
9e4cc4b
Merge github.com:tendermint/tendermint into ADR-52-Tendermint-Mode-re…
cmwaters Mar 17, 2021
073e92e
apply some cosmetic changes
cmwaters Mar 18, 2021
8432063
Merge branch 'master' into ADR-52-Tendermint-Mode-reopen-PR
cmwaters Mar 18, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG_PENDING.md
Expand Up @@ -51,6 +51,8 @@ Friendly reminder: We have a [bug bounty program](https://hackerone.com/tendermi

### FEATURES

- [config] Add `--mode` flag and config variable. See [ADR-52](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-052-tendermint-mode.md) @dongsam

### IMPROVEMENTS

- [crypto/ed25519] \#5632 Adopt zip215 `ed25519` verification. (@marbar3778)
Expand Down
7 changes: 5 additions & 2 deletions UPGRADING.md
Expand Up @@ -17,7 +17,10 @@ This guide provides instructions for upgrading to specific versions of Tendermin
* `fast_sync = "v1"` is no longer supported. Please use `v2` instead.

* All config parameters are now hyphen-case (also known as kebab-case) instead of snake_case. Before restarting the node make sure
you have updated all the variables in your `config.toml` file.
you have updated all the variables in your `config.toml` file.

* Added `--mode` flag and `mode` config variable on `config.toml` for setting Mode of the Node: `full` | `validator` | `seed` (default: `full`)
[ADR-52](https://github.com/tendermint/tendermint/blob/master/docs/architecture/adr-052-tendermint-mode.md)

### CLI Changes

Expand All @@ -30,7 +33,7 @@ This guide provides instructions for upgrading to specific versions of Tendermin
$ tendermint gen_node_key > $TMHOME/config/node_key.json
```

* CLI commands and flags are all now hyphen-case instead of snake_case.
* CLI commands and flags are all now hyphen-case instead of snake_case.
Make sure to adjust any scripts that calls a cli command with snake_casing
## v0.34.0

Expand Down
4 changes: 3 additions & 1 deletion cmd/tendermint/commands/run_node.go
Expand Up @@ -24,6 +24,9 @@ func AddNodeFlags(cmd *cobra.Command) {
// bind flags
cmd.Flags().String("moniker", config.Moniker, "node name")

// mode flags
cmd.Flags().String("mode", config.Mode, "node mode (full | validator | seed)")

// priv val flags
cmd.Flags().String(
"priv-validator-laddr",
Expand Down Expand Up @@ -71,7 +74,6 @@ func AddNodeFlags(cmd *cobra.Command) {
config.P2P.UnconditionalPeerIDs, "comma-delimited IDs of unconditional peers")
cmd.Flags().Bool("p2p.upnp", config.P2P.UPNP, "enable/disable UPNP port forwarding")
cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "enable/disable Peer-Exchange")
cmd.Flags().Bool("p2p.seed-mode", config.P2P.SeedMode, "enable/disable seed mode")
cmd.Flags().String("p2p.private-peer-ids", config.P2P.PrivatePeerIDs, "comma-delimited private peer IDs")

// consensus flags
Expand Down
2 changes: 2 additions & 0 deletions cmd/tendermint/commands/testnet.go
Expand Up @@ -105,7 +105,9 @@ func testnetFiles(cmd *cobra.Command, args []string) error {
)
}

// set mode to validator for testnet
config := cfg.DefaultConfig()
config.Mode = cfg.ModeValidator

// overwrite default config if set and valid
if configFile != "" {
Expand Down
40 changes: 30 additions & 10 deletions config/config.go
Expand Up @@ -23,6 +23,13 @@ const (

// DefaultLogLevel defines a default log level as INFO.
DefaultLogLevel = "info"

ModeFull = "full"
ModeValidator = "validator"
ModeSeed = "seed"

BlockchainV0 = "v0"
BlockchainV2 = "v2"
)

// NOTE: Most of the structs & relevant comments + the
Expand All @@ -39,6 +46,7 @@ var (
defaultConfigFileName = "config.toml"
defaultGenesisJSONName = "genesis.json"

defaultMode = ModeFull
defaultPrivValKeyName = "priv_validator_key.json"
defaultPrivValStateName = "priv_validator_state.json"

Expand Down Expand Up @@ -159,6 +167,18 @@ type BaseConfig struct { //nolint: maligned
// A custom human readable name for this node
Moniker string `mapstructure:"moniker"`

// Mode of Node: full | validator | seed (default: "full")
// * full (default)
// - all reactors
// - No priv_validator_key.json, priv_validator_state.json
// * validator
// - all reactors
// - with priv_validator_key.json, priv_validator_state.json
// * seed
// - only P2P, PEX Reactor
// - No priv_validator_key.json, priv_validator_state.json
Mode string `mapstructure:"mode"`

// If this node is many blocks behind the tip of the chain, FastSync
// allows them to catchup quickly by downloading blocks in parallel
// and verifying their commits
Expand Down Expand Up @@ -235,6 +255,7 @@ func DefaultBaseConfig() BaseConfig {
PrivValidatorKey: defaultPrivValKeyPath,
PrivValidatorState: defaultPrivValStatePath,
NodeKey: defaultNodeKeyPath,
Mode: defaultMode,
Moniker: defaultMoniker,
ProxyApp: "tcp://127.0.0.1:26658",
ABCI: "socket",
Expand All @@ -251,6 +272,7 @@ func DefaultBaseConfig() BaseConfig {
func TestBaseConfig() BaseConfig {
cfg := DefaultBaseConfig()
cfg.chainID = "tendermint_test"
cfg.Mode = ModeValidator
cfg.ProxyApp = "kvstore"
cfg.FastSyncMode = false
cfg.DBBackend = "memdb"
Expand Down Expand Up @@ -322,6 +344,11 @@ func (cfg BaseConfig) ValidateBasic() error {
default:
return errors.New("unknown log format (must be 'plain' or 'json')")
}
switch cfg.Mode {
case ModeFull, ModeValidator, ModeSeed:
default:
return fmt.Errorf("unknown mode: %v", cfg.Mode)
}
return nil
}

Expand Down Expand Up @@ -557,12 +584,6 @@ type P2PConfig struct { //nolint: maligned
// Set true to enable the peer-exchange reactor
PexReactor bool `mapstructure:"pex"`

// Seed mode, in which node constantly crawls the network and looks for
// peers. If another node asks it for addresses, it responds and disconnects.
//
// Does not work if the peer-exchange reactor is disabled.
SeedMode bool `mapstructure:"seed-mode"`

// Comma separated list of peer IDs to keep private (will not be gossiped to
// other peers)
PrivatePeerIDs string `mapstructure:"private-peer-ids"`
Expand Down Expand Up @@ -600,7 +621,6 @@ func DefaultP2PConfig() *P2PConfig {
SendRate: 5120000, // 5 mB/s
RecvRate: 5120000, // 5 mB/s
PexReactor: true,
SeedMode: false,
AllowDuplicateIP: false,
HandshakeTimeout: 20 * time.Second,
DialTimeout: 3 * time.Second,
Expand Down Expand Up @@ -807,7 +827,7 @@ type FastSyncConfig struct {
// DefaultFastSyncConfig returns a default configuration for the fast sync service
func DefaultFastSyncConfig() *FastSyncConfig {
return &FastSyncConfig{
Version: "v0",
Version: BlockchainV0,
}
}

Expand All @@ -819,9 +839,9 @@ func TestFastSyncConfig() *FastSyncConfig {
// ValidateBasic performs basic validation.
func (cfg *FastSyncConfig) ValidateBasic() error {
switch cfg.Version {
case "v0":
case BlockchainV0:
return nil
case "v2":
case BlockchainV2:
return nil
default:
return fmt.Errorf("unknown fastsync version %s", cfg.Version)
Expand Down
19 changes: 13 additions & 6 deletions config/toml.go
Expand Up @@ -88,6 +88,19 @@ proxy-app = "{{ .BaseConfig.ProxyApp }}"
# A custom human readable name for this node
moniker = "{{ .BaseConfig.Moniker }}"

# Mode of Node: full | validator | seed (default: "full")
# You will need to set it to "validator" if you want to run the node as a validator
# * full node (default)
# - all reactors
# - No priv_validator_key.json, priv_validator_state.json
# * validator node
# - all reactors
# - with priv_validator_key.json, priv_validator_state.json
# * seed node
# - only P2P, PEX Reactor
# - No priv_validator_key.json, priv_validator_state.json
mode = "{{ .BaseConfig.Mode }}"

# If this node is many blocks behind the tip of the chain, FastSync
# allows them to catchup quickly by downloading blocks in parallel
# and verifying their commits
Expand Down Expand Up @@ -305,12 +318,6 @@ recv-rate = {{ .P2P.RecvRate }}
# Set true to enable the peer-exchange reactor
pex = {{ .P2P.PexReactor }}

# Seed mode, in which node constantly crawls the network and looks for
# peers. If another node asks it for addresses, it responds and disconnects.
#
# Does not work if the peer-exchange reactor is disabled.
seed-mode = {{ .P2P.SeedMode }}

# Comma separated list of peer IDs to keep private (will not be gossiped to other peers)
private-peer-ids = "{{ .P2P.PrivatePeerIDs }}"

Expand Down
2 changes: 1 addition & 1 deletion consensus/wal_generator.go
Expand Up @@ -89,7 +89,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) {
consensusState := NewState(config.Consensus, state.Copy(), blockExec, blockStore, mempool, evpool)
consensusState.SetLogger(logger)
consensusState.SetEventBus(eventBus)
if privValidator != nil {
if privValidator != nil && privValidator != (*privval.FilePV)(nil) {
consensusState.SetPrivValidator(privValidator)
}
// END OF COPY PASTE
Expand Down
20 changes: 11 additions & 9 deletions docs/architecture/adr-052-tendermint-mode.md
Expand Up @@ -7,23 +7,24 @@

## Context

- Fullnode mode: fullnode mode does not have the capability to become a validator.
- Full mode: full mode does not have the capability to become a validator.
- Validator mode : this mode is exactly same as existing state machine behavior. sync without voting on consensus, and participate consensus when fully synced
- Seed mode : lightweight seed mode maintaining an address book, p2p like [TenderSeed](https://gitlab.com/polychainlabs/tenderseed)
- Seed mode : lightweight seed node maintaining an address book, p2p like [TenderSeed](https://gitlab.com/polychainlabs/tenderseed)

## Decision

We would like to suggest a simple Tendermint mode abstraction. These modes will live under one binary, and when initializing a node the user will be able to specify which node they would like to create.

- Which reactor, component to include for each node
- fullnode *(default)*
- full *(default)*
- switch, transport
- reactors
- mempool
- consensus
- evidence
- blockchain
- p2p/pex
- statesync
- rpc (safe connections only)
- *~~no privValidator(priv_validator_key.json, priv_validator_state.json)~~*
- validator
Expand All @@ -33,7 +34,8 @@ We would like to suggest a simple Tendermint mode abstraction. These modes will
- consensus
- evidence
- blockchain
  - p2p/pex
- p2p/pex
- statesync
- rpc (safe connections only)
- with privValidator(priv_validator_key.json, priv_validator_state.json)
- seed
Expand All @@ -44,17 +46,17 @@ We would like to suggest a simple Tendermint mode abstraction. These modes will
- We would like to suggest by introducing `mode` parameter in `config.toml` and cli
- <span v-pre>`mode = "{{ .BaseConfig.Mode }}"`</span> in `config.toml`
- `tendermint node --mode validator` in cli
- fullnode | validator | seed (default: "fullnode")
- full | validator | seednode (default: "full")
- RPC modification
- `host:26657/status`
- return empty `validator_info` when fullnode mode
- no rpc server in seed mode
- return empty `validator_info` when in full mode
- no rpc server in seednode
- Where to modify in codebase
- Add switch for `config.Mode` on `node/node.go:DefaultNewNode`
- If `config.Mode==validator`, call default `NewNode` (current logic)
- If `config.Mode==fullnode`, call `NewNode` with `nil` `privValidator` (do not load or generation)
- If `config.Mode==full`, call `NewNode` with `nil` `privValidator` (do not load or generation)
- Need to add exception routine for `nil` `privValidator` to related functions
- If `config.Mode==seed`, call `NewSeedNode` (seed version of `node/node.go:NewNode`)
- If `config.Mode==seed`, call `NewSeedNode` (seed node version of `node/node.go:NewNode`)
- Need to add exception routine for `nil` `reactor`, `component` to related functions

## Status
Expand Down
20 changes: 13 additions & 7 deletions docs/nodes/configuration.md
Expand Up @@ -41,6 +41,19 @@ moniker = "anonymous"
# and verifying their commits
fast-sync = true

# Mode of Node: full | validator | seed
# You will need to set it to "validator" if you want to run the node as a validator
# * full node (default)
# - all reactors
# - No priv_validator_key.json, priv_validator_state.json
# * validator node
# - all reactors
# - with priv_validator_key.json, priv_validator_state.json
# * seed node
# - only P2P, PEX Reactor
# - No priv_validator_key.json, priv_validator_state.json
mode = "full"

# Database backend: goleveldb | cleveldb | boltdb | rocksdb | badgerdb
# * goleveldb (github.com/syndtr/goleveldb - most popular implementation)
# - pure go
Expand Down Expand Up @@ -242,12 +255,6 @@ recv-rate = 5120000
# Set true to enable the peer-exchange reactor
pex = true

# Seed mode, in which node constantly crawls the network and looks for
# peers. If another node asks it for addresses, it responds and disconnects.
#
# Does not work if the peer-exchange reactor is disabled.
seed-mode = false

# Comma separated list of peer IDs to keep private (will not be gossiped to other peers)
private-peer-ids = ""

Expand Down Expand Up @@ -494,5 +501,4 @@ This section will cover settings within the p2p section of the `config.toml`.
- `max-num-outbound-peers` = is the maximum number of peers you will initiate outbound connects to at one time (where you dial their address and initiate the connection).
- `unconditional-peer-ids` = is similar to `persistent-peers` except that these peers will be connected to even if you are already connected to the maximum number of peers. This can be a validator node ID on your sentry node.
- `pex` = turns the peer exchange reactor on or off. Validator node will want the `pex` turned off so it would not begin gossiping to unknown peers on the network. PeX can also be turned off for statically configured networks with fixed network connectivity. For full nodes on open, dynamic networks, it should be turned on.
- `seed-mode` = is used for when node operators want to run their node as a seed node. Seed node's run a variation of the PeX protocol that disconnects from peers after sending them a list of peers to connect to. To minimize the servers usage, it is recommended to set the mempool's size to 0.
- `private-peer-ids` = is a comma-separated list of node ids that will _not_ be exposed to other peers (i.e., you will not tell other peers about the ids in this list). This can be filled with a validator's node id.
5 changes: 4 additions & 1 deletion docs/nodes/validators.md
Expand Up @@ -56,6 +56,7 @@ The validator will only talk to the sentry that are provided, the sentry nodes w

When initializing nodes there are five parameters in the `config.toml` that may need to be altered.

- `mode:` (full | validator | seed) Mode of node (default: 'full'). If you want to run the node as validator, change it to 'validator'.
- `pex:` boolean. This turns the peer exchange reactor on or off for a node. When `pex=false`, only the `persistent-peers` list is available for connection.
- `persistent-peers:` a comma separated list of `nodeID@ip:port` values that define a list of peers that are expected to be online at all times. This is necessary at first startup because by setting `pex=false` the node will not be able to join the network.
- `unconditional-peer-ids:` comma separated list of nodeID's. These nodes will be connected to no matter the limits of inbound and outbound peers. This is useful for when sentry nodes have full address books.
Expand All @@ -67,19 +68,21 @@ When initializing nodes there are five parameters in the `config.toml` that may

| Config Option | Setting |
| ------------------------ | -------------------------- |
| mode | validator |
| pex | false |
| persistent-peers | list of sentry nodes |
| private-peer-ids | none |
| unconditional-peer-ids | optionally sentry node IDs |
| addr-book-strict | false |
| double-sign-check-height | 10 |

The validator node should have `pex=false` so it does not gossip to the entire network. The persistent peers will be your sentry nodes. Private peers can be left empty as the validator is not trying to hide who it is communicating with. Setting unconditional peers is optional for a validator because they will not have a full address books.
To run the node as validator ensure `mode=validator`. The validator node should have `pex=false` so it does not gossip to the entire network. The persistent peers will be your sentry nodes. Private peers can be left empty as the validator is not trying to hide who it is communicating with. Setting unconditional peers is optional for a validator because they will not have a full address books.

#### Sentry Node Configuration

| Config Option | Setting |
| ---------------------- | --------------------------------------------- |
| mode | full |
| pex | true |
| persistent-peers | validator node, optionally other sentry nodes |
| private-peer-ids | validator node ID |
Expand Down
2 changes: 1 addition & 1 deletion networks/remote/integration.sh
Expand Up @@ -124,7 +124,7 @@ Restart=on-failure
User={{service}}
Group={{service}}
PermissionsStartOnly=true
ExecStart=/usr/bin/tendermint node --proxy-app=kvstore --p2p.persistent-peers=$id0@$ip0:26656,$id1@$ip1:26656,$id2@$ip2:26656,$id3@$ip3:26656
ExecStart=/usr/bin/tendermint node --mode validator --proxy-app=kvstore --p2p.persistent-peers=$id0@$ip0:26656,$id1@$ip1:26656,$id2@$ip2:26656,$id3@$ip3:26656
ExecReload=/bin/kill -HUP \$MAINPID
KillSignal=SIGTERM

Expand Down