@cello-protocol/daemon 0.0.15 → 0.0.17
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.
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +60 -1
- package/dist/daemon.js.map +1 -1
- package/dist/directory-bootstrap.d.ts +45 -0
- package/dist/directory-bootstrap.d.ts.map +1 -1
- package/dist/directory-bootstrap.js +63 -0
- package/dist/directory-bootstrap.js.map +1 -1
- package/dist/registration-context.d.ts +3 -0
- package/dist/registration-context.d.ts.map +1 -1
- package/dist/registration-context.js +8 -0
- package/dist/registration-context.js.map +1 -1
- package/dist/registration-manager.d.ts +11 -0
- package/dist/registration-manager.d.ts.map +1 -1
- package/dist/registration-manager.js +55 -12
- package/dist/registration-manager.js.map +1 -1
- package/dist/session-ceremony.d.ts +9 -1
- package/dist/session-ceremony.d.ts.map +1 -1
- package/dist/session-ceremony.js +34 -8
- package/dist/session-ceremony.js.map +1 -1
- package/package.json +4 -4
package/dist/daemon.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EAQrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAM/D,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAoB7G,OAAO,KAAK,EAAE,kBAAkB,EAA+C,MAAM,yBAAyB,CAAC;AAM/G,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAqInF,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,SAAS,IAAI,oBAAoB,CAAC;IAClC;;;;OAIG;IACH,qBAAqB,IAAI,kBAAkB,CAAC;IAC5C;;;;;;;;OAQG;IACH,gBAAgB,IAAI,SAAS,GAAG,IAAI,CAAC;IACrC;;;;OAIG;IACH,oBAAoB,IAAI,kBAAkB,CAAC;IAC3C;;;OAGG;IACH,iBAAiB,IAAI,eAAe,CAAC;CACtC;AAyCD,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,oBAAoB,EAQrB,MAAM,YAAY,CAAC;AAIpB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAM/D,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAoB7G,OAAO,KAAK,EAAE,kBAAkB,EAA+C,MAAM,yBAAyB,CAAC;AAM/G,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAqInF,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,SAAS,IAAI,oBAAoB,CAAC;IAClC;;;;OAIG;IACH,qBAAqB,IAAI,kBAAkB,CAAC;IAC5C;;;;;;;;OAQG;IACH,gBAAgB,IAAI,SAAS,GAAG,IAAI,CAAC;IACrC;;;;OAIG;IACH,oBAAoB,IAAI,kBAAkB,CAAC;IAC3C;;;OAGG;IACH,iBAAiB,IAAI,eAAe,CAAC;CACtC;AAyCD,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAyzH7E"}
|
package/dist/daemon.js
CHANGED
|
@@ -55,7 +55,7 @@ import { wireSessionCeremonyHandler, wireSessionOfferHandler, wireSealCeremonyHa
|
|
|
55
55
|
import { reDeriveFrontiers, findInflatedFrontier } from "./seal-frontier-verify.js";
|
|
56
56
|
import { LocalAutoNatStub } from "@cello-protocol/transport";
|
|
57
57
|
import { startHttpManifestPoll } from "./http-manifest-poll.js";
|
|
58
|
-
import { resolveDirectoryUrl } from "./directory-bootstrap.js";
|
|
58
|
+
import { resolveDirectoryUrl, manifestNodesToEndpoints } from "./directory-bootstrap.js";
|
|
59
59
|
/**
|
|
60
60
|
* M7-SESSION-001 (H-1): canonical byte encoding of a SEAL-INTERRUPTED leaf for
|
|
61
61
|
* Ed25519 signing/verification. Field order is fixed and deterministic. Both the
|
|
@@ -226,6 +226,10 @@ export async function startDaemon(config) {
|
|
|
226
226
|
// M7 Keystone: the version of the verified manifest, surfaced in ConnectResult.
|
|
227
227
|
// Stays 0 when no manifestProvider is configured (the M6 backward-compat path).
|
|
228
228
|
let verifiedManifestVersion = 0;
|
|
229
|
+
// DOD-MANIFEST-1: the consortium node set resolved to live directory endpoints from
|
|
230
|
+
// the VERIFIED manifest — the N-node roster a T-of-N ceremony (DOD-DKG-1) fans out to.
|
|
231
|
+
// Empty in the M6 backward-compat path (no manifest) or if no node resolves.
|
|
232
|
+
let consortiumEndpoints = [];
|
|
229
233
|
if (manifestProvider && manifestRootKeys && manifestThreshold !== undefined) {
|
|
230
234
|
try {
|
|
231
235
|
const manifest = await manifestProvider.loadAndVerify(manifestRootKeys, manifestThreshold);
|
|
@@ -262,6 +266,38 @@ export async function startDaemon(config) {
|
|
|
262
266
|
manifestVersion: manifest.version,
|
|
263
267
|
signerCount: manifest.signatures.length,
|
|
264
268
|
});
|
|
269
|
+
// DOD-MANIFEST-1: resolve the FULL verified node set to live directory
|
|
270
|
+
// endpoints (replaces the implicit single-endpoint assumption). This is the
|
|
271
|
+
// roster T-of-N ceremonies fan out to. Availability-aware — a node that is
|
|
272
|
+
// down is skipped, the rest still resolve (redundancy invariant: a ceremony
|
|
273
|
+
// needs only T of N). The resolved count is logged so an operator sees the
|
|
274
|
+
// real reachable consortium at startup; the ceremony layer (DOD-DKG-1)
|
|
275
|
+
// re-checks the threshold against this roster and never silently falls back
|
|
276
|
+
// to the single hardcoded endpoint for a missing/forged node.
|
|
277
|
+
consortiumEndpoints = await manifestNodesToEndpoints(manifest.nodes, { logger });
|
|
278
|
+
const declaredNodes = manifest.nodes.length;
|
|
279
|
+
const resolvedNodes = consortiumEndpoints.length;
|
|
280
|
+
// Carry the nodeId↔peerId pairing (not just peerIds) so a consumer/test can verify
|
|
281
|
+
// each manifest identity bound to the right live directory, not merely the set.
|
|
282
|
+
const consortiumLog = {
|
|
283
|
+
manifestVersion: manifest.version,
|
|
284
|
+
declaredNodes,
|
|
285
|
+
resolvedNodes,
|
|
286
|
+
nodes: consortiumEndpoints.map((e) => ({ nodeId: e.nodeId, peerId: e.peerId })),
|
|
287
|
+
};
|
|
288
|
+
// Degraded ≠ healthy: a verified manifest whose nodes don't all resolve must NOT
|
|
289
|
+
// log at the same severity as a full roster. Threshold-REFUSAL (refusing to run a
|
|
290
|
+
// ceremony below T) is DOD-DKG-1's gate; here we make the health signal loud so a
|
|
291
|
+
// shrunken/empty roster is visible and never buried at info.
|
|
292
|
+
if (resolvedNodes === 0) {
|
|
293
|
+
logger.error("directory.consortium.none", consortiumLog);
|
|
294
|
+
}
|
|
295
|
+
else if (resolvedNodes < declaredNodes) {
|
|
296
|
+
logger.warn("directory.consortium.partial", consortiumLog);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
logger.info("directory.consortium.resolved", consortiumLog);
|
|
300
|
+
}
|
|
265
301
|
}
|
|
266
302
|
}
|
|
267
303
|
}
|
|
@@ -286,6 +322,14 @@ export async function startDaemon(config) {
|
|
|
286
322
|
throw new Error("Manifest verification failed. The daemon cannot start with an unverified manifest when manifestProvider is configured. " +
|
|
287
323
|
"Check the logs for the specific failure reason (manifest_signature_invalid, manifest_expired, or manifest_version_rollback).");
|
|
288
324
|
}
|
|
325
|
+
// DOD-SIGN-1: resolve the consortium roster for a session/seal FROST ceremony (same source as
|
|
326
|
+
// registration's DOD-DKG-1 path — the verified manifest, re-resolved at ceremony time). NULL when
|
|
327
|
+
// no consortium manifest is configured → single-node ceremony (M6/M7 back-compat). Shared by all
|
|
328
|
+
// wireSessionCeremonyHandler / wireSealCeremonyHandler call sites below.
|
|
329
|
+
const resolveConsortiumRoster = async () => {
|
|
330
|
+
const m = manifestProvider?.getCurrentManifest();
|
|
331
|
+
return m ? await manifestNodesToEndpoints(m.nodes, { logger }) : null;
|
|
332
|
+
};
|
|
289
333
|
// CELLO-M7-CONN-001 (DOD-CONN-3): start the daemon-level HTTP manifest poll. It fetches
|
|
290
334
|
// ${directoryHttpUrl}/manifest, verifies the threshold signature against the locally-pinned
|
|
291
335
|
// root keys, applies anti-rollback + expiry, and adopts a newer manifest — independent of any
|
|
@@ -440,6 +484,7 @@ export async function startDaemon(config) {
|
|
|
440
484
|
agentPubkeyHex,
|
|
441
485
|
getNode: entry.getNode,
|
|
442
486
|
getDirectoryEndpoint: async () => (directoryEndpointResolver ? (await directoryEndpointResolver()) ?? null : null),
|
|
487
|
+
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
443
488
|
signaling: mgr,
|
|
444
489
|
logger,
|
|
445
490
|
});
|
|
@@ -450,6 +495,7 @@ export async function startDaemon(config) {
|
|
|
450
495
|
agentPubkeyHex,
|
|
451
496
|
getNode: entry.getNode,
|
|
452
497
|
getDirectoryEndpoint: async () => (directoryEndpointResolver ? (await directoryEndpointResolver()) ?? null : null),
|
|
498
|
+
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
453
499
|
signaling: mgr,
|
|
454
500
|
logger,
|
|
455
501
|
});
|
|
@@ -516,6 +562,7 @@ export async function startDaemon(config) {
|
|
|
516
562
|
agentPubkeyHex: agent.pubkey,
|
|
517
563
|
getNode: getDirectoryNode,
|
|
518
564
|
getDirectoryEndpoint: async () => (directoryEndpointResolver ? (await directoryEndpointResolver()) ?? null : null),
|
|
565
|
+
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
519
566
|
signaling: mgr,
|
|
520
567
|
logger,
|
|
521
568
|
});
|
|
@@ -525,6 +572,7 @@ export async function startDaemon(config) {
|
|
|
525
572
|
agentPubkeyHex: agent.pubkey,
|
|
526
573
|
getNode: getDirectoryNode,
|
|
527
574
|
getDirectoryEndpoint: async () => (directoryEndpointResolver ? (await directoryEndpointResolver()) ?? null : null),
|
|
575
|
+
getConsortiumEndpoints: resolveConsortiumRoster,
|
|
528
576
|
signaling: mgr,
|
|
529
577
|
logger,
|
|
530
578
|
});
|
|
@@ -1373,10 +1421,21 @@ export async function startDaemon(config) {
|
|
|
1373
1421
|
};
|
|
1374
1422
|
}
|
|
1375
1423
|
const persistence = getPersistence(name);
|
|
1424
|
+
// DOD-DKG-1: resolve the full consortium roster from the VERIFIED manifest so the DKG fans
|
|
1425
|
+
// across all N directory nodes. Re-resolved here (ceremony time) for fresh failover
|
|
1426
|
+
// coordinates. NULL when NO manifest is configured (→ single-node DKG, M6/M7 back-compat);
|
|
1427
|
+
// a (possibly EMPTY) array when a manifest IS configured. The null-vs-empty distinction is
|
|
1428
|
+
// load-bearing: an empty roster (consortium configured but unreachable) must REFUSE in
|
|
1429
|
+
// registration-manager, NOT downgrade to single-node (code-reviewer B1 / fallback-finder).
|
|
1430
|
+
const currentManifest = manifestProvider?.getCurrentManifest();
|
|
1431
|
+
const consortiumRoster = currentManifest
|
|
1432
|
+
? await manifestNodesToEndpoints(currentManifest.nodes, { logger })
|
|
1433
|
+
: null;
|
|
1376
1434
|
const ctx = new DaemonRegistrationContext({
|
|
1377
1435
|
signaling: agentSignaling,
|
|
1378
1436
|
getDirectoryNode: agentGetNode,
|
|
1379
1437
|
getDirectoryEndpoint: () => directoryEndpoint,
|
|
1438
|
+
getConsortiumEndpoints: () => consortiumRoster,
|
|
1380
1439
|
keyProvider,
|
|
1381
1440
|
persistence,
|
|
1382
1441
|
logger,
|