Use AuthChainProvider to try and speed up federated joins (#1100)

* Use MissingAuthEventHandler on performjoin to try and speed up cases where we have missing events

* Update gomatrixserverlib

* Use supplied room version

* Use AuthChainProvider

* Tweaks

* Update gomatrixserverlib

* Signature checks
This commit is contained in:
Neil Alexander 2020-06-05 11:48:52 +01:00 committed by GitHub
parent 29a20d1da7
commit 76ff47c052
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 67 additions and 33 deletions

View File

@ -675,7 +675,7 @@ func (t *txnReq) lookupMissingStateViaState(roomID, eventID string, roomVersion
return nil, err return nil, err
} }
// Check that the returned state is valid. // Check that the returned state is valid.
if err := state.Check(t.context, t.keys); err != nil { if err := state.Check(t.context, t.keys, nil); err != nil {
return nil, err return nil, err
} }
return &state, nil return &state, nil

View File

@ -33,38 +33,72 @@ func (r joinContext) CheckSendJoinResponse(
) error { ) error {
// A list of events that we have retried, if they were not included in // A list of events that we have retried, if they were not included in
// the auth events supplied in the send_join. // the auth events supplied in the send_join.
retries := map[string]bool{} retries := map[string][]gomatrixserverlib.Event{}
// Define a function which we can pass to Check to retrieve missing
// auth events inline. This greatly increases our chances of not having
// to repeat the entire set of checks just for a missing event or two.
missingAuth := func(roomVersion gomatrixserverlib.RoomVersion, eventIDs []string) ([]gomatrixserverlib.Event, error) {
returning := []gomatrixserverlib.Event{}
// See if we have retry entries for each of the supplied event IDs.
for _, eventID := range eventIDs {
// If we've already satisfied a request for this event ID before then
// just append the results. We won't retry the request.
if retry, ok := retries[eventID]; ok {
if retry == nil {
return nil, fmt.Errorf("missingAuth: not retrying failed event ID %q", eventID)
}
returning = append(returning, retry...)
continue
}
// Make a note of the fact that we tried to do something with this
// event ID, even if we don't succeed.
retries[event.EventID()] = nil
// Try to retrieve the event from the server that sent us the send
// join response.
tx, txerr := r.federation.GetEvent(ctx, server, eventID)
if txerr != nil {
return nil, fmt.Errorf("missingAuth r.federation.GetEvent: %w", txerr)
}
// For each event returned, add it to the set of return events. We
// also will populate the retries, in case someone asks for this
// event ID again.
for _, pdu := range tx.PDUs {
// Try to parse the event.
ev, everr := gomatrixserverlib.NewEventFromUntrustedJSON(pdu, roomVersion)
if everr != nil {
return nil, fmt.Errorf("missingAuth gomatrixserverlib.NewEventFromUntrustedJSON: %w", everr)
}
// Check the signatures of the event.
if res, err := gomatrixserverlib.VerifyEventSignatures(ctx, []gomatrixserverlib.Event{ev}, r.keyRing); err != nil {
return nil, fmt.Errorf("missingAuth VerifyEventSignatures: %w", err)
} else {
for _, err := range res {
if err != nil {
return nil, fmt.Errorf("missingAuth VerifyEventSignatures: %w", err)
}
}
}
// If the event is OK then add it to the results and the retry map.
returning = append(returning, ev)
retries[event.EventID()] = append(retries[event.EventID()], ev)
retries[ev.EventID()] = append(retries[ev.EventID()], ev)
}
}
return returning, nil
}
retryCheck:
// TODO: Can we expand Check here to return a list of missing auth // TODO: Can we expand Check here to return a list of missing auth
// events rather than failing one at a time? // events rather than failing one at a time?
if err := respSendJoin.Check(ctx, r.keyRing, event); err != nil { if err := respSendJoin.Check(ctx, r.keyRing, event, missingAuth); err != nil {
switch e := err.(type) { return fmt.Errorf("respSendJoin: %w", err)
case gomatrixserverlib.MissingAuthEventError:
// Check that we haven't already retried for this event, prevents
// us from ending up in endless loops
if !retries[e.AuthEventID] {
// Ask the server that we're talking to right now for the event
tx, txerr := r.federation.GetEvent(ctx, server, e.AuthEventID)
if txerr != nil {
return fmt.Errorf("r.federation.GetEvent: %w", txerr)
}
// For each event returned, add it to the auth events.
for _, pdu := range tx.PDUs {
ev, everr := gomatrixserverlib.NewEventFromUntrustedJSON(pdu, respMakeJoin.RoomVersion)
if everr != nil {
return fmt.Errorf("gomatrixserverlib.NewEventFromUntrustedJSON: %w", everr)
}
respSendJoin.AuthEvents = append(respSendJoin.AuthEvents, ev)
}
// Mark the event as retried and then give the check another go.
retries[e.AuthEventID] = true
goto retryCheck
}
return fmt.Errorf("respSendJoin (after retries): %w", e)
default:
return fmt.Errorf("respSendJoin: %w", err)
}
} }
return nil return nil
} }

2
go.mod
View File

@ -18,7 +18,7 @@ require (
github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4 github.com/matrix-org/go-http-js-libp2p v0.0.0-20200518170932-783164aeeda4
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3 github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26
github.com/matrix-org/gomatrixserverlib v0.0.0-20200604122934-a06b83e7f324 github.com/matrix-org/gomatrixserverlib v0.0.0-20200605101319-57093b526cb1
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7
github.com/mattn/go-sqlite3 v2.0.2+incompatible github.com/mattn/go-sqlite3 v2.0.2+incompatible

4
go.sum
View File

@ -356,8 +356,8 @@ github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3 h1:Yb+Wlf
github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo= github.com/matrix-org/go-sqlite3-js v0.0.0-20200522092705-bc8506ccbcf3/go.mod h1:e+cg2q7C7yE5QnAXgzo512tgFh1RbQLC0+jozuegKgo=
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bhrnp3Ky1qgx/fzCtCALOoGYylh2tpS9K4= github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bhrnp3Ky1qgx/fzCtCALOoGYylh2tpS9K4=
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0= github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26/go.mod h1:3fxX6gUjWyI/2Bt7J1OLhpCzOfO/bB3AiX0cJtEKud0=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200604122934-a06b83e7f324 h1:TjHTrOkX+G99F1NitCwNOPa62beQMAQklBuEBkDP8Hc= github.com/matrix-org/gomatrixserverlib v0.0.0-20200605101319-57093b526cb1 h1:T9nY1X24uHDkC3uMLwoo2W+JE2o0t3k/lYwqORfKSUg=
github.com/matrix-org/gomatrixserverlib v0.0.0-20200604122934-a06b83e7f324/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU= github.com/matrix-org/gomatrixserverlib v0.0.0-20200605101319-57093b526cb1/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU=
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f h1:pRz4VTiRCO4zPlEMc3ESdUOcW4PXHH4Kj+YDz1XyE+Y= github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f h1:pRz4VTiRCO4zPlEMc3ESdUOcW4PXHH4Kj+YDz1XyE+Y=
github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f/go.mod h1:y0oDTjZDv5SM9a2rp3bl+CU+bvTRINQsdb7YlDql5Go= github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f/go.mod h1:y0oDTjZDv5SM9a2rp3bl+CU+bvTRINQsdb7YlDql5Go=
github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo= github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo=