From dde63a552fb61b93e9839d0b5218e59442fa9dcb Mon Sep 17 00:00:00 2001 From: Beaudan Date: Fri, 25 Jan 2019 12:48:51 +1100 Subject: [PATCH] Fix bug with replayable errors, fix bug with set representation of swarmNodes not being handled properly --- js/models/messages.js | 2 ++ js/modules/data.js | 37 ++++++++++------------------------ js/modules/loki_message_api.js | 16 +++------------ js/modules/loki_snode_api.js | 6 +++--- 4 files changed, 19 insertions(+), 42 deletions(-) diff --git a/js/models/messages.js b/js/models/messages.js index fe684e961..790349056 100644 --- a/js/models/messages.js +++ b/js/models/messages.js @@ -847,6 +847,8 @@ e.name === 'SendMessageNetworkError' || e.name === 'SignedPreKeyRotationError' || e.name === 'OutgoingIdentityKeyError' || + e.name === 'DNSResolutionError' || + e.name === 'EmptySwarmError' || e.name === 'PoWError' ); }, diff --git a/js/modules/data.js b/js/modules/data.js index 1d937b521..c5489ae6c 100644 --- a/js/modules/data.js +++ b/js/modules/data.js @@ -663,18 +663,14 @@ async function removeAllSessions(id) { function setifyProperty(data, propertyName) { if (!data) return data; const returnData = data; - if (returnData[propertyName]) { + if (returnData[propertyName] && Array.isArray(returnData[propertyName])) { returnData[propertyName] = new Set(returnData[propertyName]); } return returnData; } async function getSwarmNodesByPubkey(pubkey) { - let swarmNodes = await channels.getSwarmNodesByPubkey(pubkey); - if (Array.isArray(swarmNodes)) { - swarmNodes = new Set(swarmNodes); - } - return swarmNodes; + return channels.getSwarmNodesByPubkey(pubkey); } async function getConversationCount() { @@ -682,11 +678,7 @@ async function getConversationCount() { } async function saveConversation(data) { - const storeData = data; - if (storeData.swarmNodes) { - storeData.swarmNodes = Array.from(storeData.swarmNodes); - } - await channels.saveConversation(storeData); + await channels.saveConversation(data); } async function saveConversations(data) { @@ -694,8 +686,7 @@ async function saveConversations(data) { } async function getConversationById(id, { Conversation }) { - const rawData = await channels.getConversationById(id); - const data = setifyProperty(rawData, 'swarmNodes'); + const data = await channels.getConversationById(id); return new Conversation(data); } @@ -704,8 +695,10 @@ async function updateConversation(id, data, { Conversation }) { if (!existing) { throw new Error(`Conversation ${id} does not exist!`); } + const setData = setifyProperty(data, 'swarmNodes'); + const setExisting = setifyProperty(existing.attributes, 'swarmNodes'); - const merged = merge({}, existing.attributes, data); + const merged = merge({}, setExisting, setData); if (merged.swarmNodes instanceof Set) { merged.swarmNodes = Array.from(merged.swarmNodes); } @@ -729,9 +722,7 @@ async function _removeConversations(ids) { } async function getAllConversations({ ConversationCollection }) { - const conversations = (await channels.getAllConversations()).map(c => - setifyProperty(c, 'swarmNodes') - ); + const conversations = await channels.getAllConversations(); const collection = new ConversationCollection(); collection.add(conversations); @@ -744,9 +735,7 @@ async function getAllConversationIds() { } async function getAllPrivateConversations({ ConversationCollection }) { - const conversations = (await channels.getAllPrivateConversations()).map(c => - setifyProperty(c, 'swarmNodes') - ); + const conversations = await channels.getAllPrivateConversations(); const collection = new ConversationCollection(); collection.add(conversations); @@ -754,9 +743,7 @@ async function getAllPrivateConversations({ ConversationCollection }) { } async function getAllGroupsInvolvingId(id, { ConversationCollection }) { - const conversations = (await channels.getAllGroupsInvolvingId(id)).map(c => - setifyProperty(c, 'swarmNodes') - ); + const conversations = await channels.getAllGroupsInvolvingId(id); const collection = new ConversationCollection(); collection.add(conversations); @@ -764,9 +751,7 @@ async function getAllGroupsInvolvingId(id, { ConversationCollection }) { } async function searchConversations(query, { ConversationCollection }) { - const conversations = (await channels.searchConversations(query)).map(c => - setifyProperty(c, 'swarmNodes') - ); + const conversations = await channels.searchConversations(query); const collection = new ConversationCollection(); collection.add(conversations); diff --git a/js/modules/loki_message_api.js b/js/modules/loki_message_api.js index 358dd33c0..bb333cd01 100644 --- a/js/modules/loki_message_api.js +++ b/js/modules/loki_message_api.js @@ -106,21 +106,11 @@ class LokiMessageAPI { } try { swarmNodes = await window.LokiSnodeAPI.getSwarmNodesByPubkey(pubKey); - // Filter out the nodes we have already got responses from - swarmNodes = Object.keys(swarmNodes) - .filter(node => !(node in completedNodes)) - .reduce( - // eslint-disable-next-line no-loop-func - (obj, node) => ({ - ...obj, - [node]: swarmNodes[node], - }), - {} - ); + swarmNodes = swarmNodes.filter(node => !(node in completedNodes)); } catch (e) { throw new window.textsecure.EmptySwarmError(pubKey, e); } - if (!swarmNodes || swarmNodes.size === 0) { + if (!swarmNodes || swarmNodes.length === 0) { if (completedNodes.length !== 0) { // TODO: Decide how to handle some completed requests but not enough return; @@ -134,7 +124,7 @@ class LokiMessageAPI { const remainingRequests = MINIMUM_SUCCESSFUL_REQUESTS - completedNodes.length; await Promise.all( - Array.from(swarmNodes) + swarmNodes .splice(0, remainingRequests) .map(nodeUrl => doRequest(nodeUrl)) ); diff --git a/js/modules/loki_snode_api.js b/js/modules/loki_snode_api.js index 7dd4cffa6..1ba2a2124 100644 --- a/js/modules/loki_snode_api.js +++ b/js/modules/loki_snode_api.js @@ -108,7 +108,7 @@ class LokiSnodeAPI { async getSwarmNodesByPubkey(pubKey) { const swarmNodes = await window.Signal.Data.getSwarmNodesByPubkey(pubKey); // TODO: Check if swarm list is below a threshold rather than empty - if (swarmNodes && swarmNodes.size !== 0) { + if (swarmNodes && swarmNodes.length !== 0) { return swarmNodes; } return this.replenishSwarm(pubKey); @@ -120,10 +120,10 @@ class LokiSnodeAPI { this.swarmsPendingReplenish[pubKey] = new Promise(async resolve => { let newSwarmNodes; try { - newSwarmNodes = new Set(await this.getSwarmNodes(pubKey)); + newSwarmNodes = await this.getSwarmNodes(pubKey); } catch (e) { // TODO: Handle these errors sensibly - newSwarmNodes = new Set([]); + newSwarmNodes = []; } conversation.set({ swarmNodes: newSwarmNodes }); await window.Signal.Data.updateConversation(