Resolve state after event against current room state when determining latest state changes

This commit is contained in:
Neil Alexander 2020-10-05 16:46:28 +01:00
parent 4e6b7f726d
commit 6ccfee63af
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
2 changed files with 25 additions and 6 deletions

View file

@ -215,10 +215,27 @@ func (u *latestEventsUpdater) latestState() error {
var err error var err error
roomState := state.NewStateResolution(u.api.DB, *u.roomInfo) roomState := state.NewStateResolution(u.api.DB, *u.roomInfo)
// Get a list of the current latest events. // Get a list of the current room state events if available.
latestStateAtEvents := make([]types.StateAtEvent, len(u.latest)) 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 { 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 // Takes the NIDs of the latest events and creates a state snapshot

View file

@ -118,7 +118,7 @@ func (v StateResolution) LoadCombinedStateAfterEvents(
// the snapshot of the room state before them was the same. // the snapshot of the room state before them was the same.
stateBlockNIDLists, err := v.db.StateBlockNIDs(ctx, uniqueStateSnapshotNIDs(stateNIDs)) stateBlockNIDLists, err := v.db.StateBlockNIDs(ctx, uniqueStateSnapshotNIDs(stateNIDs))
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("v.db.StateBlockNIDs: %w", err)
} }
var stateBlockNIDs []types.StateBlockNID var stateBlockNIDs []types.StateBlockNID
@ -131,7 +131,7 @@ func (v StateResolution) LoadCombinedStateAfterEvents(
// multiple snapshots. // multiple snapshots.
stateEntryLists, err := v.db.StateEntries(ctx, uniqueStateBlockNIDs(stateBlockNIDs)) stateEntryLists, err := v.db.StateEntries(ctx, uniqueStateBlockNIDs(stateBlockNIDs))
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("v.db.StateEntries: %w", err)
} }
stateBlockNIDsMap := stateBlockNIDListMap(stateBlockNIDLists) stateBlockNIDsMap := stateBlockNIDListMap(stateBlockNIDLists)
stateEntriesMap := stateEntryListMap(stateEntryLists) stateEntriesMap := stateEntryListMap(stateEntryLists)
@ -623,7 +623,7 @@ func (v StateResolution) calculateAndStoreStateAfterManyEvents(
v.calculateStateAfterManyEvents(ctx, v.roomInfo.RoomVersion, prevStates) v.calculateStateAfterManyEvents(ctx, v.roomInfo.RoomVersion, prevStates)
metrics.algorithm = algorithm metrics.algorithm = algorithm
if err != nil { 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 // 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. // First stage: load the state after each of the prev events.
combined, err = v.LoadCombinedStateAfterEvents(ctx, prevStates) combined, err = v.LoadCombinedStateAfterEvents(ctx, prevStates)
if err != nil { if err != nil {
err = fmt.Errorf("v.LoadCombinedStateAfterEvents: %w", err)
algorithm = "_load_combined_state" algorithm = "_load_combined_state"
return return
} }
@ -672,6 +673,7 @@ func (v StateResolution) calculateStateAfterManyEvents(
var resolved []types.StateEntry var resolved []types.StateEntry
resolved, err = v.resolveConflicts(ctx, roomVersion, notConflicted, conflicts) resolved, err = v.resolveConflicts(ctx, roomVersion, notConflicted, conflicts)
if err != nil { if err != nil {
err = fmt.Errorf("v.resolveConflits: %w", err)
algorithm = "_resolve_conflicts" algorithm = "_resolve_conflicts"
return return
} }