mirror of https://codeberg.org/pzp/pzp-db.git
use Tangle data structure in feed format
This commit is contained in:
parent
6a19cd91a8
commit
babfd5e39f
|
@ -5,6 +5,7 @@
|
|||
const stringify = require('fast-json-stable-stringify')
|
||||
const ed25519 = require('ssb-keys/sodium')
|
||||
const base58 = require('bs58')
|
||||
const union = require('set.prototype.union')
|
||||
const { stripAuthor } = require('./strip')
|
||||
const { getMsgId, getMsgHash } = require('./get-msg-id')
|
||||
const representContent = require('./represent-content')
|
||||
|
@ -15,6 +16,7 @@ const {
|
|||
validateBatch,
|
||||
validateMsgHash,
|
||||
} = require('./validation')
|
||||
const Tangle = require('../tangle')
|
||||
|
||||
/**
|
||||
* @typedef {Iterator<Msg> & {values: () => Iterator<Msg>}} MsgIter
|
||||
|
@ -51,7 +53,7 @@ const {
|
|||
* @property {string} type
|
||||
* @property {number} when
|
||||
* @property {Keys} keys
|
||||
* @property {Record<string, MsgIter>} tangles
|
||||
* @property {Record<string, Tangle>} tangles
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -93,122 +95,6 @@ function toPlaintextBuffer(opts) {
|
|||
return Buffer.from(stringify(opts.content), 'utf8')
|
||||
}
|
||||
|
||||
function calculateDepth(existing, tangleId = null) {
|
||||
let max = -1
|
||||
for (const msg of existing.values()) {
|
||||
const depth = msg.metadata.tangles[tangleId]?.depth ?? 0
|
||||
if (depth > max) {
|
||||
max = depth
|
||||
}
|
||||
}
|
||||
return max + 1
|
||||
}
|
||||
|
||||
function lipmaa(n) {
|
||||
let m = 1
|
||||
let po3 = 3
|
||||
let u = n
|
||||
|
||||
// find k such that (3^k - 1)/2 >= n
|
||||
while (m < n) {
|
||||
po3 *= 3
|
||||
m = (po3 - 1) / 2
|
||||
}
|
||||
|
||||
// find longest possible backjump
|
||||
po3 /= 3
|
||||
if (m !== n) {
|
||||
while (u !== 0) {
|
||||
m = (po3 - 1) / 2
|
||||
po3 /= 3
|
||||
u %= m
|
||||
}
|
||||
|
||||
if (m !== po3) {
|
||||
po3 = m
|
||||
}
|
||||
}
|
||||
|
||||
return n - po3
|
||||
}
|
||||
|
||||
function determineTips(existing, tangleId = null) {
|
||||
const tips = new Set()
|
||||
for (const msg of existing.values()) {
|
||||
tips.add(getMsgHash(msg))
|
||||
}
|
||||
|
||||
for (const msg of existing.values()) {
|
||||
const prev = msg.metadata.tangles[tangleId]?.prev ?? []
|
||||
for (const p of prev) {
|
||||
tips.delete(p)
|
||||
}
|
||||
}
|
||||
return tips
|
||||
}
|
||||
|
||||
function calculatePrev(existing, depth, lipmaaDepth, tangleId = null) {
|
||||
const prev = []
|
||||
const tips = determineTips(existing, tangleId)
|
||||
for (const msg of existing.values()) {
|
||||
const msgDepth = msg.metadata.tangles[tangleId]?.depth ?? 0
|
||||
const msgHash = getMsgHash(msg)
|
||||
if (
|
||||
msgDepth === depth - 1 ||
|
||||
msgDepth === lipmaaDepth ||
|
||||
tips.has(msgHash)
|
||||
) {
|
||||
prev.push(msgHash)
|
||||
}
|
||||
}
|
||||
return prev
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {MsgIter} existing
|
||||
* @param {string} tangleId
|
||||
* @returns
|
||||
*/
|
||||
function prevalidateExisting(existing, tangleId) {
|
||||
if (!existing?.[Symbol.iterator]) {
|
||||
// prettier-ignore
|
||||
return new Error(`existing must be an iterator, but got ${typeof existing}`)
|
||||
}
|
||||
if (typeof existing?.values !== 'function') {
|
||||
// prettier-ignore
|
||||
return new Error(`existing must be a Map, Set, or Array, but got ${existing}`)
|
||||
}
|
||||
if (!tangleId) {
|
||||
// prettier-ignore
|
||||
return new Error(`tangleId must be a string, but got ${typeof tangleId}`)
|
||||
}
|
||||
let isEmpty = true
|
||||
let hasDepthZeroMsg = false
|
||||
for (const p of existing.values()) {
|
||||
isEmpty = false
|
||||
if (!p.metadata) {
|
||||
// prettier-ignore
|
||||
return new Error(`existing must contain messages, but got ${typeof p}`)
|
||||
}
|
||||
|
||||
if (!p.metadata.tangles[tangleId] && getMsgHash(p) === tangleId) {
|
||||
if (hasDepthZeroMsg) {
|
||||
// prettier-ignore
|
||||
return new Error(`existing must contain only 1 message with depth 0`)
|
||||
} else {
|
||||
hasDepthZeroMsg = true
|
||||
}
|
||||
} else if (!p.metadata.tangles[tangleId]) {
|
||||
// prettier-ignore
|
||||
return new Error(`existing must refer to the tangleId ${tangleId}`)
|
||||
}
|
||||
}
|
||||
if (!isEmpty && !hasDepthZeroMsg) {
|
||||
// prettier-ignore
|
||||
return new Error(`opts.existing must contain the message with depth 0`)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {CreateOpts} opts
|
||||
* @returns {Msg}
|
||||
|
@ -224,12 +110,11 @@ function create(opts) {
|
|||
if (opts.tangles) {
|
||||
for (const rootId in opts.tangles) {
|
||||
if ((err = validateMsgHash(rootId))) throw err
|
||||
const existing = opts.tangles[rootId]
|
||||
if ((err = prevalidateExisting(existing, rootId))) throw err
|
||||
|
||||
const depth = calculateDepth(existing, rootId)
|
||||
const lipmaaDepth = lipmaa(depth + 1) - 1
|
||||
const prev = calculatePrev(existing, depth, lipmaaDepth, rootId)
|
||||
const tangle = opts.tangles[rootId]
|
||||
const depth = tangle.getMaxDepth() + 1
|
||||
const tips = tangle.getTips()
|
||||
const lipmaaSet = tangle.getLipmaaSet(depth)
|
||||
const prev = [...union(lipmaaSet, tips)]
|
||||
tangles[rootId] = { depth, prev }
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const base58 = require('bs58')
|
||||
const ed25519 = require('ssb-keys/sodium')
|
||||
const stringify = require('fast-json-stable-stringify')
|
||||
const Tangle = require('../tangle')
|
||||
|
||||
function validateShape(msg) {
|
||||
if (!msg || typeof msg !== 'object') {
|
||||
|
@ -73,13 +74,23 @@ function validateSignature(msg) {
|
|||
}
|
||||
}
|
||||
|
||||
function validateTangle(msg, existingMsgs, tangleId) {
|
||||
const tangle = msg.metadata.tangles[tangleId]
|
||||
if (!tangle?.prev || !Array.isArray(tangle.prev)) {
|
||||
/**
|
||||
*
|
||||
* @param {any} msg
|
||||
* @param {Tangle} tangle
|
||||
* @param {*} tangleId
|
||||
* @returns
|
||||
*/
|
||||
function validateTangle(msg, tangle, tangleId) {
|
||||
if (!msg.metadata.tangles[tangleId]) {
|
||||
return new Error('invalid message: must have metadata.tangles.' + tangleId)
|
||||
}
|
||||
const { depth, prev } = msg.metadata.tangles[tangleId]
|
||||
if (!prev || !Array.isArray(prev)) {
|
||||
// prettier-ignore
|
||||
return new Error('invalid message: prev must be an array, on feed: ' + msg.metadata.who);
|
||||
}
|
||||
for (const p of tangle.prev) {
|
||||
for (const p of prev) {
|
||||
if (typeof p !== 'string') {
|
||||
// prettier-ignore
|
||||
return new Error('invalid message: prev must contain strings but found ' + p + ', on feed: ' + msg.metadata.who);
|
||||
|
@ -89,18 +100,13 @@ function validateTangle(msg, existingMsgs, tangleId) {
|
|||
return new Error('invalid message: prev must not contain URIs, on feed: ' + msg.metadata.who);
|
||||
}
|
||||
|
||||
if (!existingMsgs.has(p)) {
|
||||
if (!tangle.has(p)) {
|
||||
// prettier-ignore
|
||||
return new Error('invalid message: prev ' + p + ' is not locally known, on feed: ' + msg.metadata.who);
|
||||
}
|
||||
const existingMsg = existingMsgs.get(p)
|
||||
const prevDepth = tangle.getDepth(p)
|
||||
|
||||
if (existingMsg.metadata.type !== msg.metadata.type) {
|
||||
// prettier-ignore
|
||||
return new Error('invalid message: prev ' + p + ' is not from the same type, on feed: ' + msg.metadata.who);
|
||||
}
|
||||
const existingDepth = existingMsg.metadata.tangles[tangleId]?.depth ?? 0
|
||||
if (existingDepth >= tangle.depth) {
|
||||
if (prevDepth >= depth) {
|
||||
// prettier-ignore
|
||||
return new Error('invalid message: depth of prev ' + p + ' is not lower, on feed: ' + msg.metadata.who);
|
||||
}
|
||||
|
@ -158,7 +164,7 @@ function validateContent(msg) {
|
|||
|
||||
// FIXME: validateDepth should be +1 of the max of prev depth
|
||||
|
||||
function validateSync(msg, existingMsgs, msgHash, rootHash) {
|
||||
function validateSync(msg, tangle, msgHash, rootHash) {
|
||||
let err
|
||||
if ((err = validateShape(msg))) return err
|
||||
if ((err = validateWho(msg))) return err
|
||||
|
@ -166,15 +172,15 @@ function validateSync(msg, existingMsgs, msgHash, rootHash) {
|
|||
if (msgHash === rootHash) {
|
||||
if ((err = validateTangleRoot(msg))) return err
|
||||
} else {
|
||||
if ((err = validateTangle(msg, existingMsgs, rootHash))) return err
|
||||
if ((err = validateTangle(msg, tangle, rootHash))) return err
|
||||
}
|
||||
if ((err = validateContent(msg))) return err
|
||||
if ((err = validateSignature(msg))) return err
|
||||
}
|
||||
|
||||
function validate(msg, existingMsgs, msgHash, rootHash, cb) {
|
||||
function validate(msg, tangle, msgHash, rootHash, cb) {
|
||||
let err
|
||||
if ((err = validateSync(msg, existingMsgs, msgHash, rootHash))) {
|
||||
if ((err = validateSync(msg, tangle, msgHash, rootHash))) {
|
||||
return cb(err)
|
||||
}
|
||||
cb()
|
||||
|
|
|
@ -4,6 +4,7 @@ const AAOL = require('async-append-only-log')
|
|||
const promisify = require('promisify-4loc')
|
||||
const Obz = require('obz')
|
||||
const FeedV1 = require('./feed-v1')
|
||||
const Tangle = require('./tangle')
|
||||
const { ReadyGate, isEmptyObject } = require('./utils')
|
||||
const { decrypt } = require('./encryption')
|
||||
|
||||
|
@ -149,10 +150,10 @@ exports.init = function initDB(peer, config) {
|
|||
function add(msg, tangleRootHash, cb) {
|
||||
// TODO: optimize this. This may be slow if you're adding many msgs in a
|
||||
// row, because it creates a new Map() each time.
|
||||
const tangleMsgs = populateTangle(tangleRootHash)
|
||||
const tangle = new Tangle(tangleRootHash, records())
|
||||
|
||||
const msgHash = FeedV1.getMsgHash(msg)
|
||||
FeedV1.validate(msg, tangleMsgs, msgHash, tangleRootHash, validationCB)
|
||||
FeedV1.validate(msg, tangle, msgHash, tangleRootHash, validationCB)
|
||||
|
||||
function validationCB(err) {
|
||||
// prettier-ignore
|
||||
|
@ -180,20 +181,10 @@ exports.init = function initDB(peer, config) {
|
|||
return null
|
||||
}
|
||||
|
||||
function populateTangle(tangleId) {
|
||||
const map = new Map()
|
||||
for (const rec of records()) {
|
||||
if (rec.hash === tangleId || rec.msg.metadata.tangles?.[tangleId]) {
|
||||
map.set(rec.hash, rec.msg)
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
function populateTangles(tangleIds) {
|
||||
const tangles = {}
|
||||
for (const tangleId of tangleIds) {
|
||||
tangles[tangleId] ??= populateTangle(tangleId)
|
||||
tangles[tangleId] ??= new Tangle(tangleId, records())
|
||||
}
|
||||
return tangles
|
||||
}
|
||||
|
@ -325,5 +316,8 @@ exports.init = function initDB(peer, config) {
|
|||
|
||||
// internal
|
||||
findEncryptionFormatFor,
|
||||
|
||||
// mockable by tests
|
||||
_getLog: () => log,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,6 +40,11 @@ function compareMsgHashes(a, b) {
|
|||
}
|
||||
|
||||
class Tangle {
|
||||
/**
|
||||
* @type {string}
|
||||
*/
|
||||
#rootHash
|
||||
|
||||
/**
|
||||
* @type {Set<string>}
|
||||
*/
|
||||
|
@ -70,23 +75,28 @@ class Tangle {
|
|||
* @param {string} rootHash
|
||||
* @param {Iterable<Rec>} recordsIter
|
||||
*/
|
||||
constructor(rootHash, recordsIter) {
|
||||
constructor(rootHash, recordsIter = []) {
|
||||
this.#rootHash = rootHash
|
||||
this.#maxDepth = 0
|
||||
for (const rec of recordsIter) {
|
||||
const msgHash = rec.hash
|
||||
const tangles = rec.msg.metadata.tangles
|
||||
if (msgHash === rootHash) {
|
||||
this.add(rec.hash, rec.msg)
|
||||
}
|
||||
}
|
||||
|
||||
add(msgHash, msg) {
|
||||
const tangles = msg.metadata.tangles
|
||||
if (msgHash === this.#rootHash) {
|
||||
this.#tips.add(msgHash)
|
||||
this.#perDepth.set(0, [msgHash])
|
||||
this.#depth.set(msgHash, 0)
|
||||
} else if (tangles[rootHash]) {
|
||||
} else if (tangles[this.#rootHash]) {
|
||||
this.#tips.add(msgHash)
|
||||
const prev = tangles[rootHash].prev
|
||||
const prev = tangles[this.#rootHash].prev
|
||||
for (const p of prev) {
|
||||
this.#tips.delete(p)
|
||||
}
|
||||
this.#prev.set(msgHash, prev)
|
||||
const depth = tangles[rootHash].depth
|
||||
const depth = tangles[this.#rootHash].depth
|
||||
if (depth > this.#maxDepth) this.#maxDepth = depth
|
||||
this.#depth.set(msgHash, depth)
|
||||
const atDepth = this.#perDepth.get(depth) ?? []
|
||||
|
@ -95,7 +105,6 @@ class Tangle {
|
|||
this.#perDepth.set(depth, atDepth)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} depth
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
"obz": "^1.1.0",
|
||||
"promisify-4loc": "^1.0.0",
|
||||
"push-stream": "^11.2.0",
|
||||
"set.prototype.union": "^1.0.2",
|
||||
"ssb-uri2": "^2.4.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -44,7 +45,7 @@
|
|||
"tape": "^5.6.3"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "tape test/*.js | tap-arc --bail",
|
||||
"test": "tape test/*.test.js | tap-arc --bail",
|
||||
"format-code": "prettier --write \"*.js\" \"(test|compat|indexes|operators)/*.js\"",
|
||||
"format-code-staged": "pretty-quick --staged --pattern \"*.js\" --pattern \"(test|compat|indexes|operators)/*.js\"",
|
||||
"coverage": "c8 --reporter=lcov npm run test"
|
||||
|
|
|
@ -5,6 +5,7 @@ const rimraf = require('rimraf')
|
|||
const SecretStack = require('secret-stack')
|
||||
const caps = require('ssb-caps')
|
||||
const FeedV1 = require('../lib/feed-v1')
|
||||
const Tangle = require('../lib/tangle')
|
||||
const p = require('util').promisify
|
||||
const { generateKeypair } = require('./util')
|
||||
|
||||
|
@ -32,7 +33,7 @@ test('add()', async (t) => {
|
|||
type: 'post',
|
||||
content: { text: 'This is the first post!' },
|
||||
tangles: {
|
||||
[rootHash]: new Map([[FeedV1.getMsgHash(rootMsg), rootMsg]]),
|
||||
[rootHash]: new Tangle(rootHash, [recRoot]),
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ const SecretStack = require('secret-stack')
|
|||
const caps = require('ssb-caps')
|
||||
const p = require('util').promisify
|
||||
const FeedV1 = require('../lib/feed-v1')
|
||||
const Tangle = require('../lib/tangle')
|
||||
const { generateKeypair } = require('./util')
|
||||
|
||||
const DIR = path.join(os.tmpdir(), 'ppppp-db-create')
|
||||
|
@ -72,9 +73,9 @@ test('add() forked then create() merged', async (t) => {
|
|||
type: 'post',
|
||||
content: { text: '3rd post forked from 1st' },
|
||||
tangles: {
|
||||
[rootHash]: new Map([
|
||||
[rootHash, rootMsg],
|
||||
[rec1.hash, rec1.msg],
|
||||
[rootHash]: new Tangle(rootHash, [
|
||||
{ hash: rootHash, msg: rootMsg },
|
||||
rec1,
|
||||
]),
|
||||
},
|
||||
})
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
const tape = require('tape')
|
||||
const FeedV1 = require('../lib/feed-v1')
|
||||
const Tangle = require('../lib/tangle')
|
||||
const { generateKeypair } = require('./util')
|
||||
|
||||
let rootMsg = null
|
||||
|
@ -30,7 +31,7 @@ tape('FeedV1.create()', (t) => {
|
|||
content,
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: new Map([[rootHash, rootMsg]]),
|
||||
[rootHash]: new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }]),
|
||||
},
|
||||
when,
|
||||
})
|
||||
|
@ -71,9 +72,9 @@ tape('FeedV1.create()', (t) => {
|
|||
content: content2,
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: new Map([
|
||||
[rootHash, rootMsg],
|
||||
[msgHash1, msg1],
|
||||
[rootHash]: new Tangle(rootHash, [
|
||||
{ hash: rootHash, msg: rootMsg },
|
||||
{ hash: msgHash1, msg: msg1 },
|
||||
]),
|
||||
},
|
||||
when: when + 1,
|
||||
|
@ -111,14 +112,14 @@ tape('FeedV1.create()', (t) => {
|
|||
tape('create() handles DAG tips correctly', (t) => {
|
||||
const keys = generateKeypair('alice')
|
||||
const when = 1652037377204
|
||||
const existing = new Map([[rootHash, rootMsg]])
|
||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||
|
||||
const msg1 = FeedV1.create({
|
||||
keys,
|
||||
content: { text: '1' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: when + 1,
|
||||
})
|
||||
|
@ -129,14 +130,14 @@ tape('create() handles DAG tips correctly', (t) => {
|
|||
'msg1.prev is root'
|
||||
)
|
||||
|
||||
existing.set(msgHash1, msg1)
|
||||
tangle.add(msgHash1, msg1)
|
||||
|
||||
const msg2A = FeedV1.create({
|
||||
keys,
|
||||
content: { text: '2A' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: when + 2,
|
||||
})
|
||||
|
@ -151,9 +152,8 @@ tape('create() handles DAG tips correctly', (t) => {
|
|||
content: { text: '2B' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
existing,
|
||||
when: when + 2,
|
||||
})
|
||||
const msgHash2B = FeedV1.getMsgHash(msg2B)
|
||||
|
@ -163,14 +163,14 @@ tape('create() handles DAG tips correctly', (t) => {
|
|||
'msg2B.prev is msg1'
|
||||
)
|
||||
|
||||
existing.set(msgHash2B, msg2B)
|
||||
tangle.add(msgHash2B, msg2B)
|
||||
|
||||
const msg3 = FeedV1.create({
|
||||
keys,
|
||||
content: { text: '3' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: when + 3,
|
||||
})
|
||||
|
@ -180,10 +180,10 @@ tape('create() handles DAG tips correctly', (t) => {
|
|||
[rootHash, msgHash2B],
|
||||
'msg3.prev is root(lipmaa),msg2B(previous)'
|
||||
)
|
||||
existing.set(msgHash3, msg3)
|
||||
tangle.add(msgHash3, msg3)
|
||||
|
||||
const msgHash2A = FeedV1.getMsgHash(msg2A)
|
||||
existing.set(msgHash2A, msg2A)
|
||||
tangle.add(msgHash2A, msg2A)
|
||||
t.pass('msg2A comes into awareness')
|
||||
|
||||
const msg4 = FeedV1.create({
|
||||
|
@ -191,7 +191,7 @@ tape('create() handles DAG tips correctly', (t) => {
|
|||
content: { text: '4' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: when + 4,
|
||||
})
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const tape = require('tape')
|
||||
const base58 = require('bs58')
|
||||
const FeedV1 = require('../lib/feed-v1')
|
||||
const Tangle = require('../lib/tangle')
|
||||
const { generateKeypair } = require('./util')
|
||||
|
||||
tape('invalid msg with non-array prev', (t) => {
|
||||
|
@ -9,21 +10,21 @@ tape('invalid msg with non-array prev', (t) => {
|
|||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||
|
||||
const existing = new Map([[rootHash, rootMsg]])
|
||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||
|
||||
const msg = FeedV1.create({
|
||||
keys,
|
||||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: 1652030001000,
|
||||
})
|
||||
msg.metadata.tangles[rootHash].prev = null
|
||||
const msgHash = FeedV1.getMsgHash(msg)
|
||||
|
||||
FeedV1.validate(msg, existing, msgHash, rootHash, (err) => {
|
||||
FeedV1.validate(msg, tangle, msgHash, rootHash, (err) => {
|
||||
t.ok(err, 'invalid 2nd msg throws')
|
||||
t.match(err.message, /prev must be an array/, 'invalid 2nd msg description')
|
||||
t.end()
|
||||
|
@ -36,26 +37,26 @@ tape('invalid msg with bad prev', (t) => {
|
|||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||
|
||||
const existing = new Map([[rootHash, rootMsg]])
|
||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||
|
||||
const msg1 = FeedV1.create({
|
||||
keys,
|
||||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: 1652030001000,
|
||||
})
|
||||
const msgHash1 = FeedV1.getMsgHash(msg1)
|
||||
existing.set(msgHash1, msg1)
|
||||
tangle.add(msgHash1, msg1)
|
||||
|
||||
const msg2 = FeedV1.create({
|
||||
keys,
|
||||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: 1652030002000,
|
||||
})
|
||||
|
@ -63,7 +64,7 @@ tape('invalid msg with bad prev', (t) => {
|
|||
msg2.metadata.tangles[rootHash].prev = [1234]
|
||||
const msgHash2 = FeedV1.getMsgHash(msg2)
|
||||
|
||||
FeedV1.validate(msg2, existing, msgHash2, rootHash, (err) => {
|
||||
FeedV1.validate(msg2, tangle, msgHash2, rootHash, (err) => {
|
||||
t.ok(err, 'invalid 2nd msg throws')
|
||||
t.match(
|
||||
err.message,
|
||||
|
@ -80,26 +81,26 @@ tape('invalid msg with URI in prev', (t) => {
|
|||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||
|
||||
const existing = new Map([[rootHash, rootMsg]])
|
||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||
|
||||
const msg1 = FeedV1.create({
|
||||
keys,
|
||||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: 1652030001000,
|
||||
})
|
||||
const msgHash1 = FeedV1.getMsgHash(msg1)
|
||||
existing.set(msgHash1, msg1)
|
||||
tangle.add(msgHash1, msg1)
|
||||
|
||||
const msg2 = FeedV1.create({
|
||||
keys,
|
||||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: 1652030002000,
|
||||
})
|
||||
|
@ -109,7 +110,7 @@ tape('invalid msg with URI in prev', (t) => {
|
|||
msg2.metadata.tangles[rootHash].depth = 1
|
||||
msg2.metadata.tangles[rootHash].prev = [fakeMsgKey1]
|
||||
|
||||
FeedV1.validate(msg2, existing, msgHash2, rootHash, (err) => {
|
||||
FeedV1.validate(msg2, tangle, msgHash2, rootHash, (err) => {
|
||||
t.ok(err, 'invalid 2nd msg throws')
|
||||
t.match(
|
||||
err.message,
|
||||
|
@ -126,26 +127,26 @@ tape('invalid msg with unknown prev', (t) => {
|
|||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||
|
||||
const existing = new Map([[rootHash, rootMsg]])
|
||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||
|
||||
const msg1 = FeedV1.create({
|
||||
keys,
|
||||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: 1652030001000,
|
||||
})
|
||||
const msgHash1 = FeedV1.getMsgHash(msg1)
|
||||
existing.set(msgHash1, msg1)
|
||||
tangle.add(msgHash1, msg1)
|
||||
|
||||
const unknownMsg = FeedV1.create({
|
||||
keys,
|
||||
content: { text: 'Alien' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: 1652030001000,
|
||||
})
|
||||
|
@ -156,13 +157,16 @@ tape('invalid msg with unknown prev', (t) => {
|
|||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: new Map([[rootHash, rootMsg], [unknownMsgHash, unknownMsg]]),
|
||||
[rootHash]: new Tangle(rootHash, [
|
||||
{ hash: rootHash, msg: rootMsg },
|
||||
{ hash: unknownMsgHash, msg: unknownMsg },
|
||||
]),
|
||||
},
|
||||
when: 1652030002000,
|
||||
})
|
||||
const msgHash2 = FeedV1.getMsgHash(msg2)
|
||||
|
||||
FeedV1.validate(msg2, existing, msgHash2, rootHash, (err) => {
|
||||
FeedV1.validate(msg2, tangle, msgHash2, rootHash, (err) => {
|
||||
t.ok(err, 'invalid 2nd msg throws')
|
||||
t.match(
|
||||
err.message,
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
const tape = require('tape')
|
||||
const FeedV1 = require('../lib/feed-v1')
|
||||
const Tangle = require('../lib/tangle')
|
||||
const { generateKeypair } = require('./util')
|
||||
|
||||
tape('lipmaa prevs', (t) => {
|
||||
const keys = generateKeypair('alice')
|
||||
const content = { text: 'Hello world!' }
|
||||
const when = 1652037377204
|
||||
const existing = new Map()
|
||||
|
||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||
existing.set(rootHash, rootMsg)
|
||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||
|
||||
const msg1 = FeedV1.create({
|
||||
keys,
|
||||
content,
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: when + 1,
|
||||
})
|
||||
const msgHash1 = FeedV1.getMsgHash(msg1)
|
||||
existing.set(msgHash1, msg1)
|
||||
tangle.add(msgHash1, msg1)
|
||||
t.equals(msg1.metadata.tangles[rootHash].depth, 1, 'msg1 depth')
|
||||
t.deepEquals(msg1.metadata.tangles[rootHash].prev, [rootHash], 'msg1 prev')
|
||||
|
||||
|
@ -31,30 +31,26 @@ tape('lipmaa prevs', (t) => {
|
|||
content,
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: when + 2,
|
||||
})
|
||||
const msgHash2 = FeedV1.getMsgHash(msg2)
|
||||
existing.set(msgHash2, msg2)
|
||||
tangle.add(msgHash2, msg2)
|
||||
t.equals(msg2.metadata.tangles[rootHash].depth, 2, 'msg2 depth')
|
||||
t.deepEquals(
|
||||
msg2.metadata.tangles[rootHash].prev,
|
||||
[msgHash1],
|
||||
'msg2 prev'
|
||||
)
|
||||
t.deepEquals(msg2.metadata.tangles[rootHash].prev, [msgHash1], 'msg2 prev')
|
||||
|
||||
const msg3 = FeedV1.create({
|
||||
keys,
|
||||
content,
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: when + 3,
|
||||
})
|
||||
const msgHash3 = FeedV1.getMsgHash(msg3)
|
||||
existing.set(msgHash3, msg3)
|
||||
tangle.add(msgHash3, msg3)
|
||||
t.equals(msg3.metadata.tangles[rootHash].depth, 3, 'msg3 depth')
|
||||
t.deepEquals(
|
||||
msg3.metadata.tangles[rootHash].prev,
|
||||
|
@ -67,66 +63,54 @@ tape('lipmaa prevs', (t) => {
|
|||
content,
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: when + 4,
|
||||
})
|
||||
const msgHash4 = FeedV1.getMsgHash(msg4)
|
||||
existing.set(msgHash4, msg4)
|
||||
tangle.add(msgHash4, msg4)
|
||||
t.equals(msg4.metadata.tangles[rootHash].depth, 4, 'msg4 depth')
|
||||
t.deepEquals(
|
||||
msg4.metadata.tangles[rootHash].prev,
|
||||
[msgHash3],
|
||||
'msg4 prev'
|
||||
)
|
||||
t.deepEquals(msg4.metadata.tangles[rootHash].prev, [msgHash3], 'msg4 prev')
|
||||
|
||||
const msg5 = FeedV1.create({
|
||||
keys,
|
||||
content,
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: when + 5,
|
||||
})
|
||||
const msgHash5 = FeedV1.getMsgHash(msg5)
|
||||
existing.set(msgHash5, msg5)
|
||||
tangle.add(msgHash5, msg5)
|
||||
t.equals(msg5.metadata.tangles[rootHash].depth, 5, 'msg5 depth')
|
||||
t.deepEquals(
|
||||
msg5.metadata.tangles[rootHash].prev,
|
||||
[msgHash4],
|
||||
'msg5 prev'
|
||||
)
|
||||
t.deepEquals(msg5.metadata.tangles[rootHash].prev, [msgHash4], 'msg5 prev')
|
||||
|
||||
const msg6 = FeedV1.create({
|
||||
keys,
|
||||
content,
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: when + 6,
|
||||
})
|
||||
const msgHash6 = FeedV1.getMsgHash(msg6)
|
||||
existing.set(msgHash6, msg6)
|
||||
tangle.add(msgHash6, msg6)
|
||||
t.equals(msg6.metadata.tangles[rootHash].depth, 6, 'msg6 depth')
|
||||
t.deepEquals(
|
||||
msg6.metadata.tangles[rootHash].prev,
|
||||
[msgHash5],
|
||||
'msg6 prev'
|
||||
)
|
||||
t.deepEquals(msg6.metadata.tangles[rootHash].prev, [msgHash5], 'msg6 prev')
|
||||
|
||||
const msg7 = FeedV1.create({
|
||||
keys,
|
||||
content,
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: when + 7,
|
||||
})
|
||||
const msgHash7 = FeedV1.getMsgHash(msg7)
|
||||
existing.set(msgHash7, msg7)
|
||||
tangle.add(msgHash7, msg7)
|
||||
t.equals(msg7.metadata.tangles[rootHash].depth, 7, 'msg7 depth')
|
||||
t.deepEquals(
|
||||
msg7.metadata.tangles[rootHash].prev,
|
||||
|
@ -134,6 +118,5 @@ tape('lipmaa prevs', (t) => {
|
|||
'msg7 prev (has lipmaa!)'
|
||||
)
|
||||
|
||||
|
||||
t.end()
|
||||
})
|
||||
|
|
|
@ -1,27 +1,26 @@
|
|||
const tape = require('tape')
|
||||
const FeedV1 = require('../lib/feed-v1')
|
||||
const Tangle = require('../lib/tangle')
|
||||
const { generateKeypair } = require('./util')
|
||||
|
||||
tape('simple multi-author tangle', (t) => {
|
||||
const keysA = generateKeypair('alice')
|
||||
const keysB = generateKeypair('bob')
|
||||
const existingA = new Map()
|
||||
const existingB = new Map()
|
||||
|
||||
const rootMsgA = FeedV1.createRoot(keysA, 'post')
|
||||
const rootHashA = FeedV1.getMsgHash(rootMsgA)
|
||||
existingA.set(rootHashA, rootMsgA)
|
||||
const tangleA = new Tangle(rootHashA, [{ hash: rootHashA, msg: rootMsgA }])
|
||||
|
||||
const rootMsgB = FeedV1.createRoot(keysB, 'post')
|
||||
const rootHashB = FeedV1.getMsgHash(rootMsgB)
|
||||
existingB.set(rootHashB, rootMsgB)
|
||||
const tangleB = new Tangle(rootHashB, [{ hash: rootHashB, msg: rootMsgB }])
|
||||
|
||||
const msg1 = FeedV1.create({
|
||||
keys: keysA,
|
||||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHashA]: existingA,
|
||||
[rootHashA]: tangleA,
|
||||
},
|
||||
when: 1652030001000,
|
||||
})
|
||||
|
@ -36,10 +35,9 @@ tape('simple multi-author tangle', (t) => {
|
|||
keys: keysB,
|
||||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
existing: new Map(),
|
||||
tangles: {
|
||||
[rootHashB]: existingB,
|
||||
[msgHash1]: new Map([[msgHash1, msg1]]),
|
||||
[rootHashB]: tangleB,
|
||||
[msgHash1]: new Tangle(msgHash1, [{ hash: msgHash1, msg: msg1 }]),
|
||||
},
|
||||
when: 1652030002000,
|
||||
})
|
||||
|
@ -72,48 +70,47 @@ tape('lipmaa in multi-author tangle', (t) => {
|
|||
|
||||
const content = { text: 'Hello world!' }
|
||||
const when = 1652037377204
|
||||
const existingA = new Map()
|
||||
const existingB = new Map()
|
||||
const tangleExisting = new Map()
|
||||
|
||||
const rootMsgA = FeedV1.createRoot(keysA, 'post')
|
||||
const rootHashA = FeedV1.getMsgHash(rootMsgA)
|
||||
existingA.set(rootHashA, rootMsgA)
|
||||
const tangleA = new Tangle(rootHashA, [{ hash: rootHashA, msg: rootMsgA }])
|
||||
|
||||
const rootMsgB = FeedV1.createRoot(keysB, 'post')
|
||||
const rootHashB = FeedV1.getMsgHash(rootMsgB)
|
||||
existingB.set(rootHashB, rootMsgB)
|
||||
|
||||
const tangleB = new Tangle(rootHashB, [{ hash: rootHashB, msg: rootMsgB }])
|
||||
|
||||
const msg1 = FeedV1.create({
|
||||
keys: keysA,
|
||||
content,
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHashA]: existingA,
|
||||
[rootHashA]: tangleA,
|
||||
},
|
||||
when: when + 1,
|
||||
})
|
||||
const msgHash1 = FeedV1.getMsgHash(msg1)
|
||||
existingA.set(msgHash1, msg1)
|
||||
tangleExisting.set(msgHash1, msg1)
|
||||
tangleA.add(msgHash1, msg1)
|
||||
const tangleThread = new Tangle(msgHash1, [{ hash: msgHash1, msg: msg1 }])
|
||||
|
||||
t.deepEquals(Object.keys(msg1.metadata.tangles),[rootHashA], 'A:msg1 has only feed tangle')
|
||||
t.deepEquals(
|
||||
Object.keys(msg1.metadata.tangles),
|
||||
[rootHashA],
|
||||
'A:msg1 has only feed tangle'
|
||||
)
|
||||
|
||||
const msg2 = FeedV1.create({
|
||||
keys: keysB,
|
||||
content,
|
||||
type: 'post',
|
||||
existing: existingB,
|
||||
tangles: {
|
||||
[rootHashB]: existingB,
|
||||
[msgHash1]: tangleExisting,
|
||||
[rootHashB]: tangleB,
|
||||
[msgHash1]: tangleThread,
|
||||
},
|
||||
when: when + 2,
|
||||
})
|
||||
const msgHash2 = FeedV1.getMsgHash(msg2)
|
||||
existingB.set(msgHash2, msg2)
|
||||
tangleExisting.set(msgHash2, msg2)
|
||||
tangleB.add(msgHash2, msg2)
|
||||
tangleThread.add(msgHash2, msg2)
|
||||
|
||||
t.deepEquals(
|
||||
msg2.metadata.tangles[msgHash1].prev,
|
||||
|
@ -125,16 +122,15 @@ tape('lipmaa in multi-author tangle', (t) => {
|
|||
keys: keysB,
|
||||
content,
|
||||
type: 'post',
|
||||
existing: existingB,
|
||||
tangles: {
|
||||
[rootHashB]: existingB,
|
||||
[msgHash1]: tangleExisting,
|
||||
[rootHashB]: tangleB,
|
||||
[msgHash1]: tangleThread,
|
||||
},
|
||||
when: when + 3,
|
||||
})
|
||||
const msgHash3 = FeedV1.getMsgHash(msg3)
|
||||
existingB.set(msgHash3, msg3)
|
||||
tangleExisting.set(msgHash3, msg3)
|
||||
tangleB.add(msgHash3, msg3)
|
||||
tangleThread.add(msgHash3, msg3)
|
||||
|
||||
t.deepEquals(
|
||||
msg3.metadata.tangles[msgHash1].prev,
|
||||
|
@ -146,16 +142,15 @@ tape('lipmaa in multi-author tangle', (t) => {
|
|||
keys: keysA,
|
||||
content,
|
||||
type: 'post',
|
||||
existing: existingA,
|
||||
tangles: {
|
||||
[rootHashA]: existingA,
|
||||
[msgHash1]: tangleExisting,
|
||||
[rootHashA]: tangleA,
|
||||
[msgHash1]: tangleThread,
|
||||
},
|
||||
when: when + 4,
|
||||
})
|
||||
const msgHash4 = FeedV1.getMsgHash(msg4)
|
||||
existingB.set(msgHash4, msg4)
|
||||
tangleExisting.set(msgHash4, msg4)
|
||||
tangleB.add(msgHash4, msg4)
|
||||
tangleThread.add(msgHash4, msg4)
|
||||
|
||||
t.deepEquals(
|
||||
msg4.metadata.tangles[msgHash1].prev,
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
const tape = require('tape')
|
||||
const base58 = require('bs58')
|
||||
const FeedV1 = require('../lib/feed-v1')
|
||||
const Tangle = require('../lib/tangle')
|
||||
const { generateKeypair } = require('./util')
|
||||
|
||||
tape('validate root msg', (t) => {
|
||||
const keys = generateKeypair('alice')
|
||||
const existing = new Map()
|
||||
|
||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||
existing.set(rootHash, rootMsg)
|
||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||
|
||||
FeedV1.validate(rootMsg, existing, rootHash, rootHash, (err) => {
|
||||
FeedV1.validate(rootMsg, tangle, rootHash, rootHash, (err) => {
|
||||
if (err) console.log(err)
|
||||
t.error(err, 'valid root msg')
|
||||
t.end()
|
||||
|
@ -20,25 +20,24 @@ tape('validate root msg', (t) => {
|
|||
|
||||
tape('validate 2nd msg with existing root', (t) => {
|
||||
const keys = generateKeypair('alice')
|
||||
const existing = new Map()
|
||||
|
||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||
existing.set(rootHash, rootMsg)
|
||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||
|
||||
const msg1 = FeedV1.create({
|
||||
keys,
|
||||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: 1652030001000,
|
||||
})
|
||||
const msgHash1 = FeedV1.getMsgHash(msg1)
|
||||
existing.set(msgHash1, msg1)
|
||||
tangle.add(msgHash1, msg1)
|
||||
|
||||
FeedV1.validate(msg1, existing, msgHash1, rootHash, (err) => {
|
||||
FeedV1.validate(msg1, tangle, msgHash1, rootHash, (err) => {
|
||||
if (err) console.log(err)
|
||||
t.error(err, 'valid 2nd msg')
|
||||
t.end()
|
||||
|
@ -48,18 +47,16 @@ tape('validate 2nd msg with existing root', (t) => {
|
|||
tape('validate 2nd forked msg', (t) => {
|
||||
const keys = generateKeypair('alice')
|
||||
|
||||
const existing = new Map()
|
||||
|
||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||
existing.set(rootHash, rootMsg)
|
||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||
|
||||
const msg1A = FeedV1.create({
|
||||
keys,
|
||||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
existing: new Map(),
|
||||
when: 1652030001000,
|
||||
|
@ -71,15 +68,15 @@ tape('validate 2nd forked msg', (t) => {
|
|||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: 1652030002000,
|
||||
})
|
||||
const msgHash1B = FeedV1.getMsgHash(msg1B)
|
||||
|
||||
existing.set(msgHash1A, msg1A)
|
||||
existing.set(msgHash1B, msg1B)
|
||||
FeedV1.validate(msg1B, existing, msgHash1B, rootHash, (err) => {
|
||||
tangle.add(msgHash1A, msg1A)
|
||||
tangle.add(msgHash1B, msg1B)
|
||||
FeedV1.validate(msg1B, tangle, msgHash1B, rootHash, (err) => {
|
||||
if (err) console.log(err)
|
||||
t.error(err, 'valid 2nd forked msg')
|
||||
t.end()
|
||||
|
@ -89,18 +86,16 @@ tape('validate 2nd forked msg', (t) => {
|
|||
tape('invalid msg with unknown previous', (t) => {
|
||||
const keys = generateKeypair('alice')
|
||||
|
||||
const existing = new Map()
|
||||
|
||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||
existing.set(rootHash, rootMsg)
|
||||
const tangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||
|
||||
const msg1 = FeedV1.create({
|
||||
keys,
|
||||
content: { text: 'Hello world!' },
|
||||
type: 'post',
|
||||
tangles: {
|
||||
[rootHash]: existing,
|
||||
[rootHash]: tangle,
|
||||
},
|
||||
when: 1652030001000,
|
||||
})
|
||||
|
@ -110,7 +105,7 @@ tape('invalid msg with unknown previous', (t) => {
|
|||
|
||||
msg1.metadata.tangles[rootHash].prev = [fakeMsgHash]
|
||||
|
||||
FeedV1.validate(msg1, existing, msgHash1, rootHash, (err) => {
|
||||
FeedV1.validate(msg1, tangle, msgHash1, rootHash, (err) => {
|
||||
t.ok(err, 'invalid 2nd msg throws')
|
||||
t.match(
|
||||
err.message,
|
||||
|
|
Loading…
Reference in New Issue