autobee 2.9.1 → 2.9.3
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/index.js +17 -1
- package/lib/encoding.js +3 -1
- package/lib/migrations.js +17 -5
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -1172,8 +1172,8 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1172
1172
|
if (!this.writers.writable) return false
|
|
1173
1173
|
|
|
1174
1174
|
if (this.writers.localWriter.pending !== null) return false
|
|
1175
|
-
|
|
1176
1175
|
if ((await this._flushesBehind()) < this._ackThreshold) return false
|
|
1176
|
+
if (await this._allHeadsTrusted()) return false
|
|
1177
1177
|
|
|
1178
1178
|
const links = this.system.getLinks(this.local.key)
|
|
1179
1179
|
const t = Math.max(this._now(), this.system.timestamp)
|
|
@@ -1182,6 +1182,22 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1182
1182
|
return true
|
|
1183
1183
|
}
|
|
1184
1184
|
|
|
1185
|
+
async _allHeadsTrusted() {
|
|
1186
|
+
const heads = this.system.heads.slice()
|
|
1187
|
+
if (!heads.length) return false
|
|
1188
|
+
|
|
1189
|
+
const promises = []
|
|
1190
|
+
for (const head of heads) {
|
|
1191
|
+
promises.push(this.trusted.isTrusted(head.key, this._workingView.view))
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
for (const isTrusted of await Promise.all(promises)) {
|
|
1195
|
+
if (!isTrusted) return false
|
|
1196
|
+
}
|
|
1197
|
+
|
|
1198
|
+
return true
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1185
1201
|
async _flushesBehind() {
|
|
1186
1202
|
if (this._ackFlushes === -1) {
|
|
1187
1203
|
const latest = await this.writers.getLatestLocalOplog()
|
package/lib/encoding.js
CHANGED
|
@@ -13,6 +13,8 @@ const SystemWriter = getEncoding('@autobee/system-writer')
|
|
|
13
13
|
const ManifestData = getEncoding('@autobee/manifest-data')
|
|
14
14
|
const AutobaseBootRecord = getEncoding('@autobase-compat/boot-record')
|
|
15
15
|
|
|
16
|
+
const LEGACY_TIME = 1789460100000
|
|
17
|
+
|
|
16
18
|
exports.OPLOG_VERSION = OPLOG_VERSION
|
|
17
19
|
|
|
18
20
|
exports.Oplog = Oplog
|
|
@@ -155,7 +157,7 @@ function decodeOplog(buf) {
|
|
|
155
157
|
if (m.version <= LEGACY_OPLOG_VERSION) {
|
|
156
158
|
return {
|
|
157
159
|
version: m.version,
|
|
158
|
-
timestamp:
|
|
160
|
+
timestamp: LEGACY_TIME,
|
|
159
161
|
links: m.node.heads,
|
|
160
162
|
batch: { start: 0, end: m.node.batch - 1 },
|
|
161
163
|
views: null,
|
package/lib/migrations.js
CHANGED
|
@@ -77,20 +77,21 @@ async function checkAutobaseMigration(store, local, bootstrap) {
|
|
|
77
77
|
const encryptionKey = await local.getUserData('autobase/encryption')
|
|
78
78
|
await AutobeeEncryption.setSystemEncryption(bootstrap.key, encryptionKey, core)
|
|
79
79
|
|
|
80
|
-
const length = await findLocalSystemLength(core, systemLength)
|
|
81
|
-
const system = { key, length }
|
|
82
|
-
|
|
83
80
|
const session = core.session({ name: 'batch' })
|
|
84
81
|
await session.ready()
|
|
85
82
|
|
|
83
|
+
let length
|
|
86
84
|
let catchup
|
|
87
85
|
|
|
88
86
|
try {
|
|
87
|
+
length = await findLocalSystemLength(core, session, systemLength)
|
|
89
88
|
catchup = await getCatchupHeads(session, length)
|
|
90
89
|
} finally {
|
|
91
90
|
await session.close()
|
|
92
91
|
}
|
|
93
92
|
|
|
93
|
+
const system = { key, length }
|
|
94
|
+
|
|
94
95
|
// nothing reads the info here anymore, but a legacy system that will not
|
|
95
96
|
// decode has to throw for migrateWithFallback pathway
|
|
96
97
|
await readLegacySystemInfo(core, length, { wait: false })
|
|
@@ -201,7 +202,9 @@ function deriveNamespace(name, bootstrap, entropy, encryptionKey) {
|
|
|
201
202
|
// the record's length can run past the signed core into the local batch
|
|
202
203
|
// session, and the signed core can carry verified-but-undownloaded blocks -
|
|
203
204
|
// scan back for the newest block the signed core actually has locally
|
|
204
|
-
|
|
205
|
+
// the newest INFO the signed core holds that the batch session agrees with -
|
|
206
|
+
// past its dependency the batch is speculative and may have diverged
|
|
207
|
+
async function findLocalSystemLength(core, session, systemLength) {
|
|
205
208
|
let length = Math.min(core.length, systemLength)
|
|
206
209
|
|
|
207
210
|
while (length > 0) {
|
|
@@ -211,7 +214,7 @@ async function findLocalSystemLength(core, systemLength) {
|
|
|
211
214
|
if (node) {
|
|
212
215
|
const blk = decodeBlock(node)
|
|
213
216
|
const entry = blk.keys[0]
|
|
214
|
-
if (b4a.equals(entry.key, INFO)) return length
|
|
217
|
+
if (b4a.equals(entry.key, INFO) && (await sameTree(core, session, length))) return length
|
|
215
218
|
}
|
|
216
219
|
|
|
217
220
|
length--
|
|
@@ -220,6 +223,12 @@ async function findLocalSystemLength(core, systemLength) {
|
|
|
220
223
|
assert(false, 'Expected system block to exist locally')
|
|
221
224
|
}
|
|
222
225
|
|
|
226
|
+
async function sameTree(core, session, length) {
|
|
227
|
+
if (length <= session.signedLength) return true
|
|
228
|
+
if (length > session.length) return false
|
|
229
|
+
return b4a.equals(await core.treeHash(length), await session.treeHash(length))
|
|
230
|
+
}
|
|
231
|
+
|
|
223
232
|
function coreLength(core, timeout) {
|
|
224
233
|
if (core.length) return core.length
|
|
225
234
|
|
|
@@ -292,6 +301,9 @@ async function getCatchupHeads(session, from) {
|
|
|
292
301
|
const entry = blk.keys[0]
|
|
293
302
|
|
|
294
303
|
if (b4a.equals(entry.key, INFO)) {
|
|
304
|
+
// a replayed node flushes an INFO without a member block
|
|
305
|
+
if (batch.length === 0) continue
|
|
306
|
+
|
|
295
307
|
const oplog = getOplog(entry, batch)
|
|
296
308
|
const { key, length } = encoding.decodeSystemWriter(oplog.key, oplog.value)
|
|
297
309
|
|