mirror of
https://github.com/fluencelabs/tendermint
synced 2025-05-29 22:21:21 +00:00
fewer structs. remove viper from consensus
This commit is contained in:
parent
d8fb226ec4
commit
75b6c5215f
@ -222,7 +222,7 @@ FOR_LOOP:
|
|||||||
// We need both to sync the first block.
|
// We need both to sync the first block.
|
||||||
break SYNC_LOOP
|
break SYNC_LOOP
|
||||||
}
|
}
|
||||||
firstParts := first.MakePartSet(types.DefaultPartSetSize)
|
firstParts := first.MakePartSet(types.DefaultBlockPartSize)
|
||||||
firstPartsHeader := firstParts.Header()
|
firstPartsHeader := firstParts.Header()
|
||||||
// Finally, verify the first block using the second's commit
|
// Finally, verify the first block using the second's commit
|
||||||
// NOTE: we can probably make this more efficient, but note that calling
|
// NOTE: we can probably make this more efficient, but note that calling
|
||||||
|
@ -5,8 +5,8 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
cmn "github.com/tendermint/tmlibs/common"
|
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
|
cmn "github.com/tendermint/tmlibs/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
var initFilesCmd = &cobra.Command{
|
var initFilesCmd = &cobra.Command{
|
||||||
@ -20,13 +20,13 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func initFiles(cmd *cobra.Command, args []string) {
|
func initFiles(cmd *cobra.Command, args []string) {
|
||||||
privValFile := config.GetString("priv_validator_file")
|
privValFile := config.PrivValidatorFile
|
||||||
if _, err := os.Stat(privValFile); os.IsNotExist(err) {
|
if _, err := os.Stat(privValFile); os.IsNotExist(err) {
|
||||||
privValidator := types.GenPrivValidator()
|
privValidator := types.GenPrivValidator()
|
||||||
privValidator.SetFile(privValFile)
|
privValidator.SetFile(privValFile)
|
||||||
privValidator.Save()
|
privValidator.Save()
|
||||||
|
|
||||||
genFile := config.GetString("genesis_file")
|
genFile := config.GenesisFile
|
||||||
|
|
||||||
if _, err := os.Stat(genFile); os.IsNotExist(err) {
|
if _, err := os.Stat(genFile); os.IsNotExist(err) {
|
||||||
genDoc := types.GenesisDoc{
|
genDoc := types.GenesisDoc{
|
||||||
@ -40,8 +40,8 @@ func initFiles(cmd *cobra.Command, args []string) {
|
|||||||
genDoc.SaveAs(genFile)
|
genDoc.SaveAs(genFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Notice("Initialized tendermint", "genesis", config.GetString("genesis_file"), "priv_validator", config.GetString("priv_validator_file"))
|
log.Notice("Initialized tendermint", "genesis", config.GenesisFile, "priv_validator", config.PrivValidatorFile)
|
||||||
} else {
|
} else {
|
||||||
log.Notice("Already initialized", "priv_validator", config.GetString("priv_validator_file"))
|
log.Notice("Already initialized", "priv_validator", config.PrivValidatorFile)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,36 +1,26 @@
|
|||||||
package commands
|
package commands
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"github.com/tendermint/tendermint/consensus"
|
"github.com/tendermint/tendermint/consensus"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var replayCmd = &cobra.Command{
|
var replayCmd = &cobra.Command{
|
||||||
Use: "replay [walfile]",
|
Use: "replay",
|
||||||
Short: "Replay messages from WAL",
|
Short: "Replay messages from WAL",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
config := getConfig()
|
||||||
if len(args) > 1 {
|
consensus.RunReplayFile(config.Config, config.Consensus, false)
|
||||||
consensus.RunReplayFile(config, args[1], false)
|
|
||||||
} else {
|
|
||||||
fmt.Println("replay requires an argument (walfile)")
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var replayConsoleCmd = &cobra.Command{
|
var replayConsoleCmd = &cobra.Command{
|
||||||
Use: "replay_console [walfile]",
|
Use: "replay_console",
|
||||||
Short: "Replay messages from WAL in a console",
|
Short: "Replay messages from WAL in a console",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
config := getConfig()
|
||||||
if len(args) > 1 {
|
consensus.RunReplayFile(config.Config, config.Consensus, true)
|
||||||
consensus.RunReplayFile(config, args[1], true)
|
|
||||||
} else {
|
|
||||||
fmt.Println("replay_console requires an argument (walfile)")
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,13 +29,15 @@ func init() {
|
|||||||
// XXX: this is totally unsafe.
|
// XXX: this is totally unsafe.
|
||||||
// it's only suitable for testnets.
|
// it's only suitable for testnets.
|
||||||
func resetAll(cmd *cobra.Command, args []string) {
|
func resetAll(cmd *cobra.Command, args []string) {
|
||||||
ResetAll(config.GetString("db_dir"), config.GetString("priv_validator_file"), log)
|
config := getConfig()
|
||||||
|
ResetAll(config.DBDir, config.PrivValidatorFile, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
// XXX: this is totally unsafe.
|
// XXX: this is totally unsafe.
|
||||||
// it's only suitable for testnets.
|
// it's only suitable for testnets.
|
||||||
func resetPrivValidator(cmd *cobra.Command, args []string) {
|
func resetPrivValidator(cmd *cobra.Command, args []string) {
|
||||||
resetPrivValidatorLocal(config.GetString("priv_validator_file"), log)
|
config := getConfig()
|
||||||
|
resetPrivValidatorLocal(config.PrivValidatorFile, log)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exported so other CLI tools can use it
|
// Exported so other CLI tools can use it
|
||||||
|
@ -2,16 +2,34 @@ package commands
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
|
||||||
tmcfg "github.com/tendermint/tendermint/config/tendermint"
|
"github.com/tendermint/tendermint/node"
|
||||||
"github.com/tendermint/tmlibs/logger"
|
"github.com/tendermint/tmlibs/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
config = tmcfg.GetConfig("")
|
viperConfig *viper.Viper
|
||||||
log = logger.New("module", "main")
|
config *node.Config
|
||||||
|
log = logger.New("module", "main")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
// Set config to be used as defaults by flags.
|
||||||
|
// This will be overwritten by whatever is unmarshalled from viper
|
||||||
|
config = node.NewDefaultConfig("")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// unmarshal viper into the Tendermint config
|
||||||
|
func getConfig() *node.Config {
|
||||||
|
config := new(node.Config)
|
||||||
|
if err := viperConfig.Unmarshal(config); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
//global flag
|
//global flag
|
||||||
var logLevel string
|
var logLevel string
|
||||||
|
|
||||||
@ -19,13 +37,14 @@ var RootCmd = &cobra.Command{
|
|||||||
Use: "tendermint",
|
Use: "tendermint",
|
||||||
Short: "Tendermint Core (BFT Consensus) in Go",
|
Short: "Tendermint Core (BFT Consensus) in Go",
|
||||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
// set the log level in the config and logger
|
// set the log level
|
||||||
config.Set("node.log_level", logLevel)
|
config := getConfig()
|
||||||
logger.SetLogLevel(logLevel)
|
logger.SetLogLevel(config.LogLevel)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
//parse flag and set config
|
//parse flag and set config
|
||||||
RootCmd.PersistentFlags().StringVar(&logLevel, "log_level", config.GetString("node.log_level"), "Log level")
|
RootCmd.PersistentFlags().StringVar(&logLevel, "log_level", config.LogLevel, "Log level")
|
||||||
|
viperConfig.BindPFlag("log_level", RootCmd.Flags().Lookup("log_level"))
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,9 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var runNodeCmd = &cobra.Command{
|
var runNodeCmd = &cobra.Command{
|
||||||
Use: "node",
|
Use: "node",
|
||||||
Short: "Run the tendermint node",
|
Short: "Run the tendermint node",
|
||||||
PreRun: setConfigFlags,
|
RunE: runNode,
|
||||||
RunE: runNode,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//flags
|
//flags
|
||||||
@ -35,49 +34,55 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
// bind flags
|
||||||
|
|
||||||
// configuration options
|
// node flags
|
||||||
runNodeCmd.Flags().StringVar(&moniker, "moniker", config.GetString("node.moniker"),
|
runNodeCmd.Flags().StringVar(&moniker, "moniker", config.Moniker,
|
||||||
"Node Name")
|
"Node Name")
|
||||||
runNodeCmd.Flags().StringVar(&nodeLaddr, "node_laddr", config.GetString("node.listen_addr"),
|
viperConfig.BindPFlag("moniker", runNodeCmd.Flags().Lookup("moniker"))
|
||||||
"Node listen address. (0.0.0.0:0 means any interface, any port)")
|
|
||||||
runNodeCmd.Flags().StringVar(&seeds, "seeds", config.GetString("network.seeds"),
|
runNodeCmd.Flags().BoolVar(&fastSync, "fast_sync", config.FastSync,
|
||||||
"Comma delimited host:port seed nodes")
|
|
||||||
runNodeCmd.Flags().BoolVar(&fastSync, "fast_sync", config.GetBool("blockchain.fast_sync"),
|
|
||||||
"Fast blockchain syncing")
|
"Fast blockchain syncing")
|
||||||
runNodeCmd.Flags().BoolVar(&skipUPNP, "skip_upnp", config.GetBool("network.skip_upnp"),
|
viperConfig.BindPFlag("fast_sync", runNodeCmd.Flags().Lookup("fast_sync"))
|
||||||
"Skip UPNP configuration")
|
|
||||||
runNodeCmd.Flags().StringVar(&rpcLaddr, "rpc_laddr", config.GetString("rpc.listen_addr"),
|
// abci flags
|
||||||
"RPC listen address. Port required")
|
runNodeCmd.Flags().StringVar(&proxyApp, "proxy_app", config.ProxyApp,
|
||||||
runNodeCmd.Flags().StringVar(&grpcLaddr, "grpc_laddr", config.GetString("grpc.listen_addr"),
|
|
||||||
"GRPC listen address (BroadcastTx only). Port required")
|
|
||||||
runNodeCmd.Flags().StringVar(&proxyApp, "proxy_app", config.GetString("abci.proxy_app"),
|
|
||||||
"Proxy app address, or 'nilapp' or 'dummy' for local testing.")
|
"Proxy app address, or 'nilapp' or 'dummy' for local testing.")
|
||||||
runNodeCmd.Flags().StringVar(&abciTransport, "abci", config.GetString("abci.mode"),
|
viperConfig.BindPFlag("proxy_app", runNodeCmd.Flags().Lookup("proxy_app"))
|
||||||
|
|
||||||
|
runNodeCmd.Flags().StringVar(&abciTransport, "abci", config.ABCI,
|
||||||
"Specify abci transport (socket | grpc)")
|
"Specify abci transport (socket | grpc)")
|
||||||
|
viperConfig.BindPFlag("abci", runNodeCmd.Flags().Lookup("abci"))
|
||||||
|
|
||||||
|
// rpc flags
|
||||||
|
runNodeCmd.Flags().StringVar(&rpcLaddr, "rpc_laddr", config.RPCListenAddress,
|
||||||
|
"RPC listen address. Port required")
|
||||||
|
viperConfig.BindPFlag("rpc_laddr", runNodeCmd.Flags().Lookup("rpc_laddr"))
|
||||||
|
|
||||||
|
runNodeCmd.Flags().StringVar(&grpcLaddr, "grpc_laddr", config.GRPCListenAddress,
|
||||||
|
"GRPC listen address (BroadcastTx only). Port required")
|
||||||
|
viperConfig.BindPFlag("grpc_laddr", runNodeCmd.Flags().Lookup("grpc_laddr"))
|
||||||
|
|
||||||
|
// p2p flags
|
||||||
|
runNodeCmd.Flags().StringVar(&nodeLaddr, "p2p.laddr", config.P2P.ListenAddress,
|
||||||
|
"Node listen address. (0.0.0.0:0 means any interface, any port)")
|
||||||
|
viperConfig.BindPFlag("p2p.laddr", runNodeCmd.Flags().Lookup("p2p.laddr"))
|
||||||
|
|
||||||
|
runNodeCmd.Flags().StringVar(&seeds, "p2p.seeds", config.P2P.Seeds,
|
||||||
|
"Comma delimited host:port seed nodes")
|
||||||
|
viperConfig.BindPFlag("p2p.seeds", runNodeCmd.Flags().Lookup("p2p.seeds"))
|
||||||
|
|
||||||
|
runNodeCmd.Flags().BoolVar(&skipUPNP, "p2p.skip_upnp", config.P2P.SkipUPNP,
|
||||||
|
"Skip UPNP configuration")
|
||||||
|
viperConfig.BindPFlag("p2p.skip_upnp", runNodeCmd.Flags().Lookup("p2p.skip_upnp"))
|
||||||
|
|
||||||
// feature flags
|
// feature flags
|
||||||
runNodeCmd.Flags().BoolVar(&pex, "pex", config.GetBool("pex_reactor"),
|
runNodeCmd.Flags().BoolVar(&pex, "p2p.pex", config.P2P.PexReactor,
|
||||||
"Enable Peer-Exchange (dev feature)")
|
"Enable Peer-Exchange (dev feature)")
|
||||||
|
|
||||||
RootCmd.AddCommand(runNodeCmd)
|
RootCmd.AddCommand(runNodeCmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setConfigFlags(cmd *cobra.Command, args []string) {
|
|
||||||
|
|
||||||
// Merge parsed flag values onto config
|
|
||||||
config.Set("node.moniker", moniker)
|
|
||||||
config.Set("node.listen_addr", nodeLaddr)
|
|
||||||
config.Set("network.seeds", seeds)
|
|
||||||
config.Set("network.skip_upnp", skipUPNP)
|
|
||||||
config.Set("network.pex_reactor", pex)
|
|
||||||
config.Set("blockchain.fast_sync", fastSync)
|
|
||||||
config.Set("rpc.listen_addr", rpcLaddr)
|
|
||||||
config.Set("rpc.grpc_listen_addr", grpcLaddr)
|
|
||||||
config.Set("abci.proxy_app", proxyApp)
|
|
||||||
config.Set("abci.mode", abciTransport)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Users wishing to:
|
// Users wishing to:
|
||||||
// * Use an external signer for their validators
|
// * Use an external signer for their validators
|
||||||
// * Supply an in-proc abci app
|
// * Supply an in-proc abci app
|
||||||
@ -90,7 +95,7 @@ func runNode(cmd *cobra.Command, args []string) error {
|
|||||||
// This is for Mintnet compatibility.
|
// This is for Mintnet compatibility.
|
||||||
// TODO: If Mintnet gets deprecated or genesis_file is
|
// TODO: If Mintnet gets deprecated or genesis_file is
|
||||||
// always available, remove.
|
// always available, remove.
|
||||||
genDocFile := config.GetString("genesis_file")
|
genDocFile := config.GenesisFile
|
||||||
if !cmn.FileExists(genDocFile) {
|
if !cmn.FileExists(genDocFile) {
|
||||||
log.Notice(cmn.Fmt("Waiting for genesis file %v...", genDocFile))
|
log.Notice(cmn.Fmt("Waiting for genesis file %v...", genDocFile))
|
||||||
for {
|
for {
|
||||||
@ -109,12 +114,13 @@ func runNode(cmd *cobra.Command, args []string) error {
|
|||||||
if genDoc.ChainID == "" {
|
if genDoc.ChainID == "" {
|
||||||
return fmt.Errorf("Genesis doc %v must include non-empty chain_id", genDocFile)
|
return fmt.Errorf("Genesis doc %v must include non-empty chain_id", genDocFile)
|
||||||
}
|
}
|
||||||
config.Set("chain_id", genDoc.ChainID)
|
|
||||||
|
// config.SetChainID("chain_id", genDoc.ChainID) TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create & start node
|
// Create & start node
|
||||||
n := node.NewNodeDefault(config) //tmConfig)
|
n := node.NewNodeDefault(getConfig())
|
||||||
if _, err := n.Start(); err != nil {
|
if _, err := n.Start(); err != nil {
|
||||||
return fmt.Errorf("Failed to start node: %v", err)
|
return fmt.Errorf("Failed to start node: %v", err)
|
||||||
} else {
|
} else {
|
||||||
|
@ -20,8 +20,8 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func showValidator(cmd *cobra.Command, args []string) {
|
func showValidator(cmd *cobra.Command, args []string) {
|
||||||
privValidatorFile := config.GetString("priv_validator_file")
|
config := getConfig()
|
||||||
privValidator := types.LoadOrGenPrivValidator(privValidatorFile)
|
privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile)
|
||||||
pubKeyJSONBytes, _ := data.ToJSON(privValidator.PubKey)
|
pubKeyJSONBytes, _ := data.ToJSON(privValidator.PubKey)
|
||||||
fmt.Println(string(pubKeyJSONBytes))
|
fmt.Println(string(pubKeyJSONBytes))
|
||||||
}
|
}
|
||||||
|
73
config/config.go
Normal file
73
config/config.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
// Config struct for a Tendermint node
|
||||||
|
type Config struct {
|
||||||
|
// The ID of the chain to join (should be signed with every transaction and vote)
|
||||||
|
ChainID string `mapstructure:"chain_id"`
|
||||||
|
|
||||||
|
// A JSON file containing the initial validator set and other meta data
|
||||||
|
GenesisFile string `mapstructure:"genesis_file"`
|
||||||
|
|
||||||
|
// A JSON file containing the private key to use as a validator in the consensus protocol
|
||||||
|
PrivValidatorFile string `mapstructure:"priv_validator_file"`
|
||||||
|
|
||||||
|
// A custom human readable name for this node
|
||||||
|
Moniker string `mapstructure:"moniker"`
|
||||||
|
|
||||||
|
// 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
|
||||||
|
ABCI string `mapstructure:"abci"`
|
||||||
|
|
||||||
|
// 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 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
|
||||||
|
|
||||||
|
// What indexer to use for transactions
|
||||||
|
TxIndex string `mapstructure:"tx_index"`
|
||||||
|
|
||||||
|
// Database backend: leveldb | memdb
|
||||||
|
DBBackend string `mapstructure:"db_backend"`
|
||||||
|
|
||||||
|
// Database directory
|
||||||
|
DBDir string `mapstructure:"db_dir"`
|
||||||
|
|
||||||
|
// TCP or UNIX socket address for the RPC server to listen on
|
||||||
|
RPCListenAddress string `mapstructure:"rpc_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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultConfig(rootDir string) *Config {
|
||||||
|
return &Config{
|
||||||
|
GenesisFile: rootDir + "/genesis.json",
|
||||||
|
PrivValidatorFile: rootDir + "/priv_validator.json",
|
||||||
|
Moniker: "anonymous",
|
||||||
|
ProxyApp: "tcp://127.0.0.1:46658",
|
||||||
|
ABCI: "socket",
|
||||||
|
LogLevel: "info",
|
||||||
|
ProfListenAddress: "",
|
||||||
|
FastSync: true,
|
||||||
|
FilterPeers: false,
|
||||||
|
TxIndex: "kv",
|
||||||
|
DBBackend: "leveldb",
|
||||||
|
DBDir: rootDir + "/data",
|
||||||
|
RPCListenAddress: "tcp://0.0.0.0:46657",
|
||||||
|
GRPCListenAddress: "",
|
||||||
|
}
|
||||||
|
}
|
@ -1,89 +0,0 @@
|
|||||||
package tendermint
|
|
||||||
|
|
||||||
type Config struct {
|
|
||||||
Node NodeConfig `mapstructure:"node"`
|
|
||||||
Chain ChainConfig `mapstructure:"chain"`
|
|
||||||
ABCI ABCIConfig `mapstructure:"abci"`
|
|
||||||
Network NetworkConfig `mapstructure:"network"`
|
|
||||||
Blockchain BlockchainConfig `mapstructure:"blockchain"`
|
|
||||||
Consensus ConsensusConfig `mapstructure:"consensus"`
|
|
||||||
Block BlockConfig `mapstructure:"block"`
|
|
||||||
Mempool MempoolConfig `mapstructure:"mempool"`
|
|
||||||
RPC RPCConfig `mapstructure:"rpc"`
|
|
||||||
DB DBConfig `mapstructure:"db"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type NodeConfig struct {
|
|
||||||
Moniker string `mapstructure:"moniker"` // "anonymous"
|
|
||||||
PrivValidatorFile string `mapstructure:"priv_validator_file"` // rootDir+"/priv_validator.json")
|
|
||||||
|
|
||||||
LogLevel string `mapstructure:"log_level"` // info
|
|
||||||
ProfListenAddr string `mapstructure:"prof_laddr"` // ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type ChainConfig struct {
|
|
||||||
ChainID string `mapstructure:"chain_id"`
|
|
||||||
GenesisFile string `mapstructure:"genesis_file"` // rootDir/genesis.json
|
|
||||||
}
|
|
||||||
|
|
||||||
type ABCIConfig struct {
|
|
||||||
ProxyApp string `mapstructure:"proxy_app"` // tcp://0.0.0.0:46658
|
|
||||||
Mode string `mapstructure:"mode"` // socket
|
|
||||||
|
|
||||||
FilterPeers bool `mapstructure:"filter_peers"` // false
|
|
||||||
}
|
|
||||||
|
|
||||||
type NetworkConfig struct {
|
|
||||||
ListenAddr string `mapstructure:"listen_adddr"` // "tcp://0.0.0.0:46656")
|
|
||||||
Seeds string `mapstructure:"seeds"` // []string ...
|
|
||||||
SkipUPNP bool `mapstructure:"skip_upnp"`
|
|
||||||
AddrBookFile string `mapstructure:"addr_book_file"` // rootDir+"/addrbook.json")
|
|
||||||
AddrBookString bool `mapstructure:"addr_book_string"` // true
|
|
||||||
PexReactor bool `mapstructure:"pex_reactor"` // false
|
|
||||||
}
|
|
||||||
|
|
||||||
type BlockchainConfig struct {
|
|
||||||
FastSync bool `mapstructure:"fast_sync"` // true
|
|
||||||
}
|
|
||||||
|
|
||||||
type ConsensusConfig struct {
|
|
||||||
WalFile string `mapstructure:"wal_file"` //rootDir+"/data/cs.wal/wal")
|
|
||||||
WalLight bool `mapstructure:"wal_light"` // false
|
|
||||||
|
|
||||||
// all timeouts are in ms
|
|
||||||
TimeoutPropose int `mapstructure:"timeout_propose"` // 3000
|
|
||||||
TimeoutProposeDelta int `mapstructure:"timeout_propose_delta"` // 500
|
|
||||||
TimeoutPrevote int `mapstructure:"timeout_prevote"` // 1000
|
|
||||||
TimeoutPrevoteDelta int `mapstructure:"timeout_prevote_delta"` // 500
|
|
||||||
TimeoutPrecommit int `mapstructure:"timeout_precommit"` // 1000
|
|
||||||
TimeoutPrecommitDelta int `mapstructure:"timeout_precommit_delta"` // 500
|
|
||||||
TimeoutCommit int `mapstructure:"timeout_commit"` // 1000
|
|
||||||
|
|
||||||
// make progress asap (no `timeout_commit`) on full precommit votes
|
|
||||||
SkipTimeoutCommit bool `mapstructure:"skip_timeout_commit"` // false
|
|
||||||
}
|
|
||||||
|
|
||||||
type BlockConfig struct {
|
|
||||||
MaxTxs int `mapstructure:"max_txs"` // 10000
|
|
||||||
PartSize int `mapstructure:"part_size"` // 65536
|
|
||||||
DisableDataHash bool `mapstructure:"disable_data_hash"` // false
|
|
||||||
}
|
|
||||||
|
|
||||||
type MempoolConfig struct {
|
|
||||||
Recheck bool `mapstructure:"recheck"` // true
|
|
||||||
RecheckEmpty bool `mapstructure:"recheck_empty"` // true
|
|
||||||
Broadcast bool `mapstructure:"broadcast"` // true
|
|
||||||
WalDir string `mapstructure:"wal_dir"` // rootDir+"/data/mempool.wal")
|
|
||||||
}
|
|
||||||
|
|
||||||
type RPCConfig struct {
|
|
||||||
RPCListenAddress string `mapstructure:"rpc_listen_addr"` // "tcp://0.0.0.0:46657")
|
|
||||||
GRPCListenAddress string `mapstructure:"grpc_listen_addr"` // ""
|
|
||||||
}
|
|
||||||
|
|
||||||
type DBConfig struct {
|
|
||||||
Backend string `mapstructure:"backend"` // leveldb
|
|
||||||
Dir string `mapstructure:"dir"` // rootDir/data
|
|
||||||
|
|
||||||
TxIndex string `mapstructure:"tx_index"` // "kv"
|
|
||||||
}
|
|
@ -28,6 +28,7 @@ import (
|
|||||||
"github.com/tendermint/abci/example/dummy"
|
"github.com/tendermint/abci/example/dummy"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// genesis, chain_id, priv_val
|
||||||
var config *viper.Viper // NOTE: must be reset for each _test.go file
|
var config *viper.Viper // NOTE: must be reset for each _test.go file
|
||||||
var ensureTimeout = time.Duration(2)
|
var ensureTimeout = time.Duration(2)
|
||||||
|
|
||||||
|
@ -8,9 +8,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/viper"
|
|
||||||
|
|
||||||
bc "github.com/tendermint/tendermint/blockchain"
|
bc "github.com/tendermint/tendermint/blockchain"
|
||||||
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
"github.com/tendermint/tendermint/proxy"
|
"github.com/tendermint/tendermint/proxy"
|
||||||
sm "github.com/tendermint/tendermint/state"
|
sm "github.com/tendermint/tendermint/state"
|
||||||
"github.com/tendermint/tendermint/types"
|
"github.com/tendermint/tendermint/types"
|
||||||
@ -21,10 +20,10 @@ import (
|
|||||||
//--------------------------------------------------------
|
//--------------------------------------------------------
|
||||||
// replay messages interactively or all at once
|
// replay messages interactively or all at once
|
||||||
|
|
||||||
func RunReplayFile(config *viper.Viper, walFile string, console bool) {
|
func RunReplayFile(config *cfg.Config, csConfig *Config, console bool) {
|
||||||
consensusState := newConsensusStateForReplay(config)
|
consensusState := newConsensusStateForReplay(config, csConfig)
|
||||||
|
|
||||||
if err := consensusState.ReplayFile(walFile, console); err != nil {
|
if err := consensusState.ReplayFile(csConfig.WalFile, console); err != nil {
|
||||||
cmn.Exit(cmn.Fmt("Error during consensus replay: %v", err))
|
cmn.Exit(cmn.Fmt("Error during consensus replay: %v", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,33 +235,30 @@ func (pb *playback) replayConsoleLoop() int {
|
|||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
|
||||||
// convenience for replay mode
|
// convenience for replay mode
|
||||||
func newConsensusStateForReplay(config *viper.Viper) *ConsensusState {
|
func newConsensusStateForReplay(config *cfg.Config, csConfig *Config) *ConsensusState {
|
||||||
// Get BlockStore
|
// Get BlockStore
|
||||||
blockStoreDB := dbm.NewDB("blockstore", config.GetString("db_backend"), config.GetString("db_dir"))
|
blockStoreDB := dbm.NewDB("blockstore", config.DBBackend, config.DBDir)
|
||||||
blockStore := bc.NewBlockStore(blockStoreDB)
|
blockStore := bc.NewBlockStore(blockStoreDB)
|
||||||
|
|
||||||
// Get State
|
// Get State
|
||||||
stateDB := dbm.NewDB("state", config.GetString("db_backend"), config.GetString("db_dir"))
|
stateDB := dbm.NewDB("state", config.DBBackend, config.DBDir)
|
||||||
state := sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file"))
|
state := sm.MakeGenesisStateFromFile(stateDB, config.GenesisFile)
|
||||||
|
|
||||||
// Create proxyAppConn connection (consensus, mempool, query)
|
// Create proxyAppConn connection (consensus, mempool, query)
|
||||||
clientCreator := proxy.DefaultClientCreator(config.GetString("proxy_app"), config.GetString("abci"), config.GetString("db_dir"))
|
clientCreator := proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir)
|
||||||
proxyApp := proxy.NewAppConns(clientCreator, NewHandshaker(state, blockStore))
|
proxyApp := proxy.NewAppConns(clientCreator, NewHandshaker(state, blockStore))
|
||||||
_, err := proxyApp.Start()
|
_, err := proxyApp.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
cmn.Exit(cmn.Fmt("Error starting proxy app conns: %v", err))
|
cmn.Exit(cmn.Fmt("Error starting proxy app conns: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the chainid to the global config
|
|
||||||
config.Set("chain_id", state.ChainID)
|
|
||||||
|
|
||||||
// Make event switch
|
// Make event switch
|
||||||
eventSwitch := types.NewEventSwitch()
|
eventSwitch := types.NewEventSwitch()
|
||||||
if _, err := eventSwitch.Start(); err != nil {
|
if _, err := eventSwitch.Start(); err != nil {
|
||||||
cmn.Exit(cmn.Fmt("Failed to start event switch: %v", err))
|
cmn.Exit(cmn.Fmt("Failed to start event switch: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
consensusState := NewConsensusState(config, state.Copy(), proxyApp.Consensus(), blockStore, types.MockMempool{})
|
consensusState := NewConsensusState(csConfig, state.Copy(), proxyApp.Consensus(), blockStore, types.MockMempool{})
|
||||||
consensusState.SetEventSwitch(eventSwitch)
|
consensusState.SetEventSwitch(eventSwitch)
|
||||||
return consensusState
|
return consensusState
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/ebuchman/fail-test"
|
"github.com/ebuchman/fail-test"
|
||||||
"github.com/spf13/viper"
|
|
||||||
|
|
||||||
"github.com/tendermint/go-wire"
|
"github.com/tendermint/go-wire"
|
||||||
"github.com/tendermint/tendermint/proxy"
|
"github.com/tendermint/tendermint/proxy"
|
||||||
@ -20,53 +19,90 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Timeout Parameters
|
// Config
|
||||||
|
|
||||||
// TimeoutParams holds timeouts and deltas for each round step.
|
// Config holds timeouts and details about the WAL, the block structure,
|
||||||
// All timeouts and deltas in milliseconds.
|
// and timeouts in the consensus protocol.
|
||||||
type TimeoutParams struct {
|
type Config struct {
|
||||||
Propose0 int
|
WalFile string `mapstructure:"wal_file"`
|
||||||
ProposeDelta int
|
WalLight bool `mapstructure:"wal_light"`
|
||||||
Prevote0 int
|
|
||||||
PrevoteDelta int
|
// All timeouts are in ms
|
||||||
Precommit0 int
|
TimeoutPropose int `mapstructure:"timeout_propose"`
|
||||||
PrecommitDelta int
|
TimeoutProposeDelta int `mapstructure:"timeout_propose_delta"`
|
||||||
Commit0 int
|
TimeoutPrevote int `mapstructure:"timeout_prevote"`
|
||||||
SkipTimeoutCommit bool
|
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:"block_size_txs"`
|
||||||
|
MaxBlockSizeBytes int `mapstructure:"block_size_bytes"`
|
||||||
|
|
||||||
|
// TODO: This probably shouldn't be exposed but it makes it
|
||||||
|
// easy to write tests for the wal/replay
|
||||||
|
BlockPartSize int `mapstructure:"block_part_size"`
|
||||||
|
|
||||||
|
chainID string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultConfig(rootDir string) *Config {
|
||||||
|
return &Config{
|
||||||
|
WalFile: rootDir + "/data/cs.wal/wal",
|
||||||
|
WalLight: false,
|
||||||
|
TimeoutPropose: 3000,
|
||||||
|
TimeoutProposeDelta: 500,
|
||||||
|
TimeoutPrevote: 1000,
|
||||||
|
TimeoutPrevoteDelta: 500,
|
||||||
|
TimeoutPrecommit: 1000,
|
||||||
|
TimeoutPrecommitDelta: 500,
|
||||||
|
TimeoutCommit: 1000,
|
||||||
|
SkipTimeoutCommit: false,
|
||||||
|
MaxBlockSizeTxs: 10000,
|
||||||
|
MaxBlockSizeBytes: 1, // TODO
|
||||||
|
BlockPartSize: types.DefaultBlockPartSize,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewTestConfig(rootDir string) *Config {
|
||||||
|
config := NewDefaultConfig(rootDir)
|
||||||
|
config.TimeoutPropose = 2000
|
||||||
|
config.TimeoutProposeDelta = 1
|
||||||
|
config.TimeoutPrevote = 10
|
||||||
|
config.TimeoutPrevoteDelta = 1
|
||||||
|
config.TimeoutPrecommit = 10
|
||||||
|
config.TimeoutPrecommitDelta = 1
|
||||||
|
config.TimeoutCommit = 10
|
||||||
|
config.SkipTimeoutCommit = true
|
||||||
|
return config
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cfg *Config) SetChainID(chainID string) {
|
||||||
|
cfg.chainID = chainID
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait this long for a proposal
|
// Wait this long for a proposal
|
||||||
func (tp *TimeoutParams) Propose(round int) time.Duration {
|
func (cfg *Config) Propose(round int) time.Duration {
|
||||||
return time.Duration(tp.Propose0+tp.ProposeDelta*round) * time.Millisecond
|
return time.Duration(cfg.TimeoutPropose+cfg.TimeoutProposeDelta*round) * time.Millisecond
|
||||||
}
|
}
|
||||||
|
|
||||||
// After receiving any +2/3 prevote, wait this long for stragglers
|
// After receiving any +2/3 prevote, wait this long for stragglers
|
||||||
func (tp *TimeoutParams) Prevote(round int) time.Duration {
|
func (cfg *Config) Prevote(round int) time.Duration {
|
||||||
return time.Duration(tp.Prevote0+tp.PrevoteDelta*round) * time.Millisecond
|
return time.Duration(cfg.TimeoutPrevote+cfg.TimeoutPrevoteDelta*round) * time.Millisecond
|
||||||
}
|
}
|
||||||
|
|
||||||
// After receiving any +2/3 precommits, wait this long for stragglers
|
// After receiving any +2/3 precommits, wait this long for stragglers
|
||||||
func (tp *TimeoutParams) Precommit(round int) time.Duration {
|
func (cfg *Config) Precommit(round int) time.Duration {
|
||||||
return time.Duration(tp.Precommit0+tp.PrecommitDelta*round) * time.Millisecond
|
return time.Duration(cfg.TimeoutPrecommit+cfg.TimeoutPrecommitDelta*round) * time.Millisecond
|
||||||
}
|
}
|
||||||
|
|
||||||
// After receiving +2/3 precommits for a single block (a commit), wait this long for stragglers in the next height's RoundStepNewHeight
|
// After receiving +2/3 precommits for a single block (a commit), wait this long for stragglers in the next height's RoundStepNewHeight
|
||||||
func (tp *TimeoutParams) Commit(t time.Time) time.Time {
|
func (cfg *Config) Commit(t time.Time) time.Time {
|
||||||
return t.Add(time.Duration(tp.Commit0) * time.Millisecond)
|
return t.Add(time.Duration(cfg.TimeoutCommit) * time.Millisecond)
|
||||||
}
|
|
||||||
|
|
||||||
// InitTimeoutParamsFromConfig initializes parameters from config
|
|
||||||
func InitTimeoutParamsFromConfig(config *viper.Viper) *TimeoutParams {
|
|
||||||
return &TimeoutParams{
|
|
||||||
Propose0: config.GetInt("timeout_propose"),
|
|
||||||
ProposeDelta: config.GetInt("timeout_propose_delta"),
|
|
||||||
Prevote0: config.GetInt("timeout_prevote"),
|
|
||||||
PrevoteDelta: config.GetInt("timeout_prevote_delta"),
|
|
||||||
Precommit0: config.GetInt("timeout_precommit"),
|
|
||||||
PrecommitDelta: config.GetInt("timeout_precommit_delta"),
|
|
||||||
Commit0: config.GetInt("timeout_commit"),
|
|
||||||
SkipTimeoutCommit: config.GetBool("skip_timeout_commit"),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -224,38 +260,48 @@ type PrivValidator interface {
|
|||||||
type ConsensusState struct {
|
type ConsensusState struct {
|
||||||
cmn.BaseService
|
cmn.BaseService
|
||||||
|
|
||||||
config *viper.Viper
|
// config details
|
||||||
|
config *Config
|
||||||
|
privValidator PrivValidator // for signing votes
|
||||||
|
|
||||||
|
// services for creating and executing blocks
|
||||||
proxyAppConn proxy.AppConnConsensus
|
proxyAppConn proxy.AppConnConsensus
|
||||||
blockStore types.BlockStore
|
blockStore types.BlockStore
|
||||||
mempool types.Mempool
|
mempool types.Mempool
|
||||||
|
|
||||||
privValidator PrivValidator // for signing votes
|
// internal state
|
||||||
|
|
||||||
mtx sync.Mutex
|
mtx sync.Mutex
|
||||||
RoundState
|
RoundState
|
||||||
state *sm.State // State until height-1.
|
state *sm.State // State until height-1.
|
||||||
|
|
||||||
peerMsgQueue chan msgInfo // serializes msgs affecting state (proposals, block parts, votes)
|
// state changes may be triggered by msgs from peers,
|
||||||
internalMsgQueue chan msgInfo // like peerMsgQueue but for our own proposals, parts, votes
|
// msgs from ourself, or by timeouts
|
||||||
timeoutTicker TimeoutTicker // ticker for timeouts
|
peerMsgQueue chan msgInfo
|
||||||
timeoutParams *TimeoutParams // parameters and functions for timeout intervals
|
internalMsgQueue chan msgInfo
|
||||||
|
timeoutTicker TimeoutTicker
|
||||||
|
|
||||||
|
// we use PubSub to trigger msg broadcasts in the reactor,
|
||||||
|
// and to notify external subscribers, eg. through a websocket
|
||||||
evsw types.EventSwitch
|
evsw types.EventSwitch
|
||||||
|
|
||||||
|
// a Write-Ahead Log ensures we can recover from any kind of crash
|
||||||
|
// and helps us avoid signing conflicting votes
|
||||||
wal *WAL
|
wal *WAL
|
||||||
replayMode bool // so we don't log signing errors during replay
|
replayMode bool // so we don't log signing errors during replay
|
||||||
|
|
||||||
nSteps int // used for testing to limit the number of transitions the state makes
|
// for tests where we want to limit the number of transitions the state makes
|
||||||
|
nSteps int
|
||||||
|
|
||||||
// allow certain function to be overwritten for testing
|
// some functions can be overwritten for testing
|
||||||
decideProposal func(height, round int)
|
decideProposal func(height, round int)
|
||||||
doPrevote func(height, round int)
|
doPrevote func(height, round int)
|
||||||
setProposal func(proposal *types.Proposal) error
|
setProposal func(proposal *types.Proposal) error
|
||||||
|
|
||||||
|
// closed when we finish shutting down
|
||||||
done chan struct{}
|
done chan struct{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConsensusState(config *viper.Viper, state *sm.State, proxyAppConn proxy.AppConnConsensus, blockStore types.BlockStore, mempool types.Mempool) *ConsensusState {
|
func NewConsensusState(config *Config, state *sm.State, proxyAppConn proxy.AppConnConsensus, blockStore types.BlockStore, mempool types.Mempool) *ConsensusState {
|
||||||
cs := &ConsensusState{
|
cs := &ConsensusState{
|
||||||
config: config,
|
config: config,
|
||||||
proxyAppConn: proxyAppConn,
|
proxyAppConn: proxyAppConn,
|
||||||
@ -264,7 +310,6 @@ func NewConsensusState(config *viper.Viper, state *sm.State, proxyAppConn proxy.
|
|||||||
peerMsgQueue: make(chan msgInfo, msgQueueSize),
|
peerMsgQueue: make(chan msgInfo, msgQueueSize),
|
||||||
internalMsgQueue: make(chan msgInfo, msgQueueSize),
|
internalMsgQueue: make(chan msgInfo, msgQueueSize),
|
||||||
timeoutTicker: NewTimeoutTicker(),
|
timeoutTicker: NewTimeoutTicker(),
|
||||||
timeoutParams: InitTimeoutParamsFromConfig(config),
|
|
||||||
done: make(chan struct{}),
|
done: make(chan struct{}),
|
||||||
}
|
}
|
||||||
// set function defaults (may be overwritten before calling Start)
|
// set function defaults (may be overwritten before calling Start)
|
||||||
@ -341,7 +386,7 @@ func (cs *ConsensusState) LoadCommit(height int) *types.Commit {
|
|||||||
|
|
||||||
func (cs *ConsensusState) OnStart() error {
|
func (cs *ConsensusState) OnStart() error {
|
||||||
|
|
||||||
walFile := cs.config.GetString("cs_wal_file")
|
walFile := cs.config.WalFile
|
||||||
if err := cs.OpenWAL(walFile); err != nil {
|
if err := cs.OpenWAL(walFile); err != nil {
|
||||||
log.Error("Error loading ConsensusState wal", "error", err.Error())
|
log.Error("Error loading ConsensusState wal", "error", err.Error())
|
||||||
return err
|
return err
|
||||||
@ -406,7 +451,7 @@ func (cs *ConsensusState) OpenWAL(walFile string) (err error) {
|
|||||||
|
|
||||||
cs.mtx.Lock()
|
cs.mtx.Lock()
|
||||||
defer cs.mtx.Unlock()
|
defer cs.mtx.Unlock()
|
||||||
wal, err := NewWAL(walFile, cs.config.GetBool("cs_wal_light"))
|
wal, err := NewWAL(walFile, cs.config.WalLight)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -512,7 +557,7 @@ func (cs *ConsensusState) reconstructLastCommit(state *sm.State) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
seenCommit := cs.blockStore.LoadSeenCommit(state.LastBlockHeight)
|
seenCommit := cs.blockStore.LoadSeenCommit(state.LastBlockHeight)
|
||||||
lastPrecommits := types.NewVoteSet(cs.config.GetString("chain_id"), state.LastBlockHeight, seenCommit.Round(), types.VoteTypePrecommit, state.LastValidators)
|
lastPrecommits := types.NewVoteSet(cs.config.chainID, state.LastBlockHeight, seenCommit.Round(), types.VoteTypePrecommit, state.LastValidators)
|
||||||
for _, precommit := range seenCommit.Precommits {
|
for _, precommit := range seenCommit.Precommits {
|
||||||
if precommit == nil {
|
if precommit == nil {
|
||||||
continue
|
continue
|
||||||
@ -572,9 +617,9 @@ func (cs *ConsensusState) updateToState(state *sm.State) {
|
|||||||
// to be gathered for the first block.
|
// to be gathered for the first block.
|
||||||
// And alternative solution that relies on clocks:
|
// And alternative solution that relies on clocks:
|
||||||
// cs.StartTime = state.LastBlockTime.Add(timeoutCommit)
|
// cs.StartTime = state.LastBlockTime.Add(timeoutCommit)
|
||||||
cs.StartTime = cs.timeoutParams.Commit(time.Now())
|
cs.StartTime = cs.config.Commit(time.Now())
|
||||||
} else {
|
} else {
|
||||||
cs.StartTime = cs.timeoutParams.Commit(cs.CommitTime)
|
cs.StartTime = cs.config.Commit(cs.CommitTime)
|
||||||
}
|
}
|
||||||
cs.Validators = validators
|
cs.Validators = validators
|
||||||
cs.Proposal = nil
|
cs.Proposal = nil
|
||||||
@ -583,7 +628,7 @@ func (cs *ConsensusState) updateToState(state *sm.State) {
|
|||||||
cs.LockedRound = 0
|
cs.LockedRound = 0
|
||||||
cs.LockedBlock = nil
|
cs.LockedBlock = nil
|
||||||
cs.LockedBlockParts = nil
|
cs.LockedBlockParts = nil
|
||||||
cs.Votes = NewHeightVoteSet(cs.config.GetString("chain_id"), height, validators)
|
cs.Votes = NewHeightVoteSet(cs.config.chainID, height, validators)
|
||||||
cs.CommitRound = -1
|
cs.CommitRound = -1
|
||||||
cs.LastCommit = lastPrecommits
|
cs.LastCommit = lastPrecommits
|
||||||
cs.LastValidators = state.LastValidators
|
cs.LastValidators = state.LastValidators
|
||||||
@ -799,7 +844,7 @@ func (cs *ConsensusState) enterPropose(height int, round int) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// If we don't get the proposal and all block parts quick enough, enterPrevote
|
// If we don't get the proposal and all block parts quick enough, enterPrevote
|
||||||
cs.scheduleTimeout(cs.timeoutParams.Propose(round), height, round, RoundStepPropose)
|
cs.scheduleTimeout(cs.config.Propose(round), height, round, RoundStepPropose)
|
||||||
|
|
||||||
// Nothing more to do if we're not a validator
|
// Nothing more to do if we're not a validator
|
||||||
if cs.privValidator == nil {
|
if cs.privValidator == nil {
|
||||||
@ -893,10 +938,10 @@ func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Mempool validated transactions
|
// Mempool validated transactions
|
||||||
txs := cs.mempool.Reap(cs.config.GetInt("block_size"))
|
txs := cs.mempool.Reap(cs.config.MaxBlockSizeTxs)
|
||||||
|
|
||||||
return types.MakeBlock(cs.Height, cs.state.ChainID, txs, commit,
|
return types.MakeBlock(cs.Height, cs.state.ChainID, txs, commit,
|
||||||
cs.state.LastBlockID, cs.state.Validators.Hash(), cs.state.AppHash, cs.config.GetInt("block_part_size"))
|
cs.state.LastBlockID, cs.state.Validators.Hash(), cs.state.AppHash, cs.config.BlockPartSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enter: `timeoutPropose` after entering Propose.
|
// Enter: `timeoutPropose` after entering Propose.
|
||||||
@ -982,7 +1027,7 @@ func (cs *ConsensusState) enterPrevoteWait(height int, round int) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// Wait for some more prevotes; enterPrecommit
|
// Wait for some more prevotes; enterPrecommit
|
||||||
cs.scheduleTimeout(cs.timeoutParams.Prevote(round), height, round, RoundStepPrevoteWait)
|
cs.scheduleTimeout(cs.config.Prevote(round), height, round, RoundStepPrevoteWait)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enter: +2/3 precomits for block or nil.
|
// Enter: +2/3 precomits for block or nil.
|
||||||
@ -1102,7 +1147,7 @@ func (cs *ConsensusState) enterPrecommitWait(height int, round int) {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
// Wait for some more precommits; enterNewRound
|
// Wait for some more precommits; enterNewRound
|
||||||
cs.scheduleTimeout(cs.timeoutParams.Precommit(round), height, round, RoundStepPrecommitWait)
|
cs.scheduleTimeout(cs.config.Precommit(round), height, round, RoundStepPrecommitWait)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1397,7 +1442,7 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerKey string) (added bool,
|
|||||||
types.FireEventVote(cs.evsw, types.EventDataVote{vote})
|
types.FireEventVote(cs.evsw, types.EventDataVote{vote})
|
||||||
|
|
||||||
// if we can skip timeoutCommit and have all the votes now,
|
// if we can skip timeoutCommit and have all the votes now,
|
||||||
if cs.timeoutParams.SkipTimeoutCommit && cs.LastCommit.HasAll() {
|
if cs.config.SkipTimeoutCommit && cs.LastCommit.HasAll() {
|
||||||
// go straight to new round (skip timeout commit)
|
// go straight to new round (skip timeout commit)
|
||||||
// cs.scheduleTimeout(time.Duration(0), cs.Height, 0, RoundStepNewHeight)
|
// cs.scheduleTimeout(time.Duration(0), cs.Height, 0, RoundStepNewHeight)
|
||||||
cs.enterNewRound(cs.Height, 0)
|
cs.enterNewRound(cs.Height, 0)
|
||||||
@ -1460,7 +1505,7 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerKey string) (added bool,
|
|||||||
cs.enterPrecommit(height, vote.Round)
|
cs.enterPrecommit(height, vote.Round)
|
||||||
cs.enterCommit(height, vote.Round)
|
cs.enterCommit(height, vote.Round)
|
||||||
|
|
||||||
if cs.timeoutParams.SkipTimeoutCommit && precommits.HasAll() {
|
if cs.config.SkipTimeoutCommit && precommits.HasAll() {
|
||||||
// if we have all the votes now,
|
// if we have all the votes now,
|
||||||
// go straight to new round (skip timeout commit)
|
// go straight to new round (skip timeout commit)
|
||||||
// cs.scheduleTimeout(time.Duration(0), cs.Height, 0, RoundStepNewHeight)
|
// cs.scheduleTimeout(time.Duration(0), cs.Height, 0, RoundStepNewHeight)
|
||||||
|
@ -47,7 +47,7 @@ TODO: Better handle abci client errors. (make it automatically handle connection
|
|||||||
const cacheSize = 100000
|
const cacheSize = 100000
|
||||||
|
|
||||||
type Mempool struct {
|
type Mempool struct {
|
||||||
config Config
|
config *Config
|
||||||
|
|
||||||
proxyMtx sync.Mutex
|
proxyMtx sync.Mutex
|
||||||
proxyAppConn proxy.AppConnMempool
|
proxyAppConn proxy.AppConnMempool
|
||||||
@ -66,7 +66,7 @@ type Mempool struct {
|
|||||||
wal *auto.AutoFile
|
wal *auto.AutoFile
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMempool(config Config, proxyAppConn proxy.AppConnMempool) *Mempool {
|
func NewMempool(config *Config, proxyAppConn proxy.AppConnMempool) *Mempool {
|
||||||
mempool := &Mempool{
|
mempool := &Mempool{
|
||||||
config: config,
|
config: config,
|
||||||
proxyAppConn: proxyAppConn,
|
proxyAppConn: proxyAppConn,
|
||||||
|
@ -22,21 +22,30 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Recheck bool // true
|
Recheck bool `mapstructure:"recheck"` // true
|
||||||
RecheckEmpty bool // true
|
RecheckEmpty bool `mapstructure:"recheck_empty"` // true
|
||||||
Broadcast bool // true
|
Broadcast bool `mapstructure:"broadcast"` // true
|
||||||
WalDir string // rootDir+"/data/mempool.wal")
|
WalDir string `mapstructure:"wal_dir"` //
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultConfig(rootDir string) *Config {
|
||||||
|
return &Config{
|
||||||
|
Recheck: true,
|
||||||
|
RecheckEmpty: true,
|
||||||
|
Broadcast: true,
|
||||||
|
WalDir: rootDir + "/data/mempool.wal",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MempoolReactor handles mempool tx broadcasting amongst peers.
|
// MempoolReactor handles mempool tx broadcasting amongst peers.
|
||||||
type MempoolReactor struct {
|
type MempoolReactor struct {
|
||||||
p2p.BaseReactor
|
p2p.BaseReactor
|
||||||
config Config
|
config *Config
|
||||||
Mempool *Mempool
|
Mempool *Mempool
|
||||||
evsw types.EventSwitch
|
evsw types.EventSwitch
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewMempoolReactor(config Config, mempool *Mempool) *MempoolReactor {
|
func NewMempoolReactor(config *Config, mempool *Mempool) *MempoolReactor {
|
||||||
memR := &MempoolReactor{
|
memR := &MempoolReactor{
|
||||||
config: config,
|
config: config,
|
||||||
Mempool: mempool,
|
Mempool: mempool,
|
||||||
|
113
node/node.go
113
node/node.go
@ -13,7 +13,8 @@ import (
|
|||||||
crypto "github.com/tendermint/go-crypto"
|
crypto "github.com/tendermint/go-crypto"
|
||||||
wire "github.com/tendermint/go-wire"
|
wire "github.com/tendermint/go-wire"
|
||||||
bc "github.com/tendermint/tendermint/blockchain"
|
bc "github.com/tendermint/tendermint/blockchain"
|
||||||
tmcfg "github.com/tendermint/tendermint/config/tendermint"
|
cfg "github.com/tendermint/tendermint/config"
|
||||||
|
// tmcfg "github.com/tendermint/tendermint/config/tendermint"
|
||||||
"github.com/tendermint/tendermint/consensus"
|
"github.com/tendermint/tendermint/consensus"
|
||||||
mempl "github.com/tendermint/tendermint/mempool"
|
mempl "github.com/tendermint/tendermint/mempool"
|
||||||
p2p "github.com/tendermint/tendermint/p2p"
|
p2p "github.com/tendermint/tendermint/p2p"
|
||||||
@ -34,11 +35,30 @@ import (
|
|||||||
_ "net/http/pprof"
|
_ "net/http/pprof"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Config struct {
|
||||||
|
// Top level options use an anonymous struct
|
||||||
|
*cfg.Config `mapstructure:",squash"`
|
||||||
|
|
||||||
|
// Options for services
|
||||||
|
P2P *p2p.NetworkConfig `mapstructure:"p2p"`
|
||||||
|
Mempool *mempl.Config `mapstructure:"mempool"`
|
||||||
|
Consensus *consensus.Config `mapstructure:"consensus"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultConfig(rootDir string) *Config {
|
||||||
|
return &Config{
|
||||||
|
Config: cfg.NewDefaultConfig(rootDir),
|
||||||
|
P2P: p2p.NewDefaultConfig(rootDir),
|
||||||
|
Mempool: mempl.NewDefaultConfig(rootDir),
|
||||||
|
Consensus: consensus.NewDefaultConfig(rootDir),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Node struct {
|
type Node struct {
|
||||||
cmn.BaseService
|
cmn.BaseService
|
||||||
|
|
||||||
// config
|
// config
|
||||||
config *viper.Viper // user config
|
config *Config
|
||||||
genesisDoc *types.GenesisDoc // initial validator set
|
genesisDoc *types.GenesisDoc // initial validator set
|
||||||
privValidator *types.PrivValidator // local node's validator key
|
privValidator *types.PrivValidator // local node's validator key
|
||||||
|
|
||||||
@ -59,35 +79,27 @@ type Node struct {
|
|||||||
txIndexer txindex.TxIndexer
|
txIndexer txindex.TxIndexer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNodeDefault(config *viper.Viper) *Node {
|
func NewNodeDefault(config *Config) *Node {
|
||||||
// Get PrivValidator
|
// Get PrivValidator
|
||||||
privValidatorFile := config.GetString("priv_validator_file")
|
privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile)
|
||||||
privValidator := types.LoadOrGenPrivValidator(privValidatorFile)
|
return NewNode(config, privValidator,
|
||||||
return NewNode(config, privValidator, proxy.DefaultClientCreator(
|
proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir))
|
||||||
config.GetString("proxy_app"),
|
|
||||||
config.GetString("abci"),
|
|
||||||
config.GetString("db_dir"),
|
|
||||||
))
|
|
||||||
// config.ABCI.ProxyApp, config.ABCI.Mode, config.DB.Dir))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCreator proxy.ClientCreator) *Node {
|
func NewNode(config *Config, privValidator *types.PrivValidator, clientCreator proxy.ClientCreator) *Node {
|
||||||
|
|
||||||
tmConfig := new(tmcfg.Config)
|
|
||||||
if err := config.Unmarshal(tmConfig); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get BlockStore
|
// Get BlockStore
|
||||||
blockStoreDB := dbm.NewDB("blockstore", tmConfig.DB.Backend, tmConfig.DB.Dir)
|
blockStoreDB := dbm.NewDB("blockstore", config.DBBackend, config.DBDir)
|
||||||
blockStore := bc.NewBlockStore(blockStoreDB)
|
blockStore := bc.NewBlockStore(blockStoreDB)
|
||||||
|
|
||||||
// Get State
|
// Get State
|
||||||
stateDB := dbm.NewDB("state", tmConfig.DB.Backend, tmConfig.DB.Dir)
|
stateDB := dbm.NewDB("state", config.DBBackend, config.DBDir)
|
||||||
state := sm.GetState(stateDB, tmConfig.Chain.GenesisFile)
|
state := sm.GetState(stateDB, config.GenesisFile)
|
||||||
|
|
||||||
// add the chainid and number of validators to the global config
|
// add the chainid and number of validators to the global config
|
||||||
config.Set("chain_id", state.ChainID)
|
// TODO: Set ChainID. eg:
|
||||||
|
// config.Consensus.SetChainID(state.ChainID) // ...
|
||||||
|
// but actually consensus doesnt need it since the cs has the state ...
|
||||||
|
|
||||||
// Create the proxyApp, which manages connections (consensus, mempool, query)
|
// Create the proxyApp, which manages connections (consensus, mempool, query)
|
||||||
// and sync tendermint and the app by replaying any necessary blocks
|
// and sync tendermint and the app by replaying any necessary blocks
|
||||||
@ -101,9 +113,9 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||||||
|
|
||||||
// Transaction indexing
|
// Transaction indexing
|
||||||
var txIndexer txindex.TxIndexer
|
var txIndexer txindex.TxIndexer
|
||||||
switch tmConfig.DB.TxIndex {
|
switch config.TxIndex {
|
||||||
case "kv":
|
case "kv":
|
||||||
store := dbm.NewDB("tx_index", tmConfig.DB.Backend, tmConfig.DB.Dir)
|
store := dbm.NewDB("tx_index", config.DBBackend, config.DBDir)
|
||||||
txIndexer = kv.NewTxIndex(store)
|
txIndexer = kv.NewTxIndex(store)
|
||||||
default:
|
default:
|
||||||
txIndexer = &null.TxIndex{}
|
txIndexer = &null.TxIndex{}
|
||||||
@ -122,7 +134,7 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||||||
|
|
||||||
// Decide whether to fast-sync or not
|
// Decide whether to fast-sync or not
|
||||||
// We don't fast-sync when the only validator is us.
|
// We don't fast-sync when the only validator is us.
|
||||||
fastSync := config.GetBool("fast_sync")
|
fastSync := config.FastSync
|
||||||
if state.Validators.Size() == 1 {
|
if state.Validators.Size() == 1 {
|
||||||
addr, _ := state.Validators.GetByIndex(0)
|
addr, _ := state.Validators.GetByIndex(0)
|
||||||
if bytes.Equal(privValidator.Address, addr) {
|
if bytes.Equal(privValidator.Address, addr) {
|
||||||
@ -134,21 +146,20 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||||||
bcReactor := bc.NewBlockchainReactor(state.Copy(), proxyApp.Consensus(), blockStore, fastSync)
|
bcReactor := bc.NewBlockchainReactor(state.Copy(), proxyApp.Consensus(), blockStore, fastSync)
|
||||||
|
|
||||||
// Make MempoolReactor
|
// Make MempoolReactor
|
||||||
mempool := mempl.NewMempool(mempoolConfig(config), proxyApp.Mempool())
|
mempool := mempl.NewMempool(config.Mempool, proxyApp.Mempool())
|
||||||
mempoolReactor := mempl.NewMempoolReactor(mempoolConfig(config), mempool)
|
mempoolReactor := mempl.NewMempoolReactor(config.Mempool, mempool)
|
||||||
|
|
||||||
// Make ConsensusReactor
|
// Make ConsensusReactor
|
||||||
consensusState := consensus.NewConsensusState(config, state.Copy(), proxyApp.Consensus(), blockStore, mempool)
|
consensusState := consensus.NewConsensusState(config.Consensus, state.Copy(), proxyApp.Consensus(), blockStore, mempool)
|
||||||
if privValidator != nil {
|
if privValidator != nil {
|
||||||
consensusState.SetPrivValidator(privValidator)
|
consensusState.SetPrivValidator(privValidator)
|
||||||
}
|
}
|
||||||
consensusReactor := consensus.NewConsensusReactor(consensusState, fastSync)
|
consensusReactor := consensus.NewConsensusReactor(consensusState, fastSync)
|
||||||
|
|
||||||
// Make p2p network switch
|
// Make p2p network switch
|
||||||
|
// TODO : p2pConfig := config.P2P
|
||||||
p2pConfig := viper.New()
|
p2pConfig := viper.New()
|
||||||
if config.IsSet("p2p") { //TODO verify this necessary, where is this ever set?
|
|
||||||
p2pConfig = config.Get("p2p").(*viper.Viper)
|
|
||||||
}
|
|
||||||
sw := p2p.NewSwitch(p2pConfig)
|
sw := p2p.NewSwitch(p2pConfig)
|
||||||
sw.AddReactor("MEMPOOL", mempoolReactor)
|
sw.AddReactor("MEMPOOL", mempoolReactor)
|
||||||
sw.AddReactor("BLOCKCHAIN", bcReactor)
|
sw.AddReactor("BLOCKCHAIN", bcReactor)
|
||||||
@ -156,8 +167,8 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||||||
|
|
||||||
// Optionally, start the pex reactor
|
// Optionally, start the pex reactor
|
||||||
var addrBook *p2p.AddrBook
|
var addrBook *p2p.AddrBook
|
||||||
if config.GetBool("pex_reactor") {
|
if config.P2P.PexReactor {
|
||||||
addrBook = p2p.NewAddrBook(config.GetString("addrbook_file"), config.GetBool("addrbook_strict"))
|
addrBook = p2p.NewAddrBook(config.P2P.AddrBookFile, config.P2P.AddrBookStrict)
|
||||||
pexReactor := p2p.NewPEXReactor(addrBook)
|
pexReactor := p2p.NewPEXReactor(addrBook)
|
||||||
sw.AddReactor("PEX", pexReactor)
|
sw.AddReactor("PEX", pexReactor)
|
||||||
}
|
}
|
||||||
@ -165,7 +176,7 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||||||
// Filter peers by addr or pubkey with an ABCI query.
|
// Filter peers by addr or pubkey with an ABCI query.
|
||||||
// If the query return code is OK, add peer.
|
// If the query return code is OK, add peer.
|
||||||
// XXX: Query format subject to change
|
// XXX: Query format subject to change
|
||||||
if config.GetBool("filter_peers") {
|
if config.FilterPeers {
|
||||||
// NOTE: addr is ip:port
|
// NOTE: addr is ip:port
|
||||||
sw.SetAddrFilter(func(addr net.Addr) error {
|
sw.SetAddrFilter(func(addr net.Addr) error {
|
||||||
resQuery, err := proxyApp.Query().QuerySync(abci.RequestQuery{Path: cmn.Fmt("/p2p/filter/addr/%s", addr.String())})
|
resQuery, err := proxyApp.Query().QuerySync(abci.RequestQuery{Path: cmn.Fmt("/p2p/filter/addr/%s", addr.String())})
|
||||||
@ -194,7 +205,7 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||||||
SetEventSwitch(eventSwitch, bcReactor, mempoolReactor, consensusReactor)
|
SetEventSwitch(eventSwitch, bcReactor, mempoolReactor, consensusReactor)
|
||||||
|
|
||||||
// run the profile server
|
// run the profile server
|
||||||
profileHost := config.GetString("prof_laddr")
|
profileHost := config.ProfListenAddress
|
||||||
if profileHost != "" {
|
if profileHost != "" {
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@ -227,8 +238,8 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||||||
func (n *Node) OnStart() error {
|
func (n *Node) OnStart() error {
|
||||||
|
|
||||||
// Create & add listener
|
// Create & add listener
|
||||||
protocol, address := ProtocolAndAddress(n.config.GetString("node_laddr"))
|
protocol, address := ProtocolAndAddress(n.config.P2P.ListenAddress)
|
||||||
l := p2p.NewDefaultListener(protocol, address, n.config.GetBool("skip_upnp"))
|
l := p2p.NewDefaultListener(protocol, address, n.config.P2P.SkipUPNP)
|
||||||
n.sw.AddListener(l)
|
n.sw.AddListener(l)
|
||||||
|
|
||||||
// Start the switch
|
// Start the switch
|
||||||
@ -240,16 +251,16 @@ func (n *Node) OnStart() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If seeds exist, add them to the address book and dial out
|
// If seeds exist, add them to the address book and dial out
|
||||||
if n.config.GetString("seeds") != "" {
|
if n.config.P2P.Seeds != "" {
|
||||||
// dial out
|
// dial out
|
||||||
seeds := strings.Split(n.config.GetString("seeds"), ",")
|
seeds := strings.Split(n.config.P2P.Seeds, ",")
|
||||||
if err := n.DialSeeds(seeds); err != nil {
|
if err := n.DialSeeds(seeds); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the RPC server
|
// Run the RPC server
|
||||||
if n.config.GetString("rpc_laddr") != "" {
|
if n.config.RPCListenAddress != "" {
|
||||||
listeners, err := n.startRPC()
|
listeners, err := n.startRPC()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -313,7 +324,7 @@ func (n *Node) ConfigureRPC() {
|
|||||||
|
|
||||||
func (n *Node) startRPC() ([]net.Listener, error) {
|
func (n *Node) startRPC() ([]net.Listener, error) {
|
||||||
n.ConfigureRPC()
|
n.ConfigureRPC()
|
||||||
listenAddrs := strings.Split(n.config.GetString("rpc_laddr"), ",")
|
listenAddrs := strings.Split(n.config.RPCListenAddress, ",")
|
||||||
|
|
||||||
// we may expose the rpc over both a unix and tcp socket
|
// we may expose the rpc over both a unix and tcp socket
|
||||||
listeners := make([]net.Listener, len(listenAddrs))
|
listeners := make([]net.Listener, len(listenAddrs))
|
||||||
@ -330,7 +341,7 @@ func (n *Node) startRPC() ([]net.Listener, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we expose a simplified api over grpc for convenience to app devs
|
// we expose a simplified api over grpc for convenience to app devs
|
||||||
grpcListenAddr := n.config.GetString("grpc_laddr")
|
grpcListenAddr := n.config.GRPCListenAddress
|
||||||
if grpcListenAddr != "" {
|
if grpcListenAddr != "" {
|
||||||
listener, err := grpccore.StartGRPCServer(grpcListenAddr)
|
listener, err := grpccore.StartGRPCServer(grpcListenAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -387,8 +398,8 @@ func (n *Node) makeNodeInfo() *p2p.NodeInfo {
|
|||||||
|
|
||||||
nodeInfo := &p2p.NodeInfo{
|
nodeInfo := &p2p.NodeInfo{
|
||||||
PubKey: n.privKey.PubKey().Unwrap().(crypto.PubKeyEd25519),
|
PubKey: n.privKey.PubKey().Unwrap().(crypto.PubKeyEd25519),
|
||||||
Moniker: n.config.GetString("moniker"),
|
Moniker: n.config.Moniker,
|
||||||
Network: n.config.GetString("chain_id"),
|
Network: n.consensusState.GetState().ChainID,
|
||||||
Version: version.Version,
|
Version: version.Version,
|
||||||
Other: []string{
|
Other: []string{
|
||||||
cmn.Fmt("wire_version=%v", wire.Version),
|
cmn.Fmt("wire_version=%v", wire.Version),
|
||||||
@ -400,9 +411,10 @@ func (n *Node) makeNodeInfo() *p2p.NodeInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// include git hash in the nodeInfo if available
|
// include git hash in the nodeInfo if available
|
||||||
if rev, err := cmn.ReadFile(n.config.GetString("revision_file")); err == nil {
|
// TODO: use ld-flags
|
||||||
|
/*if rev, err := cmn.ReadFile(n.config.GetString("revision_file")); err == nil {
|
||||||
nodeInfo.Other = append(nodeInfo.Other, cmn.Fmt("revision=%v", string(rev)))
|
nodeInfo.Other = append(nodeInfo.Other, cmn.Fmt("revision=%v", string(rev)))
|
||||||
}
|
}*/
|
||||||
|
|
||||||
if !n.sw.IsListening() {
|
if !n.sw.IsListening() {
|
||||||
return nodeInfo
|
return nodeInfo
|
||||||
@ -411,7 +423,7 @@ func (n *Node) makeNodeInfo() *p2p.NodeInfo {
|
|||||||
p2pListener := n.sw.Listeners()[0]
|
p2pListener := n.sw.Listeners()[0]
|
||||||
p2pHost := p2pListener.ExternalAddress().IP.String()
|
p2pHost := p2pListener.ExternalAddress().IP.String()
|
||||||
p2pPort := p2pListener.ExternalAddress().Port
|
p2pPort := p2pListener.ExternalAddress().Port
|
||||||
rpcListenAddr := n.config.GetString("rpc_laddr")
|
rpcListenAddr := n.config.RPCListenAddress
|
||||||
|
|
||||||
// We assume that the rpcListener has the same ExternalAddress.
|
// We assume that the rpcListener has the same ExternalAddress.
|
||||||
// This is probably true because both P2P and RPC listeners use UPnP,
|
// This is probably true because both P2P and RPC listeners use UPnP,
|
||||||
@ -442,12 +454,3 @@ func ProtocolAndAddress(listenAddr string) (string, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
func mempoolConfig(config *viper.Viper) mempl.Config {
|
|
||||||
return mempl.Config{
|
|
||||||
Recheck: config.GetBool("mempool_recheck"),
|
|
||||||
RecheckEmpty: config.GetBool("mempool_recheck_empty"),
|
|
||||||
Broadcast: config.GetBool("mempool_broadcast"),
|
|
||||||
WalDir: config.GetString("mempool_wal_dir"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -4,6 +4,23 @@ import (
|
|||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// for node.Config
|
||||||
|
type NetworkConfig struct {
|
||||||
|
ListenAddress string `mapstructure:"laddr"`
|
||||||
|
Seeds string `mapstructure:"seeds"`
|
||||||
|
SkipUPNP bool `mapstructure:"skip_upnp"`
|
||||||
|
AddrBookFile string `mapstructure:"addr_book_file"`
|
||||||
|
AddrBookStrict bool `mapstructure:"addr_book_strict"`
|
||||||
|
PexReactor bool `mapstructure:"pex_reactor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewDefaultConfig(rootDir string) *NetworkConfig {
|
||||||
|
return &NetworkConfig{
|
||||||
|
AddrBookFile: rootDir + "/addrbook.json",
|
||||||
|
AddrBookStrict: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Switch config keys
|
// Switch config keys
|
||||||
configKeyDialTimeoutSeconds = "dial_timeout_seconds"
|
configKeyDialTimeoutSeconds = "dial_timeout_seconds"
|
||||||
|
@ -15,8 +15,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MaxBlockSize = 22020096 // 21MB TODO make it configurable
|
MaxBlockSize = 22020096 // 21MB TODO make it configurable
|
||||||
DefaultPartSetSize = 65536 // 64kB TODO: put part size in parts header?
|
DefaultBlockPartSize = 65536 // 64kB TODO: put part size in parts header?
|
||||||
)
|
)
|
||||||
|
|
||||||
type Block struct {
|
type Block struct {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user