mirror of
https://github.com/DeBrosOfficial/network.git
synced 2025-12-15 04:48:50 +00:00
Fixed discoverability issues and bugs
This commit is contained in:
parent
f2d5a0790e
commit
85e0bc13f4
@ -54,11 +54,15 @@ func parse_and_return_network_flags() (configPath *string, dataDir, nodeID *stri
|
|||||||
|
|
||||||
// Return config values but preserve command line flag values for overrides
|
// Return config values but preserve command line flag values for overrides
|
||||||
// The command line flags will be applied later in load_args_into_config
|
// The command line flags will be applied later in load_args_into_config
|
||||||
|
// Create separate variables to avoid modifying config directly
|
||||||
|
configDataDir := cfg.Node.DataDir
|
||||||
|
configAdvAddr := cfg.Discovery.HttpAdvAddress
|
||||||
|
|
||||||
return configPath,
|
return configPath,
|
||||||
&cfg.Node.DataDir,
|
&configDataDir,
|
||||||
&cfg.Node.ID,
|
nodeID, // Keep the command line flag value, not config value
|
||||||
p2pPort, // Keep the command line flag value
|
p2pPort, // Keep the command line flag value
|
||||||
&cfg.Discovery.HttpAdvAddress,
|
&configAdvAddr,
|
||||||
help,
|
help,
|
||||||
cfg // Return the loaded config
|
cfg // Return the loaded config
|
||||||
}
|
}
|
||||||
@ -91,13 +95,12 @@ func check_if_should_open_help(help *bool) {
|
|||||||
func select_data_dir(dataDir *string, nodeID *string) {
|
func select_data_dir(dataDir *string, nodeID *string) {
|
||||||
logger := setup_logger(logging.ComponentNode)
|
logger := setup_logger(logging.ComponentNode)
|
||||||
|
|
||||||
// If dataDir is not set from config, set it based on nodeID
|
// If nodeID is provided via command line, use it to override the data directory
|
||||||
if *dataDir == "" {
|
if *nodeID != "" {
|
||||||
if *nodeID == "" {
|
*dataDir = fmt.Sprintf("./data/%s", *nodeID)
|
||||||
*dataDir = "./data/node"
|
} else if *dataDir == "" {
|
||||||
} else {
|
// Fallback to default if neither nodeID nor dataDir is set
|
||||||
*dataDir = fmt.Sprintf("./data/%s", *nodeID)
|
*dataDir = "./data/node"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Info("Successfully selected Data Directory of: %s", zap.String("dataDir", *dataDir))
|
logger.Info("Successfully selected Data Directory of: %s", zap.String("dataDir", *dataDir))
|
||||||
@ -175,7 +178,6 @@ func main() {
|
|||||||
_, dataDir, nodeID, p2pPort, advAddr, help, loadedConfig := parse_and_return_network_flags()
|
_, dataDir, nodeID, p2pPort, advAddr, help, loadedConfig := parse_and_return_network_flags()
|
||||||
|
|
||||||
check_if_should_open_help(help)
|
check_if_should_open_help(help)
|
||||||
select_data_dir(dataDir, nodeID)
|
|
||||||
|
|
||||||
// Load Node Configuration - use loaded config if available, otherwise use default
|
// Load Node Configuration - use loaded config if available, otherwise use default
|
||||||
var cfg *config.Config
|
var cfg *config.Config
|
||||||
@ -187,6 +189,9 @@ func main() {
|
|||||||
logger.ComponentInfo(logging.ComponentNode, "Using default configuration")
|
logger.ComponentInfo(logging.ComponentNode, "Using default configuration")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Select data directory based on node ID (this overrides config)
|
||||||
|
select_data_dir(dataDir, nodeID)
|
||||||
|
|
||||||
// Apply command line argument overrides
|
// Apply command line argument overrides
|
||||||
load_args_into_config(cfg, p2pPort, advAddr, dataDir)
|
load_args_into_config(cfg, p2pPort, advAddr, dataDir)
|
||||||
logger.ComponentInfo(logging.ComponentNode, "Command line arguments applied to configuration")
|
logger.ComponentInfo(logging.ComponentNode, "Command line arguments applied to configuration")
|
||||||
|
|||||||
@ -114,7 +114,7 @@ func DefaultConfig() *Config {
|
|||||||
},
|
},
|
||||||
Discovery: DiscoveryConfig{
|
Discovery: DiscoveryConfig{
|
||||||
BootstrapPeers: []string{
|
BootstrapPeers: []string{
|
||||||
"/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWKdj4B3LdZ8whYGaa97giwWCoSELciRp6qsFrDvz2Etah",
|
"/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWJSkwRXX1PYA5g2bkAnKani7frhygZp5iY6U853JJPb7K",
|
||||||
// "/ip4/217.76.54.168/tcp/4001/p2p/12D3KooWDp7xeShVY9uHfqNVPSsJeCKUatAviFZV8Y1joox5nUvx",
|
// "/ip4/217.76.54.168/tcp/4001/p2p/12D3KooWDp7xeShVY9uHfqNVPSsJeCKUatAviFZV8Y1joox5nUvx",
|
||||||
// "/ip4/217.76.54.178/tcp/4001/p2p/12D3KooWKZnirPwNT4URtNSWK45f6vLkEs4xyUZ792F8Uj1oYnm1",
|
// "/ip4/217.76.54.178/tcp/4001/p2p/12D3KooWKZnirPwNT4URtNSWK45f6vLkEs4xyUZ792F8Uj1oYnm1",
|
||||||
// "/ip4/51.83.128.181/tcp/4001/p2p/12D3KooWBn2Zf1R8v9pEfmz7hDZ5b3oADxfejA3zJBYzKRCzgvhR",
|
// "/ip4/51.83.128.181/tcp/4001/p2p/12D3KooWBn2Zf1R8v9pEfmz7hDZ5b3oADxfejA3zJBYzKRCzgvhR",
|
||||||
|
|||||||
@ -38,8 +38,9 @@ type Node struct {
|
|||||||
clusterManager *database.ClusterManager
|
clusterManager *database.ClusterManager
|
||||||
|
|
||||||
// Peer discovery
|
// Peer discovery
|
||||||
discoveryCancel context.CancelFunc
|
discoveryCancel context.CancelFunc
|
||||||
bootstrapCancel context.CancelFunc
|
bootstrapCancel context.CancelFunc
|
||||||
|
peerDiscoveryService *pubsub.PeerDiscoveryService
|
||||||
|
|
||||||
// PubSub
|
// PubSub
|
||||||
pubsub *pubsub.ClientAdapter
|
pubsub *pubsub.ClientAdapter
|
||||||
@ -255,6 +256,15 @@ func (n *Node) startLibP2P() error {
|
|||||||
n.pubsub = pubsub.NewClientAdapter(ps, n.config.Discovery.NodeNamespace)
|
n.pubsub = pubsub.NewClientAdapter(ps, n.config.Discovery.NodeNamespace)
|
||||||
n.logger.Info("Initialized pubsub adapter on namespace", zap.String("namespace", n.config.Discovery.NodeNamespace))
|
n.logger.Info("Initialized pubsub adapter on namespace", zap.String("namespace", n.config.Discovery.NodeNamespace))
|
||||||
|
|
||||||
|
// Initialize peer discovery service
|
||||||
|
// Note: We need to access the internal manager from the adapter
|
||||||
|
peerDiscoveryManager := pubsub.NewManager(ps, n.config.Discovery.NodeNamespace)
|
||||||
|
n.peerDiscoveryService = pubsub.NewPeerDiscoveryService(h, peerDiscoveryManager, n.logger.Logger)
|
||||||
|
if err := n.peerDiscoveryService.Start(); err != nil {
|
||||||
|
return fmt.Errorf("failed to start peer discovery service: %w", err)
|
||||||
|
}
|
||||||
|
n.logger.ComponentInfo(logging.ComponentNode, "Started active peer discovery service")
|
||||||
|
|
||||||
// Log configured bootstrap peers
|
// Log configured bootstrap peers
|
||||||
if len(n.config.Discovery.BootstrapPeers) > 0 {
|
if len(n.config.Discovery.BootstrapPeers) > 0 {
|
||||||
n.logger.ComponentInfo(logging.ComponentNode, "Configured bootstrap peers",
|
n.logger.ComponentInfo(logging.ComponentNode, "Configured bootstrap peers",
|
||||||
@ -564,6 +574,13 @@ func (n *Node) Stop() error {
|
|||||||
// Stop peer discovery
|
// Stop peer discovery
|
||||||
n.stopPeerDiscovery()
|
n.stopPeerDiscovery()
|
||||||
|
|
||||||
|
// Stop peer discovery service
|
||||||
|
if n.peerDiscoveryService != nil {
|
||||||
|
if err := n.peerDiscoveryService.Stop(); err != nil {
|
||||||
|
n.logger.ComponentWarn(logging.ComponentNode, "Error stopping peer discovery service", zap.Error(err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Stop cluster manager
|
// Stop cluster manager
|
||||||
if n.clusterManager != nil {
|
if n.clusterManager != nil {
|
||||||
if err := n.clusterManager.Stop(); err != nil {
|
if err := n.clusterManager.Stop(); err != nil {
|
||||||
|
|||||||
@ -41,4 +41,4 @@ func (a *ClientAdapter) ListTopics(ctx context.Context) ([]string, error) {
|
|||||||
// Close closes all subscriptions and topics
|
// Close closes all subscriptions and topics
|
||||||
func (a *ClientAdapter) Close() error {
|
func (a *ClientAdapter) Close() error {
|
||||||
return a.manager.Close()
|
return a.manager.Close()
|
||||||
}
|
}
|
||||||
|
|||||||
194
pkg/pubsub/peer_discovery.go
Normal file
194
pkg/pubsub/peer_discovery.go
Normal file
@ -0,0 +1,194 @@
|
|||||||
|
package pubsub
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/libp2p/go-libp2p/core/host"
|
||||||
|
"github.com/libp2p/go-libp2p/core/peer"
|
||||||
|
"github.com/multiformats/go-multiaddr"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PeerAnnouncement represents a peer announcing its addresses
|
||||||
|
type PeerAnnouncement struct {
|
||||||
|
PeerID string `json:"peer_id"`
|
||||||
|
Addresses []string `json:"addresses"`
|
||||||
|
Timestamp int64 `json:"timestamp"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PeerDiscoveryService handles active peer discovery via pubsub
|
||||||
|
type PeerDiscoveryService struct {
|
||||||
|
host host.Host
|
||||||
|
manager *Manager
|
||||||
|
logger *zap.Logger
|
||||||
|
ctx context.Context
|
||||||
|
cancel context.CancelFunc
|
||||||
|
topicName string
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPeerDiscoveryService creates a new peer discovery service
|
||||||
|
func NewPeerDiscoveryService(host host.Host, manager *Manager, logger *zap.Logger) *PeerDiscoveryService {
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
return &PeerDiscoveryService{
|
||||||
|
host: host,
|
||||||
|
manager: manager,
|
||||||
|
logger: logger,
|
||||||
|
ctx: ctx,
|
||||||
|
cancel: cancel,
|
||||||
|
topicName: "/debros/peer-discovery/v1",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start begins the peer discovery service
|
||||||
|
func (pds *PeerDiscoveryService) Start() error {
|
||||||
|
// Subscribe to peer discovery topic
|
||||||
|
if err := pds.manager.Subscribe(pds.ctx, pds.topicName, pds.handlePeerAnnouncement); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Announce our own presence periodically
|
||||||
|
go pds.announcePeriodically()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Stop stops the peer discovery service
|
||||||
|
func (pds *PeerDiscoveryService) Stop() error {
|
||||||
|
pds.cancel()
|
||||||
|
return pds.manager.Unsubscribe(pds.ctx, pds.topicName)
|
||||||
|
}
|
||||||
|
|
||||||
|
// announcePeriodically announces this peer's addresses to the network
|
||||||
|
func (pds *PeerDiscoveryService) announcePeriodically() {
|
||||||
|
// Initial announcement after a short delay to ensure subscriptions are ready
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
pds.announceOurselves()
|
||||||
|
|
||||||
|
// Then announce periodically
|
||||||
|
ticker := time.NewTicker(30 * time.Second)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-pds.ctx.Done():
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
|
pds.announceOurselves()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// announceOurselves publishes our peer info to the discovery topic
|
||||||
|
func (pds *PeerDiscoveryService) announceOurselves() {
|
||||||
|
// Get our listen addresses
|
||||||
|
addrs := pds.host.Addrs()
|
||||||
|
addrStrs := make([]string, 0, len(addrs))
|
||||||
|
|
||||||
|
for _, addr := range addrs {
|
||||||
|
// Create full multiaddr with peer ID
|
||||||
|
fullAddr := addr.Encapsulate(multiaddr.StringCast("/p2p/" + pds.host.ID().String()))
|
||||||
|
addrStrs = append(addrStrs, fullAddr.String())
|
||||||
|
}
|
||||||
|
|
||||||
|
announcement := PeerAnnouncement{
|
||||||
|
PeerID: pds.host.ID().String(),
|
||||||
|
Addresses: addrStrs,
|
||||||
|
Timestamp: time.Now().Unix(),
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := json.Marshal(announcement)
|
||||||
|
if err != nil {
|
||||||
|
pds.logger.Debug("Failed to marshal peer announcement", zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := pds.manager.Publish(pds.ctx, pds.topicName, data); err != nil {
|
||||||
|
pds.logger.Debug("Failed to publish peer announcement", zap.Error(err))
|
||||||
|
} else {
|
||||||
|
pds.logger.Debug("Announced peer presence",
|
||||||
|
zap.String("peer_id", pds.host.ID().String()[:16]+"..."),
|
||||||
|
zap.Int("addresses", len(addrStrs)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handlePeerAnnouncement processes incoming peer announcements
|
||||||
|
func (pds *PeerDiscoveryService) handlePeerAnnouncement(topic string, data []byte) error {
|
||||||
|
var announcement PeerAnnouncement
|
||||||
|
if err := json.Unmarshal(data, &announcement); err != nil {
|
||||||
|
pds.logger.Debug("Failed to unmarshal peer announcement", zap.Error(err))
|
||||||
|
return nil // Don't return error, just skip invalid messages
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip our own announcements
|
||||||
|
if announcement.PeerID == pds.host.ID().String() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the announcement is recent (within last 5 minutes)
|
||||||
|
if time.Now().Unix()-announcement.Timestamp > 300 {
|
||||||
|
return nil // Ignore stale announcements
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse peer ID
|
||||||
|
peerID, err := peer.Decode(announcement.PeerID)
|
||||||
|
if err != nil {
|
||||||
|
pds.logger.Debug("Invalid peer ID in announcement", zap.Error(err))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Skip if it's our own ID (redundant check)
|
||||||
|
if peerID == pds.host.ID() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse and add addresses to peerstore
|
||||||
|
var validAddrs []multiaddr.Multiaddr
|
||||||
|
for _, addrStr := range announcement.Addresses {
|
||||||
|
addr, err := multiaddr.NewMultiaddr(addrStr)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
validAddrs = append(validAddrs, addr)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(validAddrs) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add peer info to peerstore with a reasonable TTL
|
||||||
|
pds.host.Peerstore().AddAddrs(peerID, validAddrs, time.Hour*24)
|
||||||
|
|
||||||
|
pds.logger.Debug("Discovered peer via announcement",
|
||||||
|
zap.String("peer_id", peerID.String()[:16]+"..."),
|
||||||
|
zap.Int("addresses", len(validAddrs)))
|
||||||
|
|
||||||
|
// Try to connect to the peer if we're not already connected
|
||||||
|
if pds.host.Network().Connectedness(peerID) != 1 { // 1 = Connected
|
||||||
|
go pds.tryConnectToPeer(peerID, validAddrs)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// tryConnectToPeer attempts to connect to a discovered peer
|
||||||
|
func (pds *PeerDiscoveryService) tryConnectToPeer(peerID peer.ID, addrs []multiaddr.Multiaddr) {
|
||||||
|
ctx, cancel := context.WithTimeout(pds.ctx, 15*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
peerInfo := peer.AddrInfo{
|
||||||
|
ID: peerID,
|
||||||
|
Addrs: addrs,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := pds.host.Connect(ctx, peerInfo); err != nil {
|
||||||
|
pds.logger.Debug("Failed to connect to discovered peer",
|
||||||
|
zap.String("peer_id", peerID.String()[:16]+"..."),
|
||||||
|
zap.Error(err))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pds.logger.Info("Successfully connected to discovered peer",
|
||||||
|
zap.String("peer_id", peerID.String()[:16]+"..."))
|
||||||
|
}
|
||||||
@ -363,7 +363,16 @@ func (cm *ClusterManager) announceCapacity() {
|
|||||||
|
|
||||||
// monitorHealth monitors the health of active databases
|
// monitorHealth monitors the health of active databases
|
||||||
func (cm *ClusterManager) monitorHealth() {
|
func (cm *ClusterManager) monitorHealth() {
|
||||||
ticker := time.NewTicker(cm.discoveryConfig.HealthCheckInterval)
|
// Use a default interval if the configured one is invalid
|
||||||
|
interval := cm.discoveryConfig.HealthCheckInterval
|
||||||
|
if interval <= 0 {
|
||||||
|
interval = 10 * time.Second
|
||||||
|
cm.logger.Warn("Invalid health check interval, using default",
|
||||||
|
zap.Duration("configured", cm.discoveryConfig.HealthCheckInterval),
|
||||||
|
zap.Duration("default", interval))
|
||||||
|
}
|
||||||
|
|
||||||
|
ticker := time.NewTicker(interval)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
||||||
for {
|
for {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user