From 441fa147eb893801ab74a3f3434ec906e959ea58 Mon Sep 17 00:00:00 2001 From: Axel Chalon Date: Wed, 11 Jul 2018 16:28:47 +0200 Subject: [PATCH 1/4] Compute time drift (without nodeHealth) --- .../src/main/messages/index.js | 10 +++++-- .../fether-react/src/stores/healthStore.js | 22 +++++++++----- .../fether-react/src/stores/parityStore.js | 2 +- packages/parity-electron/README.md | 4 +++ packages/parity-electron/package.json | 3 +- packages/parity-electron/src/checkTime.ts | 10 +++++++ packages/parity-electron/src/index.ts | 1 + yarn.lock | 30 +++++++++++++++++++ 8 files changed, 71 insertions(+), 11 deletions(-) create mode 100644 packages/parity-electron/src/checkTime.ts diff --git a/packages/fether-electron/src/main/messages/index.js b/packages/fether-electron/src/main/messages/index.js index 42e9d3d6..d68c6fe3 100644 --- a/packages/fether-electron/src/main/messages/index.js +++ b/packages/fether-electron/src/main/messages/index.js @@ -3,7 +3,7 @@ // // SPDX-License-Identifier: BSD-3-Clause -import { signerNewToken } from '@parity/electron'; +import { signerNewToken, checkTime } from '@parity/electron'; import Pino from '../utils/pino'; @@ -24,10 +24,16 @@ export default async (mainWindow, event, action, ...args) => { mainWindow.setContentSize(width, Math.round(newHeight) + 2); break; } + case 'check-time': { + checkTime().then(t => { + event.sender.send('check-time-reply', t); + }); + break; + } case 'signer-new-token': { const token = await signerNewToken(); // Send back the token to the renderer process - event.sender.send('asynchronous-reply', token); + event.sender.send('signer-new-token-reply', token); break; } default: diff --git a/packages/fether-react/src/stores/healthStore.js b/packages/fether-react/src/stores/healthStore.js index a0457e85..3dc6a824 100644 --- a/packages/fether-react/src/stores/healthStore.js +++ b/packages/fether-react/src/stores/healthStore.js @@ -5,10 +5,13 @@ import { action, computed, observable } from 'mobx'; import BigNumber from 'bignumber.js'; -import { nodeHealth$, syncing$ } from '@parity/light.js'; +import isElectron from 'is-electron'; +import { nodeHealth$, syncing$ } from '@parity/light.js'; import parityStore from './parityStore'; +const electron = isElectron() ? window.require('electron') : null; + // List here all possible states of our health store. Each state can have a // payload. export const STATUS = { @@ -22,19 +25,28 @@ export const STATUS = { SYNCING: 'SYNCING' // Obvious }; +export const MAX_TIME_DRIFT = 10000; // seconds + export class HealthStore { @observable nodeHealth; @observable syncing; + @observable timeDrift; constructor () { nodeHealth$().subscribe(this.setNodeHealth); syncing$().subscribe(this.setSyncing); + + const { ipcRenderer } = electron; + ipcRenderer.send('asynchronous-message', 'check-time'); + ipcRenderer.once('check-time-reply', (_, {drift}) => { + this.timeDrift = drift; + }); } /** * Calculate the current status. * - * @return [Object{ status: StatusEnum, payload: Any}] - An object which + * @return {Object{ status: StatusEnum, payload: Any}} - An object which * represents the current status, with a custom payload. */ @computed @@ -133,11 +145,7 @@ export class HealthStore { return { status: STATUS.NOINTERNET, payload: message }; } - if ( - message.includes( - 'Your clock is not in sync. Detected difference is too big for the protocol to work' - ) - ) { + if (this.timeDrift !== undefined && this.timeDrift > MAX_TIME_DRIFT) { return { status: STATUS.CLOCKNOTSYNC, payload: message }; } diff --git a/packages/fether-react/src/stores/parityStore.js b/packages/fether-react/src/stores/parityStore.js index 0c026a06..78b830f9 100644 --- a/packages/fether-react/src/stores/parityStore.js +++ b/packages/fether-react/src/stores/parityStore.js @@ -94,7 +94,7 @@ export class ParityStore { // Request new token from Electron debug('Requesting new token.'); ipcRenderer.send('asynchronous-message', 'signer-new-token'); - ipcRenderer.once('asynchronous-reply', (_, token) => { + ipcRenderer.once('signer-new-token-reply', (_, token) => { if (!token) { return; } diff --git a/packages/parity-electron/README.md b/packages/parity-electron/README.md index 9b194f7e..b8a8db47 100644 --- a/packages/parity-electron/README.md +++ b/packages/parity-electron/README.md @@ -76,3 +76,7 @@ If Parity has been downloaded to Electron's `userData` folder, then it deletes t #### `signerNewToken(): Promise` Runs `parity signer new-token` and resolves with a new secure token to be used in a dapp. Rejects if no token could be extracted. + +#### `checkTime(): Promise` + +Use SNTP to check if the local clock is synchronized; return the time drift. \ No newline at end of file diff --git a/packages/parity-electron/package.json b/packages/parity-electron/package.json index fe706c2b..1809a99a 100644 --- a/packages/parity-electron/package.json +++ b/packages/parity-electron/package.json @@ -37,7 +37,8 @@ "command-exists": "^1.2.6", "debug": "^3.1.0", "electron-dl": "^1.11.0", - "promise-any": "^0.2.0" + "promise-any": "^0.2.0", + "sntp": "^3.0.1" }, "devDependencies": { "electron": "^2.0.2", diff --git a/packages/parity-electron/src/checkTime.ts b/packages/parity-electron/src/checkTime.ts new file mode 100644 index 00000000..b9371fb5 --- /dev/null +++ b/packages/parity-electron/src/checkTime.ts @@ -0,0 +1,10 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +const sntp = require('sntp'); + +export const checkTime = () => { + return sntp.time().then(({t}) => ({drift: t})); +} \ No newline at end of file diff --git a/packages/parity-electron/src/index.ts b/packages/parity-electron/src/index.ts index 3c8c1863..e287701a 100644 --- a/packages/parity-electron/src/index.ts +++ b/packages/parity-electron/src/index.ts @@ -7,6 +7,7 @@ import { CliObject, LoggerFunction } from './types'; import { setCli } from './utils/cli'; import { setLogger } from './utils/logger'; +export * from './checkTime'; export * from './getParityPath'; export * from './fetchParity'; export * from './isParityRunning'; diff --git a/yarn.lock b/yarn.lock index 67801d85..de316cfb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2540,6 +2540,19 @@ boom@2.x.x: dependencies: hoek "2.x.x" +boom@7.x.x: + version "7.2.0" + resolved "https://registry.yarnpkg.com/boom/-/boom-7.2.0.tgz#2bff24a55565767fde869ec808317eb10c48e966" + dependencies: + hoek "5.x.x" + +bounce@1.x.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/bounce/-/bounce-1.2.0.tgz#e3bac68c73fd256e38096551efc09f504873c8c8" + dependencies: + boom "7.x.x" + hoek "5.x.x" + boxen@^1.2.1: version "1.3.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b" @@ -5993,6 +6006,10 @@ hoek@2.x.x: version "2.16.3" resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" +hoek@5.x.x: + version "5.0.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-5.0.3.tgz#b71d40d943d0a95da01956b547f83c4a5b4a34ac" + hoist-non-react-statics@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz#aa448cf0986d55cc40773b17174b7dd066cb7cfb" @@ -10634,6 +10651,15 @@ sntp@1.x.x: dependencies: hoek "2.x.x" +sntp@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-3.0.1.tgz#1aa9088d3eb844ea8c0980fce1877884d4117d09" + dependencies: + boom "7.x.x" + bounce "1.x.x" + hoek "5.x.x" + teamwork "3.x.x" + sockjs-client@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.4.tgz#5babe386b775e4cf14e7520911452654016c8b12" @@ -11208,6 +11234,10 @@ tar@^4: safe-buffer "^5.1.2" yallist "^3.0.2" +teamwork@3.x.x: + version "3.0.1" + resolved "https://registry.yarnpkg.com/teamwork/-/teamwork-3.0.1.tgz#ff38c7161f41f8070b7813716eb6154036ece196" + temp-dir@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" -- GitLab From f05a32677dc26b42038486c63d0b6749c9a3b3e7 Mon Sep 17 00:00:00 2001 From: Axel Chalon Date: Wed, 11 Jul 2018 17:56:04 +0200 Subject: [PATCH 2/4] Grumbles --- package.json | 2 +- .../src/main/messages/index.js | 8 +++---- .../fether-react/src/stores/healthStore.js | 22 +++++++++++-------- packages/parity-electron/README.md | 2 +- .../parity-electron/src/checkClockSync.ts | 15 +++++++++++++ packages/parity-electron/src/checkTime.ts | 10 --------- packages/parity-electron/src/index.ts | 2 +- 7 files changed, 35 insertions(+), 26 deletions(-) create mode 100644 packages/parity-electron/src/checkClockSync.ts delete mode 100644 packages/parity-electron/src/checkTime.ts diff --git a/package.json b/package.json index 7d79472e..534ab12b 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "build-parity-electron": "cd packages/parity-electron && yarn build", "preelectron": "yarn build", "electron": "cd packages/fether-electron && yarn electron", - "lint": "semistandard 'packages/**/*.js' --parser babel-eslint", + "lint": "semistandard 'packages/**/*.js' 'packages/**/*.ts' --parser babel-eslint", "prepackage": "yarn build", "package": "cd packages/fether-electron && yarn package", "release": "cd packages/fether-electron && yarn release", diff --git a/packages/fether-electron/src/main/messages/index.js b/packages/fether-electron/src/main/messages/index.js index d68c6fe3..a2a1125c 100644 --- a/packages/fether-electron/src/main/messages/index.js +++ b/packages/fether-electron/src/main/messages/index.js @@ -3,7 +3,7 @@ // // SPDX-License-Identifier: BSD-3-Clause -import { signerNewToken, checkTime } from '@parity/electron'; +import { checkClockSync, signerNewToken } from '@parity/electron'; import Pino from '../utils/pino'; @@ -24,9 +24,9 @@ export default async (mainWindow, event, action, ...args) => { mainWindow.setContentSize(width, Math.round(newHeight) + 2); break; } - case 'check-time': { - checkTime().then(t => { - event.sender.send('check-time-reply', t); + case 'check-clock-sync': { + checkClockSync().then(t => { + event.sender.send('check-clock-sync-reply', t); }); break; } diff --git a/packages/fether-react/src/stores/healthStore.js b/packages/fether-react/src/stores/healthStore.js index 3dc6a824..869ca54a 100644 --- a/packages/fether-react/src/stores/healthStore.js +++ b/packages/fether-react/src/stores/healthStore.js @@ -8,6 +8,7 @@ import BigNumber from 'bignumber.js'; import isElectron from 'is-electron'; import { nodeHealth$, syncing$ } from '@parity/light.js'; + import parityStore from './parityStore'; const electron = isElectron() ? window.require('electron') : null; @@ -25,21 +26,19 @@ export const STATUS = { SYNCING: 'SYNCING' // Obvious }; -export const MAX_TIME_DRIFT = 10000; // seconds - export class HealthStore { @observable nodeHealth; @observable syncing; - @observable timeDrift; + @observable clockSync; - constructor () { + constructor() { nodeHealth$().subscribe(this.setNodeHealth); syncing$().subscribe(this.setSyncing); const { ipcRenderer } = electron; - ipcRenderer.send('asynchronous-message', 'check-time'); - ipcRenderer.once('check-time-reply', (_, {drift}) => { - this.timeDrift = drift; + ipcRenderer.send('asynchronous-message', 'check-clock-sync'); + ipcRenderer.once('check-clock-sync-reply', (_, clockSync) => { + this.setClockSync(clockSync); }); } @@ -50,7 +49,7 @@ export class HealthStore { * represents the current status, with a custom payload. */ @computed - get health () { + get health() { // Check download progress if (parityStore.downloadProgress > 0 && !parityStore.isParityRunning) { return { @@ -145,7 +144,7 @@ export class HealthStore { return { status: STATUS.NOINTERNET, payload: message }; } - if (this.timeDrift !== undefined && this.timeDrift > MAX_TIME_DRIFT) { + if (this.clockSync && this.clockSync.isSync) { return { status: STATUS.CLOCKNOTSYNC, payload: message }; } @@ -157,6 +156,11 @@ export class HealthStore { this.nodeHealth = nodeHealth; }; + @action + setClockSync = clockSync => { + this.clockSync = clockSync; + }; + @action setSyncing = syncing => { this.syncing = syncing; diff --git a/packages/parity-electron/README.md b/packages/parity-electron/README.md index b8a8db47..48f15512 100644 --- a/packages/parity-electron/README.md +++ b/packages/parity-electron/README.md @@ -77,6 +77,6 @@ If Parity has been downloaded to Electron's `userData` folder, then it deletes t Runs `parity signer new-token` and resolves with a new secure token to be used in a dapp. Rejects if no token could be extracted. -#### `checkTime(): Promise` +#### `checkClockSync(): Promise` Use SNTP to check if the local clock is synchronized; return the time drift. \ No newline at end of file diff --git a/packages/parity-electron/src/checkClockSync.ts b/packages/parity-electron/src/checkClockSync.ts new file mode 100644 index 00000000..09a8f940 --- /dev/null +++ b/packages/parity-electron/src/checkClockSync.ts @@ -0,0 +1,15 @@ +// Copyright 2015-2018 Parity Technologies (UK) Ltd. +// This file is part of Parity. +// +// SPDX-License-Identifier: BSD-3-Clause + +const sntp = require('sntp'); + +export const MAX_TIME_DRIFT = 10000; // seconds + +export const checkClockSync = () => { + return sntp.time().then(({ t: timeDrift }) => ({ + isSync: timeDrift < MAX_TIME_DRIFT, + timeDrift + })); +}; diff --git a/packages/parity-electron/src/checkTime.ts b/packages/parity-electron/src/checkTime.ts deleted file mode 100644 index b9371fb5..00000000 --- a/packages/parity-electron/src/checkTime.ts +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2015-2018 Parity Technologies (UK) Ltd. -// This file is part of Parity. -// -// SPDX-License-Identifier: BSD-3-Clause - -const sntp = require('sntp'); - -export const checkTime = () => { - return sntp.time().then(({t}) => ({drift: t})); -} \ No newline at end of file diff --git a/packages/parity-electron/src/index.ts b/packages/parity-electron/src/index.ts index e287701a..a7852aff 100644 --- a/packages/parity-electron/src/index.ts +++ b/packages/parity-electron/src/index.ts @@ -7,7 +7,7 @@ import { CliObject, LoggerFunction } from './types'; import { setCli } from './utils/cli'; import { setLogger } from './utils/logger'; -export * from './checkTime'; +export * from './checkClockSync'; export * from './getParityPath'; export * from './fetchParity'; export * from './isParityRunning'; -- GitLab From b00545078ccdca8bce12f354b013e83e58c3039e Mon Sep 17 00:00:00 2001 From: Axel Chalon Date: Thu, 12 Jul 2018 15:37:01 +0200 Subject: [PATCH 3/4] Grumbles; lint Fix lint error "Redundant use of `await` on a return value." --- packages/fether-react/src/stores/healthStore.js | 6 +++--- packages/parity-electron/src/checkClockSync.ts | 10 +++++----- packages/parity-electron/src/fetchParity.ts | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/fether-react/src/stores/healthStore.js b/packages/fether-react/src/stores/healthStore.js index 869ca54a..76860905 100644 --- a/packages/fether-react/src/stores/healthStore.js +++ b/packages/fether-react/src/stores/healthStore.js @@ -31,7 +31,7 @@ export class HealthStore { @observable syncing; @observable clockSync; - constructor() { + constructor () { nodeHealth$().subscribe(this.setNodeHealth); syncing$().subscribe(this.setSyncing); @@ -49,7 +49,7 @@ export class HealthStore { * represents the current status, with a custom payload. */ @computed - get health() { + get health () { // Check download progress if (parityStore.downloadProgress > 0 && !parityStore.isParityRunning) { return { @@ -144,7 +144,7 @@ export class HealthStore { return { status: STATUS.NOINTERNET, payload: message }; } - if (this.clockSync && this.clockSync.isSync) { + if (this.clockSync && this.clockSync.isClockSync) { return { status: STATUS.CLOCKNOTSYNC, payload: message }; } diff --git a/packages/parity-electron/src/checkClockSync.ts b/packages/parity-electron/src/checkClockSync.ts index 09a8f940..e98956f0 100644 --- a/packages/parity-electron/src/checkClockSync.ts +++ b/packages/parity-electron/src/checkClockSync.ts @@ -3,13 +3,13 @@ // // SPDX-License-Identifier: BSD-3-Clause -const sntp = require('sntp'); +const { time } = require('sntp'); -export const MAX_TIME_DRIFT = 10000; // seconds +export const MAX_TIME_DRIFT = 10000; // milliseconds -export const checkClockSync = () => { - return sntp.time().then(({ t: timeDrift }) => ({ - isSync: timeDrift < MAX_TIME_DRIFT, +export const checkClockSync : () => Promise<{isClockSync: boolean, timeDrift: number}> = () => { + return time().then(({ t: timeDrift }) => ({ + isClockSync: timeDrift < MAX_TIME_DRIFT, timeDrift })); }; diff --git a/packages/parity-electron/src/fetchParity.ts b/packages/parity-electron/src/fetchParity.ts index c10a8575..43414017 100644 --- a/packages/parity-electron/src/fetchParity.ts +++ b/packages/parity-electron/src/fetchParity.ts @@ -123,7 +123,7 @@ export const fetchParity = async ( await fsChmod(downloadPath, '755'); // Double-check that Parity exists now. - return await getParityPath(); + return getParityPath(); }, { retries: 3 -- GitLab From 70be242ef5c0f9f12ef98a87a70825d488bb204f Mon Sep 17 00:00:00 2001 From: Axel Chalon Date: Fri, 13 Jul 2018 14:55:16 +0200 Subject: [PATCH 4/4] Grumbles --- packages/fether-react/src/stores/healthStore.js | 9 +++++++++ packages/parity-electron/src/checkClockSync.ts | 9 +++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/packages/fether-react/src/stores/healthStore.js b/packages/fether-react/src/stores/healthStore.js index 76860905..435b8ffe 100644 --- a/packages/fether-react/src/stores/healthStore.js +++ b/packages/fether-react/src/stores/healthStore.js @@ -9,8 +9,10 @@ import isElectron from 'is-electron'; import { nodeHealth$, syncing$ } from '@parity/light.js'; +import Debug from '../utils/debug'; import parityStore from './parityStore'; +const debug = Debug('healthStore'); const electron = isElectron() ? window.require('electron') : null; // List here all possible states of our health store. Each state can have a @@ -35,6 +37,13 @@ export class HealthStore { nodeHealth$().subscribe(this.setNodeHealth); syncing$().subscribe(this.setSyncing); + if (!electron) { + debug( + 'Not in Electron, ignoring clock sync verification.' + ); + return; + } + const { ipcRenderer } = electron; ipcRenderer.send('asynchronous-message', 'check-clock-sync'); ipcRenderer.once('check-clock-sync-reply', (_, clockSync) => { diff --git a/packages/parity-electron/src/checkClockSync.ts b/packages/parity-electron/src/checkClockSync.ts index e98956f0..cf8b5eb1 100644 --- a/packages/parity-electron/src/checkClockSync.ts +++ b/packages/parity-electron/src/checkClockSync.ts @@ -3,13 +3,14 @@ // // SPDX-License-Identifier: BSD-3-Clause -const { time } = require('sntp'); +import { time } from 'sntp'; export const MAX_TIME_DRIFT = 10000; // milliseconds -export const checkClockSync : () => Promise<{isClockSync: boolean, timeDrift: number}> = () => { - return time().then(({ t: timeDrift }) => ({ +export const checkClockSync = async () => { + const { t: timeDrift }: { t: number } = await time(); + return { isClockSync: timeDrift < MAX_TIME_DRIFT, timeDrift - })); + }; }; -- GitLab