validate is synchronous

This commit is contained in:
Andre Staltz 2023-04-18 18:40:52 +03:00
parent 8288432785
commit 3ab7d98550
5 changed files with 93 additions and 93 deletions

View File

@ -222,6 +222,10 @@ class Tangle {
return path
}
size() {
return this.#depth.size
}
getMaxDepth() {
return this.#maxDepth
}

View File

@ -110,6 +110,7 @@ function validateTangle(msg, tangle, tangleId) {
}
}
let minDiff = Infinity
let countPrevUnknown = 0
for (const p of prev) {
if (typeof p !== 'string') {
// prettier-ignore
@ -121,8 +122,8 @@ function validateTangle(msg, tangle, tangleId) {
}
if (!tangle.has(p)) {
// prettier-ignore
return new Error('invalid message: prev ' + p + ' is not locally known, on feed: ' + msg.metadata.who);
countPrevUnknown += 1
continue
}
const prevDepth = tangle.getDepth(p)
@ -133,13 +134,23 @@ function validateTangle(msg, tangle, tangleId) {
}
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
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]) {
// prettier-ignore
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
function validateSync(msg, tangle, msgHash, rootHash) {
function validate(msg, tangle, msgHash, rootHash) {
let err
if ((err = validateShape(msg))) return err
if ((err = validateWho(msg))) return err
if (msgHash === rootHash) {
if ((err = validateTangleRoot(msg))) return err
if (tangle.size() === 0) {
if ((err = validateTangleRoot(msg, msgHash, rootHash))) return err
} else {
if ((err = validateTangle(msg, tangle, rootHash))) return err
}
@ -203,14 +214,6 @@ function validateSync(msg, tangle, msgHash, rootHash) {
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) {
// let err
// let prev = prevNativeMsg

View File

@ -189,19 +189,22 @@ exports.init = function initDB(peer, config) {
const tangle = new DBTangle(tangleRootHash, records())
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
if (err) return cb(new Error('add() failed validation for feed format v1', {cause: err}))
logAppend(msgHash, msg, logAppendCB)
return cb(new Error('add() failed validation for feed format v1', {cause: err}))
}
function logAppendCB(err, rec) {
logAppend(msgHash, msg, (err, rec) => {
if (err) return cb(new Error('add() failed in the log', { cause: err }))
onRecordAdded.set(rec)
cb(null, rec)
}
})
}
function create(opts, cb) {

View File

@ -23,11 +23,10 @@ tape('invalid msg with non-array prev', (t) => {
msg.metadata.tangles[rootHash].prev = null
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.match(err.message, /prev must be an array/, 'invalid 2nd msg description')
t.end()
})
})
tape('invalid msg with bad prev', (t) => {
@ -62,7 +61,7 @@ tape('invalid msg with bad prev', (t) => {
msg2.metadata.tangles[rootHash].prev = [1234]
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.match(
err.message,
@ -70,7 +69,6 @@ tape('invalid msg with bad prev', (t) => {
'invalid 2nd msg description'
)
t.end()
})
})
tape('invalid msg with URI in prev', (t) => {
@ -107,7 +105,7 @@ tape('invalid msg with URI in prev', (t) => {
msg2.metadata.tangles[rootHash].depth = 1
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.match(
err.message,
@ -115,7 +113,6 @@ tape('invalid msg with URI in prev', (t) => {
'invalid 2nd msg description'
)
t.end()
})
})
tape('invalid msg with unknown prev', (t) => {
@ -148,8 +145,9 @@ tape('invalid msg with unknown prev', (t) => {
})
const unknownMsgHash = FeedV1.getMsgHash(unknownMsg)
const tangle2 = new FeedV1.Tangle(rootHash)
tangle2.add(rootHash, rootMsg)
const fakeRootHash = 'ABCDEabcde' + rootHash.substring(10)
const tangle2 = new FeedV1.Tangle(fakeRootHash)
tangle2.add(fakeRootHash, rootMsg)
tangle2.add(unknownMsgHash, unknownMsg)
const msg2 = FeedV1.create({
@ -157,20 +155,19 @@ tape('invalid msg with unknown prev', (t) => {
content: { text: 'Hello world!' },
type: 'post',
tangles: {
[rootHash]: tangle2
[rootHash]: tangle2,
},
})
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.match(
err.message,
/prev .+ is not locally known/,
/all prev are locally unknown/,
'invalid 2nd msg description'
)
t.end()
})
})
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)
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.end()
})
})
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)
FeedV1.validate(msg, feedTangle, msgHash, rootHash, (err) => {
const err = FeedV1.validate(msg, feedTangle, msgHash, rootHash)
t.match(
err.message,
/type "comment" does not match feed type "post"/,
'invalid feed msg'
)
t.end()
})
})

View File

@ -9,13 +9,11 @@ tape('validate root msg', (t) => {
const rootMsg = FeedV1.createRoot(keys, 'post')
const rootHash = FeedV1.getMsgHash(rootMsg)
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)
t.error(err, 'valid root msg')
t.end()
})
})
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)
tangle.add(msgHash1, msg1)
FeedV1.validate(msg1, tangle, msgHash1, rootHash, (err) => {
const err = FeedV1.validate(msg1, tangle, msgHash1, rootHash)
if (err) console.log(err)
t.error(err, 'valid 2nd msg')
t.end()
})
})
tape('validate 2nd forked msg', (t) => {
@ -75,11 +72,10 @@ tape('validate 2nd forked msg', (t) => {
tangle.add(msgHash1A, msg1A)
tangle.add(msgHash1B, msg1B)
FeedV1.validate(msg1B, tangle, msgHash1B, rootHash, (err) => {
const err = FeedV1.validate(msg1B, tangle, msgHash1B, rootHash)
if (err) console.log(err)
t.error(err, 'valid 2nd forked msg')
t.end()
})
})
tape('invalid msg with unknown previous', (t) => {
@ -104,13 +100,12 @@ tape('invalid msg with unknown previous', (t) => {
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.match(
err.message,
/prev .+ is not locally known/,
/all prev are locally unknown/,
'invalid 2nd msg description'
)
t.end()
})
})