UNPKG

envio

Version:

A latency and sync speed optimized, developer friendly blockchain data indexer.

197 lines (184 loc) • 7.27 kB
// Generated by ReScript, PLEASE EDIT WITH CARE 'use strict'; var Belt_Array = require("rescript/lib/js/belt_Array.js"); var Belt_Option = require("rescript/lib/js/belt_Option.js"); function reorgDetectedToLogParams(reorgDetected, shouldRollbackOnReorg) { var scannedBlock = reorgDetected.scannedBlock; return { msg: "Blockchain reorg detected. " + ( shouldRollbackOnReorg ? "Initiating indexer rollback" : "NOT initiating indexer rollback due to configuration" ) + ".", blockNumber: scannedBlock.blockNumber, indexedBlockHash: scannedBlock.blockHash, receivedBlockHash: reorgDetected.receivedBlock.blockHash }; } function make(chainReorgCheckpoints, maxReorgDepth, shouldRollbackOnReorg) { var dataByBlockNumber = {}; Belt_Array.forEach(chainReorgCheckpoints, (function (block) { dataByBlockNumber[block.block_number] = { blockHash: block.block_hash, blockNumber: block.block_number }; })); return { shouldRollbackOnReorg: shouldRollbackOnReorg, maxReorgDepth: maxReorgDepth, dataByBlockNumber: dataByBlockNumber }; } function getDataByBlockNumberCopyInThreshold(param, currentBlockHeight) { var dataByBlockNumber = param.dataByBlockNumber; var ascBlockNumberKeys = Object.keys(dataByBlockNumber); var thresholdBlockNumber = currentBlockHeight - param.maxReorgDepth | 0; var copy = {}; for(var idx = 0 ,idx_finish = ascBlockNumberKeys.length; idx < idx_finish; ++idx){ var blockNumberKey = ascBlockNumberKeys[idx]; var scannedBlock = dataByBlockNumber[blockNumberKey]; var isInReorgThreshold = scannedBlock.blockNumber >= thresholdBlockNumber; if (isInReorgThreshold) { copy[blockNumberKey] = scannedBlock; } } return copy; } function registerReorgGuard(self, reorgGuard, currentBlockHeight) { var maxReorgDepth = self.maxReorgDepth; var shouldRollbackOnReorg = self.shouldRollbackOnReorg; var dataByBlockNumberCopyInThreshold = getDataByBlockNumberCopyInThreshold(self, currentBlockHeight); var prevRangeLastBlock = reorgGuard.prevRangeLastBlock; var rangeLastBlock = reorgGuard.rangeLastBlock; var scannedBlock = dataByBlockNumberCopyInThreshold[String(rangeLastBlock.blockNumber)]; var maybeReorgDetected; var exit = 0; if (scannedBlock !== undefined && scannedBlock.blockHash !== rangeLastBlock.blockHash) { maybeReorgDetected = { scannedBlock: scannedBlock, receivedBlock: rangeLastBlock }; } else { exit = 1; } if (exit === 1) { if (prevRangeLastBlock !== undefined) { var scannedBlock$1 = dataByBlockNumberCopyInThreshold[String(prevRangeLastBlock.blockNumber)]; maybeReorgDetected = scannedBlock$1 !== undefined && scannedBlock$1.blockHash !== prevRangeLastBlock.blockHash ? ({ scannedBlock: scannedBlock$1, receivedBlock: prevRangeLastBlock }) : undefined; } else { maybeReorgDetected = undefined; } } if (maybeReorgDetected !== undefined) { return [ shouldRollbackOnReorg ? self : make([], maxReorgDepth, shouldRollbackOnReorg), { TAG: "ReorgDetected", _0: maybeReorgDetected } ]; } else { dataByBlockNumberCopyInThreshold[String(rangeLastBlock.blockNumber)] = rangeLastBlock; if (prevRangeLastBlock !== undefined) { dataByBlockNumberCopyInThreshold[String(prevRangeLastBlock.blockNumber)] = prevRangeLastBlock; } return [ { shouldRollbackOnReorg: shouldRollbackOnReorg, maxReorgDepth: maxReorgDepth, dataByBlockNumber: dataByBlockNumberCopyInThreshold }, "NoReorg" ]; } } function getLatestValidScannedBlock(reorgDetection, blockNumbersAndHashes) { var verifiedDataByBlockNumber = {}; for(var idx = 0 ,idx_finish = blockNumbersAndHashes.length; idx < idx_finish; ++idx){ var blockData = blockNumbersAndHashes[idx]; verifiedDataByBlockNumber[String(blockData.blockNumber)] = blockData; } var ascBlockNumberKeys = Object.keys(verifiedDataByBlockNumber); var getPrevScannedBlockNumber = function (idx) { return Belt_Option.map(Belt_Array.get(ascBlockNumberKeys, idx - 1 | 0), (function (key) { return verifiedDataByBlockNumber[key].blockNumber; })); }; var _idx = 0; while(true) { var idx$1 = _idx; var blockNumberKey = Belt_Array.get(ascBlockNumberKeys, idx$1); if (blockNumberKey === undefined) { return getPrevScannedBlockNumber(idx$1); } var scannedBlock = reorgDetection.dataByBlockNumber[blockNumberKey]; if (scannedBlock === undefined) { return getPrevScannedBlockNumber(idx$1); } if (verifiedDataByBlockNumber[blockNumberKey].blockHash !== scannedBlock.blockHash) { return getPrevScannedBlockNumber(idx$1); } _idx = idx$1 + 1 | 0; continue ; }; } function rollbackToValidBlockNumber(param, blockNumber) { var dataByBlockNumber = param.dataByBlockNumber; var ascBlockNumberKeys = Object.keys(dataByBlockNumber); var newDataByBlockNumber = {}; var loop = function (_idx) { while(true) { var idx = _idx; var blockNumberKey = Belt_Array.get(ascBlockNumberKeys, idx); if (blockNumberKey === undefined) { return ; } var scannedBlock = dataByBlockNumber[blockNumberKey]; var shouldKeep = scannedBlock.blockNumber <= blockNumber; if (!shouldKeep) { return ; } newDataByBlockNumber[blockNumberKey] = scannedBlock; _idx = idx + 1 | 0; continue ; }; }; loop(0); return { shouldRollbackOnReorg: param.shouldRollbackOnReorg, maxReorgDepth: param.maxReorgDepth, dataByBlockNumber: newDataByBlockNumber }; } function getThresholdBlockNumbersBelowBlock(self, blockNumber, currentBlockHeight) { var arr = []; var ascBlockNumberKeys = Object.keys(self.dataByBlockNumber); var thresholdBlockNumber = currentBlockHeight - self.maxReorgDepth | 0; for(var idx = 0 ,idx_finish = ascBlockNumberKeys.length; idx < idx_finish; ++idx){ var blockNumberKey = ascBlockNumberKeys[idx]; var scannedBlock = self.dataByBlockNumber[blockNumberKey]; var isInReorgThreshold = scannedBlock.blockNumber >= thresholdBlockNumber; if (isInReorgThreshold && scannedBlock.blockNumber < blockNumber) { arr.push(scannedBlock.blockNumber); } } return arr; } function getHashByBlockNumber(reorgDetection, blockNumber) { var v = reorgDetection.dataByBlockNumber[blockNumber]; if (v !== undefined) { return v.blockHash; } else { return null; } } exports.reorgDetectedToLogParams = reorgDetectedToLogParams; exports.make = make; exports.getDataByBlockNumberCopyInThreshold = getDataByBlockNumberCopyInThreshold; exports.registerReorgGuard = registerReorgGuard; exports.getLatestValidScannedBlock = getLatestValidScannedBlock; exports.rollbackToValidBlockNumber = rollbackToValidBlockNumber; exports.getThresholdBlockNumbersBelowBlock = getThresholdBlockNumbersBelowBlock; exports.getHashByBlockNumber = getHashByBlockNumber; /* No side effect */