@serfab/cadre-core 1.13.0 → 1.15.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 +293 -274
- package/dist/cadre-invite-protocol.d.ts +383 -0
- package/dist/cadre-invite-protocol.js +774 -0
- package/dist/cadre-invite-protocol.js.map +1 -0
- package/dist/cadre-join-request.d.ts +42 -0
- package/dist/cadre-join-request.js +144 -0
- package/dist/cadre-join-request.js.map +1 -0
- package/dist/cadre-node.d.ts +849 -210
- package/dist/cadre-node.js +1574 -374
- package/dist/cadre-node.js.map +1 -1
- package/dist/claim-proof.d.ts +45 -0
- package/dist/claim-proof.js +132 -0
- package/dist/claim-proof.js.map +1 -0
- package/dist/control-authorization.d.ts +80 -19
- package/dist/control-authorization.js +55 -13
- package/dist/control-authorization.js.map +1 -1
- package/dist/control-cohort.js +1 -1
- package/dist/control-cohort.js.map +1 -1
- package/dist/control-database.d.ts +605 -108
- package/dist/control-database.js +1299 -280
- package/dist/control-database.js.map +1 -1
- package/dist/control-protocol-guard.d.ts +142 -0
- package/dist/control-protocol-guard.js +293 -0
- package/dist/control-protocol-guard.js.map +1 -0
- package/dist/control-schema.d.ts +1 -1
- package/dist/control-schema.js +817 -1067
- package/dist/control-schema.js.map +1 -1
- package/dist/control-stream.d.ts +4 -0
- package/dist/control-stream.js +22 -7
- package/dist/control-stream.js.map +1 -1
- package/dist/delegate-admission.d.ts +1 -1
- package/dist/delegate-admission.js +1 -1
- package/dist/device-token.d.ts +11 -9
- package/dist/device-token.js +14 -12
- package/dist/device-token.js.map +1 -1
- package/dist/ed25519-key.d.ts +22 -9
- package/dist/ed25519-key.js +47 -10
- package/dist/ed25519-key.js.map +1 -1
- package/dist/fetch-impl.d.ts +12 -0
- package/dist/fetch-impl.js +23 -0
- package/dist/fetch-impl.js.map +1 -0
- package/dist/file-durable-slot.js +2 -1
- package/dist/file-durable-slot.js.map +1 -1
- package/dist/file-safe-name.d.ts +25 -0
- package/dist/file-safe-name.js +29 -0
- package/dist/file-safe-name.js.map +1 -0
- package/dist/formation-approval.js +5 -11
- package/dist/formation-approval.js.map +1 -1
- package/dist/fs-atomic.d.ts +0 -19
- package/dist/fs-atomic.js +3 -24
- package/dist/fs-atomic.js.map +1 -1
- package/dist/index.d.ts +22 -10
- package/dist/index.js +54 -11
- package/dist/index.js.map +1 -1
- package/dist/invitation-bootstrap.d.ts +50 -12
- package/dist/invitation-bootstrap.js +76 -13
- package/dist/invitation-bootstrap.js.map +1 -1
- package/dist/joined-strand-store.d.ts +7 -0
- package/dist/joined-strand-store.js +9 -0
- package/dist/joined-strand-store.js.map +1 -1
- package/dist/key-store-file.js +2 -1
- package/dist/key-store-file.js.map +1 -1
- package/dist/link-budget.d.ts +25 -33
- package/dist/link-budget.js +25 -35
- package/dist/link-budget.js.map +1 -1
- package/dist/machine-removal.d.ts +78 -0
- package/dist/machine-removal.js +166 -0
- package/dist/machine-removal.js.map +1 -0
- package/dist/membership-connection-gater.d.ts +191 -151
- package/dist/membership-connection-gater.js +236 -173
- package/dist/membership-connection-gater.js.map +1 -1
- package/dist/node-claim-payload.d.ts +74 -0
- package/dist/node-claim-payload.js +224 -0
- package/dist/node-claim-payload.js.map +1 -0
- package/dist/node-default-transports.d.ts +27 -0
- package/dist/node-default-transports.js +35 -0
- package/dist/node-default-transports.js.map +1 -0
- package/dist/node-transports.d.ts +30 -0
- package/dist/node-transports.js +40 -0
- package/dist/node-transports.js.map +1 -0
- package/dist/owner-anchor-sync.d.ts +22 -0
- package/dist/owner-anchor-sync.js +143 -0
- package/dist/owner-anchor-sync.js.map +1 -0
- package/dist/peer-authorization.d.ts +113 -18
- package/dist/peer-authorization.js +225 -29
- package/dist/peer-authorization.js.map +1 -1
- package/dist/peer-dial.d.ts +143 -27
- package/dist/peer-dial.js +276 -31
- package/dist/peer-dial.js.map +1 -1
- package/dist/peer-join-backfill.d.ts +26 -2
- package/dist/peer-join-backfill.js +60 -12
- package/dist/peer-join-backfill.js.map +1 -1
- package/dist/peer-record.d.ts +17 -52
- package/dist/peer-record.js +20 -58
- package/dist/peer-record.js.map +1 -1
- package/dist/pending-join-runner.d.ts +66 -58
- package/dist/pending-join-runner.js +136 -145
- package/dist/pending-join-runner.js.map +1 -1
- package/dist/primary-lan-address.d.ts +8 -0
- package/dist/primary-lan-address.js +46 -0
- package/dist/primary-lan-address.js.map +1 -0
- package/dist/provider/client.d.ts +131 -0
- package/dist/provider/client.js +226 -0
- package/dist/provider/client.js.map +1 -0
- package/dist/provider/descriptor.d.ts +41 -0
- package/dist/provider/descriptor.js +103 -0
- package/dist/provider/descriptor.js.map +1 -0
- package/dist/provider/index.d.ts +9 -0
- package/dist/provider/index.js +10 -0
- package/dist/provider/index.js.map +1 -0
- package/dist/provider/oauth.d.ts +125 -0
- package/dist/provider/oauth.js +199 -0
- package/dist/provider/oauth.js.map +1 -0
- package/dist/provider/rent-node.d.ts +101 -0
- package/dist/provider/rent-node.js +220 -0
- package/dist/provider/rent-node.js.map +1 -0
- package/dist/push-fanout.d.ts +8 -2
- package/dist/push-fanout.js +8 -2
- package/dist/push-fanout.js.map +1 -1
- package/dist/relay-addrs.d.ts +9 -4
- package/dist/relay-addrs.js +9 -4
- package/dist/relay-addrs.js.map +1 -1
- package/dist/relay-reservation.d.ts +51 -16
- package/dist/relay-reservation.js +107 -24
- package/dist/relay-reservation.js.map +1 -1
- package/dist/seed-bootstrap.d.ts +165 -123
- package/dist/seed-bootstrap.js +313 -275
- package/dist/seed-bootstrap.js.map +1 -1
- package/dist/seed-trust-policy.d.ts +98 -37
- package/dist/seed-trust-policy.js +188 -2
- package/dist/seed-trust-policy.js.map +1 -1
- package/dist/strand-addr-protocol.d.ts +24 -26
- package/dist/strand-addr-protocol.js +19 -26
- package/dist/strand-addr-protocol.js.map +1 -1
- package/dist/strand-commit-durability.d.ts +54 -0
- package/dist/strand-commit-durability.js +74 -0
- package/dist/strand-commit-durability.js.map +1 -0
- package/dist/strand-database.d.ts +23 -8
- package/dist/strand-database.js +41 -13
- package/dist/strand-database.js.map +1 -1
- package/dist/strand-first-sync-gate.d.ts +7 -1
- package/dist/strand-first-sync-gate.js +7 -1
- package/dist/strand-first-sync-gate.js.map +1 -1
- package/dist/strand-formation-protocol.js +5 -2
- package/dist/strand-formation-protocol.js.map +1 -1
- package/dist/strand-fret-addrs.d.ts +19 -1
- package/dist/strand-fret-addrs.js +27 -9
- package/dist/strand-fret-addrs.js.map +1 -1
- package/dist/strand-instance-manager.d.ts +81 -19
- package/dist/strand-instance-manager.js +216 -105
- package/dist/strand-instance-manager.js.map +1 -1
- package/dist/strand-move.d.ts +124 -0
- package/dist/strand-move.js +438 -0
- package/dist/strand-move.js.map +1 -0
- package/dist/strand-network-config.js +7 -6
- package/dist/strand-network-config.js.map +1 -1
- package/dist/strand-peer-redial.d.ts +113 -0
- package/dist/strand-peer-redial.js +236 -0
- package/dist/strand-peer-redial.js.map +1 -0
- package/dist/strand-revocation-enforcer.d.ts +11 -11
- package/dist/strand-revocation-enforcer.js +11 -11
- package/dist/strand-wake-protocol.d.ts +13 -16
- package/dist/strand-wake-protocol.js +23 -27
- package/dist/strand-wake-protocol.js.map +1 -1
- package/dist/trusted-owner-store.d.ts +35 -5
- package/dist/trusted-owner-store.js +50 -8
- package/dist/trusted-owner-store.js.map +1 -1
- package/dist/types.d.ts +512 -89
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -1
- package/package.json +19 -10
- package/src/cadre-invite-protocol.ts +1052 -0
- package/src/cadre-join-request.ts +167 -0
- package/src/cadre-node.ts +1703 -386
- package/src/claim-proof.ts +147 -0
- package/src/control-authorization.ts +203 -117
- package/src/control-cohort.ts +1 -1
- package/src/control-database.ts +4663 -3453
- package/src/control-protocol-guard.ts +348 -0
- package/src/control-schema.ts +828 -1078
- package/src/control-stream.ts +26 -7
- package/src/delegate-admission.ts +1 -1
- package/src/device-token.ts +14 -10
- package/src/ed25519-key.ts +47 -10
- package/src/fetch-impl.ts +23 -0
- package/src/file-durable-slot.ts +64 -63
- package/src/file-safe-name.ts +32 -0
- package/src/formation-approval.ts +604 -610
- package/src/fs-atomic.ts +92 -117
- package/src/index.ts +789 -648
- package/src/invitation-bootstrap.ts +91 -13
- package/src/joined-strand-store.ts +508 -498
- package/src/key-store-file.ts +142 -141
- package/src/link-budget.ts +25 -36
- package/src/machine-removal.ts +216 -0
- package/src/membership-connection-gater.ts +259 -191
- package/src/node-claim-payload.ts +259 -0
- package/src/node-default-transports.ts +38 -0
- package/src/node-transports.ts +49 -0
- package/src/owner-anchor-sync.ts +171 -0
- package/src/peer-authorization.ts +258 -29
- package/src/peer-dial.ts +604 -315
- package/src/peer-join-backfill.ts +62 -11
- package/src/peer-record.ts +159 -197
- package/src/pending-join-runner.ts +729 -735
- package/src/primary-lan-address.ts +47 -0
- package/src/provider/client.ts +326 -0
- package/src/provider/descriptor.ts +129 -0
- package/src/provider/index.ts +59 -0
- package/src/provider/oauth.ts +285 -0
- package/src/provider/rent-node.ts +275 -0
- package/src/push-fanout.ts +8 -2
- package/src/relay-addrs.ts +9 -4
- package/src/relay-reservation.ts +1211 -1121
- package/src/seed-bootstrap.ts +1502 -1448
- package/src/seed-trust-policy.ts +353 -140
- package/src/strand-addr-protocol.ts +26 -35
- package/src/strand-commit-durability.ts +116 -0
- package/src/strand-database.ts +46 -14
- package/src/strand-first-sync-gate.ts +7 -1
- package/src/strand-formation-protocol.ts +1039 -1036
- package/src/strand-fret-addrs.ts +179 -145
- package/src/strand-instance-manager.ts +2026 -1883
- package/src/strand-move.ts +585 -0
- package/src/strand-network-config.ts +7 -6
- package/src/strand-peer-redial.ts +307 -0
- package/src/strand-revocation-enforcer.ts +11 -11
- package/src/strand-wake-protocol.ts +23 -30
- package/src/trusted-owner-store.ts +242 -171
- package/src/types.ts +2687 -2242
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
* one stream, so each side reads to EOF (under a read timeout) and decodes one
|
|
19
19
|
* frame via the shared {@link decodeLengthPrefixedFrame} guard.
|
|
20
20
|
*
|
|
21
|
-
* **Authorization (v1):** like wake, the
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* own rows into the replicated control DB
|
|
27
|
-
*
|
|
28
|
-
* `MemberPeer`) and is out of scope here.
|
|
21
|
+
* **Authorization (v1):** like wake, the request carries no signature. Membership
|
|
22
|
+
* is checked before this handler runs, by the control node's protocol guard
|
|
23
|
+
* (`control-protocol-guard.ts`, the `members` class: `CadreNode.isAuthorizedMember`,
|
|
24
|
+
* a voucher on the requester's `CadrePeer` row verified against the node-local
|
|
25
|
+
* trusted-owner anchor). A peer it refuses gets its stream reset, never a reply, so
|
|
26
|
+
* an outsider that published its own rows into the replicated control DB can neither
|
|
27
|
+
* harvest live strand addresses nor announce a delegate. Cross-party strand bootstrap
|
|
28
|
+
* is a different mechanism (strand formation / `MemberPeer`) and is out of scope here.
|
|
29
29
|
*/
|
|
30
30
|
import debug from 'debug';
|
|
31
31
|
import { peerIdFromString } from '@libp2p/peer-id';
|
|
@@ -58,16 +58,16 @@ async function readFrame(stream, timeoutMs) {
|
|
|
58
58
|
const body = decodeLengthPrefixedFrame(data, MAX_ADDR_SIZE);
|
|
59
59
|
return JSON.parse(new TextDecoder().decode(body));
|
|
60
60
|
}
|
|
61
|
-
/** An address-free reply, for every path but a
|
|
61
|
+
/** An address-free reply, for every path but a lookup: over the cap, an unreadable request, a lookup that threw. */
|
|
62
62
|
function addrlessResponse(status, strandId) {
|
|
63
63
|
return { status, strandId, multiaddrs: [] };
|
|
64
64
|
}
|
|
65
65
|
/**
|
|
66
66
|
* Receiver side of the strand-address RPC. Registers a `STRAND_ADDR_PROTOCOL`
|
|
67
|
-
* handler on the control node and, for each inbound {@link StrandAddrRequest}
|
|
68
|
-
*
|
|
69
|
-
* multiaddrs — `ok` with an empty
|
|
70
|
-
*
|
|
67
|
+
* handler on the control node and, for each inbound {@link StrandAddrRequest}
|
|
68
|
+
* (from a peer the protocol guard has already admitted as an authorized member),
|
|
69
|
+
* replies with the local strand instance's live multiaddrs — `ok` with an empty
|
|
70
|
+
* list when the strand is not running, `unavailable` when it could not answer at all.
|
|
71
71
|
*/
|
|
72
72
|
export class StrandAddrService {
|
|
73
73
|
constructor(options) {
|
|
@@ -117,8 +117,8 @@ export class StrandAddrService {
|
|
|
117
117
|
* (over {@link maxConcurrent}, reply without looking up any address), a read
|
|
118
118
|
* timeout (a peer that never half-closes is aborted inside {@link readFrame}/
|
|
119
119
|
* `readStreamToEnd`), and the existing malformed/oversized-frame guard. A
|
|
120
|
-
* lookup that throws
|
|
121
|
-
*
|
|
120
|
+
* lookup that throws is `unavailable` too, never an empty `ok` the asker would
|
|
121
|
+
* wait ten minutes on.
|
|
122
122
|
*/
|
|
123
123
|
async handleStream(stream, remotePeerId) {
|
|
124
124
|
log('Incoming strand-addr request from: %s', remotePeerId);
|
|
@@ -155,21 +155,14 @@ export class StrandAddrService {
|
|
|
155
155
|
* decision matrix can be unit-tested directly (mirrors wake's
|
|
156
156
|
* `processWakeRequest`).
|
|
157
157
|
*
|
|
158
|
-
* -
|
|
159
|
-
* - Member request carrying a `delegatePeerId` → recorded via
|
|
158
|
+
* - Request carrying a `delegatePeerId` → recorded via
|
|
160
159
|
* {@link StrandAddrServiceOptions.onDelegateAnnounce} before the lookup.
|
|
161
160
|
* - Strand not running locally → `ok` with empty `multiaddrs` (`getStrandMultiaddrs` → `[]`).
|
|
162
|
-
* -
|
|
161
|
+
* - Running strand → `ok` with the strand's live, signaling-first multiaddrs.
|
|
163
162
|
*
|
|
164
|
-
* A throwing
|
|
163
|
+
* A throwing lookup propagates; {@link handleStream} answers it `unavailable`.
|
|
165
164
|
*/
|
|
166
165
|
async processAddrRequest(request, remotePeerId) {
|
|
167
|
-
// Control-network membership is the v1 authorization: only this party's
|
|
168
|
-
// cadre peers may ask us for a strand address (or announce a delegate).
|
|
169
|
-
if (!(await this.options.isMember(remotePeerId))) {
|
|
170
|
-
log('Refusing strand-addr from non-member %s', remotePeerId);
|
|
171
|
-
return addrlessResponse('refused', request.strandId);
|
|
172
|
-
}
|
|
173
166
|
this.recordDelegateAnnounce(request, remotePeerId);
|
|
174
167
|
const multiaddrs = this.options.getStrandMultiaddrs(request.strandId);
|
|
175
168
|
log('Strand-addr for %s → %d addr(s)', request.strandId, multiaddrs.length);
|
|
@@ -361,7 +354,7 @@ async function sendStrandAddr(node, target, protocolId, request, timeoutMs, sign
|
|
|
361
354
|
log('Strand-addr response: %s, %d addr(s) for %s', response.status, response.multiaddrs.length, response.strandId);
|
|
362
355
|
return response;
|
|
363
356
|
}
|
|
364
|
-
const STRAND_ADDR_STATUSES = new Set(['ok', 'unavailable'
|
|
357
|
+
const STRAND_ADDR_STATUSES = new Set(['ok', 'unavailable']);
|
|
365
358
|
/**
|
|
366
359
|
* Shape check on a decoded reply: the responder is another machine, so a reply
|
|
367
360
|
* missing its status (an older responder, or a buggy one) or carrying anything but
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strand-addr-protocol.js","sourceRoot":"","sources":["../src/strand-addr-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAsB,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACtH,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,GAAG,GAAG,KAAK,CAAC,0BAA0B,CAAC,CAAC;AAE9C,wGAAwG;AACxG,MAAM,CAAC,MAAM,oBAAoB,GAAG,2BAA2B,CAAC;AAEhE;;;;GAIG;AACH,MAAM,aAAa,GAAG,EAAE,GAAG,IAAI,CAAC;AAEhC,yFAAyF;AACzF,uNAAuN;AACvN,MAAM,4BAA4B,GAAG,KAAM,CAAC;AAE5C,wFAAwF;AACxF,MAAM,4BAA4B,GAAG,GAAG,CAAC;AAEzC;;;;;GAKG;AACH,KAAK,UAAU,SAAS,CAAI,MAAqB,EAAE,SAAiB;IAClE,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,CAAC,CAAC;IACzG,MAAM,IAAI,GAAG,yBAAyB,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAM,CAAC;AACzD,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"strand-addr-protocol.js","sourceRoot":"","sources":["../src/strand-addr-protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { CommitFullyHeld, SqlCommitDurability } from '@serfab/quereus-plugin-sereus';
|
|
2
|
+
/** What one commit on a strand wrote, and whether it survives this machine stopping for good. */
|
|
3
|
+
export interface StrandCommitDurability {
|
|
4
|
+
readonly strandId: string;
|
|
5
|
+
/** `StampId()` inside the committed transaction. */
|
|
6
|
+
readonly transactionId: string;
|
|
7
|
+
/**
|
|
8
|
+
* Another member holds every block the commit wrote: the overall answer is `majority` or `full`
|
|
9
|
+
* and no block was abandoned (`torn`). False for `local`, `unrouted`, an unknown overall, or a
|
|
10
|
+
* torn commit. Becomes true once `strand:commit-held` fires for the commit.
|
|
11
|
+
*/
|
|
12
|
+
readonly heldElsewhere: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* When {@link heldElsewhere} is false: `strand:commit-held` will fire for this commit if it
|
|
15
|
+
* reaches the others while this database stays open. False means nothing will say so.
|
|
16
|
+
*/
|
|
17
|
+
readonly followed: boolean;
|
|
18
|
+
/** The plugin's report, for per-table detail. */
|
|
19
|
+
readonly report: SqlCommitDurability;
|
|
20
|
+
}
|
|
21
|
+
/** A commit that was held only below full replication is now held by every member of its cohort. */
|
|
22
|
+
export interface StrandCommitHeld {
|
|
23
|
+
readonly strandId: string;
|
|
24
|
+
readonly transactionId: string;
|
|
25
|
+
}
|
|
26
|
+
/** Where a strand database forwards each commit's durability and each held commit. */
|
|
27
|
+
export interface StrandCommitListeners {
|
|
28
|
+
onCommitDurability?: (commit: StrandCommitDurability) => void;
|
|
29
|
+
onCommitHeld?: (event: StrandCommitHeld) => void;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The durability of the most recent commits on one strand database, by transaction id. The
|
|
33
|
+
* plugin reports a commit — and a `covered` commit is held — before the statement that made it
|
|
34
|
+
* resolves, so an app that learns its id from `returning StampId()` reads the answer from here
|
|
35
|
+
* afterwards. Each entry is frozen and replaced when the commit becomes held, so a value read
|
|
36
|
+
* from {@link get} never changes under its reader.
|
|
37
|
+
*/
|
|
38
|
+
export declare class StrandCommitRecord {
|
|
39
|
+
private readonly strandId;
|
|
40
|
+
private readonly listeners;
|
|
41
|
+
private readonly commits;
|
|
42
|
+
constructor(strandId: string, listeners: StrandCommitListeners);
|
|
43
|
+
get(transactionId: string): StrandCommitDurability | undefined;
|
|
44
|
+
/** A plugin `onCommitDurability` report: record it, then forward it. */
|
|
45
|
+
reportCommit(report: SqlCommitDurability): void;
|
|
46
|
+
/** A plugin `onCommitFullyHeld` event: mark the commit held, then forward it — also for one no longer recorded. */
|
|
47
|
+
reportHeld({ transactionId }: CommitFullyHeld): void;
|
|
48
|
+
private remember;
|
|
49
|
+
/**
|
|
50
|
+
* Run an app's handler isolated: it runs inside the commit, and a throw reaching the plugin
|
|
51
|
+
* would be logged there as the plugin's own listener failing.
|
|
52
|
+
*/
|
|
53
|
+
private forward;
|
|
54
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import debug from 'debug';
|
|
2
|
+
import { durabilityRank } from '@optimystic/db-core';
|
|
3
|
+
const log = debug('sereus:cadre:strand-commit-durability');
|
|
4
|
+
// NOTE: if an app reads a commit's durability later than 256 commits after it, raise this or let
|
|
5
|
+
// the app pass the id up front.
|
|
6
|
+
const RECENT_COMMIT_LIMIT = 256;
|
|
7
|
+
/**
|
|
8
|
+
* `majority` counts: a strict majority of a cohort of at least two is at least two machines, so
|
|
9
|
+
* the write survives this one stopping. A torn commit does not, though it can succeed as `majority`
|
|
10
|
+
* (Optimystic clamps a torn `full` to it): its abandoned blocks are held by nobody. The one place
|
|
11
|
+
* this rule lives; apps read the field.
|
|
12
|
+
*/
|
|
13
|
+
function isHeldElsewhere(overall) {
|
|
14
|
+
return overall !== undefined
|
|
15
|
+
&& durabilityRank(overall.quorum) >= durabilityRank('majority')
|
|
16
|
+
&& (overall.torn?.length ?? 0) === 0;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The durability of the most recent commits on one strand database, by transaction id. The
|
|
20
|
+
* plugin reports a commit — and a `covered` commit is held — before the statement that made it
|
|
21
|
+
* resolves, so an app that learns its id from `returning StampId()` reads the answer from here
|
|
22
|
+
* afterwards. Each entry is frozen and replaced when the commit becomes held, so a value read
|
|
23
|
+
* from {@link get} never changes under its reader.
|
|
24
|
+
*/
|
|
25
|
+
export class StrandCommitRecord {
|
|
26
|
+
constructor(strandId, listeners) {
|
|
27
|
+
this.strandId = strandId;
|
|
28
|
+
this.listeners = listeners;
|
|
29
|
+
this.commits = new Map();
|
|
30
|
+
}
|
|
31
|
+
get(transactionId) {
|
|
32
|
+
return this.commits.get(transactionId);
|
|
33
|
+
}
|
|
34
|
+
/** A plugin `onCommitDurability` report: record it, then forward it. */
|
|
35
|
+
reportCommit(report) {
|
|
36
|
+
const commit = Object.freeze({
|
|
37
|
+
strandId: this.strandId,
|
|
38
|
+
transactionId: report.transactionId,
|
|
39
|
+
heldElsewhere: isHeldElsewhere(report.durability.overall),
|
|
40
|
+
followed: report.followed,
|
|
41
|
+
report
|
|
42
|
+
});
|
|
43
|
+
this.remember(commit);
|
|
44
|
+
this.forward('durability', report.transactionId, () => this.listeners.onCommitDurability?.(commit));
|
|
45
|
+
}
|
|
46
|
+
/** A plugin `onCommitFullyHeld` event: mark the commit held, then forward it — also for one no longer recorded. */
|
|
47
|
+
reportHeld({ transactionId }) {
|
|
48
|
+
const recorded = this.commits.get(transactionId);
|
|
49
|
+
if (recorded) {
|
|
50
|
+
this.commits.set(transactionId, Object.freeze({ ...recorded, heldElsewhere: true }));
|
|
51
|
+
}
|
|
52
|
+
this.forward('held', transactionId, () => this.listeners.onCommitHeld?.({ strandId: this.strandId, transactionId }));
|
|
53
|
+
}
|
|
54
|
+
remember(commit) {
|
|
55
|
+
this.commits.set(commit.transactionId, commit);
|
|
56
|
+
if (this.commits.size > RECENT_COMMIT_LIMIT) {
|
|
57
|
+
const oldest = this.commits.keys().next().value;
|
|
58
|
+
this.commits.delete(oldest);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Run an app's handler isolated: it runs inside the commit, and a throw reaching the plugin
|
|
63
|
+
* would be logged there as the plugin's own listener failing.
|
|
64
|
+
*/
|
|
65
|
+
forward(kind, transactionId, deliver) {
|
|
66
|
+
try {
|
|
67
|
+
deliver();
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
log('strand %s: %s handler threw for transaction %s: %O', this.strandId, kind, transactionId, error);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=strand-commit-durability.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strand-commit-durability.js","sourceRoot":"","sources":["../src/strand-commit-durability.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAIrD,MAAM,GAAG,GAAG,KAAK,CAAC,uCAAuC,CAAC,CAAC;AAkC3D,iGAAiG;AACjG,gCAAgC;AAChC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEhC;;;;;GAKG;AACH,SAAS,eAAe,CAAC,OAAoC;IAC3D,OAAO,OAAO,KAAK,SAAS;WACvB,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,cAAc,CAAC,UAAU,CAAC;WAC5D,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;AACzC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAO,kBAAkB;IAG7B,YACmB,QAAgB,EAChB,SAAgC;QADhC,aAAQ,GAAR,QAAQ,CAAQ;QAChB,cAAS,GAAT,SAAS,CAAuB;QAJlC,YAAO,GAAG,IAAI,GAAG,EAAkC,CAAC;IAKlE,CAAC;IAEJ,GAAG,CAAC,aAAqB;QACvB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACzC,CAAC;IAED,wEAAwE;IACxE,YAAY,CAAC,MAA2B;QACtC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YAC3B,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,aAAa,EAAE,eAAe,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC;YACzD,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,MAAM;SACP,CAAC,CAAC;QACH,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IACtG,CAAC;IAED,mHAAmH;IACnH,UAAU,CAAC,EAAE,aAAa,EAAmB;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;QACjD,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,QAAQ,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QACvF,CAAC;QACD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC;IACvH,CAAC;IAEO,QAAQ,CAAC,MAA8B;QAC7C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QAC/C,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,mBAAmB,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAM,CAAC;YACjD,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,OAAO,CAAC,IAAY,EAAE,aAAqB,EAAE,OAAmB;QACtE,IAAI,CAAC;YACH,OAAO,EAAE,CAAC;QACZ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,oDAAoD,EAAE,IAAI,CAAC,QAAQ,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,CAAC,CAAC;QACvG,CAAC;IACH,CAAC;CACF"}
|
|
@@ -3,7 +3,8 @@ import type { SereusPluginResult } from '@serfab/quereus-plugin-sereus';
|
|
|
3
3
|
import type { Libp2p } from '@libp2p/interface';
|
|
4
4
|
import type { IRepo } from '@optimystic/db-core';
|
|
5
5
|
import type { SAppConfig } from './types.js';
|
|
6
|
-
|
|
6
|
+
import type { StrandCommitDurability, StrandCommitListeners } from './strand-commit-durability.js';
|
|
7
|
+
export interface StrandDatabaseConfig extends StrandCommitListeners {
|
|
7
8
|
/** The strand ID */
|
|
8
9
|
strandId: string;
|
|
9
10
|
/**
|
|
@@ -54,10 +55,12 @@ export interface StrandDatabaseConfig {
|
|
|
54
55
|
* but delegates the actual SQL-surface composition — plugin registration, node
|
|
55
56
|
* wiring, catalog hydration, schema apply — to `connectToStrand` from
|
|
56
57
|
* `@serfab/quereus-plugin-sereus`, the single shared composition. The libp2p
|
|
57
|
-
* node is injected here, so `connectToStrand`
|
|
58
|
-
* `StrandInstanceManager` owns the node lifecycle
|
|
59
|
-
*
|
|
60
|
-
*
|
|
58
|
+
* node is injected here, so `connectToStrand` neither creates nor stops it:
|
|
59
|
+
* `StrandInstanceManager` owns the node lifecycle, and a failed or closed
|
|
60
|
+
* database leaves the node running.
|
|
61
|
+
*
|
|
62
|
+
* One instance is one attempt: a failed {@link initialize} is closed and a new
|
|
63
|
+
* instance built for the next attempt.
|
|
61
64
|
*/
|
|
62
65
|
export declare class StrandDatabase {
|
|
63
66
|
private db;
|
|
@@ -65,6 +68,8 @@ export declare class StrandDatabase {
|
|
|
65
68
|
private resolvedTransactor;
|
|
66
69
|
private readonly config;
|
|
67
70
|
private initialized;
|
|
71
|
+
private readonly commits;
|
|
72
|
+
private unsubscribeCommits;
|
|
68
73
|
constructor(config: StrandDatabaseConfig);
|
|
69
74
|
/**
|
|
70
75
|
* Initialize the database — create the `Database` and delegate the strand
|
|
@@ -72,6 +77,7 @@ export declare class StrandDatabase {
|
|
|
72
77
|
* `connectToStrand` with the injected libp2p node.
|
|
73
78
|
*/
|
|
74
79
|
initialize(): Promise<void>;
|
|
80
|
+
private subscribeToCommits;
|
|
75
81
|
/**
|
|
76
82
|
* Run the founder membership bootstrap against the freshly-composed strand DB.
|
|
77
83
|
*
|
|
@@ -126,6 +132,15 @@ export declare class StrandDatabase {
|
|
|
126
132
|
* Get the underlying database for queries
|
|
127
133
|
*/
|
|
128
134
|
getDatabase(): Database;
|
|
135
|
+
/**
|
|
136
|
+
* The durability of a recent commit on this database, by its `StampId()` — the id a single
|
|
137
|
+
* `insert … returning StampId() as Tx` statement returns. Read it after that statement
|
|
138
|
+
* resolves: the plugin reports the commit before the statement returns, and a commit already
|
|
139
|
+
* held everywhere is marked held by then too. `undefined` for a commit that wrote nothing, one
|
|
140
|
+
* made before this database was built, or one more than 256 commits back. Each value is a
|
|
141
|
+
* snapshot: read again after `strand:commit-held` to see the change.
|
|
142
|
+
*/
|
|
143
|
+
commitDurability(transactionId: string): StrandCommitDurability | undefined;
|
|
129
144
|
/**
|
|
130
145
|
* The Optimystic transactor this strand's connection resolved to — always
|
|
131
146
|
* `'network'` here, since cadre-core passes no `transactor` option and takes
|
|
@@ -136,9 +151,9 @@ export declare class StrandDatabase {
|
|
|
136
151
|
getTransactor(): SereusPluginResult['transactor'];
|
|
137
152
|
/**
|
|
138
153
|
* Close the database and cleanup resources. Runs the strand-connection
|
|
139
|
-
* shutdown (collection-factory teardown
|
|
140
|
-
* then closes the `Database`.
|
|
141
|
-
*
|
|
154
|
+
* shutdown (collection-factory teardown; the injected node keeps running),
|
|
155
|
+
* then closes the `Database`. Safe on an instance whose {@link initialize}
|
|
156
|
+
* failed part-way.
|
|
142
157
|
*/
|
|
143
158
|
close(): Promise<void>;
|
|
144
159
|
private ensureInitialized;
|
package/dist/strand-database.js
CHANGED
|
@@ -3,6 +3,7 @@ import { Database } from '@quereus/quereus';
|
|
|
3
3
|
import { applyAppSchema, connectToStrand } from '@serfab/quereus-plugin-sereus';
|
|
4
4
|
import { bootstrapFounderMembership } from './strand-membership-writer.js';
|
|
5
5
|
import { strandMemberKeyPair } from './strand-member-key.js';
|
|
6
|
+
import { StrandCommitRecord } from './strand-commit-durability.js';
|
|
6
7
|
const log = debug('sereus:cadre:strand-db');
|
|
7
8
|
const timing = debug('sereus:cadre:timing');
|
|
8
9
|
/**
|
|
@@ -14,10 +15,12 @@ const timing = debug('sereus:cadre:timing');
|
|
|
14
15
|
* but delegates the actual SQL-surface composition — plugin registration, node
|
|
15
16
|
* wiring, catalog hydration, schema apply — to `connectToStrand` from
|
|
16
17
|
* `@serfab/quereus-plugin-sereus`, the single shared composition. The libp2p
|
|
17
|
-
* node is injected here, so `connectToStrand`
|
|
18
|
-
* `StrandInstanceManager` owns the node lifecycle
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* node is injected here, so `connectToStrand` neither creates nor stops it:
|
|
19
|
+
* `StrandInstanceManager` owns the node lifecycle, and a failed or closed
|
|
20
|
+
* database leaves the node running.
|
|
21
|
+
*
|
|
22
|
+
* One instance is one attempt: a failed {@link initialize} is closed and a new
|
|
23
|
+
* instance built for the next attempt.
|
|
21
24
|
*/
|
|
22
25
|
export class StrandDatabase {
|
|
23
26
|
constructor(config) {
|
|
@@ -25,7 +28,9 @@ export class StrandDatabase {
|
|
|
25
28
|
this.shutdownStrand = null;
|
|
26
29
|
this.resolvedTransactor = null;
|
|
27
30
|
this.initialized = false;
|
|
31
|
+
this.unsubscribeCommits = null;
|
|
28
32
|
this.config = config;
|
|
33
|
+
this.commits = new StrandCommitRecord(config.strandId, config);
|
|
29
34
|
}
|
|
30
35
|
/**
|
|
31
36
|
* Initialize the database — create the `Database` and delegate the strand
|
|
@@ -47,10 +52,8 @@ export class StrandDatabase {
|
|
|
47
52
|
log('Initializing StrandDatabase for strand: %s (%s)', sid, sAppConfig ? `sApp: ${sAppConfig.id} v${sAppConfig.version}` : 'storage replica');
|
|
48
53
|
this.db = new Database();
|
|
49
54
|
// Delegate to the shared composition. The node is injected, so:
|
|
50
|
-
// - `connectToStrand` never creates a node
|
|
51
|
-
//
|
|
52
|
-
// still stop the injected node via the collection factory, so the
|
|
53
|
-
// manager's later `node.stop()` is an idempotent second stop;
|
|
55
|
+
// - `connectToStrand` never creates or stops a node; `StrandInstanceManager`
|
|
56
|
+
// owns the node lifecycle;
|
|
54
57
|
// - no `storage` is passed: the plugin consumes it only to build a local
|
|
55
58
|
// transactor's raw-storage factory or to create a node it was not given,
|
|
56
59
|
// and cadre-core always injects the node and runs the network transactor.
|
|
@@ -70,17 +73,27 @@ export class StrandDatabase {
|
|
|
70
73
|
});
|
|
71
74
|
this.shutdownStrand = result.shutdown;
|
|
72
75
|
this.resolvedTransactor = result.transactor;
|
|
76
|
+
// Before the founder bootstrap, so its commits are reported like any other.
|
|
77
|
+
this.subscribeToCommits(result);
|
|
73
78
|
timing('[strandDb:%s] connectToStrand: %dms (hydrated tables=%d, indexes=%d)', sid, Math.round(performance.now() - t0), result.hydrated?.tables ?? 0, result.hydrated?.indexes ?? 0);
|
|
74
79
|
// Founder-only: write the one-time membership bootstrap now that the schema is
|
|
75
80
|
// applied (connectToStrand has returned). A throw here propagates out of
|
|
76
|
-
// initialize()
|
|
77
|
-
//
|
|
81
|
+
// initialize(), and the caller closes this half-built database (close() runs the
|
|
82
|
+
// composition's shutdown). Joiners skip this — their rows arrive via sync.
|
|
78
83
|
if (this.config.founder === true) {
|
|
79
84
|
await this.bootstrapFounder();
|
|
80
85
|
}
|
|
81
86
|
this.initialized = true;
|
|
82
87
|
log('StrandDatabase for strand %s initialized successfully', sid);
|
|
83
88
|
}
|
|
89
|
+
subscribeToCommits(result) {
|
|
90
|
+
const unsubscribeDurability = result.onCommitDurability(report => this.commits.reportCommit(report));
|
|
91
|
+
const unsubscribeHeld = result.onCommitFullyHeld(event => this.commits.reportHeld(event));
|
|
92
|
+
this.unsubscribeCommits = () => {
|
|
93
|
+
unsubscribeDurability();
|
|
94
|
+
unsubscribeHeld();
|
|
95
|
+
};
|
|
96
|
+
}
|
|
84
97
|
/**
|
|
85
98
|
* Run the founder membership bootstrap against the freshly-composed strand DB.
|
|
86
99
|
*
|
|
@@ -177,6 +190,18 @@ export class StrandDatabase {
|
|
|
177
190
|
this.ensureInitialized();
|
|
178
191
|
return this.db;
|
|
179
192
|
}
|
|
193
|
+
/**
|
|
194
|
+
* The durability of a recent commit on this database, by its `StampId()` — the id a single
|
|
195
|
+
* `insert … returning StampId() as Tx` statement returns. Read it after that statement
|
|
196
|
+
* resolves: the plugin reports the commit before the statement returns, and a commit already
|
|
197
|
+
* held everywhere is marked held by then too. `undefined` for a commit that wrote nothing, one
|
|
198
|
+
* made before this database was built, or one more than 256 commits back. Each value is a
|
|
199
|
+
* snapshot: read again after `strand:commit-held` to see the change.
|
|
200
|
+
*/
|
|
201
|
+
commitDurability(transactionId) {
|
|
202
|
+
this.ensureInitialized();
|
|
203
|
+
return this.commits.get(transactionId);
|
|
204
|
+
}
|
|
180
205
|
/**
|
|
181
206
|
* The Optimystic transactor this strand's connection resolved to — always
|
|
182
207
|
* `'network'` here, since cadre-core passes no `transactor` option and takes
|
|
@@ -190,11 +215,14 @@ export class StrandDatabase {
|
|
|
190
215
|
}
|
|
191
216
|
/**
|
|
192
217
|
* Close the database and cleanup resources. Runs the strand-connection
|
|
193
|
-
* shutdown (collection-factory teardown
|
|
194
|
-
* then closes the `Database`.
|
|
195
|
-
*
|
|
218
|
+
* shutdown (collection-factory teardown; the injected node keeps running),
|
|
219
|
+
* then closes the `Database`. Safe on an instance whose {@link initialize}
|
|
220
|
+
* failed part-way.
|
|
196
221
|
*/
|
|
197
222
|
async close() {
|
|
223
|
+
// First, so an event from the closing connection reaches no app handler.
|
|
224
|
+
this.unsubscribeCommits?.();
|
|
225
|
+
this.unsubscribeCommits = null;
|
|
198
226
|
if (this.shutdownStrand) {
|
|
199
227
|
await this.shutdownStrand();
|
|
200
228
|
this.shutdownStrand = null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strand-database.js","sourceRoot":"","sources":["../src/strand-database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAKhF,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"strand-database.js","sourceRoot":"","sources":["../src/strand-database.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAKhF,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAGnE,MAAM,GAAG,GAAG,KAAK,CAAC,wBAAwB,CAAC,CAAC;AAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,qBAAqB,CAAC,CAAC;AA6C5C;;;;;;;;;;;;;;;GAeG;AACH,MAAM,OAAO,cAAc;IASzB,YAAY,MAA4B;QARhC,OAAE,GAAoB,IAAI,CAAC;QAC3B,mBAAc,GAA0C,IAAI,CAAC;QAC7D,uBAAkB,GAA4C,IAAI,CAAC;QAEnE,gBAAW,GAAG,KAAK,CAAC;QAEpB,uBAAkB,GAAwB,IAAI,CAAC;QAGrD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,IAAI,kBAAkB,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjE,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,UAAU;QACd,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,GAAG,CAAC,kDAAkD,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAC9E,OAAO;QACT,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;QACjC,MAAM,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QACnC,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACjC,6EAA6E;YAC7E,wCAAwC;YACxC,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,CAAC;QACD,GAAG,CAAC,iDAAiD,EAAE,GAAG,EACxD,UAAU,CAAC,CAAC,CAAC,SAAS,UAAU,CAAC,EAAE,KAAK,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC;QAEpF,IAAI,CAAC,EAAE,GAAG,IAAI,QAAQ,EAAE,CAAC;QAEzB,gEAAgE;QAChE,8EAA8E;QAC9E,8BAA8B;QAC9B,0EAA0E;QAC1E,4EAA4E;QAC5E,6EAA6E;QAC7E,0EAA0E;QAC1E,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAC7B,EAAE;QACF,wFAAwF;QACxF,wFAAwF;QACxF,yFAAyF;QACzF,kEAAkE;QAClE,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE;YAC5C,QAAQ,EAAE,GAAG;YACb,MAAM,EAAE,UAAU,EAAE,MAAM;YAC1B,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU;YAClC,eAAe,EAAE,IAAI,CAAC,MAAM,CAAC,eAAe;YAC5C,WAAW,EAAE,IAAI;SAClB,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC;QACtC,IAAI,CAAC,kBAAkB,GAAG,MAAM,CAAC,UAAU,CAAC;QAC5C,4EAA4E;QAC5E,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;QAChC,MAAM,CAAC,sEAAsE,EAC3E,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EACvC,MAAM,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAE,MAAM,CAAC,QAAQ,EAAE,OAAO,IAAI,CAAC,CAAC,CAAC;QAE/D,+EAA+E;QAC/E,yEAAyE;QACzE,iFAAiF;QACjF,2EAA2E;QAC3E,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;YACjC,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAChC,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,GAAG,CAAC,uDAAuD,EAAE,GAAG,CAAC,CAAC;IACpE,CAAC;IAEO,kBAAkB,CAAC,MAA0B;QACnD,MAAM,qBAAqB,GAAG,MAAM,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QACrG,MAAM,eAAe,GAAG,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1F,IAAI,CAAC,kBAAkB,GAAG,GAAG,EAAE;YAC7B,qBAAqB,EAAE,CAAC;YACxB,eAAe,EAAE,CAAC;QACpB,CAAC,CAAC;IACJ,CAAC;IAED;;;;;;;;;;;OAWG;IACK,KAAK,CAAC,gBAAgB;QAC5B,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QACtF,MAAM,MAAM,GAAG,UAAU,KAAK,GAAG,CAAC;QAClC,MAAM,0BAA0B,CAAC,IAAI,CAAC,EAAG,EAAE;YACzC,QAAQ;YACR,IAAI,EAAE,UAAU;YAChB,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE;YACxB,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,qBAAqB,CAAC,CAAC,CAAC,CAAC,SAAS;YAC/F,qBAAqB,EAAE,MAAM,IAAI,gBAAgB;gBAC/C,CAAC,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC,YAAY;gBACpD,CAAC,CAAC,SAAS;SACd,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACK,WAAW;QACjB,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAC7C,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,uBAAuB,QAAQ,sDAAsD;gBACrF,+EAA+E,CAChF,CAAC;QACJ,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;;;OAIG;IACK,oBAAoB,CAAC,QAAgB,EAAE,qBAAyC;QACtF,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CACb,8BAA8B,QAAQ,6CAA6C;gBACnF,gFAAgF;gBAChF,mFAAmF;gBACnF,kFAAkF;gBAClF,uCAAuC,CACxC,CAAC;QACJ,CAAC;QACD,OAAO,mBAAmB,CAAC,qBAAqB,CAAC,CAAC;IACpD,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,KAAK,CAAC,sBAAsB,CAAC,qBAA8B;;QACzD,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,MAAA,IAAI,CAAC,MAAM,EAAC,qBAAqB,QAArB,qBAAqB,GAAK,qBAAqB,EAAC;QAC5D,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,eAAe,CAAC,UAAsB;QAC1C,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,MAAM,cAAc,CAAC,IAAI,CAAC,EAAG,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;QACpC,GAAG,CAAC,mDAAmD,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,UAAU,CAAC,EAAE,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC;IACpH,CAAC;IAED;;OAEG;IACH,WAAW;QACT,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,EAAG,CAAC;IAClB,CAAC;IAED;;;;;;;OAOG;IACH,gBAAgB,CAAC,aAAqB;QACpC,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;OAMG;IACH,aAAa;QACX,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,OAAO,IAAI,CAAC,kBAAmB,CAAC;IAClC,CAAC;IAED;;;;;OAKG;IACH,KAAK,CAAC,KAAK;QACT,yEAAyE;QACzE,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC;QAC5B,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;YAC5B,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;QAC7B,CAAC;QACD,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,KAAK,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YACrB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,GAAG,CAAC,qCAAqC,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IACnE,CAAC;IAEO,iBAAiB;QACvB,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YAClC,MAAM,IAAI,KAAK,CAAC,6BAA6B,IAAI,CAAC,MAAM,CAAC,QAAQ,4CAA4C,CAAC,CAAC;QACjH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
* seed writes the catalog collection (`optimystic/schema` plus two hash-named blocks,
|
|
56
56
|
* measured 2026-09-16) alone, during `connectToStrand`'s schema apply, before any peer
|
|
57
57
|
* contact. (One with a seed cannot until a seed peer answers — Optimystic refuses the
|
|
58
|
-
* absence ruling — and
|
|
58
|
+
* absence ruling — and retries its database build on a timer, `StrandInstanceManager.deferUnreachableJoin`.) That is the same "two histories under one id" shape this gate
|
|
59
59
|
* exists to prevent, and it is only safe because both sides derive byte-identical content
|
|
60
60
|
* from the same schema text. If the catalog ever carries per-machine or ordering-dependent
|
|
61
61
|
* content (optimystic's own `0.5-same-named-tables-in-two-schemas-share-storage` re-keys
|
|
@@ -236,6 +236,12 @@ export interface StrandFirstSyncGateDeps {
|
|
|
236
236
|
* Holds one launch's `StrandDatabase` until {@link strandFirstSyncComplete}. Probes are
|
|
237
237
|
* sequential (the next is scheduled only after the previous read settles), so a slow
|
|
238
238
|
* network read never stacks probes.
|
|
239
|
+
*
|
|
240
|
+
* NOTE: a probe's reads dial the founder, through the relay when that is the only route, even
|
|
241
|
+
* while the founder is unreachable: one run of `joiner-first-commit-over-slow-relay` logged 17
|
|
242
|
+
* `hop connect denied` at the relay in about 10 s, each a few frames on the joiner's relay
|
|
243
|
+
* connection. If that connection ever shows saturated while no strand member is connected, hold
|
|
244
|
+
* the probe while the strand member redial (`strand-peer-redial.ts`) reports none connected.
|
|
239
245
|
*/
|
|
240
246
|
export declare class StrandFirstSyncGate {
|
|
241
247
|
private readonly deps;
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
* seed writes the catalog collection (`optimystic/schema` plus two hash-named blocks,
|
|
56
56
|
* measured 2026-09-16) alone, during `connectToStrand`'s schema apply, before any peer
|
|
57
57
|
* contact. (One with a seed cannot until a seed peer answers — Optimystic refuses the
|
|
58
|
-
* absence ruling — and
|
|
58
|
+
* absence ruling — and retries its database build on a timer, `StrandInstanceManager.deferUnreachableJoin`.) That is the same "two histories under one id" shape this gate
|
|
59
59
|
* exists to prevent, and it is only safe because both sides derive byte-identical content
|
|
60
60
|
* from the same schema text. If the catalog ever carries per-machine or ordering-dependent
|
|
61
61
|
* content (optimystic's own `0.5-same-named-tables-in-two-schemas-share-storage` re-keys
|
|
@@ -250,6 +250,12 @@ export async function strandFirstSyncComplete(db, label) {
|
|
|
250
250
|
* Holds one launch's `StrandDatabase` until {@link strandFirstSyncComplete}. Probes are
|
|
251
251
|
* sequential (the next is scheduled only after the previous read settles), so a slow
|
|
252
252
|
* network read never stacks probes.
|
|
253
|
+
*
|
|
254
|
+
* NOTE: a probe's reads dial the founder, through the relay when that is the only route, even
|
|
255
|
+
* while the founder is unreachable: one run of `joiner-first-commit-over-slow-relay` logged 17
|
|
256
|
+
* `hop connect denied` at the relay in about 10 s, each a few frames on the joiner's relay
|
|
257
|
+
* connection. If that connection ever shows saturated while no strand member is connected, hold
|
|
258
|
+
* the probe while the strand member redial (`strand-peer-redial.ts`) reports none connected.
|
|
253
259
|
*/
|
|
254
260
|
export class StrandFirstSyncGate {
|
|
255
261
|
constructor(deps, config) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"strand-first-sync-gate.js","sourceRoot":"","sources":["../src/strand-first-sync-gate.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"strand-first-sync-gate.js","sourceRoot":"","sources":["../src/strand-first-sync-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+DG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,uBAAuB,EAAyB,MAAM,wBAAwB,CAAC;AAExF,MAAM,GAAG,GAAG,KAAK,CAAC,gCAAgC,CAAC,CAAC;AAEpD,qHAAqH;AACrH,MAAM,CAAC,MAAM,iCAAiC,GAAG,GAAG,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0GG;AACH,iNAAiN;AACjN,MAAM,CAAC,MAAM,oCAAoC,GAAG,MAAO,CAAC;AAc5D;;;;;;;GAOG;AACH,MAAM,OAAO,4BAA6B,SAAQ,KAAK;IAIrD,YAAY,QAAgB,EAAE,QAAgB;QAC5C,KAAK,CACH,UAAU,QAAQ,4EAA4E;YAC9F,+BAA+B,QAAQ,oDAAoD;YAC3F,6FAA6F;YAC7F,2FAA2F;YAC3F,kCAAkC,CACnC,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,8BAA8B,CAAC;QAC3C,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EAAY,EAAE,KAAa;IAChE,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,CAAC,IAAI,CAAC,6CAA6C,CAAC,EAAE,CAAC;YAC/E,OAAO,CAAE,GAAG,CAAC,KAAgB,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,GAAG,CAAC,wDAAwD,EAAE,KAAK,EACjE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1D,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,iFAAiF;AACjF,SAAS,aAAa,CAAC,EAAY;IACjC,MAAM,GAAG,GAAG,EAAE,CAAC,aAAa,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC/G,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EAAY,EAAE,KAAa;IACjE,KAAK,MAAM,KAAK,IAAI,aAAa,CAAC,EAAE,CAAC,EAAE,CAAC;QACtC,IAAI,CAAC;YACH,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,EAAE,CAAC,IAAI,CAAC,sCAAsC,KAAK,GAAG,CAAC,EAAE,CAAC;gBACjF,MAAM;YACR,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,0DAA0D,EAAE,KAAK,EAAE,KAAK,EAC1E,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC1D,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,EAAY,EAAE,KAAa;IACvE,OAAO,MAAM,gBAAgB,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,MAAM,iBAAiB,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AACjF,CAAC;AAiBD;;;;;;;;;;GAUG;AACH,MAAM,OAAO,mBAAmB;IAQ9B,YAA6B,IAA6B,EAAE,MAA8B;QAA7D,SAAI,GAAJ,IAAI,CAAyB;QAJlD,YAAO,GAAG,KAAK,CAAC;QAChB,WAAM,GAAG,KAAK,CAAC;QACf,YAAO,GAAG,KAAK,CAAC;QAGtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,uBAAuB,CAAC;QAC3D,IAAI,CAAC,cAAc,GAAG,MAAM,EAAE,cAAc,IAAI,iCAAiC,CAAC;IACpF,CAAC;IAED,8CAA8C;IAC9C,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC5B,CAAC;IAED,2FAA2F;IAC3F,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED,oGAAoG;IACpG,KAAK;QACH,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS;YAAE,OAAO;QACpE,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChB,GAAG,CAAC,2EAA2E,EAC7E,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;OAKG;IACH,IAAI;QACF,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,GAAG,CAAC,mFAAmF,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC5G,CAAC;IAED,gFAAgF;IAChF,IAAI;QACF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,IAAI,IAAI,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;QACzB,CAAC;IACH,CAAC;IAEO,QAAQ;QACd,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE;YAC1C,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC;YACvB,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;IAC1B,CAAC;IAEO,KAAK,CAAC,KAAK;QACjB,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACxD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACpB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACpC,gFAAgF;QAChF,IAAI,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,IAAI,CAAC,IAAI,EAAE,CAAC;QACZ,GAAG,CAAC,iFAAiF,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACxG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;IAC3B,CAAC;IAED;;;;;;OAMG;IACK,KAAK,CAAC,SAAS;QACrB,IAAI,CAAC;YACH,OAAO,MAAM,uBAAuB,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC1F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,6DAA6D,EAAE,IAAI,CAAC,IAAI,CAAC,KAAK,EAChF,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC1D,OAAO,KAAK,CAAC;QACf,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -25,8 +25,8 @@ import { requireEd25519PublicKeyB64 } from './ed25519-key.js';
|
|
|
25
25
|
import { verifyFormationConsent } from './peer-authorization.js';
|
|
26
26
|
// seed-bootstrap imports neither this protocol nor the manager/solicitation layers,
|
|
27
27
|
// so this import introduces no cycle.
|
|
28
|
-
import { ed25519PublicKeyB64FromPeerId } from './
|
|
29
|
-
import { trailingPeerId } from './peer-
|
|
28
|
+
import { ed25519PublicKeyB64FromPeerId } from './ed25519-key.js';
|
|
29
|
+
import { trailingPeerId } from './peer-dial.js';
|
|
30
30
|
import { formationDeadlines, resolveProvisionTimeoutMs, responderClampReserveMs, splitProvisionBudget } from './strand-formation-deadlines.js';
|
|
31
31
|
import { FormationRejectedError, FormationUnreachableError } from './strand-formation-rejection.js';
|
|
32
32
|
const log = debug('sereus:cadre:formation-proto');
|
|
@@ -509,6 +509,9 @@ export class FormationListener {
|
|
|
509
509
|
* refused fails fast and still hands over to the next. A budget per address here would overrun
|
|
510
510
|
* the session or shrink the await-response budget ({@link formationDeadlines}). If joins through a
|
|
511
511
|
* hung first address are seen in practice, give each address a sub-budget or dial them in parallel.
|
|
512
|
+
* The same dial can also be joined to another dial of the responder in flight (the queue keys
|
|
513
|
+
* jobs by peer id — see `peer-dial.ts` → `dialAddr`), which then holds this one on that job's
|
|
514
|
+
* address; the remedy, when that is seen, is the same per-address dial.
|
|
512
515
|
*/
|
|
513
516
|
function openFormationStream(node, addrs, protocolId, dialTimeoutMs) {
|
|
514
517
|
return withDeadline(dialTimeoutMs, 'Formation dial-connect', async (signal) => {
|