flatten tagged union in msg AccountData

This commit is contained in:
Andre Staltz 2023-11-16 11:29:55 +02:00
parent 9223402335
commit 1ff84756bc
No known key found for this signature in database
GPG Key ID: 9EDE23EA7E8A4890
7 changed files with 73 additions and 89 deletions

View File

@ -310,9 +310,9 @@ function initDB(peer, config) {
/** @type {AccountData} */ /** @type {AccountData} */
const data = msg.data const data = msg.data
if (data.action !== 'add') continue if (data.action !== 'add') continue
if (data.add.key.purpose !== 'sig') continue if (data.key.purpose !== 'sig') continue
if (data.add.key.algorithm !== 'ed25519') continue if (data.key.algorithm !== 'ed25519') continue
pubkeys.add(data.add.key.bytes) pubkeys.add(data.key.bytes)
} }
return pubkeys return pubkeys
} }
@ -510,7 +510,7 @@ function initDB(peer, config) {
if (rec.msg.metadata.account !== ACCOUNT_SELF) continue if (rec.msg.metadata.account !== ACCOUNT_SELF) continue
if (rec.msg.metadata.domain !== domain) continue if (rec.msg.metadata.domain !== domain) continue
const data = /** @type {AccountData} */ (rec.msg.data) 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) const accountID = getAccountID(rec)
if (accountID) { if (accountID) {
cb(null, accountID) cb(null, accountID)
@ -546,8 +546,8 @@ function initDB(peer, config) {
/** @type {AccountData} */ /** @type {AccountData} */
const data = msg.data const data = msg.data
if (data.action !== 'add') continue if (data.action !== 'add') continue
if (data.add.key.algorithm !== keypair.curve) continue if (data.key.algorithm !== keypair.curve) continue
if (data.add.key.bytes === keypair.public) { if (data.key.bytes === keypair.public) {
return true return true
} }
} }
@ -625,10 +625,10 @@ function initDB(peer, config) {
/** @type {AccountData} */ /** @type {AccountData} */
const data = msg.data const data = msg.data
if (data.action !== 'add') continue if (data.action !== 'add') continue
if (data.add.key.algorithm !== keypair.curve) continue if (data.key.algorithm !== keypair.curve) continue
if (data.add.key.bytes !== keypair.public) continue if (data.key.bytes !== keypair.public) continue
if (data.add.powers) { if (data.powers) {
for (const power of data.add.powers) { for (const power of data.powers) {
powers.add(power) powers.add(power)
} }
} }
@ -741,16 +741,14 @@ function initDB(peer, config) {
/** @type {AccountData} */ /** @type {AccountData} */
const data = { const data = {
action: 'add', action: 'add',
add: {
key: { key: {
purpose: 'sig', purpose: 'sig',
algorithm: 'ed25519', algorithm: 'ed25519',
bytes: addedKeypair.public, bytes: addedKeypair.public,
}, },
consent, consent,
},
} }
if (opts.powers) data.add.powers = opts.powers if (opts.powers) data.powers = opts.powers
// Fill-in tangle opts: // Fill-in tangle opts:
const fullOpts = { const fullOpts = {

View File

@ -59,11 +59,7 @@ const { isEmptyObject } = require('./util')
* prev: Array<string>; * prev: Array<string>;
* }} TangleMetadata * }} TangleMetadata
* *
* @typedef {{ * @typedef {AccountAdd | AccountDel} AccountData
* action: 'add', add: AccountAdd
* } | {
* action: 'del', del: AccountDel
* }} AccountData
* *
* @typedef {'add' | 'del' | 'box'} AccountPower * @typedef {'add' | 'del' | 'box'} AccountPower
* *
@ -82,6 +78,7 @@ const { isEmptyObject } = require('./util')
* @typedef {SigKey | BoxKey} AccountKey * @typedef {SigKey | BoxKey} AccountKey
* *
* @typedef {{ * @typedef {{
* action: 'add',
* key: AccountKey; * key: AccountKey;
* nonce?: string; * nonce?: string;
* consent?: string; * consent?: string;
@ -89,6 +86,7 @@ const { isEmptyObject } = require('./util')
* }} AccountAdd * }} AccountAdd
* *
* @typedef {{ * @typedef {{
* action: 'del',
* key: AccountKey; * key: AccountKey;
* }} AccountDel * }} AccountDel
* *
@ -235,7 +233,6 @@ function createAccount(keypair, domain, nonce = getRandomNonce) {
/** @type {AccountData} */ /** @type {AccountData} */
const data = { const data = {
action: 'add', action: 'add',
add: {
key: { key: {
purpose: 'sig', purpose: 'sig',
algorithm: 'ed25519', algorithm: 'ed25519',
@ -243,7 +240,6 @@ function createAccount(keypair, domain, nonce = getRandomNonce) {
}, },
nonce: typeof nonce === 'function' ? nonce() : nonce, nonce: typeof nonce === 'function' ? nonce() : nonce,
powers: ['add', 'del', 'box'], powers: ['add', 'del', 'box'],
},
} }
return create({ return create({

View File

@ -4,9 +4,9 @@ Background: https://github.com/ssbc/ssb2-discussion-forum/issues/24
## Terminology ## Terminology
- **Msg** = published data that is signed and shareable - **Msg** = `{data,metadata,pubkey,sig}` published by a peer
- **Msg hash** = hash(msg.metadata) - **Msg ID** = `hash(msg.metadata)`
- **Tangle** = any single-root DAG of msgs that can be replicated by peers - **Tangle** = a single-root DAG of msgs that can be replicated by peers
- **Tangle Root** = the origin msg of a tangle - **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 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 - **Tangle ID** = Msg hash of the tangle's root msg
@ -68,9 +68,7 @@ interface Msg {
sig: Signature sig: Signature
} }
type AccountData = type AccountData = AccountAdd | AccountDel
| { action: 'add', add: AccountAdd }
| { action: 'del', del: AccountDel }
// "add" means this shs peer can validly add more keys to the account tangle // "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 // "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 AccountPower = 'add' | 'del' | 'internal-encryption' | 'external-encryption'
type AccountAdd = { type AccountAdd = {
action: 'add'
key: Key key: Key
nonce?: string // nonce required only on the account tangle's root nonce?: string // nonce required only on the account tangle's root
consent?: string // base58 encoded signature of the string `:account-add:<ID>` where `<ID>` is the account's ID, required only on non-root msgs consent?: string // base58 encoded signature of the string `:account-add:<ID>` where `<ID>` is the account's ID, required only on non-root msgs
@ -86,6 +85,7 @@ type AccountAdd = {
} }
type AccountDel = { type AccountDel = {
action: 'del'
key: Key key: Key
} }
@ -113,7 +113,6 @@ Examples of `AccountData`:
```json ```json
{ {
"action": "add", "action": "add",
"add": {
"key": { "key": {
"purpose": "shs-and-external-signature", "purpose": "shs-and-external-signature",
"algorithm": "ed25519", "algorithm": "ed25519",
@ -121,20 +120,17 @@ Examples of `AccountData`:
}, },
"nonce": "6GHR1ZFFSB3C5qAGwmSwVH8f7byNo8Cqwn5PcyG3qDvS" "nonce": "6GHR1ZFFSB3C5qAGwmSwVH8f7byNo8Cqwn5PcyG3qDvS"
} }
}
``` ```
- Revoking a signing pubkey: - Revoking a signing pubkey:
```json ```json
{ {
"action": "del", "action": "del",
"del": {
"key": { "key": {
"purpose": "shs-and-external-signature", "purpose": "shs-and-external-signature",
"algorithm": "ed25519", "algorithm": "ed25519",
"bytes": "3JrJiHEQzRFMzEqWawfBgq2DSZDyihP1NHXshqcL8pB9" "bytes": "3JrJiHEQzRFMzEqWawfBgq2DSZDyihP1NHXshqcL8pB9"
} }
} }
}
``` ```
## Feed root ## Feed root

View File

@ -44,7 +44,6 @@ test('account.add()', async (t) => {
msg.data, msg.data,
{ {
action: 'add', action: 'add',
add: {
key: { key: {
purpose: 'sig', purpose: 'sig',
algorithm: 'ed25519', algorithm: 'ed25519',
@ -53,7 +52,6 @@ test('account.add()', async (t) => {
consent, consent,
powers: ['box'], powers: ['box'],
}, },
},
'msg.data.add NEW KEY' 'msg.data.add NEW KEY'
) )
assert.equal(msg.metadata.account, 'self', 'msg.metadata.account') assert.equal(msg.metadata.account, 'self', 'msg.metadata.account')
@ -94,7 +92,7 @@ test('account.add()', async (t) => {
keypair: keypair2, keypair: keypair2,
powers: [], 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) assert.equal(peer1.db.account.has({ account: id, keypair: keypair2 }), true)
@ -128,7 +126,7 @@ test('account.add()', async (t) => {
_disobey: true, _disobey: true,
}) })
assert.equal(msg3.data.add.key.bytes, keypair3.public) assert.equal(msg3.data.key.bytes, keypair3.public)
await p(peer2.close)() await p(peer2.close)()
rimraf.sync(DIR) rimraf.sync(DIR)

View File

@ -30,7 +30,6 @@ test('account.create() ', async (t) => {
msg.data, msg.data,
{ {
action: 'add', action: 'add',
add: {
key: { key: {
purpose: 'sig', purpose: 'sig',
algorithm: 'ed25519', algorithm: 'ed25519',
@ -39,8 +38,7 @@ test('account.create() ', async (t) => {
nonce: 'MYNONCE', nonce: 'MYNONCE',
powers: ['add', 'del', 'box'], powers: ['add', 'del', 'box'],
}, },
}, 'msg.data'
'msg.data.add'
) )
assert.equal(msg.metadata.account, 'self', 'msg.metadata.account') assert.equal(msg.metadata.account, 'self', 'msg.metadata.account')
assert.equal(msg.metadata.accountTips, null, 'msg.metadata.accountTips') assert.equal(msg.metadata.accountTips, null, 'msg.metadata.accountTips')
@ -70,7 +68,7 @@ test('account.create() ', async (t) => {
}) })
assert.ok(account, 'account created') assert.ok(account, 'account created')
const msg = peer.db.get(account) 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.account, 'self', 'msg.metadata.account')
assert.equal(msg.metadata.accountTips, null, 'msg.metadata.accountTips') assert.equal(msg.metadata.accountTips, null, 'msg.metadata.accountTips')
assert.deepEqual( assert.deepEqual(
@ -145,7 +143,7 @@ test('account.create() ', async (t) => {
const account = await p(peer.db.account.findOrCreate)({ keypair, domain }) const account = await p(peer.db.account.findOrCreate)({ keypair, domain })
assert.ok(account, 'account created') assert.ok(account, 'account created')
const msg = peer.db.get(account) 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.account, 'self', 'msg.metadata.account')
assert.equal(msg.metadata.accountTips, null, 'msg.metadata.accountTips') assert.equal(msg.metadata.accountTips, null, 'msg.metadata.accountTips')
assert.deepEqual( assert.deepEqual(

View File

@ -50,7 +50,7 @@ test('add()', async (t) => {
await p(peer.db._getLog().onDrain)() await p(peer.db._getLog().onDrain)()
const stats = await p(peer.db.logStats)() 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) await p(peer.close)(true)
}) })

View File

@ -14,7 +14,6 @@ test('MsgV3.createAccount()', (t) => {
accountMsg0.data, accountMsg0.data,
{ {
action: 'add', action: 'add',
add: {
key: { key: {
purpose: 'sig', purpose: 'sig',
algorithm: 'ed25519', algorithm: 'ed25519',
@ -23,11 +22,10 @@ test('MsgV3.createAccount()', (t) => {
nonce: 'MYNONCE', nonce: 'MYNONCE',
powers: ['add', 'del', 'box'], powers: ['add', 'del', 'box'],
}, },
},
'data' 'data'
) )
assert.equal(accountMsg0.metadata.dataHash, 'R5az9nC1CB3Afd5Q57HYRQ', 'hash') assert.equal(accountMsg0.metadata.dataHash, 'DQCPxgzni6UTZ5DSCms9Y', 'hash')
assert.equal(accountMsg0.metadata.dataSize, 172, 'size') assert.equal(accountMsg0.metadata.dataSize, 164, 'size')
assert.equal(accountMsg0.metadata.account, 'self', 'account') assert.equal(accountMsg0.metadata.account, 'self', 'account')
assert.equal(accountMsg0.metadata.accountTips, null, 'accountTips') assert.equal(accountMsg0.metadata.accountTips, null, 'accountTips')
assert.deepEqual(accountMsg0.metadata.tangles, {}, 'tangles') assert.deepEqual(accountMsg0.metadata.tangles, {}, 'tangles')
@ -36,7 +34,7 @@ test('MsgV3.createAccount()', (t) => {
assert.equal(accountMsg0.pubkey, keypair.public, 'pubkey') assert.equal(accountMsg0.pubkey, keypair.public, 'pubkey')
account = MsgV3.getMsgID(accountMsg0) account = MsgV3.getMsgID(accountMsg0)
assert.equal(account, 'J2SUr6XtJuFuTusNbagEW5', 'account ID') assert.equal(account, 'Hx9Fuitrg3WQCCcBaPqpeo', 'account ID')
}) })
let moot = null let moot = null
@ -58,7 +56,7 @@ test('MsgV3.createMoot()', (t) => {
assert.equal(moot.pubkey, keypair.public, 'pubkey') assert.equal(moot.pubkey, keypair.public, 'pubkey')
mootID = MsgV3.getMsgID(moot) mootID = MsgV3.getMsgID(moot)
assert.equal(mootID, 'VsBFptgidvAspk4xTKZx6c', 'moot ID') assert.equal(mootID, 'YYrum2aUPGLarrVnjM5o93', 'moot ID')
}) })
test('MsgV3.create()', (t) => { test('MsgV3.create()', (t) => {
@ -118,11 +116,11 @@ test('MsgV3.create()', (t) => {
) )
assert.equal( assert.equal(
msg1.sig, msg1.sig,
'46CjqZzC8RAanRHnUKs147PMNFvrQcc9Y7a8tMP3s4qQubCtgYsypgzNA7XkSxM6vqRCe2ZBSKM2WR9AoHN3VoDz', '5wrhPju22NHuq1qFK9qMrNafUMAhCHnLurGfASCVhPTjQTVQE4SqdV9G3zmUTesxFmynn7a1P6nJFgfvWGuSw86h',
'sig' 'sig'
) )
const msgID1 = 'R5G9WtDAQrco4FABRdvrUH' const msgID1 = '7qfYPwQ1qYHYHLSXzGQCCy'
assert.equal(MsgV3.getMsgID(msg1), msgID1, 'getMsgID') assert.equal(MsgV3.getMsgID(msg1), msgID1, 'getMsgID')
@ -182,11 +180,11 @@ test('MsgV3.create()', (t) => {
) )
assert.equal( assert.equal(
msg2.sig, msg2.sig,
'31StEDDnoDoDtRi49L94XPTGXxNtDJa9QXSJTd4o3wBtFAJvfQA1RsHvunU4CxdY9iC69WnxnkaW6QryrztJZkiA', '2xsdFCPsUzmaGzoQaANJSJHkCAZt3qyVUDW88RBV3r1PCspzU3BbKdQxHoxKYKcwLrpxxi4cSd5eyfcEt3DV61ge',
'sig' 'sig'
) )
assert.deepEqual(MsgV3.getMsgID(msg2), 'LxWgRRr4wXd29sLDNGNTkr', 'getMsgID') assert.deepEqual(MsgV3.getMsgID(msg2), '38GT4SxtEqfZffkCrNYLtY', 'getMsgID')
}) })
test('MsgV3.create() handles DAG tips correctly', (t) => { test('MsgV3.create() handles DAG tips correctly', (t) => {