mirror of
https://github.com/ChainSafe/lodestar.git
synced 2026-01-09 15:48:08 -05:00
chore: add logs and metrics to GetBlobsTracker (#8432)
**Motivation** - we want to know the result of getBlobsV2 and how it helps our block import **Description** - add logs and metrics to GetBlobsTracker Closes #8401 --------- Co-authored-by: Tuyen Nguyen <twoeths@users.noreply.github.com>
This commit is contained in:
@@ -4,7 +4,11 @@ import {ChainEventEmitter} from "./emitter.js";
|
||||
import {Metrics} from "../metrics/metrics.js";
|
||||
import {ChainForkConfig} from "@lodestar/config";
|
||||
import {IBlockInput, isBlockInputBlobs} from "./blocks/blockInput/index.js";
|
||||
import {getBlobSidecarsFromExecution, getDataColumnSidecarsFromExecution} from "../util/execution.js";
|
||||
import {
|
||||
DataColumnEngineResult,
|
||||
getBlobSidecarsFromExecution,
|
||||
getDataColumnSidecarsFromExecution,
|
||||
} from "../util/execution.js";
|
||||
import {callInNextEventLoop} from "../util/eventLoop.js";
|
||||
import {computeEpochAtSlot} from "@lodestar/state-transition";
|
||||
import {BLOB_AND_PROOF_V2_RPC_BYTES} from "../execution/engine/types.js";
|
||||
@@ -49,8 +53,11 @@ export class GetBlobsTracker {
|
||||
// store the index for the preallocated buffers
|
||||
this.activeReconstructions.add(blockInput.blockRootHex);
|
||||
callInNextEventLoop(() => {
|
||||
const logCtx = {slot: blockInput.slot, root: blockInput.blockRootHex};
|
||||
this.logger.verbose("Trigger getBlobsV1 for block", logCtx);
|
||||
getBlobSidecarsFromExecution(this.config, this.executionEngine, this.metrics, this.emitter, blockInput).finally(
|
||||
() => {
|
||||
this.logger.verbose("Completed getBlobsV1 for block", logCtx);
|
||||
this.activeReconstructions.delete(blockInput.blockRootHex);
|
||||
}
|
||||
);
|
||||
@@ -80,6 +87,8 @@ export class GetBlobsTracker {
|
||||
this.activeReconstructions.add(blockInput.blockRootHex);
|
||||
this.blobsAndProofsBuffers[freeIndex].inUse = true;
|
||||
callInNextEventLoop(() => {
|
||||
const logCtx = {slot: blockInput.slot, root: blockInput.blockRootHex};
|
||||
this.logger.verbose("Trigger getBlobsV2 for block", logCtx);
|
||||
getDataColumnSidecarsFromExecution(
|
||||
this.config,
|
||||
this.executionEngine,
|
||||
@@ -87,10 +96,20 @@ export class GetBlobsTracker {
|
||||
blockInput,
|
||||
this.metrics,
|
||||
this.blobsAndProofsBuffers[freeIndex].buffers
|
||||
).finally(() => {
|
||||
this.activeReconstructions.delete(blockInput.blockRootHex);
|
||||
this.blobsAndProofsBuffers[freeIndex].inUse = false;
|
||||
});
|
||||
)
|
||||
.then((result) => {
|
||||
this.logger.debug("getBlobsV2 result for block", {...logCtx, result});
|
||||
this.metrics?.dataColumns.dataColumnEngineResult.inc({result});
|
||||
})
|
||||
.catch((error) => {
|
||||
this.logger.debug("Error during getBlobsV2 for block", logCtx, error as Error);
|
||||
this.metrics?.dataColumns.dataColumnEngineResult.inc({result: DataColumnEngineResult.Failed});
|
||||
})
|
||||
.finally(() => {
|
||||
this.logger.verbose("Completed getBlobsV2 for block", logCtx);
|
||||
this.activeReconstructions.delete(blockInput.blockRootHex);
|
||||
this.blobsAndProofsBuffers[freeIndex].inUse = false;
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ import {AllocSource} from "../../util/bufferPool.js";
|
||||
import {DataColumnReconstructionCode} from "../../util/dataColumns.js";
|
||||
import {LodestarMetadata} from "../options.js";
|
||||
import {RegistryMetricCreator} from "../utils/registryMetricCreator.js";
|
||||
import {DataColumnEngineResult} from "../../util/execution.js";
|
||||
|
||||
export type LodestarMetrics = ReturnType<typeof createLodestarMetrics>;
|
||||
|
||||
@@ -841,6 +842,11 @@ export function createLodestarMetrics(
|
||||
name: "lodestar_data_columns_missing_custody_columns_count",
|
||||
help: "Total number of missing columns that should be in the database but were not when requested",
|
||||
}),
|
||||
dataColumnEngineResult: register.counter<{result: DataColumnEngineResult}>({
|
||||
name: "lodestar_data_column_engine_result_total",
|
||||
help: "The total result of sending data column to execution layer",
|
||||
labelNames: ["result"],
|
||||
}),
|
||||
},
|
||||
importBlock: {
|
||||
persistBlockNoSerializedDataCount: register.gauge({
|
||||
|
||||
@@ -16,6 +16,21 @@ import {signedBlockToSignedHeader} from "@lodestar/state-transition";
|
||||
import {routes} from "@lodestar/api";
|
||||
import {toHex} from "@lodestar/utils";
|
||||
|
||||
export enum DataColumnEngineResult {
|
||||
PreFulu = "pre_fulu",
|
||||
// the recover is not attempted because it has full data columns
|
||||
NotAttemptedFull = "not_attempted_full",
|
||||
// block has no blob so no need to call EL
|
||||
NotAttemptedNoBlobs = "not_attempted_no_blobs",
|
||||
// EL call returned null, meaning it could not find the blobs
|
||||
NullResponse = "null_response",
|
||||
// the recover is a success and it helps resolve availability
|
||||
SuccessResolved = "success_resolved",
|
||||
// the recover is a success but it's late, availability is already resolved by either gossip or getBlobsV2
|
||||
SuccessLate = "success_late",
|
||||
Failed = "failed",
|
||||
}
|
||||
|
||||
export async function getBlobSidecarsFromExecution(
|
||||
config: ChainForkConfig,
|
||||
executionEngine: IExecutionEngine,
|
||||
@@ -118,22 +133,22 @@ export async function getDataColumnSidecarsFromExecution(
|
||||
blockInput: IBlockInput,
|
||||
metrics: Metrics | null,
|
||||
blobAndProofBuffers?: Uint8Array[]
|
||||
): Promise<void> {
|
||||
): Promise<DataColumnEngineResult> {
|
||||
// If its not a column block input, exit
|
||||
if (!isBlockInputColumns(blockInput)) {
|
||||
return;
|
||||
return DataColumnEngineResult.PreFulu;
|
||||
}
|
||||
|
||||
// If already have all columns, exit
|
||||
if (blockInput.hasAllData()) {
|
||||
return;
|
||||
return DataColumnEngineResult.NotAttemptedFull;
|
||||
}
|
||||
|
||||
const versionedHashes = blockInput.getVersionedHashes();
|
||||
|
||||
// If there are no blobs in this block, exit
|
||||
if (versionedHashes.length === 0) {
|
||||
return;
|
||||
return DataColumnEngineResult.NotAttemptedNoBlobs;
|
||||
}
|
||||
|
||||
// Get blobs from execution engine
|
||||
@@ -148,13 +163,13 @@ export async function getDataColumnSidecarsFromExecution(
|
||||
|
||||
// Execution engine was unable to find one or more blobs
|
||||
if (blobs === null) {
|
||||
return;
|
||||
return DataColumnEngineResult.NullResponse;
|
||||
}
|
||||
metrics?.peerDas.getBlobsV2Responses.inc();
|
||||
|
||||
// Return if we received all data columns while waiting for getBlobs
|
||||
if (blockInput.hasAllData()) {
|
||||
return;
|
||||
return DataColumnEngineResult.SuccessLate;
|
||||
}
|
||||
|
||||
let dataColumnSidecars: fulu.DataColumnSidecars;
|
||||
@@ -187,4 +202,5 @@ export async function getDataColumnSidecarsFromExecution(
|
||||
}
|
||||
|
||||
metrics?.dataColumns.bySource.inc({source: BlockInputSource.engine}, previouslyMissingColumns.length);
|
||||
return DataColumnEngineResult.SuccessResolved;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user