mirror of
https://github.com/fluencelabs/tendermint
synced 2025-06-23 17:51:39 +00:00
Pulled out all config structs (except p2p.PeerConfig) into config package
This commit is contained in:
committed by
Ethan Buchman
parent
f217f2b2c5
commit
604bf03f3a
153
config/config.go
153
config/config.go
@ -1,7 +1,41 @@
|
||||
package config
|
||||
|
||||
// Config struct for a Tendermint node
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
// Top level options use an anonymous struct
|
||||
*BaseConfig `mapstructure:",squash"`
|
||||
|
||||
// Options for services
|
||||
P2P *P2PConfig `mapstructure:"p2p"`
|
||||
Mempool *MempoolConfig `mapstructure:"mempool"`
|
||||
Consensus *ConsensusConfig `mapstructure:"consensus"`
|
||||
}
|
||||
|
||||
func DefaultConfig(rootDir string) *Config {
|
||||
return &Config{
|
||||
BaseConfig: DefaultBaseConfig(rootDir),
|
||||
P2P: DefaultP2PConfig(rootDir),
|
||||
Mempool: DefaultMempoolConfig(rootDir),
|
||||
Consensus: DefaultConsensusConfig(rootDir),
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig(rootDir string) *Config {
|
||||
return &Config{
|
||||
BaseConfig: DefaultBaseConfig(rootDir),
|
||||
P2P: DefaultP2PConfig(rootDir),
|
||||
Mempool: DefaultMempoolConfig(rootDir),
|
||||
Consensus: TestConsensusConfig(rootDir),
|
||||
}
|
||||
}
|
||||
|
||||
// BaseConfig struct for a Tendermint node
|
||||
type BaseConfig struct {
|
||||
// The ID of the chain to join (should be signed with every transaction and vote)
|
||||
ChainID string `mapstructure:"chain_id"`
|
||||
|
||||
@ -53,8 +87,8 @@ type Config struct {
|
||||
GRPCListenAddress string `mapstructure:"grpc_laddr"`
|
||||
}
|
||||
|
||||
func NewDefaultConfig(rootDir string) *Config {
|
||||
return &Config{
|
||||
func DefaultBaseConfig(rootDir string) *BaseConfig {
|
||||
return &BaseConfig{
|
||||
GenesisFile: rootDir + "/genesis.json",
|
||||
PrivValidatorFile: rootDir + "/priv_validator.json",
|
||||
Moniker: "anonymous",
|
||||
@ -71,3 +105,116 @@ func NewDefaultConfig(rootDir string) *Config {
|
||||
GRPCListenAddress: "",
|
||||
}
|
||||
}
|
||||
|
||||
type P2PConfig struct {
|
||||
ListenAddress string `mapstructure:"laddr"`
|
||||
Seeds string `mapstructure:"seeds"`
|
||||
SkipUPNP bool `mapstructure:"skip_upnp"`
|
||||
AddrBookFile string `mapstructure:"addr_book_file"`
|
||||
AddrBookStrict bool `mapstructure:"addr_book_strict"`
|
||||
PexReactor bool `mapstructure:"pex_reactor"`
|
||||
MaxNumPeers int `mapstructure:"max_num_peers"`
|
||||
}
|
||||
|
||||
func DefaultP2PConfig(rootDir string) *P2PConfig {
|
||||
return &P2PConfig{
|
||||
ListenAddress: "tcp://0.0.0.0:46656",
|
||||
AddrBookFile: rootDir + "/addrbook.json",
|
||||
AddrBookStrict: true,
|
||||
MaxNumPeers: 50,
|
||||
}
|
||||
}
|
||||
|
||||
type MempoolConfig struct {
|
||||
Recheck bool `mapstructure:"recheck"` // true
|
||||
RecheckEmpty bool `mapstructure:"recheck_empty"` // true
|
||||
Broadcast bool `mapstructure:"broadcast"` // true
|
||||
WalDir string `mapstructure:"wal_dir"` //
|
||||
}
|
||||
|
||||
func DefaultMempoolConfig(rootDir string) *MempoolConfig {
|
||||
return &MempoolConfig{
|
||||
Recheck: true,
|
||||
RecheckEmpty: true,
|
||||
Broadcast: true,
|
||||
WalDir: rootDir + "/data/mempool.wal",
|
||||
}
|
||||
}
|
||||
|
||||
// ConsensusConfig holds timeouts and details about the WAL, the block structure,
|
||||
// and timeouts in the consensus protocol.
|
||||
type ConsensusConfig struct {
|
||||
WalFile string `mapstructure:"wal_file"`
|
||||
WalLight bool `mapstructure:"wal_light"`
|
||||
|
||||
// All timeouts are in ms
|
||||
TimeoutPropose int `mapstructure:"timeout_propose"`
|
||||
TimeoutProposeDelta int `mapstructure:"timeout_propose_delta"`
|
||||
TimeoutPrevote int `mapstructure:"timeout_prevote"`
|
||||
TimeoutPrevoteDelta int `mapstructure:"timeout_prevote_delta"`
|
||||
TimeoutPrecommit int `mapstructure:"timeout_precommit"`
|
||||
TimeoutPrecommitDelta int `mapstructure:"timeout_precommit_delta"`
|
||||
TimeoutCommit int `mapstructure:"timeout_commit"`
|
||||
|
||||
// Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
|
||||
SkipTimeoutCommit bool `mapstructure:"skip_timeout_commit"`
|
||||
|
||||
// BlockSize
|
||||
MaxBlockSizeTxs int `mapstructure:"max_block_size_txs"`
|
||||
MaxBlockSizeBytes int `mapstructure:"max_block_size_bytes"`
|
||||
|
||||
// TODO: This probably shouldn't be exposed but it makes it
|
||||
// easy to write tests for the wal/replay
|
||||
BlockPartSize int `mapstructure:"block_part_size"`
|
||||
}
|
||||
|
||||
// Wait this long for a proposal
|
||||
func (cfg *ConsensusConfig) Propose(round int) time.Duration {
|
||||
return time.Duration(cfg.TimeoutPropose+cfg.TimeoutProposeDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving any +2/3 prevote, wait this long for stragglers
|
||||
func (cfg *ConsensusConfig) Prevote(round int) time.Duration {
|
||||
return time.Duration(cfg.TimeoutPrevote+cfg.TimeoutPrevoteDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving any +2/3 precommits, wait this long for stragglers
|
||||
func (cfg *ConsensusConfig) Precommit(round int) time.Duration {
|
||||
return time.Duration(cfg.TimeoutPrecommit+cfg.TimeoutPrecommitDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving +2/3 precommits for a single block (a commit), wait this long for stragglers in the next height's RoundStepNewHeight
|
||||
func (cfg *ConsensusConfig) Commit(t time.Time) time.Time {
|
||||
return t.Add(time.Duration(cfg.TimeoutCommit) * time.Millisecond)
|
||||
}
|
||||
|
||||
func DefaultConsensusConfig(rootDir string) *ConsensusConfig {
|
||||
return &ConsensusConfig{
|
||||
WalFile: rootDir + "/data/cs.wal/wal",
|
||||
WalLight: false,
|
||||
TimeoutPropose: 3000,
|
||||
TimeoutProposeDelta: 500,
|
||||
TimeoutPrevote: 1000,
|
||||
TimeoutPrevoteDelta: 500,
|
||||
TimeoutPrecommit: 1000,
|
||||
TimeoutPrecommitDelta: 500,
|
||||
TimeoutCommit: 1000,
|
||||
SkipTimeoutCommit: false,
|
||||
MaxBlockSizeTxs: 10000,
|
||||
MaxBlockSizeBytes: 1, // TODO
|
||||
BlockPartSize: types.DefaultBlockPartSize,
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsensusConfig(rootDir string) *ConsensusConfig {
|
||||
config := DefaultConsensusConfig(rootDir)
|
||||
config.TimeoutPropose = 2000
|
||||
config.TimeoutProposeDelta = 1
|
||||
config.TimeoutPrevote = 10
|
||||
config.TimeoutPrevoteDelta = 1
|
||||
config.TimeoutPrecommit = 10
|
||||
config.TimeoutPrecommitDelta = 1
|
||||
config.TimeoutCommit = 10
|
||||
config.SkipTimeoutCommit = true
|
||||
return config
|
||||
}
|
||||
|
@ -1,122 +0,0 @@
|
||||
package tendermint
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
func getTMRoot(rootDir string) string {
|
||||
if rootDir == "" {
|
||||
rootDir = os.Getenv("TMHOME")
|
||||
}
|
||||
if rootDir == "" {
|
||||
// deprecated, use TMHOME (TODO: remove in TM 0.11.0)
|
||||
rootDir = os.Getenv("TMROOT")
|
||||
}
|
||||
if rootDir == "" {
|
||||
rootDir = os.Getenv("HOME") + "/.tendermint"
|
||||
}
|
||||
return rootDir
|
||||
}
|
||||
|
||||
func initTMRoot(rootDir string) {
|
||||
rootDir = getTMRoot(rootDir)
|
||||
cmn.EnsureDir(rootDir, 0700)
|
||||
cmn.EnsureDir(rootDir+"/data", 0700)
|
||||
|
||||
configFilePath := path.Join(rootDir, "config.toml")
|
||||
|
||||
// Write default config file if missing.
|
||||
if !cmn.FileExists(configFilePath) {
|
||||
// Ask user for moniker
|
||||
// moniker := cfg.Prompt("Type hostname: ", "anonymous")
|
||||
cmn.MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644)
|
||||
}
|
||||
}
|
||||
|
||||
func GetConfig(rootDir string) *viper.Viper {
|
||||
rootDir = getTMRoot(rootDir)
|
||||
initTMRoot(rootDir)
|
||||
|
||||
config := viper.New()
|
||||
config.SetConfigName("config")
|
||||
config.SetConfigType("toml")
|
||||
config.AddConfigPath(rootDir)
|
||||
err := config.ReadInConfig()
|
||||
if err != nil {
|
||||
cmn.Exit(cmn.Fmt("Could not read config from directory %v: %v", rootDir, err))
|
||||
}
|
||||
//config.WatchConfig()
|
||||
|
||||
// Set defaults or panic
|
||||
if config.IsSet("chain.chain_id") {
|
||||
cmn.Exit("Cannot set 'chain_id' via config.toml")
|
||||
}
|
||||
//mapConfig.SetRequired("chain_id") // blows up if you try to use it before setting.
|
||||
config.SetDefault("moniker", "anonymous")
|
||||
config.SetDefault("log_level", "info")
|
||||
config.SetDefault("prof_laddr", "")
|
||||
config.SetDefault("genesis_file", rootDir+"/genesis.json")
|
||||
config.SetDefault("proxy_app", "tcp://127.0.0.1:46658")
|
||||
config.SetDefault("abci", "socket")
|
||||
config.SetDefault("filter_peers", false)
|
||||
config.SetDefault("fast_sync", true)
|
||||
config.SetDefault("priv_validator_file", rootDir+"/priv_validator.json")
|
||||
config.SetDefault("db_backend", "leveldb")
|
||||
config.SetDefault("db_dir", rootDir+"/data")
|
||||
config.SetDefault("rpc_laddr", "tcp://0.0.0.0:46657")
|
||||
config.SetDefault("grpc_laddr", "")
|
||||
config.SetDefault("tx_index", "kv")
|
||||
|
||||
config.SetDefault("p2p.laddr", "tcp://0.0.0.0:46656")
|
||||
config.SetDefault("p2p.seeds", "")
|
||||
config.SetDefault("p2p.skip_upnp", false)
|
||||
config.SetDefault("p2p.addrbook_file", rootDir+"/addrbook.json")
|
||||
config.SetDefault("p2p.addrbook_strict", true) // disable to allow connections locally
|
||||
config.SetDefault("p2p.pex_reactor", false) // enable for peer exchange
|
||||
|
||||
config.SetDefault("consensus.wal_file", rootDir+"/data/cs.wal/wal")
|
||||
config.SetDefault("consensus.wal_light", false)
|
||||
config.SetDefault("consensus.max_block_size_txs", 10000) // max number of txs
|
||||
config.SetDefault("consensus.block_part_size", 65536) // part size 64K
|
||||
// all timeouts are in ms
|
||||
config.SetDefault("consensus.timeout_handshake", 10000)
|
||||
config.SetDefault("consensus.timeout_propose", 3000)
|
||||
config.SetDefault("consensus.timeout_propose_delta", 500)
|
||||
config.SetDefault("consensus.timeout_prevote", 1000)
|
||||
config.SetDefault("consensus.timeout_prevote_delta", 500)
|
||||
config.SetDefault("consensus.timeout_precommit", 1000)
|
||||
config.SetDefault("consensus.timeout_precommit_delta", 500)
|
||||
config.SetDefault("consensus.timeout_commit", 1000)
|
||||
// make progress asap (no `timeout_commit`) on full precommit votes
|
||||
config.SetDefault("consensus.skip_timeout_commit", false)
|
||||
|
||||
config.SetDefault("mempool.recheck", true)
|
||||
config.SetDefault("mempool.recheck_empty", true)
|
||||
config.SetDefault("mempool.broadcast", true)
|
||||
config.SetDefault("mempool.wal_dir", rootDir+"/data/mempool.wal")
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
var defaultConfigTmpl = `# This is a TOML config file.
|
||||
# For more information, see https://github.com/toml-lang/toml
|
||||
|
||||
proxy_app = "tcp://127.0.0.1:46658"
|
||||
moniker = "__MONIKER__"
|
||||
node_laddr = "tcp://0.0.0.0:46656"
|
||||
seeds = ""
|
||||
fast_sync = true
|
||||
db_backend = "leveldb"
|
||||
log_level = "notice"
|
||||
rpc_laddr = "tcp://0.0.0.0:46657"
|
||||
`
|
||||
|
||||
func defaultConfig(moniker string) (defaultConfig string) {
|
||||
defaultConfig = strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1)
|
||||
return
|
||||
}
|
@ -1,170 +0,0 @@
|
||||
// Import this in all *_test.go files to initialize ~/.tendermint_test.
|
||||
|
||||
package tendermint_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/logger"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Creates ~/.tendermint_test
|
||||
EnsureDir(os.Getenv("HOME")+"/.tendermint_test", 0700)
|
||||
}
|
||||
|
||||
func initTMRoot(rootDir string) {
|
||||
// Remove ~/.tendermint_test_bak
|
||||
if FileExists(rootDir + "_bak") {
|
||||
err := os.RemoveAll(rootDir + "_bak")
|
||||
if err != nil {
|
||||
PanicSanity(err.Error())
|
||||
}
|
||||
}
|
||||
// Move ~/.tendermint_test to ~/.tendermint_test_bak
|
||||
if FileExists(rootDir) {
|
||||
err := os.Rename(rootDir, rootDir+"_bak")
|
||||
if err != nil {
|
||||
PanicSanity(err.Error())
|
||||
}
|
||||
}
|
||||
// Create new dir
|
||||
EnsureDir(rootDir, 0700)
|
||||
EnsureDir(rootDir+"/data", 0700)
|
||||
|
||||
configFilePath := path.Join(rootDir, "config.toml")
|
||||
genesisFilePath := path.Join(rootDir, "genesis.json")
|
||||
privFilePath := path.Join(rootDir, "priv_validator.json")
|
||||
|
||||
// Write default config file if missing.
|
||||
if !FileExists(configFilePath) {
|
||||
// Ask user for moniker
|
||||
MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644)
|
||||
}
|
||||
if !FileExists(genesisFilePath) {
|
||||
MustWriteFile(genesisFilePath, []byte(defaultGenesis), 0644)
|
||||
}
|
||||
// we always overwrite the priv val
|
||||
MustWriteFile(privFilePath, []byte(defaultPrivValidator), 0644)
|
||||
}
|
||||
|
||||
func ResetConfig(localPath string) *viper.Viper {
|
||||
rootDir := os.Getenv("HOME") + "/.tendermint_test/" + localPath
|
||||
initTMRoot(rootDir)
|
||||
|
||||
config := viper.New()
|
||||
config.SetConfigName("config")
|
||||
config.SetConfigType("toml")
|
||||
config.AddConfigPath(rootDir)
|
||||
err := config.ReadInConfig()
|
||||
if err != nil {
|
||||
Exit(Fmt("Could not read config: %v", err))
|
||||
}
|
||||
//config.WatchConfig()
|
||||
|
||||
// Set defaults or panic
|
||||
if config.IsSet("chain_id") {
|
||||
Exit(fmt.Sprintf("Cannot set 'chain_id' via config.toml:\n %v\n %v\n ", config.Get("chain_id"), rootDir))
|
||||
}
|
||||
|
||||
config.SetDefault("chain_id", "tendermint_test")
|
||||
config.SetDefault("genesis_file", rootDir+"/genesis.json")
|
||||
config.SetDefault("proxy_app", "dummy")
|
||||
config.SetDefault("abci", "socket")
|
||||
config.SetDefault("moniker", "anonymous")
|
||||
config.SetDefault("node_laddr", "tcp://0.0.0.0:36656")
|
||||
config.SetDefault("fast_sync", false)
|
||||
config.SetDefault("priv_validator_file", rootDir+"/priv_validator.json")
|
||||
config.SetDefault("db_backend", "memdb")
|
||||
config.SetDefault("db_dir", rootDir+"/data")
|
||||
config.SetDefault("log_level", "info")
|
||||
config.SetDefault("rpc_laddr", "tcp://0.0.0.0:36657")
|
||||
config.SetDefault("grpc_laddr", "tcp://0.0.0.0:36658")
|
||||
config.SetDefault("prof_laddr", "")
|
||||
config.SetDefault("filter_peers", false)
|
||||
config.SetDefault("tx_index", "kv")
|
||||
|
||||
config.SetDefault("p2p.laddr", "tcp://0.0.0.0:36656")
|
||||
config.SetDefault("p2p.skip_upnp", true)
|
||||
config.SetDefault("p2p.addrbook_file", rootDir+"/addrbook.json")
|
||||
config.SetDefault("p2p.addrbook_strict", true) // disable to allow connections locally
|
||||
config.SetDefault("p2p.pex_reactor", false) // enable for peer exchange
|
||||
|
||||
config.SetDefault("consensus.wal_file", rootDir+"/data/cs.wal/wal")
|
||||
config.SetDefault("consensus.wal_light", false)
|
||||
config.SetDefault("consensus.max_block_size_txs", 10000)
|
||||
config.SetDefault("consensus.block_part_size", 65536) // part size 64K
|
||||
config.SetDefault("consensus.timeout_handshake", 10000)
|
||||
config.SetDefault("consensus.timeout_propose", 2000)
|
||||
config.SetDefault("consensus.timeout_propose_delta", 1)
|
||||
config.SetDefault("consensus.timeout_prevote", 10)
|
||||
config.SetDefault("consensus.timeout_prevote_delta", 1)
|
||||
config.SetDefault("consensus.timeout_precommit", 10)
|
||||
config.SetDefault("consensus.timeout_precommit_delta", 1)
|
||||
config.SetDefault("consensus.timeout_commit", 10)
|
||||
config.SetDefault("consensus.skip_timeout_commit", true)
|
||||
|
||||
config.SetDefault("mempool.recheck", true)
|
||||
config.SetDefault("mempool.recheck_empty", true)
|
||||
config.SetDefault("mempool.broadcast", true)
|
||||
config.SetDefault("mempool.wal_dir", "")
|
||||
|
||||
logger.SetLogLevel(config.GetString("log_level"))
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
var defaultConfigTmpl = `# This is a TOML config file.
|
||||
# For more information, see https://github.com/toml-lang/toml
|
||||
|
||||
proxy_app = "dummy"
|
||||
moniker = "__MONIKER__"
|
||||
node_laddr = "tcp://0.0.0.0:36656"
|
||||
seeds = ""
|
||||
fast_sync = false
|
||||
db_backend = "memdb"
|
||||
log_level = "info"
|
||||
rpc_laddr = "tcp://0.0.0.0:36657"
|
||||
`
|
||||
|
||||
func defaultConfig(moniker string) (defaultConfig string) {
|
||||
defaultConfig = strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1)
|
||||
return
|
||||
}
|
||||
|
||||
var defaultGenesis = `{
|
||||
"genesis_time": "0001-01-01T00:00:00.000Z",
|
||||
"chain_id": "tendermint_test",
|
||||
"validators": [
|
||||
{
|
||||
"pub_key": {
|
||||
"type": "ed25519",
|
||||
"data":"3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"amount": 10,
|
||||
"name": ""
|
||||
}
|
||||
],
|
||||
"app_hash": ""
|
||||
}`
|
||||
|
||||
var defaultPrivValidator = `{
|
||||
"address": "D028C9981F7A87F3093672BF0D5B0E2A1B3ED456",
|
||||
"pub_key": {
|
||||
"type": "ed25519",
|
||||
"data": "3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"priv_key": {
|
||||
"type": "ed25519",
|
||||
"data": "27F82582AEFAE7AB151CFB01C48BB6C1A0DA78F9BDDA979A9F70A84D074EB07D3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"last_height": 0,
|
||||
"last_round": 0,
|
||||
"last_step": 0
|
||||
}`
|
129
config/toml.go
Normal file
129
config/toml.go
Normal file
@ -0,0 +1,129 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
/****** these are for production settings ***********/
|
||||
|
||||
func initRoot(rootDir string) {
|
||||
cmn.EnsureDir(rootDir, 0700)
|
||||
cmn.EnsureDir(rootDir+"/data", 0700)
|
||||
|
||||
configFilePath := path.Join(rootDir, "config.toml")
|
||||
|
||||
// Write default config file if missing.
|
||||
if !cmn.FileExists(configFilePath) {
|
||||
// Ask user for moniker
|
||||
// moniker := cfg.Prompt("Type hostname: ", "anonymous")
|
||||
cmn.MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644)
|
||||
}
|
||||
}
|
||||
|
||||
var defaultConfigTmpl = `# This is a TOML config file.
|
||||
# For more information, see https://github.com/toml-lang/toml
|
||||
|
||||
proxy_app = "tcp://127.0.0.1:46658"
|
||||
moniker = "__MONIKER__"
|
||||
node_laddr = "tcp://0.0.0.0:46656"
|
||||
seeds = ""
|
||||
fast_sync = true
|
||||
db_backend = "leveldb"
|
||||
log_level = "notice"
|
||||
rpc_laddr = "tcp://0.0.0.0:46657"
|
||||
`
|
||||
|
||||
func defaultConfig(moniker string) (defaultConfig string) {
|
||||
defaultConfig = strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1)
|
||||
return
|
||||
}
|
||||
|
||||
/****** these are for test settings ***********/
|
||||
|
||||
func initTestRoot(rootDir string) {
|
||||
// Remove ~/.tendermint_test_bak
|
||||
if cmn.FileExists(rootDir + "_bak") {
|
||||
err := os.RemoveAll(rootDir + "_bak")
|
||||
if err != nil {
|
||||
cmn.PanicSanity(err.Error())
|
||||
}
|
||||
}
|
||||
// Move ~/.tendermint_test to ~/.tendermint_test_bak
|
||||
if cmn.FileExists(rootDir) {
|
||||
err := os.Rename(rootDir, rootDir+"_bak")
|
||||
if err != nil {
|
||||
cmn.PanicSanity(err.Error())
|
||||
}
|
||||
}
|
||||
// Create new dir
|
||||
cmn.EnsureDir(rootDir, 0700)
|
||||
cmn.EnsureDir(rootDir+"/data", 0700)
|
||||
|
||||
configFilePath := path.Join(rootDir, "config.toml")
|
||||
genesisFilePath := path.Join(rootDir, "genesis.json")
|
||||
privFilePath := path.Join(rootDir, "priv_validator.json")
|
||||
|
||||
// Write default config file if missing.
|
||||
if !cmn.FileExists(configFilePath) {
|
||||
// Ask user for moniker
|
||||
cmn.MustWriteFile(configFilePath, []byte(testConfig("anonymous")), 0644)
|
||||
}
|
||||
if !cmn.FileExists(genesisFilePath) {
|
||||
cmn.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644)
|
||||
}
|
||||
// we always overwrite the priv val
|
||||
cmn.MustWriteFile(privFilePath, []byte(testPrivValidator), 0644)
|
||||
}
|
||||
|
||||
var testConfigTmpl = `# This is a TOML config file.
|
||||
# For more information, see https://github.com/toml-lang/toml
|
||||
|
||||
proxy_app = "dummy"
|
||||
moniker = "__MONIKER__"
|
||||
node_laddr = "tcp://0.0.0.0:36656"
|
||||
seeds = ""
|
||||
fast_sync = false
|
||||
db_backend = "memdb"
|
||||
log_level = "info"
|
||||
rpc_laddr = "tcp://0.0.0.0:36657"
|
||||
`
|
||||
|
||||
func testConfig(moniker string) (testConfig string) {
|
||||
testConfig = strings.Replace(testConfigTmpl, "__MONIKER__", moniker, -1)
|
||||
return
|
||||
}
|
||||
|
||||
var testGenesis = `{
|
||||
"genesis_time": "0001-01-01T00:00:00.000Z",
|
||||
"chain_id": "tendermint_test",
|
||||
"validators": [
|
||||
{
|
||||
"pub_key": {
|
||||
"type": "ed25519",
|
||||
"data":"3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"amount": 10,
|
||||
"name": ""
|
||||
}
|
||||
],
|
||||
"app_hash": ""
|
||||
}`
|
||||
|
||||
var testPrivValidator = `{
|
||||
"address": "D028C9981F7A87F3093672BF0D5B0E2A1B3ED456",
|
||||
"pub_key": {
|
||||
"type": "ed25519",
|
||||
"data": "3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"priv_key": {
|
||||
"type": "ed25519",
|
||||
"data": "27F82582AEFAE7AB151CFB01C48BB6C1A0DA78F9BDDA979A9F70A84D074EB07D3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"last_height": 0,
|
||||
"last_round": 0,
|
||||
"last_step": 0
|
||||
}`
|
@ -20,7 +20,7 @@ import (
|
||||
//--------------------------------------------------------
|
||||
// replay messages interactively or all at once
|
||||
|
||||
func RunReplayFile(config *cfg.Config, csConfig *Config, console bool) {
|
||||
func RunReplayFile(config *cfg.Config, csConfig *cfg.ConsensusConfig, console bool) {
|
||||
consensusState := newConsensusStateForReplay(config, csConfig)
|
||||
|
||||
if err := consensusState.ReplayFile(csConfig.WalFile, console); err != nil {
|
||||
@ -235,7 +235,7 @@ func (pb *playback) replayConsoleLoop() int {
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
// convenience for replay mode
|
||||
func newConsensusStateForReplay(config *cfg.Config, csConfig *Config) *ConsensusState {
|
||||
func newConsensusStateForReplay(config *cfg.Config, csConfig *cfg.ConsensusConfig) *ConsensusState {
|
||||
// Get BlockStore
|
||||
blockStoreDB := dbm.NewDB("blockstore", config.DBBackend, config.DBDir)
|
||||
blockStore := bc.NewBlockStore(blockStoreDB)
|
||||
|
@ -9,9 +9,9 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ebuchman/fail-test"
|
||||
|
||||
fail "github.com/ebuchman/fail-test"
|
||||
"github.com/tendermint/go-wire"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@ -21,84 +21,6 @@ import (
|
||||
//-----------------------------------------------------------------------------
|
||||
// Config
|
||||
|
||||
// Config holds timeouts and details about the WAL, the block structure,
|
||||
// and timeouts in the consensus protocol.
|
||||
type Config struct {
|
||||
WalFile string `mapstructure:"wal_file"`
|
||||
WalLight bool `mapstructure:"wal_light"`
|
||||
|
||||
// All timeouts are in ms
|
||||
TimeoutPropose int `mapstructure:"timeout_propose"`
|
||||
TimeoutProposeDelta int `mapstructure:"timeout_propose_delta"`
|
||||
TimeoutPrevote int `mapstructure:"timeout_prevote"`
|
||||
TimeoutPrevoteDelta int `mapstructure:"timeout_prevote_delta"`
|
||||
TimeoutPrecommit int `mapstructure:"timeout_precommit"`
|
||||
TimeoutPrecommitDelta int `mapstructure:"timeout_precommit_delta"`
|
||||
TimeoutCommit int `mapstructure:"timeout_commit"`
|
||||
|
||||
// Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
|
||||
SkipTimeoutCommit bool `mapstructure:"skip_timeout_commit"`
|
||||
|
||||
// BlockSize
|
||||
MaxBlockSizeTxs int `mapstructure:"max_block_size_txs"`
|
||||
MaxBlockSizeBytes int `mapstructure:"max_block_size_bytes"`
|
||||
|
||||
// TODO: This probably shouldn't be exposed but it makes it
|
||||
// easy to write tests for the wal/replay
|
||||
BlockPartSize int `mapstructure:"block_part_size"`
|
||||
}
|
||||
|
||||
func NewDefaultConfig(rootDir string) *Config {
|
||||
return &Config{
|
||||
WalFile: rootDir + "/data/cs.wal/wal",
|
||||
WalLight: false,
|
||||
TimeoutPropose: 3000,
|
||||
TimeoutProposeDelta: 500,
|
||||
TimeoutPrevote: 1000,
|
||||
TimeoutPrevoteDelta: 500,
|
||||
TimeoutPrecommit: 1000,
|
||||
TimeoutPrecommitDelta: 500,
|
||||
TimeoutCommit: 1000,
|
||||
SkipTimeoutCommit: false,
|
||||
MaxBlockSizeTxs: 10000,
|
||||
MaxBlockSizeBytes: 1, // TODO
|
||||
BlockPartSize: types.DefaultBlockPartSize,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTestConfig(rootDir string) *Config {
|
||||
config := NewDefaultConfig(rootDir)
|
||||
config.TimeoutPropose = 2000
|
||||
config.TimeoutProposeDelta = 1
|
||||
config.TimeoutPrevote = 10
|
||||
config.TimeoutPrevoteDelta = 1
|
||||
config.TimeoutPrecommit = 10
|
||||
config.TimeoutPrecommitDelta = 1
|
||||
config.TimeoutCommit = 10
|
||||
config.SkipTimeoutCommit = true
|
||||
return config
|
||||
}
|
||||
|
||||
// Wait this long for a proposal
|
||||
func (cfg *Config) Propose(round int) time.Duration {
|
||||
return time.Duration(cfg.TimeoutPropose+cfg.TimeoutProposeDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving any +2/3 prevote, wait this long for stragglers
|
||||
func (cfg *Config) Prevote(round int) time.Duration {
|
||||
return time.Duration(cfg.TimeoutPrevote+cfg.TimeoutPrevoteDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving any +2/3 precommits, wait this long for stragglers
|
||||
func (cfg *Config) Precommit(round int) time.Duration {
|
||||
return time.Duration(cfg.TimeoutPrecommit+cfg.TimeoutPrecommitDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving +2/3 precommits for a single block (a commit), wait this long for stragglers in the next height's RoundStepNewHeight
|
||||
func (cfg *Config) Commit(t time.Time) time.Time {
|
||||
return t.Add(time.Duration(cfg.TimeoutCommit) * time.Millisecond)
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Errors
|
||||
|
||||
@ -255,7 +177,7 @@ type ConsensusState struct {
|
||||
cmn.BaseService
|
||||
|
||||
// config details
|
||||
config *Config
|
||||
config *cfg.ConsensusConfig
|
||||
privValidator PrivValidator // for signing votes
|
||||
|
||||
// services for creating and executing blocks
|
||||
@ -295,7 +217,7 @@ type ConsensusState struct {
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func NewConsensusState(config *Config, state *sm.State, proxyAppConn proxy.AppConnConsensus, blockStore types.BlockStore, mempool types.Mempool) *ConsensusState {
|
||||
func NewConsensusState(config *cfg.ConsensusConfig, state *sm.State, proxyAppConn proxy.AppConnConsensus, blockStore types.BlockStore, mempool types.Mempool) *ConsensusState {
|
||||
cs := &ConsensusState{
|
||||
config: config,
|
||||
proxyAppConn: proxyAppConn,
|
||||
|
9
glide.lock
generated
9
glide.lock
generated
@ -1,5 +1,5 @@
|
||||
hash: 6f8962f6ca0e25b8e43bc6e496bd46c9ff3a79dcf789578efeeaee2fffc39c6e
|
||||
updated: 2017-04-27T19:56:37.342860938-04:00
|
||||
hash: 1bdb98b332fc88df3659092ce571b74851f54465c11d91e273a10098dd4d8011
|
||||
updated: 2017-05-04T19:50:25.718540841+02:00
|
||||
imports:
|
||||
- name: github.com/btcsuite/btcd
|
||||
version: 4b348c1d33373d672edd83fc576892d0e46686d2
|
||||
@ -56,7 +56,7 @@ imports:
|
||||
- name: github.com/pelletier/go-toml
|
||||
version: 13d49d4606eb801b8f01ae542b4afc4c6ee3d84a
|
||||
- name: github.com/pkg/errors
|
||||
version: 645ef00459ed84a119197bfb8d8205042c6df63d
|
||||
version: bfd5150e4e41705ded2129ec33379de1cb90b513
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
@ -119,7 +119,7 @@ imports:
|
||||
subpackages:
|
||||
- term
|
||||
- name: github.com/tendermint/merkleeyes
|
||||
version: ea4dd9c7b773435de26bf59fddf90afd43a07d67
|
||||
version: 0fab643ccac1a3f93b90e0e2682a5d1b9d17f8c4
|
||||
subpackages:
|
||||
- app
|
||||
- client
|
||||
@ -129,6 +129,7 @@ imports:
|
||||
version: df250b69416a35a943a6e2a92118667e9ef031d4
|
||||
subpackages:
|
||||
- autofile
|
||||
- cli
|
||||
- clist
|
||||
- common
|
||||
- db
|
||||
|
@ -31,6 +31,7 @@ import:
|
||||
version: develop
|
||||
subpackages:
|
||||
- autofile
|
||||
- cli
|
||||
- clist
|
||||
- common
|
||||
- db
|
||||
|
@ -12,6 +12,7 @@ import (
|
||||
"github.com/tendermint/tmlibs/clist"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
@ -47,7 +48,7 @@ TODO: Better handle abci client errors. (make it automatically handle connection
|
||||
const cacheSize = 100000
|
||||
|
||||
type Mempool struct {
|
||||
config *Config
|
||||
config *cfg.MempoolConfig
|
||||
|
||||
proxyMtx sync.Mutex
|
||||
proxyAppConn proxy.AppConnMempool
|
||||
@ -66,7 +67,7 @@ type Mempool struct {
|
||||
wal *auto.AutoFile
|
||||
}
|
||||
|
||||
func NewMempool(config *Config, proxyAppConn proxy.AppConnMempool) *Mempool {
|
||||
func NewMempool(config *cfg.MempoolConfig, proxyAppConn proxy.AppConnMempool) *Mempool {
|
||||
mempool := &Mempool{
|
||||
config: config,
|
||||
proxyAppConn: proxyAppConn,
|
||||
|
@ -10,6 +10,7 @@ import (
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/tmlibs/clist"
|
||||
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
@ -21,31 +22,15 @@ const (
|
||||
peerCatchupSleepIntervalMS = 100 // If peer is behind, sleep this amount
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
Recheck bool `mapstructure:"recheck"` // true
|
||||
RecheckEmpty bool `mapstructure:"recheck_empty"` // true
|
||||
Broadcast bool `mapstructure:"broadcast"` // true
|
||||
WalDir string `mapstructure:"wal_dir"` //
|
||||
}
|
||||
|
||||
func NewDefaultConfig(rootDir string) *Config {
|
||||
return &Config{
|
||||
Recheck: true,
|
||||
RecheckEmpty: true,
|
||||
Broadcast: true,
|
||||
WalDir: rootDir + "/data/mempool.wal",
|
||||
}
|
||||
}
|
||||
|
||||
// MempoolReactor handles mempool tx broadcasting amongst peers.
|
||||
type MempoolReactor struct {
|
||||
p2p.BaseReactor
|
||||
config *Config
|
||||
config *cfg.MempoolConfig
|
||||
Mempool *Mempool
|
||||
evsw types.EventSwitch
|
||||
}
|
||||
|
||||
func NewMempoolReactor(config *Config, mempool *Mempool) *MempoolReactor {
|
||||
func NewMempoolReactor(config *cfg.MempoolConfig, mempool *Mempool) *MempoolReactor {
|
||||
memR := &MempoolReactor{
|
||||
config: config,
|
||||
Mempool: mempool,
|
||||
|
36
node/node.go
36
node/node.go
@ -7,14 +7,11 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
bc "github.com/tendermint/tendermint/blockchain"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
// tmcfg "github.com/tendermint/tendermint/config/tendermint"
|
||||
"github.com/tendermint/tendermint/consensus"
|
||||
mempl "github.com/tendermint/tendermint/mempool"
|
||||
p2p "github.com/tendermint/tendermint/p2p"
|
||||
@ -35,38 +32,11 @@ import (
|
||||
_ "net/http/pprof"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
// Top level options use an anonymous struct
|
||||
cfg.Config `mapstructure:",squash"`
|
||||
|
||||
// Options for services
|
||||
P2P *p2p.Config `mapstructure:"p2p"`
|
||||
Mempool *mempl.Config `mapstructure:"mempool"`
|
||||
Consensus *consensus.Config `mapstructure:"consensus"`
|
||||
}
|
||||
|
||||
func NewDefaultConfig(rootDir string) *Config {
|
||||
return &Config{
|
||||
Config: *cfg.NewDefaultConfig(rootDir),
|
||||
P2P: p2p.NewDefaultConfig(rootDir),
|
||||
Mempool: mempl.NewDefaultConfig(rootDir),
|
||||
Consensus: consensus.NewDefaultConfig(rootDir),
|
||||
}
|
||||
}
|
||||
|
||||
func ConfigFromViper(viperConfig *viper.Viper) *Config {
|
||||
tmConfig := new(Config)
|
||||
if err := viperConfig.Unmarshal(tmConfig); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return tmConfig
|
||||
}
|
||||
|
||||
type Node struct {
|
||||
cmn.BaseService
|
||||
|
||||
// config
|
||||
config *Config
|
||||
config *cfg.Config
|
||||
genesisDoc *types.GenesisDoc // initial validator set
|
||||
privValidator *types.PrivValidator // local node's validator key
|
||||
|
||||
@ -87,14 +57,14 @@ type Node struct {
|
||||
txIndexer txindex.TxIndexer
|
||||
}
|
||||
|
||||
func NewNodeDefault(config *Config) *Node {
|
||||
func NewNodeDefault(config *cfg.Config) *Node {
|
||||
// Get PrivValidator
|
||||
privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile)
|
||||
return NewNode(config, privValidator,
|
||||
proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir))
|
||||
}
|
||||
|
||||
func NewNode(config *Config, privValidator *types.PrivValidator, clientCreator proxy.ClientCreator) *Node {
|
||||
func NewNode(config *cfg.Config, privValidator *types.PrivValidator, clientCreator proxy.ClientCreator) *Node {
|
||||
|
||||
// Get BlockStore
|
||||
blockStoreDB := dbm.NewDB("blockstore", config.DBBackend, config.DBDir)
|
||||
|
@ -9,6 +9,7 @@ import (
|
||||
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/log15"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
@ -17,29 +18,6 @@ const (
|
||||
reconnectInterval = 3 * time.Second
|
||||
)
|
||||
|
||||
// for node.Config
|
||||
type Config struct {
|
||||
ListenAddress string `mapstructure:"laddr"`
|
||||
Seeds string `mapstructure:"seeds"`
|
||||
SkipUPNP bool `mapstructure:"skip_upnp"`
|
||||
AddrBookFile string `mapstructure:"addr_book_file"`
|
||||
AddrBookStrict bool `mapstructure:"addr_book_strict"`
|
||||
PexReactor bool `mapstructure:"pex_reactor"`
|
||||
MaxNumPeers int `mapstructure:"max_num_peers"`
|
||||
|
||||
peer *PeerConfig // Not exposed
|
||||
}
|
||||
|
||||
func NewDefaultConfig(rootDir string) *Config {
|
||||
return &Config{
|
||||
ListenAddress: "tcp://0.0.0.0:46656",
|
||||
AddrBookFile: rootDir + "/addrbook.json",
|
||||
AddrBookStrict: true,
|
||||
MaxNumPeers: 50,
|
||||
peer: DefaultPeerConfig(),
|
||||
}
|
||||
}
|
||||
|
||||
type Reactor interface {
|
||||
cmn.Service // Start, Stop
|
||||
|
||||
@ -83,7 +61,8 @@ incoming messages are received on the reactor.
|
||||
type Switch struct {
|
||||
cmn.BaseService
|
||||
|
||||
config *Config
|
||||
config *cfg.P2PConfig
|
||||
peerConfig *PeerConfig
|
||||
listeners []Listener
|
||||
reactors map[string]Reactor
|
||||
chDescs []*ChannelDescriptor
|
||||
@ -102,10 +81,10 @@ var (
|
||||
ErrSwitchMaxPeersPerIPRange = errors.New("IP range has too many peers")
|
||||
)
|
||||
|
||||
func NewSwitch(config *Config) *Switch {
|
||||
config.peer = DefaultPeerConfig()
|
||||
func NewSwitch(config *cfg.P2PConfig) *Switch {
|
||||
sw := &Switch{
|
||||
config: config,
|
||||
peerConfig: DefaultPeerConfig(),
|
||||
reactors: make(map[string]Reactor),
|
||||
chDescs: make([]*ChannelDescriptor, 0),
|
||||
reactorsByCh: make(map[byte]Reactor),
|
||||
@ -229,7 +208,7 @@ func (sw *Switch) AddPeer(peer *Peer) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := peer.HandshakeTimeout(sw.nodeInfo, time.Duration(sw.config.peer.HandshakeTimeout*time.Second)); err != nil {
|
||||
if err := peer.HandshakeTimeout(sw.nodeInfo, time.Duration(sw.peerConfig.HandshakeTimeout*time.Second)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -338,7 +317,7 @@ func (sw *Switch) DialPeerWithAddress(addr *NetAddress, persistent bool) (*Peer,
|
||||
sw.dialing.Set(addr.IP.String(), addr)
|
||||
defer sw.dialing.Delete(addr.IP.String())
|
||||
|
||||
peer, err := newOutboundPeerWithConfig(addr, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError, sw.nodePrivKey, sw.config.peer)
|
||||
peer, err := newOutboundPeerWithConfig(addr, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError, sw.nodePrivKey, sw.peerConfig)
|
||||
if err != nil {
|
||||
log.Info("Failed dialing peer", "address", addr, "error", err)
|
||||
return nil, err
|
||||
@ -457,7 +436,7 @@ func (sw *Switch) listenerRoutine(l Listener) {
|
||||
}
|
||||
|
||||
// New inbound connection!
|
||||
err := sw.addPeerWithConnectionAndConfig(inConn, sw.config.peer)
|
||||
err := sw.addPeerWithConnectionAndConfig(inConn, sw.peerConfig)
|
||||
if err != nil {
|
||||
log.Notice("Ignoring inbound connection: error while adding peer", "address", inConn.RemoteAddr().String(), "error", err)
|
||||
continue
|
||||
@ -489,7 +468,7 @@ type SwitchEventDonePeer struct {
|
||||
// If connect==Connect2Switches, the switches will be fully connected.
|
||||
// initSwitch defines how the ith switch should be initialized (ie. with what reactors).
|
||||
// NOTE: panics if any switch fails to start.
|
||||
func MakeConnectedSwitches(cfg *Config, n int, initSwitch func(int, *Switch) *Switch, connect func([]*Switch, int, int)) []*Switch {
|
||||
func MakeConnectedSwitches(cfg *cfg.P2PConfig, n int, initSwitch func(int, *Switch) *Switch, connect func([]*Switch, int, int)) []*Switch {
|
||||
switches := make([]*Switch, n)
|
||||
for i := 0; i < n; i++ {
|
||||
switches[i] = makeSwitch(cfg, i, "testing", "123.123.123", initSwitch)
|
||||
@ -546,7 +525,7 @@ func StartSwitches(switches []*Switch) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func makeSwitch(cfg *Config, i int, network, version string, initSwitch func(int, *Switch) *Switch) *Switch {
|
||||
func makeSwitch(cfg *cfg.P2PConfig, i int, network, version string, initSwitch func(int, *Switch) *Switch) *Switch {
|
||||
privKey := crypto.GenPrivKeyEd25519()
|
||||
// new switch, add reactors
|
||||
// TODO: let the config be passed in?
|
||||
|
Reference in New Issue
Block a user