From c8ac815e2bc1673468d476058137663b585600de Mon Sep 17 00:00:00 2001 From: Sosthene Date: Mon, 8 Sep 2025 21:59:52 +0200 Subject: [PATCH] Refactor handleHandshakeMsg --- src/services/service.ts | 89 +++++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 43 deletions(-) diff --git a/src/services/service.ts b/src/services/service.ts index c06b700..482e3f5 100755 --- a/src/services/service.ts +++ b/src/services/service.ts @@ -1405,8 +1405,8 @@ export default class Services { 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.state_id) { continue; } // shouldn't happen if (state.state_id === EMPTY32BYTES) { @@ -1414,62 +1414,65 @@ export default class Services { const existingTip = existing.states[existing.states.length - 1].commited_in; if (existingTip !== state.commited_in) { console.log('Found new tip for process', processId); - // We update the process - new_states.push(state.state_id); - roles.push(state.roles); + 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(); + if (!existingLastState) { + // This should never happen + console.error('Failed to get last state for process', processId); + break; + } + 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); + } + } else { + // We already have the state, but we check if we have the keys + const existingState = this.getStateFromId(existing, state.state_id); + if (existingState!.keys && Object.keys(existingState!.keys).length != 0) { + // We have some keys, so we just assume everything ok and move on for now + continue; + } else { + // We verify we are part of the roles + const roles = state.roles; + if (this.rolesContainsUs(roles)) { + // We don't have keys, but we are part of the roles, so we need to request the keys + // that may also be because we are part of a role that don't have any fields + // It's possible but let's request for nothing anyway + newStates.push(state.state_id); + newRoles.push(roles); + } else { + // We are simply not involved, move on + continue; + } } } } - if (new_states.length != 0) { - // We request the new states - // filter out the empty state, if any - // empty state will always be last, so that's easy - if (new_states.findLast(state => state === EMPTY32BYTES)) { - new_states.pop(); - roles.pop(); - } - 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']); - // 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) {