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.0–1.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]
- Discovery — New peer connects or is discovered via mesh gossip
- Authentication — Challenge-response handshake (see Node-Identity)
- Active — Poindexter scoring, periodic ping, task-eligible
- Stale — No response after timeout; evicted or retry attempted
See Also
- Home — Package overview
- Node-Identity — Identity and authentication
- Protocol-Messages — Message types for peer communication