Browse Source

Merge pull request #1030 from tendermint/864-distinguish-between-seeds-and-manual-peers

Distinguish between seeds and manual peers
pull/1107/head
Ethan Buchman 7 years ago
committed by GitHub
parent
commit
47a6928890
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 225 additions and 111 deletions
  1. +9
    -0
      CHANGELOG.md
  2. +1
    -1
      benchmarks/blockchain/localsync.sh
  3. +1
    -0
      cmd/tendermint/commands/run_node.go
  4. +6
    -1
      config/config.go
  5. +3
    -0
      config/toml.go
  6. +3
    -3
      docs/deploy-testnets.rst
  7. +3
    -0
      docs/specification/configuration.rst
  8. +1
    -0
      docs/specification/rpc.rst
  9. +23
    -12
      docs/using-tendermint.rst
  10. +6
    -11
      node/node.go
  11. +23
    -7
      p2p/pex_reactor.go
  12. +53
    -6
      p2p/pex_reactor_test.go
  13. +12
    -16
      p2p/switch.go
  14. +2
    -0
      p2p/trust/metric_test.go
  15. +1
    -1
      p2p/trust/ticker.go
  16. +4
    -0
      rpc/client/localclient.go
  17. +4
    -0
      rpc/client/mock/client.go
  18. +1
    -0
      rpc/core/doc.go
  19. +17
    -6
      rpc/core/net.go
  20. +1
    -1
      rpc/core/pipe.go
  21. +1
    -0
      rpc/core/routes.go
  22. +4
    -0
      rpc/core/types/responses.go
  23. +1
    -1
      test/p2p/README.md
  24. +3
    -3
      test/p2p/fast_sync/test_peer.sh
  25. +5
    -5
      test/p2p/local_testnet_start.sh
  26. +12
    -0
      test/p2p/persistent_peers.sh
  27. +8
    -8
      test/p2p/pex/dial_persistent_peers.sh
  28. +4
    -4
      test/p2p/pex/test.sh
  29. +4
    -4
      test/p2p/pex/test_addrbook.sh
  30. +7
    -7
      test/p2p/pex/test_dial_persistent_peers.sh
  31. +0
    -12
      test/p2p/seeds.sh
  32. +2
    -2
      test/p2p/test.sh

+ 9
- 0
CHANGELOG.md View File

@ -26,6 +26,15 @@ BUG FIXES:
- Graceful handling/recovery for apps that have non-determinism or fail to halt
- Graceful handling/recovery for violations of safety, or liveness
## 0.16.0 (TBD)
BREAKING CHANGES:
- [p2p] old `seeds` is now `persistent_peers` (persistent peers to which TM will always connect to)
- [p2p] now `seeds` only used for getting addresses (if addrbook is empty; not persistent)
FEATURES:
- [p2p] added new `/dial_persistent_peers` **unsafe** endpoint
## 0.15.0 (December 29, 2017)
BREAKING CHANGES:


+ 1
- 1
benchmarks/blockchain/localsync.sh View File

@ -51,7 +51,7 @@ tendermint node \
--proxy_app dummy \
--p2p.laddr tcp://127.0.0.1:56666 \
--rpc.laddr tcp://127.0.0.1:56667 \
--p2p.seeds 127.0.0.1:56656 \
--p2p.persistent_peers 127.0.0.1:56656 \
--log_level error &
# wait for node to start up so we only count time where we are actually syncing


+ 1
- 0
cmd/tendermint/commands/run_node.go View File

@ -29,6 +29,7 @@ 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().Bool("p2p.skip_upnp", config.P2P.SkipUPNP, "Skip UPNP configuration")
cmd.Flags().Bool("p2p.pex", config.P2P.PexReactor, "Enable/disable Peer-Exchange")


+ 6
- 1
config/config.go View File

@ -194,7 +194,7 @@ type RPCConfig struct {
// NOTE: This server only supports /broadcast_tx_commit
GRPCListenAddress string `mapstructure:"grpc_laddr"`
// Activate unsafe RPC commands like /dial_seeds and /unsafe_flush_mempool
// Activate unsafe RPC commands like /dial_persistent_peers and /unsafe_flush_mempool
Unsafe bool `mapstructure:"unsafe"`
}
@ -227,8 +227,13 @@ type P2PConfig struct {
ListenAddress string `mapstructure:"laddr"`
// Comma separated list of seed nodes to connect to
// 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
PersistentPeers string `mapstructure:"persistent_peers"`
// Skip UPNP port forwarding
SkipUPNP bool `mapstructure:"skip_upnp"`


+ 3
- 0
config/toml.go View File

@ -121,6 +121,9 @@ laddr = "{{ .P2P.ListenAddress }}"
# Comma separated list of seed nodes to connect to
seeds = ""
# Comma separated list of nodes to keep persistent connections to
persistent_peers = ""
# Path to address book
addr_book_file = "{{ .P2P.AddrBook }}"


+ 3
- 3
docs/deploy-testnets.rst View File

@ -24,13 +24,13 @@ Here are the steps to setting up a testnet manually:
``tendermint gen_validator``
4) Compile a list of public keys for each validator into a
``genesis.json`` file.
5) Run ``tendermint node --p2p.seeds=< seed addresses >`` on each node,
where ``< seed addresses >`` is a comma separated list of the IP:PORT
5) Run ``tendermint node --p2p.persistent_peers=< peer addresses >`` on each node,
where ``< peer addresses >`` is a comma separated list of the IP:PORT
combination for each node. The default port for Tendermint is
``46656``. Thus, if the IP addresses of your nodes were
``192.168.0.1, 192.168.0.2, 192.168.0.3, 192.168.0.4``, the command
would look like:
``tendermint node --p2p.seeds=192.168.0.1:46656,192.168.0.2:46656,192.168.0.3:46656,192.168.0.4:46656``.
``tendermint node --p2p.persistent_peers=192.168.0.1:46656,192.168.0.2:46656,192.168.0.3:46656,192.168.0.4:46656``.
After a few seconds, all the nodes should connect to eachother and start
making blocks! For more information, see the Tendermint Networks section


+ 3
- 0
docs/specification/configuration.rst View File

@ -88,6 +88,9 @@ like the file below, however, double check by inspecting the
# Comma separated list of seed nodes to connect to
seeds = ""
# Comma separated list of nodes to keep persistent connections to
persistent_peers = ""
# Path to address book
addr_book_file = "addrbook.json"


+ 1
- 0
docs/specification/rpc.rst View File

@ -112,6 +112,7 @@ An HTTP Get request to the root RPC endpoint (e.g.
http://localhost:46657/broadcast_tx_sync?tx=_
http://localhost:46657/commit?height=_
http://localhost:46657/dial_seeds?seeds=_
http://localhost:46657/dial_peers?peers=_&persistent=_
http://localhost:46657/subscribe?event=_
http://localhost:46657/tx?hash=_&prove=_
http://localhost:46657/unsafe_start_cpu_profiler?filename=_


+ 23
- 12
docs/using-tendermint.rst View File

@ -272,7 +272,9 @@ Peers
~~~~~
To connect to peers on start-up, specify them in the ``$TMHOME/config/config.toml`` or
on the command line.
on the command line. Use `seeds` to specify seed nodes from which you can get many other
peer addresses, and ``persistent_peers`` to specify peers that your node will maintain
persistent connections with.
For instance,
@ -281,26 +283,35 @@ For instance,
tendermint node --p2p.seeds "1.2.3.4:46656,5.6.7.8:46656"
Alternatively, you can use the ``/dial_seeds`` endpoint of the RPC to
specify peers for a running node to connect to:
specify seeds for a running node to connect to:
::
curl --data-urlencode "seeds=[\"1.2.3.4:46656\",\"5.6.7.8:46656\"]" localhost:46657/dial_seeds
curl 'localhost:46657/dial_seeds?seeds=\["1.2.3.4:46656","5.6.7.8:46656"\]'
Additionally, the peer-exchange protocol can be enabled using the
``--pex`` flag, though this feature is `still under
development <https://github.com/tendermint/tendermint/issues/598>`__. If
``--pex`` is enabled, peers will gossip about known peers and form a
more resilient network.
Note, if the peer-exchange protocol (PEX) is enabled (default), you should not
normally need seeds after the first start. Peers will be gossipping about known
peers and forming a network, storing peer addresses in the addrbook.
If you want Tendermint to connect to specific set of addresses and maintain a
persistent connection with each, you can use the ``--p2p.persistent_peers``
flag or the corresponding setting in the ``config.toml`` or the
``/dial_peers`` RPC endpoint to do it without stopping Tendermint
core instance.
::
tendermint node --p2p.persistent_peers "10.11.12.13:46656,10.11.12.14:46656"
curl 'localhost:46657/dial_peers?persistent=true&peers=\["1.2.3.4:46656","5.6.7.8:46656"\]'
Adding a Non-Validator
~~~~~~~~~~~~~~~~~~~~~~
Adding a non-validator is simple. Just copy the original
``genesis.json`` to ``~/.tendermint/config`` on the new machine and start the
node, specifying seeds as necessary. If no seeds are specified, the node
won't make any blocks, because it's not a validator, and it won't hear
about any blocks, because it's not connected to the other peer.
node, specifying seeds or persistent peers as necessary. If no seeds or persistent
peers are specified, the node won't make any blocks, because it's not a validator,
and it won't hear about any blocks, because it's not connected to the other peer.
Adding a Validator
~~~~~~~~~~~~~~~~~~
@ -371,7 +382,7 @@ and the new ``priv_validator.json`` to the ``~/.tendermint/config`` on a new
machine.
Now run ``tendermint node`` on both machines, and use either
``--p2p.seeds`` or the ``/dial_seeds`` to get them to peer up. They
``--p2p.persistent_peers`` or the ``/dial_peers`` to get them to peer up. They
should start making blocks, and will only continue to do so as long as
both of them are online.


+ 6
- 11
node/node.go View File

@ -255,7 +255,8 @@ func NewNode(config *cfg.Config,
trustMetricStore = trust.NewTrustMetricStore(trustHistoryDB, trust.DefaultConfig())
trustMetricStore.SetLogger(p2pLogger)
pexReactor := p2p.NewPEXReactor(addrBook)
pexReactor := p2p.NewPEXReactor(addrBook,
&p2p.PEXReactorConfig{Seeds: strings.Split(config.P2P.Seeds, ",")})
pexReactor.SetLogger(p2pLogger)
sw.AddReactor("PEX", pexReactor)
}
@ -379,11 +380,10 @@ func (n *Node) OnStart() error {
return err
}
// If seeds exist, add them to the address book and dial out
if n.config.P2P.Seeds != "" {
// dial out
seeds := strings.Split(n.config.P2P.Seeds, ",")
if err := n.DialSeeds(seeds); err != nil {
// Always connect to persistent peers
if n.config.P2P.PersistentPeers != "" {
err = n.sw.DialPeersAsync(n.addrBook, strings.Split(n.config.P2P.PersistentPeers, ","), true)
if err != nil {
return err
}
}
@ -575,11 +575,6 @@ func (n *Node) NodeInfo() *p2p.NodeInfo {
return n.sw.NodeInfo()
}
// DialSeeds dials the given seeds on the Switch.
func (n *Node) DialSeeds(seeds []string) error {
return n.sw.DialSeeds(n.addrBook, seeds)
}
//------------------------------------------------------------------------------
var (


+ 23
- 7
p2p/pex_reactor.go View File

@ -45,6 +45,7 @@ type PEXReactor struct {
BaseReactor
book *AddrBook
config *PEXReactorConfig
ensurePeersPeriod time.Duration
// tracks message count by peer, so we can prevent abuse
@ -52,10 +53,18 @@ type PEXReactor struct {
maxMsgCountByPeer uint16
}
// PEXReactorConfig holds reactor specific configuration data.
type PEXReactorConfig struct {
// Seeds is a list of addresses reactor may use if it can't connect to peers
// in the addrbook.
Seeds []string
}
// NewPEXReactor creates new PEX reactor.
func NewPEXReactor(b *AddrBook) *PEXReactor {
func NewPEXReactor(b *AddrBook, config *PEXReactorConfig) *PEXReactor {
r := &PEXReactor{
book: b,
config: config,
ensurePeersPeriod: defaultEnsurePeersPeriod,
msgCountByPeer: cmn.NewCMap(),
maxMsgCountByPeer: defaultMaxMsgCountByPeer,
@ -100,7 +109,7 @@ func (r *PEXReactor) GetChannels() []*ChannelDescriptor {
func (r *PEXReactor) AddPeer(p Peer) {
if p.IsOutbound() {
// For outbound peers, the address is already in the books.
// Either it was added in DialSeeds or when we
// Either it was added in DialPersistentPeers or when we
// received the peer's address in r.Receive
if r.book.NeedMoreAddrs() {
r.RequestPEX(p)
@ -238,7 +247,7 @@ func (r *PEXReactor) ensurePeersRoutine() {
// placeholder. It should not be the case that an address becomes old/vetted
// upon a single successful connection.
func (r *PEXReactor) ensurePeers() {
numOutPeers, _, numDialing := r.Switch.NumPeers()
numOutPeers, numInPeers, numDialing := r.Switch.NumPeers()
numToDial := minNumOutboundPeers - (numOutPeers + numDialing)
r.Logger.Info("Ensure peers", "numOutPeers", numOutPeers, "numDialing", numDialing, "numToDial", numToDial)
if numToDial <= 0 {
@ -284,13 +293,20 @@ func (r *PEXReactor) ensurePeers() {
// If we need more addresses, pick a random peer and ask for more.
if r.book.NeedMoreAddrs() {
if peers := r.Switch.Peers().List(); len(peers) > 0 {
i := rand.Int() % len(peers) // nolint: gas
peer := peers[i]
r.Logger.Info("No addresses to dial. Sending pexRequest to random peer", "peer", peer)
peers := r.Switch.Peers().List()
peersCount := len(peers)
if peersCount > 0 {
peer := peers[rand.Int()%peersCount] // nolint: gas
r.Logger.Info("We need more addresses. Sending pexRequest to random peer", "peer", peer)
r.RequestPEX(peer)
}
}
// If we are not connected to nor dialing anybody, fallback to dialing seeds.
if numOutPeers+numInPeers+numDialing+len(toDial) == 0 {
r.Logger.Info("No addresses to dial nor connected peers. Will dial seeds", "seeds", r.config.Seeds)
r.Switch.DialPeersAsync(r.book, r.config.Seeds, false)
}
}
func (r *PEXReactor) flushMsgCountByPeer() {


+ 53
- 6
p2p/pex_reactor_test.go View File

@ -24,7 +24,7 @@ func TestPEXReactorBasic(t *testing.T) {
book := NewAddrBook(dir+"addrbook.json", true)
book.SetLogger(log.TestingLogger())
r := NewPEXReactor(book)
r := NewPEXReactor(book, &PEXReactorConfig{})
r.SetLogger(log.TestingLogger())
assert.NotNil(r)
@ -40,7 +40,7 @@ func TestPEXReactorAddRemovePeer(t *testing.T) {
book := NewAddrBook(dir+"addrbook.json", true)
book.SetLogger(log.TestingLogger())
r := NewPEXReactor(book)
r := NewPEXReactor(book, &PEXReactorConfig{})
r.SetLogger(log.TestingLogger())
size := book.Size()
@ -76,7 +76,7 @@ func TestPEXReactorRunning(t *testing.T) {
switches[i] = makeSwitch(config, i, "127.0.0.1", "123.123.123", func(i int, sw *Switch) *Switch {
sw.SetLogger(log.TestingLogger().With("switch", i))
r := NewPEXReactor(book)
r := NewPEXReactor(book, &PEXReactorConfig{})
r.SetLogger(log.TestingLogger())
r.SetEnsurePeersPeriod(250 * time.Millisecond)
sw.AddReactor("pex", r)
@ -107,6 +107,7 @@ func TestPEXReactorRunning(t *testing.T) {
func assertSomePeersWithTimeout(t *testing.T, switches []*Switch, checkPeriod, timeout time.Duration) {
ticker := time.NewTicker(checkPeriod)
remaining := timeout
for {
select {
case <-ticker.C:
@ -118,16 +119,21 @@ func assertSomePeersWithTimeout(t *testing.T, switches []*Switch, checkPeriod, t
allGood = false
}
}
remaining -= checkPeriod
if remaining < 0 {
remaining = 0
}
if allGood {
return
}
case <-time.After(timeout):
case <-time.After(remaining):
numPeersStr := ""
for i, s := range switches {
outbound, inbound, _ := s.NumPeers()
numPeersStr += fmt.Sprintf("%d => {outbound: %d, inbound: %d}, ", i, outbound, inbound)
}
t.Errorf("expected all switches to be connected to at least one peer (switches: %s)", numPeersStr)
return
}
}
}
@ -141,7 +147,7 @@ func TestPEXReactorReceive(t *testing.T) {
book := NewAddrBook(dir+"addrbook.json", false)
book.SetLogger(log.TestingLogger())
r := NewPEXReactor(book)
r := NewPEXReactor(book, &PEXReactorConfig{})
r.SetLogger(log.TestingLogger())
peer := createRandomPeer(false)
@ -166,7 +172,7 @@ func TestPEXReactorAbuseFromPeer(t *testing.T) {
book := NewAddrBook(dir+"addrbook.json", true)
book.SetLogger(log.TestingLogger())
r := NewPEXReactor(book)
r := NewPEXReactor(book, &PEXReactorConfig{})
r.SetLogger(log.TestingLogger())
r.SetMaxMsgCountByPeer(5)
@ -180,6 +186,47 @@ func TestPEXReactorAbuseFromPeer(t *testing.T) {
assert.True(r.ReachedMaxMsgCountForPeer(peer.NodeInfo().ListenAddr))
}
func TestPEXReactorUsesSeedsIfNeeded(t *testing.T) {
dir, err := ioutil.TempDir("", "pex_reactor")
require.Nil(t, err)
defer os.RemoveAll(dir) // nolint: errcheck
book := NewAddrBook(dir+"addrbook.json", false)
book.SetLogger(log.TestingLogger())
// 1. create seed
seed := makeSwitch(config, 0, "127.0.0.1", "123.123.123", func(i int, sw *Switch) *Switch {
sw.SetLogger(log.TestingLogger())
r := NewPEXReactor(book, &PEXReactorConfig{})
r.SetLogger(log.TestingLogger())
r.SetEnsurePeersPeriod(250 * time.Millisecond)
sw.AddReactor("pex", r)
return sw
})
seed.AddListener(NewDefaultListener("tcp", seed.NodeInfo().ListenAddr, true, log.TestingLogger()))
err = seed.Start()
require.Nil(t, err)
defer seed.Stop()
// 2. create usual peer
sw := makeSwitch(config, 1, "127.0.0.1", "123.123.123", func(i int, sw *Switch) *Switch {
sw.SetLogger(log.TestingLogger())
r := NewPEXReactor(book, &PEXReactorConfig{Seeds: []string{seed.NodeInfo().ListenAddr}})
r.SetLogger(log.TestingLogger())
r.SetEnsurePeersPeriod(250 * time.Millisecond)
sw.AddReactor("pex", r)
return sw
})
err = sw.Start()
require.Nil(t, err)
defer sw.Stop()
// 3. check that peer at least connects to seed
assertSomePeersWithTimeout(t, []*Switch{sw}, 10*time.Millisecond, 10*time.Second)
}
func createRoutableAddr() (addr string, netAddr *NetAddress) {
for {
addr = cmn.Fmt("%v.%v.%v.%v:46656", rand.Int()%256, rand.Int()%256, rand.Int()%256, rand.Int()%256)


+ 12
- 16
p2p/switch.go View File

@ -16,7 +16,7 @@ import (
const (
// wait a random amount of time from this interval
// before dialing seeds or reconnecting to help prevent DoS
// before dialing peers or reconnecting to help prevent DoS
dialRandomizerIntervalMilliseconds = 3000
// repeatedly try to reconnect for a few minutes
@ -315,15 +315,15 @@ func (sw *Switch) startInitPeer(peer *peer) {
}
}
// DialSeeds dials a list of seeds asynchronously in random order.
func (sw *Switch) DialSeeds(addrBook *AddrBook, seeds []string) error {
netAddrs, errs := NewNetAddressStrings(seeds)
// DialPeersAsync dials a list of peers asynchronously in random order (optionally, making them persistent).
func (sw *Switch) DialPeersAsync(addrBook *AddrBook, peers []string, persistent bool) error {
netAddrs, errs := NewNetAddressStrings(peers)
for _, err := range errs {
sw.Logger.Error("Error in seed's address", "err", err)
sw.Logger.Error("Error in peer's address", "err", err)
}
if addrBook != nil {
// add seeds to `addrBook`
// add peers to `addrBook`
ourAddrS := sw.nodeInfo.ListenAddr
ourAddr, _ := NewNetAddressString(ourAddrS)
for _, netAddr := range netAddrs {
@ -342,7 +342,12 @@ func (sw *Switch) DialSeeds(addrBook *AddrBook, seeds []string) error {
go func(i int) {
sw.randomSleep(0)
j := perm[i]
sw.dialSeed(netAddrs[j])
peer, err := sw.DialPeerWithAddress(netAddrs[j], persistent)
if err != nil {
sw.Logger.Error("Error dialing peer", "err", err)
} else {
sw.Logger.Info("Connected to peer", "peer", peer)
}
}(i)
}
return nil
@ -354,15 +359,6 @@ func (sw *Switch) randomSleep(interval time.Duration) {
time.Sleep(r + interval)
}
func (sw *Switch) dialSeed(addr *NetAddress) {
peer, err := sw.DialPeerWithAddress(addr, true)
if err != nil {
sw.Logger.Error("Error dialing seed", "err", err)
} else {
sw.Logger.Info("Connected to seed", "peer", peer)
}
}
// DialPeerWithAddress dials the given peer and runs sw.addPeer if it connects successfully.
// If `persistent == true`, the switch will always try to reconnect to this peer if the connection ever fails.
func (sw *Switch) DialPeerWithAddress(addr *NetAddress, persistent bool) (Peer, error) {


+ 2
- 0
p2p/trust/metric_test.go View File

@ -68,7 +68,9 @@ func TestTrustMetricStopPause(t *testing.T) {
tt.NextTick()
tm.Pause()
// could be 1 or 2 because Pause and NextTick race
first := tm.Copy().numIntervals
// Allow more time to pass and check the intervals are unchanged
tt.NextTick()
tt.NextTick()


+ 1
- 1
p2p/trust/ticker.go View File

@ -24,7 +24,7 @@ type TestTicker struct {
// NewTestTicker returns our ticker used within test routines
func NewTestTicker() *TestTicker {
c := make(chan time.Time, 1)
c := make(chan time.Time)
return &TestTicker{
C: c,
}


+ 4
- 0
rpc/client/localclient.go View File

@ -88,6 +88,10 @@ 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) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
return core.BlockchainInfo(minHeight, maxHeight)
}


+ 4
- 0
rpc/client/mock/client.go View File

@ -111,6 +111,10 @@ 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) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
return core.BlockchainInfo(minHeight, maxHeight)
}


+ 1
- 0
rpc/core/doc.go View File

@ -95,6 +95,7 @@ Endpoints that require arguments:
/broadcast_tx_sync?tx=_
/commit?height=_
/dial_seeds?seeds=_
/dial_persistent_peers?persistent_peers=_
/subscribe?event=_
/tx?hash=_&prove=_
/unsafe_start_cpu_profiler?filename=_


+ 17
- 6
rpc/core/net.go View File

@ -1,8 +1,7 @@
package core
import (
"fmt"
"github.com/pkg/errors"
ctypes "github.com/tendermint/tendermint/rpc/core/types"
)
@ -55,19 +54,31 @@ func NetInfo() (*ctypes.ResultNetInfo, error) {
}
func UnsafeDialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) {
if len(seeds) == 0 {
return &ctypes.ResultDialSeeds{}, fmt.Errorf("No seeds provided")
return &ctypes.ResultDialSeeds{}, errors.New("No seeds provided")
}
// starts go routines to dial each seed after random delays
// starts go routines to dial each peer after random delays
logger.Info("DialSeeds", "addrBook", addrBook, "seeds", seeds)
err := p2pSwitch.DialSeeds(addrBook, seeds)
err := p2pSwitch.DialPeersAsync(addrBook, seeds, false)
if err != nil {
return &ctypes.ResultDialSeeds{}, err
}
return &ctypes.ResultDialSeeds{"Dialing seeds in progress. See /net_info for details"}, nil
}
func UnsafeDialPeers(peers []string, persistent 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)
if err != nil {
return &ctypes.ResultDialPeers{}, err
}
return &ctypes.ResultDialPeers{"Dialing peers in progress. See /net_info for details"}, nil
}
// Get genesis file.
//
// ```shell


+ 1
- 1
rpc/core/pipe.go View File

@ -32,7 +32,7 @@ type P2P interface {
NumPeers() (outbound, inbound, dialig int)
NodeInfo() *p2p.NodeInfo
IsListening() bool
DialSeeds(*p2p.AddrBook, []string) error
DialPeersAsync(*p2p.AddrBook, []string, bool) error
}
//----------------------------------------------


+ 1
- 0
rpc/core/routes.go View File

@ -39,6 +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["unsafe_flush_mempool"] = rpc.NewRPCFunc(UnsafeFlushMempool, "")
// profiler API


+ 4
- 0
rpc/core/types/responses.go View File

@ -86,6 +86,10 @@ type ResultDialSeeds struct {
Log string `json:"log"`
}
type ResultDialPeers struct {
Log string `json:"log"`
}
type Peer struct {
p2p.NodeInfo `json:"node_info"`
IsOutbound bool `json:"is_outbound"`


+ 1
- 1
test/p2p/README.md View File

@ -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 --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
tendermint_tester node --p2p.persistent_peers 172.57.0.101:46656,172.57.0.102:46656,172.57.0.103:46656,172.57.0.104:46656 --proxy_app=dummy
done
```


+ 3
- 3
test/p2p/fast_sync/test_peer.sh View File

@ -23,11 +23,11 @@ docker rm -vf local_testnet_$ID
set -e
# restart peer - should have an empty blockchain
SEEDS="$(test/p2p/ip.sh 1):46656"
PERSISTENT_PEERS="$(test/p2p/ip.sh 1):46656"
for j in `seq 2 $N`; do
SEEDS="$SEEDS,$(test/p2p/ip.sh $j):46656"
PERSISTENT_PEERS="$PERSISTENT_PEERS,$(test/p2p/ip.sh $j):46656"
done
bash test/p2p/peer.sh $DOCKER_IMAGE $NETWORK_NAME $ID $PROXY_APP "--p2p.seeds $SEEDS --p2p.pex --rpc.unsafe"
bash test/p2p/peer.sh $DOCKER_IMAGE $NETWORK_NAME $ID $PROXY_APP "--p2p.persistent_peers $PERSISTENT_PEERS --p2p.pex --rpc.unsafe"
# 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"


+ 5
- 5
test/p2p/local_testnet_start.sh View File

@ -7,10 +7,10 @@ N=$3
APP_PROXY=$4
set +u
SEEDS=$5
if [[ "$SEEDS" != "" ]]; then
echo "Seeds: $SEEDS"
SEEDS="--p2p.seeds $SEEDS"
PERSISTENT_PEERS=$5
if [[ "$PERSISTENT_PEERS" != "" ]]; then
echo "PersistentPeers: $PERSISTENT_PEERS"
PERSISTENT_PEERS="--p2p.persistent_peers $PERSISTENT_PEERS"
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 --p2p.pex --rpc.unsafe"
bash test/p2p/peer.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$i" "$APP_PROXY" "$PERSISTENT_PEERS --p2p.pex --rpc.unsafe"
done

+ 12
- 0
test/p2p/persistent_peers.sh View File

@ -0,0 +1,12 @@
#! /bin/bash
set -eu
N=$1
cd "$GOPATH/src/github.com/tendermint/tendermint"
persistent_peers="$(test/p2p/ip.sh 1):46656"
for i in $(seq 2 $N); do
persistent_peers="$persistent_peers,$(test/p2p/ip.sh $i):46656"
done
echo "$persistent_peers"

test/p2p/pex/dial_seeds.sh → test/p2p/pex/dial_persistent_peers.sh View File


+ 4
- 4
test/p2p/pex/test.sh View File

@ -6,10 +6,10 @@ NETWORK_NAME=$2
N=$3
PROXY_APP=$4
cd $GOPATH/src/github.com/tendermint/tendermint
cd "$GOPATH/src/github.com/tendermint/tendermint"
echo "Test reconnecting from the address book"
bash test/p2p/pex/test_addrbook.sh $DOCKER_IMAGE $NETWORK_NAME $N $PROXY_APP
bash test/p2p/pex/test_addrbook.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$N" "$PROXY_APP"
echo "Test connecting via /dial_seeds"
bash test/p2p/pex/test_dial_seeds.sh $DOCKER_IMAGE $NETWORK_NAME $N $PROXY_APP
echo "Test connecting via /dial_persistent_peers"
bash test/p2p/pex/test_dial_persistent_peers.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$N" "$PROXY_APP"

+ 4
- 4
test/p2p/pex/test_addrbook.sh View File

@ -9,7 +9,7 @@ PROXY_APP=$4
ID=1
echo "----------------------------------------------------------------------"
echo "Testing pex creates the addrbook and uses it if seeds are not provided"
echo "Testing pex creates the addrbook and uses it if persistent_peers are not provided"
echo "(assuming peers are started with pex enabled)"
CLIENT_NAME="pex_addrbook_$ID"
@ -22,7 +22,7 @@ set +e #CIRCLE
docker rm -vf "local_testnet_$ID"
set -e
# NOTE that we do not provide seeds
# NOTE that we do not provide persistent_peers
bash test/p2p/peer.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$ID" "$PROXY_APP" "--p2p.pex --rpc.unsafe"
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:"
@ -35,7 +35,7 @@ echo ""
bash test/p2p/client.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$CLIENT_NAME" "test/p2p/pex/check_peer.sh $ID $N"
echo "----------------------------------------------------------------------"
echo "Testing other peers connect to us if we have neither seeds nor the addrbook"
echo "Testing other peers connect to us if we have neither persistent_peers nor the addrbook"
echo "(assuming peers are started with pex enabled)"
CLIENT_NAME="pex_no_addrbook_$ID"
@ -46,7 +46,7 @@ set +e #CIRCLE
docker rm -vf "local_testnet_$ID"
set -e
# NOTE that we do not provide seeds
# NOTE that we do not provide persistent_peers
bash test/p2p/peer.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$ID" "$PROXY_APP" "--p2p.pex --rpc.unsafe"
# if the client runs forever, it means other peers have removed us from their books (which should not happen)


test/p2p/pex/test_dial_seeds.sh → test/p2p/pex/test_dial_persistent_peers.sh View File


+ 0
- 12
test/p2p/seeds.sh View File

@ -1,12 +0,0 @@
#! /bin/bash
set -eu
N=$1
cd "$GOPATH/src/github.com/tendermint/tendermint"
seeds="$(test/p2p/ip.sh 1):46656"
for i in $(seq 2 $N); do
seeds="$seeds,$(test/p2p/ip.sh $i):46656"
done
echo "$seeds"

+ 2
- 2
test/p2p/test.sh View File

@ -13,11 +13,11 @@ set +e
bash test/p2p/local_testnet_stop.sh "$NETWORK_NAME" "$N"
set -e
SEEDS=$(bash test/p2p/seeds.sh $N)
PERSISTENT_PEERS=$(bash test/p2p/persistent_peers.sh $N)
# start the testnet on a local network
# NOTE we re-use the same network for all tests
bash test/p2p/local_testnet_start.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$N" "$PROXY_APP" "$SEEDS"
bash test/p2p/local_testnet_start.sh "$DOCKER_IMAGE" "$NETWORK_NAME" "$N" "$PROXY_APP" "$PERSISTENT_PEERS"
# test basic connectivity and consensus
# start client container and check the num peers and height for all nodes


Loading…
Cancel
Save