diff --git a/cmd/serve.go b/cmd/serve.go index 4adf175efa3b42caf6be2e5dd62d7d554e1d0194..b99ae99c21c295b8b819df7bf4b566bce9874b56 100644 --- a/cmd/serve.go +++ b/cmd/serve.go @@ -91,9 +91,9 @@ func Serve(cmd *cobra.Command, args []string) { os.Exit(1) } // load the genesis file path - if do.GenesisFile = path.Join(do.WorkDir, - do.Config.GetString("chain.genesis_file")); - do.GenesisFile == "" { + do.GenesisFile = path.Join(do.WorkDir, + do.Config.GetString("chain.genesis_file")) + if do.Config.GetString("chain.genesis_file") == "" { log.Fatalf("Failed to read non-empty string for genesis file from config.") os.Exit(1) } @@ -124,7 +124,10 @@ func Serve(cmd *cobra.Command, args []string) { "consensusModule": consensusConfig.Version, "applicationManager": managerConfig.Version, }).Debug("Modules configured") - core.NewCore(do.ChainId, do.GenesisFile, consensusConfig, managerConfig) + _, err = core.NewCore(do.ChainId, consensusConfig, managerConfig) + if err != nil { + log.Fatalf("Failed to load core: %s", err) + } } //------------------------------------------------------------------------------ diff --git a/consensus/consensus.go b/consensus/consensus.go index 2c5a48d6b68d9935d9f3abcfa7eb86587d1e7025..cb1a4fc77f951146e18fd3759a1d6533bf796d51 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -35,7 +35,10 @@ func LoadConsensusEngineInPipe(moduleConfig *config.ModuleConfig, pipe definitions.Pipe) error { switch moduleConfig.Name { case "tendermint" : - tendermint.NewTendermintNode(moduleConfig, nil) + _, err := tendermint.NewTendermintNode(moduleConfig, pipe.GetApplication()) + if err != nil { + return err + } } return nil } diff --git a/consensus/tendermint/config.go b/consensus/tendermint/config.go index 9d840ab308a3f8eda4ed7a489d0cfed57c883042..54ee9034e8a78b924b3f26692af18781a247e81d 100644 --- a/consensus/tendermint/config.go +++ b/consensus/tendermint/config.go @@ -20,8 +20,8 @@ package tendermint import ( - "time" "path" + "time" tendermintConfig "github.com/tendermint/go-config" viper "github.com/spf13/viper" @@ -97,15 +97,12 @@ func (tmintConfig *TendermintConfig) AssertTendermintDefaults(chainId, workDir, // Tendermint consistency checks func(tmintConfig *TendermintConfig) AssertTendermintConsistency( - consensusConfig *config.ModuleConfig) { + consensusConfig *config.ModuleConfig, privateValidatorFilePath string) { tmintConfig.Set("chain_id", consensusConfig.ChainId) tmintConfig.Set("genesis_file", consensusConfig.GenesisFile) // private validator file - if consensusConfig.Config.IsSet("private_validator_file") { - tmintConfig.Set("priv_validator_file", - consensusConfig.Config.GetString("priv_validator_file")) - } + tmintConfig.Set("priv_validator_file", privateValidatorFilePath) } // implement interface github.com/tendermint/go-config/config.Config diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go index ae9a3c39a0a043f13c8486d31056b621f2644a28..fbdf94f3bb47b1df56cbc6c6101bb35addf71b98 100644 --- a/consensus/tendermint/tendermint.go +++ b/consensus/tendermint/tendermint.go @@ -22,21 +22,28 @@ package tendermint import ( "fmt" "path" + "strings" + "sync" node "github.com/tendermint/tendermint/node" + proxy "github.com/tendermint/tendermint/proxy" + p2p "github.com/tendermint/go-p2p" tendermint_types "github.com/tendermint/tendermint/types" + log "github.com/eris-ltd/eris-logger" + config "github.com/eris-ltd/eris-db/config" manager_types "github.com/eris-ltd/eris-db/manager/types" // files "github.com/eris-ltd/eris-db/files" ) type TendermintNode struct { - tmintNode *node.Node + tmintNode *node.Node + tmintConfig *TendermintConfig } func NewTendermintNode(moduleConfig *config.ModuleConfig, - applicaton *manager_types.Application) (*TendermintNode, error) { + application manager_types.Application) (*TendermintNode, error) { // re-assert proper configuration for module if moduleConfig.Version != GetTendermintVersion().GetMinorVersionString() { return nil, fmt.Errorf("Version string %s did not match %s", @@ -57,24 +64,70 @@ func NewTendermintNode(moduleConfig *config.ModuleConfig, // complete the tendermint configuration with default flags tmintConfig.AssertTendermintDefaults(moduleConfig.ChainId, moduleConfig.WorkDir, moduleConfig.DataDir, moduleConfig.RootDir) + + privateValidatorFilePath := path.Join(moduleConfig.RootDir, + moduleConfig.Config.GetString("private_validator_file")) + if moduleConfig.Config.GetString("private_validator_file") == "" { + return nil, fmt.Errorf("No private validator file provided.") + } // override tendermint configurations to force consistency with overruling // settings - tmintConfig.AssertTendermintConsistency(moduleConfig) - + tmintConfig.AssertTendermintConsistency(moduleConfig, + privateValidatorFilePath) + log.WithFields(log.Fields{ + "chainId": tmintConfig.GetString("chain_id"), + "genesisFile": tmintConfig.GetString("genesis_file"), + "nodeLocalAddress": tmintConfig.GetString("node_laddr"), + "moniker": tmintConfig.GetString("moniker"), + "seeds": tmintConfig.GetString("seeds"), + "fastSync": tmintConfig.GetBool("fast_sync"), + "rpcLocalAddress": tmintConfig.GetString("rpc_laddr"), + "databaseDirectory": tmintConfig.GetString("db_dir"), + "privateValidatorFile": tmintConfig.GetString("priv_validator_file"), + "privValFile": moduleConfig.Config.GetString("private_validator_file"), + }).Debug("Loaded Tendermint sub-configuration") // TODO: [ben] do not "or Generate Validator keys", rather fail directly // TODO: [ben] implement the signer for Private validator over eris-keys // TODO: [ben] copy from rootDir to tendermint workingDir; privateValidator := tendermint_types.LoadOrGenPrivValidator( path.Join(moduleConfig.RootDir, moduleConfig.Config.GetString("private_validator_file"))) - fmt.Printf("priv: %s", privateValidator.Address) - // newNode := node.NewNode(tmintConfig, ) - - // newNode := node.NewNode() - // return &TendermintNode{ - // node: newNode, - // } - return nil, fmt.Errorf("PLACEHOLDER") + + newNode := node.NewNode(tmintConfig, privateValidator, func(addr string, + hash []byte) proxy.AppConn { + return NewLocalClient(new(sync.Mutex), application) + }) + + listener := p2p.NewDefaultListener("tcp", tmintConfig.GetString("node_laddr"), + tmintConfig.GetBool("skip_upnp")) + + newNode.AddListener(listener) + // TODO: [ben] delay starting the node to a different function, to hand + // control over events to Core + if err := newNode.Start(); err != nil { + newNode.Stop() + return nil, fmt.Errorf("Failed to start Tendermint consensus node: %v", err) + } + log.WithFields(log.Fields{ + "nodeAddress": tmintConfig.GetString("node_laddr"), + "transportProtocol": "tcp", + "upnp": !tmintConfig.GetBool("skip_upnp"), + "moniker": tmintConfig.GetString("moniker"), + }).Info("Tendermint consensus node started") + + // If seedNode is provided by config, dial out. + if tmintConfig.GetString("seeds") != "" { + seeds := strings.Split(tmintConfig.GetString("seeds"), ",") + newNode.DialSeeds(seeds) + log.WithFields(log.Fields{ + "seeds": seeds, + }).Debug("Tendermint node called seeds") + } + + return &TendermintNode{ + tmintNode: newNode, + tmintConfig: tmintConfig, + }, nil } diff --git a/core/core.go b/core/core.go index ed17d3412911468b8f24b362f88e2b0d4b71afe2..fc0941e45a2597d73e97b1f890d41d567ac2ff98 100644 --- a/core/core.go +++ b/core/core.go @@ -22,6 +22,8 @@ import ( // TODO: [ben] swap out go-events with eris-db/event (currently unused) events "github.com/tendermint/go-events" + log "github.com/eris-ltd/eris-logger" + config "github.com/eris-ltd/eris-db/config" consensus "github.com/eris-ltd/eris-db/consensus" definitions "github.com/eris-ltd/eris-db/definitions" @@ -35,19 +37,19 @@ type Core struct { pipe definitions.Pipe } -func NewCore(chainId, genesisFile string, consensusConfig *config.ModuleConfig, +func NewCore(chainId string, consensusConfig *config.ModuleConfig, managerConfig *config.ModuleConfig) (*Core, error) { - // start new event switch, TODO: [ben] replace with eris-db/event evsw := events.NewEventSwitch() evsw.Start() // start a new application pipe that will load an application manager pipe, err := manager.NewApplicationPipe(managerConfig, evsw, - consensusConfig.Version, genesisFile) + consensusConfig.Version) if err != nil { - return nil, fmt.Errorf("PLACEHOLDER") + return nil, fmt.Errorf("Failed to load application pipe: %v", err) } + log.Debug("Loaded pipe with application manager") // pass the consensus engine into the pipe consensus.LoadConsensusEngineInPipe(consensusConfig, pipe) diff --git a/definitions/pipe.go b/definitions/pipe.go index cfd02e713d0c7f94854effbac4ffd2a01e8da1fd..cb6df44fa061dcab35c0fcbce5260808f1903dae 100644 --- a/definitions/pipe.go +++ b/definitions/pipe.go @@ -28,9 +28,10 @@ import ( events "github.com/tendermint/go-events" tendermint_types "github.com/tendermint/tendermint/types" - account "github.com/eris-ltd/eris-db/account" - transaction "github.com/eris-ltd/eris-db/txs" - types "github.com/eris-ltd/eris-db/core/types" + account "github.com/eris-ltd/eris-db/account" + manager_types "github.com/eris-ltd/eris-db/manager/types" + transaction "github.com/eris-ltd/eris-db/txs" + types "github.com/eris-ltd/eris-db/core/types" ) type Pipe interface { @@ -41,6 +42,8 @@ type Pipe interface { NameReg() NameReg Net() Net Transactor() Transactor + // NOTE: [ben] added to Pipe interface on 0.12 refactor + GetApplication() manager_types.Application } type Accounts interface { diff --git a/manager/eris-mint/pipe.go b/manager/eris-mint/pipe.go index ffcf920945a534c959285c8ca0f36fb6573984f0..ecb8ccd3769b37cab42e75b34005b54d74ce7eec 100644 --- a/manager/eris-mint/pipe.go +++ b/manager/eris-mint/pipe.go @@ -26,10 +26,11 @@ import ( log "github.com/eris-ltd/eris-logger" - config "github.com/eris-ltd/eris-db/config" - definitions "github.com/eris-ltd/eris-db/definitions" - state "github.com/eris-ltd/eris-db/manager/eris-mint/state" - state_types "github.com/eris-ltd/eris-db/manager/eris-mint/state/types" + config "github.com/eris-ltd/eris-db/config" + definitions "github.com/eris-ltd/eris-db/definitions" + manager_types "github.com/eris-ltd/eris-db/manager/types" + state "github.com/eris-ltd/eris-db/manager/eris-mint/state" + state_types "github.com/eris-ltd/eris-db/manager/eris-mint/state/types" ) type ErisMintPipe struct { @@ -46,17 +47,25 @@ type ErisMintPipe struct { transactor definitions.Transactor } +// NOTE [ben] Compiler check to ensure ErisMintPipe successfully implements +// eris-db/definitions.Pipe +var _ definitions.Pipe = (*ErisMintPipe)(nil) + func NewErisMintPipe(moduleConfig *config.ModuleConfig, - genesisFile string, eventSwitch *tendermint_events.EventSwitch) (*ErisMintPipe, error) { + eventSwitch *tendermint_events.EventSwitch) (*ErisMintPipe, error) { startedState, err := startState(moduleConfig.DataDir, - moduleConfig.Config.GetString("db_backend"), genesisFile, + moduleConfig.Config.GetString("db_backend"), moduleConfig.GenesisFile, moduleConfig.ChainId) if err != nil { return nil, fmt.Errorf("Failed to start state: %v", err) } // assert ChainId matches genesis ChainId - + log.WithFields(log.Fields{ + "chainId": startedState.ChainID, + "lastBlockHeight": startedState.LastBlockHeight, + "lastBlockHash": startedState.LastBlockHash, + }).Debug("Loaded state") // start the application erisMint := NewErisMint(startedState, eventSwitch) @@ -64,8 +73,8 @@ func NewErisMintPipe(moduleConfig *config.ModuleConfig, // of the old Eris-DB / Tendermint and should be considered as an in-process // call when possible tendermintHost := moduleConfig.Config.GetString("tendermint_host") - log.Debug("Starting ErisMint RPC client to Tendermint host on %s", - tendermintHost) + log.Debug(fmt.Sprintf("Starting ErisMint RPC client to Tendermint host on %s", + tendermintHost)) erisMint.SetHostAddress(tendermintHost) // initialise the components of the pipe @@ -166,3 +175,7 @@ func (pipe *ErisMintPipe) Net() definitions.Net { func (pipe *ErisMintPipe) Transactor() definitions.Transactor { return pipe.transactor } + +func (pipe *ErisMintPipe) GetApplication() manager_types.Application { + return pipe.erisMint +} diff --git a/manager/manager.go b/manager/manager.go index b7e34fe79a3db1e075756c7ca042a02b3ae696cb..44a3b5dfb6627d3ae693a3a38f58c2f885de0e40 100644 --- a/manager/manager.go +++ b/manager/manager.go @@ -21,6 +21,8 @@ import ( events "github.com/tendermint/go-events" + log "github.com/eris-ltd/eris-logger" + config "github.com/eris-ltd/eris-db/config" definitions "github.com/eris-ltd/eris-db/definitions" erismint "github.com/eris-ltd/eris-db/manager/eris-mint" @@ -33,15 +35,19 @@ import ( // of an application. It is feasible this will be insufficient to support // different types of applications later down the line. func NewApplicationPipe(moduleConfig *config.ModuleConfig, - evsw *events.EventSwitch, consensusMinorVersion, - genesisFile string) (definitions.Pipe, error) { + evsw *events.EventSwitch, consensusMinorVersion string) (definitions.Pipe, + error) { switch moduleConfig.Name { case "erismint" : if err := erismint.AssertCompatibleConsensus(consensusMinorVersion); err != nil { return nil, err } - return erismint.NewErisMintPipe(moduleConfig, genesisFile, evsw) + log.WithFields(log.Fields{ + "compatibleConsensus": consensusMinorVersion, + "erisMintVersion": erismint.GetErisMintVersion().GetVersionString(), + }).Debug("Loading ErisMint") + return erismint.NewErisMintPipe(moduleConfig, evsw) } - return nil, fmt.Errorf("PLACEHOLDER") + return nil, fmt.Errorf("Failed to return Pipe for %s", moduleConfig.Name) } diff --git a/server_config.toml b/server_config.toml index 191c1978144c69d2355d3f4417de1370da5c7105..bd96bbce39f0f3f52f4217c61513b0726228979f 100644 --- a/server_config.toml +++ b/server_config.toml @@ -111,7 +111,7 @@ listener = "tcp://0.0.0.0:46658" # of the private validator, but also (currently) holds the private key # for the private vaildator to sign with. This private key needs to be moved # out and directly managed by eris-keys -# This file needs to be in the working directory of tendermint. +# This file needs to be in the root directory private_validator_file = "priv_validator.json" # Tendermint requires additional configuration parameters.