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