@cello-protocol/daemon 0.0.202 → 0.0.204

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Build the registrar.
3
+ *
4
+ * `getHandler` is resolved at FRAME time, not at registration time: the daemon builds its signaling
5
+ * wiring before the inbound-session handlers exist, so capturing the handler when the listener is
6
+ * registered would bind whatever was there at boot — which for this frame type is nothing.
7
+ */
8
+ export function createPickupListenerRegistrar(getHandler) {
9
+ return (signaling, agentName, agentKeyProvider, origin) => {
10
+ // WHY IN-FLIGHT WORK IS TRACKED RATHER THAN FLOATED AND FORGOTTEN.
11
+ //
12
+ // A visiting connection is transient: `openVisitingConnection`'s caller stops it the moment the
13
+ // session handoff finishes. The handler is asynchronous — it opens the seal, decodes, writes to
14
+ // the wallet, and only THEN acks — so a teardown can win the race and the ACK never lands. The
15
+ // signal itself is safe (the wallet write already happened and is content-addressed), but the
16
+ // directory keeps the row and re-sends the same pickup on every future visit, and the log names
17
+ // the failed send rather than the teardown that caused it.
18
+ //
19
+ // It also matters for what comes next: the fan-out closes each visiting connection on a terminal
20
+ // end-of-drain frame or a bounded ceiling, and a ceiling that fires mid-handler would truncate
21
+ // the drain the terminal frame exists to complete. Tracked here so that comes for free.
22
+ const inFlight = new Set();
23
+ signaling.registerInboundHandler((frame) => {
24
+ if (frame["type"] !== "trust_signal_pickup")
25
+ return;
26
+ // `signaling` is the stream the frame ARRIVED on, and that is what the handler ACKs down.
27
+ // Acking a visiting node's pickup down the home stream would leave the visited node's row
28
+ // unacked forever — re-sent on every visit, which is this bug wearing a different hat.
29
+ const p = getHandler()(frame, agentKeyProvider, signaling, agentName, origin)
30
+ .catch(() => { })
31
+ .finally(() => { inFlight.delete(p); });
32
+ inFlight.add(p);
33
+ });
34
+ return {
35
+ settle: async (timeoutMs) => {
36
+ if (inFlight.size === 0)
37
+ return;
38
+ // BOUNDED. A handler wedged on a slow database must delay a teardown, never prevent one —
39
+ // an unbounded wait here would turn a stuck pickup into a stuck session close.
40
+ await Promise.race([
41
+ Promise.allSettled([...inFlight]),
42
+ new Promise((r) => setTimeout(r, timeoutMs)),
43
+ ]);
44
+ },
45
+ };
46
+ };
47
+ }
48
+ //# sourceMappingURL=trust-signal-pickup-listener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust-signal-pickup-listener.js","sourceRoot":"","sources":["../src/trust-signal-pickup-listener.ts"],"names":[],"mappings":"AA6CA;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAC3C,UAA0C;IAE1C,OAAO,CAAC,SAAS,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE;QACxD,mEAAmE;QACnE,EAAE;QACF,gGAAgG;QAChG,gGAAgG;QAChG,+FAA+F;QAC/F,8FAA8F;QAC9F,gGAAgG;QAChG,2DAA2D;QAC3D,EAAE;QACF,iGAAiG;QACjG,+FAA+F;QAC/F,wFAAwF;QACxF,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAiB,CAAC;QAC1C,SAAS,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,EAAE;YACzC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,qBAAqB;gBAAE,OAAO;YACpD,0FAA0F;YAC1F,0FAA0F;YAC1F,uFAAuF;YACvF,MAAM,CAAC,GAAG,UAAU,EAAE,CAAC,KAAgC,EAAE,gBAAgB,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,CAAC;iBACrG,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC;iBACf,OAAO,CAAC,GAAG,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1C,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC,CAAC,CAAC;QACH,OAAO;YACL,MAAM,EAAE,KAAK,EAAE,SAAiB,EAAE,EAAE;gBAClC,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC;oBAAE,OAAO;gBAChC,0FAA0F;gBAC1F,+EAA+E;gBAC/E,MAAM,OAAO,CAAC,IAAI,CAAC;oBACjB,OAAO,CAAC,UAAU,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC;oBACjC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;iBAC7C,CAAC,CAAC;YACL,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Collecting trust signals parked at nodes this daemon is not connected to.
3
+ *
4
+ * ─── WHY A SWEEP IS NEEDED AT ALL ──────────────────────────────────────────────────────────────
5
+ *
6
+ * `pickup_queue` is node-local by design and does NOT replicate, so a signal delivered to one
7
+ * directory is collectable only from that directory. The one thing that collects it is a stream
8
+ * AUTHENTICATING there, because the drain runs on auth. An agent connects to a single directory —
9
+ * chosen at random on every start — so a signal parked anywhere else simply waited.
10
+ *
11
+ * C1 made a visiting connection able to receive pickups at all. This makes it deterministic rather
12
+ * than incidental: without it, collection happens only if you happen to start a session with
13
+ * someone who lives on that node.
14
+ *
15
+ * ─── WHAT THIS DELIBERATELY IS NOT ─────────────────────────────────────────────────────────────
16
+ *
17
+ * Not on the login path. The home stream drains inline on its own auth, as it always has; this runs
18
+ * in the background afterwards. The signaling wait is already the reason bootstrap needed a fast
19
+ * probe, and n round trips added to it would be felt on every start for a benefit that is never
20
+ * urgent — a signal that has waited for a directory to be visited can wait another few seconds.
21
+ *
22
+ * Not a node list. The roster comes from the signed manifest the daemon already polls, so a fleet
23
+ * of five sweeps five with no code change.
24
+ */
25
+ import type { KeyProvider } from "@cello-protocol/crypto";
26
+ import type { Logger } from "./types.js";
27
+ import type { ConsortiumEndpoint } from "./directory-bootstrap.js";
28
+ /** What a sweep found, per node. Never collapsed into a single boolean — see `unreachable`. */
29
+ export interface SweepResult {
30
+ /** Nodes that answered and said their drain was finished. */
31
+ visited: string[];
32
+ /** Nodes that could not be dialled at all. */
33
+ unreachable: string[];
34
+ /** Nodes that answered but never said they were finished — we hit the ceiling instead. */
35
+ incomplete: string[];
36
+ /** True when the manifest could not be resolved, so we do not know who to ask. */
37
+ rosterUnavailable: boolean;
38
+ }
39
+ export interface TrustSignalSweepDeps {
40
+ logger: Logger;
41
+ resolveConsortiumRoster: () => Promise<ConsortiumEndpoint[] | null>;
42
+ /**
43
+ * Nodes the manifest declares that could NOT be resolved this sweep.
44
+ *
45
+ * Without this the `unreachable` bucket can never fill, because the roster is already the
46
+ * REACHABLE SUBSET — `manifestNodesToEndpoints` drops a node whose /bootstrap probe failed. A
47
+ * dead node therefore appeared in no bucket at all and the sweep reported "visited 2,
48
+ * unreachable 0" for a three-node fleet, which is exactly the false negative the order forbids:
49
+ * the operator is told nothing is waiting when nobody looked.
50
+ */
51
+ getUnresolvedNodes?: () => ReadonlyArray<{
52
+ nodeId: string;
53
+ reason: string;
54
+ }>;
55
+ openVisitingConnection: (agentName: string, agentKeyProvider: KeyProvider, agentPubkeyHex: string, endpoint: {
56
+ peerId: string;
57
+ multiaddr: string;
58
+ }, correlationId: string, nodeId: string) => {
59
+ mgr: {
60
+ registerInboundHandler: (h: (f: Record<string, unknown>) => void) => void;
61
+ /** "connected" once the stream is authenticated; the manager connects asynchronously. */
62
+ readonly status?: string;
63
+ };
64
+ stop: (reason: string) => Promise<void>;
65
+ };
66
+ /** How long to wait for a node's end-of-drain frame before closing anyway. */
67
+ ceilingMs?: number;
68
+ }
69
+ export type TrustSignalSweep = (agentName: string, agentKeyProvider: KeyProvider, agentPubkeyHex: string,
70
+ /**
71
+ * The node this daemon is already connected to, skipped because its drain ran on its own auth.
72
+ *
73
+ * Optional because the caller does not always know it. When it is unknown every node is visited,
74
+ * including home — which costs one extra connection whose drain immediately reports nothing left,
75
+ * not a wrong answer. A wasted round trip in the background beats guessing which node to skip.
76
+ */
77
+ homeNodeId?: string) => Promise<SweepResult>;
78
+ export declare function createTrustSignalSweep(deps: TrustSignalSweepDeps): TrustSignalSweep;
79
+ //# sourceMappingURL=trust-signal-sweep.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust-signal-sweep.d.ts","sourceRoot":"","sources":["../src/trust-signal-sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAGnE,+FAA+F;AAC/F,MAAM,WAAW,WAAW;IAC1B,6DAA6D;IAC7D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,8CAA8C;IAC9C,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,0FAA0F;IAC1F,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,kFAAkF;IAClF,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB,EAAE,MAAM,OAAO,CAAC,kBAAkB,EAAE,GAAG,IAAI,CAAC,CAAC;IACpE;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,MAAM,aAAa,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC7E,sBAAsB,EAAE,CACtB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,WAAW,EAC7B,cAAc,EAAE,MAAM,EACtB,QAAQ,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAC/C,aAAa,EAAE,MAAM,EACrB,MAAM,EAAE,MAAM,KACX;QACH,GAAG,EAAE;YACH,sBAAsB,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK,IAAI,CAAC;YAC1E,yFAAyF;YACzF,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;SAC1B,CAAC;QACF,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;KACzC,CAAC;IACF,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,gBAAgB,GAAG,CAC7B,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,WAAW,EAC7B,cAAc,EAAE,MAAM;AACtB;;;;;;GAMG;AACH,UAAU,CAAC,EAAE,MAAM,KAChB,OAAO,CAAC,WAAW,CAAC,CAAC;AAE1B,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,oBAAoB,GAAG,gBAAgB,CAiInF"}
@@ -0,0 +1,123 @@
1
+ import { extractErrorMessage } from "./error-message.js";
2
+ export function createTrustSignalSweep(deps) {
3
+ const { logger, resolveConsortiumRoster, openVisitingConnection, getUnresolvedNodes } = deps;
4
+ const ceilingMs = deps.ceilingMs ?? 10_000;
5
+ // One sweep per agent at a time. `onConnected` fires on every reconnect, so a flapping stream
6
+ // would otherwise stack sweeps, each holding up to N authenticated visiting streams and
7
+ // re-triggering every node's drain. Duplicate delivery is safe — the wallet write is
8
+ // content-addressed and the drain deletes only on ACK — so this is load, not corruption, but it
9
+ // is load that arrives exactly when the network is already struggling.
10
+ const inFlight = new Set();
11
+ return async (agentName, agentKeyProvider, agentPubkeyHex, homeNodeId) => {
12
+ if (inFlight.has(agentName)) {
13
+ logger.info("trust_signal.sweep.already_running", { agentName });
14
+ return { visited: [], unreachable: [], incomplete: [], rosterUnavailable: false };
15
+ }
16
+ inFlight.add(agentName);
17
+ try {
18
+ return await run(agentName, agentKeyProvider, agentPubkeyHex, homeNodeId);
19
+ }
20
+ finally {
21
+ inFlight.delete(agentName);
22
+ }
23
+ };
24
+ async function run(agentName, agentKeyProvider, agentPubkeyHex, homeNodeId) {
25
+ const result = { visited: [], unreachable: [], incomplete: [], rosterUnavailable: false };
26
+ // Declared-but-unresolvable nodes, named BEFORE any dialling. These never reach the loop below
27
+ // because the roster excludes them, and saying nothing about them is how one dead node makes
28
+ // "nothing waiting" look true.
29
+ for (const n of getUnresolvedNodes?.() ?? []) {
30
+ if (n.nodeId === homeNodeId)
31
+ continue;
32
+ result.unreachable.push(n.nodeId);
33
+ logger.warn("trust_signal.sweep.node_unreachable", { agentName, node: n.nodeId, reason: n.reason });
34
+ }
35
+ const roster = await resolveConsortiumRoster();
36
+ if (!roster) {
37
+ // NOT the same as "nobody had anything". We do not know who to ask, and saying nothing was
38
+ // waiting would be a claim we cannot support.
39
+ result.rosterUnavailable = true;
40
+ logger.warn("trust_signal.sweep.roster_unavailable", { agentName });
41
+ return result;
42
+ }
43
+ // Skip home when we know it: its drain already ran on this stream's own auth, so visiting it
44
+ // would open a second authenticated connection to a node we are already on, for nothing.
45
+ const targets = homeNodeId ? roster.filter((n) => n.nodeId !== homeNodeId) : roster;
46
+ if (targets.length === 0)
47
+ return result;
48
+ for (const node of targets) {
49
+ const correlationId = `sweep-${agentName}-${node.nodeId}-${Date.now()}`;
50
+ let conn;
51
+ try {
52
+ conn = openVisitingConnection(agentName, agentKeyProvider, agentPubkeyHex, { peerId: node.peerId, multiaddr: node.multiaddr }, correlationId, node.nodeId);
53
+ }
54
+ catch (err) {
55
+ // openVisitingConnection connects ASYNCHRONOUSLY, so in practice it does not throw on a
56
+ // dial failure — that case is caught after the ceiling instead. This catches a synchronous
57
+ // fault while it wires the connection up, where `conn` is undefined and there is nothing to
58
+ // stop. One node failing must never end the sweep.
59
+ result.unreachable.push(node.nodeId);
60
+ logger.warn("trust_signal.sweep.node_unreachable", { agentName, node: node.nodeId, reason: extractErrorMessage(err) });
61
+ continue;
62
+ }
63
+ // try/finally, because the teardown is not optional. A throw between here and `stop()` would
64
+ // leave an AUTHENTICATED visiting connection open — and the order names the consequence
65
+ // directly: the directory drains its durable notification queue down any such stream, which
66
+ // is a bug this connection type has already caused once.
67
+ try {
68
+ // Register BEFORE the promise, so a throw here cannot reject it and skip the teardown.
69
+ let onComplete;
70
+ conn.mgr.registerInboundHandler((frame) => {
71
+ if (frame["type"] !== "trust_signal_drain_complete")
72
+ return;
73
+ onComplete?.();
74
+ });
75
+ // Wait for the node to say the drain is finished — or give up at the ceiling.
76
+ //
77
+ // The terminal frame is what makes this correct: a timer alone truncates a slow drain and
78
+ // re-drops the remainder on the next sweep, forever, because the directory deletes on ACK
79
+ // and an un-acked row simply comes back. The ceiling is the backstop for a node that never
80
+ // sends one, including any directory older than that change.
81
+ const completed = await new Promise((resolve) => {
82
+ const timer = setTimeout(() => resolve(false), ceilingMs);
83
+ // Do not hold the process open waiting on a node that has gone quiet.
84
+ timer.unref?.();
85
+ onComplete = () => { clearTimeout(timer); resolve(true); };
86
+ });
87
+ if (completed)
88
+ result.visited.push(node.nodeId);
89
+ else if (conn.mgr.status !== undefined && conn.mgr.status !== "connected") {
90
+ // NEVER CONNECTED, so this is a transport failure and not a slow drain. Filing it as
91
+ // `incomplete` would name the directory's drain for something that is the network —
92
+ // an exit-point label standing in for the real cause, which is the reading an operator
93
+ // would then act on.
94
+ result.unreachable.push(node.nodeId);
95
+ logger.warn("trust_signal.sweep.node_unreachable", {
96
+ agentName, node: node.nodeId, reason: "never_connected", ceilingMs,
97
+ });
98
+ }
99
+ else {
100
+ // Connected and answering, but never said it was done. We may have collected everything
101
+ // or only part of it and cannot tell — a different answer from a clean sweep, recorded
102
+ // as one.
103
+ result.incomplete.push(node.nodeId);
104
+ logger.warn("trust_signal.sweep.no_terminal_frame", { agentName, node: node.nodeId, ceilingMs });
105
+ }
106
+ }
107
+ finally {
108
+ // `stop` awaits any in-flight pickup handler before tearing the stream down (C1 review), so
109
+ // a signal still being opened and stored is not cut off by this close.
110
+ await conn.stop("sweep_finished");
111
+ }
112
+ }
113
+ logger.info("trust_signal.sweep.finished", {
114
+ agentName,
115
+ visited: result.visited.length,
116
+ unreachable: result.unreachable.length,
117
+ incomplete: result.incomplete.length,
118
+ });
119
+ return result;
120
+ }
121
+ ;
122
+ }
123
+ //# sourceMappingURL=trust-signal-sweep.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trust-signal-sweep.js","sourceRoot":"","sources":["../src/trust-signal-sweep.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cello-protocol/daemon",
3
- "version": "0.0.202",
3
+ "version": "0.0.204",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "engines": {
@@ -35,10 +35,10 @@
35
35
  "@signalapp/sqlcipher": "^3.3.5",
36
36
  "cbor-x": "^1.6.0",
37
37
  "it-length-prefixed": "^10.0.1",
38
- "@cello-protocol/crypto": "0.0.78",
39
- "@cello-protocol/gateway": "0.0.62",
40
- "@cello-protocol/protocol-types": "0.0.82",
41
- "@cello-protocol/transport": "0.0.84"
38
+ "@cello-protocol/gateway": "0.0.64",
39
+ "@cello-protocol/crypto": "0.0.80",
40
+ "@cello-protocol/transport": "0.0.86",
41
+ "@cello-protocol/protocol-types": "0.0.84"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/node": "^25.6.2",