put lock around buildNewOnionPaths since it's called multiple times

pull/1171/head
Ryan Tharp 5 years ago
parent 54ee9e3ad4
commit e2d5d9e793

@ -416,87 +416,87 @@ class LokiSnodeAPI {
});
}
// 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
// Note: this function may be called concurrently
const _ = window.Lodash;
log.info('LokiSnodeAPI::buildNewOnionPaths - building new onion paths');
return primitives.allowOnlyOneAtATime('buildNewOnionPaths', async () => {
const _ = window.Lodash;
const allNodes = await this.getRandomSnodePool();
log.info('LokiSnodeAPI::buildNewOnionPaths - building new onion paths');
if (this.guardNodes.length === 0) {
// Not cached, load from DB
const nodes = await window.libloki.storage.getGuardNodes();
const allNodes = await this.getRandomSnodePool();
if (nodes.length === 0) {
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);
this.guardNodes = allNodes.filter(
x => edKeys.indexOf(x.pubkey_ed25519) !== -1
);
if (this.guardNodes.length === 0) {
// Not cached, load from DB
const nodes = await window.libloki.storage.getGuardNodes();
if (this.guardNodes.length < edKeys.length) {
if (nodes.length === 0) {
log.warn(
`LokiSnodeAPI::buildNewOnionPaths - could not find some guard nodes: ${
this.guardNodes.length
}/${edKeys.length} left`
'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);
this.guardNodes = allNodes.filter(
x => edKeys.indexOf(x.pubkey_ed25519) !== -1
);
if (this.guardNodes.length < edKeys.length) {
log.warn(
`LokiSnodeAPI::buildNewOnionPaths - could not find some guard nodes: ${
this.guardNodes.length
}/${edKeys.length} left`
);
}
}
}
// If guard nodes is still empty (the old nodes are now invalid), select new ones:
if (this.guardNodes.length === 0) {
this.guardNodes = await this.selectGuardNodes();
// If guard nodes is still empty (the old nodes are now invalid), select new ones:
if (this.guardNodes.length === 0) {
this.guardNodes = await this.selectGuardNodes();
}
}
}
// TODO: select one guard node and 2 other nodes randomly
let otherNodes = _.difference(allNodes, this.guardNodes);
// TODO: select one guard node and 2 other nodes randomly
let otherNodes = _.difference(allNodes, this.guardNodes);
if (otherNodes.length < 2) {
log.warn(
'LokiSnodeAPI::buildNewOnionPaths - Too few nodes to build an onion path! Refreshing pool and retrying'
);
await this.refreshRandomPool();
await this.buildNewOnionPaths();
return;
}
if (otherNodes.length < 2) {
log.warn(
'LokiSnodeAPI::buildNewOnionPaths - Too few nodes to build an onion path! Refreshing pool and retrying'
);
await this.refreshRandomPool();
await this.buildNewOnionPaths();
return;
}
otherNodes = _.shuffle(otherNodes);
const guards = _.shuffle(this.guardNodes);
otherNodes = _.shuffle(otherNodes);
const guards = _.shuffle(this.guardNodes);
// Create path for every guard node:
const nodesNeededPerPaths = window.lokiFeatureFlags.onionRequestHops - 1;
// Create path for every guard node:
const nodesNeededPerPaths = window.lokiFeatureFlags.onionRequestHops - 1;
// Each path needs X (nodesNeededPerPaths) nodes in addition to the guard node:
const maxPath = Math.floor(
Math.min(
guards.length,
nodesNeededPerPaths
? otherNodes.length / nodesNeededPerPaths
: otherNodes.length
)
);
// Each path needs X (nodesNeededPerPaths) nodes in addition to the guard node:
const maxPath = Math.floor(
Math.min(
guards.length,
nodesNeededPerPaths
? otherNodes.length / nodesNeededPerPaths
: otherNodes.length
)
);
// TODO: might want to keep some of the existing paths
this.onionPaths = [];
// TODO: might want to keep some of the existing paths
this.onionPaths = [];
for (let i = 0; i < maxPath; i += 1) {
const path = [guards[i]];
for (let j = 0; j < nodesNeededPerPaths; j += 1) {
path.push(otherNodes[i * nodesNeededPerPaths + j]);
for (let i = 0; i < maxPath; i += 1) {
const path = [guards[i]];
for (let j = 0; j < nodesNeededPerPaths; j += 1) {
path.push(otherNodes[i * nodesNeededPerPaths + j]);
}
this.onionPaths.push({ path, bad: false });
}
this.onionPaths.push({ path, bad: false });
}
log.info(`Built ${this.onionPaths.length} onion paths`, this.onionPaths);
log.info(`Built ${this.onionPaths.length} onion paths`, this.onionPaths);
});
}
async getRandomSnodeAddress() {

Loading…
Cancel
Save