node: configure p2p routing table with bootstrapping nodes (#1455)
Configure the bootstrapping nodes that we will connect to to seed and refresh the Routing Table if it becomes empty. Fixes an issue where the spy stops receiving gossiped messages after the node is restarted, because the Routing Table becomes empty and is never refreshed.
This commit is contained in:
parent
33f1b28662
commit
536a97066e
|
@ -92,17 +92,40 @@ func Run(obsvC chan *gossipv1.SignedObservation, obsvReqC chan *gossipv1.Observa
|
||||||
// Let's prevent our peer from having too many
|
// Let's prevent our peer from having too many
|
||||||
// connections by attaching a connection manager.
|
// connections by attaching a connection manager.
|
||||||
libp2p.ConnectionManager(connmgr.NewConnManager(
|
libp2p.ConnectionManager(connmgr.NewConnManager(
|
||||||
100, // Lowwater
|
100, // LowWater
|
||||||
400, // HighWater,
|
400, // HighWater,
|
||||||
time.Minute, // GracePeriod
|
time.Minute, // GracePeriod
|
||||||
)),
|
)),
|
||||||
|
|
||||||
// Let this host use the DHT to find other hosts
|
// Let this host use the DHT to find other hosts
|
||||||
libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) {
|
libp2p.Routing(func(h host.Host) (routing.PeerRouting, error) {
|
||||||
|
logger.Info("Connecting to bootstrap peers", zap.String("bootstrap_peers", bootstrapPeers))
|
||||||
|
bootstrappers := make([]peer.AddrInfo, 0)
|
||||||
|
for _, addr := range strings.Split(bootstrapPeers, ",") {
|
||||||
|
if addr == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
ma, err := multiaddr.NewMultiaddr(addr)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Invalid bootstrap address", zap.String("peer", addr), zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
pi, err := peer.AddrInfoFromP2pAddr(ma)
|
||||||
|
if err != nil {
|
||||||
|
logger.Error("Invalid bootstrap address", zap.String("peer", addr), zap.Error(err))
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if pi.ID == h.ID() {
|
||||||
|
logger.Info("We're a bootstrap node")
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
bootstrappers = append(bootstrappers, *pi)
|
||||||
|
}
|
||||||
// TODO(leo): Persistent data store (i.e. address book)
|
// TODO(leo): Persistent data store (i.e. address book)
|
||||||
idht, err := dht.New(ctx, h, dht.Mode(dht.ModeServer),
|
idht, err := dht.New(ctx, h, dht.Mode(dht.ModeServer),
|
||||||
// This intentionally makes us incompatible with the global IPFS DHT
|
// This intentionally makes us incompatible with the global IPFS DHT
|
||||||
dht.ProtocolPrefix(protocol.ID("/"+networkID)),
|
dht.ProtocolPrefix(protocol.ID("/"+networkID)),
|
||||||
|
dht.BootstrapPeers(bootstrappers...),
|
||||||
)
|
)
|
||||||
return idht, err
|
return idht, err
|
||||||
}),
|
}),
|
||||||
|
@ -118,8 +141,6 @@ func Run(obsvC chan *gossipv1.SignedObservation, obsvReqC chan *gossipv1.Observa
|
||||||
rootCtxCancel()
|
rootCtxCancel()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
logger.Info("Connecting to bootstrap peers", zap.String("bootstrap_peers", bootstrapPeers))
|
|
||||||
|
|
||||||
topic := fmt.Sprintf("%s/%s", networkID, "broadcast")
|
topic := fmt.Sprintf("%s/%s", networkID, "broadcast")
|
||||||
|
|
||||||
logger.Info("Subscribing pubsub topic", zap.String("topic", topic))
|
logger.Info("Subscribing pubsub topic", zap.String("topic", topic))
|
||||||
|
@ -138,49 +159,6 @@ func Run(obsvC chan *gossipv1.SignedObservation, obsvReqC chan *gossipv1.Observa
|
||||||
return fmt.Errorf("failed to subscribe topic: %w", err)
|
return fmt.Errorf("failed to subscribe topic: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add our own bootstrap nodes
|
|
||||||
|
|
||||||
// Count number of successful connection attempts. If we fail to connect to any bootstrap peer, kill
|
|
||||||
// the service and have supervisor retry it.
|
|
||||||
successes := 0
|
|
||||||
// Are we a bootstrap node? If so, it's okay to not have any peers.
|
|
||||||
bootstrapNode := false
|
|
||||||
|
|
||||||
for _, addr := range strings.Split(bootstrapPeers, ",") {
|
|
||||||
if addr == "" {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
ma, err := multiaddr.NewMultiaddr(addr)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("Invalid bootstrap address", zap.String("peer", addr), zap.Error(err))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
pi, err := peer.AddrInfoFromP2pAddr(ma)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("Invalid bootstrap address", zap.String("peer", addr), zap.Error(err))
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if pi.ID == h.ID() {
|
|
||||||
logger.Info("We're a bootstrap node")
|
|
||||||
bootstrapNode = true
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = h.Connect(ctx, *pi); err != nil {
|
|
||||||
logger.Error("Failed to connect to bootstrap peer", zap.String("peer", addr), zap.Error(err))
|
|
||||||
} else {
|
|
||||||
successes += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: continually reconnect to bootstrap nodes?
|
|
||||||
if successes == 0 && !bootstrapNode {
|
|
||||||
return fmt.Errorf("failed to connect to any bootstrap peer")
|
|
||||||
} else {
|
|
||||||
logger.Info("Connected to bootstrap peers", zap.Int("num", successes))
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.Info("Node has been started", zap.String("peer_id", h.ID().String()),
|
logger.Info("Node has been started", zap.String("peer_id", h.ID().String()),
|
||||||
zap.String("addrs", fmt.Sprintf("%v", h.Addrs())))
|
zap.String("addrs", fmt.Sprintf("%v", h.Addrs())))
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue