Browse Source

node: remove mode defaults. Make node mode explicit (#6282)

pull/6314/head
Callum Waters 3 years ago
committed by GitHub
parent
commit
358d1a28b8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 120 additions and 90 deletions
  1. +1
    -0
      .gitignore
  2. +1
    -0
      CHANGELOG_PENDING.md
  3. +1
    -1
      DOCKER/docker-entrypoint.sh
  4. +3
    -1
      UPGRADING.md
  5. +46
    -28
      cmd/tendermint/commands/init.go
  6. +2
    -3
      cmd/tendermint/commands/testnet.go
  7. +13
    -4
      config/config.go
  8. +16
    -23
      config/toml.go
  9. +2
    -0
      config/toml_test.go
  10. +1
    -1
      docs/app-dev/getting-started.md
  11. +1
    -1
      docs/architecture/adr-008-priv-validator.md
  12. +4
    -2
      docs/architecture/adr-052-tendermint-mode.md
  13. +1
    -1
      docs/introduction/install.md
  14. +1
    -1
      docs/introduction/quick-start.md
  15. +6
    -7
      docs/nodes/configuration.md
  16. +1
    -1
      docs/tendermint-core/using-tendermint.md
  17. +1
    -1
      docs/tools/remote-signer-validation.md
  18. +5
    -4
      docs/tutorials/go-built-in.md
  19. +3
    -2
      docs/tutorials/go.md
  20. +2
    -1
      docs/tutorials/java.md
  21. +3
    -2
      docs/tutorials/kotlin.md
  22. +5
    -5
      test/app/test.sh
  23. +1
    -1
      test/e2e/runner/setup.go

+ 1
- 0
.gitignore View File

@ -35,6 +35,7 @@ shunit2
terraform.tfstate
terraform.tfstate.backup
terraform.tfstate.d
test/app/grpc_client
test/e2e/build
test/e2e/networks/*/
test/logs


+ 1
- 0
CHANGELOG_PENDING.md View File

@ -15,6 +15,7 @@ Friendly reminder: We have a [bug bounty program](https://hackerone.com/tendermi
- [cli] \#5777 use hyphen-case instead of snake_case for all cli commands and config parameters (@cmwaters)
- [rpc] \#6019 standardise RPC errors and return the correct status code (@bipulprasad & @cmwaters)
- [rpc] \#6168 Change default sorting to desc for `/tx_search` results (@melekes)
- [cli] \#6282 User must specify the node mode when using `tendermint init` (@cmwaters)
- Apps
- [ABCI] \#5447 Remove `SetOption` method from `ABCI.Client` interface


+ 1
- 1
DOCKER/docker-entrypoint.sh View File

@ -3,7 +3,7 @@ set -e
if [ ! -d "$TMHOME/config" ]; then
echo "Running tendermint init to create (default) configuration for docker run."
tendermint init
tendermint init validator
sed -i \
-e "s/^proxy-app\s*=.*/proxy-app = \"$PROXY_APP\"/" \


+ 3
- 1
UPGRADING.md View File

@ -24,9 +24,11 @@ This guide provides instructions for upgrading to specific versions of Tendermin
### CLI Changes
* You must now specify the node mode (validator|full|seed) in `tendermint init [mode]`
* If you had previously used `tendermint gen_node_key` to generate a new node
key, keep in mind that it no longer saves the output to a file. You can use
`tendermint init` or pipe the output of `tendermint gen_node_key` to
`tendermint init validator` or pipe the output of `tendermint gen_node_key` to
`$TMHOME/config/node_key.json`:
```


+ 46
- 28
cmd/tendermint/commands/init.go View File

@ -2,6 +2,7 @@ package commands
import (
"context"
"errors"
"fmt"
"github.com/spf13/cobra"
@ -17,9 +18,12 @@ import (
// InitFilesCmd initializes a fresh Tendermint Core instance.
var InitFilesCmd = &cobra.Command{
Use: "init",
Short: "Initialize Tendermint",
RunE: initFiles,
Use: "init [full|validator|seed]",
Short: "Initializes a Tendermint node",
ValidArgs: []string{"full", "validator", "seed"},
// We allow for zero args so we can throw a more informative error
Args: cobra.MaximumNArgs(1),
RunE: initFiles,
}
var (
@ -32,33 +36,40 @@ func init() {
}
func initFiles(cmd *cobra.Command, args []string) error {
if len(args) == 0 {
return errors.New("must specify a node type: tendermint init [validator|full|seed]")
}
config.Mode = args[0]
return initFilesWithConfig(config)
}
func initFilesWithConfig(config *cfg.Config) error {
// private validator
privValKeyFile := config.PrivValidatorKeyFile()
privValStateFile := config.PrivValidatorStateFile()
var (
pv *privval.FilePV
err error
)
if tmos.FileExists(privValKeyFile) {
pv, err = privval.LoadFilePV(privValKeyFile, privValStateFile)
if err != nil {
return err
}
logger.Info("Found private validator", "keyFile", privValKeyFile,
"stateFile", privValStateFile)
} else {
pv, err = privval.GenFilePV(privValKeyFile, privValStateFile, keyType)
if err != nil {
return err
if config.Mode == cfg.ModeValidator {
// private validator
privValKeyFile := config.PrivValidatorKeyFile()
privValStateFile := config.PrivValidatorStateFile()
if tmos.FileExists(privValKeyFile) {
pv, err = privval.LoadFilePV(privValKeyFile, privValStateFile)
if err != nil {
return err
}
logger.Info("Found private validator", "keyFile", privValKeyFile,
"stateFile", privValStateFile)
} else {
pv, err = privval.GenFilePV(privValKeyFile, privValStateFile, keyType)
if err != nil {
return err
}
pv.Save()
logger.Info("Generated private validator", "keyFile", privValKeyFile,
"stateFile", privValStateFile)
}
pv.Save()
logger.Info("Generated private validator", "keyFile", privValKeyFile,
"stateFile", privValStateFile)
}
nodeKeyFile := config.NodeKeyFile()
@ -91,15 +102,18 @@ func initFilesWithConfig(config *cfg.Config) error {
ctx, cancel := context.WithTimeout(context.TODO(), ctxTimeout)
defer cancel()
pubKey, err := pv.GetPubKey(ctx)
if err != nil {
return fmt.Errorf("can't get pubkey: %w", err)
// if this is a validator we add it to genesis
if pv != nil {
pubKey, err := pv.GetPubKey(ctx)
if err != nil {
return fmt.Errorf("can't get pubkey: %w", err)
}
genDoc.Validators = []types.GenesisValidator{{
Address: pubKey.Address(),
PubKey: pubKey,
Power: 10,
}}
}
genDoc.Validators = []types.GenesisValidator{{
Address: pubKey.Address(),
PubKey: pubKey,
Power: 10,
}}
if err := genDoc.SaveAs(genFile); err != nil {
return err
@ -107,5 +121,9 @@ func initFilesWithConfig(config *cfg.Config) error {
logger.Info("Generated genesis file", "path", genFile)
}
// write config file
cfg.WriteConfigFile(config.RootDir, config)
logger.Info("Generated config", "mode", config.Mode)
return nil
}

+ 2
- 3
cmd/tendermint/commands/testnet.go View File

@ -106,8 +106,7 @@ func testnetFiles(cmd *cobra.Command, args []string) error {
}
// set mode to validator for testnet
config := cfg.DefaultConfig()
config.Mode = cfg.ModeValidator
config := cfg.DefaultValidatorConfig()
// overwrite default config if set and valid
if configFile != "" {
@ -242,7 +241,7 @@ func testnetFiles(cmd *cobra.Command, args []string) error {
}
config.Moniker = moniker(i)
cfg.WriteConfigFile(filepath.Join(nodeDir, "config", "config.toml"), config)
cfg.WriteConfigFile(nodeDir, config)
}
fmt.Printf("Successfully initialized %v node directories\n", nValidators+nNonValidators)


+ 13
- 4
config/config.go View File

@ -93,6 +93,13 @@ func DefaultConfig() *Config {
}
}
// DefaultValidatorConfig returns default config with mode as validator
func DefaultValidatorConfig() *Config {
cfg := DefaultConfig()
cfg.Mode = ModeValidator
return cfg
}
// TestConfig returns a configuration that can be used for testing
func TestConfig() *Config {
return &Config{
@ -167,13 +174,13 @@ 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
// Mode of Node: full | validator | seed
// * validator
// - all reactors
// - with priv_validator_key.json, priv_validator_state.json
// * full
// - all reactors
// - No priv_validator_key.json, priv_validator_state.json
// * seed
// - only P2P, PEX Reactor
// - No priv_validator_key.json, priv_validator_state.json
@ -346,6 +353,8 @@ func (cfg BaseConfig) ValidateBasic() error {
}
switch cfg.Mode {
case ModeFull, ModeValidator, ModeSeed:
case "":
return errors.New("no mode has been set")
default:
return fmt.Errorf("unknown mode: %v", cfg.Mode)
}


+ 16
- 23
config/toml.go View File

@ -41,32 +41,29 @@ func EnsureRoot(rootDir string) {
if err := tmos.EnsureDir(filepath.Join(rootDir, defaultDataDir), DefaultDirPerm); err != nil {
panic(err.Error())
}
configFilePath := filepath.Join(rootDir, defaultConfigFilePath)
// Write default config file if missing.
if !tmos.FileExists(configFilePath) {
writeDefaultConfigFile(configFilePath)
}
}
// XXX: this func should probably be called by cmd/tendermint/commands/init.go
// alongside the writing of the genesis.json and priv_validator.json
func writeDefaultConfigFile(configFilePath string) {
WriteConfigFile(configFilePath, DefaultConfig())
}
// WriteConfigFile renders config using the template and writes it to configFilePath.
func WriteConfigFile(configFilePath string, config *Config) {
// This function is called by cmd/tendermint/commands/init.go
func WriteConfigFile(rootDir string, config *Config) {
var buffer bytes.Buffer
if err := configTemplate.Execute(&buffer, config); err != nil {
panic(err)
}
configFilePath := filepath.Join(rootDir, defaultConfigFilePath)
mustWriteFile(configFilePath, buffer.Bytes(), 0644)
}
func writeDefaultConfigFileIfNone(rootDir string) {
configFilePath := filepath.Join(rootDir, defaultConfigFilePath)
if !tmos.FileExists(configFilePath) {
WriteConfigFile(rootDir, DefaultConfig())
}
}
// Note: any changes to the comments/variables/mapstructure
// must be reflected in the appropriate struct in config/config.go
const defaultConfigTemplate = `# This is a TOML config file.
@ -88,14 +85,13 @@ 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
# Mode of Node: full | validator | seed
# * validator node
# - all reactors
# - with priv_validator_key.json, priv_validator_state.json
# * full node
# - all reactors
# - No priv_validator_key.json, priv_validator_state.json
# * seed node
# - only P2P, PEX Reactor
# - No priv_validator_key.json, priv_validator_state.json
@ -502,15 +498,12 @@ func ResetTestRootWithChainID(testName string, chainID string) *Config {
}
baseConfig := DefaultBaseConfig()
configFilePath := filepath.Join(rootDir, defaultConfigFilePath)
genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis)
privKeyFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorKey)
privStateFilePath := filepath.Join(rootDir, baseConfig.PrivValidatorState)
// Write default config file if missing.
if !tmos.FileExists(configFilePath) {
writeDefaultConfigFile(configFilePath)
}
writeDefaultConfigFileIfNone(rootDir)
if !tmos.FileExists(genesisFilePath) {
if chainID == "" {
chainID = "tendermint_test"


+ 2
- 0
config/toml_test.go View File

@ -30,6 +30,8 @@ func TestEnsureRoot(t *testing.T) {
// create root dir
EnsureRoot(tmpDir)
WriteConfigFile(tmpDir, DefaultConfig())
// make sure config is set properly
data, err := ioutil.ReadFile(filepath.Join(tmpDir, defaultConfigFilePath))
require.Nil(err)


+ 1
- 1
docs/app-dev/getting-started.md View File

@ -63,7 +63,7 @@ Tendermint binary installed. If not, follow the steps from
before, use:
```sh
tendermint init
tendermint init validator
tendermint start
```


+ 1
- 1
docs/architecture/adr-008-priv-validator.md View File

@ -4,7 +4,7 @@ Tendermint node's should support only two in-process PrivValidator
implementations:
- FilePV uses an unencrypted private key in a "priv_validator.json" file - no
configuration required (just `tendermint init`).
configuration required (just `tendermint init validator`).
- TCPVal and IPCVal use TCP and Unix sockets respectively to send signing requests
to another process - the user is responsible for starting that process themselves.


+ 4
- 2
docs/architecture/adr-052-tendermint-mode.md View File

@ -4,6 +4,7 @@
* 27-11-2019: Initial draft from ADR-051
* 13-01-2020: Separate ADR Tendermint Mode from ADR-051
* 29-03-2021: Update info regarding defaults
## Context
@ -16,7 +17,7 @@
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
- full *(default)*
- full
- switch, transport
- reactors
- mempool
@ -46,7 +47,8 @@ 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 start --mode validator` in cli
- full | validator | seednode (default: "full")
- full | validator | seednode
- There will be no default. Users will need to specify when they run `tendermint init`
- RPC modification
- `host:26657/status`
- return empty `validator_info` when in full mode


+ 1
- 1
docs/introduction/install.md View File

@ -56,7 +56,7 @@ tendermint version
To start a one-node blockchain with a simple in-process application:
```sh
tendermint init
tendermint init validator
tendermint start --proxy-app=kvstore
```


+ 1
- 1
docs/introduction/quick-start.md View File

@ -34,7 +34,7 @@ For manual installation, see the [install instructions](install.md)
Running:
```sh
tendermint init
tendermint init validator
```
will create the required files for a single, local node.


+ 6
- 7
docs/nodes/configuration.md View File

@ -41,18 +41,17 @@ 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
# Mode of Node: full | validator | seed (default: "validator")
# * validator node (default)
# - all reactors
# - with priv_validator_key.json, priv_validator_state.json
# * full node
# - all reactors
# - No 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"
mode = "validator"
# Database backend: goleveldb | cleveldb | boltdb | rocksdb | badgerdb
# * goleveldb (github.com/syndtr/goleveldb - most popular implementation)


+ 1
- 1
docs/tendermint-core/using-tendermint.md View File

@ -21,7 +21,7 @@ this by setting the `TMHOME` environment variable.
Initialize the root directory by running:
```sh
tendermint init
tendermint init validator
```
This will create a new private key (`priv_validator_key.json`), and a


+ 1
- 1
docs/tools/remote-signer-validation.md View File

@ -75,7 +75,7 @@ example, we will simply export a signing key from our local Tendermint instance.
# Will generate all necessary Tendermint configuration files, including:
# - ~/.tendermint/config/priv_validator_key.json
# - ~/.tendermint/data/priv_validator_state.json
tendermint init
tendermint init validator
# Extract the signing key from our local Tendermint instance
tm-signer-harness extract_key \ # Use the "extract_key" command


+ 5
- 4
docs/tutorials/go-built-in.md View File

@ -393,7 +393,7 @@ func main() {
func newTendermint(app abci.Application, configFile string) (*nm.Node, error) {
// read config
config := cfg.DefaultConfig()
config := cfg.DefaultValidatorConfig()
config.RootDir = filepath.Dir(filepath.Dir(configFile))
viper.SetConfigFile(configFile)
if err := viper.ReadInConfig(); err != nil {
@ -503,7 +503,7 @@ of one communicating through a socket or gRPC.
which we will generate later using the `tendermint init` command.
```go
config := cfg.DefaultConfig()
config := cfg.DefaultValidatorConfig()
config.RootDir = filepath.Dir(filepath.Dir(configFile))
viper.SetConfigFile(configFile)
if err := viper.ReadInConfig(); err != nil {
@ -604,7 +604,7 @@ go build
```
To create a default configuration, nodeKey and private validator files, let's
execute `tendermint init`. But before we do that, we will need to install
execute `tendermint init validator`. But before we do that, we will need to install
Tendermint Core. Please refer to [the official
guide](https://docs.tendermint.com/master/introduction/install.html). If you're
installing from source, don't forget to checkout the latest release (`git
@ -613,11 +613,12 @@ major version.
```bash
$ rm -rf /tmp/example
$ TMHOME="/tmp/example" tendermint init
$ TMHOME="/tmp/example" tendermint init validator
I[2019-07-16|18:40:36.480] Generated private validator module=main keyFile=/tmp/example/config/priv_validator_key.json stateFile=/tmp/example2/data/priv_validator_state.json
I[2019-07-16|18:40:36.481] Generated node key module=main path=/tmp/example/config/node_key.json
I[2019-07-16|18:40:36.482] Generated genesis file module=main path=/tmp/example/config/genesis.json
I[2019-07-16|18:40:36.483] Generated config module=main mode=validator
```
We are ready to start our application:


+ 3
- 2
docs/tutorials/go.md View File

@ -461,7 +461,7 @@ go build
```
To create a default configuration, nodeKey and private validator files, let's
execute `tendermint init`. But before we do that, we will need to install
execute `tendermint init validator`. But before we do that, we will need to install
Tendermint Core. Please refer to [the official
guide](https://docs.tendermint.com/master/introduction/install.html). If you're
installing from source, don't forget to checkout the latest release (`git
@ -470,11 +470,12 @@ major version.
```bash
rm -rf /tmp/example
TMHOME="/tmp/example" tendermint init
TMHOME="/tmp/example" tendermint init validator
I[2019-07-16|18:20:36.480] Generated private validator module=main keyFile=/tmp/example/config/priv_validator_key.json stateFile=/tmp/example2/data/priv_validator_state.json
I[2019-07-16|18:20:36.481] Generated node key module=main path=/tmp/example/config/node_key.json
I[2019-07-16|18:20:36.482] Generated genesis file module=main path=/tmp/example/config/genesis.json
I[2019-07-16|18:20:36.483] Generated config module=main mode=validator
```
Feel free to explore the generated files, which can be found at


+ 2
- 1
docs/tutorials/java.md View File

@ -550,11 +550,12 @@ Tendermint Core.
$ rm -rf /tmp/example
$ cd $GOPATH/src/github.com/tendermint/tendermint
$ make install
$ TMHOME="/tmp/example" tendermint init
$ TMHOME="/tmp/example" tendermint init validator
I[2019-07-16|18:20:36.480] Generated private validator module=main keyFile=/tmp/example/config/priv_validator_key.json stateFile=/tmp/example2/data/priv_validator_state.json
I[2019-07-16|18:20:36.481] Generated node key module=main path=/tmp/example/config/node_key.json
I[2019-07-16|18:20:36.482] Generated genesis file module=main path=/tmp/example/config/genesis.json
I[2019-07-16|18:20:36.483] Generated config module=main mode=validator
```
Feel free to explore the generated files, which can be found at


+ 3
- 2
docs/tutorials/kotlin.md View File

@ -517,18 +517,19 @@ class GrpcServer(
## 1.5 Getting Up and Running
To create a default configuration, nodeKey and private validator files, let's
execute `tendermint init`. But before we do that, we will need to install
execute `tendermint init validator`. But before we do that, we will need to install
Tendermint Core.
```bash
rm -rf /tmp/example
cd $GOPATH/src/github.com/tendermint/tendermint
make install
TMHOME="/tmp/example" tendermint init
TMHOME="/tmp/example" tendermint init validator
I[2019-07-16|18:20:36.480] Generated private validator module=main keyFile=/tmp/example/config/priv_validator_key.json stateFile=/tmp/example2/data/priv_validator_state.json
I[2019-07-16|18:20:36.481] Generated node key module=main path=/tmp/example/config/node_key.json
I[2019-07-16|18:20:36.482] Generated genesis file module=main path=/tmp/example/config/genesis.json
I[2019-07-16|18:20:36.482] Generated config module=main mode=validator
```
Feel free to explore the generated files, which can be found at


+ 5
- 5
test/app/test.sh View File

@ -13,7 +13,7 @@ export TMHOME=$HOME/.tendermint_app
function kvstore_over_socket(){
rm -rf $TMHOME
tendermint init
tendermint init validator
echo "Starting kvstore_over_socket"
abci-cli kvstore > /dev/null &
pid_kvstore=$!
@ -30,7 +30,7 @@ function kvstore_over_socket(){
# start tendermint first
function kvstore_over_socket_reorder(){
rm -rf $TMHOME
tendermint init
tendermint init validator
echo "Starting kvstore_over_socket_reorder (ie. start tendermint first)"
tendermint start --mode validator > tendermint.log &
pid_tendermint=$!
@ -48,7 +48,7 @@ function kvstore_over_socket_reorder(){
function counter_over_socket() {
rm -rf $TMHOME
tendermint init
tendermint init validator
echo "Starting counter_over_socket"
abci-cli counter --serial > /dev/null &
pid_counter=$!
@ -64,7 +64,7 @@ function counter_over_socket() {
function counter_over_grpc() {
rm -rf $TMHOME
tendermint init
tendermint init validator
echo "Starting counter_over_grpc"
abci-cli counter --serial --abci grpc > /dev/null &
pid_counter=$!
@ -80,7 +80,7 @@ function counter_over_grpc() {
function counter_over_grpc_grpc() {
rm -rf $TMHOME
tendermint init
tendermint init validator
echo "Starting counter_over_grpc_grpc (ie. with grpc broadcast_tx)"
abci-cli counter --serial --abci grpc > /dev/null &
pid_counter=$!


+ 1
- 1
test/e2e/runner/setup.go View File

@ -85,7 +85,7 @@ func Setup(testnet *e2e.Testnet) error {
if err != nil {
return err
}
config.WriteConfigFile(filepath.Join(nodeDir, "config", "config.toml"), cfg) // panics
config.WriteConfigFile(nodeDir, cfg) // panics
appCfg, err := MakeAppConfig(node)
if err != nil {


Loading…
Cancel
Save