mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-06 22:43:10 -06:00
Fix state resets (#3231)
Needs https://github.com/matrix-org/gomatrixserverlib/pull/419 May fix: https://github.com/matrix-org/dendrite/issues/2508, https://github.com/matrix-org/dendrite/issues/1760
This commit is contained in:
parent
e73a37a6a9
commit
96e67a7836
|
|
@ -290,7 +290,7 @@ func updateProfile(
|
|||
}, e
|
||||
}
|
||||
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, events, device.UserDomain(), domain, domain, nil, true); err != nil {
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, events, device.UserDomain(), domain, domain, nil, false); err != nil {
|
||||
util.GetLogger(ctx).WithError(err).Error("SendEvents failed")
|
||||
return util.JSONResponse{
|
||||
Code: http.StatusInternalServerError,
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -19,7 +19,7 @@ require (
|
|||
github.com/lib/pq v1.10.9
|
||||
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e
|
||||
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20230628151943-f6e3c7f7b093
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20231023121512-16e7431168be
|
||||
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66
|
||||
github.com/mattn/go-sqlite3 v1.14.17
|
||||
github.com/nats-io/nats-server/v2 v2.9.19
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -184,8 +184,8 @@ github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e h1:DP5RC0Z3XdyBE
|
|||
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e/go.mod h1:NgPCr+UavRGH6n5jmdX8DuqFZ4JiCWIJoZiuhTRLSUg=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530 h1:kHKxCOLcHH8r4Fzarl4+Y3K5hjothkVW5z7T1dUM11U=
|
||||
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530/go.mod h1:/gBX06Kw0exX1HrwmoBibFA98yBk/jxKpGVeyQbff+s=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20230628151943-f6e3c7f7b093 h1:FHd3SYhU2ZxZhkssZ/7ms5+M2j+g94lYp8ztvA1E6tA=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20230628151943-f6e3c7f7b093/go.mod h1:H9V9N3Uqn1bBJqYJNGK1noqtgJTaCEhtTdcH/mp50uU=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20231023121512-16e7431168be h1:bZP16ydP8uRoRBo1p/7WHMexjg7JJGj81fKzZ1FULb4=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20231023121512-16e7431168be/go.mod h1:M8m7seOroO5ePlgxA7AFZymnG90Cnh94rYQyngSrZkk=
|
||||
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y=
|
||||
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66/go.mod h1:iBI1foelCqA09JJgPV0FYz4qA5dUXYOxMi57FxKBdd4=
|
||||
github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE=
|
||||
|
|
|
|||
|
|
@ -404,7 +404,9 @@ type fledglingEvent struct {
|
|||
RoomID string
|
||||
Redacts string
|
||||
Depth int64
|
||||
PrevEvents []interface{}
|
||||
PrevEvents []any
|
||||
AuthEvents []any
|
||||
Content map[string]any
|
||||
}
|
||||
|
||||
func mustCreateEvent(t *testing.T, ev fledglingEvent) (result *types.HeaderedEvent) {
|
||||
|
|
@ -421,7 +423,13 @@ func mustCreateEvent(t *testing.T, ev fledglingEvent) (result *types.HeaderedEve
|
|||
Depth: ev.Depth,
|
||||
PrevEvents: ev.PrevEvents,
|
||||
})
|
||||
err := eb.SetContent(map[string]interface{}{})
|
||||
if ev.Content == nil {
|
||||
ev.Content = map[string]any{}
|
||||
}
|
||||
if ev.AuthEvents != nil {
|
||||
eb.AuthEvents = ev.AuthEvents
|
||||
}
|
||||
err := eb.SetContent(ev.Content)
|
||||
if err != nil {
|
||||
t.Fatalf("mustCreateEvent: failed to marshal event content %v", err)
|
||||
}
|
||||
|
|
@ -1071,3 +1079,103 @@ func TestUpgrade(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestStateReset(t *testing.T) {
|
||||
alice := test.NewUser(t)
|
||||
bob := test.NewUser(t)
|
||||
charlie := test.NewUser(t)
|
||||
ctx := context.Background()
|
||||
|
||||
test.WithAllDatabases(t, func(t *testing.T, dbType test.DBType) {
|
||||
// Prepare APIs
|
||||
cfg, processCtx, close := testrig.CreateConfig(t, dbType)
|
||||
defer close()
|
||||
|
||||
cm := sqlutil.NewConnectionManager(processCtx, cfg.Global.DatabaseOptions)
|
||||
natsInstance := jetstream.NATSInstance{}
|
||||
caches := caching.NewRistrettoCache(128*1024*1024, time.Hour, caching.DisableMetrics)
|
||||
rsAPI := roomserver.NewInternalAPI(processCtx, cfg, cm, &natsInstance, caches, caching.DisableMetrics)
|
||||
rsAPI.SetFederationAPI(nil, nil)
|
||||
|
||||
// create a new room
|
||||
room := test.NewRoom(t, alice, test.RoomPreset(test.PresetPublicChat))
|
||||
|
||||
// join with Bob and Charlie
|
||||
bobJoinEv := room.CreateAndInsert(t, bob, spec.MRoomMember, map[string]any{"membership": "join"}, test.WithStateKey(bob.ID))
|
||||
charlieJoinEv := room.CreateAndInsert(t, charlie, spec.MRoomMember, map[string]any{"membership": "join"}, test.WithStateKey(charlie.ID))
|
||||
|
||||
// Send and create the room
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, room.Events(), "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
|
||||
// send a message
|
||||
bobMsg := room.CreateAndInsert(t, bob, "m.room.message", map[string]any{"body": "hello world"})
|
||||
charlieMsg := room.CreateAndInsert(t, charlie, "m.room.message", map[string]any{"body": "hello world"})
|
||||
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, []*types.HeaderedEvent{bobMsg, charlieMsg}, "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
|
||||
// Bob changes his name
|
||||
expectedDisplayname := "Bob!"
|
||||
bobDisplayname := room.CreateAndInsert(t, bob, spec.MRoomMember, map[string]any{"membership": "join", "displayname": expectedDisplayname}, test.WithStateKey(bob.ID))
|
||||
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, []*types.HeaderedEvent{bobDisplayname}, "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
|
||||
// Change another state event
|
||||
jrEv := room.CreateAndInsert(t, alice, spec.MRoomJoinRules, gomatrixserverlib.JoinRuleContent{JoinRule: "invite"}, test.WithStateKey(""))
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, []*types.HeaderedEvent{jrEv}, "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
|
||||
// send a message
|
||||
bobMsg = room.CreateAndInsert(t, bob, "m.room.message", map[string]any{"body": "hello world"})
|
||||
charlieMsg = room.CreateAndInsert(t, charlie, "m.room.message", map[string]any{"body": "hello world"})
|
||||
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, []*types.HeaderedEvent{bobMsg, charlieMsg}, "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
|
||||
// Craft the state reset message, which is using Bobs initial join event and the
|
||||
// last message Charlie sent as the prev_events. This should trigger the recalculation
|
||||
// of the "current" state, since the message event does not have state and no missing events in the DB.
|
||||
stateResetMsg := mustCreateEvent(t, fledglingEvent{
|
||||
Type: "m.room.message",
|
||||
SenderID: charlie.ID,
|
||||
RoomID: room.ID,
|
||||
Depth: charlieMsg.Depth() + 1,
|
||||
PrevEvents: []any{
|
||||
bobJoinEv.EventID(),
|
||||
charlieMsg.EventID(),
|
||||
},
|
||||
AuthEvents: []any{
|
||||
room.Events()[0].EventID(), // create event
|
||||
room.Events()[2].EventID(), // PL event
|
||||
charlieJoinEv.EventID(), // Charlie join event
|
||||
},
|
||||
})
|
||||
|
||||
// Send the state reset message
|
||||
if err := api.SendEvents(ctx, rsAPI, api.KindNew, []*types.HeaderedEvent{stateResetMsg}, "test", "test", "test", nil, false); err != nil {
|
||||
t.Errorf("failed to send events: %v", err)
|
||||
}
|
||||
|
||||
// Validate that there is a membership event for Bob
|
||||
bobMembershipEv := api.GetStateEvent(ctx, rsAPI, room.ID, gomatrixserverlib.StateKeyTuple{
|
||||
EventType: spec.MRoomMember,
|
||||
StateKey: bob.ID,
|
||||
})
|
||||
|
||||
if bobMembershipEv == nil {
|
||||
t.Fatalf("Membership event for Bob does not exist. State reset?")
|
||||
} else {
|
||||
// Validate it's the correct membership event
|
||||
if dn := gjson.GetBytes(bobMembershipEv.Content(), "displayname").Str; dn != expectedDisplayname {
|
||||
t.Fatalf("Expected displayname to be %q, got %q", expectedDisplayname, dn)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue