mirror of https://codeberg.org/pzp/pzp-db.git
Tangle class belongs to FeedV1
This commit is contained in:
parent
0917361305
commit
d2023b5bc0
|
@ -16,8 +16,14 @@ const {
|
||||||
validateBatch,
|
validateBatch,
|
||||||
validateMsgHash,
|
validateMsgHash,
|
||||||
} = require('./validation')
|
} = require('./validation')
|
||||||
const { isEmptyObject } = require('../utils')
|
const Tangle = require('./tangle')
|
||||||
const Tangle = require('../tangle')
|
|
||||||
|
function isEmptyObject(obj) {
|
||||||
|
for (const _key in obj) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {Iterator<Msg> & {values: () => Iterator<Msg>}} MsgIter
|
* @typedef {Iterator<Msg> & {values: () => Iterator<Msg>}} MsgIter
|
||||||
|
@ -215,6 +221,7 @@ module.exports = {
|
||||||
stripAuthor,
|
stripAuthor,
|
||||||
toPlaintextBuffer,
|
toPlaintextBuffer,
|
||||||
fromPlaintextBuffer,
|
fromPlaintextBuffer,
|
||||||
|
Tangle,
|
||||||
validate,
|
validate,
|
||||||
validateBatch,
|
validateBatch,
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,5 @@
|
||||||
/**
|
/**
|
||||||
* @typedef {import("./plugin").Rec} Rec
|
* @typedef {import("./index").Msg} Msg
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {import("./feed-v1").Msg} Msg
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
function lipmaa(n) {
|
function lipmaa(n) {
|
||||||
|
@ -80,16 +76,12 @@ class Tangle {
|
||||||
#maxDepth
|
#maxDepth
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param {string} rootHash
|
* @param {string} rootHash
|
||||||
* @param {Iterable<Rec>} recordsIter
|
* @param {Iterable<Msg>} msgsIter
|
||||||
*/
|
*/
|
||||||
constructor(rootHash, recordsIter = []) {
|
constructor(rootHash) {
|
||||||
this.#rootHash = rootHash
|
this.#rootHash = rootHash
|
||||||
this.#maxDepth = 0
|
this.#maxDepth = 0
|
||||||
for (const rec of recordsIter) {
|
|
||||||
this.add(rec.hash, rec.msg)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
add(msgHash, msg) {
|
add(msgHash, msg) {
|
||||||
|
@ -184,7 +176,7 @@ class Tangle {
|
||||||
return { type, who }
|
return { type, who }
|
||||||
}
|
}
|
||||||
|
|
||||||
#shortestPathToRoot(msgHash) {
|
shortestPathToRoot(msgHash) {
|
||||||
const path = []
|
const path = []
|
||||||
let current = msgHash
|
let current = msgHash
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -207,16 +199,6 @@ class Tangle {
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
getDeletablesAndErasables(msgHash) {
|
|
||||||
const erasables = this.#shortestPathToRoot(msgHash)
|
|
||||||
const sorted = this.topoSort()
|
|
||||||
const index = sorted.indexOf(msgHash)
|
|
||||||
const deletables = sorted.filter(
|
|
||||||
(msgHash, i) => i < index && !erasables.includes(msgHash)
|
|
||||||
)
|
|
||||||
return { deletables, erasables }
|
|
||||||
}
|
|
||||||
|
|
||||||
getMaxDepth() {
|
getMaxDepth() {
|
||||||
return this.#maxDepth
|
return this.#maxDepth
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
const base58 = require('bs58')
|
const base58 = require('bs58')
|
||||||
const ed25519 = require('ssb-keys/sodium')
|
const ed25519 = require('ssb-keys/sodium')
|
||||||
const stringify = require('fast-json-stable-stringify')
|
const stringify = require('fast-json-stable-stringify')
|
||||||
const Tangle = require('../tangle')
|
const Tangle = require('./tangle')
|
||||||
|
|
||||||
function validateShape(msg) {
|
function validateShape(msg) {
|
||||||
if (!msg || typeof msg !== 'object') {
|
if (!msg || typeof msg !== 'object') {
|
||||||
|
|
|
@ -4,7 +4,6 @@ const AAOL = require('async-append-only-log')
|
||||||
const promisify = require('promisify-4loc')
|
const promisify = require('promisify-4loc')
|
||||||
const Obz = require('obz')
|
const Obz = require('obz')
|
||||||
const FeedV1 = require('./feed-v1')
|
const FeedV1 = require('./feed-v1')
|
||||||
const Tangle = require('./tangle')
|
|
||||||
const { ReadyGate } = require('./utils')
|
const { ReadyGate } = require('./utils')
|
||||||
const { decrypt } = require('./encryption')
|
const { decrypt } = require('./encryption')
|
||||||
|
|
||||||
|
@ -41,6 +40,29 @@ const { decrypt } = require('./encryption')
|
||||||
* @typedef {RecPresent | RecDeleted} Rec
|
* @typedef {RecPresent | RecDeleted} Rec
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
class DBTangle extends FeedV1.Tangle {
|
||||||
|
/**
|
||||||
|
* @param {string} rootHash
|
||||||
|
* @param {Iterable<Rec>} recordsIter
|
||||||
|
*/
|
||||||
|
constructor(rootHash, recordsIter) {
|
||||||
|
super(rootHash)
|
||||||
|
for (const rec of recordsIter) {
|
||||||
|
this.add(rec.hash, rec.msg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getDeletablesAndErasables(msgHash) {
|
||||||
|
const erasables = this.shortestPathToRoot(msgHash)
|
||||||
|
const sorted = this.topoSort()
|
||||||
|
const index = sorted.indexOf(msgHash)
|
||||||
|
const deletables = sorted.filter(
|
||||||
|
(msgHash, i) => i < index && !erasables.includes(msgHash)
|
||||||
|
)
|
||||||
|
return { deletables, erasables }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exports.name = 'db'
|
exports.name = 'db'
|
||||||
|
|
||||||
exports.init = function initDB(peer, config) {
|
exports.init = function initDB(peer, config) {
|
||||||
|
@ -150,7 +172,7 @@ exports.init = function initDB(peer, config) {
|
||||||
function populateTangles(tangleIds) {
|
function populateTangles(tangleIds) {
|
||||||
const tangles = {}
|
const tangles = {}
|
||||||
for (const tangleId of tangleIds) {
|
for (const tangleId of tangleIds) {
|
||||||
tangles[tangleId] ??= new Tangle(tangleId, records())
|
tangles[tangleId] ??= new DBTangle(tangleId, records())
|
||||||
}
|
}
|
||||||
return tangles
|
return tangles
|
||||||
}
|
}
|
||||||
|
@ -162,8 +184,8 @@ exports.init = function initDB(peer, config) {
|
||||||
|
|
||||||
function add(msg, tangleRootHash, cb) {
|
function add(msg, tangleRootHash, cb) {
|
||||||
// TODO: optimize this. This may be slow if you're adding many msgs in a
|
// TODO: optimize this. This may be slow if you're adding many msgs in a
|
||||||
// row, because it creates a new Map() each time.
|
// row, because it creates a new Map() each time. Perhaps with QuickLRU
|
||||||
const tangle = new Tangle(tangleRootHash, records())
|
const tangle = new DBTangle(tangleRootHash, records())
|
||||||
|
|
||||||
const msgHash = FeedV1.getMsgHash(msg)
|
const msgHash = FeedV1.getMsgHash(msg)
|
||||||
FeedV1.validate(msg, tangle, msgHash, tangleRootHash, validationCB)
|
FeedV1.validate(msg, tangle, msgHash, tangleRootHash, validationCB)
|
||||||
|
@ -293,7 +315,7 @@ exports.init = function initDB(peer, config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTangle(tangleId) {
|
function getTangle(tangleId) {
|
||||||
return new Tangle(tangleId, records())
|
return new DBTangle(tangleId, records())
|
||||||
}
|
}
|
||||||
|
|
||||||
function* msgs() {
|
function* msgs() {
|
||||||
|
|
|
@ -18,11 +18,4 @@ class ReadyGate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function isEmptyObject(obj) {
|
module.exports = { ReadyGate }
|
||||||
for (const _key in obj) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = { ReadyGate, isEmptyObject }
|
|
||||||
|
|
|
@ -5,7 +5,6 @@ const rimraf = require('rimraf')
|
||||||
const SecretStack = require('secret-stack')
|
const SecretStack = require('secret-stack')
|
||||||
const caps = require('ssb-caps')
|
const caps = require('ssb-caps')
|
||||||
const FeedV1 = require('../lib/feed-v1')
|
const FeedV1 = require('../lib/feed-v1')
|
||||||
const Tangle = require('../lib/tangle')
|
|
||||||
const p = require('util').promisify
|
const p = require('util').promisify
|
||||||
const { generateKeypair } = require('./util')
|
const { generateKeypair } = require('./util')
|
||||||
|
|
||||||
|
@ -26,6 +25,8 @@ test('add()', async (t) => {
|
||||||
|
|
||||||
const recRoot = await p(peer.db.add)(rootMsg, rootHash)
|
const recRoot = await p(peer.db.add)(rootMsg, rootHash)
|
||||||
t.equals(recRoot.msg.metadata.when, 0, 'root msg added')
|
t.equals(recRoot.msg.metadata.when, 0, 'root msg added')
|
||||||
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(recRoot.hash, recRoot.msg)
|
||||||
|
|
||||||
const inputMsg = FeedV1.create({
|
const inputMsg = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
|
@ -33,7 +34,7 @@ test('add()', async (t) => {
|
||||||
type: 'post',
|
type: 'post',
|
||||||
content: { text: 'This is the first post!' },
|
content: { text: 'This is the first post!' },
|
||||||
tangles: {
|
tangles: {
|
||||||
[rootHash]: new Tangle(rootHash, [recRoot]),
|
[rootHash]: tangle,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ const SecretStack = require('secret-stack')
|
||||||
const caps = require('ssb-caps')
|
const caps = require('ssb-caps')
|
||||||
const p = require('util').promisify
|
const p = require('util').promisify
|
||||||
const FeedV1 = require('../lib/feed-v1')
|
const FeedV1 = require('../lib/feed-v1')
|
||||||
const Tangle = require('../lib/tangle')
|
|
||||||
const { generateKeypair } = require('./util')
|
const { generateKeypair } = require('./util')
|
||||||
|
|
||||||
const DIR = path.join(os.tmpdir(), 'ppppp-db-create')
|
const DIR = path.join(os.tmpdir(), 'ppppp-db-create')
|
||||||
|
@ -67,16 +66,17 @@ test('create()', async (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('add() forked then create() merged', async (t) => {
|
test('add() forked then create() merged', async (t) => {
|
||||||
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(rootHash, rootMsg)
|
||||||
|
tangle.add(rec1.hash, rec1.msg)
|
||||||
|
|
||||||
const msg3 = FeedV1.create({
|
const msg3 = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
when: Date.now(),
|
when: Date.now(),
|
||||||
type: 'post',
|
type: 'post',
|
||||||
content: { text: '3rd post forked from 1st' },
|
content: { text: '3rd post forked from 1st' },
|
||||||
tangles: {
|
tangles: {
|
||||||
[rootHash]: new Tangle(rootHash, [
|
[rootHash]: tangle
|
||||||
{ hash: rootHash, msg: rootMsg },
|
|
||||||
rec1,
|
|
||||||
]),
|
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
const tape = require('tape')
|
const tape = require('tape')
|
||||||
const FeedV1 = require('../lib/feed-v1')
|
const FeedV1 = require('../lib/feed-v1')
|
||||||
const Tangle = require('../lib/tangle')
|
|
||||||
const { generateKeypair } = require('./util')
|
const { generateKeypair } = require('./util')
|
||||||
|
|
||||||
let rootMsg = null
|
let rootMsg = null
|
||||||
|
@ -26,12 +25,15 @@ tape('FeedV1.create()', (t) => {
|
||||||
const content = { text: 'Hello world!' }
|
const content = { text: 'Hello world!' }
|
||||||
const when = 1652037377204
|
const when = 1652037377204
|
||||||
|
|
||||||
|
const tangle1 = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle1.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg1 = FeedV1.create({
|
const msg1 = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
content,
|
content,
|
||||||
type: 'post',
|
type: 'post',
|
||||||
tangles: {
|
tangles: {
|
||||||
[rootHash]: new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }]),
|
[rootHash]: tangle1,
|
||||||
},
|
},
|
||||||
when,
|
when,
|
||||||
})
|
})
|
||||||
|
@ -65,6 +67,10 @@ tape('FeedV1.create()', (t) => {
|
||||||
'getMsgId'
|
'getMsgId'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const tangle2 = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle2.add(rootHash, rootMsg)
|
||||||
|
tangle2.add(msgHash1, msg1)
|
||||||
|
|
||||||
const content2 = { text: 'Ola mundo!' }
|
const content2 = { text: 'Ola mundo!' }
|
||||||
|
|
||||||
const msg2 = FeedV1.create({
|
const msg2 = FeedV1.create({
|
||||||
|
@ -72,10 +78,7 @@ tape('FeedV1.create()', (t) => {
|
||||||
content: content2,
|
content: content2,
|
||||||
type: 'post',
|
type: 'post',
|
||||||
tangles: {
|
tangles: {
|
||||||
[rootHash]: new Tangle(rootHash, [
|
[rootHash]: tangle2,
|
||||||
{ hash: rootHash, msg: rootMsg },
|
|
||||||
{ hash: msgHash1, msg: msg1 },
|
|
||||||
]),
|
|
||||||
},
|
},
|
||||||
when: when + 1,
|
when: when + 1,
|
||||||
})
|
})
|
||||||
|
@ -112,7 +115,8 @@ tape('FeedV1.create()', (t) => {
|
||||||
tape('create() handles DAG tips correctly', (t) => {
|
tape('create() handles DAG tips correctly', (t) => {
|
||||||
const keys = generateKeypair('alice')
|
const keys = generateKeypair('alice')
|
||||||
const when = 1652037377204
|
const when = 1652037377204
|
||||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg1 = FeedV1.create({
|
const msg1 = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
const tape = require('tape')
|
const tape = require('tape')
|
||||||
const base58 = require('bs58')
|
const base58 = require('bs58')
|
||||||
const FeedV1 = require('../lib/feed-v1')
|
const FeedV1 = require('../lib/feed-v1')
|
||||||
const Tangle = require('../lib/tangle')
|
|
||||||
const { generateKeypair } = require('./util')
|
const { generateKeypair } = require('./util')
|
||||||
|
|
||||||
tape('invalid msg with non-array prev', (t) => {
|
tape('invalid msg with non-array prev', (t) => {
|
||||||
|
@ -10,7 +9,8 @@ tape('invalid msg with non-array prev', (t) => {
|
||||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
|
|
||||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg = FeedV1.create({
|
const msg = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
|
@ -37,7 +37,8 @@ tape('invalid msg with bad prev', (t) => {
|
||||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
|
|
||||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg1 = FeedV1.create({
|
const msg1 = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
|
@ -81,7 +82,8 @@ tape('invalid msg with URI in prev', (t) => {
|
||||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
|
|
||||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg1 = FeedV1.create({
|
const msg1 = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
|
@ -127,7 +129,8 @@ tape('invalid msg with unknown prev', (t) => {
|
||||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
|
|
||||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg1 = FeedV1.create({
|
const msg1 = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
|
@ -152,15 +155,16 @@ tape('invalid msg with unknown prev', (t) => {
|
||||||
})
|
})
|
||||||
const unknownMsgHash = FeedV1.getMsgHash(unknownMsg)
|
const unknownMsgHash = FeedV1.getMsgHash(unknownMsg)
|
||||||
|
|
||||||
|
const tangle2 = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle2.add(rootHash, rootMsg)
|
||||||
|
tangle2.add(unknownMsgHash, unknownMsg)
|
||||||
|
|
||||||
const msg2 = FeedV1.create({
|
const msg2 = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
content: { text: 'Hello world!' },
|
content: { text: 'Hello world!' },
|
||||||
type: 'post',
|
type: 'post',
|
||||||
tangles: {
|
tangles: {
|
||||||
[rootHash]: new Tangle(rootHash, [
|
[rootHash]: tangle2
|
||||||
{ hash: rootHash, msg: rootMsg },
|
|
||||||
{ hash: unknownMsgHash, msg: unknownMsg },
|
|
||||||
]),
|
|
||||||
},
|
},
|
||||||
when: 1652030002000,
|
when: 1652030002000,
|
||||||
})
|
})
|
||||||
|
@ -183,7 +187,8 @@ tape('invalid feed msg with a different who', (t) => {
|
||||||
|
|
||||||
const rootMsg = FeedV1.createRoot(keysA, 'post')
|
const rootMsg = FeedV1.createRoot(keysA, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
const feedTangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const feedTangle = new FeedV1.Tangle(rootHash)
|
||||||
|
feedTangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg = FeedV1.create({
|
const msg = FeedV1.create({
|
||||||
keys: keysB,
|
keys: keysB,
|
||||||
|
@ -207,7 +212,8 @@ tape('invalid feed msg with a different type', (t) => {
|
||||||
|
|
||||||
const rootMsg = FeedV1.createRoot(keysA, 'post')
|
const rootMsg = FeedV1.createRoot(keysA, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
const feedTangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const feedTangle = new FeedV1.Tangle(rootHash)
|
||||||
|
feedTangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg = FeedV1.create({
|
const msg = FeedV1.create({
|
||||||
keys: keysA,
|
keys: keysA,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
const tape = require('tape')
|
const tape = require('tape')
|
||||||
const FeedV1 = require('../lib/feed-v1')
|
const FeedV1 = require('../lib/feed-v1')
|
||||||
const Tangle = require('../lib/tangle')
|
|
||||||
const { generateKeypair } = require('./util')
|
const { generateKeypair } = require('./util')
|
||||||
|
|
||||||
tape('lipmaa prevs', (t) => {
|
tape('lipmaa prevs', (t) => {
|
||||||
|
@ -10,7 +9,8 @@ tape('lipmaa prevs', (t) => {
|
||||||
|
|
||||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg1 = FeedV1.create({
|
const msg1 = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
const tape = require('tape')
|
const tape = require('tape')
|
||||||
const FeedV1 = require('../lib/feed-v1')
|
const FeedV1 = require('../lib/feed-v1')
|
||||||
const Tangle = require('../lib/tangle')
|
|
||||||
const { generateKeypair } = require('./util')
|
const { generateKeypair } = require('./util')
|
||||||
|
|
||||||
tape('simple multi-author tangle', (t) => {
|
tape('simple multi-author tangle', (t) => {
|
||||||
|
@ -9,11 +8,13 @@ tape('simple multi-author tangle', (t) => {
|
||||||
|
|
||||||
const rootMsgA = FeedV1.createRoot(keysA, 'post')
|
const rootMsgA = FeedV1.createRoot(keysA, 'post')
|
||||||
const rootHashA = FeedV1.getMsgHash(rootMsgA)
|
const rootHashA = FeedV1.getMsgHash(rootMsgA)
|
||||||
const tangleA = new Tangle(rootHashA, [{ hash: rootHashA, msg: rootMsgA }])
|
const tangleA = new FeedV1.Tangle(rootHashA)
|
||||||
|
tangleA.add(rootHashA, rootMsgA)
|
||||||
|
|
||||||
const rootMsgB = FeedV1.createRoot(keysB, 'post')
|
const rootMsgB = FeedV1.createRoot(keysB, 'post')
|
||||||
const rootHashB = FeedV1.getMsgHash(rootMsgB)
|
const rootHashB = FeedV1.getMsgHash(rootMsgB)
|
||||||
const tangleB = new Tangle(rootHashB, [{ hash: rootHashB, msg: rootMsgB }])
|
const tangleB = new FeedV1.Tangle(rootHashB)
|
||||||
|
tangleB.add(rootHashB, rootMsgB)
|
||||||
|
|
||||||
const msg1 = FeedV1.create({
|
const msg1 = FeedV1.create({
|
||||||
keys: keysA,
|
keys: keysA,
|
||||||
|
@ -31,13 +32,16 @@ tape('simple multi-author tangle', (t) => {
|
||||||
'msg1 has only feed tangle'
|
'msg1 has only feed tangle'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const tangleX = new FeedV1.Tangle(msgHash1)
|
||||||
|
tangleX.add(msgHash1, msg1)
|
||||||
|
|
||||||
const msg2 = FeedV1.create({
|
const msg2 = FeedV1.create({
|
||||||
keys: keysB,
|
keys: keysB,
|
||||||
content: { text: 'Hello world!' },
|
content: { text: 'Hello world!' },
|
||||||
type: 'post',
|
type: 'post',
|
||||||
tangles: {
|
tangles: {
|
||||||
[rootHashB]: tangleB,
|
[rootHashB]: tangleB,
|
||||||
[msgHash1]: new Tangle(msgHash1, [{ hash: msgHash1, msg: msg1 }]),
|
[msgHash1]: tangleX,
|
||||||
},
|
},
|
||||||
when: 1652030002000,
|
when: 1652030002000,
|
||||||
})
|
})
|
||||||
|
@ -73,11 +77,13 @@ tape('lipmaa in multi-author tangle', (t) => {
|
||||||
|
|
||||||
const rootMsgA = FeedV1.createRoot(keysA, 'post')
|
const rootMsgA = FeedV1.createRoot(keysA, 'post')
|
||||||
const rootHashA = FeedV1.getMsgHash(rootMsgA)
|
const rootHashA = FeedV1.getMsgHash(rootMsgA)
|
||||||
const tangleA = new Tangle(rootHashA, [{ hash: rootHashA, msg: rootMsgA }])
|
const tangleA = new FeedV1.Tangle(rootHashA)
|
||||||
|
tangleA.add(rootHashA, rootMsgA)
|
||||||
|
|
||||||
const rootMsgB = FeedV1.createRoot(keysB, 'post')
|
const rootMsgB = FeedV1.createRoot(keysB, 'post')
|
||||||
const rootHashB = FeedV1.getMsgHash(rootMsgB)
|
const rootHashB = FeedV1.getMsgHash(rootMsgB)
|
||||||
const tangleB = new Tangle(rootHashB, [{ hash: rootHashB, msg: rootMsgB }])
|
const tangleB = new FeedV1.Tangle(rootHashB)
|
||||||
|
tangleB.add(rootHashB, rootMsgB)
|
||||||
|
|
||||||
const msg1 = FeedV1.create({
|
const msg1 = FeedV1.create({
|
||||||
keys: keysA,
|
keys: keysA,
|
||||||
|
@ -90,7 +96,8 @@ tape('lipmaa in multi-author tangle', (t) => {
|
||||||
})
|
})
|
||||||
const msgHash1 = FeedV1.getMsgHash(msg1)
|
const msgHash1 = FeedV1.getMsgHash(msg1)
|
||||||
tangleA.add(msgHash1, msg1)
|
tangleA.add(msgHash1, msg1)
|
||||||
const tangleThread = new Tangle(msgHash1, [{ hash: msgHash1, msg: msg1 }])
|
const tangleThread = new FeedV1.Tangle(msgHash1)
|
||||||
|
tangleThread.add(msgHash1, msg1)
|
||||||
|
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
Object.keys(msg1.metadata.tangles),
|
Object.keys(msg1.metadata.tangles),
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
const tape = require('tape')
|
const tape = require('tape')
|
||||||
const base58 = require('bs58')
|
const base58 = require('bs58')
|
||||||
const FeedV1 = require('../lib/feed-v1')
|
const FeedV1 = require('../lib/feed-v1')
|
||||||
const Tangle = require('../lib/tangle')
|
|
||||||
const { generateKeypair } = require('./util')
|
const { generateKeypair } = require('./util')
|
||||||
|
|
||||||
tape('validate root msg', (t) => {
|
tape('validate root msg', (t) => {
|
||||||
|
@ -9,7 +8,8 @@ tape('validate root msg', (t) => {
|
||||||
|
|
||||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
FeedV1.validate(rootMsg, tangle, rootHash, rootHash, (err) => {
|
FeedV1.validate(rootMsg, tangle, rootHash, rootHash, (err) => {
|
||||||
if (err) console.log(err)
|
if (err) console.log(err)
|
||||||
|
@ -23,7 +23,8 @@ tape('validate 2nd msg with existing root', (t) => {
|
||||||
|
|
||||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg1 = FeedV1.create({
|
const msg1 = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
|
@ -49,7 +50,8 @@ tape('validate 2nd forked msg', (t) => {
|
||||||
|
|
||||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg1A = FeedV1.create({
|
const msg1A = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
|
@ -88,7 +90,8 @@ tape('invalid msg with unknown previous', (t) => {
|
||||||
|
|
||||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
|
tangle.add(rootHash, rootMsg)
|
||||||
|
|
||||||
const msg1 = FeedV1.create({
|
const msg1 = FeedV1.create({
|
||||||
keys,
|
keys,
|
||||||
|
|
|
@ -6,13 +6,13 @@ const SecretStack = require('secret-stack')
|
||||||
const caps = require('ssb-caps')
|
const caps = require('ssb-caps')
|
||||||
const p = require('util').promisify
|
const p = require('util').promisify
|
||||||
const { generateKeypair } = require('./util')
|
const { generateKeypair } = require('./util')
|
||||||
const Tangle = require('../lib/tangle')
|
|
||||||
|
|
||||||
const DIR = path.join(os.tmpdir(), 'ppppp-db-tangle')
|
const DIR = path.join(os.tmpdir(), 'ppppp-db-tangle')
|
||||||
rimraf.sync(DIR)
|
rimraf.sync(DIR)
|
||||||
|
|
||||||
let peer
|
let peer
|
||||||
let rootPost, reply1Lo, reply1Hi, reply2A, reply3Lo, reply3Hi
|
let rootPost, reply1Lo, reply1Hi, reply2A, reply3Lo, reply3Hi
|
||||||
|
let tangle
|
||||||
test('setup', async (t) => {
|
test('setup', async (t) => {
|
||||||
const keysA = generateKeypair('alice')
|
const keysA = generateKeypair('alice')
|
||||||
const keysB = generateKeypair('bob')
|
const keysB = generateKeypair('bob')
|
||||||
|
@ -81,11 +81,11 @@ test('setup', async (t) => {
|
||||||
])
|
])
|
||||||
reply3Lo = reply3B.localeCompare(reply3C) < 0 ? reply3B : reply3C
|
reply3Lo = reply3B.localeCompare(reply3C) < 0 ? reply3B : reply3C
|
||||||
reply3Hi = reply3B.localeCompare(reply3C) < 0 ? reply3C : reply3B
|
reply3Hi = reply3B.localeCompare(reply3C) < 0 ? reply3C : reply3B
|
||||||
|
|
||||||
|
tangle = peer.db.getTangle(rootPost)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Tangle.has', (t) => {
|
test('Tangle.has', (t) => {
|
||||||
const tangle = new Tangle(rootPost, peer.db.records())
|
|
||||||
|
|
||||||
t.true(tangle.has(rootPost), 'has rootPost')
|
t.true(tangle.has(rootPost), 'has rootPost')
|
||||||
t.true(tangle.has(reply1Lo), 'has reply1Lo')
|
t.true(tangle.has(reply1Lo), 'has reply1Lo')
|
||||||
t.true(tangle.has(reply1Hi), 'has reply1Hi')
|
t.true(tangle.has(reply1Hi), 'has reply1Hi')
|
||||||
|
@ -97,7 +97,6 @@ test('Tangle.has', (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Tangle.getDepth', t=> {
|
test('Tangle.getDepth', t=> {
|
||||||
const tangle = new Tangle(rootPost, peer.db.records())
|
|
||||||
t.equals(tangle.getDepth(rootPost), 0, 'depth of rootPost is 0')
|
t.equals(tangle.getDepth(rootPost), 0, 'depth of rootPost is 0')
|
||||||
t.equals(tangle.getDepth(reply1Lo), 1, 'depth of reply1Lo is 1')
|
t.equals(tangle.getDepth(reply1Lo), 1, 'depth of reply1Lo is 1')
|
||||||
t.equals(tangle.getDepth(reply1Hi), 1, 'depth of reply1Hi is 1')
|
t.equals(tangle.getDepth(reply1Hi), 1, 'depth of reply1Hi is 1')
|
||||||
|
@ -108,13 +107,11 @@ test('Tangle.getDepth', t=> {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Tangle.getMaxDepth', t => {
|
test('Tangle.getMaxDepth', t => {
|
||||||
const tangle = new Tangle(rootPost, peer.db.records())
|
|
||||||
t.equals(tangle.getMaxDepth(), 3, 'max depth is 3')
|
t.equals(tangle.getMaxDepth(), 3, 'max depth is 3')
|
||||||
t.end()
|
t.end()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Tangle.topoSort', (t) => {
|
test('Tangle.topoSort', (t) => {
|
||||||
const tangle = new Tangle(rootPost, peer.db.records())
|
|
||||||
const sorted = tangle.topoSort()
|
const sorted = tangle.topoSort()
|
||||||
|
|
||||||
t.deepEquals(sorted, [
|
t.deepEquals(sorted, [
|
||||||
|
@ -129,7 +126,6 @@ test('Tangle.topoSort', (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Tangle.getTips', (t) => {
|
test('Tangle.getTips', (t) => {
|
||||||
const tangle = new Tangle(rootPost, peer.db.records())
|
|
||||||
const tips = tangle.getTips()
|
const tips = tangle.getTips()
|
||||||
|
|
||||||
t.equals(tips.size, 2, 'there are 2 tips')
|
t.equals(tips.size, 2, 'there are 2 tips')
|
||||||
|
@ -139,7 +135,6 @@ test('Tangle.getTips', (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Tangle.getLipmaaSet', (t) => {
|
test('Tangle.getLipmaaSet', (t) => {
|
||||||
const tangle = new Tangle(rootPost, peer.db.records())
|
|
||||||
t.equals(tangle.getLipmaaSet(0).size, 0, 'lipmaa 0 (empty)')
|
t.equals(tangle.getLipmaaSet(0).size, 0, 'lipmaa 0 (empty)')
|
||||||
|
|
||||||
t.equals(tangle.getLipmaaSet(1).size, 1, 'lipmaa 1 (-1)')
|
t.equals(tangle.getLipmaaSet(1).size, 1, 'lipmaa 1 (-1)')
|
||||||
|
@ -162,7 +157,6 @@ test('Tangle.getLipmaaSet', (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Tangle.getDeletablesAndErasables basic', (t) => {
|
test('Tangle.getDeletablesAndErasables basic', (t) => {
|
||||||
const tangle = new Tangle(rootPost, peer.db.records())
|
|
||||||
const { deletables, erasables } = tangle.getDeletablesAndErasables(reply2A)
|
const { deletables, erasables } = tangle.getDeletablesAndErasables(reply2A)
|
||||||
|
|
||||||
t.deepEquals(deletables, [reply1Hi], 'deletables')
|
t.deepEquals(deletables, [reply1Hi], 'deletables')
|
||||||
|
@ -171,7 +165,6 @@ test('Tangle.getDeletablesAndErasables basic', (t) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
test('Tangle.getDeletablesAndErasables with lipmaa', (t) => {
|
test('Tangle.getDeletablesAndErasables with lipmaa', (t) => {
|
||||||
const tangle = new Tangle(rootPost, peer.db.records())
|
|
||||||
const { deletables, erasables } = tangle.getDeletablesAndErasables(reply3Lo)
|
const { deletables, erasables } = tangle.getDeletablesAndErasables(reply3Lo)
|
||||||
|
|
||||||
t.deepEquals(deletables, [reply1Lo, reply1Hi, reply2A], 'deletables')
|
t.deepEquals(deletables, [reply1Lo, reply1Hi, reply2A], 'deletables')
|
Loading…
Reference in New Issue