Skip to content

Commit

Permalink
fix: handle outOfRangeData when range sync Deneb (#7249)
Browse files Browse the repository at this point in the history
* fix: handle outOfRangeData for beaconBlocksMaybeBlobsByRange()

* fix: lint

* fix: archiveBlocks - handle deneb outOfRangeData block
  • Loading branch information
twoeths authored Nov 27, 2024
1 parent 443e3a8 commit 0c1ad93
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 14 deletions.
44 changes: 33 additions & 11 deletions packages/beacon-node/src/chain/archiver/archiveBlocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ export async function archiveBlocks(
});

if (finalizedPostDeneb) {
await migrateBlobSidecarsFromHotToColdDb(config, db, finalizedCanonicalBlockRoots);
logger.verbose("Migrated blobSidecars from hot DB to cold DB");
const migrate = await migrateBlobSidecarsFromHotToColdDb(config, db, finalizedCanonicalBlockRoots, currentEpoch);
logger.verbose(migrate ? "Migrated blobSidecars from hot DB to cold DB" : "Skip blobSidecars migration");
}
}

Expand Down Expand Up @@ -157,22 +157,36 @@ async function migrateBlocksFromHotToColdDb(db: IBeaconDb, blocks: BlockRootSlot
}
}

/**
* Migrate blobSidecars from hot db to cold db.
* @returns true if we do that, false if block is out of range data.
*/
async function migrateBlobSidecarsFromHotToColdDb(
config: ChainForkConfig,
db: IBeaconDb,
blocks: BlockRootSlot[]
): Promise<void> {
blocks: BlockRootSlot[],
currentEpoch: Epoch
): Promise<boolean> {
let result = false;

for (let i = 0; i < blocks.length; i += BLOB_SIDECAR_BATCH_SIZE) {
const toIdx = Math.min(i + BLOB_SIDECAR_BATCH_SIZE, blocks.length);
const canonicalBlocks = blocks.slice(i, toIdx);

// processCanonicalBlocks
if (canonicalBlocks.length === 0) return;
if (canonicalBlocks.length === 0) return false;

// load Buffer instead of ssz deserialized to improve performance
const canonicalBlobSidecarsEntries: KeyValue<Slot, Uint8Array>[] = await Promise.all(
canonicalBlocks
.filter((block) => config.getForkSeq(block.slot) >= ForkSeq.deneb)
.filter((block) => {
const blockSlot = block.slot;
const blockEpoch = computeEpochAtSlot(blockSlot);
return (
config.getForkSeq(blockSlot) >= ForkSeq.deneb &&
blockEpoch >= currentEpoch - config.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS
);
})
.map(async (block) => {
const bytes = await db.blobSidecars.getBinary(block.root);
if (!bytes) {
Expand All @@ -182,12 +196,20 @@ async function migrateBlobSidecarsFromHotToColdDb(
})
);

// put to blockArchive db and delete block db
await Promise.all([
db.blobSidecarsArchive.batchPutBinary(canonicalBlobSidecarsEntries),
db.blobSidecars.batchDelete(canonicalBlocks.map((block) => block.root)),
]);
const migrate = canonicalBlobSidecarsEntries.length > 0;

if (migrate) {
// put to blockArchive db and delete block db
await Promise.all([
db.blobSidecarsArchive.batchPutBinary(canonicalBlobSidecarsEntries),
db.blobSidecars.batchDelete(canonicalBlocks.map((block) => block.root)),
]);
}

result = result || migrate;
}

return result;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ export async function beaconBlocksMaybeBlobsByRange(
return blocks.map((block) => getBlockInput.preData(config, block.data, BlockSource.byRange, block.bytes));
}

// From Deneb
// Only request blobs if they are recent enough
if (computeEpochAtSlot(startSlot) >= currentEpoch - config.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS) {
if (startEpoch >= currentEpoch - config.MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS) {
const [allBlocks, allBlobSidecars] = await Promise.all([
network.sendBeaconBlocksByRange(peerId, request),
network.sendBlobSidecarsByRange(peerId, request),
Expand All @@ -46,8 +47,9 @@ export async function beaconBlocksMaybeBlobsByRange(
return matchBlockWithBlobs(config, allBlocks, allBlobSidecars, endSlot, BlockSource.byRange, BlobsSource.byRange);
}

// Post Deneb but old blobs
throw Error("Cannot sync blobs outside of blobs prune window");
// Data is out of range, only request blocks
const blocks = await network.sendBeaconBlocksByRange(peerId, request);
return blocks.map((block) => getBlockInput.outOfRangeData(config, block.data, BlockSource.byRange, block.bytes));
}

// Assumes that the blobs are in the same sequence as blocks, doesn't require block to be sorted
Expand Down

0 comments on commit 0c1ad93

Please sign in to comment.