autobee 2.7.2 → 2.7.4

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.
Files changed (3) hide show
  1. package/index.js +23 -3
  2. package/lib/topo.js +22 -7
  3. package/package.json +3 -2
package/index.js CHANGED
@@ -810,6 +810,13 @@ module.exports = class Autobee extends ReadyResource {
810
810
  if (this.fastForwardTo !== null || this.fastForwarding !== null) return
811
811
  if (this._interrupting || this.closing || this.bootFrom) return
812
812
 
813
+ // the migrated legacy nodes have to land on the legacy system before we
814
+ // move off it - requeue the hints so the ff is retried once they applied
815
+ if (this._catchupMigratedNodes !== null) {
816
+ this._wakeup.hint(hints)
817
+ return
818
+ }
819
+
813
820
  try {
814
821
  const heads = await this._readCandidateHeads(hints, FastForward.DEFAULT_TIMEOUT)
815
822
 
@@ -1025,19 +1032,32 @@ module.exports = class Autobee extends ReadyResource {
1025
1032
  return anchor
1026
1033
  }
1027
1034
 
1035
+ // apply in linearizer order so the catchup never undoes. weights are fixed,
1036
+ // legacy nodes carry no witness
1028
1037
  async _bumpMigratedWriters() {
1029
1038
  const opened = new Set()
1030
1039
  let updated = false
1031
1040
 
1032
1041
  for (const batch of this._catchupMigratedNodes) {
1033
- await this._processBatch(batch)
1034
- updated = true
1035
1042
  for (const node of batch) {
1036
1043
  if (node.from) opened.add(node.from)
1037
1044
  }
1038
1045
  }
1039
1046
 
1040
- for (const core of opened) await core.close()
1047
+ try {
1048
+ for (const batch of this._catchupMigratedNodes) {
1049
+ const weight = await resolveWeight(this, batch[0])
1050
+ for (const node of batch) node.weight = weight
1051
+ }
1052
+
1053
+ for (const batch of topo.linearize(this._catchupMigratedNodes)) {
1054
+ await this._processBatch(batch)
1055
+ updated = true
1056
+ }
1057
+ } finally {
1058
+ for (const core of opened) await core.close()
1059
+ }
1060
+
1041
1061
  return updated
1042
1062
  }
1043
1063
 
package/lib/topo.js CHANGED
@@ -9,6 +9,8 @@ const INFO_LEGACY_KEY = b4a.concat([b4a.from([0, 0]), b4a.from('info')])
9
9
 
10
10
  exports.sort = sort
11
11
  exports.replay = replay
12
+ exports.linearize = linearize
13
+ exports.getOplogBatch = getOplogBatch
12
14
 
13
15
  exports.isLinking = isLinking
14
16
  exports.isLinkingAll = isLinkingAll
@@ -92,6 +94,18 @@ async function sort(auto, batch) {
92
94
  }
93
95
  }
94
96
 
97
+ // the order the batches settle in - applying them in it never undoes.
98
+ // batches must arrive after the batches they link
99
+ function linearize(batches) {
100
+ const list = []
101
+
102
+ for (const batch of batches) {
103
+ addSorted(list, { undo: null, batch, index: -1 })
104
+ }
105
+
106
+ return list.map((e) => e.batch)
107
+ }
108
+
95
109
  function addSorted(list, entry) {
96
110
  const node = entry.batch[0]
97
111
  const clock = new Clock()
@@ -215,16 +229,17 @@ async function getOplogBatch(undo, core, length, weight, index, readOpts = null)
215
229
  const head = createNode(core, length, weight, oplog)
216
230
  const legacy = oplog.version <= LEGACY_OPLOG_VERSION
217
231
 
218
- // if this is legacy the start pointer is always 0, fix
219
- if (legacy && !oplog.links.length) {
232
+ // legacy start is always 0, walk back to the previous head (end 0). links
233
+ // do not mark the start, legacy batch nodes link their own predecessor.
234
+ // only the block before the batch can be missing (legacy ff), so a miss is
235
+ // the boundary
236
+ if (legacy) {
220
237
  for (let i = length - 1; i > 0; i--) {
221
- const block = await core.get(i - 1, readOpts)
222
- if (block === null) return null // wait: false in replay helper
238
+ const block = await core.get(i - 1, { wait: false })
239
+ if (block === null) break
223
240
 
224
- const oplog = encoding.decodeOplog(block)
225
- if (oplog.batch.end === 0) break
241
+ if (encoding.decodeOplog(block).batch.end === 0) break
226
242
  head.batch.start++
227
- if (oplog.links.length > 0) break // always start of batch in legacy
228
243
  }
229
244
  }
230
245
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autobee",
3
- "version": "2.7.2",
3
+ "version": "2.7.4",
4
4
  "description": "Bee based autobase",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Holepunch Inc.",
@@ -46,6 +46,7 @@
46
46
  "prettier": "^3.8.1",
47
47
  "prettier-config-holepunch": "^2.0.0",
48
48
  "protomux-wakeup": "^2.9.0",
49
- "replication-simulator": "^3.0.0"
49
+ "replication-simulator": "^3.0.0",
50
+ "uncaughts": "^1.1.3"
50
51
  }
51
52
  }