|
|
|
@ -27,11 +27,8 @@ async function tryGetSnodeListFromLokidSeednode(
|
|
|
|
|
seedNodes = window.seedNodeList
|
|
|
|
|
) {
|
|
|
|
|
if (!seedNodes.length) {
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_snodes:::tryGetSnodeListFromLokidSeednode - no seedNodes given`,
|
|
|
|
|
seedNodes,
|
|
|
|
|
'window',
|
|
|
|
|
window.seedNodeList
|
|
|
|
|
log.info(
|
|
|
|
|
'loki_snode_api::tryGetSnodeListFromLokidSeednode - seedNodes are empty'
|
|
|
|
|
);
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
@ -48,13 +45,10 @@ async function tryGetSnodeListFromLokidSeednode(
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
// FIXME: use sample
|
|
|
|
|
const seedNode = seedNodes.splice(
|
|
|
|
|
Math.floor(Math.random() * seedNodes.length),
|
|
|
|
|
1
|
|
|
|
|
)[0];
|
|
|
|
|
const seedNode = seedNodes[Math.floor(Math.random() * seedNodes.length)];
|
|
|
|
|
if (!seedNode) {
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_snodes:::tryGetSnodeListFromLokidSeednode - seedNode selection failure - seedNodes`,
|
|
|
|
|
log.warn(
|
|
|
|
|
'loki_snode_api::tryGetSnodeListFromLokidSeednode - Could not select random snodes from',
|
|
|
|
|
seedNodes
|
|
|
|
|
);
|
|
|
|
|
return [];
|
|
|
|
@ -72,7 +66,7 @@ async function tryGetSnodeListFromLokidSeednode(
|
|
|
|
|
);
|
|
|
|
|
if (!response) {
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_snodes:::tryGetSnodeListFromLokidSeednode - invalid response from seed ${urlObj.toString()}:`,
|
|
|
|
|
`loki_snode_api:::tryGetSnodeListFromLokidSeednode - invalid response from seed ${urlObj.toString()}:`,
|
|
|
|
|
response
|
|
|
|
|
);
|
|
|
|
|
return [];
|
|
|
|
@ -81,7 +75,7 @@ async function tryGetSnodeListFromLokidSeednode(
|
|
|
|
|
// should we try to JSON.parse this?
|
|
|
|
|
if (typeof response === 'string') {
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_snodes:::tryGetSnodeListFromLokidSeednode - invalid string response from seed ${urlObj.toString()}:`,
|
|
|
|
|
`loki_snode_api:::tryGetSnodeListFromLokidSeednode - invalid string response from seed ${urlObj.toString()}:`,
|
|
|
|
|
response
|
|
|
|
|
);
|
|
|
|
|
return [];
|
|
|
|
@ -89,7 +83,7 @@ async function tryGetSnodeListFromLokidSeednode(
|
|
|
|
|
|
|
|
|
|
if (!response.result) {
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_snodes:::tryGetSnodeListFromLokidSeednode - invalid result from seed ${urlObj.toString()}:`,
|
|
|
|
|
`loki_snode_api:::tryGetSnodeListFromLokidSeednode - invalid result from seed ${urlObj.toString()}:`,
|
|
|
|
|
response
|
|
|
|
|
);
|
|
|
|
|
return [];
|
|
|
|
@ -103,10 +97,17 @@ async function tryGetSnodeListFromLokidSeednode(
|
|
|
|
|
snodes = await getSnodesFromSeedUrl(tryUrl);
|
|
|
|
|
// throw before clearing the lock, so the retries can kick in
|
|
|
|
|
if (snodes.length === 0) {
|
|
|
|
|
log.warn(
|
|
|
|
|
`loki_snode_api::tryGetSnodeListFromLokidSeednode - ${seedNode.url} did not return any snodes, falling back to IP`,
|
|
|
|
|
seedNode.ip_url
|
|
|
|
|
);
|
|
|
|
|
// fall back on ip_url
|
|
|
|
|
const tryIpUrl = new URL(seedNode.ip_url);
|
|
|
|
|
snodes = await getSnodesFromSeedUrl(tryIpUrl);
|
|
|
|
|
if (snodes.length === 0) {
|
|
|
|
|
log.warn(
|
|
|
|
|
`loki_snode_api::tryGetSnodeListFromLokidSeednode - ${seedNode.ip_url} did not return any snodes`
|
|
|
|
|
);
|
|
|
|
|
// does this error message need to be exactly this?
|
|
|
|
|
throw new window.textsecure.SeedNodeError(
|
|
|
|
|
'Failed to contact seed node'
|
|
|
|
@ -115,15 +116,17 @@ async function tryGetSnodeListFromLokidSeednode(
|
|
|
|
|
}
|
|
|
|
|
if (snodes.length) {
|
|
|
|
|
log.info(
|
|
|
|
|
`loki_snodes:::tryGetSnodeListFromLokidSeednode - got ${snodes.length} service nodes from seed`
|
|
|
|
|
`loki_snode_api::tryGetSnodeListFromLokidSeednode - ${seedNode.url} returned ${snodes.length} snodes`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
return snodes;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.warn(
|
|
|
|
|
'loki_snodes:::tryGetSnodeListFromLokidSeednode - error',
|
|
|
|
|
'LokiSnodeAPI::tryGetSnodeListFromLokidSeednode - error',
|
|
|
|
|
e.code,
|
|
|
|
|
e.message
|
|
|
|
|
e.message,
|
|
|
|
|
'on',
|
|
|
|
|
seedNode
|
|
|
|
|
);
|
|
|
|
|
if (snodes.length === 0) {
|
|
|
|
|
throw new window.textsecure.SeedNodeError('Failed to contact seed node');
|
|
|
|
@ -137,11 +140,8 @@ async function getSnodeListFromLokidSeednode(
|
|
|
|
|
retries = 0
|
|
|
|
|
) {
|
|
|
|
|
if (!seedNodes.length) {
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_snodes:::getSnodeListFromLokidSeednode - no seedNodes given`,
|
|
|
|
|
seedNodes,
|
|
|
|
|
'window',
|
|
|
|
|
window.seedNodeList
|
|
|
|
|
log.info(
|
|
|
|
|
'loki_snode_api::getSnodeListFromLokidSeednode - seedNodes are empty'
|
|
|
|
|
);
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
@ -150,7 +150,7 @@ async function getSnodeListFromLokidSeednode(
|
|
|
|
|
snodes = await tryGetSnodeListFromLokidSeednode(seedNodes);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.warn(
|
|
|
|
|
'loki_snodes:::getSnodeListFromLokidSeednode - error',
|
|
|
|
|
'loki_snode_api::getSnodeListFromLokidSeednode - error',
|
|
|
|
|
e.code,
|
|
|
|
|
e.message
|
|
|
|
|
);
|
|
|
|
@ -158,13 +158,15 @@ async function getSnodeListFromLokidSeednode(
|
|
|
|
|
if (retries < SEED_NODE_RETRIES) {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
log.info(
|
|
|
|
|
'loki_snodes:::refreshRandomPoolPromise - Retrying initialising random snode pool, try #',
|
|
|
|
|
retries
|
|
|
|
|
'loki_snode_api::getSnodeListFromLokidSeednode - Retrying initialising random snode pool, try #',
|
|
|
|
|
retries,
|
|
|
|
|
'seed nodes total',
|
|
|
|
|
seedNodes.length
|
|
|
|
|
);
|
|
|
|
|
getSnodeListFromLokidSeednode(seedNodes, retries + 1);
|
|
|
|
|
}, retries * retries * 5000);
|
|
|
|
|
} else {
|
|
|
|
|
log.error('loki_snodes:::getSnodeListFromLokidSeednode - failing');
|
|
|
|
|
log.error('loki_snode_api::getSnodeListFromLokidSeednode - failing');
|
|
|
|
|
throw new window.textsecure.SeedNodeError('Failed to contact seed node');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -240,6 +242,8 @@ class LokiSnodeAPI {
|
|
|
|
|
let response;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// Log this line for testing
|
|
|
|
|
// curl -k -X POST -H 'Content-Type: application/json' -d '"+fetchOptions.body.replace(/"/g, "\\'")+"'", url
|
|
|
|
|
response = await nodeFetch(url, fetchOptions);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
if (e.type === 'request-timeout') {
|
|
|
|
@ -329,21 +333,32 @@ class LokiSnodeAPI {
|
|
|
|
|
async getOnionPath(toExclude = null) {
|
|
|
|
|
const _ = window.Lodash;
|
|
|
|
|
|
|
|
|
|
const goodPaths = this.onionPaths.filter(x => !x.bad);
|
|
|
|
|
let goodPaths = this.onionPaths.filter(x => !x.bad);
|
|
|
|
|
|
|
|
|
|
if (goodPaths.length < MIN_GUARD_COUNT) {
|
|
|
|
|
let attemptNumber = 0;
|
|
|
|
|
while (goodPaths.length < MIN_GUARD_COUNT) {
|
|
|
|
|
log.error(
|
|
|
|
|
`Must have at least 2 good onion paths, actual: ${goodPaths.length}`
|
|
|
|
|
`Must have at least 2 good onion paths, actual: ${goodPaths.length}, attempt #${attemptNumber} fetching more...`
|
|
|
|
|
);
|
|
|
|
|
// eslint-disable-next-line no-await-in-loop
|
|
|
|
|
await this.buildNewOnionPaths();
|
|
|
|
|
// should we add a delay? buildNewOnionPaths should act as one
|
|
|
|
|
|
|
|
|
|
// reload goodPaths now
|
|
|
|
|
return this.getOnionPath(toExclude);
|
|
|
|
|
attemptNumber += 1;
|
|
|
|
|
goodPaths = this.onionPaths.filter(x => !x.bad);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const paths = _.shuffle(goodPaths);
|
|
|
|
|
|
|
|
|
|
if (!toExclude) {
|
|
|
|
|
if (!paths[0]) {
|
|
|
|
|
log.error('LokiSnodeAPI::getOnionPath - no path in', paths);
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
if (!paths[0].path) {
|
|
|
|
|
log.error('LokiSnodeAPI::getOnionPath - no path in', paths[0]);
|
|
|
|
|
}
|
|
|
|
|
return paths[0].path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -359,7 +374,7 @@ class LokiSnodeAPI {
|
|
|
|
|
// await this.buildNewOnionPaths();
|
|
|
|
|
// and restart call?
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_snode_api::getOnionPath - no paths without`,
|
|
|
|
|
`LokiSnodeAPI::getOnionPath - no paths without`,
|
|
|
|
|
toExclude.pubkey_ed25519,
|
|
|
|
|
'path count',
|
|
|
|
|
paths.length,
|
|
|
|
@ -371,11 +386,21 @@ class LokiSnodeAPI {
|
|
|
|
|
throw new Error('No onion paths available after filtering');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!otherPaths[0].path) {
|
|
|
|
|
log.error(
|
|
|
|
|
'LokiSnodeAPI::getOnionPath - otherPaths no path in',
|
|
|
|
|
otherPaths[0]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return otherPaths[0].path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async markPathAsBad(path) {
|
|
|
|
|
markPathAsBad(path) {
|
|
|
|
|
this.onionPaths.forEach(p => {
|
|
|
|
|
if (!p.path) {
|
|
|
|
|
log.error('LokiSnodeAPI::markPathAsBad - no path in', p);
|
|
|
|
|
}
|
|
|
|
|
if (p.path === path) {
|
|
|
|
|
// eslint-disable-next-line no-param-reassign
|
|
|
|
|
p.bad = true;
|
|
|
|
@ -383,14 +408,14 @@ class LokiSnodeAPI {
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Does this get called multiple times on startup??
|
|
|
|
|
// FIXME: need a lock because it is being called multiple times in parallel
|
|
|
|
|
async buildNewOnionPaths() {
|
|
|
|
|
// Note: this function may be called concurrently, so
|
|
|
|
|
// might consider blocking the other calls
|
|
|
|
|
|
|
|
|
|
const _ = window.Lodash;
|
|
|
|
|
|
|
|
|
|
log.info('building new onion paths');
|
|
|
|
|
log.info('LokiSnodeAPI::buildNewOnionPaths - building new onion paths');
|
|
|
|
|
|
|
|
|
|
const allNodes = await this.getRandomSnodePool();
|
|
|
|
|
|
|
|
|
@ -399,7 +424,9 @@ class LokiSnodeAPI {
|
|
|
|
|
const nodes = await window.libloki.storage.getGuardNodes();
|
|
|
|
|
|
|
|
|
|
if (nodes.length === 0) {
|
|
|
|
|
log.warn('no guard nodes in DB. Will be selecting new guards nodes...');
|
|
|
|
|
log.warn(
|
|
|
|
|
'LokiSnodeAPI::buildNewOnionPaths - no guard nodes in DB. Will be selecting new guards nodes...'
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
// We only store the nodes' keys, need to find full entries:
|
|
|
|
|
const edKeys = nodes.map(x => x.ed25519PubKey);
|
|
|
|
@ -409,7 +436,7 @@ class LokiSnodeAPI {
|
|
|
|
|
|
|
|
|
|
if (this.guardNodes.length < edKeys.length) {
|
|
|
|
|
log.warn(
|
|
|
|
|
`could not find some guard nodes: ${this.guardNodes.length}/${edKeys.length} left`
|
|
|
|
|
`LokiSnodeAPI::buildNewOnionPaths - could not find some guard nodes: ${this.guardNodes.length}/${edKeys.length} left`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -425,7 +452,11 @@ class LokiSnodeAPI {
|
|
|
|
|
let otherNodes = _.difference(allNodes, this.guardNodes);
|
|
|
|
|
|
|
|
|
|
if (otherNodes.length < 2) {
|
|
|
|
|
log.error('Too few nodes to build an onion path!');
|
|
|
|
|
log.warn(
|
|
|
|
|
'LokiSnodeAPI::buildNewOnionPaths - Too few nodes to build an onion path! Refreshing pool and retrying'
|
|
|
|
|
);
|
|
|
|
|
await this.refreshRandomPool();
|
|
|
|
|
await this.buildNewOnionPaths();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -494,7 +525,7 @@ class LokiSnodeAPI {
|
|
|
|
|
await this.refreshRandomPool();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_snode:::getRandomProxySnodeAddress - error ${e.code} ${e.message}`
|
|
|
|
|
`LokiSnodeAPI::getRandomProxySnodeAddress - error ${e.code} ${e.message}`
|
|
|
|
|
);
|
|
|
|
|
throw e;
|
|
|
|
|
}
|
|
|
|
@ -506,7 +537,7 @@ class LokiSnodeAPI {
|
|
|
|
|
if (!goodPool.length) {
|
|
|
|
|
// FIXME: retry
|
|
|
|
|
log.warn(
|
|
|
|
|
`loki_snode:::getRandomProxySnodeAddress - no good versions yet`
|
|
|
|
|
`LokiSnodeAPI::getRandomProxySnodeAddress - no good versions yet`
|
|
|
|
|
);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
@ -538,7 +569,7 @@ class LokiSnodeAPI {
|
|
|
|
|
} else {
|
|
|
|
|
// maybe already marked bad...
|
|
|
|
|
log.debug(
|
|
|
|
|
`loki_snode:::_getVersion - can't find ${node.ip}:${node.port} in randomSnodePool`
|
|
|
|
|
`LokiSnodeAPI::_getVersion - can't find ${node.ip}:${node.port} in randomSnodePool`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -553,13 +584,13 @@ class LokiSnodeAPI {
|
|
|
|
|
const randomNodesLeft = this.getRandomPoolLength();
|
|
|
|
|
// clean up these error messages to be a little neater
|
|
|
|
|
log.warn(
|
|
|
|
|
`loki_snode:::_getVersion - ${node.ip}:${node.port} is offline, removing, leaving ${randomNodesLeft} in the randomPool`
|
|
|
|
|
`LokiSnodeAPI::_getVersion - ${node.ip}:${node.port} is offline, removing, leaving ${randomNodesLeft} in the randomPool`
|
|
|
|
|
);
|
|
|
|
|
// if not ECONNREFUSED, it's mostly ECONNRESETs
|
|
|
|
|
// ENOTFOUND could mean no internet or hiccup
|
|
|
|
|
} else if (retries < SNODE_VERSION_RETRIES) {
|
|
|
|
|
log.warn(
|
|
|
|
|
'loki_snode:::_getVersion - Error',
|
|
|
|
|
'LokiSnodeAPI::_getVersion - Error',
|
|
|
|
|
e.code,
|
|
|
|
|
e.message,
|
|
|
|
|
`on ${node.ip}:${node.port} retrying in 1s`
|
|
|
|
@ -570,7 +601,7 @@ class LokiSnodeAPI {
|
|
|
|
|
this.markRandomNodeUnreachable(node);
|
|
|
|
|
const randomNodesLeft = this.getRandomPoolLength();
|
|
|
|
|
log.warn(
|
|
|
|
|
`loki_snode:::_getVersion - failing to get version for ${node.ip}:${node.port}, removing, leaving ${randomNodesLeft} in the randomPool`
|
|
|
|
|
`LokiSnodeAPI::_getVersion - failing to get version for ${node.ip}:${node.port}, removing, leaving ${randomNodesLeft} in the randomPool`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
// maybe throw?
|
|
|
|
@ -596,19 +627,19 @@ class LokiSnodeAPI {
|
|
|
|
|
// give stats
|
|
|
|
|
const diff = Date.now() - verionStart;
|
|
|
|
|
log.debug(
|
|
|
|
|
`loki_snode:::_getAllVerionsForRandomSnodePool - ${count}/${total} pool version status update, has taken ${diff.toLocaleString()}ms`
|
|
|
|
|
`LokiSnodeAPI:::_getAllVerionsForRandomSnodePool - ${count}/${total} pool version status update, has taken ${diff.toLocaleString()}ms`
|
|
|
|
|
);
|
|
|
|
|
Object.keys(this.versionPools).forEach(version => {
|
|
|
|
|
const nodes = this.versionPools[version].length;
|
|
|
|
|
log.debug(
|
|
|
|
|
`loki_snode:::_getAllVerionsForRandomSnodePool - version ${version} has ${nodes.toLocaleString()} snodes`
|
|
|
|
|
`LokiSnodeAPI:::_getAllVerionsForRandomSnodePool - version ${version} has ${nodes.toLocaleString()} snodes`
|
|
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
*/
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_snode:::_getAllVerionsForRandomSnodePool - error`,
|
|
|
|
|
`LokiSnodeAPI::_getAllVerionsForRandomSnodePool - error`,
|
|
|
|
|
e.code,
|
|
|
|
|
e.message
|
|
|
|
|
);
|
|
|
|
@ -628,7 +659,7 @@ class LokiSnodeAPI {
|
|
|
|
|
return curVal;
|
|
|
|
|
}, []);
|
|
|
|
|
log.debug(
|
|
|
|
|
`loki_snode:::_getAllVerionsForRandomSnodePool - ${versions.length} versions retrieved from network!:`,
|
|
|
|
|
`LokiSnodeAPI::_getAllVerionsForRandomSnodePool - ${versions.length} versions retrieved from network!:`,
|
|
|
|
|
versions.join(',')
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
@ -637,7 +668,7 @@ class LokiSnodeAPI {
|
|
|
|
|
if (!seedNodes.length) {
|
|
|
|
|
if (!window.seedNodeList || !window.seedNodeList.length) {
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_snodes:::refreshRandomPool - seedNodeList has not been loaded yet`
|
|
|
|
|
`LokiSnodeAPI:::refreshRandomPool - seedNodeList has not been loaded yet`
|
|
|
|
|
);
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
@ -664,17 +695,17 @@ class LokiSnodeAPI {
|
|
|
|
|
pubkey_ed25519: snode.pubkey_ed25519,
|
|
|
|
|
}));
|
|
|
|
|
log.info(
|
|
|
|
|
'loki_snodes:::refreshRandomPool - Refreshed random snode pool with',
|
|
|
|
|
'LokiSnodeAPI::refreshRandomPool - Refreshed random snode pool with',
|
|
|
|
|
this.randomSnodePool.length,
|
|
|
|
|
'snodes'
|
|
|
|
|
);
|
|
|
|
|
// start polling versions but no need to await it
|
|
|
|
|
this._getAllVerionsForRandomSnodePool();
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.warn('loki_snodes:::refreshRandomPool - error', e.code, e.message);
|
|
|
|
|
log.warn('LokiSnodeAPI::refreshRandomPool - error', e.code, e.message);
|
|
|
|
|
/*
|
|
|
|
|
log.error(
|
|
|
|
|
'loki_snodes:::refreshRandomPoolPromise - Giving up trying to contact seed node'
|
|
|
|
|
'LokiSnodeAPI:::refreshRandomPoolPromise - Giving up trying to contact seed node'
|
|
|
|
|
);
|
|
|
|
|
*/
|
|
|
|
|
if (snodes.length === 0) {
|
|
|
|
@ -693,7 +724,7 @@ class LokiSnodeAPI {
|
|
|
|
|
const swarmNodes = [...conversation.get('swarmNodes')];
|
|
|
|
|
if (typeof unreachableNode === 'string') {
|
|
|
|
|
log.warn(
|
|
|
|
|
'loki_snodes:::unreachableNode - String passed as unreachableNode to unreachableNode'
|
|
|
|
|
'LokiSnodeAPI::unreachableNode - String passed as unreachableNode to unreachableNode'
|
|
|
|
|
);
|
|
|
|
|
return swarmNodes;
|
|
|
|
|
}
|
|
|
|
@ -710,13 +741,13 @@ class LokiSnodeAPI {
|
|
|
|
|
});
|
|
|
|
|
if (!found) {
|
|
|
|
|
log.warn(
|
|
|
|
|
`loki_snodes:::unreachableNode - snode ${unreachableNode.ip}:${unreachableNode.port} has already been marked as bad`
|
|
|
|
|
`LokiSnodeAPI::unreachableNode - snode ${unreachableNode.ip}:${unreachableNode.port} has already been marked as bad`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
await conversation.updateSwarmNodes(filteredNodes);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.error(`loki_snodes:::unreachableNode - error ${e.code} ${e.message}`);
|
|
|
|
|
log.error(`LokiSnodeAPI::unreachableNode - error ${e.code} ${e.message}`);
|
|
|
|
|
throw e;
|
|
|
|
|
}
|
|
|
|
|
return filteredNodes;
|
|
|
|
@ -754,7 +785,7 @@ class LokiSnodeAPI {
|
|
|
|
|
node.address
|
|
|
|
|
);
|
|
|
|
|
log.debug(
|
|
|
|
|
`loki_snode:::getSwarmNodesForPubKey - ${j} ${node.ip}:${node.port}`
|
|
|
|
|
`LokiSnodeAPI::getSwarmNodesForPubKey - ${j} ${node.ip}:${node.port}`
|
|
|
|
|
);
|
|
|
|
|
swarmNodes[j] = {
|
|
|
|
|
...node,
|
|
|
|
@ -781,7 +812,7 @@ class LokiSnodeAPI {
|
|
|
|
|
return filteredNodes;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.error(
|
|
|
|
|
`loki_snodes:::updateSwarmNodes - error ${e.code} ${e.message}`
|
|
|
|
|
`LokiSnodeAPI::updateSwarmNodes - error ${e.code} ${e.message}`
|
|
|
|
|
);
|
|
|
|
|
throw new window.textsecure.ReplayableError({
|
|
|
|
|
message: 'Could not get conversation',
|
|
|
|
@ -794,6 +825,10 @@ class LokiSnodeAPI {
|
|
|
|
|
async refreshSwarmNodesForPubKey(pubKey) {
|
|
|
|
|
// FIXME: handle rejections
|
|
|
|
|
const newNodes = await this._getFreshSwarmNodes(pubKey);
|
|
|
|
|
log.debug(
|
|
|
|
|
'LokiSnodeAPI::refreshSwarmNodesForPubKey - newNodes',
|
|
|
|
|
newNodes.length
|
|
|
|
|
);
|
|
|
|
|
const filteredNodes = this.updateSwarmNodes(pubKey, newNodes);
|
|
|
|
|
return filteredNodes;
|
|
|
|
|
}
|
|
|
|
@ -805,7 +840,7 @@ class LokiSnodeAPI {
|
|
|
|
|
newSwarmNodes = await this._getSwarmNodes(pubKey);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
log.error(
|
|
|
|
|
'loki_snodes:::_getFreshSwarmNodes - error',
|
|
|
|
|
'LokiSnodeAPI::_getFreshSwarmNodes - error',
|
|
|
|
|
e.code,
|
|
|
|
|
e.message
|
|
|
|
|
);
|
|
|
|
@ -960,7 +995,7 @@ class LokiSnodeAPI {
|
|
|
|
|
|
|
|
|
|
// get snodes for pubkey from random snode
|
|
|
|
|
async _getSnodesForPubkey(pubKey) {
|
|
|
|
|
let snode = {};
|
|
|
|
|
let snode = { ip: '', port: 0 };
|
|
|
|
|
try {
|
|
|
|
|
snode = await this.getRandomSnodeAddress();
|
|
|
|
|
const result = await lokiRpc(
|
|
|
|
@ -976,7 +1011,7 @@ class LokiSnodeAPI {
|
|
|
|
|
);
|
|
|
|
|
if (!result) {
|
|
|
|
|
log.warn(
|
|
|
|
|
`loki_snode:::_getSnodesForPubkey - lokiRpc on ${snode.ip}:${snode.port} returned falsish value`,
|
|
|
|
|
`LokiSnodeAPI::_getSnodesForPubkey - lokiRpc on ${snode.ip}:${snode.port} returned falsish value`,
|
|
|
|
|
result
|
|
|
|
|
);
|
|
|
|
|
return [];
|
|
|
|
@ -984,7 +1019,7 @@ class LokiSnodeAPI {
|
|
|
|
|
if (!result.snodes) {
|
|
|
|
|
// we hit this when snode gives 500s
|
|
|
|
|
log.warn(
|
|
|
|
|
`loki_snode:::_getSnodesForPubkey - lokiRpc on ${snode.ip}:${snode.port} returned falsish value for snodes`,
|
|
|
|
|
`LokiSnodeAPI::_getSnodesForPubkey - lokiRpc on ${snode.ip}:${snode.port} returned falsish value for snodes`,
|
|
|
|
|
result
|
|
|
|
|
);
|
|
|
|
|
return [];
|
|
|
|
@ -995,7 +1030,7 @@ class LokiSnodeAPI {
|
|
|
|
|
this.markRandomNodeUnreachable(snode);
|
|
|
|
|
const randomPoolRemainingCount = this.getRandomPoolLength();
|
|
|
|
|
log.error(
|
|
|
|
|
'loki_snodes:::_getSnodesForPubkey - error',
|
|
|
|
|
'LokiSnodeAPI::_getSnodesForPubkey - error',
|
|
|
|
|
e.code,
|
|
|
|
|
e.message,
|
|
|
|
|
`for ${snode.ip}:${snode.port}. ${randomPoolRemainingCount} snodes remaining in randomPool`
|
|
|
|
@ -1010,9 +1045,14 @@ class LokiSnodeAPI {
|
|
|
|
|
const questions = [...Array(RANDOM_SNODES_TO_USE_FOR_PUBKEY_SWARM).keys()];
|
|
|
|
|
// FIXME: handle rejections
|
|
|
|
|
await Promise.all(
|
|
|
|
|
questions.map(async () => {
|
|
|
|
|
questions.map(async qNum => {
|
|
|
|
|
// allow exceptions to pass through upwards
|
|
|
|
|
const resList = await this._getSnodesForPubkey(pubKey);
|
|
|
|
|
log.info(
|
|
|
|
|
`LokiSnodeAPI::_getSwarmNodes - question ${qNum} got`,
|
|
|
|
|
resList.length,
|
|
|
|
|
'snodes'
|
|
|
|
|
);
|
|
|
|
|
resList.map(item => {
|
|
|
|
|
const hasItem = snodes.some(n => compareSnodes(n, item));
|
|
|
|
|
if (!hasItem) {
|
|
|
|
@ -1022,7 +1062,7 @@ class LokiSnodeAPI {
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
// should we only activate entries that are in all results?
|
|
|
|
|
// should we only activate entries that are in all results? yes
|
|
|
|
|
return snodes;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|