envio
Version:
A latency and sync speed optimized, developer friendly blockchain data indexer.
197 lines (184 loc) • 7.27 kB
JavaScript
// Generated by ReScript, PLEASE EDIT WITH CARE
;
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 */