some breaking change renaming

msgHash => msgID
Feed root => moot
rec.hash => rec.id
This commit is contained in:
Andre Staltz 2023-08-28 15:14:15 +03:00
parent c06828cd99
commit c76584953b
No known key found for this signature in database
GPG Key ID: 9EDE23EA7E8A4890
24 changed files with 549 additions and 607 deletions

View File

@ -64,7 +64,7 @@ function decrypt(rec, peer, config) {
const msgDecrypted = MsgV3.fromPlaintextBuffer(plaintextBuf, msgEncrypted)
return {
hash: rec.hash,
id: rec.id,
msg: msgDecrypted,
received: rec.received,
misc: {
@ -78,20 +78,18 @@ function decrypt(rec, peer, config) {
/**
* @param {RecPresent} rec
* @returns {RecPresent}
*/
function reEncrypt(rec) {
return {
hash: rec.hash,
id: rec.id,
msg: { ...rec.msg, data: rec.misc.originalData },
received: rec.received,
...(rec.misc.size
? {
misc: {
offset: rec.misc.offset,
size: rec.misc.size,
},
}
: null),
misc: {
seq: rec.misc.seq,
offset: rec.misc.offset,
size: rec.misc.size,
},
}
}

View File

@ -31,7 +31,7 @@ const { decrypt } = require('./encryption')
/**
* @typedef {{
* hash?: never;
* id?: never;
* msg?: never;
* received?: never;
* misc: {
@ -42,7 +42,7 @@ const { decrypt } = require('./encryption')
* }} RecDeleted
*
* @typedef {{
* hash: string;
* id: string;
* msg: Msg;
* received: number;
* misc: {
@ -69,26 +69,26 @@ const { decrypt } = require('./encryption')
class DBTangle extends MsgV3.Tangle {
/**
* @param {string} rootHash
* @param {string} rootID
* @param {Iterable<Rec>} recordsIter
*/
constructor(rootHash, recordsIter) {
super(rootHash)
constructor(rootID, recordsIter) {
super(rootID)
for (const rec of recordsIter) {
if (!rec.msg) continue
this.add(rec.hash, rec.msg)
this.add(rec.id, rec.msg)
}
}
/**
* @param {string} msgHash
* @param {string} msgID
*/
getDeletablesAndErasables(msgHash) {
const erasables = this.shortestPathToRoot(msgHash)
getDeletablesAndErasables(msgID) {
const erasables = this.shortestPathToRoot(msgID)
const sorted = this.topoSort()
const index = sorted.indexOf(msgHash)
const index = sorted.indexOf(msgID)
const deletables = sorted.filter(
(msgHash, i) => i < index && !erasables.includes(msgHash)
(id, i) => i < index && !erasables.includes(id)
)
return { deletables, erasables }
}
@ -180,14 +180,14 @@ function initDB(peer, config) {
})
/**
* @param {string} hash
* @param {string} id
* @param {Msg} msg
* @param {CB<Rec>} cb
* @param {CB<RecPresent>} cb
*/
function logAppend(hash, msg, cb) {
function logAppend(id, msg, cb) {
/** @type {RecPresent} */
const rec = {
hash,
id,
msg,
received: Date.now(),
misc: {
@ -244,13 +244,13 @@ function initDB(peer, config) {
}
/**
* @param {Array<string>} tangleIds
* @param {Array<string>} tangleIDs
*/
function populateTangles(tangleIds) {
function populateTangles(tangleIDs) {
/** @type {Record<string, DBTangle>} */
const tangles = {}
for (const tangleId of tangleIds) {
tangles[tangleId] ??= new DBTangle(tangleId, records())
for (const tangleID of tangleIDs) {
tangles[tangleID] ??= new DBTangle(tangleID, records())
}
return tangles
}
@ -265,21 +265,21 @@ function initDB(peer, config) {
/**
* @param {Msg} msg
* @param {string} tangleRootHash
* @param {CB<Rec>} cb
* @param {string} tangleID
* @param {CB<RecPresent>} cb
*/
function add(msg, tangleRootHash, cb) {
const msgHash = MsgV3.getMsgHash(msg)
function add(msg, tangleID, cb) {
const msgID = MsgV3.getMsgID(msg)
// TODO: optimize this. Perhaps have a Map() of msgHash -> record
// TODO: optimize this. Perhaps have a Map() of msgID -> record
// Or even better, a bloom filter. If you just want to answer no/perhaps.
let rec
if ((rec = getRecord(msgHash))) return cb(null, rec)
else rec = { msg, hash: msgHash }
if ((rec = getRecord(msgID))) return cb(null, rec)
else rec = { msg, id: msgID }
// TODO: optimize this. This may be slow if you're adding many msgs in a
// row, because it creates a new Map() each time. Perhaps with QuickLRU
const tangle = new DBTangle(tangleRootHash, records())
const tangle = new DBTangle(tangleID, records())
// Find which pubkeys are authorized to sign this msg given the account:
const pubkeys = new Set()
@ -292,8 +292,8 @@ function initDB(peer, config) {
return cb(new Error('add() failed because the account tangle is unknown'))
}
// TODO: prune the accountTangle beyond msg.metadata.accountTips
for (const msgHash of accountTangle.topoSort()) {
const msg = get(msgHash)
for (const msgID of accountTangle.topoSort()) {
const msg = get(msgID)
if (!msg?.data) continue
/** @type {AccountData} */
const data = msg.data
@ -305,7 +305,7 @@ function initDB(peer, config) {
}
let err
if ((err = MsgV3.validate(msg, tangle, pubkeys, msgHash, tangleRootHash))) {
if ((err = MsgV3.validate(msg, tangle, pubkeys, msgID, tangleID))) {
return cb(new Error('add() failed msg validation', { cause: err }))
}
@ -325,7 +325,7 @@ function initDB(peer, config) {
// TODO validate 'del'
}
logAppend(msgHash, msg, (err, rec) => {
logAppend(msgID, msg, (err, rec) => {
if (err) return cb(new Error('add() failed in the log', { cause: err }))
onRecordAdded.set(rec)
cb(null, rec)
@ -340,31 +340,30 @@ function initDB(peer, config) {
const keypair = opts.keypair ?? config.keypair
const { account, domain } = opts
const feedRootHash = getFeedId(account, domain)
if (feedRootHash) return cb(null, feedRootHash)
const mootID = getFeedID(account, domain)
if (mootID) return cb(null, mootID)
const feedRoot = MsgV3.createRoot(account, domain, keypair)
add(feedRoot, MsgV3.getMsgHash(feedRoot), (err, rec) => {
const moot = MsgV3.createMoot(account, domain, keypair)
add(moot, MsgV3.getMsgID(moot), (err, rec) => {
// prettier-ignore
if (err) return cb(new Error('initializeFeed() failed to add root', { cause: err }));
const recHash = /** @type {string} */ (rec.hash)
cb(null, recHash)
cb(null, rec.id)
})
}
/**
* Public the account ID from the given record.
*
* @param {Pick<RecPresent, 'msg' | 'hash'>} rec
* @param {Pick<RecPresent, 'msg' | 'id'>} rec
* @returns {string | null}
*/
function getAccountID(rec) {
if (!rec.msg) return null
if (rec.msg.metadata.account === ACCOUNT_SELF) {
for (const tangleId in rec.msg.metadata.tangles) {
return tangleId
for (const tangleID in rec.msg.metadata.tangles) {
return tangleID
}
return rec.hash
return rec.id
} else if (rec.msg.metadata.account) {
return rec.msg.metadata.account
} else {
@ -398,9 +397,9 @@ function initDB(peer, config) {
if (rec.msg.metadata.domain !== domain) continue
const data = /** @type {AccountData} */ (rec.msg.data)
if (data.action === 'add' && data.add.key.bytes === keypair.public) {
const accountId = getAccountID(rec)
if (accountId) {
cb(null, accountId)
const accountID = getAccountID(rec)
if (accountID) {
cb(null, accountID)
} else {
// prettier-ignore
cb(new Error(`account.find() failed to find ID in ${JSON.stringify(rec.msg)}`))
@ -427,8 +426,8 @@ function initDB(peer, config) {
const keypair = opts?.keypair ?? config.keypair
const accountTangle = new DBTangle(opts.account, records())
for (const msgHash of accountTangle.topoSort()) {
const msg = get(msgHash)
for (const msgID of accountTangle.topoSort()) {
const msg = get(msgID)
if (!msg?.data) continue
/** @type {AccountData} */
const data = msg.data
@ -465,14 +464,13 @@ function initDB(peer, config) {
} catch (err) {
return cb(new Error('account.create() failed', { cause: err }))
}
const msgHash = MsgV3.getMsgHash(msg)
const msgID = MsgV3.getMsgID(msg)
logAppend(msgHash, msg, (err, rec) => {
logAppend(msgID, msg, (err, rec) => {
// prettier-ignore
if (err) return cb(new Error('account.create() failed in the log', { cause: err }))
onRecordAdded.set(rec)
const recHash = /** @type {string} */ (rec.hash)
cb(null, recHash)
cb(null, rec.id)
})
}
@ -507,8 +505,8 @@ function initDB(peer, config) {
*/
function getAccountPowers(accountTangle, keypair) {
const powers = new Set()
for (const msgHash of accountTangle.topoSort()) {
const msg = get(msgHash)
for (const msgID of accountTangle.topoSort()) {
const msg = get(msgID)
if (!msg?.data) continue
/** @type {AccountData} */
const data = msg.data
@ -564,7 +562,7 @@ function initDB(peer, config) {
* keypair: Keypair;
* consent?: never;
* })} opts
* @param {CB<Rec>} cb
* @param {CB<RecPresent>} cb
*/
function addToAccount(opts, cb) {
if (!opts) return cb(new Error('account.add() requires an `opts`'))
@ -659,9 +657,9 @@ function initDB(peer, config) {
} catch (err) {
return cb(new Error('account.add() failed', { cause: err }))
}
const msgHash = MsgV3.getMsgHash(msg)
const msgID = MsgV3.getMsgID(msg)
logAppend(msgHash, msg, (err, rec) => {
logAppend(msgID, msg, (err, rec) => {
// prettier-ignore
if (err) return cb(new Error('account.add() failed to append the log', { cause: err }))
onRecordAdded.set(rec)
@ -678,7 +676,7 @@ function initDB(peer, config) {
* account: string;
* tangles?: Array<string>;
* }} opts
* @param {CB<Rec>} cb
* @param {CB<RecPresent>} cb
*/
function publishToFeed(opts, cb) {
if (!opts) return cb(new Error('feed.publish() requires an `opts`'))
@ -695,13 +693,13 @@ function initDB(peer, config) {
if (!opts.account)
return cb(new Error('feed.publish() requires a `account`'))
initializeFeed(opts, (err, feedRootHash) => {
initializeFeed(opts, (err, mootID) => {
// prettier-ignore
if (err) return cb(new Error('feed.publish() failed to initialize feed', { cause: err }));
// Fill-in tangle opts:
const tangleTemplates = opts.tangles ?? []
tangleTemplates.push(feedRootHash)
tangleTemplates.push(mootID)
const tangles = populateTangles(tangleTemplates)
const accountTangle = new DBTangle(opts.account, records())
const accountTips = [...accountTangle.getTips()]
@ -746,10 +744,10 @@ function initDB(peer, config) {
} catch (err) {
return cb(new Error('feed.publish() failed', { cause: err }))
}
const msgHash = MsgV3.getMsgHash(msg)
const msgID = MsgV3.getMsgID(msg)
// Encode the native message and append it to the log:
logAppend(msgHash, msg, (err, rec) => {
logAppend(msgID, msg, (err, rec) => {
// prettier-ignore
if (err) return cb(new Error('feed.publish() failed to append the log', { cause: err }))
onRecordAdded.set(rec)
@ -762,45 +760,46 @@ function initDB(peer, config) {
* @param {string} id
* @param {string} findDomain
*/
function getFeedId(id, findDomain) {
function getFeedID(id, findDomain) {
const findAccount = MsgV3.stripAccount(id)
for (const rec of records()) {
if (rec.msg && MsgV3.isFeedRoot(rec.msg, findAccount, findDomain)) {
return rec.hash
if (rec.msg && MsgV3.isMoot(rec.msg, findAccount, findDomain)) {
return rec.id
}
}
return null
}
/**
* @param {string} msgId
* @param {string} msgID
* @returns {RecPresent | null}
*/
function getRecord(msgId) {
function getRecord(msgID) {
// TODO: improve performance of this when getting many messages, the arg
// could be an array of hashes, so we can do a single pass over the records.
const isUri = msgId.startsWith('ppppp:')
const isUri = msgID.startsWith('ppppp:')
for (let i = 0; i < recs.length; i++) {
const rec = recs[i]
if (!rec) continue
if (isUri && rec.hash && msgId.endsWith(rec.hash)) return rec
else if (!isUri && rec.hash === msgId) return rec
if (isUri && rec.id && msgID.endsWith(rec.id)) return rec
else if (!isUri && rec.id === msgID) return rec
}
return null
}
/**
* @param {string} msgId
* @param {string} msgID
*/
function get(msgId) {
return getRecord(msgId)?.msg
function get(msgID) {
return getRecord(msgID)?.msg
}
/**
* @param {string} msgId
* @param {string} msgID
* @param {CBVoid} cb
*/
function del(msgId, cb) {
const rec = getRecord(msgId)
function del(msgID, cb) {
const rec = getRecord(msgID)
if (!rec) return cb()
if (!rec.msg) return cb()
const { offset, size, seq } = rec.misc
@ -811,11 +810,11 @@ function initDB(peer, config) {
}
/**
* @param {string} msgId
* @param {string} msgID
* @param {CBVoid} cb
*/
function erase(msgId, cb) {
const rec = getRecord(msgId)
function erase(msgID, cb) {
const rec = getRecord(msgID)
if (!rec) return cb()
if (!rec.msg) return cb()
if (!rec.msg.data) return cb()
@ -825,11 +824,11 @@ function initDB(peer, config) {
}
/**
* @param {string} tangleId
* @param {string} tangleID
* @returns {DBTangle}
*/
function getTangle(tangleId) {
return new DBTangle(tangleId, records())
function getTangle(tangleID) {
return new DBTangle(tangleID, records())
}
function* msgs() {
@ -861,7 +860,7 @@ function initDB(peer, config) {
},
feed: {
publish: publishToFeed,
getId: getFeedId,
getID: getFeedID,
},
getRecord,
get,

View File

@ -23,7 +23,7 @@ function getMsgHashBuf(msg) {
* @param {Msg | string} x
* @returns {string}
*/
function getMsgHash(x) {
function getMsgID(x) {
if (typeof x === 'string') {
if (x.startsWith('ppppp:message/v3/')) {
const msgUri = x
@ -44,9 +44,9 @@ function getMsgHash(x) {
* @param {Msg} msg
* @returns {string}
*/
function getMsgId(msg) {
function getMsgURI(msg) {
const { account, domain } = msg.metadata
const msgHash = getMsgHash(msg)
const msgHash = getMsgID(msg)
if (domain) {
return `ppppp:message/v3/${account}/${domain}/${msgHash}`
} else {
@ -54,4 +54,4 @@ function getMsgId(msg) {
}
}
module.exports = { getMsgId, getMsgHash }
module.exports = { getMsgURI, getMsgID }

View File

@ -7,14 +7,14 @@ const Keypair = require('ppppp-keypair')
// @ts-ignore
const union = require('set.prototype.union')
const { stripAccount } = require('./strip')
const isFeedRoot = require('./is-feed-root')
const { getMsgId, getMsgHash } = require('./get-msg-id')
const isMoot = require('./is-moot')
const { getMsgID } = require('./get-msg-id')
const representData = require('./represent-data')
const {
validateDomain,
validateData,
validate,
validateMsgHash,
validateMsgID,
} = require('./validation')
const Tangle = require('./tangle')
const {
@ -101,7 +101,7 @@ const { isEmptyObject } = require('./util')
* @param {string} domain
* @returns {string}
*/
function getFeedRootHash(id, domain) {
function getMootID(id, domain) {
/** @type {Msg} */
const msg = {
data: null,
@ -118,7 +118,7 @@ function getFeedRootHash(id, domain) {
sig: '',
}
return getMsgHash(msg)
return getMsgID(msg)
}
/**
@ -144,18 +144,18 @@ function create(opts) {
const tangles = /** @type {Msg['metadata']['tangles']} */ ({})
if (opts.tangles) {
for (const rootId in opts.tangles) {
if ((err = validateMsgHash(rootId))) throw err
const tangle = opts.tangles[rootId]
for (const rootID in opts.tangles) {
if ((err = validateMsgID(rootID))) throw err
const tangle = opts.tangles[rootID]
const depth = tangle.getMaxDepth() + 1
const tips = tangle.getTips()
const lipmaaSet = tangle.getLipmaaSet(depth)
const prev = [...union(lipmaaSet, tips)].sort()
tangles[rootId] = { depth, prev }
tangles[rootID] = { depth, prev }
}
} else {
// prettier-ignore
throw new Error(`cannot create msg without tangles, that's the case for createRoot()`)
throw new Error(`cannot create msg without tangles, that's the case for createMoot()`)
}
/** @type {Msg} */
@ -190,7 +190,7 @@ function create(opts) {
* @param {Keypair} keypair
* @returns {Msg}
*/
function createRoot(id, domain, keypair) {
function createMoot(id, domain, keypair) {
let err
if ((err = validateDomain(domain))) throw err
@ -279,18 +279,17 @@ function isRoot(msg) {
}
module.exports = {
getMsgHash,
getMsgId,
isFeedRoot,
getFeedRootHash,
isMoot,
isRoot,
getMsgID,
getMootID,
create,
createRoot,
createMoot,
createAccount,
erase,
stripAccount,
toPlaintextBuffer,
fromPlaintextBuffer,
isRoot,
Tangle,
validate,
}

View File

@ -10,7 +10,7 @@ const { isEmptyObject } = require('./util')
* @param {string | 0} id
* @param {string | 0} findDomain
*/
function isFeedRoot(msg, id = 0, findDomain = 0) {
function isMoot(msg, id = 0, findDomain = 0) {
const { dataHash, dataSize, account, accountTips, tangles, domain } =
msg.metadata
if (dataHash !== null) return false
@ -23,4 +23,4 @@ function isFeedRoot(msg, id = 0, findDomain = 0) {
return true
}
module.exports = isFeedRoot
module.exports = isMoot

View File

@ -1,25 +1,7 @@
const { getMsgHash } = require('./get-msg-id')
/**
* @typedef {import('.').Msg} Msg
*/
/**
* @param {any} msgKey
*/
function stripMsgKey(msgKey) {
if (typeof msgKey === 'object') {
if (msgKey.key) return stripMsgKey(msgKey.key)
else return getMsgHash(msgKey)
}
if (msgKey.startsWith('ppppp:message/v3/')) {
const parts = msgKey.split('/')
return parts[parts.length - 1]
} else {
return msgKey
}
}
/**
* @param {string} id
* @returns {string}
@ -31,6 +13,5 @@ function stripAccount(id) {
}
module.exports = {
stripMsgKey,
stripAccount,
}

View File

@ -1,3 +1,5 @@
const isMoot = require('./is-moot')
/**
* @typedef {import("./index").Msg} Msg
*/
@ -38,7 +40,7 @@ function lipmaa(n) {
* @param {string} b
* @returns number
*/
function compareMsgHashes(a, b) {
function compareMsgIDs(a, b) {
return a.localeCompare(b)
}
@ -46,7 +48,7 @@ class Tangle {
/**
* @type {string}
*/
#rootHash
#rootID
/**
* @type {Msg | undefined}
@ -79,41 +81,41 @@ class Tangle {
#maxDepth
/**
* @param {string} rootHash
* @param {string} rootID
*/
constructor(rootHash) {
this.#rootHash = rootHash
constructor(rootID) {
this.#rootID = rootID
this.#maxDepth = 0
}
/**
* @param {string} msgHash
* @param {string} msgID
* @param {Msg} msg
*/
add(msgHash, msg) {
if (msgHash === this.#rootHash && !this.#rootMsg) {
this.#tips.add(msgHash)
this.#perDepth.set(0, [msgHash])
this.#depth.set(msgHash, 0)
add(msgID, msg) {
if (msgID === this.#rootID && !this.#rootMsg) {
this.#tips.add(msgID)
this.#perDepth.set(0, [msgID])
this.#depth.set(msgID, 0)
this.#rootMsg = msg
return
}
const tangles = msg.metadata.tangles
if (msgHash !== this.#rootHash && tangles[this.#rootHash]) {
if (this.#depth.has(msgHash)) return
this.#tips.add(msgHash)
const prev = tangles[this.#rootHash].prev
if (msgID !== this.#rootID && tangles[this.#rootID]) {
if (this.#depth.has(msgID)) return
this.#tips.add(msgID)
const prev = tangles[this.#rootID].prev
for (const p of prev) {
this.#tips.delete(p)
}
this.#prev.set(msgHash, prev)
const depth = tangles[this.#rootHash].depth
this.#prev.set(msgID, prev)
const depth = tangles[this.#rootID].depth
if (depth > this.#maxDepth) this.#maxDepth = depth
this.#depth.set(msgHash, depth)
this.#depth.set(msgID, depth)
const atDepth = this.#perDepth.get(depth) ?? []
atDepth.push(msgHash)
atDepth.sort(compareMsgHashes)
atDepth.push(msgID)
atDepth.sort(compareMsgIDs)
this.#perDepth.set(depth, atDepth)
return
}
@ -139,8 +141,8 @@ class Tangle {
const max = this.#maxDepth
for (let i = 0; i <= max; i++) {
const atDepth = this.#getAllAtDepth(i)
for (const msgHash of atDepth) {
sorted.push(msgHash)
for (const msgID of atDepth) {
sorted.push(msgID)
}
}
return sorted
@ -171,19 +173,19 @@ class Tangle {
}
/**
* @param {string} msgHash
* @param {string} msgID
* @returns {boolean}
*/
has(msgHash) {
return this.#depth.has(msgHash)
has(msgID) {
return this.#depth.has(msgID)
}
/**
* @param {string} msgHash
* @param {string} msgID
* @returns {number}
*/
getDepth(msgHash) {
return this.#depth.get(msgHash) ?? -1
getDepth(msgID) {
return this.#depth.get(msgID) ?? -1
}
isFeed() {
@ -191,34 +193,29 @@ class Tangle {
console.trace('Tangle is missing root message')
return false
}
if (this.#rootMsg.data) return false
const metadata = this.#rootMsg.metadata
if (metadata.dataSize > 0) return false
if (metadata.dataHash !== null) return false
if (metadata.accountTips !== null) return false
return true
return isMoot(this.#rootMsg)
}
getFeed() {
getMoot() {
if (!this.isFeed()) return null
if (!this.#rootMsg) {
console.trace('Tangle is missing root message')
return null
}
const { account, domain } = this.#rootMsg.metadata
return { account, domain }
return { account, domain, id: this.#rootID }
}
/**
* @param {string} msgHash
* @param {string} msgID
*/
shortestPathToRoot(msgHash) {
shortestPathToRoot(msgID) {
if (!this.#rootMsg) {
console.trace('Tangle is missing root message')
return []
}
const path = []
let current = msgHash
let current = msgID
while (true) {
const prev = this.#prev.get(current)
if (!prev) break
@ -229,7 +226,7 @@ class Tangle {
if (d < minDepth) {
minDepth = d
min = p
} else if (d === minDepth && compareMsgHashes(p, min) < 0) {
} else if (d === minDepth && compareMsgIDs(p, min) < 0) {
min = p
}
}
@ -240,21 +237,21 @@ class Tangle {
}
/**
* @param {string} msgHashA
* @param {string} msgHashB
* @param {string} msgAID
* @param {string} msgBID
*/
precedes(msgHashA, msgHashB) {
precedes(msgAID, msgBID) {
if (!this.#rootMsg) {
console.trace('Tangle is missing root message')
return false
}
if (msgHashA === msgHashB) return false
if (msgHashB === this.#rootHash) return false
let toCheck = [msgHashB]
if (msgAID === msgBID) return false
if (msgBID === this.#rootID) return false
let toCheck = [msgBID]
while (toCheck.length > 0) {
const prev = this.#prev.get(/** @type {string} */ (toCheck.shift()))
if (!prev) continue
if (prev.includes(msgHashA)) return true
if (prev.includes(msgAID)) return true
toCheck.push(...prev)
}
return false

View File

@ -5,7 +5,7 @@ const Keypair = require('ppppp-keypair')
const stringify = require('json-canon')
const Tangle = require('./tangle')
const representData = require('./represent-data')
const isFeedRoot = require('./is-feed-root')
const isMoot = require('./is-moot')
const { SIGNATURE_TAG_MSG_V3, ACCOUNT_SELF } = require('./constants')
/**
@ -87,7 +87,7 @@ function validatePubkey(msg) {
*/
function validateAccountPubkey(msg, pubkeys) {
// Unusual case: if the msg is a feed root, ignore the account and pubkey
if (isFeedRoot(msg)) return
if (isMoot(msg)) return
if (
msg.metadata.account &&
@ -103,7 +103,7 @@ function validateAccountPubkey(msg, pubkeys) {
* @param {string} str
* @returns {string | undefined}
*/
function validateMsgHash(str) {
function validateMsgID(str) {
try {
const hashBuf = b4a.from(base58.decode(str))
if (hashBuf.length !== 16) {
@ -111,7 +111,7 @@ function validateMsgHash(str) {
return `invalid message: decoded hash should be 16 bytes but was ${hashBuf.length}`
}
} catch (err) {
return `invalid message: msgHash "${str}" should have been a base58 string`
return `invalid message: msgID "${str}" should have been a base58 string`
}
}
@ -163,21 +163,21 @@ function validateSignature(msg) {
}
/**
* @typedef {NonNullable<ReturnType<Tangle['getFeed']>>} FeedDetails
* @typedef {NonNullable<ReturnType<Tangle['getMoot']>>} FeedDetails
*/
/**
* @param {Msg} msg
* @param {Tangle} tangle
* @param {string} tangleId
* @param {string} tangleID
* @returns
*/
function validateTangle(msg, tangle, tangleId) {
if (!msg.metadata.tangles[tangleId]) {
function validateTangle(msg, tangle, tangleID) {
if (!msg.metadata.tangles[tangleID]) {
// prettier-ignore
return `invalid message: must have metadata.tangles.${tangleId}\n` + JSON.stringify(msg)
return `invalid message: must have metadata.tangles.${tangleID}\n` + JSON.stringify(msg)
}
const { depth, prev } = msg.metadata.tangles[tangleId]
const { depth, prev } = msg.metadata.tangles[tangleID]
if (!prev || !Array.isArray(prev)) {
// prettier-ignore
return `invalid message: prev "${prev}" should have been an array\n` + JSON.stringify(msg)
@ -187,7 +187,7 @@ function validateTangle(msg, tangle, tangleId) {
return `invalid message: depth "${depth}" should have been a positive integer\n` + JSON.stringify(msg)
}
if (tangle.isFeed()) {
const { account, domain } = /** @type {FeedDetails} */ (tangle.getFeed())
const { account, domain } = /** @type {FeedDetails} */ (tangle.getMoot())
if (domain !== msg.metadata.domain) {
// prettier-ignore
return `invalid message: domain "${msg.metadata.domain}" should have been feed domain "${domain}"\n` + JSON.stringify(msg)
@ -248,17 +248,17 @@ function validateTangle(msg, tangle, tangleId) {
/**
* @param {Msg} msg
* @param {string} msgHash
* @param {string} tangleId
* @param {string} msgID
* @param {string} tangleID
*/
function validateTangleRoot(msg, msgHash, tangleId) {
if (msgHash !== tangleId) {
function validateTangleRoot(msg, msgID, tangleID) {
if (msgID !== tangleID) {
// prettier-ignore
return `invalid message: tangle root hash "${msgHash}" must match tangleId "${tangleId}"\n` + JSON.stringify(msg)
return `invalid message: tangle root "${msgID}" must match tangleID "${tangleID}"\n` + JSON.stringify(msg)
}
if (msg.metadata.tangles[tangleId]) {
if (msg.metadata.tangles[tangleID]) {
// prettier-ignore
return `invalid message: tangle root "${tangleId}" must not have self tangle data\n` + JSON.stringify(msg)
return `invalid message: tangle root "${tangleID}" must not have self tangle data\n` + JSON.stringify(msg)
}
}
@ -319,10 +319,10 @@ function validateData(msg) {
* @param {Msg} msg
* @param {Tangle} tangle
* @param {Set<string>} pubkeys
* @param {string} msgHash
* @param {string} rootHash
* @param {string} msgID
* @param {string} rootID
*/
function validate(msg, tangle, pubkeys, msgHash, rootHash) {
function validate(msg, tangle, pubkeys, msgID, rootID) {
let err
if ((err = validateShape(msg))) return err
if ((err = validatePubkey(msg))) return err
@ -331,9 +331,9 @@ function validate(msg, tangle, pubkeys, msgHash, rootHash) {
if ((err = validateDomain(msg.metadata.domain))) return err
if ((err = validateAccountPubkey(msg, pubkeys))) return err
if (tangle.size() === 0) {
if ((err = validateTangleRoot(msg, msgHash, rootHash))) return err
if ((err = validateTangleRoot(msg, msgID, rootID))) return err
} else {
if ((err = validateTangle(msg, tangle, rootHash))) return err
if ((err = validateTangle(msg, tangle, rootID))) return err
}
if ((err = validateSignature(msg))) return err
}
@ -342,5 +342,5 @@ module.exports = {
validateDomain,
validateData,
validate,
validateMsgHash,
validateMsgID,
}

View File

@ -55,7 +55,7 @@ interface Msg {
dataSize: number
domain: string // alphanumeric string, at least 3 chars, max 100 chars
tangles: {
[accountTangleId: string]: {
[accountTangleID: string]: {
depth: number // maximum distance (positive integer) from this msg to the root
prev: Array<MsgHash> // list of msg hashes of existing msgs, unique set and ordered alphabetically
}

View File

@ -21,24 +21,24 @@ test('account.add()', async (t) => {
.call(null, { keypair: keypair1, path: DIR })
await peer.db.loaded()
const id = await p(peer.db.account.create)({
const account = await p(peer.db.account.create)({
keypair: keypair1,
domain: 'person',
})
assert.equal(peer.db.account.has({ account: id, keypair: keypair2 }), false)
assert.equal(peer.db.account.has({ account, keypair: keypair2 }), false)
const consent = peer.db.account.consent({ account: id, keypair: keypair2 })
const consent = peer.db.account.consent({ account, keypair: keypair2 })
const accountRec1 = await p(peer.db.account.add)({
account: id,
account,
keypair: keypair2,
consent,
powers: ['box'],
})
assert.ok(accountRec1, 'accountRec1 exists')
const { hash, msg } = accountRec1
assert.ok(hash, 'hash exists')
const { id, msg } = accountRec1
assert.ok(account, 'id exists')
assert.deepEqual(
msg.data,
{
@ -60,12 +60,12 @@ test('account.add()', async (t) => {
assert.equal(msg.metadata.domain, 'person', 'msg.metadata.domain')
assert.deepEqual(
msg.metadata.tangles,
{ [id]: { depth: 1, prev: [id] } },
{ [account]: { depth: 1, prev: [account] } },
'msg.metadata.tangles'
)
assert.equal(msg.pubkey, keypair1.public, 'msg.pubkey OLD KEY')
assert.equal(peer.db.account.has({ account: id, keypair: keypair2 }), true)
assert.equal(peer.db.account.has({ account, keypair: keypair2 }), true)
await p(peer.close)()
})
@ -182,8 +182,8 @@ test('publish with a key in the account', async (t) => {
keypair: keypair2,
})
assert.equal(postRec.msg.data.text, 'hello', 'post text correct')
const postsId = peer.db.feed.getId(account, 'post')
assert.ok(postsId, 'postsId exists')
const postsID = peer.db.feed.getID(account, 'post')
assert.ok(postsID, 'postsID exists')
const recs = [...peer.db.records()]
assert.equal(recs.length, 4, '4 records')
@ -220,8 +220,8 @@ test('publish with a key in the account', async (t) => {
await p(carol.db.add)(accountMsg0, account)
await p(carol.db.add)(accountRec1.msg, account)
await p(carol.db.add)(postsRoot.msg, postsId)
await p(carol.db.add)(postRec.msg, postsId)
await p(carol.db.add)(postsRoot.msg, postsID)
await p(carol.db.add)(postRec.msg, postsID)
// t.pass('carol added all messages successfully')
await p(carol.close)()

View File

@ -22,17 +22,17 @@ test('add()', async (t) => {
await peer.db.loaded()
const accountMsg0 = MsgV3.createAccount(keypair, 'person')
const id = MsgV3.getMsgHash(accountMsg0)
const id = MsgV3.getMsgID(accountMsg0)
await p(peer.db.add)(accountMsg0, id)
const rootMsg = MsgV3.createRoot(id, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const rootMsg = MsgV3.createMoot(id, 'post', keypair)
const rootID = MsgV3.getMsgID(rootMsg)
const recRoot = await p(peer.db.add)(rootMsg, rootHash)
const recRoot = await p(peer.db.add)(rootMsg, rootID)
assert.equal(recRoot.msg.metadata.dataSize, 0, 'root msg added')
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(recRoot.hash, recRoot.msg)
const tangle = new MsgV3.Tangle(rootID)
tangle.add(recRoot.id, recRoot.msg)
const inputMsg = MsgV3.create({
keypair,
@ -41,11 +41,11 @@ test('add()', async (t) => {
account: id,
accountTips: [id],
tangles: {
[rootHash]: tangle,
[rootID]: tangle,
},
})
const rec = await p(peer.db.add)(inputMsg, rootHash)
const rec = await p(peer.db.add)(inputMsg, rootID)
assert.equal(rec.msg.data.text, 'This is the first post!')
await p(peer.close)(true)

View File

@ -23,14 +23,14 @@ test('del', async (t) => {
const id = await p(peer.db.account.create)({ domain: 'person' })
const msgHashes = []
const msgIDs = []
for (let i = 0; i < 5; i++) {
const rec = await p(peer.db.feed.publish)({
account: id,
domain: 'post',
data: { text: 'm' + i },
})
msgHashes.push(rec.hash)
msgIDs.push(rec.id)
}
const before = []
@ -46,7 +46,7 @@ test('del', async (t) => {
'msgs before the delete'
)
await p(peer.db.del)(msgHashes[2])
await p(peer.db.del)(msgIDs[2])
const after = []
for (const msg of peer.db.msgs()) {

View File

@ -23,14 +23,14 @@ test('erase', async (t) => {
const id = await p(peer.db.account.create)({ domain: 'person' })
const msgHashes = []
const msgIDs = []
for (let i = 0; i < 5; i++) {
const rec = await p(peer.db.feed.publish)({
account: id,
domain: 'post',
data: { text: 'm' + i },
})
msgHashes.push(rec.hash)
msgIDs.push(rec.id)
}
const before = []
@ -46,7 +46,7 @@ test('erase', async (t) => {
'5 msgs before the erase'
)
await p(peer.db.erase)(msgHashes[2])
await p(peer.db.erase)(msgIDs[2])
const after = []
for (const msg of peer.db.msgs()) {
@ -59,8 +59,8 @@ test('erase', async (t) => {
const after2 = []
for (const msg of peer.db.msgs()) {
for (const tangleId in msg.metadata.tangles) {
after2.push(msg.metadata.tangles[tangleId].depth)
for (const tangleID in msg.metadata.tangles) {
after2.push(msg.metadata.tangles[tangleID].depth)
}
}

View File

@ -15,8 +15,8 @@ rimraf.sync(DIR)
const keypair = Keypair.generate('ed25519', 'alice')
let peer
let id
let rootMsg
let rootHash
let moot
let mootID
test('setup', async (t) => {
peer = SecretStack({ appKey: caps.shse })
.use(require('../lib'))
@ -26,15 +26,15 @@ test('setup', async (t) => {
await peer.db.loaded()
id = (await p(peer.db.account.create)({domain: 'person'}))
rootMsg = MsgV3.createRoot(id, 'post', keypair)
rootHash = MsgV3.getMsgHash(rootMsg)
moot = MsgV3.createMoot(id, 'post', keypair)
mootID = MsgV3.getMsgID(moot)
await p(peer.db.add)(rootMsg, rootHash)
await p(peer.db.add)(moot, mootID)
})
test('feed.getId()', async (t) => {
const feedId = peer.db.feed.getId(id, 'post')
assert.equal(feedId, rootHash, 'feed.getId() returns root hash')
test('feed.getID()', async (t) => {
const feedID = peer.db.feed.getID(id, 'post')
assert.equal(feedID, mootID, 'feed.getID() returns moot ID')
})
test('teardown', (t) => {

View File

@ -16,8 +16,8 @@ const keypair = Keypair.generate('ed25519', 'alice')
const bobKeypair = Keypair.generate('ed25519', 'bob')
let peer
let id
let rootMsg
let rootHash
let moot
let mootID
test('setup', async (t) => {
peer = SecretStack({ appKey: caps.shse })
.use(require('../lib'))
@ -27,13 +27,13 @@ test('setup', async (t) => {
await peer.db.loaded()
id = (await p(peer.db.account.create)({domain: 'person'}))
rootMsg = MsgV3.createRoot(id, 'post', keypair)
rootHash = MsgV3.getMsgHash(rootMsg)
moot = MsgV3.createMoot(id, 'post', keypair)
mootID = MsgV3.getMsgID(moot)
})
let msgHash1
let msgID1
let rec1
let msgHash2
let msgID2
test('feed.publish()', async (t) => {
rec1 = await p(peer.db.feed.publish)({
account: id,
@ -42,17 +42,17 @@ test('feed.publish()', async (t) => {
})
assert.equal(rec1.msg.data.text, 'I am 1st post', 'msg1 text correct')
assert.equal(
rec1.msg.metadata.tangles[rootHash].depth,
rec1.msg.metadata.tangles[mootID].depth,
1,
'msg1 tangle depth correct'
)
assert.deepEqual(
rec1.msg.metadata.tangles[rootHash].prev,
[rootHash],
rec1.msg.metadata.tangles[mootID].prev,
[mootID],
'msg1 tangle prev correct'
)
msgHash1 = MsgV3.getMsgHash(rec1.msg)
msgID1 = MsgV3.getMsgID(rec1.msg)
const rec2 = await p(peer.db.feed.publish)({
account: id,
@ -61,22 +61,22 @@ test('feed.publish()', async (t) => {
})
assert.equal(rec2.msg.data.text, 'I am 2nd post', 'msg2 text correct')
assert.equal(
rec2.msg.metadata.tangles[rootHash].depth,
rec2.msg.metadata.tangles[mootID].depth,
2,
'msg2 tangle depth correct'
)
assert.deepEqual(
rec2.msg.metadata.tangles[rootHash].prev,
[msgHash1],
rec2.msg.metadata.tangles[mootID].prev,
[msgID1],
'msg2 tangle prev correct'
)
msgHash2 = MsgV3.getMsgHash(rec2.msg)
msgID2 = MsgV3.getMsgID(rec2.msg)
})
test('add() forked then feed.publish() merged', async (t) => {
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(rootHash, rootMsg)
tangle.add(rec1.hash, rec1.msg)
const tangle = new MsgV3.Tangle(mootID)
tangle.add(mootID, moot)
tangle.add(rec1.id, rec1.msg)
const msg3 = MsgV3.create({
keypair,
@ -85,12 +85,12 @@ test('add() forked then feed.publish() merged', async (t) => {
domain: 'post',
data: { text: '3rd post forked from 1st' },
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const rec3 = await p(peer.db.add)(msg3, rootHash)
const msgHash3 = MsgV3.getMsgHash(rec3.msg)
const rec3 = await p(peer.db.add)(msg3, mootID)
const msgID3 = MsgV3.getMsgID(rec3.msg)
const rec4 = await p(peer.db.feed.publish)({
account: id,
@ -99,20 +99,20 @@ test('add() forked then feed.publish() merged', async (t) => {
})
assert.ok(rec4, '4th post published')
assert.equal(
rec4.msg.metadata.tangles[rootHash].prev.length,
rec4.msg.metadata.tangles[mootID].prev.length,
3,
'msg4 prev has 3' // is root, msg2 and msg3'
)
assert.ok(
rec4.msg.metadata.tangles[rootHash].prev.includes(rootHash),
rec4.msg.metadata.tangles[mootID].prev.includes(mootID),
'msg4 prev has root'
)
assert.ok(
rec4.msg.metadata.tangles[rootHash].prev.includes(msgHash2),
rec4.msg.metadata.tangles[mootID].prev.includes(msgID2),
'msg4 prev has msg2'
)
assert.ok(
rec4.msg.metadata.tangles[rootHash].prev.includes(msgHash3),
rec4.msg.metadata.tangles[mootID].prev.includes(msgID3),
'msg4 prev has msg3'
)
})
@ -127,7 +127,7 @@ test('feed.publish() encrypted with box', async (t) => {
assert.equal(typeof recEncrypted.msg.data, 'string')
assert.ok(recEncrypted.msg.data.endsWith('.box'), '.box')
const msgDecrypted = peer.db.get(recEncrypted.hash)
const msgDecrypted = peer.db.get(recEncrypted.id)
assert.equal(msgDecrypted.data.text, 'I am chewing food')
})
@ -143,13 +143,13 @@ test('feed.publish() with tangles', async (t) => {
account: id,
domain: 'comment',
data: { text: 'I am comment 1' },
tangles: [recA.hash],
tangles: [recA.id],
keypair: bobKeypair,
})
assert.equal(recB.msg.metadata.tangles[recA.hash].depth, 1, 'tangle depth 1')
assert.equal(recB.msg.metadata.tangles[recA.id].depth, 1, 'tangle depth 1')
assert.deepEqual(
recB.msg.metadata.tangles[recA.hash].prev,
[recA.hash],
recB.msg.metadata.tangles[recA.id].prev,
[recA.id],
'tangle prev'
)
})

View File

@ -15,8 +15,7 @@ rimraf.sync(DIR)
const keypair = Keypair.generate('ed25519', 'alice')
let peer
let id
let msgHash1
let msgId1
let msgID1
test('setup', async (t) => {
peer = SecretStack({ appKey: caps.shse })
.use(require('../lib'))
@ -32,18 +31,11 @@ test('setup', async (t) => {
domain: 'post',
data: { text: 'I am 1st post' },
})
msgHash1 = MsgV3.getMsgHash(rec1.msg)
msgId1 = MsgV3.getMsgId(rec1.msg)
msgID1 = MsgV3.getMsgID(rec1.msg)
})
test('get() supports ppppp URIs', async (t) => {
const msg = peer.db.get(msgId1)
assert.ok(msg, 'msg exists')
assert.equal(msg.data.text, 'I am 1st post')
})
test('get() supports msg hashes', async (t) => {
const msg = peer.db.get(msgHash1)
test('get() supports msg IDs', async (t) => {
const msg = peer.db.get(msgID1)
assert.ok(msg, 'msg exists')
assert.equal(msg.data.text, 'I am 1st post')
})

View File

@ -41,9 +41,9 @@ test('setup', async (t) => {
domain: 'comment',
data: { text: 'root' },
})
).hash
).id
const [{ hash: reply1B }, { hash: reply1C }] = await Promise.all([
const [{ id: reply1B }, { id: reply1C }] = await Promise.all([
p(peer.db.feed.publish)({
account: id,
keypair: keypairB,
@ -70,9 +70,9 @@ test('setup', async (t) => {
data: { text: 'reply 2' },
tangles: [rootPost],
})
).hash
).id
const [{ hash: reply3B }, { hash: reply3C }] = await Promise.all([
const [{ id: reply3B }, { id: reply3C }] = await Promise.all([
p(peer.db.feed.publish)({
account: id,
keypair: keypairB,
@ -217,11 +217,11 @@ test('Tangle.getDeletablesAndErasables with lipmaa', (t) => {
test('Tangle.topoSort after some have been deleted and erased', async (t) => {
const { deletables, erasables } = tangle.getDeletablesAndErasables(reply3Lo)
for (const msgHash of deletables) {
await p(peer.db.del)(msgHash)
for (const msgID of deletables) {
await p(peer.db.del)(msgID)
}
for (const msgHash of erasables) {
await p(peer.db.erase)(msgHash)
for (const msgID of erasables) {
await p(peer.db.erase)(msgID)
}
const tangle2 = peer.db.getTangle(rootPost)

View File

@ -35,38 +35,38 @@ test('MsgV3.createAccount()', (t) => {
assert.equal(accountMsg0.metadata.v, 3, 'v')
assert.equal(accountMsg0.pubkey, keypair.public, 'pubkey')
account = MsgV3.getMsgHash(accountMsg0)
account = MsgV3.getMsgID(accountMsg0)
assert.equal(account, 'J2SUr6XtJuFuTusNbagEW5', 'account ID')
})
let rootMsg = null
let rootHash = null
test('MsgV3.createRoot()', (t) => {
let moot = null
let mootID = null
test('MsgV3.createMoot()', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
rootMsg = MsgV3.createRoot(account, 'post', keypair)
console.log(JSON.stringify(rootMsg, null, 2))
moot = MsgV3.createMoot(account, 'post', keypair)
console.log(JSON.stringify(moot, null, 2))
assert.equal(rootMsg.data, null, 'data')
assert.equal(rootMsg.metadata.dataHash, null, 'hash')
assert.equal(rootMsg.metadata.dataSize, 0, 'size')
assert.equal(rootMsg.metadata.account, account, 'account')
assert.equal(rootMsg.metadata.accountTips, null, 'accountTips')
assert.deepEqual(rootMsg.metadata.tangles, {}, 'tangles')
assert.equal(rootMsg.metadata.domain, 'post', 'domain')
assert.equal(rootMsg.metadata.v, 3, 'v')
assert.equal(rootMsg.pubkey, keypair.public, 'pubkey')
assert.equal(moot.data, null, 'data')
assert.equal(moot.metadata.dataHash, null, 'hash')
assert.equal(moot.metadata.dataSize, 0, 'size')
assert.equal(moot.metadata.account, account, 'account')
assert.equal(moot.metadata.accountTips, null, 'accountTips')
assert.deepEqual(moot.metadata.tangles, {}, 'tangles')
assert.equal(moot.metadata.domain, 'post', 'domain')
assert.equal(moot.metadata.v, 3, 'v')
assert.equal(moot.pubkey, keypair.public, 'pubkey')
rootHash = MsgV3.getMsgHash(rootMsg)
assert.equal(rootHash, 'VsBFptgidvAspk4xTKZx6c', 'root hash')
mootID = MsgV3.getMsgID(moot)
assert.equal(mootID, 'VsBFptgidvAspk4xTKZx6c', 'moot ID')
})
test('MsgV3.create()', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const data = { text: 'Hello world!' }
const tangle1 = new MsgV3.Tangle(rootHash)
tangle1.add(rootHash, rootMsg)
const tangle1 = new MsgV3.Tangle(mootID)
tangle1.add(mootID, moot)
const msg1 = MsgV3.create({
keypair,
@ -75,7 +75,7 @@ test('MsgV3.create()', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle1,
[mootID]: tangle1,
},
})
console.log(JSON.stringify(msg1, null, 2))
@ -101,22 +101,14 @@ test('MsgV3.create()', (t) => {
)
assert.deepEqual(msg1.metadata.dataSize, 23, 'metadata.dataSize')
assert.equal(msg1.metadata.account, account, 'metadata.account')
assert.deepEqual(
msg1.metadata.accountTips,
[account],
'metadata.accountTips'
)
assert.deepEqual(msg1.metadata.accountTips, [account], 'metadata.accountTips')
assert.deepEqual(
Object.keys(msg1.metadata.tangles),
[rootHash],
[mootID],
'metadata.tangles'
)
assert.equal(msg1.metadata.tangles[rootHash].depth, 1, 'tangle depth')
assert.deepEqual(
msg1.metadata.tangles[rootHash].prev,
[rootHash],
'tangle prev'
)
assert.equal(msg1.metadata.tangles[mootID].depth, 1, 'tangle depth')
assert.deepEqual(msg1.metadata.tangles[mootID].prev, [mootID], 'tangle prev')
assert.equal(msg1.metadata.domain, 'post', 'metadata.domain')
assert.deepEqual(msg1.metadata.v, 3, 'metadata.v')
assert.equal(
@ -130,17 +122,13 @@ test('MsgV3.create()', (t) => {
'sig'
)
const msgHash1 = 'R5G9WtDAQrco4FABRdvrUH'
const msgID1 = 'R5G9WtDAQrco4FABRdvrUH'
assert.equal(
MsgV3.getMsgId(msg1),
`ppppp:message/v3/${account}/post/${msgHash1}`,
'getMsgId'
)
assert.equal(MsgV3.getMsgID(msg1), msgID1, 'getMsgID')
const tangle2 = new MsgV3.Tangle(rootHash)
tangle2.add(rootHash, rootMsg)
tangle2.add(msgHash1, msg1)
const tangle2 = new MsgV3.Tangle(mootID)
tangle2.add(mootID, moot)
tangle2.add(msgID1, msg1)
const data2 = { text: 'Ola mundo!' }
@ -151,7 +139,7 @@ test('MsgV3.create()', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle2,
[mootID]: tangle2,
},
})
console.log(JSON.stringify(msg2, null, 2))
@ -177,22 +165,14 @@ test('MsgV3.create()', (t) => {
)
assert.deepEqual(msg2.metadata.dataSize, 21, 'metadata.dataSize')
assert.equal(msg2.metadata.account, account, 'metadata.account')
assert.deepEqual(
msg2.metadata.accountTips,
[account],
'metadata.accountTips'
)
assert.deepEqual(msg2.metadata.accountTips, [account], 'metadata.accountTips')
assert.deepEqual(
Object.keys(msg2.metadata.tangles),
[rootHash],
[mootID],
'metadata.tangles'
)
assert.equal(msg2.metadata.tangles[rootHash].depth, 2, 'tangle depth')
assert.deepEqual(
msg2.metadata.tangles[rootHash].prev,
[msgHash1],
'tangle prev'
)
assert.equal(msg2.metadata.tangles[mootID].depth, 2, 'tangle depth')
assert.deepEqual(msg2.metadata.tangles[mootID].prev, [msgID1], 'tangle prev')
assert.equal(msg2.metadata.domain, 'post', 'metadata.domain')
assert.deepEqual(msg2.metadata.v, 3, 'metadata.v')
assert.equal(
@ -206,17 +186,13 @@ test('MsgV3.create()', (t) => {
'sig'
)
assert.deepEqual(
MsgV3.getMsgId(msg2),
`ppppp:message/v3/${account}/post/LxWgRRr4wXd29sLDNGNTkr`,
'getMsgId'
)
assert.deepEqual(MsgV3.getMsgID(msg2), 'LxWgRRr4wXd29sLDNGNTkr', 'getMsgID')
})
test('create() handles DAG tips correctly', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(rootHash, rootMsg)
const tangle = new MsgV3.Tangle(mootID)
tangle.add(mootID, moot)
const msg1 = MsgV3.create({
keypair,
@ -225,17 +201,17 @@ test('create() handles DAG tips correctly', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const msgHash1 = MsgV3.getMsgHash(msg1)
const msgID1 = MsgV3.getMsgID(msg1)
assert.deepEqual(
msg1.metadata.tangles[rootHash].prev,
[MsgV3.getFeedRootHash(account, 'post')],
msg1.metadata.tangles[mootID].prev,
[MsgV3.getMootID(account, 'post')],
'msg1.prev is root'
)
tangle.add(msgHash1, msg1)
tangle.add(msgID1, msg1)
const msg2A = MsgV3.create({
keypair,
@ -244,12 +220,12 @@ test('create() handles DAG tips correctly', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
assert.deepEqual(
msg2A.metadata.tangles[rootHash].prev,
[msgHash1],
msg2A.metadata.tangles[mootID].prev,
[msgID1],
'msg2A.prev is msg1'
)
@ -260,17 +236,17 @@ test('create() handles DAG tips correctly', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const msgHash2B = MsgV3.getMsgHash(msg2B)
const msgID2B = MsgV3.getMsgID(msg2B)
assert.deepEqual(
msg2B.metadata.tangles[rootHash].prev,
[msgHash1],
msg2B.metadata.tangles[mootID].prev,
[msgID1],
'msg2B.prev is msg1'
)
tangle.add(msgHash2B, msg2B)
tangle.add(msgID2B, msg2B)
const msg3 = MsgV3.create({
keypair,
@ -279,19 +255,19 @@ test('create() handles DAG tips correctly', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const msgHash3 = MsgV3.getMsgHash(msg3)
const msgID3 = MsgV3.getMsgID(msg3)
assert.deepEqual(
msg3.metadata.tangles[rootHash].prev,
[rootHash, msgHash2B].sort(),
msg3.metadata.tangles[mootID].prev,
[mootID, msgID2B].sort(),
'msg3.prev is [root(lipmaa),msg2B(previous)], sorted'
)
tangle.add(msgHash3, msg3)
tangle.add(msgID3, msg3)
const msgHash2A = MsgV3.getMsgHash(msg2A)
tangle.add(msgHash2A, msg2A)
const msgID2A = MsgV3.getMsgID(msg2A)
tangle.add(msgID2A, msg2A)
// t.pass('msg2A comes into awareness')
const msg4 = MsgV3.create({
@ -301,12 +277,12 @@ test('create() handles DAG tips correctly', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
assert.deepEqual(
msg4.metadata.tangles[rootHash].prev,
[msgHash3, msgHash2A].sort(),
msg4.metadata.tangles[mootID].prev,
[msgID3, msgID2A].sort(),
'msg4.prev is [msg3(previous),msg2A(old fork as tip)], sorted'
)
})

View File

@ -5,7 +5,7 @@ const Keypair = require('ppppp-keypair')
const MsgV3 = require('../../lib/msg-v3')
const keypair = Keypair.generate('ed25519', 'alice')
const account = MsgV3.getMsgHash(
const account = MsgV3.getMsgID(
MsgV3.createAccount(keypair, 'person', 'MYNONCE')
)
const pubkeys = new Set([keypair.public])
@ -13,11 +13,11 @@ const pubkeys = new Set([keypair.public])
test('invalid msg with non-array prev', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(rootHash, rootMsg)
const tangle = new MsgV3.Tangle(mootID)
tangle.add(mootID, moot)
const msg = MsgV3.create({
keypair,
@ -26,13 +26,13 @@ test('invalid msg with non-array prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
msg.metadata.tangles[rootHash].prev = null
const msgHash = MsgV3.getMsgHash(msg)
msg.metadata.tangles[mootID].prev = null
const msgID = MsgV3.getMsgID(msg)
const err = MsgV3.validate(msg, tangle, pubkeys, msgHash, rootHash)
const err = MsgV3.validate(msg, tangle, pubkeys, msgID, mootID)
assert.ok(err, 'invalid 2nd msg throws')
assert.match(
err,
@ -44,11 +44,11 @@ test('invalid msg with non-array prev', (t) => {
test('invalid msg with bad prev', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(rootHash, rootMsg)
const tangle = new MsgV3.Tangle(mootID)
tangle.add(mootID, moot)
const msg1 = MsgV3.create({
keypair,
@ -57,11 +57,11 @@ test('invalid msg with bad prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const msgHash1 = MsgV3.getMsgHash(msg1)
tangle.add(msgHash1, msg1)
const msgID1 = MsgV3.getMsgID(msg1)
tangle.add(msgID1, msg1)
const msg2 = MsgV3.create({
keypair,
@ -70,14 +70,14 @@ test('invalid msg with bad prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
msg2.metadata.tangles[rootHash].depth = 1
msg2.metadata.tangles[rootHash].prev = [1234]
const msgHash2 = MsgV3.getMsgHash(msg2)
msg2.metadata.tangles[mootID].depth = 1
msg2.metadata.tangles[mootID].prev = [1234]
const msgID2 = MsgV3.getMsgID(msg2)
const err = MsgV3.validate(msg2, tangle, pubkeys, msgHash2, rootHash)
const err = MsgV3.validate(msg2, tangle, pubkeys, msgID2, mootID)
assert.ok(err, 'invalid 2nd msg throws')
assert.match(
err,
@ -89,11 +89,11 @@ test('invalid msg with bad prev', (t) => {
test('invalid msg with URI in prev', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(rootHash, rootMsg)
const tangle = new MsgV3.Tangle(mootID)
tangle.add(mootID, moot)
const msg1 = MsgV3.create({
keypair,
@ -102,11 +102,11 @@ test('invalid msg with URI in prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const msgHash1 = MsgV3.getMsgHash(msg1)
tangle.add(msgHash1, msg1)
const msgID1 = MsgV3.getMsgID(msg1)
tangle.add(msgID1, msg1)
const msg2 = MsgV3.create({
keypair,
@ -115,16 +115,16 @@ test('invalid msg with URI in prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const msgHash2 = MsgV3.getMsgHash(msg2)
const msgID2 = MsgV3.getMsgID(msg2)
const randBuf = Buffer.alloc(16).fill(16)
const fakeMsgKey1 = `ppppp:message/v3/${base58.encode(randBuf)}`
msg2.metadata.tangles[rootHash].depth = 1
msg2.metadata.tangles[rootHash].prev = [fakeMsgKey1]
msg2.metadata.tangles[mootID].depth = 1
msg2.metadata.tangles[mootID].prev = [fakeMsgKey1]
const err = MsgV3.validate(msg2, tangle, pubkeys, msgHash2, rootHash)
const err = MsgV3.validate(msg2, tangle, pubkeys, msgID2, mootID)
assert.ok(err, 'invalid 2nd msg throws')
assert.match(err, /prev item ".*" is a URI/, 'invalid 2nd msg description')
})
@ -132,11 +132,11 @@ test('invalid msg with URI in prev', (t) => {
test('invalid msg with unknown prev', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(rootHash, rootMsg)
const tangle = new MsgV3.Tangle(mootID)
tangle.add(mootID, moot)
const msg1 = MsgV3.create({
keypair,
@ -145,11 +145,11 @@ test('invalid msg with unknown prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const msgHash1 = MsgV3.getMsgHash(msg1)
tangle.add(msgHash1, msg1)
const msgID1 = MsgV3.getMsgID(msg1)
tangle.add(msgID1, msg1)
const unknownMsg = MsgV3.create({
keypair,
@ -158,15 +158,15 @@ test('invalid msg with unknown prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const unknownMsgHash = MsgV3.getMsgHash(unknownMsg)
const unknownMsgID = MsgV3.getMsgID(unknownMsg)
const fakeRootHash = 'ABCDEabcde' + rootHash.substring(10)
const tangle2 = new MsgV3.Tangle(fakeRootHash)
tangle2.add(fakeRootHash, rootMsg)
tangle2.add(unknownMsgHash, unknownMsg)
const fakeMootID = 'ABCDEabcde' + mootID.substring(10)
const tangle2 = new MsgV3.Tangle(fakeMootID)
tangle2.add(fakeMootID, moot)
tangle2.add(unknownMsgID, unknownMsg)
const msg2 = MsgV3.create({
keypair,
@ -175,12 +175,12 @@ test('invalid msg with unknown prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle2,
[mootID]: tangle2,
},
})
const msgHash2 = MsgV3.getMsgHash(msg2)
const msgID2 = MsgV3.getMsgID(msg2)
const err = MsgV3.validate(msg2, tangle, pubkeys, msgHash2, rootHash)
const err = MsgV3.validate(msg2, tangle, pubkeys, msgID2, mootID)
assert.ok(err, 'invalid 2nd msg throws')
assert.match(
err,
@ -193,14 +193,14 @@ test('invalid feed msg with a different pubkey', (t) => {
const keypairA = Keypair.generate('ed25519', 'alice')
const keypairB = Keypair.generate('ed25519', 'bob')
const accountB = MsgV3.getMsgHash(
const accountB = MsgV3.getMsgID(
MsgV3.createAccount(keypairB, 'person', 'MYNONCE')
)
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const feedTangle = new MsgV3.Tangle(rootHash)
feedTangle.add(rootHash, rootMsg)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const feedTangle = new MsgV3.Tangle(mootID)
feedTangle.add(mootID, moot)
const msg = MsgV3.create({
keypair: keypairB,
@ -209,12 +209,12 @@ test('invalid feed msg with a different pubkey', (t) => {
accountTips: [accountB],
domain: 'post',
tangles: {
[rootHash]: feedTangle,
[mootID]: feedTangle,
},
})
const msgHash = MsgV3.getMsgHash(msg)
const msgID = MsgV3.getMsgID(msg)
const err = MsgV3.validate(msg, feedTangle, pubkeys, msgHash, rootHash)
const err = MsgV3.validate(msg, feedTangle, pubkeys, msgID, mootID)
assert.ok(err, 'invalid msg throws')
assert.match(
err,
@ -226,10 +226,10 @@ test('invalid feed msg with a different pubkey', (t) => {
test('invalid feed msg with a different domain', (t) => {
const keypairA = Keypair.generate('ed25519', 'alice')
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const feedTangle = new MsgV3.Tangle(rootHash)
feedTangle.add(rootHash, rootMsg)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const feedTangle = new MsgV3.Tangle(mootID)
feedTangle.add(mootID, moot)
const msg = MsgV3.create({
keypair: keypairA,
@ -238,12 +238,12 @@ test('invalid feed msg with a different domain', (t) => {
accountTips: [account],
domain: 'comment',
tangles: {
[rootHash]: feedTangle,
[mootID]: feedTangle,
},
})
const msgHash = MsgV3.getMsgHash(msg)
const msgID = MsgV3.getMsgID(msg)
const err = MsgV3.validate(msg, feedTangle, pubkeys, msgHash, rootHash)
const err = MsgV3.validate(msg, feedTangle, pubkeys, msgID, mootID)
assert.ok(err, 'invalid msg throws')
assert.match(
err,
@ -255,11 +255,11 @@ test('invalid feed msg with a different domain', (t) => {
test('invalid feed msg with non-alphabetical prev', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(rootHash, rootMsg)
const tangle = new MsgV3.Tangle(mootID)
tangle.add(mootID, moot)
const msg1 = MsgV3.create({
keypair,
@ -268,10 +268,10 @@ test('invalid feed msg with non-alphabetical prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const msgHash1 = MsgV3.getMsgHash(msg1)
const msgID1 = MsgV3.getMsgID(msg1)
const msg2 = MsgV3.create({
keypair,
@ -280,13 +280,13 @@ test('invalid feed msg with non-alphabetical prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const msgHash2 = MsgV3.getMsgHash(msg2)
const msgID2 = MsgV3.getMsgID(msg2)
tangle.add(msgHash1, msg1)
tangle.add(msgHash2, msg2)
tangle.add(msgID1, msg1)
tangle.add(msgID2, msg2)
const msg3 = MsgV3.create({
keypair,
@ -295,20 +295,20 @@ test('invalid feed msg with non-alphabetical prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const msgHash3 = MsgV3.getMsgHash(msg3)
const msgID3 = MsgV3.getMsgID(msg3)
let prevHashes = msg3.metadata.tangles[rootHash].prev
if (prevHashes[0] < prevHashes[1]) {
prevHashes = [prevHashes[1], prevHashes[0]]
let prevMsgIDs = msg3.metadata.tangles[mootID].prev
if (prevMsgIDs[0] < prevMsgIDs[1]) {
prevMsgIDs = [prevMsgIDs[1], prevMsgIDs[0]]
} else {
prevHashes = [prevHashes[0], prevHashes[1]]
prevMsgIDs = [prevMsgIDs[0], prevMsgIDs[1]]
}
msg3.metadata.tangles[rootHash].prev = prevHashes
msg3.metadata.tangles[mootID].prev = prevMsgIDs
const err = MsgV3.validate(msg3, tangle, pubkeys, msgHash3, rootHash)
const err = MsgV3.validate(msg3, tangle, pubkeys, msgID3, mootID)
assert.ok(err, 'invalid 3rd msg throws')
assert.match(
err,
@ -320,11 +320,11 @@ test('invalid feed msg with non-alphabetical prev', (t) => {
test('invalid feed msg with duplicate prev', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(rootHash, rootMsg)
const tangle = new MsgV3.Tangle(mootID)
tangle.add(mootID, moot)
const msg1 = MsgV3.create({
keypair,
@ -333,15 +333,15 @@ test('invalid feed msg with duplicate prev', (t) => {
accountTips: [account],
domain: 'post',
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
})
const msgHash1 = MsgV3.getMsgHash(msg1)
const msgID1 = MsgV3.getMsgID(msg1)
const [prevHash] = msg1.metadata.tangles[rootHash].prev
msg1.metadata.tangles[rootHash].prev = [prevHash, prevHash]
const [prevID] = msg1.metadata.tangles[mootID].prev
msg1.metadata.tangles[mootID].prev = [prevID, prevID]
const err = MsgV3.validate(msg1, tangle, pubkeys, msgHash1, rootHash)
const err = MsgV3.validate(msg1, tangle, pubkeys, msgID1, mootID)
assert.ok(err, 'invalid 1st msg throws')
assert.match(err, /prev ".*" contains duplicates/, 'invalid error message')
})

View File

@ -5,15 +5,15 @@ const MsgV3 = require('../../lib/msg-v3')
test('lipmaa prevs', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const account = MsgV3.getMsgHash(
const account = MsgV3.getMsgID(
MsgV3.createAccount(keypair, 'person', 'MYNONCE')
)
const data = { text: 'Hello world!' }
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(rootHash, rootMsg)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const tangle = new MsgV3.Tangle(mootID)
tangle.add(mootID, moot)
const msg1 = MsgV3.create({
account,
@ -21,16 +21,16 @@ test('lipmaa prevs', (t) => {
domain: 'post',
data,
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
keypair,
})
const msgHash1 = MsgV3.getMsgHash(msg1)
tangle.add(msgHash1, msg1)
assert.equal(msg1.metadata.tangles[rootHash].depth, 1, 'msg1 depth')
const msgID1 = MsgV3.getMsgID(msg1)
tangle.add(msgID1, msg1)
assert.equal(msg1.metadata.tangles[mootID].depth, 1, 'msg1 depth')
assert.deepEqual(
msg1.metadata.tangles[rootHash].prev,
[rootHash],
msg1.metadata.tangles[mootID].prev,
[mootID],
'msg1 prev'
)
@ -40,16 +40,16 @@ test('lipmaa prevs', (t) => {
domain: 'post',
data,
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
keypair,
})
const msgHash2 = MsgV3.getMsgHash(msg2)
tangle.add(msgHash2, msg2)
assert.equal(msg2.metadata.tangles[rootHash].depth, 2, 'msg2 depth')
const msgID2 = MsgV3.getMsgID(msg2)
tangle.add(msgID2, msg2)
assert.equal(msg2.metadata.tangles[mootID].depth, 2, 'msg2 depth')
assert.deepEqual(
msg2.metadata.tangles[rootHash].prev,
[msgHash1],
msg2.metadata.tangles[mootID].prev,
[msgID1],
'msg2 prev'
)
@ -59,16 +59,16 @@ test('lipmaa prevs', (t) => {
domain: 'post',
data,
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
keypair,
})
const msgHash3 = MsgV3.getMsgHash(msg3)
tangle.add(msgHash3, msg3)
assert.equal(msg3.metadata.tangles[rootHash].depth, 3, 'msg3 depth')
const msgID3 = MsgV3.getMsgID(msg3)
tangle.add(msgID3, msg3)
assert.equal(msg3.metadata.tangles[mootID].depth, 3, 'msg3 depth')
assert.deepEqual(
msg3.metadata.tangles[rootHash].prev,
[rootHash, msgHash2].sort(),
msg3.metadata.tangles[mootID].prev,
[mootID, msgID2].sort(),
'msg3 prev (has lipmaa!)'
)
@ -78,16 +78,16 @@ test('lipmaa prevs', (t) => {
domain: 'post',
keypair,
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
data,
})
const msgHash4 = MsgV3.getMsgHash(msg4)
tangle.add(msgHash4, msg4)
assert.equal(msg4.metadata.tangles[rootHash].depth, 4, 'msg4 depth')
const msgID4 = MsgV3.getMsgID(msg4)
tangle.add(msgID4, msg4)
assert.equal(msg4.metadata.tangles[mootID].depth, 4, 'msg4 depth')
assert.deepEqual(
msg4.metadata.tangles[rootHash].prev,
[msgHash3],
msg4.metadata.tangles[mootID].prev,
[msgID3],
'msg4 prev'
)
@ -97,16 +97,16 @@ test('lipmaa prevs', (t) => {
domain: 'post',
data,
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
keypair,
})
const msgHash5 = MsgV3.getMsgHash(msg5)
tangle.add(msgHash5, msg5)
assert.equal(msg5.metadata.tangles[rootHash].depth, 5, 'msg5 depth')
const msgID5 = MsgV3.getMsgID(msg5)
tangle.add(msgID5, msg5)
assert.equal(msg5.metadata.tangles[mootID].depth, 5, 'msg5 depth')
assert.deepEqual(
msg5.metadata.tangles[rootHash].prev,
[msgHash4],
msg5.metadata.tangles[mootID].prev,
[msgID4],
'msg5 prev'
)
@ -116,16 +116,16 @@ test('lipmaa prevs', (t) => {
domain: 'post',
data,
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
keypair,
})
const msgHash6 = MsgV3.getMsgHash(msg6)
tangle.add(msgHash6, msg6)
assert.equal(msg6.metadata.tangles[rootHash].depth, 6, 'msg6 depth')
const msgID6 = MsgV3.getMsgID(msg6)
tangle.add(msgID6, msg6)
assert.equal(msg6.metadata.tangles[mootID].depth, 6, 'msg6 depth')
assert.deepEqual(
msg6.metadata.tangles[rootHash].prev,
[msgHash5],
msg6.metadata.tangles[mootID].prev,
[msgID5],
'msg6 prev'
)
@ -135,16 +135,16 @@ test('lipmaa prevs', (t) => {
domain: 'post',
data,
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
keypair,
})
const msgHash7 = MsgV3.getMsgHash(msg7)
tangle.add(msgHash7, msg7)
assert.equal(msg7.metadata.tangles[rootHash].depth, 7, 'msg7 depth')
const msgID7 = MsgV3.getMsgID(msg7)
tangle.add(msgID7, msg7)
assert.equal(msg7.metadata.tangles[mootID].depth, 7, 'msg7 depth')
assert.deepEqual(
msg7.metadata.tangles[rootHash].prev,
[msgHash3, msgHash6].sort(),
msg7.metadata.tangles[mootID].prev,
[msgID3, msgID6].sort(),
'msg7 prev (has lipmaa!)'
)
})

View File

@ -6,22 +6,22 @@ const MsgV3 = require('../../lib/msg-v3')
test('simple multi-author tangle', (t) => {
const keypairA = Keypair.generate('ed25519', 'alice')
const keypairB = Keypair.generate('ed25519', 'bob')
const accountA = MsgV3.getMsgHash(
const accountA = MsgV3.getMsgID(
MsgV3.createAccount(keypairA, 'person', 'alice')
)
const accountB = MsgV3.getMsgHash(
const accountB = MsgV3.getMsgID(
MsgV3.createAccount(keypairB, 'person', 'bob')
)
const rootMsgA = MsgV3.createRoot(accountA, 'post', keypairA)
const rootHashA = MsgV3.getMsgHash(rootMsgA)
const tangleA = new MsgV3.Tangle(rootHashA)
tangleA.add(rootHashA, rootMsgA)
const mootA = MsgV3.createMoot(accountA, 'post', keypairA)
const mootAID = MsgV3.getMsgID(mootA)
const tangleA = new MsgV3.Tangle(mootAID)
tangleA.add(mootAID, mootA)
const rootMsgB = MsgV3.createRoot(accountB, 'post', keypairB)
const rootHashB = MsgV3.getMsgHash(rootMsgB)
const tangleB = new MsgV3.Tangle(rootHashB)
tangleB.add(rootHashB, rootMsgB)
const mootB = MsgV3.createMoot(accountB, 'post', keypairB)
const mootBID = MsgV3.getMsgID(mootB)
const tangleB = new MsgV3.Tangle(mootBID)
tangleB.add(mootBID, mootB)
const msg1 = MsgV3.create({
account: accountA,
@ -29,19 +29,19 @@ test('simple multi-author tangle', (t) => {
domain: 'post',
data: { text: 'Hello world!' },
tangles: {
[rootHashA]: tangleA,
[mootAID]: tangleA,
},
keypair: keypairA,
})
const msgHash1 = MsgV3.getMsgHash(msg1)
const msgID1 = MsgV3.getMsgID(msg1)
assert.deepEqual(
Object.keys(msg1.metadata.tangles),
[rootHashA],
[mootAID],
'msg1 has only feed tangle'
)
const tangleX = new MsgV3.Tangle(msgHash1)
tangleX.add(msgHash1, msg1)
const tangleX = new MsgV3.Tangle(msgID1)
tangleX.add(msgID1, msg1)
const msg2 = MsgV3.create({
account: accountB,
@ -49,36 +49,36 @@ test('simple multi-author tangle', (t) => {
domain: 'post',
data: { text: 'Hello world!' },
tangles: {
[rootHashB]: tangleB,
[msgHash1]: tangleX,
[mootBID]: tangleB,
[msgID1]: tangleX,
},
keypair: keypairB,
})
assert.deepEqual(
Object.keys(msg2.metadata.tangles).sort(),
[rootHashB, msgHash1].sort(),
[mootBID, msgID1].sort(),
'msg2 has feed tangle and misc tangle'
)
assert.equal(
msg2.metadata.tangles[rootHashB].depth,
msg2.metadata.tangles[mootBID].depth,
1,
'msg2 feed tangle depth'
)
assert.deepEqual(
msg2.metadata.tangles[rootHashB].prev,
[rootHashB],
msg2.metadata.tangles[mootBID].prev,
[mootBID],
'msg2 feed tangle prev'
)
assert.equal(
msg2.metadata.tangles[msgHash1].depth,
msg2.metadata.tangles[msgID1].depth,
1,
'msg2 has tangle depth 1'
)
assert.deepEqual(
msg2.metadata.tangles[msgHash1].prev,
[msgHash1],
msg2.metadata.tangles[msgID1].prev,
[msgID1],
'msg2 has tangle prev'
)
})
@ -86,24 +86,24 @@ test('simple multi-author tangle', (t) => {
test('lipmaa in multi-author tangle', (t) => {
const keypairA = Keypair.generate('ed25519', 'alice')
const keypairB = Keypair.generate('ed25519', 'bob')
const accountA = MsgV3.getMsgHash(
const accountA = MsgV3.getMsgID(
MsgV3.createAccount(keypairA, 'person', 'alice')
)
const accountB = MsgV3.getMsgHash(
const accountB = MsgV3.getMsgID(
MsgV3.createAccount(keypairB, 'person', 'bob')
)
const data = { text: 'Hello world!' }
const rootMsgA = MsgV3.createRoot(accountA, 'post', keypairA)
const rootHashA = MsgV3.getMsgHash(rootMsgA)
const tangleA = new MsgV3.Tangle(rootHashA)
tangleA.add(rootHashA, rootMsgA)
const mootA = MsgV3.createMoot(accountA, 'post', keypairA)
const mootAID = MsgV3.getMsgID(mootA)
const tangleA = new MsgV3.Tangle(mootAID)
tangleA.add(mootAID, mootA)
const rootMsgB = MsgV3.createRoot(accountB, 'post', keypairB)
const rootHashB = MsgV3.getMsgHash(rootMsgB)
const tangleB = new MsgV3.Tangle(rootHashB)
tangleB.add(rootHashB, rootMsgB)
const mootB = MsgV3.createMoot(accountB, 'post', keypairB)
const mootBID = MsgV3.getMsgID(mootB)
const tangleB = new MsgV3.Tangle(mootBID)
tangleB.add(mootBID, mootB)
const msg1 = MsgV3.create({
account: accountA,
@ -111,18 +111,18 @@ test('lipmaa in multi-author tangle', (t) => {
domain: 'post',
data,
tangles: {
[rootHashA]: tangleA,
[mootAID]: tangleA,
},
keypair: keypairA,
})
const msgHash1 = MsgV3.getMsgHash(msg1)
tangleA.add(msgHash1, msg1)
const tangleThread = new MsgV3.Tangle(msgHash1)
tangleThread.add(msgHash1, msg1)
const msgID1 = MsgV3.getMsgID(msg1)
tangleA.add(msgID1, msg1)
const tangleThread = new MsgV3.Tangle(msgID1)
tangleThread.add(msgID1, msg1)
assert.deepEqual(
Object.keys(msg1.metadata.tangles),
[rootHashA],
[mootAID],
'A:msg1 has only feed tangle'
)
@ -132,18 +132,18 @@ test('lipmaa in multi-author tangle', (t) => {
domain: 'post',
data,
tangles: {
[rootHashB]: tangleB,
[msgHash1]: tangleThread,
[mootBID]: tangleB,
[msgID1]: tangleThread,
},
keypair: keypairB,
})
const msgHash2 = MsgV3.getMsgHash(msg2)
tangleB.add(msgHash2, msg2)
tangleThread.add(msgHash2, msg2)
const msgID2 = MsgV3.getMsgID(msg2)
tangleB.add(msgID2, msg2)
tangleThread.add(msgID2, msg2)
assert.deepEqual(
msg2.metadata.tangles[msgHash1].prev,
[msgHash1],
msg2.metadata.tangles[msgID1].prev,
[msgID1],
'B:msg2 points to A:msg1'
)
@ -153,18 +153,18 @@ test('lipmaa in multi-author tangle', (t) => {
domain: 'post',
data,
tangles: {
[rootHashB]: tangleB,
[msgHash1]: tangleThread,
[mootBID]: tangleB,
[msgID1]: tangleThread,
},
keypair: keypairB,
})
const msgHash3 = MsgV3.getMsgHash(msg3)
tangleB.add(msgHash3, msg3)
tangleThread.add(msgHash3, msg3)
const msgID3 = MsgV3.getMsgID(msg3)
tangleB.add(msgID3, msg3)
tangleThread.add(msgID3, msg3)
assert.deepEqual(
msg3.metadata.tangles[msgHash1].prev,
[msgHash2],
msg3.metadata.tangles[msgID1].prev,
[msgID2],
'B:msg3 points to B:msg2'
)
@ -174,18 +174,18 @@ test('lipmaa in multi-author tangle', (t) => {
domain: 'post',
data,
tangles: {
[rootHashA]: tangleA,
[msgHash1]: tangleThread,
[mootAID]: tangleA,
[msgID1]: tangleThread,
},
keypair: keypairA,
})
const msgHash4 = MsgV3.getMsgHash(msg4)
tangleB.add(msgHash4, msg4)
tangleThread.add(msgHash4, msg4)
const msgID4 = MsgV3.getMsgID(msg4)
tangleB.add(msgID4, msg4)
tangleThread.add(msgID4, msg4)
assert.deepEqual(
msg4.metadata.tangles[msgHash1].prev,
[msgHash1, msgHash3].sort(),
msg4.metadata.tangles[msgID1].prev,
[msgID1, msgID3].sort(),
'A:msg4 points to A:msg1,B:msg3'
)
})

View File

@ -5,16 +5,16 @@ const MsgV3 = require('../../lib/msg-v3')
test('validate root msg', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const account = MsgV3.getMsgHash(
const account = MsgV3.getMsgID(
MsgV3.createAccount(keypair, 'person', 'alice')
)
const pubkeys = new Set([keypair.public])
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const tangle = new MsgV3.Tangle(rootHash)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const tangle = new MsgV3.Tangle(mootID)
const err = MsgV3.validate(rootMsg, tangle, pubkeys, rootHash, rootHash)
const err = MsgV3.validate(moot, tangle, pubkeys, mootID, mootID)
assert.ifError(err, 'valid root msg')
})
@ -24,8 +24,8 @@ test('validate account tangle', (t) => {
pubkeys.add(keypair1.public)
const accountMsg0 = MsgV3.createAccount(keypair1, 'person', 'alice')
const account = MsgV3.getMsgHash(accountMsg0)
const accountMsg0Hash = account
const account = MsgV3.getMsgID(accountMsg0)
const accountMsg0ID = account
const tangle = new MsgV3.Tangle(account)
@ -33,7 +33,7 @@ test('validate account tangle', (t) => {
accountMsg0,
tangle,
pubkeys,
accountMsg0Hash,
accountMsg0ID,
account
)
assert.ifError(err, 'valid account root msg')
@ -52,13 +52,13 @@ test('validate account tangle', (t) => {
},
keypair: keypair1, // announcing keypair2 but signing with keypair1
})
const accountMsg1Hash = MsgV3.getMsgHash(accountMsg1)
const accountMsg1ID = MsgV3.getMsgID(accountMsg1)
err = MsgV3.validate(
accountMsg1,
tangle,
pubkeys,
accountMsg1Hash,
accountMsg1ID,
account
)
assert.ifError(err, 'valid account msg')
@ -66,15 +66,15 @@ test('validate account tangle', (t) => {
test('validate 2nd msg with existing root', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const account = MsgV3.getMsgHash(
const account = MsgV3.getMsgID(
MsgV3.createAccount(keypair, 'person', 'alice')
)
const pubkeys = new Set([keypair.public])
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(rootHash, rootMsg)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const tangle = new MsgV3.Tangle(mootID)
tangle.add(mootID, moot)
const msg1 = MsgV3.create({
account,
@ -82,28 +82,28 @@ test('validate 2nd msg with existing root', (t) => {
domain: 'post',
data: { text: 'Hello world!' },
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
keypair,
})
const msgHash1 = MsgV3.getMsgHash(msg1)
tangle.add(msgHash1, msg1)
const msgID1 = MsgV3.getMsgID(msg1)
tangle.add(msgID1, msg1)
const err = MsgV3.validate(msg1, tangle, pubkeys, msgHash1, rootHash)
const err = MsgV3.validate(msg1, tangle, pubkeys, msgID1, mootID)
assert.ifError(err, 'valid 2nd msg')
})
test('validate 2nd forked msg', (t) => {
const keypair = Keypair.generate('ed25519', 'alice')
const account = MsgV3.getMsgHash(
const account = MsgV3.getMsgID(
MsgV3.createAccount(keypair, 'person', 'alice')
)
const pubkeys = new Set([keypair.public])
const rootMsg = MsgV3.createRoot(account, 'post', keypair)
const rootHash = MsgV3.getMsgHash(rootMsg)
const tangle = new MsgV3.Tangle(rootHash)
tangle.add(rootHash, rootMsg)
const moot = MsgV3.createMoot(account, 'post', keypair)
const mootID = MsgV3.getMsgID(moot)
const tangle = new MsgV3.Tangle(mootID)
tangle.add(mootID, moot)
const msg1A = MsgV3.create({
account,
@ -111,11 +111,11 @@ test('validate 2nd forked msg', (t) => {
domain: 'post',
data: { text: 'Hello world!' },
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
keypair,
})
const msgHash1A = MsgV3.getMsgHash(msg1A)
const msgID1A = MsgV3.getMsgID(msg1A)
const msg1B = MsgV3.create({
account,
@ -123,14 +123,14 @@ test('validate 2nd forked msg', (t) => {
domain: 'post',
data: { text: 'Hello world!' },
tangles: {
[rootHash]: tangle,
[mootID]: tangle,
},
keypair,
})
const msgHash1B = MsgV3.getMsgHash(msg1B)
const msgID1B = MsgV3.getMsgID(msg1B)
tangle.add(msgHash1A, msg1A)
tangle.add(msgHash1B, msg1B)
const err = MsgV3.validate(msg1B, tangle, pubkeys, msgHash1B, rootHash)
tangle.add(msgID1A, msg1A)
tangle.add(msgID1B, msg1B)
const err = MsgV3.validate(msg1B, tangle, pubkeys, msgID1B, mootID)
assert.ifError(err, 'valid 2nd forked msg')
})

View File

@ -22,18 +22,18 @@ test('publish some msgs, close, re-open', async (t) => {
const account = await p(peer.db.account.create)({ domain: 'person' })
// t.pass('opened db')
const msgHashes = []
const msgIDs = []
for (let i = 0; i < 6; i++) {
const rec = await p(peer.db.feed.publish)({
account,
domain: 'post',
data: { text: 'hello ' + i },
})
msgHashes.push(rec.hash)
msgIDs.push(rec.id)
}
// t.pass('created some msgs')
await p(peer.db.del)(msgHashes[2])
await p(peer.db.del)(msgIDs[2])
// t.pass('deleted the 3rd msg')
await p(peer.close)(true)