diff --git a/packages/autopeering/discover/manager.go b/packages/autopeering/discover/manager.go index 055dd9bb02973a7507e6bc0e2815b55215a27a29..5fbded485bc9c4e2f1f6f43fe83da88e14bb3e0e 100644 --- a/packages/autopeering/discover/manager.go +++ b/packages/autopeering/discover/manager.go @@ -25,7 +25,7 @@ const ( type network interface { local() *peer.Local - ping(*peer.Peer) error + Ping(*peer.Peer) error discoveryRequest(*peer.Peer) ([]*peer.Peer, error) } @@ -139,7 +139,7 @@ func (m *manager) doReverify(done chan<- struct{}) { var err error for i := 0; i < reverifyTries; i++ { - err = m.net.ping(unwrapPeer(p)) + err = m.net.Ping(unwrapPeer(p)) if err == nil { break } else { diff --git a/packages/autopeering/discover/manager_test.go b/packages/autopeering/discover/manager_test.go index fba880e4182ac77b57a029a917b9f33fbe7d6c35..090371232430ac348eda54759d6110d9abfe251b 100644 --- a/packages/autopeering/discover/manager_test.go +++ b/packages/autopeering/discover/manager_test.go @@ -22,7 +22,7 @@ func (m *NetworkMock) local() *peer.Local { return m.loc } -func (m *NetworkMock) ping(p *peer.Peer) error { +func (m *NetworkMock) Ping(p *peer.Peer) error { args := m.Called(p) return args.Error(0) } @@ -70,7 +70,7 @@ func TestMgrVerifyDiscoveredPeer(t *testing.T) { p := newDummyPeer("p") // expect ping of peer p - m.On("ping", p).Return(nil).Once() + m.On("Ping", p).Return(nil).Once() // ignore discoveryRequest calls m.On("discoveryRequest", mock.Anything).Return([]*peer.Peer{}, nil).Maybe() @@ -90,7 +90,7 @@ func TestMgrReverifyPeer(t *testing.T) { p := newDummyPeer("p") // expect ping of peer p - m.On("ping", p).Return(nil).Once() + m.On("Ping", p).Return(nil).Once() // ignore discoveryRequest calls m.On("discoveryRequest", mock.Anything).Return([]*peer.Peer{}, nil).Maybe() @@ -113,7 +113,7 @@ func TestMgrRequestDiscoveredPeer(t *testing.T) { // expect discoveryRequest on the discovered peer m.On("discoveryRequest", p1).Return([]*peer.Peer{p2}, nil).Once() // ignore any ping - m.On("ping", mock.Anything).Return(nil).Maybe() + m.On("Ping", mock.Anything).Return(nil).Maybe() mgr.addVerifiedPeer(p1) mgr.addDiscoveredPeer(p2) @@ -129,7 +129,7 @@ func TestMgrAddManyVerifiedPeers(t *testing.T) { p := newDummyPeer("p") // expect ping of peer p - m.On("ping", p).Return(nil).Once() + m.On("Ping", p).Return(nil).Once() // ignore discoveryRequest calls m.On("discoveryRequest", mock.Anything).Return([]*peer.Peer{}, nil).Maybe() @@ -157,7 +157,7 @@ func TestMgrDeleteUnreachablePeer(t *testing.T) { p := newDummyPeer("p") // expect ping of peer p, but return error - m.On("ping", p).Return(server.ErrTimeout).Times(reverifyTries) + m.On("Ping", p).Return(server.ErrTimeout).Times(reverifyTries) // ignore discoveryRequest calls m.On("discoveryRequest", mock.Anything).Return([]*peer.Peer{}, nil).Maybe() diff --git a/packages/autopeering/discover/protocol.go b/packages/autopeering/discover/protocol.go index 756f5fe1c25e842df22c4ddc9d3386ea3a04cc7e..3cbe49361e744677789f59af69919cf8944ee543 100644 --- a/packages/autopeering/discover/protocol.go +++ b/packages/autopeering/discover/protocol.go @@ -149,7 +149,7 @@ func (p *Protocol) HandleMessage(s *server.Server, fromAddr string, fromID peer. // ------ message senders ------ // ping sends a ping to the specified peer and blocks until a reply is received or timeout. -func (p *Protocol) ping(to *peer.Peer) error { +func (p *Protocol) Ping(to *peer.Peer) error { return <-p.sendPing(to.Address(), to.ID()) } diff --git a/packages/autopeering/discover/protocol_test.go b/packages/autopeering/discover/protocol_test.go index 223c2c3ef19ec12d18f26f2887aa5da0f51d8d90..e262865122e1ef15883a869b1d2fa30bf8986590 100644 --- a/packages/autopeering/discover/protocol_test.go +++ b/packages/autopeering/discover/protocol_test.go @@ -89,11 +89,11 @@ func TestProtPingPong(t *testing.T) { peerB := getPeer(srvB) // send a ping from node A to B - t.Run("A->B", func(t *testing.T) { assert.NoError(t, protA.ping(peerB)) }) + t.Run("A->B", func(t *testing.T) { assert.NoError(t, protA.Ping(peerB)) }) time.Sleep(graceTime) // send a ping from node B to A - t.Run("B->A", func(t *testing.T) { assert.NoError(t, protB.ping(peerA)) }) + t.Run("B->A", func(t *testing.T) { assert.NoError(t, protB.Ping(peerA)) }) time.Sleep(graceTime) } @@ -109,7 +109,7 @@ func TestProtPingTimeout(t *testing.T) { peerB := getPeer(srvB) // send a ping from node A to B - err := protA.ping(peerB) + err := protA.Ping(peerB) assert.EqualError(t, err, server.ErrTimeout.Error()) } @@ -125,7 +125,7 @@ func TestProtVerifiedPeers(t *testing.T) { peerB := getPeer(srvB) // send a ping from node A to B - assert.NoError(t, protA.ping(peerB)) + assert.NoError(t, protA.Ping(peerB)) time.Sleep(graceTime) // protA should have peerB as the single verified peer @@ -148,7 +148,7 @@ func TestProtVerifiedPeer(t *testing.T) { peerB := getPeer(srvB) // send a ping from node A to B - assert.NoError(t, protA.ping(peerB)) + assert.NoError(t, protA.Ping(peerB)) time.Sleep(graceTime) // we should have peerB as a verified peer @@ -248,14 +248,14 @@ func BenchmarkPingPong(b *testing.B) { peerB := getPeer(srvB) // send initial ping to ensure that every peer is verified - err := protA.ping(peerB) + err := protA.Ping(peerB) require.NoError(b, err) time.Sleep(graceTime) b.ResetTimer() for n := 0; n < b.N; n++ { // send a ping from node A to B - _ = protA.ping(peerB) + _ = protA.Ping(peerB) } b.StopTimer() diff --git a/plugins/autopeering/autopeering.go b/plugins/autopeering/autopeering.go index f2cac97dd1aef4c7ba304f8159860e7ff4e5382f..33fb047aa5397424180c8d1641ce2a87926652f9 100644 --- a/plugins/autopeering/autopeering.go +++ b/plugins/autopeering/autopeering.go @@ -15,6 +15,7 @@ import ( "github.com/iotaledger/goshimmer/packages/autopeering/transport" "github.com/iotaledger/goshimmer/packages/parameter" "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/goshimmer/plugins/cli" "github.com/iotaledger/goshimmer/plugins/gossip" "github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/node" @@ -53,7 +54,7 @@ func configureAP() { } func start(shutdownSignal <-chan struct{}) { - defer log.Info("Stopping Auto Peering server ... done") + defer log.Info("Stopping " + name + " ... done") addr := local.GetInstance().Services().Get(service.PeeringKey) udpAddr, err := net.ResolveUDPAddr(addr.Network(), addr.String()) @@ -92,17 +93,22 @@ func start(shutdownSignal <-chan struct{}) { Discovery.Start(srv) defer Discovery.Close() + //check that discovery is working and the port is open + log.Info("Testing service ...") + checkConnection(srv, &local.GetInstance().Peer) + log.Info("Testing service ... done") + if Selection != nil { // start the peering on that connection Selection.Start(srv) defer Selection.Close() } - log.Infof("Auto Peering started: address=%s", srv.LocalAddr()) - log.Debugf("Auto Peering server started: PubKey=%s", base64.StdEncoding.EncodeToString(local.GetInstance().PublicKey())) + log.Infof(name+" started: address=%s/udp", srv.LocalAddr()) + log.Debugf(name+" server started: PubKey=%s", base64.StdEncoding.EncodeToString(local.GetInstance().PublicKey())) <-shutdownSignal - log.Info("Stopping Auto Peering server ...") + log.Info("Stopping " + name + " ...") } func parseEntryNodes() (result []*peer.Peer, err error) { @@ -128,3 +134,15 @@ func parseEntryNodes() (result []*peer.Peer, err error) { return result, nil } + +func checkConnection(srv *server.Server, self *peer.Peer) { + if err := Discovery.Ping(self); err != nil { + if err == server.ErrTimeout { + log.Errorf("Error testing service: %s", err) + addr := self.Services().Get(service.PeeringKey) + log.Panicf("Please check that %s is publicly reachable at %s/%s", + cli.AppName, addr.String(), addr.Network()) + } + log.Panicf("Error: %s", err) + } +} diff --git a/plugins/gossip/gossip.go b/plugins/gossip/gossip.go index 2e53b3364dd654e0778fea70cdf42a6b1d797dee..b6ea302a756c98149dfa9b68c849244e3a6b99d0 100644 --- a/plugins/gossip/gossip.go +++ b/plugins/gossip/gossip.go @@ -4,12 +4,15 @@ import ( "fmt" "net" "strconv" + "sync" + "github.com/iotaledger/goshimmer/packages/autopeering/peer" "github.com/iotaledger/goshimmer/packages/autopeering/peer/service" gp "github.com/iotaledger/goshimmer/packages/gossip" "github.com/iotaledger/goshimmer/packages/gossip/server" "github.com/iotaledger/goshimmer/packages/parameter" "github.com/iotaledger/goshimmer/plugins/autopeering/local" + "github.com/iotaledger/goshimmer/plugins/cli" "github.com/iotaledger/goshimmer/plugins/tangle" "github.com/iotaledger/hive.go/logger" "github.com/iotaledger/hive.go/typeutils" @@ -39,7 +42,7 @@ func configureGossip() { } func start(shutdownSignal <-chan struct{}) { - defer log.Info("Stopping Gossip ... done") + defer log.Info("Stopping " + name + " ... done") srv, err := server.ListenTCP(local.GetInstance(), log) if err != nil { @@ -47,13 +50,40 @@ func start(shutdownSignal <-chan struct{}) { } defer srv.Close() + //check that the server is working and the port is open + log.Info("Testing service ...") + checkConnection(srv, &local.GetInstance().Peer) + log.Info("Testing service ... done") + mgr.Start(srv) defer mgr.Close() - log.Infof("Gossip started: address=%v", mgr.LocalAddr()) + log.Infof(name+" started: address=%s/%s", mgr.LocalAddr().String(), mgr.LocalAddr().Network()) <-shutdownSignal - log.Info("Stopping Gossip ...") + log.Info("Stopping " + name + " ...") +} + +func checkConnection(srv *server.TCP, self *peer.Peer) { + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + conn, err := srv.AcceptPeer(self) + if err != nil { + return + } + _ = conn.Close() + }() + conn, err := srv.DialPeer(self) + if err != nil { + log.Errorf("Error testing: %s", err) + addr := self.Services().Get(service.GossipKey) + log.Panicf("Please check that %s is publicly reachable at %s/%s", + cli.AppName, addr.String(), addr.Network()) + } + _ = conn.Close() + wg.Wait() } func loadTransaction(hash []byte) ([]byte, error) {