From edfabd8d14c69fe51845ed53dbd6d551a368a025 Mon Sep 17 00:00:00 2001 From: Andre Staltz Date: Sat, 8 Apr 2023 18:46:02 +0300 Subject: [PATCH] fix logic determining tips of the tangle --- lib/feed-v1/index.js | 36 +++++++++++++++++-- test/feed-v1-create.test.js | 69 +++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+), 3 deletions(-) diff --git a/lib/feed-v1/index.js b/lib/feed-v1/index.js index 6079547..a27329f 100644 --- a/lib/feed-v1/index.js +++ b/lib/feed-v1/index.js @@ -91,7 +91,16 @@ function readDepth(msg, tangleId = null) { return msg.metadata.tangles?.[tangleId]?.depth ?? 0 } else { return msg.metadata.depth - }} + } +} + +function readPrev(msg, tangleId = null) { + if (tangleId) { + return msg.metadata.tangles?.[tangleId]?.prev ?? [] + } else { + return msg.metadata.prev + } +} function calculateDepth(existing, tangleId = null) { let max = -1 @@ -132,12 +141,33 @@ function lipmaa(n) { return n - po3 } +function determineTips(existing, tangleId = null) { + const tips = new Set() + for (const msg of existing.values()) { + tips.add(getMsgHash(msg)) + } + + for (const msg of existing.values()) { + const prev = readPrev(msg, tangleId) + for (const p of prev) { + tips.delete(p) + } + } + return tips +} + function calculatePrev(existing, depth, lipmaaDepth, tangleId = null) { const prev = [] + const tips = determineTips(existing, tangleId) for (const msg of existing.values()) { const msgDepth = readDepth(msg, tangleId) - if (msgDepth === lipmaaDepth || msgDepth === depth - 1) { - prev.push(getMsgHash(msg)) + const msgHash = getMsgHash(msg) + if ( + msgDepth === depth - 1 || + msgDepth === lipmaaDepth || + tips.has(msgHash) + ) { + prev.push(msgHash) } } return prev diff --git a/test/feed-v1-create.test.js b/test/feed-v1-create.test.js index 3616aa7..018ee75 100644 --- a/test/feed-v1-create.test.js +++ b/test/feed-v1-create.test.js @@ -80,3 +80,72 @@ tape('FeedV1.create()', (t) => { t.end() }) + +tape('create() handles DAG tips correctly', (t) => { + const keys = generateKeypair('alice') + const when = 1652037377204 + const existing = new Map() + + const msg1 = FeedV1.create({ + keys, + content: { text: '1' }, + type: 'post', + existing: new Map(), + when: when + 1, + }) + const msgHash1 = FeedV1.getMsgHash(msg1) + t.deepEquals(msg1.metadata.prev, [], 'msg1.prev is empty') + + existing.set(msgHash1, msg1) + + const msg2A = FeedV1.create({ + keys, + content: { text: '2A' }, + type: 'post', + existing, + when: when + 2, + }) + t.deepEquals(msg2A.metadata.prev, [msgHash1], 'msg2A.prev is msg1') + + const msg2B = FeedV1.create({ + keys, + content: { text: '2B' }, + type: 'post', + existing, + when: when + 2, + }) + const msgHash2B = FeedV1.getMsgHash(msg2B) + t.deepEquals(msg2B.metadata.prev, [msgHash1], 'msg2B.prev is msg1') + + existing.set(msgHash2B, msg2B) + + const msg3 = FeedV1.create({ + keys, + content: { text: '3' }, + type: 'post', + existing, + when: when + 3, + }) + const msgHash3 = FeedV1.getMsgHash(msg3) + t.deepEquals(msg3.metadata.prev, [msgHash2B], 'msg3.prev is msg2B') + existing.set(msgHash3, msg3) + + const msgHash2A = FeedV1.getMsgHash(msg2A) + existing.set(msgHash2A, msg2A) + t.pass('msg2A comes into awareness') + + const msg4 = FeedV1.create({ + keys, + content: { text: '4' }, + type: 'post', + existing, + when: when + 4, + }) + t.deepEquals( + msg4.metadata.prev, + [msgHash1, msgHash3, msgHash2A], + 'msg4.prev is [msg1(lipmaa),msg3(previous),msg2A(old fork as tip)]' + ) + + t.end() +})