blob: f00e7f6a7173fb9911f288f08053bbe718f30776 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import type { RuntimeHostPeerRouteResolution } from '../client/peer-client.js';
import type {
RuntimeHostPeerIdentityProof,
RuntimeHostPeerNativeStream,
RuntimeHostPeerTransitRelayCandidate,
RuntimeHostPeerTransitSnapshot,
} from '../transport/peer-native.js';
import { createHash } from 'node:crypto';
import { performance } from 'node:perf_hooks';
import {
canonicalPeerMeshMemberAdvertisement,
canonicalPeerMeshRoster,
createPeerMeshInvitationSecret,
validatePeerMeshInvitation,
decodeSignedPeerMeshMemberAdvertisement,
decodeSignedPeerMeshRoster,
generatePeerMeshAuthorityKeyPair,
matchesPeerMeshInvitationSecret,
PEER_MESH_MAX_MEMBERS,
PEER_MESH_MAX_MESHES,
PEER_MESH_MAX_INVITATION_RECORDS,
PEER_MESH_MAX_PENDING_INVITATIONS,
PEER_MESH_MAX_TRANSIT_ADDRESSES_PER_RELAY,
PEER_MESH_MAX_TRANSIT_RELAY_ADDRESSES,
peerMeshMemberAdvertisementSigningBytes,
peerMeshId,
peerMeshInvitationSecretDigest,
signPeerMeshRoster,
type SignedPeerMeshMemberAdvertisementV1,
type SignedPeerMeshRosterV1,
} from './model.js';
import { canonicalPeerMeshDisplayName } from './display-name.js';
import type { PeerMeshInvitationV1 } from '../protocol/peer-mesh.js';
import {
authenticateSignedPeerReachabilityLease,
decodeSignedPeerReachabilityLease,
isPeerReachabilityLeaseCurrent,
PEER_REACHABILITY_MAX_CLOCK_SKEW_MS,
peerReachabilityLeaseSigningBytes,
peerReachabilityLeaseReceipt,
PEER_REACHABILITY_RECOVERY_HORIZON_MS,
verifySignedPeerReachabilityLease,
type PeerReachabilityPublisher,
type PeerReachabilityLeaseReceipt,
type SignedPeerReachabilityLeaseV1,
} from '../peer-reachability/index.js';
import {
authorityKeys,
isActivePeerMeshMembership as isActiveMembership,
isRetiredPeerMeshState as isRetired,
openPeerMeshStateStore,
type PendingPeerMeshJoin,
type PeerMeshAuthorityStateV1,
type PeerMeshReplicaStateV1,
type PeerMeshStateStore,
type PeerMeshStateV1,
type PeerMeshStoredStateV1,
} from './store.js';
const CONTROL_FRAME_MAX_BYTES = 128 * 1024;
const DEFAULT_INVITATION_TTL_MS = 15 * 60 * 1_000;
const CONNECT_DEADLINE_MS = 30_000;
const CONTROL_REQUEST_DEADLINE_MS = 10_000;
const MAX_ACTIVE_CONTROL_STREAMS = 32;
const MAX_ACTIVE_CONTROL_STREAMS_PER_PEER = 2;
const EVIDENCE_PAGE_SIZE = 2;
const RECONCILE_CONCURRENCY = 4;
const RECONCILE_DEADLINE_MS = 60 * 1_000;
const RECONCILE_INTERVAL_MS = 5 * 60 * 1_000;
interface RedeemInvitationRequest {
readonly kind: 'redeem-invitation';
readonly meshId: string;
readonly secret: string;
readonly reachability: SignedPeerReachabilityLeaseV1;
readonly advertisement: SignedPeerMeshMemberAdvertisementV1;
}
type RedeemInvitationResponse =
| {
readonly kind: 'invitation-redeemed';
readonly roster: SignedPeerMeshRosterV1;
readonly reachability: readonly SignedPeerReachabilityLeaseV1[];
readonly advertisements: readonly SignedPeerMeshMemberAdvertisementV1[];
}
| {
readonly kind: 'invitation-rejected';
readonly reason: RedeemInvitationRejectionReason;
};
type RedeemInvitationRejectionReason = 'invalid' | 'expired' | 'closed' | 'full';
interface PeerMeshEvidenceSummary {
readonly peerId: string;
readonly revision: number;
readonly digest: string;
}
interface SyncPeerMeshRequest {
readonly kind: 'sync';
readonly meshId: string;
readonly roster: SignedPeerMeshRosterV1;
readonly reachability: SignedPeerReachabilityLeaseV1;
readonly advertisement: SignedPeerMeshMemberAdvertisementV1;
readonly knownReachability: readonly PeerMeshEvidenceSummary[];
readonly knownAdvertisements: readonly PeerMeshEvidenceSummary[];
}
type SyncPeerMeshResponse =
| {
readonly kind: 'sync-result';
readonly roster: SignedPeerMeshRosterV1;
readonly reachability: readonly SignedPeerReachabilityLeaseV1[];
readonly advertisements: readonly SignedPeerMeshMemberAdvertisementV1[];
readonly more: boolean;
}
| { readonly kind: 'sync-rejected'; readonly reason: 'unknown' };
interface LeavePeerMeshRequest {
readonly kind: 'leave';
readonly meshId: string;
readonly roster: SignedPeerMeshRosterV1;
}
type LeavePeerMeshResponse =
| { readonly kind: 'left'; readonly roster: SignedPeerMeshRosterV1 }
| { readonly kind: 'leave-rejected'; readonly reason: 'unknown' };
interface AnnouncePeerMeshRosterRequest {
readonly kind: 'announce-roster';
readonly meshId: string;
readonly roster: SignedPeerMeshRosterV1;
}
type AnnouncePeerMeshRosterResponse =
| { readonly kind: 'roster-observed' }
| { readonly kind: 'roster-rejected'; readonly reason: 'unknown' };
type PeerMeshControlRequest =
| RedeemInvitationRequest
| SyncPeerMeshRequest
| LeavePeerMeshRequest
| AnnouncePeerMeshRosterRequest;
interface LocalPeerMeshEvidence {
readonly reachability: SignedPeerReachabilityLeaseV1;
readonly advertisements: readonly SignedPeerMeshMemberAdvertisementV1[];
}
export interface PeerMeshNode {
localPeerId(): string;
displayName(): string | undefined;
setDisplayName(displayName: string | null): Promise<void>;
setMeshDisplayName(meshId: string, displayName: string | null): Promise<PeerMeshStatus>;
status(): readonly PeerMeshStatus[];
create(): Promise<PeerMeshStatus>;
invite(meshId: string, input?: { readonly ttlMs?: number }): Promise<PeerMeshInvitationV1>;
join(invitation: PeerMeshInvitationV1, signal?: AbortSignal): Promise<PeerMeshStatus>;
remove(meshId: string, peerId: string): Promise<PeerMeshStatus>;
leave(meshId: string, signal?: AbortSignal): Promise<void>;
closeMesh(meshId: string): Promise<PeerMeshStatus>;
setTransitMesh(meshId: string | null): Promise<void>;
transitMeshId(): string | null;
transitSnapshot(): RuntimeHostPeerTransitSnapshot;
resolveRoutes(peerId: string): RuntimeHostPeerRouteResolution;
prepareRoutes(peerId: string, signal: AbortSignal): Promise<void>;
subscribeRoutes(peerId: string, listener: () => void): () => void;
peerConnected(peerId: string): void;
reconcile(signal?: AbortSignal): Promise<void>;
serve(): Promise<void>;
close(): Promise<void>;
}
export interface PeerMeshStatus {
readonly role: 'authority' | 'member';
readonly authorityPeerId: string;
readonly roster: SignedPeerMeshRosterV1;
readonly pendingInvitationCount: number;
readonly memberRoutes: readonly PeerMeshMemberRouteStatus[];
}
export interface PeerMeshMemberRouteStatus {
readonly peerId: string;
readonly endpointKind?: 'client' | 'host';
readonly displayName?: string;
readonly state: 'local' | 'connecting' | 'reachable' | 'reconnecting' | 'needs_repair';
readonly expiresAt?: number;
}
export interface PeerMeshTransport {
identity(): Readonly<{
peerId: string;
}>;
signIdentity(payload: Buffer): Promise<RuntimeHostPeerIdentityProof>;
verifyIdentity(peerId: string, payload: Buffer, proof: RuntimeHostPeerIdentityProof): boolean;
isConnected(peerId: string): boolean;
transitSnapshot(): RuntimeHostPeerTransitSnapshot;
configureTransit(input: {
readonly allowedPeerIds: readonly string[];
readonly approvedRelayPeerIds: readonly string[];
readonly relayCandidates: readonly RuntimeHostPeerTransitRelayCandidate[];
}): Promise<void>;
connectMeshControl(
input: {
readonly peerId: string;
readonly routeHints: readonly string[];
readonly coordinationRelays?: readonly string[];
readonly transitRelayPeerIds?: readonly string[];
readonly directDeadlineMs: number;
},
signal?: AbortSignal,
): Promise<RuntimeHostPeerNativeStream>;
serveMeshControl(
onStream: (stream: RuntimeHostPeerNativeStream) => void,
signal: AbortSignal,
): Promise<void>;
}
export async function openPeerMeshNode(input: {
readonly dataRoot: string;
readonly peer: PeerMeshTransport;
readonly reachability: PeerReachabilityPublisher;
readonly endpointKind?: 'client' | 'host';
readonly now?: () => number;
readonly monotonicNow?: () => number;
readonly onBackgroundReconcileError?: (error: unknown) => void;
}): Promise<PeerMeshNode> {
const store = await openPeerMeshStateStore(input.dataRoot, input.peer.identity().peerId);
const node = new PeerMeshNodeImpl({ ...input, store });
try {
await node.initialize();
return node;
} catch (error) {
await node.close().catch(() => undefined);
throw error;
}
}
class PeerMeshNodeImpl implements PeerMeshNode {
readonly #store: PeerMeshStateStore;
readonly #peer: PeerMeshTransport;
readonly #reachability: PeerReachabilityPublisher;
readonly #endpointKind: 'client' | 'host' | undefined;
readonly #now: () => number;
readonly #monotonicNow: () => number;
readonly #onBackgroundReconcileError: ((error: unknown) => void) | undefined;
readonly #activeControlStreams = new Set<RuntimeHostPeerNativeStream>();
readonly #lifetime = new AbortController();
#admissionTail = Promise.resolve();
#reconcileTail = Promise.resolve();
#transitTail = Promise.resolve();
#reconcileCursor = 0;
#gossipCursor = 0;
#evidenceRefreshTask: Promise<LocalPeerMeshEvidence | undefined> | undefined;
#unsubscribeReachability: (() => void) | undefined;
#reconcileGeneration = 0;
readonly #reconcileWaiters = new Set<() => void>();
readonly #reachabilityReceipts = new Map<string, PeerReachabilityLeaseReceipt>();
readonly #completedRecoverySweeps = new Set<string>();
readonly #routeResolutionListeners = new Map<string, Set<() => void>>();
#serveTask: Promise<void> | undefined;
#closeTask: Promise<void> | undefined;
constructor(input: {
readonly store: PeerMeshStateStore;
readonly peer: PeerMeshTransport;
readonly reachability: PeerReachabilityPublisher;
readonly endpointKind?: 'client' | 'host';
readonly now?: () => number;
readonly monotonicNow?: () => number;
readonly onBackgroundReconcileError?: (error: unknown) => void;
}) {
this.#store = input.store;
this.#peer = input.peer;
this.#reachability = input.reachability;
this.#endpointKind = input.endpointKind;
this.#now = input.now ?? Date.now;
this.#monotonicNow = input.monotonicNow ?? (input.now ? input.now : () => performance.now());
this.#onBackgroundReconcileError = input.onBackgroundReconcileError;
}
async initialize(): Promise<void> {
const stored = this.#store.read();
const now = this.#now();
for (const lease of stored.reachability) {
const signed = authenticateSignedPeerReachabilityLease({
value: lease,
expectedPeerId: lease.lease.peerId,
verifyIdentity: this.#peer.verifyIdentity.bind(this.#peer),
});
if (
usableHistoricalReachability(signed, now) &&
signed.lease.issuedAt <= now + PEER_REACHABILITY_MAX_CLOCK_SKEW_MS
) {
this.#recordReachabilityReceipt(signed);
}
}
for (const advertisement of stored.advertisements) {
this.#assertAdvertisementSignature(advertisement);
}
if (stored.reachability.some((signed) => !usableHistoricalReachability(signed, now))) {
await this.#store.mutate((current) => ({
state: {
...current,
reachability: current.reachability.filter((signed) =>
usableHistoricalReachability(signed, now),
),
},
result: undefined,
}));
}
await this.#refreshLocalEvidence();
this.#unsubscribeReachability = this.#reachability.subscribe(() => {
this.#triggerReconciliation();
});
await this.#reconcileTransit();
}
localPeerId(): string {
this.#assertOpen();
return this.#peer.identity().peerId;
}
displayName(): string | undefined {
this.#assertOpen();
return this.#store.read().displayName ?? undefined;
}
setDisplayName(displayName: string | null): Promise<void> {
return this.#admitMesh(async () => {
const canonical = displayName === null ? null : canonicalPeerMeshDisplayName(displayName);
await this.#store.mutate(async (current) => {
if (current.displayName === canonical) return { state: current, result: undefined };
const next = { ...current, displayName: canonical };
const advertisements = await this.#localAdvertisementsFor(next);
return {
state: {
...next,
advertisements: mergeAdvertisements(current.advertisements, advertisements),
},
result: undefined,
};
});
this.#triggerReconciliation();
});
}
setMeshDisplayName(meshId: string, displayName: string | null): Promise<PeerMeshStatus> {
return this.#admitMesh(async () => {
const canonical =
displayName === null ? undefined : canonicalPeerMeshDisplayName(displayName);
const announcement = await this.#store.mutate((current) => {
const state = requireAuthority(current.meshes, meshId);
if (state.roster.roster.closed) throw new Error('Peer Mesh is closed');
if (state.roster.roster.displayName === canonical)
return { state: current, result: undefined };
const { displayName: _currentDisplayName, ...currentRoster } = state.roster.roster;
const roster = signPeerMeshRoster(
canonicalPeerMeshRoster({
...currentRoster,
revision: state.roster.roster.revision + 1,
...(canonical ? { displayName: canonical } : {}),
}),
authorityKeys(state),
);
return {
state: {
...current,
meshes: replaceMesh(current.meshes, { ...state, roster }),
},
result: {
roster,
targets: rosterAnnouncementTargets(
state.roster.roster.members,
current.reachability,
this.#peer.identity().peerId,
this.#now(),
),
},
};
});
if (announcement) this.#scheduleRosterAnnouncement(announcement.roster, announcement.targets);
const stored = this.#store.read();
return peerMeshStatus(
requireAuthority(stored.meshes, meshId),
this.#peer.identity(),
this.#endpointKind,
stored.reachability,
stored.advertisements,
this.#now(),
(peerId) => this.#peer.isConnected(peerId),
(peerId) => this.resolveRoutes(peerId),
(signed) => this.#isReachabilityCurrent(signed),
);
});
}
status(): readonly PeerMeshStatus[] {
this.#assertOpen();
const identity = this.#peer.identity();
const stored = this.#store.read();
return Object.freeze(
stored.meshes
.filter((state) => state.roster.roster.closed || isActiveMembership(state, identity.peerId))
.map((state) =>
peerMeshStatus(
state,
identity,
this.#endpointKind,
stored.reachability,
stored.advertisements,
this.#now(),
(peerId) => this.#peer.isConnected(peerId),
(peerId) => this.resolveRoutes(peerId),
(signed) => this.#isReachabilityCurrent(signed),
),
),
);
}
create(): Promise<PeerMeshStatus> {
return this.#admitMesh(async () => {
const identity = this.#peer.identity();
const keys = generatePeerMeshAuthorityKeyPair();
const roster = signPeerMeshRoster(
canonicalPeerMeshRoster({
version: 1,
meshId: peerMeshId(keys.publicKey),
authorityPeerId: identity.peerId,
revision: 1,
members: [identity.peerId],
closed: false,
}),
keys,
);
const state: PeerMeshStateV1 = {
role: 'authority',
roster,
authorityPrivateKey: keys.privateKey,
invitations: [],
};
const reachability = await this.#reachability.refresh();
const now = this.#now();
await this.#store.mutate((current) => {
assertMeshCapacity(current.meshes, identity.peerId, current.pendingJoins.length);
return {
state: {
...current,
meshes: appendMesh(current.meshes, state, identity.peerId),
reachability: mergeReachability(current.reachability, [reachability], now),
},
result: undefined,
};
});
await this.#refreshLocalEvidence();
const stored = this.#store.read();
return peerMeshStatus(
findMesh(stored.meshes, state.roster.roster.meshId)!,
identity,
this.#endpointKind,
stored.reachability,
stored.advertisements,
now,
(peerId) => this.#peer.isConnected(peerId),
(peerId) => this.resolveRoutes(peerId),
(signed) => this.#isReachabilityCurrent(signed),
);
});
}
async invite(
meshId: string,
input: { readonly ttlMs?: number } = {},
): Promise<PeerMeshInvitationV1> {
if (this.#lifetime.signal.aborted) throw new Error('Peer Mesh node is closed');
const now = this.#now();
const identity = this.#peer.identity();
const ttlMs = input.ttlMs ?? DEFAULT_INVITATION_TTL_MS;
if (!Number.isSafeInteger(ttlMs) || ttlMs < 1_000 || ttlMs > 24 * 60 * 60 * 1_000) {
throw new Error('Peer Mesh invitation TTL must be between 1 second and 1 day');
}
const reachability = await this.#reachability.refresh();
return this.#store.mutate((current) => {
const state = requireAuthority(current.meshes, meshId);
if (state.roster.roster.closed) throw new Error('Peer Mesh is closed');
const invitations = state.invitations.filter(
(invitation) => invitation.status === 'redeemed' || invitation.expiresAt > now,
);
if (
invitations.filter(({ status }) => status === 'pending').length >=
PEER_MESH_MAX_PENDING_INVITATIONS
)
throw new Error('Peer Mesh has too many pending invitations');
if (invitations.length >= PEER_MESH_MAX_INVITATION_RECORDS)
throw new Error('Peer Mesh has too many recent invitations');
const secret = createPeerMeshInvitationSecret();
const expiresAt = now + ttlMs;
const invitation: PeerMeshInvitationV1 = {
version: 1,
meshId: state.roster.roster.meshId,
authorityPublicKey: state.roster.authorityPublicKey,
secret,
expiresAt,
reachability,
};
return {
state: {
...current,
meshes: replaceMesh(current.meshes, {
...state,
invitations: [
...invitations,
{
status: 'pending',
secretDigest: peerMeshInvitationSecretDigest(secret),
expiresAt,
},
],
}),
},
result: Object.freeze(invitation),
};
});
}
join(invitationValue: PeerMeshInvitationV1, signal?: AbortSignal): Promise<PeerMeshStatus> {
return this.#admitMesh(async () => {
const invitation = validatePeerMeshInvitation(invitationValue);
const authorityReachability = this.#authenticateReachability(
invitation.reachability,
invitation.reachability.lease.peerId,
true,
);
const current = this.#store.read();
const existing = findMesh(current.meshes, invitation.meshId);
const pending = current.pendingJoins.find(
({ invitation: candidate }) => candidate.meshId === invitation.meshId,
);
if (!pending && invitation.expiresAt <= this.#now()) {
throw new Error('Peer Mesh invitation has expired');
}
const localPeerId = this.#peer.identity().peerId;
if (existing?.roster.roster.closed) {
throw new Error('Peer Mesh is closed');
}
if (existing?.role === 'authority') {
throw new Error('This peer already belongs to that Peer Mesh');
}
if (
existing?.role === 'replica' &&
authorityReachability.lease.peerId !== existing.roster.roster.authorityPeerId
) {
throw new Error('Peer Mesh repair invitation has the wrong authority identity');
}
assertRejoinSettled(existing, localPeerId);
if (pending && pending.invitation.secret !== invitation.secret) {
throw new Error('This Peer Mesh already has an unresolved join attempt');
}
if (pending?.phase === 'leave_pending') {
throw new Error('This Peer Mesh join is still being cancelled');
}
if (!existing && !pending) {
assertMeshCapacity(current.meshes, localPeerId, current.pendingJoins.length);
}
const operationSignal = signal
? AbortSignal.any([signal, this.#lifetime.signal])
: this.#lifetime.signal;
let stream: RuntimeHostPeerNativeStream | undefined;
let joinIntentAdmitted = pending !== undefined;
try {
stream = await this.#peer.connectMeshControl(
{
...dialTarget(authorityReachability),
directDeadlineMs: CONNECT_DEADLINE_MS,
},
operationSignal,
);
if (stream.peerId !== authorityReachability.lease.peerId) {
throw new Error('Peer Mesh control stream has the wrong peer identity');
}
const localReachability = await this.#reachability.refresh();
const localAdvertisement = await this.#signLocalAdvertisement(invitation.meshId);
await this.#store.mutate((current) => {
const existing = findMesh(current.meshes, invitation.meshId);
if (existing?.role === 'authority') {
throw new Error('This peer already belongs to that Peer Mesh');
}
assertRejoinSettled(existing, localPeerId);
const pending = current.pendingJoins.find(
({ invitation: candidate }) => candidate.meshId === invitation.meshId,
);
if (pending && pending.invitation.secret !== invitation.secret) {
throw new Error('This Peer Mesh already has an unresolved join attempt');
}
if (pending?.phase === 'leave_pending') {
throw new Error('This Peer Mesh join is still being cancelled');
}
if (!existing && !pending) {
assertMeshCapacity(current.meshes, localPeerId, current.pendingJoins.length);
}
const next: PendingPeerMeshJoin = pending
? { ...pending, invitation }
: { invitation, phase: 'prepared' };
return {
state: {
...current,
pendingJoins: pending
? current.pendingJoins.map((candidate) =>
candidate === pending ? next : candidate,
)
: [...current.pendingJoins, next],
},
result: undefined,
};
});
joinIntentAdmitted = true;
return await this.#redeemPendingJoin(
invitation,
localReachability,
localAdvertisement,
stream,
operationSignal,
);
} catch (error) {
if (signal?.aborted && joinIntentAdmitted) {
await this.#cancelPendingJoin(invitation.meshId);
await this.#reconcileTransit();
}
void this.reconcile().catch(() => undefined);
throw error;
} finally {
await stream?.close().catch(() => undefined);
}
});
}
async #redeemPendingJoin(
invitation: PeerMeshInvitationV1,
localReachability: SignedPeerReachabilityLeaseV1,
localAdvertisement: SignedPeerMeshMemberAdvertisementV1,
stream: RuntimeHostPeerNativeStream,
signal: AbortSignal,
): Promise<PeerMeshStatus> {
signal.throwIfAborted();
const authorityReachability = this.#authenticateReachability(
invitation.reachability,
invitation.reachability.lease.peerId,
true,
);
const dispatch = await this.#store.mutate((current) => {
const pending = current.pendingJoins.find(
({ invitation: candidate }) =>
candidate.meshId === invitation.meshId && candidate.secret === invitation.secret,
);
if (!pending) {
return { state: current, result: false };
}
if (pending.phase !== 'prepared') {
return { state: current, result: true };
}
return {
state: {
...current,
pendingJoins: current.pendingJoins.map((candidate) =>
candidate === pending ? { ...candidate, phase: 'outcome_unknown' } : candidate,
),
},
result: true,
};
});
if (!dispatch) throw new Error('Peer Mesh join is no longer pending');
signal.throwIfAborted();
const response = await exchangeControl(
stream,
{
kind: 'redeem-invitation',
meshId: invitation.meshId,
secret: invitation.secret,
reachability: localReachability,
advertisement: localAdvertisement,
},
decodeRedeemResponse,
signal,
);
if (response.kind === 'invitation-rejected') {
await this.#discardPendingJoin(invitation);
throw new Error(`Peer Mesh invitation was rejected: ${response.reason}`);
}
const roster = decodeSignedPeerMeshRoster(response.roster);
const identity = this.#peer.identity();
if (
roster.roster.meshId !== invitation.meshId ||
roster.authorityPublicKey !== invitation.authorityPublicKey ||
roster.roster.authorityPeerId !== stream.peerId ||
invitation.reachability.lease.peerId !== stream.peerId ||
!roster.roster.members.includes(identity.peerId)
) {
await this.#discardPendingJoin(invitation);
throw new Error('Peer Mesh authority returned an unrelated roster');
}
const reachability = this.#validateReachabilityPage(response.reachability, roster, true);
const advertisements = this.#validateAdvertisementPage(response.advertisements, roster);
signal.throwIfAborted();
await this.#store.mutate((current) => {
const pending = current.pendingJoins.find(
({ invitation: candidate }) =>
candidate.meshId === invitation.meshId && candidate.secret === invitation.secret,
);
const existing = findMesh(current.meshes, invitation.meshId);
if (!pending) {
if (!existing || existing.role === 'authority') {
throw new Error('Peer Mesh join is no longer pending');
}
return { state: current, result: undefined };
}
const selectedRoster = existing ? selectRoster(existing.roster, roster) : roster;
if (!selectedRoster.roster.members.includes(identity.peerId)) {
throw new Error('Peer Mesh invitation did not establish an active membership');
}
const state: PeerMeshReplicaStateV1 = {
role: 'replica',
roster: selectedRoster,
desiredMembership: pending.phase === 'leave_pending' ? 'left' : 'active',
};
return {
state: {
...current,
meshes: existing
? replaceMesh(current.meshes, state)
: appendMesh(current.meshes, state, identity.peerId),
pendingJoins: current.pendingJoins.filter((candidate) => candidate !== pending),
reachability: mergeReachability(
current.reachability,
[...reachability, authorityReachability, localReachability],
this.#now(),
),
advertisements: mergeAdvertisements(current.advertisements, [
...advertisements,
localAdvertisement,
]),
},
result: undefined,
};
});
this.#recordReachabilityReceipts([...reachability, authorityReachability, localReachability]);
signal.throwIfAborted();
await this.#refreshLocalEvidence();
signal.throwIfAborted();
await this.#reconcileTransit();
signal.throwIfAborted();
const stored = this.#store.read();
const state = findMesh(stored.meshes, invitation.meshId);
if (!state) throw new Error('Peer Mesh join was not retained');
return peerMeshStatus(
state,
identity,
this.#endpointKind,
stored.reachability,
stored.advertisements,
this.#now(),
(peerId) => this.#peer.isConnected(peerId),
(peerId) => this.resolveRoutes(peerId),
(signed) => this.#isReachabilityCurrent(signed),
);
}
#discardPendingJoin(invitation: PeerMeshInvitationV1): Promise<void> {
return this.#store.mutate((current) => ({
state: {
...current,
pendingJoins: current.pendingJoins.filter(
({ invitation: candidate }) =>
candidate.meshId !== invitation.meshId || candidate.secret !== invitation.secret,
),
},
result: undefined,
}));
}
#cancelPendingJoin(meshId: string): Promise<void> {
return this.#store.mutate((current) => {
const existing = findMesh(current.meshes, meshId);
return {
state: {
...current,
meshes:
existing?.role === 'replica'
? replaceMesh(current.meshes, {
...existing,
desiredMembership: 'left',
})
: current.meshes,
pendingJoins: current.pendingJoins.flatMap((pending) => {
if (pending.invitation.meshId !== meshId) return [pending];
return pending.phase === 'prepared' ? [] : [{ ...pending, phase: 'leave_pending' }];
}),
},
result: undefined,
};
});
}
async #resumePendingJoin(pending: PendingPeerMeshJoin, signal: AbortSignal): Promise<void> {
const authorityReachability = this.#authenticateReachability(
pending.invitation.reachability,
pending.invitation.reachability.lease.peerId,
true,
);
const existing = findMesh(this.#store.read().meshes, pending.invitation.meshId);
if (
existing?.role === 'replica' &&
authorityReachability.lease.peerId !== existing.roster.roster.authorityPeerId
) {
throw new Error('Peer Mesh repair invitation has the wrong authority identity');
}
const stream = await this.#peer.connectMeshControl(
{
...dialTarget(authorityReachability),
directDeadlineMs: CONNECT_DEADLINE_MS,
},
signal,
);
try {
const localReachability = await this.#reachability.refresh();
const localAdvertisement = await this.#signLocalAdvertisement(pending.invitation.meshId);
await this.#redeemPendingJoin(
pending.invitation,
localReachability,
localAdvertisement,
stream,
signal,
);
} finally {
await stream.close().catch(() => undefined);
}
}
remove(meshId: string, peerId: string): Promise<PeerMeshStatus> {
if (this.#lifetime.signal.aborted) return Promise.reject(new Error('Peer Mesh node is closed'));
return this.#updateAuthorityRoster(meshId, false, (state) => {
if (peerId === this.#peer.identity().peerId) {
throw new Error('Peer Mesh authority cannot remove itself');
}
const members = state.roster.roster.members.filter((member) => member !== peerId);
if (members.length === state.roster.roster.members.length) {
throw new Error('Peer is not a member of this Peer Mesh');
}
return { members, closed: false };
});
}
leave(meshId: string, signal?: AbortSignal): Promise<void> {
return this.#admitMesh(async () => {
signal?.throwIfAborted();
const localPeerId = this.#peer.identity().peerId;
await this.#store.mutate((current) => {
const state = findMesh(current.meshes, meshId);
if (!state || !isActiveMembership(state, localPeerId)) {
throw new Error('This peer does not belong to that Peer Mesh');
}
if (state.role === 'authority') {
throw new Error('Close a Peer Mesh instead of leaving its authority');
}
return {
state: {
...current,
meshes: replaceMesh(current.meshes, {
...state,
desiredMembership: 'left',
}),
},
result: undefined,
};
});
try {
await this.#reconcileTransit();
} finally {
void this.reconcile().catch(() => undefined);
}
});
}
closeMesh(meshId: string): Promise<PeerMeshStatus> {
if (this.#lifetime.signal.aborted) return Promise.reject(new Error('Peer Mesh node is closed'));
return this.#updateAuthorityRoster(meshId, true, (state) => ({
members: state.roster.roster.members,
closed: true,
}));
}
setTransitMesh(meshId: string | null): Promise<void> {
return this.#admitMesh(async () => {
const localPeerId = this.#peer.identity().peerId;
await this.#store.mutate(async (current) => {
if (
meshId !== null &&
!current.meshes.some(
(mesh) => mesh.roster.roster.meshId === meshId && isActiveMembership(mesh, localPeerId),
)
) {
throw new Error('Transit requires an active Peer Mesh membership');
}
if (current.transitMeshId === meshId) return { state: current, result: undefined };
const next = { ...current, transitMeshId: meshId };
const advertisements = await this.#localAdvertisementsFor(next);
return {
state: {
...next,
advertisements: mergeAdvertisements(current.advertisements, advertisements),
},
result: undefined,
};
});
try {
await this.#reconcileTransit();
} finally {
this.#triggerReconciliation();
}
});
}
transitSnapshot(): RuntimeHostPeerTransitSnapshot {
this.#assertOpen();
return this.#peer.transitSnapshot();
}
transitMeshId(): string | null {
this.#assertOpen();
return this.#store.read().transitMeshId;
}
resolveRoutes(peerId: string) {
this.#assertOpen();
const now = this.#now();
const stored = this.#store.read();
const localPeerId = this.#peer.identity().peerId;
this.#pruneCompletedRecoverySweeps(stored, localPeerId);
const sharedMeshIds = stored.meshes
.filter(
(state) =>
isActiveMembership(state, localPeerId) && state.roster.roster.members.includes(peerId),
)
.map(({ roster }) => roster.roster.meshId);
const visible = sharedMeshIds.length > 0;
if (!visible) return emptyRouteResolution('exhausted');
const reachability = latestReachability(stored.reachability, peerId, now, true)?.lease;
const transitRelayPeerIds = transitRelayCandidates(
eligibleTransitEvidence(stored, localPeerId, now, (signed) =>
this.#isReachabilityCurrent(signed),
).filter(
({ meshId, lease }) => lease.lease.peerId !== peerId && sharedMeshIds.includes(meshId),
),
).map(({ peerId: relayPeerId }) => relayPeerId);
const routeHints = reachability?.directRoutes ?? [];
const coordinationRelays = reachability?.coordinationRoutes ?? [];
const hasCandidates =
routeHints.length + coordinationRelays.length + transitRelayPeerIds.length > 0;
const state = hasCandidates
? 'available'
: hasPeerRecoverySource(stored, sharedMeshIds, peerId, localPeerId, now)
? 'recovering'
: this.#completedRecoverySweeps.has(peerId)
? 'exhausted'
: 'recovering';
return Object.freeze({
state,
routeHints,
coordinationRelays,
transitRelayPeerIds: Object.freeze(transitRelayPeerIds),
});
}
peerConnected(peerId: string): void {
if (this.#lifetime.signal.aborted) return;
const localPeerId = this.#peer.identity().peerId;
if (
peerId !== localPeerId &&
this.#store
.read()
.meshes.some(
(state) =>
isActiveMembership(state, localPeerId) && state.roster.roster.members.includes(peerId),
)
)
this.#triggerReconciliation();
}
async prepareRoutes(peerId: string, signal: AbortSignal): Promise<void> {
this.#assertOpen();
signal.throwIfAborted();
this.#setRecoverySweepCompleted(peerId, false);
const localPeerId = this.#peer.identity().peerId;
const stored = this.#store.read();
const visible = this.#pruneCompletedRecoverySweeps(stored, localPeerId).has(peerId);
if (!visible) return;
// A signed route can remain within its TTL after a peer restarted or
// rotated Relay reservations. Every connection establishment therefore
// asks the Mesh control plane for its newest record. Callers with a
// self-contained invitation run this reconciliation in parallel with the
// first dial; callers without usable routes wait for it.
try {
await this.#queueReconcile(signal, peerId);
} finally {
if (!signal.aborted && !this.#lifetime.signal.aborted) {
this.#setRecoverySweepCompleted(peerId, true);
}
}
}
#pruneCompletedRecoverySweeps(
stored = this.#store.read(),
localPeerId = this.#peer.identity().peerId,
): ReadonlySet<string> {
const visiblePeerIds = new Set<string>();
for (const state of stored.meshes) {
if (!isActiveMembership(state, localPeerId)) continue;
for (const memberPeerId of state.roster.roster.members) {
if (memberPeerId !== localPeerId) visiblePeerIds.add(memberPeerId);
}
}
for (const peerId of this.#completedRecoverySweeps) {
if (!visiblePeerIds.has(peerId)) this.#completedRecoverySweeps.delete(peerId);
}
return visiblePeerIds;
}
subscribeRoutes(peerId: string, listener: () => void): () => void {
this.#assertOpen();
let current = this.resolveRoutes(peerId);
const observe = () => {
const next = this.resolveRoutes(peerId);
if (sameResolvedRoutes(current, next)) return;
current = next;
try {
listener();
} catch {
// Route observers cannot control Mesh reconciliation.
}
};
const listeners = this.#routeResolutionListeners.get(peerId) ?? new Set<() => void>();
listeners.add(observe);
this.#routeResolutionListeners.set(peerId, listeners);
const unsubscribeStore = this.#store.subscribe(observe);
return () => {
unsubscribeStore();
listeners.delete(observe);
if (listeners.size === 0) this.#routeResolutionListeners.delete(peerId);
};
}
#setRecoverySweepCompleted(peerId: string, completed: boolean): void {
const retain = completed && this.#pruneCompletedRecoverySweeps().has(peerId);
const changed = retain
? !this.#completedRecoverySweeps.has(peerId)
: this.#completedRecoverySweeps.has(peerId);
if (!changed) return;
if (retain) this.#completedRecoverySweeps.add(peerId);
else this.#completedRecoverySweeps.delete(peerId);
for (const listener of this.#routeResolutionListeners.get(peerId) ?? []) listener();
}
reconcile(signal?: AbortSignal): Promise<void> {
return this.#queueReconcile(signal);
}
#queueReconcile(signal?: AbortSignal, excludedPeerId?: string): Promise<void> {
if (this.#lifetime.signal.aborted) return Promise.reject(new Error('Peer Mesh node is closed'));
const previous = this.#reconcileTail;
let release!: () => void;
const turn = new Promise<void>((resolve) => {
release = resolve;
});
this.#reconcileTail = previous.then(() => turn);
return waitForTurn(previous, signal)
.then(() => this.#reconcile(signal, excludedPeerId))
.finally(release);
}
async serve(): Promise<void> {
if (this.#lifetime.signal.aborted) throw new Error('Peer Mesh node is closed');
if (this.#serveTask) throw new Error('Peer Mesh node is already serving');
const serveLifetime = new AbortController();
const signal = AbortSignal.any([this.#lifetime.signal, serveLifetime.signal]);
const inbound = this.#peer.serveMeshControl((stream) => this.#acceptIncoming(stream), signal);
const reconciliation = this.#runReconciliation(signal);
const serving = (async () => {
try {
await Promise.race([inbound, this.#store.terminalFailure]);
if (!signal.aborted) throw new Error('Peer Mesh control transport stopped unexpectedly');
} finally {
serveLifetime.abort();
await reconciliation;
}
})();
this.#serveTask = serving;
try {
await serving;
} finally {
if (this.#serveTask === serving) {
this.#serveTask = undefined;
}
}
}
close(): Promise<void> {
this.#closeTask ??= this.#close();
return this.#closeTask;
}
async #close(): Promise<void> {
this.#lifetime.abort();
this.#unsubscribeReachability?.();
this.#unsubscribeReachability = undefined;
for (const wake of this.#reconcileWaiters) wake();
this.#reconcileWaiters.clear();
await this.#serveTask?.catch(() => undefined);
for (const stream of this.#activeControlStreams) stream.abort();
this.#activeControlStreams.clear();
this.#routeResolutionListeners.clear();
await Promise.all([this.#admissionTail, this.#reconcileTail, this.#transitTail]);
return this.#store.close();
}
async #runReconciliation(signal: AbortSignal): Promise<void> {
let failureReported = false;
while (!signal.aborted) {
const observedGeneration = this.#reconcileGeneration;
try {
await this.reconcile(signal);
failureReported = false;
} catch (error) {
if (!signal.aborted && !failureReported) {
failureReported = true;
try {
this.#onBackgroundReconcileError?.(error);
} catch {
// Diagnostics cannot control Peer Mesh reconciliation.
}
}
}
await this.#waitForReconciliationTrigger(observedGeneration, signal).catch(() => undefined);
}
}
async #waitForReconciliationTrigger(
observedGeneration: number,
signal: AbortSignal,
): Promise<void> {
if (this.#reconcileGeneration !== observedGeneration || signal.aborted) return;
let wake!: () => void;
const triggered = new Promise<void>((resolve) => {
wake = resolve;
this.#reconcileWaiters.add(wake);
});
const timeout = setTimeout(wake, RECONCILE_INTERVAL_MS);
signal.addEventListener('abort', wake, { once: true });
if (this.#reconcileGeneration !== observedGeneration || signal.aborted) wake();
try {
await triggered;
} finally {
clearTimeout(timeout);
signal.removeEventListener('abort', wake);
this.#reconcileWaiters.delete(wake);
}
}
#triggerReconciliation(): void {
this.#reconcileGeneration += 1;
for (const wake of this.#reconcileWaiters) wake();
this.#reconcileWaiters.clear();
}
async #reconcile(signal?: AbortSignal, excludedPeerId?: string): Promise<void> {
const lifetimeSignal = signal
? AbortSignal.any([signal, this.#lifetime.signal])
: this.#lifetime.signal;
lifetimeSignal.throwIfAborted();
await this.#reconcileTransit();
await this.#refreshLocalEvidence();
const identity = this.#peer.identity();
const stored = this.#store.read();
const memberships = stored.meshes.filter(
(state) =>
!state.roster.roster.closed && state.roster.roster.members.includes(identity.peerId),
);
const pending: Array<
| { readonly kind: 'join'; readonly join: PendingPeerMeshJoin }
| {
readonly kind: 'membership';
readonly meshId: string;
readonly target: ReturnType<typeof dialTarget>;
readonly desiredMembership: 'active' | 'left';
readonly roster: SignedPeerMeshRosterV1;
}
> = stored.pendingJoins
.filter(({ invitation }) => invitation.reachability.lease.peerId !== excludedPeerId)
.map((join) => ({ kind: 'join', join }));
const gossipCursor = this.#gossipCursor;
this.#gossipCursor = (this.#gossipCursor + 1) % PEER_MESH_MAX_MEMBERS;
const now = this.#now();
const targetFor = (peerId: string): ReturnType<typeof dialTarget> | undefined => {
const signed = latestReachability(stored.reachability, peerId, now, true);
if (signed) return dialTarget(signed);
// A fresh Session Share can reconnect an existing member after all of
// its stored routes expired. Reuse that authenticated connection to
// exchange signed evidence; the connection itself grants no membership.
return this.#peer.isConnected(peerId)
? { peerId, routeHints: [], coordinationRelays: [] }
: undefined;
};
for (const [index, state] of memberships.entries()) {
const meshId = state.roster.roster.meshId;
const desiredMembership = state.role === 'replica' ? state.desiredMembership : 'active';
const authority =
state.role === 'replica' ? targetFor(state.roster.roster.authorityPeerId) : undefined;
if (authority && authority.peerId !== excludedPeerId) {
pending.push({
kind: 'membership',
meshId,
target: authority,
desiredMembership,
roster: state.roster,
});
}
if (desiredMembership === 'left') continue;
const rotatingTargets = state.roster.roster.members
.filter(
(peerId) =>
peerId !== identity.peerId &&
peerId !== excludedPeerId &&
(state.role === 'authority' || peerId !== state.roster.roster.authorityPeerId),
)
.flatMap((peerId) => {
const target = targetFor(peerId);
return target ? [target] : [];
});
if (rotatingTargets.length === 0) continue;
pending.push({
kind: 'membership',
meshId,
target: rotatingTargets[(gossipCursor + index) % rotatingTargets.length]!,
desiredMembership,
roster: state.roster,
});
}
if (pending.length === 0) return;
const start = this.#reconcileCursor % pending.length;
const deadline = AbortSignal.timeout(RECONCILE_DEADLINE_MS);
const operationSignal = AbortSignal.any([lifetimeSignal, deadline]);
const failures: unknown[] = [];
let next = 0;
const worker = async () => {
while (!operationSignal.aborted) {
const offset = next;
next += 1;
if (offset >= pending.length) return;
const operation = pending[(start + offset) % pending.length]!;
try {
if (operation.kind === 'join') {
await this.#resumePendingJoin(operation.join, operationSignal);
} else if (operation.desiredMembership === 'left') {
await this.#notifyLeave(
operation.meshId,
operation.target,
operation.roster,
operationSignal,
);
} else {
await this.#syncPeer(operation.meshId, operation.target, operationSignal);
}
} catch (error) {
if (lifetimeSignal.aborted) lifetimeSignal.throwIfAborted();
if (operation.kind === 'join' || operation.desiredMembership === 'left') {
failures.push(error);
}
if (deadline.aborted) return;
}
}
};
await Promise.all(
Array.from({ length: Math.min(RECONCILE_CONCURRENCY, pending.length) }, worker),
);
this.#reconcileCursor = (start + Math.min(next, pending.length)) % pending.length;
await this.#reconcileTransit();
lifetimeSignal.throwIfAborted();
if (failures.length > 0) {
throw new AggregateError(
failures,
'Peer Mesh reconciliation did not reach every pending intent',
);
}
}
async #notifyLeave(
meshId: string,
target: ReturnType<typeof dialTarget>,
roster: SignedPeerMeshRosterV1,
signal: AbortSignal,
): Promise<void> {
const stream = await this.#peer.connectMeshControl(
{
...target,
directDeadlineMs: CONNECT_DEADLINE_MS,
},
signal,
);
try {
const response = await exchangeControl(
stream,
{ kind: 'leave', meshId, roster },
decodeLeaveResponse,
signal,
);
if (response.kind === 'leave-rejected') {
throw new Error('Peer Mesh authority rejected the leave request');
}
await this.#applySync(meshId, response.roster, [], []);
} finally {
await stream.close().catch(() => undefined);
}
}
async #syncPeer(
meshId: string,
target: ReturnType<typeof dialTarget>,
signal: AbortSignal,
): Promise<void> {
const localPeerId = this.#peer.identity().peerId;
const targetPeerId = target.peerId;
for (let page = 0; page <= PEER_MESH_MAX_MEMBERS; page += 1) {
if (!isActiveMeshMember(this.#store.read().meshes, meshId, localPeerId, targetPeerId)) return;
const discovered = this.resolveRoutes(targetPeerId);
const stream = await this.#peer.connectMeshControl(
{
peerId: targetPeerId,
routeHints: mergeAddresses(discovered?.routeHints ?? [], target.routeHints),
coordinationRelays: mergeAddresses(
discovered?.coordinationRelays ?? [],
target.coordinationRelays,
),
transitRelayPeerIds: discovered?.transitRelayPeerIds,
directDeadlineMs: CONNECT_DEADLINE_MS,
},
signal,
);
try {
await this.#refreshLocalEvidence();
const stored = this.#store.read();
if (!isActiveMeshMember(stored.meshes, meshId, localPeerId, targetPeerId)) return;
const state = findMesh(stored.meshes, meshId)!;
const reachability = latestReachability(
stored.reachability,
localPeerId,
this.#now(),
true,
);
const advertisement = findAdvertisement(stored.advertisements, meshId, localPeerId);
if (!reachability || !advertisement) {
throw new Error('Peer Mesh local evidence is unavailable');
}
const response = await exchangeControl(
stream,
{
kind: 'sync',
meshId,
roster: state.roster,
reachability,
advertisement,
knownReachability: reachabilitySummaries(
stored.reachability,
state.roster,
this.#now(),
),
knownAdvertisements: advertisementSummaries(stored.advertisements, state.roster),
},
decodeSyncResponse,
signal,
);
if (response.kind === 'sync-rejected') {
throw new Error(`Peer Mesh synchronization was rejected: ${response.reason}`);
}
await this.#applySync(
meshId,
response.roster,
response.reachability,
response.advertisements,
);
if (!response.more) return;
} finally {
await stream.close().catch(() => undefined);
}
}
throw new Error('Peer Mesh synchronization exceeded its page bound');
}
#refreshLocalEvidence(): Promise<LocalPeerMeshEvidence | undefined> {
this.#evidenceRefreshTask ??= this.#refreshLocalEvidenceOnce().finally(() => {
this.#evidenceRefreshTask = undefined;
});
return this.#evidenceRefreshTask;
}
async #refreshLocalEvidenceOnce(): Promise<LocalPeerMeshEvidence | undefined> {
const reachability = await this.#reachability.refresh();
const identity = this.#peer.identity();
const now = this.#now();
return this.#store.mutate(async (current) => {
const active = current.meshes.filter((state) => isActiveMembership(state, identity.peerId));
if (active.length === 0) {
return { state: current, result: undefined };
}
const advertisements = await this.#localAdvertisementsFor(current);
return {
state: {
...current,
reachability: mergeReachability(current.reachability, [reachability], now),
advertisements: mergeAdvertisements(current.advertisements, advertisements),
},
result: Object.freeze({
reachability,
advertisements: Object.freeze(advertisements),
}),
};
});
}
async #localAdvertisementsFor(
stored: PeerMeshStoredStateV1,
): Promise<readonly SignedPeerMeshMemberAdvertisementV1[]> {
const identity = this.#peer.identity();
const advertisements: SignedPeerMeshMemberAdvertisementV1[] = [];
for (const state of stored.meshes) {
if (!isActiveMembership(state, identity.peerId)) continue;
const meshId = state.roster.roster.meshId;
const existing = findAdvertisement(stored.advertisements, meshId, identity.peerId);
advertisements.push(
isCurrentLocalAdvertisement(existing, meshId, identity.peerId, stored, this.#endpointKind)
? existing
: await this.#signLocalAdvertisement(meshId, stored),
);
}
return Object.freeze(advertisements);
}
async #signLocalAdvertisement(
meshId: string,
stored: PeerMeshStoredStateV1 = this.#store.read(),
): Promise<SignedPeerMeshMemberAdvertisementV1> {
const identity = this.#peer.identity();
const maxRevision = stored.advertisements
.filter(
({ advertisement }) =>
advertisement.meshId === meshId && advertisement.peerId === identity.peerId,
)
.reduce((maximum, { advertisement }) => Math.max(maximum, advertisement.revision), 0);
const advertisement = canonicalPeerMeshMemberAdvertisement({
version: 1,
meshId,
peerId: identity.peerId,
revision: maxRevision + 1,
...(this.#endpointKind ? { endpointKind: this.#endpointKind } : {}),
...(stored.displayName ? { displayName: stored.displayName } : {}),
offersTransit: stored.transitMeshId === meshId,
});
const proof = await this.#peer.signIdentity(
peerMeshMemberAdvertisementSigningBytes(advertisement),
);
const signed = decodeSignedPeerMeshMemberAdvertisement({
advertisement,
publicKey: proof.publicKey.toString('base64url'),
signature: proof.signature.toString('base64url'),
});
this.#assertAdvertisementSignature(signed);
return signed;
}
#validateReachabilityPage(
values: readonly SignedPeerReachabilityLeaseV1[],
roster: SignedPeerMeshRosterV1,
allowExpired: boolean,
): readonly SignedPeerReachabilityLeaseV1[] {
if (values.length > EVIDENCE_PAGE_SIZE) {
throw new Error('Too many Peer Mesh reachability leases');
}
const reachability = values.map((value) => {
const signed = decodeSignedPeerReachabilityLease(value);
if (!roster.roster.members.includes(signed.lease.peerId)) {
throw new Error('Peer Mesh reachability is outside the active roster');
}
return this.#authenticateReachability(signed, signed.lease.peerId, allowExpired);
});
if (new Set(reachability.map(({ lease }) => lease.peerId)).size !== reachability.length) {
throw new Error('Duplicate Peer Mesh reachability leases');
}
return Object.freeze(reachability);
}
#authenticateReachability(
value: SignedPeerReachabilityLeaseV1,
expectedPeerId: string,
allowExpired = false,
): SignedPeerReachabilityLeaseV1 {
const signed = verifySignedPeerReachabilityLease({
value,
expectedPeerId,
now: this.#now(),
verifyIdentity: this.#peer.verifyIdentity.bind(this.#peer),
...(allowExpired ? { allowExpired: true } : {}),
});
if (
allowExpired &&
signed.lease.expiresAt <= this.#now() - PEER_REACHABILITY_RECOVERY_HORIZON_MS
) {
throw new Error('Peer Mesh reachability is outside the recovery horizon');
}
return signed;
}
#validateAdvertisementPage(
values: readonly SignedPeerMeshMemberAdvertisementV1[],
roster: SignedPeerMeshRosterV1,
): readonly SignedPeerMeshMemberAdvertisementV1[] {
if (values.length > EVIDENCE_PAGE_SIZE) {
throw new Error('Too many Peer Mesh member advertisements');
}
const advertisements = values.map((value) => {
const signed = decodeSignedPeerMeshMemberAdvertisement(value);
if (
signed.advertisement.meshId !== roster.roster.meshId ||
!roster.roster.members.includes(signed.advertisement.peerId)
) {
throw new Error('Peer Mesh member advertisement is outside the active roster');
}
this.#assertAdvertisementSignature(signed);
return signed;
});
const keys = advertisements.map(({ advertisement }) => advertisement.peerId);
if (new Set(keys).size !== keys.length) {
throw new Error('Duplicate Peer Mesh member advertisements');
}
return Object.freeze(advertisements);
}
#validateAdvertisementForPeer(
value: SignedPeerMeshMemberAdvertisementV1,
meshId: string,
peerId: string,
): SignedPeerMeshMemberAdvertisementV1 {
const signed = decodeSignedPeerMeshMemberAdvertisement(value);
if (signed.advertisement.meshId !== meshId || signed.advertisement.peerId !== peerId) {
throw new Error('Peer Mesh member advertisement belongs to a different member');
}
this.#assertAdvertisementSignature(signed);
return signed;
}
#assertAdvertisementSignature(signedValue: SignedPeerMeshMemberAdvertisementV1): void {
const signed = decodeSignedPeerMeshMemberAdvertisement(signedValue);
const valid = this.#peer.verifyIdentity(
signed.advertisement.peerId,
peerMeshMemberAdvertisementSigningBytes(signed.advertisement),
{
publicKey: Buffer.from(signed.publicKey, 'base64url'),
signature: Buffer.from(signed.signature, 'base64url'),
},
);
if (!valid) throw new Error('Peer Mesh member advertisement signature is invalid');
}
#recordReachabilityReceipt(signed: SignedPeerReachabilityLeaseV1): void {
this.#recordReachabilityReceipts([signed]);
}
#recordReachabilityReceipts(values: readonly SignedPeerReachabilityLeaseV1[]): void {
const retained = this.#retainedReachabilityReceiptPeerIds();
for (const peerId of this.#reachabilityReceipts.keys()) {
if (!retained.has(peerId)) this.#reachabilityReceipts.delete(peerId);
}
for (const signed of values) {
if (!retained.has(signed.lease.peerId)) continue;
const previous = this.#reachabilityReceipts.get(signed.lease.peerId);
if (previous && previous.revision > signed.lease.revision) continue;
if (
previous &&
previous.revision === signed.lease.revision &&
previous.signature !== signed.signature
) {
continue;
}
this.#reachabilityReceipts.set(
signed.lease.peerId,
peerReachabilityLeaseReceipt({
signed,
wallNow: this.#now(),
monotonicNow: this.#monotonicNow(),
...(previous ? { previous } : {}),
}),
);
}
}
#retainedReachabilityReceiptPeerIds(): ReadonlySet<string> {
const stored = this.#store.read();
const localPeerId = this.#peer.identity().peerId;
const retained = new Set<string>();
for (const state of stored.meshes) {
if (!isActiveMembership(state, localPeerId)) continue;
for (const peerId of state.roster.roster.members) {
if (peerId !== localPeerId) retained.add(peerId);
}
}
return retained;
}
#isReachabilityCurrent(signed: SignedPeerReachabilityLeaseV1): boolean {
return isPeerReachabilityLeaseCurrent(
signed,
this.#reachabilityReceipts.get(signed.lease.peerId),
this.#monotonicNow(),
);
}
async #applySync(
meshId: string,
rosterValue: SignedPeerMeshRosterV1,
reachabilityValues: readonly SignedPeerReachabilityLeaseV1[],
advertisementValues: readonly SignedPeerMeshMemberAdvertisementV1[],
): Promise<void> {
const roster = decodeSignedPeerMeshRoster(rosterValue);
if (roster.roster.meshId !== meshId) throw new Error('Peer Mesh synchronization changed Mesh');
const reachability = this.#validateReachabilityPage(reachabilityValues, roster, true);
const advertisements = this.#validateAdvertisementPage(advertisementValues, roster);
const localPeerId = this.#peer.identity().peerId;
const accepted = await this.#store.mutate((current) => {
const state = findMesh(current.meshes, meshId);
if (!state || state.roster.authorityPublicKey !== roster.authorityPublicKey) {
throw new Error('Peer Mesh synchronization has the wrong authority');
}
const nextRoster = selectRoster(state.roster, roster);
const next = {
...state,
roster: nextRoster,
};
return {
state: {
...current,
meshes: replaceMesh(current.meshes, next),
reachability: !isActiveMembership(next, localPeerId)
? current.reachability
: mergeReachability(current.reachability, reachability, this.#now()),
advertisements: !isActiveMembership(next, localPeerId)
? current.advertisements
: mergeAdvertisements(current.advertisements, advertisements),
},
result: isActiveMembership(next, localPeerId),
};
});
if (accepted) this.#recordReachabilityReceipts(reachability);
await this.#refreshLocalEvidence();
await this.#reconcileTransit();
}
#assertOpen(): void {
if (this.#lifetime.signal.aborted) throw new Error('Peer Mesh node is closed');
}
async #updateAuthorityRoster(
meshId: string,
closedIsSuccess: boolean,
update: (state: PeerMeshAuthorityStateV1) => {
readonly members: readonly string[];
readonly closed: boolean;
},
): Promise<PeerMeshStatus> {
const announcement = await this.#store.mutate((current) => {
const state = requireAuthority(current.meshes, meshId);
if (state.roster.roster.closed) {
if (closedIsSuccess) {
return {
state: current,
result: undefined,
};
}
throw new Error('Peer Mesh is closed');
}
const next = update(state);
const roster = signPeerMeshRoster(
{
version: 1,
meshId: state.roster.roster.meshId,
authorityPeerId: state.roster.roster.authorityPeerId,
revision: state.roster.roster.revision + 1,
members: next.members,
closed: next.closed,
...(state.roster.roster.displayName
? { displayName: state.roster.roster.displayName }
: {}),
},
authorityKeys(state),
);
const updated = {
...state,
roster,
invitations: next.closed
? state.invitations.filter(({ status }) => status === 'redeemed')
: state.invitations.filter(
(invitation) =>
invitation.status === 'pending' || next.members.includes(invitation.peerId),
),
};
return {
state: { ...current, meshes: replaceMesh(current.meshes, updated) },
result: {
roster,
targets: rosterAnnouncementTargets(
state.roster.roster.members,
current.reachability,
this.#peer.identity().peerId,
this.#now(),
),
},
};
});
try {
await this.#reconcileTransit();
} finally {
if (announcement) {
this.#scheduleRosterAnnouncement(announcement.roster, announcement.targets);
}
this.#scheduleMaintenance();
}
const stored = this.#store.read();
return peerMeshStatus(
findMesh(stored.meshes, meshId)!,
this.#peer.identity(),
this.#endpointKind,
stored.reachability,
stored.advertisements,
this.#now(),
(peerId) => this.#peer.isConnected(peerId),
(peerId) => this.resolveRoutes(peerId),
(signed) => this.#isReachabilityCurrent(signed),
);
}
#scheduleRosterAnnouncement(
roster: SignedPeerMeshRosterV1,
targets: readonly SignedPeerReachabilityLeaseV1[],
): void {
if (targets.length === 0 || this.#lifetime.signal.aborted) return;
const signal = this.#lifetime.signal;
void Promise.allSettled(
targets.map(async (target) => {
const stream = await this.#peer.connectMeshControl(
{
...dialTarget(target),
directDeadlineMs: CONNECT_DEADLINE_MS,
},
signal,
);
try {
const response = await exchangeControl(
stream,
{
kind: 'announce-roster',
meshId: roster.roster.meshId,
roster,
},
decodeAnnounceRosterResponse,
signal,
);
if (response.kind === 'roster-rejected') {
throw new Error('Peer Mesh roster announcement was rejected');
}
} finally {
await stream.close().catch(() => undefined);
}
}),
);
}
#scheduleMaintenance(): void {
this.#triggerReconciliation();
void this.#refreshLocalEvidence().catch(() => undefined);
void this.#reconcileTransit().catch(() => undefined);
}
#acceptIncoming(stream: RuntimeHostPeerNativeStream): void {
let peerStreams = 0;
for (const active of this.#activeControlStreams) {
if (active.peerId === stream.peerId) peerStreams += 1;
}
if (
this.#lifetime.signal.aborted ||
this.#activeControlStreams.size >= MAX_ACTIVE_CONTROL_STREAMS ||
peerStreams >= MAX_ACTIVE_CONTROL_STREAMS_PER_PEER
) {
stream.abort();
return;
}
this.#activeControlStreams.add(stream);
void this.#handleIncoming(stream).finally(() => {
this.#activeControlStreams.delete(stream);
});
}
#admitMesh<T>(operation: () => Promise<T>): Promise<T> {
if (this.#lifetime.signal.aborted) return Promise.reject(new Error('Peer Mesh node is closed'));
const task = this.#admissionTail.then(() => {
if (this.#lifetime.signal.aborted) throw new Error('Peer Mesh node is closed');
return operation();
});
this.#admissionTail = task.then(
() => undefined,
() => undefined,
);
return task;
}
async #handleIncoming(stream: RuntimeHostPeerNativeStream): Promise<void> {
const deadline = setTimeout(() => stream.abort(), CONTROL_REQUEST_DEADLINE_MS);
try {
const request = decodeControlRequest(await readFrame(stream));
let response:
| RedeemInvitationResponse
| SyncPeerMeshResponse
| LeavePeerMeshResponse
| AnnouncePeerMeshRosterResponse;
if (request.kind === 'redeem-invitation') {
await this.#refreshLocalEvidence();
response = await this.#redeem(
request,
stream.peerId,
this.#authenticateReachability(request.reachability, stream.peerId),
this.#validateAdvertisementForPeer(request.advertisement, request.meshId, stream.peerId),
);
} else if (request.kind === 'sync') {
response = await this.#sync(request, stream.peerId);
} else if (request.kind === 'leave') {
response = await this.#leave(request, stream.peerId);
} else {
response = await this.#observeRoster(request);
}
await writeFrame(stream, response);
await stream.close();
this.#scheduleMaintenance();
} catch {
stream.abort();
} finally {
clearTimeout(deadline);
}
}
async #observeRoster(
request: AnnouncePeerMeshRosterRequest,
): Promise<AnnouncePeerMeshRosterResponse> {
const response = await this.#store.mutate<AnnouncePeerMeshRosterResponse>((current) => {
const state = findMesh(current.meshes, request.meshId);
if (!state || state.roster.authorityPublicKey !== request.roster.authorityPublicKey) {
return {
state: current,
result: { kind: 'roster-rejected', reason: 'unknown' },
};
}
const roster = selectRoster(state.roster, request.roster);
return {
state: {
...current,
meshes: replaceMesh(current.meshes, { ...state, roster }),
},
result: { kind: 'roster-observed' },
};
});
if (response.kind === 'roster-observed') await this.#reconcileTransit();
return response;
}
async #redeem(
request: RedeemInvitationRequest,
remotePeerId: string,
remoteReachability: SignedPeerReachabilityLeaseV1,
remoteAdvertisement: SignedPeerMeshMemberAdvertisementV1,
): Promise<RedeemInvitationResponse> {
const now = this.#now();
const response = await this.#store.mutate<RedeemInvitationResponse>((current) => {
const state = findMesh(current.meshes, request.meshId);
if (!state || state.role !== 'authority')
return { state: current, result: rejected('invalid') };
const invitation = state.invitations.find(({ secretDigest }) =>
matchesPeerMeshInvitationSecret(request.secret, secretDigest),
);
if (request.meshId !== state.roster.roster.meshId || !invitation) {
return { state: current, result: rejected('invalid') };
}
if (invitation.status === 'redeemed') {
if (
invitation.peerId !== remotePeerId ||
!state.roster.roster.members.includes(remotePeerId)
) {
return { state: current, result: rejected('invalid') };
}
const reachability = mergeReachability(current.reachability, [remoteReachability], now);
const advertisements = mergeAdvertisements(current.advertisements, [remoteAdvertisement]);
const evidence = initialEvidence(
state,
reachability,
advertisements,
this.#peer.identity().peerId,
now,
);
return {
state: { ...current, reachability, advertisements },
result: {
kind: 'invitation-redeemed',
roster: state.roster,
...evidence,
},
};
}
const remaining = state.invitations.filter(
(record) =>
record !== invitation && (record.status === 'redeemed' || record.expiresAt > now),
);
if (invitation.expiresAt <= now) {
return {
state: {
...current,
meshes: replaceMesh(current.meshes, {
...state,
invitations: remaining,
}),
},
result: rejected('expired'),
};
}
if (state.roster.roster.closed) {
return {
state: {
...current,
meshes: replaceMesh(current.meshes, {
...state,
invitations: remaining,
}),
},
result: rejected('closed'),
};
}
if (
!state.roster.roster.members.includes(remotePeerId) &&
state.roster.roster.members.length >= PEER_MESH_MAX_MEMBERS
) {
return {
state: {
...current,
meshes: replaceMesh(current.meshes, {
...state,
invitations: remaining,
}),
},
result: rejected('full'),
};
}
const existingMember = state.roster.roster.members.includes(remotePeerId);
const roster = existingMember
? state.roster
: signPeerMeshRoster(
{
...state.roster.roster,
revision: state.roster.roster.revision + 1,
members: [...state.roster.roster.members, remotePeerId].sort(),
},
authorityKeys(state),
);
const updated = {
...state,
roster,
invitations: [
...remaining.filter(
(record) => record.status === 'pending' || record.peerId !== remotePeerId,
),
redeemedInvitation(invitation, remotePeerId),
],
};
const reachability = mergeReachability(current.reachability, [remoteReachability], now);
const advertisements = mergeAdvertisements(current.advertisements, [remoteAdvertisement]);
const evidence = initialEvidence(
updated,
reachability,
advertisements,
this.#peer.identity().peerId,
now,
);
return {
state: {
...current,
meshes: replaceMesh(current.meshes, updated),
reachability,
advertisements,
},
result: {
kind: 'invitation-redeemed',
roster,
...evidence,
},
};
});
if (response.kind === 'invitation-redeemed') {
this.#recordReachabilityReceipt(remoteReachability);
const stored = this.#store.read();
const state = findMesh(stored.meshes, request.meshId);
if (state) {
this.#scheduleRosterAnnouncement(
state.roster,
rosterAnnouncementTargets(
state.roster.roster.members,
stored.reachability,
this.#peer.identity().peerId,
this.#now(),
).filter(({ lease }) => lease.peerId !== remotePeerId),
);
}
}
return response;
}
async #leave(
request: LeavePeerMeshRequest,
remotePeerId: string,
): Promise<LeavePeerMeshResponse> {
const response = await this.#store.mutate<LeavePeerMeshResponse>((current) => {
const state = findMesh(current.meshes, request.meshId);
if (
!state ||
state.role !== 'authority' ||
request.roster.roster.meshId !== request.meshId ||
request.roster.authorityPublicKey !== state.roster.authorityPublicKey ||
request.roster.roster.revision > state.roster.roster.revision ||
!request.roster.roster.members.includes(remotePeerId)
) {
return {
state: current,
result: { kind: 'leave-rejected', reason: 'unknown' },
};
}
if (state.roster.roster.closed || !state.roster.roster.members.includes(remotePeerId)) {
return {
state: current,
result: { kind: 'left', roster: state.roster },
};
}
const roster = signPeerMeshRoster(
{
...state.roster.roster,
revision: state.roster.roster.revision + 1,
members: state.roster.roster.members.filter((peerId) => peerId !== remotePeerId),
},
authorityKeys(state),
);
const updated = {
...state,
roster,
};
return {
state: { ...current, meshes: replaceMesh(current.meshes, updated) },
result: { kind: 'left', roster },
};
});
if (response.kind === 'left') {
await this.#reconcileTransit();
const stored = this.#store.read();
const state = findMesh(stored.meshes, request.meshId);
if (state) {
this.#scheduleRosterAnnouncement(
state.roster,
rosterAnnouncementTargets(
state.roster.roster.members,
stored.reachability,
this.#peer.identity().peerId,
this.#now(),
),
);
}
}
return response;
}
async #sync(request: SyncPeerMeshRequest, remotePeerId: string): Promise<SyncPeerMeshResponse> {
const remoteReachability = this.#authenticateReachability(request.reachability, remotePeerId);
const remoteAdvertisement = this.#validateAdvertisementForPeer(
request.advertisement,
request.meshId,
remotePeerId,
);
await this.#refreshLocalEvidence();
const incomingRoster = decodeSignedPeerMeshRoster(request.roster);
const response = await this.#store.mutate<SyncPeerMeshResponse>((current) => {
const state = findMesh(current.meshes, request.meshId);
if (!state || state.roster.authorityPublicKey !== incomingRoster.authorityPublicKey) {
return {
state: current,
result: { kind: 'sync-rejected', reason: 'unknown' } as const,
};
}
const roster = selectRoster(state.roster, incomingRoster);
const localPeerId = this.#peer.identity().peerId;
const updated = {
...state,
roster,
};
const localMember = isActiveMembership(updated, localPeerId);
const remoteMember = !roster.roster.closed && roster.roster.members.includes(remotePeerId);
const reachability =
localMember && remoteMember
? mergeReachability(current.reachability, [remoteReachability], this.#now())
: current.reachability;
const advertisements =
localMember && remoteMember
? mergeAdvertisements(current.advertisements, [remoteAdvertisement])
: current.advertisements;
if (!localMember || !remoteMember) {
return {
state: {
...current,
meshes: replaceMesh(current.meshes, updated),
reachability,
advertisements,
},
result: {
kind: 'sync-result',
roster,
reachability: [],
advertisements: [],
more: false,
} as const,
};
}
const page = responseEvidence(
updated,
reachability,
advertisements,
request.knownReachability,
request.knownAdvertisements,
this.#now(),
);
return {
state: {
...current,
meshes: replaceMesh(current.meshes, updated),
reachability,
advertisements,
},
result: {
kind: 'sync-result',
roster,
...page,
} as const,
};
});
if (response.kind === 'sync-result') {
const localPeerId = this.#peer.identity().peerId;
if (
!response.roster.roster.closed &&
response.roster.roster.members.includes(localPeerId) &&
response.roster.roster.members.includes(remotePeerId)
) {
this.#recordReachabilityReceipt(remoteReachability);
}
await this.#reconcileTransit();
}
return response;
}
#reconcileTransit(): Promise<void> {
const task = this.#transitTail.then(() => this.#applyTransitSnapshot());
this.#transitTail = task.then(
() => undefined,
() => undefined,
);
return task;
}
async #applyTransitSnapshot(): Promise<void> {
const stored = this.#store.read();
const localPeerId = this.#peer.identity().peerId;
const now = this.#now();
const selected = stored.meshes.find(
(mesh) =>
mesh.roster.roster.meshId === stored.transitMeshId && isActiveMembership(mesh, localPeerId),
);
const eligibleRelays = eligibleTransitEvidence(stored, localPeerId, now, (signed) =>
this.#isReachabilityCurrent(signed),
);
const relayCandidates = transitRelayCandidates(eligibleRelays);
const approvedRelayPeerIds = [
...new Set(
stored.meshes
.filter((mesh) => isActiveMembership(mesh, localPeerId))
.flatMap((mesh) => mesh.roster.roster.members)
.filter((peerId) => peerId !== localPeerId),
),
].sort();
await this.#peer.configureTransit({
allowedPeerIds: selected
? selected.roster.roster.members.filter((peerId) => peerId !== localPeerId)
: [],
approvedRelayPeerIds,
relayCandidates,
});
}
}
interface PeerMeshTransitEvidence {
readonly meshId: string;
readonly lease: SignedPeerReachabilityLeaseV1;
}
function sameResolvedRoutes(
left: ReturnType<PeerMeshNode['resolveRoutes']>,
right: ReturnType<PeerMeshNode['resolveRoutes']>,
): boolean {
return (
left.state === right.state &&
sameStringValues(left.routeHints, right.routeHints) &&
sameStringValues(left.coordinationRelays, right.coordinationRelays) &&
sameStringValues(left.transitRelayPeerIds, right.transitRelayPeerIds)
);
}
function sameStringValues(left: readonly string[], right: readonly string[]): boolean {
return left.length === right.length && left.every((value, index) => value === right[index]);
}
function eligibleTransitEvidence(
stored: PeerMeshStoredStateV1,
localPeerId: string,
now: number,
isCurrent: (signed: SignedPeerReachabilityLeaseV1) => boolean,
): readonly PeerMeshTransitEvidence[] {
const evidence = new Map<string, PeerMeshTransitEvidence>();
for (const { advertisement } of stored.advertisements) {
if (
advertisement.peerId === localPeerId ||
!advertisement.offersTransit ||
!isActiveMeshMember(stored.meshes, advertisement.meshId, localPeerId, advertisement.peerId)
) {
continue;
}
const lease = latestReachability(stored.reachability, advertisement.peerId, now, true);
if (
!lease ||
!isCurrent(lease) ||
lease.lease.directRoutes.length + lease.lease.coordinationRoutes.length === 0
) {
continue;
}
evidence.set(advertisement.peerId, {
meshId: advertisement.meshId,
lease,
});
}
return Object.freeze(
[...evidence.values()].sort((left, right) =>
left.lease.lease.peerId.localeCompare(right.lease.lease.peerId),
),
);
}
function transitRelayCandidates(
evidence: readonly PeerMeshTransitEvidence[],
): readonly RuntimeHostPeerTransitRelayCandidate[] {
let remaining = PEER_MESH_MAX_TRANSIT_RELAY_ADDRESSES;
const candidates: RuntimeHostPeerTransitRelayCandidate[] = [];
for (const {
lease: { lease },
} of evidence) {
if (remaining === 0) break;
const routeHints = [
...new Set(lease.directRoutes.filter((address) => isBaseRelayFor(address, lease.peerId))),
].slice(0, Math.min(PEER_MESH_MAX_TRANSIT_ADDRESSES_PER_RELAY, remaining));
const coordinationRelays = [...new Set(lease.coordinationRoutes)].slice(
0,
Math.min(
PEER_MESH_MAX_TRANSIT_ADDRESSES_PER_RELAY - routeHints.length,
remaining - routeHints.length,
),
);
if (routeHints.length + coordinationRelays.length === 0) continue;
candidates.push(
Object.freeze({
peerId: lease.peerId,
addresses: Object.freeze(routeHints),
coordinationRelays: Object.freeze(coordinationRelays),
}),
);
remaining -= routeHints.length + coordinationRelays.length;
}
return Object.freeze(candidates);
}
function isBaseRelayFor(address: string, peerId: string): boolean {
const segments = address.split('/');
const peerProtocol = segments.indexOf('p2p');
return (
!segments.includes('p2p-circuit') &&
peerProtocol === segments.lastIndexOf('p2p') &&
peerProtocol === segments.length - 2 &&
segments.at(-1) === peerId
);
}
function isActiveMeshMember(
meshes: readonly PeerMeshStateV1[],
meshId: string,
localPeerId: string,
peerId: string,
): boolean {
return meshes.some(
(mesh) =>
mesh.roster.roster.meshId === meshId &&
isActiveMembership(mesh, localPeerId) &&
mesh.roster.roster.members.includes(peerId),
);
}
function peerMeshStatus(
state: PeerMeshStateV1,
identity: ReturnType<PeerMeshTransport['identity']>,
endpointKind: 'client' | 'host' | undefined,
reachability: readonly SignedPeerReachabilityLeaseV1[],
advertisements: readonly SignedPeerMeshMemberAdvertisementV1[],
now: number,
isConnected: (peerId: string) => boolean,
resolveRoutes: (peerId: string) => RuntimeHostPeerRouteResolution,
isCurrent: (signed: SignedPeerReachabilityLeaseV1) => boolean,
): PeerMeshStatus {
const meshId = state.roster.roster.meshId;
const localAdvertisement = findAdvertisement(advertisements, meshId, identity.peerId);
return Object.freeze({
role: state.role === 'authority' ? 'authority' : 'member',
authorityPeerId: state.roster.roster.authorityPeerId,
roster: state.roster,
pendingInvitationCount:
state.role === 'authority'
? state.invitations.filter(
(invitation) => invitation.status === 'pending' && invitation.expiresAt > now,
).length
: 0,
memberRoutes: Object.freeze(
state.roster.roster.members.map((peerId) => {
if (peerId === identity.peerId) {
return Object.freeze({
peerId,
...(endpointKind ? { endpointKind } : {}),
...(localAdvertisement?.advertisement.displayName
? { displayName: localAdvertisement.advertisement.displayName }
: {}),
state: 'local' as const,
});
}
const advertisement = findAdvertisement(advertisements, meshId, peerId)?.advertisement;
const signed = latestReachability(reachability, peerId, now, true);
const lease = signed?.lease;
const resolution = resolveRoutes(peerId);
const current = Boolean(signed && isCurrent(signed));
const memberState = isConnected(peerId)
? ('reachable' as const)
: resolution.state === 'exhausted'
? ('needs_repair' as const)
: resolution.state === 'recovering'
? signed
? ('reconnecting' as const)
: ('connecting' as const)
: current
? ('connecting' as const)
: ('reconnecting' as const);
return Object.freeze({
peerId,
...(advertisement?.endpointKind ? { endpointKind: advertisement.endpointKind } : {}),
...(advertisement?.displayName ? { displayName: advertisement.displayName } : {}),
state: memberState,
...(lease ? { expiresAt: lease.expiresAt } : {}),
});
}),
),
});
}
function rosterAnnouncementTargets(
memberPeerIds: readonly string[],
reachability: readonly SignedPeerReachabilityLeaseV1[],
localPeerId: string,
now: number,
): readonly SignedPeerReachabilityLeaseV1[] {
const members = new Set(memberPeerIds);
return Object.freeze(
reachability.filter(
(signed) =>
signed.lease.peerId !== localPeerId &&
members.has(signed.lease.peerId) &&
usableHistoricalReachability(signed, now),
),
);
}
function requireAuthority(
states: readonly PeerMeshStateV1[],
meshId: string,
): PeerMeshAuthorityStateV1 {
const state = findMesh(states, meshId);
if (!state || state.role !== 'authority')
throw new Error('Peer Mesh operation requires authority');
return state;
}
function findMesh(states: readonly PeerMeshStateV1[], meshId: string): PeerMeshStateV1 | undefined {
return states.find(({ roster }) => roster.roster.meshId === meshId);
}
function replaceMesh(
states: readonly PeerMeshStateV1[],
next: PeerMeshStateV1,
): readonly PeerMeshStateV1[] {
return states.map((state) =>
state.roster.roster.meshId === next.roster.roster.meshId ? next : state,
);
}
function rejected(reason: RedeemInvitationRejectionReason) {
return { kind: 'invitation-rejected', reason } as const;
}
function redeemedInvitation(invitation: { readonly secretDigest: string }, peerId: string) {
return {
status: 'redeemed' as const,
secretDigest: invitation.secretDigest,
peerId,
};
}
function assertMeshCapacity(
states: readonly PeerMeshStateV1[],
localPeerId: string,
pendingJoinCount = 0,
): void {
if (
states.filter((state) => !isRetired(state, localPeerId)).length + pendingJoinCount >=
PEER_MESH_MAX_MESHES
) {
throw new Error('This peer belongs to too many Peer Meshes');
}
}
function appendMesh(
states: readonly PeerMeshStateV1[],
state: PeerMeshStateV1,
localPeerId: string,
): readonly PeerMeshStateV1[] {
if (states.length < PEER_MESH_MAX_MESHES) return [...states, state];
const retired = states.findIndex((candidate) => isRetired(candidate, localPeerId));
if (retired < 0) throw new Error('This peer belongs to too many Peer Meshes');
return [...states.slice(0, retired), ...states.slice(retired + 1), state];
}
function assertRejoinSettled(state: PeerMeshStateV1 | undefined, localPeerId: string): void {
if (
state?.role === 'replica' &&
state.desiredMembership === 'left' &&
state.roster.roster.members.includes(localPeerId)
) {
throw new Error('This Peer Mesh leave is still being reconciled');
}
}
function selectRoster(
current: SignedPeerMeshRosterV1,
candidate: SignedPeerMeshRosterV1,
): SignedPeerMeshRosterV1 {
if (
current.roster.meshId !== candidate.roster.meshId ||
current.authorityPublicKey !== candidate.authorityPublicKey ||
current.roster.authorityPeerId !== candidate.roster.authorityPeerId
) {
throw new Error('Peer Mesh roster has the wrong authority');
}
if (candidate.roster.revision < current.roster.revision) return current;
if (candidate.roster.revision === current.roster.revision) {
if (JSON.stringify(candidate) !== JSON.stringify(current)) {
throw new Error('Peer Mesh roster revision identifies conflicting facts');
}
return current;
}
return candidate;
}
function mergeReachability(
current: readonly SignedPeerReachabilityLeaseV1[],
candidates: readonly SignedPeerReachabilityLeaseV1[],
now: number,
): readonly SignedPeerReachabilityLeaseV1[] {
const leases = new Map(
current
.filter((signed) => usableHistoricalReachability(signed, now))
.map((signed) => [signed.lease.peerId, signed] as const),
);
for (const candidate of candidates) {
if (!usableHistoricalReachability(candidate, now)) continue;
const existing = leases.get(candidate.lease.peerId);
if (!existing || candidate.lease.revision > existing.lease.revision) {
leases.set(candidate.lease.peerId, candidate);
continue;
}
if (
candidate.lease.revision === existing.lease.revision &&
reachabilityFactDigest(candidate) !== reachabilityFactDigest(existing)
) {
throw new Error('Peer reachability revision identifies conflicting facts');
}
}
return Object.freeze(
[...leases.values()].sort((left, right) => left.lease.peerId.localeCompare(right.lease.peerId)),
);
}
function mergeAdvertisements(
current: readonly SignedPeerMeshMemberAdvertisementV1[],
candidates: readonly SignedPeerMeshMemberAdvertisementV1[],
): readonly SignedPeerMeshMemberAdvertisementV1[] {
const advertisements = new Map(
current.map((signed) => [advertisementKey(signed.advertisement), signed] as const),
);
for (const candidate of candidates) {
const key = advertisementKey(candidate.advertisement);
const existing = advertisements.get(key);
if (!existing || candidate.advertisement.revision > existing.advertisement.revision) {
advertisements.set(key, candidate);
continue;
}
if (
candidate.advertisement.revision === existing.advertisement.revision &&
advertisementFactDigest(candidate) !== advertisementFactDigest(existing)
) {
throw new Error('Peer Mesh advertisement revision identifies conflicting facts');
}
}
return Object.freeze(
[...advertisements.values()].sort((left, right) =>
advertisementKey(left.advertisement).localeCompare(advertisementKey(right.advertisement)),
),
);
}
function reachabilitySummaries(
reachability: readonly SignedPeerReachabilityLeaseV1[],
roster: SignedPeerMeshRosterV1,
now: number,
): readonly PeerMeshEvidenceSummary[] {
return Object.freeze(
reachability
.filter(
(signed) =>
usableHistoricalReachability(signed, now) &&
roster.roster.members.includes(signed.lease.peerId),
)
.map((signed) =>
Object.freeze({
peerId: signed.lease.peerId,
revision: signed.lease.revision,
digest: reachabilityFactDigest(signed),
}),
)
.sort((left, right) => left.peerId.localeCompare(right.peerId)),
);
}
function advertisementSummaries(
advertisements: readonly SignedPeerMeshMemberAdvertisementV1[],
roster: SignedPeerMeshRosterV1,
): readonly PeerMeshEvidenceSummary[] {
return Object.freeze(
advertisements
.filter(
({ advertisement }) =>
advertisement.meshId === roster.roster.meshId &&
roster.roster.members.includes(advertisement.peerId),
)
.map((signed) =>
Object.freeze({
peerId: signed.advertisement.peerId,
revision: signed.advertisement.revision,
digest: advertisementFactDigest(signed),
}),
)
.sort((left, right) => left.peerId.localeCompare(right.peerId)),
);
}
function responseEvidence(
state: PeerMeshStateV1,
reachability: readonly SignedPeerReachabilityLeaseV1[],
advertisements: readonly SignedPeerMeshMemberAdvertisementV1[],
knownReachability: readonly PeerMeshEvidenceSummary[],
knownAdvertisements: readonly PeerMeshEvidenceSummary[],
now: number,
): {
readonly reachability: readonly SignedPeerReachabilityLeaseV1[];
readonly advertisements: readonly SignedPeerMeshMemberAdvertisementV1[];
readonly more: boolean;
} {
const knownLeases = new Map(knownReachability.map((summary) => [summary.peerId, summary]));
const knownAds = new Map(knownAdvertisements.map((summary) => [summary.peerId, summary]));
const missing = [
...reachability
.filter(
(signed) =>
usableHistoricalReachability(signed, now) &&
state.roster.roster.members.includes(signed.lease.peerId) &&
evidenceRequiresTransfer(
{
peerId: signed.lease.peerId,
revision: signed.lease.revision,
digest: reachabilityFactDigest(signed),
},
knownLeases.get(signed.lease.peerId),
'Peer reachability',
),
)
.map((value) => ({
kind: 'reachability' as const,
peerId: value.lease.peerId,
value,
})),
...advertisements
.filter(
(signed) =>
signed.advertisement.meshId === state.roster.roster.meshId &&
state.roster.roster.members.includes(signed.advertisement.peerId) &&
evidenceRequiresTransfer(
{
peerId: signed.advertisement.peerId,
revision: signed.advertisement.revision,
digest: advertisementFactDigest(signed),
},
knownAds.get(signed.advertisement.peerId),
'Peer Mesh advertisement',
),
)
.map((value) => ({
kind: 'advertisement' as const,
peerId: value.advertisement.peerId,
value,
})),
].sort((left, right) =>
left.peerId === right.peerId
? left.kind.localeCompare(right.kind)
: left.peerId.localeCompare(right.peerId),
);
const page = missing.slice(0, EVIDENCE_PAGE_SIZE);
return Object.freeze({
reachability: Object.freeze(
page.flatMap((entry) => (entry.kind === 'reachability' ? [entry.value] : [])),
),
advertisements: Object.freeze(
page.flatMap((entry) => (entry.kind === 'advertisement' ? [entry.value] : [])),
),
more: missing.length > EVIDENCE_PAGE_SIZE,
});
}
function evidenceRequiresTransfer(
local: PeerMeshEvidenceSummary,
remote: PeerMeshEvidenceSummary | undefined,
label: string,
): boolean {
if (!remote || local.revision > remote.revision) return true;
if (local.revision < remote.revision) return false;
if (local.digest !== remote.digest) {
throw new Error(`${label} revision identifies conflicting facts`);
}
return false;
}
function reachabilityFactDigest(signed: SignedPeerReachabilityLeaseV1): string {
return evidenceDigest(peerReachabilityLeaseSigningBytes(signed.lease));
}
function advertisementFactDigest(signed: SignedPeerMeshMemberAdvertisementV1): string {
return evidenceDigest(peerMeshMemberAdvertisementSigningBytes(signed.advertisement));
}
function evidenceDigest(bytes: Uint8Array): string {
return createHash('sha256').update(bytes).digest('hex');
}
function initialEvidence(
state: PeerMeshStateV1,
reachability: readonly SignedPeerReachabilityLeaseV1[],
advertisements: readonly SignedPeerMeshMemberAdvertisementV1[],
localPeerId: string,
now: number,
): {
readonly reachability: readonly SignedPeerReachabilityLeaseV1[];
readonly advertisements: readonly SignedPeerMeshMemberAdvertisementV1[];
} {
const lease = latestReachability(reachability, localPeerId, now, true);
const advertisement = findAdvertisement(advertisements, state.roster.roster.meshId, localPeerId);
if (!lease || !advertisement) throw new Error('Peer Mesh authority evidence is unavailable');
return Object.freeze({
reachability: Object.freeze([lease]),
advertisements: Object.freeze([advertisement]),
});
}
function isCurrentLocalAdvertisement(
existing: SignedPeerMeshMemberAdvertisementV1 | undefined,
meshId: string,
peerId: string,
current: Pick<PeerMeshStoredStateV1, 'displayName' | 'transitMeshId'>,
endpointKind: 'client' | 'host' | undefined,
): existing is SignedPeerMeshMemberAdvertisementV1 {
return Boolean(
existing &&
existing.advertisement.meshId === meshId &&
existing.advertisement.peerId === peerId &&
existing.advertisement.endpointKind === endpointKind &&
existing.advertisement.displayName === (current.displayName ?? undefined) &&
existing.advertisement.offersTransit === (current.transitMeshId === meshId),
);
}
function latestReachability(
reachability: readonly SignedPeerReachabilityLeaseV1[],
peerId: string,
now: number,
includeHistorical: boolean,
): SignedPeerReachabilityLeaseV1 | undefined {
const signed = reachability.find(({ lease }) => lease.peerId === peerId);
if (!signed) return undefined;
if (signed.lease.expiresAt > now) return signed;
return includeHistorical && usableHistoricalReachability(signed, now) ? signed : undefined;
}
function emptyRouteResolution(state: 'recovering' | 'exhausted'): RuntimeHostPeerRouteResolution {
return Object.freeze({
state,
routeHints: Object.freeze([]),
coordinationRelays: Object.freeze([]),
transitRelayPeerIds: Object.freeze([]),
});
}
function hasPeerRecoverySource(
stored: PeerMeshStoredStateV1,
sharedMeshIds: readonly string[],
targetPeerId: string,
localPeerId: string,
now: number,
): boolean {
const shared = new Set(sharedMeshIds);
const sourcePeerIds = new Set(
stored.meshes
.filter(({ roster }) => shared.has(roster.roster.meshId))
.flatMap(({ roster }) => roster.roster.members)
.filter((peerId) => peerId !== localPeerId && peerId !== targetPeerId),
);
for (const sourcePeerId of sourcePeerIds) {
const signed = latestReachability(stored.reachability, sourcePeerId, now, true);
if (signed && hasReachabilityRoutes(signed)) return true;
}
return false;
}
function hasReachabilityRoutes(signed: SignedPeerReachabilityLeaseV1): boolean {
return signed.lease.directRoutes.length + signed.lease.coordinationRoutes.length > 0;
}
function usableHistoricalReachability(signed: SignedPeerReachabilityLeaseV1, now: number): boolean {
return signed.lease.expiresAt > now - PEER_REACHABILITY_RECOVERY_HORIZON_MS;
}
function dialTarget(reachability: SignedPeerReachabilityLeaseV1): {
readonly peerId: string;
readonly routeHints: readonly string[];
readonly coordinationRelays: readonly string[];
} {
return Object.freeze({
peerId: reachability.lease.peerId,
routeHints: reachability.lease.directRoutes,
coordinationRelays: reachability.lease.coordinationRoutes,
});
}
function findAdvertisement(
advertisements: readonly SignedPeerMeshMemberAdvertisementV1[],
meshId: string,
peerId: string,
): SignedPeerMeshMemberAdvertisementV1 | undefined {
return advertisements.find(
({ advertisement }) => advertisement.meshId === meshId && advertisement.peerId === peerId,
);
}
function advertisementKey(advertisement: {
readonly meshId: string;
readonly peerId: string;
}): string {
return `${advertisement.meshId}\n${advertisement.peerId}`;
}
function mergeAddresses(
primary: readonly string[],
fallback: readonly string[],
): readonly string[] {
return Object.freeze([...new Set([...primary, ...fallback])].slice(0, 32));
}
function waitForTurn(previous: Promise<void>, signal?: AbortSignal): Promise<void> {
if (!signal) return previous;
if (signal.aborted) return Promise.reject(signal.reason);
return new Promise((resolve, reject) => {
const onAbort = () => reject(signal.reason);
signal.addEventListener('abort', onAbort, { once: true });
void previous.then(() => {
signal.removeEventListener('abort', onAbort);
resolve();
});
});
}
async function exchangeControl<Request, Response>(
stream: RuntimeHostPeerNativeStream,
request: Request,
decode: (value: unknown) => Response,
signal?: AbortSignal,
): Promise<Response> {
const timeout = AbortSignal.timeout(CONTROL_REQUEST_DEADLINE_MS);
const operationSignal = signal ? AbortSignal.any([signal, timeout]) : timeout;
const abort = () => stream.abort();
operationSignal.addEventListener('abort', abort, { once: true });
if (operationSignal.aborted) abort();
try {
operationSignal.throwIfAborted();
await writeFrame(stream, request);
const response = decode(await readFrame(stream));
operationSignal.throwIfAborted();
return response;
} catch (error) {
operationSignal.throwIfAborted();
throw error;
} finally {
operationSignal.removeEventListener('abort', abort);
}
}
function decodeControlRequest(value: unknown): PeerMeshControlRequest {
const record = recordValue(value);
if (
record.kind === 'redeem-invitation' &&
hasExactKeys(record, ['kind', 'meshId', 'secret', 'reachability', 'advertisement'])
) {
return {
kind: 'redeem-invitation',
meshId: requiredString(record.meshId, 128),
secret: requiredString(record.secret, 64),
reachability: decodeSignedPeerReachabilityLease(record.reachability),
advertisement: decodeSignedPeerMeshMemberAdvertisement(record.advertisement),
};
}
if (
record.kind === 'sync' &&
hasExactKeys(record, [
'kind',
'meshId',
'roster',
'reachability',
'advertisement',
'knownReachability',
'knownAdvertisements',
])
) {
return {
kind: 'sync',
meshId: requiredString(record.meshId, 128),
roster: decodeSignedPeerMeshRoster(record.roster),
reachability: decodeSignedPeerReachabilityLease(record.reachability),
advertisement: decodeSignedPeerMeshMemberAdvertisement(record.advertisement),
knownReachability: decodeEvidenceSummaries(record.knownReachability),
knownAdvertisements: decodeEvidenceSummaries(record.knownAdvertisements),
};
}
if (record.kind === 'leave' && hasExactKeys(record, ['kind', 'meshId', 'roster'])) {
return {
kind: 'leave',
meshId: requiredString(record.meshId, 128),
roster: decodeSignedPeerMeshRoster(record.roster),
};
}
if (record.kind === 'announce-roster' && hasExactKeys(record, ['kind', 'meshId', 'roster'])) {
return {
kind: 'announce-roster',
meshId: requiredString(record.meshId, 128),
roster: decodeSignedPeerMeshRoster(record.roster),
};
}
throw new Error('Unsupported Peer Mesh control request');
}
function decodeRedeemResponse(value: unknown): RedeemInvitationResponse {
const record = recordValue(value);
if (
record.kind === 'invitation-redeemed' &&
hasExactKeys(record, ['kind', 'roster', 'reachability', 'advertisements'])
) {
const reachability = decodeReachabilityPage(record.reachability);
const advertisements = decodeAdvertisementPage(record.advertisements);
assertEvidencePageSize(reachability, advertisements);
return {
kind: 'invitation-redeemed',
roster: decodeSignedPeerMeshRoster(record.roster),
reachability,
advertisements,
};
}
if (
record.kind === 'invitation-rejected' &&
hasExactKeys(record, ['kind', 'reason']) &&
(record.reason === 'invalid' ||
record.reason === 'expired' ||
record.reason === 'closed' ||
record.reason === 'full')
) {
return { kind: 'invitation-rejected', reason: record.reason };
}
throw new Error('Invalid Peer Mesh control response');
}
function decodeSyncResponse(value: unknown): SyncPeerMeshResponse {
const record = recordValue(value);
if (
record.kind === 'sync-result' &&
hasExactKeys(record, ['kind', 'roster', 'reachability', 'advertisements', 'more']) &&
typeof record.more === 'boolean'
) {
const reachability = decodeReachabilityPage(record.reachability);
const advertisements = decodeAdvertisementPage(record.advertisements);
assertEvidencePageSize(reachability, advertisements);
return {
kind: 'sync-result',
roster: decodeSignedPeerMeshRoster(record.roster),
reachability,
advertisements,
more: record.more,
};
}
if (
record.kind === 'sync-rejected' &&
hasExactKeys(record, ['kind', 'reason']) &&
record.reason === 'unknown'
) {
return { kind: 'sync-rejected', reason: record.reason };
}
throw new Error('Invalid Peer Mesh synchronization response');
}
function decodeLeaveResponse(value: unknown): LeavePeerMeshResponse {
const record = recordValue(value);
if (record.kind === 'left' && hasExactKeys(record, ['kind', 'roster'])) {
return { kind: 'left', roster: decodeSignedPeerMeshRoster(record.roster) };
}
if (
record.kind === 'leave-rejected' &&
hasExactKeys(record, ['kind', 'reason']) &&
record.reason === 'unknown'
) {
return { kind: 'leave-rejected', reason: 'unknown' };
}
throw new Error('Invalid Peer Mesh leave response');
}
function decodeAnnounceRosterResponse(value: unknown): AnnouncePeerMeshRosterResponse {
const record = recordValue(value);
if (record.kind === 'roster-observed' && hasExactKeys(record, ['kind'])) {
return { kind: 'roster-observed' };
}
if (
record.kind === 'roster-rejected' &&
hasExactKeys(record, ['kind', 'reason']) &&
record.reason === 'unknown'
) {
return { kind: 'roster-rejected', reason: 'unknown' };
}
throw new Error('Invalid Peer Mesh roster announcement response');
}
function decodeReachabilityPage(value: unknown): readonly SignedPeerReachabilityLeaseV1[] {
if (!Array.isArray(value) || value.length > EVIDENCE_PAGE_SIZE) {
throw new Error('Invalid Peer Mesh reachability page');
}
return Object.freeze(value.map(decodeSignedPeerReachabilityLease));
}
function decodeAdvertisementPage(value: unknown): readonly SignedPeerMeshMemberAdvertisementV1[] {
if (!Array.isArray(value) || value.length > EVIDENCE_PAGE_SIZE) {
throw new Error('Invalid Peer Mesh advertisement page');
}
return Object.freeze(value.map(decodeSignedPeerMeshMemberAdvertisement));
}
function assertEvidencePageSize(
reachability: readonly SignedPeerReachabilityLeaseV1[],
advertisements: readonly SignedPeerMeshMemberAdvertisementV1[],
): void {
if (reachability.length + advertisements.length > EVIDENCE_PAGE_SIZE) {
throw new Error('Peer Mesh evidence page exceeds its bound');
}
}
function decodeEvidenceSummaries(value: unknown): readonly PeerMeshEvidenceSummary[] {
if (!Array.isArray(value) || value.length > PEER_MESH_MAX_MEMBERS) {
throw new Error('Invalid Peer Mesh evidence revisions');
}
const revisions = value.map((entry) => {
const record = recordValue(entry);
if (!hasExactKeys(record, ['peerId', 'revision', 'digest'])) {
throw new Error('Invalid Peer Mesh evidence revision');
}
const revision = record.revision;
if (!Number.isSafeInteger(revision) || (revision as number) < 1) {
throw new Error('Invalid Peer Mesh evidence revision');
}
if (typeof record.digest !== 'string' || !/^[0-9a-f]{64}$/u.test(record.digest)) {
throw new Error('Invalid Peer Mesh evidence digest');
}
return Object.freeze({
peerId: requiredString(record.peerId, 256),
revision: revision as number,
digest: record.digest,
});
});
if (new Set(revisions.map(({ peerId }) => peerId)).size !== revisions.length) {
throw new Error('Duplicate Peer Mesh evidence revision');
}
return Object.freeze(revisions);
}
async function writeFrame(stream: RuntimeHostPeerNativeStream, value: unknown): Promise<void> {
const bytes = Buffer.from(`${JSON.stringify(value)}\n`);
if (bytes.length > CONTROL_FRAME_MAX_BYTES)
throw new Error('Peer Mesh control frame is too large');
await stream.write(bytes);
}
async function readFrame(stream: RuntimeHostPeerNativeStream): Promise<unknown> {
let buffered = Buffer.alloc(0);
for (;;) {
const chunk = await stream.read();
if (!chunk) throw new Error('Peer Mesh control stream ended before a frame arrived');
buffered = Buffer.concat([buffered, chunk]);
if (buffered.length > CONTROL_FRAME_MAX_BYTES)
throw new Error('Peer Mesh control frame is too large');
const newline = buffered.indexOf(0x0a);
if (newline < 0) continue;
if (buffered.subarray(newline + 1).some((byte) => byte > 0x20)) {
throw new Error('Peer Mesh control stream contained multiple frames');
}
return JSON.parse(buffered.subarray(0, newline).toString('utf8')) as unknown;
}
}
function recordValue(value: unknown): Record<string, unknown> {
if (!value || typeof value !== 'object' || Array.isArray(value)) {
throw new Error('Invalid Peer Mesh control frame');
}
return value as Record<string, unknown>;
}
function hasExactKeys(record: Record<string, unknown>, keys: readonly string[]): boolean {
return (
Object.keys(record).length === keys.length && keys.every((key) => Object.hasOwn(record, key))
);
}
function requiredString(value: unknown, maxLength: number): string {
if (typeof value !== 'string' || value.length === 0 || value.length > maxLength) {
throw new Error('Invalid Peer Mesh control value');
}
return value;
}