UNPKG

envio

Version:

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

391 lines (366 loc) • 17.5 kB
// Generated by ReScript, PLEASE EDIT WITH CARE 'use strict'; var Utils = require("./Utils.res.js"); var ChainMap = require("./ChainMap.res.js"); var Belt_Array = require("rescript/lib/js/belt_Array.js"); var FetchState = require("./FetchState.res.js"); var ReorgDetection = require("./ReorgDetection.res.js"); function getOrderedNextChain(fetchStates, batchSizePerChain) { var earliestChain; var earliestChainTimestamp = 0; var chainKeys = ChainMap.keys(fetchStates); for(var idx = 0 ,idx_finish = chainKeys.length - 1; idx <= idx_finish; ++idx){ var chain = chainKeys[idx]; var fetchState = ChainMap.get(fetchStates, chain); if (FetchState.isActivelyIndexing(fetchState)) { var batchSize = batchSizePerChain[chain]; var timestamp = FetchState.getTimestampAt(fetchState, batchSize !== undefined ? batchSize : 0); var earliestChain$1 = earliestChain; if (!(earliestChain$1 !== undefined && (timestamp > earliestChainTimestamp || timestamp === earliestChainTimestamp && chain > earliestChain$1.chainId))) { earliestChain = fetchState; earliestChainTimestamp = timestamp; } } } return earliestChain; } var immutableEmptyBatchSizePerChain = {}; function hasOrderedReadyItem(fetchStates) { var fetchState = getOrderedNextChain(fetchStates, immutableEmptyBatchSizePerChain); if (fetchState !== undefined) { return FetchState.hasReadyItem(fetchState); } else { return false; } } function hasUnorderedReadyItem(fetchStates) { return ChainMap.values(fetchStates).some(function (fetchState) { if (FetchState.isActivelyIndexing(fetchState)) { return FetchState.hasReadyItem(fetchState); } else { return false; } }); } function hasMultichainReadyItem(fetchStates, multichain) { if (multichain === "ordered") { return hasOrderedReadyItem(fetchStates); } else { return hasUnorderedReadyItem(fetchStates); } } function getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, fetchStateAfterBatch, batchSize) { if (chainBeforeBatch.progressBlockNumber < progressBlockNumberAfterBatch) { return { batchSize: batchSize, progressBlockNumber: progressBlockNumberAfterBatch, totalEventsProcessed: chainBeforeBatch.totalEventsProcessed + batchSize, fetchState: fetchStateAfterBatch, isProgressAtHeadWhenBatchCreated: progressBlockNumberAfterBatch >= chainBeforeBatch.sourceBlockNumber }; } } function getProgressedChainsById(chainsBeforeBatch, batchSizePerChain, progressBlockNumberPerChain) { var progressedChainsById = {}; Belt_Array.forEachU(ChainMap.values(chainsBeforeBatch), (function (chainBeforeBatch) { var fetchState = chainBeforeBatch.fetchState; var progressBlockNumber = progressBlockNumberPerChain[String(fetchState.chainId)]; var progressBlockNumberAfterBatch = progressBlockNumber !== undefined ? progressBlockNumber : chainBeforeBatch.progressBlockNumber; var batchSize = batchSizePerChain[String(fetchState.chainId)]; var progressedChain; if (batchSize !== undefined) { var leftItems = fetchState.buffer.slice(batchSize); progressedChain = getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, FetchState.updateInternal(fetchState, undefined, undefined, undefined, leftItems, undefined), batchSize); } else { progressedChain = getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, chainBeforeBatch.fetchState, 0); } if (progressedChain !== undefined) { progressedChainsById[chainBeforeBatch.fetchState.chainId] = progressedChain; return ; } })); return progressedChainsById; } function addReorgCheckpoints(prevCheckpointId, reorgDetection, fromBlockExclusive, toBlockExclusive, chainId, mutCheckpointIds, mutCheckpointChainIds, mutCheckpointBlockNumbers, mutCheckpointBlockHashes, mutCheckpointEventsProcessed) { if (!(reorgDetection.shouldRollbackOnReorg && !Utils.Dict.isEmpty(reorgDetection.dataByBlockNumber))) { return prevCheckpointId; } var prevCheckpointId$1 = prevCheckpointId; for(var blockNumber = fromBlockExclusive + 1 ,blockNumber_finish = toBlockExclusive - 1; blockNumber <= blockNumber_finish; ++blockNumber){ var hash = ReorgDetection.getHashByBlockNumber(reorgDetection, blockNumber); if (hash !== null) { var checkpointId = prevCheckpointId$1 + 1; prevCheckpointId$1 = checkpointId; mutCheckpointIds.push(checkpointId); mutCheckpointChainIds.push(chainId); mutCheckpointBlockNumbers.push(blockNumber); mutCheckpointBlockHashes.push(hash); mutCheckpointEventsProcessed.push(0); } } return prevCheckpointId$1; } function prepareOrderedBatch(checkpointIdBeforeBatch, chainsBeforeBatch, batchSizeTarget) { var totalBatchSize = 0; var isFinished = false; var prevCheckpointId = checkpointIdBeforeBatch; var mutBatchSizePerChain = {}; var mutProgressBlockNumberPerChain = {}; var fetchStates = ChainMap.map(chainsBeforeBatch, (function (chainBeforeBatch) { return chainBeforeBatch.fetchState; })); var items = []; var checkpointIds = []; var checkpointChainIds = []; var checkpointBlockNumbers = []; var checkpointBlockHashes = []; var checkpointEventsProcessed = []; while(totalBatchSize < batchSizeTarget && !isFinished) { var fetchState = getOrderedNextChain(fetchStates, mutBatchSizePerChain); if (fetchState !== undefined) { var chainBeforeBatch = ChainMap.get(chainsBeforeBatch, ChainMap.Chain.makeUnsafe(fetchState.chainId)); var batchSize = mutBatchSizePerChain[fetchState.chainId]; var itemsCountBefore = batchSize !== undefined ? batchSize : 0; var progressBlockNumber = mutProgressBlockNumberPerChain[fetchState.chainId]; var prevBlockNumber = progressBlockNumber !== undefined ? progressBlockNumber : chainBeforeBatch.progressBlockNumber; var newItemsCount = FetchState.getReadyItemsCount(fetchState, 1, itemsCountBefore); if (newItemsCount > 0) { var item0 = fetchState.buffer[itemsCountBefore]; var blockNumber = item0.blockNumber; var chainId = fetchState.chainId; var reorgDetection = chainBeforeBatch.reorgDetection; var prevCheckpointId$1 = prevCheckpointId; var tmp; if (reorgDetection.shouldRollbackOnReorg && !Utils.Dict.isEmpty(reorgDetection.dataByBlockNumber)) { var prevCheckpointId$2 = prevCheckpointId$1; for(var blockNumber$1 = prevBlockNumber + 1 ,blockNumber_finish = blockNumber - 1; blockNumber$1 <= blockNumber_finish; ++blockNumber$1){ var hash = ReorgDetection.getHashByBlockNumber(reorgDetection, blockNumber$1); if (hash !== null) { var checkpointId = prevCheckpointId$2 + 1; prevCheckpointId$2 = checkpointId; checkpointIds.push(checkpointId); checkpointChainIds.push(chainId); checkpointBlockNumbers.push(blockNumber$1); checkpointBlockHashes.push(hash); checkpointEventsProcessed.push(0); } } tmp = prevCheckpointId$2; } else { tmp = prevCheckpointId$1; } prevCheckpointId = tmp; var checkpointId$1 = prevCheckpointId + 1; items.push(item0); for(var idx = 1 ,idx_finish = newItemsCount - 1; idx <= idx_finish; ++idx){ items.push(fetchState.buffer[itemsCountBefore + idx]); } checkpointIds.push(checkpointId$1); checkpointChainIds.push(fetchState.chainId); checkpointBlockNumbers.push(blockNumber); checkpointBlockHashes.push(ReorgDetection.getHashByBlockNumber(chainBeforeBatch.reorgDetection, blockNumber)); checkpointEventsProcessed.push(newItemsCount); prevCheckpointId = checkpointId$1; totalBatchSize = totalBatchSize + newItemsCount; mutBatchSizePerChain[fetchState.chainId] = itemsCountBefore + newItemsCount; mutProgressBlockNumberPerChain[fetchState.chainId] = blockNumber; } else { var blockNumberAfterBatch = FetchState.bufferBlockNumber(fetchState); var chainId$1 = fetchState.chainId; var toBlockExclusive = blockNumberAfterBatch + 1; var reorgDetection$1 = chainBeforeBatch.reorgDetection; var prevCheckpointId$3 = prevCheckpointId; var tmp$1; if (reorgDetection$1.shouldRollbackOnReorg && !Utils.Dict.isEmpty(reorgDetection$1.dataByBlockNumber)) { var prevCheckpointId$4 = prevCheckpointId$3; for(var blockNumber$2 = prevBlockNumber + 1 ,blockNumber_finish$1 = toBlockExclusive - 1; blockNumber$2 <= blockNumber_finish$1; ++blockNumber$2){ var hash$1 = ReorgDetection.getHashByBlockNumber(reorgDetection$1, blockNumber$2); if (hash$1 !== null) { var checkpointId$2 = prevCheckpointId$4 + 1; prevCheckpointId$4 = checkpointId$2; checkpointIds.push(checkpointId$2); checkpointChainIds.push(chainId$1); checkpointBlockNumbers.push(blockNumber$2); checkpointBlockHashes.push(hash$1); checkpointEventsProcessed.push(0); } } tmp$1 = prevCheckpointId$4; } else { tmp$1 = prevCheckpointId$3; } prevCheckpointId = tmp$1; mutProgressBlockNumberPerChain[fetchState.chainId] = blockNumberAfterBatch; isFinished = true; } } else { isFinished = true; } }; return { totalBatchSize: totalBatchSize, items: items, progressedChainsById: getProgressedChainsById(chainsBeforeBatch, mutBatchSizePerChain, mutProgressBlockNumberPerChain), checkpointIds: checkpointIds, checkpointChainIds: checkpointChainIds, checkpointBlockNumbers: checkpointBlockNumbers, checkpointBlockHashes: checkpointBlockHashes, checkpointEventsProcessed: checkpointEventsProcessed }; } function prepareUnorderedBatch(checkpointIdBeforeBatch, chainsBeforeBatch, batchSizeTarget) { var preparedFetchStates = FetchState.sortForUnorderedBatch(ChainMap.values(chainsBeforeBatch).map(function (chainBeforeBatch) { return chainBeforeBatch.fetchState; }), batchSizeTarget); var chainIdx = 0; var preparedNumber = preparedFetchStates.length; var totalBatchSize = 0; var prevCheckpointId = checkpointIdBeforeBatch; var mutBatchSizePerChain = {}; var mutProgressBlockNumberPerChain = {}; var items = []; var checkpointIds = []; var checkpointChainIds = []; var checkpointBlockNumbers = []; var checkpointBlockHashes = []; var checkpointEventsProcessed = []; while(totalBatchSize < batchSizeTarget && chainIdx < preparedNumber) { var fetchState = preparedFetchStates[chainIdx]; var chainBatchSize = FetchState.getReadyItemsCount(fetchState, batchSizeTarget - totalBatchSize, 0); var chainBeforeBatch = ChainMap.get(chainsBeforeBatch, ChainMap.Chain.makeUnsafe(fetchState.chainId)); var prevBlockNumber = chainBeforeBatch.progressBlockNumber; if (chainBatchSize > 0) { for(var idx = 0 ,idx_finish = chainBatchSize - 1; idx <= idx_finish; ++idx){ var item = fetchState.buffer[idx]; var blockNumber = item.blockNumber; if (blockNumber !== prevBlockNumber) { var chainId = fetchState.chainId; var fromBlockExclusive = prevBlockNumber; var reorgDetection = chainBeforeBatch.reorgDetection; var prevCheckpointId$1 = prevCheckpointId; var tmp; if (reorgDetection.shouldRollbackOnReorg && !Utils.Dict.isEmpty(reorgDetection.dataByBlockNumber)) { var prevCheckpointId$2 = prevCheckpointId$1; for(var blockNumber$1 = fromBlockExclusive + 1 ,blockNumber_finish = blockNumber - 1; blockNumber$1 <= blockNumber_finish; ++blockNumber$1){ var hash = ReorgDetection.getHashByBlockNumber(reorgDetection, blockNumber$1); if (hash !== null) { var checkpointId = prevCheckpointId$2 + 1; prevCheckpointId$2 = checkpointId; checkpointIds.push(checkpointId); checkpointChainIds.push(chainId); checkpointBlockNumbers.push(blockNumber$1); checkpointBlockHashes.push(hash); checkpointEventsProcessed.push(0); } } tmp = prevCheckpointId$2; } else { tmp = prevCheckpointId$1; } prevCheckpointId = tmp; var checkpointId$1 = prevCheckpointId + 1; checkpointIds.push(checkpointId$1); checkpointChainIds.push(fetchState.chainId); checkpointBlockNumbers.push(blockNumber); checkpointBlockHashes.push(ReorgDetection.getHashByBlockNumber(chainBeforeBatch.reorgDetection, blockNumber)); checkpointEventsProcessed.push(1); prevBlockNumber = blockNumber; prevCheckpointId = checkpointId$1; } else { var lastIndex = checkpointEventsProcessed.length - 1; checkpointEventsProcessed[lastIndex] = checkpointEventsProcessed[lastIndex] + 1; } items.push(item); } totalBatchSize = totalBatchSize + chainBatchSize; mutBatchSizePerChain[fetchState.chainId] = chainBatchSize; } var progressBlockNumberAfterBatch = FetchState.getUnorderedMultichainProgressBlockNumberAt(fetchState, chainBatchSize); var chainId$1 = fetchState.chainId; var toBlockExclusive = progressBlockNumberAfterBatch + 1; var fromBlockExclusive$1 = prevBlockNumber; var reorgDetection$1 = chainBeforeBatch.reorgDetection; var prevCheckpointId$3 = prevCheckpointId; var tmp$1; if (reorgDetection$1.shouldRollbackOnReorg && !Utils.Dict.isEmpty(reorgDetection$1.dataByBlockNumber)) { var prevCheckpointId$4 = prevCheckpointId$3; for(var blockNumber$2 = fromBlockExclusive$1 + 1 ,blockNumber_finish$1 = toBlockExclusive - 1; blockNumber$2 <= blockNumber_finish$1; ++blockNumber$2){ var hash$1 = ReorgDetection.getHashByBlockNumber(reorgDetection$1, blockNumber$2); if (hash$1 !== null) { var checkpointId$2 = prevCheckpointId$4 + 1; prevCheckpointId$4 = checkpointId$2; checkpointIds.push(checkpointId$2); checkpointChainIds.push(chainId$1); checkpointBlockNumbers.push(blockNumber$2); checkpointBlockHashes.push(hash$1); checkpointEventsProcessed.push(0); } } tmp$1 = prevCheckpointId$4; } else { tmp$1 = prevCheckpointId$3; } prevCheckpointId = tmp$1; mutProgressBlockNumberPerChain[fetchState.chainId] = progressBlockNumberAfterBatch; chainIdx = chainIdx + 1; }; return { totalBatchSize: totalBatchSize, items: items, progressedChainsById: getProgressedChainsById(chainsBeforeBatch, mutBatchSizePerChain, mutProgressBlockNumberPerChain), checkpointIds: checkpointIds, checkpointChainIds: checkpointChainIds, checkpointBlockNumbers: checkpointBlockNumbers, checkpointBlockHashes: checkpointBlockHashes, checkpointEventsProcessed: checkpointEventsProcessed }; } function make(checkpointIdBeforeBatch, chainsBeforeBatch, multichain, batchSizeTarget) { var tmp; tmp = multichain === "ordered" ? ChainMap.size(chainsBeforeBatch) === 1 : true; if (tmp) { return prepareUnorderedBatch(checkpointIdBeforeBatch, chainsBeforeBatch, batchSizeTarget); } else { return prepareOrderedBatch(checkpointIdBeforeBatch, chainsBeforeBatch, batchSizeTarget); } } function findFirstEventBlockNumber(batch, chainId) { var idx = 0; var result; var checkpointsLength = batch.checkpointIds.length; while(idx < checkpointsLength && result === undefined) { var checkpointChainId = batch.checkpointChainIds[idx]; if (checkpointChainId === chainId && batch.checkpointEventsProcessed[idx] > 0) { result = batch.checkpointBlockNumbers[idx]; } else { idx = idx + 1; } }; return result; } function findLastEventItem(batch, chainId) { var idx = batch.items.length - 1; var result; while(idx >= 0 && result === undefined) { var item = batch.items[idx]; if (item.kind === 0 && item.chain === chainId) { result = item; } else { idx = idx - 1; } }; return result; } exports.getOrderedNextChain = getOrderedNextChain; exports.immutableEmptyBatchSizePerChain = immutableEmptyBatchSizePerChain; exports.hasOrderedReadyItem = hasOrderedReadyItem; exports.hasUnorderedReadyItem = hasUnorderedReadyItem; exports.hasMultichainReadyItem = hasMultichainReadyItem; exports.getProgressedChainsById = getProgressedChainsById; exports.addReorgCheckpoints = addReorgCheckpoints; exports.prepareOrderedBatch = prepareOrderedBatch; exports.prepareUnorderedBatch = prepareUnorderedBatch; exports.make = make; exports.findFirstEventBlockNumber = findFirstEventBlockNumber; exports.findLastEventItem = findLastEventItem; /* Utils Not a pure module */