@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
55 lines • 2.56 kB
JavaScript
import { MapDef } from "@lodestar/utils";
import { PendingBlockInputStatus, getBlockInputSyncCacheItemRootHex, isPendingBlockInput, } from "../types.js";
export function getAllDescendantBlocks(blockRootHex, blocks) {
// Do one pass over all blocks to index by parent
const byParent = new MapDef(() => []);
for (const block of blocks.values()) {
if (isPendingBlockInput(block)) {
byParent.getOrDefault(block.blockInput.parentRootHex).push(block);
}
}
// Then, do a second pass recursively to get `blockRootHex` child blocks
return addToDescendantBlocks(blockRootHex, byParent);
}
/** Recursive function for `getAllDescendantBlocks()` */
function addToDescendantBlocks(childBlockRootHex, byParent, descendantBlocks = []) {
const firstDescendantBlocks = byParent.get(childBlockRootHex);
if (firstDescendantBlocks) {
for (const firstDescendantBlock of firstDescendantBlocks) {
descendantBlocks.push(firstDescendantBlock);
addToDescendantBlocks(getBlockInputSyncCacheItemRootHex(firstDescendantBlock), byParent, descendantBlocks);
}
}
return descendantBlocks;
}
/**
* Returns two arrays.
* The first one has the earliest blocks that are not linked to fork-choice yet, meaning they require parent blocks to be pulled.
* The second one has the earliest blocks that are linked to fork-choice, meaning they are ready to be processed.
*
* Given this chain segment unknown block n => downloaded block n + 1 => downloaded block n + 2
* return `{incomplete: [n], ancestors: []}`
*
* Given this chain segment: downloaded block n => downloaded block n + 1 => downloaded block n + 2
* return {incomplete: [], ancestors: [n]}
*/
export function getUnknownAndAncestorBlocks(blocks) {
const unknowns = new Map();
const ancestors = new Map();
for (const block of blocks.values()) {
if (block.status === PendingBlockInputStatus.pending &&
(isPendingBlockInput(block) ? !block.blockInput.hasBlockAndAllData() : true)) {
unknowns.set(getBlockInputSyncCacheItemRootHex(block), block);
}
else if (isPendingBlockInput(block) &&
block.status === PendingBlockInputStatus.downloaded &&
!blocks.has(block.blockInput.parentRootHex)) {
ancestors.set(block.blockInput.blockRootHex, block);
}
}
return {
unknowns: Array.from(unknowns.values()),
ancestors: Array.from(ancestors.values()),
};
}
//# sourceMappingURL=pendingBlocksTree.js.map