diff --git a/src/message.ts b/src/message.ts index 7142bc3..a40bd95 100644 --- a/src/message.ts +++ b/src/message.ts @@ -5,7 +5,9 @@ export function parseMessage(data: Data): Maybe { try { const message = JSON.parse(data.toString()); - if (message && typeof message.msg === 'string') { + if (message && typeof message.msg === 'string' && typeof message.ts === 'string') { + message.ts = new Date(message.ts); + return message; } } catch (_) { @@ -27,14 +29,14 @@ export function getBestBlock(message: Message): Maybe { } interface MessageBase { - ts: string, // Timestamp + ts: Date, level: 'INFO' | 'WARN', } export interface BestBlock { best: string, height: number, - ts: string, + ts: Date, } interface SystemConnected { diff --git a/src/node.ts b/src/node.ts index 5188c58..f919cf2 100644 --- a/src/node.ts +++ b/src/node.ts @@ -1,6 +1,9 @@ import * as WebSocket from 'ws'; +import { Maybe } from './maybe'; import { parseMessage, getBestBlock, Message, BestBlock } from './message'; +const BLOCK_TIME_HISTORY = 10; + export default class Node { private socket: WebSocket; private name: string; @@ -8,6 +11,8 @@ export default class Node { private implementation: string; private version: string; private height: number = 0; + private blockTimes: Array = new Array(BLOCK_TIME_HISTORY); + private lastBlockTime: Maybe = null; constructor(socket: WebSocket, name: string, config: string, implentation: string, version: string) { this.socket = socket; @@ -33,14 +38,46 @@ export default class Node { }); } - updateBestBlock(update: BestBlock) { - if (this.height < update.height) { - this.height = update.height; + private updateBestBlock(update: BestBlock) { + const { height, ts: time, best } = update; - console.log(`Best block for ${this.name} is ${this.height}`); + if (this.height < height) { + const blockTime = this.getBlockTime(time); + + this.height = height; + this.lastBlockTime = time; + this.blockTimes[height % BLOCK_TIME_HISTORY] = blockTime; + + console.log(`Best block for ${this.name} is ${this.height}, block time: ${blockTime / 1000}s, average: ${this.average / 1000}s`); } } + private getBlockTime(time: Date): number { + if (!this.lastBlockTime) { + return 0; + } + + return +time - +this.lastBlockTime; + } + + get average(): number { + let accounted = 0; + let sum = 0; + + for (const time of this.blockTimes) { + if (time) { + accounted += 1; + sum += time; + } + } + + if (accounted === 0) { + return 0; + } + + return sum / accounted; + } + static fromSocket(socket: WebSocket): Promise { return new Promise((resolve, reject) => { function cleanup() {