@serfab/cadre-core 1.16.0 → 1.18.0
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/README.md +4 -3
- package/dist/bootstrap-peer-store-file.js +1 -1
- package/dist/bootstrap-peer-store.d.ts +1 -1
- package/dist/bootstrap-peer-store.js +4 -4
- package/dist/cadre-invite-protocol.d.ts +81 -142
- package/dist/cadre-invite-protocol.js +168 -458
- package/dist/cadre-invite-protocol.js.map +1 -1
- package/dist/cadre-join-request.d.ts +15 -2
- package/dist/cadre-join-request.js +22 -3
- package/dist/cadre-join-request.js.map +1 -1
- package/dist/cadre-node.d.ts +1089 -475
- package/dist/cadre-node.js +2170 -1037
- package/dist/cadre-node.js.map +1 -1
- package/dist/control-authorization.d.ts +36 -14
- package/dist/control-authorization.js +20 -3
- package/dist/control-authorization.js.map +1 -1
- package/dist/control-cohort.d.ts +88 -32
- package/dist/control-cohort.js +91 -33
- package/dist/control-cohort.js.map +1 -1
- package/dist/control-database.d.ts +856 -318
- package/dist/control-database.js +1422 -701
- package/dist/control-database.js.map +1 -1
- package/dist/control-formation-recorder.d.ts +46 -43
- package/dist/control-formation-recorder.js +77 -78
- package/dist/control-formation-recorder.js.map +1 -1
- package/dist/control-protocol-guard.d.ts +11 -4
- package/dist/control-protocol-guard.js +20 -5
- package/dist/control-protocol-guard.js.map +1 -1
- package/dist/control-schema-version.d.ts +97 -0
- package/dist/control-schema-version.js +225 -0
- package/dist/control-schema-version.js.map +1 -0
- package/dist/control-schema.d.ts +45 -5
- package/dist/control-schema.js +262 -78
- package/dist/control-schema.js.map +1 -1
- package/dist/control-write-retry.d.ts +45 -10
- package/dist/control-write-retry.js +92 -22
- package/dist/control-write-retry.js.map +1 -1
- package/dist/delegate-admission.d.ts +13 -0
- package/dist/delegate-admission.js +27 -0
- package/dist/delegate-admission.js.map +1 -1
- package/dist/ed25519-key.d.ts +10 -7
- package/dist/ed25519-key.js +23 -20
- package/dist/ed25519-key.js.map +1 -1
- package/dist/edge-node/config.d.ts +122 -0
- package/dist/edge-node/config.js +199 -0
- package/dist/edge-node/config.js.map +1 -0
- package/dist/edge-node/dissolve.d.ts +95 -0
- package/dist/edge-node/dissolve.js +184 -0
- package/dist/edge-node/dissolve.js.map +1 -0
- package/dist/edge-node/edge-join.d.ts +44 -0
- package/dist/edge-node/edge-join.js +227 -0
- package/dist/edge-node/edge-join.js.map +1 -0
- package/dist/edge-node/edge-node.d.ts +295 -0
- package/dist/edge-node/edge-node.js +704 -0
- package/dist/edge-node/edge-node.js.map +1 -0
- package/dist/edge-node/index.d.ts +18 -0
- package/dist/edge-node/index.js +18 -0
- package/dist/edge-node/index.js.map +1 -0
- package/dist/edge-node/join-credential.d.ts +11 -0
- package/dist/edge-node/join-credential.js +11 -0
- package/dist/edge-node/join-credential.js.map +1 -0
- package/dist/edge-node/lazy-raw-storage.d.ts +40 -0
- package/dist/edge-node/lazy-raw-storage.js +134 -0
- package/dist/edge-node/lazy-raw-storage.js.map +1 -0
- package/dist/edge-node/node-local.d.ts +60 -0
- package/dist/edge-node/node-local.js +58 -0
- package/dist/edge-node/node-local.js.map +1 -0
- package/dist/edge-node/options.d.ts +83 -0
- package/dist/edge-node/options.js +110 -0
- package/dist/edge-node/options.js.map +1 -0
- package/dist/edge-node/owner-grant.d.ts +41 -0
- package/dist/edge-node/owner-grant.js +38 -0
- package/dist/edge-node/owner-grant.js.map +1 -0
- package/dist/edge-node/platform.d.ts +140 -0
- package/dist/edge-node/platform.js +12 -0
- package/dist/edge-node/platform.js.map +1 -0
- package/dist/edge-node/strand-move.d.ts +115 -0
- package/dist/edge-node/strand-move.js +223 -0
- package/dist/edge-node/strand-move.js.map +1 -0
- package/dist/edge-node/strands.d.ts +28 -0
- package/dist/edge-node/strands.js +60 -0
- package/dist/edge-node/strands.js.map +1 -0
- package/dist/enrolled-machine-store.d.ts +3 -3
- package/dist/enrolled-machine-store.js +3 -3
- package/dist/formation-token.d.ts +48 -0
- package/dist/formation-token.js +26 -0
- package/dist/formation-token.js.map +1 -0
- package/dist/index.d.ts +27 -17
- package/dist/index.js +39 -17
- package/dist/index.js.map +1 -1
- package/dist/joined-strand-store.d.ts +29 -12
- package/dist/joined-strand-store.js +66 -27
- package/dist/joined-strand-store.js.map +1 -1
- package/dist/key-store.d.ts +9 -4
- package/dist/key-store.js +9 -4
- package/dist/key-store.js.map +1 -1
- package/dist/link-budget.d.ts +9 -7
- package/dist/link-budget.js +9 -7
- package/dist/link-budget.js.map +1 -1
- package/dist/machine-removal.d.ts +19 -39
- package/dist/machine-removal.js +24 -98
- package/dist/machine-removal.js.map +1 -1
- package/dist/member-redemption.d.ts +256 -0
- package/dist/member-redemption.js +490 -0
- package/dist/member-redemption.js.map +1 -0
- package/dist/membership-view.d.ts +91 -0
- package/dist/membership-view.js +110 -0
- package/dist/membership-view.js.map +1 -0
- package/dist/owner-anchor-sync.d.ts +4 -4
- package/dist/owner-anchor-sync.js +16 -15
- package/dist/owner-anchor-sync.js.map +1 -1
- package/dist/owner-grant-protocol.d.ts +251 -0
- package/dist/owner-grant-protocol.js +344 -0
- package/dist/owner-grant-protocol.js.map +1 -0
- package/dist/owner-key-export.d.ts +70 -0
- package/dist/owner-key-export.js +279 -0
- package/dist/owner-key-export.js.map +1 -0
- package/dist/owner-key-flows.d.ts +55 -0
- package/dist/owner-key-flows.js +60 -0
- package/dist/owner-key-flows.js.map +1 -0
- package/dist/owner-key-store.d.ts +31 -0
- package/dist/owner-key-store.js +81 -0
- package/dist/owner-key-store.js.map +1 -0
- package/dist/owner-keys.d.ts +78 -0
- package/dist/owner-keys.js +133 -0
- package/dist/owner-keys.js.map +1 -0
- package/dist/owner-signer.d.ts +54 -0
- package/dist/owner-signer.js +51 -0
- package/dist/owner-signer.js.map +1 -0
- package/dist/peer-addr-book.d.ts +10 -1
- package/dist/peer-addr-book.js +4 -3
- package/dist/peer-addr-book.js.map +1 -1
- package/dist/peer-authorization.d.ts +83 -18
- package/dist/peer-authorization.js +123 -53
- package/dist/peer-authorization.js.map +1 -1
- package/dist/peer-join-backfill.d.ts +89 -20
- package/dist/peer-join-backfill.js +265 -108
- package/dist/peer-join-backfill.js.map +1 -1
- package/dist/pending-join-runner.d.ts +48 -18
- package/dist/pending-join-runner.js +74 -56
- package/dist/pending-join-runner.js.map +1 -1
- package/dist/provider/rent-node.js +1 -1
- package/dist/provider/rent-node.js.map +1 -1
- package/dist/seed-bootstrap.d.ts +162 -133
- package/dist/seed-bootstrap.js +300 -283
- package/dist/seed-bootstrap.js.map +1 -1
- package/dist/seed-trust-policy.js +4 -4
- package/dist/strand-addr-protocol.d.ts +4 -1
- package/dist/strand-addr-protocol.js +8 -2
- package/dist/strand-addr-protocol.js.map +1 -1
- package/dist/strand-cohort.d.ts +3 -0
- package/dist/strand-cohort.js.map +1 -1
- package/dist/strand-database.d.ts +24 -2
- package/dist/strand-database.js +29 -6
- package/dist/strand-database.js.map +1 -1
- package/dist/strand-first-sync-gate.d.ts +176 -88
- package/dist/strand-first-sync-gate.js +288 -121
- package/dist/strand-first-sync-gate.js.map +1 -1
- package/dist/strand-formation-deadlines.d.ts +9 -9
- package/dist/strand-formation-deadlines.js +9 -9
- package/dist/strand-formation-manager.d.ts +23 -17
- package/dist/strand-formation-manager.js +46 -44
- package/dist/strand-formation-manager.js.map +1 -1
- package/dist/strand-formation-protocol.d.ts +5 -8
- package/dist/strand-formation-protocol.js +101 -16
- package/dist/strand-formation-protocol.js.map +1 -1
- package/dist/strand-instance-manager.d.ts +27 -18
- package/dist/strand-instance-manager.js +119 -50
- package/dist/strand-instance-manager.js.map +1 -1
- package/dist/strand-membership-reconciler.d.ts +16 -13
- package/dist/strand-membership-reconciler.js +30 -22
- package/dist/strand-membership-reconciler.js.map +1 -1
- package/dist/strand-membership-writer.d.ts +45 -22
- package/dist/strand-membership-writer.js +226 -131
- package/dist/strand-membership-writer.js.map +1 -1
- package/dist/strand-move.d.ts +6 -5
- package/dist/strand-move.js +36 -32
- package/dist/strand-move.js.map +1 -1
- package/dist/strand-peer-redial.js +2 -3
- package/dist/strand-peer-redial.js.map +1 -1
- package/dist/strand-revocation-enforcer.d.ts +134 -60
- package/dist/strand-revocation-enforcer.js +144 -71
- package/dist/strand-revocation-enforcer.js.map +1 -1
- package/dist/strand-solicitation.d.ts +50 -39
- package/dist/strand-solicitation.js +10 -3
- package/dist/strand-solicitation.js.map +1 -1
- package/dist/strand-watcher.d.ts +80 -13
- package/dist/strand-watcher.js +152 -48
- package/dist/strand-watcher.js.map +1 -1
- package/dist/table-change-watch.d.ts +63 -0
- package/dist/table-change-watch.js +209 -0
- package/dist/table-change-watch.js.map +1 -0
- package/dist/timeout-scheduler.d.ts +4 -3
- package/dist/timeout-scheduler.js +4 -3
- package/dist/timeout-scheduler.js.map +1 -1
- package/dist/types.d.ts +374 -150
- package/dist/types.js +4 -4
- package/dist/types.js.map +1 -1
- package/package.json +17 -8
- package/src/bootstrap-peer-store-file.ts +44 -44
- package/src/bootstrap-peer-store.ts +214 -214
- package/src/cadre-invite-protocol.ts +740 -1052
- package/src/cadre-join-request.ts +24 -3
- package/src/cadre-node.ts +2402 -1079
- package/src/control-authorization.ts +47 -14
- package/src/control-cohort.ts +204 -128
- package/src/control-database.ts +1749 -820
- package/src/control-formation-recorder.ts +359 -353
- package/src/control-protocol-guard.ts +23 -6
- package/src/control-schema-version.ts +301 -0
- package/src/control-schema.ts +273 -78
- package/src/control-write-retry.ts +641 -567
- package/src/delegate-admission.ts +351 -314
- package/src/ed25519-key.ts +174 -171
- package/src/edge-node/config.ts +277 -0
- package/src/edge-node/dissolve.ts +251 -0
- package/src/edge-node/edge-join.ts +319 -0
- package/src/edge-node/edge-node.ts +1045 -0
- package/src/edge-node/index.ts +59 -0
- package/src/edge-node/join-credential.ts +16 -0
- package/src/edge-node/lazy-raw-storage.ts +178 -0
- package/src/edge-node/node-local.ts +84 -0
- package/src/edge-node/options.ts +179 -0
- package/src/edge-node/owner-grant.ts +63 -0
- package/src/edge-node/platform.ts +151 -0
- package/src/edge-node/strand-move.ts +270 -0
- package/src/edge-node/strands.ts +72 -0
- package/src/enrolled-machine-store.ts +3 -3
- package/src/formation-token.ts +63 -0
- package/src/index.ts +899 -789
- package/src/joined-strand-store.ts +73 -28
- package/src/key-store.ts +10 -4
- package/src/link-budget.ts +9 -7
- package/src/machine-removal.ts +26 -111
- package/src/member-redemption.ts +649 -0
- package/src/membership-view.ts +144 -0
- package/src/owner-anchor-sync.ts +19 -18
- package/src/owner-grant-protocol.ts +547 -0
- package/src/owner-key-export.ts +348 -0
- package/src/owner-key-flows.ts +109 -0
- package/src/owner-key-store.ts +85 -0
- package/src/owner-keys.ts +178 -0
- package/src/owner-signer.ts +94 -0
- package/src/peer-addr-book.ts +4 -3
- package/src/peer-authorization.ts +558 -488
- package/src/peer-join-backfill.ts +971 -761
- package/src/pending-join-runner.ts +76 -53
- package/src/provider/rent-node.ts +1 -1
- package/src/seed-bootstrap.ts +343 -349
- package/src/seed-trust-policy.ts +4 -4
- package/src/strand-addr-protocol.ts +547 -538
- package/src/strand-cohort.ts +4 -0
- package/src/strand-database.ts +352 -319
- package/src/strand-first-sync-gate.ts +334 -133
- package/src/strand-formation-deadlines.ts +227 -227
- package/src/strand-formation-manager.ts +731 -725
- package/src/strand-formation-protocol.ts +122 -24
- package/src/strand-instance-manager.ts +2092 -2026
- package/src/strand-membership-reconciler.ts +33 -25
- package/src/strand-membership-writer.ts +2093 -1974
- package/src/strand-move.ts +50 -38
- package/src/strand-peer-redial.ts +2 -3
- package/src/strand-revocation-enforcer.ts +740 -654
- package/src/strand-solicitation.ts +61 -34
- package/src/strand-watcher.ts +175 -56
- package/src/table-change-watch.ts +285 -0
- package/src/timeout-scheduler.ts +29 -28
- package/src/types.ts +391 -152
package/src/strand-move.ts
CHANGED
|
@@ -21,9 +21,9 @@
|
|
|
21
21
|
* Built over `CadreNode`'s public surface, so `cadre-node.ts` does not grow by the feature.
|
|
22
22
|
*/
|
|
23
23
|
import debug from 'debug';
|
|
24
|
-
import { sign } from '@optimystic/quereus-plugin-crypto';
|
|
25
24
|
import type { PersistedNetworkState } from '@optimystic/db-p2p';
|
|
26
25
|
import type { CadreNode } from './cadre-node.js';
|
|
26
|
+
import type { OwnerSign } from './owner-signer.js';
|
|
27
27
|
import {
|
|
28
28
|
isPendingJoinConflict,
|
|
29
29
|
isStrandIdConflict,
|
|
@@ -98,10 +98,10 @@ export interface StrandMoveReport {
|
|
|
98
98
|
pendingJoinsMoved: number;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
/** {@link adoptStrandBundle} refused before any write: the running node's key is not an owner of its party. */
|
|
101
|
+
/** {@link adoptStrandBundle} refused before any write: the running node's owner key is not an owner of its party. */
|
|
102
102
|
export class StrandMoveNotOwnerError extends Error {
|
|
103
103
|
constructor(readonly partyId: string) {
|
|
104
|
-
super(`Cannot adopt strands into party ${partyId}: this node's key is not one of its owners, and every re-seated row is owner-signed`);
|
|
104
|
+
super(`Cannot adopt strands into party ${partyId}: this node's owner key is not one of its owners, and every re-seated row is owner-signed`);
|
|
105
105
|
this.name = 'StrandMoveNotOwnerError';
|
|
106
106
|
}
|
|
107
107
|
}
|
|
@@ -201,10 +201,11 @@ async function exportFormationInvites(database: ControlDatabase, now: number): P
|
|
|
201
201
|
}
|
|
202
202
|
|
|
203
203
|
/**
|
|
204
|
-
* Seat `bundle` in the running node's party, every row owner-signed
|
|
205
|
-
*
|
|
206
|
-
*
|
|
207
|
-
* ({@link
|
|
204
|
+
* Seat `bundle` in the running node's party, every row owner-signed through the node's owner
|
|
205
|
+
* signer (`CadreNode.getOwnerSigner`, wired here by `wireOwnKeyIfOwner` when it is not yet),
|
|
206
|
+
* in one approval for the whole bundle. Refuses up front, with a typed error and no write, when
|
|
207
|
+
* that signer's key is not an owner of the party ({@link StrandMoveNotOwnerError}) or the
|
|
208
|
+
* bundle came from this very party ({@link StrandMoveSamePartyError}).
|
|
208
209
|
*
|
|
209
210
|
* Strands first, then the invitations, then the pending joins. Every write is idempotent (a row
|
|
210
211
|
* already present with the same content is skipped and counted as moved), so the same bundle
|
|
@@ -221,11 +222,28 @@ export async function adoptStrandBundle(node: CadreNode, bundle: StrandBundle):
|
|
|
221
222
|
if (bundle.partyId === node.partyId) {
|
|
222
223
|
throw new StrandMoveSamePartyError(node.partyId);
|
|
223
224
|
}
|
|
224
|
-
|
|
225
|
+
const owner = (await node.wireOwnKeyIfOwner()) ? node.getOwnerSigner() : null;
|
|
226
|
+
if (owner === null) {
|
|
225
227
|
throw new StrandMoveNotOwnerError(node.partyId);
|
|
226
228
|
}
|
|
227
|
-
const
|
|
228
|
-
|
|
229
|
+
const action = `Move ${bundle.strands.length} strand(s) from the cadre ${bundle.partyId} into this one`;
|
|
230
|
+
return await owner.approve({ partyId: node.partyId, action }, (sign) =>
|
|
231
|
+
adoptUnderApproval(node, database, bundle, { ownerKey: owner.publicKey, sign }));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/** An open owner approval: the key every row is written under, and the approval's `sign`. */
|
|
235
|
+
interface OwnerApproval {
|
|
236
|
+
ownerKey: string;
|
|
237
|
+
sign: OwnerSign;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/** {@link adoptStrandBundle}'s writes, every one signed inside the one approval `approval`. */
|
|
241
|
+
async function adoptUnderApproval(
|
|
242
|
+
node: CadreNode,
|
|
243
|
+
database: ControlDatabase,
|
|
244
|
+
bundle: StrandBundle,
|
|
245
|
+
approval: OwnerApproval
|
|
246
|
+
): Promise<StrandMoveReport> {
|
|
229
247
|
const report: StrandMoveReport = {
|
|
230
248
|
fromPartyId: bundle.partyId,
|
|
231
249
|
moved: [],
|
|
@@ -236,15 +254,15 @@ export async function adoptStrandBundle(node: CadreNode, bundle: StrandBundle):
|
|
|
236
254
|
pendingJoinsMoved: 0
|
|
237
255
|
};
|
|
238
256
|
for (const entry of bundle.strands) {
|
|
239
|
-
await adoptStrand(node, database,
|
|
257
|
+
await adoptStrand(node, database, approval, entry, report);
|
|
240
258
|
}
|
|
241
259
|
const settled = settledStrands(report);
|
|
242
260
|
const now = Date.now();
|
|
243
261
|
for (const invite of bundle.formationInvites) {
|
|
244
|
-
await adoptFormationInvite(node, database, invite, settled, report, now);
|
|
262
|
+
await adoptFormationInvite(node, database, approval.sign, invite, settled, report, now);
|
|
245
263
|
}
|
|
246
264
|
for (const join of bundle.pendingJoins) {
|
|
247
|
-
await adoptPendingJoin(database,
|
|
265
|
+
await adoptPendingJoin(database, approval, join, report);
|
|
248
266
|
}
|
|
249
267
|
log('adopt(%s ← %s): %d moved, %d refused, %d failed; %d invitation(s) moved, %d dropped; %d pending join(s)',
|
|
250
268
|
node.partyId, bundle.partyId, report.moved.length, report.refused.length, report.failed.length,
|
|
@@ -252,11 +270,6 @@ export async function adoptStrandBundle(node: CadreNode, bundle: StrandBundle):
|
|
|
252
270
|
return report;
|
|
253
271
|
}
|
|
254
272
|
|
|
255
|
-
interface OwnerSigner {
|
|
256
|
-
ownerKey: string;
|
|
257
|
-
signMessage: (message: Uint8Array) => string;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
273
|
/** The strands an adoption has decided on, by outcome, for the invitations bound to them. */
|
|
261
274
|
interface SettledStrands {
|
|
262
275
|
moved: Set<string>;
|
|
@@ -271,8 +284,8 @@ function settledStrands(report: StrandMoveReport): SettledStrands {
|
|
|
271
284
|
}
|
|
272
285
|
|
|
273
286
|
/**
|
|
274
|
-
* Seat one strand, in the order the adopting node's strand watcher demands. The watcher
|
|
275
|
-
* `Strand` and `JoinedStrand`
|
|
287
|
+
* Seat one strand, in the order the adopting node's strand watcher demands. The watcher runs
|
|
288
|
+
* on every change to `Strand` and `JoinedStrand` and launches, or offers, a new row at once; a
|
|
276
289
|
* closed strand's founder launch resolves the party key and, finding none, mints a fresh one,
|
|
277
290
|
* which would found the strand a second time under a stranger's identity. So the party key is
|
|
278
291
|
* seated before the row, and the strand's peers (its saved routing table and carried addresses)
|
|
@@ -282,7 +295,7 @@ function settledStrands(report: StrandMoveReport): SettledStrands {
|
|
|
282
295
|
async function adoptStrand(
|
|
283
296
|
node: CadreNode,
|
|
284
297
|
database: ControlDatabase,
|
|
285
|
-
|
|
298
|
+
approval: OwnerApproval,
|
|
286
299
|
entry: StrandBundleEntry,
|
|
287
300
|
report: StrandMoveReport
|
|
288
301
|
): Promise<void> {
|
|
@@ -297,12 +310,15 @@ async function adoptStrand(
|
|
|
297
310
|
}
|
|
298
311
|
await seatStrandPeers(node, entry);
|
|
299
312
|
if (entry.partyKey !== null) {
|
|
300
|
-
await node.ensureStrandPartyKey(strandId, entry.partyKey);
|
|
313
|
+
await node.ensureStrandPartyKey(strandId, entry.partyKey, approval.sign);
|
|
301
314
|
}
|
|
302
315
|
if (entry.kind === 'own') {
|
|
303
|
-
|
|
316
|
+
// NOTE: with the party key seated first, a closed strand's founding transaction is refused
|
|
317
|
+
// on `StrandPartyKey.Id` and written again without a key: a local refusal, no extra commit.
|
|
318
|
+
// If moves of many closed strands get slow, let publishStrand take a known party key.
|
|
319
|
+
await node.publishStrand(strandId, entry.row.Type, entry.row.MemberPrivateKey ?? undefined, approval.sign);
|
|
304
320
|
} else {
|
|
305
|
-
await seatJoinedStrand(database,
|
|
321
|
+
await seatJoinedStrand(database, approval, entry.row, live.joined);
|
|
306
322
|
}
|
|
307
323
|
report.moved.push(strandId);
|
|
308
324
|
} catch (error) {
|
|
@@ -377,7 +393,7 @@ async function seatStrandPeers(node: CadreNode, entry: StrandBundleEntry): Promi
|
|
|
377
393
|
*/
|
|
378
394
|
async function seatJoinedStrand(
|
|
379
395
|
database: ControlDatabase,
|
|
380
|
-
|
|
396
|
+
approval: OwnerApproval,
|
|
381
397
|
row: StrandBundleEntry['row'],
|
|
382
398
|
existing: StrandRow | null
|
|
383
399
|
): Promise<void> {
|
|
@@ -385,7 +401,7 @@ async function seatJoinedStrand(
|
|
|
385
401
|
return;
|
|
386
402
|
}
|
|
387
403
|
try {
|
|
388
|
-
await database.insertJoinedStrand(row,
|
|
404
|
+
await database.insertJoinedStrand(row, approval.ownerKey, approval.sign);
|
|
389
405
|
} catch (error) {
|
|
390
406
|
if (!isStrandIdConflict(error, 'JoinedStrand')) {
|
|
391
407
|
throw error;
|
|
@@ -412,6 +428,7 @@ async function seatJoinedStrand(
|
|
|
412
428
|
async function adoptFormationInvite(
|
|
413
429
|
node: CadreNode,
|
|
414
430
|
database: ControlDatabase,
|
|
431
|
+
sign: OwnerSign,
|
|
415
432
|
invite: FormationInviteEntry,
|
|
416
433
|
settled: SettledStrands,
|
|
417
434
|
report: StrandMoveReport,
|
|
@@ -434,7 +451,7 @@ async function adoptFormationInvite(
|
|
|
434
451
|
expiresAtMs: invite.expiresAtMs ?? undefined,
|
|
435
452
|
totalUses: invite.usesLeft ?? undefined,
|
|
436
453
|
strandId: invite.strandId ?? undefined
|
|
437
|
-
});
|
|
454
|
+
}, sign);
|
|
438
455
|
}
|
|
439
456
|
report.invitationsMoved += 1;
|
|
440
457
|
} catch (error) {
|
|
@@ -464,15 +481,15 @@ async function adoptFormationInvite(
|
|
|
464
481
|
*/
|
|
465
482
|
async function adoptPendingJoin(
|
|
466
483
|
database: ControlDatabase,
|
|
467
|
-
|
|
484
|
+
approval: OwnerApproval,
|
|
468
485
|
join: PendingJoin,
|
|
469
486
|
report: StrandMoveReport
|
|
470
487
|
): Promise<void> {
|
|
471
488
|
const { StampId: _stampId, outcome, ...request } = join;
|
|
472
489
|
try {
|
|
473
|
-
const live = await seatJoinRequest(database,
|
|
490
|
+
const live = await seatJoinRequest(database, approval, request);
|
|
474
491
|
if (live !== null && outcome !== null && live.outcome === null) {
|
|
475
|
-
await database.recordJoinOutcome(live, outcome,
|
|
492
|
+
await database.recordJoinOutcome(live, outcome, approval.ownerKey, approval.sign);
|
|
476
493
|
}
|
|
477
494
|
report.pendingJoinsMoved += 1;
|
|
478
495
|
} catch (error) {
|
|
@@ -487,9 +504,9 @@ async function adoptPendingJoin(
|
|
|
487
504
|
* own ask, left alone) or a dismissed one whose retired stamp is still held until the reap
|
|
488
505
|
* pass (the party chose not to have it).
|
|
489
506
|
*/
|
|
490
|
-
async function seatJoinRequest(database: ControlDatabase,
|
|
507
|
+
async function seatJoinRequest(database: ControlDatabase, approval: OwnerApproval, request: JoinRequestFields): Promise<PendingJoin | null> {
|
|
491
508
|
try {
|
|
492
|
-
return await database.insertJoinRequest(request,
|
|
509
|
+
return await database.insertJoinRequest(request, approval.ownerKey, approval.sign);
|
|
493
510
|
} catch (error) {
|
|
494
511
|
if (!isPendingJoinConflict(error)) {
|
|
495
512
|
throw error;
|
|
@@ -557,7 +574,7 @@ function isOpenJoin(join: PendingJoin, nowMs: number): boolean {
|
|
|
557
574
|
return join.outcome === null && nowMs < join.ExpiresAt;
|
|
558
575
|
}
|
|
559
576
|
|
|
560
|
-
/** Content only: `Type` and the read secret.
|
|
577
|
+
/** Content only: `Type` and the read secret. The founder columns are provenance, and a moved strand's change. */
|
|
561
578
|
function sameStrandContent(live: StrandRow, desired: StrandBundleEntry['row']): boolean {
|
|
562
579
|
return live.Type === desired.Type && (live.MemberPrivateKey ?? null) === (desired.MemberPrivateKey ?? null);
|
|
563
580
|
}
|
|
@@ -575,11 +592,6 @@ function requireControlDatabase(node: CadreNode, action: string): ControlDatabas
|
|
|
575
592
|
return database;
|
|
576
593
|
}
|
|
577
594
|
|
|
578
|
-
function signMessageWith(privateKeyB64: string): (message: Uint8Array) => string {
|
|
579
|
-
return (message: Uint8Array): string =>
|
|
580
|
-
sign(message, privateKeyB64, 'ed25519', 'bytes', 'base64url', 'base64url') as string;
|
|
581
|
-
}
|
|
582
|
-
|
|
583
595
|
function errorText(error: unknown): string {
|
|
584
596
|
return error instanceof Error ? error.message : String(error);
|
|
585
597
|
}
|
|
@@ -234,9 +234,8 @@ class StrandPeerRedialLoop implements StrandPeerRedial {
|
|
|
234
234
|
*
|
|
235
235
|
* NOTE: a round whose dials failed within milliseconds (a relay connection that is still
|
|
236
236
|
* closing, the member's relay reservation not back yet) waits as long as one whose dials ran
|
|
237
|
-
* out their budget.
|
|
238
|
-
*
|
|
239
|
-
* ever matters, retry a round that failed that fast after a short delay instead.
|
|
237
|
+
* out their budget. If reconnecting within seconds of a cut ever matters, retry a round that
|
|
238
|
+
* failed that fast after a short delay instead.
|
|
240
239
|
*
|
|
241
240
|
* NOTE: one such fast failure is `ConnectionClosedError: The connection muxer is "closed"`. A
|
|
242
241
|
* relay that aborts its connection to this node cannot tell it so (`@libp2p/websockets`'
|