@cero-base/core 1.11.0 → 1.12.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cero-base/core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "cero p2p primitives — identity, storage, network, database, blobs, rpc, pairing.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
},
|
|
145
145
|
"dependencies": {
|
|
146
146
|
"@hyperswarm/secret-stream": "^6.9.1",
|
|
147
|
-
"autobee": "2.0.0-rc.
|
|
147
|
+
"autobee": "2.0.0-rc.19",
|
|
148
148
|
"autobee-encryption": "0.1.3",
|
|
149
149
|
"b4a": "^1.8.1",
|
|
150
150
|
"bare-crypto": "^1.15.3",
|
|
@@ -152,18 +152,18 @@
|
|
|
152
152
|
"bare-path": "^3.1.1",
|
|
153
153
|
"bip39-mnemonic": "^2.5.0",
|
|
154
154
|
"blind-pairing": "^2.3.1",
|
|
155
|
-
"blind-peering": "^2.6.
|
|
156
|
-
"compact-encoding": "^3.3.
|
|
155
|
+
"blind-peering": "^2.6.3",
|
|
156
|
+
"compact-encoding": "^3.3.2",
|
|
157
157
|
"corestore": "^7.12.0",
|
|
158
158
|
"framed-stream": "^1.0.1",
|
|
159
|
-
"hrpc": "^4.3.
|
|
159
|
+
"hrpc": "^4.3.1",
|
|
160
160
|
"hyperblobs": "^2.12.1",
|
|
161
|
-
"hypercore": "^11.35.
|
|
161
|
+
"hypercore": "^11.35.2",
|
|
162
162
|
"hypercore-blob-server": "^1.15.0",
|
|
163
163
|
"hypercore-crypto": "^3.7.0",
|
|
164
164
|
"hypercore-id-encoding": "^1.3.0",
|
|
165
|
-
"hypercore-storage": "^3.2.
|
|
166
|
-
"hyperdb": "^6.
|
|
165
|
+
"hypercore-storage": "^3.2.1",
|
|
166
|
+
"hyperdb": "^6.9.0",
|
|
167
167
|
"hyperdispatch": "^1.6.0",
|
|
168
168
|
"hyperschema": "^1.22.0",
|
|
169
169
|
"hyperswarm": "^4.17.0",
|
|
@@ -182,7 +182,7 @@
|
|
|
182
182
|
"bare-fetch": "^3.2.0",
|
|
183
183
|
"bare-process": "^4.5.1",
|
|
184
184
|
"bare-url": "^2.5.2",
|
|
185
|
-
"blind-peer": "^3.13.
|
|
185
|
+
"blind-peer": "^3.13.3",
|
|
186
186
|
"brittle": "^4.1.0",
|
|
187
187
|
"typescript": "^5.9.3",
|
|
188
188
|
"which-runtime": "^1.4.0"
|
package/src/database/dispatch.js
CHANGED
|
@@ -114,7 +114,11 @@ export function makeDispatcher(
|
|
|
114
114
|
if (!isKey(op.master) || !isKey(op.writer) || !isSig(op.sig)) return
|
|
115
115
|
if (!Identity.verify(op.master, addWriterPayload(ctx.dbKey, op.writer, ctx.key), op.sig)) return
|
|
116
116
|
if (!(await isGenesis(ctx.view)) && !can(await getRole(ctx.view, op.master), INVITE)) return
|
|
117
|
-
|
|
117
|
+
// always an indexer, like claim-writer below. The op's optional isIndexer
|
|
118
|
+
// bool decodes to false when absent (nothing sets it), which silently made
|
|
119
|
+
// every device a weight-1 writer — autobee 2.0 gc's caught-up non-indexer
|
|
120
|
+
// sessions, and a gc'd writer misses later appends until a wakeup revives it
|
|
121
|
+
await ctx.host.addWriter(op.writer, { isIndexer: true })
|
|
118
122
|
const ts = op.ts || 0
|
|
119
123
|
await insert(ctx.view, 'devices', `@${ns}/devices`, {
|
|
120
124
|
id: toId(op.writer),
|
|
@@ -230,54 +230,36 @@ export class EpochAutobee extends Autobee {
|
|
|
230
230
|
await primeKeyring(this.keyring, this.local)
|
|
231
231
|
}
|
|
232
232
|
|
|
233
|
-
//
|
|
234
|
-
//
|
|
235
|
-
//
|
|
236
|
-
//
|
|
237
|
-
//
|
|
238
|
-
//
|
|
239
|
-
// instead of crashing the bee.
|
|
233
|
+
// A writer whose next blocks sit at an epoch we haven't learned yet parks:
|
|
234
|
+
// its next() reports "nothing to offer" instead of throwing, so upstream's
|
|
235
|
+
// drain keeps selecting among the other writers — the announcement carrying
|
|
236
|
+
// the missing epoch lives in one of THEIR cores and unlocks the parked
|
|
237
|
+
// writer on a later bump (the scheduled retry pokes the drain). The outer
|
|
238
|
+
// catch backstops an UNKNOWN_EPOCH surfacing from batch processing itself.
|
|
240
239
|
async _bumpPendingWriters() {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
240
|
+
for (const w of this.writers.pending) this._parkOnUnknownEpoch(w)
|
|
241
|
+
try {
|
|
242
|
+
return await super._bumpPendingWriters()
|
|
243
|
+
} catch (err) {
|
|
244
|
+
if (err?.code !== 'UNKNOWN_EPOCH') throw err
|
|
245
|
+
this._scheduleEpochRetry()
|
|
246
|
+
return false
|
|
244
247
|
}
|
|
248
|
+
}
|
|
245
249
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
const w = pending[i]
|
|
252
|
-
|
|
250
|
+
_parkOnUnknownEpoch(w) {
|
|
251
|
+
if (w._epochParking) return
|
|
252
|
+
w._epochParking = true
|
|
253
|
+
const next = w.next.bind(w)
|
|
254
|
+
w.next = async () => {
|
|
253
255
|
try {
|
|
254
|
-
|
|
255
|
-
if (batch === null) continue
|
|
256
|
-
|
|
257
|
-
if (w.isAdded || (w.isRemoved && w.hasReferrals())) {
|
|
258
|
-
await this._processBatch(batch)
|
|
259
|
-
w.notify(batch)
|
|
260
|
-
updated = true
|
|
261
|
-
continue
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
if (this.optimistic && !w.isRemoved && batch[0].optimistic) {
|
|
265
|
-
if (!(await this._optimisticBatch(batch))) {
|
|
266
|
-
w.removePending()
|
|
267
|
-
continue
|
|
268
|
-
}
|
|
269
|
-
w.notify(batch)
|
|
270
|
-
updated = true
|
|
271
|
-
continue
|
|
272
|
-
}
|
|
256
|
+
return await next()
|
|
273
257
|
} catch (err) {
|
|
274
258
|
if (err?.code !== 'UNKNOWN_EPOCH') throw err
|
|
275
259
|
this._scheduleEpochRetry()
|
|
276
|
-
|
|
260
|
+
return null
|
|
277
261
|
}
|
|
278
262
|
}
|
|
279
|
-
|
|
280
|
-
return updated
|
|
281
263
|
}
|
|
282
264
|
|
|
283
265
|
// a parked writer produces no wake-up of its own — poke the bee until the
|
|
@@ -11,13 +11,20 @@ export function blobEpochKey(entropy: Uint8Array): Uint8Array;
|
|
|
11
11
|
* Wire codec for a rotation announcement's envelope list — one sealed box
|
|
12
12
|
* per remaining member, addressed by member id.
|
|
13
13
|
*/
|
|
14
|
-
export const wraps: any
|
|
14
|
+
export const wraps: c.Encoder<any[], {
|
|
15
|
+
id: string;
|
|
16
|
+
box: Uint8Array<ArrayBufferLike>;
|
|
17
|
+
}[]>;
|
|
15
18
|
/**
|
|
16
19
|
* Wire codec for locally persisted / pairing-delivered epoch secrets.
|
|
17
20
|
* `epoch` is the apply-order sequence; `stamp` is the content-addressed
|
|
18
21
|
* uint32 written into block headers.
|
|
19
22
|
*/
|
|
20
|
-
export const epochEntries: any
|
|
23
|
+
export const epochEntries: c.Encoder<any[], {
|
|
24
|
+
epoch: number;
|
|
25
|
+
stamp: number;
|
|
26
|
+
entropy: Uint8Array<ArrayBufferLike>;
|
|
27
|
+
}[]>;
|
|
21
28
|
/**
|
|
22
29
|
* Per-database registry of rotation epochs. Stamp 0 is the base key era
|
|
23
30
|
* (no entry needed — it derives from the upstream GENESIS_ENTROPY path).
|
|
@@ -83,8 +90,9 @@ export class EpochAutobee {
|
|
|
83
90
|
_epochRetryDelay: number;
|
|
84
91
|
_epochRetrySeen: number;
|
|
85
92
|
_bootState(): Promise<void>;
|
|
86
|
-
_bumpPendingWriters(): Promise<
|
|
87
|
-
|
|
93
|
+
_bumpPendingWriters(): Promise<any>;
|
|
94
|
+
_parkOnUnknownEpoch(w: any): void;
|
|
88
95
|
_scheduleEpochRetry(): void;
|
|
89
96
|
_close(): Promise<any>;
|
|
90
97
|
}
|
|
98
|
+
import c from 'compact-encoding';
|