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 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: 0,
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
- async function findLocalSystemLength(core, systemLength) {
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autobee",
3
- "version": "2.9.1",
3
+ "version": "2.9.3",
4
4
  "description": "Bee based autobase",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Holepunch Inc.",