lipmaa in multi-author tangles

This commit is contained in:
Andre Staltz 2023-04-07 17:57:53 +03:00
parent e0337a2c68
commit 448bd44a41
2 changed files with 105 additions and 7 deletions

View File

@ -86,11 +86,19 @@ function toPlaintextBuffer(opts) {
return Buffer.from(stringify(opts.content), 'utf8') return Buffer.from(stringify(opts.content), 'utf8')
} }
function calculateDepth(existing) { function readDepth(msg, tangleId = null) {
if (tangleId) {
return msg.metadata.tangles?.[tangleId]?.depth ?? 0
} else {
return msg.metadata.depth
}}
function calculateDepth(existing, tangleId = null) {
let max = -1 let max = -1
for (const msg of existing.values()) { for (const msg of existing.values()) {
if (msg.metadata.depth > max) { const depth = readDepth(msg, tangleId)
max = msg.metadata.depth if (depth > max) {
max = depth
} }
} }
return max + 1 return max + 1
@ -124,10 +132,10 @@ function lipmaa(n) {
return n - po3 return n - po3
} }
function calculatePrev(existing, depth, lipmaaDepth) { function calculatePrev(existing, depth, lipmaaDepth, tangleId = null) {
const prev = [] const prev = []
for (const msg of existing.values()) { for (const msg of existing.values()) {
const msgDepth = msg.metadata.depth const msgDepth = readDepth(msg, tangleId)
if (msgDepth === lipmaaDepth || msgDepth === depth - 1) { if (msgDepth === lipmaaDepth || msgDepth === depth - 1) {
prev.push(getMsgHash(msg)) prev.push(getMsgHash(msg))
} }
@ -168,6 +176,9 @@ function prevalidateExisting(existing, tangleId = null) {
} else { } else {
hasDepthZeroMsg = true hasDepthZeroMsg = true
} }
} else if (!p.metadata.tangles?.[tangleId]) {
// prettier-ignore
return new Error(`existing must refer to the tangleId ${tangleId}`)
} }
} }
} }
@ -197,9 +208,10 @@ function create(opts) {
if ((err = validateMsgHash(rootId))) throw err if ((err = validateMsgHash(rootId))) throw err
const existing = opts.tangles[rootId] const existing = opts.tangles[rootId]
if ((err = prevalidateExisting(existing, rootId))) throw err if ((err = prevalidateExisting(existing, rootId))) throw err
const depth = calculateDepth(existing)
const depth = calculateDepth(existing, rootId)
const lipmaaDepth = lipmaa(depth + 1) - 1 const lipmaaDepth = lipmaa(depth + 1) - 1
const prev = calculatePrev(existing, depth, lipmaaDepth) const prev = calculatePrev(existing, depth, lipmaaDepth, rootId)
tangles ??= {} tangles ??= {}
tangles[rootId] = { depth, prev } tangles[rootId] = { depth, prev }
} }

View File

@ -37,3 +37,89 @@ tape('simple multi-author tangle', (t) => {
t.end() t.end()
}) })
tape('lipmaa in multi-author tangle', (t) => {
const keysA = generateKeypair('alice')
const keysB = generateKeypair('bob')
const content = { text: 'Hello world!' }
const when = 1652037377204
const existingA = new Map()
const existingB = new Map()
const tangleExisting = new Map()
const msg1 = FeedV1.create({
keys: keysA,
content,
type: 'post',
existing: existingA,
when: when + 1,
})
const msgHash1 = FeedV1.getMsgHash(msg1)
existingA.set(msgHash1, msg1)
tangleExisting.set(msgHash1, msg1)
t.notOk(msg1.metadata.tangles, 'A:msg1 has no extra tangles')
const msg2 = FeedV1.create({
keys: keysB,
content,
type: 'post',
existing: existingB,
tangles: {
[msgHash1]: tangleExisting,
},
when: when + 2,
})
const msgHash2 = FeedV1.getMsgHash(msg2)
existingB.set(msgHash2, msg2)
tangleExisting.set(msgHash2, msg2)
t.deepEquals(
msg2.metadata.tangles[msgHash1].prev,
[msgHash1],
'B:msg2 points to A:msg1'
)
const msg3 = FeedV1.create({
keys: keysB,
content,
type: 'post',
existing: existingB,
tangles: {
[msgHash1]: tangleExisting,
},
when: when + 3,
})
const msgHash3 = FeedV1.getMsgHash(msg3)
existingB.set(msgHash3, msg3)
tangleExisting.set(msgHash3, msg3)
t.deepEquals(
msg3.metadata.tangles[msgHash1].prev,
[msgHash2],
'B:msg3 points to B:msg2'
)
const msg4 = FeedV1.create({
keys: keysA,
content,
type: 'post',
existing: existingA,
tangles: {
[msgHash1]: tangleExisting,
},
when: when + 4,
})
const msgHash4 = FeedV1.getMsgHash(msg4)
existingB.set(msgHash4, msg4)
tangleExisting.set(msgHash4, msg4)
t.deepEquals(
msg4.metadata.tangles[msgHash1].prev,
[msgHash1, msgHash3],
'A:msg4 points to A:msg1,B:msg3'
)
t.end()
})