Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions packages/federation-sdk/src/services/state.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,9 @@ export class StateService {
event,
roomVersion,
);

await Promise.all([
this.addAuthEvents(instance),
this.addPrevEvents(instance),
instance.event.auth_events.length === 0 && this.addAuthEvents(instance),
instance.event.prev_events.length === 0 && this.addPrevEvents(instance),
]);
Comment on lines 417 to 420
Copy link

Copilot AI Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using logical && inside Promise.all results in boolean false entries when conditions fail, which is unconventional and can obscure intent. Recommend building the promise list explicitly: const tasks = []; if (instance.event.auth_events.length === 0) tasks.push(this.addAuthEvents(instance)); if (instance.event.prev_events.length === 0) tasks.push(this.addPrevEvents(instance)); await Promise.all(tasks);

Copilot uses AI. Check for mistakes.
await this.signEvent(instance);

Expand Down
27 changes: 21 additions & 6 deletions packages/room/src/manager/event-wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export abstract class PersistentEventBase<

protected rawEvent: PduWithHashesAndSignaturesOptional;

private authEventsIds: Set<EventID> = new Set();
private prevEventsIds: Set<EventID> = new Set();

constructor(
event: PduWithHashesAndSignaturesOptional,
public readonly version: Version,
Expand All @@ -58,6 +61,16 @@ export abstract class PersistentEventBase<
if (this.rawEvent.signatures) {
this.signatures = this.rawEvent.signatures;
}
if (this.rawEvent.auth_events) {
for (const id of this.rawEvent.auth_events) {
this.authEventsIds.add(id);
}
}
if (this.rawEvent.prev_events) {
for (const id of this.rawEvent.prev_events) {
this.prevEventsIds.add(id);
}
}
}

Comment on lines +67 to 75
Copy link

Copilot AI Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The constructor copies auth_events and prev_events into new Sets, creating two sources of truth (rawEvent.auth_events / rawEvent.prev_events vs authEventsIds / prevEventsIds) without marking the originals as deprecated or keeping them in sync. Consider either (a) normalizing by replacing rawEvent.auth_events/prev_events with the Set-backed arrays at creation time, (b) updating the rawEvent arrays whenever the Sets change, or (c) encapsulating access so external code cannot read stale rawEvent.* arrays.

Suggested change
}
}
if (this.rawEvent.prev_events) {
for (const id of this.rawEvent.prev_events) {
this.prevEventsIds.add(id);
}
}
}
}
delete this.rawEvent.auth_events;
}
if (this.rawEvent.prev_events) {
for (const id of this.rawEvent.prev_events) {
this.prevEventsIds.add(id);
}
delete this.rawEvent.prev_events;
}
}
/**
* Returns the current list of auth event IDs as an array.
*/
getAuthEventsArray(): EventID[] {
return Array.from(this.authEventsIds);
}
/**
* Returns the current list of prev event IDs as an array.
*/
getPrevEventsArray(): EventID[] {
return Array.from(this.prevEventsIds);
}

Copilot uses AI. Check for mistakes.
// don't recalculate the hash if it is already set
Expand Down Expand Up @@ -118,8 +131,8 @@ export abstract class PersistentEventBase<
const { hashes, signatures, ...event } = this.rawEvent;
return {
...event,
auth_events: Array.from(new Set([...this.rawEvent.auth_events])),
prev_events: Array.from(new Set([...this.rawEvent.prev_events])),
auth_events: Array.from(this.authEventsIds),
prev_events: Array.from(this.prevEventsIds),
};
}

Expand All @@ -143,11 +156,11 @@ export abstract class PersistentEventBase<
}

getAuthEventIds() {
return this.rawEvent.auth_events;
return Array.from(this.authEventsIds);
}

getPreviousEventIds() {
return this.rawEvent.prev_events;
return Array.from(this.prevEventsIds);
}

isState() {
Expand Down Expand Up @@ -419,15 +432,17 @@ export abstract class PersistentEventBase<
}

addPrevEvents(events: PersistentEventBase<Version>[]) {
this.rawEvent.prev_events.push(...events.map((e) => e.eventId));
for (const event of events) {
this.prevEventsIds.add(event.eventId);
}
Comment on lines +435 to +437
Copy link

Copilot AI Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addPrevEvents and authedBy now update only the Sets and no longer mutate rawEvent.prev_events or rawEvent.auth_events, which can leave rawEvent.* arrays stale if any other code paths still access them directly. To avoid divergence, either also update rawEvent.* arrays here, or refactor remaining internal/external usages to always go through the Set-backed accessors and document rawEvent.* as legacy.

Copilot uses AI. Check for mistakes.
if (this.rawEvent.depth <= events[events.length - 1].depth) {
this.rawEvent.depth = events[events.length - 1].depth + 1;
}
return this;
}

authedBy(event: PersistentEventBase<Version>) {
this.rawEvent.auth_events.push(event.eventId);
this.authEventsIds.add(event.eventId);
Copy link

Copilot AI Oct 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addPrevEvents and authedBy now update only the Sets and no longer mutate rawEvent.prev_events or rawEvent.auth_events, which can leave rawEvent.* arrays stale if any other code paths still access them directly. To avoid divergence, either also update rawEvent.* arrays here, or refactor remaining internal/external usages to always go through the Set-backed accessors and document rawEvent.* as legacy.

Copilot uses AI. Check for mistakes.
return this;
}

Expand Down