/** * Super-peer topology — well-resourced "super peers" form a full * mesh among themselves and accept connections from any peer; ordinary * peers connect to a bounded number of super peers (default 3). */ import type { PeerInfo } from "../../types/peer.types.js"; import { type AdmitDecision, pickLowestScore, type TopologySelectOptions, type TopologyStrategy, } from "./topology-strategy.js"; export interface SuperPeerStrategyOptions { /** Whether this node is itself a super peer. */ readonly selfIsSuperPeer: boolean; /** Set of peer ids known to be super peers. */ readonly superPeerIds: ReadonlySet; /** Cap on outbound super-peer connections for non-super peers. */ readonly targetSuperPeers?: number; } const DEFAULT_TARGET_SUPER_PEERS = 3; export class SuperPeerStrategy implements TopologyStrategy { public readonly name = "super-peer" as const; private readonly selfIsSuperPeer: boolean; private readonly superPeerIds: ReadonlySet; private readonly targetSuperPeers: number; public constructor(opts: SuperPeerStrategyOptions) { this.selfIsSuperPeer = opts.selfIsSuperPeer; this.superPeerIds = opts.superPeerIds; this.targetSuperPeers = opts.targetSuperPeers ?? DEFAULT_TARGET_SUPER_PEERS; } public selectConnections( currentPeers: readonly PeerInfo[], newPeer: PeerInfo, options: TopologySelectOptions ): readonly PeerInfo[] { if (newPeer.id === options.selfPeerId) return []; if (this.selfIsSuperPeer) { if (currentPeers.length >= options.maxPeers) return []; return [newPeer]; } if (!this.superPeerIds.has(newPeer.id)) return []; const connectedSuperPeers = currentPeers.filter((p) => this.superPeerIds.has(p.id) ).length; if (connectedSuperPeers >= this.targetSuperPeers) return []; if (currentPeers.length >= options.maxPeers) return []; return [newPeer]; } public admitOrEvict( currentPeers: readonly PeerInfo[], newPeer: PeerInfo, options: TopologySelectOptions ): AdmitDecision { if (currentPeers.some((p) => p.id === newPeer.id)) { return { admit: false }; } if (this.selfIsSuperPeer) { if (currentPeers.length < options.maxPeers) { return { admit: true }; } const evict = pickLowestScore( currentPeers.filter((p) => !this.superPeerIds.has(p.id)), options.metricsFor ); if (evict === undefined) return { admit: false }; return { admit: true, evict }; } if (!this.superPeerIds.has(newPeer.id)) return { admit: false }; const connectedSuperPeers = currentPeers.filter((p) => this.superPeerIds.has(p.id) ); if ( connectedSuperPeers.length < this.targetSuperPeers && currentPeers.length < options.maxPeers ) { return { admit: true }; } return { admit: false }; } }