Merge pull request #187 from BeaudanBrown/swarm-fixes

Swarm fixes
pull/188/head
sachaaaaa 6 years ago committed by GitHub
commit a5871f56b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -185,7 +185,6 @@
await window.Signal.Data.saveConversation(conversation.attributes, { await window.Signal.Data.saveConversation(conversation.attributes, {
Conversation: Whisper.Conversation, Conversation: Whisper.Conversation,
}); });
window.LokiSnodeAPI.refreshSwarmNodesForPubKey(id);
} catch (error) { } catch (error) {
window.log.error( window.log.error(
'Conversation save failed! ', 'Conversation save failed! ',
@ -200,9 +199,11 @@
return conversation; return conversation;
}; };
conversation.initialPromise = create().then(() => conversation.initialPromise = create();
conversation.updateProfileAvatar() conversation.initialPromise.then(async () => {
); await window.lokiSnodeAPI.refreshSwarmNodesForPubKey(id);
await conversation.updateProfileAvatar();
});
return conversation; return conversation;
}, },

@ -78,7 +78,7 @@
friendRequestStatus: FriendRequestStatusEnum.none, friendRequestStatus: FriendRequestStatusEnum.none,
unlockTimestamp: null, // Timestamp used for expiring friend requests. unlockTimestamp: null, // Timestamp used for expiring friend requests.
sessionResetStatus: SessionResetEnum.none, sessionResetStatus: SessionResetEnum.none,
swarmNodes: new Set([]), swarmNodes: [],
isOnline: false, isOnline: false,
}; };
}, },
@ -1406,6 +1406,12 @@
}, },
}; };
}, },
async updateSwarmNodes(swarmNodes) {
this.set({ swarmNodes });
await window.Signal.Data.updateConversation(this.id, this.attributes, {
Conversation: Whisper.Conversation,
});
},
async updateLastMessage() { async updateLastMessage() {
if (!this.id) { if (!this.id) {
return; return;

@ -111,7 +111,6 @@ module.exports = {
removeAllSessions, removeAllSessions,
getSwarmNodesByPubkey, getSwarmNodesByPubkey,
saveSwarmNodesForPubKey,
getConversationCount, getConversationCount,
saveConversation, saveConversation,
@ -676,14 +675,6 @@ async function getSwarmNodesByPubkey(pubkey) {
return channels.getSwarmNodesByPubkey(pubkey); return channels.getSwarmNodesByPubkey(pubkey);
} }
async function saveSwarmNodesForPubKey(pubKey, swarmNodes, { Conversation }) {
const conversation = await getConversationById(pubKey, { Conversation });
conversation.set({ swarmNodes });
await updateConversation(conversation.id, conversation.attributes, {
Conversation,
});
}
async function getConversationCount() { async function getConversationCount() {
return channels.getConversationCount(); return channels.getConversationCount();
} }

@ -1,6 +1,6 @@
/* eslint-disable no-await-in-loop */ /* eslint-disable no-await-in-loop */
/* eslint-disable no-loop-func */ /* eslint-disable no-loop-func */
/* global log, dcodeIO, window, callWorker, Whisper, lokiP2pAPI */ /* global log, dcodeIO, window, callWorker, lokiP2pAPI, lokiSnodeAPI */
const nodeFetch = require('node-fetch'); const nodeFetch = require('node-fetch');
const _ = require('lodash'); const _ = require('lodash');
@ -106,10 +106,11 @@ class LokiMessageAPI {
throw err; throw err;
} }
const completedNodes = []; const completedNodes = [];
const failedNodes = [];
let successfulRequests = 0; let successfulRequests = 0;
let canResolve = true; let canResolve = true;
let swarmNodes = await window.Signal.Data.getSwarmNodesByPubkey(pubKey); let swarmNodes = await lokiSnodeAPI.getSwarmNodesForPubKey(pubKey);
const nodeComplete = nodeUrl => { const nodeComplete = nodeUrl => {
completedNodes.push(nodeUrl); completedNodes.push(nodeUrl);
@ -148,8 +149,9 @@ class LokiMessageAPI {
nodeComplete(nodeUrl); nodeComplete(nodeUrl);
} else { } else {
log.error('Loki SendMessages:', e); log.error('Loki SendMessages:', e);
if (window.LokiSnodeAPI.unreachableNode(pubKey, nodeUrl)) { if (lokiSnodeAPI.unreachableNode(pubKey, nodeUrl)) {
nodeComplete(nodeUrl); nodeComplete(nodeUrl);
failedNodes.push(nodeUrl);
} }
} }
} }
@ -160,7 +162,9 @@ class LokiMessageAPI {
throw new window.textsecure.DNSResolutionError('Sending messages'); throw new window.textsecure.DNSResolutionError('Sending messages');
} }
if (swarmNodes.length === 0) { if (swarmNodes.length === 0) {
const freshNodes = await window.LokiSnodeAPI.getFreshSwarmNodes(pubKey); const freshNodes = await lokiSnodeAPI.getFreshSwarmNodes(pubKey);
const goodNodes = _.difference(freshNodes, failedNodes);
await lokiSnodeAPI.updateSwarmNodes(pubKey, goodNodes);
swarmNodes = _.difference(freshNodes, completedNodes); swarmNodes = _.difference(freshNodes, completedNodes);
if (swarmNodes.length === 0) { if (swarmNodes.length === 0) {
if (successfulRequests !== 0) { if (successfulRequests !== 0) {
@ -172,13 +176,10 @@ class LokiMessageAPI {
new Error('Ran out of swarm nodes to query') new Error('Ran out of swarm nodes to query')
); );
} }
await window.Signal.Data.saveSwarmNodesForPubKey(pubKey, swarmNodes, {
Conversation: Whisper.Conversation,
});
} }
const remainingRequests = const remainingRequests =
MINIMUM_SUCCESSFUL_REQUESTS - completedNodes.length; MINIMUM_SUCCESSFUL_REQUESTS - successfulRequests;
await Promise.all( await Promise.all(
swarmNodes swarmNodes
@ -196,7 +197,7 @@ class LokiMessageAPI {
let ourSwarmNodes; let ourSwarmNodes;
try { try {
ourSwarmNodes = await window.LokiSnodeAPI.getOurSwarmNodes(); ourSwarmNodes = await lokiSnodeAPI.getOurSwarmNodes();
} catch (e) { } catch (e) {
throw new window.textsecure.EmptySwarmError(ourKey, e); throw new window.textsecure.EmptySwarmError(ourKey, e);
} }
@ -224,7 +225,7 @@ class LokiMessageAPI {
nodeComplete(nodeUrl); nodeComplete(nodeUrl);
if (result.lastHash) { if (result.lastHash) {
window.LokiSnodeAPI.updateLastHash(nodeUrl, result.lastHash); lokiSnodeAPI.updateLastHash(nodeUrl, result.lastHash);
callback(result.messages); callback(result.messages);
} }
successfulRequests += 1; successfulRequests += 1;
@ -242,7 +243,7 @@ class LokiMessageAPI {
nodeComplete(nodeUrl); nodeComplete(nodeUrl);
} else { } else {
log.error('Loki RetrieveMessages:', e); log.error('Loki RetrieveMessages:', e);
if (window.LokiSnodeAPI.unreachableNode(ourKey, nodeUrl)) { if (lokiSnodeAPI.unreachableNode(ourKey, nodeUrl)) {
nodeComplete(nodeUrl); nodeComplete(nodeUrl);
} }
} }
@ -255,7 +256,7 @@ class LokiMessageAPI {
} }
if (Object.keys(ourSwarmNodes).length === 0) { if (Object.keys(ourSwarmNodes).length === 0) {
try { try {
ourSwarmNodes = await window.LokiSnodeAPI.getOurSwarmNodes(); ourSwarmNodes = await lokiSnodeAPI.getOurSwarmNodes();
// Filter out the nodes we have already got responses from // Filter out the nodes we have already got responses from
completedNodes.forEach(nodeUrl => delete ourSwarmNodes[nodeUrl]); completedNodes.forEach(nodeUrl => delete ourSwarmNodes[nodeUrl]);
} catch (e) { } catch (e) {
@ -277,7 +278,7 @@ class LokiMessageAPI {
} }
const remainingRequests = const remainingRequests =
MINIMUM_SUCCESSFUL_REQUESTS - completedNodes.length; MINIMUM_SUCCESSFUL_REQUESTS - successfulRequests;
await Promise.all( await Promise.all(
Object.entries(ourSwarmNodes) Object.entries(ourSwarmNodes)

@ -1,5 +1,5 @@
/* eslint-disable class-methods-use-this */ /* eslint-disable class-methods-use-this */
/* global log, window, Whisper */ /* global log, window, ConversationController */
const fetch = require('node-fetch'); const fetch = require('node-fetch');
const is = require('@sindresorhus/is'); const is = require('@sindresorhus/is');
@ -58,17 +58,11 @@ class LokiSnodeAPI {
if (this.contactSwarmNodes[nodeUrl].failureCount < FAILURE_THRESHOLD) { if (this.contactSwarmNodes[nodeUrl].failureCount < FAILURE_THRESHOLD) {
return false; return false;
} }
const conversation = window.ConversationController.get(pubKey); const conversation = ConversationController.get(pubKey);
const swarmNodes = conversation.get('swarmNodes'); const swarmNodes = [...conversation.get('swarmNodes')];
if (swarmNodes.delete(nodeUrl)) { if (nodeUrl in swarmNodes) {
conversation.set({ swarmNodes }); const filteredNodes = swarmNodes.filter(node => node !== nodeUrl);
await window.Signal.Data.updateConversation( await conversation.updateSwarmNodes(filteredNodes);
conversation.id,
conversation.attributes,
{
Conversation: Whisper.Conversation,
}
);
delete this.contactSwarmNodes[nodeUrl]; delete this.contactSwarmNodes[nodeUrl];
} }
return true; return true;
@ -84,6 +78,29 @@ class LokiSnodeAPI {
} }
} }
async getSwarmNodesForPubKey(pubKey) {
try {
const conversation = ConversationController.get(pubKey);
const swarmNodes = [...conversation.get('swarmNodes')];
return swarmNodes;
} catch (e) {
throw new window.textsecure.ReplayableError({
message: 'Could not get conversation',
});
}
}
async updateSwarmNodes(pubKey, newNodes) {
try {
const conversation = ConversationController.get(pubKey);
await conversation.updateSwarmNodes(newNodes);
} catch (e) {
throw new window.textsecure.ReplayableError({
message: 'Could not get conversation',
});
}
}
async getOurSwarmNodes() { async getOurSwarmNodes() {
if ( if (
!this.ourSwarmNodes || !this.ourSwarmNodes ||
@ -108,9 +125,7 @@ class LokiSnodeAPI {
async refreshSwarmNodesForPubKey(pubKey) { async refreshSwarmNodesForPubKey(pubKey) {
const newNodes = await this.getFreshSwarmNodes(pubKey); const newNodes = await this.getFreshSwarmNodes(pubKey);
await window.Signal.Data.saveSwarmNodesForPubKey(pubKey, newNodes, { this.updateSwarmNodes(pubKey, newNodes);
Conversation: Whisper.Conversation,
});
} }
async getFreshSwarmNodes(pubKey) { async getFreshSwarmNodes(pubKey) {
@ -121,6 +136,7 @@ class LokiSnodeAPI {
newSwarmNodes = await this.getSwarmNodes(pubKey); newSwarmNodes = await this.getSwarmNodes(pubKey);
} catch (e) { } catch (e) {
// TODO: Handle these errors sensibly // TODO: Handle these errors sensibly
log.error('Failed to get new swarm nodes');
newSwarmNodes = []; newSwarmNodes = [];
} }
resolve(newSwarmNodes); resolve(newSwarmNodes);

@ -288,7 +288,7 @@ window.WebAPI = initializeWebAPI({
const LokiSnodeAPI = require('./js/modules/loki_snode_api'); const LokiSnodeAPI = require('./js/modules/loki_snode_api');
window.LokiSnodeAPI = new LokiSnodeAPI({ window.lokiSnodeAPI = new LokiSnodeAPI({
url: config.serverUrl, url: config.serverUrl,
swarmServerPort: config.swarmServerPort, swarmServerPort: config.swarmServerPort,
}); });

Loading…
Cancel
Save