1 Peer Discovery
Claude edited this page 2026-02-19 23:29:30 +00:00
This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Peer Discovery

Peer management, scoring, and integration with Poindexter and Borg.

Peer Structure

Each remote node in the mesh is represented as a Peer. Peers carry identity, network, and scoring information used for intelligent routing and task assignment.

type Peer struct {
    ID        string    `json:"id"`         // Node ID (derived from public key)
    Name      string    `json:"name"`       // Human-readable name
    PublicKey string    `json:"public_key"` // X25519 public key (hex)
    Address   string    `json:"address"`    // Network address (host:port)
    Role      NodeRole  `json:"role"`       // controller, worker, or dual
    AddedAt   time.Time `json:"added_at"`   // When the peer was first discovered
    LastSeen  time.Time `json:"last_seen"`  // Last successful communication
    PingMS    float64   `json:"ping_ms"`    // Round-trip latency in milliseconds
    Hops      int       `json:"hops"`       // Network hops to peer
    GeoKM     float64   `json:"geo_km"`     // Geographic distance in kilometres
    Score     float64   `json:"score"`      // Composite reliability score (0.01.0)
    Connected bool      `json:"connected"`  // Whether the peer is currently connected
}

Authentication Modes

Peer discovery supports two authentication modes to balance openness with security.

type PeerAuthMode int

const (
    PeerAuthOpen      PeerAuthMode = iota // Accept any peer that authenticates
    PeerAuthAllowlist                      // Only accept pre-approved peers
)
Mode Behaviour
PeerAuthOpen Any node that completes the challenge-response handshake is accepted
PeerAuthAllowlist Only nodes whose public keys appear on the allowlist are accepted

Scoring with Poindexter

go-p2p integrates with Poindexter to compute composite peer scores based on real network and geographic metrics.

Scoring Factors

Factor Weight Source
Latency (PingMS) High Direct WebSocket ping measurement
Hops Medium Network traceroute via Poindexter
Geographic distance (GeoKM) Low IP geolocation via Poindexter
Reliability High Historical uptime and response rate

How Scoring Works

// Poindexter measures network characteristics for each peer
metrics := poindexter.Measure(peer.Address)

peer.PingMS = metrics.Latency      // e.g. 12.5ms
peer.Hops   = metrics.Hops         // e.g. 3
peer.GeoKM  = metrics.GeoDistance   // e.g. 450.2km

// Composite score combines all factors (0.0 = worst, 1.0 = best)
peer.Score = poindexter.ComputeScore(metrics)

Using Scores for Task Assignment

Controllers use peer scores to make intelligent routing decisions:

// Sort peers by score (highest first) for task assignment
sort.Slice(peers, func(i, j int) bool {
    return peers[i].Score > peers[j].Score
})

// Assign work to the best available worker
for _, peer := range peers {
    if peer.Connected && peer.Role != node.RoleController {
        assignWork(peer, task)
        break
    }
}

Borg Integration

go-p2p uses Borg for secure storage of peer identity and mesh state via the stmf (Secure Typed Message Format) package.

Secure Peer Storage

import "github.com/Snider/Borg/stmf"

// Store peer identity as an encrypted blob
blob, err := stmf.Encrypt(peerData, encryptionKey)

// Retrieve and decrypt peer data
peerData, err := stmf.Decrypt(blob, encryptionKey)

Pointer Maps

Borg's pointer system provides indirection for peer discovery. A pointer references a blob without revealing its contents, allowing nodes to advertise their existence without exposing their full identity.

// Create a pointer to peer identity
pointer := stmf.NewPointer(blob.ID, metadata)

// Resolve pointer to retrieve peer data
blob, err := stmf.Resolve(pointer, encryptionKey)

Peer Lifecycle

Discovery          Authentication         Active              Stale
   |                    |                   |                   |
   |  handshake    +---------+     +--------+------+     +-----+
   +-------------->| Auth    |---->| Score  | Ping |---->| Evict|
                   | Check   |     | Update | Loop |     | or   |
                   +---------+     +--------+------+     | Retry|
                        |                                 +-----+
                   [rejected]
  1. Discovery — New peer connects or is discovered via mesh gossip
  2. Authentication — Challenge-response handshake (see Node-Identity)
  3. Active — Poindexter scoring, periodic ping, task-eligible
  4. Stale — No response after timeout; evicted or retry attempted

See Also