mirror of https://codeberg.org/pzp/pzp-db.git
validate is synchronous
This commit is contained in:
parent
8288432785
commit
3ab7d98550
|
@ -222,6 +222,10 @@ class Tangle {
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size() {
|
||||||
|
return this.#depth.size
|
||||||
|
}
|
||||||
|
|
||||||
getMaxDepth() {
|
getMaxDepth() {
|
||||||
return this.#maxDepth
|
return this.#maxDepth
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,6 +110,7 @@ function validateTangle(msg, tangle, tangleId) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let minDiff = Infinity
|
let minDiff = Infinity
|
||||||
|
let countPrevUnknown = 0
|
||||||
for (const p of prev) {
|
for (const p of prev) {
|
||||||
if (typeof p !== 'string') {
|
if (typeof p !== 'string') {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
|
@ -121,8 +122,8 @@ function validateTangle(msg, tangle, tangleId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tangle.has(p)) {
|
if (!tangle.has(p)) {
|
||||||
// prettier-ignore
|
countPrevUnknown += 1
|
||||||
return new Error('invalid message: prev ' + p + ' is not locally known, on feed: ' + msg.metadata.who);
|
continue
|
||||||
}
|
}
|
||||||
const prevDepth = tangle.getDepth(p)
|
const prevDepth = tangle.getDepth(p)
|
||||||
|
|
||||||
|
@ -133,13 +134,23 @@ function validateTangle(msg, tangle, tangleId) {
|
||||||
}
|
}
|
||||||
if (diff < minDiff) minDiff = diff
|
if (diff < minDiff) minDiff = diff
|
||||||
}
|
}
|
||||||
if (minDiff !== 1) {
|
|
||||||
|
if (countPrevUnknown === prev.length) {
|
||||||
|
// prettier-ignore
|
||||||
|
return new Error('invalid message: all prev are locally unknown, on feed: ' + msg.metadata.who)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (countPrevUnknown === 0 && minDiff !== 1) {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return new Error('invalid message: depth must be the largest prev depth plus one');
|
return new Error('invalid message: depth must be the largest prev depth plus one');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateTangleRoot(msg, tangleId) {
|
function validateTangleRoot(msg, msgHash, tangleId) {
|
||||||
|
if (msgHash !== tangleId) {
|
||||||
|
// prettier-ignore
|
||||||
|
return new Error('invalid message: tangle root hash must match tangleId, on feed: ' + msg.metadata.who);
|
||||||
|
}
|
||||||
if (msg.metadata.tangles[tangleId]) {
|
if (msg.metadata.tangles[tangleId]) {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return new Error('invalid message: tangle root must not have self tangle data, on feed: ' + msg.metadata.who);
|
return new Error('invalid message: tangle root must not have self tangle data, on feed: ' + msg.metadata.who);
|
||||||
|
@ -190,12 +201,12 @@ function validateContent(msg) {
|
||||||
|
|
||||||
// FIXME: validateDepth should be +1 of the max of prev depth
|
// FIXME: validateDepth should be +1 of the max of prev depth
|
||||||
|
|
||||||
function validateSync(msg, tangle, msgHash, rootHash) {
|
function validate(msg, tangle, msgHash, rootHash) {
|
||||||
let err
|
let err
|
||||||
if ((err = validateShape(msg))) return err
|
if ((err = validateShape(msg))) return err
|
||||||
if ((err = validateWho(msg))) return err
|
if ((err = validateWho(msg))) return err
|
||||||
if (msgHash === rootHash) {
|
if (tangle.size() === 0) {
|
||||||
if ((err = validateTangleRoot(msg))) return err
|
if ((err = validateTangleRoot(msg, msgHash, rootHash))) return err
|
||||||
} else {
|
} else {
|
||||||
if ((err = validateTangle(msg, tangle, rootHash))) return err
|
if ((err = validateTangle(msg, tangle, rootHash))) return err
|
||||||
}
|
}
|
||||||
|
@ -203,14 +214,6 @@ function validateSync(msg, tangle, msgHash, rootHash) {
|
||||||
if ((err = validateSignature(msg))) return err
|
if ((err = validateSignature(msg))) return err
|
||||||
}
|
}
|
||||||
|
|
||||||
function validate(msg, tangle, msgHash, rootHash, cb) {
|
|
||||||
let err
|
|
||||||
if ((err = validateSync(msg, tangle, msgHash, rootHash))) {
|
|
||||||
return cb(err)
|
|
||||||
}
|
|
||||||
cb()
|
|
||||||
}
|
|
||||||
|
|
||||||
// function validateBatch(nativeMsgs, prevNativeMsg, hmacKey, cb) {
|
// function validateBatch(nativeMsgs, prevNativeMsg, hmacKey, cb) {
|
||||||
// let err
|
// let err
|
||||||
// let prev = prevNativeMsg
|
// let prev = prevNativeMsg
|
||||||
|
|
|
@ -189,19 +189,22 @@ exports.init = function initDB(peer, config) {
|
||||||
const tangle = new DBTangle(tangleRootHash, records())
|
const tangle = new DBTangle(tangleRootHash, records())
|
||||||
|
|
||||||
const msgHash = FeedV1.getMsgHash(msg)
|
const msgHash = FeedV1.getMsgHash(msg)
|
||||||
FeedV1.validate(msg, tangle, msgHash, tangleRootHash, validationCB)
|
|
||||||
|
|
||||||
function validationCB(err) {
|
// TODO: optimize this. Perhaps have a Map() of msgHash -> record
|
||||||
|
let rec
|
||||||
|
if ((rec = getRecord(msgHash))) return cb(null, rec)
|
||||||
|
|
||||||
|
let err
|
||||||
|
if ((err = FeedV1.validate(msg, tangle, msgHash, tangleRootHash))) {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
if (err) return cb(new Error('add() failed validation for feed format v1', {cause: err}))
|
return cb(new Error('add() failed validation for feed format v1', {cause: err}))
|
||||||
logAppend(msgHash, msg, logAppendCB)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function logAppendCB(err, rec) {
|
logAppend(msgHash, msg, (err, rec) => {
|
||||||
if (err) return cb(new Error('add() failed in the log', { cause: err }))
|
if (err) return cb(new Error('add() failed in the log', { cause: err }))
|
||||||
onRecordAdded.set(rec)
|
onRecordAdded.set(rec)
|
||||||
cb(null, rec)
|
cb(null, rec)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function create(opts, cb) {
|
function create(opts, cb) {
|
||||||
|
|
|
@ -23,11 +23,10 @@ tape('invalid msg with non-array prev', (t) => {
|
||||||
msg.metadata.tangles[rootHash].prev = null
|
msg.metadata.tangles[rootHash].prev = null
|
||||||
const msgHash = FeedV1.getMsgHash(msg)
|
const msgHash = FeedV1.getMsgHash(msg)
|
||||||
|
|
||||||
FeedV1.validate(msg, tangle, msgHash, rootHash, (err) => {
|
const err = FeedV1.validate(msg, tangle, msgHash, rootHash)
|
||||||
t.ok(err, 'invalid 2nd msg throws')
|
t.ok(err, 'invalid 2nd msg throws')
|
||||||
t.match(err.message, /prev must be an array/, 'invalid 2nd msg description')
|
t.match(err.message, /prev must be an array/, 'invalid 2nd msg description')
|
||||||
t.end()
|
t.end()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
tape('invalid msg with bad prev', (t) => {
|
tape('invalid msg with bad prev', (t) => {
|
||||||
|
@ -62,15 +61,14 @@ tape('invalid msg with bad prev', (t) => {
|
||||||
msg2.metadata.tangles[rootHash].prev = [1234]
|
msg2.metadata.tangles[rootHash].prev = [1234]
|
||||||
const msgHash2 = FeedV1.getMsgHash(msg2)
|
const msgHash2 = FeedV1.getMsgHash(msg2)
|
||||||
|
|
||||||
FeedV1.validate(msg2, tangle, msgHash2, rootHash, (err) => {
|
const err = FeedV1.validate(msg2, tangle, msgHash2, rootHash)
|
||||||
t.ok(err, 'invalid 2nd msg throws')
|
t.ok(err, 'invalid 2nd msg throws')
|
||||||
t.match(
|
t.match(
|
||||||
err.message,
|
err.message,
|
||||||
/prev must contain strings/,
|
/prev must contain strings/,
|
||||||
'invalid 2nd msg description'
|
'invalid 2nd msg description'
|
||||||
)
|
)
|
||||||
t.end()
|
t.end()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
tape('invalid msg with URI in prev', (t) => {
|
tape('invalid msg with URI in prev', (t) => {
|
||||||
|
@ -107,15 +105,14 @@ tape('invalid msg with URI in prev', (t) => {
|
||||||
msg2.metadata.tangles[rootHash].depth = 1
|
msg2.metadata.tangles[rootHash].depth = 1
|
||||||
msg2.metadata.tangles[rootHash].prev = [fakeMsgKey1]
|
msg2.metadata.tangles[rootHash].prev = [fakeMsgKey1]
|
||||||
|
|
||||||
FeedV1.validate(msg2, tangle, msgHash2, rootHash, (err) => {
|
const err = FeedV1.validate(msg2, tangle, msgHash2, rootHash)
|
||||||
t.ok(err, 'invalid 2nd msg throws')
|
t.ok(err, 'invalid 2nd msg throws')
|
||||||
t.match(
|
t.match(
|
||||||
err.message,
|
err.message,
|
||||||
/prev must not contain URIs/,
|
/prev must not contain URIs/,
|
||||||
'invalid 2nd msg description'
|
'invalid 2nd msg description'
|
||||||
)
|
)
|
||||||
t.end()
|
t.end()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
tape('invalid msg with unknown prev', (t) => {
|
tape('invalid msg with unknown prev', (t) => {
|
||||||
|
@ -148,8 +145,9 @@ tape('invalid msg with unknown prev', (t) => {
|
||||||
})
|
})
|
||||||
const unknownMsgHash = FeedV1.getMsgHash(unknownMsg)
|
const unknownMsgHash = FeedV1.getMsgHash(unknownMsg)
|
||||||
|
|
||||||
const tangle2 = new FeedV1.Tangle(rootHash)
|
const fakeRootHash = 'ABCDEabcde' + rootHash.substring(10)
|
||||||
tangle2.add(rootHash, rootMsg)
|
const tangle2 = new FeedV1.Tangle(fakeRootHash)
|
||||||
|
tangle2.add(fakeRootHash, rootMsg)
|
||||||
tangle2.add(unknownMsgHash, unknownMsg)
|
tangle2.add(unknownMsgHash, unknownMsg)
|
||||||
|
|
||||||
const msg2 = FeedV1.create({
|
const msg2 = FeedV1.create({
|
||||||
|
@ -157,20 +155,19 @@ tape('invalid msg with unknown prev', (t) => {
|
||||||
content: { text: 'Hello world!' },
|
content: { text: 'Hello world!' },
|
||||||
type: 'post',
|
type: 'post',
|
||||||
tangles: {
|
tangles: {
|
||||||
[rootHash]: tangle2
|
[rootHash]: tangle2,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
const msgHash2 = FeedV1.getMsgHash(msg2)
|
const msgHash2 = FeedV1.getMsgHash(msg2)
|
||||||
|
|
||||||
FeedV1.validate(msg2, tangle, msgHash2, rootHash, (err) => {
|
const err = FeedV1.validate(msg2, tangle, msgHash2, rootHash)
|
||||||
t.ok(err, 'invalid 2nd msg throws')
|
t.ok(err, 'invalid 2nd msg throws')
|
||||||
t.match(
|
t.match(
|
||||||
err.message,
|
err.message,
|
||||||
/prev .+ is not locally known/,
|
/all prev are locally unknown/,
|
||||||
'invalid 2nd msg description'
|
'invalid 2nd msg description'
|
||||||
)
|
)
|
||||||
t.end()
|
t.end()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
tape('invalid feed msg with a different who', (t) => {
|
tape('invalid feed msg with a different who', (t) => {
|
||||||
|
@ -192,10 +189,9 @@ tape('invalid feed msg with a different who', (t) => {
|
||||||
})
|
})
|
||||||
const msgHash = FeedV1.getMsgHash(msg)
|
const msgHash = FeedV1.getMsgHash(msg)
|
||||||
|
|
||||||
FeedV1.validate(msg, feedTangle, msgHash, rootHash, (err) => {
|
const err = FeedV1.validate(msg, feedTangle, msgHash, rootHash)
|
||||||
t.match(err.message, /who ".*" does not match feed who/, 'invalid feed msg')
|
t.match(err.message, /who ".*" does not match feed who/, 'invalid feed msg')
|
||||||
t.end()
|
t.end()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
tape('invalid feed msg with a different type', (t) => {
|
tape('invalid feed msg with a different type', (t) => {
|
||||||
|
@ -216,12 +212,11 @@ tape('invalid feed msg with a different type', (t) => {
|
||||||
})
|
})
|
||||||
const msgHash = FeedV1.getMsgHash(msg)
|
const msgHash = FeedV1.getMsgHash(msg)
|
||||||
|
|
||||||
FeedV1.validate(msg, feedTangle, msgHash, rootHash, (err) => {
|
const err = FeedV1.validate(msg, feedTangle, msgHash, rootHash)
|
||||||
t.match(
|
t.match(
|
||||||
err.message,
|
err.message,
|
||||||
/type "comment" does not match feed type "post"/,
|
/type "comment" does not match feed type "post"/,
|
||||||
'invalid feed msg'
|
'invalid feed msg'
|
||||||
)
|
)
|
||||||
t.end()
|
t.end()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
|
@ -9,13 +9,11 @@ tape('validate root msg', (t) => {
|
||||||
const rootMsg = FeedV1.createRoot(keys, 'post')
|
const rootMsg = FeedV1.createRoot(keys, 'post')
|
||||||
const rootHash = FeedV1.getMsgHash(rootMsg)
|
const rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
const tangle = new FeedV1.Tangle(rootHash)
|
const tangle = new FeedV1.Tangle(rootHash)
|
||||||
tangle.add(rootHash, rootMsg)
|
|
||||||
|
|
||||||
FeedV1.validate(rootMsg, tangle, rootHash, rootHash, (err) => {
|
const err = FeedV1.validate(rootMsg, tangle, rootHash, rootHash)
|
||||||
if (err) console.log(err)
|
if (err) console.log(err)
|
||||||
t.error(err, 'valid root msg')
|
t.error(err, 'valid root msg')
|
||||||
t.end()
|
t.end()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
tape('validate 2nd msg with existing root', (t) => {
|
tape('validate 2nd msg with existing root', (t) => {
|
||||||
|
@ -37,11 +35,10 @@ tape('validate 2nd msg with existing root', (t) => {
|
||||||
const msgHash1 = FeedV1.getMsgHash(msg1)
|
const msgHash1 = FeedV1.getMsgHash(msg1)
|
||||||
tangle.add(msgHash1, msg1)
|
tangle.add(msgHash1, msg1)
|
||||||
|
|
||||||
FeedV1.validate(msg1, tangle, msgHash1, rootHash, (err) => {
|
const err = FeedV1.validate(msg1, tangle, msgHash1, rootHash)
|
||||||
if (err) console.log(err)
|
if (err) console.log(err)
|
||||||
t.error(err, 'valid 2nd msg')
|
t.error(err, 'valid 2nd msg')
|
||||||
t.end()
|
t.end()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
tape('validate 2nd forked msg', (t) => {
|
tape('validate 2nd forked msg', (t) => {
|
||||||
|
@ -75,11 +72,10 @@ tape('validate 2nd forked msg', (t) => {
|
||||||
|
|
||||||
tangle.add(msgHash1A, msg1A)
|
tangle.add(msgHash1A, msg1A)
|
||||||
tangle.add(msgHash1B, msg1B)
|
tangle.add(msgHash1B, msg1B)
|
||||||
FeedV1.validate(msg1B, tangle, msgHash1B, rootHash, (err) => {
|
const err = FeedV1.validate(msg1B, tangle, msgHash1B, rootHash)
|
||||||
if (err) console.log(err)
|
if (err) console.log(err)
|
||||||
t.error(err, 'valid 2nd forked msg')
|
t.error(err, 'valid 2nd forked msg')
|
||||||
t.end()
|
t.end()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
tape('invalid msg with unknown previous', (t) => {
|
tape('invalid msg with unknown previous', (t) => {
|
||||||
|
@ -104,13 +100,12 @@ tape('invalid msg with unknown previous', (t) => {
|
||||||
|
|
||||||
msg1.metadata.tangles[rootHash].prev = [fakeMsgHash]
|
msg1.metadata.tangles[rootHash].prev = [fakeMsgHash]
|
||||||
|
|
||||||
FeedV1.validate(msg1, tangle, msgHash1, rootHash, (err) => {
|
const err = FeedV1.validate(msg1, tangle, msgHash1, rootHash)
|
||||||
t.ok(err, 'invalid 2nd msg throws')
|
t.ok(err, 'invalid 2nd msg throws')
|
||||||
t.match(
|
t.match(
|
||||||
err.message,
|
err.message,
|
||||||
/prev .+ is not locally known/,
|
/all prev are locally unknown/,
|
||||||
'invalid 2nd msg description'
|
'invalid 2nd msg description'
|
||||||
)
|
)
|
||||||
t.end()
|
t.end()
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue