From 77e3dfc29c1cdedb7bb56bcf8b461da8fe811805 Mon Sep 17 00:00:00 2001 From: Sosthene Date: Wed, 3 Sep 2025 15:09:35 +0200 Subject: [PATCH] [bug] fix broken update of processes --- src/service.ts | 65 ++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 36 deletions(-) diff --git a/src/service.ts b/src/service.ts index 41a9b70..e4ce0f4 100644 --- a/src/service.ts +++ b/src/service.ts @@ -80,56 +80,49 @@ export class Service { const existing = await this.getProcess(processId); if (existing) { // Look for state id we don't know yet - let new_states = []; - let roles = []; + let newStates: string[] = []; + let newRoles: Record[] = []; for (const state of process.states) { - if (!state.state_id || state.state_id === EMPTY32BYTES) { continue; } - if (!this.lookForStateId(existing, state.state_id)) { + if (!state || !state.state_id) { continue; } // shouldn't happen + if (state.state_id === EMPTY32BYTES) { + // We check that the tip is the same we have, if not we update + const existingTip = existing.states[existing.states.length - 1].commited_in; + if (existingTip !== state.commited_in) { + console.log('Found new tip for process', processId); + existing.states.pop(); // We discard the last state + existing.states.push(state); + // We know that's the last state, so we just trigger the update + toSave[processId] = existing; + } + } else if (!this.lookForStateId(existing, state.state_id)) { + // We don't want to overwrite what we already have for existing processes + // We may end up overwriting the keys for example + // So the process we're going to save needs to merge new states with what we already have + const existingLastState = existing.states.pop(); + existing.states.push(state); + existing.states.push(existingLastState); + toSave[processId] = existing; // We mark it for update if (this.rolesContainsUs(state.roles)) { - new_states.push(state.state_id); - roles.push(state.roles); + newStates.push(state.state_id); + newRoles.push(state.roles); } } } - if (new_states.length != 0) { - // We request the new states - await this.requestDataFromPeers(processId, new_states, roles); - toSave[processId] = process; + if (newStates.length != 0) { + await this.requestDataFromPeers(processId, newStates, newRoles); } - - // Just to be sure check if that's a pairing process - const lastCommitedState = this.getLastCommitedState(process); - if (lastCommitedState && lastCommitedState.public_data && lastCommitedState.public_data['pairedAddresses']) { - // This is a pairing process - try { - const pairedAddresses = this.decodeValue(lastCommitedState.public_data['pairedAddresses'] as unknown as number[]); - // Are we part of it? - if (pairedAddresses && pairedAddresses.length > 0 && pairedAddresses.includes(this.getDeviceAddress())) { - // We save the process to db - await this.saveProcessToDb(processId, process as Process); - // We update the device - await this.updateDevice(); - } - } catch (e) { - console.error('Failed to check for pairing process:', e); - } - } - // Otherwise we're probably just in the initial loading at page initialization - - // We may learn an update for this process - // TODO maybe actually check if what the relay is sending us contains more information than what we have - // relay should always have more info than us, but we never know - // For now let's keep it simple and let the worker do the job } else { // We add it to db - console.log(`Saving ${processId} to db`); toSave[processId] = process; } } - await this.batchSaveProcessesToDb(toSave); + if (toSave && Object.keys(toSave).length > 0) { + console.log('batch saving processes to db', toSave); + await this.batchSaveProcessesToDb(toSave); + } } }, 500) } catch (e) {