autobee 2.9.6 → 2.10.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/encoding/legacy.js +4 -3
- package/encoding/spec/autobee/index.js +35 -29
- package/encoding/spec/autobee/schema.json +14 -0
- package/index.js +76 -16
- package/lib/boot.js +8 -8
- package/lib/encoding.js +3 -1
- package/lib/migrations.js +10 -6
- package/lib/writers.js +13 -6
- package/package.json +2 -2
package/encoding/legacy.js
CHANGED
|
@@ -215,7 +215,6 @@ const OplogMessageV1 = {
|
|
|
215
215
|
throw new Error('Encoding not supported')
|
|
216
216
|
},
|
|
217
217
|
decode(state) {
|
|
218
|
-
c.uint.decode(state) // version
|
|
219
218
|
const maxSupportedVersion = c.uint.decode(state)
|
|
220
219
|
|
|
221
220
|
const flags = c.uint.decode(state)
|
|
@@ -246,7 +245,6 @@ const OplogMessageV0 = {
|
|
|
246
245
|
throw new Error('Encoding not supported')
|
|
247
246
|
},
|
|
248
247
|
decode(state) {
|
|
249
|
-
c.uint.decode(state) // version
|
|
250
248
|
const flags = c.uint.decode(state)
|
|
251
249
|
|
|
252
250
|
const isCheckpointer = (flags & 1) !== 0
|
|
@@ -276,6 +274,7 @@ const SystemWriterV0 = {
|
|
|
276
274
|
throw new Error('Encoding not supported')
|
|
277
275
|
},
|
|
278
276
|
decode(state) {
|
|
277
|
+
state.start-- // Undo the hack to nest this in a versioned struct w/o a version
|
|
279
278
|
const flags = c.uint.decode(state)
|
|
280
279
|
|
|
281
280
|
return {
|
|
@@ -328,7 +327,9 @@ function oplogLegacyMap(m) {
|
|
|
328
327
|
witness: null,
|
|
329
328
|
approvals: null,
|
|
330
329
|
optimistic: m.optimistic,
|
|
331
|
-
value: m.value
|
|
330
|
+
value: m.value,
|
|
331
|
+
weightHint: 0,
|
|
332
|
+
drift: 0
|
|
332
333
|
}
|
|
333
334
|
}
|
|
334
335
|
|
|
@@ -108,13 +108,12 @@ const encoding4 = {
|
|
|
108
108
|
if (m.recoveries) c.uint.encode(state, m.recoveries)
|
|
109
109
|
},
|
|
110
110
|
decode(state) {
|
|
111
|
-
const v = c.uint.decode(state)
|
|
112
111
|
const r0 = c.fixed32.decode(state)
|
|
113
112
|
const r1 = c.uint.decode(state)
|
|
114
113
|
const flags = c.uint.decode(state)
|
|
115
114
|
|
|
116
115
|
return {
|
|
117
|
-
version:
|
|
116
|
+
version: 0,
|
|
118
117
|
key: r0,
|
|
119
118
|
systemLength: r1,
|
|
120
119
|
indexersUpdated: (flags & 1) !== 0,
|
|
@@ -159,18 +158,18 @@ const encoding5 = {
|
|
|
159
158
|
}
|
|
160
159
|
},
|
|
161
160
|
decode(state) {
|
|
162
|
-
const start = state.start
|
|
163
161
|
const v = c.uint.decode(state)
|
|
164
|
-
state.start = start
|
|
165
162
|
switch (v) {
|
|
166
163
|
case 0: {
|
|
167
164
|
const decoded = encoding3.decode(state)
|
|
165
|
+
decoded.version = v
|
|
168
166
|
return decoded
|
|
169
167
|
}
|
|
170
168
|
case 1:
|
|
171
169
|
case 2:
|
|
172
170
|
case 3: {
|
|
173
171
|
const decoded = encoding4.decode(state)
|
|
172
|
+
decoded.version = v
|
|
174
173
|
return decoded
|
|
175
174
|
}
|
|
176
175
|
default:
|
|
@@ -377,12 +376,11 @@ const encoding14 = {
|
|
|
377
376
|
if (m.trace) encoding14_4.encode(state, m.trace)
|
|
378
377
|
},
|
|
379
378
|
decode(state) {
|
|
380
|
-
const v = c.uint.decode(state)
|
|
381
379
|
const r0 = encoding9.decode(state)
|
|
382
380
|
const flags = c.uint.decode(state)
|
|
383
381
|
|
|
384
382
|
return {
|
|
385
|
-
version:
|
|
383
|
+
version: 0,
|
|
386
384
|
node: r0,
|
|
387
385
|
checkpoint: (flags & 1) !== 0 ? encoding14_1.decode(state) : null,
|
|
388
386
|
digest: (flags & 2) !== 0 ? encoding14_2.decode(state) : null,
|
|
@@ -412,7 +410,6 @@ const encoding15 = {
|
|
|
412
410
|
encoding1.encode(state, m.views)
|
|
413
411
|
},
|
|
414
412
|
decode(state) {
|
|
415
|
-
const v = c.uint.decode(state)
|
|
416
413
|
const r0 = c.uint.decode(state)
|
|
417
414
|
const r1 = encoding15_1.decode(state)
|
|
418
415
|
const r2 = encoding1.decode(state)
|
|
@@ -420,7 +417,7 @@ const encoding15 = {
|
|
|
420
417
|
const r4 = encoding1.decode(state)
|
|
421
418
|
|
|
422
419
|
return {
|
|
423
|
-
version:
|
|
420
|
+
version: 0,
|
|
424
421
|
members: r0,
|
|
425
422
|
pendingIndexers: r1,
|
|
426
423
|
indexers: r2,
|
|
@@ -460,7 +457,6 @@ const encoding16 = {
|
|
|
460
457
|
if (m.entropy) c.fixed32.encode(state, m.entropy)
|
|
461
458
|
},
|
|
462
459
|
decode(state) {
|
|
463
|
-
const v = c.uint.decode(state)
|
|
464
460
|
const r0 = c.uint.decode(state)
|
|
465
461
|
const r1 = encoding16_1.decode(state)
|
|
466
462
|
const r2 = encoding1.decode(state)
|
|
@@ -470,7 +466,7 @@ const encoding16 = {
|
|
|
470
466
|
const flags = c.uint.decode(state)
|
|
471
467
|
|
|
472
468
|
return {
|
|
473
|
-
version:
|
|
469
|
+
version: 0,
|
|
474
470
|
members: r0,
|
|
475
471
|
pendingIndexers: r1,
|
|
476
472
|
indexers: r2,
|
|
@@ -514,7 +510,6 @@ const encoding18 = {
|
|
|
514
510
|
if (m.hash) c.fixed8.encode(state, m.hash)
|
|
515
511
|
},
|
|
516
512
|
decode(state) {
|
|
517
|
-
const v = c.uint.decode(state)
|
|
518
513
|
const r0 = c.uint.decode(state)
|
|
519
514
|
const r1 = c.uint.decode(state)
|
|
520
515
|
const r2 = encoding22.decode(state)
|
|
@@ -522,7 +517,7 @@ const encoding18 = {
|
|
|
522
517
|
const flags = c.uint.decode(state)
|
|
523
518
|
|
|
524
519
|
return {
|
|
525
|
-
version:
|
|
520
|
+
version: 0,
|
|
526
521
|
timestamp: r0,
|
|
527
522
|
flushes: r1,
|
|
528
523
|
view: r2,
|
|
@@ -573,22 +568,23 @@ const encoding19 = {
|
|
|
573
568
|
}
|
|
574
569
|
},
|
|
575
570
|
decode(state) {
|
|
576
|
-
const start = state.start
|
|
577
571
|
const v = c.uint.decode(state)
|
|
578
|
-
state.start = start
|
|
579
572
|
switch (v) {
|
|
580
573
|
case 0:
|
|
581
574
|
case 1: {
|
|
582
575
|
const decoded = encoding15.decode(state)
|
|
576
|
+
decoded.version = v
|
|
583
577
|
const map = external0.infoLegacyMap
|
|
584
578
|
return map(decoded)
|
|
585
579
|
}
|
|
586
580
|
case 2: {
|
|
587
581
|
const decoded = encoding16.decode(state)
|
|
582
|
+
decoded.version = v
|
|
588
583
|
return decoded
|
|
589
584
|
}
|
|
590
585
|
case 3: {
|
|
591
586
|
const decoded = encoding18.decode(state)
|
|
587
|
+
decoded.version = v
|
|
592
588
|
return decoded
|
|
593
589
|
}
|
|
594
590
|
default:
|
|
@@ -625,11 +621,10 @@ const encoding20 = {
|
|
|
625
621
|
if (m.timestamp) c.int.encode(state, m.timestamp)
|
|
626
622
|
},
|
|
627
623
|
decode(state) {
|
|
628
|
-
const v = c.uint.decode(state)
|
|
629
624
|
const flags = c.uint.decode(state)
|
|
630
625
|
|
|
631
626
|
return {
|
|
632
|
-
version:
|
|
627
|
+
version: 0,
|
|
633
628
|
isRemoved: (flags & 1) !== 0,
|
|
634
629
|
isOplog: (flags & 2) !== 0,
|
|
635
630
|
weight: c.uint.decode(state),
|
|
@@ -686,24 +681,25 @@ const encoding21 = {
|
|
|
686
681
|
}
|
|
687
682
|
},
|
|
688
683
|
decode(state) {
|
|
689
|
-
const start = state.start
|
|
690
684
|
const v = c.uint.decode(state)
|
|
691
|
-
state.start = start
|
|
692
685
|
switch (v) {
|
|
693
686
|
case 0:
|
|
694
687
|
case 1:
|
|
695
688
|
case 2:
|
|
696
689
|
case 3: {
|
|
697
690
|
const decoded = encoding17.decode(state)
|
|
691
|
+
decoded.version = v
|
|
698
692
|
const map = external0.memberLegacyMap
|
|
699
693
|
return map(decoded)
|
|
700
694
|
}
|
|
701
695
|
case 4: {
|
|
702
696
|
const decoded = encoding20.decode(state)
|
|
697
|
+
decoded.version = v
|
|
703
698
|
return decoded
|
|
704
699
|
}
|
|
705
700
|
case 5: {
|
|
706
701
|
const decoded = encoding34.decode(state)
|
|
702
|
+
decoded.version = v
|
|
707
703
|
return decoded
|
|
708
704
|
}
|
|
709
705
|
default:
|
|
@@ -953,13 +949,12 @@ const encoding29 = {
|
|
|
953
949
|
if (m.trusted) encoding29_8.encode(state, m.trusted)
|
|
954
950
|
},
|
|
955
951
|
decode(state) {
|
|
956
|
-
const v = c.uint.decode(state)
|
|
957
952
|
const r0 = c.uint.decode(state)
|
|
958
953
|
const r1 = encoding29_1.decode(state)
|
|
959
954
|
const flags = c.uint.decode(state)
|
|
960
955
|
|
|
961
956
|
return {
|
|
962
|
-
version:
|
|
957
|
+
version: 0,
|
|
963
958
|
timestamp: r0,
|
|
964
959
|
links: r1,
|
|
965
960
|
batch: (flags & 1) !== 0 ? encoding24.decode(state) : null,
|
|
@@ -1022,29 +1017,32 @@ const encoding30 = {
|
|
|
1022
1017
|
}
|
|
1023
1018
|
},
|
|
1024
1019
|
decode(state) {
|
|
1025
|
-
const start = state.start
|
|
1026
1020
|
const v = c.uint.decode(state)
|
|
1027
|
-
state.start = start
|
|
1028
1021
|
switch (v) {
|
|
1029
1022
|
case 0: {
|
|
1030
1023
|
const decoded = encoding12.decode(state)
|
|
1024
|
+
decoded.version = v
|
|
1031
1025
|
return decoded
|
|
1032
1026
|
}
|
|
1033
1027
|
case 1: {
|
|
1034
1028
|
const decoded = encoding13.decode(state)
|
|
1029
|
+
decoded.version = v
|
|
1035
1030
|
return decoded
|
|
1036
1031
|
}
|
|
1037
1032
|
case 2: {
|
|
1038
1033
|
const decoded = encoding14.decode(state)
|
|
1034
|
+
decoded.version = v
|
|
1039
1035
|
return decoded
|
|
1040
1036
|
}
|
|
1041
1037
|
case 3: {
|
|
1042
1038
|
const decoded = encoding29.decode(state)
|
|
1039
|
+
decoded.version = v
|
|
1043
1040
|
const map = external0.oplogLegacyMap
|
|
1044
1041
|
return map(decoded)
|
|
1045
1042
|
}
|
|
1046
1043
|
case 4: {
|
|
1047
1044
|
const decoded = encoding37.decode(state)
|
|
1045
|
+
decoded.version = v
|
|
1048
1046
|
return decoded
|
|
1049
1047
|
}
|
|
1050
1048
|
default:
|
|
@@ -1154,11 +1152,10 @@ const encoding34 = {
|
|
|
1154
1152
|
c.uint.encode(state, m.timestamp)
|
|
1155
1153
|
},
|
|
1156
1154
|
decode(state) {
|
|
1157
|
-
const v = c.uint.decode(state)
|
|
1158
1155
|
const flags = c.uint.decode(state)
|
|
1159
1156
|
|
|
1160
1157
|
return {
|
|
1161
|
-
version:
|
|
1158
|
+
version: 0,
|
|
1162
1159
|
isRemoved: (flags & 1) !== 0,
|
|
1163
1160
|
isOplog: (flags & 2) !== 0,
|
|
1164
1161
|
isGenesis: (flags & 4) !== 0,
|
|
@@ -1226,7 +1223,9 @@ const encoding37 = {
|
|
|
1226
1223
|
(m.approvals ? 16 : 0) |
|
|
1227
1224
|
(m.optimistic ? 32 : 0) |
|
|
1228
1225
|
(m.value ? 64 : 0) |
|
|
1229
|
-
(m.hash ? 128 : 0)
|
|
1226
|
+
(m.hash ? 128 : 0) |
|
|
1227
|
+
(m.weightHint ? 256 : 0) |
|
|
1228
|
+
(m.drift ? 512 : 0)
|
|
1230
1229
|
|
|
1231
1230
|
c.uint.preencode(state, m.timestamp)
|
|
1232
1231
|
encoding37_1.preencode(state, m.links)
|
|
@@ -1239,6 +1238,8 @@ const encoding37 = {
|
|
|
1239
1238
|
if (m.approvals) encoding37_6.preencode(state, m.approvals)
|
|
1240
1239
|
if (m.value) c.buffer.preencode(state, m.value)
|
|
1241
1240
|
if (m.hash) c.fixed8.preencode(state, m.hash)
|
|
1241
|
+
if (m.weightHint) c.uint.preencode(state, m.weightHint)
|
|
1242
|
+
if (m.drift) c.uint.preencode(state, m.drift)
|
|
1242
1243
|
},
|
|
1243
1244
|
encode(state, m) {
|
|
1244
1245
|
const flags =
|
|
@@ -1249,7 +1250,9 @@ const encoding37 = {
|
|
|
1249
1250
|
(m.approvals ? 16 : 0) |
|
|
1250
1251
|
(m.optimistic ? 32 : 0) |
|
|
1251
1252
|
(m.value ? 64 : 0) |
|
|
1252
|
-
(m.hash ? 128 : 0)
|
|
1253
|
+
(m.hash ? 128 : 0) |
|
|
1254
|
+
(m.weightHint ? 256 : 0) |
|
|
1255
|
+
(m.drift ? 512 : 0)
|
|
1253
1256
|
|
|
1254
1257
|
c.uint.encode(state, m.timestamp)
|
|
1255
1258
|
encoding37_1.encode(state, m.links)
|
|
@@ -1262,15 +1265,16 @@ const encoding37 = {
|
|
|
1262
1265
|
if (m.approvals) encoding37_6.encode(state, m.approvals)
|
|
1263
1266
|
if (m.value) c.buffer.encode(state, m.value)
|
|
1264
1267
|
if (m.hash) c.fixed8.encode(state, m.hash)
|
|
1268
|
+
if (m.weightHint) c.uint.encode(state, m.weightHint)
|
|
1269
|
+
if (m.drift) c.uint.encode(state, m.drift)
|
|
1265
1270
|
},
|
|
1266
1271
|
decode(state) {
|
|
1267
|
-
const v = c.uint.decode(state)
|
|
1268
1272
|
const r0 = c.uint.decode(state)
|
|
1269
1273
|
const r1 = encoding37_1.decode(state)
|
|
1270
1274
|
const flags = c.uint.decode(state)
|
|
1271
1275
|
|
|
1272
1276
|
return {
|
|
1273
|
-
version:
|
|
1277
|
+
version: 0,
|
|
1274
1278
|
timestamp: r0,
|
|
1275
1279
|
links: r1,
|
|
1276
1280
|
batch: (flags & 1) !== 0 ? encoding24.decode(state) : null,
|
|
@@ -1280,7 +1284,9 @@ const encoding37 = {
|
|
|
1280
1284
|
approvals: (flags & 16) !== 0 ? encoding37_6.decode(state) : null,
|
|
1281
1285
|
optimistic: (flags & 32) !== 0,
|
|
1282
1286
|
value: (flags & 64) !== 0 ? c.buffer.decode(state) : null,
|
|
1283
|
-
hash: (flags & 128) !== 0 ? c.fixed8.decode(state) : null
|
|
1287
|
+
hash: (flags & 128) !== 0 ? c.fixed8.decode(state) : null,
|
|
1288
|
+
weightHint: (flags & 256) !== 0 ? c.uint.decode(state) : 0,
|
|
1289
|
+
drift: (flags & 512) !== 0 ? c.uint.decode(state) : 0
|
|
1284
1290
|
}
|
|
1285
1291
|
}
|
|
1286
1292
|
}
|
|
@@ -93,6 +93,7 @@
|
|
|
93
93
|
{
|
|
94
94
|
"name": "boot-record",
|
|
95
95
|
"namespace": "autobase-compat",
|
|
96
|
+
"framed": false,
|
|
96
97
|
"versions": [
|
|
97
98
|
{
|
|
98
99
|
"type": "@autobase-compat/boot-record-v0",
|
|
@@ -445,6 +446,7 @@
|
|
|
445
446
|
{
|
|
446
447
|
"name": "system-info",
|
|
447
448
|
"namespace": "autobee",
|
|
449
|
+
"framed": false,
|
|
448
450
|
"versions": [
|
|
449
451
|
{
|
|
450
452
|
"type": "@autobase-compat/info-v1",
|
|
@@ -528,6 +530,7 @@
|
|
|
528
530
|
{
|
|
529
531
|
"name": "system-writer",
|
|
530
532
|
"namespace": "autobee",
|
|
533
|
+
"framed": false,
|
|
531
534
|
"versions": [
|
|
532
535
|
{
|
|
533
536
|
"type": "@autobase-compat/member",
|
|
@@ -778,6 +781,7 @@
|
|
|
778
781
|
{
|
|
779
782
|
"name": "oplog",
|
|
780
783
|
"namespace": "autobee",
|
|
784
|
+
"framed": false,
|
|
781
785
|
"versions": [
|
|
782
786
|
{
|
|
783
787
|
"type": "@autobase-compat/oplog-message-v0",
|
|
@@ -1028,6 +1032,16 @@
|
|
|
1028
1032
|
"name": "hash",
|
|
1029
1033
|
"type": "fixed8",
|
|
1030
1034
|
"version": 1
|
|
1035
|
+
},
|
|
1036
|
+
{
|
|
1037
|
+
"name": "weightHint",
|
|
1038
|
+
"type": "uint",
|
|
1039
|
+
"version": 1
|
|
1040
|
+
},
|
|
1041
|
+
{
|
|
1042
|
+
"name": "drift",
|
|
1043
|
+
"type": "uint",
|
|
1044
|
+
"version": 1
|
|
1031
1045
|
}
|
|
1032
1046
|
]
|
|
1033
1047
|
}
|
package/index.js
CHANGED
|
@@ -114,6 +114,8 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
114
114
|
this.ff = null
|
|
115
115
|
this.fastForwarding = null
|
|
116
116
|
this.fastForwardTo = null
|
|
117
|
+
this._ffCandidates = new Map()
|
|
118
|
+
this._ffSearching = null
|
|
117
119
|
|
|
118
120
|
this._workingBee = bee
|
|
119
121
|
this._workingView = new ApplyView(this._workingBee, this)
|
|
@@ -127,7 +129,6 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
127
129
|
this._localViewStart = 0
|
|
128
130
|
this._localViewLength = 0
|
|
129
131
|
|
|
130
|
-
this._appending = []
|
|
131
132
|
this._draining = null
|
|
132
133
|
this._updating = null
|
|
133
134
|
|
|
@@ -179,6 +180,10 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
179
180
|
return this.writers ? this.writers.localWriter.isIndexer : false
|
|
180
181
|
}
|
|
181
182
|
|
|
183
|
+
get appending() {
|
|
184
|
+
return this.writers ? this.writers.localWriter.appending : false
|
|
185
|
+
}
|
|
186
|
+
|
|
182
187
|
get writable() {
|
|
183
188
|
return this.writers ? this.writers.writable : false
|
|
184
189
|
}
|
|
@@ -425,6 +430,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
425
430
|
// rugpull the rest
|
|
426
431
|
await this.store.close()
|
|
427
432
|
|
|
433
|
+
if (this._ffSearching) await this._ffSearching
|
|
428
434
|
if (this._updating) await this._updating
|
|
429
435
|
if (this._draining) await this._draining
|
|
430
436
|
|
|
@@ -816,8 +822,22 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
816
822
|
const hints = await this._applyWakeupHints()
|
|
817
823
|
if (!hints.length) return
|
|
818
824
|
|
|
825
|
+
this._queueFastForward(hints)
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
_queueFastForward(hints) {
|
|
819
829
|
if (!this._ffEnabled) return
|
|
820
830
|
|
|
831
|
+
for (const { key, length } of hints) {
|
|
832
|
+
if (length === 0) continue
|
|
833
|
+
|
|
834
|
+
const hex = b4a.toString(key, 'hex')
|
|
835
|
+
const previous = this._ffCandidates.get(hex)
|
|
836
|
+
if (previous === undefined || previous < length) this._ffCandidates.set(hex, length)
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
if (!this._ffCandidates.size || this._ffSearching !== null) return
|
|
840
|
+
|
|
821
841
|
// a scheduled fast-forward is applied by the drain before we look again
|
|
822
842
|
if (this.fastForwardTo !== null || this.fastForwarding !== null) return
|
|
823
843
|
if (this._interrupting || this.closing || this.bootFrom) return
|
|
@@ -829,14 +849,34 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
829
849
|
return
|
|
830
850
|
}
|
|
831
851
|
|
|
852
|
+
this._ffSearching = this._searchFastForward().finally(() => {
|
|
853
|
+
this._ffSearching = null
|
|
854
|
+
})
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
async _searchFastForward() {
|
|
832
858
|
try {
|
|
833
|
-
|
|
859
|
+
while (this._ffCandidates.size) {
|
|
860
|
+
if (this.fastForwardTo !== null || this.fastForwarding !== null) return
|
|
861
|
+
if (this._interrupting || this.closing || this.bootFrom) return
|
|
834
862
|
|
|
835
|
-
|
|
836
|
-
timeout: FastForward.DEFAULT_TIMEOUT
|
|
837
|
-
})
|
|
863
|
+
const hints = flushCandidates(this._ffCandidates)
|
|
838
864
|
|
|
839
|
-
|
|
865
|
+
const heads = await this._readCandidateHeads(hints, FastForward.DEFAULT_TIMEOUT)
|
|
866
|
+
|
|
867
|
+
const ff = await FastForward.fromHeads(this, heads, {
|
|
868
|
+
timeout: FastForward.DEFAULT_TIMEOUT
|
|
869
|
+
})
|
|
870
|
+
|
|
871
|
+
if (ff === null) continue
|
|
872
|
+
|
|
873
|
+
if (this._interrupting || this.closing) {
|
|
874
|
+
await ff.close()
|
|
875
|
+
return
|
|
876
|
+
}
|
|
877
|
+
|
|
878
|
+
if (await this._runFastForward(ff)) return
|
|
879
|
+
}
|
|
840
880
|
} catch (err) {
|
|
841
881
|
safetyCatch(err)
|
|
842
882
|
}
|
|
@@ -1176,9 +1216,10 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1176
1216
|
if (await this._allHeadsTrusted()) return false
|
|
1177
1217
|
|
|
1178
1218
|
const links = this.system.getLinks(this.local.key)
|
|
1179
|
-
const
|
|
1219
|
+
const now = this._now()
|
|
1220
|
+
const t = Math.max(now, this.system.timestamp)
|
|
1180
1221
|
|
|
1181
|
-
this.writers.appendLocal(null, t, { start: 0, end: 0 }, links, false, null)
|
|
1222
|
+
this.writers.appendLocal(null, t, { start: 0, end: 0 }, links, false, null, null, null, t - now)
|
|
1182
1223
|
return true
|
|
1183
1224
|
}
|
|
1184
1225
|
|
|
@@ -1404,8 +1445,10 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1404
1445
|
const links = this.system.getLinks(this.local.key)
|
|
1405
1446
|
const hash = this.system.hash
|
|
1406
1447
|
|
|
1407
|
-
// never stamp before anything we link
|
|
1408
|
-
const
|
|
1448
|
+
// never stamp before anything we link, but record how far our clock lagged
|
|
1449
|
+
const now = this._now()
|
|
1450
|
+
const t = Math.max(now, this.system.timestamp)
|
|
1451
|
+
const drift = t - now
|
|
1409
1452
|
const batch = []
|
|
1410
1453
|
|
|
1411
1454
|
const rec = await this.system.get(this.local.key)
|
|
@@ -1431,7 +1474,8 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1431
1474
|
optimistic,
|
|
1432
1475
|
i === 0 ? witness : null,
|
|
1433
1476
|
i === 0 ? approvals : null,
|
|
1434
|
-
i === 0 ? hash : null
|
|
1477
|
+
i === 0 ? hash : null,
|
|
1478
|
+
drift
|
|
1435
1479
|
)
|
|
1436
1480
|
batch.push(node)
|
|
1437
1481
|
}
|
|
@@ -1475,7 +1519,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1475
1519
|
const ff = await FastForward.fromHead(this, head, null, { force: true, timeout })
|
|
1476
1520
|
if (ff === null) return null
|
|
1477
1521
|
|
|
1478
|
-
if (!(await this._runFastForward(ff))) return null
|
|
1522
|
+
if (!(await this._runFastForward(ff, { force: true }))) return null
|
|
1479
1523
|
|
|
1480
1524
|
return this.ff.promise
|
|
1481
1525
|
}
|
|
@@ -1484,7 +1528,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1484
1528
|
async _bootFromSystem(system) {
|
|
1485
1529
|
try {
|
|
1486
1530
|
const ff = new FastForward(this, system, { timeout: FastForward.DEFAULT_TIMEOUT })
|
|
1487
|
-
return await this._runFastForward(ff)
|
|
1531
|
+
return await this._runFastForward(ff, { force: true })
|
|
1488
1532
|
} catch (err) {
|
|
1489
1533
|
safetyCatch(err)
|
|
1490
1534
|
return false
|
|
@@ -1500,14 +1544,14 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1500
1544
|
|
|
1501
1545
|
const ff = await FastForward.fromHead(this, oplog, null, { force: true, timeout })
|
|
1502
1546
|
|
|
1503
|
-
return ff !== null && (await this._runFastForward(ff))
|
|
1547
|
+
return ff !== null && (await this._runFastForward(ff, { force: true }))
|
|
1504
1548
|
} catch (err) {
|
|
1505
1549
|
safetyCatch(err)
|
|
1506
1550
|
return false
|
|
1507
1551
|
}
|
|
1508
1552
|
}
|
|
1509
1553
|
|
|
1510
|
-
async _runFastForward(ff) {
|
|
1554
|
+
async _runFastForward(ff, { force = false } = {}) {
|
|
1511
1555
|
if (this.fastForwardTo !== null || this.fastForwarding !== null) {
|
|
1512
1556
|
await ff.close()
|
|
1513
1557
|
return false
|
|
@@ -1516,12 +1560,16 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1516
1560
|
this.fastForwarding = ff
|
|
1517
1561
|
|
|
1518
1562
|
const result = await ff.run()
|
|
1563
|
+
const flushes = ff.system.flushes
|
|
1519
1564
|
await ff.close()
|
|
1520
1565
|
|
|
1521
1566
|
if (this.fastForwarding === ff) this.fastForwarding = null
|
|
1522
1567
|
|
|
1523
1568
|
if (!result) return false
|
|
1524
1569
|
|
|
1570
|
+
// apply ran while we searched, only drop it if it no longer moves us forward
|
|
1571
|
+
if (!force && flushes <= this.system.flushes) return false
|
|
1572
|
+
|
|
1525
1573
|
this.fastForwardTo = result
|
|
1526
1574
|
this.ff = rrp()
|
|
1527
1575
|
|
|
@@ -1561,7 +1609,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1561
1609
|
this.fastForwardTo = null
|
|
1562
1610
|
|
|
1563
1611
|
// process any wakeup while fast-forward itself was in flight
|
|
1564
|
-
await this._applyWakeupHints()
|
|
1612
|
+
this._queueFastForward(await this._applyWakeupHints())
|
|
1565
1613
|
await this.writers.refresh()
|
|
1566
1614
|
|
|
1567
1615
|
// we moved, so ask our peers to tell us their heads again
|
|
@@ -1597,6 +1645,18 @@ function getBootOption(boot) {
|
|
|
1597
1645
|
return boot
|
|
1598
1646
|
}
|
|
1599
1647
|
|
|
1648
|
+
function flushCandidates(candidates) {
|
|
1649
|
+
const hints = []
|
|
1650
|
+
|
|
1651
|
+
for (const [hex, length] of candidates) {
|
|
1652
|
+
hints.push({ key: b4a.from(hex, 'hex'), length })
|
|
1653
|
+
}
|
|
1654
|
+
|
|
1655
|
+
candidates.clear()
|
|
1656
|
+
|
|
1657
|
+
return hints
|
|
1658
|
+
}
|
|
1659
|
+
|
|
1600
1660
|
function noop() {}
|
|
1601
1661
|
|
|
1602
1662
|
function createAnchorCore(store, prologue, manifestData) {
|
package/lib/boot.js
CHANGED
|
@@ -93,16 +93,16 @@ module.exports = async function boot(
|
|
|
93
93
|
await result.bootstrap.setUserData('referrer', result.key)
|
|
94
94
|
await result.bootstrap.setUserData('autobee/local', result.local.key)
|
|
95
95
|
await result.local.setUserData('referrer', result.key)
|
|
96
|
+
}
|
|
96
97
|
|
|
97
|
-
|
|
98
|
+
result.migration = await migrateWithFallback(corestore, result.local, result.bootstrap)
|
|
98
99
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
100
|
+
if (result.migration) {
|
|
101
|
+
await result.local.setUserData(
|
|
102
|
+
'autobee/head',
|
|
103
|
+
encoding.encodeBootRecord(result.migration.system)
|
|
104
|
+
)
|
|
105
|
+
await result.local.setUserData('autobee/encryption', result.migration.encryptionKey)
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
const [systemHead, encryptionKeyBuffer, prevDrainBuffer] = await Promise.all([
|
package/lib/encoding.js
CHANGED
package/lib/migrations.js
CHANGED
|
@@ -173,14 +173,18 @@ function decodeLegacySystemInfo(buffer) {
|
|
|
173
173
|
const state = { start: 0, end: buffer.length, buffer }
|
|
174
174
|
const version = c.uint.decode(state)
|
|
175
175
|
|
|
176
|
-
state.start--
|
|
177
|
-
|
|
178
176
|
switch (version) {
|
|
179
177
|
case 0:
|
|
180
|
-
case 1:
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
return
|
|
178
|
+
case 1: {
|
|
179
|
+
const decoded = SystemInfoV1.decode(state)
|
|
180
|
+
decoded.version = version
|
|
181
|
+
return decoded
|
|
182
|
+
}
|
|
183
|
+
case 2: {
|
|
184
|
+
const decoded = SystemInfoV2.decode(state)
|
|
185
|
+
decoded.version = version
|
|
186
|
+
return decoded
|
|
187
|
+
}
|
|
184
188
|
default:
|
|
185
189
|
bail('Expected legacy system info')
|
|
186
190
|
}
|
package/lib/writers.js
CHANGED
|
@@ -92,7 +92,7 @@ class ActiveWriters {
|
|
|
92
92
|
return this.localWriter.getLatest()
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
appendLocal(value, timestamp, batch, links, optimistic, witness, approvals
|
|
95
|
+
appendLocal(value, timestamp, batch, links, optimistic, witness, approvals, hash, drift) {
|
|
96
96
|
return this.localWriter.append(
|
|
97
97
|
value,
|
|
98
98
|
timestamp,
|
|
@@ -101,7 +101,8 @@ class ActiveWriters {
|
|
|
101
101
|
optimistic,
|
|
102
102
|
witness,
|
|
103
103
|
approvals,
|
|
104
|
-
hash
|
|
104
|
+
hash,
|
|
105
|
+
drift
|
|
105
106
|
)
|
|
106
107
|
}
|
|
107
108
|
|
|
@@ -725,7 +726,7 @@ class Writer {
|
|
|
725
726
|
return this.pending !== null
|
|
726
727
|
}
|
|
727
728
|
|
|
728
|
-
append(value, timestamp, batch, links, optimistic, witness, approvals
|
|
729
|
+
append(value, timestamp, batch, links, optimistic, witness, approvals, hash, drift) {
|
|
729
730
|
if (this.pending === null) this.pending = []
|
|
730
731
|
|
|
731
732
|
const oplog = {
|
|
@@ -739,7 +740,9 @@ class Writer {
|
|
|
739
740
|
approvals,
|
|
740
741
|
optimistic: optimistic && !this.writers.writable,
|
|
741
742
|
value,
|
|
742
|
-
hash
|
|
743
|
+
hash,
|
|
744
|
+
weightHint: 0,
|
|
745
|
+
drift
|
|
743
746
|
}
|
|
744
747
|
|
|
745
748
|
const node = createNode(this.core, this.appendLength++, -1, oplog)
|
|
@@ -773,7 +776,9 @@ class Writer {
|
|
|
773
776
|
|
|
774
777
|
const buffers = []
|
|
775
778
|
for (let i = 0; i < this.processed; i++) {
|
|
776
|
-
|
|
779
|
+
const node = this.pending[i]
|
|
780
|
+
node.weightHint = node.weight > 0 ? node.weight : 0
|
|
781
|
+
buffers.push(encoding.encodeOplog(node))
|
|
777
782
|
}
|
|
778
783
|
|
|
779
784
|
try {
|
|
@@ -817,7 +822,9 @@ function createNode(core, length, weight, oplog) {
|
|
|
817
822
|
approvals: oplog.approvals || null,
|
|
818
823
|
optimistic: oplog.optimistic,
|
|
819
824
|
value: oplog.value,
|
|
820
|
-
hash: oplog.hash || null
|
|
825
|
+
hash: oplog.hash || null,
|
|
826
|
+
weightHint: oplog.weightHint || 0,
|
|
827
|
+
drift: oplog.drift || 0
|
|
821
828
|
}
|
|
822
829
|
}
|
|
823
830
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autobee",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.10.1",
|
|
4
4
|
"description": "Bee based autobase",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Holepunch Inc.",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"hyperbee2": "^2.16.0",
|
|
31
31
|
"hypercore": "^11.33.2",
|
|
32
32
|
"hypercore-id-encoding": "^1.3.0",
|
|
33
|
-
"hyperschema": "^1.
|
|
33
|
+
"hyperschema": "^1.26.2",
|
|
34
34
|
"read-write-mutexify": "^2.1.0",
|
|
35
35
|
"ready-guard": "^1.0.0",
|
|
36
36
|
"ready-resource": "^1.2.0",
|