Persist PoW difficulty and update if get response from snodes

pull/294/head
Beaudan 5 years ago
parent e9b1359bab
commit e520bf109a

@ -5,6 +5,7 @@
"contentProxyUrl": "random.snode",
"localServerPort": "8081",
"snodeServerPort": "8080",
"defaultPoWDifficulty": "10",
"disableAutoUpdate": false,
"updatesUrl": "https://updates2.signal.org/desktop",
"updatesPublicKey":

@ -233,6 +233,11 @@
window.libloki.api.sendOnlineBroadcastMessage(pubKey, isPing);
});
const currentPoWDifficulty = storage.get('PoWDifficulty', null);
if (!currentPoWDifficulty) {
storage.put('PoWDifficulty', window.getDefaultPoWDifficulty());
}
// These make key operations available to IPC handlers created in preload.js
window.Events = {
getDeviceName: () => textsecure.storage.user.getDeviceName(),

@ -164,6 +164,11 @@ class LokiMessageAPI {
await lokiSnodeAPI.updateSwarmNodes(params.pubKey, newSwarm);
this.sendingSwarmNodes[params.timestamp] = newSwarm;
return false;
} else if (e instanceof textsecure.WrongDifficultyError) {
const { newDifficulty } = e;
if (!Number.isNaN(newDifficulty)) {
window.storage.put('PoWDifficulty', newDifficulty);
}
} else if (e instanceof textsecure.NotFoundError) {
// TODO: Handle resolution error
successiveFailures += 1;

@ -40,23 +40,46 @@ const fetch = async (url, options = {}) => {
});
if (response.status === 421) {
let newSwarm = await response.text();
let responseJson = await response.text();
let newSwarm = [];
if (doEncryptChannel) {
try {
newSwarm = await libloki.crypto.snodeCipher.decrypt(
responseJson = await libloki.crypto.snodeCipher.decrypt(
address,
newSwarm
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);
}
throw new textsecure.WrongSwarmError(newSwarm);
}
if (response.status === 402) {
let responseJson = await response.text();
if (doEncryptChannel) {
try {
newSwarm = newSwarm === '' ? {} : JSON.parse(newSwarm);
responseJson = await libloki.crypto.snodeCipher.decrypt(
address,
responseJson
);
} catch (e) {
log.warn(`Could not parse string to json ${newSwarm}`, e);
log.warn(`Could not decrypt response from ${address}`, e);
}
}
throw new textsecure.WrongSwarmError(newSwarm);
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);
}
if (!response.ok) {

@ -47,7 +47,7 @@ function calcPoW(
pubKey,
data,
development,
nonceTrials = undefined,
difficulty = undefined,
increment = 1,
startNonce = 0
) {
@ -57,7 +57,7 @@ function calcPoW(
pubKey,
data,
development,
nonceTrials,
difficulty,
increment,
startNonce
);

@ -1,8 +1,8 @@
/* global dcodeIO, crypto, JSBI */
const NONCE_LEN = 8;
// Modify this value for difficulty scaling
const DEV_NONCE_TRIALS = 10;
const PROD_NONCE_TRIALS = 100;
const DEV_DIFFICULTY = 10;
const PROD_DIFFICULTY = 100;
const pow = {
// Increment Uint8Array nonce by '_increment' with carrying
@ -63,7 +63,7 @@ const pow = {
pubKey,
data,
development = false,
_nonceTrials = null,
_difficulty = null,
increment = 1,
startNonce = 0
) {
@ -74,9 +74,9 @@ const pow = {
).toArrayBuffer()
);
const nonceTrials =
_nonceTrials || (development ? DEV_NONCE_TRIALS : PROD_NONCE_TRIALS);
const target = pow.calcTarget(ttl, payload.length, nonceTrials);
const difficulty =
_difficulty || (development ? DEV_DIFFICULTY : PROD_DIFFICULTY);
const target = pow.calcTarget(ttl, payload.length, difficulty);
let nonce = new Uint8Array(NONCE_LEN);
nonce = pow.incrementNonce(nonce, startNonce); // initial value
@ -103,7 +103,7 @@ const pow = {
return pow.bufferToBase64(nonce);
},
calcTarget(ttl, payloadLen, nonceTrials = PROD_NONCE_TRIALS) {
calcTarget(ttl, payloadLen, difficulty = PROD_DIFFICULTY) {
// payloadLength + NONCE_LEN
const totalLen = JSBI.add(JSBI.BigInt(payloadLen), JSBI.BigInt(NONCE_LEN));
// ttl converted to seconds
@ -119,9 +119,9 @@ const pow = {
const innerFrac = JSBI.divide(ttlMult, two16);
// totalLen + innerFrac
const lenPlusInnerFrac = JSBI.add(totalLen, innerFrac);
// nonceTrials * lenPlusInnerFrac
// difficulty * lenPlusInnerFrac
const denominator = JSBI.multiply(
JSBI.BigInt(nonceTrials),
JSBI.BigInt(difficulty),
lenPlusInnerFrac
);
// 2^64 - 1

@ -3,7 +3,7 @@ let jobId = 0;
let currentTrace = 0;
let plotlyDiv;
const workers = [];
async function run(messageLength, numWorkers = 1, nonceTrials = 100, ttl = 72) {
async function run(messageLength, numWorkers = 1, difficulty = 100, ttl = 72) {
const timestamp = Math.floor(Date.now() / 1000);
const pubKey =
'05ec8635a07a13743516c7c9b3412f3e8252efb7fcaf67eb1615ffba62bebc6802';
@ -29,7 +29,7 @@ async function run(messageLength, numWorkers = 1, nonceTrials = 100, ttl = 72) {
pubKey,
data,
false,
nonceTrials,
difficulty,
increment,
index,
]);
@ -50,12 +50,12 @@ async function run(messageLength, numWorkers = 1, nonceTrials = 100, ttl = 72) {
async function runPoW({
iteration,
nonceTrials,
difficulty,
numWorkers,
messageLength = 50,
ttl = 72,
}) {
const name = `W:${numWorkers} - NT: ${nonceTrials} - L:${messageLength} - TTL:${ttl}`;
const name = `W:${numWorkers} - NT: ${difficulty} - L:${messageLength} - TTL:${ttl}`;
Plotly.addTraces(plotlyDiv, {
y: [],
type: 'box',
@ -64,7 +64,7 @@ async function runPoW({
});
for (let i = 0; i < iteration; i += 1) {
// eslint-disable-next-line no-await-in-loop
await run(messageLength, numWorkers, nonceTrials, ttl);
await run(messageLength, numWorkers, difficulty, ttl);
}
currentTrace += 1;
@ -86,9 +86,7 @@ function addPoint(duration) {
}
async function startMessageLengthRun() {
const iteration0 = parseFloat(document.getElementById('iteration0').value);
const nonceTrials0 = parseFloat(
document.getElementById('nonceTrials0').value
);
const difficulty0 = parseFloat(document.getElementById('difficulty0').value);
const numWorkers0 = parseFloat(document.getElementById('numWorkers0').value);
const messageLengthStart0 = parseFloat(
document.getElementById('messageLengthStart0').value
@ -108,7 +106,7 @@ async function startMessageLengthRun() {
// eslint-disable-next-line no-await-in-loop
await runPoW({
iteration: iteration0,
nonceTrials: nonceTrials0,
difficulty: difficulty0,
numWorkers: numWorkers0,
messageLength: l,
ttl: TTL0,
@ -117,9 +115,7 @@ async function startMessageLengthRun() {
}
async function startNumWorkerRun() {
const iteration1 = parseFloat(document.getElementById('iteration1').value);
const nonceTrials1 = parseFloat(
document.getElementById('nonceTrials1').value
);
const difficulty1 = parseFloat(document.getElementById('difficulty1').value);
const numWorkersStart1 = parseFloat(
document.getElementById('numWorkersStart1').value
);
@ -138,34 +134,34 @@ async function startNumWorkerRun() {
// eslint-disable-next-line no-await-in-loop
await runPoW({
iteration: iteration1,
nonceTrials: nonceTrials1,
difficulty: difficulty1,
numWorkers,
messageLength: messageLength1,
ttl: TTL1,
});
}
}
async function startNonceTrialsRun() {
async function startDifficultyRun() {
const iteration2 = parseFloat(document.getElementById('iteration2').value);
const messageLength2 = parseFloat(
document.getElementById('messageLength2').value
);
const numWorkers2 = parseFloat(document.getElementById('numWorkers2').value);
const nonceTrialsStart2 = parseFloat(
document.getElementById('nonceTrialsStart2').value
const difficultyStart2 = parseFloat(
document.getElementById('difficultyStart2').value
);
const nonceTrialsStop2 = parseFloat(
document.getElementById('nonceTrialsStop2').value
const difficultyStop2 = parseFloat(
document.getElementById('difficultyStop2').value
);
const nonceTrialsStep2 = parseFloat(
document.getElementById('nonceTrialsStep2').value
const difficultyStep2 = parseFloat(
document.getElementById('difficultyStep2').value
);
const TTL2 = parseFloat(document.getElementById('TTL2').value);
for (let n = nonceTrialsStart2; n < nonceTrialsStop2; n += nonceTrialsStep2) {
for (let n = difficultyStart2; n < difficultyStop2; n += difficultyStep2) {
// eslint-disable-next-line no-await-in-loop
await runPoW({
iteration: iteration2,
nonceTrials: n,
difficulty: n,
numWorkers: numWorkers2,
messageLength: messageLength2,
ttl: TTL2,
@ -174,9 +170,7 @@ async function startNonceTrialsRun() {
}
async function starTTLRun() {
const iteration3 = parseFloat(document.getElementById('iteration3').value);
const nonceTrials3 = parseFloat(
document.getElementById('nonceTrials3').value
);
const difficulty3 = parseFloat(document.getElementById('difficulty3').value);
const messageLength3 = parseFloat(
document.getElementById('messageLength3').value
);
@ -188,7 +182,7 @@ async function starTTLRun() {
// eslint-disable-next-line no-await-in-loop
await runPoW({
iteration: iteration3,
nonceTrials: nonceTrials3,
difficulty: difficulty3,
numWorkers: numWorkers3,
messageLength: messageLength3,
ttl,
@ -216,7 +210,7 @@ async function start(index) {
await startNumWorkerRun();
break;
case 2:
await startNonceTrialsRun();
await startDifficultyRun();
break;
case 3:
await starTTLRun();

@ -222,6 +222,19 @@
}
}
function WrongDifficultyError(newDifficulty) {
this.name = 'WrongDifficultyError';
this.newDifficulty = newDifficulty;
Error.call(this, this.name);
// Maintains proper stack trace, where our error was thrown (only available on V8)
// via https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
if (Error.captureStackTrace) {
Error.captureStackTrace(this);
}
}
window.textsecure.UnregisteredUserError = UnregisteredUserError;
window.textsecure.SendMessageNetworkError = SendMessageNetworkError;
window.textsecure.IncomingIdentityKeyError = IncomingIdentityKeyError;
@ -237,4 +250,5 @@
window.textsecure.HTTPError = HTTPError;
window.textsecure.NotFoundError = NotFoundError;
window.textsecure.WrongSwarmError = WrongSwarmError;
window.textsecure.WrongDifficultyError = WrongDifficultyError;
})();

@ -156,6 +156,7 @@ function prepareURL(pathSegments, moreKeys) {
cdnUrl: config.get('cdnUrl'),
snodeServerPort: config.get('snodeServerPort'),
localServerPort: config.get('localServerPort'),
defaultPoWDifficulty: config.get('defaultPoWDifficulty'),
certificateAuthority: config.get('certificateAuthority'),
environment: config.environment,
node_version: process.versions.node,

@ -22,6 +22,7 @@ if (config.appInstance) {
}
window.platform = process.platform;
window.getDefaultPoWDifficulty = () => config.defaultPoWDifficulty;
window.getTitle = () => title;
window.getEnvironment = () => config.environment;
window.getAppInstance = () => config.appInstance;

Loading…
Cancel
Save