bugfix: Fix a bug which caused failures to join rooms over federation (#917)
* bugfix: Fix a bug which caused failures to join rooms over federation The cause of this was the semantics of `/send_join`'s `auth_chain` response. Previously, we would only send back the auth chain *for the join event* and not the entire room state. However, we would then try to check that the room state is valid, and then be missing auth events. Now, we send back the entire auth chain for all room state in `/send_join`. The spec needs to be clarified that this is what the chain should be. * refactor: split out grabbing state to reduce cyclo complexitymain
parent
4af8323df3
commit
1467cc10d8
|
@ -637,12 +637,6 @@ func (r *RoomserverQueryAPI) QueryStateAndAuthChain(
|
||||||
request *api.QueryStateAndAuthChainRequest,
|
request *api.QueryStateAndAuthChainRequest,
|
||||||
response *api.QueryStateAndAuthChainResponse,
|
response *api.QueryStateAndAuthChainResponse,
|
||||||
) error {
|
) error {
|
||||||
// TODO: get the correct room version
|
|
||||||
roomState, err := state.GetStateResolutionAlgorithm(state.StateResolutionAlgorithmV1, r.DB)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
response.QueryStateAndAuthChainRequest = *request
|
response.QueryStateAndAuthChainRequest = *request
|
||||||
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
roomNID, err := r.DB.RoomNID(ctx, request.RoomID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -653,31 +647,21 @@ func (r *RoomserverQueryAPI) QueryStateAndAuthChain(
|
||||||
}
|
}
|
||||||
response.RoomExists = true
|
response.RoomExists = true
|
||||||
|
|
||||||
prevStates, err := r.DB.StateAtEventIDs(ctx, request.PrevEventIDs)
|
stateEvents, err := r.loadStateAtEventIDs(ctx, request.PrevEventIDs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
switch err.(type) {
|
|
||||||
case types.MissingEventError:
|
|
||||||
return nil
|
|
||||||
default:
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
response.PrevEventsExist = true
|
response.PrevEventsExist = true
|
||||||
|
|
||||||
// Look up the currrent state for the requested tuples.
|
// add the auth event IDs for the current state events too
|
||||||
stateEntries, err := roomState.LoadCombinedStateAfterEvents(
|
var authEventIDs []string
|
||||||
ctx, prevStates,
|
authEventIDs = append(authEventIDs, request.AuthEventIDs...)
|
||||||
)
|
for _, se := range stateEvents {
|
||||||
if err != nil {
|
authEventIDs = append(authEventIDs, se.AuthEventIDs()...)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
authEventIDs = util.UniqueStrings(authEventIDs) // de-dupe
|
||||||
|
|
||||||
stateEvents, err := r.loadStateEvents(ctx, stateEntries)
|
authEvents, err := getAuthChain(ctx, r.DB, authEventIDs)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
authEvents, err := getAuthChain(ctx, r.DB, request.AuthEventIDs)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -699,6 +683,34 @@ func (r *RoomserverQueryAPI) QueryStateAndAuthChain(
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *RoomserverQueryAPI) loadStateAtEventIDs(ctx context.Context, eventIDs []string) ([]gomatrixserverlib.Event, error) {
|
||||||
|
// TODO: get the correct room version
|
||||||
|
roomState, err := state.GetStateResolutionAlgorithm(state.StateResolutionAlgorithmV1, r.DB)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
prevStates, err := r.DB.StateAtEventIDs(ctx, eventIDs)
|
||||||
|
if err != nil {
|
||||||
|
switch err.(type) {
|
||||||
|
case types.MissingEventError:
|
||||||
|
return nil, nil
|
||||||
|
default:
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Look up the currrent state for the requested tuples.
|
||||||
|
stateEntries, err := roomState.LoadCombinedStateAfterEvents(
|
||||||
|
ctx, prevStates,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.loadStateEvents(ctx, stateEntries)
|
||||||
|
}
|
||||||
|
|
||||||
// getAuthChain fetches the auth chain for the given auth events. An auth chain
|
// getAuthChain fetches the auth chain for the given auth events. An auth chain
|
||||||
// is the list of all events that are referenced in the auth_events section, and
|
// is the list of all events that are referenced in the auth_events section, and
|
||||||
// all their auth_events, recursively. The returned set of events contain the
|
// all their auth_events, recursively. The returned set of events contain the
|
||||||
|
|
Loading…
Reference in New Issue