Skip to content

Commit 8cd1c66

Browse files
committed
fix: keep state-sync retry armed until the authoritative server responds
The RES_CRDT_STATE handler cleared requestingState (and reset the retry timer) before the authoritative-server guard, so a state response from any non-authoritative peer disarmed the retry loop without marking the client synchronized. On a cold launch a non-auth response can arrive before the server's identity resolves to 'authoritative-server', permanently wedging the client on waitForSceneReady / isStateSyncronized. Move the clears after the guard so only an authoritative response stops the pending request; the retry keeps firing until the real server answers. Adds test/sdk/network/state-sync-retry.spec.ts covering the regression.
1 parent 96e9a29 commit 8cd1c66

2 files changed

Lines changed: 63 additions & 1 deletion

File tree

packages/@dcl/sdk/src/network/message-bus-sync.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ export function addSyncTransport(
128128
}
129129
})
130130
binaryMessageBus.on(CommsMessage.RES_CRDT_STATE, async (data, sender) => {
131+
if (isServerAtom.getOrNull() || sender !== AUTH_SERVER_PEER_ID) return
131132
requestingState = false
132133
elapsedTimeSinceRequest = 0
133-
if (isServerAtom.getOrNull() || sender !== AUTH_SERVER_PEER_ID) return
134134
DEBUG_NETWORK_MESSAGES() && console.log('[Processing CRDT State]', data.byteLength / 1024, 'KB')
135135
if (data.byteLength > 0) {
136136
transport.onmessage!(serverValidator.processClientMessages(data, sender))
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import { engine, RealmInfo } from '../../../packages/@dcl/ecs/dist'
2+
import * as components from '../../../packages/@dcl/ecs/dist/components'
3+
import { addSyncTransport } from '../../../packages/@dcl/sdk/src/network/message-bus-sync'
4+
import { CommsMessage, encodeString } from '../../../packages/@dcl/sdk/src/network/binary-message-bus'
5+
import type { SendBinaryRequest, SendBinaryResponse } from '~system/CommunicationsController'
6+
7+
function craftResCrdtState(sender: string): Uint8Array {
8+
const senderBytes = encodeString(sender)
9+
const buf = new Uint8Array(1 + senderBytes.byteLength + 1)
10+
buf[0] = senderBytes.byteLength
11+
buf.set(senderBytes, 1)
12+
buf[1 + senderBytes.byteLength] = CommsMessage.RES_CRDT_STATE
13+
return buf
14+
}
15+
16+
describe('state-sync request retry', () => {
17+
it('keeps retrying REQ_CRDT_STATE after a non-authoritative RES_CRDT_STATE', async () => {
18+
components.NetworkEntity(engine as any)
19+
components.NetworkParent(engine as any)
20+
components.Transform(engine as any)
21+
components.SyncComponents(engine as any)
22+
23+
let reqCount = 0
24+
const sendBinary = async (msg: SendBinaryRequest): Promise<SendBinaryResponse> => {
25+
for (const peerData of msg.peerData) {
26+
for (const data of peerData.data) {
27+
if (data[0] === CommsMessage.REQ_CRDT_STATE) reqCount++
28+
}
29+
}
30+
return { data: [] }
31+
}
32+
const getUserData = async () => ({
33+
data: { userId: 'clientA', version: 1, displayName: 'A', hasConnectedWeb3: true, avatar: undefined }
34+
})
35+
const isServerFn = async () => ({ isServer: false })
36+
37+
const sync = addSyncTransport(engine as any, sendBinary, getUserData as any, isServerFn as any, 'clientA')
38+
39+
RealmInfo.createOrReplace(engine.RootEntity, {
40+
baseUrl: 'http://localhost:8000',
41+
realmName: 'LocalPreview',
42+
networkId: 0,
43+
commsAdapter: 'ws-room',
44+
isPreview: true,
45+
room: 'room-1',
46+
isConnectedSceneRoom: true
47+
} as any)
48+
await engine.update(1)
49+
await engine.update(1)
50+
51+
expect(reqCount).toBeGreaterThanOrEqual(1)
52+
const reqsBeforeNonAuthResponse = reqCount
53+
54+
sync.binaryMessageBus.__processMessages([craftResCrdtState('some-other-peer')])
55+
expect(sync.isStateSyncronized()).toBe(false)
56+
57+
await engine.update(3)
58+
await engine.update(1)
59+
60+
expect(reqCount).toBeGreaterThan(reqsBeforeNonAuthResponse)
61+
})
62+
})

0 commit comments

Comments
 (0)