aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--roomserver/internal/input/input_latest_events.go23
-rw-r--r--roomserver/state/state.go8
-rw-r--r--sytest-blacklist7
-rw-r--r--sytest-whitelist4
4 files changed, 31 insertions, 11 deletions
diff --git a/roomserver/internal/input/input_latest_events.go b/roomserver/internal/input/input_latest_events.go
index 5c2a1de6..2e9f3b4e 100644
--- a/roomserver/internal/input/input_latest_events.go
+++ b/roomserver/internal/input/input_latest_events.go
@@ -215,10 +215,27 @@ func (u *latestEventsUpdater) latestState() error {
var err error
roomState := state.NewStateResolution(u.api.DB, *u.roomInfo)
- // Get a list of the current latest events.
- latestStateAtEvents := make([]types.StateAtEvent, len(u.latest))
+ // Get a list of the current room state events if available.
+ var currentState []types.StateEntry
+ if u.roomInfo.StateSnapshotNID != 0 {
+ currentState, _ = roomState.LoadStateAtSnapshot(u.ctx, u.roomInfo.StateSnapshotNID)
+ }
+
+ // Get a list of the current latest events. This will include both
+ // the current room state and the latest events after the input event.
+ // The idea is that we will perform state resolution on this set and
+ // any conflicting events will be resolved properly.
+ latestStateAtEvents := make([]types.StateAtEvent, len(u.latest)+len(currentState))
+ offset := 0
+ for i := range currentState {
+ latestStateAtEvents[i] = types.StateAtEvent{
+ BeforeStateSnapshotNID: u.roomInfo.StateSnapshotNID,
+ StateEntry: currentState[i],
+ }
+ offset++
+ }
for i := range u.latest {
- latestStateAtEvents[i] = u.latest[i].StateAtEvent
+ latestStateAtEvents[offset+i] = u.latest[i].StateAtEvent
}
// Takes the NIDs of the latest events and creates a state snapshot
diff --git a/roomserver/state/state.go b/roomserver/state/state.go
index 0663499e..2944f71c 100644
--- a/roomserver/state/state.go
+++ b/roomserver/state/state.go
@@ -118,7 +118,7 @@ func (v StateResolution) LoadCombinedStateAfterEvents(
// the snapshot of the room state before them was the same.
stateBlockNIDLists, err := v.db.StateBlockNIDs(ctx, uniqueStateSnapshotNIDs(stateNIDs))
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("v.db.StateBlockNIDs: %w", err)
}
var stateBlockNIDs []types.StateBlockNID
@@ -131,7 +131,7 @@ func (v StateResolution) LoadCombinedStateAfterEvents(
// multiple snapshots.
stateEntryLists, err := v.db.StateEntries(ctx, uniqueStateBlockNIDs(stateBlockNIDs))
if err != nil {
- return nil, err
+ return nil, fmt.Errorf("v.db.StateEntries: %w", err)
}
stateBlockNIDsMap := stateBlockNIDListMap(stateBlockNIDLists)
stateEntriesMap := stateEntryListMap(stateEntryLists)
@@ -623,7 +623,7 @@ func (v StateResolution) calculateAndStoreStateAfterManyEvents(
v.calculateStateAfterManyEvents(ctx, v.roomInfo.RoomVersion, prevStates)
metrics.algorithm = algorithm
if err != nil {
- return metrics.stop(0, err)
+ return metrics.stop(0, fmt.Errorf("v.calculateStateAfterManyEvents: %w", err))
}
// TODO: Check if we can encode the new state as a delta against the
@@ -642,6 +642,7 @@ func (v StateResolution) calculateStateAfterManyEvents(
// First stage: load the state after each of the prev events.
combined, err = v.LoadCombinedStateAfterEvents(ctx, prevStates)
if err != nil {
+ err = fmt.Errorf("v.LoadCombinedStateAfterEvents: %w", err)
algorithm = "_load_combined_state"
return
}
@@ -672,6 +673,7 @@ func (v StateResolution) calculateStateAfterManyEvents(
var resolved []types.StateEntry
resolved, err = v.resolveConflicts(ctx, roomVersion, notConflicted, conflicts)
if err != nil {
+ err = fmt.Errorf("v.resolveConflits: %w", err)
algorithm = "_resolve_conflicts"
return
}
diff --git a/sytest-blacklist b/sytest-blacklist
index 2f80fc78..ff7fdf7e 100644
--- a/sytest-blacklist
+++ b/sytest-blacklist
@@ -52,4 +52,9 @@ Inbound federation accepts a second soft-failed event
Outbound federation requests missing prev_events and then asks for /state_ids and resolves the state
# We don't implement lazy membership loading yet.
-The only membership state included in a gapped incremental sync is for senders in the timeline \ No newline at end of file
+The only membership state included in a gapped incremental sync is for senders in the timeline
+
+# Blacklisted out of flakiness after #1479
+Invited user can reject local invite after originator leaves
+Invited user can reject invite for empty room
+If user leaves room, remote user changes device and rejoins we see update in /sync and /keys/changes \ No newline at end of file
diff --git a/sytest-whitelist b/sytest-whitelist
index a811259f..9a013cbf 100644
--- a/sytest-whitelist
+++ b/sytest-whitelist
@@ -400,8 +400,6 @@ Uninvited users cannot join the room
Users cannot invite themselves to a room
Users cannot invite a user that is already in the room
Invited user can reject invite
-Invited user can reject invite for empty room
-Invited user can reject local invite after originator leaves
PUT /rooms/:room_id/typing/:user_id sets typing notification
Typing notification sent to local room members
Typing notifications also sent to remote room members
@@ -431,7 +429,6 @@ A prev_batch token can be used in the v1 messages API
We don't send redundant membership state across incremental syncs by default
Typing notifications don't leak
Users cannot kick users from a room they are not in
-Users cannot kick users who have already left a room
User appears in user directory
User directory correctly update on display name change
User in shared private room does appear in user directory
@@ -451,7 +448,6 @@ Banned servers cannot backfill
Inbound /v1/send_leave rejects leaves from other servers
Guest users can accept invites to private rooms over federation
AS user (not ghost) can join room without registering
-If user leaves room, remote user changes device and rejoins we see update in /sync and /keys/changes
Can search public room list
Can get remote public room list
Asking for a remote rooms list, but supplying the local server's name, returns the local rooms list