mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-17 03:43:11 -06:00
Try to use room version to get correct state resolution algorithm
This commit is contained in:
parent
6654b86b0b
commit
92ed93db38
|
|
@ -156,11 +156,8 @@ func calculateAndSetState(
|
||||||
stateAtEvent *types.StateAtEvent,
|
stateAtEvent *types.StateAtEvent,
|
||||||
event gomatrixserverlib.Event,
|
event gomatrixserverlib.Event,
|
||||||
) error {
|
) error {
|
||||||
// TODO: get the correct room version
|
var err error
|
||||||
roomState, err := state.Prepare(db, gomatrixserverlib.RoomVersionV1)
|
roomState := state.Prepare(db)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.HasState {
|
if input.HasState {
|
||||||
// We've been told what the state at the event is so we don't need to calculate it.
|
// We've been told what the state at the event is so we don't need to calculate it.
|
||||||
|
|
|
||||||
|
|
@ -178,11 +178,7 @@ func (u *latestEventsUpdater) doUpdateLatestEvents() error {
|
||||||
|
|
||||||
func (u *latestEventsUpdater) latestState() error {
|
func (u *latestEventsUpdater) latestState() error {
|
||||||
var err error
|
var err error
|
||||||
// TODO: get the correct room version
|
roomState := state.Prepare(u.db)
|
||||||
roomState, err := state.Prepare(u.db, gomatrixserverlib.RoomVersionV1)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
latestStateAtEvents := make([]types.StateAtEvent, len(u.latest))
|
latestStateAtEvents := make([]types.StateAtEvent, len(u.latest))
|
||||||
for i := range u.latest {
|
for i := range u.latest {
|
||||||
|
|
|
||||||
|
|
@ -111,10 +111,7 @@ func (r *RoomserverQueryAPI) QueryLatestEventsAndState(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
roomState, err := state.Prepare(r.DB, roomVersion)
|
roomState := state.Prepare(r.DB)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
response.QueryLatestEventsAndStateRequest = *request
|
response.QueryLatestEventsAndStateRequest = *request
|
||||||
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
||||||
|
|
@ -164,10 +161,7 @@ func (r *RoomserverQueryAPI) QueryStateAfterEvents(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
roomState, err := state.Prepare(r.DB, roomVersion)
|
roomState := state.Prepare(r.DB)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
response.QueryStateAfterEventsRequest = *request
|
response.QueryStateAfterEventsRequest = *request
|
||||||
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
||||||
|
|
@ -192,7 +186,7 @@ func (r *RoomserverQueryAPI) QueryStateAfterEvents(
|
||||||
|
|
||||||
// Look up the currrent state for the requested tuples.
|
// Look up the currrent state for the requested tuples.
|
||||||
stateEntries, err := roomState.LoadStateAfterEventsForStringTuples(
|
stateEntries, err := roomState.LoadStateAfterEventsForStringTuples(
|
||||||
ctx, prevStates, request.StateToFetch,
|
ctx, roomNID, prevStates, request.StateToFetch,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -358,11 +352,7 @@ func (r *RoomserverQueryAPI) QueryMembershipsForRoom(
|
||||||
func (r *RoomserverQueryAPI) getMembershipsBeforeEventNID(
|
func (r *RoomserverQueryAPI) getMembershipsBeforeEventNID(
|
||||||
ctx context.Context, eventNID types.EventNID, joinedOnly bool,
|
ctx context.Context, eventNID types.EventNID, joinedOnly bool,
|
||||||
) ([]types.Event, error) {
|
) ([]types.Event, error) {
|
||||||
// TODO: get the correct room version
|
roomState := state.Prepare(r.DB)
|
||||||
roomState, err := state.Prepare(r.DB, gomatrixserverlib.RoomVersionV1)
|
|
||||||
if err != nil {
|
|
||||||
return []types.Event{}, err
|
|
||||||
}
|
|
||||||
events := []types.Event{}
|
events := []types.Event{}
|
||||||
// Lookup the event NID
|
// Lookup the event NID
|
||||||
eIDs, err := r.DB.EventIDs(ctx, []types.EventNID{eventNID})
|
eIDs, err := r.DB.EventIDs(ctx, []types.EventNID{eventNID})
|
||||||
|
|
@ -464,12 +454,7 @@ func (r *RoomserverQueryAPI) QueryServerAllowedToSeeEvent(
|
||||||
func (r *RoomserverQueryAPI) checkServerAllowedToSeeEvent(
|
func (r *RoomserverQueryAPI) checkServerAllowedToSeeEvent(
|
||||||
ctx context.Context, eventID string, serverName gomatrixserverlib.ServerName,
|
ctx context.Context, eventID string, serverName gomatrixserverlib.ServerName,
|
||||||
) (bool, error) {
|
) (bool, error) {
|
||||||
// TODO: get the correct room version
|
roomState := state.Prepare(r.DB)
|
||||||
roomState, err := state.Prepare(r.DB, gomatrixserverlib.RoomVersionV1)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
stateEntries, err := roomState.LoadStateAtEvent(ctx, eventID)
|
stateEntries, err := roomState.LoadStateAtEvent(ctx, eventID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|
@ -689,12 +674,7 @@ func (r *RoomserverQueryAPI) QueryStateAndAuthChain(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RoomserverQueryAPI) loadStateAtEventIDs(ctx context.Context, eventIDs []string) ([]gomatrixserverlib.Event, error) {
|
func (r *RoomserverQueryAPI) loadStateAtEventIDs(ctx context.Context, eventIDs []string) ([]gomatrixserverlib.Event, error) {
|
||||||
// TODO: get the correct room version
|
roomState := state.Prepare(r.DB)
|
||||||
roomState, err := state.Prepare(r.DB, gomatrixserverlib.RoomVersionV1)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
prevStates, err := r.DB.StateAtEventIDs(ctx, eventIDs)
|
prevStates, err := r.DB.StateAtEventIDs(ctx, eventIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/matrix-org/dendrite/roomserver/types"
|
"github.com/matrix-org/dendrite/roomserver/types"
|
||||||
|
"github.com/matrix-org/gomatrixserverlib"
|
||||||
)
|
)
|
||||||
|
|
||||||
// A RoomStateDatabase has the storage APIs needed to load state from the database
|
// A RoomStateDatabase has the storage APIs needed to load state from the database
|
||||||
|
|
@ -61,4 +62,6 @@ type RoomStateDatabase interface {
|
||||||
Events(ctx context.Context, eventNIDs []types.EventNID) ([]types.Event, error)
|
Events(ctx context.Context, eventNIDs []types.EventNID) ([]types.Event, error)
|
||||||
// Look up snapshot NID for an event ID string
|
// Look up snapshot NID for an event ID string
|
||||||
SnapshotNIDFromEventID(ctx context.Context, eventID string) (types.StateSnapshotNID, error)
|
SnapshotNIDFromEventID(ctx context.Context, eventID string) (types.StateSnapshotNID, error)
|
||||||
|
// Look up a room version from the room NID.
|
||||||
|
GetRoomVersionForRoomNID(ctx context.Context, roomNID types.RoomNID) (gomatrixserverlib.RoomVersion, error)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -33,25 +33,11 @@ import (
|
||||||
|
|
||||||
type StateResolution struct {
|
type StateResolution struct {
|
||||||
db database.RoomStateDatabase
|
db database.RoomStateDatabase
|
||||||
version gomatrixserverlib.RoomVersion
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func Prepare(db database.RoomStateDatabase, version gomatrixserverlib.RoomVersion) (StateResolution, error) {
|
func Prepare(db database.RoomStateDatabase) StateResolution {
|
||||||
stateResAlgo, err := version.StateResAlgorithm()
|
|
||||||
if err != nil {
|
|
||||||
return StateResolution{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch stateResAlgo {
|
|
||||||
case gomatrixserverlib.StateResV1:
|
|
||||||
fallthrough
|
|
||||||
case gomatrixserverlib.StateResV2:
|
|
||||||
return StateResolution{
|
return StateResolution{
|
||||||
db: db,
|
db: db,
|
||||||
version: version,
|
|
||||||
}, nil
|
|
||||||
default:
|
|
||||||
return StateResolution{}, errors.New("unsupported state resolution algorithm")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -350,7 +336,7 @@ func (v StateResolution) loadStateAtSnapshotForNumericTuples(
|
||||||
// This is typically the state before an event.
|
// This is typically the state before an event.
|
||||||
// Returns a sorted list of state entries or an error if there was a problem talking to the database.
|
// Returns a sorted list of state entries or an error if there was a problem talking to the database.
|
||||||
func (v StateResolution) LoadStateAfterEventsForStringTuples(
|
func (v StateResolution) LoadStateAfterEventsForStringTuples(
|
||||||
ctx context.Context,
|
ctx context.Context, roomNID types.RoomNID,
|
||||||
prevStates []types.StateAtEvent,
|
prevStates []types.StateAtEvent,
|
||||||
stateKeyTuples []gomatrixserverlib.StateKeyTuple,
|
stateKeyTuples []gomatrixserverlib.StateKeyTuple,
|
||||||
) ([]types.StateEntry, error) {
|
) ([]types.StateEntry, error) {
|
||||||
|
|
@ -358,14 +344,19 @@ func (v StateResolution) LoadStateAfterEventsForStringTuples(
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return v.loadStateAfterEventsForNumericTuples(ctx, prevStates, numericTuples)
|
return v.loadStateAfterEventsForNumericTuples(ctx, roomNID, prevStates, numericTuples)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v StateResolution) loadStateAfterEventsForNumericTuples(
|
func (v StateResolution) loadStateAfterEventsForNumericTuples(
|
||||||
ctx context.Context,
|
ctx context.Context, roomNID types.RoomNID,
|
||||||
prevStates []types.StateAtEvent,
|
prevStates []types.StateAtEvent,
|
||||||
stateKeyTuples []types.StateKeyTuple,
|
stateKeyTuples []types.StateKeyTuple,
|
||||||
) ([]types.StateEntry, error) {
|
) ([]types.StateEntry, error) {
|
||||||
|
roomVersion, err := v.db.GetRoomVersionForRoomNID(ctx, roomNID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
if len(prevStates) == 1 {
|
if len(prevStates) == 1 {
|
||||||
// Fast path for a single event.
|
// Fast path for a single event.
|
||||||
prevState := prevStates[0]
|
prevState := prevStates[0]
|
||||||
|
|
@ -408,7 +399,7 @@ func (v StateResolution) loadStateAfterEventsForNumericTuples(
|
||||||
|
|
||||||
// TODO: Add metrics for this as it could take a long time for big rooms
|
// TODO: Add metrics for this as it could take a long time for big rooms
|
||||||
// with large conflicts.
|
// with large conflicts.
|
||||||
fullState, _, _, err := v.calculateStateAfterManyEvents(ctx, prevStates)
|
fullState, _, _, err := v.calculateStateAfterManyEvents(ctx, roomVersion, prevStates)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -617,9 +608,13 @@ func (v StateResolution) calculateAndStoreStateAfterManyEvents(
|
||||||
prevStates []types.StateAtEvent,
|
prevStates []types.StateAtEvent,
|
||||||
metrics calculateStateMetrics,
|
metrics calculateStateMetrics,
|
||||||
) (types.StateSnapshotNID, error) {
|
) (types.StateSnapshotNID, error) {
|
||||||
|
roomVersion, err := v.db.GetRoomVersionForRoomNID(ctx, roomNID)
|
||||||
|
if err != nil {
|
||||||
|
return metrics.stop(0, err)
|
||||||
|
}
|
||||||
|
|
||||||
state, algorithm, conflictLength, err :=
|
state, algorithm, conflictLength, err :=
|
||||||
v.calculateStateAfterManyEvents(ctx, prevStates)
|
v.calculateStateAfterManyEvents(ctx, roomVersion, prevStates)
|
||||||
metrics.algorithm = algorithm
|
metrics.algorithm = algorithm
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return metrics.stop(0, err)
|
return metrics.stop(0, err)
|
||||||
|
|
@ -633,7 +628,8 @@ func (v StateResolution) calculateAndStoreStateAfterManyEvents(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v StateResolution) calculateStateAfterManyEvents(
|
func (v StateResolution) calculateStateAfterManyEvents(
|
||||||
ctx context.Context, prevStates []types.StateAtEvent,
|
ctx context.Context, roomVersion gomatrixserverlib.RoomVersion,
|
||||||
|
prevStates []types.StateAtEvent,
|
||||||
) (state []types.StateEntry, algorithm string, conflictLength int, err error) {
|
) (state []types.StateEntry, algorithm string, conflictLength int, err error) {
|
||||||
var combined []types.StateEntry
|
var combined []types.StateEntry
|
||||||
// Conflict resolution.
|
// Conflict resolution.
|
||||||
|
|
@ -668,7 +664,7 @@ func (v StateResolution) calculateStateAfterManyEvents(
|
||||||
}
|
}
|
||||||
|
|
||||||
var resolved []types.StateEntry
|
var resolved []types.StateEntry
|
||||||
resolved, err = v.resolveConflicts(ctx, notConflicted, conflicts)
|
resolved, err = v.resolveConflicts(ctx, roomVersion, notConflicted, conflicts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
algorithm = "_resolve_conflicts"
|
algorithm = "_resolve_conflicts"
|
||||||
return
|
return
|
||||||
|
|
@ -684,10 +680,10 @@ func (v StateResolution) calculateStateAfterManyEvents(
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v StateResolution) resolveConflicts(
|
func (v StateResolution) resolveConflicts(
|
||||||
ctx context.Context,
|
ctx context.Context, version gomatrixserverlib.RoomVersion,
|
||||||
notConflicted, conflicted []types.StateEntry,
|
notConflicted, conflicted []types.StateEntry,
|
||||||
) ([]types.StateEntry, error) {
|
) ([]types.StateEntry, error) {
|
||||||
stateResAlgo, err := v.version.StateResAlgorithm()
|
stateResAlgo, err := version.StateResAlgorithm()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -46,5 +46,4 @@ type Database interface {
|
||||||
GetMembershipEventNIDsForRoom(ctx context.Context, roomNID types.RoomNID, joinOnly bool) ([]types.EventNID, error)
|
GetMembershipEventNIDsForRoom(ctx context.Context, roomNID types.RoomNID, joinOnly bool) ([]types.EventNID, error)
|
||||||
EventsFromIDs(ctx context.Context, eventIDs []string) ([]types.Event, error)
|
EventsFromIDs(ctx context.Context, eventIDs []string) ([]types.Event, error)
|
||||||
GetRoomVersionForRoom(ctx context.Context, roomID string) (gomatrixserverlib.RoomVersion, error)
|
GetRoomVersionForRoom(ctx context.Context, roomID string) (gomatrixserverlib.RoomVersion, error)
|
||||||
GetRoomVersionForRoomNID(ctx context.Context, roomNID types.RoomNID) (gomatrixserverlib.RoomVersion, error)
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue