@lodestar/beacon-node
Version:
A Typescript implementation of the beacon chain
75 lines • 2.97 kB
JavaScript
import { sleep } from "@lodestar/utils";
import { DataColumnReconstructionCode, recoverDataColumnSidecars } from "../util/dataColumns.js";
/**
* Minimum time to wait before attempting reconstruction
*/
const RECONSTRUCTION_DELAY_MIN_BPS = 667;
/**
* Maximum time to wait before attempting reconstruction
*/
const RECONSTRUCTION_DELAY_MAX_BPS = 1000;
/**
* Tracks column reconstruction attempts to avoid duplicate and multiple in-flight calls
*/
export class ColumnReconstructionTracker {
logger;
emitter;
metrics;
config;
/**
* Track last attempted block root
*
* This is sufficient to avoid duplicate calls since we only call this
* function when we see a new data column sidecar from gossip.
*/
lastBlockRootHex = null;
/** Track if a reconstruction attempt is in-flight */
running = false;
minDelayMs;
maxDelayMs;
constructor(init) {
this.logger = init.logger;
this.emitter = init.emitter;
this.metrics = init.metrics;
this.config = init.config;
this.minDelayMs = this.config.getSlotComponentDurationMs(RECONSTRUCTION_DELAY_MIN_BPS);
this.maxDelayMs = this.config.getSlotComponentDurationMs(RECONSTRUCTION_DELAY_MAX_BPS);
}
triggerColumnReconstruction(input) {
if (this.running) {
return;
}
if (this.lastBlockRootHex === input.blockRootHex) {
return;
}
// We don't care about the outcome of this call,
// just that it has been triggered for this block root.
this.running = true;
this.lastBlockRootHex = input.blockRootHex;
const delay = this.minDelayMs + Math.random() * (this.maxDelayMs - this.minDelayMs);
sleep(delay)
.then(() => {
const logCtx = { slot: input.slot, root: input.blockRootHex };
this.logger.debug("Attempting data column sidecar reconstruction", logCtx);
recoverDataColumnSidecars(input, this.emitter, this.metrics)
.then((result) => {
this.metrics?.recoverDataColumnSidecars.reconstructionResult.inc({ result });
this.logger.debug("Data column sidecar reconstruction complete", { ...logCtx, result });
})
.catch((e) => {
this.metrics?.recoverDataColumnSidecars.reconstructionResult.inc({
result: DataColumnReconstructionCode.Failed,
});
this.logger.debug("Error during data column sidecar reconstruction", logCtx, e);
})
.finally(() => {
this.logger.debug("Data column sidecar reconstruction attempt finished", logCtx);
this.running = false;
});
})
.catch((err) => {
this.logger.debug("ColumnReconstructionTracker unreachable error", {}, err);
});
}
}
//# sourceMappingURL=ColumnReconstructionTracker.js.map