From df98d499f168248b8798fa359f1b06a0404c95ba Mon Sep 17 00:00:00 2001 From: Andre Staltz Date: Sun, 25 Jun 2023 20:48:20 +0300 Subject: [PATCH] identity tangle always has metadata.identity=self --- lib/index.js | 128 ++++++++++++++++++++++++++----- lib/msg-v3/index.js | 10 ++- lib/msg-v3/is-feed-root.js | 3 +- lib/msg-v3/validation.js | 6 +- protospec.md | 6 +- test/add.test.js | 2 +- test/del.test.js | 18 +++-- test/erase.test.js | 10 ++- test/feed-get-id.test.js | 2 +- test/feed-publish.test.js | 2 +- test/get.test.js | 2 +- test/getTangle.test.js | 2 +- test/identity-add.test.js | 51 +++++++----- test/identity-create.test.js | 37 +++++---- test/msg-v3/create.test.js | 18 ++--- test/msg-v3/invalid-prev.test.js | 14 +++- test/msg-v3/lipmaa.test.js | 4 +- test/msg-v3/tangles.test.js | 16 +++- test/msg-v3/validate.test.js | 30 ++++++-- test/msgs-iterator.test.js | 2 +- test/on-record-added.test.js | 4 +- test/re-open.test.js | 4 +- test/records-iterator.test.js | 4 +- 23 files changed, 271 insertions(+), 104 deletions(-) diff --git a/lib/index.js b/lib/index.js index c152e91..766e09b 100644 --- a/lib/index.js +++ b/lib/index.js @@ -8,7 +8,7 @@ const b4a = require('b4a') const base58 = require('bs58') // @ts-ignore const Obz = require('obz') -const MsgV2 = require('./msg-v3') +const MsgV3 = require('./msg-v3') const { ReadyGate } = require('./utils') const { decrypt } = require('./encryption') @@ -58,7 +58,7 @@ const { decrypt } = require('./encryption') * @typedef {(...args: [Error] | []) => void} CBVoid */ -class DBTangle extends MsgV2.Tangle { +class DBTangle extends MsgV3.Tangle { /** * @param {string} rootHash * @param {Iterable} recordsIter @@ -260,7 +260,7 @@ function initDB(peer, config) { * @param {CB} 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 // 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 pubkeys = new Set() - if (msg.metadata.identity) { + if (msg.metadata.identity && msg.metadata.identity !== 'self') { const identityTangle = new DBTangle(msg.metadata.identity, records()) if (!identityTangle.has(msg.metadata.identity)) { // prettier-ignore @@ -286,7 +286,7 @@ function initDB(peer, config) { } 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 })) } @@ -308,8 +308,8 @@ function initDB(peer, config) { const feedRootHash = getFeedId(identity, domain) if (feedRootHash) return cb(null, feedRootHash) - const feedRoot = MsgV2.createRoot(identity, domain, keypair) - add(feedRoot, MsgV2.getMsgHash(feedRoot), (err, rec) => { + const feedRoot = MsgV3.createRoot(identity, domain, keypair) + add(feedRoot, MsgV3.getMsgHash(feedRoot), (err, rec) => { // prettier-ignore if (err) return cb(new Error('initializeFeed() failed to add root', { cause: err })); const recHash = /** @type {string} */ (rec.hash) @@ -318,25 +318,109 @@ function initDB(peer, config) { } /** - * @param {{keypair?: Keypair, _nonce?: string} | null} opts - * @param {CB} cb + * @param {Rec} rec + * @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} 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} cb */ function createIdentity(opts, cb) { + if (!opts.domain) + return cb(new Error('identity.create() requires a `domain`')) const keypair = opts?.keypair ?? config.keypair + const domain = opts.domain let msg try { - msg = MsgV2.createIdentity(keypair, opts?._nonce) + msg = MsgV3.createIdentity(keypair, domain, opts?._nonce) } catch (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) => { // prettier-ignore if (err) return cb(new Error('identity.create() failed in the log', { cause: err })) 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} 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: const tangles = populateTangles([opts.identity]) const fullOpts = { - identity: null, + identity: 'self', identityTips: null, tangles, keypair: signingKeypair, @@ -366,11 +450,11 @@ function initDB(peer, config) { // Create the actual message: let msg try { - msg = MsgV2.create(fullOpts) + msg = MsgV3.create(fullOpts) } catch (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) => { // prettier-ignore @@ -421,7 +505,7 @@ function initDB(peer, config) { // If opts ask for encryption, encrypt and put ciphertext in opts.data const recps = fullOpts.data.recps if (Array.isArray(recps) && recps.length > 0) { - const plaintext = MsgV2.toPlaintextBuffer(fullOpts) + const plaintext = MsgV3.toPlaintextBuffer(fullOpts) const encryptOpts = { ...fullOpts, recps: recps.map( @@ -454,11 +538,11 @@ function initDB(peer, config) { // Create the actual message: let msg try { - msg = MsgV2.create(fullOpts) + msg = MsgV3.create(fullOpts) } catch (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: logAppend(msgHash, msg, (err, rec) => { @@ -475,9 +559,9 @@ function initDB(peer, config) { * @param {string} findDomain */ function getFeedId(id, findDomain) { - const findIdentity = MsgV2.stripIdentity(id) + const findIdentity = MsgV3.stripIdentity(id) 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 } } @@ -531,7 +615,7 @@ function initDB(peer, config) { if (!rec) return cb() if (!rec.msg) 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 cb() } @@ -564,7 +648,9 @@ function initDB(peer, config) { loaded, add, identity: { + find: findIdentity, create: createIdentity, + findOrCreate: findOrCreateIdentity, add: addToIdentity, }, feed: { diff --git a/lib/msg-v3/index.js b/lib/msg-v3/index.js index 5a719bc..06d9b6b 100644 --- a/lib/msg-v3/index.js +++ b/lib/msg-v3/index.js @@ -37,7 +37,7 @@ const Tangle = require('./tangle') * metadata: { * dataHash: string | null; * dataSize: number; - * identity: string | null; + * identity: string | (typeof IDENTITY_SELF) | null; * identityTips: Array | null; * tangles: Record; * domain: string; @@ -57,6 +57,8 @@ const Tangle = require('./tangle') * }} CreateOpts */ +const IDENTITY_SELF = /** @type {const} */ 'self' + /** * @param {string} id * @param {string} domain @@ -178,21 +180,23 @@ function createRoot(id, domain, keypair) { /** * @param {Keypair} keypair + * @param {string} domain * @param {string | (() => string)} nonce * @returns {Msg} */ function createIdentity( keypair, + domain, nonce = () => base58.encode(crypto.randomBytes(32)) ) { const actualNonce = typeof nonce === 'function' ? nonce() : nonce return create({ data: { add: keypair.public, nonce: actualNonce }, - identity: null, + identity: IDENTITY_SELF, identityTips: null, keypair, tangles: {}, - domain: 'identity', + domain, }) } diff --git a/lib/msg-v3/is-feed-root.js b/lib/msg-v3/is-feed-root.js index 2bf43d0..cd309ae 100644 --- a/lib/msg-v3/is-feed-root.js +++ b/lib/msg-v3/is-feed-root.js @@ -20,7 +20,8 @@ function isEmptyObject(obj) { * @param {string | 0} findDomain */ 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 (dataSize !== 0) return false if (id === 0 && !identity) return false diff --git a/lib/msg-v3/validation.js b/lib/msg-v3/validation.js index 6250eba..407afe5 100644 --- a/lib/msg-v3/validation.js +++ b/lib/msg-v3/validation.js @@ -88,7 +88,11 @@ function validateIdentityPubkey(msg, pubkeys) { // Unusual case: if the msg is a feed root, ignore the identity and pubkey 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 return `invalid message: pubkey "${msg.pubkey}" should have been one of "${[...pubkeys]}" from the identity "${msg.metadata.identity}"\n` + JSON.stringify(msg) } diff --git a/protospec.md b/protospec.md index 6dc94e5..56bf534 100644 --- a/protospec.md +++ b/protospec.md @@ -24,7 +24,7 @@ interface Msg { metadata: { dataHash: ContentHash | null // blake3 hash 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 | null // list of blake3 hashes of identity tangle tips, or null tangles: { // for each tangle this msg belongs to, identified by the tangle's root @@ -54,7 +54,7 @@ interface Msg { metadata: { dataHash: ContentHash dataSize: number - identity: null // MUST be null + identity: 'self' // MUST be the string 'self' identityTips: null // MUST be null tangles: { [identityTangleId: string]: { @@ -62,7 +62,7 @@ interface Msg { prev: Array // 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 } pubkey: Pubkey diff --git a/test/add.test.js b/test/add.test.js index 1c1de50..e485adb 100644 --- a/test/add.test.js +++ b/test/add.test.js @@ -21,7 +21,7 @@ test('add()', async (t) => { await peer.db.loaded() - const identityMsg0 = MsgV3.createIdentity(keypair) + const identityMsg0 = MsgV3.createIdentity(keypair, 'person') const id = MsgV3.getMsgHash(identityMsg0) await p(peer.db.add)(identityMsg0, id) diff --git a/test/del.test.js b/test/del.test.js index 130e91e..94e9d5c 100644 --- a/test/del.test.js +++ b/test/del.test.js @@ -21,7 +21,7 @@ test('del', async (t) => { 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 = [] for (let i = 0; i < 5; i++) { @@ -35,16 +35,24 @@ test('del', async (t) => { const before = [] 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]) const after = [] 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') @@ -83,7 +91,7 @@ test('del', async (t) => { assert.deepEqual( persistedMsgs - .filter((msg) => msg.data && msg.metadata.identity) + .filter((msg) => msg.data && msg.metadata.identity?.length > 4) .map((msg) => msg.data.text), ['m0', 'm1', 'm3', 'm4'], 'msgs in disk after the delete' diff --git a/test/erase.test.js b/test/erase.test.js index b23c8cd..1d2e0fc 100644 --- a/test/erase.test.js +++ b/test/erase.test.js @@ -21,7 +21,7 @@ test('erase', async (t) => { 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 = [] for (let i = 0; i < 5; i++) { @@ -35,7 +35,9 @@ test('erase', async (t) => { const before = [] 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( @@ -48,7 +50,9 @@ test('erase', async (t) => { const after = [] 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') diff --git a/test/feed-get-id.test.js b/test/feed-get-id.test.js index e6dd8b5..1fea06f 100644 --- a/test/feed-get-id.test.js +++ b/test/feed-get-id.test.js @@ -25,7 +25,7 @@ test('setup', async (t) => { 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) rootHash = MsgV3.getMsgHash(rootMsg) diff --git a/test/feed-publish.test.js b/test/feed-publish.test.js index b82f85d..20ef9f5 100644 --- a/test/feed-publish.test.js +++ b/test/feed-publish.test.js @@ -26,7 +26,7 @@ test('setup', async (t) => { 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) rootHash = MsgV3.getMsgHash(rootMsg) }) diff --git a/test/get.test.js b/test/get.test.js index 03bbad6..6c7d1cf 100644 --- a/test/get.test.js +++ b/test/get.test.js @@ -25,7 +25,7 @@ test('setup', async (t) => { 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)({ identity: id, diff --git a/test/getTangle.test.js b/test/getTangle.test.js index 292ae20..11d11dc 100644 --- a/test/getTangle.test.js +++ b/test/getTangle.test.js @@ -26,7 +26,7 @@ test('setup', async (t) => { 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 const originalAppend = peer.db._getLog().append diff --git a/test/identity-add.test.js b/test/identity-add.test.js index 20b7c41..c548770 100644 --- a/test/identity-add.test.js +++ b/test/identity-add.test.js @@ -21,15 +21,20 @@ test('identity.add()', async (t) => { .call(null, { keypair: keypair1, path: DIR }) await peer.db.loaded() - const identityRec0 = await p(peer.db.identity.create)({ keypair: keypair1 }) - const id = identityRec0.hash + const id = await p(peer.db.identity.create)({ + 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') const { hash, msg } = identityRec1 assert.ok(hash, 'hash exists') 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.deepEqual( msg.metadata.tangles, @@ -54,9 +59,15 @@ test('publish with a key in the identity', async (t) => { await peer.db.loaded() - const identityRec0 = await p(peer.db.identity.create)({ keypair: keypair1 }) - const identity = identityRec0.hash - const identityRec1 = await p(peer.db.identity.add)({ identity, keypair: keypair2 }) + const identity = await p(peer.db.identity.create)({ + keypair: keypair1, + 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)({ identity, @@ -71,17 +82,21 @@ test('publish with a key in the identity', async (t) => { const recs = [...peer.db.records()] assert.equal(recs.length, 4, '4 records') 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(postsRoot.msg.metadata, { - dataHash: null, - dataSize: 0, - identity, - identityTips: null, - tangles: {}, - domain: 'post', - v: 3, - }, 'postsRoot') + assert.deepEqual( + postsRoot.msg.metadata, + { + dataHash: null, + dataSize: 0, + identity, + identityTips: null, + tangles: {}, + domain: 'post', + v: 3, + }, + 'postsRoot' + ) assert.deepEqual(_post.msg, postRec.msg, 'postMsg') await p(peer.close)() @@ -97,7 +112,7 @@ test('publish with a key in the identity', async (t) => { 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)(postsRoot.msg, postsId) await p(carol.db.add)(postRec.msg, postsId) diff --git a/test/identity-create.test.js b/test/identity-create.test.js index 7ecc330..dfea93c 100644 --- a/test/identity-create.test.js +++ b/test/identity-create.test.js @@ -11,7 +11,7 @@ const Keypair = require('ppppp-keypair') const DIR = path.join(os.tmpdir(), 'ppppp-db-identity-create') 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 peer = SecretStack({ appKey: caps.shse }) .use(require('../lib')) @@ -19,20 +19,23 @@ test('identity.create() without args', async (t) => { .call(null, { keypair, path: DIR }) await peer.db.loaded() - const identityRec0 = await p(peer.db.identity.create)({}) - assert.ok(identityRec0, 'identityRec0 exists') - const { hash, msg } = identityRec0 - assert.ok(hash, 'hash exists') + const identity = await p(peer.db.identity.create)({ domain: 'person' }) + assert.ok(identity, 'identityRec0 exists') + const msg = peer.db.get(identity) 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.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') 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 peer = SecretStack({ appKey: caps.shse }) @@ -41,14 +44,20 @@ test('identity.create() with "keypair" arg', async (t) => { .call(null, { keypair, path: DIR }) await peer.db.loaded() - const identityRec0 = await p(peer.db.identity.create)({ keypair }) - assert.ok(identityRec0, 'identityRec0 exists') - const { hash, msg } = identityRec0 - assert.ok(hash, 'hash exists') + const identity = await p(peer.db.identity.create)({ + keypair, + domain: 'person', + }) + assert.ok(identity, 'identity created') + const msg = peer.db.get(identity) 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.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') await p(peer.close)() diff --git a/test/msg-v3/create.test.js b/test/msg-v3/create.test.js index 002c7f8..9cbef7b 100644 --- a/test/msg-v3/create.test.js +++ b/test/msg-v3/create.test.js @@ -7,21 +7,21 @@ let identity test('MsgV3.createIdentity()', (t) => { 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)) assert.equal(identityMsg0.data.add, keypair.public, 'data.add') assert.equal(identityMsg0.metadata.dataHash, 'THi3VkJeaf8aTkLSNJUdFD', 'hash') 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.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.pubkey, keypair.public, 'pubkey') identity = MsgV3.getMsgHash(identityMsg0) - assert.equal(identity, 'WnAX17Lm2ktfPUJ5ARXq73', 'identity ID') + assert.equal(identity, 'v7vBrnrCTahjgkpoaZrWm', 'identity ID') }) let rootMsg = null @@ -43,7 +43,7 @@ test('MsgV3.createRoot()', (t) => { assert.equal(rootMsg.pubkey, keypair.public, 'pubkey') rootHash = MsgV3.getMsgHash(rootMsg) - assert.equal(rootHash, '5G4FJTWaGr7ZBUJGge6Qeg', 'root hash') + assert.equal(rootHash, 'HPtwPD552ajEurwpgQRfTX', 'root hash') }) test('MsgV3.create()', (t) => { @@ -95,11 +95,11 @@ test('MsgV3.create()', (t) => { ) assert.equal( msg1.sig, - 'xZGu2Kb19XicfoihgBZ84jRs4XuNgVBd2bK45Cum2fdVDNJUE3f8Ejf6apfZFyE8iAfPDEVWFNAJB6E52EaWEAm', + '2FhnKsDKCxEV4JUM1nmPp3oSFJ8zL7r4SjMNogDHeAzCWQLgVmKiexgUDSE4k9C3eT4Uy3SZbBhRY75WJAqvtHHf', 'sig' ) - const msgHash1 = 'NF389yT2td9gz5TvRuZMB6' + const msgHash1 = 'FK4jCKFZDGwecydC8bitgR' assert.equal( MsgV3.getMsgId(msg1), @@ -155,13 +155,13 @@ test('MsgV3.create()', (t) => { ) assert.equal( msg2.sig, - '2XHQcG8KeNbdz8m5fDs2QtT7jcxgEqHxv7SkSYVpKQAJ1S8HGn3dmLxw3J5vWmu1vhYhWS6GDE1hfMtvmfiCAy54', + '3B6WQvDdKvRhZeZDfE9LY4HrnhZTJHRJ86FazBg1xxco2S1eHG44UwR9TSpthiXQ1X51h2VeDeGPV6Fdma69BMN9', 'sig' ) assert.deepEqual( MsgV3.getMsgId(msg2), - `ppppp:message/v3/${identity}/post/HNQp1oUu3zmgD1s11xiR7y`, + `ppppp:message/v3/${identity}/post/AYXun8rEc3SNGZYM252TAS`, 'getMsgId' ) }) diff --git a/test/msg-v3/invalid-prev.test.js b/test/msg-v3/invalid-prev.test.js index 198e9c3..05952d6 100644 --- a/test/msg-v3/invalid-prev.test.js +++ b/test/msg-v3/invalid-prev.test.js @@ -5,7 +5,9 @@ const Keypair = require('ppppp-keypair') const MsgV3 = require('../../lib/msg-v3') 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]) 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) 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) => { const keypairA = Keypair.generate('ed25519', 'alice') 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 rootHash = MsgV3.getMsgHash(rootMsg) diff --git a/test/msg-v3/lipmaa.test.js b/test/msg-v3/lipmaa.test.js index 40c81c0..983c16c 100644 --- a/test/msg-v3/lipmaa.test.js +++ b/test/msg-v3/lipmaa.test.js @@ -5,7 +5,9 @@ const MsgV3 = require('../../lib/msg-v3') test('lipmaa prevs', (t) => { 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 rootMsg = MsgV3.createRoot(identity, 'post', keypair) diff --git a/test/msg-v3/tangles.test.js b/test/msg-v3/tangles.test.js index a044987..c3d5e2c 100644 --- a/test/msg-v3/tangles.test.js +++ b/test/msg-v3/tangles.test.js @@ -6,8 +6,12 @@ const MsgV3 = require('../../lib/msg-v3') test('simple multi-author tangle', (t) => { const keypairA = Keypair.generate('ed25519', 'alice') const keypairB = Keypair.generate('ed25519', 'bob') - const identityA = MsgV3.getMsgHash(MsgV3.createIdentity(keypairA, 'alice')) - const identityB = MsgV3.getMsgHash(MsgV3.createIdentity(keypairB, 'bob')) + const identityA = MsgV3.getMsgHash( + MsgV3.createIdentity(keypairA, 'person', 'alice') + ) + const identityB = MsgV3.getMsgHash( + MsgV3.createIdentity(keypairB, 'person', 'bob') + ) const rootMsgA = MsgV3.createRoot(identityA, 'post', keypairA) const rootHashA = MsgV3.getMsgHash(rootMsgA) @@ -82,8 +86,12 @@ test('simple multi-author tangle', (t) => { test('lipmaa in multi-author tangle', (t) => { const keypairA = Keypair.generate('ed25519', 'alice') const keypairB = Keypair.generate('ed25519', 'bob') - const identityA = MsgV3.getMsgHash(MsgV3.createIdentity(keypairA, 'alice')) - const identityB = MsgV3.getMsgHash(MsgV3.createIdentity(keypairB, 'bob')) + const identityA = MsgV3.getMsgHash( + MsgV3.createIdentity(keypairA, 'person', 'alice') + ) + const identityB = MsgV3.getMsgHash( + MsgV3.createIdentity(keypairB, 'person', 'bob') + ) const data = { text: 'Hello world!' } diff --git a/test/msg-v3/validate.test.js b/test/msg-v3/validate.test.js index 5cdf291..00abad6 100644 --- a/test/msg-v3/validate.test.js +++ b/test/msg-v3/validate.test.js @@ -5,7 +5,9 @@ const MsgV3 = require('../../lib/msg-v3') test('validate root msg', (t) => { 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 rootMsg = MsgV3.createRoot(identity, 'post', keypair) @@ -21,13 +23,19 @@ test('validate identity tangle', (t) => { const keypair1 = Keypair.generate('ed25519', 'alice') pubkeys.add(keypair1.public) - const identityMsg0 = MsgV3.createIdentity(keypair1, 'alice') + const identityMsg0 = MsgV3.createIdentity(keypair1, 'person', 'alice') const identity = MsgV3.getMsgHash(identityMsg0) const identityMsg0Hash = 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') tangle.add(identity, identityMsg0) @@ -46,13 +54,21 @@ test('validate identity tangle', (t) => { }) 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') }) test('validate 2nd msg with existing root', (t) => { 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 rootMsg = MsgV3.createRoot(identity, 'post', keypair) @@ -79,7 +95,9 @@ test('validate 2nd msg with existing root', (t) => { test('validate 2nd forked msg', (t) => { 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 rootMsg = MsgV3.createRoot(identity, 'post', keypair) diff --git a/test/msgs-iterator.test.js b/test/msgs-iterator.test.js index 15c2ad3..ef90473 100644 --- a/test/msgs-iterator.test.js +++ b/test/msgs-iterator.test.js @@ -19,7 +19,7 @@ test('msgs() iterator', async (t) => { 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++) { await p(peer.db.feed.publish)({ diff --git a/test/on-record-added.test.js b/test/on-record-added.test.js index db824cf..d70f147 100644 --- a/test/on-record-added.test.js +++ b/test/on-record-added.test.js @@ -19,7 +19,7 @@ test('onRecordAdded', async (t) => { 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 = [] var remove = peer.db.onRecordAdded((ev) => { @@ -36,7 +36,7 @@ test('onRecordAdded', async (t) => { await p(setTimeout)(500) 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.metadata.dataSize, 0, 'root') assert.deepEqual(listened[2], rec1, 'actual record') diff --git a/test/re-open.test.js b/test/re-open.test.js index b4d79d2..0a8f216 100644 --- a/test/re-open.test.js +++ b/test/re-open.test.js @@ -19,7 +19,7 @@ test('publish some msgs, close, re-open', async (t) => { .call(null, { keypair, path: DIR }) 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') const msgHashes = [] @@ -49,7 +49,7 @@ test('publish some msgs, close, re-open', async (t) => { const texts = [] 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) } diff --git a/test/records-iterator.test.js b/test/records-iterator.test.js index e4affaf..97220a5 100644 --- a/test/records-iterator.test.js +++ b/test/records-iterator.test.js @@ -18,7 +18,7 @@ test('records() iterator', async (t) => { .call(null, { keypair, path: DIR }) 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++) { await p(peer.db.feed.publish)({ @@ -34,7 +34,7 @@ test('records() iterator', async (t) => { let count = 0 for (const rec of peer.db.records()) { 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') count++ }