commit
14d0d395f2
|
@ -6,8 +6,6 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
|
@ -44,7 +42,6 @@ type consensusReactor interface {
|
|||
type BlockchainReactor struct {
|
||||
p2p.BaseReactor
|
||||
|
||||
config *viper.Viper
|
||||
state *sm.State
|
||||
proxyAppConn proxy.AppConnConsensus // same as consensus.proxyAppConn
|
||||
store *BlockStore
|
||||
|
@ -58,7 +55,7 @@ type BlockchainReactor struct {
|
|||
}
|
||||
|
||||
// NewBlockchainReactor returns new reactor instance.
|
||||
func NewBlockchainReactor(config *viper.Viper, state *sm.State, proxyAppConn proxy.AppConnConsensus, store *BlockStore, fastSync bool) *BlockchainReactor {
|
||||
func NewBlockchainReactor(state *sm.State, proxyAppConn proxy.AppConnConsensus, store *BlockStore, fastSync bool) *BlockchainReactor {
|
||||
if state.LastBlockHeight == store.Height()-1 {
|
||||
store.height-- // XXX HACK, make this better
|
||||
}
|
||||
|
@ -73,7 +70,6 @@ func NewBlockchainReactor(config *viper.Viper, state *sm.State, proxyAppConn pro
|
|||
timeoutsCh,
|
||||
)
|
||||
bcR := &BlockchainReactor{
|
||||
config: config,
|
||||
state: state,
|
||||
proxyAppConn: proxyAppConn,
|
||||
store: store,
|
||||
|
@ -226,7 +222,7 @@ FOR_LOOP:
|
|||
// We need both to sync the first block.
|
||||
break SYNC_LOOP
|
||||
}
|
||||
firstParts := first.MakePartSet(bcR.config.GetInt("block_part_size")) // TODO: put part size in parts header?
|
||||
firstParts := first.MakePartSet(types.DefaultBlockPartSize)
|
||||
firstPartsHeader := firstParts.Header()
|
||||
// Finally, verify the first block using the second's commit
|
||||
// NOTE: we can probably make this more efficient, but note that calling
|
||||
|
|
|
@ -5,8 +5,8 @@ import (
|
|||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
var initFilesCmd = &cobra.Command{
|
||||
|
@ -20,13 +20,13 @@ func init() {
|
|||
}
|
||||
|
||||
func initFiles(cmd *cobra.Command, args []string) {
|
||||
privValFile := config.GetString("priv_validator_file")
|
||||
privValFile := config.PrivValidatorFile()
|
||||
if _, err := os.Stat(privValFile); os.IsNotExist(err) {
|
||||
privValidator := types.GenPrivValidator()
|
||||
privValidator.SetFile(privValFile)
|
||||
privValidator.Save()
|
||||
|
||||
genFile := config.GetString("genesis_file")
|
||||
genFile := config.GenesisFile()
|
||||
|
||||
if _, err := os.Stat(genFile); os.IsNotExist(err) {
|
||||
genDoc := types.GenesisDoc{
|
||||
|
@ -40,8 +40,8 @@ func initFiles(cmd *cobra.Command, args []string) {
|
|||
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 {
|
||||
log.Notice("Already initialized", "priv_validator", config.GetString("priv_validator_file"))
|
||||
log.Notice("Already initialized", "priv_validator", config.PrivValidatorFile())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,36 +1,24 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"github.com/tendermint/tendermint/consensus"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var replayCmd = &cobra.Command{
|
||||
Use: "replay [walfile]",
|
||||
Use: "replay",
|
||||
Short: "Replay messages from WAL",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
if len(args) > 1 {
|
||||
consensus.RunReplayFile(config, args[1], false)
|
||||
} else {
|
||||
fmt.Println("replay requires an argument (walfile)")
|
||||
}
|
||||
consensus.RunReplayFile(config.BaseConfig, config.Consensus, false)
|
||||
},
|
||||
}
|
||||
|
||||
var replayConsoleCmd = &cobra.Command{
|
||||
Use: "replay_console [walfile]",
|
||||
Use: "replay_console",
|
||||
Short: "Replay messages from WAL in a console",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
|
||||
if len(args) > 1 {
|
||||
consensus.RunReplayFile(config, args[1], true)
|
||||
} else {
|
||||
fmt.Println("replay_console requires an argument (walfile)")
|
||||
}
|
||||
consensus.RunReplayFile(config.BaseConfig, config.Consensus, true)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/tendermint/log15"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
|
@ -30,36 +29,34 @@ func init() {
|
|||
// XXX: this is totally unsafe.
|
||||
// it's only suitable for testnets.
|
||||
func resetAll(cmd *cobra.Command, args []string) {
|
||||
ResetAll(config, log)
|
||||
ResetAll(config.DBDir(), config.PrivValidatorFile(), log)
|
||||
}
|
||||
|
||||
// XXX: this is totally unsafe.
|
||||
// it's only suitable for testnets.
|
||||
func resetPrivValidator(cmd *cobra.Command, args []string) {
|
||||
resetPrivValidatorLocal(config, log)
|
||||
resetPrivValidatorLocal(config.PrivValidatorFile(), log)
|
||||
}
|
||||
|
||||
// Exported so other CLI tools can use it
|
||||
func ResetAll(c *viper.Viper, l log15.Logger) {
|
||||
resetPrivValidatorLocal(c, l)
|
||||
dataDir := c.GetString("db_dir")
|
||||
os.RemoveAll(dataDir)
|
||||
l.Notice("Removed all data", "dir", dataDir)
|
||||
func ResetAll(dbDir, privValFile string, l log15.Logger) {
|
||||
resetPrivValidatorLocal(privValFile, l)
|
||||
os.RemoveAll(dbDir)
|
||||
l.Notice("Removed all data", "dir", dbDir)
|
||||
}
|
||||
|
||||
func resetPrivValidatorLocal(c *viper.Viper, l log15.Logger) {
|
||||
func resetPrivValidatorLocal(privValFile string, l log15.Logger) {
|
||||
|
||||
// Get PrivValidator
|
||||
var privValidator *types.PrivValidator
|
||||
privValidatorFile := c.GetString("priv_validator_file")
|
||||
if _, err := os.Stat(privValidatorFile); err == nil {
|
||||
privValidator = types.LoadPrivValidator(privValidatorFile)
|
||||
if _, err := os.Stat(privValFile); err == nil {
|
||||
privValidator = types.LoadPrivValidator(privValFile)
|
||||
privValidator.Reset()
|
||||
l.Notice("Reset PrivValidator", "file", privValidatorFile)
|
||||
l.Notice("Reset PrivValidator", "file", privValFile)
|
||||
} else {
|
||||
privValidator = types.GenPrivValidator()
|
||||
privValidator.SetFile(privValidatorFile)
|
||||
privValidator.SetFile(privValFile)
|
||||
privValidator.Save()
|
||||
l.Notice("Generated PrivValidator", "file", privValidatorFile)
|
||||
l.Notice("Generated PrivValidator", "file", privValFile)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,30 +2,29 @@ package commands
|
|||
|
||||
import (
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
tmcfg "github.com/tendermint/tendermint/config/tendermint"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tmlibs/logger"
|
||||
)
|
||||
|
||||
var (
|
||||
config = tmcfg.GetConfig("")
|
||||
config = cfg.DefaultConfig()
|
||||
log = logger.New("module", "main")
|
||||
)
|
||||
|
||||
//global flag
|
||||
var logLevel string
|
||||
func init() {
|
||||
RootCmd.PersistentFlags().String("log_level", config.LogLevel, "Log level")
|
||||
}
|
||||
|
||||
var RootCmd = &cobra.Command{
|
||||
Use: "tendermint",
|
||||
Short: "Tendermint Core (BFT Consensus) in Go",
|
||||
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||
// set the log level in the config and logger
|
||||
config.Set("log_level", logLevel)
|
||||
logger.SetLogLevel(logLevel)
|
||||
PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
err := viper.Unmarshal(config)
|
||||
config.SetRoot(config.RootDir)
|
||||
cfg.EnsureRoot(config.RootDir)
|
||||
logger.SetLogLevel(config.LogLevel)
|
||||
return err
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
//parse flag and set config
|
||||
RootCmd.PersistentFlags().StringVar(&logLevel, "log_level", config.GetString("log_level"), "Log level")
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
package commands
|
||||
|
||||
import (
|
||||
"os"
|
||||
"strconv"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tmlibs/cli"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
var (
|
||||
defaultRoot = os.ExpandEnv("$HOME/.some/test/dir")
|
||||
)
|
||||
|
||||
const (
|
||||
rootName = "root"
|
||||
)
|
||||
|
||||
// isolate provides a clean setup and returns a copy of RootCmd you can
|
||||
// modify in the test cases
|
||||
func isolate(cmds ...*cobra.Command) cli.Executable {
|
||||
viper.Reset()
|
||||
config = cfg.DefaultConfig()
|
||||
r := &cobra.Command{
|
||||
Use: rootName,
|
||||
PersistentPreRunE: RootCmd.PersistentPreRunE,
|
||||
}
|
||||
r.AddCommand(cmds...)
|
||||
wr := cli.PrepareBaseCmd(r, "TM", defaultRoot)
|
||||
return wr
|
||||
}
|
||||
|
||||
func TestRootConfig(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
// we pre-create a config file we can refer to in the rest of
|
||||
// the test cases.
|
||||
cvals := map[string]string{
|
||||
"moniker": "monkey",
|
||||
"fast_sync": "false",
|
||||
}
|
||||
// proper types of the above settings
|
||||
cfast := false
|
||||
conf, err := cli.WriteDemoConfig(cvals)
|
||||
require.Nil(err)
|
||||
|
||||
defaults := cfg.DefaultConfig()
|
||||
dmax := defaults.P2P.MaxNumPeers
|
||||
|
||||
cases := []struct {
|
||||
args []string
|
||||
env map[string]string
|
||||
root string
|
||||
moniker string
|
||||
fastSync bool
|
||||
maxPeer int
|
||||
}{
|
||||
{nil, nil, defaultRoot, defaults.Moniker, defaults.FastSync, dmax},
|
||||
// try multiple ways of setting root (two flags, cli vs. env)
|
||||
{[]string{"--home", conf}, nil, conf, cvals["moniker"], cfast, dmax},
|
||||
{nil, map[string]string{"TMROOT": conf}, conf, cvals["moniker"], cfast, dmax},
|
||||
// check setting p2p subflags two different ways
|
||||
{[]string{"--p2p.max_num_peers", "420"}, nil, defaultRoot, defaults.Moniker, defaults.FastSync, 420},
|
||||
{nil, map[string]string{"TM_P2P_MAX_NUM_PEERS": "17"}, defaultRoot, defaults.Moniker, defaults.FastSync, 17},
|
||||
// try to set env that have no flags attached...
|
||||
{[]string{"--home", conf}, map[string]string{"TM_MONIKER": "funny"}, conf, "funny", cfast, dmax},
|
||||
}
|
||||
|
||||
for idx, tc := range cases {
|
||||
i := strconv.Itoa(idx)
|
||||
// test command that does nothing, except trigger unmarshalling in root
|
||||
noop := &cobra.Command{
|
||||
Use: "noop",
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
return nil
|
||||
},
|
||||
}
|
||||
noop.Flags().Int("p2p.max_num_peers", defaults.P2P.MaxNumPeers, "")
|
||||
cmd := isolate(noop)
|
||||
|
||||
args := append([]string{rootName, noop.Use}, tc.args...)
|
||||
err := cli.RunWithArgs(cmd, args, tc.env)
|
||||
require.Nil(err, i)
|
||||
assert.Equal(tc.root, config.RootDir, i)
|
||||
assert.Equal(tc.root, config.P2P.RootDir, i)
|
||||
assert.Equal(tc.root, config.Consensus.RootDir, i)
|
||||
assert.Equal(tc.root, config.Mempool.RootDir, i)
|
||||
assert.Equal(tc.moniker, config.Moniker, i)
|
||||
assert.Equal(tc.fastSync, config.FastSync, i)
|
||||
assert.Equal(tc.maxPeer, config.P2P.MaxNumPeers, i)
|
||||
}
|
||||
|
||||
}
|
|
@ -13,70 +13,37 @@ import (
|
|||
)
|
||||
|
||||
var runNodeCmd = &cobra.Command{
|
||||
Use: "node",
|
||||
Short: "Run the tendermint node",
|
||||
PreRun: setConfigFlags,
|
||||
RunE: runNode,
|
||||
Use: "node",
|
||||
Short: "Run the tendermint node",
|
||||
RunE: runNode,
|
||||
}
|
||||
|
||||
//flags
|
||||
var (
|
||||
moniker string
|
||||
nodeLaddr string
|
||||
seeds string
|
||||
fastSync bool
|
||||
skipUPNP bool
|
||||
rpcLaddr string
|
||||
grpcLaddr string
|
||||
proxyApp string
|
||||
abciTransport string
|
||||
pex bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
// bind flags
|
||||
runNodeCmd.Flags().String("moniker", config.Moniker, "Node Name")
|
||||
|
||||
// configuration options
|
||||
runNodeCmd.Flags().StringVar(&moniker, "moniker", config.GetString("moniker"),
|
||||
"Node Name")
|
||||
runNodeCmd.Flags().StringVar(&nodeLaddr, "node_laddr", config.GetString("node_laddr"),
|
||||
"Node listen address. (0.0.0.0:0 means any interface, any port)")
|
||||
runNodeCmd.Flags().StringVar(&seeds, "seeds", config.GetString("seeds"),
|
||||
"Comma delimited host:port seed nodes")
|
||||
runNodeCmd.Flags().BoolVar(&fastSync, "fast_sync", config.GetBool("fast_sync"),
|
||||
"Fast blockchain syncing")
|
||||
runNodeCmd.Flags().BoolVar(&skipUPNP, "skip_upnp", config.GetBool("skip_upnp"),
|
||||
"Skip UPNP configuration")
|
||||
runNodeCmd.Flags().StringVar(&rpcLaddr, "rpc_laddr", config.GetString("rpc_laddr"),
|
||||
"RPC listen address. Port required")
|
||||
runNodeCmd.Flags().StringVar(&grpcLaddr, "grpc_laddr", config.GetString("grpc_laddr"),
|
||||
"GRPC listen address (BroadcastTx only). Port required")
|
||||
runNodeCmd.Flags().StringVar(&proxyApp, "proxy_app", config.GetString("proxy_app"),
|
||||
"Proxy app address, or 'nilapp' or 'dummy' for local testing.")
|
||||
runNodeCmd.Flags().StringVar(&abciTransport, "abci", config.GetString("abci"),
|
||||
"Specify abci transport (socket | grpc)")
|
||||
// node flags
|
||||
runNodeCmd.Flags().Bool("fast_sync", config.FastSync, "Fast blockchain syncing")
|
||||
|
||||
// abci flags
|
||||
runNodeCmd.Flags().String("proxy_app", config.ProxyApp, "Proxy app address, or 'nilapp' or 'dummy' for local testing.")
|
||||
runNodeCmd.Flags().String("abci", config.ABCI, "Specify abci transport (socket | grpc)")
|
||||
|
||||
// rpc flags
|
||||
runNodeCmd.Flags().String("rpc_laddr", config.RPCListenAddress, "RPC listen address. Port required")
|
||||
runNodeCmd.Flags().String("grpc_laddr", config.GRPCListenAddress, "GRPC listen address (BroadcastTx only). Port required")
|
||||
|
||||
// p2p flags
|
||||
runNodeCmd.Flags().String("p2p.laddr", config.P2P.ListenAddress, "Node listen address. (0.0.0.0:0 means any interface, any port)")
|
||||
runNodeCmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma delimited host:port seed nodes")
|
||||
runNodeCmd.Flags().Bool("p2p.skip_upnp", config.P2P.SkipUPNP, "Skip UPNP configuration")
|
||||
|
||||
// feature flags
|
||||
runNodeCmd.Flags().BoolVar(&pex, "pex", config.GetBool("pex_reactor"),
|
||||
"Enable Peer-Exchange (dev feature)")
|
||||
runNodeCmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable Peer-Exchange (dev feature)")
|
||||
|
||||
RootCmd.AddCommand(runNodeCmd)
|
||||
}
|
||||
|
||||
func setConfigFlags(cmd *cobra.Command, args []string) {
|
||||
|
||||
// Merge parsed flag values onto config
|
||||
config.Set("moniker", moniker)
|
||||
config.Set("node_laddr", nodeLaddr)
|
||||
config.Set("seeds", seeds)
|
||||
config.Set("fast_sync", fastSync)
|
||||
config.Set("skip_upnp", skipUPNP)
|
||||
config.Set("rpc_laddr", rpcLaddr)
|
||||
config.Set("grpc_laddr", grpcLaddr)
|
||||
config.Set("proxy_app", proxyApp)
|
||||
config.Set("abci", abciTransport)
|
||||
config.Set("pex_reactor", pex)
|
||||
}
|
||||
|
||||
// Users wishing to:
|
||||
// * Use an external signer for their validators
|
||||
// * Supply an in-proc abci app
|
||||
|
@ -89,7 +56,7 @@ func runNode(cmd *cobra.Command, args []string) error {
|
|||
// This is for Mintnet compatibility.
|
||||
// TODO: If Mintnet gets deprecated or genesis_file is
|
||||
// always available, remove.
|
||||
genDocFile := config.GetString("genesis_file")
|
||||
genDocFile := config.GenesisFile()
|
||||
if !cmn.FileExists(genDocFile) {
|
||||
log.Notice(cmn.Fmt("Waiting for genesis file %v...", genDocFile))
|
||||
for {
|
||||
|
@ -108,7 +75,7 @@ func runNode(cmd *cobra.Command, args []string) error {
|
|||
if genDoc.ChainID == "" {
|
||||
return fmt.Errorf("Genesis doc %v must include non-empty chain_id", genDocFile)
|
||||
}
|
||||
config.Set("chain_id", genDoc.ChainID)
|
||||
config.ChainID = genDoc.ChainID
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -20,8 +20,7 @@ func init() {
|
|||
}
|
||||
|
||||
func showValidator(cmd *cobra.Command, args []string) {
|
||||
privValidatorFile := config.GetString("priv_validator_file")
|
||||
privValidator := types.LoadOrGenPrivValidator(privValidatorFile)
|
||||
privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile())
|
||||
pubKeyJSONBytes, _ := data.ToJSON(privValidator.PubKey)
|
||||
fmt.Println(string(pubKeyJSONBytes))
|
||||
}
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/tendermint/tendermint/cmd/tendermint/commands"
|
||||
"github.com/tendermint/tmlibs/cli"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := commands.RootCmd.Execute(); err != nil {
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
cmd := cli.PrepareBaseCmd(commands.RootCmd, "TM", os.ExpandEnv("$HOME/.tendermint"))
|
||||
cmd.Execute()
|
||||
}
|
||||
|
|
|
@ -0,0 +1,295 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
// Top level options use an anonymous struct
|
||||
BaseConfig `mapstructure:",squash"`
|
||||
|
||||
// Options for services
|
||||
P2P *P2PConfig `mapstructure:"p2p"`
|
||||
Mempool *MempoolConfig `mapstructure:"mempool"`
|
||||
Consensus *ConsensusConfig `mapstructure:"consensus"`
|
||||
}
|
||||
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
BaseConfig: DefaultBaseConfig(),
|
||||
P2P: DefaultP2PConfig(),
|
||||
Mempool: DefaultMempoolConfig(),
|
||||
Consensus: DefaultConsensusConfig(),
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig() *Config {
|
||||
return &Config{
|
||||
BaseConfig: TestBaseConfig(),
|
||||
P2P: TestP2PConfig(),
|
||||
Mempool: DefaultMempoolConfig(),
|
||||
Consensus: TestConsensusConfig(),
|
||||
}
|
||||
}
|
||||
|
||||
// Set the RootDir for all Config structs
|
||||
func (cfg *Config) SetRoot(root string) *Config {
|
||||
cfg.BaseConfig.RootDir = root
|
||||
cfg.P2P.RootDir = root
|
||||
cfg.Mempool.RootDir = root
|
||||
cfg.Consensus.RootDir = root
|
||||
return cfg
|
||||
}
|
||||
|
||||
// BaseConfig struct for a Tendermint node
|
||||
type BaseConfig struct {
|
||||
// The root directory for all data.
|
||||
// This should be set in viper so it can unmarshal into this struct
|
||||
RootDir string `mapstructure:"home"`
|
||||
|
||||
// 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
|
||||
Genesis string `mapstructure:"genesis_file"`
|
||||
|
||||
// A JSON file containing the private key to use as a validator in the consensus protocol
|
||||
PrivValidator 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
|
||||
DBPath 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 DefaultBaseConfig() BaseConfig {
|
||||
return BaseConfig{
|
||||
Genesis: "genesis.json",
|
||||
PrivValidator: "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",
|
||||
DBPath: "data",
|
||||
RPCListenAddress: "tcp://0.0.0.0:46657",
|
||||
GRPCListenAddress: "",
|
||||
}
|
||||
}
|
||||
|
||||
func TestBaseConfig() BaseConfig {
|
||||
conf := DefaultBaseConfig()
|
||||
conf.ChainID = "tendermint_test"
|
||||
conf.ProxyApp = "dummy"
|
||||
conf.FastSync = false
|
||||
conf.DBBackend = "memdb"
|
||||
conf.RPCListenAddress = "tcp://0.0.0.0:36657"
|
||||
conf.GRPCListenAddress = "tcp://0.0.0.0:36658"
|
||||
return conf
|
||||
}
|
||||
|
||||
func (b BaseConfig) GenesisFile() string {
|
||||
return rootify(b.Genesis, b.RootDir)
|
||||
}
|
||||
|
||||
func (b BaseConfig) PrivValidatorFile() string {
|
||||
return rootify(b.PrivValidator, b.RootDir)
|
||||
}
|
||||
|
||||
func (b BaseConfig) DBDir() string {
|
||||
return rootify(b.DBPath, b.RootDir)
|
||||
}
|
||||
|
||||
type P2PConfig struct {
|
||||
RootDir string `mapstructure:"home"`
|
||||
ListenAddress string `mapstructure:"laddr"`
|
||||
Seeds string `mapstructure:"seeds"`
|
||||
SkipUPNP bool `mapstructure:"skip_upnp"`
|
||||
AddrBook string `mapstructure:"addr_book_file"`
|
||||
AddrBookStrict bool `mapstructure:"addr_book_strict"`
|
||||
PexReactor bool `mapstructure:"pex"`
|
||||
MaxNumPeers int `mapstructure:"max_num_peers"`
|
||||
}
|
||||
|
||||
func DefaultP2PConfig() *P2PConfig {
|
||||
return &P2PConfig{
|
||||
ListenAddress: "tcp://0.0.0.0:46656",
|
||||
AddrBook: "addrbook.json",
|
||||
AddrBookStrict: true,
|
||||
MaxNumPeers: 50,
|
||||
}
|
||||
}
|
||||
|
||||
func TestP2PConfig() *P2PConfig {
|
||||
conf := DefaultP2PConfig()
|
||||
conf.ListenAddress = "tcp://0.0.0.0:36656"
|
||||
conf.SkipUPNP = true
|
||||
return conf
|
||||
}
|
||||
|
||||
func (p *P2PConfig) AddrBookFile() string {
|
||||
return rootify(p.AddrBook, p.RootDir)
|
||||
}
|
||||
|
||||
type MempoolConfig struct {
|
||||
RootDir string `mapstructure:"home"`
|
||||
Recheck bool `mapstructure:"recheck"`
|
||||
RecheckEmpty bool `mapstructure:"recheck_empty"`
|
||||
Broadcast bool `mapstructure:"broadcast"`
|
||||
WalPath string `mapstructure:"wal_dir"`
|
||||
}
|
||||
|
||||
func DefaultMempoolConfig() *MempoolConfig {
|
||||
return &MempoolConfig{
|
||||
Recheck: true,
|
||||
RecheckEmpty: true,
|
||||
Broadcast: true,
|
||||
WalPath: "data/mempool.wal",
|
||||
}
|
||||
}
|
||||
|
||||
func (m *MempoolConfig) WalDir() string {
|
||||
return rootify(m.WalPath, m.RootDir)
|
||||
}
|
||||
|
||||
// ConsensusConfig holds timeouts and details about the WAL, the block structure,
|
||||
// and timeouts in the consensus protocol.
|
||||
type ConsensusConfig struct {
|
||||
RootDir string `mapstructure:"home"`
|
||||
WalPath string `mapstructure:"wal_file"`
|
||||
WalLight bool `mapstructure:"wal_light"`
|
||||
walFile string // overrides WalPath if set
|
||||
|
||||
// All timeouts are in ms
|
||||
TimeoutPropose int `mapstructure:"timeout_propose"`
|
||||
TimeoutProposeDelta int `mapstructure:"timeout_propose_delta"`
|
||||
TimeoutPrevote int `mapstructure:"timeout_prevote"`
|
||||
TimeoutPrevoteDelta int `mapstructure:"timeout_prevote_delta"`
|
||||
TimeoutPrecommit int `mapstructure:"timeout_precommit"`
|
||||
TimeoutPrecommitDelta int `mapstructure:"timeout_precommit_delta"`
|
||||
TimeoutCommit int `mapstructure:"timeout_commit"`
|
||||
|
||||
// Make progress as soon as we have all the precommits (as if TimeoutCommit = 0)
|
||||
SkipTimeoutCommit bool `mapstructure:"skip_timeout_commit"`
|
||||
|
||||
// BlockSize
|
||||
MaxBlockSizeTxs int `mapstructure:"max_block_size_txs"`
|
||||
MaxBlockSizeBytes int `mapstructure:"max_block_size_bytes"`
|
||||
|
||||
// TODO: This probably shouldn't be exposed but it makes it
|
||||
// easy to write tests for the wal/replay
|
||||
BlockPartSize int `mapstructure:"block_part_size"`
|
||||
}
|
||||
|
||||
// Wait this long for a proposal
|
||||
func (cfg *ConsensusConfig) Propose(round int) time.Duration {
|
||||
return time.Duration(cfg.TimeoutPropose+cfg.TimeoutProposeDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving any +2/3 prevote, wait this long for stragglers
|
||||
func (cfg *ConsensusConfig) Prevote(round int) time.Duration {
|
||||
return time.Duration(cfg.TimeoutPrevote+cfg.TimeoutPrevoteDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving any +2/3 precommits, wait this long for stragglers
|
||||
func (cfg *ConsensusConfig) Precommit(round int) time.Duration {
|
||||
return time.Duration(cfg.TimeoutPrecommit+cfg.TimeoutPrecommitDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving +2/3 precommits for a single block (a commit), wait this long for stragglers in the next height's RoundStepNewHeight
|
||||
func (cfg *ConsensusConfig) Commit(t time.Time) time.Time {
|
||||
return t.Add(time.Duration(cfg.TimeoutCommit) * time.Millisecond)
|
||||
}
|
||||
|
||||
func DefaultConsensusConfig() *ConsensusConfig {
|
||||
return &ConsensusConfig{
|
||||
WalPath: "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, // TODO: we shouldnt be importing types
|
||||
}
|
||||
}
|
||||
|
||||
func TestConsensusConfig() *ConsensusConfig {
|
||||
config := DefaultConsensusConfig()
|
||||
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 (c *ConsensusConfig) WalFile() string {
|
||||
if c.walFile != "" {
|
||||
return c.walFile
|
||||
}
|
||||
return rootify(c.WalPath, c.RootDir)
|
||||
}
|
||||
|
||||
func (c *ConsensusConfig) SetWalFile(walFile string) {
|
||||
c.walFile = walFile
|
||||
}
|
||||
|
||||
// helper function to make config creation independent of root dir
|
||||
func rootify(path, root string) string {
|
||||
if filepath.IsAbs(path) {
|
||||
return path
|
||||
}
|
||||
return filepath.Join(root, path)
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDefaultConfig(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
// set up some defaults
|
||||
cfg := DefaultConfig()
|
||||
assert.NotNil(cfg.P2P)
|
||||
assert.NotNil(cfg.Mempool)
|
||||
assert.NotNil(cfg.Consensus)
|
||||
|
||||
// check the root dir stuff...
|
||||
cfg.SetRoot("/foo")
|
||||
cfg.Genesis = "bar"
|
||||
cfg.DBPath = "/opt/data"
|
||||
cfg.Mempool.WalPath = "wal/mem/"
|
||||
|
||||
assert.Equal("/foo/bar", cfg.GenesisFile())
|
||||
assert.Equal("/opt/data", cfg.DBDir())
|
||||
assert.Equal("/foo/wal/mem", cfg.Mempool.WalDir())
|
||||
|
||||
}
|
|
@ -1,129 +0,0 @@
|
|||
package tendermint
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
func getTMRoot(rootDir string) string {
|
||||
if rootDir == "" {
|
||||
rootDir = os.Getenv("TMHOME")
|
||||
}
|
||||
if rootDir == "" {
|
||||
// deprecated, use TMHOME (TODO: remove in TM 0.11.0)
|
||||
rootDir = os.Getenv("TMROOT")
|
||||
}
|
||||
if rootDir == "" {
|
||||
rootDir = os.Getenv("HOME") + "/.tendermint"
|
||||
}
|
||||
return rootDir
|
||||
}
|
||||
|
||||
func initTMRoot(rootDir string) {
|
||||
rootDir = getTMRoot(rootDir)
|
||||
cmn.EnsureDir(rootDir, 0700)
|
||||
cmn.EnsureDir(rootDir+"/data", 0700)
|
||||
|
||||
configFilePath := path.Join(rootDir, "config.toml")
|
||||
|
||||
// Write default config file if missing.
|
||||
if !cmn.FileExists(configFilePath) {
|
||||
// Ask user for moniker
|
||||
// moniker := cfg.Prompt("Type hostname: ", "anonymous")
|
||||
cmn.MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644)
|
||||
}
|
||||
}
|
||||
|
||||
func GetConfig(rootDir string) *viper.Viper {
|
||||
rootDir = getTMRoot(rootDir)
|
||||
initTMRoot(rootDir)
|
||||
|
||||
config := viper.New()
|
||||
config.SetConfigName("config")
|
||||
config.SetConfigType("toml")
|
||||
config.AddConfigPath(rootDir)
|
||||
err := config.ReadInConfig()
|
||||
if err != nil {
|
||||
cmn.Exit(cmn.Fmt("Could not read config from directory %v: %v", rootDir, err))
|
||||
}
|
||||
//config.WatchConfig()
|
||||
|
||||
// Set defaults or panic
|
||||
if config.IsSet("chain_id") {
|
||||
cmn.Exit("Cannot set 'chain_id' via config.toml")
|
||||
}
|
||||
if config.IsSet("revision_file") {
|
||||
cmn.Exit("Cannot set 'revision_file' via config.toml. It must match what's in the Makefile")
|
||||
}
|
||||
//mapConfig.SetRequired("chain_id") // blows up if you try to use it before setting.
|
||||
config.SetDefault("genesis_file", rootDir+"/genesis.json")
|
||||
config.SetDefault("proxy_app", "tcp://127.0.0.1:46658")
|
||||
config.SetDefault("abci", "socket")
|
||||
config.SetDefault("moniker", "anonymous")
|
||||
config.SetDefault("node_laddr", "tcp://0.0.0.0:46656")
|
||||
config.SetDefault("seeds", "")
|
||||
// config.SetDefault("seeds", "goldenalchemist.chaintest.net:46656")
|
||||
config.SetDefault("fast_sync", true)
|
||||
config.SetDefault("skip_upnp", false)
|
||||
config.SetDefault("addrbook_file", rootDir+"/addrbook.json")
|
||||
config.SetDefault("addrbook_strict", true) // disable to allow connections locally
|
||||
config.SetDefault("pex_reactor", false) // enable for peer exchange
|
||||
config.SetDefault("priv_validator_file", rootDir+"/priv_validator.json")
|
||||
config.SetDefault("db_backend", "leveldb")
|
||||
config.SetDefault("db_dir", rootDir+"/data")
|
||||
config.SetDefault("log_level", "info")
|
||||
config.SetDefault("rpc_laddr", "tcp://0.0.0.0:46657")
|
||||
config.SetDefault("grpc_laddr", "")
|
||||
config.SetDefault("prof_laddr", "")
|
||||
config.SetDefault("revision_file", rootDir+"/revision")
|
||||
config.SetDefault("cs_wal_file", rootDir+"/data/cs.wal/wal")
|
||||
config.SetDefault("cs_wal_light", false)
|
||||
config.SetDefault("filter_peers", false)
|
||||
|
||||
config.SetDefault("block_size", 10000) // max number of txs
|
||||
config.SetDefault("block_part_size", 65536) // part size 64K
|
||||
config.SetDefault("disable_data_hash", false)
|
||||
|
||||
// all timeouts are in ms
|
||||
config.SetDefault("timeout_handshake", 10000)
|
||||
config.SetDefault("timeout_propose", 3000)
|
||||
config.SetDefault("timeout_propose_delta", 500)
|
||||
config.SetDefault("timeout_prevote", 1000)
|
||||
config.SetDefault("timeout_prevote_delta", 500)
|
||||
config.SetDefault("timeout_precommit", 1000)
|
||||
config.SetDefault("timeout_precommit_delta", 500)
|
||||
config.SetDefault("timeout_commit", 1000)
|
||||
|
||||
// make progress asap (no `timeout_commit`) on full precommit votes
|
||||
config.SetDefault("skip_timeout_commit", false)
|
||||
config.SetDefault("mempool_recheck", true)
|
||||
config.SetDefault("mempool_recheck_empty", true)
|
||||
config.SetDefault("mempool_broadcast", true)
|
||||
config.SetDefault("mempool_wal_dir", rootDir+"/data/mempool.wal")
|
||||
|
||||
config.SetDefault("tx_index", "kv")
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
var defaultConfigTmpl = `# This is a TOML config file.
|
||||
# For more information, see https://github.com/toml-lang/toml
|
||||
|
||||
proxy_app = "tcp://127.0.0.1:46658"
|
||||
moniker = "__MONIKER__"
|
||||
node_laddr = "tcp://0.0.0.0:46656"
|
||||
seeds = ""
|
||||
fast_sync = true
|
||||
db_backend = "leveldb"
|
||||
log_level = "notice"
|
||||
rpc_laddr = "tcp://0.0.0.0:46657"
|
||||
`
|
||||
|
||||
func defaultConfig(moniker string) (defaultConfig string) {
|
||||
defaultConfig = strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1)
|
||||
return
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
// If you wanted to use logrotate, I suppose this might be the config you want.
|
||||
// Instead, I'll just write our own, that way we don't need sudo to install.
|
||||
|
||||
$HOME/.tendermint/logs/tendermint.log {
|
||||
missingok
|
||||
notifempty
|
||||
rotate 12
|
||||
daily
|
||||
size 10M
|
||||
compress
|
||||
delaycompress
|
||||
}
|
||||
|
||||
$HOME/.barak/logs/barak.log {
|
||||
missingok
|
||||
notifempty
|
||||
rotate 12
|
||||
weekly
|
||||
size 10M
|
||||
compress
|
||||
delaycompress
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
// Import this in all *_test.go files to initialize ~/.tendermint_test.
|
||||
|
||||
package tendermint_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/logger"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// Creates ~/.tendermint_test
|
||||
EnsureDir(os.Getenv("HOME")+"/.tendermint_test", 0700)
|
||||
}
|
||||
|
||||
func initTMRoot(rootDir string) {
|
||||
// Remove ~/.tendermint_test_bak
|
||||
if FileExists(rootDir + "_bak") {
|
||||
err := os.RemoveAll(rootDir + "_bak")
|
||||
if err != nil {
|
||||
PanicSanity(err.Error())
|
||||
}
|
||||
}
|
||||
// Move ~/.tendermint_test to ~/.tendermint_test_bak
|
||||
if FileExists(rootDir) {
|
||||
err := os.Rename(rootDir, rootDir+"_bak")
|
||||
if err != nil {
|
||||
PanicSanity(err.Error())
|
||||
}
|
||||
}
|
||||
// Create new dir
|
||||
EnsureDir(rootDir, 0700)
|
||||
EnsureDir(rootDir+"/data", 0700)
|
||||
|
||||
configFilePath := path.Join(rootDir, "config.toml")
|
||||
genesisFilePath := path.Join(rootDir, "genesis.json")
|
||||
privFilePath := path.Join(rootDir, "priv_validator.json")
|
||||
|
||||
// Write default config file if missing.
|
||||
if !FileExists(configFilePath) {
|
||||
// Ask user for moniker
|
||||
MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644)
|
||||
}
|
||||
if !FileExists(genesisFilePath) {
|
||||
MustWriteFile(genesisFilePath, []byte(defaultGenesis), 0644)
|
||||
}
|
||||
// we always overwrite the priv val
|
||||
MustWriteFile(privFilePath, []byte(defaultPrivValidator), 0644)
|
||||
}
|
||||
|
||||
func ResetConfig(localPath string) *viper.Viper {
|
||||
rootDir := os.Getenv("HOME") + "/.tendermint_test/" + localPath
|
||||
initTMRoot(rootDir)
|
||||
|
||||
config := viper.New()
|
||||
config.SetConfigName("config")
|
||||
config.SetConfigType("toml")
|
||||
config.AddConfigPath(rootDir)
|
||||
err := config.ReadInConfig()
|
||||
if err != nil {
|
||||
Exit(Fmt("Could not read config: %v", err))
|
||||
}
|
||||
//config.WatchConfig()
|
||||
|
||||
// Set defaults or panic
|
||||
if config.IsSet("chain_id") {
|
||||
Exit(fmt.Sprintf("Cannot set 'chain_id' via config.toml:\n %v\n %v\n ", config.Get("chain_id"), rootDir))
|
||||
}
|
||||
|
||||
config.SetDefault("chain_id", "tendermint_test")
|
||||
config.SetDefault("genesis_file", rootDir+"/genesis.json")
|
||||
config.SetDefault("proxy_app", "dummy")
|
||||
config.SetDefault("abci", "socket")
|
||||
config.SetDefault("moniker", "anonymous")
|
||||
config.SetDefault("node_laddr", "tcp://0.0.0.0:36656")
|
||||
config.SetDefault("fast_sync", false)
|
||||
config.SetDefault("skip_upnp", true)
|
||||
config.SetDefault("addrbook_file", rootDir+"/addrbook.json")
|
||||
config.SetDefault("addrbook_strict", true) // disable to allow connections locally
|
||||
config.SetDefault("pex_reactor", false) // enable for peer exchange
|
||||
config.SetDefault("priv_validator_file", rootDir+"/priv_validator.json")
|
||||
config.SetDefault("db_backend", "memdb")
|
||||
config.SetDefault("db_dir", rootDir+"/data")
|
||||
config.SetDefault("log_level", "info")
|
||||
config.SetDefault("rpc_laddr", "tcp://0.0.0.0:36657")
|
||||
config.SetDefault("grpc_laddr", "tcp://0.0.0.0:36658")
|
||||
config.SetDefault("prof_laddr", "")
|
||||
config.SetDefault("revision_file", rootDir+"/revision")
|
||||
config.SetDefault("cs_wal_file", rootDir+"/data/cs.wal/wal")
|
||||
config.SetDefault("cs_wal_light", false)
|
||||
config.SetDefault("filter_peers", false)
|
||||
|
||||
config.SetDefault("block_size", 10000)
|
||||
config.SetDefault("block_part_size", 65536) // part size 64K
|
||||
config.SetDefault("disable_data_hash", false)
|
||||
config.SetDefault("timeout_handshake", 10000)
|
||||
config.SetDefault("timeout_propose", 2000)
|
||||
config.SetDefault("timeout_propose_delta", 1)
|
||||
config.SetDefault("timeout_prevote", 10)
|
||||
config.SetDefault("timeout_prevote_delta", 1)
|
||||
config.SetDefault("timeout_precommit", 10)
|
||||
config.SetDefault("timeout_precommit_delta", 1)
|
||||
config.SetDefault("timeout_commit", 10)
|
||||
config.SetDefault("skip_timeout_commit", true)
|
||||
config.SetDefault("mempool_recheck", true)
|
||||
config.SetDefault("mempool_recheck_empty", true)
|
||||
config.SetDefault("mempool_broadcast", true)
|
||||
config.SetDefault("mempool_wal_dir", "")
|
||||
|
||||
config.SetDefault("tx_index", "kv")
|
||||
|
||||
logger.SetLogLevel(config.GetString("log_level"))
|
||||
|
||||
return config
|
||||
}
|
||||
|
||||
var defaultConfigTmpl = `# This is a TOML config file.
|
||||
# For more information, see https://github.com/toml-lang/toml
|
||||
|
||||
proxy_app = "dummy"
|
||||
moniker = "__MONIKER__"
|
||||
node_laddr = "tcp://0.0.0.0:36656"
|
||||
seeds = ""
|
||||
fast_sync = false
|
||||
db_backend = "memdb"
|
||||
log_level = "info"
|
||||
rpc_laddr = "tcp://0.0.0.0:36657"
|
||||
`
|
||||
|
||||
func defaultConfig(moniker string) (defaultConfig string) {
|
||||
defaultConfig = strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1)
|
||||
return
|
||||
}
|
||||
|
||||
var defaultGenesis = `{
|
||||
"genesis_time": "0001-01-01T00:00:00.000Z",
|
||||
"chain_id": "tendermint_test",
|
||||
"validators": [
|
||||
{
|
||||
"pub_key": {
|
||||
"type": "ed25519",
|
||||
"data":"3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"amount": 10,
|
||||
"name": ""
|
||||
}
|
||||
],
|
||||
"app_hash": ""
|
||||
}`
|
||||
|
||||
var defaultPrivValidator = `{
|
||||
"address": "D028C9981F7A87F3093672BF0D5B0E2A1B3ED456",
|
||||
"pub_key": {
|
||||
"type": "ed25519",
|
||||
"data": "3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"priv_key": {
|
||||
"type": "ed25519",
|
||||
"data": "27F82582AEFAE7AB151CFB01C48BB6C1A0DA78F9BDDA979A9F70A84D074EB07D3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"last_height": 0,
|
||||
"last_round": 0,
|
||||
"last_step": 0
|
||||
}`
|
|
@ -0,0 +1,137 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tmlibs/logger"
|
||||
)
|
||||
|
||||
/****** these are for production settings ***********/
|
||||
|
||||
func EnsureRoot(rootDir string) {
|
||||
cmn.EnsureDir(rootDir, 0700)
|
||||
cmn.EnsureDir(rootDir+"/data", 0700)
|
||||
|
||||
configFilePath := path.Join(rootDir, "config.toml")
|
||||
|
||||
// Write default config file if missing.
|
||||
if !cmn.FileExists(configFilePath) {
|
||||
// Ask user for moniker
|
||||
// moniker := cfg.Prompt("Type hostname: ", "anonymous")
|
||||
cmn.MustWriteFile(configFilePath, []byte(defaultConfig("anonymous")), 0644)
|
||||
}
|
||||
}
|
||||
|
||||
var defaultConfigTmpl = `# This is a TOML config file.
|
||||
# For more information, see https://github.com/toml-lang/toml
|
||||
|
||||
proxy_app = "tcp://127.0.0.1:46658"
|
||||
moniker = "__MONIKER__"
|
||||
node_laddr = "tcp://0.0.0.0:46656"
|
||||
seeds = ""
|
||||
fast_sync = true
|
||||
db_backend = "leveldb"
|
||||
log_level = "notice"
|
||||
rpc_laddr = "tcp://0.0.0.0:46657"
|
||||
`
|
||||
|
||||
func defaultConfig(moniker string) (defaultConfig string) {
|
||||
defaultConfig = strings.Replace(defaultConfigTmpl, "__MONIKER__", moniker, -1)
|
||||
return
|
||||
}
|
||||
|
||||
/****** these are for test settings ***********/
|
||||
|
||||
func ResetTestRoot(testName string) *Config {
|
||||
rootDir := os.ExpandEnv("$HOME/.tendermint_test")
|
||||
rootDir = filepath.Join(rootDir, testName)
|
||||
// Remove ~/.tendermint_test_bak
|
||||
if cmn.FileExists(rootDir + "_bak") {
|
||||
err := os.RemoveAll(rootDir + "_bak")
|
||||
if err != nil {
|
||||
cmn.PanicSanity(err.Error())
|
||||
}
|
||||
}
|
||||
// Move ~/.tendermint_test to ~/.tendermint_test_bak
|
||||
if cmn.FileExists(rootDir) {
|
||||
err := os.Rename(rootDir, rootDir+"_bak")
|
||||
if err != nil {
|
||||
cmn.PanicSanity(err.Error())
|
||||
}
|
||||
}
|
||||
// Create new dir
|
||||
cmn.EnsureDir(rootDir, 0700)
|
||||
cmn.EnsureDir(rootDir+"/data", 0700)
|
||||
|
||||
configFilePath := path.Join(rootDir, "config.toml")
|
||||
genesisFilePath := path.Join(rootDir, "genesis.json")
|
||||
privFilePath := path.Join(rootDir, "priv_validator.json")
|
||||
|
||||
// Write default config file if missing.
|
||||
if !cmn.FileExists(configFilePath) {
|
||||
// Ask user for moniker
|
||||
cmn.MustWriteFile(configFilePath, []byte(testConfig("anonymous")), 0644)
|
||||
}
|
||||
if !cmn.FileExists(genesisFilePath) {
|
||||
cmn.MustWriteFile(genesisFilePath, []byte(testGenesis), 0644)
|
||||
}
|
||||
// we always overwrite the priv val
|
||||
cmn.MustWriteFile(privFilePath, []byte(testPrivValidator), 0644)
|
||||
|
||||
config := TestConfig().SetRoot(rootDir)
|
||||
logger.SetLogLevel(config.LogLevel)
|
||||
return config
|
||||
}
|
||||
|
||||
var testConfigTmpl = `# This is a TOML config file.
|
||||
# For more information, see https://github.com/toml-lang/toml
|
||||
|
||||
proxy_app = "dummy"
|
||||
moniker = "__MONIKER__"
|
||||
node_laddr = "tcp://0.0.0.0:36656"
|
||||
seeds = ""
|
||||
fast_sync = false
|
||||
db_backend = "memdb"
|
||||
log_level = "info"
|
||||
rpc_laddr = "tcp://0.0.0.0:36657"
|
||||
`
|
||||
|
||||
func testConfig(moniker string) (testConfig string) {
|
||||
testConfig = strings.Replace(testConfigTmpl, "__MONIKER__", moniker, -1)
|
||||
return
|
||||
}
|
||||
|
||||
var testGenesis = `{
|
||||
"genesis_time": "0001-01-01T00:00:00.000Z",
|
||||
"chain_id": "tendermint_test",
|
||||
"validators": [
|
||||
{
|
||||
"pub_key": {
|
||||
"type": "ed25519",
|
||||
"data":"3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"amount": 10,
|
||||
"name": ""
|
||||
}
|
||||
],
|
||||
"app_hash": ""
|
||||
}`
|
||||
|
||||
var testPrivValidator = `{
|
||||
"address": "D028C9981F7A87F3093672BF0D5B0E2A1B3ED456",
|
||||
"pub_key": {
|
||||
"type": "ed25519",
|
||||
"data": "3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"priv_key": {
|
||||
"type": "ed25519",
|
||||
"data": "27F82582AEFAE7AB151CFB01C48BB6C1A0DA78F9BDDA979A9F70A84D074EB07D3B3069C422E19688B45CBFAE7BB009FC0FA1B1EA86593519318B7214853803C8"
|
||||
},
|
||||
"last_height": 0,
|
||||
"last_round": 0,
|
||||
"last_step": 0
|
||||
}`
|
|
@ -0,0 +1,57 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func ensureFiles(t *testing.T, rootDir string, files ...string) {
|
||||
for _, f := range files {
|
||||
p := rootify(rootDir, f)
|
||||
_, err := os.Stat(p)
|
||||
assert.Nil(t, err, p)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEnsureRoot(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
// setup temp dir for test
|
||||
tmpDir, err := ioutil.TempDir("", "config-test")
|
||||
require.Nil(err)
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
// create root dir
|
||||
EnsureRoot(tmpDir)
|
||||
|
||||
// make sure config is set properly
|
||||
data, err := ioutil.ReadFile(filepath.Join(tmpDir, "config.toml"))
|
||||
require.Nil(err)
|
||||
assert.Equal([]byte(defaultConfig("anonymous")), data)
|
||||
|
||||
ensureFiles(t, tmpDir, "data")
|
||||
}
|
||||
|
||||
func TestEnsureTestRoot(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
testName := "ensureTestRoot"
|
||||
|
||||
// create root dir
|
||||
cfg := ResetTestRoot(testName)
|
||||
rootDir := cfg.RootDir
|
||||
|
||||
// make sure config is set properly
|
||||
data, err := ioutil.ReadFile(filepath.Join(rootDir, "config.toml"))
|
||||
require.Nil(err)
|
||||
assert.Equal([]byte(testConfig("anonymous")), data)
|
||||
|
||||
// TODO: make sure the cfg returned and testconfig are the same!
|
||||
|
||||
ensureFiles(t, rootDir, "data", "genesis.json", "priv_validator.json")
|
||||
}
|
|
@ -5,9 +5,6 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
|
@ -15,7 +12,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
config = tendermint_test.ResetConfig("consensus_byzantine_test")
|
||||
config = ResetConfig("consensus_byzantine_test")
|
||||
}
|
||||
|
||||
//----------------------------------------------
|
||||
|
@ -36,7 +33,7 @@ func TestByzantine(t *testing.T) {
|
|||
|
||||
switches := make([]*p2p.Switch, N)
|
||||
for i := 0; i < N; i++ {
|
||||
switches[i] = p2p.NewSwitch(viper.New())
|
||||
switches[i] = p2p.NewSwitch(config.P2P)
|
||||
}
|
||||
|
||||
reactors := make([]p2p.Reactor, N)
|
||||
|
@ -80,7 +77,7 @@ func TestByzantine(t *testing.T) {
|
|||
reactors[i] = conRI
|
||||
}
|
||||
|
||||
p2p.MakeConnectedSwitches(N, func(i int, s *p2p.Switch) *p2p.Switch {
|
||||
p2p.MakeConnectedSwitches(config.P2P, N, func(i int, s *p2p.Switch) *p2p.Switch {
|
||||
// ignore new switch s, we already made ours
|
||||
switches[i].AddReactor("CONSENSUS", reactors[i])
|
||||
return switches[i]
|
||||
|
|
|
@ -11,12 +11,10 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
abcicli "github.com/tendermint/abci/client"
|
||||
abci "github.com/tendermint/abci/types"
|
||||
bc "github.com/tendermint/tendermint/blockchain"
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
mempl "github.com/tendermint/tendermint/mempool"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
|
@ -28,7 +26,8 @@ import (
|
|||
"github.com/tendermint/abci/example/dummy"
|
||||
)
|
||||
|
||||
var config *viper.Viper // NOTE: must be reset for each _test.go file
|
||||
// genesis, chain_id, priv_val
|
||||
var config *cfg.Config // NOTE: must be reset for each _test.go file
|
||||
var ensureTimeout = time.Duration(2)
|
||||
|
||||
func ensureDir(dir string, mode os.FileMode) {
|
||||
|
@ -37,6 +36,10 @@ func ensureDir(dir string, mode os.FileMode) {
|
|||
}
|
||||
}
|
||||
|
||||
func ResetConfig(name string) *cfg.Config {
|
||||
return cfg.ResetTestRoot(name)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------
|
||||
// validator stub (a dummy consensus peer we control)
|
||||
|
||||
|
@ -65,7 +68,7 @@ func (vs *validatorStub) signVote(voteType byte, hash []byte, header types.PartS
|
|||
Type: voteType,
|
||||
BlockID: types.BlockID{hash, header},
|
||||
}
|
||||
err := vs.PrivValidator.SignVote(config.GetString("chain_id"), vote)
|
||||
err := vs.PrivValidator.SignVote(config.ChainID, vote)
|
||||
return vote, err
|
||||
}
|
||||
|
||||
|
@ -116,7 +119,7 @@ func decideProposal(cs1 *ConsensusState, vs *validatorStub, height, round int) (
|
|||
// Make proposal
|
||||
polRound, polBlockID := cs1.Votes.POLInfo()
|
||||
proposal = types.NewProposal(height, round, blockParts.Header(), polRound, polBlockID)
|
||||
if err := vs.SignProposal(config.GetString("chain_id"), proposal); err != nil {
|
||||
if err := vs.SignProposal(config.ChainID, proposal); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
|
@ -234,7 +237,7 @@ func newConsensusState(state *sm.State, pv *types.PrivValidator, app abci.Applic
|
|||
return newConsensusStateWithConfig(config, state, pv, app)
|
||||
}
|
||||
|
||||
func newConsensusStateWithConfig(thisConfig *viper.Viper, state *sm.State, pv *types.PrivValidator, app abci.Application) *ConsensusState {
|
||||
func newConsensusStateWithConfig(thisConfig *cfg.Config, state *sm.State, pv *types.PrivValidator, app abci.Application) *ConsensusState {
|
||||
// Get BlockStore
|
||||
blockDB := dbm.NewMemDB()
|
||||
blockStore := bc.NewBlockStore(blockDB)
|
||||
|
@ -245,10 +248,10 @@ func newConsensusStateWithConfig(thisConfig *viper.Viper, state *sm.State, pv *t
|
|||
proxyAppConnCon := abcicli.NewLocalClient(mtx, app)
|
||||
|
||||
// Make Mempool
|
||||
mempool := mempl.NewMempool(thisConfig, proxyAppConnMem)
|
||||
mempool := mempl.NewMempool(thisConfig.Mempool, proxyAppConnMem)
|
||||
|
||||
// Make ConsensusReactor
|
||||
cs := NewConsensusState(thisConfig, state, proxyAppConnCon, blockStore, mempool)
|
||||
cs := NewConsensusState(thisConfig.Consensus, state, proxyAppConnCon, blockStore, mempool)
|
||||
cs.SetPrivValidator(pv)
|
||||
|
||||
evsw := types.NewEventSwitch()
|
||||
|
@ -257,8 +260,8 @@ func newConsensusStateWithConfig(thisConfig *viper.Viper, state *sm.State, pv *t
|
|||
return cs
|
||||
}
|
||||
|
||||
func loadPrivValidator(conf *viper.Viper) *types.PrivValidator {
|
||||
privValidatorFile := conf.GetString("priv_validator_file")
|
||||
func loadPrivValidator(config *cfg.Config) *types.PrivValidator {
|
||||
privValidatorFile := config.PrivValidatorFile()
|
||||
ensureDir(path.Dir(privValidatorFile), 0700)
|
||||
privValidator := types.LoadOrGenPrivValidator(privValidatorFile)
|
||||
privValidator.Reset()
|
||||
|
@ -267,7 +270,7 @@ func loadPrivValidator(conf *viper.Viper) *types.PrivValidator {
|
|||
|
||||
func fixedConsensusState() *ConsensusState {
|
||||
stateDB := dbm.NewMemDB()
|
||||
state := sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file"))
|
||||
state := sm.MakeGenesisStateFromFile(stateDB, config.GenesisFile())
|
||||
privValidator := loadPrivValidator(config)
|
||||
cs := newConsensusState(state, privValidator, counter.NewCounterApplication(true))
|
||||
return cs
|
||||
|
@ -275,7 +278,7 @@ func fixedConsensusState() *ConsensusState {
|
|||
|
||||
func fixedConsensusStateDummy() *ConsensusState {
|
||||
stateDB := dbm.NewMemDB()
|
||||
state := sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file"))
|
||||
state := sm.MakeGenesisStateFromFile(stateDB, config.GenesisFile())
|
||||
privValidator := loadPrivValidator(config)
|
||||
cs := newConsensusState(state, privValidator, dummy.NewDummyApplication())
|
||||
return cs
|
||||
|
@ -320,8 +323,8 @@ func randConsensusNet(nValidators int, testName string, tickerFunc func() Timeou
|
|||
db := dbm.NewMemDB() // each state needs its own db
|
||||
state := sm.MakeGenesisState(db, genDoc)
|
||||
state.Save()
|
||||
thisConfig := tendermint_test.ResetConfig(Fmt("%s_%d", testName, i))
|
||||
ensureDir(path.Dir(thisConfig.GetString("cs_wal_file")), 0700) // dir for wal
|
||||
thisConfig := ResetConfig(Fmt("%s_%d", testName, i))
|
||||
ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
|
||||
css[i] = newConsensusStateWithConfig(thisConfig, state, privVals[i], appFunc())
|
||||
css[i].SetTimeoutTicker(tickerFunc())
|
||||
}
|
||||
|
@ -336,8 +339,8 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF
|
|||
db := dbm.NewMemDB() // each state needs its own db
|
||||
state := sm.MakeGenesisState(db, genDoc)
|
||||
state.Save()
|
||||
thisConfig := tendermint_test.ResetConfig(Fmt("%s_%d", testName, i))
|
||||
ensureDir(path.Dir(thisConfig.GetString("cs_wal_file")), 0700) // dir for wal
|
||||
thisConfig := ResetConfig(Fmt("%s_%d", testName, i))
|
||||
ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
|
||||
var privVal *types.PrivValidator
|
||||
if i < nValidators {
|
||||
privVal = privVals[i]
|
||||
|
@ -380,7 +383,7 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G
|
|||
sort.Sort(types.PrivValidatorsByAddress(privValidators))
|
||||
return &types.GenesisDoc{
|
||||
GenesisTime: time.Now(),
|
||||
ChainID: config.GetString("chain_id"),
|
||||
ChainID: config.ChainID,
|
||||
Validators: validators,
|
||||
}, privValidators
|
||||
}
|
||||
|
|
|
@ -3,19 +3,18 @@ package consensus
|
|||
import (
|
||||
"testing"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
func init() {
|
||||
config = tendermint_test.ResetConfig("consensus_height_vote_set_test")
|
||||
config = ResetConfig("consensus_height_vote_set_test")
|
||||
}
|
||||
|
||||
func TestPeerCatchupRounds(t *testing.T) {
|
||||
valSet, privVals := types.RandValidatorSet(10, 1)
|
||||
|
||||
hvs := NewHeightVoteSet(config.GetString("chain_id"), 1, valSet)
|
||||
hvs := NewHeightVoteSet(config.ChainID, 1, valSet)
|
||||
|
||||
vote999_0 := makeVoteHR(t, 1, 999, privVals, 0)
|
||||
added, err := hvs.AddVote(vote999_0, "peer1")
|
||||
|
@ -52,7 +51,7 @@ func makeVoteHR(t *testing.T, height, round int, privVals []*types.PrivValidator
|
|||
Type: types.VoteTypePrecommit,
|
||||
BlockID: types.BlockID{[]byte("fakehash"), types.PartSetHeader{}},
|
||||
}
|
||||
chainID := config.GetString("chain_id")
|
||||
chainID := config.ChainID
|
||||
err := privVal.SignVote(chainID, vote)
|
||||
if err != nil {
|
||||
panic(Fmt("Error signing vote: %v", err))
|
||||
|
|
|
@ -6,14 +6,13 @@ import (
|
|||
"time"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
func init() {
|
||||
config = tendermint_test.ResetConfig("consensus_mempool_test")
|
||||
config = ResetConfig("consensus_mempool_test")
|
||||
}
|
||||
|
||||
func TestTxConcurrentWithCommit(t *testing.T) {
|
||||
|
|
|
@ -6,8 +6,6 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
|
||||
"github.com/tendermint/abci/example/dummy"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
|
@ -15,7 +13,7 @@ import (
|
|||
)
|
||||
|
||||
func init() {
|
||||
config = tendermint_test.ResetConfig("consensus_reactor_test")
|
||||
config = ResetConfig("consensus_reactor_test")
|
||||
}
|
||||
|
||||
//----------------------------------------------
|
||||
|
@ -41,7 +39,7 @@ func startConsensusNet(t *testing.T, css []*ConsensusState, N int, subscribeEven
|
|||
}
|
||||
}
|
||||
// make connected switches and start all reactors
|
||||
p2p.MakeConnectedSwitches(N, func(i int, s *p2p.Switch) *p2p.Switch {
|
||||
p2p.MakeConnectedSwitches(config.P2P, N, func(i int, s *p2p.Switch) *p2p.Switch {
|
||||
s.AddReactor("CONSENSUS", reactors[i])
|
||||
return s
|
||||
}, p2p.Connect2Switches)
|
||||
|
@ -236,7 +234,7 @@ func TestReactorWithTimeoutCommit(t *testing.T) {
|
|||
css := randConsensusNet(N, "consensus_reactor_with_timeout_commit_test", newMockTickerFunc(false), newCounter)
|
||||
// override default SkipTimeoutCommit == true for tests
|
||||
for i := 0; i < N; i++ {
|
||||
css[i].timeoutParams.SkipTimeoutCommit = false
|
||||
css[i].config.SkipTimeoutCommit = false
|
||||
}
|
||||
|
||||
reactors, eventChans := startConsensusNet(t, css, N-1, false)
|
||||
|
|
|
@ -10,8 +10,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/go-wire"
|
||||
auto "github.com/tendermint/tmlibs/autofile"
|
||||
|
@ -200,15 +198,14 @@ func makeHeightSearchFunc(height int) auto.SearchFunc {
|
|||
// we were last and using the WAL to recover there
|
||||
|
||||
type Handshaker struct {
|
||||
config *viper.Viper
|
||||
state *sm.State
|
||||
store types.BlockStore
|
||||
state *sm.State
|
||||
store types.BlockStore
|
||||
|
||||
nBlocks int // number of blocks applied to the state
|
||||
}
|
||||
|
||||
func NewHandshaker(config *viper.Viper, state *sm.State, store types.BlockStore) *Handshaker {
|
||||
return &Handshaker{config, state, store, 0}
|
||||
func NewHandshaker(state *sm.State, store types.BlockStore) *Handshaker {
|
||||
return &Handshaker{state, store, 0}
|
||||
}
|
||||
|
||||
func (h *Handshaker) NBlocks() int {
|
||||
|
|
|
@ -8,10 +8,8 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
bc "github.com/tendermint/tendermint/blockchain"
|
||||
mempl "github.com/tendermint/tendermint/mempool"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
|
@ -22,10 +20,10 @@ import (
|
|||
//--------------------------------------------------------
|
||||
// replay messages interactively or all at once
|
||||
|
||||
func RunReplayFile(config *viper.Viper, walFile string, console bool) {
|
||||
consensusState := newConsensusStateForReplay(config)
|
||||
func RunReplayFile(config cfg.BaseConfig, csConfig *cfg.ConsensusConfig, console bool) {
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
@ -237,34 +235,30 @@ func (pb *playback) replayConsoleLoop() int {
|
|||
//--------------------------------------------------------------------------------
|
||||
|
||||
// convenience for replay mode
|
||||
func newConsensusStateForReplay(config *viper.Viper) *ConsensusState {
|
||||
func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cfg.ConsensusConfig) *ConsensusState {
|
||||
// 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)
|
||||
|
||||
// Get State
|
||||
stateDB := dbm.NewDB("state", config.GetString("db_backend"), config.GetString("db_dir"))
|
||||
state := sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file"))
|
||||
stateDB := dbm.NewDB("state", config.DBBackend, config.DBDir())
|
||||
state := sm.MakeGenesisStateFromFile(stateDB, config.GenesisFile())
|
||||
|
||||
// Create proxyAppConn connection (consensus, mempool, query)
|
||||
proxyApp := proxy.NewAppConns(config, proxy.DefaultClientCreator(config), NewHandshaker(config, state, blockStore))
|
||||
clientCreator := proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir())
|
||||
proxyApp := proxy.NewAppConns(clientCreator, NewHandshaker(state, blockStore))
|
||||
_, err := proxyApp.Start()
|
||||
if err != nil {
|
||||
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
|
||||
eventSwitch := types.NewEventSwitch()
|
||||
if _, err := eventSwitch.Start(); err != nil {
|
||||
cmn.Exit(cmn.Fmt("Failed to start event switch: %v", err))
|
||||
}
|
||||
|
||||
mempool := mempl.NewMempool(config, proxyApp.Mempool())
|
||||
|
||||
consensusState := NewConsensusState(config, state.Copy(), proxyApp.Consensus(), blockStore, mempool)
|
||||
consensusState := NewConsensusState(csConfig, state.Copy(), proxyApp.Consensus(), blockStore, types.MockMempool{})
|
||||
consensusState.SetEventSwitch(eventSwitch)
|
||||
return consensusState
|
||||
}
|
||||
|
|
|
@ -12,21 +12,20 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/tendermint/abci/example/dummy"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
)
|
||||
|
||||
func init() {
|
||||
config = tendermint_test.ResetConfig("consensus_replay_test")
|
||||
config = ResetConfig("consensus_replay_test")
|
||||
}
|
||||
|
||||
// These tests ensure we can always recover from failure at any part of the consensus process.
|
||||
|
@ -136,7 +135,7 @@ func waitForBlock(newBlockCh chan interface{}, thisCase *testCase, i int) {
|
|||
func runReplayTest(t *testing.T, cs *ConsensusState, walFile string, newBlockCh chan interface{},
|
||||
thisCase *testCase, i int) {
|
||||
|
||||
cs.config.Set("cs_wal_file", walFile)
|
||||
cs.config.SetWalFile(walFile)
|
||||
started, err := cs.Start()
|
||||
if err != nil {
|
||||
t.Fatalf("Cannot start consensus: %v", err)
|
||||
|
@ -309,7 +308,7 @@ func TestHandshakeReplayNone(t *testing.T) {
|
|||
|
||||
// Make some blocks. Start a fresh app and apply nBlocks blocks. Then restart the app and sync it up with the remaining blocks
|
||||
func testHandshakeReplay(t *testing.T, nBlocks int, mode uint) {
|
||||
config := tendermint_test.ResetConfig("proxy_test_")
|
||||
config := ResetConfig("proxy_test_")
|
||||
|
||||
// copy the many_blocks file
|
||||
walBody, err := cmn.ReadFile(path.Join(data_dir, "many_blocks.cswal"))
|
||||
|
@ -317,10 +316,10 @@ func testHandshakeReplay(t *testing.T, nBlocks int, mode uint) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
walFile := writeWAL(string(walBody))
|
||||
config.Set("cs_wal_file", walFile)
|
||||
config.Consensus.SetWalFile(walFile)
|
||||
|
||||
privVal := types.LoadPrivValidator(config.GetString("priv_validator_file"))
|
||||
testPartSize = config.GetInt("block_part_size")
|
||||
privVal := types.LoadPrivValidator(config.PrivValidatorFile())
|
||||
testPartSize = config.Consensus.BlockPartSize
|
||||
|
||||
wal, err := NewWAL(walFile, false)
|
||||
if err != nil {
|
||||
|
@ -339,19 +338,19 @@ func testHandshakeReplay(t *testing.T, nBlocks int, mode uint) {
|
|||
latestAppHash := buildTMStateFromChain(config, state, chain, mode)
|
||||
|
||||
// make a new client creator
|
||||
dummyApp := dummy.NewPersistentDummyApplication(path.Join(config.GetString("db_dir"), "2"))
|
||||
dummyApp := dummy.NewPersistentDummyApplication(path.Join(config.DBDir(), "2"))
|
||||
clientCreator2 := proxy.NewLocalClientCreator(dummyApp)
|
||||
if nBlocks > 0 {
|
||||
// run nBlocks against a new client to build up the app state.
|
||||
// use a throwaway tendermint state
|
||||
proxyApp := proxy.NewAppConns(config, clientCreator2, nil)
|
||||
proxyApp := proxy.NewAppConns(clientCreator2, nil)
|
||||
state, _ := stateAndStore(config, privVal.PubKey)
|
||||
buildAppStateFromChain(proxyApp, state, chain, nBlocks, mode)
|
||||
}
|
||||
|
||||
// now start the app using the handshake - it should sync
|
||||
handshaker := NewHandshaker(config, state, store)
|
||||
proxyApp := proxy.NewAppConns(config, clientCreator2, handshaker)
|
||||
handshaker := NewHandshaker(state, store)
|
||||
proxyApp := proxy.NewAppConns(clientCreator2, handshaker)
|
||||
if _, err := proxyApp.Start(); err != nil {
|
||||
t.Fatalf("Error starting proxy app connections: %v", err)
|
||||
}
|
||||
|
@ -418,10 +417,10 @@ func buildAppStateFromChain(proxyApp proxy.AppConns,
|
|||
|
||||
}
|
||||
|
||||
func buildTMStateFromChain(config *viper.Viper, state *sm.State, chain []*types.Block, mode uint) []byte {
|
||||
func buildTMStateFromChain(config *cfg.Config, state *sm.State, chain []*types.Block, mode uint) []byte {
|
||||
// run the whole chain against this client to build up the tendermint state
|
||||
clientCreator := proxy.NewLocalClientCreator(dummy.NewPersistentDummyApplication(path.Join(config.GetString("db_dir"), "1")))
|
||||
proxyApp := proxy.NewAppConns(config, clientCreator, nil) // sm.NewHandshaker(config, state, store, ReplayLastBlock))
|
||||
clientCreator := proxy.NewLocalClientCreator(dummy.NewPersistentDummyApplication(path.Join(config.DBDir(), "1")))
|
||||
proxyApp := proxy.NewAppConns(clientCreator, nil) // sm.NewHandshaker(config, state, store, ReplayLastBlock))
|
||||
if _, err := proxyApp.Start(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -615,10 +614,9 @@ func makeBlockchain(t *testing.T, chainID string, nBlocks int, privVal *types.Pr
|
|||
}
|
||||
|
||||
// fresh state and mock store
|
||||
func stateAndStore(config *viper.Viper, pubKey crypto.PubKey) (*sm.State, *mockBlockStore) {
|
||||
func stateAndStore(config *cfg.Config, pubKey crypto.PubKey) (*sm.State, *mockBlockStore) {
|
||||
stateDB := dbm.NewMemDB()
|
||||
|
||||
state := sm.MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file"))
|
||||
state := sm.MakeGenesisStateFromFile(stateDB, config.GenesisFile())
|
||||
store := NewMockBlockStore(config)
|
||||
return state, store
|
||||
}
|
||||
|
@ -627,13 +625,13 @@ func stateAndStore(config *viper.Viper, pubKey crypto.PubKey) (*sm.State, *mockB
|
|||
// mock block store
|
||||
|
||||
type mockBlockStore struct {
|
||||
config *viper.Viper
|
||||
config *cfg.Config
|
||||
chain []*types.Block
|
||||
commits []*types.Commit
|
||||
}
|
||||
|
||||
// TODO: NewBlockStore(db.NewMemDB) ...
|
||||
func NewMockBlockStore(config *viper.Viper) *mockBlockStore {
|
||||
func NewMockBlockStore(config *cfg.Config) *mockBlockStore {
|
||||
return &mockBlockStore{config, nil, nil}
|
||||
}
|
||||
|
||||
|
@ -642,7 +640,7 @@ func (bs *mockBlockStore) LoadBlock(height int) *types.Block { return bs.chain[h
|
|||
func (bs *mockBlockStore) LoadBlockMeta(height int) *types.BlockMeta {
|
||||
block := bs.chain[height-1]
|
||||
return &types.BlockMeta{
|
||||
BlockID: types.BlockID{block.Hash(), block.MakePartSet(bs.config.GetInt("block_part_size")).Header()},
|
||||
BlockID: types.BlockID{block.Hash(), block.MakePartSet(bs.config.Consensus.BlockPartSize).Header()},
|
||||
Header: block.Header,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,10 +9,9 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/ebuchman/fail-test"
|
||||
"github.com/spf13/viper"
|
||||
|
||||
fail "github.com/ebuchman/fail-test"
|
||||
"github.com/tendermint/go-wire"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
sm "github.com/tendermint/tendermint/state"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
|
@ -20,54 +19,7 @@ import (
|
|||
)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Timeout Parameters
|
||||
|
||||
// TimeoutParams holds timeouts and deltas for each round step.
|
||||
// All timeouts and deltas in milliseconds.
|
||||
type TimeoutParams struct {
|
||||
Propose0 int
|
||||
ProposeDelta int
|
||||
Prevote0 int
|
||||
PrevoteDelta int
|
||||
Precommit0 int
|
||||
PrecommitDelta int
|
||||
Commit0 int
|
||||
SkipTimeoutCommit bool
|
||||
}
|
||||
|
||||
// Wait this long for a proposal
|
||||
func (tp *TimeoutParams) Propose(round int) time.Duration {
|
||||
return time.Duration(tp.Propose0+tp.ProposeDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving any +2/3 prevote, wait this long for stragglers
|
||||
func (tp *TimeoutParams) Prevote(round int) time.Duration {
|
||||
return time.Duration(tp.Prevote0+tp.PrevoteDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving any +2/3 precommits, wait this long for stragglers
|
||||
func (tp *TimeoutParams) Precommit(round int) time.Duration {
|
||||
return time.Duration(tp.Precommit0+tp.PrecommitDelta*round) * time.Millisecond
|
||||
}
|
||||
|
||||
// After receiving +2/3 precommits for a single block (a commit), wait this long for stragglers in the next height's RoundStepNewHeight
|
||||
func (tp *TimeoutParams) Commit(t time.Time) time.Time {
|
||||
return t.Add(time.Duration(tp.Commit0) * 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"),
|
||||
}
|
||||
}
|
||||
// Config
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Errors
|
||||
|
@ -224,38 +176,48 @@ type PrivValidator interface {
|
|||
type ConsensusState struct {
|
||||
cmn.BaseService
|
||||
|
||||
config *viper.Viper
|
||||
// config details
|
||||
config *cfg.ConsensusConfig
|
||||
privValidator PrivValidator // for signing votes
|
||||
|
||||
// services for creating and executing blocks
|
||||
proxyAppConn proxy.AppConnConsensus
|
||||
blockStore types.BlockStore
|
||||
mempool types.Mempool
|
||||
|
||||
privValidator PrivValidator // for signing votes
|
||||
|
||||
// internal state
|
||||
mtx sync.Mutex
|
||||
RoundState
|
||||
state *sm.State // State until height-1.
|
||||
|
||||
peerMsgQueue chan msgInfo // serializes msgs affecting state (proposals, block parts, votes)
|
||||
internalMsgQueue chan msgInfo // like peerMsgQueue but for our own proposals, parts, votes
|
||||
timeoutTicker TimeoutTicker // ticker for timeouts
|
||||
timeoutParams *TimeoutParams // parameters and functions for timeout intervals
|
||||
// state changes may be triggered by msgs from peers,
|
||||
// msgs from ourself, or by timeouts
|
||||
peerMsgQueue chan msgInfo
|
||||
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
|
||||
|
||||
// a Write-Ahead Log ensures we can recover from any kind of crash
|
||||
// and helps us avoid signing conflicting votes
|
||||
wal *WAL
|
||||
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)
|
||||
doPrevote func(height, round int)
|
||||
setProposal func(proposal *types.Proposal) error
|
||||
|
||||
// closed when we finish shutting down
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
func NewConsensusState(config *viper.Viper, state *sm.State, proxyAppConn proxy.AppConnConsensus, blockStore types.BlockStore, mempool types.Mempool) *ConsensusState {
|
||||
func NewConsensusState(config *cfg.ConsensusConfig, state *sm.State, proxyAppConn proxy.AppConnConsensus, blockStore types.BlockStore, mempool types.Mempool) *ConsensusState {
|
||||
cs := &ConsensusState{
|
||||
config: config,
|
||||
proxyAppConn: proxyAppConn,
|
||||
|
@ -264,7 +226,6 @@ func NewConsensusState(config *viper.Viper, state *sm.State, proxyAppConn proxy.
|
|||
peerMsgQueue: make(chan msgInfo, msgQueueSize),
|
||||
internalMsgQueue: make(chan msgInfo, msgQueueSize),
|
||||
timeoutTicker: NewTimeoutTicker(),
|
||||
timeoutParams: InitTimeoutParamsFromConfig(config),
|
||||
done: make(chan struct{}),
|
||||
}
|
||||
// set function defaults (may be overwritten before calling Start)
|
||||
|
@ -341,7 +302,7 @@ func (cs *ConsensusState) LoadCommit(height int) *types.Commit {
|
|||
|
||||
func (cs *ConsensusState) OnStart() error {
|
||||
|
||||
walFile := cs.config.GetString("cs_wal_file")
|
||||
walFile := cs.config.WalFile()
|
||||
if err := cs.OpenWAL(walFile); err != nil {
|
||||
log.Error("Error loading ConsensusState wal", "error", err.Error())
|
||||
return err
|
||||
|
@ -406,7 +367,7 @@ func (cs *ConsensusState) OpenWAL(walFile string) (err error) {
|
|||
|
||||
cs.mtx.Lock()
|
||||
defer cs.mtx.Unlock()
|
||||
wal, err := NewWAL(walFile, cs.config.GetBool("cs_wal_light"))
|
||||
wal, err := NewWAL(walFile, cs.config.WalLight)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -512,7 +473,7 @@ func (cs *ConsensusState) reconstructLastCommit(state *sm.State) {
|
|||
return
|
||||
}
|
||||
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.state.ChainID, state.LastBlockHeight, seenCommit.Round(), types.VoteTypePrecommit, state.LastValidators)
|
||||
for _, precommit := range seenCommit.Precommits {
|
||||
if precommit == nil {
|
||||
continue
|
||||
|
@ -572,9 +533,9 @@ func (cs *ConsensusState) updateToState(state *sm.State) {
|
|||
// to be gathered for the first block.
|
||||
// And alternative solution that relies on clocks:
|
||||
// cs.StartTime = state.LastBlockTime.Add(timeoutCommit)
|
||||
cs.StartTime = cs.timeoutParams.Commit(time.Now())
|
||||
cs.StartTime = cs.config.Commit(time.Now())
|
||||
} else {
|
||||
cs.StartTime = cs.timeoutParams.Commit(cs.CommitTime)
|
||||
cs.StartTime = cs.config.Commit(cs.CommitTime)
|
||||
}
|
||||
cs.Validators = validators
|
||||
cs.Proposal = nil
|
||||
|
@ -583,7 +544,7 @@ func (cs *ConsensusState) updateToState(state *sm.State) {
|
|||
cs.LockedRound = 0
|
||||
cs.LockedBlock = nil
|
||||
cs.LockedBlockParts = nil
|
||||
cs.Votes = NewHeightVoteSet(cs.config.GetString("chain_id"), height, validators)
|
||||
cs.Votes = NewHeightVoteSet(state.ChainID, height, validators)
|
||||
cs.CommitRound = -1
|
||||
cs.LastCommit = lastPrecommits
|
||||
cs.LastValidators = state.LastValidators
|
||||
|
@ -799,7 +760,7 @@ func (cs *ConsensusState) enterPropose(height int, round int) {
|
|||
}()
|
||||
|
||||
// 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
|
||||
if cs.privValidator == nil {
|
||||
|
@ -893,10 +854,10 @@ func (cs *ConsensusState) createProposalBlock() (block *types.Block, blockParts
|
|||
}
|
||||
|
||||
// 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,
|
||||
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.
|
||||
|
@ -982,7 +943,7 @@ func (cs *ConsensusState) enterPrevoteWait(height int, round int) {
|
|||
}()
|
||||
|
||||
// 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.
|
||||
|
@ -1102,7 +1063,7 @@ func (cs *ConsensusState) enterPrecommitWait(height int, round int) {
|
|||
}()
|
||||
|
||||
// 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 +1358,7 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerKey string) (added bool,
|
|||
types.FireEventVote(cs.evsw, types.EventDataVote{vote})
|
||||
|
||||
// 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)
|
||||
// cs.scheduleTimeout(time.Duration(0), cs.Height, 0, RoundStepNewHeight)
|
||||
cs.enterNewRound(cs.Height, 0)
|
||||
|
@ -1460,7 +1421,7 @@ func (cs *ConsensusState) addVote(vote *types.Vote, peerKey string) (added bool,
|
|||
cs.enterPrecommit(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,
|
||||
// go straight to new round (skip timeout commit)
|
||||
// cs.scheduleTimeout(time.Duration(0), cs.Height, 0, RoundStepNewHeight)
|
||||
|
|
|
@ -6,17 +6,16 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
func init() {
|
||||
config = tendermint_test.ResetConfig("consensus_state_test")
|
||||
config = ResetConfig("consensus_state_test")
|
||||
}
|
||||
|
||||
func (tp *TimeoutParams) ensureProposeTimeout() time.Duration {
|
||||
return time.Duration(tp.Propose0*2) * time.Millisecond
|
||||
func ensureProposeTimeout(timeoutPropose int) time.Duration {
|
||||
return time.Duration(timeoutPropose*2) * time.Millisecond
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -126,7 +125,7 @@ func TestEnterProposeNoPrivValidator(t *testing.T) {
|
|||
startTestRound(cs, height, round)
|
||||
|
||||
// if we're not a validator, EnterPropose should timeout
|
||||
ticker := time.NewTicker(cs.timeoutParams.ensureProposeTimeout())
|
||||
ticker := time.NewTicker(ensureProposeTimeout(cs.config.TimeoutPropose))
|
||||
select {
|
||||
case <-timeoutCh:
|
||||
case <-ticker.C:
|
||||
|
@ -167,7 +166,7 @@ func TestEnterProposeYesPrivValidator(t *testing.T) {
|
|||
}
|
||||
|
||||
// if we're a validator, enterPropose should not timeout
|
||||
ticker := time.NewTicker(cs.timeoutParams.ensureProposeTimeout())
|
||||
ticker := time.NewTicker(ensureProposeTimeout(cs.config.TimeoutPropose))
|
||||
select {
|
||||
case <-timeoutCh:
|
||||
panic("Expected EnterPropose not to timeout")
|
||||
|
@ -181,7 +180,7 @@ func TestBadProposal(t *testing.T) {
|
|||
height, round := cs1.Height, cs1.Round
|
||||
vs2 := vss[1]
|
||||
|
||||
partSize := config.GetInt("block_part_size")
|
||||
partSize := config.Consensus.BlockPartSize
|
||||
|
||||
proposalCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringCompleteProposal(), 1)
|
||||
voteCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringVote(), 1)
|
||||
|
@ -201,7 +200,7 @@ func TestBadProposal(t *testing.T) {
|
|||
propBlock.AppHash = stateHash
|
||||
propBlockParts := propBlock.MakePartSet(partSize)
|
||||
proposal := types.NewProposal(vs2.Height, round, propBlockParts.Header(), -1, types.BlockID{})
|
||||
if err := vs2.SignProposal(config.GetString("chain_id"), proposal); err != nil {
|
||||
if err := vs2.SignProposal(config.ChainID, proposal); err != nil {
|
||||
t.Fatal("failed to sign bad proposal", err)
|
||||
}
|
||||
|
||||
|
@ -328,7 +327,7 @@ func TestLockNoPOL(t *testing.T) {
|
|||
vs2 := vss[1]
|
||||
height := cs1.Height
|
||||
|
||||
partSize := config.GetInt("block_part_size")
|
||||
partSize := config.Consensus.BlockPartSize
|
||||
|
||||
timeoutProposeCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutPropose(), 1)
|
||||
timeoutWaitCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutWait(), 1)
|
||||
|
@ -494,7 +493,7 @@ func TestLockPOLRelock(t *testing.T) {
|
|||
cs1, vss := randConsensusState(4)
|
||||
vs2, vs3, vs4 := vss[1], vss[2], vss[3]
|
||||
|
||||
partSize := config.GetInt("block_part_size")
|
||||
partSize := config.Consensus.BlockPartSize
|
||||
|
||||
timeoutProposeCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutPropose(), 1)
|
||||
timeoutWaitCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutWait(), 1)
|
||||
|
@ -606,7 +605,7 @@ func TestLockPOLUnlock(t *testing.T) {
|
|||
cs1, vss := randConsensusState(4)
|
||||
vs2, vs3, vs4 := vss[1], vss[2], vss[3]
|
||||
|
||||
partSize := config.GetInt("block_part_size")
|
||||
partSize := config.Consensus.BlockPartSize
|
||||
|
||||
proposalCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringCompleteProposal(), 1)
|
||||
timeoutProposeCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutPropose(), 1)
|
||||
|
@ -701,7 +700,7 @@ func TestLockPOLSafety1(t *testing.T) {
|
|||
cs1, vss := randConsensusState(4)
|
||||
vs2, vs3, vs4 := vss[1], vss[2], vss[3]
|
||||
|
||||
partSize := config.GetInt("block_part_size")
|
||||
partSize := config.Consensus.BlockPartSize
|
||||
|
||||
proposalCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringCompleteProposal(), 1)
|
||||
timeoutProposeCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutPropose(), 1)
|
||||
|
@ -822,7 +821,7 @@ func TestLockPOLSafety2(t *testing.T) {
|
|||
cs1, vss := randConsensusState(4)
|
||||
vs2, vs3, vs4 := vss[1], vss[2], vss[3]
|
||||
|
||||
partSize := config.GetInt("block_part_size")
|
||||
partSize := config.Consensus.BlockPartSize
|
||||
|
||||
proposalCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringCompleteProposal(), 1)
|
||||
timeoutProposeCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutPropose(), 1)
|
||||
|
@ -878,7 +877,7 @@ func TestLockPOLSafety2(t *testing.T) {
|
|||
|
||||
// in round 2 we see the polkad block from round 0
|
||||
newProp := types.NewProposal(height, 2, propBlockParts0.Header(), 0, propBlockID1)
|
||||
if err := vs3.SignProposal(config.GetString("chain_id"), newProp); err != nil {
|
||||
if err := vs3.SignProposal(config.ChainID, newProp); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cs1.SetProposalAndBlock(newProp, propBlock0, propBlockParts0, "some peer")
|
||||
|
@ -997,7 +996,7 @@ func TestHalt1(t *testing.T) {
|
|||
cs1, vss := randConsensusState(4)
|
||||
vs2, vs3, vs4 := vss[1], vss[2], vss[3]
|
||||
|
||||
partSize := config.GetInt("block_part_size")
|
||||
partSize := config.Consensus.BlockPartSize
|
||||
|
||||
proposalCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringCompleteProposal(), 1)
|
||||
timeoutWaitCh := subscribeToEvent(cs1.evsw, "tester", types.EventStringTimeoutWait(), 1)
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
hash: 6f8962f6ca0e25b8e43bc6e496bd46c9ff3a79dcf789578efeeaee2fffc39c6e
|
||||
updated: 2017-04-27T19:56:37.342860938-04:00
|
||||
hash: c715f30f5021a73c8d35229ad5bb7473bd5b18a24707b3211f264658c44ef63f
|
||||
updated: 2017-05-05T00:50:11.28834974-04:00
|
||||
imports:
|
||||
- name: github.com/btcsuite/btcd
|
||||
version: 4b348c1d33373d672edd83fc576892d0e46686d2
|
||||
subpackages:
|
||||
- btcec
|
||||
- name: github.com/davecgh/go-spew
|
||||
version: 6d212800a42e8ab5c146b8ace3490ee17e5225f9
|
||||
version: 04cdfd42973bb9c8589fd6a731800cf222fde1a9
|
||||
subpackages:
|
||||
- spew
|
||||
- name: github.com/ebuchman/fail-test
|
||||
|
@ -14,22 +14,22 @@ imports:
|
|||
- name: github.com/fsnotify/fsnotify
|
||||
version: 4da3e2cfbabc9f751898f250b49f2439785783a1
|
||||
- name: github.com/go-stack/stack
|
||||
version: 100eb0c0a9c5b306ca2fb4f165df21d80ada4b82
|
||||
version: 7a2f19628aabfe68f0766b59e74d6315f8347d22
|
||||
- name: github.com/gogo/protobuf
|
||||
version: 100ba4e885062801d56799d78530b73b178a78f3
|
||||
version: 30433562cfbf487fe1df7cd26c7bab168d2f14d0
|
||||
subpackages:
|
||||
- proto
|
||||
- name: github.com/golang/protobuf
|
||||
version: 2bba0603135d7d7f5cb73b2125beeda19c09f4ef
|
||||
version: 18c9bb3261723cd5401db4d0c9fbc5c3b6c70fe8
|
||||
subpackages:
|
||||
- proto
|
||||
- ptypes/any
|
||||
- name: github.com/golang/snappy
|
||||
version: 553a641470496b2327abcac10b36396bd98e45c9
|
||||
- name: github.com/gorilla/websocket
|
||||
version: 3ab3a8b8831546bd18fd182c20687ca853b2bb13
|
||||
version: a91eba7f97777409bc2c443f5534d41dd20c5720
|
||||
- name: github.com/hashicorp/hcl
|
||||
version: 630949a3c5fa3c613328e1b8256052cbc2327c9b
|
||||
version: a4b07c25de5ff55ad3b8936cea69a79a3d95a855
|
||||
subpackages:
|
||||
- hcl/ast
|
||||
- hcl/parser
|
||||
|
@ -50,13 +50,13 @@ imports:
|
|||
- name: github.com/mattn/go-isatty
|
||||
version: fc9e8d8ef48496124e79ae0df75490096eccf6fe
|
||||
- name: github.com/mitchellh/mapstructure
|
||||
version: 53818660ed4955e899c0bcafa97299a388bd7c8e
|
||||
version: cc8532a8e9a55ea36402aa21efdf403a60d34096
|
||||
- name: github.com/pelletier/go-buffruneio
|
||||
version: c37440a7cf42ac63b919c752ca73a85067e05992
|
||||
- name: github.com/pelletier/go-toml
|
||||
version: 13d49d4606eb801b8f01ae542b4afc4c6ee3d84a
|
||||
version: 97253b98df84f9eef872866d079e74b8265150f1
|
||||
- name: github.com/pkg/errors
|
||||
version: 645ef00459ed84a119197bfb8d8205042c6df63d
|
||||
version: c605e284fe17294bda444b34710735b29d1a9d90
|
||||
- name: github.com/pmezard/go-difflib
|
||||
version: d8ed2627bdf02c080bf22230dbb337003b7aba2d
|
||||
subpackages:
|
||||
|
@ -68,15 +68,15 @@ imports:
|
|||
- name: github.com/spf13/cast
|
||||
version: acbeb36b902d72a7a4c18e8f3241075e7ab763e4
|
||||
- name: github.com/spf13/cobra
|
||||
version: 10f6b9d7e1631a54ad07c5c0fb71c28a1abfd3c2
|
||||
version: 8f0203be891287870100e4af46262cdf4a4261d1
|
||||
- name: github.com/spf13/jwalterweatherman
|
||||
version: fa7ca7e836cf3a8bb4ebf799f472c12d7e903d66
|
||||
- name: github.com/spf13/pflag
|
||||
version: 2300d0f8576fe575f71aaa5b9bbe4e1b0dc2eb51
|
||||
version: c990990ab4981d84da820b7b00c85139ca150b5f
|
||||
- name: github.com/spf13/viper
|
||||
version: 5d46e70da8c0b6f812e0b170b7a985753b5c63cb
|
||||
version: 0967fc9aceab2ce9da34061253ac10fb99bba5b2
|
||||
- name: github.com/stretchr/testify
|
||||
version: 69483b4bd14f5845b5a1e55bca19e954e827f1d0
|
||||
version: 4d4bfba8f1d1027c4fdbe371823030df51419987
|
||||
subpackages:
|
||||
- assert
|
||||
- require
|
||||
|
@ -109,26 +109,28 @@ imports:
|
|||
- edwards25519
|
||||
- extra25519
|
||||
- name: github.com/tendermint/go-crypto
|
||||
version: 197a2b270fd94ee03824b158e738fce62862d0b8
|
||||
version: 524ba917a3a1636f21ab2c0bf76b6526903ab879
|
||||
- name: github.com/tendermint/go-wire
|
||||
version: b53add0b622662731985485f3a19be7f684660b8
|
||||
subpackages:
|
||||
- data
|
||||
- data/base58
|
||||
- name: github.com/tendermint/log15
|
||||
version: ae0f3d6450da9eac7074b439c8e1c3cabf0d5ce6
|
||||
version: f91285dece9f4875421b481da3e613d83d44f29b
|
||||
subpackages:
|
||||
- term
|
||||
- name: github.com/tendermint/merkleeyes
|
||||
version: ea4dd9c7b773435de26bf59fddf90afd43a07d67
|
||||
version: d0aa363fd4e015e509038c3a0ec493bc62ee0b8a
|
||||
subpackages:
|
||||
- app
|
||||
- client
|
||||
- iavl
|
||||
- testutil
|
||||
- name: github.com/tendermint/tmlibs
|
||||
version: df250b69416a35a943a6e2a92118667e9ef031d4
|
||||
version: 2f02ed18e9b706467c9474d024a25a0b7a9c0e97
|
||||
subpackages:
|
||||
- autofile
|
||||
- cli
|
||||
- clist
|
||||
- common
|
||||
- db
|
||||
|
@ -138,7 +140,7 @@ imports:
|
|||
- merkle
|
||||
- test
|
||||
- name: golang.org/x/crypto
|
||||
version: 96846453c37f0876340a66a47f3f75b1f3a6cd2d
|
||||
version: 5a033cc77e57eca05bdb50522851d29e03569cbe
|
||||
subpackages:
|
||||
- curve25519
|
||||
- nacl/box
|
||||
|
@ -149,7 +151,7 @@ imports:
|
|||
- ripemd160
|
||||
- salsa20/salsa
|
||||
- name: golang.org/x/net
|
||||
version: c8c74377599bd978aee1cf3b9b63a8634051cec2
|
||||
version: feeb485667d1fdabe727840fe00adc22431bc86e
|
||||
subpackages:
|
||||
- context
|
||||
- http2
|
||||
|
@ -159,11 +161,11 @@ imports:
|
|||
- lex/httplex
|
||||
- trace
|
||||
- name: golang.org/x/sys
|
||||
version: ea9bcade75cb975a0b9738936568ab388b845617
|
||||
version: 9ccfe848b9db8435a24c424abbc07a921adf1df5
|
||||
subpackages:
|
||||
- unix
|
||||
- name: golang.org/x/text
|
||||
version: 19e3104b43db45fca0303f489a9536087b184802
|
||||
version: 470f45bf29f4147d6fbd7dfd0a02a848e49f5bf4
|
||||
subpackages:
|
||||
- secure/bidirule
|
||||
- transform
|
||||
|
@ -174,10 +176,11 @@ imports:
|
|||
subpackages:
|
||||
- googleapis/rpc/status
|
||||
- name: google.golang.org/grpc
|
||||
version: 6914ab1e338c92da4218a23d27fcd03d0ad78d46
|
||||
version: 844f573616520565fdc6fb4db242321b5456fd6d
|
||||
subpackages:
|
||||
- codes
|
||||
- credentials
|
||||
- grpclb/grpc_lb_v1
|
||||
- grpclog
|
||||
- internal
|
||||
- keepalive
|
||||
|
|
|
@ -28,9 +28,10 @@ import:
|
|||
- data
|
||||
- package: github.com/tendermint/log15
|
||||
- package: github.com/tendermint/tmlibs
|
||||
version: develop
|
||||
version: cli
|
||||
subpackages:
|
||||
- autofile
|
||||
- cli
|
||||
- clist
|
||||
- common
|
||||
- db
|
||||
|
|
|
@ -7,14 +7,14 @@ import (
|
|||
"sync/atomic"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
auto "github.com/tendermint/tmlibs/autofile"
|
||||
"github.com/tendermint/tmlibs/clist"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
/*
|
||||
|
@ -48,7 +48,7 @@ TODO: Better handle abci client errors. (make it automatically handle connection
|
|||
const cacheSize = 100000
|
||||
|
||||
type Mempool struct {
|
||||
config *viper.Viper
|
||||
config *cfg.MempoolConfig
|
||||
|
||||
proxyMtx sync.Mutex
|
||||
proxyAppConn proxy.AppConnMempool
|
||||
|
@ -67,7 +67,7 @@ type Mempool struct {
|
|||
wal *auto.AutoFile
|
||||
}
|
||||
|
||||
func NewMempool(config *viper.Viper, proxyAppConn proxy.AppConnMempool) *Mempool {
|
||||
func NewMempool(config *cfg.MempoolConfig, proxyAppConn proxy.AppConnMempool) *Mempool {
|
||||
mempool := &Mempool{
|
||||
config: config,
|
||||
proxyAppConn: proxyAppConn,
|
||||
|
@ -86,17 +86,17 @@ func NewMempool(config *viper.Viper, proxyAppConn proxy.AppConnMempool) *Mempool
|
|||
}
|
||||
|
||||
func (mem *Mempool) initWAL() {
|
||||
walDir := mem.config.GetString("mempool_wal_dir")
|
||||
walDir := mem.config.WalDir()
|
||||
if walDir != "" {
|
||||
err := EnsureDir(walDir, 0700)
|
||||
err := cmn.EnsureDir(walDir, 0700)
|
||||
if err != nil {
|
||||
log.Error("Error ensuring Mempool wal dir", "error", err)
|
||||
PanicSanity(err)
|
||||
cmn.PanicSanity(err)
|
||||
}
|
||||
af, err := auto.OpenAutoFile(walDir + "/wal")
|
||||
if err != nil {
|
||||
log.Error("Error opening Mempool wal file", "error", err)
|
||||
PanicSanity(err)
|
||||
cmn.PanicSanity(err)
|
||||
}
|
||||
mem.wal = af
|
||||
}
|
||||
|
@ -220,7 +220,7 @@ func (mem *Mempool) resCbRecheck(req *abci.Request, res *abci.Response) {
|
|||
case *abci.Response_CheckTx:
|
||||
memTx := mem.recheckCursor.Value.(*mempoolTx)
|
||||
if !bytes.Equal(req.GetCheckTx().Tx, memTx.tx) {
|
||||
PanicSanity(Fmt("Unexpected tx response from proxy during recheck\n"+
|
||||
cmn.PanicSanity(cmn.Fmt("Unexpected tx response from proxy during recheck\n"+
|
||||
"Expected %X, got %X", r.CheckTx.Data, memTx.tx))
|
||||
}
|
||||
if r.CheckTx.Code == abci.CodeType_OK {
|
||||
|
@ -270,7 +270,7 @@ func (mem *Mempool) collectTxs(maxTxs int) types.Txs {
|
|||
} else if maxTxs < 0 {
|
||||
maxTxs = mem.txs.Len()
|
||||
}
|
||||
txs := make([]types.Tx, 0, MinInt(mem.txs.Len(), maxTxs))
|
||||
txs := make([]types.Tx, 0, cmn.MinInt(mem.txs.Len(), maxTxs))
|
||||
for e := mem.txs.Front(); e != nil && len(txs) < maxTxs; e = e.Next() {
|
||||
memTx := e.Value.(*mempoolTx)
|
||||
txs = append(txs, memTx.tx)
|
||||
|
@ -299,8 +299,7 @@ func (mem *Mempool) Update(height int, txs types.Txs) {
|
|||
// Recheck mempool txs if any txs were committed in the block
|
||||
// NOTE/XXX: in some apps a tx could be invalidated due to EndBlock,
|
||||
// so we really still do need to recheck, but this is for debugging
|
||||
if mem.config.GetBool("mempool_recheck") &&
|
||||
(mem.config.GetBool("mempool_recheck_empty") || len(txs) > 0) {
|
||||
if mem.config.Recheck && (mem.config.RecheckEmpty || len(txs) > 0) {
|
||||
log.Info("Recheck txs", "numtxs", len(goodTxs))
|
||||
mem.recheckTxs(goodTxs)
|
||||
// At this point, mem.txs are being rechecked.
|
||||
|
|
|
@ -4,21 +4,21 @@ import (
|
|||
"encoding/binary"
|
||||
"testing"
|
||||
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
"github.com/tendermint/abci/example/counter"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
"github.com/tendermint/abci/example/counter"
|
||||
)
|
||||
|
||||
func TestSerialReap(t *testing.T) {
|
||||
config := tendermint_test.ResetConfig("mempool_mempool_test")
|
||||
config := cfg.ResetTestRoot("mempool_test")
|
||||
|
||||
app := counter.NewCounterApplication(true)
|
||||
app.SetOption("serial", "on")
|
||||
cc := proxy.NewLocalClientCreator(app)
|
||||
appConnMem, _ := cc.NewABCIClient()
|
||||
appConnCon, _ := cc.NewABCIClient()
|
||||
mempool := NewMempool(config, appConnMem)
|
||||
mempool := NewMempool(config.Mempool, appConnMem)
|
||||
|
||||
deliverTxsRange := func(start, end int) {
|
||||
// Deliver some txs.
|
||||
|
|
|
@ -6,13 +6,13 @@ import (
|
|||
"reflect"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/go-wire"
|
||||
"github.com/tendermint/tmlibs/clist"
|
||||
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
"github.com/tendermint/tmlibs/clist"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -25,12 +25,12 @@ const (
|
|||
// MempoolReactor handles mempool tx broadcasting amongst peers.
|
||||
type MempoolReactor struct {
|
||||
p2p.BaseReactor
|
||||
config *viper.Viper
|
||||
config *cfg.MempoolConfig
|
||||
Mempool *Mempool
|
||||
evsw types.EventSwitch
|
||||
}
|
||||
|
||||
func NewMempoolReactor(config *viper.Viper, mempool *Mempool) *MempoolReactor {
|
||||
func NewMempoolReactor(config *cfg.MempoolConfig, mempool *Mempool) *MempoolReactor {
|
||||
memR := &MempoolReactor{
|
||||
config: config,
|
||||
Mempool: mempool,
|
||||
|
@ -103,7 +103,7 @@ type Peer interface {
|
|||
// TODO: Handle mempool or reactor shutdown?
|
||||
// As is this routine may block forever if no new txs come in.
|
||||
func (memR *MempoolReactor) broadcastTxRoutine(peer Peer) {
|
||||
if !memR.config.GetBool("mempool_broadcast") {
|
||||
if !memR.config.Broadcast {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
84
node/node.go
84
node/node.go
|
@ -7,12 +7,11 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
bc "github.com/tendermint/tendermint/blockchain"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
"github.com/tendermint/tendermint/consensus"
|
||||
mempl "github.com/tendermint/tendermint/mempool"
|
||||
p2p "github.com/tendermint/tendermint/p2p"
|
||||
|
@ -37,7 +36,7 @@ type Node struct {
|
|||
cmn.BaseService
|
||||
|
||||
// config
|
||||
config *viper.Viper // user config
|
||||
config *cfg.Config
|
||||
genesisDoc *types.GenesisDoc // initial validator set
|
||||
privValidator *types.PrivValidator // local node's validator key
|
||||
|
||||
|
@ -58,30 +57,26 @@ type Node struct {
|
|||
txIndexer txindex.TxIndexer
|
||||
}
|
||||
|
||||
func NewNodeDefault(config *viper.Viper) *Node {
|
||||
func NewNodeDefault(config *cfg.Config) *Node {
|
||||
// Get PrivValidator
|
||||
privValidatorFile := config.GetString("priv_validator_file")
|
||||
privValidator := types.LoadOrGenPrivValidator(privValidatorFile)
|
||||
return NewNode(config, privValidator, proxy.DefaultClientCreator(config))
|
||||
privValidator := types.LoadOrGenPrivValidator(config.PrivValidatorFile())
|
||||
return NewNode(config, privValidator,
|
||||
proxy.DefaultClientCreator(config.ProxyApp, config.ABCI, config.DBDir()))
|
||||
}
|
||||
|
||||
func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCreator proxy.ClientCreator) *Node {
|
||||
func NewNode(config *cfg.Config, privValidator *types.PrivValidator, clientCreator proxy.ClientCreator) *Node {
|
||||
|
||||
// Get BlockStore
|
||||
blockStoreDB := dbm.NewDB("blockstore", config.GetString("db_backend"), config.GetString("db_dir"))
|
||||
blockStoreDB := dbm.NewDB("blockstore", config.DBBackend, config.DBDir())
|
||||
blockStore := bc.NewBlockStore(blockStoreDB)
|
||||
|
||||
// Get State
|
||||
stateDB := dbm.NewDB("state", config.GetString("db_backend"), config.GetString("db_dir"))
|
||||
state := sm.GetState(config, stateDB)
|
||||
|
||||
// add the chainid and number of validators to the global config
|
||||
config.Set("chain_id", state.ChainID)
|
||||
config.Set("num_vals", state.Validators.Size())
|
||||
stateDB := dbm.NewDB("state", config.DBBackend, config.DBDir())
|
||||
state := sm.GetState(stateDB, config.GenesisFile())
|
||||
|
||||
// Create the proxyApp, which manages connections (consensus, mempool, query)
|
||||
// and sync tendermint and the app by replaying any necessary blocks
|
||||
proxyApp := proxy.NewAppConns(config, clientCreator, consensus.NewHandshaker(config, state, blockStore))
|
||||
proxyApp := proxy.NewAppConns(clientCreator, consensus.NewHandshaker(state, blockStore))
|
||||
if _, err := proxyApp.Start(); err != nil {
|
||||
cmn.Exit(cmn.Fmt("Error starting proxy app connections: %v", err))
|
||||
}
|
||||
|
@ -91,9 +86,9 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||
|
||||
// Transaction indexing
|
||||
var txIndexer txindex.TxIndexer
|
||||
switch config.GetString("tx_index") {
|
||||
switch config.TxIndex {
|
||||
case "kv":
|
||||
store := dbm.NewDB("tx_index", config.GetString("db_backend"), config.GetString("db_dir"))
|
||||
store := dbm.NewDB("tx_index", config.DBBackend, config.DBDir())
|
||||
txIndexer = kv.NewTxIndex(store)
|
||||
default:
|
||||
txIndexer = &null.TxIndex{}
|
||||
|
@ -112,7 +107,7 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||
|
||||
// Decide whether to fast-sync or not
|
||||
// We don't fast-sync when the only validator is us.
|
||||
fastSync := config.GetBool("fast_sync")
|
||||
fastSync := config.FastSync
|
||||
if state.Validators.Size() == 1 {
|
||||
addr, _ := state.Validators.GetByIndex(0)
|
||||
if bytes.Equal(privValidator.Address, addr) {
|
||||
|
@ -121,33 +116,28 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||
}
|
||||
|
||||
// Make BlockchainReactor
|
||||
bcReactor := bc.NewBlockchainReactor(config, state.Copy(), proxyApp.Consensus(), blockStore, fastSync)
|
||||
bcReactor := bc.NewBlockchainReactor(state.Copy(), proxyApp.Consensus(), blockStore, fastSync)
|
||||
|
||||
// Make MempoolReactor
|
||||
mempool := mempl.NewMempool(config, proxyApp.Mempool())
|
||||
mempoolReactor := mempl.NewMempoolReactor(config, mempool)
|
||||
mempool := mempl.NewMempool(config.Mempool, proxyApp.Mempool())
|
||||
mempoolReactor := mempl.NewMempoolReactor(config.Mempool, mempool)
|
||||
|
||||
// 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 {
|
||||
consensusState.SetPrivValidator(privValidator)
|
||||
}
|
||||
consensusReactor := consensus.NewConsensusReactor(consensusState, fastSync)
|
||||
|
||||
// Make p2p network switch
|
||||
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(config.P2P)
|
||||
sw.AddReactor("MEMPOOL", mempoolReactor)
|
||||
sw.AddReactor("BLOCKCHAIN", bcReactor)
|
||||
sw.AddReactor("CONSENSUS", consensusReactor)
|
||||
|
||||
// Optionally, start the pex reactor
|
||||
var addrBook *p2p.AddrBook
|
||||
if config.GetBool("pex_reactor") {
|
||||
addrBook = p2p.NewAddrBook(config.GetString("addrbook_file"), config.GetBool("addrbook_strict"))
|
||||
if config.P2P.PexReactor {
|
||||
addrBook = p2p.NewAddrBook(config.P2P.AddrBookFile(), config.P2P.AddrBookStrict)
|
||||
pexReactor := p2p.NewPEXReactor(addrBook)
|
||||
sw.AddReactor("PEX", pexReactor)
|
||||
}
|
||||
|
@ -155,7 +145,7 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||
// Filter peers by addr or pubkey with an ABCI query.
|
||||
// If the query return code is OK, add peer.
|
||||
// XXX: Query format subject to change
|
||||
if config.GetBool("filter_peers") {
|
||||
if config.FilterPeers {
|
||||
// NOTE: addr is ip:port
|
||||
sw.SetAddrFilter(func(addr net.Addr) error {
|
||||
resQuery, err := proxyApp.Query().QuerySync(abci.RequestQuery{Path: cmn.Fmt("/p2p/filter/addr/%s", addr.String())})
|
||||
|
@ -184,7 +174,7 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||
SetEventSwitch(eventSwitch, bcReactor, mempoolReactor, consensusReactor)
|
||||
|
||||
// run the profile server
|
||||
profileHost := config.GetString("prof_laddr")
|
||||
profileHost := config.ProfListenAddress
|
||||
if profileHost != "" {
|
||||
|
||||
go func() {
|
||||
|
@ -217,8 +207,8 @@ func NewNode(config *viper.Viper, privValidator *types.PrivValidator, clientCrea
|
|||
func (n *Node) OnStart() error {
|
||||
|
||||
// Create & add listener
|
||||
protocol, address := ProtocolAndAddress(n.config.GetString("node_laddr"))
|
||||
l := p2p.NewDefaultListener(protocol, address, n.config.GetBool("skip_upnp"))
|
||||
protocol, address := ProtocolAndAddress(n.config.P2P.ListenAddress)
|
||||
l := p2p.NewDefaultListener(protocol, address, n.config.P2P.SkipUPNP)
|
||||
n.sw.AddListener(l)
|
||||
|
||||
// Start the switch
|
||||
|
@ -230,16 +220,16 @@ func (n *Node) OnStart() error {
|
|||
}
|
||||
|
||||
// If seeds exist, add them to the address book and dial out
|
||||
if n.config.GetString("seeds") != "" {
|
||||
if n.config.P2P.Seeds != "" {
|
||||
// dial out
|
||||
seeds := strings.Split(n.config.GetString("seeds"), ",")
|
||||
seeds := strings.Split(n.config.P2P.Seeds, ",")
|
||||
if err := n.DialSeeds(seeds); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Run the RPC server
|
||||
if n.config.GetString("rpc_laddr") != "" {
|
||||
if n.config.RPCListenAddress != "" {
|
||||
listeners, err := n.startRPC()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -289,7 +279,6 @@ func (n *Node) AddListener(l p2p.Listener) {
|
|||
// ConfigureRPC sets all variables in rpccore so they will serve
|
||||
// rpc calls from this node
|
||||
func (n *Node) ConfigureRPC() {
|
||||
rpccore.SetConfig(n.config)
|
||||
rpccore.SetEventSwitch(n.evsw)
|
||||
rpccore.SetBlockStore(n.blockStore)
|
||||
rpccore.SetConsensusState(n.consensusState)
|
||||
|
@ -304,7 +293,7 @@ func (n *Node) ConfigureRPC() {
|
|||
|
||||
func (n *Node) startRPC() ([]net.Listener, error) {
|
||||
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
|
||||
listeners := make([]net.Listener, len(listenAddrs))
|
||||
|
@ -321,7 +310,7 @@ func (n *Node) startRPC() ([]net.Listener, error) {
|
|||
}
|
||||
|
||||
// we expose a simplified api over grpc for convenience to app devs
|
||||
grpcListenAddr := n.config.GetString("grpc_laddr")
|
||||
grpcListenAddr := n.config.GRPCListenAddress
|
||||
if grpcListenAddr != "" {
|
||||
listener, err := grpccore.StartGRPCServer(grpcListenAddr)
|
||||
if err != nil {
|
||||
|
@ -378,8 +367,8 @@ func (n *Node) makeNodeInfo() *p2p.NodeInfo {
|
|||
|
||||
nodeInfo := &p2p.NodeInfo{
|
||||
PubKey: n.privKey.PubKey().Unwrap().(crypto.PubKeyEd25519),
|
||||
Moniker: n.config.GetString("moniker"),
|
||||
Network: n.config.GetString("chain_id"),
|
||||
Moniker: n.config.Moniker,
|
||||
Network: n.consensusState.GetState().ChainID,
|
||||
Version: version.Version,
|
||||
Other: []string{
|
||||
cmn.Fmt("wire_version=%v", wire.Version),
|
||||
|
@ -391,9 +380,10 @@ func (n *Node) makeNodeInfo() *p2p.NodeInfo {
|
|||
}
|
||||
|
||||
// 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)))
|
||||
}
|
||||
}*/
|
||||
|
||||
if !n.sw.IsListening() {
|
||||
return nodeInfo
|
||||
|
@ -402,7 +392,7 @@ func (n *Node) makeNodeInfo() *p2p.NodeInfo {
|
|||
p2pListener := n.sw.Listeners()[0]
|
||||
p2pHost := p2pListener.ExternalAddress().IP.String()
|
||||
p2pPort := p2pListener.ExternalAddress().Port
|
||||
rpcListenAddr := n.config.GetString("rpc_laddr")
|
||||
rpcListenAddr := n.config.RPCListenAddress
|
||||
|
||||
// We assume that the rpcListener has the same ExternalAddress.
|
||||
// This is probably true because both P2P and RPC listeners use UPnP,
|
||||
|
@ -431,3 +421,5 @@ func ProtocolAndAddress(listenAddr string) (string, string) {
|
|||
}
|
||||
return protocol, address
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
|
@ -4,11 +4,11 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
)
|
||||
|
||||
func TestNodeStartStop(t *testing.T) {
|
||||
config := tendermint_test.ResetConfig("node_node_test")
|
||||
config := cfg.ResetTestRoot("node_node_test")
|
||||
|
||||
// Create & start node
|
||||
n := NewNodeDefault(config)
|
||||
|
|
|
@ -14,8 +14,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -80,7 +80,7 @@ const (
|
|||
|
||||
// AddrBook - concurrency safe peer address manager.
|
||||
type AddrBook struct {
|
||||
BaseService
|
||||
cmn.BaseService
|
||||
|
||||
mtx sync.Mutex
|
||||
filePath string
|
||||
|
@ -107,7 +107,7 @@ func NewAddrBook(filePath string, routabilityStrict bool) *AddrBook {
|
|||
routabilityStrict: routabilityStrict,
|
||||
}
|
||||
am.init()
|
||||
am.BaseService = *NewBaseService(log, "AddrBook", am)
|
||||
am.BaseService = *cmn.NewBaseService(log, "AddrBook", am)
|
||||
return am
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ func (a *AddrBook) PickAddress(newBias int) *NetAddress {
|
|||
}
|
||||
randIndex--
|
||||
}
|
||||
PanicSanity("Should not happen")
|
||||
cmn.PanicSanity("Should not happen")
|
||||
} else {
|
||||
// pick random New bucket.
|
||||
var bucket map[string]*knownAddress = nil
|
||||
|
@ -229,7 +229,7 @@ func (a *AddrBook) PickAddress(newBias int) *NetAddress {
|
|||
}
|
||||
randIndex--
|
||||
}
|
||||
PanicSanity("Should not happen")
|
||||
cmn.PanicSanity("Should not happen")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -293,10 +293,10 @@ func (a *AddrBook) GetSelection() []*NetAddress {
|
|||
i++
|
||||
}
|
||||
|
||||
numAddresses := MaxInt(
|
||||
MinInt(minGetSelection, len(allAddr)),
|
||||
numAddresses := cmn.MaxInt(
|
||||
cmn.MinInt(minGetSelection, len(allAddr)),
|
||||
len(allAddr)*getSelectionPercent/100)
|
||||
numAddresses = MinInt(maxGetSelection, numAddresses)
|
||||
numAddresses = cmn.MinInt(maxGetSelection, numAddresses)
|
||||
|
||||
// Fisher-Yates shuffle the array. We only need to do the first
|
||||
// `numAddresses' since we are throwing the rest.
|
||||
|
@ -338,14 +338,14 @@ func (a *AddrBook) saveToFile(filePath string) {
|
|||
log.Error("Failed to save AddrBook to file", "err", err)
|
||||
return
|
||||
}
|
||||
err = WriteFileAtomic(filePath, jsonBytes, 0644)
|
||||
err = cmn.WriteFileAtomic(filePath, jsonBytes, 0644)
|
||||
if err != nil {
|
||||
log.Error("Failed to save AddrBook to file", "file", filePath, "error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Returns false if file does not exist.
|
||||
// Panics if file is corrupt.
|
||||
// cmn.Panics if file is corrupt.
|
||||
func (a *AddrBook) loadFromFile(filePath string) bool {
|
||||
// If doesn't exist, do nothing.
|
||||
_, err := os.Stat(filePath)
|
||||
|
@ -356,14 +356,14 @@ func (a *AddrBook) loadFromFile(filePath string) bool {
|
|||
// Load addrBookJSON{}
|
||||
r, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
PanicCrisis(Fmt("Error opening file %s: %v", filePath, err))
|
||||
cmn.PanicCrisis(cmn.Fmt("Error opening file %s: %v", filePath, err))
|
||||
}
|
||||
defer r.Close()
|
||||
aJSON := &addrBookJSON{}
|
||||
dec := json.NewDecoder(r)
|
||||
err = dec.Decode(aJSON)
|
||||
if err != nil {
|
||||
PanicCrisis(Fmt("Error reading file %s: %v", filePath, err))
|
||||
cmn.PanicCrisis(cmn.Fmt("Error reading file %s: %v", filePath, err))
|
||||
}
|
||||
|
||||
// Restore all the fields...
|
||||
|
@ -417,7 +417,7 @@ func (a *AddrBook) getBucket(bucketType byte, bucketIdx int) map[string]*knownAd
|
|||
case bucketTypeOld:
|
||||
return a.addrOld[bucketIdx]
|
||||
default:
|
||||
PanicSanity("Should not happen")
|
||||
cmn.PanicSanity("Should not happen")
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
@ -427,7 +427,7 @@ func (a *AddrBook) getBucket(bucketType byte, bucketIdx int) map[string]*knownAd
|
|||
func (a *AddrBook) addToNewBucket(ka *knownAddress, bucketIdx int) bool {
|
||||
// Sanity check
|
||||
if ka.isOld() {
|
||||
log.Warn(Fmt("Cannot add address already in old bucket to a new bucket: %v", ka))
|
||||
log.Warn(cmn.Fmt("Cannot add address already in old bucket to a new bucket: %v", ka))
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -461,11 +461,11 @@ func (a *AddrBook) addToNewBucket(ka *knownAddress, bucketIdx int) bool {
|
|||
func (a *AddrBook) addToOldBucket(ka *knownAddress, bucketIdx int) bool {
|
||||
// Sanity check
|
||||
if ka.isNew() {
|
||||
log.Warn(Fmt("Cannot add new address to old bucket: %v", ka))
|
||||
log.Warn(cmn.Fmt("Cannot add new address to old bucket: %v", ka))
|
||||
return false
|
||||
}
|
||||
if len(ka.Buckets) != 0 {
|
||||
log.Warn(Fmt("Cannot add already old address to another old bucket: %v", ka))
|
||||
log.Warn(cmn.Fmt("Cannot add already old address to another old bucket: %v", ka))
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -496,7 +496,7 @@ func (a *AddrBook) addToOldBucket(ka *knownAddress, bucketIdx int) bool {
|
|||
|
||||
func (a *AddrBook) removeFromBucket(ka *knownAddress, bucketType byte, bucketIdx int) {
|
||||
if ka.BucketType != bucketType {
|
||||
log.Warn(Fmt("Bucket type mismatch: %v", ka))
|
||||
log.Warn(cmn.Fmt("Bucket type mismatch: %v", ka))
|
||||
return
|
||||
}
|
||||
bucket := a.getBucket(bucketType, bucketIdx)
|
||||
|
@ -538,7 +538,7 @@ func (a *AddrBook) pickOldest(bucketType byte, bucketIdx int) *knownAddress {
|
|||
|
||||
func (a *AddrBook) addAddress(addr, src *NetAddress) {
|
||||
if a.routabilityStrict && !addr.Routable() {
|
||||
log.Warn(Fmt("Cannot add non-routable address %v", addr))
|
||||
log.Warn(cmn.Fmt("Cannot add non-routable address %v", addr))
|
||||
return
|
||||
}
|
||||
if _, ok := a.ourAddrs[addr.String()]; ok {
|
||||
|
@ -578,7 +578,7 @@ func (a *AddrBook) expireNew(bucketIdx int) {
|
|||
for addrStr, ka := range a.addrNew[bucketIdx] {
|
||||
// If an entry is bad, throw it away
|
||||
if ka.isBad() {
|
||||
log.Notice(Fmt("expiring bad address %v", addrStr))
|
||||
log.Notice(cmn.Fmt("expiring bad address %v", addrStr))
|
||||
a.removeFromBucket(ka, bucketTypeNew, bucketIdx)
|
||||
return
|
||||
}
|
||||
|
@ -595,11 +595,11 @@ func (a *AddrBook) expireNew(bucketIdx int) {
|
|||
func (a *AddrBook) moveToOld(ka *knownAddress) {
|
||||
// Sanity check
|
||||
if ka.isOld() {
|
||||
log.Warn(Fmt("Cannot promote address that is already old %v", ka))
|
||||
log.Warn(cmn.Fmt("Cannot promote address that is already old %v", ka))
|
||||
return
|
||||
}
|
||||
if len(ka.Buckets) == 0 {
|
||||
log.Warn(Fmt("Cannot promote address that isn't in any new buckets %v", ka))
|
||||
log.Warn(cmn.Fmt("Cannot promote address that isn't in any new buckets %v", ka))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -624,13 +624,13 @@ func (a *AddrBook) moveToOld(ka *knownAddress) {
|
|||
if !added {
|
||||
added := a.addToNewBucket(oldest, freedBucket)
|
||||
if !added {
|
||||
log.Warn(Fmt("Could not migrate oldest %v to freedBucket %v", oldest, freedBucket))
|
||||
log.Warn(cmn.Fmt("Could not migrate oldest %v to freedBucket %v", oldest, freedBucket))
|
||||
}
|
||||
}
|
||||
// Finally, add to bucket again.
|
||||
added = a.addToOldBucket(ka, oldBucketIdx)
|
||||
if !added {
|
||||
log.Warn(Fmt("Could not re-add ka %v to oldBucketIdx %v", ka, oldBucketIdx))
|
||||
log.Warn(cmn.Fmt("Could not re-add ka %v to oldBucketIdx %v", ka, oldBucketIdx))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -778,7 +778,7 @@ func (ka *knownAddress) markGood() {
|
|||
func (ka *knownAddress) addBucketRef(bucketIdx int) int {
|
||||
for _, bucket := range ka.Buckets {
|
||||
if bucket == bucketIdx {
|
||||
log.Warn(Fmt("Bucket already exists in ka.Buckets: %v", ka))
|
||||
log.Warn(cmn.Fmt("Bucket already exists in ka.Buckets: %v", ka))
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
@ -794,7 +794,7 @@ func (ka *knownAddress) removeBucketRef(bucketIdx int) int {
|
|||
}
|
||||
}
|
||||
if len(buckets) != len(ka.Buckets)-1 {
|
||||
log.Warn(Fmt("bucketIdx not found in ka.Buckets: %v", ka))
|
||||
log.Warn(cmn.Fmt("bucketIdx not found in ka.Buckets: %v", ka))
|
||||
return -1
|
||||
}
|
||||
ka.Buckets = buckets
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
package p2p
|
||||
|
||||
import (
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
const (
|
||||
// Switch config keys
|
||||
configKeyDialTimeoutSeconds = "dial_timeout_seconds"
|
||||
configKeyHandshakeTimeoutSeconds = "handshake_timeout_seconds"
|
||||
configKeyMaxNumPeers = "max_num_peers"
|
||||
configKeyAuthEnc = "authenticated_encryption"
|
||||
|
||||
// MConnection config keys
|
||||
configKeySendRate = "send_rate"
|
||||
configKeyRecvRate = "recv_rate"
|
||||
|
||||
// Fuzz params
|
||||
configFuzzEnable = "fuzz_enable" // use the fuzz wrapped conn
|
||||
configFuzzMode = "fuzz_mode" // eg. drop, delay
|
||||
configFuzzMaxDelayMilliseconds = "fuzz_max_delay_milliseconds"
|
||||
configFuzzProbDropRW = "fuzz_prob_drop_rw"
|
||||
configFuzzProbDropConn = "fuzz_prob_drop_conn"
|
||||
configFuzzProbSleep = "fuzz_prob_sleep"
|
||||
)
|
||||
|
||||
func setConfigDefaults(config *viper.Viper) {
|
||||
// Switch default config
|
||||
config.SetDefault(configKeyDialTimeoutSeconds, 3)
|
||||
config.SetDefault(configKeyHandshakeTimeoutSeconds, 20)
|
||||
config.SetDefault(configKeyMaxNumPeers, 50)
|
||||
config.SetDefault(configKeyAuthEnc, true)
|
||||
|
||||
// MConnection default config
|
||||
config.SetDefault(configKeySendRate, 512000) // 500KB/s
|
||||
config.SetDefault(configKeyRecvRate, 512000) // 500KB/s
|
||||
|
||||
// Fuzz defaults
|
||||
config.SetDefault(configFuzzEnable, false)
|
||||
config.SetDefault(configFuzzMode, FuzzModeDrop)
|
||||
config.SetDefault(configFuzzMaxDelayMilliseconds, 3000)
|
||||
config.SetDefault(configFuzzProbDropRW, 0.2)
|
||||
config.SetDefault(configFuzzProbDropConn, 0.00)
|
||||
config.SetDefault(configFuzzProbSleep, 0.00)
|
||||
}
|
|
@ -87,8 +87,8 @@ type MConnection struct {
|
|||
|
||||
// MConnConfig is a MConnection configuration.
|
||||
type MConnConfig struct {
|
||||
SendRate int64
|
||||
RecvRate int64
|
||||
SendRate int64 `mapstructure:"send_rate"`
|
||||
RecvRate int64 `mapstructure:"recv_rate"`
|
||||
}
|
||||
|
||||
// DefaultMConnConfig returns the default config.
|
||||
|
|
|
@ -6,8 +6,8 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
"github.com/tendermint/tendermint/p2p/upnp"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
type Listener interface {
|
||||
|
@ -20,7 +20,7 @@ type Listener interface {
|
|||
|
||||
// Implements Listener
|
||||
type DefaultListener struct {
|
||||
BaseService
|
||||
cmn.BaseService
|
||||
|
||||
listener net.Listener
|
||||
intAddr *NetAddress
|
||||
|
@ -37,11 +37,11 @@ const (
|
|||
func splitHostPort(addr string) (host string, port int) {
|
||||
host, portStr, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
PanicSanity(err)
|
||||
cmn.PanicSanity(err)
|
||||
}
|
||||
port, err = strconv.Atoi(portStr)
|
||||
if err != nil {
|
||||
PanicSanity(err)
|
||||
cmn.PanicSanity(err)
|
||||
}
|
||||
return host, port
|
||||
}
|
||||
|
@ -63,7 +63,7 @@ func NewDefaultListener(protocol string, lAddr string, skipUPNP bool) Listener {
|
|||
}
|
||||
}
|
||||
if err != nil {
|
||||
PanicCrisis(err)
|
||||
cmn.PanicCrisis(err)
|
||||
}
|
||||
// Actual listener local IP & port
|
||||
listenerIP, listenerPort := splitHostPort(listener.Addr().String())
|
||||
|
@ -73,7 +73,7 @@ func NewDefaultListener(protocol string, lAddr string, skipUPNP bool) Listener {
|
|||
var intAddr *NetAddress
|
||||
intAddr, err = NewNetAddressString(lAddr)
|
||||
if err != nil {
|
||||
PanicCrisis(err)
|
||||
cmn.PanicCrisis(err)
|
||||
}
|
||||
|
||||
// Determine external address...
|
||||
|
@ -89,7 +89,7 @@ func NewDefaultListener(protocol string, lAddr string, skipUPNP bool) Listener {
|
|||
extAddr = getNaiveExternalAddress(listenerPort)
|
||||
}
|
||||
if extAddr == nil {
|
||||
PanicCrisis("Could not determine external address!")
|
||||
cmn.PanicCrisis("Could not determine external address!")
|
||||
}
|
||||
|
||||
dl := &DefaultListener{
|
||||
|
@ -98,7 +98,7 @@ func NewDefaultListener(protocol string, lAddr string, skipUPNP bool) Listener {
|
|||
extAddr: extAddr,
|
||||
connections: make(chan net.Conn, numBufferedConnections),
|
||||
}
|
||||
dl.BaseService = *NewBaseService(log, "DefaultListener", dl)
|
||||
dl.BaseService = *cmn.NewBaseService(log, "DefaultListener", dl)
|
||||
dl.Start() // Started upon construction
|
||||
return dl
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ func (l *DefaultListener) listenRoutine() {
|
|||
// listener wasn't stopped,
|
||||
// yet we encountered an error.
|
||||
if err != nil {
|
||||
PanicCrisis(err)
|
||||
cmn.PanicCrisis(err)
|
||||
}
|
||||
|
||||
l.connections <- conn
|
||||
|
@ -199,7 +199,7 @@ func getUPNPExternalAddress(externalPort, internalPort int) *NetAddress {
|
|||
func getNaiveExternalAddress(port int) *NetAddress {
|
||||
addrs, err := net.InterfaceAddrs()
|
||||
if err != nil {
|
||||
PanicCrisis(Fmt("Could not fetch interface addresses: %v", err))
|
||||
cmn.PanicCrisis(cmn.Fmt("Could not fetch interface addresses: %v", err))
|
||||
}
|
||||
|
||||
for _, a := range addrs {
|
||||
|
|
21
p2p/peer.go
21
p2p/peer.go
|
@ -35,23 +35,24 @@ type Peer struct {
|
|||
|
||||
// PeerConfig is a Peer configuration.
|
||||
type PeerConfig struct {
|
||||
AuthEnc bool // authenticated encryption
|
||||
AuthEnc bool `mapstructure:"auth_enc"` // authenticated encryption
|
||||
|
||||
HandshakeTimeout time.Duration
|
||||
DialTimeout time.Duration
|
||||
// times are in seconds
|
||||
HandshakeTimeout time.Duration `mapstructure:"handshake_timeout"`
|
||||
DialTimeout time.Duration `mapstructure:"dial_timeout"`
|
||||
|
||||
MConfig *MConnConfig
|
||||
MConfig *MConnConfig `mapstructure:"connection"`
|
||||
|
||||
Fuzz bool // fuzz connection (for testing)
|
||||
FuzzConfig *FuzzConnConfig
|
||||
Fuzz bool `mapstructure:"fuzz"` // fuzz connection (for testing)
|
||||
FuzzConfig *FuzzConnConfig `mapstructure:"fuzz_config"`
|
||||
}
|
||||
|
||||
// DefaultPeerConfig returns the default config.
|
||||
func DefaultPeerConfig() *PeerConfig {
|
||||
return &PeerConfig{
|
||||
AuthEnc: true,
|
||||
HandshakeTimeout: 2 * time.Second,
|
||||
DialTimeout: 3 * time.Second,
|
||||
HandshakeTimeout: 20, // * time.Second,
|
||||
DialTimeout: 3, // * time.Second,
|
||||
MConfig: DefaultMConnConfig(),
|
||||
Fuzz: false,
|
||||
FuzzConfig: DefaultFuzzConnConfig(),
|
||||
|
@ -95,7 +96,7 @@ func newPeerFromConnAndConfig(rawConn net.Conn, outbound bool, reactorsByCh map[
|
|||
|
||||
// Encrypt connection
|
||||
if config.AuthEnc {
|
||||
conn.SetDeadline(time.Now().Add(config.HandshakeTimeout))
|
||||
conn.SetDeadline(time.Now().Add(config.HandshakeTimeout * time.Second))
|
||||
|
||||
var err error
|
||||
conn, err = MakeSecretConnection(conn, ourNodePrivKey)
|
||||
|
@ -279,7 +280,7 @@ func (p *Peer) Get(key string) interface{} {
|
|||
|
||||
func dial(addr *NetAddress, config *PeerConfig) (net.Conn, error) {
|
||||
log.Info("Dialing address", "address", addr)
|
||||
conn, err := addr.DialTimeout(config.DialTimeout)
|
||||
conn, err := addr.DialTimeout(config.DialTimeout * time.Second)
|
||||
if err != nil {
|
||||
log.Info("Failed dialing address", "address", addr, "error", err)
|
||||
return nil, err
|
||||
|
|
|
@ -4,16 +4,16 @@ import (
|
|||
"math/rand"
|
||||
"testing"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
// Returns an empty dummy peer
|
||||
func randPeer() *Peer {
|
||||
return &Peer{
|
||||
Key: RandStr(12),
|
||||
Key: cmn.RandStr(12),
|
||||
NodeInfo: &NodeInfo{
|
||||
RemoteAddr: Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256),
|
||||
ListenAddr: Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256),
|
||||
RemoteAddr: cmn.Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256),
|
||||
ListenAddr: cmn.Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,8 +9,8 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
func TestPEXReactorBasic(t *testing.T) {
|
||||
|
@ -68,7 +68,7 @@ func TestPEXReactorRunning(t *testing.T) {
|
|||
|
||||
// create switches
|
||||
for i := 0; i < N; i++ {
|
||||
switches[i] = makeSwitch(i, "127.0.0.1", "123.123.123", func(i int, sw *Switch) *Switch {
|
||||
switches[i] = makeSwitch(config, i, "127.0.0.1", "123.123.123", func(i int, sw *Switch) *Switch {
|
||||
r := NewPEXReactor(book)
|
||||
r.SetEnsurePeersPeriod(250 * time.Millisecond)
|
||||
sw.AddReactor("pex", r)
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
// 2 + 1024 == 1026 total frame size
|
||||
|
@ -190,7 +190,7 @@ func genEphKeys() (ephPub, ephPriv *[32]byte) {
|
|||
var err error
|
||||
ephPub, ephPriv, err = box.GenerateKey(crand.Reader)
|
||||
if err != nil {
|
||||
PanicCrisis("Could not generate ephemeral keypairs")
|
||||
cmn.PanicCrisis("Could not generate ephemeral keypairs")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ func genEphKeys() (ephPub, ephPriv *[32]byte) {
|
|||
func shareEphPubKey(conn io.ReadWriteCloser, locEphPub *[32]byte) (remEphPub *[32]byte, err error) {
|
||||
var err1, err2 error
|
||||
|
||||
Parallel(
|
||||
cmn.Parallel(
|
||||
func() {
|
||||
_, err1 = conn.Write(locEphPub[:])
|
||||
},
|
||||
|
@ -268,7 +268,7 @@ func shareAuthSignature(sc *SecretConnection, pubKey crypto.PubKeyEd25519, signa
|
|||
var recvMsg authSigMessage
|
||||
var err1, err2 error
|
||||
|
||||
Parallel(
|
||||
cmn.Parallel(
|
||||
func() {
|
||||
msgBytes := wire.BinaryBytes(authSigMessage{pubKey.Wrap(), signature.Wrap()})
|
||||
_, err1 = sc.Write(msgBytes)
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/tendermint/go-crypto"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
type dummyConn struct {
|
||||
|
@ -37,7 +37,7 @@ func makeSecretConnPair(tb testing.TB) (fooSecConn, barSecConn *SecretConnection
|
|||
barPrvKey := crypto.GenPrivKeyEd25519()
|
||||
barPubKey := barPrvKey.PubKey().Unwrap().(crypto.PubKeyEd25519)
|
||||
|
||||
Parallel(
|
||||
cmn.Parallel(
|
||||
func() {
|
||||
var err error
|
||||
fooSecConn, err = MakeSecretConnection(fooConn, fooPrvKey)
|
||||
|
@ -81,8 +81,8 @@ func TestSecretConnectionReadWrite(t *testing.T) {
|
|||
|
||||
// Pre-generate the things to write (for foo & bar)
|
||||
for i := 0; i < 100; i++ {
|
||||
fooWrites = append(fooWrites, RandStr((RandInt()%(dataMaxSize*5))+1))
|
||||
barWrites = append(barWrites, RandStr((RandInt()%(dataMaxSize*5))+1))
|
||||
fooWrites = append(fooWrites, cmn.RandStr((cmn.RandInt()%(dataMaxSize*5))+1))
|
||||
barWrites = append(barWrites, cmn.RandStr((cmn.RandInt()%(dataMaxSize*5))+1))
|
||||
}
|
||||
|
||||
// A helper that will run with (fooConn, fooWrites, fooReads) and vice versa
|
||||
|
@ -96,7 +96,7 @@ func TestSecretConnectionReadWrite(t *testing.T) {
|
|||
return
|
||||
}
|
||||
// In parallel, handle reads and writes
|
||||
Parallel(
|
||||
cmn.Parallel(
|
||||
func() {
|
||||
// Node writes
|
||||
for _, nodeWrite := range nodeWrites {
|
||||
|
@ -131,7 +131,7 @@ func TestSecretConnectionReadWrite(t *testing.T) {
|
|||
}
|
||||
|
||||
// Run foo & bar in parallel
|
||||
Parallel(
|
||||
cmn.Parallel(
|
||||
genNodeRunner(fooConn, fooWrites, &fooReads),
|
||||
genNodeRunner(barConn, barWrites, &barReads),
|
||||
)
|
||||
|
@ -174,7 +174,7 @@ func TestSecretConnectionReadWrite(t *testing.T) {
|
|||
func BenchmarkSecretConnection(b *testing.B) {
|
||||
b.StopTimer()
|
||||
fooSecConn, barSecConn := makeSecretConnPair(b)
|
||||
fooWriteText := RandStr(dataMaxSize)
|
||||
fooWriteText := cmn.RandStr(dataMaxSize)
|
||||
// Consume reads from bar's reader
|
||||
go func() {
|
||||
readBuffer := make([]byte, dataMaxSize)
|
||||
|
|
|
@ -7,11 +7,10 @@ import (
|
|||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/log15"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -20,7 +19,7 @@ const (
|
|||
)
|
||||
|
||||
type Reactor interface {
|
||||
Service // Start, Stop
|
||||
cmn.Service // Start, Stop
|
||||
|
||||
SetSwitch(*Switch)
|
||||
GetChannels() []*ChannelDescriptor
|
||||
|
@ -32,13 +31,13 @@ type Reactor interface {
|
|||
//--------------------------------------
|
||||
|
||||
type BaseReactor struct {
|
||||
BaseService // Provides Start, Stop, .Quit
|
||||
Switch *Switch
|
||||
cmn.BaseService // Provides Start, Stop, .Quit
|
||||
Switch *Switch
|
||||
}
|
||||
|
||||
func NewBaseReactor(log log15.Logger, name string, impl Reactor) *BaseReactor {
|
||||
return &BaseReactor{
|
||||
BaseService: *NewBaseService(log, name, impl),
|
||||
BaseService: *cmn.NewBaseService(log, name, impl),
|
||||
Switch: nil,
|
||||
}
|
||||
}
|
||||
|
@ -60,15 +59,16 @@ or more `Channels`. So while sending outgoing messages is typically performed o
|
|||
incoming messages are received on the reactor.
|
||||
*/
|
||||
type Switch struct {
|
||||
BaseService
|
||||
cmn.BaseService
|
||||
|
||||
config *viper.Viper
|
||||
config *cfg.P2PConfig
|
||||
peerConfig *PeerConfig
|
||||
listeners []Listener
|
||||
reactors map[string]Reactor
|
||||
chDescs []*ChannelDescriptor
|
||||
reactorsByCh map[byte]Reactor
|
||||
peers *PeerSet
|
||||
dialing *CMap
|
||||
dialing *cmn.CMap
|
||||
nodeInfo *NodeInfo // our node info
|
||||
nodePrivKey crypto.PrivKeyEd25519 // our node privkey
|
||||
|
||||
|
@ -81,19 +81,18 @@ var (
|
|||
ErrSwitchMaxPeersPerIPRange = errors.New("IP range has too many peers")
|
||||
)
|
||||
|
||||
func NewSwitch(config *viper.Viper) *Switch {
|
||||
setConfigDefaults(config)
|
||||
|
||||
func NewSwitch(config *cfg.P2PConfig) *Switch {
|
||||
sw := &Switch{
|
||||
config: config,
|
||||
peerConfig: DefaultPeerConfig(),
|
||||
reactors: make(map[string]Reactor),
|
||||
chDescs: make([]*ChannelDescriptor, 0),
|
||||
reactorsByCh: make(map[byte]Reactor),
|
||||
peers: NewPeerSet(),
|
||||
dialing: NewCMap(),
|
||||
dialing: cmn.NewCMap(),
|
||||
nodeInfo: nil,
|
||||
}
|
||||
sw.BaseService = *NewBaseService(log, "P2P Switch", sw)
|
||||
sw.BaseService = *cmn.NewBaseService(log, "P2P Switch", sw)
|
||||
return sw
|
||||
}
|
||||
|
||||
|
@ -105,7 +104,7 @@ func (sw *Switch) AddReactor(name string, reactor Reactor) Reactor {
|
|||
for _, chDesc := range reactorChannels {
|
||||
chID := chDesc.ID
|
||||
if sw.reactorsByCh[chID] != nil {
|
||||
PanicSanity(fmt.Sprintf("Channel %X has multiple reactors %v & %v", chID, sw.reactorsByCh[chID], reactor))
|
||||
cmn.PanicSanity(fmt.Sprintf("Channel %X has multiple reactors %v & %v", chID, sw.reactorsByCh[chID], reactor))
|
||||
}
|
||||
sw.chDescs = append(sw.chDescs, chDesc)
|
||||
sw.reactorsByCh[chID] = reactor
|
||||
|
@ -209,7 +208,7 @@ func (sw *Switch) AddPeer(peer *Peer) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if err := peer.HandshakeTimeout(sw.nodeInfo, time.Duration(sw.config.GetInt(configKeyHandshakeTimeoutSeconds))*time.Second); err != nil {
|
||||
if err := peer.HandshakeTimeout(sw.nodeInfo, time.Duration(sw.peerConfig.HandshakeTimeout*time.Second)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -318,7 +317,7 @@ func (sw *Switch) DialPeerWithAddress(addr *NetAddress, persistent bool) (*Peer,
|
|||
sw.dialing.Set(addr.IP.String(), addr)
|
||||
defer sw.dialing.Delete(addr.IP.String())
|
||||
|
||||
peer, err := newOutboundPeerWithConfig(addr, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError, sw.nodePrivKey, peerConfigFromGoConfig(sw.config))
|
||||
peer, err := newOutboundPeerWithConfig(addr, sw.reactorsByCh, sw.chDescs, sw.StopPeerForError, sw.nodePrivKey, sw.peerConfig)
|
||||
if err != nil {
|
||||
log.Info("Failed dialing peer", "address", addr, "error", err)
|
||||
return nil, err
|
||||
|
@ -430,14 +429,14 @@ func (sw *Switch) listenerRoutine(l Listener) {
|
|||
}
|
||||
|
||||
// ignore connection if we already have enough
|
||||
maxPeers := sw.config.GetInt(configKeyMaxNumPeers)
|
||||
maxPeers := sw.config.MaxNumPeers
|
||||
if maxPeers <= sw.peers.Size() {
|
||||
log.Info("Ignoring inbound connection: already have enough peers", "address", inConn.RemoteAddr().String(), "numPeers", sw.peers.Size(), "max", maxPeers)
|
||||
continue
|
||||
}
|
||||
|
||||
// New inbound connection!
|
||||
err := sw.addPeerWithConnectionAndConfig(inConn, peerConfigFromGoConfig(sw.config))
|
||||
err := sw.addPeerWithConnectionAndConfig(inConn, sw.peerConfig)
|
||||
if err != nil {
|
||||
log.Notice("Ignoring inbound connection: error while adding peer", "address", inConn.RemoteAddr().String(), "error", err)
|
||||
continue
|
||||
|
@ -469,10 +468,10 @@ type SwitchEventDonePeer struct {
|
|||
// If connect==Connect2Switches, the switches will be fully connected.
|
||||
// initSwitch defines how the ith switch should be initialized (ie. with what reactors).
|
||||
// NOTE: panics if any switch fails to start.
|
||||
func MakeConnectedSwitches(n int, initSwitch func(int, *Switch) *Switch, connect func([]*Switch, int, int)) []*Switch {
|
||||
func MakeConnectedSwitches(cfg *cfg.P2PConfig, n int, initSwitch func(int, *Switch) *Switch, connect func([]*Switch, int, int)) []*Switch {
|
||||
switches := make([]*Switch, n)
|
||||
for i := 0; i < n; i++ {
|
||||
switches[i] = makeSwitch(i, "testing", "123.123.123", initSwitch)
|
||||
switches[i] = makeSwitch(cfg, i, "testing", "123.123.123", initSwitch)
|
||||
}
|
||||
|
||||
if err := StartSwitches(switches); err != nil {
|
||||
|
@ -526,18 +525,18 @@ func StartSwitches(switches []*Switch) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func makeSwitch(i int, network, version string, initSwitch func(int, *Switch) *Switch) *Switch {
|
||||
func makeSwitch(cfg *cfg.P2PConfig, i int, network, version string, initSwitch func(int, *Switch) *Switch) *Switch {
|
||||
privKey := crypto.GenPrivKeyEd25519()
|
||||
// new switch, add reactors
|
||||
// TODO: let the config be passed in?
|
||||
s := initSwitch(i, NewSwitch(viper.New()))
|
||||
s := initSwitch(i, NewSwitch(cfg))
|
||||
s.SetNodeInfo(&NodeInfo{
|
||||
PubKey: privKey.PubKey().Unwrap().(crypto.PubKeyEd25519),
|
||||
Moniker: Fmt("switch%d", i),
|
||||
Moniker: cmn.Fmt("switch%d", i),
|
||||
Network: network,
|
||||
Version: version,
|
||||
RemoteAddr: Fmt("%v:%v", network, rand.Intn(64512)+1023),
|
||||
ListenAddr: Fmt("%v:%v", network, rand.Intn(64512)+1023),
|
||||
RemoteAddr: cmn.Fmt("%v:%v", network, rand.Intn(64512)+1023),
|
||||
ListenAddr: cmn.Fmt("%v:%v", network, rand.Intn(64512)+1023),
|
||||
})
|
||||
s.SetNodePrivKey(privKey)
|
||||
return s
|
||||
|
@ -572,23 +571,3 @@ func (sw *Switch) addPeerWithConnectionAndConfig(conn net.Conn, config *PeerConf
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
func peerConfigFromGoConfig(config *viper.Viper) *PeerConfig {
|
||||
return &PeerConfig{
|
||||
AuthEnc: config.GetBool(configKeyAuthEnc),
|
||||
Fuzz: config.GetBool(configFuzzEnable),
|
||||
HandshakeTimeout: time.Duration(config.GetInt(configKeyHandshakeTimeoutSeconds)) * time.Second,
|
||||
DialTimeout: time.Duration(config.GetInt(configKeyDialTimeoutSeconds)) * time.Second,
|
||||
MConfig: &MConnConfig{
|
||||
SendRate: int64(config.GetInt(configKeySendRate)),
|
||||
RecvRate: int64(config.GetInt(configKeyRecvRate)),
|
||||
},
|
||||
FuzzConfig: &FuzzConnConfig{
|
||||
Mode: config.GetInt(configFuzzMode),
|
||||
MaxDelay: time.Duration(config.GetInt(configFuzzMaxDelayMilliseconds)) * time.Millisecond,
|
||||
ProbDropRW: config.GetFloat64(configFuzzProbDropRW),
|
||||
ProbDropConn: config.GetFloat64(configFuzzProbDropConn),
|
||||
ProbSleep: config.GetFloat64(configFuzzProbSleep),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,22 +8,22 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
)
|
||||
|
||||
var (
|
||||
config *viper.Viper
|
||||
config *cfg.P2PConfig
|
||||
)
|
||||
|
||||
func init() {
|
||||
config = viper.New()
|
||||
setConfigDefaults(config)
|
||||
config = cfg.DefaultP2PConfig()
|
||||
config.PexReactor = true
|
||||
}
|
||||
|
||||
type PeerMessage struct {
|
||||
|
@ -92,7 +92,7 @@ func (tr *TestReactor) getMsgs(chID byte) []PeerMessage {
|
|||
// XXX: note this uses net.Pipe and not a proper TCP conn
|
||||
func makeSwitchPair(t testing.TB, initSwitch func(int, *Switch) *Switch) (*Switch, *Switch) {
|
||||
// Create two switches that will be interconnected.
|
||||
switches := MakeConnectedSwitches(2, initSwitch, Connect2Switches)
|
||||
switches := MakeConnectedSwitches(config, 2, initSwitch, Connect2Switches)
|
||||
return switches[0], switches[1]
|
||||
}
|
||||
|
||||
|
@ -163,8 +163,8 @@ func TestSwitches(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConnAddrFilter(t *testing.T) {
|
||||
s1 := makeSwitch(1, "testing", "123.123.123", initSwitchFunc)
|
||||
s2 := makeSwitch(1, "testing", "123.123.123", initSwitchFunc)
|
||||
s1 := makeSwitch(config, 1, "testing", "123.123.123", initSwitchFunc)
|
||||
s2 := makeSwitch(config, 1, "testing", "123.123.123", initSwitchFunc)
|
||||
|
||||
c1, c2 := net.Pipe()
|
||||
|
||||
|
@ -197,8 +197,8 @@ func TestConnAddrFilter(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestConnPubKeyFilter(t *testing.T) {
|
||||
s1 := makeSwitch(1, "testing", "123.123.123", initSwitchFunc)
|
||||
s2 := makeSwitch(1, "testing", "123.123.123", initSwitchFunc)
|
||||
s1 := makeSwitch(config, 1, "testing", "123.123.123", initSwitchFunc)
|
||||
s2 := makeSwitch(config, 1, "testing", "123.123.123", initSwitchFunc)
|
||||
|
||||
c1, c2 := net.Pipe()
|
||||
|
||||
|
@ -234,7 +234,7 @@ func TestConnPubKeyFilter(t *testing.T) {
|
|||
func TestSwitchStopsNonPersistentPeerOnError(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
sw := makeSwitch(1, "testing", "123.123.123", initSwitchFunc)
|
||||
sw := makeSwitch(config, 1, "testing", "123.123.123", initSwitchFunc)
|
||||
sw.Start()
|
||||
defer sw.Stop()
|
||||
|
||||
|
@ -260,7 +260,7 @@ func TestSwitchStopsNonPersistentPeerOnError(t *testing.T) {
|
|||
func TestSwitchReconnectsToPersistentPeer(t *testing.T) {
|
||||
assert, require := assert.New(t), require.New(t)
|
||||
|
||||
sw := makeSwitch(1, "testing", "123.123.123", initSwitchFunc)
|
||||
sw := makeSwitch(config, 1, "testing", "123.123.123", initSwitchFunc)
|
||||
sw.Start()
|
||||
defer sw.Stop()
|
||||
|
||||
|
@ -322,7 +322,7 @@ func BenchmarkSwitches(b *testing.B) {
|
|||
}
|
||||
}
|
||||
|
||||
log.Warn(Fmt("success: %v, failure: %v", numSuccess, numFailure))
|
||||
log.Warn(cmn.Fmt("success: %v, failure: %v", numSuccess, numFailure))
|
||||
|
||||
// Allow everything to flush before stopping switches & closing connections.
|
||||
b.StopTimer()
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"net"
|
||||
"time"
|
||||
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
type UPNPCapabilities struct {
|
||||
|
@ -19,19 +19,19 @@ func makeUPNPListener(intPort int, extPort int) (NAT, net.Listener, net.IP, erro
|
|||
if err != nil {
|
||||
return nil, nil, nil, errors.New(fmt.Sprintf("NAT upnp could not be discovered: %v", err))
|
||||
}
|
||||
log.Info(Fmt("ourIP: %v", nat.(*upnpNAT).ourIP))
|
||||
log.Info(cmn.Fmt("ourIP: %v", nat.(*upnpNAT).ourIP))
|
||||
|
||||
ext, err := nat.GetExternalAddress()
|
||||
if err != nil {
|
||||
return nat, nil, nil, errors.New(fmt.Sprintf("External address error: %v", err))
|
||||
}
|
||||
log.Info(Fmt("External address: %v", ext))
|
||||
log.Info(cmn.Fmt("External address: %v", ext))
|
||||
|
||||
port, err := nat.AddPortMapping("tcp", extPort, intPort, "Tendermint UPnP Probe", 0)
|
||||
if err != nil {
|
||||
return nat, nil, ext, errors.New(fmt.Sprintf("Port mapping error: %v", err))
|
||||
}
|
||||
log.Info(Fmt("Port mapping mapped: %v", port))
|
||||
log.Info(cmn.Fmt("Port mapping mapped: %v", port))
|
||||
|
||||
// also run the listener, open for all remote addresses.
|
||||
listener, err := net.Listen("tcp", fmt.Sprintf(":%v", intPort))
|
||||
|
@ -46,17 +46,17 @@ func testHairpin(listener net.Listener, extAddr string) (supportsHairpin bool) {
|
|||
go func() {
|
||||
inConn, err := listener.Accept()
|
||||
if err != nil {
|
||||
log.Notice(Fmt("Listener.Accept() error: %v", err))
|
||||
log.Notice(cmn.Fmt("Listener.Accept() error: %v", err))
|
||||
return
|
||||
}
|
||||
log.Info(Fmt("Accepted incoming connection: %v -> %v", inConn.LocalAddr(), inConn.RemoteAddr()))
|
||||
log.Info(cmn.Fmt("Accepted incoming connection: %v -> %v", inConn.LocalAddr(), inConn.RemoteAddr()))
|
||||
buf := make([]byte, 1024)
|
||||
n, err := inConn.Read(buf)
|
||||
if err != nil {
|
||||
log.Notice(Fmt("Incoming connection read error: %v", err))
|
||||
log.Notice(cmn.Fmt("Incoming connection read error: %v", err))
|
||||
return
|
||||
}
|
||||
log.Info(Fmt("Incoming connection read %v bytes: %X", n, buf))
|
||||
log.Info(cmn.Fmt("Incoming connection read %v bytes: %X", n, buf))
|
||||
if string(buf) == "test data" {
|
||||
supportsHairpin = true
|
||||
return
|
||||
|
@ -66,16 +66,16 @@ func testHairpin(listener net.Listener, extAddr string) (supportsHairpin bool) {
|
|||
// Establish outgoing
|
||||
outConn, err := net.Dial("tcp", extAddr)
|
||||
if err != nil {
|
||||
log.Notice(Fmt("Outgoing connection dial error: %v", err))
|
||||
log.Notice(cmn.Fmt("Outgoing connection dial error: %v", err))
|
||||
return
|
||||
}
|
||||
|
||||
n, err := outConn.Write([]byte("test data"))
|
||||
if err != nil {
|
||||
log.Notice(Fmt("Outgoing connection write error: %v", err))
|
||||
log.Notice(cmn.Fmt("Outgoing connection write error: %v", err))
|
||||
return
|
||||
}
|
||||
log.Info(Fmt("Outgoing connection wrote %v bytes", n))
|
||||
log.Info(cmn.Fmt("Outgoing connection wrote %v bytes", n))
|
||||
|
||||
// Wait for data receipt
|
||||
time.Sleep(1 * time.Second)
|
||||
|
@ -97,7 +97,7 @@ func Probe() (caps UPNPCapabilities, err error) {
|
|||
defer func() {
|
||||
err = nat.DeletePortMapping("tcp", intPort, extPort)
|
||||
if err != nil {
|
||||
log.Warn(Fmt("Port mapping delete error: %v", err))
|
||||
log.Warn(cmn.Fmt("Port mapping delete error: %v", err))
|
||||
}
|
||||
listener.Close()
|
||||
}()
|
||||
|
|
|
@ -4,8 +4,6 @@ import (
|
|||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
|
||||
abcicli "github.com/tendermint/abci/client"
|
||||
"github.com/tendermint/abci/example/dummy"
|
||||
"github.com/tendermint/abci/types"
|
||||
|
@ -64,15 +62,12 @@ func (r *remoteClientCreator) NewABCIClient() (abcicli.Client, error) {
|
|||
//-----------------------------------------------------------------
|
||||
// default
|
||||
|
||||
func DefaultClientCreator(config *viper.Viper) ClientCreator {
|
||||
addr := config.GetString("proxy_app")
|
||||
transport := config.GetString("abci")
|
||||
|
||||
func DefaultClientCreator(addr, transport, dbDir string) ClientCreator {
|
||||
switch addr {
|
||||
case "dummy":
|
||||
return NewLocalClientCreator(dummy.NewDummyApplication())
|
||||
case "persistent_dummy":
|
||||
return NewLocalClientCreator(dummy.NewPersistentDummyApplication(config.GetString("db_dir")))
|
||||
return NewLocalClientCreator(dummy.NewPersistentDummyApplication(dbDir))
|
||||
case "nilapp":
|
||||
return NewLocalClientCreator(types.NewBaseApplication())
|
||||
default:
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package proxy
|
||||
|
||||
import (
|
||||
"github.com/spf13/viper"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
|
@ -16,8 +15,8 @@ type AppConns interface {
|
|||
Query() AppConnQuery
|
||||
}
|
||||
|
||||
func NewAppConns(config *viper.Viper, clientCreator ClientCreator, handshaker Handshaker) AppConns {
|
||||
return NewMultiAppConn(config, clientCreator, handshaker)
|
||||
func NewAppConns(clientCreator ClientCreator, handshaker Handshaker) AppConns {
|
||||
return NewMultiAppConn(clientCreator, handshaker)
|
||||
}
|
||||
|
||||
//-----------------------------
|
||||
|
@ -34,8 +33,6 @@ type Handshaker interface {
|
|||
type multiAppConn struct {
|
||||
cmn.BaseService
|
||||
|
||||
config *viper.Viper
|
||||
|
||||
handshaker Handshaker
|
||||
|
||||
mempoolConn *appConnMempool
|
||||
|
@ -46,9 +43,8 @@ type multiAppConn struct {
|
|||
}
|
||||
|
||||
// Make all necessary abci connections to the application
|
||||
func NewMultiAppConn(config *viper.Viper, clientCreator ClientCreator, handshaker Handshaker) *multiAppConn {
|
||||
func NewMultiAppConn(clientCreator ClientCreator, handshaker Handshaker) *multiAppConn {
|
||||
multiAppConn := &multiAppConn{
|
||||
config: config,
|
||||
handshaker: handshaker,
|
||||
clientCreator: clientCreator,
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ import (
|
|||
)
|
||||
|
||||
func getHTTPClient() *client.HTTP {
|
||||
rpcAddr := rpctest.GetConfig().GetString("rpc_laddr")
|
||||
rpcAddr := rpctest.GetConfig().RPCListenAddress
|
||||
return client.NewHTTP(rpcAddr, "/websocket")
|
||||
}
|
||||
|
||||
|
@ -32,10 +32,10 @@ func GetClients() []client.Client {
|
|||
// Make sure status is correct (we connect properly)
|
||||
func TestStatus(t *testing.T) {
|
||||
for i, c := range GetClients() {
|
||||
chainID := rpctest.GetConfig().GetString("chain_id")
|
||||
moniker := rpctest.GetConfig().Moniker
|
||||
status, err := c.Status()
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
assert.Equal(t, chainID, status.NodeInfo.Network)
|
||||
assert.Equal(t, moniker, status.NodeInfo.Moniker)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,12 +77,10 @@ func TestDumpConsensusState(t *testing.T) {
|
|||
|
||||
func TestGenesisAndValidators(t *testing.T) {
|
||||
for i, c := range GetClients() {
|
||||
chainID := rpctest.GetConfig().GetString("chain_id")
|
||||
|
||||
// make sure this is the right genesis file
|
||||
gen, err := c.Genesis()
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
assert.Equal(t, chainID, gen.Genesis.ChainID)
|
||||
// get the genesis validator
|
||||
require.Equal(t, 1, len(gen.Genesis.Validators))
|
||||
gval := gen.Genesis.Validators[0]
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
"strconv"
|
||||
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
)
|
||||
|
@ -14,31 +12,6 @@ func UnsafeFlushMempool() (*ctypes.ResultUnsafeFlushMempool, error) {
|
|||
return &ctypes.ResultUnsafeFlushMempool{}, nil
|
||||
}
|
||||
|
||||
func UnsafeSetConfig(typ, key, value string) (*ctypes.ResultUnsafeSetConfig, error) {
|
||||
switch typ {
|
||||
case "string":
|
||||
config.Set(key, value)
|
||||
case "int":
|
||||
val, err := strconv.Atoi(value)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("non-integer value found. key:%s; value:%s; err:%v", key, value, err)
|
||||
}
|
||||
config.Set(key, val)
|
||||
case "bool":
|
||||
switch value {
|
||||
case "true":
|
||||
config.Set(key, true)
|
||||
case "false":
|
||||
config.Set(key, false)
|
||||
default:
|
||||
return nil, fmt.Errorf("bool value must be true or false. got %s", value)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown type %s", typ)
|
||||
}
|
||||
return &ctypes.ResultUnsafeSetConfig{}, nil
|
||||
}
|
||||
|
||||
var profFile *os.File
|
||||
|
||||
func UnsafeStartCPUProfiler(filename string) (*ctypes.ResultUnsafeProfile, error) {
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package core
|
||||
|
||||
import (
|
||||
"github.com/spf13/viper"
|
||||
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/tendermint/consensus"
|
||||
p2p "github.com/tendermint/tendermint/p2p"
|
||||
|
@ -34,7 +32,6 @@ var (
|
|||
// external, thread safe interfaces
|
||||
eventSwitch types.EventSwitch
|
||||
proxyAppQuery proxy.AppConnQuery
|
||||
config *viper.Viper
|
||||
|
||||
// interfaces defined in types and above
|
||||
blockStore types.BlockStore
|
||||
|
@ -49,10 +46,6 @@ var (
|
|||
txIndexer txindex.TxIndexer
|
||||
)
|
||||
|
||||
func SetConfig(c *viper.Viper) {
|
||||
config = c
|
||||
}
|
||||
|
||||
func SetEventSwitch(evsw types.EventSwitch) {
|
||||
eventSwitch = evsw
|
||||
}
|
||||
|
|
|
@ -36,9 +36,6 @@ var Routes = map[string]*rpc.RPCFunc{
|
|||
"dial_seeds": rpc.NewRPCFunc(UnsafeDialSeeds, "seeds"),
|
||||
"unsafe_flush_mempool": rpc.NewRPCFunc(UnsafeFlushMempool, ""),
|
||||
|
||||
// config is not in general thread safe. expose specifics if you need em
|
||||
// "unsafe_set_config": rpc.NewRPCFunc(UnsafeSetConfig, "type,key,value"),
|
||||
|
||||
// profiler API
|
||||
"unsafe_start_cpu_profiler": rpc.NewRPCFunc(UnsafeStartCPUProfiler, "filename"),
|
||||
"unsafe_stop_cpu_profiler": rpc.NewRPCFunc(UnsafeStopCPUProfiler, ""),
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
@ -116,8 +117,6 @@ type ResultABCIQuery struct {
|
|||
|
||||
type ResultUnsafeFlushMempool struct{}
|
||||
|
||||
type ResultUnsafeSetConfig struct{}
|
||||
|
||||
type ResultUnsafeProfile struct{}
|
||||
|
||||
type ResultSubscribe struct{}
|
||||
|
|
|
@ -145,7 +145,7 @@ func mapParamsToArgs(rpcFunc *RPCFunc, params map[string]*json.RawMessage, argsO
|
|||
for i, argName := range rpcFunc.argNames {
|
||||
argType := rpcFunc.args[i+argsOffset]
|
||||
|
||||
if p, ok := params[argName]; ok && len(*p) > 0 {
|
||||
if p, ok := params[argName]; ok && p != nil && len(*p) > 0 {
|
||||
val := reflect.New(argType)
|
||||
err := json.Unmarshal(*p, val.Interface())
|
||||
if err != nil {
|
||||
|
|
|
@ -13,12 +13,13 @@ import (
|
|||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/go-wire/data"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
|
||||
"github.com/tendermint/tendermint/rpc/core"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
rpc "github.com/tendermint/tendermint/rpc/lib/client"
|
||||
"github.com/tendermint/tendermint/state/txindex/null"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
. "github.com/tendermint/tmlibs/common"
|
||||
)
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
@ -38,12 +39,11 @@ func TestJSONStatus(t *testing.T) {
|
|||
}
|
||||
|
||||
func testStatus(t *testing.T, client rpc.HTTPClient) {
|
||||
chainID := GetConfig().GetString("chain_id")
|
||||
moniker := GetConfig().Moniker
|
||||
result := new(ctypes.ResultStatus)
|
||||
_, err := client.Call("status", map[string]interface{}{}, result)
|
||||
require.Nil(t, err)
|
||||
|
||||
assert.Equal(t, chainID, result.NodeInfo.Network)
|
||||
assert.Equal(t, moniker, result.NodeInfo.Moniker)
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
|
@ -158,8 +158,9 @@ func TestURITx(t *testing.T) {
|
|||
testTx(t, GetURIClient(), true)
|
||||
|
||||
core.SetTxIndexer(&null.TxIndex{})
|
||||
testTx(t, GetJSONClient(), false)
|
||||
core.SetTxIndexer(node.ConsensusState().GetState().TxIndexer)
|
||||
defer core.SetTxIndexer(node.ConsensusState().GetState().TxIndexer)
|
||||
|
||||
testTx(t, GetURIClient(), false)
|
||||
}
|
||||
|
||||
func TestJSONTx(t *testing.T) {
|
||||
|
@ -349,54 +350,3 @@ func TestWSDoubleFire(t *testing.T) {
|
|||
return nil
|
||||
})
|
||||
}*/
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
//TODO needs to be refactored so we don't use a mutable config but rather update specific values we're interested in
|
||||
// unsafe_set_config
|
||||
|
||||
//var stringVal = "my string"
|
||||
//var intVal = 987654321
|
||||
//var boolVal = true
|
||||
//
|
||||
//// don't change these
|
||||
//var testCasesUnsafeSetConfig = [][]string{
|
||||
// []string{"string", "key1", stringVal},
|
||||
// []string{"int", "key2", fmt.Sprintf("%v", intVal)},
|
||||
// []string{"bool", "key3", fmt.Sprintf("%v", boolVal)},
|
||||
//}
|
||||
//
|
||||
//func TestURIUnsafeSetConfig(t *testing.T) {
|
||||
// for _, testCase := range testCasesUnsafeSetConfig {
|
||||
// result := new(ctypes.TMResult)
|
||||
// _, err := GetURIClient().Call("unsafe_set_config", map[string]interface{}{
|
||||
// "type": testCase[0],
|
||||
// "key": testCase[1],
|
||||
// "value": testCase[2],
|
||||
// }, result)
|
||||
// require.Nil(t, err)
|
||||
// }
|
||||
// testUnsafeSetConfig(t)
|
||||
//}
|
||||
//
|
||||
//func TestJSONUnsafeSetConfig(t *testing.T) {
|
||||
// for _, testCase := range testCasesUnsafeSetConfig {
|
||||
// result := new(ctypes.TMResult)
|
||||
// _, err := GetJSONClient().Call("unsafe_set_config",
|
||||
// map[string]interface{}{"type": testCase[0], "key": testCase[1], "value": testCase[2]},
|
||||
// result)
|
||||
// require.Nil(t, err)
|
||||
// }
|
||||
// testUnsafeSetConfig(t)
|
||||
//}
|
||||
//
|
||||
//func testUnsafeSetConfig(t *testing.T) {
|
||||
// require := require.New(t)
|
||||
// s := config.GetString("key1")
|
||||
// require.Equal(stringVal, s)
|
||||
//
|
||||
// i := config.GetInt("key2")
|
||||
// require.Equal(intVal, i)
|
||||
//
|
||||
// b := config.GetBool("key3")
|
||||
// require.Equal(boolVal, b)
|
||||
//}
|
||||
|
|
|
@ -10,12 +10,11 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
"github.com/stretchr/testify/require"
|
||||
logger "github.com/tendermint/tmlibs/logger"
|
||||
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
nm "github.com/tendermint/tendermint/node"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
|
@ -24,7 +23,7 @@ import (
|
|||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
var config *viper.Viper
|
||||
var config *cfg.Config
|
||||
|
||||
const tmLogLevel = "error"
|
||||
|
||||
|
@ -54,40 +53,42 @@ func makeAddrs() (string, string, string) {
|
|||
}
|
||||
|
||||
// GetConfig returns a config for the test cases as a singleton
|
||||
func GetConfig() *viper.Viper {
|
||||
func GetConfig() *cfg.Config {
|
||||
if config == nil {
|
||||
pathname := makePathname()
|
||||
config = tendermint_test.ResetConfig(pathname)
|
||||
// Shut up the logging
|
||||
logger.SetLogLevel(tmLogLevel)
|
||||
config = cfg.ResetTestRoot(pathname)
|
||||
|
||||
// and we use random ports to run in parallel
|
||||
tm, rpc, grpc := makeAddrs()
|
||||
config.Set("node_laddr", tm)
|
||||
config.Set("rpc_laddr", rpc)
|
||||
config.Set("grpc_laddr", grpc)
|
||||
config.P2P.ListenAddress = tm
|
||||
config.RPCListenAddress = rpc
|
||||
config.GRPCListenAddress = grpc
|
||||
|
||||
// Shut up the logging
|
||||
logger.SetLogLevel(tmLogLevel)
|
||||
}
|
||||
return config
|
||||
}
|
||||
|
||||
// GetURIClient gets a uri client pointing to the test tendermint rpc
|
||||
func GetURIClient() *client.URIClient {
|
||||
rpcAddr := GetConfig().GetString("rpc_laddr")
|
||||
rpcAddr := GetConfig().RPCListenAddress
|
||||
return client.NewURIClient(rpcAddr)
|
||||
}
|
||||
|
||||
// GetJSONClient gets a http/json client pointing to the test tendermint rpc
|
||||
func GetJSONClient() *client.JSONRPCClient {
|
||||
rpcAddr := GetConfig().GetString("rpc_laddr")
|
||||
rpcAddr := GetConfig().RPCListenAddress
|
||||
return client.NewJSONRPCClient(rpcAddr)
|
||||
}
|
||||
|
||||
func GetGRPCClient() core_grpc.BroadcastAPIClient {
|
||||
grpcAddr := config.GetString("grpc_laddr")
|
||||
grpcAddr := config.GRPCListenAddress
|
||||
return core_grpc.StartGRPCClient(grpcAddr)
|
||||
}
|
||||
|
||||
func GetWSClient() *client.WSClient {
|
||||
rpcAddr := GetConfig().GetString("rpc_laddr")
|
||||
rpcAddr := GetConfig().RPCListenAddress
|
||||
wsc := client.NewWSClient(rpcAddr, "/websocket")
|
||||
if _, err := wsc.Start(); err != nil {
|
||||
panic(err)
|
||||
|
@ -107,7 +108,7 @@ func StartTendermint(app abci.Application) *nm.Node {
|
|||
func NewTendermint(app abci.Application) *nm.Node {
|
||||
// Create & start node
|
||||
config := GetConfig()
|
||||
privValidatorFile := config.GetString("priv_validator_file")
|
||||
privValidatorFile := config.PrivValidatorFile()
|
||||
privValidator := types.LoadOrGenPrivValidator(privValidatorFile)
|
||||
papp := proxy.NewLocalClientCreator(app)
|
||||
node := nm.NewNode(config, privValidator, papp)
|
||||
|
|
|
@ -7,12 +7,10 @@ import (
|
|||
"github.com/stretchr/testify/require"
|
||||
"github.com/tendermint/abci/example/dummy"
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
cfg "github.com/tendermint/tendermint/config/tendermint_test"
|
||||
"github.com/tendermint/tendermint/mempool"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
"github.com/tendermint/tendermint/state/txindex"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -24,12 +22,10 @@ var (
|
|||
|
||||
func TestApplyBlock(t *testing.T) {
|
||||
cc := proxy.NewLocalClientCreator(dummy.NewDummyApplication())
|
||||
config := cfg.ResetConfig("execution_test_")
|
||||
proxyApp := proxy.NewAppConns(config, cc, nil)
|
||||
proxyApp := proxy.NewAppConns(cc, nil)
|
||||
_, err := proxyApp.Start()
|
||||
require.Nil(t, err)
|
||||
defer proxyApp.Stop()
|
||||
mempool := mempool.NewMempool(config, proxyApp.Mempool())
|
||||
|
||||
state := state()
|
||||
indexer := &dummyIndexer{0}
|
||||
|
@ -38,7 +34,7 @@ func TestApplyBlock(t *testing.T) {
|
|||
// make block
|
||||
block := makeBlock(1, state)
|
||||
|
||||
err = state.ApplyBlock(nil, proxyApp.Consensus(), block, block.MakePartSet(testPartSize).Header(), mempool)
|
||||
err = state.ApplyBlock(nil, proxyApp.Consensus(), block, block.MakePartSet(testPartSize).Header(), types.MockMempool{})
|
||||
|
||||
require.Nil(t, err)
|
||||
assert.Equal(t, nTxsPerBlock, indexer.Indexed) // test indexing works
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
abci "github.com/tendermint/abci/types"
|
||||
cmn "github.com/tendermint/tmlibs/common"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
|
@ -169,10 +168,10 @@ func (s *State) GetValidators() (*types.ValidatorSet, *types.ValidatorSet) {
|
|||
|
||||
// Load the most recent state from "state" db,
|
||||
// or create a new one (and save) from genesis.
|
||||
func GetState(config *viper.Viper, stateDB dbm.DB) *State {
|
||||
func GetState(stateDB dbm.DB, genesisFile string) *State {
|
||||
state := LoadState(stateDB)
|
||||
if state == nil {
|
||||
state = MakeGenesisStateFromFile(stateDB, config.GetString("genesis_file"))
|
||||
state = MakeGenesisStateFromFile(stateDB, genesisFile)
|
||||
state.Save()
|
||||
}
|
||||
|
||||
|
|
|
@ -7,15 +7,16 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
abci "github.com/tendermint/abci/types"
|
||||
"github.com/tendermint/go-crypto"
|
||||
cfg "github.com/tendermint/tendermint/config"
|
||||
dbm "github.com/tendermint/tmlibs/db"
|
||||
"github.com/tendermint/tendermint/config/tendermint_test"
|
||||
)
|
||||
|
||||
func TestStateCopyEquals(t *testing.T) {
|
||||
config := tendermint_test.ResetConfig("state_")
|
||||
config := cfg.ResetTestRoot("state_")
|
||||
|
||||
// Get State db
|
||||
stateDB := dbm.NewDB("state", config.GetString("db_backend"), config.GetString("db_dir"))
|
||||
state := GetState(config, stateDB)
|
||||
stateDB := dbm.NewDB("state", config.DBBackend, config.DBDir())
|
||||
state := GetState(stateDB, config.GenesisFile())
|
||||
|
||||
stateCopy := state.Copy()
|
||||
|
||||
|
@ -31,10 +32,10 @@ func TestStateCopyEquals(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestStateSaveLoad(t *testing.T) {
|
||||
config := tendermint_test.ResetConfig("state_")
|
||||
config := cfg.ResetTestRoot("state_")
|
||||
// Get State db
|
||||
stateDB := dbm.NewDB("state", config.GetString("db_backend"), config.GetString("db_dir"))
|
||||
state := GetState(config, stateDB)
|
||||
stateDB := dbm.NewDB("state", config.DBBackend, config.DBDir())
|
||||
state := GetState(stateDB, config.GenesisFile())
|
||||
|
||||
state.LastBlockHeight += 1
|
||||
state.Save()
|
||||
|
@ -48,9 +49,9 @@ func TestStateSaveLoad(t *testing.T) {
|
|||
func TestABCIResponsesSaveLoad(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
|
||||
config := tendermint_test.ResetConfig("state_")
|
||||
stateDB := dbm.NewDB("state", config.GetString("db_backend"), config.GetString("db_dir"))
|
||||
state := GetState(config, stateDB)
|
||||
config := cfg.ResetTestRoot("state_")
|
||||
stateDB := dbm.NewDB("state", config.DBBackend, config.DBDir())
|
||||
state := GetState(stateDB, config.GenesisFile())
|
||||
|
||||
state.LastBlockHeight += 1
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ for i in $(seq 1 4); do
|
|||
--name local_testnet_$i \
|
||||
--entrypoint tendermint \
|
||||
-e TMHOME=/go/src/github.com/tendermint/tendermint/test/p2p/data/mach$i/core \
|
||||
tendermint_tester node --seeds 172.57.0.101:46656,172.57.0.102:46656,172.57.0.103:46656,172.57.0.104:46656 --proxy_app=dummy
|
||||
tendermint_tester node --p2p.seeds 172.57.0.101:46656,172.57.0.102:46656,172.57.0.103:46656,172.57.0.104:46656 --proxy_app=dummy
|
||||
done
|
||||
```
|
||||
|
||||
|
|
|
@ -17,4 +17,4 @@ git fetch origin $BRANCH
|
|||
git checkout $BRANCH
|
||||
make install
|
||||
|
||||
tendermint node --seeds="$TMSEEDS" --moniker="$TMNAME" --proxy_app="$PROXYAPP"
|
||||
tendermint node --p2p.seeds="$TMSEEDS" --moniker="$TMNAME" --proxy_app="$PROXYAPP"
|
||||
|
|
|
@ -27,7 +27,7 @@ SEEDS="$(test/p2p/ip.sh 1):46656"
|
|||
for j in `seq 2 $N`; do
|
||||
SEEDS="$SEEDS,$(test/p2p/ip.sh $j):46656"
|
||||
done
|
||||
bash test/p2p/peer.sh $DOCKER_IMAGE $NETWORK_NAME $ID $PROXY_APP "--seeds $SEEDS --pex"
|
||||
bash test/p2p/peer.sh $DOCKER_IMAGE $NETWORK_NAME $ID $PROXY_APP "--p2p.seeds $SEEDS --p2p.pex"
|
||||
|
||||
# wait for peer to sync and check the app hash
|
||||
bash test/p2p/client.sh $DOCKER_IMAGE $NETWORK_NAME fs_$ID "test/p2p/fast_sync/check_peer.sh $ID"
|
||||
|
|
|
@ -10,7 +10,7 @@ set +u
|
|||
SEEDS=$5
|
||||
if [[ "$SEEDS" != "" ]]; then
|
||||
echo "Seeds: $SEEDS"
|
||||
SEEDS="--seeds $SEEDS"
|
||||
SEEDS="--p2p.seeds $SEEDS"
|
||||
fi
|
||||
set -u
|
||||
|
||||
|
@ -20,5 +20,5 @@ cd "$GOPATH/src/github.com/tendermint/tendermint"
|
|||
docker network create --driver bridge --subnet 172.57.0.0/16 "$NETWORK_NAME"
|
||||
|
||||
for i in $(seq 1 "$N"); do
|
||||
bash test/p2p/peer.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$i" "$APP_PROXY" "$SEEDS --pex"
|
||||
bash test/p2p/peer.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$i" "$APP_PROXY" "$SEEDS --p2p.pex"
|
||||
done
|
||||
|
|
|
@ -23,7 +23,7 @@ docker rm -vf "local_testnet_$ID"
|
|||
set -e
|
||||
|
||||
# NOTE that we do not provide seeds
|
||||
bash test/p2p/peer.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$ID" "$PROXY_APP" "--pex"
|
||||
bash test/p2p/peer.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$ID" "$PROXY_APP" "--p2p.pex"
|
||||
docker cp "/tmp/addrbook.json" "local_testnet_$ID:/go/src/github.com/tendermint/tendermint/test/p2p/data/mach1/core/addrbook.json"
|
||||
echo "with the following addrbook:"
|
||||
cat /tmp/addrbook.json
|
||||
|
@ -47,7 +47,7 @@ docker rm -vf "local_testnet_$ID"
|
|||
set -e
|
||||
|
||||
# NOTE that we do not provide seeds
|
||||
bash test/p2p/peer.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$ID" "$PROXY_APP" "--pex"
|
||||
bash test/p2p/peer.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$ID" "$PROXY_APP" "--p2p.pex"
|
||||
|
||||
# if the client runs forever, it means other peers have removed us from their books (which should not happen)
|
||||
bash test/p2p/client.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$CLIENT_NAME" "test/p2p/pex/check_peer.sh $ID $N"
|
||||
|
|
|
@ -14,7 +14,10 @@ import (
|
|||
"github.com/tendermint/tmlibs/merkle"
|
||||
)
|
||||
|
||||
const MaxBlockSize = 22020096 // 21MB TODO make it configurable
|
||||
const (
|
||||
MaxBlockSize = 22020096 // 21MB TODO make it configurable
|
||||
DefaultBlockPartSize = 65536 // 64kB TODO: put part size in parts header?
|
||||
)
|
||||
|
||||
type Block struct {
|
||||
*Header `json:"header"`
|
||||
|
|
Loading…
Reference in New Issue