mirror of https://codeberg.org/pzp/pzp-db.git
validate who+type in feed tangles
This commit is contained in:
parent
5883e1df21
commit
0917361305
|
@ -90,6 +90,22 @@ function validateTangle(msg, tangle, tangleId) {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return new Error('invalid message: prev must be an array, on feed: ' + msg.metadata.who);
|
return new Error('invalid message: prev must be an array, on feed: ' + msg.metadata.who);
|
||||||
}
|
}
|
||||||
|
if (typeof depth !== 'number') {
|
||||||
|
// prettier-ignore
|
||||||
|
return new Error('invalid message: depth must be a number, on feed: ' + msg.metadata.who);
|
||||||
|
}
|
||||||
|
if (tangle.isFeed()) {
|
||||||
|
const { type, who } = tangle.getFeed()
|
||||||
|
if (type !== msg.metadata.type) {
|
||||||
|
// prettier-ignore
|
||||||
|
return new Error(`invalid message: type "${msg.metadata.type}" does not match feed type "${type}"`)
|
||||||
|
}
|
||||||
|
if (who !== msg.metadata.who) {
|
||||||
|
// prettier-ignore
|
||||||
|
return new Error(`invalid message: who "${msg.metadata.who}" does not match feed who "${who}"`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let minDiff = Infinity
|
||||||
for (const p of prev) {
|
for (const p of prev) {
|
||||||
if (typeof p !== 'string') {
|
if (typeof p !== 'string') {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
|
@ -106,10 +122,16 @@ function validateTangle(msg, tangle, tangleId) {
|
||||||
}
|
}
|
||||||
const prevDepth = tangle.getDepth(p)
|
const prevDepth = tangle.getDepth(p)
|
||||||
|
|
||||||
if (prevDepth >= depth) {
|
const diff = depth - prevDepth
|
||||||
|
if (diff <= 0) {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return new Error('invalid message: depth of prev ' + p + ' is not lower, on feed: ' + msg.metadata.who);
|
return new Error('invalid message: depth of prev ' + p + ' is not lower, on feed: ' + msg.metadata.who);
|
||||||
}
|
}
|
||||||
|
if (diff < minDiff) minDiff = diff
|
||||||
|
}
|
||||||
|
if (minDiff !== 1) {
|
||||||
|
// prettier-ignore
|
||||||
|
return new Error('invalid message: depth must be the largest prev depth plus one');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
* @typedef {import("./plugin").Rec} Rec
|
* @typedef {import("./plugin").Rec} Rec
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {import("./feed-v1").Msg} Msg
|
||||||
|
*/
|
||||||
|
|
||||||
function lipmaa(n) {
|
function lipmaa(n) {
|
||||||
let m = 1
|
let m = 1
|
||||||
let po3 = 3
|
let po3 = 3
|
||||||
|
@ -45,6 +49,11 @@ class Tangle {
|
||||||
*/
|
*/
|
||||||
#rootHash
|
#rootHash
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {Msg}
|
||||||
|
*/
|
||||||
|
#rootMsg
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {Set<string>}
|
* @type {Set<string>}
|
||||||
*/
|
*/
|
||||||
|
@ -89,6 +98,7 @@ class Tangle {
|
||||||
this.#tips.add(msgHash)
|
this.#tips.add(msgHash)
|
||||||
this.#perDepth.set(0, [msgHash])
|
this.#perDepth.set(0, [msgHash])
|
||||||
this.#depth.set(msgHash, 0)
|
this.#depth.set(msgHash, 0)
|
||||||
|
this.#rootMsg = msg
|
||||||
} else if (tangles[this.#rootHash]) {
|
} else if (tangles[this.#rootHash]) {
|
||||||
this.#tips.add(msgHash)
|
this.#tips.add(msgHash)
|
||||||
const prev = tangles[this.#rootHash].prev
|
const prev = tangles[this.#rootHash].prev
|
||||||
|
@ -162,6 +172,18 @@ class Tangle {
|
||||||
return this.#depth.get(msgHash) ?? -1
|
return this.#depth.get(msgHash) ?? -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isFeed() {
|
||||||
|
if (this.#rootMsg.content) return false
|
||||||
|
const metadata = this.#rootMsg.metadata
|
||||||
|
return metadata.size === 0 && metadata.proof === ''
|
||||||
|
}
|
||||||
|
|
||||||
|
getFeed() {
|
||||||
|
if (!this.isFeed()) return null
|
||||||
|
const { type, who } = this.#rootMsg.metadata
|
||||||
|
return { type, who }
|
||||||
|
}
|
||||||
|
|
||||||
#shortestPathToRoot(msgHash) {
|
#shortestPathToRoot(msgHash) {
|
||||||
const path = []
|
const path = []
|
||||||
let current = msgHash
|
let current = msgHash
|
||||||
|
|
|
@ -176,3 +176,56 @@ tape('invalid msg with unknown prev', (t) => {
|
||||||
t.end()
|
t.end()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
tape('invalid feed msg with a different who', (t) => {
|
||||||
|
const keysA = generateKeypair('alice')
|
||||||
|
const keysB = generateKeypair('bob')
|
||||||
|
|
||||||
|
const rootMsg = FeedV1.createRoot(keysA, 'post')
|
||||||
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
|
const feedTangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||||
|
|
||||||
|
const msg = FeedV1.create({
|
||||||
|
keys: keysB,
|
||||||
|
content: { text: 'Hello world!' },
|
||||||
|
type: 'post',
|
||||||
|
tangles: {
|
||||||
|
[rootHash]: feedTangle,
|
||||||
|
},
|
||||||
|
when: 1652030002000,
|
||||||
|
})
|
||||||
|
const msgHash = FeedV1.getMsgHash(msg)
|
||||||
|
|
||||||
|
FeedV1.validate(msg, feedTangle, msgHash, rootHash, (err) => {
|
||||||
|
t.match(err.message, /who ".*" does not match feed who/, 'invalid feed msg')
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
tape('invalid feed msg with a different type', (t) => {
|
||||||
|
const keysA = generateKeypair('alice')
|
||||||
|
|
||||||
|
const rootMsg = FeedV1.createRoot(keysA, 'post')
|
||||||
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
|
const feedTangle = new Tangle(rootHash, [{ hash: rootHash, msg: rootMsg }])
|
||||||
|
|
||||||
|
const msg = FeedV1.create({
|
||||||
|
keys: keysA,
|
||||||
|
content: { text: 'Hello world!' },
|
||||||
|
type: 'comment',
|
||||||
|
tangles: {
|
||||||
|
[rootHash]: feedTangle,
|
||||||
|
},
|
||||||
|
when: 1652030002000,
|
||||||
|
})
|
||||||
|
const msgHash = FeedV1.getMsgHash(msg)
|
||||||
|
|
||||||
|
FeedV1.validate(msg, feedTangle, msgHash, rootHash, (err) => {
|
||||||
|
t.match(
|
||||||
|
err.message,
|
||||||
|
/type "comment" does not match feed type "post"/,
|
||||||
|
'invalid feed msg'
|
||||||
|
)
|
||||||
|
t.end()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue