mirror of https://codeberg.org/pzp/pzp-db.git
lipmaa in multi-author tangles
This commit is contained in:
parent
e0337a2c68
commit
448bd44a41
|
@ -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 }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()
|
||||||
|
})
|
||||||
|
|
Loading…
Reference in New Issue