mirror of https://codeberg.org/pzp/pzp-db.git
identity tangle always has metadata.identity=self
This commit is contained in:
parent
674e2ba66c
commit
df98d499f1
128
lib/index.js
128
lib/index.js
|
@ -8,7 +8,7 @@ const b4a = require('b4a')
|
||||||
const base58 = require('bs58')
|
const base58 = require('bs58')
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const Obz = require('obz')
|
const Obz = require('obz')
|
||||||
const MsgV2 = require('./msg-v3')
|
const MsgV3 = require('./msg-v3')
|
||||||
const { ReadyGate } = require('./utils')
|
const { ReadyGate } = require('./utils')
|
||||||
const { decrypt } = require('./encryption')
|
const { decrypt } = require('./encryption')
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ const { decrypt } = require('./encryption')
|
||||||
* @typedef {(...args: [Error] | []) => void} CBVoid
|
* @typedef {(...args: [Error] | []) => void} CBVoid
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class DBTangle extends MsgV2.Tangle {
|
class DBTangle extends MsgV3.Tangle {
|
||||||
/**
|
/**
|
||||||
* @param {string} rootHash
|
* @param {string} rootHash
|
||||||
* @param {Iterable<Rec>} recordsIter
|
* @param {Iterable<Rec>} recordsIter
|
||||||
|
@ -260,7 +260,7 @@ function initDB(peer, config) {
|
||||||
* @param {CB<Rec>} cb
|
* @param {CB<Rec>} cb
|
||||||
*/
|
*/
|
||||||
function add(msg, tangleRootHash, cb) {
|
function add(msg, tangleRootHash, cb) {
|
||||||
const msgHash = MsgV2.getMsgHash(msg)
|
const msgHash = MsgV3.getMsgHash(msg)
|
||||||
|
|
||||||
// TODO: optimize this. Perhaps have a Map() of msgHash -> record
|
// TODO: optimize this. Perhaps have a Map() of msgHash -> record
|
||||||
// Or even better, a bloom filter. If you just want to answer no/perhaps.
|
// Or even better, a bloom filter. If you just want to answer no/perhaps.
|
||||||
|
@ -272,7 +272,7 @@ function initDB(peer, config) {
|
||||||
const tangle = new DBTangle(tangleRootHash, records())
|
const tangle = new DBTangle(tangleRootHash, records())
|
||||||
|
|
||||||
const pubkeys = new Set()
|
const pubkeys = new Set()
|
||||||
if (msg.metadata.identity) {
|
if (msg.metadata.identity && msg.metadata.identity !== 'self') {
|
||||||
const identityTangle = new DBTangle(msg.metadata.identity, records())
|
const identityTangle = new DBTangle(msg.metadata.identity, records())
|
||||||
if (!identityTangle.has(msg.metadata.identity)) {
|
if (!identityTangle.has(msg.metadata.identity)) {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
|
@ -286,7 +286,7 @@ function initDB(peer, config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
let err
|
let err
|
||||||
if ((err = MsgV2.validate(msg, tangle, pubkeys, msgHash, tangleRootHash))) {
|
if ((err = MsgV3.validate(msg, tangle, pubkeys, msgHash, tangleRootHash))) {
|
||||||
return cb(new Error('add() failed msg validation', { cause: err }))
|
return cb(new Error('add() failed msg validation', { cause: err }))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,8 +308,8 @@ function initDB(peer, config) {
|
||||||
const feedRootHash = getFeedId(identity, domain)
|
const feedRootHash = getFeedId(identity, domain)
|
||||||
if (feedRootHash) return cb(null, feedRootHash)
|
if (feedRootHash) return cb(null, feedRootHash)
|
||||||
|
|
||||||
const feedRoot = MsgV2.createRoot(identity, domain, keypair)
|
const feedRoot = MsgV3.createRoot(identity, domain, keypair)
|
||||||
add(feedRoot, MsgV2.getMsgHash(feedRoot), (err, rec) => {
|
add(feedRoot, MsgV3.getMsgHash(feedRoot), (err, rec) => {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
if (err) return cb(new Error('initializeFeed() failed to add root', { cause: err }));
|
if (err) return cb(new Error('initializeFeed() failed to add root', { cause: err }));
|
||||||
const recHash = /** @type {string} */ (rec.hash)
|
const recHash = /** @type {string} */ (rec.hash)
|
||||||
|
@ -318,25 +318,109 @@ function initDB(peer, config) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {{keypair?: Keypair, _nonce?: string} | null} opts
|
* @param {Rec} rec
|
||||||
* @param {CB<Rec>} cb
|
* @returns {string | null}
|
||||||
|
*/
|
||||||
|
function getIdentityId(rec) {
|
||||||
|
if (!rec.msg) return null
|
||||||
|
if (rec.msg.metadata.identity === 'self') {
|
||||||
|
for (const tangleId in rec.msg.metadata.tangles) {
|
||||||
|
return tangleId
|
||||||
|
}
|
||||||
|
return rec.hash
|
||||||
|
} else if (rec.msg.metadata.identity) {
|
||||||
|
return rec.msg.metadata.identity
|
||||||
|
} else {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{
|
||||||
|
* keypair?: Keypair;
|
||||||
|
* domain: string;
|
||||||
|
* }} opts
|
||||||
|
* @param {CB<string>} cb
|
||||||
|
*/
|
||||||
|
function findIdentity(opts, cb) {
|
||||||
|
if (!opts.domain)
|
||||||
|
return cb(new Error('identity.find() requires a `domain`'))
|
||||||
|
const keypair = opts?.keypair ?? config.keypair
|
||||||
|
const domain = opts.domain
|
||||||
|
|
||||||
|
for (let i = 0; i < recs.length; i++) {
|
||||||
|
const rec = recs[i]
|
||||||
|
if (!rec) continue
|
||||||
|
if (!rec.msg) continue
|
||||||
|
if (!rec.msg.data) continue
|
||||||
|
if (
|
||||||
|
rec.msg.metadata.identity === 'self' &&
|
||||||
|
rec.msg.data.add === keypair.public &&
|
||||||
|
rec.msg.metadata.domain === domain
|
||||||
|
) {
|
||||||
|
const identityId = getIdentityId(rec)
|
||||||
|
if (identityId) {
|
||||||
|
cb(null, identityId)
|
||||||
|
} else {
|
||||||
|
// prettier-ignore
|
||||||
|
cb(new Error(`identity.find() failed to find ID in ${JSON.stringify(rec.msg)}`))
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// prettier-ignore
|
||||||
|
const err = new Error(`identity.find() failed for pubkey=${keypair.public} domain=${domain}`, { cause: 'ENOENT' });
|
||||||
|
cb(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{
|
||||||
|
* keypair?: Keypair,
|
||||||
|
* domain: string,
|
||||||
|
* _nonce?: string
|
||||||
|
* }} opts
|
||||||
|
* @param {CB<string>} cb
|
||||||
*/
|
*/
|
||||||
function createIdentity(opts, cb) {
|
function createIdentity(opts, cb) {
|
||||||
|
if (!opts.domain)
|
||||||
|
return cb(new Error('identity.create() requires a `domain`'))
|
||||||
const keypair = opts?.keypair ?? config.keypair
|
const keypair = opts?.keypair ?? config.keypair
|
||||||
|
const domain = opts.domain
|
||||||
|
|
||||||
let msg
|
let msg
|
||||||
try {
|
try {
|
||||||
msg = MsgV2.createIdentity(keypair, opts?._nonce)
|
msg = MsgV3.createIdentity(keypair, domain, opts?._nonce)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return cb(new Error('identity.create() failed', { cause: err }))
|
return cb(new Error('identity.create() failed', { cause: err }))
|
||||||
}
|
}
|
||||||
const msgHash = MsgV2.getMsgHash(msg)
|
const msgHash = MsgV3.getMsgHash(msg)
|
||||||
|
|
||||||
logAppend(msgHash, msg, (err, rec) => {
|
logAppend(msgHash, msg, (err, rec) => {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
if (err) return cb(new Error('identity.create() failed in the log', { cause: err }))
|
if (err) return cb(new Error('identity.create() failed in the log', { cause: err }))
|
||||||
onRecordAdded.set(rec)
|
onRecordAdded.set(rec)
|
||||||
cb(null, rec)
|
const recHash = /** @type {string} */ (rec.hash)
|
||||||
|
cb(null, recHash)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {{
|
||||||
|
* keypair?: Keypair,
|
||||||
|
* domain: string,
|
||||||
|
* _nonce?: string
|
||||||
|
* }} opts
|
||||||
|
* @param {CB<string>} cb
|
||||||
|
*/
|
||||||
|
function findOrCreateIdentity(opts, cb) {
|
||||||
|
findIdentity(opts, (err, identityId) => {
|
||||||
|
if (err?.cause === 'ENOENT') {
|
||||||
|
createIdentity(opts, cb)
|
||||||
|
} else if (err) {
|
||||||
|
cb(err)
|
||||||
|
} else {
|
||||||
|
cb(null, identityId)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,7 +439,7 @@ function initDB(peer, config) {
|
||||||
// Fill-in tangle opts:
|
// Fill-in tangle opts:
|
||||||
const tangles = populateTangles([opts.identity])
|
const tangles = populateTangles([opts.identity])
|
||||||
const fullOpts = {
|
const fullOpts = {
|
||||||
identity: null,
|
identity: 'self',
|
||||||
identityTips: null,
|
identityTips: null,
|
||||||
tangles,
|
tangles,
|
||||||
keypair: signingKeypair,
|
keypair: signingKeypair,
|
||||||
|
@ -366,11 +450,11 @@ function initDB(peer, config) {
|
||||||
// Create the actual message:
|
// Create the actual message:
|
||||||
let msg
|
let msg
|
||||||
try {
|
try {
|
||||||
msg = MsgV2.create(fullOpts)
|
msg = MsgV3.create(fullOpts)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return cb(new Error('identity.add() failed', { cause: err }))
|
return cb(new Error('identity.add() failed', { cause: err }))
|
||||||
}
|
}
|
||||||
const msgHash = MsgV2.getMsgHash(msg)
|
const msgHash = MsgV3.getMsgHash(msg)
|
||||||
|
|
||||||
logAppend(msgHash, msg, (err, rec) => {
|
logAppend(msgHash, msg, (err, rec) => {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
|
@ -421,7 +505,7 @@ function initDB(peer, config) {
|
||||||
// If opts ask for encryption, encrypt and put ciphertext in opts.data
|
// If opts ask for encryption, encrypt and put ciphertext in opts.data
|
||||||
const recps = fullOpts.data.recps
|
const recps = fullOpts.data.recps
|
||||||
if (Array.isArray(recps) && recps.length > 0) {
|
if (Array.isArray(recps) && recps.length > 0) {
|
||||||
const plaintext = MsgV2.toPlaintextBuffer(fullOpts)
|
const plaintext = MsgV3.toPlaintextBuffer(fullOpts)
|
||||||
const encryptOpts = {
|
const encryptOpts = {
|
||||||
...fullOpts,
|
...fullOpts,
|
||||||
recps: recps.map(
|
recps: recps.map(
|
||||||
|
@ -454,11 +538,11 @@ function initDB(peer, config) {
|
||||||
// Create the actual message:
|
// Create the actual message:
|
||||||
let msg
|
let msg
|
||||||
try {
|
try {
|
||||||
msg = MsgV2.create(fullOpts)
|
msg = MsgV3.create(fullOpts)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return cb(new Error('feed.publish() failed', { cause: err }))
|
return cb(new Error('feed.publish() failed', { cause: err }))
|
||||||
}
|
}
|
||||||
const msgHash = MsgV2.getMsgHash(msg)
|
const msgHash = MsgV3.getMsgHash(msg)
|
||||||
|
|
||||||
// Encode the native message and append it to the log:
|
// Encode the native message and append it to the log:
|
||||||
logAppend(msgHash, msg, (err, rec) => {
|
logAppend(msgHash, msg, (err, rec) => {
|
||||||
|
@ -475,9 +559,9 @@ function initDB(peer, config) {
|
||||||
* @param {string} findDomain
|
* @param {string} findDomain
|
||||||
*/
|
*/
|
||||||
function getFeedId(id, findDomain) {
|
function getFeedId(id, findDomain) {
|
||||||
const findIdentity = MsgV2.stripIdentity(id)
|
const findIdentity = MsgV3.stripIdentity(id)
|
||||||
for (const rec of records()) {
|
for (const rec of records()) {
|
||||||
if (rec.msg && MsgV2.isFeedRoot(rec.msg, findIdentity, findDomain)) {
|
if (rec.msg && MsgV3.isFeedRoot(rec.msg, findIdentity, findDomain)) {
|
||||||
return rec.hash
|
return rec.hash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -531,7 +615,7 @@ function initDB(peer, config) {
|
||||||
if (!rec) return cb()
|
if (!rec) return cb()
|
||||||
if (!rec.msg) return cb()
|
if (!rec.msg) return cb()
|
||||||
if (!rec.msg.data) return cb()
|
if (!rec.msg.data) return cb()
|
||||||
recs[rec.misc.seq].msg = MsgV2.erase(rec.msg)
|
recs[rec.misc.seq].msg = MsgV3.erase(rec.msg)
|
||||||
// FIXME: persist this change to disk!! Not supported by AAOL yet
|
// FIXME: persist this change to disk!! Not supported by AAOL yet
|
||||||
cb()
|
cb()
|
||||||
}
|
}
|
||||||
|
@ -564,7 +648,9 @@ function initDB(peer, config) {
|
||||||
loaded,
|
loaded,
|
||||||
add,
|
add,
|
||||||
identity: {
|
identity: {
|
||||||
|
find: findIdentity,
|
||||||
create: createIdentity,
|
create: createIdentity,
|
||||||
|
findOrCreate: findOrCreateIdentity,
|
||||||
add: addToIdentity,
|
add: addToIdentity,
|
||||||
},
|
},
|
||||||
feed: {
|
feed: {
|
||||||
|
|
|
@ -37,7 +37,7 @@ const Tangle = require('./tangle')
|
||||||
* metadata: {
|
* metadata: {
|
||||||
* dataHash: string | null;
|
* dataHash: string | null;
|
||||||
* dataSize: number;
|
* dataSize: number;
|
||||||
* identity: string | null;
|
* identity: string | (typeof IDENTITY_SELF) | null;
|
||||||
* identityTips: Array<string> | null;
|
* identityTips: Array<string> | null;
|
||||||
* tangles: Record<string, TangleMetadata>;
|
* tangles: Record<string, TangleMetadata>;
|
||||||
* domain: string;
|
* domain: string;
|
||||||
|
@ -57,6 +57,8 @@ const Tangle = require('./tangle')
|
||||||
* }} CreateOpts
|
* }} CreateOpts
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
const IDENTITY_SELF = /** @type {const} */ 'self'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} id
|
* @param {string} id
|
||||||
* @param {string} domain
|
* @param {string} domain
|
||||||
|
@ -178,21 +180,23 @@ function createRoot(id, domain, keypair) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Keypair} keypair
|
* @param {Keypair} keypair
|
||||||
|
* @param {string} domain
|
||||||
* @param {string | (() => string)} nonce
|
* @param {string | (() => string)} nonce
|
||||||
* @returns {Msg}
|
* @returns {Msg}
|
||||||
*/
|
*/
|
||||||
function createIdentity(
|
function createIdentity(
|
||||||
keypair,
|
keypair,
|
||||||
|
domain,
|
||||||
nonce = () => base58.encode(crypto.randomBytes(32))
|
nonce = () => base58.encode(crypto.randomBytes(32))
|
||||||
) {
|
) {
|
||||||
const actualNonce = typeof nonce === 'function' ? nonce() : nonce
|
const actualNonce = typeof nonce === 'function' ? nonce() : nonce
|
||||||
return create({
|
return create({
|
||||||
data: { add: keypair.public, nonce: actualNonce },
|
data: { add: keypair.public, nonce: actualNonce },
|
||||||
identity: null,
|
identity: IDENTITY_SELF,
|
||||||
identityTips: null,
|
identityTips: null,
|
||||||
keypair,
|
keypair,
|
||||||
tangles: {},
|
tangles: {},
|
||||||
domain: 'identity',
|
domain,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,8 @@ function isEmptyObject(obj) {
|
||||||
* @param {string | 0} findDomain
|
* @param {string | 0} findDomain
|
||||||
*/
|
*/
|
||||||
function isFeedRoot(msg, id = 0, findDomain = 0) {
|
function isFeedRoot(msg, id = 0, findDomain = 0) {
|
||||||
const { dataHash, dataSize, identity, identityTips, tangles, domain } = msg.metadata
|
const { dataHash, dataSize, identity, identityTips, tangles, domain } =
|
||||||
|
msg.metadata
|
||||||
if (dataHash !== null) return false
|
if (dataHash !== null) return false
|
||||||
if (dataSize !== 0) return false
|
if (dataSize !== 0) return false
|
||||||
if (id === 0 && !identity) return false
|
if (id === 0 && !identity) return false
|
||||||
|
|
|
@ -88,7 +88,11 @@ function validateIdentityPubkey(msg, pubkeys) {
|
||||||
// Unusual case: if the msg is a feed root, ignore the identity and pubkey
|
// Unusual case: if the msg is a feed root, ignore the identity and pubkey
|
||||||
if (isFeedRoot(msg)) return
|
if (isFeedRoot(msg)) return
|
||||||
|
|
||||||
if (msg.metadata.identity && !pubkeys.has(msg.pubkey)) {
|
if (
|
||||||
|
msg.metadata.identity &&
|
||||||
|
msg.metadata.identity !== 'self' &&
|
||||||
|
!pubkeys.has(msg.pubkey)
|
||||||
|
) {
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
return `invalid message: pubkey "${msg.pubkey}" should have been one of "${[...pubkeys]}" from the identity "${msg.metadata.identity}"\n` + JSON.stringify(msg)
|
return `invalid message: pubkey "${msg.pubkey}" should have been one of "${[...pubkeys]}" from the identity "${msg.metadata.identity}"\n` + JSON.stringify(msg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ interface Msg {
|
||||||
metadata: {
|
metadata: {
|
||||||
dataHash: ContentHash | null // blake3 hash of the `content` object serialized
|
dataHash: ContentHash | null // blake3 hash of the `content` object serialized
|
||||||
dataSize: number // byte size (unsigned integer) of the `content` object serialized
|
dataSize: number // byte size (unsigned integer) of the `content` object serialized
|
||||||
identity: string | null // blake3 hash ofn a identity tangle root msg, or null
|
identity: string | 'self' | null // blake3 hash of an identity tangle root msg, or the string 'self', or null
|
||||||
identityTips: Array<string> | null // list of blake3 hashes of identity tangle tips, or null
|
identityTips: Array<string> | null // list of blake3 hashes of identity tangle tips, or null
|
||||||
tangles: {
|
tangles: {
|
||||||
// for each tangle this msg belongs to, identified by the tangle's root
|
// for each tangle this msg belongs to, identified by the tangle's root
|
||||||
|
@ -54,7 +54,7 @@ interface Msg {
|
||||||
metadata: {
|
metadata: {
|
||||||
dataHash: ContentHash
|
dataHash: ContentHash
|
||||||
dataSize: number
|
dataSize: number
|
||||||
identity: null // MUST be null
|
identity: 'self' // MUST be the string 'self'
|
||||||
identityTips: null // MUST be null
|
identityTips: null // MUST be null
|
||||||
tangles: {
|
tangles: {
|
||||||
[identityTangleId: string]: {
|
[identityTangleId: string]: {
|
||||||
|
@ -62,7 +62,7 @@ interface Msg {
|
||||||
prev: Array<MsgHash> // list of msg hashes of existing msgs, unique set and ordered alphabetically
|
prev: Array<MsgHash> // list of msg hashes of existing msgs, unique set and ordered alphabetically
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
domain: 'identity' // MUST be 'identity'
|
domain: string // alphanumeric string, at least 3 chars, max 100 chars
|
||||||
v: 2
|
v: 2
|
||||||
}
|
}
|
||||||
pubkey: Pubkey
|
pubkey: Pubkey
|
||||||
|
|
|
@ -21,7 +21,7 @@ test('add()', async (t) => {
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
const identityMsg0 = MsgV3.createIdentity(keypair)
|
const identityMsg0 = MsgV3.createIdentity(keypair, 'person')
|
||||||
const id = MsgV3.getMsgHash(identityMsg0)
|
const id = MsgV3.getMsgHash(identityMsg0)
|
||||||
|
|
||||||
await p(peer.db.add)(identityMsg0, id)
|
await p(peer.db.add)(identityMsg0, id)
|
||||||
|
|
|
@ -21,7 +21,7 @@ test('del', async (t) => {
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
const id = (await p(peer.db.identity.create)(null)).hash
|
const id = await p(peer.db.identity.create)({ domain: 'person' })
|
||||||
|
|
||||||
const msgHashes = []
|
const msgHashes = []
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
|
@ -35,16 +35,24 @@ test('del', async (t) => {
|
||||||
|
|
||||||
const before = []
|
const before = []
|
||||||
for (const msg of peer.db.msgs()) {
|
for (const msg of peer.db.msgs()) {
|
||||||
if (msg.data && msg.metadata.identity) before.push(msg.data.text)
|
if (msg.data && msg.metadata.identity?.length > 4) {
|
||||||
|
before.push(msg.data.text)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.deepEqual(before, ['m0', 'm1', 'm2', 'm3', 'm4'], 'msgs before the delete')
|
assert.deepEqual(
|
||||||
|
before,
|
||||||
|
['m0', 'm1', 'm2', 'm3', 'm4'],
|
||||||
|
'msgs before the delete'
|
||||||
|
)
|
||||||
|
|
||||||
await p(peer.db.del)(msgHashes[2])
|
await p(peer.db.del)(msgHashes[2])
|
||||||
|
|
||||||
const after = []
|
const after = []
|
||||||
for (const msg of peer.db.msgs()) {
|
for (const msg of peer.db.msgs()) {
|
||||||
if (msg.data && msg.metadata.identity) after.push(msg.data.text)
|
if (msg.data && msg.metadata.identity?.length > 4) {
|
||||||
|
after.push(msg.data.text)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.deepEqual(after, ['m0', 'm1', 'm3', 'm4'], 'msgs after the delete')
|
assert.deepEqual(after, ['m0', 'm1', 'm3', 'm4'], 'msgs after the delete')
|
||||||
|
@ -83,7 +91,7 @@ test('del', async (t) => {
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
persistedMsgs
|
persistedMsgs
|
||||||
.filter((msg) => msg.data && msg.metadata.identity)
|
.filter((msg) => msg.data && msg.metadata.identity?.length > 4)
|
||||||
.map((msg) => msg.data.text),
|
.map((msg) => msg.data.text),
|
||||||
['m0', 'm1', 'm3', 'm4'],
|
['m0', 'm1', 'm3', 'm4'],
|
||||||
'msgs in disk after the delete'
|
'msgs in disk after the delete'
|
||||||
|
|
|
@ -21,7 +21,7 @@ test('erase', async (t) => {
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
const id = (await p(peer.db.identity.create)(null)).hash
|
const id = await p(peer.db.identity.create)({ domain: 'person' })
|
||||||
|
|
||||||
const msgHashes = []
|
const msgHashes = []
|
||||||
for (let i = 0; i < 5; i++) {
|
for (let i = 0; i < 5; i++) {
|
||||||
|
@ -35,7 +35,9 @@ test('erase', async (t) => {
|
||||||
|
|
||||||
const before = []
|
const before = []
|
||||||
for (const msg of peer.db.msgs()) {
|
for (const msg of peer.db.msgs()) {
|
||||||
if (msg.data && msg.metadata.identity) before.push(msg.data.text)
|
if (msg.data && msg.metadata.identity?.length > 4) {
|
||||||
|
before.push(msg.data.text)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
|
@ -48,7 +50,9 @@ test('erase', async (t) => {
|
||||||
|
|
||||||
const after = []
|
const after = []
|
||||||
for (const msg of peer.db.msgs()) {
|
for (const msg of peer.db.msgs()) {
|
||||||
if (msg.data && msg.metadata.identity) after.push(msg.data.text)
|
if (msg.data && msg.metadata.identity?.length > 4) {
|
||||||
|
after.push(msg.data.text)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.deepEqual(after, ['m0', 'm1', 'm3', 'm4'], '4 msgs after the erase')
|
assert.deepEqual(after, ['m0', 'm1', 'm3', 'm4'], '4 msgs after the erase')
|
||||||
|
|
|
@ -25,7 +25,7 @@ test('setup', async (t) => {
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
id = (await p(peer.db.identity.create)(null)).hash
|
id = (await p(peer.db.identity.create)({domain: 'person'}))
|
||||||
rootMsg = MsgV3.createRoot(id, 'post', keypair)
|
rootMsg = MsgV3.createRoot(id, 'post', keypair)
|
||||||
rootHash = MsgV3.getMsgHash(rootMsg)
|
rootHash = MsgV3.getMsgHash(rootMsg)
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ test('setup', async (t) => {
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
id = (await p(peer.db.identity.create)(null)).hash
|
id = (await p(peer.db.identity.create)({domain: 'person'}))
|
||||||
rootMsg = MsgV3.createRoot(id, 'post', keypair)
|
rootMsg = MsgV3.createRoot(id, 'post', keypair)
|
||||||
rootHash = MsgV3.getMsgHash(rootMsg)
|
rootHash = MsgV3.getMsgHash(rootMsg)
|
||||||
})
|
})
|
||||||
|
|
|
@ -25,7 +25,7 @@ test('setup', async (t) => {
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
id = (await p(peer.db.identity.create)(null)).hash
|
id = (await p(peer.db.identity.create)({domain: 'person'}))
|
||||||
|
|
||||||
const rec1 = await p(peer.db.feed.publish)({
|
const rec1 = await p(peer.db.feed.publish)({
|
||||||
identity: id,
|
identity: id,
|
||||||
|
|
|
@ -26,7 +26,7 @@ test('setup', async (t) => {
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
const id = (await p(peer.db.identity.create)(null)).hash
|
const id = (await p(peer.db.identity.create)({domain: 'person'}))
|
||||||
|
|
||||||
// Slow down append so that we can trigger msg creation in parallel
|
// Slow down append so that we can trigger msg creation in parallel
|
||||||
const originalAppend = peer.db._getLog().append
|
const originalAppend = peer.db._getLog().append
|
||||||
|
|
|
@ -21,15 +21,20 @@ test('identity.add()', async (t) => {
|
||||||
.call(null, { keypair: keypair1, path: DIR })
|
.call(null, { keypair: keypair1, path: DIR })
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
const identityRec0 = await p(peer.db.identity.create)({ keypair: keypair1 })
|
const id = await p(peer.db.identity.create)({
|
||||||
const id = identityRec0.hash
|
keypair: keypair1,
|
||||||
|
domain: 'person',
|
||||||
|
})
|
||||||
|
|
||||||
const identityRec1 = await p(peer.db.identity.add)({ identity: id, keypair: keypair2 })
|
const identityRec1 = await p(peer.db.identity.add)({
|
||||||
|
identity: id,
|
||||||
|
keypair: keypair2,
|
||||||
|
})
|
||||||
assert.ok(identityRec1, 'identityRec1 exists')
|
assert.ok(identityRec1, 'identityRec1 exists')
|
||||||
const { hash, msg } = identityRec1
|
const { hash, msg } = identityRec1
|
||||||
assert.ok(hash, 'hash exists')
|
assert.ok(hash, 'hash exists')
|
||||||
assert.equal(msg.data.add, keypair2.public, 'msg.data.add NEW KEY')
|
assert.equal(msg.data.add, keypair2.public, 'msg.data.add NEW KEY')
|
||||||
assert.equal(msg.metadata.identity, null, 'msg.metadata.identity')
|
assert.equal(msg.metadata.identity, 'self', 'msg.metadata.identity')
|
||||||
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
msg.metadata.tangles,
|
msg.metadata.tangles,
|
||||||
|
@ -54,9 +59,15 @@ test('publish with a key in the identity', async (t) => {
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
const identityRec0 = await p(peer.db.identity.create)({ keypair: keypair1 })
|
const identity = await p(peer.db.identity.create)({
|
||||||
const identity = identityRec0.hash
|
keypair: keypair1,
|
||||||
const identityRec1 = await p(peer.db.identity.add)({ identity, keypair: keypair2 })
|
domain: 'person',
|
||||||
|
})
|
||||||
|
const identityMsg0 = peer.db.get(identity)
|
||||||
|
const identityRec1 = await p(peer.db.identity.add)({
|
||||||
|
identity,
|
||||||
|
keypair: keypair2,
|
||||||
|
})
|
||||||
|
|
||||||
const postRec = await p(peer.db.feed.publish)({
|
const postRec = await p(peer.db.feed.publish)({
|
||||||
identity,
|
identity,
|
||||||
|
@ -71,17 +82,21 @@ test('publish with a key in the identity', async (t) => {
|
||||||
const recs = [...peer.db.records()]
|
const recs = [...peer.db.records()]
|
||||||
assert.equal(recs.length, 4, '4 records')
|
assert.equal(recs.length, 4, '4 records')
|
||||||
const [_identityRec0, _identityRec1, postsRoot, _post] = recs
|
const [_identityRec0, _identityRec1, postsRoot, _post] = recs
|
||||||
assert.deepEqual(_identityRec0.msg, identityRec0.msg, 'identityMsg0')
|
assert.deepEqual(_identityRec0.msg, identityMsg0, 'identityMsg0')
|
||||||
assert.deepEqual(_identityRec1.msg, identityRec1.msg, 'identityMsg1')
|
assert.deepEqual(_identityRec1.msg, identityRec1.msg, 'identityMsg1')
|
||||||
assert.deepEqual(postsRoot.msg.metadata, {
|
assert.deepEqual(
|
||||||
dataHash: null,
|
postsRoot.msg.metadata,
|
||||||
dataSize: 0,
|
{
|
||||||
identity,
|
dataHash: null,
|
||||||
identityTips: null,
|
dataSize: 0,
|
||||||
tangles: {},
|
identity,
|
||||||
domain: 'post',
|
identityTips: null,
|
||||||
v: 3,
|
tangles: {},
|
||||||
}, 'postsRoot')
|
domain: 'post',
|
||||||
|
v: 3,
|
||||||
|
},
|
||||||
|
'postsRoot'
|
||||||
|
)
|
||||||
assert.deepEqual(_post.msg, postRec.msg, 'postMsg')
|
assert.deepEqual(_post.msg, postRec.msg, 'postMsg')
|
||||||
|
|
||||||
await p(peer.close)()
|
await p(peer.close)()
|
||||||
|
@ -97,7 +112,7 @@ test('publish with a key in the identity', async (t) => {
|
||||||
|
|
||||||
await carol.db.loaded()
|
await carol.db.loaded()
|
||||||
|
|
||||||
await p(carol.db.add)(identityRec0.msg, identity)
|
await p(carol.db.add)(identityMsg0, identity)
|
||||||
await p(carol.db.add)(identityRec1.msg, identity)
|
await p(carol.db.add)(identityRec1.msg, identity)
|
||||||
await p(carol.db.add)(postsRoot.msg, postsId)
|
await p(carol.db.add)(postsRoot.msg, postsId)
|
||||||
await p(carol.db.add)(postRec.msg, postsId)
|
await p(carol.db.add)(postRec.msg, postsId)
|
||||||
|
|
|
@ -11,7 +11,7 @@ const Keypair = require('ppppp-keypair')
|
||||||
const DIR = path.join(os.tmpdir(), 'ppppp-db-identity-create')
|
const DIR = path.join(os.tmpdir(), 'ppppp-db-identity-create')
|
||||||
rimraf.sync(DIR)
|
rimraf.sync(DIR)
|
||||||
|
|
||||||
test('identity.create() without args', async (t) => {
|
test('identity.create() with just "domain"', async (t) => {
|
||||||
const keypair = Keypair.generate('ed25519', 'alice')
|
const keypair = Keypair.generate('ed25519', 'alice')
|
||||||
const peer = SecretStack({ appKey: caps.shse })
|
const peer = SecretStack({ appKey: caps.shse })
|
||||||
.use(require('../lib'))
|
.use(require('../lib'))
|
||||||
|
@ -19,20 +19,23 @@ test('identity.create() without args', async (t) => {
|
||||||
.call(null, { keypair, path: DIR })
|
.call(null, { keypair, path: DIR })
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
const identityRec0 = await p(peer.db.identity.create)({})
|
const identity = await p(peer.db.identity.create)({ domain: 'person' })
|
||||||
assert.ok(identityRec0, 'identityRec0 exists')
|
assert.ok(identity, 'identityRec0 exists')
|
||||||
const { hash, msg } = identityRec0
|
const msg = peer.db.get(identity)
|
||||||
assert.ok(hash, 'hash exists')
|
|
||||||
assert.equal(msg.data.add, keypair.public, 'msg.data.add')
|
assert.equal(msg.data.add, keypair.public, 'msg.data.add')
|
||||||
assert.equal(msg.metadata.identity, null, 'msg.metadata.identity')
|
assert.equal(msg.metadata.identity, 'self', 'msg.metadata.identity')
|
||||||
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
||||||
assert.deepEqual(Object.keys(msg.metadata.tangles), [], 'msg.metadata.tangles')
|
assert.deepEqual(
|
||||||
|
Object.keys(msg.metadata.tangles),
|
||||||
|
[],
|
||||||
|
'msg.metadata.tangles'
|
||||||
|
)
|
||||||
assert.equal(msg.pubkey, keypair.public, 'msg.pubkey')
|
assert.equal(msg.pubkey, keypair.public, 'msg.pubkey')
|
||||||
|
|
||||||
await p(peer.close)()
|
await p(peer.close)()
|
||||||
})
|
})
|
||||||
|
|
||||||
test('identity.create() with "keypair" arg', async (t) => {
|
test('identity.create() with "keypair" and "domain"', async (t) => {
|
||||||
const keypair = Keypair.generate('ed25519', 'alice')
|
const keypair = Keypair.generate('ed25519', 'alice')
|
||||||
|
|
||||||
const peer = SecretStack({ appKey: caps.shse })
|
const peer = SecretStack({ appKey: caps.shse })
|
||||||
|
@ -41,14 +44,20 @@ test('identity.create() with "keypair" arg', async (t) => {
|
||||||
.call(null, { keypair, path: DIR })
|
.call(null, { keypair, path: DIR })
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
const identityRec0 = await p(peer.db.identity.create)({ keypair })
|
const identity = await p(peer.db.identity.create)({
|
||||||
assert.ok(identityRec0, 'identityRec0 exists')
|
keypair,
|
||||||
const { hash, msg } = identityRec0
|
domain: 'person',
|
||||||
assert.ok(hash, 'hash exists')
|
})
|
||||||
|
assert.ok(identity, 'identity created')
|
||||||
|
const msg = peer.db.get(identity)
|
||||||
assert.equal(msg.data.add, keypair.public, 'msg.data.add')
|
assert.equal(msg.data.add, keypair.public, 'msg.data.add')
|
||||||
assert.equal(msg.metadata.identity, null, 'msg.metadata.identity')
|
assert.equal(msg.metadata.identity, 'self', 'msg.metadata.identity')
|
||||||
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
assert.equal(msg.metadata.identityTips, null, 'msg.metadata.identityTips')
|
||||||
assert.deepEqual(Object.keys(msg.metadata.tangles), [], 'msg.metadata.tangles')
|
assert.deepEqual(
|
||||||
|
Object.keys(msg.metadata.tangles),
|
||||||
|
[],
|
||||||
|
'msg.metadata.tangles'
|
||||||
|
)
|
||||||
assert.equal(msg.pubkey, keypair.public, 'msg.pubkey')
|
assert.equal(msg.pubkey, keypair.public, 'msg.pubkey')
|
||||||
|
|
||||||
await p(peer.close)()
|
await p(peer.close)()
|
||||||
|
|
|
@ -7,21 +7,21 @@ let identity
|
||||||
test('MsgV3.createIdentity()', (t) => {
|
test('MsgV3.createIdentity()', (t) => {
|
||||||
const keypair = Keypair.generate('ed25519', 'alice')
|
const keypair = Keypair.generate('ed25519', 'alice')
|
||||||
|
|
||||||
const identityMsg0 = MsgV3.createIdentity(keypair, 'MYNONCE')
|
const identityMsg0 = MsgV3.createIdentity(keypair, 'person', 'MYNONCE')
|
||||||
console.log(JSON.stringify(identityMsg0, null, 2))
|
console.log(JSON.stringify(identityMsg0, null, 2))
|
||||||
|
|
||||||
assert.equal(identityMsg0.data.add, keypair.public, 'data.add')
|
assert.equal(identityMsg0.data.add, keypair.public, 'data.add')
|
||||||
assert.equal(identityMsg0.metadata.dataHash, 'THi3VkJeaf8aTkLSNJUdFD', 'hash')
|
assert.equal(identityMsg0.metadata.dataHash, 'THi3VkJeaf8aTkLSNJUdFD', 'hash')
|
||||||
assert.equal(identityMsg0.metadata.dataSize, 72, 'size')
|
assert.equal(identityMsg0.metadata.dataSize, 72, 'size')
|
||||||
assert.equal(identityMsg0.metadata.identity, null, 'identity')
|
assert.equal(identityMsg0.metadata.identity, 'self', 'identity')
|
||||||
assert.equal(identityMsg0.metadata.identityTips, null, 'identityTips')
|
assert.equal(identityMsg0.metadata.identityTips, null, 'identityTips')
|
||||||
assert.deepEqual(identityMsg0.metadata.tangles, {}, 'tangles')
|
assert.deepEqual(identityMsg0.metadata.tangles, {}, 'tangles')
|
||||||
assert.equal(identityMsg0.metadata.domain, 'identity', 'domain')
|
assert.equal(identityMsg0.metadata.domain, 'person', 'domain')
|
||||||
assert.equal(identityMsg0.metadata.v, 3, 'v')
|
assert.equal(identityMsg0.metadata.v, 3, 'v')
|
||||||
assert.equal(identityMsg0.pubkey, keypair.public, 'pubkey')
|
assert.equal(identityMsg0.pubkey, keypair.public, 'pubkey')
|
||||||
|
|
||||||
identity = MsgV3.getMsgHash(identityMsg0)
|
identity = MsgV3.getMsgHash(identityMsg0)
|
||||||
assert.equal(identity, 'WnAX17Lm2ktfPUJ5ARXq73', 'identity ID')
|
assert.equal(identity, 'v7vBrnrCTahjgkpoaZrWm', 'identity ID')
|
||||||
})
|
})
|
||||||
|
|
||||||
let rootMsg = null
|
let rootMsg = null
|
||||||
|
@ -43,7 +43,7 @@ test('MsgV3.createRoot()', (t) => {
|
||||||
assert.equal(rootMsg.pubkey, keypair.public, 'pubkey')
|
assert.equal(rootMsg.pubkey, keypair.public, 'pubkey')
|
||||||
|
|
||||||
rootHash = MsgV3.getMsgHash(rootMsg)
|
rootHash = MsgV3.getMsgHash(rootMsg)
|
||||||
assert.equal(rootHash, '5G4FJTWaGr7ZBUJGge6Qeg', 'root hash')
|
assert.equal(rootHash, 'HPtwPD552ajEurwpgQRfTX', 'root hash')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('MsgV3.create()', (t) => {
|
test('MsgV3.create()', (t) => {
|
||||||
|
@ -95,11 +95,11 @@ test('MsgV3.create()', (t) => {
|
||||||
)
|
)
|
||||||
assert.equal(
|
assert.equal(
|
||||||
msg1.sig,
|
msg1.sig,
|
||||||
'xZGu2Kb19XicfoihgBZ84jRs4XuNgVBd2bK45Cum2fdVDNJUE3f8Ejf6apfZFyE8iAfPDEVWFNAJB6E52EaWEAm',
|
'2FhnKsDKCxEV4JUM1nmPp3oSFJ8zL7r4SjMNogDHeAzCWQLgVmKiexgUDSE4k9C3eT4Uy3SZbBhRY75WJAqvtHHf',
|
||||||
'sig'
|
'sig'
|
||||||
)
|
)
|
||||||
|
|
||||||
const msgHash1 = 'NF389yT2td9gz5TvRuZMB6'
|
const msgHash1 = 'FK4jCKFZDGwecydC8bitgR'
|
||||||
|
|
||||||
assert.equal(
|
assert.equal(
|
||||||
MsgV3.getMsgId(msg1),
|
MsgV3.getMsgId(msg1),
|
||||||
|
@ -155,13 +155,13 @@ test('MsgV3.create()', (t) => {
|
||||||
)
|
)
|
||||||
assert.equal(
|
assert.equal(
|
||||||
msg2.sig,
|
msg2.sig,
|
||||||
'2XHQcG8KeNbdz8m5fDs2QtT7jcxgEqHxv7SkSYVpKQAJ1S8HGn3dmLxw3J5vWmu1vhYhWS6GDE1hfMtvmfiCAy54',
|
'3B6WQvDdKvRhZeZDfE9LY4HrnhZTJHRJ86FazBg1xxco2S1eHG44UwR9TSpthiXQ1X51h2VeDeGPV6Fdma69BMN9',
|
||||||
'sig'
|
'sig'
|
||||||
)
|
)
|
||||||
|
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
MsgV3.getMsgId(msg2),
|
MsgV3.getMsgId(msg2),
|
||||||
`ppppp:message/v3/${identity}/post/HNQp1oUu3zmgD1s11xiR7y`,
|
`ppppp:message/v3/${identity}/post/AYXun8rEc3SNGZYM252TAS`,
|
||||||
'getMsgId'
|
'getMsgId'
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
|
@ -5,7 +5,9 @@ const Keypair = require('ppppp-keypair')
|
||||||
const MsgV3 = require('../../lib/msg-v3')
|
const MsgV3 = require('../../lib/msg-v3')
|
||||||
|
|
||||||
const keypair = Keypair.generate('ed25519', 'alice')
|
const keypair = Keypair.generate('ed25519', 'alice')
|
||||||
const identity = MsgV3.getMsgHash(MsgV3.createIdentity(keypair, 'MYNONCE'))
|
const identity = MsgV3.getMsgHash(
|
||||||
|
MsgV3.createIdentity(keypair, 'person', 'MYNONCE')
|
||||||
|
)
|
||||||
const pubkeys = new Set([keypair.public])
|
const pubkeys = new Set([keypair.public])
|
||||||
|
|
||||||
test('invalid msg with non-array prev', (t) => {
|
test('invalid msg with non-array prev', (t) => {
|
||||||
|
@ -180,14 +182,20 @@ test('invalid msg with unknown prev', (t) => {
|
||||||
|
|
||||||
const err = MsgV3.validate(msg2, tangle, pubkeys, msgHash2, rootHash)
|
const err = MsgV3.validate(msg2, tangle, pubkeys, msgHash2, rootHash)
|
||||||
assert.ok(err, 'invalid 2nd msg throws')
|
assert.ok(err, 'invalid 2nd msg throws')
|
||||||
assert.match(err, /all prev are locally unknown/, 'invalid 2nd msg description')
|
assert.match(
|
||||||
|
err,
|
||||||
|
/all prev are locally unknown/,
|
||||||
|
'invalid 2nd msg description'
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('invalid feed msg with a different pubkey', (t) => {
|
test('invalid feed msg with a different pubkey', (t) => {
|
||||||
const keypairA = Keypair.generate('ed25519', 'alice')
|
const keypairA = Keypair.generate('ed25519', 'alice')
|
||||||
const keypairB = Keypair.generate('ed25519', 'bob')
|
const keypairB = Keypair.generate('ed25519', 'bob')
|
||||||
|
|
||||||
const identityB = MsgV3.getMsgHash(MsgV3.createIdentity(keypairB, 'MYNONCE'))
|
const identityB = MsgV3.getMsgHash(
|
||||||
|
MsgV3.createIdentity(keypairB, 'person', 'MYNONCE')
|
||||||
|
)
|
||||||
|
|
||||||
const rootMsg = MsgV3.createRoot(identity, 'post', keypair)
|
const rootMsg = MsgV3.createRoot(identity, 'post', keypair)
|
||||||
const rootHash = MsgV3.getMsgHash(rootMsg)
|
const rootHash = MsgV3.getMsgHash(rootMsg)
|
||||||
|
|
|
@ -5,7 +5,9 @@ const MsgV3 = require('../../lib/msg-v3')
|
||||||
|
|
||||||
test('lipmaa prevs', (t) => {
|
test('lipmaa prevs', (t) => {
|
||||||
const keypair = Keypair.generate('ed25519', 'alice')
|
const keypair = Keypair.generate('ed25519', 'alice')
|
||||||
const identity = MsgV3.getMsgHash(MsgV3.createIdentity(keypair, 'MYNONCE'))
|
const identity = MsgV3.getMsgHash(
|
||||||
|
MsgV3.createIdentity(keypair, 'person', 'MYNONCE')
|
||||||
|
)
|
||||||
const data = { text: 'Hello world!' }
|
const data = { text: 'Hello world!' }
|
||||||
|
|
||||||
const rootMsg = MsgV3.createRoot(identity, 'post', keypair)
|
const rootMsg = MsgV3.createRoot(identity, 'post', keypair)
|
||||||
|
|
|
@ -6,8 +6,12 @@ const MsgV3 = require('../../lib/msg-v3')
|
||||||
test('simple multi-author tangle', (t) => {
|
test('simple multi-author tangle', (t) => {
|
||||||
const keypairA = Keypair.generate('ed25519', 'alice')
|
const keypairA = Keypair.generate('ed25519', 'alice')
|
||||||
const keypairB = Keypair.generate('ed25519', 'bob')
|
const keypairB = Keypair.generate('ed25519', 'bob')
|
||||||
const identityA = MsgV3.getMsgHash(MsgV3.createIdentity(keypairA, 'alice'))
|
const identityA = MsgV3.getMsgHash(
|
||||||
const identityB = MsgV3.getMsgHash(MsgV3.createIdentity(keypairB, 'bob'))
|
MsgV3.createIdentity(keypairA, 'person', 'alice')
|
||||||
|
)
|
||||||
|
const identityB = MsgV3.getMsgHash(
|
||||||
|
MsgV3.createIdentity(keypairB, 'person', 'bob')
|
||||||
|
)
|
||||||
|
|
||||||
const rootMsgA = MsgV3.createRoot(identityA, 'post', keypairA)
|
const rootMsgA = MsgV3.createRoot(identityA, 'post', keypairA)
|
||||||
const rootHashA = MsgV3.getMsgHash(rootMsgA)
|
const rootHashA = MsgV3.getMsgHash(rootMsgA)
|
||||||
|
@ -82,8 +86,12 @@ test('simple multi-author tangle', (t) => {
|
||||||
test('lipmaa in multi-author tangle', (t) => {
|
test('lipmaa in multi-author tangle', (t) => {
|
||||||
const keypairA = Keypair.generate('ed25519', 'alice')
|
const keypairA = Keypair.generate('ed25519', 'alice')
|
||||||
const keypairB = Keypair.generate('ed25519', 'bob')
|
const keypairB = Keypair.generate('ed25519', 'bob')
|
||||||
const identityA = MsgV3.getMsgHash(MsgV3.createIdentity(keypairA, 'alice'))
|
const identityA = MsgV3.getMsgHash(
|
||||||
const identityB = MsgV3.getMsgHash(MsgV3.createIdentity(keypairB, 'bob'))
|
MsgV3.createIdentity(keypairA, 'person', 'alice')
|
||||||
|
)
|
||||||
|
const identityB = MsgV3.getMsgHash(
|
||||||
|
MsgV3.createIdentity(keypairB, 'person', 'bob')
|
||||||
|
)
|
||||||
|
|
||||||
const data = { text: 'Hello world!' }
|
const data = { text: 'Hello world!' }
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,9 @@ const MsgV3 = require('../../lib/msg-v3')
|
||||||
|
|
||||||
test('validate root msg', (t) => {
|
test('validate root msg', (t) => {
|
||||||
const keypair = Keypair.generate('ed25519', 'alice')
|
const keypair = Keypair.generate('ed25519', 'alice')
|
||||||
const identity = MsgV3.getMsgHash(MsgV3.createIdentity(keypair, 'alice'))
|
const identity = MsgV3.getMsgHash(
|
||||||
|
MsgV3.createIdentity(keypair, 'person', 'alice')
|
||||||
|
)
|
||||||
const pubkeys = new Set([keypair.public])
|
const pubkeys = new Set([keypair.public])
|
||||||
|
|
||||||
const rootMsg = MsgV3.createRoot(identity, 'post', keypair)
|
const rootMsg = MsgV3.createRoot(identity, 'post', keypair)
|
||||||
|
@ -21,13 +23,19 @@ test('validate identity tangle', (t) => {
|
||||||
const keypair1 = Keypair.generate('ed25519', 'alice')
|
const keypair1 = Keypair.generate('ed25519', 'alice')
|
||||||
pubkeys.add(keypair1.public)
|
pubkeys.add(keypair1.public)
|
||||||
|
|
||||||
const identityMsg0 = MsgV3.createIdentity(keypair1, 'alice')
|
const identityMsg0 = MsgV3.createIdentity(keypair1, 'person', 'alice')
|
||||||
const identity = MsgV3.getMsgHash(identityMsg0)
|
const identity = MsgV3.getMsgHash(identityMsg0)
|
||||||
const identityMsg0Hash = identity
|
const identityMsg0Hash = identity
|
||||||
|
|
||||||
const tangle = new MsgV3.Tangle(identity)
|
const tangle = new MsgV3.Tangle(identity)
|
||||||
|
|
||||||
let err = MsgV3.validate(identityMsg0, tangle, pubkeys, identityMsg0Hash, identity)
|
let err = MsgV3.validate(
|
||||||
|
identityMsg0,
|
||||||
|
tangle,
|
||||||
|
pubkeys,
|
||||||
|
identityMsg0Hash,
|
||||||
|
identity
|
||||||
|
)
|
||||||
assert.ifError(err, 'valid identity root msg')
|
assert.ifError(err, 'valid identity root msg')
|
||||||
|
|
||||||
tangle.add(identity, identityMsg0)
|
tangle.add(identity, identityMsg0)
|
||||||
|
@ -46,13 +54,21 @@ test('validate identity tangle', (t) => {
|
||||||
})
|
})
|
||||||
const identityMsg1Hash = MsgV3.getMsgHash(identityMsg1)
|
const identityMsg1Hash = MsgV3.getMsgHash(identityMsg1)
|
||||||
|
|
||||||
err = MsgV3.validate(identityMsg1, tangle, pubkeys, identityMsg1Hash, identity)
|
err = MsgV3.validate(
|
||||||
|
identityMsg1,
|
||||||
|
tangle,
|
||||||
|
pubkeys,
|
||||||
|
identityMsg1Hash,
|
||||||
|
identity
|
||||||
|
)
|
||||||
assert.ifError(err, 'valid identity msg')
|
assert.ifError(err, 'valid identity msg')
|
||||||
})
|
})
|
||||||
|
|
||||||
test('validate 2nd msg with existing root', (t) => {
|
test('validate 2nd msg with existing root', (t) => {
|
||||||
const keypair = Keypair.generate('ed25519', 'alice')
|
const keypair = Keypair.generate('ed25519', 'alice')
|
||||||
const identity = MsgV3.getMsgHash(MsgV3.createIdentity(keypair, 'alice'))
|
const identity = MsgV3.getMsgHash(
|
||||||
|
MsgV3.createIdentity(keypair, 'person', 'alice')
|
||||||
|
)
|
||||||
const pubkeys = new Set([keypair.public])
|
const pubkeys = new Set([keypair.public])
|
||||||
|
|
||||||
const rootMsg = MsgV3.createRoot(identity, 'post', keypair)
|
const rootMsg = MsgV3.createRoot(identity, 'post', keypair)
|
||||||
|
@ -79,7 +95,9 @@ test('validate 2nd msg with existing root', (t) => {
|
||||||
|
|
||||||
test('validate 2nd forked msg', (t) => {
|
test('validate 2nd forked msg', (t) => {
|
||||||
const keypair = Keypair.generate('ed25519', 'alice')
|
const keypair = Keypair.generate('ed25519', 'alice')
|
||||||
const identity = MsgV3.getMsgHash(MsgV3.createIdentity(keypair, 'alice'))
|
const identity = MsgV3.getMsgHash(
|
||||||
|
MsgV3.createIdentity(keypair, 'person', 'alice')
|
||||||
|
)
|
||||||
const pubkeys = new Set([keypair.public])
|
const pubkeys = new Set([keypair.public])
|
||||||
|
|
||||||
const rootMsg = MsgV3.createRoot(identity, 'post', keypair)
|
const rootMsg = MsgV3.createRoot(identity, 'post', keypair)
|
||||||
|
|
|
@ -19,7 +19,7 @@ test('msgs() iterator', async (t) => {
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
const identity = (await p(peer.db.identity.create)(null)).hash
|
const identity = (await p(peer.db.identity.create)({domain: 'person'}))
|
||||||
|
|
||||||
for (let i = 0; i < 6; i++) {
|
for (let i = 0; i < 6; i++) {
|
||||||
await p(peer.db.feed.publish)({
|
await p(peer.db.feed.publish)({
|
||||||
|
|
|
@ -19,7 +19,7 @@ test('onRecordAdded', async (t) => {
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
|
|
||||||
const identity = (await p(peer.db.identity.create)(null)).hash
|
const identity = (await p(peer.db.identity.create)({domain: 'person'}))
|
||||||
|
|
||||||
const listened = []
|
const listened = []
|
||||||
var remove = peer.db.onRecordAdded((ev) => {
|
var remove = peer.db.onRecordAdded((ev) => {
|
||||||
|
@ -36,7 +36,7 @@ test('onRecordAdded', async (t) => {
|
||||||
await p(setTimeout)(500)
|
await p(setTimeout)(500)
|
||||||
|
|
||||||
assert.equal(listened.length, 3)
|
assert.equal(listened.length, 3)
|
||||||
assert.equal(listened[0].msg.metadata.identity, null, 'identity root')
|
assert.equal(listened[0].msg.metadata.identity, 'self', 'identity root')
|
||||||
assert.equal(listened[1].msg.data, null, 'root')
|
assert.equal(listened[1].msg.data, null, 'root')
|
||||||
assert.equal(listened[1].msg.metadata.dataSize, 0, 'root')
|
assert.equal(listened[1].msg.metadata.dataSize, 0, 'root')
|
||||||
assert.deepEqual(listened[2], rec1, 'actual record')
|
assert.deepEqual(listened[2], rec1, 'actual record')
|
||||||
|
|
|
@ -19,7 +19,7 @@ test('publish some msgs, close, re-open', async (t) => {
|
||||||
.call(null, { keypair, path: DIR })
|
.call(null, { keypair, path: DIR })
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
const identity = (await p(peer.db.identity.create)(null)).hash
|
const identity = await p(peer.db.identity.create)({ domain: 'person' })
|
||||||
// t.pass('opened db')
|
// t.pass('opened db')
|
||||||
|
|
||||||
const msgHashes = []
|
const msgHashes = []
|
||||||
|
@ -49,7 +49,7 @@ test('publish some msgs, close, re-open', async (t) => {
|
||||||
|
|
||||||
const texts = []
|
const texts = []
|
||||||
for (const msg of peer2.db.msgs()) {
|
for (const msg of peer2.db.msgs()) {
|
||||||
if (!msg.data || !msg.metadata.identity) continue
|
if (!msg.data || !(msg.metadata.identity?.length > 4)) continue
|
||||||
texts.push(msg.data.text)
|
texts.push(msg.data.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@ test('records() iterator', async (t) => {
|
||||||
.call(null, { keypair, path: DIR })
|
.call(null, { keypair, path: DIR })
|
||||||
|
|
||||||
await peer.db.loaded()
|
await peer.db.loaded()
|
||||||
const identity = (await p(peer.db.identity.create)(null)).hash
|
const identity = (await p(peer.db.identity.create)({ domain: 'person' }))
|
||||||
|
|
||||||
for (let i = 0; i < 6; i++) {
|
for (let i = 0; i < 6; i++) {
|
||||||
await p(peer.db.feed.publish)({
|
await p(peer.db.feed.publish)({
|
||||||
|
@ -34,7 +34,7 @@ test('records() iterator', async (t) => {
|
||||||
let count = 0
|
let count = 0
|
||||||
for (const rec of peer.db.records()) {
|
for (const rec of peer.db.records()) {
|
||||||
if (!rec.msg.data) continue
|
if (!rec.msg.data) continue
|
||||||
if (!rec.msg.metadata.identity) continue
|
if (rec.msg.metadata.identity === 'self') continue
|
||||||
assert.ok(rec.misc.size > rec.msg.metadata.dataSize, 'size > dataSize')
|
assert.ok(rec.misc.size > rec.msg.metadata.dataSize, 'size > dataSize')
|
||||||
count++
|
count++
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue