Skip to content

Commit b09e23a

Browse files
authored
fix: Multiple tag selections for dedup key in parameterized evetns (#525)
1 parent 5c12f36 commit b09e23a

4 files changed

Lines changed: 77 additions & 3 deletions

File tree

.changeset/strong-candles-yell.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"nostream": patch
3+
---
4+
5+
Dedup keys were taking multiple tags, that was not according to NIP-01 behaviour.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
exports.up = async function (knex) {
2+
await knex.raw(`
3+
WITH ranked AS (
4+
SELECT
5+
id,
6+
row_number() OVER (
7+
PARTITION BY event_pubkey, event_kind, jsonb_build_array(COALESCE(event_deduplication->>0, ''))
8+
ORDER BY event_created_at DESC, event_id ASC
9+
) AS row_rank
10+
FROM events
11+
WHERE event_kind >= 30000
12+
AND event_kind < 40000
13+
)
14+
DELETE FROM events AS e
15+
USING ranked AS r
16+
WHERE e.id = r.id
17+
AND r.row_rank > 1;
18+
`)
19+
20+
await knex.raw(`
21+
UPDATE events
22+
SET event_deduplication = jsonb_build_array(COALESCE(event_deduplication->>0, ''))
23+
WHERE event_kind >= 30000
24+
AND event_kind < 40000
25+
AND event_deduplication IS DISTINCT FROM jsonb_build_array(COALESCE(event_deduplication->>0, ''));
26+
`)
27+
}
28+
29+
exports.down = async function () {
30+
// Irreversible data migration.
31+
}

src/services/event-import-service.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ const enrichEventMetadata = (event: Event): Event => {
2626
}
2727

2828
if (isParameterizedReplaceableEvent(event)) {
29-
const [, ...deduplication] = event.tags.find((tag) => tag.length >= 2 && tag[0] === EventTags.Deduplication) ?? [
29+
const [, deduplication] = event.tags.find((tag) => tag.length >= 2 && tag[0] === EventTags.Deduplication) ?? [
3030
null,
3131
'',
3232
]
33-
enriched = { ...enriched, [EventDeduplicationMetadataKey]: deduplication }
33+
enriched = { ...enriched, [EventDeduplicationMetadataKey]: deduplication ? [deduplication] : [''] }
3434
}
3535

3636
return enriched as Event

test/unit/services/event-import-service.spec.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,13 @@ import { join } from 'path'
33
import fs from 'fs'
44
import os from 'os'
55

6-
import { EventImportLineError, EventImportService, EventImportStats } from '../../../src/services/event-import-service'
6+
import {
7+
createEventBatchPersister,
8+
EventImportLineError,
9+
EventImportService,
10+
EventImportStats,
11+
} from '../../../src/services/event-import-service'
12+
import { EventDeduplicationMetadataKey, EventKinds, EventTags } from '../../../src/constants/base'
713
import { Event } from '../../../src/@types/event'
814
import { expect } from 'chai'
915
import { getEvents } from '../data/events'
@@ -170,4 +176,36 @@ describe('EventImportService', () => {
170176
expect(lineErrors.length).to.equal(0)
171177
}
172178
})
179+
180+
it('normalizes parameterized replaceable deduplication to first d tag value', async () => {
181+
const parameterizedEvent: Event = {
182+
id: 'a'.repeat(64),
183+
pubkey: 'b'.repeat(64),
184+
created_at: 1,
185+
kind: EventKinds.PARAMETERIZED_REPLACEABLE_FIRST,
186+
tags: [[EventTags.Deduplication, 'one', 'two']],
187+
content: 'hello',
188+
sig: 'c'.repeat(128),
189+
}
190+
191+
let upsertedEvents: Event[] = []
192+
193+
const eventRepository = {
194+
create: async () => 0,
195+
createMany: async () => 0,
196+
upsert: async () => 0,
197+
upsertMany: async (events: Event[]) => {
198+
upsertedEvents = events
199+
return events.length
200+
},
201+
deleteByPubkeyAndIds: async () => 0,
202+
} as any
203+
204+
const persistBatch = createEventBatchPersister(eventRepository)
205+
const inserted = await persistBatch([parameterizedEvent])
206+
207+
expect(inserted).to.equal(1)
208+
expect(upsertedEvents).to.have.length(1)
209+
expect((upsertedEvents[0] as any)[EventDeduplicationMetadataKey]).to.deep.equal(['one'])
210+
})
173211
})

0 commit comments

Comments
 (0)