envio
Version:
A latency and sync speed optimized, developer friendly blockchain data indexer.
221 lines (210 loc) • 9.61 kB
JavaScript
// Generated by ReScript, PLEASE EDIT WITH CARE
import * as Utils from "./Utils.res.mjs";
import * as ChainMap from "./ChainMap.res.mjs";
import * as FetchState from "./FetchState.res.mjs";
import * as ReorgDetection from "./ReorgDetection.res.mjs";
function hasReadyItem(fetchStates) {
return ChainMap.values(fetchStates).some(fetchState => {
if (FetchState.isActivelyIndexing(fetchState)) {
return FetchState.hasReadyItem(fetchState);
} else {
return false;
}
});
}
function getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, fetchStateAfterBatch, batchSize) {
if (chainBeforeBatch.progressBlockNumber < progressBlockNumberAfterBatch) {
return {
batchSize: batchSize,
progressBlockNumber: progressBlockNumberAfterBatch,
sourceBlockNumber: chainBeforeBatch.sourceBlockNumber,
totalEventsProcessed: chainBeforeBatch.totalEventsProcessed + batchSize,
fetchState: fetchStateAfterBatch,
isProgressAtHeadWhenBatchCreated: progressBlockNumberAfterBatch >= chainBeforeBatch.sourceBlockNumber - chainBeforeBatch.chainConfig.blockLag
};
}
}
function getProgressedChainsById(chainsBeforeBatch, batchSizePerChain, progressBlockNumberPerChain) {
let progressedChainsById = {};
ChainMap.values(chainsBeforeBatch).forEach(chainBeforeBatch => {
let fetchState = chainBeforeBatch.fetchState;
let progressBlockNumber = progressBlockNumberPerChain[fetchState.chainId.toString()];
let progressBlockNumberAfterBatch = progressBlockNumber !== undefined ? progressBlockNumber : chainBeforeBatch.progressBlockNumber;
let batchSize = batchSizePerChain[fetchState.chainId.toString()];
let progressedChain;
if (batchSize !== undefined) {
let leftItems = fetchState.buffer.slice(batchSize);
progressedChain = getChainAfterBatchIfProgressed(chainBeforeBatch, progressBlockNumberAfterBatch, FetchState.updateInternal(fetchState, undefined, undefined, leftItems, undefined, 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;
}
let prevCheckpointId$1 = prevCheckpointId;
for (let blockNumber = fromBlockExclusive + 1, blockNumber_finish = toBlockExclusive - 1; blockNumber <= blockNumber_finish; ++blockNumber) {
let hash = ReorgDetection.getHashByBlockNumber(reorgDetection, blockNumber);
if (hash !== null) {
let checkpointId = prevCheckpointId$1 + 1n;
prevCheckpointId$1 = checkpointId;
mutCheckpointIds.push(checkpointId);
mutCheckpointChainIds.push(chainId);
mutCheckpointBlockNumbers.push(blockNumber);
mutCheckpointBlockHashes.push(hash);
mutCheckpointEventsProcessed.push(0);
}
}
return prevCheckpointId$1;
}
function prepareBatch(checkpointIdBeforeBatch, chainsBeforeBatch, batchSizeTarget, isInReorgThreshold) {
let preparedFetchStates = FetchState.sortForUnorderedBatch(ChainMap.values(chainsBeforeBatch).map(chainBeforeBatch => chainBeforeBatch.fetchState), batchSizeTarget);
let chainIdx = 0;
let preparedNumber = preparedFetchStates.length;
let totalBatchSize = 0;
let prevCheckpointId = checkpointIdBeforeBatch;
let mutBatchSizePerChain = {};
let mutProgressBlockNumberPerChain = {};
let items = [];
let checkpointIds = [];
let checkpointChainIds = [];
let checkpointBlockNumbers = [];
let checkpointBlockHashes = [];
let checkpointEventsProcessed = [];
while (totalBatchSize < batchSizeTarget && chainIdx < preparedNumber) {
let fetchState = preparedFetchStates[chainIdx];
let chainBatchSize = FetchState.getReadyItemsCount(fetchState, batchSizeTarget - totalBatchSize, 0);
let chainBeforeBatch = ChainMap.get(chainsBeforeBatch, ChainMap.Chain.makeUnsafe(fetchState.chainId));
let prevBlockNumber = chainBeforeBatch.progressBlockNumber;
if (chainBatchSize > 0) {
for (let idx = 0, idx_finish = chainBatchSize - 1; idx <= idx_finish; ++idx) {
let item = fetchState.buffer[idx];
let blockNumber = item.blockNumber;
if (blockNumber !== prevBlockNumber) {
let chainId = fetchState.chainId;
let fromBlockExclusive = prevBlockNumber;
let reorgDetection = chainBeforeBatch.reorgDetection;
let prevCheckpointId$1 = prevCheckpointId;
let tmp;
if (reorgDetection.shouldRollbackOnReorg && !Utils.Dict.isEmpty(reorgDetection.dataByBlockNumber)) {
let prevCheckpointId$2 = prevCheckpointId$1;
for (let blockNumber$1 = fromBlockExclusive + 1, blockNumber_finish = blockNumber - 1; blockNumber$1 <= blockNumber_finish; ++blockNumber$1) {
let hash = ReorgDetection.getHashByBlockNumber(reorgDetection, blockNumber$1);
if (hash !== null) {
let checkpointId = prevCheckpointId$2 + 1n;
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;
let checkpointId$1 = prevCheckpointId + 1n;
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 {
let lastIndex = checkpointEventsProcessed.length - 1;
checkpointEventsProcessed[lastIndex] = checkpointEventsProcessed[lastIndex] + 1;
}
items.push(item);
}
totalBatchSize = totalBatchSize + chainBatchSize;
mutBatchSizePerChain[fetchState.chainId] = chainBatchSize;
}
let progressBlockNumberAfterBatch = FetchState.getProgressBlockNumberAt(fetchState, chainBatchSize);
let chainId$1 = fetchState.chainId;
let toBlockExclusive = progressBlockNumberAfterBatch + 1;
let fromBlockExclusive$1 = prevBlockNumber;
let reorgDetection$1 = chainBeforeBatch.reorgDetection;
let prevCheckpointId$3 = prevCheckpointId;
let tmp$1;
if (reorgDetection$1.shouldRollbackOnReorg && !Utils.Dict.isEmpty(reorgDetection$1.dataByBlockNumber)) {
let prevCheckpointId$4 = prevCheckpointId$3;
for (let blockNumber$2 = fromBlockExclusive$1 + 1, blockNumber_finish$1 = toBlockExclusive - 1; blockNumber$2 <= blockNumber_finish$1; ++blockNumber$2) {
let hash$1 = ReorgDetection.getHashByBlockNumber(reorgDetection$1, blockNumber$2);
if (hash$1 !== null) {
let checkpointId$2 = prevCheckpointId$4 + 1n;
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),
isInReorgThreshold: isInReorgThreshold,
checkpointIds: checkpointIds,
checkpointChainIds: checkpointChainIds,
checkpointBlockNumbers: checkpointBlockNumbers,
checkpointBlockHashes: checkpointBlockHashes,
checkpointEventsProcessed: checkpointEventsProcessed
};
}
let make = prepareBatch;
function findFirstEventBlockNumber(batch, chainId) {
let idx = 0;
let result;
let checkpointsLength = batch.checkpointIds.length;
while (idx < checkpointsLength && result === undefined) {
let 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) {
let idx = batch.items.length - 1;
let result;
while (idx >= 0 && result === undefined) {
let item = batch.items[idx];
if (item.kind === 0 && item.chain === chainId) {
result = item;
} else {
idx = idx - 1;
}
};
return result;
}
export {
hasReadyItem,
getProgressedChainsById,
addReorgCheckpoints,
prepareBatch,
make,
findFirstEventBlockNumber,
findLastEventItem,
}
/* Utils Not a pure module */