You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
91 lines
2.2 KiB
91 lines
2.2 KiB
package discovery
|
|
|
|
import (
|
|
"github.com/ethereum/go-ethereum/log"
|
|
proto_discovery "github.com/harmony-one/harmony/api/proto/discovery"
|
|
"github.com/harmony-one/harmony/p2p"
|
|
"github.com/harmony-one/harmony/p2p/host"
|
|
)
|
|
|
|
// Constants for discovery service.
|
|
const (
|
|
numIncoming = 128
|
|
numOutgoing = 16
|
|
)
|
|
|
|
// Service is the struct for discovery service.
|
|
type Service struct {
|
|
Host p2p.Host
|
|
Rendezvous string
|
|
peerChan chan p2p.Peer
|
|
stakingChan chan p2p.Peer
|
|
stopChan chan struct{}
|
|
}
|
|
|
|
// New returns discovery service.
|
|
// h is the p2p host
|
|
// r is the rendezvous string, we use shardID to start (TODO: leo, build two overlays of network)
|
|
func New(h p2p.Host, r string, peerChan chan p2p.Peer, stakingChan chan p2p.Peer) *Service {
|
|
return &Service{
|
|
Host: h,
|
|
Rendezvous: r,
|
|
peerChan: peerChan,
|
|
stakingChan: stakingChan,
|
|
stopChan: make(chan struct{}),
|
|
}
|
|
}
|
|
|
|
// StartService starts discovery service.
|
|
func (s *Service) StartService() {
|
|
log.Info("Starting discovery service.")
|
|
s.Init()
|
|
s.Run()
|
|
}
|
|
|
|
// StopService shutdowns discovery service.
|
|
func (s *Service) StopService() {
|
|
log.Info("Shutting down discovery service.")
|
|
s.stopChan <- struct{}{}
|
|
log.Info("discovery service stopped.")
|
|
}
|
|
|
|
// Run is the main function of the service
|
|
func (s *Service) Run() {
|
|
go s.contactP2pPeers()
|
|
}
|
|
|
|
func (s *Service) contactP2pPeers() {
|
|
for {
|
|
select {
|
|
case peer, ok := <-s.peerChan:
|
|
if !ok {
|
|
log.Debug("end of info", "peer", peer.PeerID)
|
|
return
|
|
}
|
|
log.Debug("[DISCOVERY]", "peer", peer)
|
|
s.Host.AddPeer(&peer)
|
|
// TODO: stop ping if pinged before
|
|
// TODO: call staking servcie here if it is a new node
|
|
s.pingPeer(peer)
|
|
case <-s.stopChan:
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
// Init is to initialize for discoveryService.
|
|
func (s *Service) Init() {
|
|
log.Info("Init discovery service")
|
|
}
|
|
|
|
func (s *Service) pingPeer(peer p2p.Peer) {
|
|
ping := proto_discovery.NewPingMessage(s.Host.GetSelfPeer())
|
|
buffer := ping.ConstructPingMessage()
|
|
log.Debug("Sending Ping Message to", "peer", peer)
|
|
content := host.ConstructP2pMessage(byte(0), buffer)
|
|
s.Host.SendMessage(peer, content)
|
|
log.Debug("Sent Ping Message to", "peer", peer)
|
|
if s.stakingChan != nil {
|
|
s.stakingChan <- peer
|
|
}
|
|
}
|
|
|