From 82ed1ed7b5df38343eba3cc4ddc955a1f06fa9ea Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Thu, 2 Oct 2025 16:50:29 -0300 Subject: [PATCH 1/3] fix missing event loop if no missing event found --- .../src/services/missing-event.service.ts | 9 ++++++--- .../src/services/staging-area.service.ts | 13 ++++++++----- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/packages/federation-sdk/src/services/missing-event.service.ts b/packages/federation-sdk/src/services/missing-event.service.ts index 64231a37b..691f465cc 100644 --- a/packages/federation-sdk/src/services/missing-event.service.ts +++ b/packages/federation-sdk/src/services/missing-event.service.ts @@ -22,7 +22,7 @@ export class MissingEventService { private readonly eventFetcherService: EventFetcherService, ) {} - async fetchMissingEvent(data: MissingEventType) { + async fetchMissingEvent(data: MissingEventType): Promise { const { eventId, roomId, origin } = data; const exists = await this.eventService.getEventById(eventId); @@ -30,7 +30,7 @@ export class MissingEventService { this.logger.debug( `Event ${eventId} already exists in database (staged or processed), marking as fetched`, ); - return; + return true; } try { @@ -43,7 +43,7 @@ export class MissingEventService { this.logger.warn( `Failed to fetch missing event ${eventId} from ${origin}`, ); - return; + return false; } for (const { event, eventId } of fetchedEvents.events) { @@ -52,10 +52,13 @@ export class MissingEventService { // TODO is there anything else we need to do with missing dependencies from received event? await this.eventService.processIncomingPDUs(origin, [event]); } + + return true; } catch (err: unknown) { this.logger.error( `Error fetching missing event ${eventId}: ${err instanceof Error ? err.message : String(err)}`, ); + return false; } } } diff --git a/packages/federation-sdk/src/services/staging-area.service.ts b/packages/federation-sdk/src/services/staging-area.service.ts index 914f2defa..e779ec07e 100644 --- a/packages/federation-sdk/src/services/staging-area.service.ts +++ b/packages/federation-sdk/src/services/staging-area.service.ts @@ -127,23 +127,26 @@ export class StagingAreaService { return; } this.logger.debug(`Missing ${missing.length} events for ${eventId}`); - // trackedEvent.missingEvents = missing; - for (const missingId of missing) { + const found = await Promise.all( + missing.map((missingId) => { this.logger.debug( `Adding missing event ${missingId} to missing events service`, ); - await this.missingEventsService.fetchMissingEvent({ + return this.missingEventsService.fetchMissingEvent({ eventId: missingId, roomId: event.event.room_id, origin: event.origin, }); - } + }), + ); + + const addedMissing = found.some((f) => f === true); // if the auth events are missing, the authorization stage will fail anyway, // so to save some time we throw an error here, and the event processing will be postponed - if (authEvents.some((e) => missing.includes(e))) { + if (addedMissing && authEvents.some((e) => missing.includes(e))) { throw new MissingAuthorizationEventsError('Missing authorization events'); } } From e2f0751c6f1293e8daffd0b1ec69e46d4d9eb0eb Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Thu, 2 Oct 2025 16:52:24 -0300 Subject: [PATCH 2/3] always remove from staging in case of error --- .../src/services/staging-area.service.ts | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/packages/federation-sdk/src/services/staging-area.service.ts b/packages/federation-sdk/src/services/staging-area.service.ts index e779ec07e..160879026 100644 --- a/packages/federation-sdk/src/services/staging-area.service.ts +++ b/packages/federation-sdk/src/services/staging-area.service.ts @@ -81,8 +81,11 @@ export class StagingAreaService { } else { this.logger.error({ msg: 'Error processing event', + event, err, }); + + await this.eventService.markEventAsUnstaged(event); } } @@ -130,15 +133,15 @@ export class StagingAreaService { const found = await Promise.all( missing.map((missingId) => { - this.logger.debug( - `Adding missing event ${missingId} to missing events service`, - ); + this.logger.debug( + `Adding missing event ${missingId} to missing events service`, + ); return this.missingEventsService.fetchMissingEvent({ - eventId: missingId, - roomId: event.event.room_id, - origin: event.origin, - }); + eventId: missingId, + roomId: event.event.room_id, + origin: event.origin, + }); }), ); From daf03e87cb4115eeaee25e37695543e27f3d36ec Mon Sep 17 00:00:00 2001 From: Diego Sampaio Date: Thu, 2 Oct 2025 16:53:55 -0300 Subject: [PATCH 3/3] remove non-used method --- .../src/repositories/event-staging.repository.ts | 11 ----------- packages/federation-sdk/src/services/event.service.ts | 10 ++-------- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/packages/federation-sdk/src/repositories/event-staging.repository.ts b/packages/federation-sdk/src/repositories/event-staging.repository.ts index e2d9168e1..f6bce6c57 100644 --- a/packages/federation-sdk/src/repositories/event-staging.repository.ts +++ b/packages/federation-sdk/src/repositories/event-staging.repository.ts @@ -51,17 +51,6 @@ export class EventStagingRepository { return this.collection.deleteOne({ _id: eventId }); } - getNextStagedEventForRoom(roomId: string): Promise { - return this.collection.findOne( - { - roomId, - }, - { - sort: { createdAt: 1 }, - }, - ); - } - async getDistinctStagedRooms(): Promise { return this.collection.distinct('roomId'); } diff --git a/packages/federation-sdk/src/services/event.service.ts b/packages/federation-sdk/src/services/event.service.ts index 263339d09..bb04d0dd9 100644 --- a/packages/federation-sdk/src/services/event.service.ts +++ b/packages/federation-sdk/src/services/event.service.ts @@ -101,12 +101,6 @@ export class EventService { return this.eventStagingRepository.getLeastDepthEventForRoom(roomId); } - async getNextStagedEventForRoom( - roomId: string, - ): Promise { - return this.eventStagingRepository.getNextStagedEventForRoom(roomId); - } - /** * Mark an event as no longer staged */ @@ -820,9 +814,9 @@ export class EventService { /** * A transaction containing the PDUs that preceded the given event(s), including the given event(s), up to the given limit. - * + * * Note: Though the PDU definitions require that prev_events and auth_events be limited in number, the response of backfill MUST NOT be validated on these specific restrictions. - * + * * Due to historical reasons, it is possible that events which were previously accepted would now be rejected by these limitations. The events should be rejected per usual by the /send, /get_missing_events, and remaining endpoints. */