diff --git a/cmd/serve.go b/cmd/serve.go index f943c7053139695a9bd403fcf67b6b80c569a374..0864d4b04ae9d977f7ce52e32aa9dd19c58f29b8 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -112,7 +112,7 @@ func Serve(cmd *cobra.Command, args []string) { } fmt.Printf("Consensus %s, App %s\n", consensusConfig.Version, managerConfig.Version) - + core.NewCore(do.ChainId, consensusConfig, managerConfig) } diff --git a/config/module.go b/config/module.go index 7fe8ef19b65f662638f94d034ba8324581cc134b..1590af2015cd7ba752b055c13a7bc7c454a77f89 100644 --- a/config/module.go +++ b/config/module.go @@ -27,5 +27,7 @@ type ModuleConfig struct { Version string WorkDir string DataDir string + RootDir string + ChainId string Config *viper.Viper } diff --git a/consensus/consensus.go b/consensus/consensus.go new file mode 100644 index 0000000000000000000000000000000000000000..cc81aa48c618f4c70e8e88caf7ded09b3a5a655e --- /dev/null +++ b/consensus/consensus.go @@ -0,0 +1,46 @@ +// Copyright 2015, 2016 Eris Industries (UK) Ltd. +// This file is part of Eris-RT + +// Eris-RT is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Eris-RT is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Eris-RT. If not, see <http://www.gnu.org/licenses/>. + +package consensus + +import ( + config "github.com/eris-ltd/eris-db/config" + + tendermint "github.com/eris-ltd/eris-db/consensus/tendermint" +) + +type ConsensusEngine struct { + // + Communicator + + // application manager + +} + +func NewConsensusEngine(moduleConfig *config.ModuleConfig) { + tendermint.NewTendermintNode(moduleConfig) +} + +type Communicator interface { + // Unicast() + Broadcast() +} + +type ConsensusModule interface { + Start() +} + +// func (consensusEngine *ConsensusEngine) setCommunicator (communicator *) diff --git a/consensus/tendermint/config.go b/consensus/tendermint/config.go index 2269edb45408e5ccee0b49cf54d91d3b2a742791..d4c080e94a5ddcb2b21d13a5e5971333568c14a3 100644 --- a/consensus/tendermint/config.go +++ b/consensus/tendermint/config.go @@ -21,6 +21,7 @@ package tendermint import ( "time" + "path" tendermintConfig "github.com/tendermint/go-config" viper "github.com/spf13/viper" @@ -40,6 +41,56 @@ type TendermintConfig struct { subTree *viper.Viper } +func GetTendermintConfig(loadedConfig *viper.Viper) *TendermintConfig { + // ensure we make an explicit copy + subTree := new(viper.Viper) + *subTree = *loadedConfig + + return &TendermintConfig { + subTree : subTree, + } +} + +//------------------------------------------------------------------------------ +// Tendermint defaults + +func (tmintConfig *TendermintConfig) AssertTendermintDefaults(chainId, workDir, + dataDir, rootDir string) { + + tmintConfig.Set("chain_id", chainId) + tmintConfig.SetDefault("genesis_file", path.Join(rootDir, "genesis.json")) + tmintConfig.SetDefault("proxy_app", "tcp://127.0.0.1:46658") + tmintConfig.SetDefault("moniker", "anonymous_marmot") + tmintConfig.SetDefault("node_laddr", "0.0.0.0:46656") + tmintConfig.SetDefault("seeds", "") + + tmintConfig.SetDefault("fast_sync", true) + tmintConfig.SetDefault("skip_upnp", false) + tmintConfig.SetDefault("addrbook_file", path.Join(rootDir, "addrbook.json")) + tmintConfig.SetDefault("priv_validator_file", path.Join(rootDir, "priv_validator.json")) + tmintConfig.SetDefault("db_backend", "leveldb") + tmintConfig.SetDefault("db_dir", dataDir) + tmintConfig.SetDefault("log_level", "info") + tmintConfig.SetDefault("rpc_laddr", "0.0.0.0:46657") + tmintConfig.SetDefault("prof_laddr", "") + tmintConfig.SetDefault("revision_file", path.Join(workDir,"revision")) + tmintConfig.SetDefault("cswal", path.Join(dataDir, "cswal")) + tmintConfig.SetDefault("cswal_light", false) + + tmintConfig.SetDefault("block_size", 10000) + tmintConfig.SetDefault("disable_data_hash", false) + tmintConfig.SetDefault("timeout_propose", 3000) + tmintConfig.SetDefault("timeout_propose_delta", 500) + tmintConfig.SetDefault("timeout_prevote", 1000) + tmintConfig.SetDefault("timeout_prevote_delta", 500) + tmintConfig.SetDefault("timeout_precommit", 1000) + tmintConfig.SetDefault("timeout_precommit_delta", 500) + tmintConfig.SetDefault("timeout_commit", 1000) + tmintConfig.SetDefault("mempool_recheck", true) + tmintConfig.SetDefault("mempool_recheck_empty", true) + tmintConfig.SetDefault("mempool_broadcast", true) +} + // implement interface github.com/tendermint/go-config/config.Config // so that `TMROOT` and config can be circumvented func (tmintConfig *TendermintConfig) Get(key string) interface{} { diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go new file mode 100644 index 0000000000000000000000000000000000000000..79cdd937728cf9ae0ec5eb98112ebbdf0496f5d6 --- /dev/null +++ b/consensus/tendermint/tendermint.go @@ -0,0 +1,77 @@ +// Copyright 2015, 2016 Eris Industries (UK) Ltd. +// This file is part of Eris-RT + +// Eris-RT is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Eris-RT is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Eris-RT. If not, see <http://www.gnu.org/licenses/>. + +// version provides the current Eris-DB version and a VersionIdentifier +// for the modules to identify their version with. + +package tendermint + +import ( + "fmt" + + node "github.com/tendermint/tendermint/node" + + config "github.com/eris-ltd/eris-db/config" + // files "github.com/eris-ltd/eris-db/files" +) + +type TendermintNode struct { + tmintNode *node.Node +} + +func NewTendermintNode(moduleConfig *config.ModuleConfig) (*TendermintConfig, error) { + // re-assert proper configuration for module + if moduleConfig.Version != GetTendermintVersion().GetMinorVersionString() { + return nil, fmt.Errorf("Version string %s did not match %s", + moduleConfig.Version, GetTendermintVersion().GetMinorVersionString()) + } + // loading the module has ensured the working and data directory + // for tendermint have been created, but the config files needs + // to be written in tendermint's root directory. + // NOTE: [ben] as elsewhere Sub panics if config file does not have this + // subtree. To shield in go-routine, or PR to viper. + tendermintConfigViper := moduleConfig.Config.Sub("configuration") + if tendermintConfigViper == nil { + return nil, fmt.Errorf("Failed to extract Tendermint configuration subtree.") + } + // wrap a copy of the viper config in a tendermint/go-config interface + tmintConfig := GetTendermintConfig(tendermintConfigViper) + tmintConfig.AssertTendermintDefaults(moduleConfig.ChainId, + moduleConfig.WorkDir, moduleConfig.DataDir, moduleConfig.RootDir) + fmt.Printf("Moniker is %s", tmintConfig.GetString("moniker")) + + // newNode := node.NewNode() + // return &TendermintNode{ + // node: newNode, + // } + return nil, fmt.Errorf("PLACEHOLDER") +} + + +//------------------------------------------------------------------------------ +// Helper functions + +// func marshalConfigToDisk(filePath string, tendermintConfig *viper.Viper) error { +// +// tendermintConfig.Unmarshal +// // marshal interface to toml bytes +// bytesConfig, err := toml.Marshal(tendermintConfig) +// if err != nil { +// return fmt.Fatalf("Failed to marshal Tendermint configuration to bytes: %v", +// err) +// } +// return files.WriteAndBackup(filePath, bytesConfig) +// } diff --git a/core/config.go b/core/config.go index ed71d737435270f90d99f8a16919b8ec68bf2012..fb76fc24ce51ef66023486635100a58bccbdaa85 100644 --- a/core/config.go +++ b/core/config.go @@ -33,37 +33,37 @@ import ( ) // LoadConsensusModuleConfig wraps specifically for the consensus module -func LoadConsensusModuleConfig(do *definitions.Do) (config.ModuleConfig, error) { +func LoadConsensusModuleConfig(do *definitions.Do) (*config.ModuleConfig, error) { return loadModuleConfig(do, "consensus") } // LoadApplicationManagerModuleConfig wraps specifically for the application // manager -func LoadApplicationManagerModuleConfig(do *definitions.Do) (config.ModuleConfig, error) { +func LoadApplicationManagerModuleConfig(do *definitions.Do) (*config.ModuleConfig, error) { return loadModuleConfig(do, "manager") } // Generic Module loader for configuration information -func loadModuleConfig(do *definitions.Do, module string) (config.ModuleConfig, error) { +func loadModuleConfig(do *definitions.Do, module string) (*config.ModuleConfig, error) { moduleName := do.Config.GetString("chain." + module + ".name") majorVersion := do.Config.GetInt("chain." + module + ".major_version") minorVersion := do.Config.GetInt("chain." + module + ".minor_version") minorVersionString := version.MakeMinorVersionString(moduleName, majorVersion, minorVersion, 0) if !assertValidModule(module, moduleName, minorVersionString) { - return config.ModuleConfig{}, fmt.Errorf("%s module %s (%s) is not supported by %s", + return nil, fmt.Errorf("%s module %s (%s) is not supported by %s", module, moduleName, minorVersionString, version.GetVersionString()) } // set up the directory structure for the module inside the data directory workDir := path.Join(do.DataDir, do.Config.GetString("chain." + module + ".relative_root")) if err := util.EnsureDir(workDir, os.ModePerm); err != nil { - return config.ModuleConfig{}, + return nil, fmt.Errorf("Failed to create module root directory %s.", workDir) } dataDir := path.Join(workDir, "data") if err := util.EnsureDir(dataDir, os.ModePerm); err != nil { - return config.ModuleConfig{}, + return nil, fmt.Errorf("Failed to create module data directory %s.", dataDir) } // load configuration subtree for module @@ -72,16 +72,18 @@ func loadModuleConfig(do *definitions.Do, module string) (config.ModuleConfig, e // and recovered from or a PR to viper is needed to address this bug. subConfig := do.Config.Sub(moduleName) if subConfig == nil { - return config.ModuleConfig{}, + return nil, fmt.Errorf("Failed to read configuration section for %s.", moduleName) } - return config.ModuleConfig { + return &config.ModuleConfig { Module : module, Name : moduleName, Version : minorVersionString, WorkDir : workDir, DataDir : dataDir, + RootDir : do.WorkDir, // Eris-DB's working directory + ChainId : do.ChainId, Config : subConfig, }, nil } diff --git a/core/core.go b/core/core.go new file mode 100644 index 0000000000000000000000000000000000000000..7f422e82825deb6766051ed5ea5fe54b9cf37a85 --- /dev/null +++ b/core/core.go @@ -0,0 +1,44 @@ +// Copyright 2015, 2016 Eris Industries (UK) Ltd. +// This file is part of Eris-RT + +// Eris-RT is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// Eris-RT is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with Eris-RT. If not, see <http://www.gnu.org/licenses/>. + +package core + +import ( + config "github.com/eris-ltd/eris-db/config" + consensus "github.com/eris-ltd/eris-db/consensus" +) + +// Core is the high-level structure +type Core struct { + chainId string + // pipe Pipe +} + +func NewCore(chainId string, consensusConfig *config.ModuleConfig, + managerConfig *config.ModuleConfig) *Core { + + consensus.NewConsensusEngine(consensusConfig) + + // create state + // from genesis + // create event switch + // give state and evsw to app + // give app to consensus + // create new Pipe + // give app + // create servers + return &Core{} +} diff --git a/server_config.toml b/server_config.toml index c3b17a9196db9da6ed0b7fd462624ac29e00a26b..6d04451f1c88ffa0473a91f3e3ef9b1f9e1a4ef8 100644 --- a/server_config.toml +++ b/server_config.toml @@ -104,21 +104,58 @@ listener = "tcp://0.0.0.0:46658" ################################################################################ [tendermint] -# Tendermint requires an external configuration file present on disk -# in the tendermint root directory. -# Eris-DB's tendermint consensus module will copy this configuration file from -# the Eris-DB working directory to the Tendermint working directory -# as `config.toml`. -# Eris-DB will respect the configurations set in this file where applicable, -# but reserves the option to override or block conflicting settings. -configuration_file = "tendermint_config.toml" -# -genesis_file = "genesis.json" -# -genesis_ -addressbook_file = "addrbook.json" -private_validator_file = "priv_validator.json" - + # Tendermint requires additional configuration parameters. + # Eris-DB's tendermint consensus module will load [tendermint.configuration] + # as the configuration for Tendermint. + # Eris-DB will respect the configurations set in this file where applicable, + # but reserves the option to override or block conflicting settings. + [tendermint.configuration] + # moniker is the name of the node on the tendermint p2p network + moniker = "anonymous_marmot" + # seeds lists the peers tendermint can connect to join the network + seeds = "" + # fast_sync allows a tendermint node to catch up faster when joining + # the network. + # NOTE: Tendermint has reported potential issues with fast_sync enabled. + # The recommended setting is for keeping it disabled. + fast_sync = false + # database backend to use for Tendermint. Supported `leveldb` and `memdb`. + db_backend = "leveldb" + # logging level. Suppored `debug`, `notice`, `info` [ben: incomplete, see Tendermint] + log_level = "notice" + # node local address + node_laddr = "0.0.0.0:46656" + # rpc local address + rpc_laddr = "0.0.0.0:46657" + # proxy application address - used for tmsp connections, + # and this port should not be exposed for in-process Tendermint + proxy_app = "tcp://127.0.0.1:46658" + + # Extended Tendermint configuration settings + # for reference to Tendermint see https://github.com/tendermint/tendermint/blob/master/config/tendermint/config.go + + # genesis_file = "./data/tendermint/genesis.json" + # skip_upnp = false + # addrbook_file = "./data/tendermint/addrbook.json" + # priv_validator_file = "./data/tendermint/priv_validator.json" + # db_dir = "./data/tendermint/data" + # prof_laddr = "" + # revision_file = "./data/tendermint/revision" + # cswal = "./data/tendermint/data/cswal" + # cswal_light = false + + # block_size = 10000 + # disable_data_hash = false + # timeout_propose = 3000 + # timeout_propose_delta = 500 + # timeout_prevote = 1000 + # timeout_prevote_delta = 500 + # timeout_precommit = 1000 + # timeout_precommit_delta = 500 + # timeout_commit = 1000 + # mempool_recheck = true + # mempool_recheck_empty = true + # mempool_broadcast = true ################################################################################ ## diff --git a/tendermint_config.toml b/tendermint_config.toml deleted file mode 100644 index e7eda22c2bd090fedc08f201356a7398f2bb5fee..0000000000000000000000000000000000000000 --- a/tendermint_config.toml +++ /dev/null @@ -1,71 +0,0 @@ -# Copyright 2015, 2016 Eris Industries (UK) Ltd. -# This file is part of Eris-RT -# -# Eris-RT is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Eris-RT is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Eris-RT. If not, see <http://www.gnu.org/licenses/>. - -# This is a TOML configuration for Tendermint consensus for Eris-DB chains - -################################################################################ -## -## Tendermint -## version 0.6.0 -## -################################################################################ - -# moniker is the name of the node on the tendermint p2p network -moniker = "anonymous_marmot" -# seeds lists the peers tendermint can connect to join the network -seeds = "" -# fast_sync allows a tendermint node to catch up faster when joining -# the network. -# NOTE: Tendermint has reported potential issues with fast_sync enabled. -# The recommended setting is for keeping it disabled. -fast_sync = false -# database backend to use for Tendermint. Supported `leveldb` and `memdb`. -db_backend = "leveldb" -# logging level. Suppored `debug`, `notice`, `info` [ben: incomplete, see Tendermint] -log_level = "notice" -# node local address -node_laddr = "0.0.0.0:46656" -# rpc local address -rpc_laddr = "0.0.0.0:46657" -# proxy application address - used for tmsp connections, -# and this port should not be exposed for in-process Tendermint -proxy_app = "tcp://127.0.0.1:46658" - -# Extended Tendermint configuration settings -# for reference to Tendermint see https://github.com/tendermint/tendermint/blob/master/config/tendermint/config.go - -# genesis_file = "./data/tendermint/genesis.json" -# skip_upnp = false -# addrbook_file = "./data/tendermint/addrbook.json" -# priv_validator_file = "./data/tendermint/priv_validator.json" -# db_dir = "./data/tendermint/data" -# prof_laddr = "" -# revision_file = "./data/tendermint/revision" -# cswal = "./data/tendermint/data/cswal" -# cswal_light = false - -# block_size = 10000 -# disable_data_hash = false -# timeout_propose = 3000 -# timeout_propose_delta = 500 -# timeout_prevote = 1000 -# timeout_prevote_delta = 500 -# timeout_precommit = 1000 -# timeout_precommit_delta = 500 -# timeout_commit = 1000 -# mempool_recheck = true -# mempool_recheck_empty = true -# mempool_broadcast = true