From 70941a2c5775480cd9729cff66606786ee6cfd0b Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 5 Jun 2020 10:11:01 +0100 Subject: [PATCH] Use MissingAuthEventHandler on performjoin to try and speed up cases where we have missing events --- federationapi/routing/send.go | 2 +- federationsender/internal/perform/join.go | 63 ++++++++++++----------- go.mod | 2 +- go.sum | 2 + 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/federationapi/routing/send.go b/federationapi/routing/send.go index 74b4c0144..a2120d81b 100644 --- a/federationapi/routing/send.go +++ b/federationapi/routing/send.go @@ -675,7 +675,7 @@ func (t *txnReq) lookupMissingStateViaState(roomID, eventID string, roomVersion return nil, err } // 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 &state, nil diff --git a/federationsender/internal/perform/join.go b/federationsender/internal/perform/join.go index 3c7ef0765..0204ef0f9 100644 --- a/federationsender/internal/perform/join.go +++ b/federationsender/internal/perform/join.go @@ -33,38 +33,43 @@ func (r joinContext) CheckSendJoinResponse( ) error { // A list of events that we have retried, if they were not included in // 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(eventID string) (*gomatrixserverlib.Event, error) { + if retry, ok := retries[eventID]; ok { + if retry == nil { + return nil, fmt.Errorf("missingAuth: not retrying failed event ID %q", eventID) + } + return retries[eventID], nil + } + // Make a note of the fact that we tried to do something with this + // event ID, even if we don't succeed. + retries[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 auth events. + for _, pdu := range tx.PDUs { + ev, everr := gomatrixserverlib.NewEventFromUntrustedJSON(pdu, respMakeJoin.RoomVersion) + if everr != nil { + return nil, fmt.Errorf("missingAuth gomatrixserverlib.NewEventFromUntrustedJSON: %w", everr) + } + respSendJoin.AuthEvents = append(respSendJoin.AuthEvents, ev) + retries[ev.EventID()] = &ev + } + return retries[eventID], nil + } -retryCheck: // TODO: Can we expand Check here to return a list of missing auth // events rather than failing one at a time? - if err := respSendJoin.Check(ctx, r.keyRing, event); err != nil { - switch e := err.(type) { - 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) - } + if err := respSendJoin.Check(ctx, r.keyRing, event, missingAuth); err != nil { + return fmt.Errorf("respSendJoin: %w", err) } return nil } diff --git a/go.mod b/go.mod index a875ef7c9..86bdc3e7b 100644 --- a/go.mod +++ b/go.mod @@ -18,7 +18,7 @@ require ( 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/gomatrix v0.0.0-20190528120928-7df988a63f26 - github.com/matrix-org/gomatrixserverlib v0.0.0-20200604122934-a06b83e7f324 + github.com/matrix-org/gomatrixserverlib v0.0.0-20200605084812-9a79e462ccf2 github.com/matrix-org/naffka v0.0.0-20200422140631-181f1ee7401f github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 github.com/mattn/go-sqlite3 v2.0.2+incompatible diff --git a/go.sum b/go.sum index 94101251b..34c5e0836 100644 --- a/go.sum +++ b/go.sum @@ -358,6 +358,8 @@ github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26 h1:Hr3zjRsq2bh 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-20200604122934-a06b83e7f324/go.mod h1:JsAzE1Ll3+gDWS9JSUHPJiiyAksvOOnGWF2nXdg4ZzU= +github.com/matrix-org/gomatrixserverlib v0.0.0-20200605084812-9a79e462ccf2 h1:68CLChI1or0tMFlAnXJrWWEhLxzIbzHjoSi9/eo6Iao= +github.com/matrix-org/gomatrixserverlib v0.0.0-20200605084812-9a79e462ccf2/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/go.mod h1:y0oDTjZDv5SM9a2rp3bl+CU+bvTRINQsdb7YlDql5Go= github.com/matrix-org/util v0.0.0-20190711121626-527ce5ddefc7 h1:ntrLa/8xVzeSs8vHFHK25k0C+NV74sYMJnNSg5NoSRo=