Send auth events as outliers, state events as rewrite

This commit is contained in:
Neil Alexander 2020-09-09 17:30:15 +01:00
parent 5e5f18e64e
commit c85da93dfd
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
4 changed files with 29 additions and 22 deletions

View file

@ -139,7 +139,7 @@ func (s *OutputRoomEventConsumer) processMessage(ore api.OutputNewRoomEvent) err
return nil
}
if ore.SendAsServer == api.DoNotSendToOtherServers || ore.Type == api.OutputRoomState {
if ore.SendAsServer == api.DoNotSendToOtherServers {
// Ignore event that we don't need to send anywhere.
return nil
}

View file

@ -47,7 +47,12 @@ func SendEventWithState(
ctx context.Context, rsAPI RoomserverInternalAPI, state *gomatrixserverlib.RespState,
event gomatrixserverlib.HeaderedEvent, haveEventIDs map[string]bool,
) error {
stateEvents, err := state.Events()
isCurrentState := map[string]struct{}{}
for _, se := range state.StateEvents {
isCurrentState[se.EventID()] = struct{}{}
}
authAndStateEvents, err := state.Events()
if err != nil {
return err
}
@ -55,36 +60,38 @@ func SendEventWithState(
var ires []InputRoomEvent
var stateIDs []string
for _, stateEvent := range stateEvents {
if stateEvent.StateKey() == nil {
for _, authOrStateEvent := range authAndStateEvents {
if authOrStateEvent.StateKey() == nil {
continue
}
if haveEventIDs[stateEvent.EventID()] {
if haveEventIDs[authOrStateEvent.EventID()] {
continue
}
if stateEvent.Type() == event.Type() && *stateEvent.StateKey() == *event.StateKey() {
// If this event is an old state event that will be replaced by the
// given event, then store it as an outlier instead. We don't want
// to include it in the current room state as we will end up violating
// unique constraints in the state block, but we need the event to
// be stored as it may be referred to as an auth_event or prev_event.
if _, ok := isCurrentState[authOrStateEvent.EventID()]; !ok {
// If this is an auth event rather than a current state event
// then store it as an outlier. We won't include it in the
// current state set for the input event.
ires = append(ires, InputRoomEvent{
Kind: KindOutlier,
Event: stateEvent.Headered(event.RoomVersion),
AuthEventIDs: stateEvent.AuthEventIDs(),
Event: authOrStateEvent.Headered(event.RoomVersion),
AuthEventIDs: authOrStateEvent.AuthEventIDs(),
})
continue
}
// The event is a current state event. Send it as a rewrite
// event so that we generate a state output event for it.
ires = append(ires, InputRoomEvent{
Kind: KindRewrite,
Event: stateEvent.Headered(event.RoomVersion),
AuthEventIDs: stateEvent.AuthEventIDs(),
Event: authOrStateEvent.Headered(event.RoomVersion),
AuthEventIDs: authOrStateEvent.AuthEventIDs(),
HasState: true,
StateEventIDs: stateIDs,
})
stateIDs = append(stateIDs, stateEvent.EventID())
stateIDs = append(stateIDs, authOrStateEvent.EventID())
}
// Send the final event as a new event, which will generate
// a timeline output event for it.
ires = append(ires, InputRoomEvent{
Kind: KindNew,
Event: event,

View file

@ -25,6 +25,7 @@ import (
"github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/roomserver/api"
"github.com/matrix-org/dendrite/roomserver/auth"
"github.com/matrix-org/dendrite/roomserver/internal/helpers"
"github.com/matrix-org/dendrite/roomserver/internal/input"
"github.com/matrix-org/dendrite/roomserver/storage"
@ -334,6 +335,10 @@ func buildEvent(
return nil, nil, fmt.Errorf("QueryLatestEventsAndState: %w", err)
}
if !auth.IsAnyUserOnServerWithMembership(cfg.ServerName, gomatrixserverlib.UnwrapEventHeaders(queryRes.StateEvents), "join") {
return nil, nil, eventutil.ErrRoomNoExists
}
ev, err := eventutil.BuildEvent(ctx, builder, cfg, time.Now(), &eventsNeeded, &queryRes)
if err != nil {
return nil, nil, err

View file

@ -143,11 +143,6 @@ func (s *OutputRoomEventConsumer) onNewRoomEvent(
}
}
if msg.Type == api.OutputRoomState {
s.notifyKeyChanges(&ev)
return nil
}
pduPos, err := s.db.WriteEvent(
ctx,
&ev,
@ -155,7 +150,7 @@ func (s *OutputRoomEventConsumer) onNewRoomEvent(
msg.AddsStateEventIDs,
msg.RemovesStateEventIDs,
msg.TransactionID,
false,
msg.Type == api.OutputRoomState,
)
if err != nil {
// panic rather than continue with an inconsistent database