better seedNode error handling, getOnionRequestNumber(), getOnionPath() fixes

pull/1100/head
Ryan Tharp 5 years ago
parent b8ed019534
commit 1f9df11a0e

@ -23,8 +23,17 @@ const compareSnodes = (current, search) =>
// just get the filtered list // just get the filtered list
async function tryGetSnodeListFromLokidSeednode( async function tryGetSnodeListFromLokidSeednode(
seedNodes = [...window.seedNodeList] seedNodes = window.seedNodeList
) { ) {
if (!seedNodes.length) {
log.error(
`loki_snodes:::tryGetSnodeListFromLokidSeednode - no seedNodes given`,
seedNodes,
'window',
window.seedNodeList
);
return [];
}
// Removed limit until there is a way to get snode info // Removed limit until there is a way to get snode info
// for individual nodes (needed for guard nodes); this way // for individual nodes (needed for guard nodes); this way
// we get all active nodes // we get all active nodes
@ -42,6 +51,13 @@ async function tryGetSnodeListFromLokidSeednode(
Math.floor(Math.random() * seedNodes.length), Math.floor(Math.random() * seedNodes.length),
1 1
)[0]; )[0];
if (!seedNode) {
log.error(
`loki_snodes:::tryGetSnodeListFromLokidSeednode - seedNode selection failure - seedNodes`,
seedNodes
);
return [];
}
let snodes = []; let snodes = [];
try { try {
const getSnodesFromSeedUrl = async urlObj => { const getSnodesFromSeedUrl = async urlObj => {
@ -53,6 +69,30 @@ async function tryGetSnodeListFromLokidSeednode(
{}, // Options {}, // Options
'/json_rpc' // Seed request endpoint '/json_rpc' // Seed request endpoint
); );
if (!response) {
log.error(
`loki_snodes:::tryGetSnodeListFromLokidSeednode - invalid response from seed ${urlObj.toString()}:`,
response
);
return [];
}
// should we try to JSON.parse this?
if (typeof response === 'string') {
log.error(
`loki_snodes:::tryGetSnodeListFromLokidSeednode - invalid string response from seed ${urlObj.toString()}:`,
response
);
return [];
}
if (!response.result) {
log.error(
`loki_snodes:::tryGetSnodeListFromLokidSeednode - invalid result from seed ${urlObj.toString()}:`,
response
);
return [];
}
// Filter 0.0.0.0 nodes which haven't submitted uptime proofs // Filter 0.0.0.0 nodes which haven't submitted uptime proofs
return response.result.service_node_states.filter( return response.result.service_node_states.filter(
snode => snode.public_ip !== '0.0.0.0' snode => snode.public_ip !== '0.0.0.0'
@ -72,6 +112,13 @@ async function tryGetSnodeListFromLokidSeednode(
); );
} }
} }
if (snodes.length) {
log.info(
`loki_snodes:::tryGetSnodeListFromLokidSeednode - got ${
snodes.length
} service nodes from seed`
);
}
return snodes; return snodes;
} catch (e) { } catch (e) {
log.warn( log.warn(
@ -87,9 +134,18 @@ async function tryGetSnodeListFromLokidSeednode(
} }
async function getSnodeListFromLokidSeednode( async function getSnodeListFromLokidSeednode(
seedNodes = [...window.seedNodeList], seedNodes = window.seedNodeList,
retries = 0 retries = 0
) { ) {
if (!seedNodes.length) {
log.error(
`loki_snodes:::getSnodeListFromLokidSeednode - no seedNodes given`,
seedNodes,
'window',
window.seedNodeList
);
return [];
}
let snodes = []; let snodes = [];
try { try {
snodes = await tryGetSnodeListFromLokidSeednode(seedNodes); snodes = await tryGetSnodeListFromLokidSeednode(seedNodes);
@ -129,6 +185,12 @@ class LokiSnodeAPI {
this.onionPaths = []; this.onionPaths = [];
this.guardNodes = []; this.guardNodes = [];
this.onionRequestCounter = 0; // Request index for debugging
}
getOnionRequestNumber() {
this.onionRequestCounter += 1;
return this.onionRequestCounter;
} }
async getRandomSnodePool() { async getRandomSnodePool() {
@ -202,7 +264,7 @@ class LokiSnodeAPI {
// FIXME: handle rejections // FIXME: handle rejections
let nodePool = await this.getRandomSnodePool(); let nodePool = await this.getRandomSnodePool();
if (nodePool.length === 0) { if (nodePool.length === 0) {
log.error(`Could not select guarn nodes: node pool is empty`); log.error(`Could not select guard nodes: node pool is empty`);
return []; return [];
} }
@ -213,7 +275,7 @@ class LokiSnodeAPI {
const DESIRED_GUARD_COUNT = 3; const DESIRED_GUARD_COUNT = 3;
if (shuffled.length < DESIRED_GUARD_COUNT) { if (shuffled.length < DESIRED_GUARD_COUNT) {
log.error( log.error(
`Could not select guarn nodes: node pool is not big enough, pool size ${ `Could not select guard nodes: node pool is not big enough, pool size ${
shuffled.length shuffled.length
}, need ${DESIRED_GUARD_COUNT}, attempting to refresh randomPool` }, need ${DESIRED_GUARD_COUNT}, attempting to refresh randomPool`
); );
@ -222,7 +284,7 @@ class LokiSnodeAPI {
shuffled = _.shuffle(nodePool); shuffled = _.shuffle(nodePool);
if (shuffled.length < DESIRED_GUARD_COUNT) { if (shuffled.length < DESIRED_GUARD_COUNT) {
log.error( log.error(
`Could not select guarn nodes: node pool is not big enough, pool size ${ `Could not select guard nodes: node pool is not big enough, pool size ${
shuffled.length shuffled.length
}, need ${DESIRED_GUARD_COUNT}, failing...` }, need ${DESIRED_GUARD_COUNT}, failing...`
); );
@ -278,12 +340,15 @@ class LokiSnodeAPI {
`Must have at least 2 good onion paths, actual: ${goodPaths.length}` `Must have at least 2 good onion paths, actual: ${goodPaths.length}`
); );
await this.buildNewOnionPaths(); await this.buildNewOnionPaths();
// should we add a delay? buildNewOnionPaths should act as one
// reload goodPaths now
return this.getOnionPath(toExclude);
} }
const paths = _.shuffle(goodPaths); const paths = _.shuffle(goodPaths);
if (!toExclude) { if (!toExclude) {
return paths[0]; return paths[0].path;
} }
// Select a path that doesn't contain `toExclude` // Select a path that doesn't contain `toExclude`
@ -294,6 +359,19 @@ class LokiSnodeAPI {
if (otherPaths.length === 0) { if (otherPaths.length === 0) {
// This should never happen! // This should never happen!
// well it did happen, should we
// await this.buildNewOnionPaths();
// and restart call?
log.error(
`loki_snode_api::getOnionPath - no paths without`,
toExclude.pubkey_ed25519,
'path count',
paths.length,
'goodPath count',
goodPaths.length,
'paths',
paths
);
throw new Error('No onion paths available after filtering'); throw new Error('No onion paths available after filtering');
} }
@ -569,7 +647,17 @@ class LokiSnodeAPI {
); );
} }
async refreshRandomPool(seedNodes = [...window.seedNodeList]) { async refreshRandomPool(seedNodes = window.seedNodeList) {
if (!seedNodes.length) {
if (!window.seedNodeList || !window.seedNodeList.length) {
log.error(
`loki_snodes:::refreshRandomPool - seedNodeList has not been loaded yet`
);
return [];
}
// eslint-disable-next-line no-param-reassign
seedNodes = window.seedNodeList;
}
return primitives.allowOnlyOneAtATime('refreshRandomPool', async () => { return primitives.allowOnlyOneAtATime('refreshRandomPool', async () => {
// are we running any _getAllVerionsForRandomSnodePool // are we running any _getAllVerionsForRandomSnodePool
if (this.stopGetAllVersionPromiseControl !== false) { if (this.stopGetAllVersionPromiseControl !== false) {

Loading…
Cancel
Save