mirror of
https://github.com/hoernschen/dendrite.git
synced 2025-07-29 04:32:47 +00:00
Federation for v3/v4 rooms (#954)
* Update gomatrixserverlib * Default to room version 4 * Update gomatrixserverlib * Limit prev_events and auth_events * Fix auth_events, prev_events * Fix linter issues * Update gomatrixserverlib * Fix getState * Update sytest-whitelist * Squashed commit of the following: commit067b875063
Author: Neil Alexander <neilalexander@users.noreply.github.com> Date: Fri Apr 3 14:29:06 2020 +0100 Invites v2 endpoint (#952) * Start converting v1 invite endpoint to v2 * Update gomatrixserverlib * Early federationsender code for sending invites * Sending invites sorta happens now * Populate invite request with stripped state * Remodel a bit, don't reflect received invites * Handle invite_room_state * Handle room versions a bit better * Update gomatrixserverlib * Tweak order in destinationQueue.next * Revert check in processMessage * Tweak federation sender destination queue code a bit * Add comments commit955244c092
Author: Ben B <benne@klimlive.de> Date: Fri Apr 3 12:40:50 2020 +0200 use custom http client instead of the http DefaultClient (#823) This commit replaces the default client from the http lib with a custom one. The previously used default client doesn't come with a timeout. This could cause unwanted locks. That solution chosen here creates a http client in the base component dendrite with a constant timeout of 30 seconds. If it should be necessary to overwrite this, we could include the timeout in the dendrite configuration. Here it would be a good idea to extend the type "Address" by a timeout and create an http client for each service. Closes #820 Signed-off-by: Benedikt Bongartz <benne@klimlive.de> Co-authored-by: Kegsay <kegan@matrix.org> * Update sytest-whitelist, sytest-blacklist * Update go.mod/go.sum * Add some error wrapping for debug * Add a NOTSPEC to common/events.go * Perform state resolution at send_join * Set default room version to v2 again * Tweak GetCapabilities * Add comments to ResolveConflictsAdhoc * Update sytest-blacklist * go mod tidy * Update sytest-whitelist, sytest-blacklist * Update versions * Updates from review comments * Update sytest-blacklist, sytest-whitelist * Check room versions compatible at make_join, add some comments, update gomatrixserverlib, other tweaks * Set default room version back to v2 * Update gomatrixserverlib, sytest-whitelist
This commit is contained in:
parent
067b875063
commit
dacee648f7
14 changed files with 235 additions and 55 deletions
|
@ -203,6 +203,9 @@ type QueryStateAndAuthChainRequest struct {
|
|||
PrevEventIDs []string `json:"prev_event_ids"`
|
||||
// The list of auth events for the event. Used to calculate the auth chain
|
||||
AuthEventIDs []string `json:"auth_event_ids"`
|
||||
// Should state resolution be ran on the result events?
|
||||
// TODO: check call sites and remove if we always want to do state res
|
||||
ResolveState bool `json:"resolve_state"`
|
||||
}
|
||||
|
||||
// QueryStateAndAuthChainResponse is a response to QueryStateAndAuthChain
|
||||
|
|
|
@ -132,7 +132,7 @@ func (r *RoomserverQueryAPI) QueryLatestEventsAndState(
|
|||
return err
|
||||
}
|
||||
|
||||
// Look up the currrent state for the requested tuples.
|
||||
// Look up the current state for the requested tuples.
|
||||
stateEntries, err := roomState.LoadStateAtSnapshotForStringTuples(
|
||||
ctx, currentStateSnapshotNID, request.StateToFetch,
|
||||
)
|
||||
|
@ -736,6 +736,14 @@ func (r *RoomserverQueryAPI) QueryStateAndAuthChain(
|
|||
return err
|
||||
}
|
||||
|
||||
if request.ResolveState {
|
||||
if stateEvents, err = state.ResolveConflictsAdhoc(
|
||||
roomVersion, stateEvents, authEvents,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, event := range stateEvents {
|
||||
response.StateEvents = append(response.StateEvents, event.Headered(roomVersion))
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package state
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
|
@ -681,6 +680,83 @@ func (v StateResolution) calculateStateAfterManyEvents(
|
|||
return
|
||||
}
|
||||
|
||||
// ResolveConflictsAdhoc is a helper function to assist the query API in
|
||||
// performing state resolution when requested. This is a different code
|
||||
// path to the rest of state.go because this assumes you already have
|
||||
// gomatrixserverlib.Event objects and not just a bunch of NIDs like
|
||||
// elsewhere in the state resolution.
|
||||
// TODO: Some of this can possibly be deduplicated
|
||||
func ResolveConflictsAdhoc(
|
||||
version gomatrixserverlib.RoomVersion,
|
||||
events []gomatrixserverlib.Event,
|
||||
authEvents []gomatrixserverlib.Event,
|
||||
) ([]gomatrixserverlib.Event, error) {
|
||||
type stateKeyTuple struct {
|
||||
Type string
|
||||
StateKey string
|
||||
}
|
||||
|
||||
// Prepare our data structures.
|
||||
eventMap := make(map[stateKeyTuple][]gomatrixserverlib.Event)
|
||||
var conflicted, notConflicted, resolved []gomatrixserverlib.Event
|
||||
|
||||
// Run through all of the events that we were given and sort them
|
||||
// into a map, sorted by (event_type, state_key) tuple. This means
|
||||
// that we can easily spot events that are "conflicted", e.g.
|
||||
// there are duplicate values for the same tuple key.
|
||||
for _, event := range events {
|
||||
if event.StateKey() == nil {
|
||||
// Ignore events that are not state events.
|
||||
continue
|
||||
}
|
||||
// Append the events if there is already a conflicted list for
|
||||
// this tuple key, create it if not.
|
||||
tuple := stateKeyTuple{event.Type(), *event.StateKey()}
|
||||
if _, ok := eventMap[tuple]; ok {
|
||||
eventMap[tuple] = append(eventMap[tuple], event)
|
||||
} else {
|
||||
eventMap[tuple] = []gomatrixserverlib.Event{event}
|
||||
}
|
||||
}
|
||||
|
||||
// Split out the events in the map into conflicted and unconflicted
|
||||
// buckets. The conflicted events will be ran through state res,
|
||||
// whereas unconfliced events will always going to appear in the
|
||||
// final resolved state.
|
||||
for _, list := range eventMap {
|
||||
if len(list) > 1 {
|
||||
conflicted = append(conflicted, list...)
|
||||
} else {
|
||||
notConflicted = append(notConflicted, list...)
|
||||
}
|
||||
}
|
||||
|
||||
// Work out which state resolution algorithm we want to run for
|
||||
// the room version.
|
||||
stateResAlgo, err := version.StateResAlgorithm()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
switch stateResAlgo {
|
||||
case gomatrixserverlib.StateResV1:
|
||||
// Currently state res v1 doesn't handle unconflicted events
|
||||
// for us, like state res v2 does, so we will need to add the
|
||||
// unconflicted events into the state ourselves.
|
||||
// TODO: Fix state res v1 so this is handled for the caller.
|
||||
resolved = gomatrixserverlib.ResolveStateConflicts(conflicted, authEvents)
|
||||
resolved = append(resolved, notConflicted...)
|
||||
case gomatrixserverlib.StateResV2:
|
||||
// TODO: auth difference here?
|
||||
resolved = gomatrixserverlib.ResolveStateConflictsV2(conflicted, notConflicted, authEvents, authEvents)
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported state resolution algorithm %v", stateResAlgo)
|
||||
}
|
||||
|
||||
// Return the final resolved state events, including both the
|
||||
// resolved set of conflicted events, and the unconflicted events.
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
func (v StateResolution) resolveConflicts(
|
||||
ctx context.Context, version gomatrixserverlib.RoomVersion,
|
||||
notConflicted, conflicted []types.StateEntry,
|
||||
|
@ -695,7 +771,7 @@ func (v StateResolution) resolveConflicts(
|
|||
case gomatrixserverlib.StateResV2:
|
||||
return v.resolveConflictsV2(ctx, notConflicted, conflicted)
|
||||
}
|
||||
return nil, errors.New("unsupported state resolution algorithm")
|
||||
return nil, fmt.Errorf("unsupported state resolution algorithm %v", stateResAlgo)
|
||||
}
|
||||
|
||||
// resolveConflicts resolves a list of conflicted state entries. It takes two lists.
|
||||
|
|
|
@ -43,12 +43,12 @@ var roomVersions = map[gomatrixserverlib.RoomVersion]RoomVersionDescription{
|
|||
Stable: true,
|
||||
},
|
||||
gomatrixserverlib.RoomVersionV3: RoomVersionDescription{
|
||||
Supported: false,
|
||||
Stable: false,
|
||||
Supported: true,
|
||||
Stable: true,
|
||||
},
|
||||
gomatrixserverlib.RoomVersionV4: RoomVersionDescription{
|
||||
Supported: false,
|
||||
Stable: false,
|
||||
Supported: true,
|
||||
Stable: true,
|
||||
},
|
||||
gomatrixserverlib.RoomVersionV5: RoomVersionDescription{
|
||||
Supported: false,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue