From 4e54589c097b790d0f89f741d9d827ae93bd6cde Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 2 Apr 2024 18:29:26 -0500 Subject: [PATCH 1/3] Deliver API events to outbox relays --- src/storages/pool-store.ts | 7 ++++--- src/utils/api.ts | 7 +++++-- src/utils/outbox.ts | 27 +++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 5 deletions(-) create mode 100644 src/utils/outbox.ts diff --git a/src/storages/pool-store.ts b/src/storages/pool-store.ts index 3d4b5d43..8ec0cc96 100644 --- a/src/storages/pool-store.ts +++ b/src/storages/pool-store.ts @@ -11,6 +11,7 @@ import { import { normalizeFilters } from '@/filter.ts'; import { purifyEvent } from '@/storages/hydrate.ts'; import { abortError } from '@/utils/abort.ts'; +import { getRelays } from '@/utils/outbox.ts'; interface PoolStoreOpts { pool: InstanceType; @@ -34,12 +35,12 @@ class PoolStore implements NStore { this.#publisher = opts.publisher; } - event(event: NostrEvent, opts: NStoreOpts = {}): Promise { + async event(event: NostrEvent, opts: NStoreOpts = {}): Promise { if (opts.signal?.aborted) return Promise.reject(abortError()); - const { relays = this.#relays } = opts; + const relays = [...await getRelays(event.pubkey)].slice(0, 4); event = purifyEvent(event); - this.#debug('EVENT', event); + this.#debug('EVENT', event, relays); this.#pool.publish(event, relays); return Promise.resolve(); diff --git a/src/utils/api.ts b/src/utils/api.ts index 476f854f..c458c50e 100644 --- a/src/utils/api.ts +++ b/src/utils/api.ts @@ -14,7 +14,7 @@ import { import * as pipeline from '@/pipeline.ts'; import { AdminSigner } from '@/signers/AdminSigner.ts'; import { APISigner } from '@/signers/APISigner.ts'; -import { eventsDB } from '@/storages.ts'; +import { client, eventsDB } from '@/storages.ts'; import { nostrNow } from '@/utils.ts'; const debug = Debug('ditto:api'); @@ -89,7 +89,10 @@ async function createAdminEvent(t: EventStub, c: AppContext): Promise { debug('EVENT', event); try { - await pipeline.handleEvent(event, c.req.raw.signal); + await Promise.all([ + pipeline.handleEvent(event, c.req.raw.signal), + client.event(event), + ]); } catch (e) { if (e instanceof pipeline.RelayError) { throw new HTTPException(422, { diff --git a/src/utils/outbox.ts b/src/utils/outbox.ts new file mode 100644 index 00000000..8189fe25 --- /dev/null +++ b/src/utils/outbox.ts @@ -0,0 +1,27 @@ +import { Conf } from '@/config.ts'; +import { eventsDB } from '@/storages.ts'; + +export async function getRelays(pubkey: string): Promise> { + const relays = new Set<`wss://${string}`>(); + + const events = await eventsDB.query([ + { kinds: [10002], authors: [pubkey, Conf.pubkey], limit: 2 }, + ]); + + for (const event of events) { + for (const [name, relay, marker] of event.tags) { + if (name === 'r' && (marker === 'write' || !marker)) { + try { + const url = new URL(relay); + if (url.protocol === 'wss:') { + relays.add(url.toString() as `wss://${string}`); + } + } catch (_e) { + // do nothing + } + } + } + } + + return relays; +} From d577c51c740293e0aa6f4a382f160259f9e6d1b8 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 2 Apr 2024 19:36:40 -0500 Subject: [PATCH 2/3] PoolStore: don't publish to own relay --- src/storages/pool-store.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/storages/pool-store.ts b/src/storages/pool-store.ts index 8ec0cc96..ec32ab47 100644 --- a/src/storages/pool-store.ts +++ b/src/storages/pool-store.ts @@ -12,6 +12,7 @@ import { normalizeFilters } from '@/filter.ts'; import { purifyEvent } from '@/storages/hydrate.ts'; import { abortError } from '@/utils/abort.ts'; import { getRelays } from '@/utils/outbox.ts'; +import { Conf } from '@/config.ts'; interface PoolStoreOpts { pool: InstanceType; @@ -37,7 +38,11 @@ class PoolStore implements NStore { async event(event: NostrEvent, opts: NStoreOpts = {}): Promise { if (opts.signal?.aborted) return Promise.reject(abortError()); - const relays = [...await getRelays(event.pubkey)].slice(0, 4); + + const relaySet = await getRelays(event.pubkey); + relaySet.delete(Conf.relay); + + const relays = [...relaySet].slice(0, 4); event = purifyEvent(event); this.#debug('EVENT', event, relays); From 5e834d2a6b859b77bd08b959f10540575fe47654 Mon Sep 17 00:00:00 2001 From: Alex Gleason Date: Tue, 2 Apr 2024 19:53:11 -0500 Subject: [PATCH 3/3] pipeline: remove broadcast function --- src/pipeline.ts | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/src/pipeline.ts b/src/pipeline.ts index 1c7a891d..8ab6b894 100644 --- a/src/pipeline.ts +++ b/src/pipeline.ts @@ -9,7 +9,7 @@ import { isEphemeralKind } from '@/kinds.ts'; import { DVM } from '@/pipeline/DVM.ts'; import { updateStats } from '@/stats.ts'; import { hydrateEvents, purifyEvent } from '@/storages/hydrate.ts'; -import { cache, client, eventsDB, reqmeister } from '@/storages.ts'; +import { cache, eventsDB, reqmeister } from '@/storages.ts'; import { Sub } from '@/subs.ts'; import { getTagSet } from '@/tags.ts'; import { eventAge, isRelay, nostrDate, nostrNow, parseNip05, Time } from '@/utils.ts'; @@ -43,7 +43,6 @@ async function handleEvent(event: DittoEvent, signal: AbortSignal): Promise