element-hq / element-hq/dendrite

`/sync` with only `timeout=0` acts as if `full_state=true`

Open
#2,066 1 comment 0 reactions 0 assignees View on GitHub
C-Sync-API T-Defect
Dominant language
Go
Stars
965
Forks
101
PR merge metrics
No merged PRs in 30d

Description

*This issue was originally created by [**@ShadowJonathan**](https://github.com/ShadowJonathan) at .*

### Background information

- **Dendrite version or git SHA**: 83b9cb4d79123ec89e18a46d5202e74a9e9305b8
- **Running in Docker?**: yes

This was found while running Complement, so build information from [this Dockerfile](https://github.com/matrix-org/complement/blob/277e25800c9b51f5dc0fb5d89430cf99d817267d/dockerfiles/Dendrite.Dockerfile) also applies.

### Description

### Steps to reproduce

When creating a complement test for an unrelated functionality, this following snippet reacts differently on dendrite compared to synapse;

```go
deployment := Deploy(t, b.BlueprintOneToOneRoom)
defer deployment.Destroy(t)

alice := deployment.Client(t, "hs1", "@alice:hs1")
bob := deployment.Client(t, "hs1", "@bob:hs1")

roomID := alice.CreateRoom(t, map[string]interface{}{
"preset": "public_chat",
})

var since string

// Get floating current next_batch
res := alice.MustDoFunc(t, "GET", []string{"_matrix", "client", "r0", "sync"}, client.WithQueries(url.Values{
"timeout": []string{"0"},
}))
body := client.ParseJSON(t, res)
since = client.GetJSONFieldStr(t, body, "next_batch")

alice.InviteRoom(t, roomID, bob.UserID)

bob.SyncUntilInvitedTo(t, roomID)

// This rejects the invite
bob.LeaveRoom(t, roomID)

// Full sync
res = bob.MustDoFunc(t, "GET", []string{"_matrix", "client", "r0", "sync"}, client.WithQueries(url.Values{
"timeout": []string{"0"},
// "full_state": []string{"true"},
// "since": []string{since},
}))
body = client.ParseJSON(t, res)
jsonRes := gjson.GetBytes(body, "rooms.leave."+client.GjsonEscape(roomID))
if !jsonRes.Exists() {
t.Errorf("Bob just rejected an invite, it should show up under 'leave' in a full sync")
}
since = client.GetJSONFieldStr(t, body, "next_batch")
```

On synapse, the last condition (as expected) fails, as it is fetching fresh information with incremental sync since `since`.

However, on dendrite, this condition **passes**, dendrite is supplying a `state_full=true` response while it should be default `false`, according to spec.

---

There's an alternate explanation for this, but that means an ambiguity in the spec, see https://github.com/matrix-org/matrix-doc/issues/3537

Contributor guide

Open the contributing guide

Research direction

Start at Dendrite's client /sync endpoint and reproduce the Complement scenario with timeout=0, comparing the response when full_state and since are omitted. Trace how those query parameters are interpreted, then verify that the response does not include the rejected invite as a full sync unless full_state=true; consult the linked Matrix spec discussion for the ambiguity.

Written by the indexing model from the issue text.

Assessment

Tech stack
go
Domain
api, backend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.