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 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. // Ignore event that we don't need to send anywhere.
return nil return nil
} }

View file

@ -47,7 +47,12 @@ func SendEventWithState(
ctx context.Context, rsAPI RoomserverInternalAPI, state *gomatrixserverlib.RespState, ctx context.Context, rsAPI RoomserverInternalAPI, state *gomatrixserverlib.RespState,
event gomatrixserverlib.HeaderedEvent, haveEventIDs map[string]bool, event gomatrixserverlib.HeaderedEvent, haveEventIDs map[string]bool,
) error { ) 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 { if err != nil {
return err return err
} }
@ -55,36 +60,38 @@ func SendEventWithState(
var ires []InputRoomEvent var ires []InputRoomEvent
var stateIDs []string var stateIDs []string
for _, stateEvent := range stateEvents { for _, authOrStateEvent := range authAndStateEvents {
if stateEvent.StateKey() == nil { if authOrStateEvent.StateKey() == nil {
continue continue
} }
if haveEventIDs[stateEvent.EventID()] { if haveEventIDs[authOrStateEvent.EventID()] {
continue continue
} }
if stateEvent.Type() == event.Type() && *stateEvent.StateKey() == *event.StateKey() { if _, ok := isCurrentState[authOrStateEvent.EventID()]; !ok {
// If this event is an old state event that will be replaced by the // If this is an auth event rather than a current state event
// given event, then store it as an outlier instead. We don't want // then store it as an outlier. We won't include it in the
// to include it in the current room state as we will end up violating // current state set for the input event.
// 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.
ires = append(ires, InputRoomEvent{ ires = append(ires, InputRoomEvent{
Kind: KindOutlier, Kind: KindOutlier,
Event: stateEvent.Headered(event.RoomVersion), Event: authOrStateEvent.Headered(event.RoomVersion),
AuthEventIDs: stateEvent.AuthEventIDs(), AuthEventIDs: authOrStateEvent.AuthEventIDs(),
}) })
continue 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{ ires = append(ires, InputRoomEvent{
Kind: KindRewrite, Kind: KindRewrite,
Event: stateEvent.Headered(event.RoomVersion), Event: authOrStateEvent.Headered(event.RoomVersion),
AuthEventIDs: stateEvent.AuthEventIDs(), AuthEventIDs: authOrStateEvent.AuthEventIDs(),
HasState: true, HasState: true,
StateEventIDs: stateIDs, 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{ ires = append(ires, InputRoomEvent{
Kind: KindNew, Kind: KindNew,
Event: event, Event: event,

View file

@ -25,6 +25,7 @@ import (
"github.com/matrix-org/dendrite/internal/config" "github.com/matrix-org/dendrite/internal/config"
"github.com/matrix-org/dendrite/internal/eventutil" "github.com/matrix-org/dendrite/internal/eventutil"
"github.com/matrix-org/dendrite/roomserver/api" "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/helpers"
"github.com/matrix-org/dendrite/roomserver/internal/input" "github.com/matrix-org/dendrite/roomserver/internal/input"
"github.com/matrix-org/dendrite/roomserver/storage" "github.com/matrix-org/dendrite/roomserver/storage"
@ -334,6 +335,10 @@ func buildEvent(
return nil, nil, fmt.Errorf("QueryLatestEventsAndState: %w", err) 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) ev, err := eventutil.BuildEvent(ctx, builder, cfg, time.Now(), &eventsNeeded, &queryRes)
if err != nil { if err != nil {
return nil, nil, err 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( pduPos, err := s.db.WriteEvent(
ctx, ctx,
&ev, &ev,
@ -155,7 +150,7 @@ func (s *OutputRoomEventConsumer) onNewRoomEvent(
msg.AddsStateEventIDs, msg.AddsStateEventIDs,
msg.RemovesStateEventIDs, msg.RemovesStateEventIDs,
msg.TransactionID, msg.TransactionID,
false, msg.Type == api.OutputRoomState,
) )
if err != nil { if err != nil {
// panic rather than continue with an inconsistent database // panic rather than continue with an inconsistent database