mirror of https://codeberg.org/pzp/pzp-sync.git
update to msg-v3 format
This commit is contained in:
parent
17b720cb60
commit
07f83677d4
|
@ -1,5 +1,5 @@
|
||||||
const { BloomFilter } = require('bloom-filters')
|
const { BloomFilter } = require('bloom-filters')
|
||||||
const MsgV2 = require('ppppp-db/msg-v2')
|
const MsgV3 = require('ppppp-db/msg-v3')
|
||||||
const p = require('util').promisify
|
const p = require('util').promisify
|
||||||
const { isEmptyRange, estimateMsgCount } = require('./range')
|
const { isEmptyRange, estimateMsgCount } = require('./range')
|
||||||
const { parseGoal } = require('./goal')
|
const { parseGoal } = require('./goal')
|
||||||
|
@ -105,7 +105,7 @@ class Algorithm {
|
||||||
const filter = BloomFilter.create(2 * filterSize, 0.00001)
|
const filter = BloomFilter.create(2 * filterSize, 0.00001)
|
||||||
if (!isEmptyRange(range)) {
|
if (!isEmptyRange(range)) {
|
||||||
for (const msg of this.yieldMsgsIn(rootMsgHash, range)) {
|
for (const msg of this.yieldMsgsIn(rootMsgHash, range)) {
|
||||||
filter.add('' + round + MsgV2.getMsgHash(msg))
|
filter.add('' + round + MsgV3.getMsgHash(msg))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const msgId of extraIds) {
|
for (const msgId of extraIds) {
|
||||||
|
@ -119,7 +119,7 @@ class Algorithm {
|
||||||
const remoteFilter = BloomFilter.fromJSON(remoteBloomJSON)
|
const remoteFilter = BloomFilter.fromJSON(remoteBloomJSON)
|
||||||
const missing = []
|
const missing = []
|
||||||
for (const msg of this.yieldMsgsIn(rootMsgHash, range)) {
|
for (const msg of this.yieldMsgsIn(rootMsgHash, range)) {
|
||||||
const msgHash = MsgV2.getMsgHash(msg)
|
const msgHash = MsgV3.getMsgHash(msg)
|
||||||
if (!remoteFilter.has('' + round + msgHash)) {
|
if (!remoteFilter.has('' + round + msgHash)) {
|
||||||
missing.push(msgHash)
|
missing.push(msgHash)
|
||||||
}
|
}
|
||||||
|
@ -166,7 +166,7 @@ class Algorithm {
|
||||||
const validNewMsgs = newMsgs
|
const validNewMsgs = newMsgs
|
||||||
.filter((msg) => {
|
.filter((msg) => {
|
||||||
const depth = msg.metadata.tangles[rootMsgHash]?.depth ?? 0
|
const depth = msg.metadata.tangles[rootMsgHash]?.depth ?? 0
|
||||||
if (depth === 0 && MsgV2.getMsgHash(msg) !== rootMsgHash) {
|
if (depth === 0 && MsgV3.getMsgHash(msg) !== rootMsgHash) {
|
||||||
return false // the rootMsg is the only acceptable depth-zero msg
|
return false // the rootMsg is the only acceptable depth-zero msg
|
||||||
}
|
}
|
||||||
if (!msg.data) {
|
if (!msg.data) {
|
||||||
|
|
|
@ -36,13 +36,14 @@ module.exports = {
|
||||||
function createStream(remoteId, iamClient) {
|
function createStream(remoteId, iamClient) {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
debug('Opening a stream with remote %s %s', iamClient ? 'server' : 'client', remoteId)
|
debug('Opening a stream with remote %s %s', iamClient ? 'server' : 'client', remoteId)
|
||||||
const stream = new SyncStream(peer.id, debug, goals, algo)
|
const stream = new SyncStream(peer.pubkey, debug, goals, algo)
|
||||||
streams.push(stream)
|
streams.push(stream)
|
||||||
return stream
|
return stream
|
||||||
}
|
}
|
||||||
|
|
||||||
peer.on('rpc:connect', function onSyncRPCConnect(rpc, iamClient) {
|
peer.on('rpc:connect', function onSyncRPCConnect(rpc, iamClient) {
|
||||||
if (rpc.id === peer.id) return // local client connecting to local server
|
// TODO: eliminate SSB base64 `.id`, use SHSE `.pubkey` instead
|
||||||
|
if (rpc.id === peer.pubkey) return // local client connecting to local server
|
||||||
if (!iamClient) return
|
if (!iamClient) return
|
||||||
const local = toPull.duplex(createStream(rpc.id, true))
|
const local = toPull.duplex(createStream(rpc.id, true))
|
||||||
|
|
||||||
|
|
|
@ -36,15 +36,14 @@
|
||||||
"bs58": "^5.0.0",
|
"bs58": "^5.0.0",
|
||||||
"c8": "7",
|
"c8": "7",
|
||||||
"ppppp-db": "github:staltz/ppppp-db",
|
"ppppp-db": "github:staltz/ppppp-db",
|
||||||
|
"ppppp-caps": "github:staltz/ppppp-caps",
|
||||||
|
"ppppp-keypair": "github:staltz/ppppp-keypair",
|
||||||
"prettier": "^2.6.2",
|
"prettier": "^2.6.2",
|
||||||
"pretty-quick": "^3.1.3",
|
"pretty-quick": "^3.1.3",
|
||||||
"rimraf": "^4.4.0",
|
"rimraf": "^4.4.0",
|
||||||
"secret-stack": "^6.4.1",
|
"secret-stack": "^6.4.1",
|
||||||
|
"secret-handshake-ext": "^0.0.7",
|
||||||
"ssb-box": "^1.0.1",
|
"ssb-box": "^1.0.1",
|
||||||
"ssb-caps": "^1.1.0",
|
|
||||||
"ssb-classic": "^1.1.0",
|
|
||||||
"ssb-keys": "^8.5.0",
|
|
||||||
"ssb-uri2": "^2.4.1",
|
|
||||||
"tap-arc": "^0.3.5",
|
"tap-arc": "^0.3.5",
|
||||||
"tape": "^5.6.3"
|
"tape": "^5.6.3"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,70 +1,41 @@
|
||||||
const test = require('tape')
|
const test = require('tape')
|
||||||
const path = require('path')
|
const p = require('node:util').promisify
|
||||||
const os = require('os')
|
const Keypair = require('ppppp-keypair')
|
||||||
const rimraf = require('rimraf')
|
|
||||||
const SecretStack = require('secret-stack')
|
|
||||||
const caps = require('ssb-caps')
|
|
||||||
const p = require('util').promisify
|
|
||||||
const Algorithm = require('../lib/algorithm')
|
const Algorithm = require('../lib/algorithm')
|
||||||
const { generateKeypair } = require('./util')
|
const { createPeer } = require('./util')
|
||||||
|
|
||||||
const createPeer = SecretStack({ appKey: caps.shs })
|
const carolKeypair = Keypair.generate('ed25519', 'carol')
|
||||||
.use(require('ppppp-db'))
|
|
||||||
.use(require('ssb-box'))
|
|
||||||
.use(require('../lib'))
|
|
||||||
|
|
||||||
const ALICE_DIR = path.join(os.tmpdir(), 'dagsync-alice')
|
|
||||||
const BOB_DIR = path.join(os.tmpdir(), 'dagsync-bob')
|
|
||||||
const aliceKeys = generateKeypair('alice')
|
|
||||||
const bobKeys = generateKeypair('bob')
|
|
||||||
|
|
||||||
test('sync a feed with goal=all', async (t) => {
|
test('sync a feed with goal=all', async (t) => {
|
||||||
rimraf.sync(ALICE_DIR)
|
const alice = createPeer({ name: 'alice' })
|
||||||
rimraf.sync(BOB_DIR)
|
const bob = createPeer({ name: 'bob' })
|
||||||
|
|
||||||
const alice = createPeer({
|
|
||||||
keys: aliceKeys,
|
|
||||||
path: ALICE_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
const bob = createPeer({
|
|
||||||
keys: bobKeys,
|
|
||||||
path: BOB_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
await alice.db.loaded()
|
await alice.db.loaded()
|
||||||
const aliceGroupRec0 = await p(alice.db.group.create)({ _nonce: 'alice' })
|
|
||||||
const aliceId = aliceGroupRec0.hash
|
|
||||||
await p(alice.db.add)(aliceGroupRec0.msg, aliceId)
|
|
||||||
|
|
||||||
await bob.db.loaded()
|
await bob.db.loaded()
|
||||||
const bobGroupRec0 = await p(bob.db.group.create)({ _nonce: 'bob' })
|
|
||||||
const bobId = bobGroupRec0.hash
|
|
||||||
await p(bob.db.add)(bobGroupRec0.msg, bobId)
|
|
||||||
|
|
||||||
const carolKeys = generateKeypair('carol')
|
const carolID = await p(alice.db.identity.create)({
|
||||||
const carolGroupRec0 = await p(alice.db.group.create)({
|
keypair: carolKeypair,
|
||||||
keys: carolKeys,
|
domain: 'account',
|
||||||
_nonce: 'carol',
|
_nonce: 'carol',
|
||||||
})
|
})
|
||||||
const carolId = carolGroupRec0.hash
|
const carolIDMsg = alice.db.get(carolID)
|
||||||
|
|
||||||
// Bob knows Alice
|
// Bob knows Carol
|
||||||
await p(bob.db.add)(carolGroupRec0.msg, carolId)
|
await p(bob.db.add)(carolIDMsg, carolID)
|
||||||
|
|
||||||
const carolMsgs = []
|
const carolMsgs = []
|
||||||
for (let i = 1; i <= 10; i++) {
|
for (let i = 1; i <= 10; i++) {
|
||||||
const rec = await p(alice.db.feed.publish)({
|
const rec = await p(alice.db.feed.publish)({
|
||||||
group: carolId,
|
identity: carolID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'm' + i },
|
data: { text: 'm' + i },
|
||||||
keys: carolKeys,
|
keypair: carolKeypair,
|
||||||
})
|
})
|
||||||
carolMsgs.push(rec.msg)
|
carolMsgs.push(rec.msg)
|
||||||
}
|
}
|
||||||
t.pass('alice has msgs 1..10 from carol')
|
t.pass('alice has msgs 1..10 from carol')
|
||||||
|
|
||||||
const carolPostsRootHash = alice.db.feed.getId(carolId, 'post')
|
const carolPostsRootHash = alice.db.feed.getId(carolID, 'post')
|
||||||
const carolPostsRootMsg = alice.db.get(carolPostsRootHash)
|
const carolPostsRootMsg = alice.db.get(carolPostsRootHash)
|
||||||
|
|
||||||
await p(bob.db.add)(carolPostsRootMsg, carolPostsRootHash)
|
await p(bob.db.add)(carolPostsRootMsg, carolPostsRootHash)
|
||||||
|
@ -74,7 +45,7 @@ test('sync a feed with goal=all', async (t) => {
|
||||||
|
|
||||||
{
|
{
|
||||||
const arr = [...bob.db.msgs()]
|
const arr = [...bob.db.msgs()]
|
||||||
.filter((msg) => msg.metadata.group === carolId && msg.data)
|
.filter((msg) => msg.metadata.identity === carolID && msg.data)
|
||||||
.map((msg) => msg.data.text)
|
.map((msg) => msg.data.text)
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
arr,
|
arr,
|
||||||
|
@ -95,7 +66,7 @@ test('sync a feed with goal=all', async (t) => {
|
||||||
|
|
||||||
{
|
{
|
||||||
const arr = [...bob.db.msgs()]
|
const arr = [...bob.db.msgs()]
|
||||||
.filter((msg) => msg.metadata.group === carolId && msg.data)
|
.filter((msg) => msg.metadata.identity === carolID && msg.data)
|
||||||
.map((msg) => msg.data.text)
|
.map((msg) => msg.data.text)
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
arr,
|
arr,
|
||||||
|
@ -110,52 +81,35 @@ test('sync a feed with goal=all', async (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('sync a feed with goal=newest', async (t) => {
|
test('sync a feed with goal=newest', async (t) => {
|
||||||
rimraf.sync(ALICE_DIR)
|
const alice = createPeer({ name: 'alice' })
|
||||||
rimraf.sync(BOB_DIR)
|
const bob = createPeer({ name: 'bob' })
|
||||||
|
|
||||||
const alice = createPeer({
|
|
||||||
keys: aliceKeys,
|
|
||||||
path: ALICE_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
const bob = createPeer({
|
|
||||||
keys: bobKeys,
|
|
||||||
path: BOB_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
await alice.db.loaded()
|
await alice.db.loaded()
|
||||||
const aliceGroupRec0 = await p(alice.db.group.create)({ _nonce: 'alice' })
|
|
||||||
const aliceId = aliceGroupRec0.hash
|
|
||||||
await p(alice.db.add)(aliceGroupRec0.msg, aliceId)
|
|
||||||
|
|
||||||
await bob.db.loaded()
|
await bob.db.loaded()
|
||||||
const bobGroupRec0 = await p(bob.db.group.create)({ _nonce: 'bob' })
|
|
||||||
const bobId = bobGroupRec0.hash
|
|
||||||
await p(bob.db.add)(bobGroupRec0.msg, bobId)
|
|
||||||
|
|
||||||
const carolKeys = generateKeypair('carol')
|
const carolID = await p(alice.db.identity.create)({
|
||||||
const carolGroupRec0 = await p(alice.db.group.create)({
|
keypair: carolKeypair,
|
||||||
keys: carolKeys,
|
domain: 'account',
|
||||||
_nonce: 'carol',
|
_nonce: 'carol',
|
||||||
})
|
})
|
||||||
const carolId = carolGroupRec0.hash
|
const carolIDMsg = alice.db.get(carolID)
|
||||||
|
|
||||||
// Bob knows Alice
|
// Bob knows Carol
|
||||||
await p(bob.db.add)(carolGroupRec0.msg, carolId)
|
await p(bob.db.add)(carolIDMsg, carolID)
|
||||||
|
|
||||||
const carolMsgs = []
|
const carolMsgs = []
|
||||||
for (let i = 1; i <= 10; i++) {
|
for (let i = 1; i <= 10; i++) {
|
||||||
const rec = await p(alice.db.feed.publish)({
|
const rec = await p(alice.db.feed.publish)({
|
||||||
group: carolId,
|
identity: carolID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'm' + i },
|
data: { text: 'm' + i },
|
||||||
keys: carolKeys,
|
keypair: carolKeypair,
|
||||||
})
|
})
|
||||||
carolMsgs.push(rec.msg)
|
carolMsgs.push(rec.msg)
|
||||||
}
|
}
|
||||||
t.pass('alice has msgs 1..10 from carol')
|
t.pass('alice has msgs 1..10 from carol')
|
||||||
|
|
||||||
const carolPostsRootHash = alice.db.feed.getId(carolId, 'post')
|
const carolPostsRootHash = alice.db.feed.getId(carolID, 'post')
|
||||||
const carolPostsRootMsg = alice.db.get(carolPostsRootHash)
|
const carolPostsRootMsg = alice.db.get(carolPostsRootHash)
|
||||||
|
|
||||||
await p(bob.db.add)(carolPostsRootMsg, carolPostsRootHash)
|
await p(bob.db.add)(carolPostsRootMsg, carolPostsRootHash)
|
||||||
|
@ -165,7 +119,7 @@ test('sync a feed with goal=newest', async (t) => {
|
||||||
|
|
||||||
{
|
{
|
||||||
const arr = [...bob.db.msgs()]
|
const arr = [...bob.db.msgs()]
|
||||||
.filter((msg) => msg.metadata.group === carolId && msg.data)
|
.filter((msg) => msg.metadata.identity === carolID && msg.data)
|
||||||
.map((msg) => msg.data.text)
|
.map((msg) => msg.data.text)
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
arr,
|
arr,
|
||||||
|
@ -186,7 +140,7 @@ test('sync a feed with goal=newest', async (t) => {
|
||||||
|
|
||||||
{
|
{
|
||||||
const arr = [...bob.db.msgs()]
|
const arr = [...bob.db.msgs()]
|
||||||
.filter((msg) => msg.metadata.group === carolId && msg.data)
|
.filter((msg) => msg.metadata.identity === carolID && msg.data)
|
||||||
.map((msg) => msg.data.text)
|
.map((msg) => msg.data.text)
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
arr,
|
arr,
|
||||||
|
@ -201,58 +155,41 @@ test('sync a feed with goal=newest', async (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('sync a feed with goal=newest but too far behind', async (t) => {
|
test('sync a feed with goal=newest but too far behind', async (t) => {
|
||||||
rimraf.sync(ALICE_DIR)
|
const alice = createPeer({ name: 'alice' })
|
||||||
rimraf.sync(BOB_DIR)
|
const bob = createPeer({ name: 'bob' })
|
||||||
|
|
||||||
const alice = createPeer({
|
|
||||||
keys: aliceKeys,
|
|
||||||
path: ALICE_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
const bob = createPeer({
|
|
||||||
keys: bobKeys,
|
|
||||||
path: BOB_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
await alice.db.loaded()
|
await alice.db.loaded()
|
||||||
const aliceGroupRec0 = await p(alice.db.group.create)({ _nonce: 'alice' })
|
|
||||||
const aliceId = aliceGroupRec0.hash
|
|
||||||
await p(alice.db.add)(aliceGroupRec0.msg, aliceId)
|
|
||||||
|
|
||||||
await bob.db.loaded()
|
await bob.db.loaded()
|
||||||
const bobGroupRec0 = await p(bob.db.group.create)({ _nonce: 'bob' })
|
|
||||||
const bobId = bobGroupRec0.hash
|
|
||||||
await p(bob.db.add)(bobGroupRec0.msg, bobId)
|
|
||||||
|
|
||||||
const carolKeys = generateKeypair('carol')
|
const carolID = await p(alice.db.identity.create)({
|
||||||
const carolGroupRec0 = await p(alice.db.group.create)({
|
keypair: carolKeypair,
|
||||||
keys: carolKeys,
|
domain: 'account',
|
||||||
_nonce: 'carol',
|
_nonce: 'carol',
|
||||||
})
|
})
|
||||||
const carolId = carolGroupRec0.hash
|
const carolIDMsg = alice.db.get(carolID)
|
||||||
|
|
||||||
// Bob knows Alice
|
// Bob knows Carol
|
||||||
await p(bob.db.add)(carolGroupRec0.msg, carolId)
|
await p(bob.db.add)(carolIDMsg, carolID)
|
||||||
|
|
||||||
const carolMsgs = []
|
const carolMsgs = []
|
||||||
for (let i = 1; i <= 10; i++) {
|
for (let i = 1; i <= 10; i++) {
|
||||||
const rec = await p(alice.db.feed.publish)({
|
const rec = await p(alice.db.feed.publish)({
|
||||||
group: carolId,
|
identity: carolID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'm' + i },
|
data: { text: 'm' + i },
|
||||||
keys: carolKeys,
|
keypair: carolKeypair,
|
||||||
})
|
})
|
||||||
carolMsgs.push(rec.msg)
|
carolMsgs.push(rec.msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
const carolPostsRootHash = alice.db.feed.getId(carolId, 'post')
|
const carolPostsRootHash = alice.db.feed.getId(carolID, 'post')
|
||||||
const carolPostsRootMsg = alice.db.get(carolPostsRootHash)
|
const carolPostsRootMsg = alice.db.get(carolPostsRootHash)
|
||||||
|
|
||||||
const algo = new Algorithm(alice)
|
const algo = new Algorithm(alice)
|
||||||
await algo.pruneNewest(carolPostsRootHash, 5)
|
await algo.pruneNewest(carolPostsRootHash, 5)
|
||||||
{
|
{
|
||||||
const arr = [...alice.db.msgs()]
|
const arr = [...alice.db.msgs()]
|
||||||
.filter((msg) => msg.metadata.group === carolId && msg.data)
|
.filter((msg) => msg.metadata.identity === carolID && msg.data)
|
||||||
.map((msg) => msg.data.text)
|
.map((msg) => msg.data.text)
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
arr,
|
arr,
|
||||||
|
@ -268,7 +205,7 @@ test('sync a feed with goal=newest but too far behind', async (t) => {
|
||||||
|
|
||||||
{
|
{
|
||||||
const arr = [...bob.db.msgs()]
|
const arr = [...bob.db.msgs()]
|
||||||
.filter((msg) => msg.metadata.group === carolId && msg.data)
|
.filter((msg) => msg.metadata.identity === carolID && msg.data)
|
||||||
.map((msg) => msg.data.text)
|
.map((msg) => msg.data.text)
|
||||||
t.deepEquals(arr, ['m1', 'm2'], 'bob has msgs 1..2 from carol')
|
t.deepEquals(arr, ['m1', 'm2'], 'bob has msgs 1..2 from carol')
|
||||||
}
|
}
|
||||||
|
@ -285,7 +222,7 @@ test('sync a feed with goal=newest but too far behind', async (t) => {
|
||||||
|
|
||||||
{
|
{
|
||||||
const arr = [...bob.db.msgs()]
|
const arr = [...bob.db.msgs()]
|
||||||
.filter((msg) => msg.metadata.group === carolId && msg.data)
|
.filter((msg) => msg.metadata.identity === carolID && msg.data)
|
||||||
.map((msg) => msg.data.text)
|
.map((msg) => msg.data.text)
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
arr,
|
arr,
|
||||||
|
|
|
@ -1,61 +1,47 @@
|
||||||
const test = require('tape')
|
const test = require('tape')
|
||||||
const path = require('path')
|
|
||||||
const os = require('os')
|
|
||||||
const rimraf = require('rimraf')
|
|
||||||
const SecretStack = require('secret-stack')
|
|
||||||
const caps = require('ssb-caps')
|
|
||||||
const p = require('util').promisify
|
const p = require('util').promisify
|
||||||
const { generateKeypair } = require('./util')
|
const Keypair = require('ppppp-keypair')
|
||||||
|
const { createPeer } = require('./util')
|
||||||
|
|
||||||
const createSSB = SecretStack({ appKey: caps.shs })
|
const aliceKeypair = Keypair.generate('ed25519', 'alice')
|
||||||
.use(require('ppppp-db'))
|
const bobKeys = Keypair.generate('ed25519', 'bob')
|
||||||
.use(require('ssb-box'))
|
|
||||||
.use(require('../lib'))
|
|
||||||
|
|
||||||
const ALICE_DIR = path.join(os.tmpdir(), 'dagsync-alice')
|
|
||||||
const BOB_DIR = path.join(os.tmpdir(), 'dagsync-bob')
|
|
||||||
const aliceKeys = generateKeypair('alice')
|
|
||||||
const bobKeys = generateKeypair('bob')
|
|
||||||
|
|
||||||
function getIdentity(iter) {
|
function getIdentity(iter) {
|
||||||
return [...iter]
|
return [...iter]
|
||||||
.filter((msg) => msg.metadata.group === null && msg.data)
|
.filter((msg) => msg.metadata.identity === 'self' && msg.data)
|
||||||
.map((msg) => msg.data.add)
|
.map((msg) => msg.data.add)
|
||||||
}
|
}
|
||||||
|
|
||||||
test('sync an identity tangle', async (t) => {
|
test('sync an identity tangle', async (t) => {
|
||||||
rimraf.sync(ALICE_DIR)
|
const alice = createPeer({ name: 'alice', keypair: aliceKeypair })
|
||||||
rimraf.sync(BOB_DIR)
|
const bob = createPeer({ name: 'bob', keypair: bobKeys })
|
||||||
|
|
||||||
const alice = createSSB({
|
|
||||||
keys: aliceKeys,
|
|
||||||
path: ALICE_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
const bob = createSSB({
|
|
||||||
keys: bobKeys,
|
|
||||||
path: BOB_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
await alice.db.loaded()
|
await alice.db.loaded()
|
||||||
await bob.db.loaded()
|
await bob.db.loaded()
|
||||||
|
|
||||||
// Alice's identity tangle
|
// Alice's identity tangle
|
||||||
await alice.db.loaded()
|
await alice.db.loaded()
|
||||||
const aliceGroupRec0 = await p(alice.db.group.create)({ _nonce: 'alice' })
|
const aliceID = await p(alice.db.identity.create)({
|
||||||
const aliceId = aliceGroupRec0.hash
|
domain: 'account',
|
||||||
await p(alice.db.add)(aliceGroupRec0.msg, aliceId)
|
_nonce: 'alice',
|
||||||
|
})
|
||||||
|
|
||||||
const aliceKeys1 = generateKeypair('alice1')
|
const aliceKeypair1 = Keypair.generate('ed25519', 'alice1')
|
||||||
await p(alice.db.group.add)({ group: aliceId, keys: aliceKeys1 })
|
await p(alice.db.identity.add)({
|
||||||
|
identity: aliceID,
|
||||||
|
keypair: aliceKeypair1,
|
||||||
|
})
|
||||||
|
|
||||||
const aliceKeys2 = generateKeypair('alice2')
|
const aliceKeypair2 = Keypair.generate('ed25519', 'alice2')
|
||||||
await p(alice.db.group.add)({ group: aliceId, keys: aliceKeys2 })
|
await p(alice.db.identity.add)({
|
||||||
|
identity: aliceID,
|
||||||
|
keypair: aliceKeypair2,
|
||||||
|
})
|
||||||
|
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
getIdentity(alice.db.msgs()),
|
getIdentity(alice.db.msgs()),
|
||||||
[aliceKeys.id, aliceKeys1.id, aliceKeys2.id],
|
[aliceKeypair.public, aliceKeypair1.public, aliceKeypair2.public],
|
||||||
"alice has her identity tangle"
|
'alice has her identity tangle'
|
||||||
)
|
)
|
||||||
|
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
|
@ -64,8 +50,8 @@ test('sync an identity tangle', async (t) => {
|
||||||
"bob doesn't have alice's identity tangle"
|
"bob doesn't have alice's identity tangle"
|
||||||
)
|
)
|
||||||
|
|
||||||
bob.tangleSync.setGoal(aliceId, 'all')
|
bob.tangleSync.setGoal(aliceID, 'all')
|
||||||
alice.tangleSync.setGoal(aliceId, 'all')
|
alice.tangleSync.setGoal(aliceID, 'all')
|
||||||
|
|
||||||
const remoteAlice = await p(bob.connect)(alice.getAddress())
|
const remoteAlice = await p(bob.connect)(alice.getAddress())
|
||||||
t.pass('bob connected to alice')
|
t.pass('bob connected to alice')
|
||||||
|
@ -76,7 +62,7 @@ test('sync an identity tangle', async (t) => {
|
||||||
|
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
getIdentity(bob.db.msgs()),
|
getIdentity(bob.db.msgs()),
|
||||||
[aliceKeys.id, aliceKeys1.id, aliceKeys2.id],
|
[aliceKeypair.public, aliceKeypair1.public, aliceKeypair2.public],
|
||||||
"bob has alice's identity tangle"
|
"bob has alice's identity tangle"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -1,26 +1,13 @@
|
||||||
const test = require('tape')
|
const test = require('tape')
|
||||||
const path = require('path')
|
|
||||||
const os = require('os')
|
|
||||||
const rimraf = require('rimraf')
|
|
||||||
const SecretStack = require('secret-stack')
|
|
||||||
const caps = require('ssb-caps')
|
|
||||||
const p = require('util').promisify
|
const p = require('util').promisify
|
||||||
const { generateKeypair } = require('./util')
|
const Keypair = require('ppppp-keypair')
|
||||||
|
const { createPeer } = require('./util')
|
||||||
|
|
||||||
const createSSB = SecretStack({ appKey: caps.shs })
|
const carolKeypair = Keypair.generate('ed25519', 'carol')
|
||||||
.use(require('ppppp-db'))
|
const daveKeypair = Keypair.generate('ed25519', 'dave')
|
||||||
.use(require('ssb-box'))
|
|
||||||
.use(require('../lib'))
|
|
||||||
|
|
||||||
const ALICE_DIR = path.join(os.tmpdir(), 'dagsync-alice')
|
|
||||||
const BOB_DIR = path.join(os.tmpdir(), 'dagsync-bob')
|
|
||||||
const aliceKeys = generateKeypair('alice')
|
|
||||||
const bobKeys = generateKeypair('bob')
|
|
||||||
|
|
||||||
function getTexts(iter) {
|
function getTexts(iter) {
|
||||||
return [...iter]
|
return [...iter].filter((msg) => msg.data?.text).map((msg) => msg.data.text)
|
||||||
.filter((msg) => msg.metadata.group && msg.data)
|
|
||||||
.map((msg) => msg.data.text)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -61,81 +48,72 @@ graph TB;
|
||||||
```
|
```
|
||||||
*/
|
*/
|
||||||
test('sync a thread where both peers have portions', async (t) => {
|
test('sync a thread where both peers have portions', async (t) => {
|
||||||
rimraf.sync(ALICE_DIR)
|
const alice = createPeer({ name: 'alice' })
|
||||||
rimraf.sync(BOB_DIR)
|
const bob = createPeer({ name: 'bob' })
|
||||||
|
|
||||||
const alice = createSSB({
|
|
||||||
keys: aliceKeys,
|
|
||||||
path: ALICE_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
const bob = createSSB({
|
|
||||||
keys: bobKeys,
|
|
||||||
path: BOB_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
await alice.db.loaded()
|
await alice.db.loaded()
|
||||||
const aliceGroupRec0 = await p(alice.db.group.create)({ _nonce: 'alice' })
|
const aliceID = await p(alice.db.identity.create)({
|
||||||
const aliceId = aliceGroupRec0.hash
|
domain: 'account',
|
||||||
await p(alice.db.add)(aliceGroupRec0.msg, aliceId)
|
_nonce: 'alice',
|
||||||
|
})
|
||||||
|
const aliceIDMsg = alice.db.get(aliceID)
|
||||||
|
|
||||||
await bob.db.loaded()
|
await bob.db.loaded()
|
||||||
const bobGroupRec0 = await p(bob.db.group.create)({ _nonce: 'bob' })
|
const bobID = await p(bob.db.identity.create)({
|
||||||
const bobId = bobGroupRec0.hash
|
domain: 'account',
|
||||||
await p(bob.db.add)(bobGroupRec0.msg, bobId)
|
_nonce: 'bob',
|
||||||
|
})
|
||||||
|
const bobIDMsg = bob.db.get(bobID)
|
||||||
|
|
||||||
// Alice created Carol
|
// Alice created Carol
|
||||||
const carolKeys = generateKeypair('carol')
|
const carolID = await p(alice.db.identity.create)({
|
||||||
const carolGroupRec0 = await p(alice.db.group.create)({
|
domain: 'account',
|
||||||
keys: carolKeys,
|
keypair: carolKeypair,
|
||||||
_nonce: 'carol',
|
_nonce: 'carol',
|
||||||
})
|
})
|
||||||
const carolId = carolGroupRec0.hash
|
const carolIDMsg = alice.db.get(carolID)
|
||||||
|
|
||||||
// Alice created Dave
|
// Alice created Dave
|
||||||
const daveKeys = generateKeypair('dave')
|
const daveID = await p(alice.db.identity.create)({
|
||||||
const daveGroupRec0 = await p(alice.db.group.create)({
|
domain: 'account',
|
||||||
keys: daveKeys,
|
keypair: daveKeypair,
|
||||||
_nonce: 'dave',
|
_nonce: 'dave',
|
||||||
})
|
})
|
||||||
const daveId = daveGroupRec0.hash
|
const daveIDMsg = alice.db.get(daveID)
|
||||||
|
|
||||||
// Alice knows Bob
|
// Alice knows Bob
|
||||||
await p(alice.db.add)(bobGroupRec0.msg, bobId)
|
await p(alice.db.add)(bobIDMsg, bobID)
|
||||||
|
|
||||||
// Bob knows Alice, Carol, and Dave
|
// Bob knows Alice, Carol, and Dave
|
||||||
await p(bob.db.add)(aliceGroupRec0.msg, aliceId)
|
await p(bob.db.add)(aliceIDMsg, aliceID)
|
||||||
await p(bob.db.add)(carolGroupRec0.msg, carolId)
|
await p(bob.db.add)(carolIDMsg, carolID)
|
||||||
await p(bob.db.add)(daveGroupRec0.msg, daveId)
|
await p(bob.db.add)(daveIDMsg, daveID)
|
||||||
|
|
||||||
const startA = await p(alice.db.feed.publish)({
|
const startA = await p(alice.db.feed.publish)({
|
||||||
group: aliceId,
|
identity: aliceID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'A' },
|
data: { text: 'A' },
|
||||||
keys: aliceKeys,
|
|
||||||
})
|
})
|
||||||
const rootHashA = alice.db.feed.getId(aliceId, 'post')
|
const rootHashA = alice.db.feed.getId(aliceID, 'post')
|
||||||
const rootMsgA = alice.db.get(rootHashA)
|
const rootMsgA = alice.db.get(rootHashA)
|
||||||
|
|
||||||
await p(bob.db.add)(rootMsgA, rootHashA)
|
await p(bob.db.add)(rootMsgA, rootHashA)
|
||||||
await p(bob.db.add)(startA.msg, rootHashA)
|
await p(bob.db.add)(startA.msg, rootHashA)
|
||||||
|
|
||||||
const replyB1 = await p(bob.db.feed.publish)({
|
const replyB1 = await p(bob.db.feed.publish)({
|
||||||
group: bobId,
|
identity: bobID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'B1' },
|
data: { text: 'B1' },
|
||||||
tangles: [startA.hash],
|
tangles: [startA.hash],
|
||||||
keys: bobKeys,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const replyB2 = await p(bob.db.feed.publish)({
|
const replyB2 = await p(bob.db.feed.publish)({
|
||||||
group: bobId,
|
identity: bobID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'B2' },
|
data: { text: 'B2' },
|
||||||
tangles: [startA.hash],
|
tangles: [startA.hash],
|
||||||
keys: bobKeys,
|
|
||||||
})
|
})
|
||||||
const rootHashB = bob.db.feed.getId(bobId, 'post')
|
const rootHashB = bob.db.feed.getId(bobID, 'post')
|
||||||
const rootMsgB = bob.db.get(rootHashB)
|
const rootMsgB = bob.db.get(rootHashB)
|
||||||
|
|
||||||
await p(alice.db.add)(rootMsgB, rootHashB)
|
await p(alice.db.add)(rootMsgB, rootHashB)
|
||||||
|
@ -143,19 +121,19 @@ test('sync a thread where both peers have portions', async (t) => {
|
||||||
await p(alice.db.add)(replyB2.msg, rootHashB)
|
await p(alice.db.add)(replyB2.msg, rootHashB)
|
||||||
|
|
||||||
const replyC1 = await p(alice.db.feed.publish)({
|
const replyC1 = await p(alice.db.feed.publish)({
|
||||||
group: carolId,
|
identity: carolID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'C1' },
|
data: { text: 'C1' },
|
||||||
tangles: [startA.hash],
|
tangles: [startA.hash],
|
||||||
keys: carolKeys,
|
keypair: carolKeypair,
|
||||||
})
|
})
|
||||||
|
|
||||||
const replyD1 = await p(bob.db.feed.publish)({
|
const replyD1 = await p(bob.db.feed.publish)({
|
||||||
group: daveId,
|
identity: daveID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'D1' },
|
data: { text: 'D1' },
|
||||||
tangles: [startA.hash],
|
tangles: [startA.hash],
|
||||||
keys: daveKeys,
|
keypair: daveKeypair,
|
||||||
})
|
})
|
||||||
|
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
|
@ -198,56 +176,47 @@ test('sync a thread where both peers have portions', async (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('sync a thread where initiator does not have the root', async (t) => {
|
test('sync a thread where initiator does not have the root', async (t) => {
|
||||||
rimraf.sync(ALICE_DIR)
|
const alice = createPeer({ name: 'alice' })
|
||||||
rimraf.sync(BOB_DIR)
|
const bob = createPeer({ name: 'bob' })
|
||||||
|
|
||||||
const alice = createSSB({
|
|
||||||
keys: aliceKeys,
|
|
||||||
path: ALICE_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
const bob = createSSB({
|
|
||||||
keys: bobKeys,
|
|
||||||
path: BOB_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
await alice.db.loaded()
|
await alice.db.loaded()
|
||||||
const aliceGroupRec0 = await p(alice.db.group.create)({ _nonce: 'alice' })
|
const aliceID = await p(alice.db.identity.create)({
|
||||||
const aliceId = aliceGroupRec0.hash
|
domain: 'account',
|
||||||
await p(alice.db.add)(aliceGroupRec0.msg, aliceId)
|
_nonce: 'alice',
|
||||||
|
})
|
||||||
|
const aliceIDMsg = alice.db.get(aliceID)
|
||||||
|
|
||||||
await bob.db.loaded()
|
await bob.db.loaded()
|
||||||
const bobGroupRec0 = await p(bob.db.group.create)({ _nonce: 'bob' })
|
const bobID = await p(bob.db.identity.create)({
|
||||||
const bobId = bobGroupRec0.hash
|
domain: 'account',
|
||||||
await p(bob.db.add)(bobGroupRec0.msg, bobId)
|
_nonce: 'bob',
|
||||||
|
})
|
||||||
|
const bobIDMsg = bob.db.get(bobID)
|
||||||
|
|
||||||
// Alice knows Bob
|
// Alice knows Bob
|
||||||
await p(alice.db.add)(bobGroupRec0.msg, bobId)
|
await p(alice.db.add)(bobIDMsg, bobID)
|
||||||
|
|
||||||
// Bob knows Alice
|
// Bob knows Alice
|
||||||
await p(bob.db.add)(aliceGroupRec0.msg, aliceId)
|
await p(bob.db.add)(aliceIDMsg, aliceID)
|
||||||
|
|
||||||
const rootA = await p(alice.db.feed.publish)({
|
const rootA = await p(alice.db.feed.publish)({
|
||||||
group: aliceId,
|
identity: aliceID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'A' },
|
data: { text: 'A' },
|
||||||
keys: aliceKeys,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const replyA1 = await p(alice.db.feed.publish)({
|
const replyA1 = await p(alice.db.feed.publish)({
|
||||||
group: aliceId,
|
identity: aliceID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'A1' },
|
data: { text: 'A1' },
|
||||||
tangles: [rootA.hash],
|
tangles: [rootA.hash],
|
||||||
keys: aliceKeys,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const replyA2 = await p(alice.db.feed.publish)({
|
const replyA2 = await p(alice.db.feed.publish)({
|
||||||
group: aliceId,
|
identity: aliceID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'A2' },
|
data: { text: 'A2' },
|
||||||
tangles: [rootA.hash],
|
tangles: [rootA.hash],
|
||||||
keys: aliceKeys,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
|
@ -281,56 +250,47 @@ test('sync a thread where initiator does not have the root', async (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('sync a thread where receiver does not have the root', async (t) => {
|
test('sync a thread where receiver does not have the root', async (t) => {
|
||||||
rimraf.sync(ALICE_DIR)
|
const alice = createPeer({ name: 'alice' })
|
||||||
rimraf.sync(BOB_DIR)
|
const bob = createPeer({ name: 'bob' })
|
||||||
|
|
||||||
const alice = createSSB({
|
|
||||||
keys: aliceKeys,
|
|
||||||
path: ALICE_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
const bob = createSSB({
|
|
||||||
keys: bobKeys,
|
|
||||||
path: BOB_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
await alice.db.loaded()
|
await alice.db.loaded()
|
||||||
const aliceGroupRec0 = await p(alice.db.group.create)({ _nonce: 'alice' })
|
const aliceID = await p(alice.db.identity.create)({
|
||||||
const aliceId = aliceGroupRec0.hash
|
domain: 'account',
|
||||||
await p(alice.db.add)(aliceGroupRec0.msg, aliceId)
|
_nonce: 'alice',
|
||||||
|
})
|
||||||
|
const aliceIDMsg = alice.db.get(aliceID)
|
||||||
|
|
||||||
await bob.db.loaded()
|
await bob.db.loaded()
|
||||||
const bobGroupRec0 = await p(bob.db.group.create)({ _nonce: 'bob' })
|
const bobID = await p(bob.db.identity.create)({
|
||||||
const bobId = bobGroupRec0.hash
|
domain: 'account',
|
||||||
await p(bob.db.add)(bobGroupRec0.msg, bobId)
|
_nonce: 'bob',
|
||||||
|
})
|
||||||
|
const bobIDMsg = bob.db.get(bobID)
|
||||||
|
|
||||||
// Alice knows Bob
|
// Alice knows Bob
|
||||||
await p(alice.db.add)(bobGroupRec0.msg, bobId)
|
await p(alice.db.add)(bobIDMsg, bobID)
|
||||||
|
|
||||||
// Bob knows Alice
|
// Bob knows Alice
|
||||||
await p(bob.db.add)(aliceGroupRec0.msg, aliceId)
|
await p(bob.db.add)(aliceIDMsg, aliceID)
|
||||||
|
|
||||||
const rootA = await p(alice.db.feed.publish)({
|
const rootA = await p(alice.db.feed.publish)({
|
||||||
group: aliceId,
|
identity: aliceID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'A' },
|
data: { text: 'A' },
|
||||||
keys: aliceKeys,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const replyA1 = await p(alice.db.feed.publish)({
|
const replyA1 = await p(alice.db.feed.publish)({
|
||||||
group: aliceId,
|
identity: aliceID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'A1' },
|
data: { text: 'A1' },
|
||||||
tangles: [rootA.hash],
|
tangles: [rootA.hash],
|
||||||
keys: aliceKeys,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const replyA2 = await p(alice.db.feed.publish)({
|
const replyA2 = await p(alice.db.feed.publish)({
|
||||||
group: aliceId,
|
identity: aliceID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'A2' },
|
data: { text: 'A2' },
|
||||||
tangles: [rootA.hash],
|
tangles: [rootA.hash],
|
||||||
keys: aliceKeys,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
|
@ -363,64 +323,54 @@ test('sync a thread where receiver does not have the root', async (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('sync a thread with reactions too', async (t) => {
|
test('sync a thread with reactions too', async (t) => {
|
||||||
rimraf.sync(ALICE_DIR)
|
const alice = createPeer({ name: 'alice' })
|
||||||
rimraf.sync(BOB_DIR)
|
const bob = createPeer({ name: 'bob' })
|
||||||
|
|
||||||
const alice = createSSB({
|
|
||||||
keys: aliceKeys,
|
|
||||||
path: ALICE_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
const bob = createSSB({
|
|
||||||
keys: bobKeys,
|
|
||||||
path: BOB_DIR,
|
|
||||||
})
|
|
||||||
|
|
||||||
await alice.db.loaded()
|
await alice.db.loaded()
|
||||||
const aliceGroupRec0 = await p(alice.db.group.create)({ _nonce: 'alice' })
|
const aliceID = await p(alice.db.identity.create)({
|
||||||
const aliceId = aliceGroupRec0.hash
|
domain: 'account',
|
||||||
await p(alice.db.add)(aliceGroupRec0.msg, aliceId)
|
_nonce: 'alice',
|
||||||
|
})
|
||||||
|
const aliceIDMsg = alice.db.get(aliceID)
|
||||||
|
|
||||||
await bob.db.loaded()
|
await bob.db.loaded()
|
||||||
const bobGroupRec0 = await p(bob.db.group.create)({ _nonce: 'bob' })
|
const bobID = await p(bob.db.identity.create)({
|
||||||
const bobId = bobGroupRec0.hash
|
domain: 'account',
|
||||||
await p(bob.db.add)(bobGroupRec0.msg, bobId)
|
_nonce: 'bob',
|
||||||
|
})
|
||||||
|
const bobIDMsg = bob.db.get(bobID)
|
||||||
|
|
||||||
// Alice knows Bob
|
// Alice knows Bob
|
||||||
await p(alice.db.add)(bobGroupRec0.msg, bobId)
|
await p(alice.db.add)(bobIDMsg, bobID)
|
||||||
|
|
||||||
// Bob knows Alice
|
// Bob knows Alice
|
||||||
await p(bob.db.add)(aliceGroupRec0.msg, aliceId)
|
await p(bob.db.add)(aliceIDMsg, aliceID)
|
||||||
|
|
||||||
const rootA = await p(alice.db.feed.publish)({
|
const rootA = await p(alice.db.feed.publish)({
|
||||||
group: aliceId,
|
identity: aliceID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'A' },
|
data: { text: 'A' },
|
||||||
keys: aliceKeys,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const replyA1 = await p(alice.db.feed.publish)({
|
const replyA1 = await p(alice.db.feed.publish)({
|
||||||
group: aliceId,
|
identity: aliceID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'A1' },
|
data: { text: 'A1' },
|
||||||
tangles: [rootA.hash],
|
tangles: [rootA.hash],
|
||||||
keys: aliceKeys,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const replyA2 = await p(alice.db.feed.publish)({
|
const replyA2 = await p(alice.db.feed.publish)({
|
||||||
group: aliceId,
|
identity: aliceID,
|
||||||
type: 'post',
|
domain: 'post',
|
||||||
data: { text: 'A2' },
|
data: { text: 'A2' },
|
||||||
tangles: [rootA.hash],
|
tangles: [rootA.hash],
|
||||||
keys: aliceKeys,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const reactionA3 = await p(alice.db.feed.publish)({
|
const reactionA3 = await p(alice.db.feed.publish)({
|
||||||
group: aliceId,
|
identity: aliceID,
|
||||||
type: 'reaction',
|
domain: 'reaction',
|
||||||
data: { text: 'yes', link: replyA1.hash },
|
data: { text: 'yes', link: replyA1.hash },
|
||||||
tangles: [rootA.hash, replyA1.hash],
|
tangles: [rootA.hash, replyA1.hash],
|
||||||
keys: aliceKeys,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
|
|
46
test/util.js
46
test/util.js
|
@ -1,14 +1,38 @@
|
||||||
const ssbKeys = require('ssb-keys')
|
const os = require('node:os')
|
||||||
const SSBURI = require('ssb-uri2')
|
const path = require('node:path')
|
||||||
const base58 = require('bs58')
|
const rimraf = require('rimraf')
|
||||||
|
const caps = require('ppppp-caps')
|
||||||
|
const Keypair = require('ppppp-keypair')
|
||||||
|
|
||||||
function generateKeypair(seed) {
|
function createPeer(opts) {
|
||||||
const keys = ssbKeys.generate('ed25519', seed, 'buttwoo-v1')
|
if (opts.name) {
|
||||||
const { data } = SSBURI.decompose(keys.id)
|
opts.path ??= path.join(os.tmpdir(), 'tanglesync-' + opts.name)
|
||||||
keys.id = base58.encode(Buffer.from(data, 'base64'))
|
opts.keypair ??= Keypair.generate('ed25519', opts.name)
|
||||||
return keys
|
opts.name = undefined
|
||||||
|
}
|
||||||
|
if (!opts.path) throw new Error('need opts.path in createPeer()')
|
||||||
|
if (!opts.keypair) throw new Error('need opts.keypair in createPeer()')
|
||||||
|
|
||||||
|
rimraf.sync(opts.path)
|
||||||
|
return require('secret-stack/lib/api')([], {})
|
||||||
|
.use(require('secret-stack/lib/core'))
|
||||||
|
.use(require('secret-stack/lib/plugins/net'))
|
||||||
|
.use(require('secret-handshake-ext/secret-stack'))
|
||||||
|
.use(require('ppppp-db'))
|
||||||
|
.use(require('ssb-box'))
|
||||||
|
.use(require('../lib'))
|
||||||
|
.call(null, {
|
||||||
|
caps,
|
||||||
|
connections: {
|
||||||
|
incoming: {
|
||||||
|
net: [{ scope: 'device', transform: 'shse', port: null }],
|
||||||
|
},
|
||||||
|
outgoing: {
|
||||||
|
net: [{ transform: 'shse' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
...opts,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { createPeer }
|
||||||
generateKeypair,
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue