Skip to content
This repository has been archived by the owner on Nov 14, 2024. It is now read-only.

Commit

Permalink
Fix state resets (#3231)
Browse files Browse the repository at this point in the history
  • Loading branch information
S7evinK authored Oct 23, 2023
1 parent 8c23c11 commit 8b3adaf
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 6 deletions.
2 changes: 1 addition & 1 deletion clientapi/routing/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,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,
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (
github.com/matrix-org/dugong v0.0.0-20210921133753-66e6b1c67e2e
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91
github.com/matrix-org/gomatrix v0.0.0-20220926102614-ceba4d9f7530
github.com/matrix-org/gomatrixserverlib v0.0.0-20230926165653-79fcff283fc4
github.com/matrix-org/gomatrixserverlib v0.0.0-20231023121512-16e7431168be
github.com/matrix-org/pinecone v0.11.1-0.20230810010612-ea4c33717fd7
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66
github.com/mattn/go-sqlite3 v1.14.17
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91 h1:s7fexw
github.com/matrix-org/go-sqlite3-js v0.0.0-20220419092513-28aa791a1c91/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo=
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-20230926165653-79fcff283fc4 h1:UuXfC7b29RBDfMdLmggeF3opu3XuGi8bNT9SKZtZc3I=
github.com/matrix-org/gomatrixserverlib v0.0.0-20230926165653-79fcff283fc4/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/pinecone v0.11.1-0.20230810010612-ea4c33717fd7 h1:6t8kJr8i1/1I5nNttw6nn1ryQJgzVlBmSGgPiiaTdw4=
github.com/matrix-org/pinecone v0.11.1-0.20230810010612-ea4c33717fd7/go.mod h1:ReWMS/LoVnOiRAdq9sNUC2NZnd1mZkMNB52QhpTRWjg=
github.com/matrix-org/util v0.0.0-20221111132719-399730281e66 h1:6z4KxomXSIGWqhHcfzExgkH3Z3UkIXry4ibJS4Aqz2Y=
Expand Down
112 changes: 110 additions & 2 deletions roomserver/roomserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,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) {
Expand All @@ -424,7 +426,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)
}
Expand Down Expand Up @@ -1077,3 +1085,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)
}
}
})
}

0 comments on commit 8b3adaf

Please sign in to comment.