Skip to content

Commit bd932c1

Browse files
committed
merge master
2 parents 2a4f9c7 + 45bf6ab commit bd932c1

File tree

4 files changed

+92
-50
lines changed

4 files changed

+92
-50
lines changed

lib/epochs/index.js

+68-23
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,26 @@
33
// SPDX-License-Identifier: LGPL-3.0-only
44

55
const { promisify: p } = require('util')
6-
const { fromMessageSigil } = require('ssb-uri2')
6+
const { fromMessageSigil, toMessageSigil } = require('ssb-uri2')
77
const pull = require('pull-stream')
88
const pullDefer = require('pull-defer')
9+
const pullMany = require('pull-many')
910
const pullFlatMerge = require('pull-flat-merge')
1011
const Strategy = require('@tangle/strategy')
1112
const Reduce = require('@tangle/reduce')
1213
const OverwriteFields = require('@tangle/overwrite-fields')
1314
const clarify = require('clarify-error')
1415
const Butt64 = require('butt64')
1516
const isCanonicalBase64 = require('is-canonical-base64')
16-
const { where, and, type, live, toPullStream } = require('ssb-db2/operators')
17+
const {
18+
where,
19+
and,
20+
type,
21+
live,
22+
key,
23+
isDecrypted,
24+
toPullStream,
25+
} = require('ssb-db2/operators')
1726
const {
1827
validator: {
1928
group: {
@@ -29,9 +38,9 @@ const isSubsetOf = require('set.prototype.issubsetof')
2938
const intersection = require('set.prototype.intersection')
3039

3140
const GetMembers = require('./get-members')
32-
33-
const { groupRecp } = require('../operators')
3441
const hookClose = require('../hook-close')
42+
const { groupRecp } = require('../operators')
43+
3544
const getTangleUpdates = require('../tangles/get-tangle-updates')
3645

3746
const msgPattern = toPattern(new Butt64('ssb:message/[a-zA-Z0-9-]+/', null, 32))
@@ -179,14 +188,16 @@ module.exports = function Epochs(ssb) {
179188
// then skip all the preferrentEpochs until we get up to the current
180189
// This is important for listMembers to not send confusing results
181190
getPreferredEpoch(groupId, (err, preferredEpoch) => {
182-
if (err) return deferredSource.abort(clarify(err, 'failed to get initial preferred epoch'))
183-
191+
// if we're live and this fails we don't really mind, just go straight to live
184192
if (!live) {
185-
deferredSource.resolve(pull.once(preferredEpoch))
193+
if (err) deferredSource.abort(clarify(err, 'failed to get initial preferred epoch'))
194+
else deferredSource.resolve(pull.once(preferredEpoch))
195+
186196
return
187197
}
188198

189-
var sync = false
199+
// if we couldn't get current preferred, we'll just go live
200+
var sync = !!err
190201
const source = pull(
191202
epochsReduce.stream(ssb, groupId, { getters: allGetters, live }),
192203
pull.asyncMap(BuildPreferredEpoch(ssb, groupId)),
@@ -411,24 +422,58 @@ function epochNodeStream(ssb, groupId, opts = {}) {
411422

412423
return deferredSource
413424
}
414-
function getGroupInit(ssb, groupId, cb) {
415-
ssb.box2.getGroupInfo(groupId, (err, info) => {
416-
// prettier-ignore
417-
if (err) return cb(clarify(err, 'Failed to get group info for ' + groupId))
418-
if (!info) return cb(new Error('Unknown group'))
419425

420-
// Fetch the tangle root
421-
ssb.db.get(info.root, (err, rootVal) => {
422-
// prettier-ignore
423-
if (err) return cb(clarify(err, 'Failed to load group root with id ' + info.root))
426+
function getRootVal(ssb, msgId, cb) {
427+
pull(
428+
pullMany([
429+
ssb.db.query(
430+
where(and(isDecrypted('box2'), key(toMessageSigil(msgId)))),
431+
live({ old: true }),
432+
toPullStream()
433+
),
434+
pull(
435+
ssb.db.reindexed(),
436+
pull.filter((msg) => fromMessageSigil(msg.key) === msgId)
437+
),
438+
]),
439+
pull.take(1),
440+
pull.drain(
441+
(msg) => cb(null, msg.value),
442+
(err) => {
443+
if (err) cb(Error('Failed getting root msg async', { cause: err }))
444+
}
445+
)
446+
)
447+
}
424448

425-
if (!isInitRoot(rootVal))
449+
function getGroupInit(ssb, groupId, cb) {
450+
pull(
451+
ssb.box2.getGroupInfoUpdates(groupId),
452+
pull.take(1),
453+
pull.drain(
454+
(info) => {
455+
if (!info) return cb(new Error('Unknown group'))
456+
457+
// Fetch the tangle root
458+
// This is based on a live stream since sometimes the group info comes in very quick, before the root msg has had time to get put into the db
459+
// and sometimes it might take ages (we haven't gotten that feed yet)
460+
getRootVal(ssb, info.root, (err, rootVal) => {
461+
// prettier-ignore
462+
if (err) return cb(clarify(err, 'Failed to load group root with id ' + info.root))
463+
464+
if (!isInitRoot(rootVal))
465+
// prettier-ignore
466+
return cb(clarify(new Error(isInitRoot.string), 'Malformed group/init root message'))
467+
468+
cb(null, { key: info.root, value: rootVal })
469+
})
470+
},
471+
(err) => {
426472
// prettier-ignore
427-
return cb(clarify(new Error(isInitRoot.string), 'Malformed group/init root message'))
428-
429-
cb(null, { key: info.root, value: rootVal })
430-
})
431-
})
473+
if (err) return cb(clarify(err, 'Failed to get group info for ' + groupId))
474+
}
475+
)
476+
)
432477
}
433478

434479
/* HELPERS */

lib/operators.js

+19-22
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
const { allocAndEncode, seekKey2, iterate } = require('bipf')
66
const { equal } = require('jitdb/operators')
77

8-
const B_VALUE = allocAndEncode('value')
98
const B_CONTENT = allocAndEncode('content')
109
const B_TANGLES = allocAndEncode('tangles')
1110
const B_ROOT = allocAndEncode('root')
@@ -21,17 +20,15 @@ module.exports = {
2120
}
2221
const B_TANGLE = B_TANGLE_MAP.get(tangle)
2322

24-
function seekTangleRoot(buffer, start, p) {
25-
if (p < 0) return -1
26-
p = seekKey2(buffer, 0, B_VALUE, 0)
27-
if (p < 0) return -1
28-
p = seekKey2(buffer, p, B_CONTENT, 0)
29-
if (p < 0) return -1
30-
p = seekKey2(buffer, p, B_TANGLES, 0)
31-
if (p < 0) return -1
32-
p = seekKey2(buffer, p, B_TANGLE, 0)
33-
if (p < 0) return -1
34-
return seekKey2(buffer, p, B_ROOT, 0)
23+
function seekTangleRoot(buffer, start, pValue) {
24+
if (pValue < 0) return -1
25+
const pValueContent = seekKey2(buffer, pValue, B_CONTENT, 0)
26+
if (pValueContent < 0) return -1
27+
const pValueContentTangles = seekKey2(buffer, pValueContent, B_TANGLES, 0)
28+
if (pValueContentTangles < 0) return -1
29+
const pValueContentTanglesTangle = seekKey2(buffer, pValueContentTangles, B_TANGLE, 0)
30+
if (pValueContentTanglesTangle < 0) return -1
31+
return seekKey2(buffer, pValueContentTanglesTangle, B_ROOT, 0)
3532
}
3633

3734
return equal(seekTangleRoot, value, {
@@ -47,18 +44,18 @@ module.exports = {
4744
},
4845
}
4946

50-
function seekFirstRecp(buffer, start, p) {
51-
if (p < 0) return -1
52-
p = seekKey2(buffer, p, B_CONTENT, 0)
53-
if (p < 0) return -1
54-
p = seekKey2(buffer, p, B_RECPS, 0)
55-
if (p < 0) return -1
47+
function seekFirstRecp(buffer, start, pValue) {
48+
if (pValue < 0) return -1
49+
const pValueContent = seekKey2(buffer, pValue, B_CONTENT, 0)
50+
if (pValueContent < 0) return -1
51+
const pValueContentRecps = seekKey2(buffer, pValueContent, B_RECPS, 0)
52+
if (pValueContentRecps < 0) return -1
5653

57-
let pValueFirstRecp
58-
const error = iterate(buffer, p, (_, pointer) => {
59-
pValueFirstRecp = pointer
54+
let pValueContentRecps0
55+
const error = iterate(buffer, pValueContentRecps, (_, pointer) => {
56+
pValueContentRecps0 = pointer
6057
return true
6158
})
6259
if (error === -1) return -1
63-
return pValueFirstRecp
60+
return pValueContentRecps0
6461
}

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ssb-tribes2",
3-
"version": "1.3.0",
3+
"version": "1.4.0",
44
"description": "SSB private groups with ssb-db2",
55
"repository": {
66
"type": "git",

test/lib/epochs.test.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ test('lib/epochs (getEpochs, getMembers)', async (t) => {
2626
async function sync(label) {
2727
return run(`(sync ${label})`, replicate(peers), { isTest: false })
2828
}
29-
t.teardown(() => peers.forEach((peer) => peer.close(true)))
29+
t.teardown(() => Promise.all(peers.map((peer) => p(peer.close)(true))))
3030

3131
const [aliceId, bobId, oscarId] = await getRootIds(peers)
3232
await run(
@@ -153,7 +153,7 @@ test('lib/epochs (getMissingMembers)', async (t) => {
153153
{ isTest: false }
154154
)
155155
}
156-
t.teardown(() => peers.forEach((peer) => peer.close(true)))
156+
t.teardown(() => Promise.all(peers.map((peer) => p(peer.close)(true))))
157157

158158
await run(
159159
'start tribes',
@@ -260,7 +260,7 @@ test('lib/epochs (getPreferredEpoch - 4.4. same membership)', async (t) => {
260260
Server({ name: 'bob' }),
261261
Server({ name: 'oscar' }),
262262
]
263-
t.teardown(() => peers.forEach((peer) => peer.close(true)))
263+
t.teardown(() => Promise.all(peers.map((peer) => p(peer.close)(true))))
264264

265265
const [alice, bob, oscar] = peers
266266
const [bobId, oscarId] = await getRootIds([bob, oscar])
@@ -381,7 +381,7 @@ test('lib/epochs (getPreferredEpoch - 4.5. subset membership)', async (t) => {
381381
Server({ name: 'carol' }),
382382
Server({ name: 'oscar' }),
383383
]
384-
t.teardown(() => peers.forEach((peer) => peer.close(true)))
384+
t.teardown(() => Promise.all(peers.map((peer) => p(peer.close)(true))))
385385

386386
const [alice, bob, carol, oscar] = peers
387387
const [bobId, carolId, oscarId] = await getRootIds([bob, carol, oscar])

0 commit comments

Comments
 (0)