Merge pull request #792 from tendermint/config

Config Improvements
This commit is contained in:
Ethan Buchman 2018-01-10 14:41:30 -05:00 committed by GitHub
commit a13b17ec6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 459 additions and 140 deletions

View File

@ -5,6 +5,7 @@
BREAKING CHANGES: BREAKING CHANGES:
- Better support for injecting randomness - Better support for injecting randomness
- Upgrade consensus for more real-time use of evidence - Upgrade consensus for more real-time use of evidence
- the files usually found in `~/.tendermint` (`config.toml`, `genesis.json`, and `priv_validator.json`) are now in `~/.tendermint/config`. The `$TMHOME/data/` directory remains unchanged.
FEATURES: FEATURES:
- Peer reputation management - Peer reputation management

View File

@ -2,11 +2,12 @@ package commands
import ( import (
"fmt" "fmt"
"path" "path/filepath"
"time" "time"
"github.com/spf13/cobra" "github.com/spf13/cobra"
cfg "github.com/tendermint/tendermint/config"
"github.com/tendermint/tendermint/types" "github.com/tendermint/tendermint/types"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
) )
@ -35,6 +36,7 @@ var TestnetFilesCmd = &cobra.Command{
func testnetFiles(cmd *cobra.Command, args []string) { func testnetFiles(cmd *cobra.Command, args []string) {
genVals := make([]types.GenesisValidator, nValidators) genVals := make([]types.GenesisValidator, nValidators)
defaultConfig := cfg.DefaultBaseConfig()
// Initialize core dir and priv_validator.json's // Initialize core dir and priv_validator.json's
for i := 0; i < nValidators; i++ { for i := 0; i < nValidators; i++ {
@ -44,7 +46,7 @@ func testnetFiles(cmd *cobra.Command, args []string) {
cmn.Exit(err.Error()) cmn.Exit(err.Error())
} }
// Read priv_validator.json to populate vals // Read priv_validator.json to populate vals
privValFile := path.Join(dataDir, mach, "priv_validator.json") privValFile := filepath.Join(dataDir, mach, defaultConfig.PrivValidator)
privVal := types.LoadPrivValidatorFS(privValFile) privVal := types.LoadPrivValidatorFS(privValFile)
genVals[i] = types.GenesisValidator{ genVals[i] = types.GenesisValidator{
PubKey: privVal.GetPubKey(), PubKey: privVal.GetPubKey(),
@ -63,7 +65,7 @@ func testnetFiles(cmd *cobra.Command, args []string) {
// Write genesis file. // Write genesis file.
for i := 0; i < nValidators; i++ { for i := 0; i < nValidators; i++ {
mach := cmn.Fmt("mach%d", i) mach := cmn.Fmt("mach%d", i)
if err := genDoc.SaveAs(path.Join(dataDir, mach, "genesis.json")); err != nil { if err := genDoc.SaveAs(filepath.Join(dataDir, mach, defaultConfig.Genesis)); err != nil {
panic(err) panic(err)
} }
} }
@ -73,14 +75,15 @@ func testnetFiles(cmd *cobra.Command, args []string) {
// Initialize per-machine core directory // Initialize per-machine core directory
func initMachCoreDirectory(base, mach string) error { func initMachCoreDirectory(base, mach string) error {
dir := path.Join(base, mach) dir := filepath.Join(base, mach)
err := cmn.EnsureDir(dir, 0777) err := cmn.EnsureDir(dir, 0777)
if err != nil { if err != nil {
return err return err
} }
// Create priv_validator.json file if not present // Create priv_validator.json file if not present
ensurePrivValidator(path.Join(dir, "priv_validator.json")) defaultConfig := cfg.DefaultBaseConfig()
ensurePrivValidator(filepath.Join(dir, defaultConfig.PrivValidator))
return nil return nil
} }

View File

@ -2,10 +2,12 @@ package main
import ( import (
"os" "os"
"path/filepath"
"github.com/tendermint/tmlibs/cli" "github.com/tendermint/tmlibs/cli"
cmd "github.com/tendermint/tendermint/cmd/tendermint/commands" cmd "github.com/tendermint/tendermint/cmd/tendermint/commands"
cfg "github.com/tendermint/tendermint/config"
nm "github.com/tendermint/tendermint/node" nm "github.com/tendermint/tendermint/node"
) )
@ -37,7 +39,7 @@ func main() {
// Create & start node // Create & start node
rootCmd.AddCommand(cmd.NewRunNodeCmd(nodeFunc)) rootCmd.AddCommand(cmd.NewRunNodeCmd(nodeFunc))
cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv("$HOME/.tendermint")) cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultTendermintDir)))
if err := cmd.Execute(); err != nil { if err := cmd.Execute(); err != nil {
panic(err) panic(err)
} }

View File

@ -7,6 +7,25 @@ import (
"time" "time"
) )
// Note: Most of the structs & relevant comments + the
// default configuration options were used to manually
// generate the config.toml. Please reflect any changes
// made here in the defaultConfigTemplate constant in
// config/toml.go
var (
DefaultTendermintDir = ".tendermint"
defaultConfigDir = "config"
defaultDataDir = "data"
defaultConfigFileName = "config.toml"
defaultGenesisJSONName = "genesis.json"
defaultPrivValName = "priv_validator.json"
defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName)
defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName)
defaultPrivValPath = filepath.Join(defaultConfigDir, defaultPrivValName)
)
// Config defines the top level configuration for a Tendermint node // Config defines the top level configuration for a Tendermint node
type Config struct { type Config struct {
// Top level options use an anonymous struct // Top level options use an anonymous struct
@ -59,17 +78,18 @@ func (cfg *Config) SetRoot(root string) *Config {
// BaseConfig defines the base configuration for a Tendermint node // BaseConfig defines the base configuration for a Tendermint node
type BaseConfig struct { type BaseConfig struct {
// chainID is unexposed and immutable but here for convenience
chainID string
// The root directory for all data. // The root directory for all data.
// This should be set in viper so it can unmarshal into this struct // This should be set in viper so it can unmarshal into this struct
RootDir string `mapstructure:"home"` RootDir string `mapstructure:"home"`
// The ID of the chain to join (should be signed with every transaction and vote) // Path to the JSON file containing the initial validator set and other meta data
ChainID string `mapstructure:"chain_id"`
// A JSON file containing the initial validator set and other meta data
Genesis string `mapstructure:"genesis_file"` Genesis string `mapstructure:"genesis_file"`
// A JSON file containing the private key to use as a validator in the consensus protocol // Path to the JSON file containing the private key to use as a validator in the consensus protocol
PrivValidator string `mapstructure:"priv_validator_file"` PrivValidator string `mapstructure:"priv_validator_file"`
// A custom human readable name for this node // A custom human readable name for this node
@ -104,11 +124,15 @@ type BaseConfig struct {
DBPath string `mapstructure:"db_dir"` DBPath string `mapstructure:"db_dir"`
} }
func (c BaseConfig) ChainID() string {
return c.chainID
}
// DefaultBaseConfig returns a default base configuration for a Tendermint node // DefaultBaseConfig returns a default base configuration for a Tendermint node
func DefaultBaseConfig() BaseConfig { func DefaultBaseConfig() BaseConfig {
return BaseConfig{ return BaseConfig{
Genesis: "genesis.json", Genesis: defaultGenesisJSONPath,
PrivValidator: "priv_validator.json", PrivValidator: defaultPrivValPath,
Moniker: defaultMoniker, Moniker: defaultMoniker,
ProxyApp: "tcp://127.0.0.1:46658", ProxyApp: "tcp://127.0.0.1:46658",
ABCI: "socket", ABCI: "socket",
@ -124,7 +148,7 @@ func DefaultBaseConfig() BaseConfig {
// TestBaseConfig returns a base configuration for testing a Tendermint node // TestBaseConfig returns a base configuration for testing a Tendermint node
func TestBaseConfig() BaseConfig { func TestBaseConfig() BaseConfig {
conf := DefaultBaseConfig() conf := DefaultBaseConfig()
conf.ChainID = "tendermint_test" conf.chainID = "tendermint_test"
conf.ProxyApp = "dummy" conf.ProxyApp = "dummy"
conf.FastSync = false conf.FastSync = false
conf.DBBackend = "memdb" conf.DBBackend = "memdb"
@ -279,7 +303,7 @@ func DefaultMempoolConfig() *MempoolConfig {
Recheck: true, Recheck: true,
RecheckEmpty: true, RecheckEmpty: true,
Broadcast: true, Broadcast: true,
WalPath: "data/mempool.wal", WalPath: filepath.Join(defaultDataDir, "mempool.wal"),
} }
} }
@ -299,7 +323,7 @@ type ConsensusConfig struct {
WalLight bool `mapstructure:"wal_light"` WalLight bool `mapstructure:"wal_light"`
walFile string // overrides WalPath if set walFile string // overrides WalPath if set
// All timeouts are in ms // All timeouts are in milliseconds
TimeoutPropose int `mapstructure:"timeout_propose"` TimeoutPropose int `mapstructure:"timeout_propose"`
TimeoutProposeDelta int `mapstructure:"timeout_propose_delta"` TimeoutProposeDelta int `mapstructure:"timeout_propose_delta"`
TimeoutPrevote int `mapstructure:"timeout_prevote"` TimeoutPrevote int `mapstructure:"timeout_prevote"`
@ -319,7 +343,7 @@ type ConsensusConfig struct {
CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"` CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"`
CreateEmptyBlocksInterval int `mapstructure:"create_empty_blocks_interval"` CreateEmptyBlocksInterval int `mapstructure:"create_empty_blocks_interval"`
// Reactor sleep duration parameters are in ms // Reactor sleep duration parameters are in milliseconds
PeerGossipSleepDuration int `mapstructure:"peer_gossip_sleep_duration"` PeerGossipSleepDuration int `mapstructure:"peer_gossip_sleep_duration"`
PeerQueryMaj23SleepDuration int `mapstructure:"peer_query_maj23_sleep_duration"` PeerQueryMaj23SleepDuration int `mapstructure:"peer_query_maj23_sleep_duration"`
} }
@ -367,7 +391,7 @@ func (cfg *ConsensusConfig) PeerQueryMaj23Sleep() time.Duration {
// DefaultConsensusConfig returns a default configuration for the consensus service // DefaultConsensusConfig returns a default configuration for the consensus service
func DefaultConsensusConfig() *ConsensusConfig { func DefaultConsensusConfig() *ConsensusConfig {
return &ConsensusConfig{ return &ConsensusConfig{
WalPath: "data/cs.wal/wal", WalPath: filepath.Join(defaultDataDir, "cs.wal", "wal"),
WalLight: false, WalLight: false,
TimeoutPropose: 3000, TimeoutPropose: 3000,
TimeoutProposeDelta: 500, TimeoutProposeDelta: 500,

View File

@ -1,52 +1,207 @@
package config package config
import ( import (
"bytes"
"os" "os"
"path"
"path/filepath" "path/filepath"
"strings" "text/template"
cmn "github.com/tendermint/tmlibs/common" cmn "github.com/tendermint/tmlibs/common"
) )
var configTemplate *template.Template
func init() {
var err error
if configTemplate, err = template.New("configFileTemplate").Parse(defaultConfigTemplate); err != nil {
panic(err)
}
}
/****** these are for production settings ***********/ /****** these are for production settings ***********/
func EnsureRoot(rootDir string) { func EnsureRoot(rootDir string) {
if err := cmn.EnsureDir(rootDir, 0700); err != nil { if err := cmn.EnsureDir(rootDir, 0700); err != nil {
cmn.PanicSanity(err.Error()) cmn.PanicSanity(err.Error())
} }
if err := cmn.EnsureDir(rootDir+"/data", 0700); err != nil { if err := cmn.EnsureDir(filepath.Join(rootDir, defaultConfigDir), 0700); err != nil {
cmn.PanicSanity(err.Error())
}
if err := cmn.EnsureDir(filepath.Join(rootDir, defaultDataDir), 0700); err != nil {
cmn.PanicSanity(err.Error()) cmn.PanicSanity(err.Error())
} }
configFilePath := path.Join(rootDir, "config.toml") configFilePath := filepath.Join(rootDir, defaultConfigFilePath)
// Write default config file if missing. // Write default config file if missing.
if !cmn.FileExists(configFilePath) { if !cmn.FileExists(configFilePath) {
cmn.MustWriteFile(configFilePath, []byte(defaultConfig(defaultMoniker)), 0644) writeConfigFile(configFilePath)
} }
} }
var defaultConfigTmpl = `# This is a TOML config file. // 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 writeConfigFile(configFilePath string) {
var buffer bytes.Buffer
if err := configTemplate.Execute(&buffer, DefaultConfig()); err != nil {
panic(err)
}
cmn.MustWriteFile(configFilePath, buffer.Bytes(), 0644)
}
// 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.
# For more information, see https://github.com/toml-lang/toml # For more information, see https://github.com/toml-lang/toml
proxy_app = "tcp://127.0.0.1:46658" ##### main base config options #####
moniker = "__MONIKER__"
fast_sync = true
db_backend = "leveldb"
log_level = "state:info,*:error"
# TCP or UNIX socket address of the ABCI application,
# or the name of an ABCI application compiled in with the Tendermint binary
proxy_app = "{{ .BaseConfig.ProxyApp }}"
# A custom human readable name for this node
moniker = "{{ .BaseConfig.Moniker }}"
# 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
fast_sync = {{ .BaseConfig.FastSync }}
# Database backend: leveldb | memdb
db_backend = "{{ .BaseConfig.DBBackend }}"
# Database directory
db_path = "{{ .BaseConfig.DBPath }}"
# Output level for logging, including package level options
log_level = "{{ .BaseConfig.LogLevel }}"
##### additional base config options #####
# Path to the JSON file containing the initial validator set and other meta data
genesis_file = "{{ .BaseConfig.Genesis }}"
# Path to the JSON file containing the private key to use as a validator in the consensus protocol
priv_validator_file = "{{ .BaseConfig.PrivValidator }}"
# Mechanism to connect to the ABCI application: socket | grpc
abci = "{{ .BaseConfig.ABCI }}"
# TCP or UNIX socket address for the profiling server to listen on
prof_laddr = "{{ .BaseConfig.ProfListenAddress }}"
# If true, query the ABCI app on connecting to a new peer
# so the app can decide if we should keep the connection or not
filter_peers = {{ .BaseConfig.FilterPeers }}
##### advanced configuration options #####
##### rpc server configuration options #####
[rpc] [rpc]
laddr = "tcp://0.0.0.0:46657"
# TCP or UNIX socket address for the RPC server to listen on
laddr = "{{ .RPC.ListenAddress }}"
# TCP or UNIX socket address for the gRPC server to listen on
# NOTE: This server only supports /broadcast_tx_commit
grpc_laddr = "{{ .RPC.GRPCListenAddress }}"
# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool
unsafe = {{ .RPC.Unsafe }}
##### peer to peer configuration options #####
[p2p] [p2p]
laddr = "tcp://0.0.0.0:46656"
seeds = ""
`
func defaultConfig(moniker string) string { # Address to listen for incoming connections
return strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1) laddr = "{{ .P2P.ListenAddress }}"
}
# Comma separated list of seed nodes to connect to
seeds = ""
# Path to address book
addr_book_file = "{{ .P2P.AddrBook }}"
# Set true for strict address routability rules
addr_book_strict = {{ .P2P.AddrBookStrict }}
# Time to wait before flushing messages out on the connection, in ms
flush_throttle_timeout = {{ .P2P.FlushThrottleTimeout }}
# Maximum number of peers to connect to
max_num_peers = {{ .P2P.MaxNumPeers }}
# Maximum size of a message packet payload, in bytes
max_msg_packet_payload_size = {{ .P2P.MaxMsgPacketPayloadSize }}
# Rate at which packets can be sent, in bytes/second
send_rate = {{ .P2P.SendRate }}
# Rate at which packets can be received, in bytes/second
recv_rate = {{ .P2P.RecvRate }}
##### mempool configuration options #####
[mempool]
recheck = {{ .Mempool.Recheck }}
recheck_empty = {{ .Mempool.RecheckEmpty }}
broadcast = {{ .Mempool.Broadcast }}
wal_dir = "{{ .Mempool.WalPath }}"
##### consensus configuration options #####
[consensus]
wal_file = "{{ .Consensus.WalPath }}"
wal_light = {{ .Consensus.WalLight }}
# All timeouts are in milliseconds
timeout_propose = {{ .Consensus.TimeoutPropose }}
timeout_propose_delta = {{ .Consensus.TimeoutProposeDelta }}
timeout_prevote = {{ .Consensus.TimeoutPrevote }}
timeout_prevote_delta = {{ .Consensus.TimeoutPrevoteDelta }}
timeout_precommit = {{ .Consensus.TimeoutPrecommit }}
timeout_precommit_delta = {{ .Consensus.TimeoutPrecommitDelta }}
timeout_commit = {{ .Consensus.TimeoutCommit }}
# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
skip_timeout_commit = {{ .Consensus.SkipTimeoutCommit }}
# BlockSize
max_block_size_txs = {{ .Consensus.MaxBlockSizeTxs }}
max_block_size_bytes = {{ .Consensus.MaxBlockSizeBytes }}
# EmptyBlocks mode and possible interval between empty blocks in seconds
create_empty_blocks = {{ .Consensus.CreateEmptyBlocks }}
create_empty_blocks_interval = {{ .Consensus.CreateEmptyBlocksInterval }}
# Reactor sleep duration parameters are in milliseconds
peer_gossip_sleep_duration = {{ .Consensus.PeerGossipSleepDuration }}
peer_query_maj23_sleep_duration = {{ .Consensus.PeerQueryMaj23SleepDuration }}
##### transactions indexer configuration options #####
[tx_index]
# What indexer to use for transactions
#
# Options:
# 1) "null" (default)
# 2) "kv" - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).
indexer = "{{ .TxIndex.Indexer }}"
# Comma-separated list of tags to index (by default the only tag is tx hash)
#
# It's recommended to index only a subset of tags due to possible memory
# bloat. This is, of course, depends on the indexer's DB and the volume of
# transactions.
index_tags = "{{ .TxIndex.IndexTags }}"
# When set to true, tells indexer to index all tags. Note this may be not
# desirable (see the comment above). IndexTags has a precedence over
# IndexAllTags (i.e. when given both, IndexTags will be indexed).
index_all_tags = {{ .TxIndex.IndexAllTags }}
`
/****** these are for test settings ***********/ /****** these are for test settings ***********/
@ -69,17 +224,21 @@ func ResetTestRoot(testName string) *Config {
if err := cmn.EnsureDir(rootDir, 0700); err != nil { if err := cmn.EnsureDir(rootDir, 0700); err != nil {
cmn.PanicSanity(err.Error()) cmn.PanicSanity(err.Error())
} }
if err := cmn.EnsureDir(rootDir+"/data", 0700); err != nil { if err := cmn.EnsureDir(filepath.Join(rootDir, defaultConfigDir), 0700); err != nil {
cmn.PanicSanity(err.Error())
}
if err := cmn.EnsureDir(filepath.Join(rootDir, defaultDataDir), 0700); err != nil {
cmn.PanicSanity(err.Error()) cmn.PanicSanity(err.Error())
} }
configFilePath := path.Join(rootDir, "config.toml") baseConfig := DefaultBaseConfig()
genesisFilePath := path.Join(rootDir, "genesis.json") configFilePath := filepath.Join(rootDir, defaultConfigFilePath)
privFilePath := path.Join(rootDir, "priv_validator.json") genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis)
privFilePath := filepath.Join(rootDir, baseConfig.PrivValidator)
// Write default config file if missing. // Write default config file if missing.
if !cmn.FileExists(configFilePath) { if !cmn.FileExists(configFilePath) {
cmn.MustWriteFile(configFilePath, []byte(testConfig(defaultMoniker)), 0644) writeConfigFile(configFilePath)
} }
if !cmn.FileExists(genesisFilePath) { if !cmn.FileExists(genesisFilePath) {
cmn.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644) cmn.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644)
@ -91,28 +250,6 @@ func ResetTestRoot(testName string) *Config {
return config return config
} }
var testConfigTmpl = `# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml
proxy_app = "dummy"
moniker = "__MONIKER__"
fast_sync = false
db_backend = "memdb"
log_level = "info"
[rpc]
laddr = "tcp://0.0.0.0:36657"
[p2p]
laddr = "tcp://0.0.0.0:36656"
seeds = ""
`
func testConfig(moniker string) (testConfig string) {
testConfig = strings.Replace(testConfigTmpl, "__MONIKER__", moniker, -1)
return
}
var testGenesis = `{ var testGenesis = `{
"genesis_time": "0001-01-01T00:00:00.000Z", "genesis_time": "0001-01-01T00:00:00.000Z",
"chain_id": "tendermint_test", "chain_id": "tendermint_test",

View File

@ -4,6 +4,7 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"strings"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -19,7 +20,7 @@ func ensureFiles(t *testing.T, rootDir string, files ...string) {
} }
func TestEnsureRoot(t *testing.T) { func TestEnsureRoot(t *testing.T) {
assert, require := assert.New(t), require.New(t) require := require.New(t)
// setup temp dir for test // setup temp dir for test
tmpDir, err := ioutil.TempDir("", "config-test") tmpDir, err := ioutil.TempDir("", "config-test")
@ -30,15 +31,18 @@ func TestEnsureRoot(t *testing.T) {
EnsureRoot(tmpDir) EnsureRoot(tmpDir)
// make sure config is set properly // make sure config is set properly
data, err := ioutil.ReadFile(filepath.Join(tmpDir, "config.toml")) data, err := ioutil.ReadFile(filepath.Join(tmpDir, defaultConfigFilePath))
require.Nil(err) require.Nil(err)
assert.Equal([]byte(defaultConfig(defaultMoniker)), data)
if !checkConfig(string(data)) {
t.Fatalf("config file missing some information")
}
ensureFiles(t, tmpDir, "data") ensureFiles(t, tmpDir, "data")
} }
func TestEnsureTestRoot(t *testing.T) { func TestEnsureTestRoot(t *testing.T) {
assert, require := assert.New(t), require.New(t) require := require.New(t)
testName := "ensureTestRoot" testName := "ensureTestRoot"
@ -47,11 +51,44 @@ func TestEnsureTestRoot(t *testing.T) {
rootDir := cfg.RootDir rootDir := cfg.RootDir
// make sure config is set properly // make sure config is set properly
data, err := ioutil.ReadFile(filepath.Join(rootDir, "config.toml")) data, err := ioutil.ReadFile(filepath.Join(rootDir, defaultConfigFilePath))
require.Nil(err) require.Nil(err)
assert.Equal([]byte(testConfig(defaultMoniker)), data)
if !checkConfig(string(data)) {
t.Fatalf("config file missing some information")
}
// TODO: make sure the cfg returned and testconfig are the same! // TODO: make sure the cfg returned and testconfig are the same!
baseConfig := DefaultBaseConfig()
ensureFiles(t, rootDir, "data", "genesis.json", "priv_validator.json") ensureFiles(t, rootDir, defaultDataDir, baseConfig.Genesis, baseConfig.PrivValidator)
}
func checkConfig(configFile string) bool {
var valid bool
// list of words we expect in the config
var elems = []string{
"moniker",
"seeds",
"proxy_app",
"fast_sync",
"create_empty_blocks",
"peer",
"timeout",
"broadcast",
"send",
"addr",
"wal",
"propose",
"max",
"genesis",
}
for _, e := range elems {
if !strings.Contains(configFile, e) {
valid = false
} else {
valid = true
}
}
return valid
} }

View File

@ -78,7 +78,7 @@ func (vs *validatorStub) signVote(voteType byte, hash []byte, header types.PartS
Type: voteType, Type: voteType,
BlockID: types.BlockID{hash, header}, BlockID: types.BlockID{hash, header},
} }
err := vs.PrivValidator.SignVote(config.ChainID, vote) err := vs.PrivValidator.SignVote(config.ChainID(), vote)
return vote, err return vote, err
} }
@ -129,7 +129,7 @@ func decideProposal(cs1 *ConsensusState, vs *validatorStub, height int64, round
// Make proposal // Make proposal
polRound, polBlockID := cs1.Votes.POLInfo() polRound, polBlockID := cs1.Votes.POLInfo()
proposal = types.NewProposal(height, round, blockParts.Header(), polRound, polBlockID) proposal = types.NewProposal(height, round, blockParts.Header(), polRound, polBlockID)
if err := vs.SignProposal(config.ChainID, proposal); err != nil { if err := vs.SignProposal(cs1.state.ChainID, proposal); err != nil {
panic(err) panic(err)
} }
return return
@ -426,9 +426,10 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G
privValidators[i] = privVal privValidators[i] = privVal
} }
sort.Sort(types.PrivValidatorsByAddress(privValidators)) sort.Sort(types.PrivValidatorsByAddress(privValidators))
return &types.GenesisDoc{ return &types.GenesisDoc{
GenesisTime: time.Now(), GenesisTime: time.Now(),
ChainID: config.ChainID, ChainID: config.ChainID(),
Validators: validators, Validators: validators,
}, privValidators }, privValidators
} }

View File

@ -204,7 +204,7 @@ func TestBadProposal(t *testing.T) {
propBlock.AppHash = stateHash propBlock.AppHash = stateHash
propBlockParts := propBlock.MakePartSet(partSize) propBlockParts := propBlock.MakePartSet(partSize)
proposal := types.NewProposal(vs2.Height, round, propBlockParts.Header(), -1, types.BlockID{}) proposal := types.NewProposal(vs2.Height, round, propBlockParts.Header(), -1, types.BlockID{})
if err := vs2.SignProposal(config.ChainID, proposal); err != nil { if err := vs2.SignProposal(config.ChainID(), proposal); err != nil {
t.Fatal("failed to sign bad proposal", err) t.Fatal("failed to sign bad proposal", err)
} }
@ -900,7 +900,7 @@ func TestLockPOLSafety2(t *testing.T) {
// in round 2 we see the polkad block from round 0 // in round 2 we see the polkad block from round 0
newProp := types.NewProposal(height, 2, propBlockParts0.Header(), 0, propBlockID1) newProp := types.NewProposal(height, 2, propBlockParts0.Header(), 0, propBlockID1)
if err := vs3.SignProposal(config.ChainID, newProp); err != nil { if err := vs3.SignProposal(config.ChainID(), newProp); err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := cs1.SetProposalAndBlock(newProp, propBlock0, propBlockParts0, "some peer"); err != nil { if err := cs1.SetProposalAndBlock(newProp, propBlock0, propBlockParts0, "some peer"); err != nil {

View File

@ -18,7 +18,7 @@ func init() {
func TestPeerCatchupRounds(t *testing.T) { func TestPeerCatchupRounds(t *testing.T) {
valSet, privVals := types.RandValidatorSet(10, 1) valSet, privVals := types.RandValidatorSet(10, 1)
hvs := NewHeightVoteSet(config.ChainID, 1, valSet) hvs := NewHeightVoteSet(config.ChainID(), 1, valSet)
vote999_0 := makeVoteHR(t, 1, 999, privVals, 0) vote999_0 := makeVoteHR(t, 1, 999, privVals, 0)
added, err := hvs.AddVote(vote999_0, "peer1") added, err := hvs.AddVote(vote999_0, "peer1")
@ -59,7 +59,7 @@ func makeVoteHR(t *testing.T, height int64, round int, privVals []*types.PrivVal
Type: types.VoteTypePrecommit, Type: types.VoteTypePrecommit,
BlockID: types.BlockID{[]byte("fakehash"), types.PartSetHeader{}}, BlockID: types.BlockID{[]byte("fakehash"), types.PartSetHeader{}},
} }
chainID := config.ChainID chainID := config.ChainID()
err := privVal.SignVote(chainID, vote) err := privVal.SignVote(chainID, vote)
if err != nil { if err != nil {
panic(cmn.Fmt("Error signing vote: %v", err)) panic(cmn.Fmt("Error signing vote: %v", err))

View File

@ -13,7 +13,7 @@ It's relatively easy to setup a Tendermint cluster manually. The only
requirements for a particular Tendermint node are a private key for the requirements for a particular Tendermint node are a private key for the
validator, stored as ``priv_validator.json``, and a list of the public validator, stored as ``priv_validator.json``, and a list of the public
keys of all validators, stored as ``genesis.json``. These files should keys of all validators, stored as ``genesis.json``. These files should
be stored in ``~/.tendermint``, or wherever the ``$TMHOME`` variable be stored in ``~/.tendermint/config``, or wherever the ``$TMHOME`` variable
might be set to. might be set to.
Here are the steps to setting up a testnet manually: Here are the steps to setting up a testnet manually:

View File

@ -1,58 +1,170 @@
Configuration Configuration
============= =============
TendermintCore can be configured via a TOML file in Tendermint Core can be configured via a TOML file in
``$TMHOME/config.toml``. Some of these parameters can be overridden by ``$TMHOME/config/config.toml``. Some of these parameters can be overridden by
command-line flags. command-line flags. For most users, the options in the ``##### main
base configuration options #####`` are intended to be modified while
config options further below are intended for advance power users.
Config parameters Config options
~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~
The main config parameters are defined The default configuration file create by ``tendermint init`` has all
`here <https://github.com/tendermint/tendermint/blob/master/config/config.go>`__. the parameters set with their default values. It will look something
like the file below, however, double check by inspecting the
``config.toml`` created with your version of ``tendermint`` installed:
- ``abci``: ABCI transport (socket \| grpc). *Default*: ``socket`` ::
- ``db_backend``: Database backend for the blockchain and
TendermintCore state. ``leveldb`` or ``memdb``. *Default*:
``"leveldb"``
- ``db_dir``: Database dir. *Default*: ``"$TMHOME/data"``
- ``fast_sync``: Whether to sync faster from the block pool. *Default*:
``true``
- ``genesis_file``: The location of the genesis file. *Default*:
``"$TMHOME/genesis.json"``
- ``log_level``: *Default*: ``"state:info,*:error"``
- ``moniker``: Name of this node. *Default*: the host name or ``"anonymous"``
if runtime fails to get the host name
- ``priv_validator_file``: Validator private key file. *Default*:
``"$TMHOME/priv_validator.json"``
- ``prof_laddr``: Profile listen address. *Default*: ``""``
- ``proxy_app``: The ABCI app endpoint. *Default*:
``"tcp://127.0.0.1:46658"``
- ``consensus.max_block_size_txs``: Maximum number of block txs. # This is a TOML config file.
*Default*: ``10000`` # For more information, see https://github.com/toml-lang/toml
- ``consensus.create_empty_blocks``: Create empty blocks w/o txs.
*Default*: ``true``
- ``consensus.create_empty_blocks_interval``: Block creation interval, even if empty.
- ``consensus.timeout_*``: Various consensus timeout parameters
- ``consensus.wal_file``: Consensus state WAL. *Default*:
``"$TMHOME/data/cs.wal/wal"``
- ``consensus.wal_light``: Whether to use light-mode for Consensus
state WAL. *Default*: ``false``
- ``mempool.*``: Various mempool parameters ##### main base config options #####
- ``p2p.addr_book_file``: Peer address book. *Default*: # TCP or UNIX socket address of the ABCI application,
``"$TMHOME/addrbook.json"``. **NOT USED** # or the name of an ABCI application compiled in with the Tendermint binary
- ``p2p.laddr``: Node listen address. (0.0.0.0:0 means any interface, proxy_app = "tcp://127.0.0.1:46658"
any port). *Default*: ``"0.0.0.0:46656"``
- ``p2p.pex``: Enable Peer-Exchange (dev feature). *Default*: ``false``
- ``p2p.seeds``: Comma delimited host:port seed nodes. *Default*:
``""``
- ``p2p.skip_upnp``: Skip UPNP detection. *Default*: ``false``
- ``rpc.grpc_laddr``: GRPC listen address (BroadcastTx only). Port # A custom human readable name for this node
required. *Default*: ``""`` moniker = "anonymous"
- ``rpc.laddr``: RPC listen address. Port required. *Default*:
``"0.0.0.0:46657"`` # If this node is many blocks behind the tip of the chain, FastSync
- ``rpc.unsafe``: Enabled unsafe rpc methods. *Default*: ``true`` # allows them to catchup quickly by downloading blocks in parallel
# and verifying their commits
fast_sync = true
# Database backend: leveldb | memdb
db_backend = "leveldb"
# Database directory
db_path = "data"
# Output level for logging
log_level = "state:info,*:error"
##### additional base config options #####
# The ID of the chain to join (should be signed with every transaction and vote)
chain_id = ""
# Path to the JSON file containing the initial validator set and other meta data
genesis_file = "genesis.json"
# Path to the JSON file containing the private key to use as a validator in the consensus protocol
priv_validator_file = "priv_validator.json"
# Mechanism to connect to the ABCI application: socket | grpc
abci = "socket"
# TCP or UNIX socket address for the profiling server to listen on
prof_laddr = ""
# If true, query the ABCI app on connecting to a new peer
# so the app can decide if we should keep the connection or not
filter_peers = false
##### advanced configuration options #####
##### rpc server configuration options #####
[rpc]
# TCP or UNIX socket address for the RPC server to listen on
laddr = "tcp://0.0.0.0:46657"
# TCP or UNIX socket address for the gRPC server to listen on
# NOTE: This server only supports /broadcast_tx_commit
grpc_laddr = ""
# Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool
unsafe = false
##### peer to peer configuration options #####
[p2p]
# Address to listen for incoming connections
laddr = "tcp://0.0.0.0:46656"
# Comma separated list of seed nodes to connect to
seeds = ""
# Path to address book
addr_book_file = "addrbook.json"
# Set true for strict address routability rules
addr_book_strict = true
# Time to wait before flushing messages out on the connection, in ms
flush_throttle_timeout = 100
# Maximum number of peers to connect to
max_num_peers = 50
# Maximum size of a message packet payload, in bytes
max_msg_packet_payload_size = 1024
# Rate at which packets can be sent, in bytes/second
send_rate = 512000
# Rate at which packets can be received, in bytes/second
recv_rate = 512000
##### mempool configuration options #####
[mempool]
recheck = true
recheck_empty = true
broadcast = true
wal_dir = "data/mempool.wal"
##### consensus configuration options #####
[consensus]
wal_file = "data/cs.wal/wal"
wal_light = false
# All timeouts are in milliseconds
timeout_propose = 3000
timeout_propose_delta = 500
timeout_prevote = 1000
timeout_prevote_delta = 500
timeout_precommit = 1000
timeout_precommit_delta = 500
timeout_commit = 1000
# Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
skip_timeout_commit = false
# BlockSize
max_block_size_txs = 10000
max_block_size_bytes = 1
# EmptyBlocks mode and possible interval between empty blocks in seconds
create_empty_blocks = true
create_empty_blocks_interval = 0
# Reactor sleep duration parameters are in milliseconds
peer_gossip_sleep_duration = 100
peer_query_maj23_sleep_duration = 2000
##### transactions indexer configuration options #####
[tx_index]
# What indexer to use for transactions
#
# Options:
# 1) "null" (default)
# 2) "kv" - the simplest possible indexer, backed by key-value storage (defaults to levelDB; see DBBackend).
indexer = "{{ .TxIndex.Indexer }}"
# Comma-separated list of tags to index (by default the only tag is tx hash)
#
# It's recommended to index only a subset of tags due to possible memory
# bloat. This is, of course, depends on the indexer's DB and the volume of
# transactions.
index_tags = "{{ .TxIndex.IndexTags }}"
# When set to true, tells indexer to index all tags. Note this may be not
# desirable (see the comment above). IndexTags has a precedence over
# IndexAllTags (i.e. when given both, IndexTags will be indexed).
index_all_tags = {{ .TxIndex.IndexAllTags }}

View File

@ -1,7 +1,7 @@
Genesis Genesis
======= =======
The genesis.json file in ``$TMHOME`` defines the initial TendermintCore The genesis.json file in ``$TMHOME/config`` defines the initial TendermintCore
state upon genesis of the blockchain (`see state upon genesis of the blockchain (`see
definition <https://github.com/tendermint/tendermint/blob/master/types/genesis.go>`__). definition <https://github.com/tendermint/tendermint/blob/master/types/genesis.go>`__).

View File

@ -18,7 +18,7 @@ Configuration
~~~~~~~~~~~~~ ~~~~~~~~~~~~~
Set the ``laddr`` config parameter under ``[rpc]`` table in the Set the ``laddr`` config parameter under ``[rpc]`` table in the
$TMHOME/config.toml file or the ``--rpc.laddr`` command-line flag to the $TMHOME/config/config.toml file or the ``--rpc.laddr`` command-line flag to the
desired protocol://host:port setting. Default: ``tcp://0.0.0.0:46657``. desired protocol://host:port setting. Default: ``tcp://0.0.0.0:46657``.
Arguments Arguments

View File

@ -24,7 +24,8 @@ Initialize the root directory by running:
tendermint init tendermint init
This will create a new private key (``priv_validator.json``), and a This will create a new private key (``priv_validator.json``), and a
genesis file (``genesis.json``) containing the associated public key. 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. This is all that's necessary to run a local testnet with one validator.
For more elaborate initialization, see our `testnet deployment For more elaborate initialization, see our `testnet deployment
@ -157,8 +158,7 @@ The block interval setting allows for a delay (in seconds) between the creation
create_empty_blocks_interval = 5 create_empty_blocks_interval = 5
With this setting, empty blocks will be produced every 5s if no block has been produced otherwise, 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`. regardless of the value of ``create_empty_blocks``.
Broadcast API Broadcast API
------------- -------------
@ -200,7 +200,7 @@ Tendermint Networks
------------------- -------------------
When ``tendermint init`` is run, both a ``genesis.json`` and When ``tendermint init`` is run, both a ``genesis.json`` and
``priv_validator.json`` are created in ``~/.tendermint``. The ``priv_validator.json`` are created in ``~/.tendermint/config``. The
``genesis.json`` might look like: ``genesis.json`` might look like:
:: ::
@ -271,7 +271,7 @@ with the consensus protocol.
Peers Peers
~~~~~ ~~~~~
To connect to peers on start-up, specify them in the ``config.toml`` or To connect to peers on start-up, specify them in the ``$TMHOME/config/config.toml`` or
on the command line. on the command line.
For instance, For instance,
@ -297,7 +297,7 @@ Adding a Non-Validator
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~
Adding a non-validator is simple. Just copy the original Adding a non-validator is simple. Just copy the original
``genesis.json`` to ``~/.tendermint`` on the new machine and start the ``genesis.json`` to ``~/.tendermint/config`` on the new machine and start the
node, specifying seeds as necessary. If no seeds are specified, the node node, specifying seeds as necessary. If no seeds are specified, the node
won't make any blocks, because it's not a validator, and it won't hear 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. about any blocks, because it's not connected to the other peer.
@ -366,8 +366,8 @@ then the new ``genesis.json`` will be:
] ]
} }
Update the ``genesis.json`` in ``~/.tendermint``. Copy the genesis file Update the ``genesis.json`` in ``~/.tendermint/config``. Copy the genesis file
and the new ``priv_validator.json`` to the ``~/.tendermint`` on a new and the new ``priv_validator.json`` to the ``~/.tendermint/config`` on a new
machine. machine.
Now run ``tendermint node`` on both machines, and use either Now run ``tendermint node`` on both machines, and use either

View File

@ -10,6 +10,7 @@ import (
liteErr "github.com/tendermint/tendermint/lite/errors" liteErr "github.com/tendermint/tendermint/lite/errors"
rpcclient "github.com/tendermint/tendermint/rpc/client" rpcclient "github.com/tendermint/tendermint/rpc/client"
rpctest "github.com/tendermint/tendermint/rpc/test" rpctest "github.com/tendermint/tendermint/rpc/test"
"github.com/tendermint/tendermint/types"
) )
func TestProvider(t *testing.T) { func TestProvider(t *testing.T) {
@ -17,7 +18,8 @@ func TestProvider(t *testing.T) {
cfg := rpctest.GetConfig() cfg := rpctest.GetConfig()
rpcAddr := cfg.RPC.ListenAddress rpcAddr := cfg.RPC.ListenAddress
chainID := cfg.ChainID genDoc, _ := types.GenesisDocFromFile(cfg.GenesisFile())
chainID := genDoc.ChainID
p := NewHTTPProvider(rpcAddr) p := NewHTTPProvider(rpcAddr)
require.NotNil(t, p) require.NotNil(t, p)

View File

@ -11,7 +11,7 @@ Tendermint RPC is built using [our own RPC library](https://github.com/tendermin
## Configuration ## Configuration
Set the `laddr` config parameter under `[rpc]` table in the `$TMHOME/config.toml` file or the `--rpc.laddr` command-line flag to the desired protocol://host:port setting. Default: `tcp://0.0.0.0:46657`. Set the `laddr` config parameter under `[rpc]` table in the `$TMHOME/config/config.toml` file or the `--rpc.laddr` command-line flag to the desired protocol://host:port setting. Default: `tcp://0.0.0.0:46657`.
## Arguments ## Arguments

View File

@ -3,7 +3,7 @@ set -euo pipefail
IFS=$'\n\t' IFS=$'\n\t'
debora run -- bash -c "cd \$GOPATH/src/github.com/tendermint/tendermint; killall tendermint; killall logjack" debora run -- bash -c "cd \$GOPATH/src/github.com/tendermint/tendermint; killall tendermint; killall logjack"
debora run -- bash -c "cd \$GOPATH/src/github.com/tendermint/tendermint; tendermint unsafe_reset_priv_validator; rm -rf ~/.tendermint/data; rm ~/.tendermint/genesis.json; rm ~/.tendermint/logs/*" debora run -- bash -c "cd \$GOPATH/src/github.com/tendermint/tendermint; tendermint unsafe_reset_priv_validator; rm -rf ~/.tendermint/data; rm ~/.tendermint/config/genesis.json; rm ~/.tendermint/logs/*"
debora run -- bash -c "cd \$GOPATH/src/github.com/tendermint/tendermint; git pull origin develop; make" debora run -- bash -c "cd \$GOPATH/src/github.com/tendermint/tendermint; git pull origin develop; make"
debora run -- bash -c "cd \$GOPATH/src/github.com/tendermint/tendermint; mkdir -p ~/.tendermint/logs" debora run -- bash -c "cd \$GOPATH/src/github.com/tendermint/tendermint; mkdir -p ~/.tendermint/logs"
debora run --bg --label tendermint -- bash -c "cd \$GOPATH/src/github.com/tendermint/tendermint; tendermint node 2>&1 | stdinwriter -outpath ~/.tendermint/logs/tendermint.log" debora run --bg --label tendermint -- bash -c "cd \$GOPATH/src/github.com/tendermint/tendermint; tendermint node 2>&1 | stdinwriter -outpath ~/.tendermint/logs/tendermint.log"