From 558cdea9c788c1c008225140b2d9ea6bdc53795e Mon Sep 17 00:00:00 2001 From: Dinh Duong Ha Date: Mon, 18 Jun 2018 07:37:25 +0700 Subject: [PATCH 1/7] Change configuration options. --- blockchain/reactor_test.go | 2 +- config/base_config.go | 483 ++++++++++++++++++++++++++++++++ config/chain_config.go | 60 ++++ config/config.go | 555 +++---------------------------------- config/config_test.go | 20 +- config/toml.go | 32 ++- config/toml_test.go | 4 + 7 files changed, 623 insertions(+), 533 deletions(-) create mode 100644 config/base_config.go create mode 100644 config/chain_config.go diff --git a/blockchain/reactor_test.go b/blockchain/reactor_test.go index bb49c28..f0662da 100644 --- a/blockchain/reactor_test.go +++ b/blockchain/reactor_test.go @@ -23,7 +23,7 @@ func makeStateAndBlockStore(logger log.Logger) (sm.State, *BlockStore) { blockStore := NewBlockStore(blockDB) state, err := sm.LoadStateFromDBOrGenesisFile(stateDB, config.GenesisFile()) if err != nil { - panic(cmn.ErrorWrap(err, "error constructing state from genesis file")) + panic(cmn.ErrorWrap(err, "error constructing state from genesis file "+config.GenesisFile())) } return state, blockStore } diff --git a/config/base_config.go b/config/base_config.go new file mode 100644 index 0000000..3868b97 --- /dev/null +++ b/config/base_config.go @@ -0,0 +1,483 @@ +package config + +import ( + "fmt" + "os" + "path/filepath" + "time" +) + +//----------------------------------------------------------------------------- +// BaseConfig + +// BaseConfig defines the base configuration for a teragrid node +type BaseConfig struct { + + // chainID is unexposed and immutable but here for convenience + chainID string + + // The root directory for all data. + // This should be set in viper so it can unmarshal into this struct + RootDir string `mapstructure:"home"` + + // Path to the JSON file containing the initial validator set and other meta data + Genesis string `mapstructure:"genesis_file"` + + // Path to the JSON file containing the private key to use as a validator in the consensus protocol + PrivValidator string `mapstructure:"priv_validator_file"` + + // A JSON file containing the private key to use for p2p authenticated encryption + NodeKey string `mapstructure:"node_key_file"` + + // A custom human readable name for this node + Moniker string `mapstructure:"moniker"` + + // TCP or UNIX socket address for teragrid to listen on for + // connections from an external PrivValidator process + PrivValidatorListenAddr string `mapstructure:"priv_validator_laddr"` + + // TCP or UNIX socket address of the Asura application, + // or the name of an Asura application compiled in with the teragrid binary + ProxyApp string `mapstructure:"proxy_app"` + + // Mechanism to connect to the Asura application: socket | grpc + Asura string `mapstructure:"Asura"` + + // Output level for logging + LogLevel string `mapstructure:"log_level"` + + // TCP or UNIX socket address for the profiling server to listen on + ProfListenAddress string `mapstructure:"prof_laddr"` + + // 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 + FastSync bool `mapstructure:"fast_sync"` + + // If true, query the Asura app on connecting to a new peer + // so the app can decide if we should keep the connection or not + FilterPeers bool `mapstructure:"filter_peers"` // false + + // Database backend: leveldb | memdb + DBBackend string `mapstructure:"db_backend"` + + // Database directory + DBPath string `mapstructure:"db_dir"` +} + +// DefaultBaseConfig returns a default base configuration for a teragrid node +func DefaultBaseConfig() BaseConfig { + return BaseConfig{ + Genesis: defaultGenesisJSONPath, + PrivValidator: defaultPrivValPath, + NodeKey: defaultNodeKeyPath, + Moniker: defaultMoniker, + ProxyApp: "tcp://127.0.0.1:46658", + Asura: "socket", + LogLevel: DefaultPackageLogLevels(), + ProfListenAddress: "", + FastSync: true, + FilterPeers: false, + DBBackend: "leveldb", + DBPath: "data", + } +} + +// TestBaseConfig returns a base configuration for testing a teragrid node +func TestBaseConfig() BaseConfig { + cfg := DefaultBaseConfig() + cfg.chainID = "teragrid_test" + cfg.ProxyApp = "kvstore" + cfg.FastSync = false + cfg.DBBackend = "memdb" + return cfg +} + +func (cfg BaseConfig) ChainID() string { + return cfg.chainID +} + +// GenesisFile returns the full path to the genesis.json file +func (cfg BaseConfig) GenesisFile() string { + return rootify(cfg.Genesis, cfg.RootDir) +} + +// PrivValidatorFile returns the full path to the priv_validator.json file +func (cfg BaseConfig) PrivValidatorFile() string { + return rootify(cfg.PrivValidator, cfg.RootDir) +} + +// NodeKeyFile returns the full path to the node_key.json file +func (cfg BaseConfig) NodeKeyFile() string { + return rootify(cfg.NodeKey, cfg.RootDir) +} + +// DBDir returns the full path to the database directory +func (cfg BaseConfig) DBDir() string { + return rootify(cfg.DBPath, cfg.RootDir) +} + +// DefaultLogLevel returns a default log level of "error" +func DefaultLogLevel() string { + return "error" +} + +// DefaultPackageLogLevels returns a default log level setting so all packages +// log at "error", while the `state` and `main` packages log at "info" +func DefaultPackageLogLevels() string { + return fmt.Sprintf("main:info,state:info,*:%s", DefaultLogLevel()) +} + +//----------------------------------------------------------------------------- +// RPCConfig + +// RPCConfig defines the configuration options for the teragrid RPC server +type RPCConfig struct { + RootDir string `mapstructure:"home"` + + // TCP or UNIX socket address for the RPC server to listen on + ListenAddress string `mapstructure:"laddr"` + + // TCP or UNIX socket address for the gRPC server to listen on + // NOTE: This server only supports /broadcast_tx_commit + GRPCListenAddress string `mapstructure:"grpc_laddr"` + + // Activate unsafe RPC commands like /dial_persistent_peers and /unsafe_flush_mempool + Unsafe bool `mapstructure:"unsafe"` +} + +// DefaultRPCConfig returns a default configuration for the RPC server +func DefaultRPCConfig() *RPCConfig { + return &RPCConfig{ + ListenAddress: "tcp://0.0.0.0:46657", + GRPCListenAddress: "", + Unsafe: false, + } +} + +// TestRPCConfig returns a configuration for testing the RPC server +func TestRPCConfig() *RPCConfig { + cfg := DefaultRPCConfig() + cfg.ListenAddress = "tcp://0.0.0.0:36657" + cfg.GRPCListenAddress = "tcp://0.0.0.0:36658" + cfg.Unsafe = true + return cfg +} + +//----------------------------------------------------------------------------- +// P2PConfig + +// P2PConfig defines the configuration options for the teragrid peer-to-peer networking layer +type P2PConfig struct { + RootDir string `mapstructure:"home"` + + // Address to listen for incoming connections + ListenAddress string `mapstructure:"laddr"` + + // Comma separated list of seed nodes to connect to + // We only use these if we can’t connect to peers in the addrbook + Seeds string `mapstructure:"seeds"` + + // Comma separated list of nodes to keep persistent connections to + // Do not add private peers to this list if you don't want them advertised + PersistentPeers string `mapstructure:"persistent_peers"` + + // Skip UPNP port forwarding + SkipUPNP bool `mapstructure:"skip_upnp"` + + // Path to address book + AddrBook string `mapstructure:"addr_book_file"` + + // Set true for strict address routability rules + AddrBookStrict bool `mapstructure:"addr_book_strict"` + + // Maximum number of peers to connect to + MaxNumPeers int `mapstructure:"max_num_peers"` + + // Time to wait before flushing messages out on the connection, in ms + FlushThrottleTimeout int `mapstructure:"flush_throttle_timeout"` + + // Maximum size of a message packet payload, in bytes + MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"` + + // Rate at which packets can be sent, in bytes/second + SendRate int64 `mapstructure:"send_rate"` + + // Rate at which packets can be received, in bytes/second + RecvRate int64 `mapstructure:"recv_rate"` + + // Set true to enable the peer-exchange reactor + PexReactor bool `mapstructure:"pex"` + + // Seed mode, in which node constantly crawls the network and looks for + // peers. If another node asks it for addresses, it responds and disconnects. + // + // Does not work if the peer-exchange reactor is disabled. + SeedMode bool `mapstructure:"seed_mode"` + + // Authenticated encryption + AuthEnc bool `mapstructure:"auth_enc"` + + // Comma separated list of peer IDs to keep private (will not be gossiped to other peers) + PrivatePeerIDs string `mapstructure:"private_peer_ids"` +} + +// DefaultP2PConfig returns a default configuration for the peer-to-peer layer +func DefaultP2PConfig() *P2PConfig { + return &P2PConfig{ + ListenAddress: "tcp://0.0.0.0:46656", + AddrBook: defaultAddrBookPath, + AddrBookStrict: true, + MaxNumPeers: 50, + FlushThrottleTimeout: 100, + MaxPacketMsgPayloadSize: 1024, // 1 kB + SendRate: 512000, // 500 kB/s + RecvRate: 512000, // 500 kB/s + PexReactor: true, + SeedMode: false, + AuthEnc: true, + } +} + +// TestP2PConfig returns a configuration for testing the peer-to-peer layer +func TestP2PConfig() *P2PConfig { + cfg := DefaultP2PConfig() + cfg.ListenAddress = "tcp://0.0.0.0:36656" + cfg.SkipUPNP = true + cfg.FlushThrottleTimeout = 10 + return cfg +} + +// AddrBookFile returns the full path to the address book +func (cfg *P2PConfig) AddrBookFile() string { + return rootify(cfg.AddrBook, cfg.RootDir) +} + +//----------------------------------------------------------------------------- +// MempoolConfig + +// MempoolConfig defines the configuration options for the teragrid mempool +type MempoolConfig struct { + RootDir string `mapstructure:"home"` + Recheck bool `mapstructure:"recheck"` + RecheckEmpty bool `mapstructure:"recheck_empty"` + Broadcast bool `mapstructure:"broadcast"` + WalPath string `mapstructure:"wal_dir"` + CacheSize int `mapstructure:"cache_size"` +} + +// DefaultMempoolConfig returns a default configuration for the teragrid mempool +func DefaultMempoolConfig() *MempoolConfig { + return &MempoolConfig{ + Recheck: true, + RecheckEmpty: true, + Broadcast: true, + WalPath: filepath.Join(defaultDataDir, "mempool.wal"), + CacheSize: 100000, + } +} + +// TestMempoolConfig returns a configuration for testing the teragrid mempool +func TestMempoolConfig() *MempoolConfig { + cfg := DefaultMempoolConfig() + cfg.CacheSize = 1000 + return cfg +} + +// WalDir returns the full path to the mempool's write-ahead log +func (cfg *MempoolConfig) WalDir() string { + return rootify(cfg.WalPath, cfg.RootDir) +} + +//----------------------------------------------------------------------------- +// ConsensusConfig + +// ConsensusConfig defines the confuguration for the teragrid consensus service, +// including timeouts and details about the WAL and the block structure. +type ConsensusConfig struct { + RootDir string `mapstructure:"home"` + WalPath string `mapstructure:"wal_file"` + WalLight bool `mapstructure:"wal_light"` + walFile string // overrides WalPath if set + + // All timeouts are in milliseconds + 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"` + + // EmptyBlocks mode and possible interval between empty blocks in seconds + CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"` + CreateEmptyBlocksInterval int `mapstructure:"create_empty_blocks_interval"` + + // Reactor sleep duration parameters are in milliseconds + PeerGossipSleepDuration int `mapstructure:"peer_gossip_sleep_duration"` + PeerQueryMaj23SleepDuration int `mapstructure:"peer_query_maj23_sleep_duration"` +} + +// DefaultConsensusConfig returns a default configuration for the consensus service +func DefaultConsensusConfig() *ConsensusConfig { + return &ConsensusConfig{ + WalPath: filepath.Join(defaultDataDir, "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 + CreateEmptyBlocks: true, + CreateEmptyBlocksInterval: 0, + PeerGossipSleepDuration: 100, + PeerQueryMaj23SleepDuration: 2000, + } +} + +// TestConsensusConfig returns a configuration for testing the consensus service +func TestConsensusConfig() *ConsensusConfig { + cfg := DefaultConsensusConfig() + cfg.TimeoutPropose = 100 + cfg.TimeoutProposeDelta = 1 + cfg.TimeoutPrevote = 10 + cfg.TimeoutPrevoteDelta = 1 + cfg.TimeoutPrecommit = 10 + cfg.TimeoutPrecommitDelta = 1 + cfg.TimeoutCommit = 10 + cfg.SkipTimeoutCommit = true + cfg.PeerGossipSleepDuration = 5 + cfg.PeerQueryMaj23SleepDuration = 250 + return cfg +} + +// WaitForTxs returns true if the consensus should wait for transactions before entering the propose step +func (cfg *ConsensusConfig) WaitForTxs() bool { + return !cfg.CreateEmptyBlocks || cfg.CreateEmptyBlocksInterval > 0 +} + +// EmptyBlocks returns the amount of time to wait before proposing an empty block or starting the propose timer if there are no txs available +func (cfg *ConsensusConfig) EmptyBlocksInterval() time.Duration { + return time.Duration(cfg.CreateEmptyBlocksInterval) * time.Second +} + +// Propose returns the amount of time to wait for a proposal +func (cfg *ConsensusConfig) Propose(round int) time.Duration { + return time.Duration(cfg.TimeoutPropose+cfg.TimeoutProposeDelta*round) * time.Millisecond +} + +// Prevote returns the amount of time to wait for straggler votes after receiving any +2/3 prevotes +func (cfg *ConsensusConfig) Prevote(round int) time.Duration { + return time.Duration(cfg.TimeoutPrevote+cfg.TimeoutPrevoteDelta*round) * time.Millisecond +} + +// Precommit returns the amount of time to wait for straggler votes after receiving any +2/3 precommits +func (cfg *ConsensusConfig) Precommit(round int) time.Duration { + return time.Duration(cfg.TimeoutPrecommit+cfg.TimeoutPrecommitDelta*round) * time.Millisecond +} + +// Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits for a single block (ie. a commit). +func (cfg *ConsensusConfig) Commit(t time.Time) time.Time { + return t.Add(time.Duration(cfg.TimeoutCommit) * time.Millisecond) +} + +// PeerGossipSleep returns the amount of time to sleep if there is nothing to send from the ConsensusReactor +func (cfg *ConsensusConfig) PeerGossipSleep() time.Duration { + return time.Duration(cfg.PeerGossipSleepDuration) * time.Millisecond +} + +// PeerQueryMaj23Sleep returns the amount of time to sleep after each VoteSetMaj23Message is sent in the ConsensusReactor +func (cfg *ConsensusConfig) PeerQueryMaj23Sleep() time.Duration { + return time.Duration(cfg.PeerQueryMaj23SleepDuration) * time.Millisecond +} + +// WalFile returns the full path to the write-ahead log file +func (cfg *ConsensusConfig) WalFile() string { + if cfg.walFile != "" { + return cfg.walFile + } + return rootify(cfg.WalPath, cfg.RootDir) +} + +// SetWalFile sets the path to the write-ahead log file +func (cfg *ConsensusConfig) SetWalFile(walFile string) { + cfg.walFile = walFile +} + +//----------------------------------------------------------------------------- +// TxIndexConfig + +// TxIndexConfig defines the confuguration for the transaction +// indexer, including tags to index. +type TxIndexConfig struct { + // 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 string `mapstructure:"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. + IndexTags string `mapstructure:"index_tags"` + + // 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). + IndexAllTags bool `mapstructure:"index_all_tags"` +} + +// DefaultTxIndexConfig returns a default configuration for the transaction indexer. +func DefaultTxIndexConfig() *TxIndexConfig { + return &TxIndexConfig{ + Indexer: "kv", + IndexTags: "", + IndexAllTags: false, + } +} + +// TestTxIndexConfig returns a default configuration for the transaction indexer. +func TestTxIndexConfig() *TxIndexConfig { + return DefaultTxIndexConfig() +} + +//----------------------------------------------------------------------------- +// Utils + +// helper function to make config creation independent of root dir +func rootify(path, root string) string { + if filepath.IsAbs(path) { + return path + } + return filepath.Join(root, path) +} + +//----------------------------------------------------------------------------- +// Moniker + +var defaultMoniker = getDefaultMoniker() + +// getDefaultMoniker returns a default moniker, which is the host name. If runtime +// fails to get the host name, "anonymous" will be returned. +func getDefaultMoniker() string { + moniker, err := os.Hostname() + if err != nil { + moniker = "anonymous" + } + return moniker +} diff --git a/config/chain_config.go b/config/chain_config.go new file mode 100644 index 0000000..01cd980 --- /dev/null +++ b/config/chain_config.go @@ -0,0 +1,60 @@ +package config + +//----------------------------------------------------------------------------- +// ShardConfig + +// ShardConfig defines the base configuration for a teragrid quorum +type ShardConfig struct { + ShardID string + Validator bool + + // Path to the JSON file containing the private key to use as a validator in the consensus protocol + PrivValidator string `mapstructure:"priv_validator_file"` +} + +// Config defines the top level configuration for a teragrid node +type ChainConfig struct { + // Top level options use an anonymous struct + BaseConfig `mapstructure:",squash"` + Shard []ShardConfig + // Options for services + RPC *RPCConfig `mapstructure:"rpc"` + P2P *P2PConfig `mapstructure:"p2p"` + Mempool *MempoolConfig `mapstructure:"mempool"` + Consensus *ConsensusConfig `mapstructure:"consensus"` + TxIndex *TxIndexConfig `mapstructure:"tx_index"` +} + +// DefaultConfig returns a default configuration for a teragrid node +func DefaultChainConfig() *ChainConfig { + return &ChainConfig{ + BaseConfig: DefaultBaseConfig(), + RPC: DefaultRPCConfig(), + P2P: DefaultP2PConfig(), + Mempool: DefaultMempoolConfig(), + Consensus: DefaultConsensusConfig(), + TxIndex: DefaultTxIndexConfig(), + } +} + +// TestConfig returns a configuration that can be used for testing +func TestChainConfig() *ChainConfig { + return &ChainConfig{ + BaseConfig: TestBaseConfig(), + RPC: TestRPCConfig(), + P2P: TestP2PConfig(), + Mempool: TestMempoolConfig(), + Consensus: TestConsensusConfig(), + TxIndex: TestTxIndexConfig(), + } +} + +// SetRoot sets the RootDir for all Config structs +func (cfg *ChainConfig) SetRoot(root string) *ChainConfig { + cfg.BaseConfig.RootDir = root + cfg.RPC.RootDir = root + cfg.P2P.RootDir = root + cfg.Mempool.RootDir = root + cfg.Consensus.RootDir = root + return cfg +} diff --git a/config/config.go b/config/config.go index 75906ab..2fa2f49 100644 --- a/config/config.go +++ b/config/config.go @@ -1,10 +1,10 @@ package config import ( - "fmt" - "os" + // "fmt" + // "os" "path/filepath" - "time" + // "time" ) // NOTE: Most of the structs & relevant comments + the @@ -15,8 +15,9 @@ import ( // NOTE: teralibs/cli must know to look in the config dir! var ( DefaultteragridDir = ".teragrid" - defaultConfigDir = "config" - defaultDataDir = "data" + defaultChainName = "default" + defaultConfigDir = "config" + defaultDataDir = "data" defaultConfigFileName = "config.toml" defaultGenesisJSONName = "genesis.json" @@ -25,531 +26,53 @@ var ( defaultNodeKeyName = "node_key.json" defaultAddrBookName = "addrbook.json" - defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName) - defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName) - defaultPrivValPath = filepath.Join(defaultConfigDir, defaultPrivValName) - defaultNodeKeyPath = filepath.Join(defaultConfigDir, defaultNodeKeyName) - defaultAddrBookPath = filepath.Join(defaultConfigDir, defaultAddrBookName) + defaultConfigFilePath = filepath.Join(defaultChainName, defaultConfigDir, defaultConfigFileName) + defaultGenesisJSONPath = filepath.Join(defaultChainName, defaultConfigDir, defaultGenesisJSONName) + defaultPrivValPath = filepath.Join(defaultChainName, defaultConfigDir, defaultPrivValName) + defaultNodeKeyPath = filepath.Join(defaultChainName, defaultConfigDir, defaultNodeKeyName) + defaultAddrBookPath = filepath.Join(defaultChainName, defaultConfigDir, defaultAddrBookName) ) -// Config defines the top level configuration for a teragrid node type Config struct { - // Top level options use an anonymous struct - BaseConfig `mapstructure:",squash"` - - // Options for services - RPC *RPCConfig `mapstructure:"rpc"` - P2P *P2PConfig `mapstructure:"p2p"` - Mempool *MempoolConfig `mapstructure:"mempool"` - Consensus *ConsensusConfig `mapstructure:"consensus"` - TxIndex *TxIndexConfig `mapstructure:"tx_index"` -} - -// DefaultConfig returns a default configuration for a teragrid node -func DefaultConfig() *Config { - return &Config{ - BaseConfig: DefaultBaseConfig(), - RPC: DefaultRPCConfig(), - P2P: DefaultP2PConfig(), - Mempool: DefaultMempoolConfig(), - Consensus: DefaultConsensusConfig(), - TxIndex: DefaultTxIndexConfig(), - } -} - -// TestConfig returns a configuration that can be used for testing -func TestConfig() *Config { - return &Config{ - BaseConfig: TestBaseConfig(), - RPC: TestRPCConfig(), - P2P: TestP2PConfig(), - Mempool: TestMempoolConfig(), - Consensus: TestConsensusConfig(), - TxIndex: TestTxIndexConfig(), - } -} - -// SetRoot sets the RootDir for all Config structs -func (cfg *Config) SetRoot(root string) *Config { - cfg.BaseConfig.RootDir = root - cfg.RPC.RootDir = root - cfg.P2P.RootDir = root - cfg.Mempool.RootDir = root - cfg.Consensus.RootDir = root - return cfg -} - -//----------------------------------------------------------------------------- -// BaseConfig - -// BaseConfig defines the base configuration for a teragrid node -type BaseConfig struct { - - // chainID is unexposed and immutable but here for convenience - chainID string - // The root directory for all data. // This should be set in viper so it can unmarshal into this struct RootDir string `mapstructure:"home"` - - // Path to the JSON file containing the initial validator set and other meta data - Genesis string `mapstructure:"genesis_file"` - - // Path to the JSON file containing the private key to use as a validator in the consensus protocol - PrivValidator string `mapstructure:"priv_validator_file"` - - // A JSON file containing the private key to use for p2p authenticated encryption - NodeKey string `mapstructure:"node_key_file"` - - // A custom human readable name for this node - Moniker string `mapstructure:"moniker"` - - // TCP or UNIX socket address for teragrid to listen on for - // connections from an external PrivValidator process - PrivValidatorListenAddr string `mapstructure:"priv_validator_laddr"` - - // TCP or UNIX socket address of the Asura application, - // or the name of an Asura application compiled in with the teragrid binary - ProxyApp string `mapstructure:"proxy_app"` - - // Mechanism to connect to the Asura application: socket | grpc - Asura string `mapstructure:"Asura"` - // Output level for logging - LogLevel string `mapstructure:"log_level"` - - // TCP or UNIX socket address for the profiling server to listen on - ProfListenAddress string `mapstructure:"prof_laddr"` - - // 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 - FastSync bool `mapstructure:"fast_sync"` - - // If true, query the Asura app on connecting to a new peer - // so the app can decide if we should keep the connection or not - FilterPeers bool `mapstructure:"filter_peers"` // false - - // Database backend: leveldb | memdb - DBBackend string `mapstructure:"db_backend"` - - // Database directory - DBPath string `mapstructure:"db_dir"` -} - -// DefaultBaseConfig returns a default base configuration for a teragrid node -func DefaultBaseConfig() BaseConfig { - return BaseConfig{ - Genesis: defaultGenesisJSONPath, - PrivValidator: defaultPrivValPath, - NodeKey: defaultNodeKeyPath, - Moniker: defaultMoniker, - ProxyApp: "tcp://127.0.0.1:46658", - Asura: "socket", - LogLevel: DefaultPackageLogLevels(), - ProfListenAddress: "", - FastSync: true, - FilterPeers: false, - DBBackend: "leveldb", - DBPath: "data", - } -} - -// TestBaseConfig returns a base configuration for testing a teragrid node -func TestBaseConfig() BaseConfig { - cfg := DefaultBaseConfig() - cfg.chainID = "teragrid_test" - cfg.ProxyApp = "kvstore" - cfg.FastSync = false - cfg.DBBackend = "memdb" - return cfg -} - -func (cfg BaseConfig) ChainID() string { - return cfg.chainID -} - -// GenesisFile returns the full path to the genesis.json file -func (cfg BaseConfig) GenesisFile() string { - return rootify(cfg.Genesis, cfg.RootDir) -} - -// PrivValidatorFile returns the full path to the priv_validator.json file -func (cfg BaseConfig) PrivValidatorFile() string { - return rootify(cfg.PrivValidator, cfg.RootDir) -} - -// NodeKeyFile returns the full path to the node_key.json file -func (cfg BaseConfig) NodeKeyFile() string { - return rootify(cfg.NodeKey, cfg.RootDir) -} - -// DBDir returns the full path to the database directory -func (cfg BaseConfig) DBDir() string { - return rootify(cfg.DBPath, cfg.RootDir) -} - -// DefaultLogLevel returns a default log level of "error" -func DefaultLogLevel() string { - return "error" -} - -// DefaultPackageLogLevels returns a default log level setting so all packages -// log at "error", while the `state` and `main` packages log at "info" -func DefaultPackageLogLevels() string { - return fmt.Sprintf("main:info,state:info,*:%s", DefaultLogLevel()) -} - -//----------------------------------------------------------------------------- -// RPCConfig - -// RPCConfig defines the configuration options for the teragrid RPC server -type RPCConfig struct { - RootDir string `mapstructure:"home"` - - // TCP or UNIX socket address for the RPC server to listen on - ListenAddress string `mapstructure:"laddr"` - - // TCP or UNIX socket address for the gRPC server to listen on - // NOTE: This server only supports /broadcast_tx_commit - GRPCListenAddress string `mapstructure:"grpc_laddr"` - - // Activate unsafe RPC commands like /dial_persistent_peers and /unsafe_flush_mempool - Unsafe bool `mapstructure:"unsafe"` -} - -// DefaultRPCConfig returns a default configuration for the RPC server -func DefaultRPCConfig() *RPCConfig { - return &RPCConfig{ - ListenAddress: "tcp://0.0.0.0:46657", - GRPCListenAddress: "", - Unsafe: false, - } -} - -// TestRPCConfig returns a configuration for testing the RPC server -func TestRPCConfig() *RPCConfig { - cfg := DefaultRPCConfig() - cfg.ListenAddress = "tcp://0.0.0.0:36657" - cfg.GRPCListenAddress = "tcp://0.0.0.0:36658" - cfg.Unsafe = true - return cfg -} - -//----------------------------------------------------------------------------- -// P2PConfig - -// P2PConfig defines the configuration options for the teragrid peer-to-peer networking layer -type P2PConfig struct { - RootDir string `mapstructure:"home"` - - // Address to listen for incoming connections - ListenAddress string `mapstructure:"laddr"` - - // Comma separated list of seed nodes to connect to - // We only use these if we can’t connect to peers in the addrbook - Seeds string `mapstructure:"seeds"` - - // Comma separated list of nodes to keep persistent connections to - // Do not add private peers to this list if you don't want them advertised - PersistentPeers string `mapstructure:"persistent_peers"` - - // Skip UPNP port forwarding - SkipUPNP bool `mapstructure:"skip_upnp"` - - // Path to address book - AddrBook string `mapstructure:"addr_book_file"` - - // Set true for strict address routability rules - AddrBookStrict bool `mapstructure:"addr_book_strict"` - - // Maximum number of peers to connect to - MaxNumPeers int `mapstructure:"max_num_peers"` - - // Time to wait before flushing messages out on the connection, in ms - FlushThrottleTimeout int `mapstructure:"flush_throttle_timeout"` - - // Maximum size of a message packet payload, in bytes - MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"` - - // Rate at which packets can be sent, in bytes/second - SendRate int64 `mapstructure:"send_rate"` - - // Rate at which packets can be received, in bytes/second - RecvRate int64 `mapstructure:"recv_rate"` - - // Set true to enable the peer-exchange reactor - PexReactor bool `mapstructure:"pex"` - - // Seed mode, in which node constantly crawls the network and looks for - // peers. If another node asks it for addresses, it responds and disconnects. - // - // Does not work if the peer-exchange reactor is disabled. - SeedMode bool `mapstructure:"seed_mode"` - - // Authenticated encryption - AuthEnc bool `mapstructure:"auth_enc"` - - // Comma separated list of peer IDs to keep private (will not be gossiped to other peers) - PrivatePeerIDs string `mapstructure:"private_peer_ids"` -} - -// DefaultP2PConfig returns a default configuration for the peer-to-peer layer -func DefaultP2PConfig() *P2PConfig { - return &P2PConfig{ - ListenAddress: "tcp://0.0.0.0:46656", - AddrBook: defaultAddrBookPath, - AddrBookStrict: true, - MaxNumPeers: 50, - FlushThrottleTimeout: 100, - MaxPacketMsgPayloadSize: 1024, // 1 kB - SendRate: 512000, // 500 kB/s - RecvRate: 512000, // 500 kB/s - PexReactor: true, - SeedMode: false, - AuthEnc: true, - } -} - -// TestP2PConfig returns a configuration for testing the peer-to-peer layer -func TestP2PConfig() *P2PConfig { - cfg := DefaultP2PConfig() - cfg.ListenAddress = "tcp://0.0.0.0:36656" - cfg.SkipUPNP = true - cfg.FlushThrottleTimeout = 10 - return cfg -} - -// AddrBookFile returns the full path to the address book -func (cfg *P2PConfig) AddrBookFile() string { - return rootify(cfg.AddrBook, cfg.RootDir) + LogLevel string `mapstructure:"log_level"` + ChainConfigs []ChainConfig } -//----------------------------------------------------------------------------- -// MempoolConfig - -// MempoolConfig defines the configuration options for the teragrid mempool -type MempoolConfig struct { - RootDir string `mapstructure:"home"` - Recheck bool `mapstructure:"recheck"` - RecheckEmpty bool `mapstructure:"recheck_empty"` - Broadcast bool `mapstructure:"broadcast"` - WalPath string `mapstructure:"wal_dir"` - CacheSize int `mapstructure:"cache_size"` -} - -// DefaultMempoolConfig returns a default configuration for the teragrid mempool -func DefaultMempoolConfig() *MempoolConfig { - return &MempoolConfig{ - Recheck: true, - RecheckEmpty: true, - Broadcast: true, - WalPath: filepath.Join(defaultDataDir, "mempool.wal"), - CacheSize: 100000, - } -} - -// TestMempoolConfig returns a configuration for testing the teragrid mempool -func TestMempoolConfig() *MempoolConfig { - cfg := DefaultMempoolConfig() - cfg.CacheSize = 1000 - return cfg -} - -// WalDir returns the full path to the mempool's write-ahead log -func (cfg *MempoolConfig) WalDir() string { - return rootify(cfg.WalPath, cfg.RootDir) -} - -//----------------------------------------------------------------------------- -// ConsensusConfig - -// ConsensusConfig defines the confuguration for the teragrid consensus service, -// including timeouts and details about the WAL and the block structure. -type ConsensusConfig struct { - RootDir string `mapstructure:"home"` - WalPath string `mapstructure:"wal_file"` - WalLight bool `mapstructure:"wal_light"` - walFile string // overrides WalPath if set - - // All timeouts are in milliseconds - 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"` - - // EmptyBlocks mode and possible interval between empty blocks in seconds - CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"` - CreateEmptyBlocksInterval int `mapstructure:"create_empty_blocks_interval"` - - // Reactor sleep duration parameters are in milliseconds - PeerGossipSleepDuration int `mapstructure:"peer_gossip_sleep_duration"` - PeerQueryMaj23SleepDuration int `mapstructure:"peer_query_maj23_sleep_duration"` -} - -// DefaultConsensusConfig returns a default configuration for the consensus service -func DefaultConsensusConfig() *ConsensusConfig { - return &ConsensusConfig{ - WalPath: filepath.Join(defaultDataDir, "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 - CreateEmptyBlocks: true, - CreateEmptyBlocksInterval: 0, - PeerGossipSleepDuration: 100, - PeerQueryMaj23SleepDuration: 2000, +// SetRoot sets the RootDir for all Config structs +func (cfg *Config) SetRoot(root string) *Config { + cfg.RootDir = root + for _, chain := range cfg.ChainConfigs { + chainDir := root + chain.ChainID() + chain.BaseConfig.RootDir = chainDir + chain.RPC.RootDir = chainDir + chain.P2P.RootDir = chainDir + chain.Mempool.RootDir = chainDir + chain.Consensus.RootDir = chainDir } -} - -// TestConsensusConfig returns a configuration for testing the consensus service -func TestConsensusConfig() *ConsensusConfig { - cfg := DefaultConsensusConfig() - cfg.TimeoutPropose = 100 - cfg.TimeoutProposeDelta = 1 - cfg.TimeoutPrevote = 10 - cfg.TimeoutPrevoteDelta = 1 - cfg.TimeoutPrecommit = 10 - cfg.TimeoutPrecommitDelta = 1 - cfg.TimeoutCommit = 10 - cfg.SkipTimeoutCommit = true - cfg.PeerGossipSleepDuration = 5 - cfg.PeerQueryMaj23SleepDuration = 250 return cfg } -// WaitForTxs returns true if the consensus should wait for transactions before entering the propose step -func (cfg *ConsensusConfig) WaitForTxs() bool { - return !cfg.CreateEmptyBlocks || cfg.CreateEmptyBlocksInterval > 0 -} - -// EmptyBlocks returns the amount of time to wait before proposing an empty block or starting the propose timer if there are no txs available -func (cfg *ConsensusConfig) EmptyBlocksInterval() time.Duration { - return time.Duration(cfg.CreateEmptyBlocksInterval) * time.Second -} - -// Propose returns the amount of time to wait for a proposal -func (cfg *ConsensusConfig) Propose(round int) time.Duration { - return time.Duration(cfg.TimeoutPropose+cfg.TimeoutProposeDelta*round) * time.Millisecond -} - -// Prevote returns the amount of time to wait for straggler votes after receiving any +2/3 prevotes -func (cfg *ConsensusConfig) Prevote(round int) time.Duration { - return time.Duration(cfg.TimeoutPrevote+cfg.TimeoutPrevoteDelta*round) * time.Millisecond -} - -// Precommit returns the amount of time to wait for straggler votes after receiving any +2/3 precommits -func (cfg *ConsensusConfig) Precommit(round int) time.Duration { - return time.Duration(cfg.TimeoutPrecommit+cfg.TimeoutPrecommitDelta*round) * time.Millisecond -} - -// Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits for a single block (ie. a commit). -func (cfg *ConsensusConfig) Commit(t time.Time) time.Time { - return t.Add(time.Duration(cfg.TimeoutCommit) * time.Millisecond) -} - -// PeerGossipSleep returns the amount of time to sleep if there is nothing to send from the ConsensusReactor -func (cfg *ConsensusConfig) PeerGossipSleep() time.Duration { - return time.Duration(cfg.PeerGossipSleepDuration) * time.Millisecond -} - -// PeerQueryMaj23Sleep returns the amount of time to sleep after each VoteSetMaj23Message is sent in the ConsensusReactor -func (cfg *ConsensusConfig) PeerQueryMaj23Sleep() time.Duration { - return time.Duration(cfg.PeerQueryMaj23SleepDuration) * time.Millisecond -} - -// WalFile returns the full path to the write-ahead log file -func (cfg *ConsensusConfig) WalFile() string { - if cfg.walFile != "" { - return cfg.walFile - } - return rootify(cfg.WalPath, cfg.RootDir) -} - -// SetWalFile sets the path to the write-ahead log file -func (cfg *ConsensusConfig) SetWalFile(walFile string) { - cfg.walFile = walFile -} - -//----------------------------------------------------------------------------- -// TxIndexConfig - -// TxIndexConfig defines the confuguration for the transaction -// indexer, including tags to index. -type TxIndexConfig struct { - // 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 string `mapstructure:"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. - IndexTags string `mapstructure:"index_tags"` - - // 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). - IndexAllTags bool `mapstructure:"index_all_tags"` -} - -// DefaultTxIndexConfig returns a default configuration for the transaction indexer. -func DefaultTxIndexConfig() *TxIndexConfig { - return &TxIndexConfig{ - Indexer: "kv", - IndexTags: "", - IndexAllTags: false, - } -} - -// TestTxIndexConfig returns a default configuration for the transaction indexer. -func TestTxIndexConfig() *TxIndexConfig { - return DefaultTxIndexConfig() -} - -//----------------------------------------------------------------------------- -// Utils - -// helper function to make config creation independent of root dir -func rootify(path, root string) string { - if filepath.IsAbs(path) { - return path +// DefaultConfig returns a default configuration for a teragrid node +func DefaultConfig() *Config { + cfg := Config{ + RootDir: "", + LogLevel: DefaultPackageLogLevels(), } - return filepath.Join(root, path) + cfg.ChainConfigs = make([]ChainConfig, 1) + var chainConfig ChainConfig + chainConfig = *DefaultChainConfig() + cfg.ChainConfigs[0] = chainConfig + return &cfg } -//----------------------------------------------------------------------------- -// Moniker - -var defaultMoniker = getDefaultMoniker() - -// getDefaultMoniker returns a default moniker, which is the host name. If runtime -// fails to get the host name, "anonymous" will be returned. -func getDefaultMoniker() string { - moniker, err := os.Hostname() - if err != nil { - moniker = "anonymous" - } - return moniker +// TestConfig returns a configuration that can be used for testing +func TestConfig() *Config { + return DefaultConfig() + // return &Config{ + // DefaultConfig(), + // } } diff --git a/config/config_test.go b/config/config_test.go index 6379960..6fdcc6a 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -11,18 +11,18 @@ func TestDefaultConfig(t *testing.T) { // set up some defaults cfg := DefaultConfig() - assert.NotNil(cfg.P2P) - assert.NotNil(cfg.Mempool) - assert.NotNil(cfg.Consensus) + assert.NotNil(cfg.RootDir) + // assert.NotNil(cfg.Mempool) + // assert.NotNil(cfg.Consensus) - // check the root dir stuff... + // // check the root dir stuff... cfg.SetRoot("/foo") - cfg.Genesis = "bar" - cfg.DBPath = "/opt/data" - cfg.Mempool.WalPath = "wal/mem/" + // cfg.Genesis = "bar" + // cfg.DBPath = "/opt/data" + // cfg.Mempool.WalPath = "wal/mem/" - assert.Equal("/foo/bar", cfg.GenesisFile()) - assert.Equal("/opt/data", cfg.DBDir()) - assert.Equal("/foo/wal/mem", cfg.Mempool.WalDir()) + // assert.Equal("/foo/bar", cfg.GenesisFile()) + // assert.Equal("/opt/data", cfg.DBDir()) + // assert.Equal("/foo/wal/mem", cfg.Mempool.WalDir()) } diff --git a/config/toml.go b/config/toml.go index 5da2141..ddb40a2 100644 --- a/config/toml.go +++ b/config/toml.go @@ -2,6 +2,7 @@ package config import ( "bytes" + "fmt" "os" "path/filepath" "text/template" @@ -14,6 +15,7 @@ var configTemplate *template.Template func init() { var err error if configTemplate, err = template.New("configFileTemplate").Parse(defaultConfigTemplate); err != nil { + fmt.Println("Error configTemplate") panic(err) } } @@ -23,18 +25,29 @@ func init() { // EnsureRoot creates the root, config, and data directories if they don't exist, // and panics if it fails. func EnsureRoot(rootDir string) { + fmt.Println("EnsureDir_rootDir " + rootDir) if err := cmn.EnsureDir(rootDir, 0700); err != nil { cmn.PanicSanity(err.Error()) } - if err := cmn.EnsureDir(filepath.Join(rootDir, defaultConfigDir), 0700); err != nil { + fmt.Println("EnsureDir_rootDir defaultChainName " + filepath.Join(rootDir, defaultChainName)) + if err := cmn.EnsureDir(filepath.Join(rootDir, defaultChainName), 0700); err != nil { cmn.PanicSanity(err.Error()) } - if err := cmn.EnsureDir(filepath.Join(rootDir, defaultDataDir), 0700); err != nil { + + fmt.Println("EnsureDir_rootDir/defaultChainName/defaultConfigDir " + filepath.Join(rootDir, defaultChainName, defaultConfigDir)) + if err := cmn.EnsureDir(filepath.Join(rootDir, defaultChainName, defaultConfigDir), 0700); err != nil { cmn.PanicSanity(err.Error()) } - configFilePath := filepath.Join(rootDir, defaultConfigFilePath) + fmt.Println("EnsureDir_rootDir/defaultChainName/defaultDataDir " + filepath.Join(rootDir, defaultChainName, defaultDataDir)) + + if err := cmn.EnsureDir(filepath.Join(rootDir, defaultChainName, defaultDataDir), 0700); err != nil { + cmn.PanicSanity(err.Error()) + } + configFilePath := rootDir //filepath.Join(rootDir, defaultChainName, defaultConfigFilePath) + + fmt.Println("EnsureDir_writeDefaultCondigFile rOOT " + configFilePath) // Write default config file if missing. if !cmn.FileExists(configFilePath) { writeDefaultCondigFile(configFilePath) @@ -44,6 +57,7 @@ func EnsureRoot(rootDir string) { // XXX: this func should probably be called by cmd/teragrid/commands/init.go // alongside the writing of the genesis.json and priv_validator.json func writeDefaultCondigFile(configFilePath string) { + fmt.Println("WriteConfigFile x " + configFilePath) WriteConfigFile(configFilePath, DefaultConfig()) } @@ -51,7 +65,8 @@ func writeDefaultCondigFile(configFilePath string) { func WriteConfigFile(configFilePath string, config *Config) { var buffer bytes.Buffer - if err := configTemplate.Execute(&buffer, config); err != nil { + if err := configTemplate.Execute(&buffer, config.ChainConfigs[0]); err != nil { + fmt.Println("WriteConfigFile Panic " + configFilePath) panic(err) } @@ -230,6 +245,7 @@ index_tags = "{{ .TxIndex.IndexTags }}" # 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 ***********/ @@ -253,10 +269,13 @@ func ResetTestRoot(testName string) *Config { if err := cmn.EnsureDir(rootDir, 0700); err != nil { cmn.PanicSanity(err.Error()) } - if err := cmn.EnsureDir(filepath.Join(rootDir, defaultConfigDir), 0700); err != nil { + if err := cmn.EnsureDir(filepath.Join(rootDir, defaultChainName), 0700); err != nil { + cmn.PanicSanity(err.Error()) + } + if err := cmn.EnsureDir(filepath.Join(rootDir, defaultChainName, defaultConfigDir), 0700); err != nil { cmn.PanicSanity(err.Error()) } - if err := cmn.EnsureDir(filepath.Join(rootDir, defaultDataDir), 0700); err != nil { + if err := cmn.EnsureDir(filepath.Join(rootDir, defaultChainName, defaultDataDir), 0700); err != nil { cmn.PanicSanity(err.Error()) } @@ -267,6 +286,7 @@ func ResetTestRoot(testName string) *Config { // Write default config file if missing. if !cmn.FileExists(configFilePath) { + fmt.Println("EnsureDir_writeDefaultCondigFile XXXX " + configFilePath) writeDefaultCondigFile(configFilePath) } if !cmn.FileExists(genesisFilePath) { diff --git a/config/toml_test.go b/config/toml_test.go index a1637f6..d2aee11 100644 --- a/config/toml_test.go +++ b/config/toml_test.go @@ -1,6 +1,7 @@ package config import ( + "fmt" "io/ioutil" "os" "path/filepath" @@ -27,9 +28,12 @@ func TestEnsureRoot(t *testing.T) { require.Nil(err) defer os.RemoveAll(tmpDir) // nolint: errcheck + fmt.Println("TestEnsureRoot, create dir " + tmpDir) // create root dir EnsureRoot(tmpDir) + fmt.Println("TestEnsureRoot " + tmpDir) + fmt.Println("Read File " + filepath.Join(tmpDir, defaultConfigFilePath)) // make sure config is set properly data, err := ioutil.ReadFile(filepath.Join(tmpDir, defaultConfigFilePath)) require.Nil(err) From 8d5ece37ac333ec89d4166f552a369da3689dc67 Mon Sep 17 00:00:00 2001 From: Ha Ly Bang Date: Tue, 26 Jun 2018 16:42:20 +0700 Subject: [PATCH 2/7] Update configs. --- config/base_config.go | 13 ++++---- config/chain_config.go | 4 +-- config/config.go | 29 ++++++++---------- config/config_test.go | 2 ++ config/toml.go | 68 +++++++++++++++++++++++++----------------- config/toml_test.go | 10 +++---- 6 files changed, 67 insertions(+), 59 deletions(-) diff --git a/config/base_config.go b/config/base_config.go index 3868b97..0dfe974 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -66,12 +66,13 @@ type BaseConfig struct { } // DefaultBaseConfig returns a default base configuration for a teragrid node -func DefaultBaseConfig() BaseConfig { +func DefaultBaseConfig(name string) BaseConfig { return BaseConfig{ - Genesis: defaultGenesisJSONPath, - PrivValidator: defaultPrivValPath, - NodeKey: defaultNodeKeyPath, - Moniker: defaultMoniker, + chainID: name, + Genesis: filepath.Join(name, defaultGenesisJSONPath), + PrivValidator: filepath.Join(name, defaultPrivValPath), + NodeKey: filepath.Join(name, defaultNodeKeyPath), + Moniker: filepath.Join(name, defaultMoniker), ProxyApp: "tcp://127.0.0.1:46658", Asura: "socket", LogLevel: DefaultPackageLogLevels(), @@ -85,7 +86,7 @@ func DefaultBaseConfig() BaseConfig { // TestBaseConfig returns a base configuration for testing a teragrid node func TestBaseConfig() BaseConfig { - cfg := DefaultBaseConfig() + cfg := DefaultBaseConfig(defaultChainName) cfg.chainID = "teragrid_test" cfg.ProxyApp = "kvstore" cfg.FastSync = false diff --git a/config/chain_config.go b/config/chain_config.go index 01cd980..c7f2b2e 100644 --- a/config/chain_config.go +++ b/config/chain_config.go @@ -26,9 +26,9 @@ type ChainConfig struct { } // DefaultConfig returns a default configuration for a teragrid node -func DefaultChainConfig() *ChainConfig { +func DefaultChainConfig(name string) *ChainConfig { return &ChainConfig{ - BaseConfig: DefaultBaseConfig(), + BaseConfig: DefaultBaseConfig(name), RPC: DefaultRPCConfig(), P2P: DefaultP2PConfig(), Mempool: DefaultMempoolConfig(), diff --git a/config/config.go b/config/config.go index 2fa2f49..ddffe9f 100644 --- a/config/config.go +++ b/config/config.go @@ -26,11 +26,11 @@ var ( defaultNodeKeyName = "node_key.json" defaultAddrBookName = "addrbook.json" - defaultConfigFilePath = filepath.Join(defaultChainName, defaultConfigDir, defaultConfigFileName) - defaultGenesisJSONPath = filepath.Join(defaultChainName, defaultConfigDir, defaultGenesisJSONName) - defaultPrivValPath = filepath.Join(defaultChainName, defaultConfigDir, defaultPrivValName) - defaultNodeKeyPath = filepath.Join(defaultChainName, defaultConfigDir, defaultNodeKeyName) - defaultAddrBookPath = filepath.Join(defaultChainName, defaultConfigDir, defaultAddrBookName) + defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName) + defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName) + defaultPrivValPath = filepath.Join(defaultConfigDir, defaultPrivValName) + defaultNodeKeyPath = filepath.Join(defaultConfigDir, defaultNodeKeyName) + defaultAddrBookPath = filepath.Join(defaultConfigDir, defaultAddrBookName) ) type Config struct { @@ -47,11 +47,7 @@ func (cfg *Config) SetRoot(root string) *Config { cfg.RootDir = root for _, chain := range cfg.ChainConfigs { chainDir := root + chain.ChainID() - chain.BaseConfig.RootDir = chainDir - chain.RPC.RootDir = chainDir - chain.P2P.RootDir = chainDir - chain.Mempool.RootDir = chainDir - chain.Consensus.RootDir = chainDir + chain.SetRoot(chainDir) } return cfg } @@ -61,18 +57,17 @@ func DefaultConfig() *Config { cfg := Config{ RootDir: "", LogLevel: DefaultPackageLogLevels(), + ChainConfigs: []ChainConfig{ + *DefaultChainConfig(defaultChainName), + }, } - cfg.ChainConfigs = make([]ChainConfig, 1) - var chainConfig ChainConfig - chainConfig = *DefaultChainConfig() - cfg.ChainConfigs[0] = chainConfig return &cfg } // TestConfig returns a configuration that can be used for testing func TestConfig() *Config { return DefaultConfig() - // return &Config{ - // DefaultConfig(), - // } + //return &Config{ + // DefaultConfig(), + //} } diff --git a/config/config_test.go b/config/config_test.go index 6fdcc6a..fbcb28f 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -3,6 +3,7 @@ package config import ( "testing" + _ "github.com/spf13/viper" "github.com/stretchr/testify/assert" ) @@ -11,6 +12,7 @@ func TestDefaultConfig(t *testing.T) { // set up some defaults cfg := DefaultConfig() + assert.NotNil(cfg.RootDir) // assert.NotNil(cfg.Mempool) // assert.NotNil(cfg.Consensus) diff --git a/config/toml.go b/config/toml.go index ddb40a2..cb57eb9 100644 --- a/config/toml.go +++ b/config/toml.go @@ -7,6 +7,7 @@ import ( "path/filepath" "text/template" + "github.com/spf13/viper" cmn "github.com/teragrid/teralibs/common" ) @@ -25,52 +26,63 @@ func init() { // EnsureRoot creates the root, config, and data directories if they don't exist, // and panics if it fails. func EnsureRoot(rootDir string) { - fmt.Println("EnsureDir_rootDir " + rootDir) - if err := cmn.EnsureDir(rootDir, 0700); err != nil { - cmn.PanicSanity(err.Error()) - } - fmt.Println("EnsureDir_rootDir defaultChainName " + filepath.Join(rootDir, defaultChainName)) - if err := cmn.EnsureDir(filepath.Join(rootDir, defaultChainName), 0700); err != nil { - cmn.PanicSanity(err.Error()) - } - fmt.Println("EnsureDir_rootDir/defaultChainName/defaultConfigDir " + filepath.Join(rootDir, defaultChainName, defaultConfigDir)) - if err := cmn.EnsureDir(filepath.Join(rootDir, defaultChainName, defaultConfigDir), 0700); err != nil { + if err := cmn.EnsureDir(rootDir, 0700); err != nil { cmn.PanicSanity(err.Error()) } - - fmt.Println("EnsureDir_rootDir/defaultChainName/defaultDataDir " + filepath.Join(rootDir, defaultChainName, defaultDataDir)) - - if err := cmn.EnsureDir(filepath.Join(rootDir, defaultChainName, defaultDataDir), 0700); err != nil { - cmn.PanicSanity(err.Error()) + config := DefaultConfig() + for _, chain := range config.ChainConfigs { + chainDir := chain.ChainID() + if err := cmn.EnsureDir(filepath.Join(rootDir, chainDir), 0700); err != nil { + cmn.PanicSanity(err.Error()) + } + if err := cmn.EnsureDir(filepath.Join(rootDir, chainDir, defaultConfigDir), 0700); err != nil { + cmn.PanicSanity(err.Error()) + } + if err := cmn.EnsureDir(filepath.Join(rootDir, chainDir, defaultDataDir), 0700); err != nil { + cmn.PanicSanity(err.Error()) + } } configFilePath := rootDir //filepath.Join(rootDir, defaultChainName, defaultConfigFilePath) fmt.Println("EnsureDir_writeDefaultCondigFile rOOT " + configFilePath) // Write default config file if missing. - if !cmn.FileExists(configFilePath) { - writeDefaultCondigFile(configFilePath) + if !cmn.FileExists(filepath.Join(configFilePath, "config.json")) { + //fmt.Println("EnsureRoot: writeDefaultCondigFile rOOT " + configFilePath) + writeDefaultConfigFile(configFilePath) } } // XXX: this func should probably be called by cmd/teragrid/commands/init.go // alongside the writing of the genesis.json and priv_validator.json -func writeDefaultCondigFile(configFilePath string) { +func writeDefaultConfigFile(configFilePath string) { fmt.Println("WriteConfigFile x " + configFilePath) WriteConfigFile(configFilePath, DefaultConfig()) } // WriteConfigFile renders config using the template and writes it to configFilePath. func WriteConfigFile(configFilePath string, config *Config) { - var buffer bytes.Buffer - - if err := configTemplate.Execute(&buffer, config.ChainConfigs[0]); err != nil { - fmt.Println("WriteConfigFile Panic " + configFilePath) - panic(err) + var runtime_viper = viper.New() + runtime_viper.SetConfigType("json") + runtime_viper.SetConfigFile(filepath.Join(configFilePath, "config.json")) + runtime_viper.SetDefault("LogLevel", config.LogLevel) + + var chains []string + chains = make([]string, len(config.ChainConfigs)) + for idx, chain := range config.ChainConfigs { + chains[idx] = chain.ChainID() + var buffer bytes.Buffer + + if err := configTemplate.Execute(&buffer, chain); err != nil { + fmt.Println("WriteConfigFile Panic " + configFilePath) + panic(err) + } else { + cmn.MustWriteFile(filepath.Join(configFilePath, chain.ChainID(), defaultConfigFilePath), buffer.Bytes(), 0644) + } } - - cmn.MustWriteFile(configFilePath, buffer.Bytes(), 0644) + runtime_viper.SetDefault("Chains", chains) + runtime_viper.WriteConfig() } // Note: any changes to the comments/variables/mapstructure @@ -279,15 +291,15 @@ func ResetTestRoot(testName string) *Config { cmn.PanicSanity(err.Error()) } - baseConfig := DefaultBaseConfig() - configFilePath := filepath.Join(rootDir, defaultConfigFilePath) + baseConfig := DefaultBaseConfig(defaultChainName) + configFilePath := filepath.Join(rootDir, defaultChainName, defaultConfigFilePath) genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis) privFilePath := filepath.Join(rootDir, baseConfig.PrivValidator) // Write default config file if missing. if !cmn.FileExists(configFilePath) { fmt.Println("EnsureDir_writeDefaultCondigFile XXXX " + configFilePath) - writeDefaultCondigFile(configFilePath) + writeDefaultConfigFile(rootDir) } if !cmn.FileExists(genesisFilePath) { cmn.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644) diff --git a/config/toml_test.go b/config/toml_test.go index d2aee11..ee8ef0d 100644 --- a/config/toml_test.go +++ b/config/toml_test.go @@ -28,14 +28,12 @@ func TestEnsureRoot(t *testing.T) { require.Nil(err) defer os.RemoveAll(tmpDir) // nolint: errcheck - fmt.Println("TestEnsureRoot, create dir " + tmpDir) // create root dir EnsureRoot(tmpDir) - fmt.Println("TestEnsureRoot " + tmpDir) - fmt.Println("Read File " + filepath.Join(tmpDir, defaultConfigFilePath)) + fmt.Println("Read File " + filepath.Join(tmpDir, defaultChainName, defaultConfigFilePath)) // make sure config is set properly - data, err := ioutil.ReadFile(filepath.Join(tmpDir, defaultConfigFilePath)) + data, err := ioutil.ReadFile(filepath.Join(tmpDir, defaultChainName, defaultConfigFilePath)) require.Nil(err) if !checkConfig(string(data)) { @@ -55,7 +53,7 @@ func TestEnsureTestRoot(t *testing.T) { rootDir := cfg.RootDir // make sure config is set properly - data, err := ioutil.ReadFile(filepath.Join(rootDir, defaultConfigFilePath)) + data, err := ioutil.ReadFile(filepath.Join(rootDir, defaultChainName, defaultConfigFilePath)) require.Nil(err) if !checkConfig(string(data)) { @@ -63,7 +61,7 @@ func TestEnsureTestRoot(t *testing.T) { } // TODO: make sure the cfg returned and testconfig are the same! - baseConfig := DefaultBaseConfig() + baseConfig := DefaultBaseConfig(defaultChainName) ensureFiles(t, rootDir, defaultDataDir, baseConfig.Genesis, baseConfig.PrivValidator) } From 7cd563b846d21c8bc87f23b9f3d82d89ddfedeb0 Mon Sep 17 00:00:00 2001 From: Ha Ly Bang Date: Tue, 26 Jun 2018 18:04:43 +0700 Subject: [PATCH 3/7] Update configs.(WIP) --- cmd/teragrid/commands/init.go | 74 ++++++++--------- cmd/teragrid/commands/root.go | 9 ++- cmd/teragrid/commands/testnet.go | 131 ++++++++++++++++--------------- cmd/teragrid/main.go | 56 ++++++++++--- config/base_config.go | 8 +- config/chain_config.go | 1 + config/config.go | 9 +-- config/toml.go | 25 +++--- consensus/wal_generator.go | 8 +- node/node.go | 12 +-- 10 files changed, 186 insertions(+), 147 deletions(-) diff --git a/cmd/teragrid/commands/init.go b/cmd/teragrid/commands/init.go index b138275..2e6f870 100644 --- a/cmd/teragrid/commands/init.go +++ b/cmd/teragrid/commands/init.go @@ -18,50 +18,52 @@ var InitFilesCmd = &cobra.Command{ } func initFiles(cmd *cobra.Command, args []string) error { - return initFilesWithConfig(config) + return initFilesWithConfig(mainConfig) } func initFilesWithConfig(config *cfg.Config) error { - // private validator - privValFile := config.PrivValidatorFile() - var pv *pvm.FilePV - if cmn.FileExists(privValFile) { - pv = pvm.LoadFilePV(privValFile) - logger.Info("Found private validator", "path", privValFile) - } else { - pv = pvm.GenFilePV(privValFile) - pv.Save() - logger.Info("Generated private validator", "path", privValFile) - } - - nodeKeyFile := config.NodeKeyFile() - if cmn.FileExists(nodeKeyFile) { - logger.Info("Found node key", "path", nodeKeyFile) - } else { - if _, err := p2p.LoadOrGenNodeKey(nodeKeyFile); err != nil { - return err + config.SetRoot(config.RootDir) + for _, chain := range config.ChainConfigs { + // private validator + privValFile := chain.PrivValidatorFile() + var pv *pvm.FilePV + if cmn.FileExists(privValFile) { + pv = pvm.LoadFilePV(privValFile) + logger.Info("Found private validator", "path", privValFile) + } else { + pv = pvm.GenFilePV(privValFile) + pv.Save() + logger.Info("Generated private validator", "path", privValFile) } - logger.Info("Generated node key", "path", nodeKeyFile) - } - // genesis file - genFile := config.GenesisFile() - if cmn.FileExists(genFile) { - logger.Info("Found genesis file", "path", genFile) - } else { - genDoc := types.GenesisDoc{ - ChainID: cmn.Fmt("test-chain-%v", cmn.RandStr(6)), + nodeKeyFile := chain.NodeKeyFile() + if cmn.FileExists(nodeKeyFile) { + logger.Info("Found node key", "path", nodeKeyFile) + } else { + if _, err := p2p.LoadOrGenNodeKey(nodeKeyFile); err != nil { + return err + } + logger.Info("Generated node key", "path", nodeKeyFile) } - genDoc.Validators = []types.GenesisValidator{{ - PubKey: pv.GetPubKey(), - Power: 10, - }} - if err := genDoc.SaveAs(genFile); err != nil { - return err + // genesis file + genFile := chain.GenesisFile() + if cmn.FileExists(genFile) { + logger.Info("Found genesis file", "path", genFile) + } else { + genDoc := types.GenesisDoc{ + ChainID: cmn.Fmt("test-chain-%v", cmn.RandStr(6)), + } + genDoc.Validators = []types.GenesisValidator{{ + PubKey: pv.GetPubKey(), + Power: 10, + }} + + if err := genDoc.SaveAs(genFile); err != nil { + return err + } + logger.Info("Generated genesis file", "path", genFile) } - logger.Info("Generated genesis file", "path", genFile) } - return nil } diff --git a/cmd/teragrid/commands/root.go b/cmd/teragrid/commands/root.go index 4d057e3..b63f4b1 100644 --- a/cmd/teragrid/commands/root.go +++ b/cmd/teragrid/commands/root.go @@ -13,8 +13,9 @@ import ( ) var ( - config = cfg.DefaultConfig() - logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + mainConfig = cfg.DefaultConfig() + config = mainConfig.ChainConfigs[0] + logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) ) func init() { @@ -34,7 +35,7 @@ func ParseConfig() (*cfg.Config, error) { return nil, err } conf.SetRoot(conf.RootDir) - cfg.EnsureRoot(conf.RootDir) + cfg.EnsureRoot(conf.RootDir, conf) return conf, err } @@ -46,7 +47,7 @@ var RootCmd = &cobra.Command{ if cmd.Name() == VersionCmd.Name() { return nil } - config, err = ParseConfig() + mainConfig, err = ParseConfig() if err != nil { return err } diff --git a/cmd/teragrid/commands/testnet.go b/cmd/teragrid/commands/testnet.go index 4aa53e0..a627b7c 100644 --- a/cmd/teragrid/commands/testnet.go +++ b/cmd/teragrid/commands/testnet.go @@ -63,66 +63,66 @@ var TestnetFilesCmd = &cobra.Command{ func testnetFiles(cmd *cobra.Command, args []string) error { config := cfg.DefaultConfig() genVals := make([]types.GenesisValidator, nValidators) - - for i := 0; i < nValidators; i++ { - nodeDirName := cmn.Fmt("%s%d", nodeDirPrefix, i) - nodeDir := filepath.Join(outputDir, nodeDirName) - config.SetRoot(nodeDir) - - err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm) - if err != nil { - _ = os.RemoveAll(outputDir) - return err + for _, chain := range config.ChainConfigs { + for i := 0; i < nValidators; i++ { + nodeDirName := cmn.Fmt("%s%d", nodeDirPrefix, i) + nodeDir := filepath.Join(outputDir, nodeDirName) + config.SetRoot(nodeDir) + + err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm) + if err != nil { + _ = os.RemoveAll(outputDir) + return err + } + + initFilesWithConfig(config) + + pvFile := filepath.Join(nodeDir, chain.BaseConfig.PrivValidator) + pv := pvm.LoadFilePV(pvFile) + genVals[i] = types.GenesisValidator{ + PubKey: pv.GetPubKey(), + Power: 1, + Name: nodeDirName, + } } - initFilesWithConfig(config) + for i := 0; i < nNonValidators; i++ { + nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i+nValidators)) + config.SetRoot(nodeDir) - pvFile := filepath.Join(nodeDir, config.BaseConfig.PrivValidator) - pv := pvm.LoadFilePV(pvFile) - genVals[i] = types.GenesisValidator{ - PubKey: pv.GetPubKey(), - Power: 1, - Name: nodeDirName, - } - } + err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm) + if err != nil { + _ = os.RemoveAll(outputDir) + return err + } - for i := 0; i < nNonValidators; i++ { - nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i+nValidators)) - config.SetRoot(nodeDir) - - err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm) - if err != nil { - _ = os.RemoveAll(outputDir) - return err + initFilesWithConfig(config) } - initFilesWithConfig(config) - } - - // Generate genesis doc from generated validators - genDoc := &types.GenesisDoc{ - GenesisTime: time.Now(), - ChainID: "chain-" + cmn.RandStr(6), - Validators: genVals, - } + // Generate genesis doc from generated validators + genDoc := &types.GenesisDoc{ + GenesisTime: time.Now(), + ChainID: "chain-" + cmn.RandStr(6), + Validators: genVals, + } - // Write genesis file. - for i := 0; i < nValidators+nNonValidators; i++ { - nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i)) - if err := genDoc.SaveAs(filepath.Join(nodeDir, config.BaseConfig.Genesis)); err != nil { - _ = os.RemoveAll(outputDir) - return err + // Write genesis file. + for i := 0; i < nValidators+nNonValidators; i++ { + nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i)) + if err := genDoc.SaveAs(filepath.Join(nodeDir, chain.BaseConfig.Genesis)); err != nil { + _ = os.RemoveAll(outputDir) + return err + } } - } - if populatePersistentPeers { - err := populatePersistentPeersInConfigAndWriteIt(config) - if err != nil { - _ = os.RemoveAll(outputDir) - return err + if populatePersistentPeers { + err := populatePersistentPeersInConfigAndWriteIt(config) + if err != nil { + _ = os.RemoveAll(outputDir) + return err + } } } - fmt.Printf("Successfully initialized %v node directories\n", nValidators+nNonValidators) return nil } @@ -147,25 +147,26 @@ func hostnameOrIP(i int) string { func populatePersistentPeersInConfigAndWriteIt(config *cfg.Config) error { persistentPeers := make([]string, nValidators+nNonValidators) - for i := 0; i < nValidators+nNonValidators; i++ { - nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i)) - config.SetRoot(nodeDir) - nodeKey, err := p2p.LoadNodeKey(config.NodeKeyFile()) - if err != nil { - return err + for _, chain := range config.ChainConfigs { + for i := 0; i < nValidators+nNonValidators; i++ { + nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i)) + config.SetRoot(nodeDir) + nodeKey, err := p2p.LoadNodeKey(chain.NodeKeyFile()) + if err != nil { + return err + } + persistentPeers[i] = p2p.IDAddressString(nodeKey.ID(), fmt.Sprintf("%s:%d", hostnameOrIP(i), p2pPort)) } - persistentPeers[i] = p2p.IDAddressString(nodeKey.ID(), fmt.Sprintf("%s:%d", hostnameOrIP(i), p2pPort)) - } - persistentPeersList := strings.Join(persistentPeers, ",") + persistentPeersList := strings.Join(persistentPeers, ",") - for i := 0; i < nValidators+nNonValidators; i++ { - nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i)) - config.SetRoot(nodeDir) - config.P2P.PersistentPeers = persistentPeersList + for i := 0; i < nValidators+nNonValidators; i++ { + nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i)) + chain.SetRoot(nodeDir) + chain.P2P.PersistentPeers = persistentPeersList - // overwrite default config - cfg.WriteConfigFile(filepath.Join(nodeDir, "config", "config.toml"), config) + // overwrite default config + cfg.WriteConfigFile(filepath.Join(nodeDir, "config", "config.toml"), config) + } } - return nil } diff --git a/cmd/teragrid/main.go b/cmd/teragrid/main.go index 57299da..d301050 100644 --- a/cmd/teragrid/main.go +++ b/cmd/teragrid/main.go @@ -1,9 +1,12 @@ package main import ( + "fmt" "os" "path/filepath" + "github.com/spf13/viper" + "github.com/teragrid/teralibs/cli" cmd "github.com/teragrid/teragrid/cmd/teragrid/commands" @@ -12,20 +15,53 @@ import ( ) func main() { + + viper.SetConfigName("config") + viper.AddConfigPath(".") + //viper.AddConfigPath(os.U) + err := viper.ReadInConfig() + if err != nil { + //panic(err) + fmt.Println("Config not found") + } else { + chains := viper.GetStringSlice("chains") + fmt.Println("ChainSize:", len(chains)) + for idx, item := range chains { + fmt.Println("Chain", idx, item) + } + } + + /* + //err2 := viper.Unmarshal(&cfgIn) + // if err2 != nil { + // cfg := config.DefaultConfig() + // fmt.Println("ConfigSize:", len(cfg.ChainConfigs)) + // viper.SetDefault("LogLevel", cfg.LogLevel) + // viper.SetDefault("Chains", cfg.ChainConfigs) + // viper.SetConfigType("json") + // viper.WriteConfig() + // return + // } + // cfgIn.ChainConfigs = []viper.GetStringMap("chains") + // cfgIn.LogLevel = viper.GetString("LogLevel") + // fmt.Println("LogLevel:", cfgIn.LogLevel) + // fmt.Println("ConfigSize:", len(cfgIn.ChainConfigs)) + return + */ rootCmd := cmd.RootCmd rootCmd.AddCommand( - cmd.GenValidatorCmd, + // cmd.GenValidatorCmd, cmd.InitFilesCmd, - cmd.ProbeUpnpCmd, - cmd.LiteCmd, - cmd.ReplayCmd, - cmd.ReplayConsoleCmd, - cmd.ResetAllCmd, - cmd.ResetPrivValidatorCmd, - cmd.ShowValidatorCmd, + // cmd.ProbeUpnpCmd, + // cmd.LiteCmd, + // cmd.ReplayCmd, + // cmd.ReplayConsoleCmd, + // cmd.ResetAllCmd, + // cmd.ResetPrivValidatorCmd, + // cmd.ShowValidatorCmd, cmd.TestnetFilesCmd, - cmd.ShowNodeIDCmd, - cmd.GenNodeKeyCmd, + // cmd.ShowNodeIDCmd, + // cmd.GenNodeKeyCmd, cmd.VersionCmd) // NOTE: diff --git a/config/base_config.go b/config/base_config.go index 0dfe974..26aaf1c 100644 --- a/config/base_config.go +++ b/config/base_config.go @@ -69,10 +69,10 @@ type BaseConfig struct { func DefaultBaseConfig(name string) BaseConfig { return BaseConfig{ chainID: name, - Genesis: filepath.Join(name, defaultGenesisJSONPath), - PrivValidator: filepath.Join(name, defaultPrivValPath), - NodeKey: filepath.Join(name, defaultNodeKeyPath), - Moniker: filepath.Join(name, defaultMoniker), + Genesis: defaultGenesisJSONPath, + PrivValidator: defaultPrivValPath, + NodeKey: defaultNodeKeyPath, + Moniker: defaultMoniker, ProxyApp: "tcp://127.0.0.1:46658", Asura: "socket", LogLevel: DefaultPackageLogLevels(), diff --git a/config/chain_config.go b/config/chain_config.go index c7f2b2e..4feaa1d 100644 --- a/config/chain_config.go +++ b/config/chain_config.go @@ -51,6 +51,7 @@ func TestChainConfig() *ChainConfig { // SetRoot sets the RootDir for all Config structs func (cfg *ChainConfig) SetRoot(root string) *ChainConfig { + cfg.RootDir = root cfg.BaseConfig.RootDir = root cfg.RPC.RootDir = root cfg.P2P.RootDir = root diff --git a/config/config.go b/config/config.go index ddffe9f..7306656 100644 --- a/config/config.go +++ b/config/config.go @@ -1,7 +1,6 @@ package config import ( - // "fmt" // "os" "path/filepath" // "time" @@ -39,14 +38,14 @@ type Config struct { RootDir string `mapstructure:"home"` // Output level for logging LogLevel string `mapstructure:"log_level"` - ChainConfigs []ChainConfig + ChainConfigs []*ChainConfig } // SetRoot sets the RootDir for all Config structs func (cfg *Config) SetRoot(root string) *Config { cfg.RootDir = root for _, chain := range cfg.ChainConfigs { - chainDir := root + chain.ChainID() + chainDir := filepath.Join(root, chain.ChainID()) chain.SetRoot(chainDir) } return cfg @@ -57,8 +56,8 @@ func DefaultConfig() *Config { cfg := Config{ RootDir: "", LogLevel: DefaultPackageLogLevels(), - ChainConfigs: []ChainConfig{ - *DefaultChainConfig(defaultChainName), + ChainConfigs: []*ChainConfig{ + DefaultChainConfig(defaultChainName), }, } return &cfg diff --git a/config/toml.go b/config/toml.go index cb57eb9..f28848c 100644 --- a/config/toml.go +++ b/config/toml.go @@ -25,12 +25,11 @@ func init() { // EnsureRoot creates the root, config, and data directories if they don't exist, // and panics if it fails. -func EnsureRoot(rootDir string) { - +func EnsureRoot(rootDir string, config *Config) { if err := cmn.EnsureDir(rootDir, 0700); err != nil { cmn.PanicSanity(err.Error()) } - config := DefaultConfig() + //config := DefaultConfig() for _, chain := range config.ChainConfigs { chainDir := chain.ChainID() if err := cmn.EnsureDir(filepath.Join(rootDir, chainDir), 0700); err != nil { @@ -46,19 +45,16 @@ func EnsureRoot(rootDir string) { configFilePath := rootDir //filepath.Join(rootDir, defaultChainName, defaultConfigFilePath) - fmt.Println("EnsureDir_writeDefaultCondigFile rOOT " + configFilePath) // Write default config file if missing. if !cmn.FileExists(filepath.Join(configFilePath, "config.json")) { - //fmt.Println("EnsureRoot: writeDefaultCondigFile rOOT " + configFilePath) - writeDefaultConfigFile(configFilePath) + writeDefaultConfigFile(configFilePath, config) } } // XXX: this func should probably be called by cmd/teragrid/commands/init.go // alongside the writing of the genesis.json and priv_validator.json -func writeDefaultConfigFile(configFilePath string) { - fmt.Println("WriteConfigFile x " + configFilePath) - WriteConfigFile(configFilePath, DefaultConfig()) +func writeDefaultConfigFile(configFilePath string, config *Config) { + WriteConfigFile(configFilePath, config) } // WriteConfigFile renders config using the template and writes it to configFilePath. @@ -72,6 +68,7 @@ func WriteConfigFile(configFilePath string, config *Config) { chains = make([]string, len(config.ChainConfigs)) for idx, chain := range config.ChainConfigs { chains[idx] = chain.ChainID() + var buffer bytes.Buffer if err := configTemplate.Execute(&buffer, chain); err != nil { @@ -291,7 +288,9 @@ func ResetTestRoot(testName string) *Config { cmn.PanicSanity(err.Error()) } - baseConfig := DefaultBaseConfig(defaultChainName) + config := DefaultConfig() + //baseConfig := DefaultBaseConfig(defaultChainName) + baseConfig := config.ChainConfigs[0] configFilePath := filepath.Join(rootDir, defaultChainName, defaultConfigFilePath) genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis) privFilePath := filepath.Join(rootDir, baseConfig.PrivValidator) @@ -299,7 +298,7 @@ func ResetTestRoot(testName string) *Config { // Write default config file if missing. if !cmn.FileExists(configFilePath) { fmt.Println("EnsureDir_writeDefaultCondigFile XXXX " + configFilePath) - writeDefaultConfigFile(rootDir) + writeDefaultConfigFile(rootDir, config) } if !cmn.FileExists(genesisFilePath) { cmn.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644) @@ -307,8 +306,8 @@ func ResetTestRoot(testName string) *Config { // we always overwrite the priv val cmn.MustWriteFile(privFilePath, []byte(testPrivValidator), 0644) - config := TestConfig().SetRoot(rootDir) - return config + configX := TestConfig().SetRoot(rootDir) + return configX } var testGenesis = `{ diff --git a/consensus/wal_generator.go b/consensus/wal_generator.go index dcc38bf..817e0d8 100644 --- a/consensus/wal_generator.go +++ b/consensus/wal_generator.go @@ -29,7 +29,7 @@ import ( // (byteBufferWAL) and waits until numBlocks are created. Then it returns a WAL // content. func WALWithNBlocks(numBlocks int) (data []byte, err error) { - config := getConfig() + config := getConfig().ChainConfigs[0] app := kvstore.NewPersistentKVStoreApplication(filepath.Join(config.DBDir(), "wal_generator")) @@ -133,9 +133,9 @@ func getConfig() *cfg.Config { // and we use random ports to run in parallel tm, rpc, grpc := makeAddrs() - c.P2P.ListenAddress = tm - c.RPC.ListenAddress = rpc - c.RPC.GRPCListenAddress = grpc + c.ChainConfigs[0].P2P.ListenAddress = tm + c.ChainConfigs[0].RPC.ListenAddress = rpc + c.ChainConfigs[0].RPC.GRPCListenAddress = grpc return c } diff --git a/node/node.go b/node/node.go index 715836c..c85ceef 100644 --- a/node/node.go +++ b/node/node.go @@ -44,7 +44,7 @@ import ( // DBContext specifies config information for loading a new DB. type DBContext struct { ID string - Config *cfg.Config + Config *cfg.ChainConfig } // DBProvider takes a DBContext and returns an instantiated DB. @@ -64,19 +64,19 @@ type GenesisDocProvider func() (*types.GenesisDoc, error) // DefaultGenesisDocProviderFunc returns a GenesisDocProvider that loads // the GenesisDoc from the config.GenesisFile() on the filesystem. -func DefaultGenesisDocProviderFunc(config *cfg.Config) GenesisDocProvider { +func DefaultGenesisDocProviderFunc(config *cfg.ChainConfig) GenesisDocProvider { return func() (*types.GenesisDoc, error) { return types.GenesisDocFromFile(config.GenesisFile()) } } // NodeProvider takes a config and a logger and returns a ready to go Node. -type NodeProvider func(*cfg.Config, log.Logger) (*Node, error) +type NodeProvider func(*cfg.ChainConfig, log.Logger) (*Node, error) // DefaultNewNode returns a teragrid node with default settings for the // PrivValidator, ClientCreator, GenesisDoc, and DBProvider. // It implements NodeProvider. -func DefaultNewNode(config *cfg.Config, logger log.Logger) (*Node, error) { +func DefaultNewNode(config *cfg.ChainConfig, logger log.Logger) (*Node, error) { return NewNode(config, pvm.LoadOrGenFilePV(config.PrivValidatorFile()), proxy.DefaultClientCreator(config.ProxyApp, config.Asura, config.DBDir()), @@ -94,7 +94,7 @@ type Node struct { cmn.BaseService // config - config *cfg.Config + config *cfg.ChainConfig genesisDoc *types.GenesisDoc // initial validator set privValidator types.PrivValidator // local node's validator key @@ -119,7 +119,7 @@ type Node struct { } // NewNode returns a new, ready to go, teragrid Node. -func NewNode(config *cfg.Config, +func NewNode(config *cfg.ChainConfig, privValidator types.PrivValidator, clientCreator proxy.ClientCreator, genesisDocProvider GenesisDocProvider, From dfab5b819c493518dad471227fc43f5afdfb1a74 Mon Sep 17 00:00:00 2001 From: Ha Ly Bang Date: Mon, 9 Jul 2018 15:56:59 +0700 Subject: [PATCH 4/7] Update --- cmd/teragrid/commands/gen_node_key.go | 18 +- cmd/teragrid/commands/gen_validator.go | 4 +- cmd/teragrid/commands/init.go | 19 +- cmd/teragrid/commands/lite.go | 12 +- cmd/teragrid/commands/replay.go | 10 +- cmd/teragrid/commands/reset_priv_validator.go | 56 +- cmd/teragrid/commands/root.go | 77 ++- cmd/teragrid/commands/run_node.go | 93 ++- cmd/teragrid/commands/show_node_id.go | 13 +- cmd/teragrid/commands/show_validator.go | 11 +- cmd/teragrid/commands/testnet.go | 34 +- cmd/teragrid/main.go | 73 +-- config/base_config.go | 484 --------------- config/chain_config.go | 10 +- config/config.go | 565 ++++++++++++++++-- config/config_test.go | 2 +- config/main_config.go | 73 +++ config/toml.go | 84 +-- config/toml_test.go | 4 +- 19 files changed, 919 insertions(+), 723 deletions(-) delete mode 100644 config/base_config.go create mode 100644 config/main_config.go diff --git a/cmd/teragrid/commands/gen_node_key.go b/cmd/teragrid/commands/gen_node_key.go index de0160a..edb2678 100644 --- a/cmd/teragrid/commands/gen_node_key.go +++ b/cmd/teragrid/commands/gen_node_key.go @@ -18,15 +18,17 @@ var GenNodeKeyCmd = &cobra.Command{ } func genNodeKey(cmd *cobra.Command, args []string) error { - nodeKeyFile := config.NodeKeyFile() - if cmn.FileExists(nodeKeyFile) { - return fmt.Errorf("node key at %s already exists", nodeKeyFile) - } + for _, config := range mainConfig.ChainConfigs { + nodeKeyFile := config.NodeKeyFile() + if cmn.FileExists(nodeKeyFile) { + return fmt.Errorf("node key at %s already exists", nodeKeyFile) + } - nodeKey, err := p2p.LoadOrGenNodeKey(nodeKeyFile) - if err != nil { - return err + nodeKey, err := p2p.LoadOrGenNodeKey(nodeKeyFile) + if err != nil { + return err + } + fmt.Println(nodeKey.ID()) } - fmt.Println(nodeKey.ID()) return nil } diff --git a/cmd/teragrid/commands/gen_validator.go b/cmd/teragrid/commands/gen_validator.go index 44a36c5..a236257 100644 --- a/cmd/teragrid/commands/gen_validator.go +++ b/cmd/teragrid/commands/gen_validator.go @@ -5,7 +5,7 @@ import ( "github.com/spf13/cobra" - pvm "github.com/teragrid/teragrid/types/priv_validator" + "github.com/teragrid/teragrid/types/priv_validator" ) // GenValidatorCmd allows the generation of a keypair for a @@ -17,7 +17,7 @@ var GenValidatorCmd = &cobra.Command{ } func genValidator(cmd *cobra.Command, args []string) { - pv := pvm.GenFilePV("") + pv := privval.GenFilePV("") jsbz, err := cdc.MarshalJSON(pv) if err != nil { panic(err) diff --git a/cmd/teragrid/commands/init.go b/cmd/teragrid/commands/init.go index 2e6f870..a7c0288 100644 --- a/cmd/teragrid/commands/init.go +++ b/cmd/teragrid/commands/init.go @@ -1,19 +1,21 @@ package commands import ( + "time" + "github.com/spf13/cobra" cfg "github.com/teragrid/teragrid/config" "github.com/teragrid/teragrid/p2p" "github.com/teragrid/teragrid/types" - pvm "github.com/teragrid/teragrid/types/priv_validator" + "github.com/teragrid/teragrid/types/priv_validator" cmn "github.com/teragrid/teralibs/common" ) -// InitFilesCmd initialises a fresh teragrid Core instance. +// InitFilesCmd initialises a fresh Tendermint Core instance. var InitFilesCmd = &cobra.Command{ Use: "init", - Short: "Initialize teragrid", + Short: "Initialize Tendermint", RunE: initFiles, } @@ -22,16 +24,16 @@ func initFiles(cmd *cobra.Command, args []string) error { } func initFilesWithConfig(config *cfg.Config) error { + // private validator config.SetRoot(config.RootDir) for _, chain := range config.ChainConfigs { - // private validator privValFile := chain.PrivValidatorFile() - var pv *pvm.FilePV + var pv *privval.FilePV if cmn.FileExists(privValFile) { - pv = pvm.LoadFilePV(privValFile) + pv = privval.LoadFilePV(privValFile) logger.Info("Found private validator", "path", privValFile) } else { - pv = pvm.GenFilePV(privValFile) + pv = privval.GenFilePV(privValFile) pv.Save() logger.Info("Generated private validator", "path", privValFile) } @@ -52,7 +54,8 @@ func initFilesWithConfig(config *cfg.Config) error { logger.Info("Found genesis file", "path", genFile) } else { genDoc := types.GenesisDoc{ - ChainID: cmn.Fmt("test-chain-%v", cmn.RandStr(6)), + ChainID: cmn.Fmt("test-chain-%v", cmn.RandStr(6)), + GenesisTime: time.Now(), } genDoc.Validators = []types.GenesisValidator{{ PubKey: pv.GetPubKey(), diff --git a/cmd/teragrid/commands/lite.go b/cmd/teragrid/commands/lite.go index 5ab38ed..4fb05fa 100644 --- a/cmd/teragrid/commands/lite.go +++ b/cmd/teragrid/commands/lite.go @@ -15,12 +15,12 @@ import ( // LiteCmd represents the base command when called without any subcommands var LiteCmd = &cobra.Command{ Use: "lite", - Short: "Run lite-client proxy server, verifying teragrid rpc", - Long: `This node will run a secure proxy to a teragrid rpc server. + Short: "Run lite-client proxy server, verifying tendermint rpc", + Long: `This node will run a secure proxy to a tendermint rpc server. All calls that can be tracked back to a block header by a proof will be verified before passing them back to the caller. Other that -that it will present the same interface as a full teragrid node, +that it will present the same interface as a full tendermint node, just with added trust and running locally.`, RunE: runProxy, SilenceUsage: true, @@ -35,9 +35,9 @@ var ( func init() { LiteCmd.Flags().StringVar(&listenAddr, "laddr", "tcp://localhost:8888", "Serve the proxy on the given address") - LiteCmd.Flags().StringVar(&nodeAddr, "node", "tcp://localhost:46657", "Connect to a teragrid node at this address") - LiteCmd.Flags().StringVar(&chainID, "chain-id", "teragrid", "Specify the teragrid chain ID") - LiteCmd.Flags().StringVar(&home, "home-dir", ".teragrid-lite", "Specify the home directory") + LiteCmd.Flags().StringVar(&nodeAddr, "node", "tcp://localhost:26657", "Connect to a Tendermint node at this address") + LiteCmd.Flags().StringVar(&chainID, "chain-id", "tendermint", "Specify the Tendermint chain ID") + LiteCmd.Flags().StringVar(&home, "home-dir", ".tendermint-lite", "Specify the home directory") } func ensureAddrHasSchemeOrDefaultToTCP(addr string) (string, error) { diff --git a/cmd/teragrid/commands/replay.go b/cmd/teragrid/commands/replay.go index ada4b15..ea6333d 100644 --- a/cmd/teragrid/commands/replay.go +++ b/cmd/teragrid/commands/replay.go @@ -11,7 +11,10 @@ var ReplayCmd = &cobra.Command{ Use: "replay", Short: "Replay messages from WAL", Run: func(cmd *cobra.Command, args []string) { - consensus.RunReplayFile(config.BaseConfig, config.Consensus, false) + /// TODO: + for _, config := range mainConfig.ChainConfigs { + consensus.RunReplayFile(config.BaseConfig, config.Consensus, false) + } }, } @@ -21,6 +24,9 @@ var ReplayConsoleCmd = &cobra.Command{ Use: "replay_console", Short: "Replay messages from WAL in a console", Run: func(cmd *cobra.Command, args []string) { - consensus.RunReplayFile(config.BaseConfig, config.Consensus, true) + /// TODO: + for _, config := range mainConfig.ChainConfigs { + consensus.RunReplayFile(config.BaseConfig, config.Consensus, true) + } }, } diff --git a/cmd/teragrid/commands/reset_priv_validator.go b/cmd/teragrid/commands/reset_priv_validator.go index 92a9363..d5ea837 100644 --- a/cmd/teragrid/commands/reset_priv_validator.go +++ b/cmd/teragrid/commands/reset_priv_validator.go @@ -5,57 +5,69 @@ import ( "github.com/spf13/cobra" - pvm "github.com/teragrid/teragrid/types/priv_validator" + "github.com/teragrid/teragrid/types/priv_validator" "github.com/teragrid/teralibs/log" ) -// ResetAllCmd removes the database of this teragrid core +// ResetAllCmd removes the database of this Tendermint core // instance. var ResetAllCmd = &cobra.Command{ Use: "unsafe_reset_all", - Short: "(unsafe) Remove all the data and WAL, reset this node's validator", + Short: "(unsafe) Remove all the data and WAL, reset this node's validator to genesis state", Run: resetAll, } // ResetPrivValidatorCmd resets the private validator files. var ResetPrivValidatorCmd = &cobra.Command{ Use: "unsafe_reset_priv_validator", - Short: "(unsafe) Reset this node's validator", + Short: "(unsafe) Reset this node's validator to genesis state", Run: resetPrivValidator, } -// ResetAll removes the privValidator files. -// Exported so other CLI tools can use it. -func ResetAll(dbDir, privValFile string, logger log.Logger) { - resetFilePV(privValFile, logger) - if err := os.RemoveAll(dbDir); err != nil { - logger.Error("Error removing directory", "err", err) - return - } - logger.Info("Removed all data", "dir", dbDir) -} - // XXX: this is totally unsafe. // it's only suitable for testnets. func resetAll(cmd *cobra.Command, args []string) { - ResetAll(config.DBDir(), config.PrivValidatorFile(), logger) + for _, config := range mainConfig.ChainConfigs { + ResetAll(config.DBDir(), config.P2P.AddrBookFile(), config.PrivValidatorFile(), logger) + } } // XXX: this is totally unsafe. // it's only suitable for testnets. func resetPrivValidator(cmd *cobra.Command, args []string) { - resetFilePV(config.PrivValidatorFile(), logger) + for _, config := range mainConfig.ChainConfigs { + resetFilePV(config.PrivValidatorFile(), logger) + } +} + +// ResetAll removes the privValidator and address book files plus all data. +// Exported so other CLI tools can use it. +func ResetAll(dbDir, addrBookFile, privValFile string, logger log.Logger) { + resetFilePV(privValFile, logger) + removeAddrBook(addrBookFile, logger) + if err := os.RemoveAll(dbDir); err == nil { + logger.Info("Removed all blockchain history", "dir", dbDir) + } else { + logger.Error("Error removing all blockchain history", "dir", dbDir, "err", err) + } } func resetFilePV(privValFile string, logger log.Logger) { - // Get PrivValidator if _, err := os.Stat(privValFile); err == nil { - pv := pvm.LoadFilePV(privValFile) + pv := privval.LoadFilePV(privValFile) pv.Reset() - logger.Info("Reset PrivValidator", "file", privValFile) + logger.Info("Reset private validator file to genesis state", "file", privValFile) } else { - pv := pvm.GenFilePV(privValFile) + pv := privval.GenFilePV(privValFile) pv.Save() - logger.Info("Generated PrivValidator", "file", privValFile) + logger.Info("Generated private validator file", "file", privValFile) + } +} + +func removeAddrBook(addrBookFile string, logger log.Logger) { + if err := os.Remove(addrBookFile); err == nil { + logger.Info("Removed existing address book", "file", addrBookFile) + } else if !os.IsNotExist(err) { + logger.Info("Error removing address book", "file", addrBookFile, "err", err) } } diff --git a/cmd/teragrid/commands/root.go b/cmd/teragrid/commands/root.go index b63f4b1..97ebc94 100644 --- a/cmd/teragrid/commands/root.go +++ b/cmd/teragrid/commands/root.go @@ -2,6 +2,10 @@ package commands import ( "os" + //"os/user" + "path/filepath" + //"runtime" + //"strings" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -14,8 +18,8 @@ import ( var ( mainConfig = cfg.DefaultConfig() - config = mainConfig.ChainConfigs[0] - logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) + //mainConfig *cfg.Config + logger = log.NewTMLogger(log.NewSyncWriter(os.Stdout)) ) func init() { @@ -23,26 +27,71 @@ func init() { } func registerFlagsRootCmd(cmd *cobra.Command) { - cmd.PersistentFlags().String("log_level", config.LogLevel, "Log level") + cmd.PersistentFlags().String("log_level", mainConfig.LogLevel, "Log level") + cmd.PersistentFlags().StringP("config", "c", "", "Alternate configuration file to read. Defaults to $HOME/.tendermint/") + + //viper.BindPFlag("ConfigFileName", cmd.PersistentFlags().Lookup("config")) + //viper.BindPFlag("Home", cmd.PersistentFlags().Lookup("home")) } // ParseConfig retrieves the default environment configuration, -// sets up the teragrid root and ensures that the root exists +// sets up the Tendermint root and ensures that the root exists func ParseConfig() (*cfg.Config, error) { - conf := cfg.DefaultConfig() - err := viper.Unmarshal(conf) - if err != nil { - return nil, err + + var conf *cfg.Config + + rootDir := viper.GetString("home") + chains := viper.GetStringSlice("chains") + + if len(chains) > 0 { + hasDefault := false + chainConfigs := make([]*cfg.ChainConfig, len(chains)) + for idx, item := range chains { + if item == "default" { + hasDefault = true + } + chainConfigs[idx] = cfg.DefaultChainConfig(item) + } + if !hasDefault { + //chainConfigs = append(chainConfigs, cfg.DefaultChainConfig("default")) + } + conf = &cfg.Config{ + RootDir: "", + LogLevel: cfg.DefaultPackageLogLevels(), + ChainConfigs: chainConfigs, + } + } else { + conf = cfg.DefaultConfig() } - conf.SetRoot(conf.RootDir) + if rootDir == "" { + panic("Error") + } + conf.SetRoot(rootDir) + + for _, chain := range conf.ChainConfigs { + var chainConfig = filepath.Join(chain.RootDir, "config", "config.toml") + //fmt.Println("chainConfig " + chainConfig) + + var chainViper = viper.New() + //chainViper.SetConfigType("json") + chainViper.SetConfigFile(chainConfig) + err := chainViper.ReadInConfig() + if err == nil { + err = chainViper.Unmarshal(chain) + if err != nil { + panic(err) + } + } + } + cfg.EnsureRoot(conf.RootDir, conf) - return conf, err + return conf, nil } -// RootCmd is the root command for teragrid core. +// RootCmd is the root command for Tendermint core. var RootCmd = &cobra.Command{ - Use: "teragrid", - Short: "teragrid Core (BFT Consensus) in Go", + Use: "tendermint", + Short: "Tendermint Core (BFT Consensus) in Go", PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { if cmd.Name() == VersionCmd.Name() { return nil @@ -51,7 +100,7 @@ var RootCmd = &cobra.Command{ if err != nil { return err } - logger, err = tmflags.ParseLogLevel(config.LogLevel, logger, cfg.DefaultLogLevel()) + logger, err = tmflags.ParseLogLevel(mainConfig.LogLevel, logger, cfg.DefaultLogLevel()) if err != nil { return err } diff --git a/cmd/teragrid/commands/run_node.go b/cmd/teragrid/commands/run_node.go index 7c4e206..ce6a7e4 100644 --- a/cmd/teragrid/commands/run_node.go +++ b/cmd/teragrid/commands/run_node.go @@ -4,13 +4,15 @@ import ( "fmt" "github.com/spf13/cobra" - + cfg "github.com/teragrid/teragrid/config" nm "github.com/teragrid/teragrid/node" + cmn "github.com/teragrid/teralibs/common" ) // AddNodeFlags exposes some common configuration options on the command-line -// These are exposed for convenience of commands embedding a teragrid node +// These are exposed for convenience of commands embedding a tendermint node func AddNodeFlags(cmd *cobra.Command) { + config := mainConfig.ChainConfigs[0] // bind flags cmd.Flags().String("moniker", config.Moniker, "Node Name") @@ -20,9 +22,9 @@ func AddNodeFlags(cmd *cobra.Command) { // node flags cmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing") - // asura flags + // abci flags cmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or 'nilapp' or 'kvstore' for local testing.") - cmd.Flags().String("asura", config.Asura, "Specify asura transport (socket | grpc)") + cmd.Flags().String("abci", config.Asura, "Specify Asura transport (socket | grpc)") // rpc flags cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required") @@ -43,11 +45,89 @@ func AddNodeFlags(cmd *cobra.Command) { } // NewRunNodeCmd returns the command that allows the CLI to start a node. -// It can be used with a custom PrivValidator and in-process asura application. +// It can be used with a custom PrivValidator and in-process ABCI application. +func NewRunNodeCmd(nodeProvider nm.NodeProvider) *cobra.Command { + cmd := &cobra.Command{ + Use: "node", + Short: "Run the tendermint node", + RunE: func(cmd *cobra.Command, args []string) error { + //runOneNode(nodeProvider) + runNodes(nodeProvider) + return nil + }, + } + AddNodeFlags(cmd) + return cmd +} + +func runOneNode(nodeProvider nm.NodeProvider) error { + // Create & start node + config := mainConfig.ChainConfigs[0] + newLogger := logger.With("chain", config.ChainID()) + + newLogger.Info("Run one node: Start with config") + n, err := nodeProvider(config, newLogger) + if err != nil { + return fmt.Errorf("Failed to create node: %v", err) + } + + if err := n.Start(); err != nil { + return fmt.Errorf("Failed to start node: %v", err) + } + newLogger.Info("Started node", "nodeInfo", n.Switch().NodeInfo()) + + // Trap signal, run forever. + n.RunForever() + newLogger.Info("runOneNode Finish") + return nil +} + +func runNodeWithConfig(nodeProvider nm.NodeProvider, config *cfg.ChainConfig) (*nm.Node, error) { + + newLogger := logger.With("chain", config.ChainID()) + newLogger.Info("runNodeWithConfig " + config.ChainID()) + + // Create & start node + n, err := nodeProvider(config, newLogger) + if err != nil { + return nil, fmt.Errorf("Failed to create node: %v", err) + } + + if err := n.Start(); err != nil { + //return fmt.Errorf("Failed to start node: %v", err) + } + newLogger.Info("Started node", "nodeInfo", n.Switch().NodeInfo()) + fmt.Println("Create node finish" + config.ChainID()) + // Trap signal, run forever. + //n.RunForever() + return n, nil +} + +func runNodes(nodeProvider nm.NodeProvider) { + logger.Info("Run multi-node") + var nodes []*nm.Node + nodes = make([]*nm.Node, len(mainConfig.ChainConfigs)) + for idx, configLoop := range mainConfig.ChainConfigs { + config := configLoop + //fmt.Println("================================== Create node " + config.ChainID()) + logger.Info("================================== Create node " + config.ChainID()) + nodes[idx], _ = runNodeWithConfig(nodeProvider, config) + } + cmn.TrapSignal(func() { + for _, n := range nodes { + n.Stop() + } + }) + return +} + +/* +// NewRunNodeCmd returns the command that allows the CLI to start a node. +// It can be used with a custom PrivValidator and in-process ABCI application. func NewRunNodeCmd(nodeProvider nm.NodeProvider) *cobra.Command { cmd := &cobra.Command{ Use: "node", - Short: "Run the teragrid node", + Short: "Run the tendermint node", RunE: func(cmd *cobra.Command, args []string) error { // Create & start node n, err := nodeProvider(config, logger) @@ -70,3 +150,4 @@ func NewRunNodeCmd(nodeProvider nm.NodeProvider) *cobra.Command { AddNodeFlags(cmd) return cmd } +*/ diff --git a/cmd/teragrid/commands/show_node_id.go b/cmd/teragrid/commands/show_node_id.go index 10f4954..55f39d0 100644 --- a/cmd/teragrid/commands/show_node_id.go +++ b/cmd/teragrid/commands/show_node_id.go @@ -6,7 +6,6 @@ import ( "github.com/spf13/cobra" "github.com/teragrid/teragrid/p2p" - ) // ShowNodeIDCmd dumps node's ID to the standard output. @@ -17,12 +16,12 @@ var ShowNodeIDCmd = &cobra.Command{ } func showNodeID(cmd *cobra.Command, args []string) error { - - nodeKey, err := p2p.LoadNodeKey(config.NodeKeyFile()) - if err != nil { - return err + for _, config := range mainConfig.ChainConfigs { + nodeKey, err := p2p.LoadNodeKey(config.NodeKeyFile()) + if err != nil { + return err + } + fmt.Println(nodeKey.ID()) } - fmt.Println(nodeKey.ID()) - return nil } diff --git a/cmd/teragrid/commands/show_validator.go b/cmd/teragrid/commands/show_validator.go index 8b71e26..777e9c4 100644 --- a/cmd/teragrid/commands/show_validator.go +++ b/cmd/teragrid/commands/show_validator.go @@ -2,9 +2,10 @@ package commands import ( "fmt" + "github.com/spf13/cobra" - privval "github.com/teragrid/teragrid/types/priv_validator" + "github.com/teragrid/teragrid/types/priv_validator" ) // ShowValidatorCmd adds capabilities for showing the validator info. @@ -15,7 +16,9 @@ var ShowValidatorCmd = &cobra.Command{ } func showValidator(cmd *cobra.Command, args []string) { - privValidator := privval.LoadOrGenFilePV(config.PrivValidatorFile()) - pubKeyJSONBytes, _ := cdc.MarshalJSON(privValidator.GetPubKey()) - fmt.Println(string(pubKeyJSONBytes)) + for _, config := range mainConfig.ChainConfigs { + privValidator := privval.LoadOrGenFilePV(config.PrivValidatorFile()) + pubKeyJSONBytes, _ := cdc.MarshalJSON(privValidator.GetPubKey()) + fmt.Println(string(pubKeyJSONBytes)) + } } diff --git a/cmd/teragrid/commands/testnet.go b/cmd/teragrid/commands/testnet.go index a627b7c..8d9cadc 100644 --- a/cmd/teragrid/commands/testnet.go +++ b/cmd/teragrid/commands/testnet.go @@ -13,7 +13,7 @@ import ( cfg "github.com/teragrid/teragrid/config" "github.com/teragrid/teragrid/p2p" "github.com/teragrid/teragrid/types" - pvm "github.com/teragrid/teragrid/types/priv_validator" + "github.com/teragrid/teragrid/types/priv_validator" cmn "github.com/teragrid/teralibs/common" ) @@ -46,18 +46,29 @@ func init() { TestnetFilesCmd.Flags().BoolVar(&populatePersistentPeers, "populate-persistent-peers", true, "Update config of each node with the list of persistent peers build using either hostname-prefix or starting-ip-address") TestnetFilesCmd.Flags().StringVar(&hostnamePrefix, "hostname-prefix", "node", - "Hostname prefix (node results in persistent peers list ID0@node0:46656, ID1@node1:46656, ...)") + "Hostname prefix (node results in persistent peers list ID0@node0:26656, ID1@node1:26656, ...)") TestnetFilesCmd.Flags().StringVar(&startingIPAddress, "starting-ip-address", "", - "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:46656, ID1@192.168.0.2:46656, ...)") - TestnetFilesCmd.Flags().IntVar(&p2pPort, "p2p-port", 46656, + "Starting IP address (192.168.0.1 results in persistent peers list ID0@192.168.0.1:26656, ID1@192.168.0.2:26656, ...)") + TestnetFilesCmd.Flags().IntVar(&p2pPort, "p2p-port", 26656, "P2P Port") } -// TestnetFilesCmd allows initialisation of files for a teragrid testnet. +// TestnetFilesCmd allows initialisation of files for a Tendermint testnet. var TestnetFilesCmd = &cobra.Command{ Use: "testnet", - Short: "Initialize files for a teragrid testnet", - RunE: testnetFiles, + Short: "Initialize files for a Tendermint testnet", + Long: `testnet will create "v" + "n" number of directories and populate each with +necessary files (private validator, genesis, config, etc.). + +Note, strict routability for addresses is turned off in the config file. + +Optionally, it will fill in persistent_peers list in config file using either hostnames or IPs. + +Example: + + tendermint testnet --v 4 --o ./output --populate-persistent-peers --starting-ip-address 192.168.10.2 + `, + RunE: testnetFiles, } func testnetFiles(cmd *cobra.Command, args []string) error { @@ -67,7 +78,7 @@ func testnetFiles(cmd *cobra.Command, args []string) error { for i := 0; i < nValidators; i++ { nodeDirName := cmn.Fmt("%s%d", nodeDirPrefix, i) nodeDir := filepath.Join(outputDir, nodeDirName) - config.SetRoot(nodeDir) + chain.SetRoot(nodeDir) err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm) if err != nil { @@ -78,7 +89,7 @@ func testnetFiles(cmd *cobra.Command, args []string) error { initFilesWithConfig(config) pvFile := filepath.Join(nodeDir, chain.BaseConfig.PrivValidator) - pv := pvm.LoadFilePV(pvFile) + pv := privval.LoadFilePV(pvFile) genVals[i] = types.GenesisValidator{ PubKey: pv.GetPubKey(), Power: 1, @@ -88,7 +99,7 @@ func testnetFiles(cmd *cobra.Command, args []string) error { for i := 0; i < nNonValidators; i++ { nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i+nValidators)) - config.SetRoot(nodeDir) + chain.SetRoot(nodeDir) err := os.MkdirAll(filepath.Join(nodeDir, "config"), nodeDirPerm) if err != nil { @@ -150,7 +161,7 @@ func populatePersistentPeersInConfigAndWriteIt(config *cfg.Config) error { for _, chain := range config.ChainConfigs { for i := 0; i < nValidators+nNonValidators; i++ { nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i)) - config.SetRoot(nodeDir) + chain.SetRoot(nodeDir) nodeKey, err := p2p.LoadNodeKey(chain.NodeKeyFile()) if err != nil { return err @@ -163,6 +174,7 @@ func populatePersistentPeersInConfigAndWriteIt(config *cfg.Config) error { nodeDir := filepath.Join(outputDir, cmn.Fmt("%s%d", nodeDirPrefix, i)) chain.SetRoot(nodeDir) chain.P2P.PersistentPeers = persistentPeersList + chain.P2P.AddrBookStrict = false // overwrite default config cfg.WriteConfigFile(filepath.Join(nodeDir, "config", "config.toml"), config) diff --git a/cmd/teragrid/main.go b/cmd/teragrid/main.go index d301050..8612f60 100644 --- a/cmd/teragrid/main.go +++ b/cmd/teragrid/main.go @@ -1,12 +1,9 @@ package main import ( - "fmt" "os" "path/filepath" - "github.com/spf13/viper" - "github.com/teragrid/teralibs/cli" cmd "github.com/teragrid/teragrid/cmd/teragrid/commands" @@ -16,68 +13,36 @@ import ( func main() { - viper.SetConfigName("config") - viper.AddConfigPath(".") - //viper.AddConfigPath(os.U) - err := viper.ReadInConfig() - if err != nil { - //panic(err) - fmt.Println("Config not found") - } else { - chains := viper.GetStringSlice("chains") - fmt.Println("ChainSize:", len(chains)) - for idx, item := range chains { - fmt.Println("Chain", idx, item) - } - } - - /* - //err2 := viper.Unmarshal(&cfgIn) - // if err2 != nil { - // cfg := config.DefaultConfig() - // fmt.Println("ConfigSize:", len(cfg.ChainConfigs)) - // viper.SetDefault("LogLevel", cfg.LogLevel) - // viper.SetDefault("Chains", cfg.ChainConfigs) - // viper.SetConfigType("json") - // viper.WriteConfig() - // return - // } - // cfgIn.ChainConfigs = []viper.GetStringMap("chains") - // cfgIn.LogLevel = viper.GetString("LogLevel") - // fmt.Println("LogLevel:", cfgIn.LogLevel) - // fmt.Println("ConfigSize:", len(cfgIn.ChainConfigs)) - return - */ rootCmd := cmd.RootCmd rootCmd.AddCommand( - // cmd.GenValidatorCmd, + cmd.GenValidatorCmd, cmd.InitFilesCmd, - // cmd.ProbeUpnpCmd, - // cmd.LiteCmd, - // cmd.ReplayCmd, - // cmd.ReplayConsoleCmd, - // cmd.ResetAllCmd, - // cmd.ResetPrivValidatorCmd, - // cmd.ShowValidatorCmd, + cmd.ProbeUpnpCmd, + cmd.LiteCmd, + cmd.ReplayCmd, + cmd.ReplayConsoleCmd, + cmd.ResetAllCmd, + cmd.ResetPrivValidatorCmd, + cmd.ShowValidatorCmd, cmd.TestnetFilesCmd, - // cmd.ShowNodeIDCmd, - // cmd.GenNodeKeyCmd, + cmd.ShowNodeIDCmd, + cmd.GenNodeKeyCmd, cmd.VersionCmd) - // NOTE: - // Users wishing to: - // * Use an external signer for their validators - // * Supply an in-proc asura app - // * Supply a genesis doc file from another source - // * Provide their own DB implementation - // can copy this file and use something other than the - // DefaultNewNode function + // // NOTE: + // // Users wishing to: + // // * Use an external signer for their validators + // // * Supply an in-proc asura app + // // * Supply a genesis doc file from another source + // // * Provide their own DB implementation + // // can copy this file and use something other than the + // // DefaultNewNode function nodeFunc := nm.DefaultNewNode // Create & start node rootCmd.AddCommand(cmd.NewRunNodeCmd(nodeFunc)) - cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultteragridDir))) + cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultTendermintDir))) if err := cmd.Execute(); err != nil { panic(err) } diff --git a/config/base_config.go b/config/base_config.go deleted file mode 100644 index 26aaf1c..0000000 --- a/config/base_config.go +++ /dev/null @@ -1,484 +0,0 @@ -package config - -import ( - "fmt" - "os" - "path/filepath" - "time" -) - -//----------------------------------------------------------------------------- -// BaseConfig - -// BaseConfig defines the base configuration for a teragrid node -type BaseConfig struct { - - // chainID is unexposed and immutable but here for convenience - chainID string - - // The root directory for all data. - // This should be set in viper so it can unmarshal into this struct - RootDir string `mapstructure:"home"` - - // Path to the JSON file containing the initial validator set and other meta data - Genesis string `mapstructure:"genesis_file"` - - // Path to the JSON file containing the private key to use as a validator in the consensus protocol - PrivValidator string `mapstructure:"priv_validator_file"` - - // A JSON file containing the private key to use for p2p authenticated encryption - NodeKey string `mapstructure:"node_key_file"` - - // A custom human readable name for this node - Moniker string `mapstructure:"moniker"` - - // TCP or UNIX socket address for teragrid to listen on for - // connections from an external PrivValidator process - PrivValidatorListenAddr string `mapstructure:"priv_validator_laddr"` - - // TCP or UNIX socket address of the Asura application, - // or the name of an Asura application compiled in with the teragrid binary - ProxyApp string `mapstructure:"proxy_app"` - - // Mechanism to connect to the Asura application: socket | grpc - Asura string `mapstructure:"Asura"` - - // Output level for logging - LogLevel string `mapstructure:"log_level"` - - // TCP or UNIX socket address for the profiling server to listen on - ProfListenAddress string `mapstructure:"prof_laddr"` - - // 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 - FastSync bool `mapstructure:"fast_sync"` - - // If true, query the Asura app on connecting to a new peer - // so the app can decide if we should keep the connection or not - FilterPeers bool `mapstructure:"filter_peers"` // false - - // Database backend: leveldb | memdb - DBBackend string `mapstructure:"db_backend"` - - // Database directory - DBPath string `mapstructure:"db_dir"` -} - -// DefaultBaseConfig returns a default base configuration for a teragrid node -func DefaultBaseConfig(name string) BaseConfig { - return BaseConfig{ - chainID: name, - Genesis: defaultGenesisJSONPath, - PrivValidator: defaultPrivValPath, - NodeKey: defaultNodeKeyPath, - Moniker: defaultMoniker, - ProxyApp: "tcp://127.0.0.1:46658", - Asura: "socket", - LogLevel: DefaultPackageLogLevels(), - ProfListenAddress: "", - FastSync: true, - FilterPeers: false, - DBBackend: "leveldb", - DBPath: "data", - } -} - -// TestBaseConfig returns a base configuration for testing a teragrid node -func TestBaseConfig() BaseConfig { - cfg := DefaultBaseConfig(defaultChainName) - cfg.chainID = "teragrid_test" - cfg.ProxyApp = "kvstore" - cfg.FastSync = false - cfg.DBBackend = "memdb" - return cfg -} - -func (cfg BaseConfig) ChainID() string { - return cfg.chainID -} - -// GenesisFile returns the full path to the genesis.json file -func (cfg BaseConfig) GenesisFile() string { - return rootify(cfg.Genesis, cfg.RootDir) -} - -// PrivValidatorFile returns the full path to the priv_validator.json file -func (cfg BaseConfig) PrivValidatorFile() string { - return rootify(cfg.PrivValidator, cfg.RootDir) -} - -// NodeKeyFile returns the full path to the node_key.json file -func (cfg BaseConfig) NodeKeyFile() string { - return rootify(cfg.NodeKey, cfg.RootDir) -} - -// DBDir returns the full path to the database directory -func (cfg BaseConfig) DBDir() string { - return rootify(cfg.DBPath, cfg.RootDir) -} - -// DefaultLogLevel returns a default log level of "error" -func DefaultLogLevel() string { - return "error" -} - -// DefaultPackageLogLevels returns a default log level setting so all packages -// log at "error", while the `state` and `main` packages log at "info" -func DefaultPackageLogLevels() string { - return fmt.Sprintf("main:info,state:info,*:%s", DefaultLogLevel()) -} - -//----------------------------------------------------------------------------- -// RPCConfig - -// RPCConfig defines the configuration options for the teragrid RPC server -type RPCConfig struct { - RootDir string `mapstructure:"home"` - - // TCP or UNIX socket address for the RPC server to listen on - ListenAddress string `mapstructure:"laddr"` - - // TCP or UNIX socket address for the gRPC server to listen on - // NOTE: This server only supports /broadcast_tx_commit - GRPCListenAddress string `mapstructure:"grpc_laddr"` - - // Activate unsafe RPC commands like /dial_persistent_peers and /unsafe_flush_mempool - Unsafe bool `mapstructure:"unsafe"` -} - -// DefaultRPCConfig returns a default configuration for the RPC server -func DefaultRPCConfig() *RPCConfig { - return &RPCConfig{ - ListenAddress: "tcp://0.0.0.0:46657", - GRPCListenAddress: "", - Unsafe: false, - } -} - -// TestRPCConfig returns a configuration for testing the RPC server -func TestRPCConfig() *RPCConfig { - cfg := DefaultRPCConfig() - cfg.ListenAddress = "tcp://0.0.0.0:36657" - cfg.GRPCListenAddress = "tcp://0.0.0.0:36658" - cfg.Unsafe = true - return cfg -} - -//----------------------------------------------------------------------------- -// P2PConfig - -// P2PConfig defines the configuration options for the teragrid peer-to-peer networking layer -type P2PConfig struct { - RootDir string `mapstructure:"home"` - - // Address to listen for incoming connections - ListenAddress string `mapstructure:"laddr"` - - // Comma separated list of seed nodes to connect to - // We only use these if we can’t connect to peers in the addrbook - Seeds string `mapstructure:"seeds"` - - // Comma separated list of nodes to keep persistent connections to - // Do not add private peers to this list if you don't want them advertised - PersistentPeers string `mapstructure:"persistent_peers"` - - // Skip UPNP port forwarding - SkipUPNP bool `mapstructure:"skip_upnp"` - - // Path to address book - AddrBook string `mapstructure:"addr_book_file"` - - // Set true for strict address routability rules - AddrBookStrict bool `mapstructure:"addr_book_strict"` - - // Maximum number of peers to connect to - MaxNumPeers int `mapstructure:"max_num_peers"` - - // Time to wait before flushing messages out on the connection, in ms - FlushThrottleTimeout int `mapstructure:"flush_throttle_timeout"` - - // Maximum size of a message packet payload, in bytes - MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"` - - // Rate at which packets can be sent, in bytes/second - SendRate int64 `mapstructure:"send_rate"` - - // Rate at which packets can be received, in bytes/second - RecvRate int64 `mapstructure:"recv_rate"` - - // Set true to enable the peer-exchange reactor - PexReactor bool `mapstructure:"pex"` - - // Seed mode, in which node constantly crawls the network and looks for - // peers. If another node asks it for addresses, it responds and disconnects. - // - // Does not work if the peer-exchange reactor is disabled. - SeedMode bool `mapstructure:"seed_mode"` - - // Authenticated encryption - AuthEnc bool `mapstructure:"auth_enc"` - - // Comma separated list of peer IDs to keep private (will not be gossiped to other peers) - PrivatePeerIDs string `mapstructure:"private_peer_ids"` -} - -// DefaultP2PConfig returns a default configuration for the peer-to-peer layer -func DefaultP2PConfig() *P2PConfig { - return &P2PConfig{ - ListenAddress: "tcp://0.0.0.0:46656", - AddrBook: defaultAddrBookPath, - AddrBookStrict: true, - MaxNumPeers: 50, - FlushThrottleTimeout: 100, - MaxPacketMsgPayloadSize: 1024, // 1 kB - SendRate: 512000, // 500 kB/s - RecvRate: 512000, // 500 kB/s - PexReactor: true, - SeedMode: false, - AuthEnc: true, - } -} - -// TestP2PConfig returns a configuration for testing the peer-to-peer layer -func TestP2PConfig() *P2PConfig { - cfg := DefaultP2PConfig() - cfg.ListenAddress = "tcp://0.0.0.0:36656" - cfg.SkipUPNP = true - cfg.FlushThrottleTimeout = 10 - return cfg -} - -// AddrBookFile returns the full path to the address book -func (cfg *P2PConfig) AddrBookFile() string { - return rootify(cfg.AddrBook, cfg.RootDir) -} - -//----------------------------------------------------------------------------- -// MempoolConfig - -// MempoolConfig defines the configuration options for the teragrid mempool -type MempoolConfig struct { - RootDir string `mapstructure:"home"` - Recheck bool `mapstructure:"recheck"` - RecheckEmpty bool `mapstructure:"recheck_empty"` - Broadcast bool `mapstructure:"broadcast"` - WalPath string `mapstructure:"wal_dir"` - CacheSize int `mapstructure:"cache_size"` -} - -// DefaultMempoolConfig returns a default configuration for the teragrid mempool -func DefaultMempoolConfig() *MempoolConfig { - return &MempoolConfig{ - Recheck: true, - RecheckEmpty: true, - Broadcast: true, - WalPath: filepath.Join(defaultDataDir, "mempool.wal"), - CacheSize: 100000, - } -} - -// TestMempoolConfig returns a configuration for testing the teragrid mempool -func TestMempoolConfig() *MempoolConfig { - cfg := DefaultMempoolConfig() - cfg.CacheSize = 1000 - return cfg -} - -// WalDir returns the full path to the mempool's write-ahead log -func (cfg *MempoolConfig) WalDir() string { - return rootify(cfg.WalPath, cfg.RootDir) -} - -//----------------------------------------------------------------------------- -// ConsensusConfig - -// ConsensusConfig defines the confuguration for the teragrid consensus service, -// including timeouts and details about the WAL and the block structure. -type ConsensusConfig struct { - RootDir string `mapstructure:"home"` - WalPath string `mapstructure:"wal_file"` - WalLight bool `mapstructure:"wal_light"` - walFile string // overrides WalPath if set - - // All timeouts are in milliseconds - 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"` - - // EmptyBlocks mode and possible interval between empty blocks in seconds - CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"` - CreateEmptyBlocksInterval int `mapstructure:"create_empty_blocks_interval"` - - // Reactor sleep duration parameters are in milliseconds - PeerGossipSleepDuration int `mapstructure:"peer_gossip_sleep_duration"` - PeerQueryMaj23SleepDuration int `mapstructure:"peer_query_maj23_sleep_duration"` -} - -// DefaultConsensusConfig returns a default configuration for the consensus service -func DefaultConsensusConfig() *ConsensusConfig { - return &ConsensusConfig{ - WalPath: filepath.Join(defaultDataDir, "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 - CreateEmptyBlocks: true, - CreateEmptyBlocksInterval: 0, - PeerGossipSleepDuration: 100, - PeerQueryMaj23SleepDuration: 2000, - } -} - -// TestConsensusConfig returns a configuration for testing the consensus service -func TestConsensusConfig() *ConsensusConfig { - cfg := DefaultConsensusConfig() - cfg.TimeoutPropose = 100 - cfg.TimeoutProposeDelta = 1 - cfg.TimeoutPrevote = 10 - cfg.TimeoutPrevoteDelta = 1 - cfg.TimeoutPrecommit = 10 - cfg.TimeoutPrecommitDelta = 1 - cfg.TimeoutCommit = 10 - cfg.SkipTimeoutCommit = true - cfg.PeerGossipSleepDuration = 5 - cfg.PeerQueryMaj23SleepDuration = 250 - return cfg -} - -// WaitForTxs returns true if the consensus should wait for transactions before entering the propose step -func (cfg *ConsensusConfig) WaitForTxs() bool { - return !cfg.CreateEmptyBlocks || cfg.CreateEmptyBlocksInterval > 0 -} - -// EmptyBlocks returns the amount of time to wait before proposing an empty block or starting the propose timer if there are no txs available -func (cfg *ConsensusConfig) EmptyBlocksInterval() time.Duration { - return time.Duration(cfg.CreateEmptyBlocksInterval) * time.Second -} - -// Propose returns the amount of time to wait for a proposal -func (cfg *ConsensusConfig) Propose(round int) time.Duration { - return time.Duration(cfg.TimeoutPropose+cfg.TimeoutProposeDelta*round) * time.Millisecond -} - -// Prevote returns the amount of time to wait for straggler votes after receiving any +2/3 prevotes -func (cfg *ConsensusConfig) Prevote(round int) time.Duration { - return time.Duration(cfg.TimeoutPrevote+cfg.TimeoutPrevoteDelta*round) * time.Millisecond -} - -// Precommit returns the amount of time to wait for straggler votes after receiving any +2/3 precommits -func (cfg *ConsensusConfig) Precommit(round int) time.Duration { - return time.Duration(cfg.TimeoutPrecommit+cfg.TimeoutPrecommitDelta*round) * time.Millisecond -} - -// Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits for a single block (ie. a commit). -func (cfg *ConsensusConfig) Commit(t time.Time) time.Time { - return t.Add(time.Duration(cfg.TimeoutCommit) * time.Millisecond) -} - -// PeerGossipSleep returns the amount of time to sleep if there is nothing to send from the ConsensusReactor -func (cfg *ConsensusConfig) PeerGossipSleep() time.Duration { - return time.Duration(cfg.PeerGossipSleepDuration) * time.Millisecond -} - -// PeerQueryMaj23Sleep returns the amount of time to sleep after each VoteSetMaj23Message is sent in the ConsensusReactor -func (cfg *ConsensusConfig) PeerQueryMaj23Sleep() time.Duration { - return time.Duration(cfg.PeerQueryMaj23SleepDuration) * time.Millisecond -} - -// WalFile returns the full path to the write-ahead log file -func (cfg *ConsensusConfig) WalFile() string { - if cfg.walFile != "" { - return cfg.walFile - } - return rootify(cfg.WalPath, cfg.RootDir) -} - -// SetWalFile sets the path to the write-ahead log file -func (cfg *ConsensusConfig) SetWalFile(walFile string) { - cfg.walFile = walFile -} - -//----------------------------------------------------------------------------- -// TxIndexConfig - -// TxIndexConfig defines the confuguration for the transaction -// indexer, including tags to index. -type TxIndexConfig struct { - // 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 string `mapstructure:"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. - IndexTags string `mapstructure:"index_tags"` - - // 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). - IndexAllTags bool `mapstructure:"index_all_tags"` -} - -// DefaultTxIndexConfig returns a default configuration for the transaction indexer. -func DefaultTxIndexConfig() *TxIndexConfig { - return &TxIndexConfig{ - Indexer: "kv", - IndexTags: "", - IndexAllTags: false, - } -} - -// TestTxIndexConfig returns a default configuration for the transaction indexer. -func TestTxIndexConfig() *TxIndexConfig { - return DefaultTxIndexConfig() -} - -//----------------------------------------------------------------------------- -// Utils - -// helper function to make config creation independent of root dir -func rootify(path, root string) string { - if filepath.IsAbs(path) { - return path - } - return filepath.Join(root, path) -} - -//----------------------------------------------------------------------------- -// Moniker - -var defaultMoniker = getDefaultMoniker() - -// getDefaultMoniker returns a default moniker, which is the host name. If runtime -// fails to get the host name, "anonymous" will be returned. -func getDefaultMoniker() string { - moniker, err := os.Hostname() - if err != nil { - moniker = "anonymous" - } - return moniker -} diff --git a/config/chain_config.go b/config/chain_config.go index 4feaa1d..c715b2f 100644 --- a/config/chain_config.go +++ b/config/chain_config.go @@ -1,9 +1,11 @@ package config +var portStep = 0 + //----------------------------------------------------------------------------- // ShardConfig -// ShardConfig defines the base configuration for a teragrid quorum +// ShardConfig defines the base configuration for a tendermint quorum type ShardConfig struct { ShardID string Validator bool @@ -12,7 +14,7 @@ type ShardConfig struct { PrivValidator string `mapstructure:"priv_validator_file"` } -// Config defines the top level configuration for a teragrid node +// Config defines the top level configuration for a tendermint node type ChainConfig struct { // Top level options use an anonymous struct BaseConfig `mapstructure:",squash"` @@ -25,8 +27,9 @@ type ChainConfig struct { TxIndex *TxIndexConfig `mapstructure:"tx_index"` } -// DefaultConfig returns a default configuration for a teragrid node +// DefaultConfig returns a default configuration for a tendermint node func DefaultChainConfig(name string) *ChainConfig { + portStep = portStep + 10 return &ChainConfig{ BaseConfig: DefaultBaseConfig(name), RPC: DefaultRPCConfig(), @@ -51,7 +54,6 @@ func TestChainConfig() *ChainConfig { // SetRoot sets the RootDir for all Config structs func (cfg *ChainConfig) SetRoot(root string) *ChainConfig { - cfg.RootDir = root cfg.BaseConfig.RootDir = root cfg.RPC.RootDir = root cfg.P2P.RootDir = root diff --git a/config/config.go b/config/config.go index 7306656..9674d2e 100644 --- a/config/config.go +++ b/config/config.go @@ -1,72 +1,537 @@ package config import ( - // "os" + "fmt" + "os" "path/filepath" - // "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 -// NOTE: teralibs/cli must know to look in the config dir! -var ( - DefaultteragridDir = ".teragrid" - defaultChainName = "default" - defaultConfigDir = "config" - defaultDataDir = "data" - - defaultConfigFileName = "config.toml" - defaultGenesisJSONName = "genesis.json" - - defaultPrivValName = "priv_validator.json" - defaultNodeKeyName = "node_key.json" - defaultAddrBookName = "addrbook.json" - - defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName) - defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName) - defaultPrivValPath = filepath.Join(defaultConfigDir, defaultPrivValName) - defaultNodeKeyPath = filepath.Join(defaultConfigDir, defaultNodeKeyName) - defaultAddrBookPath = filepath.Join(defaultConfigDir, defaultAddrBookName) +const ( + // FuzzModeDrop is a mode in which we randomly drop reads/writes, connections or sleep + FuzzModeDrop = iota + // FuzzModeDelay is a mode in which we randomly sleep + FuzzModeDelay ) -type Config struct { +//----------------------------------------------------------------------------- +// BaseConfig + +// BaseConfig defines the base configuration for a Tendermint node +type BaseConfig struct { + + // chainID is unexposed and immutable but here for convenience + chainID string + // The root directory for all data. // This should be set in viper so it can unmarshal into this struct RootDir string `mapstructure:"home"` + + // Path to the JSON file containing the initial validator set and other meta data + Genesis string `mapstructure:"genesis_file"` + + // Path to the JSON file containing the private key to use as a validator in the consensus protocol + PrivValidator string `mapstructure:"priv_validator_file"` + + // A JSON file containing the private key to use for p2p authenticated encryption + NodeKey string `mapstructure:"node_key_file"` + + // A custom human readable name for this node + Moniker string `mapstructure:"moniker"` + + // TCP or UNIX socket address for Tendermint to listen on for + // connections from an external PrivValidator process + PrivValidatorListenAddr string `mapstructure:"priv_validator_laddr"` + + // TCP or UNIX socket address of the ABCI application, + // or the name of an ABCI application compiled in with the Tendermint binary + ProxyApp string `mapstructure:"proxy_app"` + + // Mechanism to connect to the ABCI application: socket | grpc + Asura string `mapstructure:"asura"` + // Output level for logging - LogLevel string `mapstructure:"log_level"` - ChainConfigs []*ChainConfig + LogLevel string `mapstructure:"log_level"` + + // TCP or UNIX socket address for the profiling server to listen on + ProfListenAddress string `mapstructure:"prof_laddr"` + + // 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 + FastSync bool `mapstructure:"fast_sync"` + + // 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 + FilterPeers bool `mapstructure:"filter_peers"` // false + + // Database backend: leveldb | memdb + DBBackend string `mapstructure:"db_backend"` + + // Database directory + DBPath string `mapstructure:"db_dir"` +} + +// DefaultBaseConfig returns a default base configuration for a Tendermint node +func DefaultBaseConfig(name string) BaseConfig { + return BaseConfig{ + chainID: name, + Genesis: defaultGenesisJSONPath, + PrivValidator: defaultPrivValPath, + NodeKey: defaultNodeKeyPath, + Moniker: defaultMoniker, + //ProxyApp: "tcp://127.0.0.1:26658", + ProxyApp: fmt.Sprintf("tcp://127.0.0.1:%d", 26658+portStep), + Asura: "socket", + LogLevel: DefaultPackageLogLevels(), + ProfListenAddress: "", + FastSync: true, + FilterPeers: false, + DBBackend: "leveldb", + DBPath: "data", + } +} + +// TestBaseConfig returns a base configuration for testing a Tendermint node +func TestBaseConfig() BaseConfig { + cfg := DefaultBaseConfig(defaultChainName) + cfg.chainID = "dagmint_test" + cfg.ProxyApp = "kvstore" + cfg.FastSync = false + cfg.DBBackend = "memdb" + return cfg +} + +func (cfg BaseConfig) ChainID() string { + return cfg.chainID +} + +// GenesisFile returns the full path to the genesis.json file +func (cfg BaseConfig) GenesisFile() string { + return rootify(cfg.Genesis, cfg.RootDir) +} + +// PrivValidatorFile returns the full path to the priv_validator.json file +func (cfg BaseConfig) PrivValidatorFile() string { + return rootify(cfg.PrivValidator, cfg.RootDir) +} + +// NodeKeyFile returns the full path to the node_key.json file +func (cfg BaseConfig) NodeKeyFile() string { + return rootify(cfg.NodeKey, cfg.RootDir) +} + +// DBDir returns the full path to the database directory +func (cfg BaseConfig) DBDir() string { + return rootify(cfg.DBPath, cfg.RootDir) +} + +// DefaultLogLevel returns a default log level of "error" +func DefaultLogLevel() string { + return "error" +} + +// DefaultPackageLogLevels returns a default log level setting so all packages +// log at "error", while the `state` and `main` packages log at "info" +func DefaultPackageLogLevels() string { + return fmt.Sprintf("main:info,state:info,*:%s", DefaultLogLevel()) +} + +//----------------------------------------------------------------------------- +// RPCConfig + +// RPCConfig defines the configuration options for the Tendermint RPC server +type RPCConfig struct { + RootDir string `mapstructure:"home"` + + // TCP or UNIX socket address for the RPC server to listen on + ListenAddress string `mapstructure:"laddr"` + + // TCP or UNIX socket address for the gRPC server to listen on + // NOTE: This server only supports /broadcast_tx_commit + GRPCListenAddress string `mapstructure:"grpc_laddr"` + + // Activate unsafe RPC commands like /dial_persistent_peers and /unsafe_flush_mempool + Unsafe bool `mapstructure:"unsafe"` +} + +// DefaultRPCConfig returns a default configuration for the RPC server +func DefaultRPCConfig() *RPCConfig { + return &RPCConfig{ + //ListenAddress: "tcp://0.0.0.0:26657", + ListenAddress: fmt.Sprintf("tcp://127.0.0.1:%d", 26657+portStep), + GRPCListenAddress: "", + Unsafe: false, + } +} + +// TestRPCConfig returns a configuration for testing the RPC server +func TestRPCConfig() *RPCConfig { + cfg := DefaultRPCConfig() + cfg.ListenAddress = "tcp://0.0.0.0:36657" + cfg.GRPCListenAddress = "tcp://0.0.0.0:36658" + cfg.Unsafe = true + return cfg +} + +//----------------------------------------------------------------------------- +// P2PConfig + +// P2PConfig defines the configuration options for the Tendermint peer-to-peer networking layer +type P2PConfig struct { + RootDir string `mapstructure:"home"` + + // Address to listen for incoming connections + ListenAddress string `mapstructure:"laddr"` + + // Comma separated list of seed nodes to connect to + // We only use these if we can’t connect to peers in the addrbook + Seeds string `mapstructure:"seeds"` + + // Comma separated list of nodes to keep persistent connections to + // Do not add private peers to this list if you don't want them advertised + PersistentPeers string `mapstructure:"persistent_peers"` + + // Skip UPNP port forwarding + SkipUPNP bool `mapstructure:"skip_upnp"` + + // Path to address book + AddrBook string `mapstructure:"addr_book_file"` + + // Set true for strict address routability rules + AddrBookStrict bool `mapstructure:"addr_book_strict"` + + // Maximum number of peers to connect to + MaxNumPeers int `mapstructure:"max_num_peers"` + + // Time to wait before flushing messages out on the connection, in ms + FlushThrottleTimeout int `mapstructure:"flush_throttle_timeout"` + + // Maximum size of a message packet payload, in bytes + MaxPacketMsgPayloadSize int `mapstructure:"max_packet_msg_payload_size"` + + // Rate at which packets can be sent, in bytes/second + SendRate int64 `mapstructure:"send_rate"` + + // Rate at which packets can be received, in bytes/second + RecvRate int64 `mapstructure:"recv_rate"` + + // Set true to enable the peer-exchange reactor + PexReactor bool `mapstructure:"pex"` + + // Seed mode, in which node constantly crawls the network and looks for + // peers. If another node asks it for addresses, it responds and disconnects. + // + // Does not work if the peer-exchange reactor is disabled. + SeedMode bool `mapstructure:"seed_mode"` + + // Authenticated encryption + AuthEnc bool `mapstructure:"auth_enc"` + + // Comma separated list of peer IDs to keep private (will not be gossiped to + // other peers) + PrivatePeerIDs string `mapstructure:"private_peer_ids"` + + // Toggle to disable guard against peers connecting from the same ip. + AllowDuplicateIP bool `mapstructure:"allow_duplicate_ip"` + + // Peer connection configuration. + HandshakeTimeout time.Duration `mapstructure:"handshake_timeout"` + DialTimeout time.Duration `mapstructure:"dial_timeout"` + + // Testing params. + // Force dial to fail + TestDialFail bool `mapstructure:"test_dial_fail"` + // FUzz connection + TestFuzz bool `mapstructure:"test_fuzz"` + TestFuzzConfig *FuzzConnConfig `mapstructure:"test_fuzz_config"` +} + +// DefaultP2PConfig returns a default configuration for the peer-to-peer layer +func DefaultP2PConfig() *P2PConfig { + return &P2PConfig{ + ListenAddress: fmt.Sprintf("tcp://127.0.0.1:%d", 26656+portStep), + //ListenAddress: "tcp://0.0.0.0:26656", + AddrBook: defaultAddrBookPath, + AddrBookStrict: true, + MaxNumPeers: 50, + FlushThrottleTimeout: 100, + MaxPacketMsgPayloadSize: 1024, // 1 kB + SendRate: 512000, // 500 kB/s + RecvRate: 512000, // 500 kB/s + PexReactor: true, + SeedMode: false, + AllowDuplicateIP: true, // so non-breaking yet + HandshakeTimeout: 20 * time.Second, + DialTimeout: 3 * time.Second, + TestDialFail: false, + TestFuzz: false, + TestFuzzConfig: DefaultFuzzConnConfig(), + } +} + +// TestP2PConfig returns a configuration for testing the peer-to-peer layer +func TestP2PConfig() *P2PConfig { + cfg := DefaultP2PConfig() + cfg.ListenAddress = "tcp://0.0.0.0:36656" + cfg.SkipUPNP = true + cfg.FlushThrottleTimeout = 10 + cfg.AllowDuplicateIP = true + return cfg +} + +// AddrBookFile returns the full path to the address book +func (cfg *P2PConfig) AddrBookFile() string { + return rootify(cfg.AddrBook, cfg.RootDir) } -// SetRoot sets the RootDir for all Config structs -func (cfg *Config) SetRoot(root string) *Config { - cfg.RootDir = root - for _, chain := range cfg.ChainConfigs { - chainDir := filepath.Join(root, chain.ChainID()) - chain.SetRoot(chainDir) +// FuzzConnConfig is a FuzzedConnection configuration. +type FuzzConnConfig struct { + Mode int + MaxDelay time.Duration + ProbDropRW float64 + ProbDropConn float64 + ProbSleep float64 +} + +// DefaultFuzzConnConfig returns the default config. +func DefaultFuzzConnConfig() *FuzzConnConfig { + return &FuzzConnConfig{ + Mode: FuzzModeDrop, + MaxDelay: 3 * time.Second, + ProbDropRW: 0.2, + ProbDropConn: 0.00, + ProbSleep: 0.00, } +} + +//----------------------------------------------------------------------------- +// MempoolConfig + +// MempoolConfig defines the configuration options for the Tendermint mempool +type MempoolConfig struct { + RootDir string `mapstructure:"home"` + Recheck bool `mapstructure:"recheck"` + RecheckEmpty bool `mapstructure:"recheck_empty"` + Broadcast bool `mapstructure:"broadcast"` + WalPath string `mapstructure:"wal_dir"` + Size int `mapstructure:"size"` + CacheSize int `mapstructure:"cache_size"` +} + +// DefaultMempoolConfig returns a default configuration for the Tendermint mempool +func DefaultMempoolConfig() *MempoolConfig { + return &MempoolConfig{ + Recheck: true, + RecheckEmpty: true, + Broadcast: true, + WalPath: filepath.Join(defaultDataDir, "mempool.wal"), + Size: 100000, + CacheSize: 100000, + } +} + +// TestMempoolConfig returns a configuration for testing the Tendermint mempool +func TestMempoolConfig() *MempoolConfig { + cfg := DefaultMempoolConfig() + cfg.CacheSize = 1000 + return cfg +} + +// WalDir returns the full path to the mempool's write-ahead log +func (cfg *MempoolConfig) WalDir() string { + return rootify(cfg.WalPath, cfg.RootDir) +} + +//----------------------------------------------------------------------------- +// ConsensusConfig + +// ConsensusConfig defines the confuguration for the Tendermint consensus service, +// including timeouts and details about the WAL and the block structure. +type ConsensusConfig struct { + RootDir string `mapstructure:"home"` + WalPath string `mapstructure:"wal_file"` + WalLight bool `mapstructure:"wal_light"` + walFile string // overrides WalPath if set + + // All timeouts are in milliseconds + 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"` + + // EmptyBlocks mode and possible interval between empty blocks in seconds + CreateEmptyBlocks bool `mapstructure:"create_empty_blocks"` + CreateEmptyBlocksInterval int `mapstructure:"create_empty_blocks_interval"` + + // Reactor sleep duration parameters are in milliseconds + PeerGossipSleepDuration int `mapstructure:"peer_gossip_sleep_duration"` + PeerQueryMaj23SleepDuration int `mapstructure:"peer_query_maj23_sleep_duration"` +} + +// DefaultConsensusConfig returns a default configuration for the consensus service +func DefaultConsensusConfig() *ConsensusConfig { + return &ConsensusConfig{ + WalPath: filepath.Join(defaultDataDir, "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 + CreateEmptyBlocks: true, + CreateEmptyBlocksInterval: 0, + PeerGossipSleepDuration: 100, + PeerQueryMaj23SleepDuration: 2000, + } +} + +// TestConsensusConfig returns a configuration for testing the consensus service +func TestConsensusConfig() *ConsensusConfig { + cfg := DefaultConsensusConfig() + cfg.TimeoutPropose = 100 + cfg.TimeoutProposeDelta = 1 + cfg.TimeoutPrevote = 10 + cfg.TimeoutPrevoteDelta = 1 + cfg.TimeoutPrecommit = 10 + cfg.TimeoutPrecommitDelta = 1 + cfg.TimeoutCommit = 10 + cfg.SkipTimeoutCommit = true + cfg.PeerGossipSleepDuration = 5 + cfg.PeerQueryMaj23SleepDuration = 250 return cfg } -// DefaultConfig returns a default configuration for a teragrid node -func DefaultConfig() *Config { - cfg := Config{ - RootDir: "", - LogLevel: DefaultPackageLogLevels(), - ChainConfigs: []*ChainConfig{ - DefaultChainConfig(defaultChainName), - }, +// WaitForTxs returns true if the consensus should wait for transactions before entering the propose step +func (cfg *ConsensusConfig) WaitForTxs() bool { + return !cfg.CreateEmptyBlocks || cfg.CreateEmptyBlocksInterval > 0 +} + +// EmptyBlocks returns the amount of time to wait before proposing an empty block or starting the propose timer if there are no txs available +func (cfg *ConsensusConfig) EmptyBlocksInterval() time.Duration { + return time.Duration(cfg.CreateEmptyBlocksInterval) * time.Second +} + +// Propose returns the amount of time to wait for a proposal +func (cfg *ConsensusConfig) Propose(round int) time.Duration { + return time.Duration(cfg.TimeoutPropose+cfg.TimeoutProposeDelta*round) * time.Millisecond +} + +// Prevote returns the amount of time to wait for straggler votes after receiving any +2/3 prevotes +func (cfg *ConsensusConfig) Prevote(round int) time.Duration { + return time.Duration(cfg.TimeoutPrevote+cfg.TimeoutPrevoteDelta*round) * time.Millisecond +} + +// Precommit returns the amount of time to wait for straggler votes after receiving any +2/3 precommits +func (cfg *ConsensusConfig) Precommit(round int) time.Duration { + return time.Duration(cfg.TimeoutPrecommit+cfg.TimeoutPrecommitDelta*round) * time.Millisecond +} + +// Commit returns the amount of time to wait for straggler votes after receiving +2/3 precommits for a single block (ie. a commit). +func (cfg *ConsensusConfig) Commit(t time.Time) time.Time { + return t.Add(time.Duration(cfg.TimeoutCommit) * time.Millisecond) +} + +// PeerGossipSleep returns the amount of time to sleep if there is nothing to send from the ConsensusReactor +func (cfg *ConsensusConfig) PeerGossipSleep() time.Duration { + return time.Duration(cfg.PeerGossipSleepDuration) * time.Millisecond +} + +// PeerQueryMaj23Sleep returns the amount of time to sleep after each VoteSetMaj23Message is sent in the ConsensusReactor +func (cfg *ConsensusConfig) PeerQueryMaj23Sleep() time.Duration { + return time.Duration(cfg.PeerQueryMaj23SleepDuration) * time.Millisecond +} + +// WalFile returns the full path to the write-ahead log file +func (cfg *ConsensusConfig) WalFile() string { + if cfg.walFile != "" { + return cfg.walFile } - return &cfg + return rootify(cfg.WalPath, cfg.RootDir) +} + +// SetWalFile sets the path to the write-ahead log file +func (cfg *ConsensusConfig) SetWalFile(walFile string) { + cfg.walFile = walFile } -// TestConfig returns a configuration that can be used for testing -func TestConfig() *Config { - return DefaultConfig() - //return &Config{ - // DefaultConfig(), - //} +//----------------------------------------------------------------------------- +// TxIndexConfig + +// TxIndexConfig defines the confuguration for the transaction +// indexer, including tags to index. +type TxIndexConfig struct { + // 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 string `mapstructure:"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. + IndexTags string `mapstructure:"index_tags"` + + // 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). + IndexAllTags bool `mapstructure:"index_all_tags"` +} + +// DefaultTxIndexConfig returns a default configuration for the transaction indexer. +func DefaultTxIndexConfig() *TxIndexConfig { + return &TxIndexConfig{ + Indexer: "kv", + IndexTags: "", + IndexAllTags: false, + } +} + +// TestTxIndexConfig returns a default configuration for the transaction indexer. +func TestTxIndexConfig() *TxIndexConfig { + return DefaultTxIndexConfig() +} + +//----------------------------------------------------------------------------- +// Utils + +// helper function to make config creation independent of root dir +func rootify(path, root string) string { + if filepath.IsAbs(path) { + return path + } + return filepath.Join(root, path) +} + +//----------------------------------------------------------------------------- +// Moniker + +var defaultMoniker = getDefaultMoniker() + +// getDefaultMoniker returns a default moniker, which is the host name. If runtime +// fails to get the host name, "anonymous" will be returned. +func getDefaultMoniker() string { + moniker, err := os.Hostname() + if err != nil { + moniker = "anonymous" + } + return moniker } diff --git a/config/config_test.go b/config/config_test.go index fbcb28f..3f3d1dc 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -11,7 +11,7 @@ func TestDefaultConfig(t *testing.T) { assert := assert.New(t) // set up some defaults - cfg := DefaultConfig() + cfg := *DefaultConfig() assert.NotNil(cfg.RootDir) // assert.NotNil(cfg.Mempool) diff --git a/config/main_config.go b/config/main_config.go new file mode 100644 index 0000000..3f447fa --- /dev/null +++ b/config/main_config.go @@ -0,0 +1,73 @@ +package config + +import ( + // "fmt" + // "os" + "path/filepath" + // "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 +// NOTE: tendermint/cli must know to look in the config dir! +var ( + DefaultTendermintDir = ".dagmint" + defaultChainName = "default" + defaultConfigDir = "config" + defaultDataDir = "data" + + defaultConfigFileName = "config.toml" + defaultGenesisJSONName = "genesis.json" + + defaultPrivValName = "priv_validator.json" + defaultNodeKeyName = "node_key.json" + defaultAddrBookName = "addrbook.json" + + defaultConfigFilePath = filepath.Join(defaultConfigDir, defaultConfigFileName) + defaultGenesisJSONPath = filepath.Join(defaultConfigDir, defaultGenesisJSONName) + defaultPrivValPath = filepath.Join(defaultConfigDir, defaultPrivValName) + defaultNodeKeyPath = filepath.Join(defaultConfigDir, defaultNodeKeyName) + defaultAddrBookPath = filepath.Join(defaultConfigDir, defaultAddrBookName) +) + +type Config struct { + // The root directory for all data. + // This should be set in viper so it can unmarshal into this struct + RootDir string `mapstructure:"home"` + // Output level for logging + LogLevel string `mapstructure:"log_level"` + ChainConfigs []*ChainConfig +} + +// SetRoot sets the RootDir for all Config structs +func (cfg *Config) SetRoot(root string) *Config { + cfg.RootDir = root + for _, chain := range cfg.ChainConfigs { + chainDir := filepath.Join(root, chain.ChainID()) + chain.SetRoot(chainDir) + } + return cfg +} + +// DefaultConfig returns a default configuration for a tendermint node +func DefaultConfig() *Config { + cfg := Config{ + RootDir: "", + LogLevel: DefaultPackageLogLevels(), + ChainConfigs: []*ChainConfig{ + DefaultChainConfig(defaultChainName), + }, + } + return &cfg +} + +// TestConfig returns a configuration that can be used for testing +func TestConfig() *Config { + return DefaultConfig() + //return &Config{ + // DefaultConfig(), + //} +} diff --git a/config/toml.go b/config/toml.go index f28848c..b49a637 100644 --- a/config/toml.go +++ b/config/toml.go @@ -8,7 +8,7 @@ import ( "text/template" "github.com/spf13/viper" - cmn "github.com/teragrid/teralibs/common" + cmn "github.com/tendermint/tmlibs/common" ) var configTemplate *template.Template @@ -29,7 +29,6 @@ func EnsureRoot(rootDir string, config *Config) { if err := cmn.EnsureDir(rootDir, 0700); err != nil { cmn.PanicSanity(err.Error()) } - //config := DefaultConfig() for _, chain := range config.ChainConfigs { chainDir := chain.ChainID() if err := cmn.EnsureDir(filepath.Join(rootDir, chainDir), 0700); err != nil { @@ -43,15 +42,17 @@ func EnsureRoot(rootDir string, config *Config) { } } - configFilePath := rootDir //filepath.Join(rootDir, defaultChainName, defaultConfigFilePath) - + // configFilePath := rootDir //filepath.Join(rootDir, defaultChainName, defaultConfigFilePath) + // fmt.Println("EnsureRoot " + filepath.Join(configFilePath, "config.json")) // Write default config file if missing. - if !cmn.FileExists(filepath.Join(configFilePath, "config.json")) { - writeDefaultConfigFile(configFilePath, config) - } + // if !cmn.FileExists(filepath.Join(configFilePath, "config.json")) { + // fmt.Println("EnsureRoot (WRITE) " + filepath.Join(configFilePath, "config.json")) + // writeDefaultConfigFile(configFilePath, config) + // } + WriteConfigFile(rootDir, config) } -// XXX: this func should probably be called by cmd/teragrid/commands/init.go +// 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, config *Config) { WriteConfigFile(configFilePath, config) @@ -59,11 +60,6 @@ func writeDefaultConfigFile(configFilePath string, config *Config) { // WriteConfigFile renders config using the template and writes it to configFilePath. func WriteConfigFile(configFilePath string, config *Config) { - var runtime_viper = viper.New() - runtime_viper.SetConfigType("json") - runtime_viper.SetConfigFile(filepath.Join(configFilePath, "config.json")) - runtime_viper.SetDefault("LogLevel", config.LogLevel) - var chains []string chains = make([]string, len(config.ChainConfigs)) for idx, chain := range config.ChainConfigs { @@ -75,11 +71,19 @@ func WriteConfigFile(configFilePath string, config *Config) { fmt.Println("WriteConfigFile Panic " + configFilePath) panic(err) } else { - cmn.MustWriteFile(filepath.Join(configFilePath, chain.ChainID(), defaultConfigFilePath), buffer.Bytes(), 0644) + if !cmn.FileExists(filepath.Join(configFilePath, chain.ChainID(), defaultConfigFilePath)) { + cmn.MustWriteFile(filepath.Join(configFilePath, chain.ChainID(), defaultConfigFilePath), buffer.Bytes(), 0644) + } } } - runtime_viper.SetDefault("Chains", chains) - runtime_viper.WriteConfig() + if true || !cmn.FileExists(filepath.Join(configFilePath, "config.json")) { + var runtime_viper = viper.New() + runtime_viper.SetConfigType("json") + runtime_viper.SetConfigFile(filepath.Join(configFilePath, "config.json")) + runtime_viper.SetDefault("LogLevel", config.LogLevel) + runtime_viper.SetDefault("Chains", chains) + runtime_viper.WriteConfig() + } } // Note: any changes to the comments/variables/mapstructure @@ -89,8 +93,8 @@ const defaultConfigTemplate = `# This is a TOML config file. ##### main base config options ##### -# TCP or UNIX socket address of the Asura application, -# or the name of an Asura application compiled in with the teragrid binary +# 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 @@ -105,7 +109,7 @@ fast_sync = {{ .BaseConfig.FastSync }} db_backend = "{{ .BaseConfig.DBBackend }}" # Database directory -db_path = "{{ .BaseConfig.DBPath }}" +db_path = "{{ js .BaseConfig.DBPath }}" # Output level for logging, including package level options log_level = "{{ .BaseConfig.LogLevel }}" @@ -113,21 +117,21 @@ 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 }}" +genesis_file = "{{ js .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 }}" +priv_validator_file = "{{ js .BaseConfig.PrivValidator }}" # Path to the JSON file containing the private key to use for node authentication in the p2p protocol -node_key_file = "{{ .BaseConfig.NodeKey}}" +node_key_file = "{{ js .BaseConfig.NodeKey}}" -# Mechanism to connect to the Asura application: socket | grpc -Asura = "{{ .BaseConfig.Asura }}" +# 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 Asura app on connecting to a new peer +# 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 }} @@ -160,7 +164,7 @@ seeds = "{{ .P2P.Seeds }}" persistent_peers = "{{ .P2P.PersistentPeers }}" # Path to address book -addr_book_file = "{{ .P2P.AddrBook }}" +addr_book_file = "{{ js .P2P.AddrBook }}" # Set true for strict address routability rules addr_book_strict = {{ .P2P.AddrBookStrict }} @@ -189,9 +193,6 @@ pex = {{ .P2P.PexReactor }} # Does not work if the peer-exchange reactor is disabled. seed_mode = {{ .P2P.SeedMode }} -# Authenticated encryption -auth_enc = {{ .P2P.AuthEnc }} - # Comma separated list of peer IDs to keep private (will not be gossiped to other peers) private_peer_ids = "{{ .P2P.PrivatePeerIDs }}" @@ -201,13 +202,18 @@ private_peer_ids = "{{ .P2P.PrivatePeerIDs }}" recheck = {{ .Mempool.Recheck }} recheck_empty = {{ .Mempool.RecheckEmpty }} broadcast = {{ .Mempool.Broadcast }} -wal_dir = "{{ .Mempool.WalPath }}" +wal_dir = "{{ js .Mempool.WalPath }}" + +# size of the mempool +size = {{ .Mempool.Size }} + +# size of the cache (used to filter transactions we saw earlier) +cache_size = {{ .Mempool.CacheSize }} ##### consensus configuration options ##### [consensus] -wal_file = "{{ .Consensus.WalPath }}" -wal_light = {{ .Consensus.WalLight }} +wal_file = "{{ js .Consensus.WalPath }}" # All timeouts are in milliseconds timeout_propose = {{ .Consensus.TimeoutPropose }} @@ -260,15 +266,15 @@ index_all_tags = {{ .TxIndex.IndexAllTags }} /****** these are for test settings ***********/ func ResetTestRoot(testName string) *Config { - rootDir := os.ExpandEnv("$HOME/.teragrid_test") + rootDir := os.ExpandEnv("$HOME/.tendermint_test") rootDir = filepath.Join(rootDir, testName) - // Remove ~/.teragrid_test_bak + // Remove ~/.tendermint_test_bak if cmn.FileExists(rootDir + "_bak") { if err := os.RemoveAll(rootDir + "_bak"); err != nil { cmn.PanicSanity(err.Error()) } } - // Move ~/.teragrid_test to ~/.teragrid_test_bak + // Move ~/.tendermint_test to ~/.tendermint_test_bak if cmn.FileExists(rootDir) { if err := os.Rename(rootDir, rootDir+"_bak"); err != nil { cmn.PanicSanity(err.Error()) @@ -292,8 +298,8 @@ func ResetTestRoot(testName string) *Config { //baseConfig := DefaultBaseConfig(defaultChainName) baseConfig := config.ChainConfigs[0] configFilePath := filepath.Join(rootDir, defaultChainName, defaultConfigFilePath) - genesisFilePath := filepath.Join(rootDir, baseConfig.Genesis) - privFilePath := filepath.Join(rootDir, baseConfig.PrivValidator) + genesisFilePath := filepath.Join(rootDir, defaultChainName, baseConfig.Genesis) + privFilePath := filepath.Join(rootDir, defaultChainName, baseConfig.PrivValidator) // Write default config file if missing. if !cmn.FileExists(configFilePath) { @@ -301,8 +307,10 @@ func ResetTestRoot(testName string) *Config { writeDefaultConfigFile(rootDir, config) } if !cmn.FileExists(genesisFilePath) { + fmt.Println("ResetTestRoot genesisFilePath XXXX " + genesisFilePath) cmn.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644) } + fmt.Println("ResetTestRoot privFilePath XXXX " + privFilePath) // we always overwrite the priv val cmn.MustWriteFile(privFilePath, []byte(testPrivValidator), 0644) @@ -312,7 +320,7 @@ func ResetTestRoot(testName string) *Config { var testGenesis = `{ "genesis_time": "0001-01-01T00:00:00.000Z", - "chain_id": "teragrid_test", + "chain_id": "tendermint_test", "validators": [ { "pub_key": { diff --git a/config/toml_test.go b/config/toml_test.go index ee8ef0d..589e484 100644 --- a/config/toml_test.go +++ b/config/toml_test.go @@ -26,10 +26,10 @@ func TestEnsureRoot(t *testing.T) { // setup temp dir for test tmpDir, err := ioutil.TempDir("", "config-test") require.Nil(err) - defer os.RemoveAll(tmpDir) // nolint: errcheck + //defer os.RemoveAll(tmpDir) // nolint: errcheck // create root dir - EnsureRoot(tmpDir) + EnsureRoot(tmpDir, DefaultConfig()) fmt.Println("Read File " + filepath.Join(tmpDir, defaultChainName, defaultConfigFilePath)) // make sure config is set properly From 7c1017559c40a71f802a0a15a8270c9dea83d71d Mon Sep 17 00:00:00 2001 From: Ha Ly Bang Date: Tue, 10 Jul 2018 09:41:46 +0700 Subject: [PATCH 5/7] Asura :0 --- cmd/teragrid/commands/init.go | 4 +-- cmd/teragrid/commands/lite.go | 4 +-- cmd/teragrid/commands/reset_priv_validator.go | 2 +- cmd/teragrid/commands/root.go | 6 ++-- cmd/teragrid/commands/run_node.go | 8 +++--- cmd/teragrid/commands/testnet.go | 4 +-- cmd/teragrid/main.go | 2 +- config/chain_config.go | 15 ++-------- config/config.go | 28 +++++++++---------- config/main_config.go | 12 ++++---- config/toml.go | 22 +++++++-------- 11 files changed, 48 insertions(+), 59 deletions(-) diff --git a/cmd/teragrid/commands/init.go b/cmd/teragrid/commands/init.go index a7c0288..2ec0b04 100644 --- a/cmd/teragrid/commands/init.go +++ b/cmd/teragrid/commands/init.go @@ -12,10 +12,10 @@ import ( cmn "github.com/teragrid/teralibs/common" ) -// InitFilesCmd initialises a fresh Tendermint Core instance. +// InitFilesCmd initialises a fresh Teragrid Core instance. var InitFilesCmd = &cobra.Command{ Use: "init", - Short: "Initialize Tendermint", + Short: "Initialize Teragrid", RunE: initFiles, } diff --git a/cmd/teragrid/commands/lite.go b/cmd/teragrid/commands/lite.go index 4fb05fa..2d71435 100644 --- a/cmd/teragrid/commands/lite.go +++ b/cmd/teragrid/commands/lite.go @@ -35,8 +35,8 @@ var ( func init() { LiteCmd.Flags().StringVar(&listenAddr, "laddr", "tcp://localhost:8888", "Serve the proxy on the given address") - LiteCmd.Flags().StringVar(&nodeAddr, "node", "tcp://localhost:26657", "Connect to a Tendermint node at this address") - LiteCmd.Flags().StringVar(&chainID, "chain-id", "tendermint", "Specify the Tendermint chain ID") + LiteCmd.Flags().StringVar(&nodeAddr, "node", "tcp://localhost:26657", "Connect to a Teragrid node at this address") + LiteCmd.Flags().StringVar(&chainID, "chain-id", "tendermint", "Specify the Teragrid chain ID") LiteCmd.Flags().StringVar(&home, "home-dir", ".tendermint-lite", "Specify the home directory") } diff --git a/cmd/teragrid/commands/reset_priv_validator.go b/cmd/teragrid/commands/reset_priv_validator.go index d5ea837..924607f 100644 --- a/cmd/teragrid/commands/reset_priv_validator.go +++ b/cmd/teragrid/commands/reset_priv_validator.go @@ -9,7 +9,7 @@ import ( "github.com/teragrid/teralibs/log" ) -// ResetAllCmd removes the database of this Tendermint core +// ResetAllCmd removes the database of this Teragrid core // instance. var ResetAllCmd = &cobra.Command{ Use: "unsafe_reset_all", diff --git a/cmd/teragrid/commands/root.go b/cmd/teragrid/commands/root.go index 97ebc94..efd0e25 100644 --- a/cmd/teragrid/commands/root.go +++ b/cmd/teragrid/commands/root.go @@ -35,7 +35,7 @@ func registerFlagsRootCmd(cmd *cobra.Command) { } // ParseConfig retrieves the default environment configuration, -// sets up the Tendermint root and ensures that the root exists +// sets up the Teragrid root and ensures that the root exists func ParseConfig() (*cfg.Config, error) { var conf *cfg.Config @@ -88,10 +88,10 @@ func ParseConfig() (*cfg.Config, error) { return conf, nil } -// RootCmd is the root command for Tendermint core. +// RootCmd is the root command for Teragrid core. var RootCmd = &cobra.Command{ Use: "tendermint", - Short: "Tendermint Core (BFT Consensus) in Go", + Short: "Teragrid Core (BFT Consensus) in Go", PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { if cmd.Name() == VersionCmd.Name() { return nil diff --git a/cmd/teragrid/commands/run_node.go b/cmd/teragrid/commands/run_node.go index ce6a7e4..a3c8933 100644 --- a/cmd/teragrid/commands/run_node.go +++ b/cmd/teragrid/commands/run_node.go @@ -22,9 +22,9 @@ func AddNodeFlags(cmd *cobra.Command) { // node flags cmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing") - // abci flags + // Asura flags cmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or 'nilapp' or 'kvstore' for local testing.") - cmd.Flags().String("abci", config.Asura, "Specify Asura transport (socket | grpc)") + cmd.Flags().String("asura", config.Asura, "Specify Asura transport (socket | grpc)") // rpc flags cmd.Flags().String("rpc.laddr", config.RPC.ListenAddress, "RPC listen address. Port required") @@ -45,7 +45,7 @@ func AddNodeFlags(cmd *cobra.Command) { } // NewRunNodeCmd returns the command that allows the CLI to start a node. -// It can be used with a custom PrivValidator and in-process ABCI application. +// It can be used with a custom PrivValidator and in-process Asura application. func NewRunNodeCmd(nodeProvider nm.NodeProvider) *cobra.Command { cmd := &cobra.Command{ Use: "node", @@ -123,7 +123,7 @@ func runNodes(nodeProvider nm.NodeProvider) { /* // NewRunNodeCmd returns the command that allows the CLI to start a node. -// It can be used with a custom PrivValidator and in-process ABCI application. +// It can be used with a custom PrivValidator and in-process Asura application. func NewRunNodeCmd(nodeProvider nm.NodeProvider) *cobra.Command { cmd := &cobra.Command{ Use: "node", diff --git a/cmd/teragrid/commands/testnet.go b/cmd/teragrid/commands/testnet.go index 8d9cadc..77997b5 100644 --- a/cmd/teragrid/commands/testnet.go +++ b/cmd/teragrid/commands/testnet.go @@ -53,10 +53,10 @@ func init() { "P2P Port") } -// TestnetFilesCmd allows initialisation of files for a Tendermint testnet. +// TestnetFilesCmd allows initialisation of files for a Teragrid testnet. var TestnetFilesCmd = &cobra.Command{ Use: "testnet", - Short: "Initialize files for a Tendermint testnet", + Short: "Initialize files for a Teragrid testnet", Long: `testnet will create "v" + "n" number of directories and populate each with necessary files (private validator, genesis, config, etc.). diff --git a/cmd/teragrid/main.go b/cmd/teragrid/main.go index 8612f60..27e54fc 100644 --- a/cmd/teragrid/main.go +++ b/cmd/teragrid/main.go @@ -42,7 +42,7 @@ func main() { // Create & start node rootCmd.AddCommand(cmd.NewRunNodeCmd(nodeFunc)) - cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultTendermintDir))) + cmd := cli.PrepareBaseCmd(rootCmd, "TM", os.ExpandEnv(filepath.Join("$HOME", cfg.DefaultTeragridDir))) if err := cmd.Execute(); err != nil { panic(err) } diff --git a/config/chain_config.go b/config/chain_config.go index c715b2f..107b9b6 100644 --- a/config/chain_config.go +++ b/config/chain_config.go @@ -3,22 +3,11 @@ package config var portStep = 0 //----------------------------------------------------------------------------- -// ShardConfig -// ShardConfig defines the base configuration for a tendermint quorum -type ShardConfig struct { - ShardID string - Validator bool - - // Path to the JSON file containing the private key to use as a validator in the consensus protocol - PrivValidator string `mapstructure:"priv_validator_file"` -} - -// Config defines the top level configuration for a tendermint node +// Config defines the top level configuration for a teragrid node type ChainConfig struct { // Top level options use an anonymous struct BaseConfig `mapstructure:",squash"` - Shard []ShardConfig // Options for services RPC *RPCConfig `mapstructure:"rpc"` P2P *P2PConfig `mapstructure:"p2p"` @@ -27,7 +16,7 @@ type ChainConfig struct { TxIndex *TxIndexConfig `mapstructure:"tx_index"` } -// DefaultConfig returns a default configuration for a tendermint node +// DefaultConfig returns a default configuration for a teragrid node func DefaultChainConfig(name string) *ChainConfig { portStep = portStep + 10 return &ChainConfig{ diff --git a/config/config.go b/config/config.go index 9674d2e..01d4d54 100644 --- a/config/config.go +++ b/config/config.go @@ -17,7 +17,7 @@ const ( //----------------------------------------------------------------------------- // BaseConfig -// BaseConfig defines the base configuration for a Tendermint node +// BaseConfig defines the base configuration for a Teragrid node type BaseConfig struct { // chainID is unexposed and immutable but here for convenience @@ -39,15 +39,15 @@ type BaseConfig struct { // A custom human readable name for this node Moniker string `mapstructure:"moniker"` - // TCP or UNIX socket address for Tendermint to listen on for + // TCP or UNIX socket address for Teragrid to listen on for // connections from an external PrivValidator process PrivValidatorListenAddr string `mapstructure:"priv_validator_laddr"` - // TCP or UNIX socket address of the ABCI application, - // or the name of an ABCI application compiled in with the Tendermint binary + // TCP or UNIX socket address of the Asura application, + // or the name of an Asura application compiled in with the Teragrid binary ProxyApp string `mapstructure:"proxy_app"` - // Mechanism to connect to the ABCI application: socket | grpc + // Mechanism to connect to the Asura application: socket | grpc Asura string `mapstructure:"asura"` // Output level for logging @@ -61,7 +61,7 @@ type BaseConfig struct { // and verifying their commits FastSync bool `mapstructure:"fast_sync"` - // If true, query the ABCI app on connecting to a new peer + // If true, query the Asura app on connecting to a new peer // so the app can decide if we should keep the connection or not FilterPeers bool `mapstructure:"filter_peers"` // false @@ -72,7 +72,7 @@ type BaseConfig struct { DBPath string `mapstructure:"db_dir"` } -// DefaultBaseConfig returns a default base configuration for a Tendermint node +// DefaultBaseConfig returns a default base configuration for a Teragrid node func DefaultBaseConfig(name string) BaseConfig { return BaseConfig{ chainID: name, @@ -92,7 +92,7 @@ func DefaultBaseConfig(name string) BaseConfig { } } -// TestBaseConfig returns a base configuration for testing a Tendermint node +// TestBaseConfig returns a base configuration for testing a Teragrid node func TestBaseConfig() BaseConfig { cfg := DefaultBaseConfig(defaultChainName) cfg.chainID = "dagmint_test" @@ -140,7 +140,7 @@ func DefaultPackageLogLevels() string { //----------------------------------------------------------------------------- // RPCConfig -// RPCConfig defines the configuration options for the Tendermint RPC server +// RPCConfig defines the configuration options for the Teragrid RPC server type RPCConfig struct { RootDir string `mapstructure:"home"` @@ -177,7 +177,7 @@ func TestRPCConfig() *RPCConfig { //----------------------------------------------------------------------------- // P2PConfig -// P2PConfig defines the configuration options for the Tendermint peer-to-peer networking layer +// P2PConfig defines the configuration options for the Teragrid peer-to-peer networking layer type P2PConfig struct { RootDir string `mapstructure:"home"` @@ -308,7 +308,7 @@ func DefaultFuzzConnConfig() *FuzzConnConfig { //----------------------------------------------------------------------------- // MempoolConfig -// MempoolConfig defines the configuration options for the Tendermint mempool +// MempoolConfig defines the configuration options for the Teragrid mempool type MempoolConfig struct { RootDir string `mapstructure:"home"` Recheck bool `mapstructure:"recheck"` @@ -319,7 +319,7 @@ type MempoolConfig struct { CacheSize int `mapstructure:"cache_size"` } -// DefaultMempoolConfig returns a default configuration for the Tendermint mempool +// DefaultMempoolConfig returns a default configuration for the Teragrid mempool func DefaultMempoolConfig() *MempoolConfig { return &MempoolConfig{ Recheck: true, @@ -331,7 +331,7 @@ func DefaultMempoolConfig() *MempoolConfig { } } -// TestMempoolConfig returns a configuration for testing the Tendermint mempool +// TestMempoolConfig returns a configuration for testing the Teragrid mempool func TestMempoolConfig() *MempoolConfig { cfg := DefaultMempoolConfig() cfg.CacheSize = 1000 @@ -346,7 +346,7 @@ func (cfg *MempoolConfig) WalDir() string { //----------------------------------------------------------------------------- // ConsensusConfig -// ConsensusConfig defines the confuguration for the Tendermint consensus service, +// ConsensusConfig defines the confuguration for the Teragrid consensus service, // including timeouts and details about the WAL and the block structure. type ConsensusConfig struct { RootDir string `mapstructure:"home"` diff --git a/config/main_config.go b/config/main_config.go index 3f447fa..838dade 100644 --- a/config/main_config.go +++ b/config/main_config.go @@ -12,12 +12,12 @@ import ( // generate the config.toml. Please reflect any changes // made here in the defaultConfigTemplate constant in // config/toml.go -// NOTE: tendermint/cli must know to look in the config dir! +// NOTE: teragrid/cli must know to look in the config dir! var ( - DefaultTendermintDir = ".dagmint" - defaultChainName = "default" - defaultConfigDir = "config" - defaultDataDir = "data" + DefaultTeragridDir = ".teragrid" + defaultChainName = "default" + defaultConfigDir = "config" + defaultDataDir = "data" defaultConfigFileName = "config.toml" defaultGenesisJSONName = "genesis.json" @@ -52,7 +52,7 @@ func (cfg *Config) SetRoot(root string) *Config { return cfg } -// DefaultConfig returns a default configuration for a tendermint node +// DefaultConfig returns a default configuration for a teragrid node func DefaultConfig() *Config { cfg := Config{ RootDir: "", diff --git a/config/toml.go b/config/toml.go index b49a637..4d57446 100644 --- a/config/toml.go +++ b/config/toml.go @@ -8,7 +8,7 @@ import ( "text/template" "github.com/spf13/viper" - cmn "github.com/tendermint/tmlibs/common" + cmn "github.com/teragrid/teralibs/common" ) var configTemplate *template.Template @@ -52,7 +52,7 @@ func EnsureRoot(rootDir string, config *Config) { WriteConfigFile(rootDir, config) } -// XXX: this func should probably be called by cmd/tendermint/commands/init.go +// XXX: this func should probably be called by cmd/teragrid/commands/init.go // alongside the writing of the genesis.json and priv_validator.json func writeDefaultConfigFile(configFilePath string, config *Config) { WriteConfigFile(configFilePath, config) @@ -93,8 +93,8 @@ const defaultConfigTemplate = `# This is a TOML config file. ##### main base config options ##### -# TCP or UNIX socket address of the ABCI application, -# or the name of an ABCI application compiled in with the Tendermint binary +# TCP or UNIX socket address of the Asura application, +# or the name of an Asura application compiled in with the Teragrid binary proxy_app = "{{ .BaseConfig.ProxyApp }}" # A custom human readable name for this node @@ -125,13 +125,13 @@ priv_validator_file = "{{ js .BaseConfig.PrivValidator }}" # Path to the JSON file containing the private key to use for node authentication in the p2p protocol node_key_file = "{{ js .BaseConfig.NodeKey}}" -# Mechanism to connect to the ABCI application: socket | grpc -abci = "{{ .BaseConfig.ABCI }}" +# Mechanism to connect to the Asura application: socket | grpc +asura = "{{ .BaseConfig.Asura }}" # 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 +# If true, query the Asura app on connecting to a new peer # so the app can decide if we should keep the connection or not filter_peers = {{ .BaseConfig.FilterPeers }} @@ -266,15 +266,15 @@ index_all_tags = {{ .TxIndex.IndexAllTags }} /****** these are for test settings ***********/ func ResetTestRoot(testName string) *Config { - rootDir := os.ExpandEnv("$HOME/.tendermint_test") + rootDir := os.ExpandEnv("$HOME/.teragrid_test") rootDir = filepath.Join(rootDir, testName) - // Remove ~/.tendermint_test_bak + // Remove ~/.teragrid_test_bak if cmn.FileExists(rootDir + "_bak") { if err := os.RemoveAll(rootDir + "_bak"); err != nil { cmn.PanicSanity(err.Error()) } } - // Move ~/.tendermint_test to ~/.tendermint_test_bak + // Move ~/.teragrid_test to ~/.teragrid_test_bak if cmn.FileExists(rootDir) { if err := os.Rename(rootDir, rootDir+"_bak"); err != nil { cmn.PanicSanity(err.Error()) @@ -320,7 +320,7 @@ func ResetTestRoot(testName string) *Config { var testGenesis = `{ "genesis_time": "0001-01-01T00:00:00.000Z", - "chain_id": "tendermint_test", + "chain_id": "teragrid_test", "validators": [ { "pub_key": { From 884f7075ad1241032a815faed49495d090e131f9 Mon Sep 17 00:00:00 2001 From: vietking Date: Thu, 6 Sep 2018 20:09:49 +0700 Subject: [PATCH 6/7] CORE-02: Updated command lines for teragrid --- Gopkg.lock | 47 ++++++++++++++++--------------- README.md | 2 +- cmd/teragrid/commands/lite.go | 10 +++---- cmd/teragrid/commands/root.go | 6 ++-- cmd/teragrid/commands/run_node.go | 6 ++-- cmd/teragrid/commands/testnet.go | 2 +- 6 files changed, 37 insertions(+), 36 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index a6558b1..869d0bd 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -5,13 +5,13 @@ branch = "master" name = "github.com/btcsuite/btcd" packages = ["btcec"] - revision = "86fed781132ac890ee03e906e4ecd5d6fa180c64" + revision = "cff30e1d23fc9e800b2b5b4b41ef1817dda07e9f" [[projects]] name = "github.com/davecgh/go-spew" packages = ["spew"] - revision = "346938d642f2ec3594ed81d874461961cd0faa76" - version = "v1.1.0" + revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" + version = "v1.1.1" [[projects]] branch = "master" @@ -20,10 +20,10 @@ revision = "95f809107225be108efcf10a3509e4ea6ceef3c4" [[projects]] + branch = "master" name = "github.com/fortytw2/leaktest" packages = ["."] - revision = "a5ef70473c97b71626b9abeda80ee92ba2a7de9e" - version = "v1.2.0" + revision = "b433bbd6d743c1854040b39062a3916ed5f78fe8" [[projects]] name = "github.com/fsnotify/fsnotify" @@ -50,8 +50,8 @@ [[projects]] name = "github.com/go-stack/stack" packages = ["."] - revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc" - version = "v1.7.0" + revision = "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a" + version = "v1.8.0" [[projects]] name = "github.com/gogo/protobuf" @@ -76,7 +76,7 @@ "ptypes/duration", "ptypes/timestamp" ] - revision = "925541529c1fa6821df4e44ce2723319eb2be768" + revision = "b27b920f9e71b439b873b17bf99f56467623814a" [[projects]] branch = "master" @@ -91,7 +91,6 @@ version = "v1.2.0" [[projects]] - branch = "master" name = "github.com/hashicorp/hcl" packages = [ ".", @@ -105,7 +104,8 @@ "json/scanner", "json/token" ] - revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168" + revision = "8cb6e5b959231cc1119e43259c4a608f9c51a241" + version = "v1.0.0" [[projects]] name = "github.com/inconshreveable/mousetrap" @@ -132,10 +132,10 @@ version = "v1.8.0" [[projects]] - branch = "master" name = "github.com/mitchellh/mapstructure" packages = ["."] - revision = "bb74f1db0675b241733089d5a1faa5dd8b0ef57b" + revision = "fa473d140ef3c6adf42d6b391fe76707f1f243c8" + version = "v1.0.0" [[projects]] name = "github.com/pelletier/go-toml" @@ -153,7 +153,7 @@ name = "github.com/pmezard/go-difflib" packages = ["difflib"] revision = "792786c7400a136282c1664665ae0a8db921c6c2" - version = "v1.1.0" + version = "v1.0.0" [[projects]] branch = "master" @@ -186,13 +186,13 @@ branch = "master" name = "github.com/spf13/jwalterweatherman" packages = ["."] - revision = "7c0cea34c8ece3fbeb2b27ab9b59511d360fb394" + revision = "14d3d4c518341bea657dd8a226f5121c0ff8c9f2" [[projects]] name = "github.com/spf13/pflag" packages = ["."] - revision = "583c0c0531f06d5278b7d917446061adc344b5cd" - version = "v1.0.1" + revision = "9a97c102cda95a86cec2345a6f09f55a939babf5" + version = "v1.0.2" [[projects]] name = "github.com/spf13/viper" @@ -226,7 +226,7 @@ "leveldb/table", "leveldb/util" ] - revision = "e2150783cd35f5b607daca48afd8c57ec54cc995" + revision = "ae2bd5eed72d46b28834ec3f60db3a3ebedd8dbd" [[projects]] branch = "master" @@ -260,13 +260,13 @@ branch = "master" name = "github.com/teragrid/go-amino" packages = ["."] - revision = "cda24e4f1b69ad6be3242f232bce42391e614fab" + revision = "0eab9ff210aa0337e1d9647b46f47baa9b266a4a" [[projects]] branch = "master" name = "github.com/teragrid/go-crypto" packages = ["."] - revision = "d22b3d2026e45348974f68b4606fefc20d3854ff" + revision = "4ac0a56fe910e18b2e3c1661f035760b045a59e7" [[projects]] branch = "master" @@ -292,6 +292,7 @@ name = "golang.org/x/crypto" packages = [ "curve25519", + "internal/subtle", "nacl/box", "nacl/secretbox", "openpgp/armor", @@ -300,7 +301,7 @@ "ripemd160", "salsa20/salsa" ] - revision = "8ac0e0d97ce45cd83d1d7243c060cb8461dda5e9" + revision = "182538f80094b6a8efaade63a8fd8e0d9d5843dd" [[projects]] branch = "master" @@ -314,13 +315,13 @@ "internal/timeseries", "trace" ] - revision = "1e491301e022f8f977054da4c2d852decd59571f" + revision = "8a410e7b638dca158bf9e766925842f6651ff828" [[projects]] branch = "master" name = "golang.org/x/sys" packages = ["unix"] - revision = "bff228c7b664c5fce602223a05fb708fd8654986" + revision = "2b024373dcd9800f0cae693839fac6ede8d64a8c" [[projects]] name = "golang.org/x/text" @@ -347,7 +348,7 @@ branch = "master" name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] - revision = "32ee49c4dd805befd833990acba36cb75042378c" + revision = "11092d34479b07829b72e10713b159248caf5dad" [[projects]] name = "google.golang.org/grpc" diff --git a/README.md b/README.md index f7a34d2..d715d10 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ All resources involving the use of, building application on, or developing for, ### Sub-projects * [Asura](http://github.com/teragrid/asura), the Application Blockchain Interface -* [Parkhill](http://github.com/teragrid/parkhill), a D-Apps MVC Framwork for rapid development and adoptation +* [Parkhill](http://github.com/teragrid/parkhill), a D-Apps MVC Framework for rapid development and adoptation ### Tools * [Deployment, Benchmarking, and Monitoring](http://teragrid.readthedocs.io/projects/tools/en/develop/index.html#teragrid-tools) diff --git a/cmd/teragrid/commands/lite.go b/cmd/teragrid/commands/lite.go index 2d71435..51c2662 100644 --- a/cmd/teragrid/commands/lite.go +++ b/cmd/teragrid/commands/lite.go @@ -15,12 +15,12 @@ import ( // LiteCmd represents the base command when called without any subcommands var LiteCmd = &cobra.Command{ Use: "lite", - Short: "Run lite-client proxy server, verifying tendermint rpc", - Long: `This node will run a secure proxy to a tendermint rpc server. + Short: "Run lite-client proxy server, verifying teragrid rpc", + Long: `This node will run a secure proxy to a teragrid rpc server. All calls that can be tracked back to a block header by a proof will be verified before passing them back to the caller. Other that -that it will present the same interface as a full tendermint node, +that it will present the same interface as a full teragrid node, just with added trust and running locally.`, RunE: runProxy, SilenceUsage: true, @@ -36,8 +36,8 @@ var ( func init() { LiteCmd.Flags().StringVar(&listenAddr, "laddr", "tcp://localhost:8888", "Serve the proxy on the given address") LiteCmd.Flags().StringVar(&nodeAddr, "node", "tcp://localhost:26657", "Connect to a Teragrid node at this address") - LiteCmd.Flags().StringVar(&chainID, "chain-id", "tendermint", "Specify the Teragrid chain ID") - LiteCmd.Flags().StringVar(&home, "home-dir", ".tendermint-lite", "Specify the home directory") + LiteCmd.Flags().StringVar(&chainID, "chain-id", "teragrid", "Specify the Teragrid chain ID") + LiteCmd.Flags().StringVar(&home, "home-dir", ".teragrid-lite", "Specify the home directory") } func ensureAddrHasSchemeOrDefaultToTCP(addr string) (string, error) { diff --git a/cmd/teragrid/commands/root.go b/cmd/teragrid/commands/root.go index efd0e25..f005ec0 100644 --- a/cmd/teragrid/commands/root.go +++ b/cmd/teragrid/commands/root.go @@ -28,7 +28,7 @@ func init() { func registerFlagsRootCmd(cmd *cobra.Command) { cmd.PersistentFlags().String("log_level", mainConfig.LogLevel, "Log level") - cmd.PersistentFlags().StringP("config", "c", "", "Alternate configuration file to read. Defaults to $HOME/.tendermint/") + cmd.PersistentFlags().StringP("config", "c", "", "Alternate configuration file to read. Defaults to $HOME/.teragrid/") //viper.BindPFlag("ConfigFileName", cmd.PersistentFlags().Lookup("config")) //viper.BindPFlag("Home", cmd.PersistentFlags().Lookup("home")) @@ -90,8 +90,8 @@ func ParseConfig() (*cfg.Config, error) { // RootCmd is the root command for Teragrid core. var RootCmd = &cobra.Command{ - Use: "tendermint", - Short: "Teragrid Core (BFT Consensus) in Go", + Use: "teragrid", + Short: "Teragrid Core (FBA Consensus) in Go", PersistentPreRunE: func(cmd *cobra.Command, args []string) (err error) { if cmd.Name() == VersionCmd.Name() { return nil diff --git a/cmd/teragrid/commands/run_node.go b/cmd/teragrid/commands/run_node.go index a3c8933..f46395c 100644 --- a/cmd/teragrid/commands/run_node.go +++ b/cmd/teragrid/commands/run_node.go @@ -10,7 +10,7 @@ import ( ) // AddNodeFlags exposes some common configuration options on the command-line -// These are exposed for convenience of commands embedding a tendermint node +// These are exposed for convenience of commands embedding a teragrid node func AddNodeFlags(cmd *cobra.Command) { config := mainConfig.ChainConfigs[0] // bind flags @@ -49,7 +49,7 @@ func AddNodeFlags(cmd *cobra.Command) { func NewRunNodeCmd(nodeProvider nm.NodeProvider) *cobra.Command { cmd := &cobra.Command{ Use: "node", - Short: "Run the tendermint node", + Short: "Run the teragrid node", RunE: func(cmd *cobra.Command, args []string) error { //runOneNode(nodeProvider) runNodes(nodeProvider) @@ -127,7 +127,7 @@ func runNodes(nodeProvider nm.NodeProvider) { func NewRunNodeCmd(nodeProvider nm.NodeProvider) *cobra.Command { cmd := &cobra.Command{ Use: "node", - Short: "Run the tendermint node", + Short: "Run the teragrid node", RunE: func(cmd *cobra.Command, args []string) error { // Create & start node n, err := nodeProvider(config, logger) diff --git a/cmd/teragrid/commands/testnet.go b/cmd/teragrid/commands/testnet.go index 77997b5..540c831 100644 --- a/cmd/teragrid/commands/testnet.go +++ b/cmd/teragrid/commands/testnet.go @@ -66,7 +66,7 @@ Optionally, it will fill in persistent_peers list in config file using either ho Example: - tendermint testnet --v 4 --o ./output --populate-persistent-peers --starting-ip-address 192.168.10.2 + teragrid testnet --v 4 --o ./output --populate-persistent-peers --starting-ip-address 192.168.10.2 `, RunE: testnetFiles, } From 5b187591482c41fc6fa625fc5ba9b4157657adea Mon Sep 17 00:00:00 2001 From: vietking Date: Sat, 30 Mar 2019 12:06:18 +0700 Subject: [PATCH 7/7] COR-01: Updated docs for teragrid --- .github/ISSUE_TEMPLATE | 2 +- CODE_OF_CONDUCT.md | 4 +- CONTRIBUTING.md | 2 +- Gopkg.lock | 2 +- README.md | 1 - .../adr-002-event-subscription.md | 2 +- docs/deploy-testnets.rst | 12 +++--- docs/getting-started.rst | 10 ++--- docs/index.rst | 4 +- docs/introduction.rst | 42 +++++++++---------- docs/specification/block-structure.rst | 3 +- lite/doc.go | 2 +- 12 files changed, 41 insertions(+), 45 deletions(-) diff --git a/.github/ISSUE_TEMPLATE b/.github/ISSUE_TEMPLATE index 580816f..542725b 100644 --- a/.github/ISSUE_TEMPLATE +++ b/.github/ISSUE_TEMPLATE @@ -14,7 +14,7 @@ manner. We might ask you to provide additional logs and data (teragrid & app) in a case of bug. --> -**Tendermint version** (use `teragrid version` or `git rev-parse --verify HEAD` if installed from source): +**Teragrid version** (use `teragrid version` or `git rev-parse --verify HEAD` if installed from source): **Asura app** (name for built-in, URL for self-written if it's publicly available): diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 8387117..9fb151f 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -47,10 +47,10 @@ These are the policies for upholding our community’s standards of conduct. If 8. Moderators are held to a higher standard than other community members. If a moderator creates an inappropriate situation, they should expect less leeway than others. -In the Teragrid/COSMOS community we strive to go the extra step to look out for each other. Don’t just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they’re off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. +In the Teragrid community we strive to go the extra step to look out for each other. Don’t just aim to be technically unimpeachable, try to be your best self. In particular, avoid flirting with offensive or sensitive issues, particularly if they’re off-topic; this all too often leads to unnecessary fights, hurt feelings, and damaged trust; worse, it can drive people away from the community entirely. And if someone takes issue with something you said or did, resist the urge to be defensive. Just stop doing what it was they complained about and apologize. Even if you feel you were misinterpreted or unfairly accused, chances are good there was something you could’ve communicated better — remember that it’s your responsibility to make your fellow Cosmonauts comfortable. Everyone wants to get along and we are all here first and foremost because we want to talk about cool technology. You will find that people will be eager to assume good intent and forgive as long as you earn their trust. -The enforcement policies listed above apply to all official Teragrid/COSMOS venues.For other projects adopting the Teragrid/COSMOS Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. +The enforcement policies listed above apply to all official Teragrid venues.For other projects adopting the Teragrid Code of Conduct, please contact the maintainers of those projects for enforcement. If you wish to use this code of conduct for your own project, consider explicitly mentioning your moderation policy or making a copy with your own moderation policy so as to avoid confusion. *Adapted from the [Node.js Policy on Trolling](http://blog.izs.me/post/30036893703/policy-on-trolling), the [Contributor Covenant v1.3.0](http://contributor-covenant.org/version/1/3/0/) and the [Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5d79972..bf92fcb 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -19,7 +19,7 @@ For instance, to create a fork and work on a branch of it, I would: * Create the fork on github, using the fork button. * Go to the original repo checked out locally (ie. `$GOPATH/src/github.com/teragrid/teragrid`) * `git remote rename origin upstream` - * `git remote add origin git@github.com:ebuchman/basecoin.git` + * `git remote add origin git@github.com:ebuchman/teracoin.git` Now `origin` refers to my fork and `upstream` refers to the teragrid version. So I can `git push -u origin master` to update my fork, and make pull requests to teragrid from there. diff --git a/Gopkg.lock b/Gopkg.lock index 869d0bd..299ed3d 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -230,7 +230,7 @@ [[projects]] branch = "master" - name = "github.com/tendermint/ed25519" + name = "github.com/teragrid/ed25519" packages = ["edwards25519"] revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" diff --git a/README.md b/README.md index d715d10..69d8e79 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ Or [Blockchain](https://en.wikipedia.org/wiki/Blockchain_(database)) for short. https://teragrid.network/api/docs )](https://godoc.org/github.com/teragrid/teragrid) [![Go version](https://img.shields.io/badge/go-1.9.2-blue.svg)](https://github.com/moovweb/gvm) -[![Rocket.Chat](https://demo.rocket.chat/images/join-chat.svg)](https://cosmos.rocket.chat/) [![license](https://img.shields.io/github/license/teragrid/teragrid.svg)](https://github.com/teragrid/teragrid/blob/master/LICENSE) [![](https://tokei.rs/b1/github/teragrid/teragrid?category=lines)](https://github.com/teragrid/teragrid) diff --git a/docs/architecture/adr-002-event-subscription.md b/docs/architecture/adr-002-event-subscription.md index a2479ff..e86e863 100644 --- a/docs/architecture/adr-002-event-subscription.md +++ b/docs/architecture/adr-002-event-subscription.md @@ -66,7 +66,7 @@ For historic queries we will need a indexing storage (Postgres, SQLite, ...). ### Issues -- https://github.com/teragrid/basecoin/issues/91 +- https://github.com/teragrid/teracoin/issues/91 - https://github.com/teragrid/teragrid/issues/376 - https://github.com/teragrid/teragrid/issues/287 - https://github.com/teragrid/teragrid/issues/525 (related) diff --git a/docs/deploy-testnets.rst b/docs/deploy-testnets.rst index 16cbb1f..b31c1b6 100644 --- a/docs/deploy-testnets.rst +++ b/docs/deploy-testnets.rst @@ -4,7 +4,7 @@ Deploy a Testnet Now that we've seen how asura works, and even played with a few applications on a single validator node, it's time to deploy a test network to four validator nodes. For this deployment, we'll use the -``basecoin`` application. +``teracoin`` application. Manual Deployments ------------------ @@ -58,17 +58,17 @@ The `terraform-digitalocean tool `__ -allow creating and managing a ``basecoin`` or ``ethermint`` testnet on provisioned servers. +allow creating and managing a ``teracoin`` or ``ethermint`` testnet on provisioned servers. Package Deployment on Linux for developers ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The ``teragrid`` and ``basecoin`` applications can be installed from RPM or DEB packages on +The ``teragrid`` and ``teracoin`` applications can be installed from RPM or DEB packages on Linux machines for development purposes. The packages are configured to be validators on the one-node network that the machine represents. The services are not started after installation, this way giving an opportunity to reconfigure the applications before starting. -The Ansible playbooks in the previous section use this repository to install ``basecoin``. +The Ansible playbooks in the previous section use this repository to install ``teracoin``. After installation, additional steps are executed to make sure that the multi-node testnet has the right configuration before start. @@ -78,7 +78,7 @@ Install from the CentOS/RedHat repository: rpm --import https://teragrid-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-teragrid wget -O /etc/yum.repos.d/teragrid.repo https://teragrid-packages.interblock.io/centos/7/os/x86_64/teragrid.repo - yum install basecoin + yum install teracoin Install from the Debian/Ubuntu repository: @@ -86,5 +86,5 @@ Install from the Debian/Ubuntu repository: wget -O - https://teragrid-packages.interblock.io/centos/7/os/x86_64/RPM-GPG-KEY-teragrid | apt-key add - wget -O /etc/apt/sources.list.d/teragrid.list https://teragrid-packages.interblock.io/debian/teragrid.list - apt-get update && apt-get install basecoin + apt-get update && apt-get install teracoin diff --git a/docs/getting-started.rst b/docs/getting-started.rst index 6f67f63..f567dd5 100644 --- a/docs/getting-started.rst +++ b/docs/getting-started.rst @@ -306,15 +306,15 @@ like before - the results should be the same: Neat, eh? -Basecoin - A More Interesting Example +teracoin - A More Interesting Example ------------------------------------- -We saved the best for last; the `Cosmos SDK `__ is a general purpose framework for building cryptocurrencies. Unlike the ``kvstore`` and ``counter``, which are strictly for example purposes. The reference implementation of Cosmos SDK is ``basecoin``, which demonstrates how to use the building blocks of the Cosmos SDK. +We saved the best for last; the `Blockchain Framework Parkhill `__ is a highly flexible and robust blockchain framework for building blockchain applications. Unlike the ``kvstore`` and ``counter``, which are strictly for example purposes. The reference implementation of Parkhill is ``Teracoin``, which demonstrates how to use the building blocks of Parkhill. -The default ``basecoin`` application is a multi-asset cryptocurrency +The default ``Teracoin`` application is a multi-asset cryptocurrency that supports inter-blockchain communication (IBC). For more details on how -basecoin works and how to use it, see our `basecoin -guide `__ +teracoin works and how to use it, see our `teracoin +guide `__ In this tutorial you learned how to run applications using teragrid on a single node. You saw how applications could be written in different diff --git a/docs/index.rst b/docs/index.rst index 49078b4..52d4cc6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -70,7 +70,7 @@ teragrid 201 * For a deeper dive, see `this thesis `__. * There is also the `original whitepaper `__, though it is now quite outdated. -* Readers might also be interested in the `Cosmos Whitepaper `__ which describes teragrid, asura, and how to build a scalable, heterogeneous, cryptocurrency network. +* Readers might also be interested in the `Teragrid Whitepaper `__ which describes teragrid, asura, and how to build a scalable, heterogeneous, blockchain network. * For example applications and related software built by the teragrid team and other, see the `software ecosystem `__. -Join the `community `__ to ask questions and discuss projects. +Join the `community `__ to ask questions and discuss projects. diff --git a/docs/introduction.rst b/docs/introduction.rst index 2f1464a..16f9fc4 100644 --- a/docs/introduction.rst +++ b/docs/introduction.rst @@ -10,13 +10,13 @@ What is teragrid? teragrid is software for securely and consistently replicating an application on many machines. By securely, we mean that teragrid works even if up to 1/3 of machines fail in arbitrary ways. By consistently, we mean that every non-faulty machine sees the same transaction log and computes the same state. -Secure and consistent replication is a fundamental problem in distributed systems; -it plays a critical role in the fault tolerance of a broad range of applications, +Secure and consistent replication is a fundamental problem in distributed systems; +it plays a critical role in the fault tolerance of a broad range of applications, from currencies, to elections, to infrastructure orchestration, and beyond. The ability to tolerate machines failing in arbitrary ways, including becoming malicious, is known as Byzantine fault tolerance (BFT). The theory of BFT is decades old, but software implementations have only became popular recently, -due largely to the success of "blockchain technology" like Bitcoin and Ethereum. +due largely to the success of "blockchain technology" like Bitcoin and Ethereum. Blockchain technology is just a reformalization of BFT in a more modern setting, with emphasis on peer-to-peer networking and cryptographic authentication. The name derives from the way transactions are batched in blocks, @@ -27,7 +27,7 @@ teragrid consists of two chief technical components: a blockchain consensus engi The consensus engine, called teragrid Core, ensures that the same transactions are recorded on every machine in the same order. The application interface, called the Application BlockChain Interface (asura), enables the transactions to be processed in any programming language. Unlike other blockchain and consensus solutions, which come pre-packaged with built in state machines (like a fancy key-value store, -or a quirky scripting language), developers can use teragrid for BFT state machine replication of applications written in +or a quirky scripting language), developers can use teragrid for BFT state machine replication of applications written in whatever programming language and development environment is right for them. teragrid is designed to be easy-to-use, simple-to-understand, highly performant, and useful @@ -40,16 +40,16 @@ teragrid vs. Other Software ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ teragrid is broadly similar to two classes of software. -The first class consists of distributed key-value stores, +The first class consists of distributed key-value stores, like Zookeeper, etcd, and consul, which use non-BFT consensus. The second class is known as "blockchain technology", -and consists of both cryptocurrencies like Bitcoin and Ethereum, +and consists of both cryptocurrencies like Bitcoin and Ethereum, and alternative distributed ledger designs like Hyperledger's Burrow. Zookeeper, etcd, consul ~~~~~~~~~~~~~~~~~~~~~~~ -Zookeeper, etcd, and consul are all implementations of a key-value store atop a classical, +Zookeeper, etcd, and consul are all implementations of a key-value store atop a classical, non-BFT consensus algorithm. Zookeeper uses a version of Paxos called Zookeeper Atomic Broadcast, while etcd and consul use the Raft consensus algorithm, which is much younger and simpler. A typical cluster contains 3-5 machines, and can tolerate crash failures in up to 1/2 of the machines, @@ -62,7 +62,7 @@ such as dynamic configuration, service discovery, locking, leader-election, and teragrid is in essence similar software, but with two key differences: - It is Byzantine Fault Tolerant, meaning it can only tolerate up to a 1/3 of failures, but those failures can include arbitrary behaviour - including hacking and malicious attacks. -- It does not specify a particular application, like a fancy key-value store. Instead, +- It does not specify a particular application, like a fancy key-value store. Instead, it focuses on arbitrary state machine replication, so developers can build the application logic that's right for them, from key-value store to cryptocurrency to e-voting platform and beyond. @@ -84,17 +84,15 @@ So one can take the current Ethereum code base, whether in Rust, or Go, or Haske using teragrid consensus. Indeed, `we did that with Ethereum `__. And we plan to do the same for Bitcoin, ZCash, and various other deterministic applications as well. -Another example of a cryptocurrency application built on teragrid is `the Cosmos network `__. - Other Blockchain Projects ~~~~~~~~~~~~~~~~~~~~~~~~~ `Fabric `__ takes a similar approach to teragrid, but is more opinionated about how the state is managed, -and requires that all application behaviour runs in potentially many docker containers, modules it calls "chaincode". +and requires that all application behaviour runs in potentially many docker containers, modules it calls "chaincode". It uses an implementation of `PBFT `__. -from a team at IBM that is +from a team at IBM that is `augmented to handle potentially non-deterministic chaincode `__ -It is possible to implement this docker-based behaviour as a asura app in teragrid, +It is possible to implement this docker-based behaviour as a asura app in teragrid, though extending teragrid to handle non-determinism remains for future work. `Burrow `__ is an implementation of the Ethereum Virtual Machine and Ethereum transaction mechanics, @@ -125,10 +123,10 @@ Thus we have an interface, the Application BlockChain Interface (asura), and its Intro to asura ~~~~~~~~~~~~~ -`teragrid Core `__ (the "consensus engine") communicates with the application via a socket protocol that +`teragrid Core `__ (the "consensus engine") communicates with the application via a socket protocol that satisfies the `asura `__. -To draw an analogy, lets talk about a well-known cryptocurrency, Bitcoin. Bitcoin is a cryptocurrency blockchain where each node maintains a fully audited Unspent Transaction Output (UTXO) database. If one wanted to create a Bitcoin-like system on top of asura, teragrid Core would be responsible for +To draw an analogy, lets talk about a well-known cryptocurrency, Bitcoin. Bitcoin is a cryptocurrency blockchain where each node maintains a fully audited Unspent Transaction Output (UTXO) database. If one wanted to create a Bitcoin-like system on top of asura, teragrid Core would be responsible for - Sharing blocks and transactions between nodes - Establishing a canonical/immutable order of transactions (the blockchain) @@ -195,7 +193,7 @@ There is a picture of a couple doing the polka because validators are doing some When more than two-thirds of the validators pre-vote for the same block, we call that a **polka**. Every pre-commit must be justified by a polka in the same round. -Validators may fail to commit a block for a number of reasons; +Validators may fail to commit a block for a number of reasons; the current proposer may be offline, or the network may be slow. teragrid allows them to establish that a validator should be skipped. Validators wait a small amount of time to receive a complete proposal block from the proposer before voting to move to the next round. @@ -206,7 +204,7 @@ A simplifying element of teragrid is that it uses the same mechanism to commit a Assuming less than one-third of the validators are Byzantine, teragrid guarantees that safety will never be violated - that is, validators will never commit conflicting blocks at the same height. To do this it introduces a few **locking** rules which modulate which paths can be followed in the flow diagram. Once a validator precommits a block, it is locked on that block. -Then, +Then, 1) it must prevote for the block it is locked on 2) it can only unlock, and precommit for a new block, if there is a polka for that block in a later round @@ -214,17 +212,17 @@ Then, Stake ----- -In many systems, not all validators will have the same "weight" in the consensus protocol. -Thus, we are not so much interested in one-third or two-thirds of the validators, but in those proportions of the total voting power, +In many systems, not all validators will have the same "weight" in the consensus protocol. +Thus, we are not so much interested in one-third or two-thirds of the validators, but in those proportions of the total voting power, which may not be uniformly distributed across individual validators. Since teragrid can replicate arbitrary applications, it is possible to define a currency, and denominate the voting power in that currency. When voting power is denominated in a native currency, the system is often referred to as Proof-of-Stake. -Validators can be forced, by logic in the application, +Validators can be forced, by logic in the application, to "bond" their currency holdings in a security deposit that can be destroyed if they're found to misbehave in the consensus protocol. -This adds an economic element to the security of the protocol, allowing one to quantify the cost of violating the assumption that less than one-third of voting power is Byzantine. +This adds an economic element to the security of the protocol, allowing one to quantify the cost of violating the assumption that less than one-third of voting power is Byzantine. -The `Cosmos Network `__ is designed to use this Proof-of-Stake mechanism across an array of cryptocurrencies implemented as asura applications. +The `Teragrid Network `__ is designed to use this Proof-of-Stake mechanism across an array of cryptocurrencies implemented as asura applications. The following diagram is teragrid in a (technical) nutshell. `See here for high resolution version `__. diff --git a/docs/specification/block-structure.rst b/docs/specification/block-structure.rst index 6f49acd..dcedcf9 100644 --- a/docs/specification/block-structure.rst +++ b/docs/specification/block-structure.rst @@ -97,8 +97,7 @@ If you look at the code, you will notice that we need to provide the This is to protect anyone from swapping votes between chains to fake (or frame) a validator. Also note that this ``chainID`` is in the ``genesis.json`` from *teragrid*, not the ``genesis.json`` from the -basecoin app (`that is a different -chainID... `__). +teracoin app. Once we have those votes, and we calculated the proper `sign bytes `__ diff --git a/lite/doc.go b/lite/doc.go index 676499a..687b58f 100644 --- a/lite/doc.go +++ b/lite/doc.go @@ -18,7 +18,7 @@ that does this for you, so you can just build nice UI. We design for clients who have no strong trust relationship with any teragrid node, just the validator set as a whole. Beyond building nice mobile or desktop applications, the -cosmos hub is another important example of a client, +BaseLeague is another important example of a client, that needs undeniable proof without syncing the full chain, in order to efficiently implement IBC.