autobee 2.4.0 → 2.5.1
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 +1 -1
- package/index.js +25 -12
- package/lib/system.js +14 -2
- package/lib/trusted.js +14 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -279,7 +279,7 @@ Pass `{ timeout }` to bound the reads, so a head nobody can serve fails instead
|
|
|
279
279
|
|
|
280
280
|
Peers fast-forward onto the heads of writers they trust, so a trusted writer that has nothing to say still has to stamp its view progress into its own oplog.
|
|
281
281
|
|
|
282
|
-
Acking does that: an empty node is appended whenever the local writer falls `ackThreshold` (default `
|
|
282
|
+
Acking does that: an empty node is appended whenever the local writer falls `ackThreshold` (default `32`) flushes behind the system.
|
|
283
283
|
|
|
284
284
|
It is enabled for exactly the writers `isTrusted` accepts. The local key is judged when the db opens, after a fast-forward, and after the local writer rotates, so a writer that becomes trusted starts acking without being told to. `setAcking` overrides it until the next of those points.
|
|
285
285
|
|
package/index.js
CHANGED
|
@@ -99,9 +99,9 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
99
99
|
this.bootFrom = (fastForward && fastForward.boot) || null
|
|
100
100
|
|
|
101
101
|
// conservative (default on): only fast-forward onto a head someone can serve whole
|
|
102
|
-
this._conservativeFF = !fastForward || fastForward.conservative
|
|
102
|
+
this._conservativeFF = !fastForward || !!fastForward.conservative
|
|
103
103
|
|
|
104
|
-
this.trusted = new TrustedPeers(handlers)
|
|
104
|
+
this.trusted = new TrustedPeers(this, handlers)
|
|
105
105
|
|
|
106
106
|
this.ff = null
|
|
107
107
|
this.fastForwarding = null
|
|
@@ -1098,6 +1098,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1098
1098
|
|
|
1099
1099
|
for await (const p of this._servableRequests(standing)) {
|
|
1100
1100
|
approving.push(fetchApproval.call(this, p.key, p.amount, approvals))
|
|
1101
|
+
if (approving.length === 32) break
|
|
1101
1102
|
}
|
|
1102
1103
|
|
|
1103
1104
|
if (!approving.length) return null
|
|
@@ -1179,6 +1180,10 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1179
1180
|
return true
|
|
1180
1181
|
}
|
|
1181
1182
|
|
|
1183
|
+
// not added and not applicable optimistically: nothing can apply this
|
|
1184
|
+
// batch now, so drop the writer for this drain instead of reselecting it
|
|
1185
|
+
// (a refresh re-adds it once it has been added or has new blocks)
|
|
1186
|
+
w.removePending()
|
|
1182
1187
|
return true
|
|
1183
1188
|
}
|
|
1184
1189
|
|
|
@@ -1190,19 +1195,19 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1190
1195
|
if (t.view) this._workingBee.move(t.view)
|
|
1191
1196
|
|
|
1192
1197
|
for (const b of t.tip) {
|
|
1193
|
-
|
|
1198
|
+
const optimistic = b[0].optimistic
|
|
1199
|
+
let accepted = false
|
|
1194
1200
|
try {
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
} catch {}
|
|
1201
|
+
accepted = await this._applyBatch(b, optimistic)
|
|
1202
|
+
} catch (err) {
|
|
1203
|
+
if (!optimistic) throw err
|
|
1204
|
+
}
|
|
1200
1205
|
|
|
1201
1206
|
// only check if batch was successful
|
|
1202
1207
|
if (b !== batch) continue
|
|
1203
1208
|
|
|
1204
|
-
|
|
1205
|
-
if (!
|
|
1209
|
+
// declined: apply threw, or never called addWriter/ackWriter for this writer
|
|
1210
|
+
if (!accepted) {
|
|
1206
1211
|
this._workingBee.move(rollbackView)
|
|
1207
1212
|
this.system.bee.move(rollbackSystem)
|
|
1208
1213
|
await this.system.reset()
|
|
@@ -1289,10 +1294,16 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1289
1294
|
if (this._hasApply && (await this.system.canApply(batch[0].key, optimistic))) {
|
|
1290
1295
|
this.stats.applies++
|
|
1291
1296
|
this._host.applying = batch
|
|
1292
|
-
|
|
1293
|
-
|
|
1297
|
+
try {
|
|
1298
|
+
await this._workingView.apply(userBatch)
|
|
1299
|
+
} finally {
|
|
1300
|
+
this._host.applying = null
|
|
1301
|
+
}
|
|
1294
1302
|
}
|
|
1295
1303
|
|
|
1304
|
+
// read before flush clears it
|
|
1305
|
+
const accepted = this.system.touched(batch[0].key)
|
|
1306
|
+
|
|
1296
1307
|
const changed = await this.system.flush(batch, this._workingBee)
|
|
1297
1308
|
|
|
1298
1309
|
if (this.system.promotions.changed) this._prefetchApprovals().catch(safetyCatch)
|
|
@@ -1307,6 +1318,8 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1307
1318
|
if (added) await this.writers.add(key)
|
|
1308
1319
|
else await this.writers.remove(key)
|
|
1309
1320
|
}
|
|
1321
|
+
|
|
1322
|
+
return accepted
|
|
1310
1323
|
}
|
|
1311
1324
|
|
|
1312
1325
|
async _storeBoot() {
|
package/lib/system.js
CHANGED
|
@@ -48,6 +48,7 @@ module.exports = class Systembee {
|
|
|
48
48
|
this.updates = new Map()
|
|
49
49
|
this.writers = new Map()
|
|
50
50
|
this.encrypted = opts.encrypted === true
|
|
51
|
+
this.indexers = null
|
|
51
52
|
this.promotions = new Promotions(this.bee)
|
|
52
53
|
}
|
|
53
54
|
|
|
@@ -85,11 +86,14 @@ module.exports = class Systembee {
|
|
|
85
86
|
}
|
|
86
87
|
|
|
87
88
|
async ackWriter(key, { length = 0 } = {}) {
|
|
89
|
+
const info = await this.get(key, { unflushed: true })
|
|
88
90
|
if (length === 0) {
|
|
89
|
-
const info = await this.get(key, { unflushed: false })
|
|
90
91
|
length = info ? info.length : 0
|
|
91
92
|
}
|
|
92
|
-
|
|
93
|
+
// acked but never granted: keep the op (record its length) but record the
|
|
94
|
+
// writer as removed so nothing else from it is applied
|
|
95
|
+
const isRemoved = !info || info.isAdded === false
|
|
96
|
+
this.update(key, length, -1, -1, false, false, isRemoved, -1, null)
|
|
93
97
|
}
|
|
94
98
|
|
|
95
99
|
async removeWriter(key, { length = 0 } = {}) {
|
|
@@ -143,6 +147,9 @@ module.exports = class Systembee {
|
|
|
143
147
|
// ~~~ good enough estimation
|
|
144
148
|
this.flushes = Math.floor(this.bee.core.length / 2)
|
|
145
149
|
this.view = await this._migrate(info, { timeout })
|
|
150
|
+
this.indexers = info ? info.indexers : null
|
|
151
|
+
} else {
|
|
152
|
+
this.indexers = null
|
|
146
153
|
}
|
|
147
154
|
|
|
148
155
|
this.updates.clear()
|
|
@@ -220,6 +227,11 @@ module.exports = class Systembee {
|
|
|
220
227
|
this.update(node.key, node.length, node.weight, -1, false, false, false, node.timestamp, null)
|
|
221
228
|
}
|
|
222
229
|
|
|
230
|
+
// did this apply add or remove (ack) the writer
|
|
231
|
+
touched(key) {
|
|
232
|
+
return this.writers.has(b4a.toString(key, 'hex'))
|
|
233
|
+
}
|
|
234
|
+
|
|
223
235
|
async canApply(key, optimistic) {
|
|
224
236
|
const id = b4a.toString(key, 'hex')
|
|
225
237
|
const w = this.writers.get(id)
|
package/lib/trusted.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
const b4a = require('b4a')
|
|
2
2
|
|
|
3
3
|
class TrustedPeers {
|
|
4
|
-
constructor(hooks) {
|
|
4
|
+
constructor(auto, hooks) {
|
|
5
5
|
this.trusted = new Map()
|
|
6
6
|
this.pending = new Map()
|
|
7
|
+
this.auto = auto
|
|
7
8
|
this.hooks = hooks
|
|
8
9
|
}
|
|
9
10
|
|
|
@@ -11,6 +12,18 @@ class TrustedPeers {
|
|
|
11
12
|
const hex = b4a.toString(key, 'hex')
|
|
12
13
|
if (this.trusted.get(hex)) return true
|
|
13
14
|
|
|
15
|
+
// bootstrap
|
|
16
|
+
if (this.auto.system.isGenesis() && b4a.equals(key, this.auto.key)) {
|
|
17
|
+
return true
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// legacy handling
|
|
21
|
+
if (this.auto.system.indexers) {
|
|
22
|
+
for (const idx of this.auto.system.indexers) {
|
|
23
|
+
if (b4a.equals(key, idx.key)) return true
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
14
27
|
let promise = this.pending.get(hex)
|
|
15
28
|
if (promise) return promise
|
|
16
29
|
|