From c27d1ef69ab91670ce35d03eaad451f9294d09f3 Mon Sep 17 00:00:00 2001 From: Beaudan Date: Thu, 30 May 2019 17:16:32 +1000 Subject: [PATCH] Clean some stuff in loki_rpc and get new difficulty from successful requests --- config/default.json | 2 +- js/modules/loki_message_api.js | 9 ++++- js/modules/loki_rpc.js | 74 +++++++++++++--------------------- 3 files changed, 38 insertions(+), 47 deletions(-) diff --git a/config/default.json b/config/default.json index 8429f2a80..c2b0f0e2f 100644 --- a/config/default.json +++ b/config/default.json @@ -5,7 +5,7 @@ "contentProxyUrl": "random.snode", "localServerPort": "8081", "snodeServerPort": "8080", - "defaultPoWDifficulty": "10", + "defaultPoWDifficulty": "100", "disableAutoUpdate": false, "updatesUrl": "https://updates2.signal.org/desktop", "updatesPublicKey": diff --git a/js/modules/loki_message_api.js b/js/modules/loki_message_api.js index 6ec02c117..e2354a94d 100644 --- a/js/modules/loki_message_api.js +++ b/js/modules/loki_message_api.js @@ -155,7 +155,14 @@ class LokiMessageAPI { while (successiveFailures < 3) { await sleepFor(successiveFailures * 500); try { - await rpc(`http://${url}`, this.snodeServerPort, 'store', params); + const result = await rpc(`http://${url}`, this.snodeServerPort, 'store', params); + + // Make sure we aren't doing too much PoW + const currentDifficulty = window.storage.get('PoWDifficulty', null); + const newDifficulty = result.difficulty; + if (!Number.isNaN(newDifficulty) && newDifficulty !== currentDifficulty) { + window.storage.put('PoWDifficulty', newDifficulty); + } return true; } catch (e) { log.warn('Loki send message:', e); diff --git a/js/modules/loki_rpc.js b/js/modules/loki_rpc.js index 7cc3c45b2..1f4b29f4c 100644 --- a/js/modules/loki_rpc.js +++ b/js/modules/loki_rpc.js @@ -6,6 +6,21 @@ const { parse } = require('url'); const LOKI_EPHEMKEY_HEADER = 'X-Loki-EphemKey'; const endpointBase = '/v1/storage_rpc'; +const decryptResponse = async (response, address) => { + try { + const ciphertext = await response.text(); + const plaintext = await libloki.crypto.snodeCipher.decrypt( + address, + ciphertext + ); + const result = plaintext === '' ? {} : JSON.parse(plaintext); + return result; + } catch (e) { + log.warn(`Could not decrypt response from ${address}`, e); + } + return {}; +} + // A small wrapper around node-fetch which deserializes response const fetch = async (url, options = {}) => { const timeout = options.timeout || 10000; @@ -39,72 +54,41 @@ const fetch = async (url, options = {}) => { method, }); + let result; + // Wrong swarm if (response.status === 421) { - let responseJson = await response.text(); - let newSwarm = []; if (doEncryptChannel) { - try { - responseJson = await libloki.crypto.snodeCipher.decrypt( - address, - responseJson - ); - } catch (e) { - log.warn(`Could not decrypt response from ${address}`, e); - } - } - try { - responseJson = responseJson === '' ? {} : JSON.parse(responseJson); - newSwarm = responseJson.snodes ? responseJson.snodes : []; - } catch (e) { - log.warn(`Could not parse string to json ${newSwarm}`, e); + result = decryptResponse(response, address); + } else { + result = await response.json(); } + const newSwarm = result.snodes ? result.snodes : []; throw new textsecure.WrongSwarmError(newSwarm); } + // Wrong PoW difficulty if (response.status === 402) { - let responseJson = await response.text(); if (doEncryptChannel) { - try { - responseJson = await libloki.crypto.snodeCipher.decrypt( - address, - responseJson - ); - } catch (e) { - log.warn(`Could not decrypt response from ${address}`, e); - } + result = decryptResponse(response, address); + } else { + result = await response.json(); } - try { - responseJson = responseJson === '' ? {} : JSON.parse(responseJson); - } catch (e) { - log.warn(`Could not parse string to json ${responseJson}`, e); - } - const newDifficulty = parseInt(responseJson.difficulty, 10); - throw new textsecure.WrongDifficultyError(newDifficulty); + const { difficulty } = result; + throw new textsecure.WrongDifficultyError(difficulty); } if (!response.ok) { throw new textsecure.HTTPError('Loki_rpc error', response); } - let result; if (response.headers.get('Content-Type') === 'application/json') { result = await response.json(); } else if (options.responseType === 'arraybuffer') { result = await response.buffer(); + } else if (doEncryptChannel) { + result = decryptResponse(response, address); } else { result = await response.text(); - if (doEncryptChannel) { - try { - result = await libloki.crypto.snodeCipher.decrypt(address, result); - } catch (e) { - log.warn(`Could not decrypt response from ${address}`, e); - } - try { - result = result === '' ? {} : JSON.parse(result); - } catch (e) { - log.warn(`Could not parse string to json ${result}`, e); - } - } } return result;