mirror of https://codeberg.org/pzp/pzp-db.git
add metadata.v, rename metadata.proof to metadata.hash
This commit is contained in:
parent
faa7b13c92
commit
3686f5de24
|
@ -39,10 +39,11 @@ function isEmptyObject(obj) {
|
||||||
* @typedef {Object} Msg
|
* @typedef {Object} Msg
|
||||||
* @property {*} content
|
* @property {*} content
|
||||||
* @property {Object} metadata
|
* @property {Object} metadata
|
||||||
* @property {string} metadata.proof
|
* @property {string} metadata.hash
|
||||||
* @property {number} metadata.size
|
* @property {number} metadata.size
|
||||||
* @property {Record<string, TangleMetadata>} metadata.tangles
|
* @property {Record<string, TangleMetadata>} metadata.tangles
|
||||||
* @property {string} metadata.type
|
* @property {string} metadata.type
|
||||||
|
* @property {1} metadata.v
|
||||||
* @property {string} metadata.who
|
* @property {string} metadata.who
|
||||||
* @property {string} sig
|
* @property {string} sig
|
||||||
*/
|
*/
|
||||||
|
@ -115,7 +116,7 @@ function create(opts) {
|
||||||
if ((err = validateType(opts.type))) throw err
|
if ((err = validateType(opts.type))) throw err
|
||||||
if (!opts.tangles) throw new Error('opts.tangles is required')
|
if (!opts.tangles) throw new Error('opts.tangles is required')
|
||||||
|
|
||||||
const [proof, size] = representContent(opts.content)
|
const [hash, size] = representContent(opts.content)
|
||||||
|
|
||||||
const tangles = {}
|
const tangles = {}
|
||||||
if (opts.tangles) {
|
if (opts.tangles) {
|
||||||
|
@ -136,10 +137,11 @@ function create(opts) {
|
||||||
const msg = {
|
const msg = {
|
||||||
content: opts.content,
|
content: opts.content,
|
||||||
metadata: {
|
metadata: {
|
||||||
proof,
|
hash,
|
||||||
size,
|
size,
|
||||||
tangles,
|
tangles,
|
||||||
type: opts.type,
|
type: opts.type,
|
||||||
|
v: 1,
|
||||||
who: stripAuthor(opts.keys.id),
|
who: stripAuthor(opts.keys.id),
|
||||||
},
|
},
|
||||||
sig: '',
|
sig: '',
|
||||||
|
@ -168,10 +170,11 @@ function createRoot(keys, type) {
|
||||||
const msg = {
|
const msg = {
|
||||||
content: null,
|
content: null,
|
||||||
metadata: {
|
metadata: {
|
||||||
proof: '',
|
hash: null,
|
||||||
size: 0,
|
size: 0,
|
||||||
tangles: {},
|
tangles: {},
|
||||||
type,
|
type,
|
||||||
|
v: 1,
|
||||||
who: stripAuthor(keys.id),
|
who: stripAuthor(keys.id),
|
||||||
},
|
},
|
||||||
sig: '',
|
sig: '',
|
||||||
|
|
|
@ -167,7 +167,7 @@ class Tangle {
|
||||||
isFeed() {
|
isFeed() {
|
||||||
if (this.#rootMsg.content) return false
|
if (this.#rootMsg.content) return false
|
||||||
const metadata = this.#rootMsg.metadata
|
const metadata = this.#rootMsg.metadata
|
||||||
return metadata.size === 0 && metadata.proof === ''
|
return metadata.size === 0 && metadata.hash === null
|
||||||
}
|
}
|
||||||
|
|
||||||
getFeed() {
|
getFeed() {
|
||||||
|
|
|
@ -2,6 +2,7 @@ const base58 = require('bs58')
|
||||||
const ed25519 = require('ssb-keys/sodium')
|
const ed25519 = require('ssb-keys/sodium')
|
||||||
const stringify = require('fast-json-stable-stringify')
|
const stringify = require('fast-json-stable-stringify')
|
||||||
const Tangle = require('./tangle')
|
const Tangle = require('./tangle')
|
||||||
|
const representContent = require('./represent-content')
|
||||||
|
|
||||||
function validateShape(msg) {
|
function validateShape(msg) {
|
||||||
if (!msg || typeof msg !== 'object') {
|
if (!msg || typeof msg !== 'object') {
|
||||||
|
@ -13,11 +14,14 @@ function validateShape(msg) {
|
||||||
if (typeof msg.metadata.who === 'undefined') {
|
if (typeof msg.metadata.who === 'undefined') {
|
||||||
return new Error('invalid message: must have metadata.who')
|
return new Error('invalid message: must have metadata.who')
|
||||||
}
|
}
|
||||||
|
if (msg.metadata.v !== 1) {
|
||||||
|
return new Error('invalid message: must have metadata.v 1')
|
||||||
|
}
|
||||||
if (typeof msg.metadata.tangles !== 'object') {
|
if (typeof msg.metadata.tangles !== 'object') {
|
||||||
return new Error('invalid message: must have metadata.tangles')
|
return new Error('invalid message: must have metadata.tangles')
|
||||||
}
|
}
|
||||||
if (typeof msg.metadata.proof === 'undefined') {
|
if (typeof msg.metadata.hash === 'undefined') {
|
||||||
return new Error('invalid message: must have metadata.proof')
|
return new Error('invalid message: must have metadata.hash')
|
||||||
}
|
}
|
||||||
if (typeof msg.metadata.size === 'undefined') {
|
if (typeof msg.metadata.size === 'undefined') {
|
||||||
return new Error('invalid message: must have metadata.size')
|
return new Error('invalid message: must have metadata.size')
|
||||||
|
@ -162,10 +166,8 @@ function validateType(type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateContent(msg) {
|
function validateContent(msg) {
|
||||||
// FIXME: if content exists, check it against `proof` and `size`
|
|
||||||
// FIXME: if content does not exist, do nothing
|
|
||||||
const { content } = msg
|
const { content } = msg
|
||||||
if (!content) {
|
if (content === null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (Array.isArray(content)) {
|
if (Array.isArray(content)) {
|
||||||
|
@ -175,6 +177,15 @@ function validateContent(msg) {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return new Error('invalid message: content must be an object or string, on feed: ' + msg.metadata.who);
|
return new Error('invalid message: content must be an object or string, on feed: ' + msg.metadata.who);
|
||||||
}
|
}
|
||||||
|
const [hash, size] = representContent(content)
|
||||||
|
if (hash !== msg.metadata.hash) {
|
||||||
|
// prettier-ignore
|
||||||
|
return new Error('invalid message: content hash does not match metadata.hash, on feed: ' + msg.metadata.who);
|
||||||
|
}
|
||||||
|
if (size !== msg.metadata.size) {
|
||||||
|
// prettier-ignore
|
||||||
|
return new Error('invalid message: content size does not match metadata.size, on feed: ' + msg.metadata.who);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: validateDepth should be +1 of the max of prev depth
|
// FIXME: validateDepth should be +1 of the max of prev depth
|
||||||
|
|
|
@ -20,7 +20,7 @@ test('erase', async (t) => {
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
const rootHash = 'PGwQiuwFnB7EySQHBit2mA'
|
const rootHash = 'Nf2kuXAYsLBHEgU9eonYdn'
|
||||||
const msgHashes = []
|
const msgHashes = []
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
const rec = await p(peer.db.create)({
|
const rec = await p(peer.db.create)({
|
||||||
|
|
|
@ -8,14 +8,14 @@ tape('FeedV1.createRoot()', (t) => {
|
||||||
const keys = generateKeypair('alice')
|
const keys = generateKeypair('alice')
|
||||||
rootMsg = FeedV1.createRoot(keys, 'post')
|
rootMsg = FeedV1.createRoot(keys, 'post')
|
||||||
t.equals(rootMsg.content, null, 'content')
|
t.equals(rootMsg.content, null, 'content')
|
||||||
t.equals(rootMsg.metadata.proof, '', 'proof')
|
t.equals(rootMsg.metadata.hash, null, 'hash')
|
||||||
t.equals(rootMsg.metadata.size, 0, 'size')
|
t.equals(rootMsg.metadata.size, 0, 'size')
|
||||||
t.equals(rootMsg.metadata.type, 'post', 'type')
|
t.equals(rootMsg.metadata.type, 'post', 'type')
|
||||||
t.equals(rootMsg.metadata.who, FeedV1.stripAuthor(keys.id), 'who')
|
t.equals(rootMsg.metadata.who, FeedV1.stripAuthor(keys.id), 'who')
|
||||||
t.deepEquals(rootMsg.metadata.tangles, {}, 'tangles')
|
t.deepEquals(rootMsg.metadata.tangles, {}, 'tangles')
|
||||||
|
|
||||||
rootHash = FeedV1.getMsgHash(rootMsg)
|
rootHash = FeedV1.getMsgHash(rootMsg)
|
||||||
t.equals(rootHash, 'PGwQiuwFnB7EySQHBit2mA', 'root hash')
|
t.equals(rootHash, 'Nf2kuXAYsLBHEgU9eonYdn', 'root hash')
|
||||||
t.end()
|
t.end()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ tape('FeedV1.create()', (t) => {
|
||||||
})
|
})
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
Object.keys(msg1.metadata),
|
Object.keys(msg1.metadata),
|
||||||
['proof', 'size', 'tangles', 'type', 'who'],
|
['hash', 'size', 'tangles', 'type', 'v', 'who'],
|
||||||
'metadata fields'
|
'metadata fields'
|
||||||
)
|
)
|
||||||
t.equals(
|
t.equals(
|
||||||
|
@ -45,7 +45,7 @@ tape('FeedV1.create()', (t) => {
|
||||||
'metadata.who'
|
'metadata.who'
|
||||||
)
|
)
|
||||||
t.equals(msg1.metadata.type, 'post', 'metadata.type')
|
t.equals(msg1.metadata.type, 'post', 'metadata.type')
|
||||||
t.deepEquals(msg1.metadata.proof, '9R7XmBhHF5ooPg34j9TQcz', 'metadata.proof')
|
t.deepEquals(msg1.metadata.hash, '9R7XmBhHF5ooPg34j9TQcz', 'metadata.hash')
|
||||||
t.deepEquals(Object.keys(msg1.metadata.tangles), [rootHash], 'tangles')
|
t.deepEquals(Object.keys(msg1.metadata.tangles), [rootHash], 'tangles')
|
||||||
t.equals(msg1.metadata.tangles[rootHash].depth, 1, 'tangle depth')
|
t.equals(msg1.metadata.tangles[rootHash].depth, 1, 'tangle depth')
|
||||||
t.deepEquals(msg1.metadata.tangles[rootHash].prev, [rootHash], 'tangle prev')
|
t.deepEquals(msg1.metadata.tangles[rootHash].prev, [rootHash], 'tangle prev')
|
||||||
|
@ -54,7 +54,7 @@ tape('FeedV1.create()', (t) => {
|
||||||
|
|
||||||
console.log(msg1)
|
console.log(msg1)
|
||||||
|
|
||||||
const msgHash1 = 'M31mLeV2wNDwp9ZRkkF8pL'
|
const msgHash1 = 'SktCiaHrUxz2mXS1SRSDmj'
|
||||||
|
|
||||||
t.equals(
|
t.equals(
|
||||||
FeedV1.getMsgId(msg1),
|
FeedV1.getMsgId(msg1),
|
||||||
|
@ -79,7 +79,7 @@ tape('FeedV1.create()', (t) => {
|
||||||
})
|
})
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
Object.keys(msg2.metadata),
|
Object.keys(msg2.metadata),
|
||||||
['proof', 'size', 'tangles', 'type', 'who'],
|
['hash', 'size', 'tangles', 'type', 'v', 'who'],
|
||||||
'metadata keys'
|
'metadata keys'
|
||||||
)
|
)
|
||||||
t.equals(
|
t.equals(
|
||||||
|
@ -91,7 +91,7 @@ tape('FeedV1.create()', (t) => {
|
||||||
t.deepEquals(Object.keys(msg1.metadata.tangles), [rootHash], 'tangles')
|
t.deepEquals(Object.keys(msg1.metadata.tangles), [rootHash], 'tangles')
|
||||||
t.equals(msg2.metadata.tangles[rootHash].depth, 2, 'tangle depth')
|
t.equals(msg2.metadata.tangles[rootHash].depth, 2, 'tangle depth')
|
||||||
t.deepEquals(msg2.metadata.tangles[rootHash].prev, [msgHash1], 'tangle prev')
|
t.deepEquals(msg2.metadata.tangles[rootHash].prev, [msgHash1], 'tangle prev')
|
||||||
t.deepEquals(msg2.metadata.proof, 'XuZEzH1Dhy1yuRMcviBBcN', 'metadata.proof')
|
t.deepEquals(msg2.metadata.hash, 'XuZEzH1Dhy1yuRMcviBBcN', 'metadata.hash')
|
||||||
t.deepEquals(msg2.metadata.size, 21, 'metadata.size')
|
t.deepEquals(msg2.metadata.size, 21, 'metadata.size')
|
||||||
t.deepEqual(msg2.content, content2, 'content is correct')
|
t.deepEqual(msg2.content, content2, 'content is correct')
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ tape('FeedV1.create()', (t) => {
|
||||||
|
|
||||||
t.deepEqual(
|
t.deepEqual(
|
||||||
FeedV1.getMsgId(msg2),
|
FeedV1.getMsgId(msg2),
|
||||||
'ppppp:message/v1/4mjQ5aJu378cEu6TksRG3uXAiKFiwGjYQtWAjfVjDAJW/post/MHLPVrHFzCLXVeXUkY1W4a',
|
'ppppp:message/v1/4mjQ5aJu378cEu6TksRG3uXAiKFiwGjYQtWAjfVjDAJW/post/Nej4ibHrxryTduWqDeCJE4',
|
||||||
'getMsgId'
|
'getMsgId'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ tape('create() handles DAG tips correctly', (t) => {
|
||||||
const msgHash1 = FeedV1.getMsgHash(msg1)
|
const msgHash1 = FeedV1.getMsgHash(msg1)
|
||||||
t.deepEquals(
|
t.deepEquals(
|
||||||
msg1.metadata.tangles[rootHash].prev,
|
msg1.metadata.tangles[rootHash].prev,
|
||||||
['PGwQiuwFnB7EySQHBit2mA'],
|
['Nf2kuXAYsLBHEgU9eonYdn'],
|
||||||
'msg1.prev is root'
|
'msg1.prev is root'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue