diff --git a/CHANGELOG.md b/CHANGELOG.md index bece3471..decf8506 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,9 @@ IMPROVEMENTS: (`persistent_kvstore`) (name "dummy" is deprecated and will not work in release after this one) +FEATURES: +- [config] added the `--p2p.private_peers` flag and `PrivatePeers` config variable (see config for description) + ## 0.16.0 (February 20th, 2017) BREAKING CHANGES: diff --git a/cmd/tendermint/commands/run_node.go b/cmd/tendermint/commands/run_node.go index 0e18be03..45a502c3 100644 --- a/cmd/tendermint/commands/run_node.go +++ b/cmd/tendermint/commands/run_node.go @@ -31,11 +31,12 @@ func AddNodeFlags(cmd *cobra.Command) { // p2p flags cmd.Flags().String("p2p.laddr", config.P2P.ListenAddress, "Node listen address. (0.0.0.0:0 means any interface, any port)") - cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma delimited host:port seed nodes") - cmd.Flags().String("p2p.persistent_peers", config.P2P.PersistentPeers, "Comma delimited host:port persistent peers") + cmd.Flags().String("p2p.seeds", config.P2P.Seeds, "Comma-delimited host:port seed nodes") + cmd.Flags().String("p2p.persistent_peers", config.P2P.PersistentPeers, "Comma-delimited host:port persistent peers") cmd.Flags().Bool("p2p.skip_upnp", config.P2P.SkipUPNP, "Skip UPNP configuration") cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable/disable Peer-Exchange") cmd.Flags().Bool("p2p.seed_mode", config.P2P.SeedMode, "Enable/disable seed mode") + cmd.Flags().String("p2p.private_peers", config.P2P.PrivatePeers, "Comma-delimited host:port private peers") // consensus flags cmd.Flags().Bool("consensus.create_empty_blocks", config.Consensus.CreateEmptyBlocks, "Set this to false to only produce blocks when there are txs or when the AppHash changes") diff --git a/config/config.go b/config/config.go index a433047f..fd77a9db 100644 --- a/config/config.go +++ b/config/config.go @@ -250,8 +250,7 @@ type P2PConfig struct { // We only use these if we can’t connect to peers in the addrbook Seeds string `mapstructure:"seeds"` - // Comma separated list of persistent peers to connect to - // We always connect to these + // Comma separated list of nodes to keep persistent connections to PersistentPeers string `mapstructure:"persistent_peers"` // Skip UPNP port forwarding @@ -289,6 +288,9 @@ type P2PConfig struct { // Authenticated encryption AuthEnc bool `mapstructure:"auth_enc"` + + // Comma separated list of nodes to keep private (will not be gossiped to other peers) connections to + PrivatePeers string `mapstructure:"private_peers"` } // DefaultP2PConfig returns a default configuration for the peer-to-peer layer diff --git a/config/toml.go b/config/toml.go index 35e0985f..38c5a333 100644 --- a/config/toml.go +++ b/config/toml.go @@ -162,6 +162,9 @@ seed_mode = {{ .P2P.SeedMode }} # Authenticated encryption auth_enc = {{ .P2P.AuthEnc }} +# Comma separated list of nodes to keep private (will not be gossiped to other peers) connections to +private_peers = {{ .P2P.PrivatePeers }} + ##### mempool configuration options ##### [mempool] diff --git a/docs/specification/configuration.rst b/docs/specification/configuration.rst index 983ac87c..33f9657f 100644 --- a/docs/specification/configuration.rst +++ b/docs/specification/configuration.rst @@ -124,6 +124,9 @@ like the file below, however, double check by inspecting the # Authenticated encryption auth_enc = true + # Comma separated list of nodes to keep private (will not be gossiped to other peers) connections to + private_peers = "" + ##### mempool configuration options ##### [mempool] diff --git a/node/node.go b/node/node.go index d40322fa..13a60c44 100644 --- a/node/node.go +++ b/node/node.go @@ -421,6 +421,14 @@ func (n *Node) OnStart() error { } } + // Always connect to private peers, but do not add them to addrbook + if n.config.P2P.PrivatePeers != "" { + err = n.sw.DialPeersAsync(nil, strings.Split(n.config.P2P.PrivatePeers, ","), true) + if err != nil { + return err + } + } + // start tx indexer return n.indexerService.Start() } diff --git a/rpc/client/localclient.go b/rpc/client/localclient.go index be989ee1..f5f6d7da 100644 --- a/rpc/client/localclient.go +++ b/rpc/client/localclient.go @@ -88,8 +88,8 @@ func (Local) DialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) { return core.UnsafeDialSeeds(seeds) } -func (Local) DialPeers(peers []string, persistent bool) (*ctypes.ResultDialPeers, error) { - return core.UnsafeDialPeers(peers, persistent) +func (Local) DialPeers(peers []string, persistent bool, private bool) (*ctypes.ResultDialPeers, error) { + return core.UnsafeDialPeers(peers, persistent, private) } func (Local) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) { diff --git a/rpc/client/mock/client.go b/rpc/client/mock/client.go index 6af9abb2..8c9b8ad7 100644 --- a/rpc/client/mock/client.go +++ b/rpc/client/mock/client.go @@ -110,8 +110,8 @@ func (c Client) DialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) { return core.UnsafeDialSeeds(seeds) } -func (c Client) DialPeers(peers []string, persistent bool) (*ctypes.ResultDialPeers, error) { - return core.UnsafeDialPeers(peers, persistent) +func (c Client) DialPeers(peers []string, persistent bool, private bool) (*ctypes.ResultDialPeers, error) { + return core.UnsafeDialPeers(peers, persistent, private) } func (c Client) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) { diff --git a/rpc/core/net.go b/rpc/core/net.go index 14e7389d..abe7f7a2 100644 --- a/rpc/core/net.go +++ b/rpc/core/net.go @@ -2,6 +2,7 @@ package core import ( "github.com/pkg/errors" + p2p "github.com/tendermint/tendermint/p2p" ctypes "github.com/tendermint/tendermint/rpc/core/types" ) @@ -66,13 +67,17 @@ func UnsafeDialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) { return &ctypes.ResultDialSeeds{"Dialing seeds in progress. See /net_info for details"}, nil } -func UnsafeDialPeers(peers []string, persistent bool) (*ctypes.ResultDialPeers, error) { +func UnsafeDialPeers(peers []string, persistent bool, private bool) (*ctypes.ResultDialPeers, error) { if len(peers) == 0 { return &ctypes.ResultDialPeers{}, errors.New("No peers provided") } // starts go routines to dial each peer after random delays logger.Info("DialPeers", "addrBook", addrBook, "peers", peers, "persistent", persistent) - err := p2pSwitch.DialPeersAsync(addrBook, peers, persistent) + var ab p2p.AddrBook + if !private { + ab = addrBook + } + err := p2pSwitch.DialPeersAsync(ab, peers, persistent) if err != nil { return &ctypes.ResultDialPeers{}, err } diff --git a/rpc/core/routes.go b/rpc/core/routes.go index 3ea7aa08..e4343cf4 100644 --- a/rpc/core/routes.go +++ b/rpc/core/routes.go @@ -39,7 +39,7 @@ var Routes = map[string]*rpc.RPCFunc{ func AddUnsafeRoutes() { // control API Routes["dial_seeds"] = rpc.NewRPCFunc(UnsafeDialSeeds, "seeds") - Routes["dial_peers"] = rpc.NewRPCFunc(UnsafeDialPeers, "peers,persistent") + Routes["dial_peers"] = rpc.NewRPCFunc(UnsafeDialPeers, "peers,persistent,private") Routes["unsafe_flush_mempool"] = rpc.NewRPCFunc(UnsafeFlushMempool, "") // profiler API