Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to db2 #96

Merged
merged 64 commits into from
Oct 31, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
e78fb74
Switch to db2 (broken tests)
Powersource Oct 13, 2023
6327c55
Install box2 and replace some queries
Powersource Oct 13, 2023
c6af752
Fix init publish
Powersource Oct 13, 2023
15894e3
Use publish helper instead of hook
Powersource Oct 13, 2023
4b3324c
Replace link queries
Powersource Oct 14, 2023
bc16b7b
Load feedstate compat
Powersource Oct 14, 2023
ff57d16
Update ssb-crut to latest
Powersource Oct 15, 2023
d6db441
Use box2 publish in crut
Powersource Oct 15, 2023
2bcafd9
Start using box2 functions
Powersource Oct 15, 2023
2c49797
Remove unneeded check in create
Powersource Oct 15, 2023
de53bb5
Fix create tests
Powersource Oct 15, 2023
265e832
Remove logs
Powersource Oct 15, 2023
2d302b9
Fix list and get tests
Powersource Oct 15, 2023
a9cb983
Fix old query in invite test
Powersource Oct 16, 2023
cda1298
Mostly fix tangle tests
Powersource Oct 17, 2023
2fdb89a
Remove tangle cache to fix branching
Powersource Oct 17, 2023
54ee6e8
Fix listAuthors
Powersource Oct 17, 2023
9ab7c68
Use box2 with pobox support
Powersource Oct 18, 2023
0bf5c63
Use box2 fns in exclude listener
Powersource Oct 18, 2023
61f48bd
Fix subtribe test query
Powersource Oct 18, 2023
b203306
Disable some publish tests for now and leave comments
Powersource Oct 18, 2023
aaa0d9a
Fix listeners not emitting newly decrypted
Powersource Oct 18, 2023
9fa098c
Fix invite test getting stuck without rebuild hook
Powersource Oct 18, 2023
c4c4b2c
Skip rebuild-manager tests and fix rebuild test
Powersource Oct 19, 2023
5bc9829
Fix a rebuild test
Powersource Oct 19, 2023
1444043
Fix the rest of the rebuild tests
Powersource Oct 19, 2023
6951c93
Skip unbox tests and format
Powersource Oct 19, 2023
e702f62
Fix lint issues
Powersource Oct 19, 2023
33d73a3
Make flaky rebuild test async
Powersource Oct 19, 2023
68323e9
Remove envelope file
Powersource Oct 20, 2023
6b7a01e
Remove onKeystoreReady
Powersource Oct 20, 2023
dd62bad
Remove some keystore usage
Powersource Oct 20, 2023
55d9754
Remove keystore refs and uninstall keyring
Powersource Oct 20, 2023
e0f8e67
Fix lint
Powersource Oct 20, 2023
45c5779
Update readme and deps
Powersource Oct 20, 2023
0584f80
Remove db1 plugins
Powersource Oct 20, 2023
8a5ed09
Use fast equal in link fns
Powersource Oct 24, 2023
2f07fbe
Remove rebuild manager
Powersource Oct 24, 2023
65eb1c5
Remove indexes check tests
Powersource Oct 24, 2023
9ff3384
Remove test for envelope self dm hack
Powersource Oct 24, 2023
6d97ded
Allow feed ids in first recps slot
Powersource Oct 24, 2023
75cd723
Fix unbox test
Powersource Oct 24, 2023
8b10fc8
Make group tangle query faster
Powersource Oct 24, 2023
109e5c6
Remove commented code
Powersource Oct 24, 2023
787b76f
Uninstall obz
Powersource Oct 24, 2023
3d6a5d9
Uninstall level
Powersource Oct 24, 2023
fd907e8
Uninstall futoin-hkdf and mkdirp
Powersource Oct 24, 2023
e5d5d32
Uninstall charwise
Powersource Oct 24, 2023
63a5f9c
Remove unbox vectors (moved to envelope-spec)
Powersource Oct 25, 2023
191da5a
Remove 10sec timeout on testbot close
Powersource Oct 26, 2023
38d58d0
Correct readme on when encryption happens
Powersource Oct 26, 2023
af5b060
Remove blank line in readme
Powersource Oct 26, 2023
4a03bc0
Move publish function out into own thing
Powersource Oct 26, 2023
bab331b
Document tribes.publish
Powersource Oct 26, 2023
50eb790
Put into subheading
Powersource Oct 26, 2023
10cb328
Merge pull request #104 from ssbc/no-close-timeout
Powersource Oct 26, 2023
0809c99
Use box2 release with pobox
Powersource Oct 30, 2023
fcb1245
Update box2 version in readme
Powersource Oct 30, 2023
68a4045
Rename seek index
Powersource Oct 30, 2023
2d8be0c
Simplify reindexed stream
Powersource Oct 30, 2023
20c7c21
Remove commented code
Powersource Oct 30, 2023
6428831
Update comment in add member fn
Powersource Oct 30, 2023
2f01a5f
Filter pobox listener more
Powersource Oct 31, 2023
dcec468
Change lint parent child index names
Powersource Oct 31, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ ssb.tribes.create({}, (err, info) => {
test: 'kia ora, e te whānau',
recps: [groupId] // <<< you can now put a groupId in the recps
}
ssb.publish(content, (err, msg) => {
ssb.tribes.publish(content, (err, msg) => {
mixmix marked this conversation as resolved.
Show resolved Hide resolved
// tada msg is encrypted to group!

const cookie = '@YXkE3TikkY4GFMX3lzXUllRkNTbj5E+604AkaO1xbz8=.ed25519'
Expand Down
94 changes: 46 additions & 48 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ function init (ssb, config) {

/* secret keys store / helper */
const keystore = {} // HACK we create an Object so we have a reference to merge into
// TODO: ssb-box2 stores the keyring at config.path/keyring. we're gonna have to merge this right?
mixmix marked this conversation as resolved.
Show resolved Hide resolved
KeyRing(join(config.path, 'tribes/keystore'), (err, api) => {
if (err) throw err

Expand All @@ -85,8 +86,8 @@ function init (ssb, config) {

/* register the boxer / unboxer */
const { boxer, unboxer } = Envelope(keystore, state)
ssb.addBoxer({ init: onKeystoreReady, value: boxer })
ssb.addUnboxer({ init: onKeystoreReady, ...unboxer })
//ssb.addBoxer({ init: onKeystoreReady, value: boxer })
//ssb.addUnboxer({ init: onKeystoreReady, ...unboxer })

function onKeystoreReady (done) {
if (state.closed === true) return
Expand Down Expand Up @@ -135,7 +136,7 @@ function init (ssb, config) {
const record = keystore.group.get(groupId)
// if we haven't been in the group since before, register the group
if (record == null) {
return keystore.group.add(groupId, { key: groupKey, root }, (err) => {
return ssb.box2.addGroupInfo(groupId, { key: groupKey, root }, (err) => {
if (err) return cb(err)
processAuthors(groupId, authors, m.value.author, cb)
})
Expand Down Expand Up @@ -219,37 +220,38 @@ function init (ssb, config) {
/* Tangle: auto-add tangles.group info to all private-group messages */
const getGroupTangle = GetGroupTangle(ssb, keystore, 'group')
const getMembersTangle = GetGroupTangle(ssb, keystore, 'members')
ssb.publish.hook(function (publish, args) {
const [content, cb] = args
if (!content.recps) return publish.apply(this, args)
// TODO: make this a ssb.tribes.publish function instead of a hook
mixmix marked this conversation as resolved.
Show resolved Hide resolved
//ssb.publish.hook(function (publish, args) {
// const [content, cb] = args
// if (!content.recps) return publish.apply(this, args)

if (!isGroup(content.recps[0])) return publish.apply(this, args)
// if (!isGroup(content.recps[0])) return publish.apply(this, args)

onKeystoreReady(() => {
if (!keystore.group.has(content.recps[0])) return cb(Error('unknown groupId'))
// onKeystoreReady(() => {
// if (!keystore.group.has(content.recps[0])) return cb(Error('unknown groupId'))

getGroupTangle(content.recps[0], (err, groupTangle) => {
if (err) return cb(Error("Couldn't get group tangle", { cause: err }))
// getGroupTangle(content.recps[0], (err, groupTangle) => {
// if (err) return cb(Error("Couldn't get group tangle", { cause: err }))

set(content, 'tangles.group', groupTangle)
tanglePrune(content) // prune the group tangle down if needed
// set(content, 'tangles.group', groupTangle)
// tanglePrune(content) // prune the group tangle down if needed

// we only want to have to calculate the members tangle if it's gonna be used
if (!isMemberType(content.type)) {
return publish.call(this, content, cb)
}
// // we only want to have to calculate the members tangle if it's gonna be used
// if (!isMemberType(content.type)) {
// return publish.call(this, content, cb)
// }

getMembersTangle(content.recps[0], (err, membersTangle) => {
if (err) return cb(Error("Couldn't get members tangle", { cause: err }))
// getMembersTangle(content.recps[0], (err, membersTangle) => {
// if (err) return cb(Error("Couldn't get members tangle", { cause: err }))

set(content, 'tangles.members', membersTangle)
tanglePrune(content, 'members')
// set(content, 'tangles.members', membersTangle)
// tanglePrune(content, 'members')

publish.call(this, content, cb)
})
})
})
})
// publish.call(this, content, cb)
// })
// })
// })
//})

/* API */
const scuttle = Method(ssb, keystore, state) // ssb db methods
Expand All @@ -260,14 +262,6 @@ function init (ssb, config) {
scuttle.group.init((err, data) => {
if (err) return cb(err)

// NOTE this checks out group/init message was encrypted with the right `previous`.
// There is a potential race condition where the init method calls `ssb.getFeedState` to
// access `previous` but while encrypting the `group/init` message content another
// message is pushed into the queue, making our enveloping invalid.
const initValue = data.groupInitMsg.value
const readKey = unboxer.key(initValue.content, initValue)
if (!readKey) return cb(new Error('tribes.group.init failed, please try again while not publishing other messages'))

// addMember the admin
scuttle.group.addMember(data.groupId, [ssb.id], {}, (err) => {
if (err) return cb(err)
Expand All @@ -286,8 +280,8 @@ function init (ssb, config) {
}

const tribeGet = (id, cb) => {
onKeystoreReady(() => {
const data = keystore.group.get(id)
ssb.box2.getGroupInfo(id, (err, data) => {
if (err) return cb(err)
if (!data) return cb(new Error(`unknown groupId ${id})`))

scuttle.link.findParentGroupLinks(id, (err, parentGroupLinks) => {
Expand All @@ -310,22 +304,26 @@ function init (ssb, config) {
function tribeList (opts, cb) {
if (typeof opts === 'function') return tribeList({}, opts)

onKeystoreReady(() => {
pull(
pull.values(keystore.group.listSync()),
paraMap(tribeGet, 4),
opts.subtribes
? null
: pull.filter(tribe => tribe.parentGroupId === undefined),
pull.map(tribe => tribe.groupId),
pull.collect(cb)
)
})
pull(
ssb.box2.listGroupIds(),
paraMap(tribeGet, 4),
opts.subtribes
? null
: pull.filter(tribe => tribe.parentGroupId === undefined),
pull.map(tribe => tribe.groupId),
pull.collect(cb)
)
}

return {
publish (content, cb) {
Powersource marked this conversation as resolved.
Show resolved Hide resolved
ssb.db.create({
content,
encryptionFormat: 'box2',
}, cb)
},
register (groupId, info, cb) {
keystore.group.add(groupId, info, cb)
ssb.box2.addGroupInfo(groupId, info, cb)
},
create: tribeCreate,
list: tribeList,
Expand Down
7 changes: 6 additions & 1 deletion lib/get-group-tangle.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const { isCloakedMsg: isGroup } = require('ssb-ref')
const pull = require('pull-stream')
const Reduce = require('@tangle/reduce')
const Strategy = require('@tangle/strategy')
const { where, and, type, isDecrypted, live: dbLive, toPullStream } = require('ssb-db2/operators')

// for figuring out what "previous" should be for the group

Expand All @@ -15,7 +16,11 @@ module.exports = function GetGroupTangle (server, keystore, tangle = 'group') {
// update the value in the cache (this will use our new addNodes functionality)

pull(
server.createLogStream({ live: true, old: false, private: true }),
server.db.query(
where(isDecrypted('box2')),
dbLive({ old: false }),
toPullStream()
),
// we need to have this here because rebuilds cause the stream to start again and updateCache isn't idempotent
pull.unique('key'),
pull.drain(updateCache)
Expand Down
3 changes: 2 additions & 1 deletion lib/group-id.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ function fromMsgKey (msg, msgKey) {
}

function fromGroupKey (msg, groupKey) {
const { author, previous, content } = msg.value
const { author, previous } = msg.value
const content = msg.meta.originalContent

const envelope = Buffer.from(content.replace('.box2', ''), 'base64')
const feed_id = bfe.encode(author)
Expand Down
38 changes: 33 additions & 5 deletions listen.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,26 @@
// const flumeView = require('flumeview-reduce')
const pull = require('pull-stream')
const CRUT = require('ssb-crut')
const { where, and, type, isDecrypted, live: dbLive, toPullStream } = require('ssb-db2/operators')
mixmix marked this conversation as resolved.
Show resolved Hide resolved

const { isValid: isAddMember } = require('./spec/group/add-member')
const { isValid: isExcludeMember } = require('./spec/group/exclude-member')

const poBoxSpec = require('./spec/group/po-box')
const mockSSB = { backlinks: true, query: true }
const { isUpdate: isPOBox } = new CRUT(mockSSB, poBoxSpec).spec

module.exports = {
addMember (ssb) {
return pull(
ssb.messagesByType({ type: 'group/add-member', private: true, live: true }),
ssb.db.query(
where(
and(
isDecrypted('box2'),
type('group/add-member'),
)
),
dbLive({ old: true }),
toPullStream()
),
// NOTE this will run through all messages on each startup, which will help guarentee
// all messages have been emitted AND processed
// (same not true if we used a dummy flume-view)
Expand All @@ -25,15 +33,35 @@ module.exports = {
},
excludeMember (ssb) {
return pull(
ssb.messagesByType({ type: 'group/exclude-member', private: true, live: true }),
ssb.db.query(
where(
and(
isDecrypted('box2'),
type('group/exclude-member'),
)
),
dbLive({ old: true }),
toPullStream()
),
pull.filter(m => m.sync !== true),
pull.filter(isExcludeMember),
pull.unique('key')
)
},
poBox (ssb, emit) {
const { isUpdate: isPOBox } = new CRUT(ssb, poBoxSpec).spec

pull(
ssb.messagesByType({ type: 'group/po-box', private: true, live: true }),
ssb.db.query(
where(
and(
isDecrypted('box2'),
type('group/po-box'),
)
),
dbLive({ old: true }),
toPullStream()
),
// NOTE this will run through all messages on each startup, which will help guarentee
// all messages have been emitted AND processed
// (same not true if we used a dummy flume-view)
Expand Down
Loading