diff --git a/js/modules/loki_snode_api.js b/js/modules/loki_snode_api.js index 5f47bab8e..1176dbad6 100644 --- a/js/modules/loki_snode_api.js +++ b/js/modules/loki_snode_api.js @@ -25,6 +25,7 @@ class LokiSnodeAPI { this.swarmsPendingReplenish = {}; this.refreshRandomPoolPromise = false; this.versionPools = {}; + this.versionMap = {}; this.onionPaths = []; this.guardNodes = []; @@ -37,6 +38,10 @@ class LokiSnodeAPI { return this.randomSnodePool; } + getRandomPoolLength() { + return this.randomSnodePool.length; + } + async testGuardNode(snode) { log.info('Testing a candidate guard node ', snode); @@ -271,38 +276,52 @@ class LokiSnodeAPI { if (this.randomSnodePool.length === 0) { throw new window.textsecure.SeedNodeError('Invalid seed node response'); } - const goodVersions = Object.keys(this.versionPools).filter(version => { - return semver.gt(version, '2.0.1') - }) + const goodVersions = Object.keys(this.versionPools).filter(version => + semver.gt(version, '2.0.1') + ); if (!goodVersions.length) { return false; } - console.log('goodVersions', goodVersions); - const goodVersion = goodVersions[Math.floor(Math.random() * goodVersions.length)]; - console.log('goodVersion', goodVersion); + const goodVersion = + goodVersions[Math.floor(Math.random() * goodVersions.length)]; const pool = this.versionPools[goodVersion]; - console.log('poolsize', pool.length); - return pool[ - Math.floor(Math.random() * pool.length) - ]; + return pool[Math.floor(Math.random() * pool.length)]; } async getVersion(node, count, total) { try { process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; - const result = await nodeFetch(`https://${node.ip}:${node.port}/get_stats/v1`, { agent: snodeHttpsAgent }); + const result = await nodeFetch( + `https://${node.ip}:${node.port}/get_stats/v1`, + { agent: snodeHttpsAgent } + ); process.env.NODE_TLS_REJECT_UNAUTHORIZED = '1'; const data = await result.json(); - console.log(`${count}/${total} ${node.ip}:${node.port}`, 'is on', data.version); + log.info( + `${count}/${total} ${node.ip}:${node.port}`, + 'is on', + data.version + ); if (data.version) { if (this.versionPools[data.version] === undefined) { - this.versionPools[data.version] = [ node ]; + this.versionPools[data.version] = [node]; } else { this.versionPools[data.version].push(node); } + // set up reverse mapping for removal lookup + this.versionMap[`${node.ip}:${node.port}`] = data.version; } - } catch(e) { - console.log('loki_snode:::getVersion - Error', e.code, e.message); + } catch (e) { + this.markRandomNodeUnreachable(node); + const randomNodesLeft = this.getRandomPoolLength(); + log.warn( + 'loki_snode:::getVersion - Error', + e.code, + e.message, + `removing ${node.ip}:${ + node.port + } leaving ${randomNodesLeft} in the randomPool` + ); } } @@ -371,10 +390,10 @@ class LokiSnodeAPI { resolve(); let c = 0; const t = this.randomSnodePool.length; - for(let node of this.randomSnodePool) { + this.randomSnodePool.forEach(async node => { c += 1; await this.getVersion(node, c, t); - } + }); } catch (e) { log.warn( 'loki_snodes:::refreshRandomPoolPromise - error', @@ -465,16 +484,22 @@ class LokiSnodeAPI { } markRandomNodeUnreachable(snode) { + const snodeVersion = this.versionMap[`${snode.ip}:${snode.port}`]; + if (this.versionPools[snodeVersion]) { + this.versionPools[snodeVersion] = _.without( + this.versionPools[snodeVersion], + _.find(this.versionPools[snodeVersion], { + ip: snode.ip, + port: snode.port, + }) + ); + } this.randomSnodePool = _.without( this.randomSnodePool, _.find(this.randomSnodePool, { ip: snode.ip, port: snode.port }) ); } - getRandomPoolLength() { - return this.randomSnodePool.length; - } - async updateLastHash(snode, hash, expiresAt) { await window.Signal.Data.updateLastHash({ snode, hash, expiresAt }); }