UNPKG

lisk-framework

Version:

Lisk blockchain application platform

80 lines 3.42 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Synchronizer = void 0; const assert = require("assert"); const lisk_utils_1 = require("@liskhq/lisk-utils"); const utils = require("./utils"); class Synchronizer { constructor({ logger, chainModule, blockExecutor, mechanisms = [] }) { assert(Array.isArray(mechanisms), 'mechanisms should be an array of mechanisms'); this.mechanisms = mechanisms; this.logger = logger; this.chainModule = chainModule; this.blockExecutor = blockExecutor; this._checkMechanismsInterfaces(); this._mutex = new lisk_utils_1.jobHandlers.Mutex(); } async init() { const isEmpty = await this.chainModule.dataAccess.isTempBlockEmpty(); if (!isEmpty) { try { await utils.restoreBlocksUponStartup(this.logger, this.chainModule, this.blockExecutor); } catch (err) { this.logger.error({ err: err }, 'Failed to restore blocks from temp table upon startup'); } } } async run(receivedBlock, peerId) { if (this._mutex.isLocked()) { this.logger.debug('Synchronizer is already running.'); return; } await this._mutex.runExclusive(async () => { assert(receivedBlock, 'A block must be provided to the Synchronizer in order to run'); this.logger.info({ blockId: receivedBlock.header.id, height: receivedBlock.header.height, generator: receivedBlock.header.generatorAddress.toString('hex'), }, 'Starting synchronizer'); this.blockExecutor.validate(receivedBlock); const validMechanism = await this._determineSyncMechanism(receivedBlock, peerId); if (!validMechanism) { this.logger.info({ blockId: receivedBlock.header.id }, 'Syncing mechanism could not be determined for the given block'); return; } this.logger.info(`Triggering: ${validMechanism.constructor.name}`); await validMechanism.run(receivedBlock, peerId); this.logger.info({ lastBlockHeight: this.chainModule.lastBlock.header.height, lastBlockID: this.chainModule.lastBlock.header.id, mechanism: validMechanism.constructor.name, }, 'Synchronization finished.'); }); } get isActive() { return this._mutex.isLocked(); } async stop() { for (const mechanism of this.mechanisms) { mechanism.stop(); } await this._mutex.acquire(); } async _determineSyncMechanism(receivedBlock, peerId) { for (const mechanism of this.mechanisms) { if (await mechanism.isValidFor(receivedBlock, peerId)) { return mechanism; } } return undefined; } _checkMechanismsInterfaces() { for (const mechanism of this.mechanisms) { assert(typeof mechanism.isValidFor === 'function', `Mechanism ${mechanism.constructor.name} should implement "isValidFor" method`); assert(typeof mechanism.run === 'function', `Mechanism ${mechanism.constructor.name} should implement "run" method`); } } } exports.Synchronizer = Synchronizer; //# sourceMappingURL=synchronizer.js.map