mirror of
https://github.com/matrix-org/dendrite.git
synced 2025-12-16 11:23:11 -06:00
Try to establish auth difference for state res v2
This commit is contained in:
parent
0ec7403c2d
commit
3f31c4d5ca
2
go.mod
2
go.mod
|
|
@ -14,7 +14,7 @@ require (
|
|||
github.com/lib/pq v1.2.0
|
||||
github.com/matrix-org/dugong v0.0.0-20171220115018-ea0a4690a0d5
|
||||
github.com/matrix-org/gomatrix v0.0.0-20190528120928-7df988a63f26
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200303114503-f4a1756605cf
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200304113232-f827b01e450c
|
||||
github.com/matrix-org/naffka v0.0.0-20200127221512-0716baaabaf1
|
||||
github.com/matrix-org/util v0.0.0-20171127121716-2e2df66af2f5
|
||||
github.com/mattn/go-sqlite3 v2.0.2+incompatible
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -73,6 +73,8 @@ github.com/matrix-org/gomatrixserverlib v0.0.0-20200228114906-771d251ca458 h1:xC
|
|||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200228114906-771d251ca458/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200303114503-f4a1756605cf h1:v1wIWdlIICrOyua4oSsw5jrqTJGmRibIL9Mpo1Ro4uc=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200303114503-f4a1756605cf/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200304113232-f827b01e450c h1:cQtAr/WkUam8xzWoYaoQVVb+7cqSpjdbG6srtWke1qk=
|
||||
github.com/matrix-org/gomatrixserverlib v0.0.0-20200304113232-f827b01e450c/go.mod h1:FsKa2pWE/bpQql9H7U4boOPXFoJX/QcqaZZ6ijLkaZI=
|
||||
github.com/matrix-org/naffka v0.0.0-20200127221512-0716baaabaf1 h1:osLoFdOy+ChQqVUn2PeTDETFftVkl4w9t/OW18g3lnk=
|
||||
github.com/matrix-org/naffka v0.0.0-20200127221512-0716baaabaf1/go.mod h1:cXoYQIENbdWIQHt1SyCo6Bl3C3raHwJ0wgVrXHSqf+A=
|
||||
github.com/matrix-org/util v0.0.0-20171127121716-2e2df66af2f5 h1:W7l5CP4V7wPyPb4tYE11dbmeAOwtFQBTW0rf4OonOS8=
|
||||
|
|
|
|||
|
|
@ -557,7 +557,6 @@ func (v StateResolution) calculateAndStoreStateAfterManyEvents(
|
|||
|
||||
func (v StateResolution) calculateStateAfterManyEvents(
|
||||
ctx context.Context,
|
||||
|
||||
prevStates []types.StateAtEvent,
|
||||
) (state []types.StateEntry, algorithm string, conflictLength int, err error) {
|
||||
var combined []types.StateEntry
|
||||
|
|
@ -608,6 +607,19 @@ func (v StateResolution) calculateStateAfterManyEvents(
|
|||
return
|
||||
}
|
||||
|
||||
func (v StateResolution) resolveConflicts(
|
||||
ctx context.Context,
|
||||
notConflicted, conflicted []types.StateEntry,
|
||||
) ([]types.StateEntry, error) {
|
||||
switch v.version {
|
||||
case StateResolutionAlgorithmV1:
|
||||
return v.resolveConflictsV1(ctx, notConflicted, conflicted)
|
||||
case StateResolutionAlgorithmV2:
|
||||
return v.resolveConflictsV2(ctx, notConflicted, conflicted)
|
||||
}
|
||||
return nil, errors.New("unsupported state resolution algorithm")
|
||||
}
|
||||
|
||||
// resolveConflicts resolves a list of conflicted state entries. It takes two lists.
|
||||
// The first is a list of all state entries that are not conflicted.
|
||||
// The second is a list of all state entries that are conflicted
|
||||
|
|
@ -615,7 +627,7 @@ func (v StateResolution) calculateStateAfterManyEvents(
|
|||
// Returns a list that combines the entries without conflicts with the result of state resolution for the entries with conflicts.
|
||||
// The returned list is sorted by state key tuple.
|
||||
// Returns an error if there was a problem talking to the database.
|
||||
func (v StateResolution) resolveConflicts(
|
||||
func (v StateResolution) resolveConflictsV1(
|
||||
ctx context.Context,
|
||||
notConflicted, conflicted []types.StateEntry,
|
||||
) ([]types.StateEntry, error) {
|
||||
|
|
@ -655,18 +667,124 @@ func (v StateResolution) resolveConflicts(
|
|||
}
|
||||
|
||||
// Resolve the conflicts.
|
||||
var resolvedEvents []gomatrixserverlib.Event
|
||||
switch v.version {
|
||||
case StateResolutionAlgorithmV1:
|
||||
fmt.Println("using room version 1")
|
||||
resolvedEvents = gomatrixserverlib.ResolveStateConflicts(conflictedEvents, authEvents)
|
||||
case StateResolutionAlgorithmV2:
|
||||
fmt.Println("using room version 2")
|
||||
resolvedEvents = gomatrixserverlib.ResolveStateConflictsV2(conflictedEvents, nil, authEvents)
|
||||
default:
|
||||
return nil, errors.New("unsupported room version")
|
||||
resolvedEvents := gomatrixserverlib.ResolveStateConflicts(conflictedEvents, authEvents)
|
||||
|
||||
// Map from the full events back to numeric state entries.
|
||||
for _, resolvedEvent := range resolvedEvents {
|
||||
entry, ok := eventIDMap[resolvedEvent.EventID()]
|
||||
if !ok {
|
||||
panic(fmt.Errorf("Missing state entry for event ID %q", resolvedEvent.EventID()))
|
||||
}
|
||||
notConflicted = append(notConflicted, entry)
|
||||
}
|
||||
|
||||
// Sort the result so it can be searched.
|
||||
sort.Sort(shared.StateEntrySorter(notConflicted))
|
||||
return notConflicted, nil
|
||||
}
|
||||
|
||||
// resolveConflicts resolves a list of conflicted state entries. It takes two lists.
|
||||
// The first is a list of all state entries that are not conflicted.
|
||||
// The second is a list of all state entries that are conflicted
|
||||
// A state entry is conflicted when there is more than one numeric event ID for the same state key tuple.
|
||||
// Returns a list that combines the entries without conflicts with the result of state resolution for the entries with conflicts.
|
||||
// The returned list is sorted by state key tuple.
|
||||
// Returns an error if there was a problem talking to the database.
|
||||
func (v StateResolution) resolveConflictsV2(
|
||||
ctx context.Context,
|
||||
notConflicted, conflicted []types.StateEntry,
|
||||
) ([]types.StateEntry, error) {
|
||||
|
||||
// Load the non-conflicted events
|
||||
nonConflictedEvents, _, err := v.loadStateEvents(ctx, notConflicted)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Load the conflicted events
|
||||
conflictedEvents, eventIDMap, err := v.loadStateEvents(ctx, conflicted)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// For each conflicted event, we will add a new set of auth events. Auth
|
||||
// events may be duplicated across these sets but that's OK.
|
||||
authSets := make(map[string][]gomatrixserverlib.Event)
|
||||
var authEvents []gomatrixserverlib.Event
|
||||
var authDifference []gomatrixserverlib.Event
|
||||
|
||||
// For each conflicted event, let's try and get the needed auth events.
|
||||
for _, conflictedEvent := range conflictedEvents {
|
||||
// Work out which auth events we need to load.
|
||||
key := conflictedEvent.EventID()
|
||||
needed := gomatrixserverlib.StateNeededForAuth([]gomatrixserverlib.Event{conflictedEvent})
|
||||
|
||||
// Find the numeric IDs for the necessary state keys.
|
||||
var neededStateKeys []string
|
||||
neededStateKeys = append(neededStateKeys, needed.Member...)
|
||||
neededStateKeys = append(neededStateKeys, needed.ThirdPartyInvite...)
|
||||
stateKeyNIDMap, err := v.db.EventStateKeyNIDs(ctx, neededStateKeys)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Load the necessary auth events.
|
||||
tuplesNeeded := v.stateKeyTuplesNeeded(stateKeyNIDMap, needed)
|
||||
var authEntries []types.StateEntry
|
||||
for _, tuple := range tuplesNeeded {
|
||||
if eventNID, ok := shared.StateEntryMap(notConflicted).Lookup(tuple); ok {
|
||||
authEntries = append(authEntries, types.StateEntry{
|
||||
StateKeyTuple: tuple,
|
||||
EventNID: eventNID,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Store the newly found auth events in the auth set for this event.
|
||||
authSets[key], _, err = v.loadStateEvents(ctx, authEntries)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
authEvents = append(authEvents, authSets[key]...)
|
||||
}
|
||||
|
||||
// This function helps us to work out whether an event exists in one of the
|
||||
// auth sets.
|
||||
isInAuthList := func(k string, event gomatrixserverlib.Event) bool {
|
||||
for _, e := range authSets[k] {
|
||||
if e.EventID() == event.EventID() {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// This function works out if an event exists in all of the auth sets.
|
||||
isInAllAuthLists := func(event gomatrixserverlib.Event) bool {
|
||||
found := true
|
||||
for k := range authSets {
|
||||
found = found && isInAuthList(k, event)
|
||||
}
|
||||
return found
|
||||
}
|
||||
|
||||
// Look through all of the auth events that we've been given and work out if
|
||||
// there are any events which don't appear in all of the auth sets. If they
|
||||
// don't then we add them to the auth difference.
|
||||
for _, event := range authEvents {
|
||||
if !isInAllAuthLists(event) {
|
||||
authDifference = append(authDifference, event)
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the conflicts.
|
||||
resolvedEvents := gomatrixserverlib.ResolveStateConflictsV2(
|
||||
conflictedEvents,
|
||||
nonConflictedEvents,
|
||||
authEvents,
|
||||
authDifference,
|
||||
)
|
||||
|
||||
// Map from the full events back to numeric state entries.
|
||||
for _, resolvedEvent := range resolvedEvents {
|
||||
entry, ok := eventIDMap[resolvedEvent.EventID()]
|
||||
|
|
|
|||
Loading…
Reference in a new issue