diff --git a/lib/index.js b/lib/index.js index f4361da..eed7ddd 100644 --- a/lib/index.js +++ b/lib/index.js @@ -310,9 +310,9 @@ function initDB(peer, config) { /** @type {AccountData} */ const data = msg.data if (data.action !== 'add') continue - if (data.add.key.purpose !== 'sig') continue - if (data.add.key.algorithm !== 'ed25519') continue - pubkeys.add(data.add.key.bytes) + if (data.key.purpose !== 'sig') continue + if (data.key.algorithm !== 'ed25519') continue + pubkeys.add(data.key.bytes) } return pubkeys } @@ -510,7 +510,7 @@ function initDB(peer, config) { if (rec.msg.metadata.account !== ACCOUNT_SELF) continue if (rec.msg.metadata.domain !== domain) continue const data = /** @type {AccountData} */ (rec.msg.data) - if (data.action === 'add' && data.add.key.bytes === keypair.public) { + if (data.action === 'add' && data.key.bytes === keypair.public) { const accountID = getAccountID(rec) if (accountID) { cb(null, accountID) @@ -546,8 +546,8 @@ function initDB(peer, config) { /** @type {AccountData} */ const data = msg.data if (data.action !== 'add') continue - if (data.add.key.algorithm !== keypair.curve) continue - if (data.add.key.bytes === keypair.public) { + if (data.key.algorithm !== keypair.curve) continue + if (data.key.bytes === keypair.public) { return true } } @@ -625,10 +625,10 @@ function initDB(peer, config) { /** @type {AccountData} */ const data = msg.data if (data.action !== 'add') continue - if (data.add.key.algorithm !== keypair.curve) continue - if (data.add.key.bytes !== keypair.public) continue - if (data.add.powers) { - for (const power of data.add.powers) { + if (data.key.algorithm !== keypair.curve) continue + if (data.key.bytes !== keypair.public) continue + if (data.powers) { + for (const power of data.powers) { powers.add(power) } } @@ -741,16 +741,14 @@ function initDB(peer, config) { /** @type {AccountData} */ const data = { action: 'add', - add: { - key: { - purpose: 'sig', - algorithm: 'ed25519', - bytes: addedKeypair.public, - }, - consent, + key: { + purpose: 'sig', + algorithm: 'ed25519', + bytes: addedKeypair.public, }, + consent, } - if (opts.powers) data.add.powers = opts.powers + if (opts.powers) data.powers = opts.powers // Fill-in tangle opts: const fullOpts = { diff --git a/lib/msg-v3/index.js b/lib/msg-v3/index.js index 77510d9..8ba58c4 100644 --- a/lib/msg-v3/index.js +++ b/lib/msg-v3/index.js @@ -59,11 +59,7 @@ const { isEmptyObject } = require('./util') * prev: Array; * }} TangleMetadata * - * @typedef {{ - * action: 'add', add: AccountAdd - * } | { - * action: 'del', del: AccountDel - * }} AccountData + * @typedef {AccountAdd | AccountDel} AccountData * * @typedef {'add' | 'del' | 'box'} AccountPower * @@ -82,6 +78,7 @@ const { isEmptyObject } = require('./util') * @typedef {SigKey | BoxKey} AccountKey * * @typedef {{ + * action: 'add', * key: AccountKey; * nonce?: string; * consent?: string; @@ -89,6 +86,7 @@ const { isEmptyObject } = require('./util') * }} AccountAdd * * @typedef {{ + * action: 'del', * key: AccountKey; * }} AccountDel * @@ -235,15 +233,13 @@ function createAccount(keypair, domain, nonce = getRandomNonce) { /** @type {AccountData} */ const data = { action: 'add', - add: { - key: { - purpose: 'sig', - algorithm: 'ed25519', - bytes: keypair.public, - }, - nonce: typeof nonce === 'function' ? nonce() : nonce, - powers: ['add', 'del', 'box'], + key: { + purpose: 'sig', + algorithm: 'ed25519', + bytes: keypair.public, }, + nonce: typeof nonce === 'function' ? nonce() : nonce, + powers: ['add', 'del', 'box'], } return create({ diff --git a/protospec.md b/protospec.md index 277ba72..65ff919 100644 --- a/protospec.md +++ b/protospec.md @@ -4,9 +4,9 @@ Background: https://github.com/ssbc/ssb2-discussion-forum/issues/24 ## Terminology -- **Msg** = published data that is signed and shareable -- **Msg hash** = hash(msg.metadata) -- **Tangle** = any single-root DAG of msgs that can be replicated by peers +- **Msg** = `{data,metadata,pubkey,sig}` published by a peer +- **Msg ID** = `hash(msg.metadata)` +- **Tangle** = a single-root DAG of msgs that can be replicated by peers - **Tangle Root** = the origin msg of a tangle - **Tangle Tips** = tangle msgs that are not yet referenced by any other msg in the tangle - **Tangle ID** = Msg hash of the tangle's root msg @@ -68,9 +68,7 @@ interface Msg { sig: Signature } -type AccountData = - | { action: 'add', add: AccountAdd } - | { action: 'del', del: AccountDel } +type AccountData = AccountAdd | AccountDel // "add" means this shs peer can validly add more keys to the account tangle // "del" means this shs peer can validly revoke keys from the account tangle @@ -79,6 +77,7 @@ type AccountData = type AccountPower = 'add' | 'del' | 'internal-encryption' | 'external-encryption' type AccountAdd = { + action: 'add' key: Key nonce?: string // nonce required only on the account tangle's root consent?: string // base58 encoded signature of the string `:account-add:` where `` is the account's ID, required only on non-root msgs @@ -86,6 +85,7 @@ type AccountAdd = { } type AccountDel = { + action: 'del' key: Key } @@ -113,26 +113,22 @@ Examples of `AccountData`: ```json { "action": "add", - "add": { - "key": { - "purpose": "shs-and-external-signature", - "algorithm": "ed25519", - "bytes": "3JrJiHEQzRFMzEqWawfBgq2DSZDyihP1NHXshqcL8pB9" - }, - "nonce": "6GHR1ZFFSB3C5qAGwmSwVH8f7byNo8Cqwn5PcyG3qDvS" - } + "key": { + "purpose": "shs-and-external-signature", + "algorithm": "ed25519", + "bytes": "3JrJiHEQzRFMzEqWawfBgq2DSZDyihP1NHXshqcL8pB9" + }, + "nonce": "6GHR1ZFFSB3C5qAGwmSwVH8f7byNo8Cqwn5PcyG3qDvS" } ``` - Revoking a signing pubkey: ```json { "action": "del", - "del": { - "key": { - "purpose": "shs-and-external-signature", - "algorithm": "ed25519", - "bytes": "3JrJiHEQzRFMzEqWawfBgq2DSZDyihP1NHXshqcL8pB9" - } + "key": { + "purpose": "shs-and-external-signature", + "algorithm": "ed25519", + "bytes": "3JrJiHEQzRFMzEqWawfBgq2DSZDyihP1NHXshqcL8pB9" } } ``` diff --git a/test/account-add.test.js b/test/account-add.test.js index a5af426..f27797d 100644 --- a/test/account-add.test.js +++ b/test/account-add.test.js @@ -44,15 +44,13 @@ test('account.add()', async (t) => { msg.data, { action: 'add', - add: { - key: { - purpose: 'sig', - algorithm: 'ed25519', - bytes: keypair2.public, - }, - consent, - powers: ['box'], + key: { + purpose: 'sig', + algorithm: 'ed25519', + bytes: keypair2.public, }, + consent, + powers: ['box'], }, 'msg.data.add NEW KEY' ) @@ -94,7 +92,7 @@ test('account.add()', async (t) => { keypair: keypair2, powers: [], }) - assert.equal(msg2.data.add.key.bytes, keypair2.public) + assert.equal(msg2.data.key.bytes, keypair2.public) assert.equal(peer1.db.account.has({ account: id, keypair: keypair2 }), true) @@ -128,7 +126,7 @@ test('account.add()', async (t) => { _disobey: true, }) - assert.equal(msg3.data.add.key.bytes, keypair3.public) + assert.equal(msg3.data.key.bytes, keypair3.public) await p(peer2.close)() rimraf.sync(DIR) diff --git a/test/account-create.test.js b/test/account-create.test.js index 0b2eb58..36e9b67 100644 --- a/test/account-create.test.js +++ b/test/account-create.test.js @@ -30,17 +30,15 @@ test('account.create() ', async (t) => { msg.data, { action: 'add', - add: { - key: { - purpose: 'sig', - algorithm: 'ed25519', - bytes: keypair.public, - }, - nonce: 'MYNONCE', - powers: ['add', 'del', 'box'], + key: { + purpose: 'sig', + algorithm: 'ed25519', + bytes: keypair.public, }, + nonce: 'MYNONCE', + powers: ['add', 'del', 'box'], }, - 'msg.data.add' + 'msg.data' ) assert.equal(msg.metadata.account, 'self', 'msg.metadata.account') assert.equal(msg.metadata.accountTips, null, 'msg.metadata.accountTips') @@ -70,7 +68,7 @@ test('account.create() ', async (t) => { }) assert.ok(account, 'account created') const msg = peer.db.get(account) - assert.equal(msg.data.add.key.bytes, keypair.public, 'msg.data.add') + assert.equal(msg.data.key.bytes, keypair.public, 'msg.data') assert.equal(msg.metadata.account, 'self', 'msg.metadata.account') assert.equal(msg.metadata.accountTips, null, 'msg.metadata.accountTips') assert.deepEqual( @@ -145,7 +143,7 @@ test('account.create() ', async (t) => { const account = await p(peer.db.account.findOrCreate)({ keypair, domain }) assert.ok(account, 'account created') const msg = peer.db.get(account) - assert.equal(msg.data.add.key.bytes, keypair.public, 'msg.data.add') + assert.equal(msg.data.key.bytes, keypair.public, 'msg.data') assert.equal(msg.metadata.account, 'self', 'msg.metadata.account') assert.equal(msg.metadata.accountTips, null, 'msg.metadata.accountTips') assert.deepEqual( diff --git a/test/add.test.js b/test/add.test.js index 3b42a7d..5c20375 100644 --- a/test/add.test.js +++ b/test/add.test.js @@ -50,7 +50,7 @@ test('add()', async (t) => { await p(peer.db._getLog().onDrain)() const stats = await p(peer.db.logStats)() - assert.deepEqual(stats, { totalBytes: 904, deletedBytes: 0 }) + assert.deepEqual(stats, { totalBytes: 897, deletedBytes: 0 }) await p(peer.close)(true) }) diff --git a/test/msg-v3/create.test.js b/test/msg-v3/create.test.js index 0240c88..9001e08 100644 --- a/test/msg-v3/create.test.js +++ b/test/msg-v3/create.test.js @@ -14,20 +14,18 @@ test('MsgV3.createAccount()', (t) => { accountMsg0.data, { action: 'add', - add: { - key: { - purpose: 'sig', - algorithm: 'ed25519', - bytes: keypair.public, - }, - nonce: 'MYNONCE', - powers: ['add', 'del', 'box'], + key: { + purpose: 'sig', + algorithm: 'ed25519', + bytes: keypair.public, }, + nonce: 'MYNONCE', + powers: ['add', 'del', 'box'], }, 'data' ) - assert.equal(accountMsg0.metadata.dataHash, 'R5az9nC1CB3Afd5Q57HYRQ', 'hash') - assert.equal(accountMsg0.metadata.dataSize, 172, 'size') + assert.equal(accountMsg0.metadata.dataHash, 'DQCPxgzni6UTZ5DSCms9Y', 'hash') + assert.equal(accountMsg0.metadata.dataSize, 164, 'size') assert.equal(accountMsg0.metadata.account, 'self', 'account') assert.equal(accountMsg0.metadata.accountTips, null, 'accountTips') assert.deepEqual(accountMsg0.metadata.tangles, {}, 'tangles') @@ -36,7 +34,7 @@ test('MsgV3.createAccount()', (t) => { assert.equal(accountMsg0.pubkey, keypair.public, 'pubkey') account = MsgV3.getMsgID(accountMsg0) - assert.equal(account, 'J2SUr6XtJuFuTusNbagEW5', 'account ID') + assert.equal(account, 'Hx9Fuitrg3WQCCcBaPqpeo', 'account ID') }) let moot = null @@ -58,7 +56,7 @@ test('MsgV3.createMoot()', (t) => { assert.equal(moot.pubkey, keypair.public, 'pubkey') mootID = MsgV3.getMsgID(moot) - assert.equal(mootID, 'VsBFptgidvAspk4xTKZx6c', 'moot ID') + assert.equal(mootID, 'YYrum2aUPGLarrVnjM5o93', 'moot ID') }) test('MsgV3.create()', (t) => { @@ -118,11 +116,11 @@ test('MsgV3.create()', (t) => { ) assert.equal( msg1.sig, - '46CjqZzC8RAanRHnUKs147PMNFvrQcc9Y7a8tMP3s4qQubCtgYsypgzNA7XkSxM6vqRCe2ZBSKM2WR9AoHN3VoDz', + '5wrhPju22NHuq1qFK9qMrNafUMAhCHnLurGfASCVhPTjQTVQE4SqdV9G3zmUTesxFmynn7a1P6nJFgfvWGuSw86h', 'sig' ) - const msgID1 = 'R5G9WtDAQrco4FABRdvrUH' + const msgID1 = '7qfYPwQ1qYHYHLSXzGQCCy' assert.equal(MsgV3.getMsgID(msg1), msgID1, 'getMsgID') @@ -182,11 +180,11 @@ test('MsgV3.create()', (t) => { ) assert.equal( msg2.sig, - '31StEDDnoDoDtRi49L94XPTGXxNtDJa9QXSJTd4o3wBtFAJvfQA1RsHvunU4CxdY9iC69WnxnkaW6QryrztJZkiA', + '2xsdFCPsUzmaGzoQaANJSJHkCAZt3qyVUDW88RBV3r1PCspzU3BbKdQxHoxKYKcwLrpxxi4cSd5eyfcEt3DV61ge', 'sig' ) - assert.deepEqual(MsgV3.getMsgID(msg2), 'LxWgRRr4wXd29sLDNGNTkr', 'getMsgID') + assert.deepEqual(MsgV3.getMsgID(msg2), '38GT4SxtEqfZffkCrNYLtY', 'getMsgID') }) test('MsgV3.create() handles DAG tips correctly', (t) => {