autobee 2.6.0 → 2.7.0
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/spec/autobee/index.js +23 -6
- package/encoding/spec/autobee/schema.json +10 -0
- package/index.js +11 -4
- package/lib/system.js +33 -1
- package/lib/writers.js +16 -5
- package/package.json +3 -2
|
@@ -494,13 +494,14 @@ const encoding18 = {
|
|
|
494
494
|
c.uint.preencode(state, m.flushes)
|
|
495
495
|
encoding22.preencode(state, m.view)
|
|
496
496
|
encoding18_3.preencode(state, m.heads)
|
|
497
|
-
state.end++ // max flag is
|
|
497
|
+
state.end++ // max flag is 4 so always one byte
|
|
498
498
|
|
|
499
499
|
if (m.indexers) encoding18_4.preencode(state, m.indexers)
|
|
500
500
|
if (m.pending) encoding18_5.preencode(state, m.pending)
|
|
501
|
+
if (m.hash) c.fixed8.preencode(state, m.hash)
|
|
501
502
|
},
|
|
502
503
|
encode(state, m) {
|
|
503
|
-
const flags = (m.indexers ? 1 : 0) | (m.pending ? 2 : 0)
|
|
504
|
+
const flags = (m.indexers ? 1 : 0) | (m.pending ? 2 : 0) | (m.hash ? 4 : 0)
|
|
504
505
|
|
|
505
506
|
c.uint.encode(state, m.timestamp)
|
|
506
507
|
c.uint.encode(state, m.flushes)
|
|
@@ -510,6 +511,7 @@ const encoding18 = {
|
|
|
510
511
|
|
|
511
512
|
if (m.indexers) encoding18_4.encode(state, m.indexers)
|
|
512
513
|
if (m.pending) encoding18_5.encode(state, m.pending)
|
|
514
|
+
if (m.hash) c.fixed8.encode(state, m.hash)
|
|
513
515
|
},
|
|
514
516
|
decode(state) {
|
|
515
517
|
const v = c.uint.decode(state)
|
|
@@ -526,7 +528,8 @@ const encoding18 = {
|
|
|
526
528
|
view: r2,
|
|
527
529
|
heads: r3,
|
|
528
530
|
indexers: (flags & 1) !== 0 ? encoding18_4.decode(state) : null,
|
|
529
|
-
pending: (flags & 2) !== 0 ? encoding18_5.decode(state) : null
|
|
531
|
+
pending: (flags & 2) !== 0 ? encoding18_5.decode(state) : null,
|
|
532
|
+
hash: (flags & 4) !== 0 ? c.fixed8.decode(state) : null
|
|
530
533
|
}
|
|
531
534
|
}
|
|
532
535
|
}
|
|
@@ -1215,9 +1218,19 @@ const encoding37_6 = c.array(encoding36)
|
|
|
1215
1218
|
// @autobee/oplog-message-v4
|
|
1216
1219
|
const encoding37 = {
|
|
1217
1220
|
preencode(state, m) {
|
|
1221
|
+
const flags =
|
|
1222
|
+
(m.batch ? 1 : 0) |
|
|
1223
|
+
(m.views ? 2 : 0) |
|
|
1224
|
+
(m.trusted ? 4 : 0) |
|
|
1225
|
+
(m.witness ? 8 : 0) |
|
|
1226
|
+
(m.approvals ? 16 : 0) |
|
|
1227
|
+
(m.optimistic ? 32 : 0) |
|
|
1228
|
+
(m.value ? 64 : 0) |
|
|
1229
|
+
(m.hash ? 128 : 0)
|
|
1230
|
+
|
|
1218
1231
|
c.uint.preencode(state, m.timestamp)
|
|
1219
1232
|
encoding37_1.preencode(state, m.links)
|
|
1220
|
-
state
|
|
1233
|
+
c.uint.preencode(state, flags)
|
|
1221
1234
|
|
|
1222
1235
|
if (m.batch) encoding24.preencode(state, m.batch)
|
|
1223
1236
|
if (m.views) encoding25.preencode(state, m.views)
|
|
@@ -1225,6 +1238,7 @@ const encoding37 = {
|
|
|
1225
1238
|
if (m.witness) encoding35.preencode(state, m.witness)
|
|
1226
1239
|
if (m.approvals) encoding37_6.preencode(state, m.approvals)
|
|
1227
1240
|
if (m.value) c.buffer.preencode(state, m.value)
|
|
1241
|
+
if (m.hash) c.fixed8.preencode(state, m.hash)
|
|
1228
1242
|
},
|
|
1229
1243
|
encode(state, m) {
|
|
1230
1244
|
const flags =
|
|
@@ -1234,7 +1248,8 @@ const encoding37 = {
|
|
|
1234
1248
|
(m.witness ? 8 : 0) |
|
|
1235
1249
|
(m.approvals ? 16 : 0) |
|
|
1236
1250
|
(m.optimistic ? 32 : 0) |
|
|
1237
|
-
(m.value ? 64 : 0)
|
|
1251
|
+
(m.value ? 64 : 0) |
|
|
1252
|
+
(m.hash ? 128 : 0)
|
|
1238
1253
|
|
|
1239
1254
|
c.uint.encode(state, m.timestamp)
|
|
1240
1255
|
encoding37_1.encode(state, m.links)
|
|
@@ -1246,6 +1261,7 @@ const encoding37 = {
|
|
|
1246
1261
|
if (m.witness) encoding35.encode(state, m.witness)
|
|
1247
1262
|
if (m.approvals) encoding37_6.encode(state, m.approvals)
|
|
1248
1263
|
if (m.value) c.buffer.encode(state, m.value)
|
|
1264
|
+
if (m.hash) c.fixed8.encode(state, m.hash)
|
|
1249
1265
|
},
|
|
1250
1266
|
decode(state) {
|
|
1251
1267
|
const v = c.uint.decode(state)
|
|
@@ -1263,7 +1279,8 @@ const encoding37 = {
|
|
|
1263
1279
|
witness: (flags & 8) !== 0 ? encoding35.decode(state) : null,
|
|
1264
1280
|
approvals: (flags & 16) !== 0 ? encoding37_6.decode(state) : null,
|
|
1265
1281
|
optimistic: (flags & 32) !== 0,
|
|
1266
|
-
value: (flags & 64) !== 0 ? c.buffer.decode(state) : null
|
|
1282
|
+
value: (flags & 64) !== 0 ? c.buffer.decode(state) : null,
|
|
1283
|
+
hash: (flags & 128) !== 0 ? c.fixed8.decode(state) : null
|
|
1267
1284
|
}
|
|
1268
1285
|
}
|
|
1269
1286
|
}
|
|
@@ -434,6 +434,11 @@
|
|
|
434
434
|
"array": true,
|
|
435
435
|
"type": "bool",
|
|
436
436
|
"version": 1
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
"name": "hash",
|
|
440
|
+
"type": "fixed8",
|
|
441
|
+
"version": 1
|
|
437
442
|
}
|
|
438
443
|
]
|
|
439
444
|
},
|
|
@@ -1018,6 +1023,11 @@
|
|
|
1018
1023
|
"name": "value",
|
|
1019
1024
|
"type": "buffer",
|
|
1020
1025
|
"version": 1
|
|
1026
|
+
},
|
|
1027
|
+
{
|
|
1028
|
+
"name": "hash",
|
|
1029
|
+
"type": "fixed8",
|
|
1030
|
+
"version": 1
|
|
1021
1031
|
}
|
|
1022
1032
|
]
|
|
1023
1033
|
}
|
package/index.js
CHANGED
|
@@ -1196,9 +1196,14 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1196
1196
|
node.weight = await resolveWeight(this, node)
|
|
1197
1197
|
for (const n of batch) n.weight = node.weight
|
|
1198
1198
|
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1199
|
+
if (
|
|
1200
|
+
node.hash &&
|
|
1201
|
+
this.system.hash &&
|
|
1202
|
+
b4a.equals(node.hash, this.system.hash) &&
|
|
1203
|
+
topo.isLinkingAll(node, this.system.heads)
|
|
1204
|
+
) {
|
|
1205
|
+
return { undo: null, view: null, tip: [batch] }
|
|
1206
|
+
}
|
|
1202
1207
|
|
|
1203
1208
|
const t = await topo.sort(this, batch)
|
|
1204
1209
|
|
|
@@ -1352,6 +1357,7 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1352
1357
|
await this.local.ready()
|
|
1353
1358
|
|
|
1354
1359
|
const links = this.system.getLinks(this.local.key)
|
|
1360
|
+
const hash = this.system.hash
|
|
1355
1361
|
|
|
1356
1362
|
// never stamp before anything we link
|
|
1357
1363
|
const t = Math.max(this._now(), this.system.timestamp)
|
|
@@ -1379,7 +1385,8 @@ module.exports = class Autobee extends ReadyResource {
|
|
|
1379
1385
|
lnk,
|
|
1380
1386
|
optimistic,
|
|
1381
1387
|
i === 0 ? witness : null,
|
|
1382
|
-
i === 0 ? approvals : null
|
|
1388
|
+
i === 0 ? approvals : null,
|
|
1389
|
+
i === 0 ? hash : null
|
|
1383
1390
|
)
|
|
1384
1391
|
batch.push(node)
|
|
1385
1392
|
}
|
package/lib/system.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const Hyperbee = require('hyperbee2')
|
|
2
2
|
const Promotions = require('./promotions.js')
|
|
3
|
+
const sodium = require('sodium-native')
|
|
4
|
+
const c = require('compact-encoding')
|
|
3
5
|
const b4a = require('b4a')
|
|
4
6
|
|
|
5
7
|
const { getViewMap, getCoreManifest } = require('./migrations.js')
|
|
@@ -13,6 +15,10 @@ const INFO_LEGACY_KEY = b4a.concat([b4a.from([0, 0]), b4a.from('info')])
|
|
|
13
15
|
const EMPTY_HEAD = { length: 0, key: null }
|
|
14
16
|
const EMPTY = b4a.from([])
|
|
15
17
|
|
|
18
|
+
const HASH = c.fixed(sodium.crypto_shorthash_BYTES)
|
|
19
|
+
const HASH_KEY = b4a.from('autobee-orderkey') // crypto_shorthash_KEYBYTES
|
|
20
|
+
const HASH_SEED = b4a.alloc(sodium.crypto_shorthash_BYTES)
|
|
21
|
+
|
|
16
22
|
class SystemSnapshot {
|
|
17
23
|
constructor(bee) {
|
|
18
24
|
this.bee = bee
|
|
@@ -41,6 +47,7 @@ module.exports = class Systembee {
|
|
|
41
47
|
this.bee = new Hyperbee(store, opts)
|
|
42
48
|
this.view = null
|
|
43
49
|
this.heads = []
|
|
50
|
+
this.hash = null
|
|
44
51
|
this.migration = null
|
|
45
52
|
this.version = 0
|
|
46
53
|
this.timestamp = 0
|
|
@@ -142,6 +149,7 @@ module.exports = class Systembee {
|
|
|
142
149
|
this.view = info ? info.view : EMPTY_HEAD
|
|
143
150
|
this.migration = null
|
|
144
151
|
this.heads = info ? info.heads : []
|
|
152
|
+
this.hash = info ? info.hash : null
|
|
145
153
|
this.timestamp = info ? info.timestamp : 0
|
|
146
154
|
this.flushes = info ? info.flushes : 0
|
|
147
155
|
|
|
@@ -224,6 +232,8 @@ module.exports = class Systembee {
|
|
|
224
232
|
this.heads.push({ key: node.key, length: node.length })
|
|
225
233
|
if (node.timestamp > this.timestamp) this.timestamp = node.timestamp // TODO: support smoothing
|
|
226
234
|
|
|
235
|
+
this.hash = advanceHash(this.hash, node)
|
|
236
|
+
|
|
227
237
|
// resolved sort weight, re-stamped on every reapplication - this is what
|
|
228
238
|
// topo reads back out of the changes stream
|
|
229
239
|
this.update(node.key, node.length, node.weight, -1, false, false, false, node.timestamp, null)
|
|
@@ -443,7 +453,8 @@ module.exports = class Systembee {
|
|
|
443
453
|
timestamp: this.timestamp,
|
|
444
454
|
flushes: this.flushes,
|
|
445
455
|
indexers: null, // legacy
|
|
446
|
-
pending: this.promotions.digest
|
|
456
|
+
pending: this.promotions.digest,
|
|
457
|
+
hash: this.hash
|
|
447
458
|
}
|
|
448
459
|
|
|
449
460
|
w.tryPut(INFO_KEY, encoding.encodeSystemInfo(info))
|
|
@@ -488,3 +499,24 @@ module.exports = class Systembee {
|
|
|
488
499
|
return this.promotions.hint(key, opts)
|
|
489
500
|
}
|
|
490
501
|
}
|
|
502
|
+
|
|
503
|
+
function advanceHash(prev, node) {
|
|
504
|
+
const state = { start: 0, end: 0, buffer: null }
|
|
505
|
+
|
|
506
|
+
HASH.preencode(state, prev || HASH_SEED)
|
|
507
|
+
c.fixed32.preencode(state, node.key)
|
|
508
|
+
c.uint.preencode(state, node.length)
|
|
509
|
+
c.uint.preencode(state, node.weight)
|
|
510
|
+
|
|
511
|
+
state.buffer = b4a.allocUnsafe(state.end)
|
|
512
|
+
|
|
513
|
+
HASH.encode(state, prev || HASH_SEED)
|
|
514
|
+
c.fixed32.encode(state, node.key)
|
|
515
|
+
c.uint.encode(state, node.length)
|
|
516
|
+
c.uint.encode(state, node.weight)
|
|
517
|
+
|
|
518
|
+
const hash = b4a.allocUnsafe(sodium.crypto_shorthash_BYTES)
|
|
519
|
+
sodium.crypto_shorthash(hash, state.buffer, HASH_KEY)
|
|
520
|
+
|
|
521
|
+
return hash
|
|
522
|
+
}
|
package/lib/writers.js
CHANGED
|
@@ -86,8 +86,17 @@ class ActiveWriters {
|
|
|
86
86
|
return this.localWriter.getLatest()
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
appendLocal(value, timestamp, batch, links, optimistic, witness, approvals = null) {
|
|
90
|
-
return this.localWriter.append(
|
|
89
|
+
appendLocal(value, timestamp, batch, links, optimistic, witness, approvals = null, hash = null) {
|
|
90
|
+
return this.localWriter.append(
|
|
91
|
+
value,
|
|
92
|
+
timestamp,
|
|
93
|
+
batch,
|
|
94
|
+
links,
|
|
95
|
+
optimistic,
|
|
96
|
+
witness,
|
|
97
|
+
approvals,
|
|
98
|
+
hash
|
|
99
|
+
)
|
|
91
100
|
}
|
|
92
101
|
|
|
93
102
|
async rotateLocalWriter(core) {
|
|
@@ -693,7 +702,7 @@ class Writer {
|
|
|
693
702
|
return this.pending !== null
|
|
694
703
|
}
|
|
695
704
|
|
|
696
|
-
append(value, timestamp, batch, links, optimistic, witness, approvals = null) {
|
|
705
|
+
append(value, timestamp, batch, links, optimistic, witness, approvals = null, hash = null) {
|
|
697
706
|
if (this.pending === null) this.pending = []
|
|
698
707
|
|
|
699
708
|
const oplog = {
|
|
@@ -706,7 +715,8 @@ class Writer {
|
|
|
706
715
|
witness: witness || null,
|
|
707
716
|
approvals,
|
|
708
717
|
optimistic: optimistic && !this.writers.writable,
|
|
709
|
-
value
|
|
718
|
+
value,
|
|
719
|
+
hash
|
|
710
720
|
}
|
|
711
721
|
|
|
712
722
|
const node = createNode(this.core, this.appendLength++, -1, oplog)
|
|
@@ -783,7 +793,8 @@ function createNode(core, length, weight, oplog) {
|
|
|
783
793
|
witness: oplog.witness || null,
|
|
784
794
|
approvals: oplog.approvals || null,
|
|
785
795
|
optimistic: oplog.optimistic,
|
|
786
|
-
value: oplog.value
|
|
796
|
+
value: oplog.value,
|
|
797
|
+
hash: oplog.hash || null
|
|
787
798
|
}
|
|
788
799
|
}
|
|
789
800
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "autobee",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Bee based autobase",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Holepunch Inc.",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"ready-guard": "^1.0.0",
|
|
36
36
|
"ready-resource": "^1.2.0",
|
|
37
37
|
"resolve-reject-promise": "^1.1.0",
|
|
38
|
-
"safety-catch": "^1.0.3"
|
|
38
|
+
"safety-catch": "^1.0.3",
|
|
39
|
+
"sodium-native": "^5.1.0"
|
|
39
40
|
},
|
|
40
41
|
"devDependencies": {
|
|
41
42
|
"brittle": "^4.1.0",
|