fix(snapshot): NIP-09-filter beachtet zeitliche reihenfolge
Per NIP-09 darf ein deletion nur events mit created_at <= deletion.created_at loeschen. Vorher wurde ein re-publizierter post nach geloeschtem vorgaenger stumm wegfiltern. Code-review-feedback aus etappe 2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0755498937
commit
848cdf763e
|
|
@ -5,18 +5,23 @@ export function filterDeleted(
|
|||
deletions: SignedEvent[],
|
||||
authorPubkey: string,
|
||||
): SignedEvent[] {
|
||||
const deletedCoords = new Set<string>()
|
||||
const deletedAtByCoord = new Map<string, number>()
|
||||
for (const del of deletions) {
|
||||
if (del.kind !== 5) continue
|
||||
if (del.pubkey !== authorPubkey) continue
|
||||
for (const tag of del.tags) {
|
||||
if (tag[0] === 'a' && tag[1]) deletedCoords.add(tag[1])
|
||||
if (tag[0] !== 'a' || !tag[1]) continue
|
||||
const previous = deletedAtByCoord.get(tag[1])
|
||||
if (previous === undefined || del.created_at > previous) {
|
||||
deletedAtByCoord.set(tag[1], del.created_at)
|
||||
}
|
||||
}
|
||||
}
|
||||
return events.filter((ev) => {
|
||||
const d = ev.tags.find((t) => t[0] === 'd')?.[1]
|
||||
if (!d) return true
|
||||
const coord = `${ev.kind}:${ev.pubkey}:${d}`
|
||||
return !deletedCoords.has(coord)
|
||||
const deletedAt = deletedAtByCoord.get(coord)
|
||||
return deletedAt === undefined || ev.created_at > deletedAt
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,3 +28,30 @@ Deno.test('filterDeleted ignoriert kind:5 fremder pubkeys', () => {
|
|||
const out = filterDeleted([post('alive', 'a')], [fremde], 'P')
|
||||
assertEquals(out.length, 1)
|
||||
})
|
||||
|
||||
Deno.test('filterDeleted: re-publizierter post (post.created_at > deletion.created_at) bleibt erhalten', () => {
|
||||
const oldDelete: SignedEvent = {
|
||||
id: 'del', pubkey: 'P', created_at: 100, kind: 5, sig: 's', content: '',
|
||||
tags: [['a', '30023:P:resurrected']],
|
||||
}
|
||||
const newPost: SignedEvent = {
|
||||
id: 'new', pubkey: 'P', created_at: 200, kind: 30023, sig: 's', content: '',
|
||||
tags: [['d', 'resurrected']],
|
||||
}
|
||||
const out = filterDeleted([newPost], [oldDelete], 'P')
|
||||
assertEquals(out.length, 1)
|
||||
assertEquals(out[0].id, 'new')
|
||||
})
|
||||
|
||||
Deno.test('filterDeleted: post mit created_at <= deletion.created_at wird entfernt', () => {
|
||||
const newDelete: SignedEvent = {
|
||||
id: 'del', pubkey: 'P', created_at: 200, kind: 5, sig: 's', content: '',
|
||||
tags: [['a', '30023:P:dead']],
|
||||
}
|
||||
const oldPost: SignedEvent = {
|
||||
id: 'old', pubkey: 'P', created_at: 100, kind: 30023, sig: 's', content: '',
|
||||
tags: [['d', 'dead']],
|
||||
}
|
||||
const out = filterDeleted([oldPost], [newDelete], 'P')
|
||||
assertEquals(out.length, 0)
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in New Issue