Skip to content

Commit e86ab16

Browse files
Performance and bug-fix backports (#443)
This contains various backports from Harmony: * Reduced allocations and performance improvements in state resolution * Reduced allocations and performance improvements in JSON handling * Event auth fixes, including correct error surfacing * Correct event ordering when returning from `PerformBackfill` calls * Improved handling rejected events in state resolution applies Closes #439 as superseded by changes in this PR. Signed-off-by: Neil Alexander <[email protected]> --------- Co-authored-by: Neil Alexander <[email protected]>
1 parent dbd5f31 commit e86ab16

18 files changed

+181
-181
lines changed

.github/workflows/tests.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ jobs:
2121
- name: Install Go
2222
uses: actions/setup-go@v3
2323
with:
24-
go-version: 1.21
24+
go-version: 1.22
2525
- name: golangci-lint
2626
uses: golangci/golangci-lint-action@v3
2727

@@ -33,7 +33,7 @@ jobs:
3333
strategy:
3434
fail-fast: false
3535
matrix:
36-
go: ["1.20", "1.21"]
36+
go: ["stable", "1.22"]
3737
steps:
3838
- uses: actions/checkout@v3
3939
- name: Setup go
@@ -83,7 +83,7 @@ jobs:
8383
strategy:
8484
fail-fast: false
8585
matrix:
86-
go: ["1.21"]
86+
go: ["stable", "1.22"]
8787
steps:
8888
- uses: actions/checkout@v3
8989
with:

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ gomatrixserverlib
33

44
[![GoDoc](https://godoc.org/github.com/matrix-org/gomatrixserverlib?status.svg)](https://godoc.org/github.com/matrix-org/gomatrixserverlib)
55

6-
Go library for common functions needed by matrix servers. This library assumes Go 1.18+.
6+
Go library for common functions needed by matrix servers. This library assumes Go 1.22+.

authstate.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ func checkAllowedByAuthEvents(
165165
event PDU, eventsByID map[string]PDU,
166166
missingAuth EventProvider, userIDForSender spec.UserIDForSender,
167167
) error {
168-
authEvents := NewAuthEvents(nil)
168+
authEvents, _ := NewAuthEvents(nil)
169169

170170
for _, ae := range event.AuthEventIDs() {
171171
retryEvent:
@@ -214,7 +214,7 @@ func checkAllowedByAuthEvents(
214214

215215
// If we made it this far then we've successfully got as many of the auth events as
216216
// as described by AuthEventIDs(). Check if they allow the event.
217-
if err := Allowed(event, &authEvents, userIDForSender); err != nil {
217+
if err := Allowed(event, authEvents, userIDForSender); err != nil {
218218
return fmt.Errorf(
219219
"gomatrixserverlib: event with ID %q is not allowed by its auth_events: %s",
220220
event.EventID(), err.Error(),
@@ -335,7 +335,7 @@ func CheckSendJoinResponse(
335335
}
336336

337337
eventsByID := map[string]PDU{}
338-
authEventProvider := NewAuthEvents(nil)
338+
authEventProvider, _ := NewAuthEvents(nil)
339339

340340
// Since checkAllowedByAuthEvents needs to be able to look up any of the
341341
// auth events by ID only, we will build a map which contains references
@@ -369,7 +369,7 @@ func CheckSendJoinResponse(
369369
}
370370

371371
// Now check that the join event is valid against the supplied state.
372-
if err := Allowed(joinEvent, &authEventProvider, userIDForSender); err != nil {
372+
if err := Allowed(joinEvent, authEventProvider, userIDForSender); err != nil {
373373
return nil, fmt.Errorf(
374374
"gomatrixserverlib: event with ID %q is not allowed by the current room state: %w",
375375
joinEvent.EventID(), err,

backfill.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,8 @@ func RequestBackfill(ctx context.Context, origin spec.ServerName, b BackfillRequ
9999
}
100100
}
101101

102-
return result, lastErr
102+
// Since we pulled in results from multiple servers we need to sort again...
103+
return ReverseTopologicalOrdering(result, TopologicalOrderByPrevEvents), lastErr
103104
}
104105

105106
/*

eventV1.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,7 @@ func (e *eventV1) SetUnsignedField(path string, value interface{}) error {
215215
eventJSON = CanonicalJSONAssumeValid(eventJSON)
216216

217217
res := gjson.GetBytes(eventJSON, "unsigned")
218-
unsigned := RawJSONFromResult(res, eventJSON)
219-
e.eventFields.Unsigned = unsigned
218+
e.eventFields.Unsigned = []byte(res.Raw)
220219

221220
e.eventJSON = eventJSON
222221

eventauth.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -301,15 +301,17 @@ func (a *AuthEvents) Clear() {
301301

302302
// NewAuthEvents returns an AuthEventProvider backed by the given events. New events can be added by
303303
// calling AddEvent().
304-
func NewAuthEvents(events []PDU) AuthEvents {
304+
func NewAuthEvents(events []PDU) (*AuthEvents, error) {
305305
a := AuthEvents{
306306
events: make(map[StateKeyTuple]PDU, len(events)),
307307
roomIDs: make(map[string]struct{}),
308308
}
309309
for _, e := range events {
310-
a.AddEvent(e) // nolint: errcheck
310+
if err := a.AddEvent(e); err != nil {
311+
return nil, err
312+
}
311313
}
312-
return a
314+
return &a, nil
313315
}
314316

315317
// A NotAllowed error is returned if an event does not pass the auth checks.

eventauth_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ func TestStateNeededForMessage(t *testing.T) {
104104
// Message events need the create event, the sender and the power_levels.
105105
testStateNeededForAuth(t, `[{
106106
"type": "m.room.message",
107-
"sender": "@u1:a",
107+
"sender": "@u1:a",
108108
"room_id": "!r1:a"
109109
}]`, &ProtoEvent{
110110
Type: "m.room.message",
@@ -139,7 +139,7 @@ func TestStateNeededForJoin(t *testing.T) {
139139
"type": "m.room.member",
140140
"state_key": "@u1:a",
141141
"sender": "@u1:a",
142-
"content": {"membership": "join"},
142+
"content": {"membership": "join"},
143143
"room_id": "!r1:a"
144144
}]`, &b, StateNeeded{
145145
Create: true,
@@ -163,7 +163,7 @@ func TestStateNeededForInvite(t *testing.T) {
163163
"type": "m.room.member",
164164
"state_key": "@u2:b",
165165
"sender": "@u1:a",
166-
"content": {"membership": "invite"},
166+
"content": {"membership": "invite"},
167167
"room_id": "!r1:a"
168168
}]`, &b, StateNeeded{
169169
Create: true,
@@ -199,7 +199,7 @@ func TestStateNeededForInvite3PID(t *testing.T) {
199199
"token": "my_token"
200200
}
201201
}
202-
},
202+
},
203203
"room_id": "!r1:a"
204204
}]`, &b, StateNeeded{
205205
Create: true,
@@ -1035,7 +1035,7 @@ func TestAuthEvents(t *testing.T) {
10351035
if err != nil {
10361036
t.Fatalf("TestAuthEvents: failed to create power_levels event: %s", err)
10371037
}
1038-
a := NewAuthEvents([]PDU{power})
1038+
a, _ := NewAuthEvents([]PDU{power})
10391039
var e PDU
10401040
if e, err = a.PowerLevels(); err != nil || e != power {
10411041
t.Errorf("TestAuthEvents: failed to get same power_levels event")
@@ -1685,15 +1685,15 @@ func TestMembershipBanned(t *testing.T) {
16851685
"state_key": "@u3:a",
16861686
"event_id": "$e4:a",
16871687
"content": {"membership": "ban"}
1688-
},
1688+
},
16891689
{
16901690
"type": "m.room.member",
16911691
"sender": "@u2:a",
16921692
"room_id": "!r1:a",
16931693
"state_key": "@u3:a",
16941694
"event_id": "$e4:a",
16951695
"content": {"membership": "ban"}
1696-
},
1696+
},
16971697
{
16981698
"type": "m.room.member",
16991699
"sender": "@u2:a",

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ require (
3131
gopkg.in/yaml.v3 v3.0.1 // indirect
3232
)
3333

34-
go 1.18
34+
go 1.22

handleinvite_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,19 @@ func (r *TestStateQuerier) GetAuthEvents(ctx context.Context, event PDU) (AuthEv
3838
return nil, fmt.Errorf("failed getting auth provider")
3939
}
4040

41-
eventProvider := AuthEvents{}
41+
eventProvider, _ := NewAuthEvents(nil)
4242
if r.createEvent != nil {
43-
eventProvider = NewAuthEvents([]PDU{r.createEvent})
43+
if err := eventProvider.AddEvent(r.createEvent); err != nil {
44+
return nil, err
45+
}
4446
if r.inviterMemberEvent != nil {
4547
err := eventProvider.AddEvent(r.inviterMemberEvent)
4648
if err != nil {
4749
return nil, err
4850
}
4951
}
5052
}
51-
return &eventProvider, nil
53+
return eventProvider, nil
5254
}
5355

5456
func (r *TestStateQuerier) GetState(ctx context.Context, roomID spec.RoomID, stateWanted []StateKeyTuple) ([]PDU, error) {

handlejoin.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,11 @@ func HandleMakeJoin(input HandleMakeJoinInput) (*HandleMakeJoinResponse, error)
116116
return nil, spec.InternalServerError{Err: fmt.Sprintf("expected join event from template builder. got: %s", event.Type())}
117117
}
118118

119-
provider := NewAuthEvents(state)
120-
if err = Allowed(event, &provider, input.UserIDQuerier); err != nil {
119+
provider, err := NewAuthEvents(state)
120+
if err != nil {
121+
return nil, spec.Forbidden(err.Error())
122+
}
123+
if err = Allowed(event, provider, input.UserIDQuerier); err != nil {
121124
return nil, spec.Forbidden(err.Error())
122125
}
123126

0 commit comments

Comments
 (0)