Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions packages/beacon-node/src/api/impl/beacon/blocks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,16 @@ import {
signedBlockToSignedHeader,
} from "@lodestar/state-transition";
import {
DataColumnSidecars,
ProducedBlockSource,
SignedBeaconBlock,
SignedBlindedBeaconBlock,
SignedBlockContents,
WithOptionalBytes,
deneb,
fulu,
gloas,
isDenebBlockContents,
isGloasDataColumnSidecar,
sszTypesFor,
} from "@lodestar/types";
import {fromHex, sleep, toHex, toRootHex} from "@lodestar/utils";
Expand Down Expand Up @@ -103,7 +104,7 @@ export function getBeaconBlockApi({
seenTimestampSec,
blockRootHex: blockRoot,
});
let blobSidecars: deneb.BlobSidecars, dataColumnSidecars: fulu.DataColumnSidecars;
let blobSidecars: deneb.BlobSidecars, dataColumnSidecars: DataColumnSidecars;

if (isDenebBlockContents(signedBlockContents)) {
if (isForkPostFulu(fork)) {
Expand Down Expand Up @@ -350,7 +351,9 @@ export function getBeaconBlockApi({
blockRoot,
slot,
index: dataColumnSidecar.index,
kzgCommitments: dataColumnSidecar.kzgCommitments.map(toHex),
kzgCommitments: isGloasDataColumnSidecar(dataColumnSidecar)
? []
: dataColumnSidecar.kzgCommitments.map(toHex),
});
}
}
Expand Down
100 changes: 64 additions & 36 deletions packages/beacon-node/src/chain/blocks/blockInput/blockInput.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ForkName, ForkPostFulu, ForkPreDeneb, ForkPreGloas, NUMBER_OF_COLUMNS} from "@lodestar/params";
import {BeaconBlockBody, BlobIndex, ColumnIndex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
import {ForkName, ForkPostFulu, ForkPreDeneb, NUMBER_OF_COLUMNS, isForkPostGloas} from "@lodestar/params";
import {BlobIndex, ColumnIndex, DataColumnSidecar, SignedBeaconBlock, Slot, deneb, gloas} from "@lodestar/types";
import {byteArrayEquals, fromHex, prettyBytes, toRootHex, withTimeout} from "@lodestar/utils";
import {VersionedHashes} from "../../../execution/index.js";
import {kzgCommitmentToVersionedHash} from "../../../util/blobs.js";
Expand Down Expand Up @@ -553,9 +553,24 @@ function assertBlockAndBlobArePaired(
}
}

function isGloasDataColumnSidecar(sidecar: DataColumnSidecar): sidecar is gloas.DataColumnSidecar {
return (sidecar as gloas.DataColumnSidecar).beaconBlockRoot !== undefined;
}

function getBlobKzgCommitmentsFromColumnsBlock(
block: SignedBeaconBlock<ForkPostFulu>,
forkName: ForkColumnsDA
): Uint8Array[] {
if (isForkPostGloas(forkName)) {
return (block as gloas.SignedBeaconBlock).message.body.signedExecutionPayloadBid.message.blobKzgCommitments;
}

return (block.message.body as {blobKzgCommitments: Uint8Array[]}).blobKzgCommitments;
}

// Columns DA

export type ForkColumnsDA = ForkName.fulu;
export type ForkColumnsDA = ForkPostFulu;

type BlockInputColumnsState =
| {
Expand Down Expand Up @@ -594,7 +609,7 @@ type BlockInputColumnsState =
* - The block is not yet seen and all required sampled columns are seen
* - The block is not yet seen and all required sampled columns are not yet seen
*/
export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.DataColumnSidecars> {
export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, DataColumnSidecar[]> {
type = DAType.Columns as const;

state: BlockInputColumnsState;
Expand All @@ -607,7 +622,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
*
* This is different from `dataPromise` which resolves when all data is available or could become available (e.g. through reconstruction)
*/
protected computedDataPromise = createPromise<fulu.DataColumnSidecars>();
protected computedDataPromise = createPromise<DataColumnSidecar[]>();

private constructor(
init: BlockInputInit,
Expand All @@ -629,15 +644,13 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
props: AddBlock<ForkColumnsDA> &
CreateBlockInputMeta & {sampledColumns: ColumnIndex[]; custodyColumns: ColumnIndex[]}
): BlockInputColumns {
const hasAllData =
props.daOutOfRange ||
props.block.message.body.blobKzgCommitments.length === 0 ||
props.sampledColumns.length === 0;
const blobKzgCommitments = getBlobKzgCommitmentsFromColumnsBlock(props.block, props.forkName as ForkColumnsDA);
const hasAllData = props.daOutOfRange || blobKzgCommitments.length === 0 || props.sampledColumns.length === 0;
const state = {
hasBlock: true,
hasAllData,
hasComputedAllData: hasAllData,
versionedHashes: props.block.message.body.blobKzgCommitments.map(kzgCommitmentToVersionedHash),
versionedHashes: blobKzgCommitments.map(kzgCommitmentToVersionedHash),
block: props.block,
source: {
source: props.source,
Expand Down Expand Up @@ -668,21 +681,35 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
static createFromColumn(
props: AddColumn & CreateBlockInputMeta & {sampledColumns: ColumnIndex[]; custodyColumns: ColumnIndex[]}
): BlockInputColumns {
const hasAllData =
props.daOutOfRange || props.columnSidecar.kzgCommitments.length === 0 || props.sampledColumns.length === 0;
const state: BlockInputColumnsState = {
hasBlock: false,
hasAllData,
hasComputedAllData: hasAllData as false,
versionedHashes: props.columnSidecar.kzgCommitments.map(kzgCommitmentToVersionedHash),
};
const sidecarKzgCommitments = isGloasDataColumnSidecar(props.columnSidecar)
? null
: props.columnSidecar.kzgCommitments;
const hasAllData = props.daOutOfRange || sidecarKzgCommitments?.length === 0 || props.sampledColumns.length === 0;
const versionedHashes = sidecarKzgCommitments?.map(kzgCommitmentToVersionedHash) ?? [];
const state: BlockInputColumnsState = hasAllData
? {
hasBlock: false,
hasAllData: true,
hasComputedAllData: true,
versionedHashes,
}
: {
hasBlock: false,
hasAllData: false,
hasComputedAllData: false,
versionedHashes,
};
const init: BlockInputInit = {
daOutOfRange: false,
timeCreated: props.seenTimestampSec,
forkName: props.forkName,
blockRootHex: props.blockRootHex,
parentRootHex: toRootHex(props.columnSidecar.signedBlockHeader.message.parentRoot),
slot: props.columnSidecar.signedBlockHeader.message.slot,
parentRootHex: isGloasDataColumnSidecar(props.columnSidecar)
? "0x"
: toRootHex(props.columnSidecar.signedBlockHeader.message.parentRoot),
slot: isGloasDataColumnSidecar(props.columnSidecar)
? props.columnSidecar.slot
: props.columnSidecar.signedBlockHeader.message.slot,
};
const blockInput = new BlockInputColumns(init, state, props.sampledColumns, props.custodyColumns);
if (hasAllData) {
Expand All @@ -693,14 +720,14 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
}

getLogMeta(): LogMetaColumns {
const blobKzgCommitments = this.state.hasBlock
? getBlobKzgCommitmentsFromColumnsBlock(this.state.block, this.forkName as ForkColumnsDA)
: [];
return {
slot: this.slot,
blockRoot: prettyBytes(this.blockRootHex),
timeCreatedSec: this.timeCreatedSec,
expectedColumns:
this.state.hasBlock && this.state.block.message.body.blobKzgCommitments.length === 0
? 0
: this.sampledColumns.length,
expectedColumns: this.state.hasBlock && blobKzgCommitments.length === 0 ? 0 : this.sampledColumns.length,
receivedColumns: this.getSampledColumns().length,
};
}
Expand Down Expand Up @@ -733,17 +760,16 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
);
}

const hasAllData =
(props.block.message.body as BeaconBlockBody<ForkPostFulu & ForkPreGloas>).blobKzgCommitments.length === 0 ||
this.state.hasAllData;
const hasComputedAllData =
props.block.message.body.blobKzgCommitments.length === 0 || this.state.hasComputedAllData;
const blobKzgCommitments = getBlobKzgCommitmentsFromColumnsBlock(props.block, this.forkName as ForkColumnsDA);
const hasAllData = blobKzgCommitments.length === 0 || this.state.hasAllData;
const hasComputedAllData = blobKzgCommitments.length === 0 || this.state.hasComputedAllData;

this.state = {
...this.state,
hasBlock: true,
hasAllData,
hasComputedAllData,
versionedHashes: blobKzgCommitments.map(kzgCommitmentToVersionedHash),
block: props.block,
source: {
source: props.source,
Expand All @@ -753,6 +779,8 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
timeCompleteSec: hasAllData ? props.seenTimestampSec : undefined,
} as BlockInputColumnsState;

this.parentRootHex = toRootHex(props.block.message.parentRoot);

this.blockPromise.resolve(props.block);
}

Expand Down Expand Up @@ -823,16 +851,16 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
return this.columnsCache.has(columnIndex);
}

getColumn(columnIndex: number): fulu.DataColumnSidecar | undefined {
getColumn(columnIndex: number): DataColumnSidecar | undefined {
return this.columnsCache.get(columnIndex)?.columnSidecar;
}

getVersionedHashes(): VersionedHashes {
return this.state.versionedHashes;
}

getCustodyColumns(): fulu.DataColumnSidecars {
const columns: fulu.DataColumnSidecars = [];
getCustodyColumns(): DataColumnSidecar[] {
const columns: DataColumnSidecar[] = [];
for (const index of this.custodyColumns) {
const column = this.columnsCache.get(index);
if (column) {
Expand All @@ -853,8 +881,8 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
return columns;
}

getSampledColumns(): fulu.DataColumnSidecars {
const columns: fulu.DataColumnSidecars = [];
getSampledColumns(): DataColumnSidecar[] {
const columns: DataColumnSidecar[] = [];
for (const index of this.sampledColumns) {
const column = this.columnsCache.get(index);
if (column) {
Expand All @@ -868,7 +896,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
return [...this.columnsCache.values()];
}

getAllColumns(): fulu.DataColumnSidecars {
getAllColumns(): DataColumnSidecar[] {
return this.getAllColumnsWithSource().map(({columnSidecar}) => columnSidecar);
}

Expand Down Expand Up @@ -896,7 +924,7 @@ export class BlockInputColumns extends AbstractBlockInput<ForkColumnsDA, fulu.Da
return this.state.hasComputedAllData;
}

waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<fulu.DataColumnSidecars> {
waitForComputedAllData(timeout: number, signal?: AbortSignal): Promise<DataColumnSidecar[]> {
if (!this.state.hasComputedAllData) {
return withTimeout(() => this.computedDataPromise.promise, timeout, signal);
}
Expand Down
6 changes: 3 additions & 3 deletions packages/beacon-node/src/chain/blocks/blockInput/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {ForkName} from "@lodestar/params";
import {ColumnIndex, RootHex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
import {ColumnIndex, DataColumnSidecar, RootHex, SignedBeaconBlock, Slot, deneb} from "@lodestar/types";
import {VersionedHashes} from "../../../execution/index.js";

export enum DAType {
Expand All @@ -8,7 +8,7 @@ export enum DAType {
Columns = "columns",
}

export type DAData = null | deneb.BlobSidecars | fulu.DataColumnSidecars;
export type DAData = null | deneb.BlobSidecars | DataColumnSidecar[];

/**
* Represents were input originated. Blocks and Data can come from different
Expand Down Expand Up @@ -55,7 +55,7 @@ export type BlockWithSource = SourceMeta & {block: SignedBeaconBlock; blockRootH

export type BlobWithSource = SourceMeta & {blobSidecar: deneb.BlobSidecar};

export type ColumnWithSource = SourceMeta & {columnSidecar: fulu.DataColumnSidecar};
export type ColumnWithSource = SourceMeta & {columnSidecar: DataColumnSidecar};

export type BlockHeaderMeta = {
forkName: ForkName;
Expand Down
4 changes: 2 additions & 2 deletions packages/beacon-node/src/chain/blocks/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type {ChainForkConfig} from "@lodestar/config";
import {MaybeValidExecutionStatus} from "@lodestar/fork-choice";
import {ForkSeq} from "@lodestar/params";
import {CachedBeaconStateAllForks, DataAvailabilityStatus, computeEpochAtSlot} from "@lodestar/state-transition";
import type {IndexedAttestation, Slot, fulu} from "@lodestar/types";
import type {DataColumnSidecar, IndexedAttestation, Slot} from "@lodestar/types";
import {IBlockInput} from "./blockInput/types.js";

export enum GossipedInputType {
Expand All @@ -12,7 +12,7 @@ export enum GossipedInputType {
}

type DataColumnData = {
dataColumn: fulu.DataColumnSidecar;
dataColumn: DataColumnSidecar;
dataColumnBytes: Uint8Array | null;
};
export type DataColumnsCacheMap = Map<number, DataColumnData>;
Expand Down
2 changes: 1 addition & 1 deletion packages/beacon-node/src/chain/chain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ export class BeaconChain implements IBeaconChain {
if (!isBlockInputColumns(blockInput)) {
throw new Error(`Expected block input to have columns: slot=${blockSlot} root=${blockRootHex}`);
}
return blockInput.getAllColumns();
return blockInput.getAllColumns() as DataColumnSidecars;
}
const sidecarsUnfinalized = await this.db.dataColumnSidecar.values(fromHex(blockRootHex));
if (sidecarsUnfinalized.length > 0) {
Expand Down
4 changes: 2 additions & 2 deletions packages/beacon-node/src/chain/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {StrictEventEmitter} from "strict-event-emitter-types";
import {routes} from "@lodestar/api";
import {CheckpointWithHex} from "@lodestar/fork-choice";
import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
import {DataColumnSidecars, RootHex, deneb, phase0} from "@lodestar/types";
import {DataColumnSidecar, RootHex, deneb, phase0} from "@lodestar/types";
import {PeerIdStr} from "../util/peerId.js";
import {BlockInputSource, IBlockInput} from "./blocks/blockInput/types.js";

Expand Down Expand Up @@ -88,7 +88,7 @@ export type IChainEvents = ApiEvents & {

[ChainEvent.updateTargetCustodyGroupCount]: (targetGroupCount: number) => void;

[ChainEvent.publishDataColumns]: (sidecars: DataColumnSidecars) => void;
[ChainEvent.publishDataColumns]: (sidecars: DataColumnSidecar[]) => void;

[ChainEvent.publishBlobSidecars]: (sidecars: deneb.BlobSidecar[]) => void;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
import {ChainForkConfig} from "@lodestar/config";
import {CheckpointWithHex} from "@lodestar/fork-choice";
import {
ForkName,
ForkPostFulu,
ForkPreGloas,
SLOTS_PER_EPOCH,
isForkPostDeneb,
isForkPostFulu,
isForkPostGloas,
} from "@lodestar/params";
import {ForkName, ForkPostFulu, SLOTS_PER_EPOCH, isForkPostDeneb, isForkPostFulu} from "@lodestar/params";
import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
import {BLSSignature, RootHex, SignedBeaconBlock, Slot, deneb, fulu} from "@lodestar/types";
import {BLSSignature, DataColumnSidecar, RootHex, SignedBeaconBlock, Slot, deneb} from "@lodestar/types";
import {LodestarError, Logger, byteArrayEquals, pruneSetToMax} from "@lodestar/utils";
import {Metrics} from "../../metrics/metrics.js";
import {MAX_LOOK_AHEAD_EPOCHS} from "../../sync/constants.js";
import {IClock} from "../../util/clock.js";
import {CustodyConfig} from "../../util/dataColumns.js";
import {CustodyConfig, getDataColumnSidecarSlot} from "../../util/dataColumns.js";
import {
BlockInput,
BlockInputBlobs,
Expand Down Expand Up @@ -179,10 +171,6 @@ export class SeenBlockInput {
if (!blockInput) {
const {forkName, daOutOfRange} = this.buildCommonProps(block.message.slot);

// TODO GLOAS: Implement
if (isForkPostGloas(forkName)) {
throw Error("Not implemented");
}
// Pre-deneb
if (!isForkPostDeneb(forkName)) {
blockInput = BlockInputPreData.createFromBlock({
Expand All @@ -197,7 +185,7 @@ export class SeenBlockInput {
// Fulu Only
} else if (isForkPostFulu(forkName)) {
blockInput = BlockInputColumns.createFromBlock({
block: block as SignedBeaconBlock<ForkPostFulu & ForkPreGloas>,
block: block as SignedBeaconBlock<ForkPostFulu>,
blockRootHex,
daOutOfRange,
forkName,
Expand Down Expand Up @@ -299,14 +287,14 @@ export class SeenBlockInput {
seenTimestampSec,
source,
peerIdStr,
}: SourceMeta & {blockRootHex: RootHex; columnSidecar: fulu.DataColumnSidecar},
}: SourceMeta & {blockRootHex: RootHex; columnSidecar: DataColumnSidecar},
opts: GetByBlobOptions = {}
): BlockInputColumns {
let blockInput = this.blockInputs.get(blockRootHex);
let created = false;
if (!blockInput) {
created = true;
const {forkName, daOutOfRange} = this.buildCommonProps(columnSidecar.signedBlockHeader.message.slot);
const {forkName, daOutOfRange} = this.buildCommonProps(getDataColumnSidecarSlot(columnSidecar));
blockInput = BlockInputColumns.createFromColumn({
columnSidecar,
blockRootHex,
Expand Down
Loading
Loading