refactor: improve types package to use forks as generics (#6825)

* Update the types to use generics

* Update the types with default generics

* Fix the block type

* Add missing type

* Add missing type

* Add ssz types

* Remove allForks namespace

* Make ssz types generic

* Update config package

* Fix blok fork types

* Fix api package types

* Update types

* Update state-transition package

* Update config package

* Fix types

* Fix types for all packages

* Update api package

* Fix types for tests files

* Fix ssz types

* Fix build error

* Fix lint errors

* Fix lint errors

* Fix type issues after rebase

* Update redundant generics

* Fix the type

* Update types to use single generic

* Fix all types

* Fix the code as per feedback

* Update the code with feedback

* Update packages/types/README.md

Co-authored-by: Nico Flaig <nflaig@protonmail.com>

* chore: review #6825 (#6887)

Review #6825

* Fix publishBlockWrapper input type

* Updated the type guard

* Remove ssz instance type

* Rename BlindedExecutionPayload to ExecutionPayloadheader

* Update code as per feedback

---------

Co-authored-by: Nico Flaig <nflaig@protonmail.com>
This commit is contained in:
Nazar Hussain
2024-06-24 09:44:32 +02:00
committed by GitHub
parent a2c389fc97
commit 802a875a73
144 changed files with 1276 additions and 1212 deletions

View File

@@ -1,7 +1,17 @@
/* eslint-disable @typescript-eslint/naming-convention */
import {ContainerType, ListCompositeType, ValueOf} from "@chainsafe/ssz";
import {ChainForkConfig} from "@lodestar/config";
import {allForks, Slot, ssz, RootHex, deneb, isSignedBlockContents} from "@lodestar/types";
import {
Slot,
ssz,
RootHex,
deneb,
isSignedBlockContents,
SignedBeaconBlock,
BeaconBlockBody,
SignedBeaconBlockOrContents,
SignedBlindedBeaconBlock,
} from "@lodestar/types";
import {ForkName, ForkSeq} from "@lodestar/params";
import {Endpoint, RequestCodec, RouteDefinitions, Schema} from "../../../utils/index.js";
import {EmptyMeta, EmptyResponseCodec, EmptyResponseData, WithVersion} from "../../../utils/codecs.js";
@@ -74,7 +84,7 @@ export type Endpoints = {
"GET",
BlockArgs,
{params: {block_id: string}},
allForks.SignedBeaconBlock,
SignedBeaconBlock,
ExecutionOptimisticFinalizedAndVersionMeta
>;
@@ -86,7 +96,7 @@ export type Endpoints = {
"GET",
BlockArgs,
{params: {block_id: string}},
allForks.BeaconBlockBody["attestations"],
BeaconBlockBody["attestations"],
ExecutionOptimisticAndFinalizedMeta
>;
@@ -139,7 +149,7 @@ export type Endpoints = {
*/
publishBlock: Endpoint<
"POST",
{signedBlockOrContents: allForks.SignedBeaconBlockOrContents},
{signedBlockOrContents: SignedBeaconBlockOrContents},
{body: unknown; headers: {[MetaHeader.Version]: string}},
EmptyResponseData,
EmptyMeta
@@ -148,7 +158,7 @@ export type Endpoints = {
publishBlockV2: Endpoint<
"POST",
{
signedBlockOrContents: allForks.SignedBeaconBlockOrContents;
signedBlockOrContents: SignedBeaconBlockOrContents;
broadcastValidation?: BroadcastValidation;
},
{body: unknown; headers: {[MetaHeader.Version]: string}; query: {broadcast_validation?: string}},
@@ -162,7 +172,7 @@ export type Endpoints = {
*/
publishBlindedBlock: Endpoint<
"POST",
{signedBlindedBlock: allForks.SignedBlindedBeaconBlock},
{signedBlindedBlock: SignedBlindedBeaconBlock},
{body: unknown; headers: {[MetaHeader.Version]: string}},
EmptyResponseData,
EmptyMeta
@@ -171,7 +181,7 @@ export type Endpoints = {
publishBlindedBlockV2: Endpoint<
"POST",
{
signedBlindedBlock: allForks.SignedBlindedBeaconBlock;
signedBlindedBlock: SignedBlindedBeaconBlock;
broadcastValidation?: BroadcastValidation;
},
{body: unknown; headers: {[MetaHeader.Version]: string}; query: {broadcast_validation?: string}},
@@ -267,9 +277,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
return {
body:
config.getForkSeq(slot) < ForkSeq.deneb
? config
.getForkTypes(slot)
.SignedBeaconBlock.toJson(signedBlockOrContents as allForks.SignedBeaconBlock)
? config.getForkTypes(slot).SignedBeaconBlock.toJson(signedBlockOrContents as SignedBeaconBlock)
: SignedBlockContentsType.toJson(signedBlockOrContents as SignedBlockContents),
headers: {
[MetaHeader.Version]: config.getForkName(slot),
@@ -286,8 +294,8 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
// Determine fork from slot in JSON payload
forkName = config.getForkName(
(body as {signed_block: unknown}).signed_block !== undefined
? (body as {signed_block: allForks.SignedBeaconBlock}).signed_block.message.slot
: (body as allForks.SignedBeaconBlock).message.slot
? (body as {signed_block: SignedBeaconBlock}).signed_block.message.slot
: (body as SignedBeaconBlock).message.slot
);
}
const forkSeq = config.forks[forkName].seq;
@@ -305,9 +313,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
return {
body:
config.getForkSeq(slot) < ForkSeq.deneb
? config
.getForkTypes(slot)
.SignedBeaconBlock.serialize(signedBlockOrContents as allForks.SignedBeaconBlock)
? config.getForkTypes(slot).SignedBeaconBlock.serialize(signedBlockOrContents as SignedBeaconBlock)
: SignedBlockContentsType.serialize(signedBlockOrContents as SignedBlockContents),
headers: {
[MetaHeader.Version]: config.getForkName(slot),
@@ -345,9 +351,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
return {
body:
config.getForkSeq(slot) < ForkSeq.deneb
? config
.getForkTypes(slot)
.SignedBeaconBlock.toJson(signedBlockOrContents as allForks.SignedBeaconBlock)
? config.getForkTypes(slot).SignedBeaconBlock.toJson(signedBlockOrContents as SignedBeaconBlock)
: SignedBlockContentsType.toJson(signedBlockOrContents as SignedBlockContents),
headers: {
[MetaHeader.Version]: config.getForkName(slot),
@@ -373,9 +377,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
return {
body:
config.getForkSeq(slot) < ForkSeq.deneb
? config
.getForkTypes(slot)
.SignedBeaconBlock.serialize(signedBlockOrContents as allForks.SignedBeaconBlock)
? config.getForkTypes(slot).SignedBeaconBlock.serialize(signedBlockOrContents as SignedBeaconBlock)
: SignedBlockContentsType.serialize(signedBlockOrContents as SignedBlockContents),
headers: {
[MetaHeader.Version]: config.getForkName(slot),

View File

@@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/naming-convention */
import {ContainerType, Type, ValueOf} from "@chainsafe/ssz";
import {ChainForkConfig} from "@lodestar/config";
import {allForks, ssz, StringType} from "@lodestar/types";
import {ssz, StringType, BeaconState} from "@lodestar/types";
import {
ArrayOf,
EmptyArgs,
@@ -98,7 +98,7 @@ export type Endpoints = {
"GET",
StateArgs,
{params: {state_id: string}},
allForks.BeaconState,
BeaconState,
ExecutionOptimisticFinalizedAndVersionMeta
>;
};
@@ -136,7 +136,7 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
},
},
resp: {
data: WithVersion((fork) => ssz[fork].BeaconState as Type<allForks.BeaconState>),
data: WithVersion((fork) => ssz[fork].BeaconState as Type<BeaconState>),
meta: ExecutionOptimisticFinalizedAndVersionCodec,
},
init: {

View File

@@ -1,6 +1,19 @@
import {ContainerType, ValueOf} from "@chainsafe/ssz";
import {ChainForkConfig} from "@lodestar/config";
import {Epoch, phase0, capella, Slot, ssz, StringType, RootHex, altair, UintNum64, allForks} from "@lodestar/types";
import {
Epoch,
phase0,
capella,
Slot,
ssz,
StringType,
RootHex,
altair,
UintNum64,
LightClientOptimisticUpdate,
LightClientFinalityUpdate,
SSEPayloadAttributes,
} from "@lodestar/types";
import {ForkName} from "@lodestar/params";
import {Endpoint, RouteDefinitions, Schema} from "../../utils/index.js";
@@ -113,9 +126,9 @@ export type EventData = {
executionOptimistic: boolean;
};
[EventType.contributionAndProof]: altair.SignedContributionAndProof;
[EventType.lightClientOptimisticUpdate]: {version: ForkName; data: allForks.LightClientOptimisticUpdate};
[EventType.lightClientFinalityUpdate]: {version: ForkName; data: allForks.LightClientFinalityUpdate};
[EventType.payloadAttributes]: {version: ForkName; data: allForks.SSEPayloadAttributes};
[EventType.lightClientOptimisticUpdate]: {version: ForkName; data: LightClientOptimisticUpdate};
[EventType.lightClientFinalityUpdate]: {version: ForkName; data: LightClientFinalityUpdate};
[EventType.payloadAttributes]: {version: ForkName; data: SSEPayloadAttributes};
[EventType.blobSidecar]: BlobSidecarSSE;
};

View File

@@ -1,6 +1,13 @@
/* eslint-disable @typescript-eslint/naming-convention */
import {ListCompositeType, ValueOf} from "@chainsafe/ssz";
import {ssz, SyncPeriod, allForks} from "@lodestar/types";
import {
LightClientBootstrap,
LightClientFinalityUpdate,
LightClientOptimisticUpdate,
LightClientUpdate,
ssz,
SyncPeriod,
} from "@lodestar/types";
import {ForkName} from "@lodestar/params";
import {ChainForkConfig} from "@lodestar/config";
import {Endpoint, RouteDefinitions, Schema} from "../../utils/index.js";
@@ -33,7 +40,7 @@ export type Endpoints = {
"GET",
{startPeriod: SyncPeriod; count: number},
{query: {start_period: number; count: number}},
allForks.LightClientUpdate[],
LightClientUpdate[],
{versions: ForkName[]}
>;
@@ -46,7 +53,7 @@ export type Endpoints = {
"GET",
EmptyArgs,
EmptyRequest,
allForks.LightClientOptimisticUpdate,
LightClientOptimisticUpdate,
VersionMeta
>;
@@ -55,7 +62,7 @@ export type Endpoints = {
"GET",
EmptyArgs,
EmptyRequest,
allForks.LightClientFinalityUpdate,
LightClientFinalityUpdate,
VersionMeta
>;
@@ -68,7 +75,7 @@ export type Endpoints = {
"GET",
{blockRoot: string},
{params: {block_root: string}},
allForks.LightClientBootstrap,
LightClientBootstrap,
VersionMeta
>;
@@ -105,7 +112,7 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
},
fromJson: (data, meta) => {
const updates = data as unknown[];
const value: allForks.LightClientUpdate[] = [];
const value: LightClientUpdate[] = [];
for (let i = 0; i < updates.length; i++) {
const version = meta.versions[i];
value.push(getLightClientForkTypes(version).LightClientUpdate.fromJson(updates[i]));
@@ -132,9 +139,9 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
if (!Array.isArray(resp)) {
throw Error("JSON is not an array");
}
const updates: allForks.LightClientUpdate[] = [];
const updates: LightClientUpdate[] = [];
const meta: {versions: ForkName[]} = {versions: []};
for (const {data, version} of resp as {data: allForks.LightClientUpdate; version: string}[]) {
for (const {data, version} of resp as {data: LightClientUpdate; version: string}[]) {
updates.push(data);
meta.versions.push(toForkName(version));
}

View File

@@ -3,7 +3,6 @@ import {ContainerType, fromHexString, toHexString, Type, ValueOf} from "@chainsa
import {ChainForkConfig} from "@lodestar/config";
import {isForkBlobs} from "@lodestar/params";
import {
allForks,
altair,
BLSSignature,
CommitteeIndex,
@@ -16,6 +15,8 @@ import {
ValidatorIndex,
ProducedBlockSource,
stringType,
BeaconBlockOrContents,
BlindedBeaconBlock,
} from "@lodestar/types";
import {Endpoint, RouteDefinitions, Schema} from "../../utils/index.js";
import {fromGraffitiHex, toBoolean, toGraffitiHex} from "../../utils/serdes.js";
@@ -315,7 +316,7 @@ export type Endpoints = {
strict_fee_recipient_check?: boolean;
};
},
allForks.BeaconBlockOrContents,
BeaconBlockOrContents,
VersionMeta
>;
@@ -349,7 +350,7 @@ export type Endpoints = {
blinded_local?: boolean;
};
},
allForks.FullOrBlindedBeaconBlockOrContents,
BeaconBlockOrContents | BlindedBeaconBlock,
ProduceBlockV3Meta
>;
@@ -361,7 +362,7 @@ export type Endpoints = {
graffiti: string;
},
{params: {slot: number}; query: {randao_reveal: string; graffiti: string}},
allForks.BlindedBeaconBlock,
BlindedBeaconBlock,
VersionMeta
>;
@@ -623,8 +624,7 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
},
resp: {
data: WithVersion(
(fork) =>
(isForkBlobs(fork) ? BlockContentsType : ssz[fork].BeaconBlock) as Type<allForks.BeaconBlockOrContents>
(fork) => (isForkBlobs(fork) ? BlockContentsType : ssz[fork].BeaconBlock) as Type<BeaconBlockOrContents>
),
meta: VersionCodec,
},
@@ -688,7 +688,7 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
? getBlindedForkTypes(version).BeaconBlock
: isForkBlobs(version)
? BlockContentsType
: ssz[version].BeaconBlock) as Type<allForks.FullOrBlindedBeaconBlockOrContents>
: ssz[version].BeaconBlock) as Type<BeaconBlockOrContents | BlindedBeaconBlock>
),
meta: {
toJson: (meta) => ({

View File

@@ -1,6 +1,16 @@
/* eslint-disable @typescript-eslint/naming-convention */
import {fromHexString, toHexString} from "@chainsafe/ssz";
import {ssz, allForks, bellatrix, Slot, Root, BLSPubkey} from "@lodestar/types";
import {
ssz,
bellatrix,
Slot,
Root,
BLSPubkey,
ExecutionPayload,
ExecutionPayloadAndBlobsBundle,
SignedBlindedBeaconBlock,
SignedBuilderBid,
} from "@lodestar/types";
import {ForkName, isForkBlobs} from "@lodestar/params";
import {ChainForkConfig} from "@lodestar/config";
@@ -26,7 +36,7 @@ import {fromHeaders} from "../utils/headers.js";
// In this case, we receive a success response (204) which is not handled as an error. The generic response
// handler already checks the status code and will not attempt to parse the body, but it will return no value.
// It is important that this type indicates that there might be no value to ensure it is properly handled downstream.
export type MaybeSignedBuilderBid = allForks.SignedBuilderBid | undefined;
export type MaybeSignedBuilderBid = SignedBuilderBid | undefined;
const RegistrationsType = ArrayOf(ssz.bellatrix.SignedValidatorRegistrationV1);
@@ -62,9 +72,9 @@ export type Endpoints = {
submitBlindedBlock: Endpoint<
"POST",
{signedBlindedBlock: allForks.SignedBlindedBeaconBlock},
{signedBlindedBlock: SignedBlindedBeaconBlock},
{body: unknown; headers: {[MetaHeader.Version]: string}},
allForks.ExecutionPayload | allForks.ExecutionPayloadAndBlobsBundle,
ExecutionPayload | ExecutionPayloadAndBlobsBundle,
VersionMeta
>;
};
@@ -138,13 +148,11 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
},
}),
resp: {
data: WithVersion<allForks.ExecutionPayload | allForks.ExecutionPayloadAndBlobsBundle, VersionMeta>(
(fork: ForkName) => {
return isForkBlobs(fork)
? ssz.allForksBlobs[fork].ExecutionPayloadAndBlobsBundle
: getExecutionForkTypes(fork).ExecutionPayload;
}
),
data: WithVersion<ExecutionPayload | ExecutionPayloadAndBlobsBundle, VersionMeta>((fork: ForkName) => {
return isForkBlobs(fork)
? ssz.allForksBlobs[fork].ExecutionPayloadAndBlobsBundle
: getExecutionForkTypes(fork).ExecutionPayload;
}),
meta: VersionCodec,
},
},

View File

@@ -1,5 +1,13 @@
import {ForkName, isForkBlobs, isForkExecution, isForkLightClient} from "@lodestar/params";
import {allForks, ssz} from "@lodestar/types";
import {
ForkBlobs,
ForkExecution,
ForkLightClient,
ForkName,
isForkBlobs,
isForkExecution,
isForkLightClient,
} from "@lodestar/params";
import {SSZBlindedTypesFor, SSZTypesFor, ssz, sszTypesFor} from "@lodestar/types";
export function toForkName(version: string): ForkName {
// Teku returns fork as UPPERCASE
@@ -11,30 +19,33 @@ export function toForkName(version: string): ForkName {
return version as ForkName;
}
export function getLightClientForkTypes(fork: ForkName): allForks.AllForksLightClientSSZTypes {
export function getLightClientForkTypes(fork: ForkName): SSZTypesFor<ForkLightClient> {
if (!isForkLightClient(fork)) {
throw Error(`Invalid fork=${fork} for lightclient fork types`);
}
return ssz.allForksLightClient[fork];
return sszTypesFor(fork);
}
export function getExecutionForkTypes(fork: ForkName): allForks.AllForksExecutionSSZTypes {
export function getExecutionForkTypes(fork: ForkName): SSZTypesFor<ForkExecution> {
if (!isForkExecution(fork)) {
throw Error(`Invalid fork=${fork} for execution fork types`);
}
return ssz.allForksExecution[fork];
return sszTypesFor(fork);
}
export function getBlindedForkTypes(fork: ForkName): allForks.AllForksBlindedSSZTypes {
export function getBlindedForkTypes(fork: ForkName): SSZBlindedTypesFor<ForkExecution> {
if (!isForkExecution(fork)) {
throw Error(`Invalid fork=${fork} for blinded fork types`);
}
return ssz.allForksBlinded[fork] as allForks.AllForksBlindedSSZTypes;
return ssz.allForksBlinded[fork];
}
export function getBlobsForkTypes(fork: ForkName): allForks.AllForksBlobsSSZTypes {
export function getBlobsForkTypes(fork: ForkName): SSZTypesFor<ForkBlobs> {
if (!isForkBlobs(fork)) {
throw Error(`Invalid fork=${fork} for blobs fork types`);
}
return ssz.allForksBlobs[fork];
return sszTypesFor(fork);
}

View File

@@ -1,6 +1,6 @@
import {toHexString} from "@chainsafe/ssz";
import {ForkName} from "@lodestar/params";
import {Slot, allForks, ssz} from "@lodestar/types";
import {SignedBlindedBeaconBlock, Slot, ssz} from "@lodestar/types";
import {
BlockHeaderResponse,
BroadcastValidation,
@@ -242,7 +242,7 @@ export const testData: GenericServerTestCases<Endpoints> = {
},
};
function getDefaultBlindedBlock(slot: Slot): allForks.SignedBlindedBeaconBlock {
function getDefaultBlindedBlock(slot: Slot): SignedBlindedBeaconBlock {
const block = ssz.bellatrix.SignedBlindedBeaconBlock.defaultValue();
block.message.slot = slot;
return block;

View File

@@ -3,7 +3,14 @@ import {ApplicationMethods} from "@lodestar/api/server";
import {computeEpochAtSlot, computeTimeAtSlot, reconstructFullBlockOrContents} from "@lodestar/state-transition";
import {SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
import {sleep, fromHex, toHex} from "@lodestar/utils";
import {allForks, deneb, isSignedBlockContents, ProducedBlockSource} from "@lodestar/types";
import {
deneb,
isSignedBlockContents,
ProducedBlockSource,
SignedBeaconBlock,
SignedBeaconBlockOrContents,
SignedBlindedBeaconBlock,
} from "@lodestar/types";
import {
BlockSource,
getBlockInput,
@@ -53,7 +60,7 @@ export function getBeaconBlockApi({
opts: PublishBlockOpts = {}
) => {
const seenTimestampSec = Date.now() / 1000;
let blockForImport: BlockInput, signedBlock: allForks.SignedBeaconBlock, blobSidecars: deneb.BlobSidecars;
let blockForImport: BlockInput, signedBlock: SignedBeaconBlock, blobSidecars: deneb.BlobSidecars;
if (isSignedBlockContents(signedBlockOrContents)) {
({signedBlock} = signedBlockOrContents);
@@ -463,8 +470,8 @@ export function getBeaconBlockApi({
async function reconstructBuilderBlockOrContents(
chain: ApiModules["chain"],
signedBlindedBlock: allForks.SignedBlindedBeaconBlock
): Promise<allForks.SignedBeaconBlockOrContents> {
signedBlindedBlock: SignedBlindedBeaconBlock
): Promise<SignedBeaconBlockOrContents> {
const executionBuilder = chain.executionBuilder;
if (!executionBuilder) {
throw Error("executionBuilder required to publish SignedBlindedBeaconBlock");

View File

@@ -1,7 +1,7 @@
import {allForks} from "@lodestar/types";
import {routes} from "@lodestar/api";
import {blockToHeader} from "@lodestar/state-transition";
import {ChainForkConfig} from "@lodestar/config";
import {SignedBeaconBlock} from "@lodestar/types";
import {GENESIS_SLOT} from "../../../../constants/index.js";
import {ApiError, ValidationError} from "../../errors.js";
import {IBeaconChain} from "../../../../chain/interface.js";
@@ -9,7 +9,7 @@ import {rootHexRegex} from "../../../../eth1/provider/utils.js";
export function toBeaconHeaderResponse(
config: ChainForkConfig,
block: allForks.SignedBeaconBlock,
block: SignedBeaconBlock,
canonical = false
): routes.beacon.BlockHeaderResponse {
return {
@@ -25,7 +25,7 @@ export function toBeaconHeaderResponse(
export async function resolveBlockId(
chain: IBeaconChain,
blockId: routes.beacon.BlockId
): Promise<{block: allForks.SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean}> {
): Promise<{block: SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean}> {
const res = await resolveBlockIdOrNull(chain, blockId);
if (!res) {
throw new ApiError(404, `No block found for id '${blockId}'`);
@@ -37,7 +37,7 @@ export async function resolveBlockId(
async function resolveBlockIdOrNull(
chain: IBeaconChain,
blockId: routes.beacon.BlockId
): Promise<{block: allForks.SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null> {
): Promise<{block: SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null> {
blockId = String(blockId).toLowerCase();
if (blockId === "head") {
return chain.getBlockByRoot(chain.forkChoice.getHead().blockRoot);

View File

@@ -31,12 +31,14 @@ import {
Epoch,
ProducedBlockSource,
bellatrix,
allForks,
BLSSignature,
isBlindedBeaconBlock,
isBlockContents,
phase0,
Wei,
BeaconBlock,
BlockContents,
BlindedBeaconBlock,
} from "@lodestar/types";
import {ExecutionStatus, DataAvailabilityStatus} from "@lodestar/fork-choice";
import {fromHex, toHex, resolveOrRacePromises, prettyWeiToEth} from "@lodestar/utils";
@@ -91,11 +93,11 @@ const BLOCK_PRODUCTION_RACE_CUTOFF_MS = 2_000;
const BLOCK_PRODUCTION_RACE_TIMEOUT_MS = 12_000;
type ProduceBlockOrContentsRes = {executionPayloadValue: Wei; consensusBlockValue: Wei} & (
| {data: allForks.BeaconBlock; version: ForkPreBlobs}
| {data: allForks.BlockContents; version: ForkBlobs}
| {data: BeaconBlock<ForkPreBlobs>; version: ForkPreBlobs}
| {data: BlockContents; version: ForkBlobs}
);
type ProduceBlindedBlockRes = {executionPayloadValue: Wei; consensusBlockValue: Wei} & {
data: allForks.BlindedBeaconBlock;
data: BlindedBeaconBlock;
version: ForkExecution;
};
@@ -503,7 +505,7 @@ export function getValidatorApi({
}
return {
data: {block, ...contents} as allForks.BlockContents,
data: {block, ...contents} as BlockContents,
version,
executionPayloadValue,
consensusBlockValue,
@@ -760,13 +762,13 @@ export function getValidatorApi({
} else {
if (isBlockContents(data)) {
const {block} = data;
const blindedBlock = beaconBlockToBlinded(config, block as allForks.AllForksExecution["BeaconBlock"]);
const blindedBlock = beaconBlockToBlinded(config, block as BeaconBlock<ForkExecution>);
return {
data: blindedBlock,
meta: {...meta, executionPayloadBlinded: true},
};
} else {
const blindedBlock = beaconBlockToBlinded(config, data as allForks.AllForksExecution["BeaconBlock"]);
const blindedBlock = beaconBlockToBlinded(config, data as BeaconBlock<ForkExecution>);
return {
data: blindedBlock,
meta: {...meta, executionPayloadBlinded: true},
@@ -786,12 +788,12 @@ export function getValidatorApi({
if (isBlockContents(data)) {
const {block} = data;
const blindedBlock = beaconBlockToBlinded(config, block as allForks.AllForksExecution["BeaconBlock"]);
const blindedBlock = beaconBlockToBlinded(config, block as BeaconBlock<ForkExecution>);
return {data: blindedBlock, meta: {version}};
} else if (isBlindedBeaconBlock(data)) {
return {data, meta: {version}};
} else {
const blindedBlock = beaconBlockToBlinded(config, data as allForks.AllForksExecution["BeaconBlock"]);
const blindedBlock = beaconBlockToBlinded(config, data as BeaconBlock<ForkExecution>);
return {data: blindedBlock, meta: {version}};
}
},

View File

@@ -1,6 +1,6 @@
import {toHexString} from "@chainsafe/ssz";
import {capella, ssz, allForks, altair} from "@lodestar/types";
import {ForkSeq, INTERVALS_PER_SLOT, MAX_SEED_LOOKAHEAD, SLOTS_PER_EPOCH} from "@lodestar/params";
import {capella, ssz, altair, BeaconBlock} from "@lodestar/types";
import {ForkLightClient, ForkSeq, INTERVALS_PER_SLOT, MAX_SEED_LOOKAHEAD, SLOTS_PER_EPOCH} from "@lodestar/params";
import {
CachedBeaconStateAltair,
computeEpochAtSlot,
@@ -306,7 +306,7 @@ export async function importBlock(
callInNextEventLoop(() => {
try {
this.lightClientServer.onImportBlockHead(
block.message as allForks.AllForksLightClient["BeaconBlock"],
block.message as BeaconBlock<ForkLightClient>,
postState as CachedBeaconStateAltair,
parentBlockSlot
);

View File

@@ -1,5 +1,5 @@
import {allForks} from "@lodestar/types";
import {toHex, isErrorAborted} from "@lodestar/utils";
import {SignedBeaconBlock} from "@lodestar/types";
import {JobItemQueue, isQueueErrorAborted} from "../../util/queue/index.js";
import {Metrics} from "../../metrics/metrics.js";
import {BlockError, BlockErrorCode, isBlockErrorAborted} from "../errors/index.js";
@@ -158,7 +158,7 @@ export async function processBlocks(
}
}
function getBlockError(e: unknown, block: allForks.SignedBeaconBlock): BlockError {
function getBlockError(e: unknown, block: SignedBeaconBlock): BlockError {
if (e instanceof BlockError) {
return e;
} else if (e instanceof Error) {

View File

@@ -1,6 +1,6 @@
import {CachedBeaconStateAllForks, computeEpochAtSlot} from "@lodestar/state-transition";
import {MaybeValidExecutionStatus, DataAvailabilityStatus} from "@lodestar/fork-choice";
import {allForks, deneb, Slot, RootHex} from "@lodestar/types";
import {deneb, Slot, RootHex, SignedBeaconBlock} from "@lodestar/types";
import {ForkSeq, ForkName} from "@lodestar/params";
import {ChainForkConfig} from "@lodestar/config";
@@ -47,7 +47,7 @@ type Availability<T> = {availabilityPromise: Promise<T>; resolveAvailability: (d
type CachedBlobs = {blobsCache: BlobsCacheMap} & Availability<BlockInputDataBlobs>;
export type CachedData = ForkBlobsInfo & CachedBlobs;
export type BlockInput = {block: allForks.SignedBeaconBlock; source: BlockSource; blockBytes: Uint8Array | null} & (
export type BlockInput = {block: SignedBeaconBlock; source: BlockSource; blockBytes: Uint8Array | null} & (
| {type: BlockInputType.preData | BlockInputType.outOfRangeData}
| ({type: BlockInputType.availableData} & {blockData: BlockInputData})
// the blobsSource here is added to BlockInputBlobs when availability is resolved
@@ -68,7 +68,7 @@ export function blockRequiresBlobs(config: ChainForkConfig, blockSlot: Slot, clo
export const getBlockInput = {
preData(
config: ChainForkConfig,
block: allForks.SignedBeaconBlock,
block: SignedBeaconBlock,
source: BlockSource,
blockBytes: Uint8Array | null
): BlockInput {
@@ -91,7 +91,7 @@ export const getBlockInput = {
// building states or where importing data isn't important if valid child exists like ILs
outOfRangeData(
config: ChainForkConfig,
block: allForks.SignedBeaconBlock,
block: SignedBeaconBlock,
source: BlockSource,
blockBytes: Uint8Array | null
): BlockInput {
@@ -108,7 +108,7 @@ export const getBlockInput = {
availableData(
config: ChainForkConfig,
block: allForks.SignedBeaconBlock,
block: SignedBeaconBlock,
source: BlockSource,
blockBytes: Uint8Array | null,
blockData: BlockInputData
@@ -127,7 +127,7 @@ export const getBlockInput = {
dataPromise(
config: ChainForkConfig,
block: allForks.SignedBeaconBlock,
block: SignedBeaconBlock,
source: BlockSource,
blockBytes: Uint8Array | null,
cachedData: CachedData

View File

@@ -6,7 +6,7 @@ import {
isMergeTransitionBlock as isMergeTransitionBlockFn,
isExecutionEnabled,
} from "@lodestar/state-transition";
import {bellatrix, allForks, Slot, deneb} from "@lodestar/types";
import {bellatrix, Slot, deneb, SignedBeaconBlock} from "@lodestar/types";
import {
IForkChoice,
assertValidTerminalPowBlock,
@@ -68,7 +68,7 @@ type VerifyBlockExecutionResponse =
export async function verifyBlocksExecutionPayload(
chain: VerifyBlockExecutionPayloadModules,
parentBlock: ProtoBlock,
blocks: allForks.SignedBeaconBlock[],
blocks: SignedBeaconBlock[],
preState0: CachedBeaconStateAllForks,
signal: AbortSignal,
opts: BlockProcessOpts & ImportBlockOpts
@@ -274,7 +274,7 @@ export async function verifyBlocksExecutionPayload(
*/
export async function verifyBlockExecutionPayload(
chain: VerifyBlockExecutionPayloadModules,
block: allForks.SignedBeaconBlock,
block: SignedBeaconBlock,
preState0: CachedBeaconStateAllForks,
opts: BlockProcessOpts,
isOptimisticallySafe: boolean,
@@ -393,7 +393,7 @@ export async function verifyBlockExecutionPayload(
function getSegmentErrorResponse(
{verifyResponse, blockIndex}: {verifyResponse: VerifyExecutionErrorResponse; blockIndex: number},
parentBlock: ProtoBlock,
blocks: allForks.SignedBeaconBlock[]
blocks: SignedBeaconBlock[]
): SegmentExecStatus {
const {executionStatus, lvhResponse, execError} = verifyResponse;
let invalidSegmentLVH: LVHInvalidResponse | undefined = undefined;

View File

@@ -1,6 +1,6 @@
import {CachedBeaconStateAllForks, getBlockSignatureSets} from "@lodestar/state-transition";
import {allForks} from "@lodestar/types";
import {Logger} from "@lodestar/utils";
import {SignedBeaconBlock} from "@lodestar/types";
import {Metrics} from "../../metrics/metrics.js";
import {IBlsVerifier} from "../bls/index.js";
import {BlockError, BlockErrorCode} from "../errors/blockError.js";
@@ -19,7 +19,7 @@ export async function verifyBlocksSignatures(
logger: Logger,
metrics: Metrics | null,
preState0: CachedBeaconStateAllForks,
blocks: allForks.SignedBeaconBlock[],
blocks: SignedBeaconBlock[],
opts: ImportBlockOpts
): Promise<{verifySignaturesTime: number}> {
const isValidPromises: Promise<boolean>[] = [];
@@ -37,7 +37,9 @@ export async function verifyBlocksSignatures(
: //
// Verify signatures per block to track which block is invalid
bls.verifySignatureSets(
getBlockSignatureSets(preState0, block, {skipProposerSignature: opts.validProposerSignature})
getBlockSignatureSets(preState0, block, {
skipProposerSignature: opts.validProposerSignature,
})
);
// getBlockSignatureSets() takes 45ms in benchmarks for 2022Q2 mainnet blocks (100 sigs). When syncing a 32 blocks

View File

@@ -16,7 +16,6 @@ import {
} from "@lodestar/state-transition";
import {BeaconConfig} from "@lodestar/config";
import {
allForks,
UintNum64,
Root,
phase0,
@@ -28,6 +27,11 @@ import {
Wei,
bellatrix,
isBlindedBeaconBlock,
BeaconBlock,
SignedBeaconBlock,
ExecutionPayload,
BlindedBeaconBlock,
BlindedBeaconBlockBody,
} from "@lodestar/types";
import {CheckpointWithHex, ExecutionStatus, IForkChoice, ProtoBlock, UpdateHeadOpt} from "@lodestar/fork-choice";
import {ProcessShutdownCallback} from "@lodestar/validator";
@@ -157,7 +161,7 @@ export class BeaconChain implements IBeaconChain {
// Cache payload from the local execution so that produceBlindedBlock or produceBlockV3 and
// send and get signed/published blinded versions which beacon can assemble into full before
// actual publish
readonly producedBlockRoot = new Map<RootHex, allForks.ExecutionPayload | null>();
readonly producedBlockRoot = new Map<RootHex, ExecutionPayload | null>();
readonly producedBlindedBlockRoot = new Set<RootHex>();
readonly opts: IChainOptions;
@@ -498,7 +502,7 @@ export class BeaconChain implements IBeaconChain {
async getCanonicalBlockAtSlot(
slot: Slot
): Promise<{block: allForks.SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null> {
): Promise<{block: SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null> {
const finalizedBlock = this.forkChoice.getFinalizedBlock();
if (slot > finalizedBlock.slot) {
// Unfinalized slot, attempt to find in fork-choice
@@ -520,7 +524,7 @@ export class BeaconChain implements IBeaconChain {
async getBlockByRoot(
root: string
): Promise<{block: allForks.SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null> {
): Promise<{block: SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null> {
const block = this.forkChoice.getBlockHex(root);
if (block) {
const data = await this.db.block.get(fromHexString(root));
@@ -554,7 +558,7 @@ export class BeaconChain implements IBeaconChain {
}
produceBlock(blockAttributes: BlockAttributes & {commonBlockBody?: CommonBlockBody}): Promise<{
block: allForks.BeaconBlock;
block: BeaconBlock;
executionPayloadValue: Wei;
consensusBlockValue: Wei;
shouldOverrideBuilder?: boolean;
@@ -563,7 +567,7 @@ export class BeaconChain implements IBeaconChain {
}
produceBlindedBlock(blockAttributes: BlockAttributes & {commonBlockBody?: CommonBlockBody}): Promise<{
block: allForks.BlindedBeaconBlock;
block: BlindedBeaconBlock;
executionPayloadValue: Wei;
consensusBlockValue: Wei;
}> {
@@ -616,7 +620,7 @@ export class BeaconChain implements IBeaconChain {
const bodyRoot =
blockType === BlockType.Full
? this.config.getForkTypes(slot).BeaconBlockBody.hashTreeRoot(body)
: this.config.getBlindedForkTypes(slot).BeaconBlockBody.hashTreeRoot(body as allForks.BlindedBeaconBlockBody);
: this.config.getBlindedForkTypes(slot).BeaconBlockBody.hashTreeRoot(body as BlindedBeaconBlockBody);
this.logger.debug("Computing block post state from the produced body", {
slot,
bodyRoot: toHexString(bodyRoot),
@@ -636,7 +640,7 @@ export class BeaconChain implements IBeaconChain {
const blockRoot =
blockType === BlockType.Full
? this.config.getForkTypes(slot).BeaconBlock.hashTreeRoot(block)
: this.config.getBlindedForkTypes(slot).BeaconBlock.hashTreeRoot(block as allForks.BlindedBeaconBlock);
: this.config.getBlindedForkTypes(slot).BeaconBlock.hashTreeRoot(block as BlindedBeaconBlock);
const blockRootHex = toHex(blockRoot);
// track the produced block for consensus broadcast validations
@@ -770,7 +774,7 @@ export class BeaconChain implements IBeaconChain {
return this.reprocessController.waitForBlockOfAttestation(slot, root);
}
persistBlock(data: allForks.BeaconBlock | allForks.BlindedBeaconBlock, suffix?: string): void {
persistBlock(data: BeaconBlock | BlindedBeaconBlock, suffix?: string): void {
const slot = data.slot;
if (isBlindedBeaconBlock(data)) {
const sszType = this.config.getBlindedForkTypes(slot).BeaconBlock;
@@ -1094,7 +1098,7 @@ export class BeaconChain implements IBeaconChain {
}
}
async getBlockRewards(block: allForks.FullOrBlindedBeaconBlock): Promise<BlockRewards> {
async getBlockRewards(block: BeaconBlock | BlindedBeaconBlock): Promise<BlockRewards> {
const preState = this.regen.getPreStateSync(block);
if (preState === null) {
@@ -1133,7 +1137,7 @@ export class BeaconChain implements IBeaconChain {
}
async getSyncCommitteeRewards(
block: allForks.FullOrBlindedBeaconBlock,
block: BeaconBlock | BlindedBeaconBlock,
validatorIds?: (ValidatorIndex | string)[]
): Promise<SyncCommitteeRewards> {
const preState = this.regen.getPreStateSync(block);

View File

@@ -1,5 +1,5 @@
import {toHexString} from "@chainsafe/ssz";
import {allForks, RootHex, Slot, ValidatorIndex} from "@lodestar/types";
import {RootHex, SignedBeaconBlock, Slot, ValidatorIndex} from "@lodestar/types";
import {LodestarError} from "@lodestar/utils";
import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
import {ExecutionPayloadStatus} from "../../execution/engine/interface.js";
@@ -112,7 +112,7 @@ export class BlockGossipError extends GossipActionError<BlockErrorType> {}
export class BlockError extends LodestarError<BlockErrorType> {
constructor(
readonly signedBlock: allForks.SignedBeaconBlock,
readonly signedBlock: SignedBeaconBlock,
type: BlockErrorType
) {
super(type);

View File

@@ -7,7 +7,7 @@ import {
computeCheckpointEpochAtStateSlot,
computeStartSlotAtEpoch,
} from "@lodestar/state-transition";
import {phase0, allForks, ssz} from "@lodestar/types";
import {SignedBeaconBlock, phase0, ssz} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {Logger, toHex} from "@lodestar/utils";
import {GENESIS_SLOT, ZERO_HASH} from "../constants/index.js";
@@ -21,7 +21,7 @@ import {GenesisResult} from "./genesis/interface.js";
export async function persistGenesisResult(
db: IBeaconDb,
genesisResult: GenesisResult,
genesisBlock: allForks.SignedBeaconBlock
genesisBlock: SignedBeaconBlock
): Promise<void> {
await Promise.all([
db.stateArchive.add(genesisResult.state),
@@ -52,10 +52,7 @@ export async function persistAnchorState(
}
}
export function createGenesisBlock(
config: ChainForkConfig,
genesisState: BeaconStateAllForks
): allForks.SignedBeaconBlock {
export function createGenesisBlock(config: ChainForkConfig, genesisState: BeaconStateAllForks): SignedBeaconBlock {
const types = config.getForkTypes(GENESIS_SLOT);
const genesisBlock = types.SignedBeaconBlock.defaultValue();
const stateRoot = genesisState.hashTreeRoot();

View File

@@ -1,6 +1,5 @@
import {CompositeTypeAny, TreeView, Type} from "@chainsafe/ssz";
import {
allForks,
UintNum64,
Root,
phase0,
@@ -12,6 +11,10 @@ import {
Wei,
capella,
altair,
BeaconBlock,
ExecutionPayload,
SignedBeaconBlock,
BlindedBeaconBlock,
} from "@lodestar/types";
import {
BeaconStateAllForks,
@@ -22,7 +25,6 @@ import {
} from "@lodestar/state-transition";
import {BeaconConfig} from "@lodestar/config";
import {Logger} from "@lodestar/utils";
import {CheckpointWithHex, IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
import {IEth1ForBlockProduction} from "../eth1/index.js";
import {IExecutionEngine, IExecutionBuilder} from "../execution/index.js";
@@ -120,7 +122,7 @@ export interface IBeaconChain {
readonly beaconProposerCache: BeaconProposerCache;
readonly checkpointBalancesCache: CheckpointBalancesCache;
readonly producedContentsCache: Map<BlockHash, deneb.Contents>;
readonly producedBlockRoot: Map<RootHex, allForks.ExecutionPayload | null>;
readonly producedBlockRoot: Map<RootHex, ExecutionPayload | null>;
readonly shufflingCache: ShufflingCache;
readonly producedBlindedBlockRoot: Set<RootHex>;
readonly opts: IChainOptions;
@@ -162,25 +164,25 @@ export interface IBeaconChain {
*/
getCanonicalBlockAtSlot(
slot: Slot
): Promise<{block: allForks.SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null>;
): Promise<{block: SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null>;
/**
* Get local block by root, does not fetch from the network
*/
getBlockByRoot(
root: RootHex
): Promise<{block: allForks.SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null>;
): Promise<{block: SignedBeaconBlock; executionOptimistic: boolean; finalized: boolean} | null>;
getContents(beaconBlock: deneb.BeaconBlock): deneb.Contents;
produceCommonBlockBody(blockAttributes: BlockAttributes): Promise<CommonBlockBody>;
produceBlock(blockAttributes: BlockAttributes & {commonBlockBody?: CommonBlockBody}): Promise<{
block: allForks.BeaconBlock;
block: BeaconBlock;
executionPayloadValue: Wei;
consensusBlockValue: Wei;
shouldOverrideBuilder?: boolean;
}>;
produceBlindedBlock(blockAttributes: BlockAttributes & {commonBlockBody?: CommonBlockBody}): Promise<{
block: allForks.BlindedBeaconBlock;
block: BlindedBeaconBlock;
executionPayloadValue: Wei;
consensusBlockValue: Wei;
}>;
@@ -204,7 +206,7 @@ export interface IBeaconChain {
updateBeaconProposerData(epoch: Epoch, proposers: ProposerPreparationData[]): Promise<void>;
persistBlock(data: allForks.BeaconBlock | allForks.BlindedBeaconBlock, suffix?: string): void;
persistBlock(data: BeaconBlock | BlindedBeaconBlock, suffix?: string): void;
persistInvalidSszValue<T>(type: Type<T>, sszObject: T | Uint8Array, suffix?: string): void;
persistInvalidSszBytes(type: string, sszBytes: Uint8Array, suffix?: string): void;
/** Persist bad items to persistInvalidSszObjectsDir dir, for example invalid state, attestations etc. */
@@ -220,13 +222,13 @@ export interface IBeaconChain {
regenCanAcceptWork(): boolean;
blsThreadPoolCanAcceptWork(): boolean;
getBlockRewards(blockRef: allForks.FullOrBlindedBeaconBlock): Promise<BlockRewards>;
getBlockRewards(blockRef: BeaconBlock | BlindedBeaconBlock): Promise<BlockRewards>;
getAttestationsRewards(
epoch: Epoch,
validatorIds?: (ValidatorIndex | string)[]
): Promise<{rewards: AttestationsRewards; executionOptimistic: boolean; finalized: boolean}>;
getSyncCommitteeRewards(
blockRef: allForks.FullOrBlindedBeaconBlock,
blockRef: BeaconBlock | BlindedBeaconBlock,
validatorIds?: (ValidatorIndex | string)[]
): Promise<SyncCommitteeRewards>;
}

View File

@@ -1,5 +1,21 @@
import {BitArray, CompositeViewDU, toHexString} from "@chainsafe/ssz";
import {altair, phase0, Root, RootHex, Slot, ssz, SyncPeriod, allForks} from "@lodestar/types";
import {
altair,
BeaconBlock,
BeaconBlockBody,
LightClientBootstrap,
LightClientFinalityUpdate,
LightClientHeader,
LightClientOptimisticUpdate,
LightClientUpdate,
phase0,
Root,
RootHex,
Slot,
ssz,
SSZTypesFor,
SyncPeriod,
} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {
CachedBeaconStateAltair,
@@ -16,7 +32,14 @@ import {
} from "@lodestar/light-client/spec";
import {Logger, MapDef, pruneSetToMax} from "@lodestar/utils";
import {routes} from "@lodestar/api";
import {MIN_SYNC_COMMITTEE_PARTICIPANTS, SYNC_COMMITTEE_SIZE, ForkName, ForkSeq, ForkExecution} from "@lodestar/params";
import {
MIN_SYNC_COMMITTEE_PARTICIPANTS,
SYNC_COMMITTEE_SIZE,
ForkName,
ForkSeq,
ForkExecution,
ForkLightClient,
} from "@lodestar/params";
import {IBeaconDb} from "../../db/index.js";
import {Metrics} from "../../metrics/index.js";
@@ -40,7 +63,7 @@ type DependentRootHex = RootHex;
type BlockRooHex = RootHex;
export type SyncAttestedData = {
attestedHeader: allForks.LightClientHeader;
attestedHeader: LightClientHeader;
/** Precomputed root to prevent re-hashing */
blockRoot: Uint8Array;
} & (
@@ -178,11 +201,11 @@ export class LightClientServer {
* Keep in memory since this data is very transient, not useful after a few slots
*/
private readonly prevHeadData = new Map<BlockRooHex, SyncAttestedData>();
private checkpointHeaders = new Map<BlockRooHex, allForks.LightClientHeader>();
private latestHeadUpdate: allForks.LightClientOptimisticUpdate | null = null;
private checkpointHeaders = new Map<BlockRooHex, LightClientHeader>();
private latestHeadUpdate: LightClientOptimisticUpdate | null = null;
private readonly zero: Pick<altair.LightClientUpdate, "finalityBranch" | "finalizedHeader">;
private finalized: allForks.LightClientFinalityUpdate | null = null;
private finalized: LightClientFinalityUpdate | null = null;
constructor(
private readonly opts: LightClientServerOpts,
@@ -225,7 +248,7 @@ export class LightClientServer {
* - Use block's syncAggregate
*/
onImportBlockHead(
block: allForks.AllForksLightClient["BeaconBlock"],
block: BeaconBlock<ForkLightClient>,
postState: CachedBeaconStateAltair,
parentBlockSlot: Slot
): void {
@@ -260,7 +283,7 @@ export class LightClientServer {
/**
* API ROUTE to get `currentSyncCommittee` and `nextSyncCommittee` from a trusted state root
*/
async getBootstrap(blockRoot: Uint8Array): Promise<allForks.LightClientBootstrap> {
async getBootstrap(blockRoot: Uint8Array): Promise<LightClientBootstrap> {
const syncCommitteeWitness = await this.db.syncCommitteeWitness.get(blockRoot);
if (!syncCommitteeWitness) {
throw new LightClientServerError(
@@ -305,7 +328,7 @@ export class LightClientServer {
* - Has the most bits
* - Signed header at the oldest slot
*/
async getUpdate(period: number): Promise<allForks.LightClientUpdate> {
async getUpdate(period: number): Promise<LightClientUpdate> {
// Signature data
const update = await this.db.bestLightClientUpdate.get(period);
if (!update) {
@@ -336,11 +359,11 @@ export class LightClientServer {
* API ROUTE to poll LightclientHeaderUpdate.
* Clients should use the SSE type `light_client_optimistic_update` if available
*/
getOptimisticUpdate(): allForks.LightClientOptimisticUpdate | null {
getOptimisticUpdate(): LightClientOptimisticUpdate | null {
return this.latestHeadUpdate;
}
getFinalityUpdate(): allForks.LightClientFinalityUpdate | null {
getFinalityUpdate(): LightClientFinalityUpdate | null {
return this.finalized;
}
@@ -356,7 +379,7 @@ export class LightClientServer {
}
private async persistPostBlockImportData(
block: allForks.AllForksLightClient["BeaconBlock"],
block: BeaconBlock<ForkLightClient>,
postState: CachedBeaconStateAltair,
parentBlockSlot: Slot
): Promise<void> {
@@ -476,7 +499,7 @@ export class LightClientServer {
return;
}
const headerUpdate: allForks.LightClientOptimisticUpdate = {
const headerUpdate: LightClientOptimisticUpdate = {
attestedHeader,
syncAggregate,
signatureSlot,
@@ -633,7 +656,7 @@ export class LightClientServer {
finalityBranch,
syncAggregate,
signatureSlot,
} as allForks.LightClientUpdate;
} as LightClientUpdate;
// attestedData and the block of syncAggregate may not be in same sync period
// should not use attested data slot as sync period
@@ -669,7 +692,7 @@ export class LightClientServer {
/**
* Get finalized header from db. Keeps a small in-memory cache to speed up most of the lookups
*/
private async getFinalizedHeader(finalizedBlockRoot: Uint8Array): Promise<allForks.LightClientHeader | null> {
private async getFinalizedHeader(finalizedBlockRoot: Uint8Array): Promise<LightClientHeader | null> {
const finalizedBlockRootHex = toHexString(finalizedBlockRoot);
const cachedFinalizedHeader = this.checkpointHeaders.get(finalizedBlockRootHex);
if (cachedFinalizedHeader) {
@@ -697,28 +720,23 @@ export function sumBits(bits: BitArray): number {
return bits.getTrueBitIndexes().length;
}
export function blockToLightClientHeader(
fork: ForkName,
block: allForks.AllForksLightClient["BeaconBlock"]
): allForks.LightClientHeader {
export function blockToLightClientHeader(fork: ForkName, block: BeaconBlock<ForkLightClient>): LightClientHeader {
const blockSlot = block.slot;
const beacon: phase0.BeaconBlockHeader = {
slot: blockSlot,
proposerIndex: block.proposerIndex,
parentRoot: block.parentRoot,
stateRoot: block.stateRoot,
bodyRoot: (ssz[fork].BeaconBlockBody as allForks.AllForksLightClientSSZTypes["BeaconBlockBody"]).hashTreeRoot(
block.body
),
bodyRoot: (ssz[fork].BeaconBlockBody as SSZTypesFor<ForkLightClient, "BeaconBlockBody">).hashTreeRoot(block.body),
};
if (ForkSeq[fork] >= ForkSeq.capella) {
const blockBody = block.body as allForks.AllForksExecution["BeaconBlockBody"];
const blockBody = block.body as BeaconBlockBody<ForkExecution>;
const execution = executionPayloadToPayloadHeader(ForkSeq[fork], blockBody.executionPayload);
return {
beacon,
execution,
executionBranch: getBlockBodyExecutionHeaderProof(fork as ForkExecution, blockBody),
} as allForks.LightClientHeader;
} as LightClientHeader;
} else {
return {beacon};
}

View File

@@ -1,7 +1,7 @@
import {Tree} from "@chainsafe/persistent-merkle-tree";
import {BeaconStateAllForks} from "@lodestar/state-transition";
import {FINALIZED_ROOT_GINDEX, BLOCK_BODY_EXECUTION_PAYLOAD_GINDEX, ForkExecution} from "@lodestar/params";
import {allForks, ssz} from "@lodestar/types";
import {BeaconBlockBody, SSZTypesFor, ssz} from "@lodestar/types";
import {SyncCommitteeWitness} from "./types.js";
@@ -47,8 +47,8 @@ export function getFinalizedRootProof(state: BeaconStateAllForks): Uint8Array[]
export function getBlockBodyExecutionHeaderProof(
fork: ForkExecution,
body: allForks.AllForksExecution["BeaconBlockBody"]
body: BeaconBlockBody<ForkExecution>
): Uint8Array[] {
const bodyView = (ssz[fork].BeaconBlockBody as allForks.AllForksExecutionSSZTypes["BeaconBlockBody"]).toView(body);
const bodyView = (ssz[fork].BeaconBlockBody as SSZTypesFor<ForkExecution, "BeaconBlockBody">).toView(body);
return new Tree(bodyView.node).getSingleProof(BigInt(BLOCK_BODY_EXECUTION_PAYLOAD_GINDEX));
}

View File

@@ -15,7 +15,7 @@ import {
MAX_ATTESTER_SLASHINGS,
ForkSeq,
} from "@lodestar/params";
import {Epoch, phase0, capella, ssz, ValidatorIndex, allForks} from "@lodestar/types";
import {Epoch, phase0, capella, ssz, ValidatorIndex, SignedBeaconBlock} from "@lodestar/types";
import {IBeaconDb} from "../../db/index.js";
import {SignedBLSToExecutionChangeVersioned} from "../../util/types.js";
import {BlockType} from "../interface.js";
@@ -304,7 +304,7 @@ export class OpPool {
/**
* Prune all types of transactions given the latest head state
*/
pruneAll(headBlock: allForks.SignedBeaconBlock, headState: CachedBeaconStateAllForks): void {
pruneAll(headBlock: SignedBeaconBlock, headState: CachedBeaconStateAllForks): void {
this.pruneAttesterSlashings(headState);
this.pruneProposerSlashings(headState);
this.pruneVoluntaryExits(headState);
@@ -377,10 +377,7 @@ export class OpPool {
* In the worse case where head block is reorged, the same BlsToExecutionChange message can be re-added
* to opPool once gossipsub seen cache TTL passes.
*/
private pruneBlsToExecutionChanges(
headBlock: allForks.SignedBeaconBlock,
headState: CachedBeaconStateAllForks
): void {
private pruneBlsToExecutionChanges(headBlock: SignedBeaconBlock, headState: CachedBeaconStateAllForks): void {
const {config} = headState;
const recentBlsToExecutionChanges =
config.getForkSeq(headBlock.message.slot) >= ForkSeq.capella

View File

@@ -5,7 +5,7 @@ import {
StateHashTreeRootSource,
stateTransition,
} from "@lodestar/state-transition";
import {allForks, Gwei, Root} from "@lodestar/types";
import {BeaconBlock, BlindedBeaconBlock, Gwei, Root} from "@lodestar/types";
import {ZERO_HASH} from "../../constants/index.js";
import {Metrics} from "../../metrics/index.js";
@@ -17,10 +17,10 @@ import {Metrics} from "../../metrics/index.js";
export function computeNewStateRoot(
metrics: Metrics | null,
state: CachedBeaconStateAllForks,
block: allForks.FullOrBlindedBeaconBlock
block: BeaconBlock | BlindedBeaconBlock
): {newStateRoot: Root; proposerReward: Gwei} {
// Set signature to zero to re-use stateTransition() function which requires the SignedBeaconBlock type
const blockEmptySig = {message: block, signature: ZERO_HASH} as allForks.FullOrBlindedSignedBeaconBlock;
const blockEmptySig = {message: block, signature: ZERO_HASH};
const postState = stateTransition(
state,

View File

@@ -1,6 +1,5 @@
import {
Bytes32,
allForks,
Root,
RootHex,
Slot,
@@ -11,6 +10,12 @@ import {
capella,
deneb,
Wei,
SSEPayloadAttributes,
BeaconBlock,
BeaconBlockBody,
ExecutionPayloadHeader,
BlindedBeaconBlockBody,
BlindedBeaconBlock,
} from "@lodestar/types";
import {
CachedBeaconStateAllForks,
@@ -27,7 +32,6 @@ import {
import {ChainForkConfig} from "@lodestar/config";
import {ForkSeq, ForkExecution, isForkExecution} from "@lodestar/params";
import {toHex, sleep, Logger} from "@lodestar/utils";
import type {BeaconChain} from "../chain.js";
import {PayloadId, IExecutionEngine, IExecutionBuilder, PayloadAttributes} from "../../execution/index.js";
import {ZERO_HASH, ZERO_HASH_HEX} from "../../constants/index.js";
@@ -73,11 +77,9 @@ export enum BlockType {
Blinded = "Blinded",
}
export type AssembledBodyType<T extends BlockType> = T extends BlockType.Full
? allForks.BeaconBlockBody
: allForks.BlindedBeaconBlockBody;
export type AssembledBlockType<T extends BlockType> = T extends BlockType.Full
? allForks.BeaconBlock
: allForks.BlindedBeaconBlock;
? BeaconBlockBody
: BlindedBeaconBlockBody;
export type AssembledBlockType<T extends BlockType> = T extends BlockType.Full ? BeaconBlock : BlindedBeaconBlock;
export enum BlobsResultType {
preDeneb,
@@ -191,7 +193,7 @@ export async function produceBlockBody<T extends BlockType>(
currentState as CachedBeaconStateBellatrix,
proposerPubKey
);
(blockBody as allForks.BlindedBeaconBlockBody).executionPayloadHeader = builderRes.header;
(blockBody as BlindedBeaconBlockBody).executionPayloadHeader = builderRes.header;
executionPayloadValue = builderRes.executionPayloadValue;
const fetchedTime = Date.now() / 1000 - computeTimeAtSlot(this.config, blockSlot, this.genesisTime);
@@ -237,7 +239,7 @@ export async function produceBlockBody<T extends BlockType>(
);
if (prepareRes.isPremerge) {
(blockBody as allForks.ExecutionBlockBody).executionPayload =
(blockBody as BeaconBlockBody<ForkExecution>).executionPayload =
ssz.allForksExecution[fork].ExecutionPayload.defaultValue();
blobsResult = {type: BlobsResultType.preDeneb};
executionPayloadValue = BigInt(0);
@@ -258,7 +260,7 @@ export async function produceBlockBody<T extends BlockType>(
const {executionPayload, blobsBundle} = engineRes;
shouldOverrideBuilder = engineRes.shouldOverrideBuilder;
(blockBody as allForks.ExecutionBlockBody).executionPayload = executionPayload;
(blockBody as BeaconBlockBody<ForkExecution>).executionPayload = executionPayload;
executionPayloadValue = engineRes.executionPayloadValue;
Object.assign(logMeta, {transactions: executionPayload.transactions.length, shouldOverrideBuilder});
@@ -307,7 +309,7 @@ export async function produceBlockBody<T extends BlockType>(
{},
e as Error
);
(blockBody as allForks.ExecutionBlockBody).executionPayload =
(blockBody as BeaconBlockBody<ForkExecution>).executionPayload =
ssz.allForksExecution[fork].ExecutionPayload.defaultValue();
blobsResult = {type: BlobsResultType.preDeneb};
executionPayloadValue = BigInt(0);
@@ -441,7 +443,7 @@ async function prepareExecutionPayloadHeader(
state: CachedBeaconStateBellatrix,
proposerPubKey: BLSPubkey
): Promise<{
header: allForks.ExecutionPayloadHeader;
header: ExecutionPayloadHeader;
executionPayloadValue: Wei;
blobKzgCommitments?: deneb.BlobKzgCommitments;
}> {
@@ -504,7 +506,7 @@ export async function getPayloadAttributesForSSE(
parentBlockRoot,
feeRecipient,
}: {prepareState: CachedBeaconStateExecutions; prepareSlot: Slot; parentBlockRoot: Root; feeRecipient: string}
): Promise<allForks.SSEPayloadAttributes> {
): Promise<SSEPayloadAttributes> {
const parentHashRes = await getExecutionPayloadParentHash(chain, prepareState);
if (!parentHashRes.isPremerge) {
@@ -516,7 +518,7 @@ export async function getPayloadAttributesForSSE(
feeRecipient,
});
const ssePayloadAttributes: allForks.SSEPayloadAttributes = {
const ssePayloadAttributes: SSEPayloadAttributes = {
proposerIndex: prepareState.epochCtx.getBeaconProposer(prepareSlot),
proposalSlot: prepareSlot,
parentBlockNumber: prepareState.latestExecutionPayloadHeader.blockNumber,
@@ -546,7 +548,7 @@ function preparePayloadAttributes(
parentBlockRoot: Root;
feeRecipient: string;
}
): allForks.SSEPayloadAttributes["payloadAttributes"] {
): SSEPayloadAttributes["payloadAttributes"] {
const timestamp = computeTimeAtSlot(chain.config, prepareSlot, prepareState.genesisTime);
const prevRandao = getRandaoMix(prepareState, prepareState.epochCtx.epoch);
const payloadAttributes = {

View File

@@ -1,11 +1,11 @@
import {allForks} from "@lodestar/types";
import {ExecutionPayload} from "@lodestar/types";
import {BlobsBundle} from "../../execution/index.js";
/**
* Optionally sanity-check that the KZG commitments match the versioned hashes in the transactions
* https://github.com/ethereum/consensus-specs/blob/11a037fd9227e29ee809c9397b09f8cc3383a8c0/specs/eip4844/validator.md#blob-kzg-commitments
*/
export function validateBlobsAndKzgCommitments(payload: allForks.ExecutionPayload, blobsBundle: BlobsBundle): void {
export function validateBlobsAndKzgCommitments(payload: ExecutionPayload, blobsBundle: BlobsBundle): void {
// sanity-check that the KZG commitments match the blobs (as produced by the execution engine)
if (blobsBundle.blobs.length !== blobsBundle.commitments.length) {
throw Error(

View File

@@ -1,4 +1,4 @@
import {allForks, phase0, Slot, RootHex, Epoch} from "@lodestar/types";
import {phase0, Slot, RootHex, Epoch, BeaconBlock} from "@lodestar/types";
import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
import {routes} from "@lodestar/api";
import {ProtoBlock} from "@lodestar/fork-choice";
@@ -36,7 +36,7 @@ export interface IStateRegenerator extends IStateRegeneratorInternal {
dropCache(): void;
dumpCacheSummary(): routes.lodestar.StateCacheItem[];
getStateSync(stateRoot: RootHex): CachedBeaconStateAllForks | null;
getPreStateSync(block: allForks.BeaconBlock): CachedBeaconStateAllForks | null;
getPreStateSync(block: BeaconBlock): CachedBeaconStateAllForks | null;
getCheckpointStateOrBytes(cp: CheckpointHex): Promise<CachedBeaconStateAllForks | Uint8Array | null>;
getCheckpointStateSync(cp: CheckpointHex): CachedBeaconStateAllForks | null;
getClosestHeadState(head: ProtoBlock): CachedBeaconStateAllForks | null;
@@ -56,11 +56,7 @@ export interface IStateRegeneratorInternal {
* Return a valid pre-state for a beacon block
* This will always return a state in the latest viable epoch
*/
getPreState(
block: allForks.BeaconBlock,
opts: StateCloneOpts,
rCaller: RegenCaller
): Promise<CachedBeaconStateAllForks>;
getPreState(block: BeaconBlock, opts: StateCloneOpts, rCaller: RegenCaller): Promise<CachedBeaconStateAllForks>;
/**
* Return a valid checkpoint state

View File

@@ -1,5 +1,5 @@
import {toHexString} from "@chainsafe/ssz";
import {phase0, Slot, allForks, RootHex, Epoch} from "@lodestar/types";
import {phase0, Slot, RootHex, Epoch, BeaconBlock} from "@lodestar/types";
import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
import {CachedBeaconStateAllForks, computeEpochAtSlot} from "@lodestar/state-transition";
import {Logger} from "@lodestar/utils";
@@ -86,7 +86,7 @@ export class QueuedStateRegenerator implements IStateRegenerator {
* which is usually the gossip block.
*/
getPreStateSync(
block: allForks.BeaconBlock,
block: BeaconBlock,
opts: StateCloneOpts = {dontTransferCache: true}
): CachedBeaconStateAllForks | null {
const parentRoot = toHexString(block.parentRoot);
@@ -200,7 +200,7 @@ export class QueuedStateRegenerator implements IStateRegenerator {
* - State after `block.parentRoot` dialed forward to block.slot
*/
async getPreState(
block: allForks.BeaconBlock,
block: BeaconBlock,
opts: StateCloneOpts,
rCaller: RegenCaller
): Promise<CachedBeaconStateAllForks> {

View File

@@ -1,5 +1,5 @@
import {fromHexString, toHexString} from "@chainsafe/ssz";
import {allForks, phase0, Slot, RootHex} from "@lodestar/types";
import {phase0, Slot, RootHex, BeaconBlock} from "@lodestar/types";
import {
CachedBeaconStateAllForks,
computeEpochAtSlot,
@@ -50,7 +50,7 @@ export class StateRegenerator implements IStateRegeneratorInternal {
* - reload state if needed in this flow
*/
async getPreState(
block: allForks.BeaconBlock,
block: BeaconBlock,
opts: StateCloneOpts,
regenCaller: RegenCaller
): Promise<CachedBeaconStateAllForks> {

View File

@@ -5,7 +5,7 @@ import {
getAttesterSlashableIndices,
processAttestationsAltair,
} from "@lodestar/state-transition";
import {allForks, altair, phase0} from "@lodestar/types";
import {BeaconBlock, altair, phase0} from "@lodestar/types";
import {ForkName, WHISTLEBLOWER_REWARD_QUOTIENT} from "@lodestar/params";
import {routes} from "@lodestar/api";
@@ -21,7 +21,7 @@ type SubRewardValue = number; // All reward values should be integer
* 3) Reporting slashable behaviours from proposer and attester
*/
export async function computeBlockRewards(
block: allForks.BeaconBlock,
block: BeaconBlock,
preState: CachedBeaconStateAllForks,
postState?: CachedBeaconStateAllForks
): Promise<BlockRewards> {
@@ -99,10 +99,7 @@ function computeSyncAggregateReward(block: altair.BeaconBlock, preState: CachedB
* Calculate rewards received by block proposer for including proposer slashings.
* All proposer slashing rewards go to block proposer and none to whistleblower as of Deneb
*/
function computeBlockProposerSlashingReward(
block: allForks.BeaconBlock,
state: CachedBeaconStateAllForks
): SubRewardValue {
function computeBlockProposerSlashingReward(block: BeaconBlock, state: CachedBeaconStateAllForks): SubRewardValue {
let proposerSlashingReward = 0;
for (const proposerSlashing of block.body.proposerSlashings) {
@@ -119,10 +116,7 @@ function computeBlockProposerSlashingReward(
* Calculate rewards received by block proposer for including attester slashings.
* All attester slashing rewards go to block proposer and none to whistleblower as of Deneb
*/
function computeBlockAttesterSlashingReward(
block: allForks.BeaconBlock,
preState: CachedBeaconStateAllForks
): SubRewardValue {
function computeBlockAttesterSlashingReward(block: BeaconBlock, preState: CachedBeaconStateAllForks): SubRewardValue {
let attesterSlashingReward = 0;
for (const attesterSlashing of block.body.attesterSlashings) {

View File

@@ -1,5 +1,5 @@
import {CachedBeaconStateAllForks, CachedBeaconStateAltair} from "@lodestar/state-transition";
import {ValidatorIndex, allForks, altair} from "@lodestar/types";
import {BeaconBlock, ValidatorIndex, altair} from "@lodestar/types";
import {ForkName, SYNC_COMMITTEE_SIZE} from "@lodestar/params";
import {routes} from "@lodestar/api";
@@ -7,7 +7,7 @@ export type SyncCommitteeRewards = routes.beacon.SyncCommitteeRewards;
type BalanceRecord = {val: number}; // Use val for convenient way to increment/decrement balance
export async function computeSyncCommitteeRewards(
block: allForks.BeaconBlock,
block: BeaconBlock,
preState: CachedBeaconStateAllForks,
validatorIds: (ValidatorIndex | string)[] = []
): Promise<SyncCommitteeRewards> {

View File

@@ -1,5 +1,5 @@
import {toHexString} from "@chainsafe/ssz";
import {deneb, RootHex, ssz, allForks} from "@lodestar/types";
import {deneb, RootHex, SignedBeaconBlock, ssz} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {pruneSetToMax} from "@lodestar/utils";
import {BLOBSIDECAR_FIXED_SIZE, isForkBlobs, ForkName} from "@lodestar/params";
@@ -23,12 +23,12 @@ export enum BlockInputAvailabilitySource {
}
type GossipedBlockInput =
| {type: GossipedInputType.block; signedBlock: allForks.SignedBeaconBlock; blockBytes: Uint8Array | null}
| {type: GossipedInputType.block; signedBlock: SignedBeaconBlock; blockBytes: Uint8Array | null}
| {type: GossipedInputType.blob; blobSidecar: deneb.BlobSidecar; blobBytes: Uint8Array | null};
type BlockInputCacheType = {
fork: ForkName;
block?: allForks.SignedBeaconBlock;
block?: SignedBeaconBlock;
blockBytes?: Uint8Array | null;
cachedData?: CachedData;
// block promise and its callback cached for delayed resolution

View File

@@ -1,6 +1,5 @@
import {toHexString} from "@chainsafe/ssz";
import {ChainForkConfig} from "@lodestar/config";
import {allForks} from "@lodestar/types";
import {
computeStartSlotAtEpoch,
computeTimeAtSlot,
@@ -11,6 +10,7 @@ import {
} from "@lodestar/state-transition";
import {sleep} from "@lodestar/utils";
import {ForkName} from "@lodestar/params";
import {SignedBeaconBlock} from "@lodestar/types";
import {MAXIMUM_GOSSIP_CLOCK_DISPARITY} from "../../constants/index.js";
import {IBeaconChain} from "../interface.js";
import {BlockGossipError, BlockErrorCode, GossipAction} from "../errors/index.js";
@@ -19,7 +19,7 @@ import {RegenCaller} from "../regen/index.js";
export async function validateGossipBlock(
config: ChainForkConfig,
chain: IBeaconChain,
signedBlock: allForks.SignedBeaconBlock,
signedBlock: SignedBeaconBlock,
fork: ForkName
): Promise<void> {
const block = signedBlock.message;

View File

@@ -1,5 +1,5 @@
import {ChainForkConfig} from "@lodestar/config";
import {allForks} from "@lodestar/types";
import {LightClientFinalityUpdate} from "@lodestar/types";
import {IBeaconChain} from "../interface.js";
import {LightClientError, LightClientErrorCode} from "../errors/lightClientError.js";
import {GossipAction} from "../errors/index.js";
@@ -9,7 +9,7 @@ import {updateReceivedTooEarly} from "./lightClientOptimisticUpdate.js";
export function validateLightClientFinalityUpdate(
config: ChainForkConfig,
chain: IBeaconChain,
gossipedFinalityUpdate: allForks.LightClientFinalityUpdate
gossipedFinalityUpdate: LightClientFinalityUpdate
): void {
// [IGNORE] No other finality_update with a lower or equal finalized_header.slot was already forwarded on the network
const gossipedFinalitySlot = gossipedFinalityUpdate.finalizedHeader.beacon.slot;

View File

@@ -1,6 +1,6 @@
import {allForks} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {computeTimeAtSlot} from "@lodestar/state-transition";
import {LightClientOptimisticUpdate} from "@lodestar/types";
import {IBeaconChain} from "../interface.js";
import {LightClientError, LightClientErrorCode} from "../errors/lightClientError.js";
import {GossipAction} from "../errors/index.js";
@@ -10,7 +10,7 @@ import {MAXIMUM_GOSSIP_CLOCK_DISPARITY} from "../../constants/index.js";
export function validateLightClientOptimisticUpdate(
config: ChainForkConfig,
chain: IBeaconChain,
gossipedOptimisticUpdate: allForks.LightClientOptimisticUpdate
gossipedOptimisticUpdate: LightClientOptimisticUpdate
): void {
// [IGNORE] No other optimistic_update with a lower or equal attested_header.slot was already forwarded on the network
const gossipedAttestedSlot = gossipedOptimisticUpdate.attestedHeader.beacon.slot;
@@ -56,7 +56,7 @@ export function validateLightClientOptimisticUpdate(
export function updateReceivedTooEarly(
config: ChainForkConfig,
genesisTime: number,
update: Pick<allForks.LightClientOptimisticUpdate, "signatureSlot">
update: Pick<LightClientOptimisticUpdate, "signatureSlot">
): boolean {
const signatureSlot13TimestampMs = computeTimeAtSlot(config, update.signatureSlot + 1 / 3, genesisTime) * 1000;
const earliestAllowedTimestampMs = signatureSlot13TimestampMs - MAXIMUM_GOSSIP_CLOCK_DISPARITY;

View File

@@ -29,7 +29,7 @@ export enum Bucket {
phase0_attesterSlashing = 15, // Root -> AttesterSlashing
capella_blsToExecutionChange = 16, // ValidatorIndex -> SignedBLSToExecutionChange
// checkpoint states
allForks_checkpointState = 17, // Root -> allForks.BeaconState
allForks_checkpointState = 17, // Root -> BeaconState
// allForks_pendingBlock = 25, // Root -> SignedBeaconBlock // DEPRECATED on v0.30.0
phase0_depositEvent = 19, // depositIndex -> DepositEvent

View File

@@ -1,6 +1,6 @@
import {ChainForkConfig} from "@lodestar/config";
import {Db, Repository} from "@lodestar/db";
import {allForks, ssz} from "@lodestar/types";
import {SignedBeaconBlock, ssz} from "@lodestar/types";
import {getSignedBlockTypeFromBytes} from "../../util/multifork.js";
import {Bucket, getBucketNameByValue} from "../buckets.js";
@@ -9,7 +9,7 @@ import {Bucket, getBucketNameByValue} from "../buckets.js";
*
* Used to store unfinalized blocks
*/
export class BlockRepository extends Repository<Uint8Array, allForks.SignedBeaconBlock> {
export class BlockRepository extends Repository<Uint8Array, SignedBeaconBlock> {
constructor(config: ChainForkConfig, db: Db) {
const bucket = Bucket.allForks_block;
const type = ssz.phase0.SignedBeaconBlock; // Pick some type but won't be used
@@ -19,15 +19,15 @@ export class BlockRepository extends Repository<Uint8Array, allForks.SignedBeaco
/**
* Id is hashTreeRoot of unsigned BeaconBlock
*/
getId(value: allForks.SignedBeaconBlock): Uint8Array {
getId(value: SignedBeaconBlock): Uint8Array {
return this.config.getForkTypes(value.message.slot).BeaconBlock.hashTreeRoot(value.message);
}
encodeValue(value: allForks.SignedBeaconBlock): Buffer {
encodeValue(value: SignedBeaconBlock): Buffer {
return this.config.getForkTypes(value.message.slot).SignedBeaconBlock.serialize(value) as Buffer;
}
decodeValue(data: Buffer): allForks.SignedBeaconBlock {
decodeValue(data: Buffer): SignedBeaconBlock {
return getSignedBlockTypeFromBytes(this.config, data).deserialize(data);
}
}

View File

@@ -1,7 +1,7 @@
import all from "it-all";
import {ChainForkConfig} from "@lodestar/config";
import {Db, Repository, KeyValue, FilterOptions} from "@lodestar/db";
import {Slot, Root, allForks, ssz} from "@lodestar/types";
import {Slot, Root, ssz, SignedBeaconBlock} from "@lodestar/types";
import {bytesToInt} from "@lodestar/utils";
import {getSignedBlockTypeFromBytes} from "../../util/multifork.js";
import {Bucket, getBucketNameByValue} from "../buckets.js";
@@ -21,7 +21,7 @@ export type BlockArchiveBatchPutBinaryItem = KeyValue<Slot, Uint8Array> & {
/**
* Stores finalized blocks. Block slot is identifier.
*/
export class BlockArchiveRepository extends Repository<Slot, allForks.SignedBeaconBlock> {
export class BlockArchiveRepository extends Repository<Slot, SignedBeaconBlock> {
constructor(config: ChainForkConfig, db: Db) {
const bucket = Bucket.allForks_blockArchive;
const type = ssz.phase0.SignedBeaconBlock; // Pick some type but won't be used
@@ -30,17 +30,17 @@ export class BlockArchiveRepository extends Repository<Slot, allForks.SignedBeac
// Overrides for multi-fork
encodeValue(value: allForks.SignedBeaconBlock): Uint8Array {
encodeValue(value: SignedBeaconBlock): Uint8Array {
return this.config.getForkTypes(value.message.slot).SignedBeaconBlock.serialize(value);
}
decodeValue(data: Uint8Array): allForks.SignedBeaconBlock {
decodeValue(data: Uint8Array): SignedBeaconBlock {
return getSignedBlockTypeFromBytes(this.config, data).deserialize(data);
}
// Handle key as slot
getId(value: allForks.SignedBeaconBlock): Slot {
getId(value: SignedBeaconBlock): Slot {
return value.message.slot;
}
@@ -50,7 +50,7 @@ export class BlockArchiveRepository extends Repository<Slot, allForks.SignedBeac
// Overrides to index
async put(key: Slot, value: allForks.SignedBeaconBlock): Promise<void> {
async put(key: Slot, value: SignedBeaconBlock): Promise<void> {
const blockRoot = this.config.getForkTypes(value.message.slot).BeaconBlock.hashTreeRoot(value.message);
const slot = value.message.slot;
await Promise.all([
@@ -60,7 +60,7 @@ export class BlockArchiveRepository extends Repository<Slot, allForks.SignedBeac
]);
}
async batchPut(items: KeyValue<Slot, allForks.SignedBeaconBlock>[]): Promise<void> {
async batchPut(items: KeyValue<Slot, SignedBeaconBlock>[]): Promise<void> {
await Promise.all([
super.batchPut(items),
Array.from(items).map((item) => {
@@ -84,7 +84,7 @@ export class BlockArchiveRepository extends Repository<Slot, allForks.SignedBeac
]);
}
async remove(value: allForks.SignedBeaconBlock): Promise<void> {
async remove(value: SignedBeaconBlock): Promise<void> {
await Promise.all([
super.remove(value),
deleteRootIndex(this.db, this.config.getForkTypes(value.message.slot).SignedBeaconBlock, value),
@@ -92,7 +92,7 @@ export class BlockArchiveRepository extends Repository<Slot, allForks.SignedBeac
]);
}
async batchRemove(values: allForks.SignedBeaconBlock[]): Promise<void> {
async batchRemove(values: SignedBeaconBlock[]): Promise<void> {
await Promise.all([
super.batchRemove(values),
Array.from(values).map((value) =>
@@ -102,7 +102,7 @@ export class BlockArchiveRepository extends Repository<Slot, allForks.SignedBeac
]);
}
async *valuesStream(opts?: BlockFilterOptions): AsyncIterable<allForks.SignedBeaconBlock> {
async *valuesStream(opts?: BlockFilterOptions): AsyncIterable<SignedBeaconBlock> {
const firstSlot = this.getFirstSlot(opts);
const valuesStream = super.valuesStream(opts);
const step = (opts && opts.step) ?? 1;
@@ -114,13 +114,13 @@ export class BlockArchiveRepository extends Repository<Slot, allForks.SignedBeac
}
}
async values(opts?: BlockFilterOptions): Promise<allForks.SignedBeaconBlock[]> {
async values(opts?: BlockFilterOptions): Promise<SignedBeaconBlock[]> {
return all(this.valuesStream(opts));
}
// INDEX
async getByRoot(root: Root): Promise<allForks.SignedBeaconBlock | null> {
async getByRoot(root: Root): Promise<SignedBeaconBlock | null> {
const slot = await this.getSlotByRoot(root);
return slot !== null ? this.get(slot) : null;
}
@@ -130,7 +130,7 @@ export class BlockArchiveRepository extends Repository<Slot, allForks.SignedBeac
return slot !== null ? ({key: slot, value: await this.getBinary(slot)} as KeyValue<Slot, Buffer>) : null;
}
async getByParentRoot(root: Root): Promise<allForks.SignedBeaconBlock | null> {
async getByParentRoot(root: Root): Promise<SignedBeaconBlock | null> {
const slot = await this.getSlotByParentRoot(root);
return slot !== null ? this.get(slot) : null;
}

View File

@@ -1,6 +1,7 @@
import {Db, encodeKey} from "@lodestar/db";
import {Slot, Root, allForks, ssz} from "@lodestar/types";
import {Slot, Root, ssz, SignedBeaconBlock, SSZTypesFor} from "@lodestar/types";
import {intToBytes} from "@lodestar/utils";
import {ForkAll} from "@lodestar/params";
import {Bucket} from "../buckets.js";
export async function storeRootIndex(db: Db, slot: Slot, blockRoot: Root): Promise<void> {
@@ -13,14 +14,14 @@ export async function storeParentRootIndex(db: Db, slot: Slot, parentRoot: Root)
export async function deleteRootIndex(
db: Db,
signedBeaconBlockType: allForks.AllForksSSZTypes["SignedBeaconBlock"],
block: allForks.SignedBeaconBlock
signedBeaconBlockType: SSZTypesFor<ForkAll, "SignedBeaconBlock">,
block: SignedBeaconBlock
): Promise<void> {
const beaconBlockType = (signedBeaconBlockType as typeof ssz.phase0.SignedBeaconBlock).fields["message"];
return db.delete(getRootIndexKey(beaconBlockType.hashTreeRoot(block.message)));
}
export async function deleteParentRootIndex(db: Db, block: allForks.SignedBeaconBlock): Promise<void> {
export async function deleteParentRootIndex(db: Db, block: SignedBeaconBlock): Promise<void> {
return db.delete(getParentRootIndexKey(block.message.parentRoot));
}

View File

@@ -1,6 +1,6 @@
import {ChainForkConfig} from "@lodestar/config";
import {DatabaseController, Repository} from "@lodestar/db";
import {ssz, SyncPeriod, allForks} from "@lodestar/types";
import {LightClientUpdate, ssz, SyncPeriod} from "@lodestar/types";
import {Bucket, getBucketNameByValue} from "../buckets.js";
const SLOT_BYTE_COUNT = 8;
@@ -10,7 +10,7 @@ const SLOT_BYTE_COUNT = 8;
*
* Used to prepare light client updates
*/
export class BestLightClientUpdateRepository extends Repository<SyncPeriod, allForks.LightClientUpdate> {
export class BestLightClientUpdateRepository extends Repository<SyncPeriod, LightClientUpdate> {
constructor(config: ChainForkConfig, db: DatabaseController<Uint8Array, Uint8Array>) {
// Pick some type but won't be used
const bucket = Bucket.lightClient_bestLightClientUpdate;
@@ -18,7 +18,7 @@ export class BestLightClientUpdateRepository extends Repository<SyncPeriod, allF
}
// Overrides for multi-fork
encodeValue(value: allForks.LightClientUpdate): Uint8Array {
encodeValue(value: LightClientUpdate): Uint8Array {
// Not easy to have a fixed slot position for all forks in attested header, so lets
// prefix by attestedHeader's slot bytes
const slotBytes = ssz.Slot.serialize(value.attestedHeader.beacon.slot);
@@ -33,7 +33,7 @@ export class BestLightClientUpdateRepository extends Repository<SyncPeriod, allF
return prefixedData;
}
decodeValue(data: Uint8Array): allForks.LightClientUpdate {
decodeValue(data: Uint8Array): LightClientUpdate {
// First slot is written
const slot = ssz.Slot.deserialize(data.subarray(0, SLOT_BYTE_COUNT));
return this.config.getLightClientForkTypes(slot).LightClientUpdate.deserialize(data.subarray(SLOT_BYTE_COUNT));

View File

@@ -1,6 +1,6 @@
import {ChainForkConfig} from "@lodestar/config";
import {DatabaseController, Repository} from "@lodestar/db";
import {ssz, allForks} from "@lodestar/types";
import {LightClientHeader, ssz} from "@lodestar/types";
import {Bucket, getBucketNameByValue} from "../buckets.js";
import {getLightClientHeaderTypeFromBytes} from "../../util/multifork.js";
@@ -10,7 +10,7 @@ import {getLightClientHeaderTypeFromBytes} from "../../util/multifork.js";
*
* Used to prepare light client updates
*/
export class CheckpointHeaderRepository extends Repository<Uint8Array, allForks.LightClientHeader> {
export class CheckpointHeaderRepository extends Repository<Uint8Array, LightClientHeader> {
constructor(config: ChainForkConfig, db: DatabaseController<Uint8Array, Uint8Array>) {
// Pick some type but won't be used
const bucket = Bucket.lightClient_checkpointHeader;
@@ -18,11 +18,11 @@ export class CheckpointHeaderRepository extends Repository<Uint8Array, allForks.
}
// Overrides for multi-fork
encodeValue(value: allForks.LightClientHeader): Uint8Array {
encodeValue(value: LightClientHeader): Uint8Array {
return this.config.getLightClientForkTypes(value.beacon.slot).LightClientHeader.serialize(value);
}
decodeValue(data: Uint8Array): allForks.LightClientHeader {
decodeValue(data: Uint8Array): LightClientHeader {
return getLightClientHeaderTypeFromBytes(this.config, data).deserialize(data);
}
}

View File

@@ -1,8 +1,8 @@
import {GENESIS_SLOT} from "@lodestar/params";
import {allForks} from "@lodestar/types";
import {ForkAll, GENESIS_SLOT} from "@lodestar/params";
import {ChainForkConfig} from "@lodestar/config";
import {Db} from "@lodestar/db";
import {BeaconStateAllForks} from "@lodestar/state-transition";
import {SSZTypesFor} from "@lodestar/types";
import {Bucket} from "../buckets.js";
export class PreGenesisState {
@@ -10,7 +10,7 @@ export class PreGenesisState {
private readonly bucket: Bucket;
private readonly db: Db;
private readonly key: Uint8Array;
private readonly type: allForks.AllForksSSZTypes["BeaconState"];
private readonly type: SSZTypesFor<ForkAll, "BeaconState">;
constructor(config: ChainForkConfig, db: Db) {
this.config = config;

View File

@@ -1,4 +1,14 @@
import {allForks, bellatrix, Slot, Root, BLSPubkey, deneb, Wei} from "@lodestar/types";
import {
bellatrix,
Slot,
Root,
BLSPubkey,
deneb,
Wei,
SignedBeaconBlockOrContents,
SignedBlindedBeaconBlock,
ExecutionPayloadHeader,
} from "@lodestar/types";
import {parseExecutionPayloadAndBlobsBundle, reconstructFullBlockOrContents} from "@lodestar/state-transition";
import {ChainForkConfig} from "@lodestar/config";
import {Logger} from "@lodestar/logger";
@@ -101,7 +111,7 @@ export class ExecutionBuilderHttp implements IExecutionBuilder {
parentHash: Root,
proposerPubkey: BLSPubkey
): Promise<{
header: allForks.ExecutionPayloadHeader;
header: ExecutionPayloadHeader;
executionPayloadValue: Wei;
blobKzgCommitments?: deneb.BlobKzgCommitments;
}> {
@@ -116,9 +126,7 @@ export class ExecutionBuilderHttp implements IExecutionBuilder {
return {header, executionPayloadValue, blobKzgCommitments};
}
async submitBlindedBlock(
signedBlindedBlock: allForks.SignedBlindedBeaconBlock
): Promise<allForks.SignedBeaconBlockOrContents> {
async submitBlindedBlock(signedBlindedBlock: SignedBlindedBeaconBlock): Promise<SignedBeaconBlockOrContents> {
const data = (await this.api.submitBlindedBlock({signedBlindedBlock}, {retries: 2})).value();
const {executionPayload, blobsBundle} = parseExecutionPayloadAndBlobsBundle(data);

View File

@@ -1,4 +1,14 @@
import {allForks, bellatrix, Root, Slot, BLSPubkey, deneb, Wei} from "@lodestar/types";
import {
bellatrix,
Root,
Slot,
BLSPubkey,
deneb,
Wei,
SignedBeaconBlockOrContents,
ExecutionPayloadHeader,
SignedBlindedBeaconBlock,
} from "@lodestar/types";
import {ForkExecution} from "@lodestar/params";
export interface IExecutionBuilder {
@@ -23,9 +33,9 @@ export interface IExecutionBuilder {
parentHash: Root,
proposerPubKey: BLSPubkey
): Promise<{
header: allForks.ExecutionPayloadHeader;
header: ExecutionPayloadHeader;
executionPayloadValue: Wei;
blobKzgCommitments?: deneb.BlobKzgCommitments;
}>;
submitBlindedBlock(signedBlock: allForks.SignedBlindedBeaconBlock): Promise<allForks.SignedBeaconBlockOrContents>;
submitBlindedBlock(signedBlock: SignedBlindedBeaconBlock): Promise<SignedBeaconBlockOrContents>;
}

View File

@@ -1,4 +1,4 @@
import {Root, RootHex, allForks, Wei} from "@lodestar/types";
import {ExecutionPayload, Root, RootHex, Wei} from "@lodestar/types";
import {SLOTS_PER_EPOCH, ForkName, ForkSeq} from "@lodestar/params";
import {Logger} from "@lodestar/logger";
import {
@@ -171,7 +171,7 @@ export class ExecutionEngineHttp implements IExecutionEngine {
*/
async notifyNewPayload(
fork: ForkName,
executionPayload: allForks.ExecutionPayload,
executionPayload: ExecutionPayload,
versionedHashes?: VersionedHashes,
parentBlockRoot?: Root
): Promise<ExecutePayloadResponse> {
@@ -364,7 +364,7 @@ export class ExecutionEngineHttp implements IExecutionEngine {
fork: ForkName,
payloadId: PayloadId
): Promise<{
executionPayload: allForks.ExecutionPayload;
executionPayload: ExecutionPayload;
executionPayloadValue: Wei;
blobsBundle?: BlobsBundle;
shouldOverrideBuilder?: boolean;

View File

@@ -1,6 +1,6 @@
import {ForkName} from "@lodestar/params";
import {KZGCommitment, Blob, KZGProof} from "@lodestar/types/deneb";
import {Root, RootHex, allForks, capella, Wei} from "@lodestar/types";
import {Root, RootHex, capella, Wei, ExecutionPayload} from "@lodestar/types";
import {DATA} from "../../eth1/provider/utils.js";
import {PayloadIdCache, PayloadId, WithdrawalV1} from "./payloadIdCache.js";
@@ -101,7 +101,7 @@ export interface IExecutionEngine {
*/
notifyNewPayload(
fork: ForkName,
executionPayload: allForks.ExecutionPayload,
executionPayload: ExecutionPayload,
versionedHashes?: VersionedHashes,
parentBeaconBlockRoot?: Root
): Promise<ExecutePayloadResponse>;
@@ -137,7 +137,7 @@ export interface IExecutionEngine {
fork: ForkName,
payloadId: PayloadId
): Promise<{
executionPayload: allForks.ExecutionPayload;
executionPayload: ExecutionPayload;
executionPayloadValue: Wei;
blobsBundle?: BlobsBundle;
shouldOverrideBuilder?: boolean;

View File

@@ -1,4 +1,4 @@
import {allForks, capella, deneb, Wei, bellatrix, Root} from "@lodestar/types";
import {capella, deneb, Wei, bellatrix, Root, ExecutionPayload} from "@lodestar/types";
import {
BYTES_PER_LOGS_BLOOM,
FIELD_ELEMENTS_PER_BLOB,
@@ -163,7 +163,7 @@ export interface BlobsBundleRpc {
proofs: DATA[]; // some ELs could also provide proofs, each 48 bytes
}
export function serializeExecutionPayload(fork: ForkName, data: allForks.ExecutionPayload): ExecutionPayloadRpc {
export function serializeExecutionPayload(fork: ForkName, data: ExecutionPayload): ExecutionPayloadRpc {
const payload: ExecutionPayloadRpc = {
parentHash: bytesToData(data.parentHash),
feeRecipient: bytesToData(data.feeRecipient),
@@ -209,7 +209,7 @@ export function parseExecutionPayload(
fork: ForkName,
response: ExecutionPayloadResponse
): {
executionPayload: allForks.ExecutionPayload;
executionPayload: ExecutionPayload;
executionPayloadValue: Wei;
blobsBundle?: BlobsBundle;
shouldOverrideBuilder?: boolean;

View File

@@ -1,5 +1,5 @@
import {EpochTransitionStep, StateCloneSource, StateHashTreeRootSource} from "@lodestar/state-transition";
import {allForks} from "@lodestar/types";
import {BeaconState} from "@lodestar/types";
import {BlockSource, BlobsSource} from "../../chain/blocks/types.js";
import {JobQueueItemType} from "../../chain/bls/index.js";
import {BlockErrorCode} from "../../chain/errors/index.js";
@@ -28,7 +28,7 @@ export type LodestarMetrics = ReturnType<typeof createLodestarMetrics>;
export function createLodestarMetrics(
register: RegistryMetricCreator,
metadata?: LodestarMetadata,
anchorState?: Pick<allForks.BeaconState, "genesisTime">
anchorState?: Pick<BeaconState, "genesisTime">
) {
if (metadata) {
register.static<LodestarMetadata>({

View File

@@ -10,7 +10,7 @@ import {
ParticipationFlags,
} from "@lodestar/state-transition";
import {LogData, LogHandler, LogLevel, Logger, MapDef, MapDefMax, toHex} from "@lodestar/utils";
import {RootHex, allForks, altair, deneb} from "@lodestar/types";
import {BeaconBlock, RootHex, altair, deneb} from "@lodestar/types";
import {ChainConfig, ChainForkConfig} from "@lodestar/config";
import {ForkSeq, INTERVALS_PER_SLOT, MIN_ATTESTATION_INCLUSION_DELAY, SLOTS_PER_EPOCH} from "@lodestar/params";
import {Epoch, Slot, ValidatorIndex} from "@lodestar/types";
@@ -40,9 +40,9 @@ export type ValidatorMonitor = {
registerLocalValidator(index: number): void;
registerLocalValidatorInSyncCommittee(index: number, untilEpoch: Epoch): void;
registerValidatorStatuses(currentEpoch: Epoch, statuses: AttesterStatus[], balances?: number[]): void;
registerBeaconBlock(src: OpSource, seenTimestampSec: Seconds, block: allForks.BeaconBlock): void;
registerBeaconBlock(src: OpSource, seenTimestampSec: Seconds, block: BeaconBlock): void;
registerBlobSidecar(src: OpSource, seenTimestampSec: Seconds, blob: deneb.BlobSidecar): void;
registerImportedBlock(block: allForks.BeaconBlock, data: {proposerBalanceDelta: number}): void;
registerImportedBlock(block: BeaconBlock, data: {proposerBalanceDelta: number}): void;
onPoolSubmitUnaggregatedAttestation(
seenTimestampSec: number,
indexedAttestation: IndexedAttestation,

View File

@@ -2,7 +2,16 @@ import {Libp2p} from "libp2p";
import {Message, TopicValidatorResult} from "@libp2p/interface";
import {PeerIdStr} from "@chainsafe/libp2p-gossipsub/types";
import {ForkName} from "@lodestar/params";
import {allForks, altair, capella, deneb, phase0, Slot} from "@lodestar/types";
import {
altair,
capella,
deneb,
LightClientFinalityUpdate,
LightClientOptimisticUpdate,
phase0,
SignedBeaconBlock,
Slot,
} from "@lodestar/types";
import {BeaconConfig} from "@lodestar/config";
import {Logger} from "@lodestar/utils";
import {IBeaconChain} from "../../chain/index.js";
@@ -69,7 +78,7 @@ export type SSZTypeOfGossipTopic<T extends GossipTopic> = T extends {type: infer
: never;
export type GossipTypeMap = {
[GossipType.beacon_block]: allForks.SignedBeaconBlock;
[GossipType.beacon_block]: SignedBeaconBlock;
[GossipType.blob_sidecar]: deneb.BlobSidecar;
[GossipType.beacon_aggregate_and_proof]: phase0.SignedAggregateAndProof;
[GossipType.beacon_attestation]: phase0.Attestation;
@@ -78,13 +87,13 @@ export type GossipTypeMap = {
[GossipType.attester_slashing]: phase0.AttesterSlashing;
[GossipType.sync_committee_contribution_and_proof]: altair.SignedContributionAndProof;
[GossipType.sync_committee]: altair.SyncCommitteeMessage;
[GossipType.light_client_finality_update]: allForks.LightClientFinalityUpdate;
[GossipType.light_client_optimistic_update]: allForks.LightClientOptimisticUpdate;
[GossipType.light_client_finality_update]: LightClientFinalityUpdate;
[GossipType.light_client_optimistic_update]: LightClientOptimisticUpdate;
[GossipType.bls_to_execution_change]: capella.SignedBLSToExecutionChange;
};
export type GossipFnByType = {
[GossipType.beacon_block]: (signedBlock: allForks.SignedBeaconBlock) => Promise<void> | void;
[GossipType.beacon_block]: (signedBlock: SignedBeaconBlock) => Promise<void> | void;
[GossipType.blob_sidecar]: (blobSidecar: deneb.BlobSidecar) => Promise<void> | void;
[GossipType.beacon_aggregate_and_proof]: (aggregateAndProof: phase0.SignedAggregateAndProof) => Promise<void> | void;
[GossipType.beacon_attestation]: (attestation: phase0.Attestation) => Promise<void> | void;
@@ -96,10 +105,10 @@ export type GossipFnByType = {
) => Promise<void> | void;
[GossipType.sync_committee]: (syncCommittee: altair.SyncCommitteeMessage) => Promise<void> | void;
[GossipType.light_client_finality_update]: (
lightClientFinalityUpdate: allForks.LightClientFinalityUpdate
lightClientFinalityUpdate: LightClientFinalityUpdate
) => Promise<void> | void;
[GossipType.light_client_optimistic_update]: (
lightClientOptimisticUpdate: allForks.LightClientOptimisticUpdate
lightClientOptimisticUpdate: LightClientOptimisticUpdate
) => Promise<void> | void;
[GossipType.bls_to_execution_change]: (
blsToExecutionChange: capella.SignedBLSToExecutionChange

View File

@@ -16,7 +16,17 @@ import {
import type {AddressManager, ConnectionManager, Registrar, TransportManager} from "@libp2p/interface-internal";
import type {Datastore} from "interface-datastore";
import {Identify} from "@chainsafe/libp2p-identify";
import {Slot, SlotRootHex, allForks, altair, capella, deneb, phase0} from "@lodestar/types";
import {
LightClientFinalityUpdate,
LightClientOptimisticUpdate,
SignedBeaconBlock,
Slot,
SlotRootHex,
altair,
capella,
deneb,
phase0,
} from "@lodestar/types";
import {PeerIdStr} from "../util/peerId.js";
import {INetworkEventBus} from "./events.js";
import {INetworkCorePublic} from "./core/types.js";
@@ -50,16 +60,16 @@ export interface INetwork extends INetworkCorePublic {
sendBeaconBlocksByRange(
peerId: PeerIdStr,
request: phase0.BeaconBlocksByRangeRequest
): Promise<WithBytes<allForks.SignedBeaconBlock>[]>;
): Promise<WithBytes<SignedBeaconBlock>[]>;
sendBeaconBlocksByRoot(
peerId: PeerIdStr,
request: phase0.BeaconBlocksByRootRequest
): Promise<WithBytes<allForks.SignedBeaconBlock>[]>;
): Promise<WithBytes<SignedBeaconBlock>[]>;
sendBlobSidecarsByRange(peerId: PeerIdStr, request: deneb.BlobSidecarsByRangeRequest): Promise<deneb.BlobSidecar[]>;
sendBlobSidecarsByRoot(peerId: PeerIdStr, request: deneb.BlobSidecarsByRootRequest): Promise<deneb.BlobSidecar[]>;
// Gossip
publishBeaconBlock(signedBlock: allForks.SignedBeaconBlock): Promise<number>;
publishBeaconBlock(signedBlock: SignedBeaconBlock): Promise<number>;
publishBlobSidecar(blobSidecar: deneb.BlobSidecar): Promise<number>;
publishBeaconAggregateAndProof(aggregateAndProof: phase0.SignedAggregateAndProof): Promise<number>;
publishBeaconAttestation(attestation: phase0.Attestation, subnet: number): Promise<number>;
@@ -69,8 +79,8 @@ export interface INetwork extends INetworkCorePublic {
publishAttesterSlashing(attesterSlashing: phase0.AttesterSlashing): Promise<number>;
publishSyncCommitteeSignature(signature: altair.SyncCommitteeMessage, subnet: number): Promise<number>;
publishContributionAndProof(contributionAndProof: altair.SignedContributionAndProof): Promise<number>;
publishLightClientFinalityUpdate(update: allForks.LightClientFinalityUpdate): Promise<number>;
publishLightClientOptimisticUpdate(update: allForks.LightClientOptimisticUpdate): Promise<number>;
publishLightClientFinalityUpdate(update: LightClientFinalityUpdate): Promise<number>;
publishLightClientOptimisticUpdate(update: LightClientOptimisticUpdate): Promise<number>;
// Debug
dumpGossipQueue(gossipType: GossipType): Promise<PendingGossipsubMessage[]>;

View File

@@ -5,7 +5,19 @@ import {BeaconConfig} from "@lodestar/config";
import {sleep} from "@lodestar/utils";
import {LoggerNode} from "@lodestar/logger/node";
import {computeStartSlotAtEpoch, computeTimeAtSlot} from "@lodestar/state-transition";
import {phase0, allForks, deneb, altair, Root, capella, SlotRootHex} from "@lodestar/types";
import {
phase0,
deneb,
altair,
Root,
capella,
SlotRootHex,
SignedBeaconBlock,
LightClientBootstrap,
LightClientFinalityUpdate,
LightClientOptimisticUpdate,
LightClientUpdate,
} from "@lodestar/types";
import {routes} from "@lodestar/api";
import {ResponseIncoming} from "@lodestar/reqresp";
import {ForkSeq, MAX_BLOBS_PER_BLOCK} from "@lodestar/params";
@@ -287,7 +299,7 @@ export class Network implements INetwork {
// Gossip
async publishBeaconBlock(signedBlock: allForks.SignedBeaconBlock): Promise<number> {
async publishBeaconBlock(signedBlock: SignedBeaconBlock): Promise<number> {
const fork = this.config.getForkName(signedBlock.message.slot);
return this.publishGossip<GossipType.beacon_block>({type: GossipType.beacon_block, fork}, signedBlock, {
ignoreDuplicatePublishError: true,
@@ -380,7 +392,7 @@ export class Network implements INetwork {
);
}
async publishLightClientFinalityUpdate(update: allForks.LightClientFinalityUpdate): Promise<number> {
async publishLightClientFinalityUpdate(update: LightClientFinalityUpdate): Promise<number> {
const fork = this.config.getForkName(update.signatureSlot);
return this.publishGossip<GossipType.light_client_finality_update>(
{type: GossipType.light_client_finality_update, fork},
@@ -388,7 +400,7 @@ export class Network implements INetwork {
);
}
async publishLightClientOptimisticUpdate(update: allForks.LightClientOptimisticUpdate): Promise<number> {
async publishLightClientOptimisticUpdate(update: LightClientOptimisticUpdate): Promise<number> {
const fork = this.config.getForkName(update.signatureSlot);
return this.publishGossip<GossipType.light_client_optimistic_update>(
{type: GossipType.light_client_optimistic_update, fork},
@@ -419,7 +431,7 @@ export class Network implements INetwork {
async sendBeaconBlocksByRange(
peerId: PeerIdStr,
request: phase0.BeaconBlocksByRangeRequest
): Promise<WithBytes<allForks.SignedBeaconBlock>[]> {
): Promise<WithBytes<SignedBeaconBlock>[]> {
return collectSequentialBlocksInRange(
this.sendReqRespRequest(
peerId,
@@ -435,7 +447,7 @@ export class Network implements INetwork {
async sendBeaconBlocksByRoot(
peerId: PeerIdStr,
request: phase0.BeaconBlocksByRootRequest
): Promise<WithBytes<allForks.SignedBeaconBlock>[]> {
): Promise<WithBytes<SignedBeaconBlock>[]> {
return collectMaxResponseTypedWithBytes(
this.sendReqRespRequest(
peerId,
@@ -449,21 +461,21 @@ export class Network implements INetwork {
);
}
async sendLightClientBootstrap(peerId: PeerIdStr, request: Root): Promise<allForks.LightClientBootstrap> {
async sendLightClientBootstrap(peerId: PeerIdStr, request: Root): Promise<LightClientBootstrap> {
return collectExactOneTyped(
this.sendReqRespRequest(peerId, ReqRespMethod.LightClientBootstrap, [Version.V1], request),
responseSszTypeByMethod[ReqRespMethod.LightClientBootstrap]
);
}
async sendLightClientOptimisticUpdate(peerId: PeerIdStr): Promise<allForks.LightClientOptimisticUpdate> {
async sendLightClientOptimisticUpdate(peerId: PeerIdStr): Promise<LightClientOptimisticUpdate> {
return collectExactOneTyped(
this.sendReqRespRequest(peerId, ReqRespMethod.LightClientOptimisticUpdate, [Version.V1], null),
responseSszTypeByMethod[ReqRespMethod.LightClientOptimisticUpdate]
);
}
async sendLightClientFinalityUpdate(peerId: PeerIdStr): Promise<allForks.LightClientFinalityUpdate> {
async sendLightClientFinalityUpdate(peerId: PeerIdStr): Promise<LightClientFinalityUpdate> {
return collectExactOneTyped(
this.sendReqRespRequest(peerId, ReqRespMethod.LightClientFinalityUpdate, [Version.V1], null),
responseSszTypeByMethod[ReqRespMethod.LightClientFinalityUpdate]
@@ -473,7 +485,7 @@ export class Network implements INetwork {
async sendLightClientUpdatesByRange(
peerId: PeerIdStr,
request: altair.LightClientUpdatesByRange
): Promise<allForks.LightClientUpdate[]> {
): Promise<LightClientUpdate[]> {
return collectMaxResponseTyped(
this.sendReqRespRequest(peerId, ReqRespMethod.LightClientUpdatesByRange, [Version.V1], request),
request.count,
@@ -571,7 +583,7 @@ export class Network implements INetwork {
return this.core.writeDiscv5HeapSnapshot(prefix, dirpath);
}
private onLightClientFinalityUpdate = async (finalityUpdate: allForks.LightClientFinalityUpdate): Promise<void> => {
private onLightClientFinalityUpdate = async (finalityUpdate: LightClientFinalityUpdate): Promise<void> => {
// TODO: Review is OK to remove if (this.hasAttachedSyncCommitteeMember())
try {
@@ -588,9 +600,7 @@ export class Network implements INetwork {
}
};
private onLightClientOptimisticUpdate = async (
optimisticUpdate: allForks.LightClientOptimisticUpdate
): Promise<void> => {
private onLightClientOptimisticUpdate = async (optimisticUpdate: LightClientOptimisticUpdate): Promise<void> => {
// TODO: Review is OK to remove if (this.hasAttachedSyncCommitteeMember())
try {

View File

@@ -2,7 +2,7 @@ import {Connection, PeerId} from "@libp2p/interface";
import {BitArray} from "@chainsafe/ssz";
import {SYNC_COMMITTEE_SUBNET_COUNT} from "@lodestar/params";
import {BeaconConfig} from "@lodestar/config";
import {allForks, altair, phase0} from "@lodestar/types";
import {Metadata, altair, phase0} from "@lodestar/types";
import {withTimeout} from "@lodestar/utils";
import {LoggerNode} from "@lodestar/logger/node";
import {GoodByeReasonCode, GOODBYE_KNOWN_CODES, Libp2pEvent} from "../../constants/index.js";
@@ -90,7 +90,7 @@ export interface IReqRespBeaconNodePeerManager {
sendPing(peerId: PeerId): Promise<phase0.Ping>;
sendStatus(peerId: PeerId, request: phase0.Status): Promise<phase0.Status>;
sendGoodbye(peerId: PeerId, request: phase0.Goodbye): Promise<void>;
sendMetadata(peerId: PeerId): Promise<allForks.Metadata>;
sendMetadata(peerId: PeerId): Promise<Metadata>;
}
export type PeerManagerModules = {
@@ -301,7 +301,7 @@ export class PeerManager {
/**
* Handle a METADATA request + response (rpc handler responds with METADATA automatically)
*/
private onMetadata(peer: PeerId, metadata: allForks.Metadata): void {
private onMetadata(peer: PeerId, metadata: Metadata): void {
// Store metadata always in case the peer updates attnets but not the sequence number
// Trust that the peer always sends the latest metadata (From Lighthouse)
const peerData = this.connectedPeers.get(peer.toString());

View File

@@ -1,7 +1,7 @@
import {toHexString} from "@chainsafe/ssz";
import {BeaconConfig, ChainForkConfig} from "@lodestar/config";
import {LogLevel, Logger, prettyBytes} from "@lodestar/utils";
import {Root, Slot, ssz, allForks, deneb, UintNum64} from "@lodestar/types";
import {Root, Slot, ssz, deneb, UintNum64, SignedBeaconBlock} from "@lodestar/types";
import {ForkName, ForkSeq} from "@lodestar/params";
import {routes} from "@lodestar/api";
import {computeTimeAtSlot} from "@lodestar/state-transition";
@@ -113,7 +113,7 @@ function getDefaultHandlers(modules: ValidatorFnsModules, options: GossipHandler
const {chain, config, metrics, events, logger, core, aggregatorTracker} = modules;
async function validateBeaconBlock(
signedBlock: allForks.SignedBeaconBlock,
signedBlock: SignedBeaconBlock,
blockBytes: Uint8Array,
fork: ForkName,
peerIdStr: string,

View File

@@ -13,7 +13,7 @@ import {
ResponseIncoming,
ResponseOutgoing,
} from "@lodestar/reqresp";
import {allForks, phase0, ssz} from "@lodestar/types";
import {Metadata, phase0, ssz} from "@lodestar/types";
import {Logger} from "@lodestar/utils";
import {INetworkEventBus, NetworkEvent} from "../events.js";
import {MetadataController} from "../metadata.js";
@@ -184,7 +184,7 @@ export class ReqRespBeaconNode extends ReqResp {
);
}
async sendMetadata(peerId: PeerId): Promise<allForks.Metadata> {
async sendMetadata(peerId: PeerId): Promise<Metadata> {
return collectExactOneTyped(
this.sendReqRespRequest(
peerId,

View File

@@ -1,5 +1,5 @@
import {ChainForkConfig} from "@lodestar/config";
import {deneb, Epoch, phase0, allForks, Slot} from "@lodestar/types";
import {deneb, Epoch, phase0, SignedBeaconBlock, Slot} from "@lodestar/types";
import {ForkSeq} from "@lodestar/params";
import {computeEpochAtSlot} from "@lodestar/state-transition";
@@ -55,7 +55,7 @@ export async function beaconBlocksMaybeBlobsByRange(
// Assumes that the blobs are in the same sequence as blocks, doesn't require block to be sorted
export function matchBlockWithBlobs(
config: ChainForkConfig,
allBlocks: WithBytes<allForks.SignedBeaconBlock>[],
allBlocks: WithBytes<SignedBeaconBlock>[],
allBlobSidecars: deneb.BlobSidecar[],
endSlot: Slot,
blockSource: BlockSource,

View File

@@ -1,7 +1,7 @@
import {Type} from "@chainsafe/ssz";
import {ForkLightClient, ForkName, isForkLightClient} from "@lodestar/params";
import {Protocol, ProtocolHandler, ReqRespRequest} from "@lodestar/reqresp";
import {Root, allForks, altair, deneb, phase0, ssz} from "@lodestar/types";
import {Metadata, Root, SignedBeaconBlock, altair, deneb, phase0, ssz} from "@lodestar/types";
export type ProtocolNoHandler = Omit<Protocol, "handler">;
@@ -42,10 +42,10 @@ type ResponseBodyByMethod = {
[ReqRespMethod.Status]: phase0.Status;
[ReqRespMethod.Goodbye]: phase0.Goodbye;
[ReqRespMethod.Ping]: phase0.Ping;
[ReqRespMethod.Metadata]: allForks.Metadata;
[ReqRespMethod.Metadata]: Metadata;
// Do not matter
[ReqRespMethod.BeaconBlocksByRange]: allForks.SignedBeaconBlock;
[ReqRespMethod.BeaconBlocksByRoot]: allForks.SignedBeaconBlock;
[ReqRespMethod.BeaconBlocksByRange]: SignedBeaconBlock;
[ReqRespMethod.BeaconBlocksByRoot]: SignedBeaconBlock;
[ReqRespMethod.BlobSidecarsByRange]: deneb.BlobSidecar;
[ReqRespMethod.BlobSidecarsByRoot]: deneb.BlobSidecar;
[ReqRespMethod.LightClientBootstrap]: altair.LightClientBootstrap;
@@ -74,7 +74,7 @@ export const requestSszTypeByMethod: {
export type ResponseTypeGetter<T> = (fork: ForkName, version: number) => Type<T>;
const blocksResponseType: ResponseTypeGetter<allForks.SignedBeaconBlock> = (fork, version) => {
const blocksResponseType: ResponseTypeGetter<SignedBeaconBlock> = (fork, version) => {
if (version === Version.V1) {
return ssz.phase0.SignedBeaconBlock;
} else {

View File

@@ -1,6 +1,6 @@
import {ResponseIncoming} from "@lodestar/reqresp";
import {allForks, phase0} from "@lodestar/types";
import {LodestarError} from "@lodestar/utils";
import {phase0, SignedBeaconBlock} from "@lodestar/types";
import {WithBytes} from "../../interface.js";
import {ReqRespMethod, responseSszTypeByMethod} from "../types.js";
import {sszDeserializeResponse} from "./collect.js";
@@ -12,8 +12,8 @@ import {sszDeserializeResponse} from "./collect.js";
export async function collectSequentialBlocksInRange(
blockStream: AsyncIterable<ResponseIncoming>,
{count, startSlot}: Pick<phase0.BeaconBlocksByRangeRequest, "count" | "startSlot">
): Promise<WithBytes<allForks.SignedBeaconBlock>[]> {
const blocks: WithBytes<allForks.SignedBeaconBlock>[] = [];
): Promise<WithBytes<SignedBeaconBlock>[]> {
const blocks: WithBytes<SignedBeaconBlock>[] = [];
for await (const chunk of blockStream) {
const blockType = responseSszTypeByMethod[ReqRespMethod.BeaconBlocksByRange](chunk.fork, chunk.protocolVersion);

View File

@@ -3,7 +3,7 @@ import {StrictEventEmitter} from "strict-event-emitter-types";
import {toHexString} from "@chainsafe/ssz";
import {BeaconStateAllForks, blockToHeader} from "@lodestar/state-transition";
import {BeaconConfig, ChainForkConfig} from "@lodestar/config";
import {phase0, Root, Slot, allForks, ssz} from "@lodestar/types";
import {phase0, Root, SignedBeaconBlock, Slot, ssz} from "@lodestar/types";
import {ErrorAborted, Logger, sleep, toHex} from "@lodestar/utils";
import {SLOTS_PER_EPOCH} from "@lodestar/params";
@@ -94,7 +94,7 @@ type BackfillSyncEmitter = StrictEventEmitter<EventEmitter, BackfillSyncEvents>;
*/
type BackFillSyncAnchor =
| {
anchorBlock: allForks.SignedBeaconBlock;
anchorBlock: SignedBeaconBlock;
anchorBlockRoot: Root;
anchorSlot: Slot;
lastBackSyncedBlock: BackfillBlock;

View File

@@ -1,6 +1,6 @@
import {CachedBeaconStateAllForks, ISignatureSet, getBlockProposerSignatureSet} from "@lodestar/state-transition";
import {BeaconConfig} from "@lodestar/config";
import {allForks, Root, allForks as allForkTypes, ssz, Slot} from "@lodestar/types";
import {Root, ssz, Slot, SignedBeaconBlock} from "@lodestar/types";
import {GENESIS_SLOT} from "@lodestar/params";
import {IBlsVerifier} from "../../chain/bls/index.js";
import {WithBytes} from "../../network/interface.js";
@@ -11,21 +11,21 @@ export type BackfillBlockHeader = {
root: Root;
};
export type BackfillBlock = BackfillBlockHeader & {block: allForks.SignedBeaconBlock};
export type BackfillBlock = BackfillBlockHeader & {block: SignedBeaconBlock};
export function verifyBlockSequence(
config: BeaconConfig,
blocks: WithBytes<allForkTypes.SignedBeaconBlock>[],
blocks: WithBytes<SignedBeaconBlock>[],
anchorRoot: Root
): {
nextAnchor: BackfillBlock | null;
verifiedBlocks: WithBytes<allForkTypes.SignedBeaconBlock>[];
verifiedBlocks: WithBytes<SignedBeaconBlock>[];
error?: BackfillSyncErrorCode.NOT_LINEAR;
} {
let nextRoot: Root = anchorRoot;
let nextAnchor: BackfillBlock | null = null;
const verifiedBlocks: WithBytes<allForkTypes.SignedBeaconBlock>[] = [];
const verifiedBlocks: WithBytes<SignedBeaconBlock>[] = [];
for (const block of blocks.reverse()) {
const blockRoot = config.getForkTypes(block.data.message.slot).BeaconBlock.hashTreeRoot(block.data.message);
if (!ssz.Root.equals(blockRoot, nextRoot)) {
@@ -44,7 +44,7 @@ export function verifyBlockSequence(
export async function verifyBlockProposerSignature(
bls: IBlsVerifier,
state: CachedBeaconStateAllForks,
blocks: WithBytes<allForkTypes.SignedBeaconBlock>[]
blocks: WithBytes<SignedBeaconBlock>[]
): Promise<void> {
if (blocks.length === 1 && blocks[0].data.message.slot === GENESIS_SLOT) return;
const signatures = blocks.reduce((sigs: ISignatureSet[], block) => {

View File

@@ -1,7 +1,7 @@
import {digest as sha256Digest} from "@chainsafe/as-sha256";
import {Tree} from "@chainsafe/persistent-merkle-tree";
import {VERSIONED_HASH_VERSION_KZG, KZG_COMMITMENT_GINDEX0, ForkName} from "@lodestar/params";
import {deneb, ssz, allForks} from "@lodestar/types";
import {VERSIONED_HASH_VERSION_KZG, KZG_COMMITMENT_GINDEX0, ForkName, ForkAll} from "@lodestar/params";
import {deneb, ssz, BeaconBlockBody, SignedBeaconBlock, SSZTypesFor} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {signedBlockToSignedHeader} from "@lodestar/state-transition";
@@ -16,17 +16,17 @@ export function kzgCommitmentToVersionedHash(kzgCommitment: deneb.KZGCommitment)
export function computeInclusionProof(
fork: ForkName,
body: allForks.BeaconBlockBody,
body: BeaconBlockBody,
index: number
): deneb.KzgCommitmentInclusionProof {
const bodyView = (ssz[fork].BeaconBlockBody as allForks.AllForksSSZTypes["BeaconBlockBody"]).toView(body);
const bodyView = (ssz[fork].BeaconBlockBody as SSZTypesFor<ForkAll, "BeaconBlockBody">).toView(body);
const commitmentGindex = KZG_COMMITMENT_GINDEX0 + index;
return new Tree(bodyView.node).getSingleProof(BigInt(commitmentGindex));
}
export function computeBlobSidecars(
config: ChainForkConfig,
signedBlock: allForks.SignedBeaconBlock,
signedBlock: SignedBeaconBlock,
contents: deneb.Contents & {kzgCommitmentInclusionProofs?: deneb.KzgCommitmentInclusionProof[]}
): deneb.BlobSidecars {
const blobKzgCommitments = (signedBlock as deneb.SignedBeaconBlock).message.body.blobKzgCommitments;

View File

@@ -1,6 +1,7 @@
import {ChainForkConfig} from "@lodestar/config";
import {Slot, allForks} from "@lodestar/types";
import {SSZTypesFor, Slot} from "@lodestar/types";
import {bytesToInt} from "@lodestar/utils";
import {ForkAll, ForkLightClient} from "@lodestar/params";
import {getSlotFromSignedBeaconBlockSerialized} from "./sszBytes.js";
/**
@@ -23,7 +24,7 @@ const SLOT_BYTES_POSITION_IN_STATE = 40;
export function getSignedBlockTypeFromBytes(
config: ChainForkConfig,
bytes: Buffer | Uint8Array
): allForks.AllForksSSZTypes["SignedBeaconBlock"] {
): SSZTypesFor<ForkAll, "SignedBeaconBlock"> {
const slot = getSlotFromSignedBeaconBlockSerialized(bytes);
if (slot === null) {
throw Error("getSignedBlockTypeFromBytes: invalid bytes");
@@ -35,7 +36,7 @@ export function getSignedBlockTypeFromBytes(
export function getStateTypeFromBytes(
config: ChainForkConfig,
bytes: Buffer | Uint8Array
): allForks.AllForksSSZTypes["BeaconState"] {
): SSZTypesFor<ForkAll, "BeaconState"> {
const slot = getStateSlotFromBytes(bytes);
return config.getForkTypes(slot).BeaconState;
}
@@ -60,7 +61,7 @@ const SLOT_BYTES_POSITION_IN_LIGHTCLIENTHEADER = 0;
export function getLightClientHeaderTypeFromBytes(
config: ChainForkConfig,
bytes: Buffer | Uint8Array
): allForks.AllForksLightClientSSZTypes["LightClientHeader"] {
): SSZTypesFor<ForkLightClient, "LightClientHeader"> {
const slot = bytesToInt(
bytes.subarray(SLOT_BYTES_POSITION_IN_LIGHTCLIENTHEADER, SLOT_BYTES_POSITION_IN_LIGHTCLIENTHEADER + SLOT_BYTE_COUNT)
);

View File

@@ -88,7 +88,7 @@ describe.skip("doppelganger / doppelganger test", function () {
const validatorUnderTest = validatorsWithDoppelganger[0];
const pubKey = validatorUnderTest.validatorStore.votingPubkeys()[0];
const beaconBlock = ssz.allForks.phase0.BeaconBlock.defaultValue();
const beaconBlock = ssz.phase0.BeaconBlock.defaultValue();
await expect(
validatorUnderTest.validatorStore.signBlock(fromHexString(pubKey), beaconBlock, bn.chain.clock.currentSlot)
@@ -241,7 +241,7 @@ describe.skip("doppelganger / doppelganger test", function () {
const validatorUnderTest = validatorsWithDoppelganger[0];
const pubKey = validatorUnderTest.validatorStore.votingPubkeys()[0];
const beaconBlock = ssz.allForks.phase0.BeaconBlock.defaultValue();
const beaconBlock = ssz.phase0.BeaconBlock.defaultValue();
await expect(
validatorUnderTest.validatorStore.signBlock(fromHexString(pubKey), beaconBlock, bn.chain.clock.currentSlot)

View File

@@ -3,7 +3,7 @@ import {createChainForkConfig, ChainForkConfig} from "@lodestar/config";
import {chainConfig} from "@lodestar/config/default";
import {ForkName} from "@lodestar/params";
import {RequestError, RequestErrorCode, ResponseOutgoing} from "@lodestar/reqresp";
import {allForks, altair, phase0, Root, ssz} from "@lodestar/types";
import {altair, phase0, Root, SignedBeaconBlock, ssz} from "@lodestar/types";
import {sleep as _sleep} from "@lodestar/utils";
import {Network, ReqRespBeaconNodeOpts} from "../../../src/network/index.js";
import {expectRejectedWithLodestarError} from "../../utils/errors.js";
@@ -328,7 +328,7 @@ function getEmptyEncodedPayloadSignedBeaconBlock(config: ChainForkConfig): Respo
return wrapBlockAsEncodedPayload(config, config.getForkTypes(0).SignedBeaconBlock.defaultValue());
}
function wrapBlockAsEncodedPayload(config: ChainForkConfig, block: allForks.SignedBeaconBlock): ResponseOutgoing {
function wrapBlockAsEncodedPayload(config: ChainForkConfig, block: SignedBeaconBlock): ResponseOutgoing {
return {
data: config.getForkTypes(block.message.slot).SignedBeaconBlock.serialize(block),
fork: config.getForkName(block.message.slot),

View File

@@ -1,5 +1,5 @@
import {ForkChoice} from "@lodestar/fork-choice";
import {Slot, allForks} from "@lodestar/types";
import {BeaconBlock, Slot} from "@lodestar/types";
/**
* A specific forkchoice implementation to mark some blocks as timely or not.
@@ -14,7 +14,7 @@ export class TimelinessForkChoice extends ForkChoice {
/**
* This is to mark the `lateSlot` as not timely.
*/
protected isBlockTimely(block: allForks.BeaconBlock, blockDelaySec: number): boolean {
protected isBlockTimely(block: BeaconBlock, blockDelaySec: number): boolean {
if (block.slot === this.lateSlot) {
return false;
}

View File

@@ -5,7 +5,7 @@ import {LogLevel, sleep} from "@lodestar/utils";
import {TimestampFormatCode} from "@lodestar/logger";
import {SLOTS_PER_EPOCH} from "@lodestar/params";
import {ChainConfig} from "@lodestar/config";
import {Epoch, allForks, bellatrix} from "@lodestar/types";
import {Epoch, SignedBeaconBlock, bellatrix} from "@lodestar/types";
import {ValidatorProposerConfig} from "@lodestar/validator";
import {routes} from "@lodestar/api";
@@ -213,7 +213,7 @@ describe("executionEngine / ExecutionEngineHttp", function () {
await new Promise<void>((resolve, _reject) => {
bn.chain.emitter.on(routes.events.EventType.block, async (blockData) => {
const {data: fullOrBlindedBlock} = (await bn.api.beacon.getBlockV2({blockId: blockData.block})) as {
data: allForks.SignedBeaconBlock;
data: SignedBeaconBlock;
};
if (fullOrBlindedBlock !== undefined) {
const blockFeeRecipient = toHexString(

View File

@@ -4,7 +4,7 @@ import {toHexString} from "@chainsafe/ssz";
import {BeaconStateAllForks, isExecutionStateType, signedBlockToSignedHeader} from "@lodestar/state-transition";
import {InputType} from "@lodestar/spec-test-util";
import {CheckpointWithHex, ForkChoice} from "@lodestar/fork-choice";
import {phase0, allForks, bellatrix, ssz, RootHex, deneb} from "@lodestar/types";
import {phase0, bellatrix, ssz, RootHex, deneb, BeaconBlock, SignedBeaconBlock} from "@lodestar/types";
import {bnToNum, fromHex} from "@lodestar/utils";
import {createBeaconConfig} from "@lodestar/config";
import {ACTIVE_PRESET, ForkSeq, isForkBlobs, ForkName} from "@lodestar/params";
@@ -345,7 +345,7 @@ const forkChoiceTest =
},
mapToTestCase: (t: Record<string, any>) => {
// t has input file name as key
const blocks = new Map<string, allForks.SignedBeaconBlock>();
const blocks = new Map<string, SignedBeaconBlock>();
const blobs = new Map<string, deneb.Blobs>();
const powBlocks = new Map<string, bellatrix.PowBlock>();
const attestations = new Map<string, phase0.Attestation>();
@@ -487,9 +487,9 @@ type ForkChoiceTestCase = {
bls_setting: bigint;
};
anchorState: BeaconStateAllForks;
anchorBlock: allForks.BeaconBlock;
anchorBlock: BeaconBlock;
steps: Step[];
blocks: Map<string, allForks.SignedBeaconBlock>;
blocks: Map<string, SignedBeaconBlock>;
blobs: Map<string, deneb.Blobs>;
powBlocks: Map<string, bellatrix.PowBlock>;
attestations: Map<string, phase0.Attestation>;

View File

@@ -1,6 +1,6 @@
import path from "node:path";
import {expect} from "vitest";
import {phase0, Root, ssz, TimeSeconds, allForks, deneb} from "@lodestar/types";
import {phase0, Root, ssz, TimeSeconds, ExecutionPayloadHeader} from "@lodestar/types";
import {InputType} from "@lodestar/spec-test-util";
import {
BeaconStateAllForks,
@@ -60,7 +60,9 @@ const genesisInitialization: TestRunnerFn<GenesisInitSpecTest, BeaconStateAllFor
deposits,
undefined,
testcase["execution_payload_header"] &&
executionPayloadHeaderType.toViewDU(testcase["execution_payload_header"] as deneb.ExecutionPayloadHeader)
executionPayloadHeaderType.toViewDU(
testcase["execution_payload_header"] as ExecutionPayloadHeader<ForkName.deneb>
)
);
},
// eth1.yaml
@@ -141,7 +143,7 @@ type GenesisInitSpecTest = {
meta: {
deposits_count: number;
};
execution_payload_header?: allForks.ExecutionPayloadHeader;
execution_payload_header?: ExecutionPayloadHeader;
state: BeaconStateAllForks;
};

View File

@@ -1,5 +1,5 @@
import {expect} from "vitest";
import {altair, ssz, allForks} from "@lodestar/types";
import {LightClientUpdate, altair, ssz} from "@lodestar/types";
import {isForkLightClient} from "@lodestar/params";
import {InputType} from "@lodestar/spec-test-util";
import {isBetterUpdate, LightClientUpdateSummary, toLightClientUpdateSummary} from "@lodestar/light-client/spec";
@@ -22,7 +22,7 @@ export const updateRanking: TestRunnerFn<UpdateRankingTestCase, void> = (fork) =
testFunction: (testcase) => {
// Parse update files
const updatesCount = Number(testcase.meta.updates_count as bigint);
const updates: allForks.LightClientUpdate[] = [];
const updates: LightClientUpdate[] = [];
for (let i = 0; i < updatesCount; i++) {
const update = (testcase as unknown as Record<string, altair.LightClientUpdate>)[`updates_${i}`];

View File

@@ -7,7 +7,7 @@ import {
processSlots,
stateTransition,
} from "@lodestar/state-transition";
import {allForks, deneb, ssz} from "@lodestar/types";
import {SignedBeaconBlock, deneb, ssz} from "@lodestar/types";
import {ACTIVE_PRESET, ForkName} from "@lodestar/params";
import {bnToNum} from "@lodestar/utils";
import {createCachedBeaconStateTest} from "../../utils/cachedBeaconState.js";
@@ -107,7 +107,7 @@ export function generateBlocksSZZTypeMapping(fork: ForkName, n: number): BlocksS
}
type SanityBlocksTestCase = {
[k: string]: allForks.SignedBeaconBlock | unknown | null | undefined;
[k: string]: SignedBeaconBlock | unknown | null | undefined;
meta: {
blocks_count: number;
bls_setting: bigint;

View File

@@ -5,7 +5,7 @@ import {
ExecutionPayloadStatus,
stateTransition,
} from "@lodestar/state-transition";
import {allForks, ssz} from "@lodestar/types";
import {SignedBeaconBlock, ssz} from "@lodestar/types";
import {createChainForkConfig, ChainConfig} from "@lodestar/config";
import {ACTIVE_PRESET, ForkName} from "@lodestar/params";
import {bnToNum} from "@lodestar/utils";
@@ -53,7 +53,7 @@ const transition =
let state = createCachedBeaconStateTest(testcase.pre, testConfig);
for (let i = 0; i < meta.blocks_count; i++) {
const signedBlock = testcase[`blocks_${i}`] as allForks.SignedBeaconBlock;
const signedBlock = testcase[`blocks_${i}`] as SignedBeaconBlock;
state = stateTransition(state, signedBlock, {
// Assume valid and available for this test
executionPayloadStatus: ExecutionPayloadStatus.valid,
@@ -108,7 +108,7 @@ function getTransitionConfig(fork: ForkName, forkEpoch: number): Partial<ChainCo
type BlocksSZZTypeMapping = Record<string, (typeof ssz)[ForkName]["SignedBeaconBlock"]>;
type TransitionTestCase = {
[k: string]: allForks.SignedBeaconBlock | unknown | null | undefined;
[k: string]: SignedBeaconBlock | unknown | null | undefined;
meta: {
post_fork: ForkName;
fork_epoch: bigint;

View File

@@ -1,6 +1,6 @@
import {expect} from "vitest";
import {allForks, ssz} from "@lodestar/types";
import {ForkName} from "@lodestar/params";
import {SSZTypesFor, ssz} from "@lodestar/types";
import {ForkAll, ForkName} from "@lodestar/params";
import {InputType} from "@lodestar/spec-test-util";
import {BeaconStateAllForks} from "@lodestar/state-transition";
@@ -14,7 +14,7 @@ export function expectEqualBeaconState(
const expected = expectedView.toValue();
const actual = actualView.toValue();
const stateType = ssz[fork].BeaconState as allForks.AllForksSSZTypes["BeaconState"];
const stateType = ssz[fork].BeaconState as SSZTypesFor<ForkAll, "BeaconState">;
if (!stateType.equals(actual, expected)) {
expect(stateType.toJson(actual)).to.deep.equal(stateType.toJson(expected));
throw Error("Wrong state");

View File

@@ -4,7 +4,7 @@ import {IForkChoice, ProtoBlock} from "@lodestar/fork-choice";
import {computeStartSlotAtEpoch} from "@lodestar/state-transition";
import {toHex} from "@lodestar/utils";
import {ChainForkConfig} from "@lodestar/config";
import {allForks, Slot, ssz} from "@lodestar/types";
import {SignedBeaconBlock, Slot, ssz} from "@lodestar/types";
import {verifyBlocksSanityChecks as verifyBlocksImportSanityChecks} from "../../../../src/chain/blocks/verifyBlocksSanityChecks.js";
import {BlockErrorCode} from "../../../../src/chain/errors/index.js";
import {expectThrowsLodestarError} from "../../../utils/errors.js";
@@ -17,7 +17,7 @@ describe("chain / blocks / verifyBlocksSanityChecks", function () {
let forkChoice: MockedBeaconChain["forkChoice"];
let clock: ClockStopped;
let modules: {forkChoice: IForkChoice; clock: IClock; config: ChainForkConfig};
let block: allForks.SignedBeaconBlock;
let block: SignedBeaconBlock;
const currentSlot = 1;
beforeEach(() => {
@@ -121,9 +121,9 @@ describe("chain / blocks / verifyBlocksSanityChecks", function () {
*/
function verifyBlocksSanityChecks(
modules: Parameters<typeof verifyBlocksImportSanityChecks>[0],
blocks: allForks.SignedBeaconBlock[],
blocks: SignedBeaconBlock[],
opts: Parameters<typeof verifyBlocksImportSanityChecks>[2]
): {relevantBlocks: allForks.SignedBeaconBlock[]; parentSlots: Slot[]; parentBlock: ProtoBlock | null} {
): {relevantBlocks: SignedBeaconBlock[]; parentSlots: Slot[]; parentBlock: ProtoBlock | null} {
const {relevantBlocks, parentSlots, parentBlock} = verifyBlocksImportSanityChecks(
modules,
blocks.map((block) => getBlockInput.preData(config, block, BlockSource.byRange, null)),
@@ -136,8 +136,8 @@ function verifyBlocksSanityChecks(
};
}
function getValidChain(count: number, initialSlot = 0): allForks.SignedBeaconBlock[] {
const blocks: allForks.SignedBeaconBlock[] = [];
function getValidChain(count: number, initialSlot = 0): SignedBeaconBlock[] {
const blocks: SignedBeaconBlock[] = [];
for (let i = 0; i < count; i++) {
const block = ssz.phase0.SignedBeaconBlock.defaultValue();
@@ -154,7 +154,7 @@ function getValidChain(count: number, initialSlot = 0): allForks.SignedBeaconBlo
return blocks;
}
function getForkChoice(knownBlocks: allForks.SignedBeaconBlock[], finalizedEpoch = 0): IForkChoice {
function getForkChoice(knownBlocks: SignedBeaconBlock[], finalizedEpoch = 0): IForkChoice {
const blocks = new Map<string, ProtoBlock>();
for (const block of knownBlocks) {
const protoBlock = toProtoBlock(block);
@@ -174,7 +174,7 @@ function getForkChoice(knownBlocks: allForks.SignedBeaconBlock[], finalizedEpoch
} as Partial<IForkChoice> as IForkChoice;
}
function toProtoBlock(block: allForks.SignedBeaconBlock): ProtoBlock {
function toProtoBlock(block: SignedBeaconBlock): ProtoBlock {
return {
slot: block.message.slot,
blockRoot: toHex(ssz.phase0.BeaconBlock.hashTreeRoot(block.message)),
@@ -183,17 +183,17 @@ function toProtoBlock(block: allForks.SignedBeaconBlock): ProtoBlock {
} as Partial<ProtoBlock> as ProtoBlock;
}
function slots(blocks: allForks.SignedBeaconBlock[]): Slot[] {
function slots(blocks: SignedBeaconBlock[]): Slot[] {
return blocks.map((block) => block.message.slot);
}
/** Since blocks have no meaning compare the indexes against `allBlocks` */
function expectBlocks(
expectedBlocks: allForks.SignedBeaconBlock[],
actualBlocks: allForks.SignedBeaconBlock[],
allBlocks: allForks.SignedBeaconBlock[]
expectedBlocks: SignedBeaconBlock[],
actualBlocks: SignedBeaconBlock[],
allBlocks: SignedBeaconBlock[]
): void {
function indexOfBlocks(blocks: allForks.SignedBeaconBlock[]): number[] {
function indexOfBlocks(blocks: SignedBeaconBlock[]): number[] {
return blocks.map((block) => allBlocks.indexOf(block));
}

View File

@@ -1,11 +1,11 @@
import {describe, it, expect, beforeEach} from "vitest";
import {ssz, allForks} from "@lodestar/types";
import {LightClientHeader, ssz} from "@lodestar/types";
import {ForkName, ForkSeq} from "@lodestar/params";
import {createBeaconConfig, createChainForkConfig, defaultChainConfig} from "@lodestar/config";
import {upgradeLightClientHeader} from "@lodestar/light-client/spec";
describe("UpgradeLightClientHeader", function () {
let lcHeaderByFork: Record<ForkName, allForks.LightClientHeader>;
let lcHeaderByFork: Record<ForkName, LightClientHeader>;
let testSlots: Record<ForkName, number>;
/* eslint-disable @typescript-eslint/naming-convention */

View File

@@ -2,7 +2,7 @@ import {Mock, Mocked, beforeEach, describe, it, vi} from "vitest";
import {config} from "@lodestar/config/default";
import {ProtoBlock} from "@lodestar/fork-choice";
import {ForkName} from "@lodestar/params";
import {allForks, ssz} from "@lodestar/types";
import {SignedBeaconBlock, ssz} from "@lodestar/types";
import {MockedBeaconChain, getMockedBeaconChain} from "../../../mocks/mockedBeaconChain.js";
import {BlockErrorCode} from "../../../../src/chain/errors/index.js";
import {QueuedStateRegenerator} from "../../../../src/chain/regen/index.js";
@@ -17,7 +17,7 @@ describe("gossip block validation", function () {
let forkChoice: MockedBeaconChain["forkChoice"];
let regen: Mocked<QueuedStateRegenerator>;
let verifySignature: Mock<[boolean]>;
let job: allForks.SignedBeaconBlock;
let job: SignedBeaconBlock;
const proposerIndex = 0;
const clockSlot = 32;
const block = ssz.phase0.BeaconBlock.defaultValue();

View File

@@ -1,5 +1,5 @@
import {describe, it, expect} from "vitest";
import {allForks, phase0, ssz} from "@lodestar/types";
import {SignedBeaconBlock, phase0, ssz} from "@lodestar/types";
import {ResponseIncoming} from "@lodestar/reqresp";
import {ForkName} from "@lodestar/params";
import {
@@ -79,7 +79,7 @@ describe("beacon-node / network / reqresp / utils / collectSequentialBlocksInRan
});
}
async function* arrToSource(arr: allForks.SignedBeaconBlock[]): AsyncGenerator<ResponseIncoming> {
async function* arrToSource(arr: SignedBeaconBlock[]): AsyncGenerator<ResponseIncoming> {
for (const item of arr) {
yield {data: ssz.phase0.SignedBeaconBlock.serialize(item), fork: ForkName.phase0, protocolVersion: 1};
}

View File

@@ -7,7 +7,7 @@ import {
} from "@lodestar/state-transition";
import {BeaconConfig} from "@lodestar/config";
import {SLOTS_PER_EPOCH, SLOTS_PER_HISTORICAL_ROOT} from "@lodestar/params";
import {allForks, Epoch, Slot} from "@lodestar/types";
import {BeaconBlock, Epoch, Slot} from "@lodestar/types";
import {Checkpoint} from "@lodestar/types/phase0";
import {Logger, mapValues} from "@lodestar/utils";
import {routes} from "@lodestar/api";
@@ -93,14 +93,14 @@ export function simTestInfoTracker(bn: BeaconNode, logger: Logger): () => void {
};
}
function sumAttestationBits(block: allForks.BeaconBlock): number {
function sumAttestationBits(block: BeaconBlock): number {
return Array.from(block.body.attestations).reduce(
(total, att) => total + att.aggregationBits.getTrueBitIndexes().length,
0
);
}
function avgInclusionDelay(block: allForks.BeaconBlock): number {
function avgInclusionDelay(block: BeaconBlock): number {
const inclDelay = Array.from(block.body.attestations).map((att) => block.slot - att.data.slot);
return avg(inclDelay);
}

View File

@@ -8,7 +8,7 @@ import {
CachedBeaconStateBellatrix,
BeaconStateBellatrix,
} from "@lodestar/state-transition";
import {allForks, altair, bellatrix, ssz} from "@lodestar/types";
import {BeaconState, altair, bellatrix, ssz} from "@lodestar/types";
import {createBeaconConfig, ChainForkConfig} from "@lodestar/config";
import {FAR_FUTURE_EPOCH, ForkName, ForkSeq, MAX_EFFECTIVE_BALANCE, SYNC_COMMITTEE_SIZE} from "@lodestar/params";
@@ -20,7 +20,7 @@ import {getConfig} from "./config.js";
/**
* Copy of BeaconState, but all fields are marked optional to allow for swapping out variables as needed.
*/
type TestBeaconState = Partial<allForks.BeaconState>;
type TestBeaconState = Partial<BeaconState>;
/**
* Generate beaconState, by default it will generate a mostly empty state with "just enough" to be valid-ish

View File

@@ -6,7 +6,7 @@ import {ApiClient} from "@lodestar/api";
import {ApiClient as KeyManagerApi} from "@lodestar/api/keymanager";
import {ChainForkConfig} from "@lodestar/config";
import {ForkName} from "@lodestar/params";
import {Slot, allForks, Epoch} from "@lodestar/types";
import {Slot, Epoch, SignedBeaconBlock} from "@lodestar/types";
import {LogLevel, Logger} from "@lodestar/logger";
import {BeaconArgs} from "../../../src/cmds/beacon/options.js";
import {IValidatorCliArgs} from "../../../src/cmds/validator/options.js";
@@ -317,7 +317,7 @@ export interface AssertionInput {
}
export interface CaptureInput<D extends Record<string, unknown>> extends AssertionInput {
block: allForks.SignedBeaconBlock;
block: SignedBeaconBlock;
dependantStores: D;
}

View File

@@ -1,5 +1,5 @@
/* eslint-disable no-console */
import {Slot, allForks} from "@lodestar/types";
import {SignedBeaconBlock, Slot} from "@lodestar/types";
import {sleep} from "@lodestar/utils";
import {BeaconClient, BeaconNode, ExecutionClient, ExecutionNode, NodePair} from "../interfaces.js";
import {Simulation} from "../simulation.js";
@@ -155,7 +155,7 @@ export async function waitForSlot(
export async function fetchBlock(
node: NodePair,
{tries, delay, slot, signal}: {slot: number; tries: number; delay: number; signal?: AbortSignal}
): Promise<allForks.SignedBeaconBlock | undefined> {
): Promise<SignedBeaconBlock | undefined> {
for (let i = 0; i < tries; i++) {
const res = await node.beacon.api.beacon.getBlockV2({blockId: slot});
if (!res.ok) {

View File

@@ -1,6 +1,7 @@
import {routes} from "@lodestar/api";
import {Slot} from "@lodestar/types";
import {SignedBeaconBlock, Slot} from "@lodestar/types";
import {sleep, toHex} from "@lodestar/utils";
import {ForkBlobs} from "@lodestar/params";
import type {Simulation} from "../simulation.js";
import {BeaconClient, ExecutionClient, NodePair} from "../interfaces.js";
import {connectNewCLNode, connectNewELNode, connectNewNode, waitForHead, waitForSlot} from "./network.js";
@@ -131,7 +132,7 @@ export async function assertUnknownBlockSync(env: Simulation): Promise<void> {
(
await unknownBlockSync.beacon.api.beacon.publishBlockV2({
signedBlockOrContents: {
signedBlock: currentHead,
signedBlock: currentHead as SignedBeaconBlock<ForkBlobs>,
blobs: currentSidecars.map((b) => b.blob),
kzgProofs: currentSidecars.map((b) => b.kzgProof),
},

View File

@@ -6,8 +6,12 @@ import {
isForkLightClient,
isForkExecution,
isForkBlobs,
ForkExecution,
ForkAll,
ForkLightClient,
ForkBlobs,
} from "@lodestar/params";
import {Slot, allForks, Version, ssz} from "@lodestar/types";
import {Slot, Version, ssz, SSZTypesFor, sszTypesFor} from "@lodestar/types";
import {ChainConfig} from "../chainConfig/index.js";
import {ForkConfig, ForkInfo} from "./types.js";
@@ -87,36 +91,36 @@ export function createForkConfig(config: ChainConfig): ForkConfig {
getForkVersion(slot: Slot): Version {
return this.getForkInfo(slot).version;
},
getForkTypes(slot: Slot): allForks.AllForksSSZTypes {
return ssz.allForks[this.getForkName(slot)] as allForks.AllForksSSZTypes;
getForkTypes<F extends ForkName = ForkAll>(slot: Slot): SSZTypesFor<F> {
return sszTypesFor(this.getForkName(slot)) as SSZTypesFor<F>;
},
getExecutionForkTypes(slot: Slot): allForks.AllForksExecutionSSZTypes {
getExecutionForkTypes(slot: Slot): SSZTypesFor<ForkExecution> {
const forkName = this.getForkName(slot);
if (!isForkExecution(forkName)) {
throw Error(`Invalid slot=${slot} fork=${forkName} for execution fork types`);
}
return ssz.allForksExecution[forkName] as allForks.AllForksExecutionSSZTypes;
return ssz.allForksExecution[forkName];
},
getBlindedForkTypes(slot: Slot): allForks.AllForksBlindedSSZTypes {
getBlindedForkTypes(slot: Slot): (typeof ssz.allForksBlinded)[ForkExecution] {
const forkName = this.getForkName(slot);
if (!isForkExecution(forkName)) {
throw Error(`Invalid slot=${slot} fork=${forkName} for blinded fork types`);
}
return ssz.allForksBlinded[forkName] as allForks.AllForksBlindedSSZTypes;
return ssz.allForksBlinded[forkName];
},
getLightClientForkTypes(slot: Slot): allForks.AllForksLightClientSSZTypes {
getLightClientForkTypes(slot: Slot): SSZTypesFor<ForkLightClient> {
const forkName = this.getForkName(slot);
if (!isForkLightClient(forkName)) {
throw Error(`Invalid slot=${slot} fork=${forkName} for lightclient fork types`);
}
return ssz.allForksLightClient[forkName] as allForks.AllForksLightClientSSZTypes;
return ssz.allForksLightClient[forkName];
},
getBlobsForkTypes(slot: Slot): allForks.AllForksBlobsSSZTypes {
getBlobsForkTypes(slot: Slot): SSZTypesFor<ForkBlobs> {
const forkName = this.getForkName(slot);
if (!isForkBlobs(forkName)) {
throw Error(`Invalid slot=${slot} fork=${forkName} for blobs fork types`);
}
return ssz.allForksBlobs[forkName] as allForks.AllForksBlobsSSZTypes;
return ssz.allForksBlobs[forkName];
},
};
}

View File

@@ -1,5 +1,5 @@
import {ForkName, ForkSeq} from "@lodestar/params";
import {allForks, Epoch, Slot, Version} from "@lodestar/types";
import {ForkAll, ForkBlobs, ForkExecution, ForkLightClient, ForkName, ForkSeq} from "@lodestar/params";
import {Epoch, SSZBlindedTypesFor, SSZTypesFor, Slot, Version} from "@lodestar/types";
export type ForkInfo = {
name: ForkName;
@@ -29,13 +29,13 @@ export type ForkConfig = {
/** Get the hard-fork version at a given slot */
getForkVersion(slot: Slot): Version;
/** Get SSZ types by hard-fork */
getForkTypes(slot: Slot): allForks.AllForksSSZTypes;
getForkTypes<F extends ForkName = ForkAll>(slot: Slot): SSZTypesFor<F>;
/** Get lightclient SSZ types by hard-fork*/
getLightClientForkTypes(slot: Slot): allForks.AllForksLightClientSSZTypes;
getLightClientForkTypes(slot: Slot): SSZTypesFor<ForkLightClient>;
/** Get execution SSZ types by hard-fork*/
getExecutionForkTypes(slot: Slot): allForks.AllForksExecutionSSZTypes;
getExecutionForkTypes(slot: Slot): SSZTypesFor<ForkExecution>;
/** Get blinded SSZ types by hard-fork */
getBlindedForkTypes(slot: Slot): allForks.AllForksBlindedSSZTypes;
getBlindedForkTypes(slot: Slot): SSZBlindedTypesFor<ForkExecution>;
/** Get blobs SSZ types by hard-fork*/
getBlobsForkTypes(slot: Slot): allForks.AllForksBlobsSSZTypes;
getBlobsForkTypes(slot: Slot): SSZTypesFor<ForkBlobs>;
};

View File

@@ -1,7 +1,7 @@
import {toHexString} from "@chainsafe/ssz";
import {Logger, fromHex} from "@lodestar/utils";
import {SLOTS_PER_HISTORICAL_ROOT, SLOTS_PER_EPOCH, INTERVALS_PER_SLOT} from "@lodestar/params";
import {bellatrix, Slot, ValidatorIndex, phase0, allForks, ssz, RootHex, Epoch, Root} from "@lodestar/types";
import {bellatrix, Slot, ValidatorIndex, phase0, ssz, RootHex, Epoch, Root, BeaconBlock} from "@lodestar/types";
import {
computeSlotsSinceEpochStart,
computeStartSlotAtEpoch,
@@ -464,7 +464,7 @@ export class ForkChoice implements IForkChoice {
* This ensures that the forkchoice is never out of sync.
*/
onBlock(
block: allForks.BeaconBlock,
block: BeaconBlock,
state: CachedBeaconStateAllForks,
blockDelaySec: number,
currentSlot: Slot,
@@ -1088,7 +1088,7 @@ export class ForkChoice implements IForkChoice {
* Return true if the block is timely for the current slot.
* Child class can overwrite this for testing purpose.
*/
protected isBlockTimely(block: allForks.BeaconBlock, blockDelaySec: number): boolean {
protected isBlockTimely(block: BeaconBlock, blockDelaySec: number): boolean {
const isBeforeAttestingInterval = blockDelaySec < this.config.SECONDS_PER_SLOT / INTERVALS_PER_SLOT;
return this.fcStore.currentSlot === block.slot && isBeforeAttestingInterval;
}

View File

@@ -1,6 +1,6 @@
import {EffectiveBalanceIncrements} from "@lodestar/state-transition";
import {CachedBeaconStateAllForks} from "@lodestar/state-transition";
import {Epoch, Slot, ValidatorIndex, phase0, allForks, Root, RootHex} from "@lodestar/types";
import {Epoch, Slot, ValidatorIndex, phase0, Root, RootHex, BeaconBlock} from "@lodestar/types";
import {
ProtoBlock,
MaybeValidExecutionStatus,
@@ -131,7 +131,7 @@ export interface IForkChoice {
* The supplied block **must** pass the `state_transition` function as it will not be run here.
*/
onBlock(
block: allForks.BeaconBlock,
block: BeaconBlock,
state: CachedBeaconStateAllForks,
blockDelaySec: number,
currentSlot: Slot,

View File

@@ -1,4 +1,4 @@
import {allForks} from "@lodestar/types";
import {LightClientHeader} from "@lodestar/types";
import {RunStatusCode} from "./index.js";
export enum LightclientEvent {
@@ -8,8 +8,8 @@ export enum LightclientEvent {
}
export type LightclientEmitterEvents = {
[LightclientEvent.lightClientOptimisticHeader]: (newHeader: allForks.LightClientHeader) => void;
[LightclientEvent.lightClientFinalityHeader]: (newHeader: allForks.LightClientHeader) => void;
[LightclientEvent.lightClientOptimisticHeader]: (newHeader: LightClientHeader) => void;
[LightclientEvent.lightClientFinalityHeader]: (newHeader: LightClientHeader) => void;
[LightclientEvent.statusChange]: (code: RunStatusCode) => void;
};

View File

@@ -1,7 +1,17 @@
import mitt from "mitt";
import {fromHexString, toHexString} from "@chainsafe/ssz";
import {EPOCHS_PER_SYNC_COMMITTEE_PERIOD} from "@lodestar/params";
import {phase0, RootHex, Slot, SyncPeriod, allForks} from "@lodestar/types";
import {
LightClientBootstrap,
LightClientFinalityUpdate,
LightClientHeader,
LightClientOptimisticUpdate,
LightClientUpdate,
phase0,
RootHex,
Slot,
SyncPeriod,
} from "@lodestar/types";
import {createBeaconConfig, BeaconConfig, ChainForkConfig} from "@lodestar/config";
import {isErrorAborted, sleep} from "@lodestar/utils";
import {getCurrentSlot, slotWithFutureTolerance, timeUntilNextEpoch} from "./utils/clock.js";
@@ -32,7 +42,7 @@ export type LightclientInitArgs = {
opts?: LightclientOpts;
genesisData: GenesisData;
transport: LightClientTransport;
bootstrap: allForks.LightClientBootstrap;
bootstrap: LightClientBootstrap;
};
/** Provides some protection against a server client sending header updates too far away in the future */
@@ -190,11 +200,11 @@ export class Lightclient {
this.updateRunStatus({code: RunStatusCode.stopped});
}
getHead(): allForks.LightClientHeader {
getHead(): LightClientHeader {
return this.lightclientSpec.store.optimisticHeader;
}
getFinalized(): allForks.LightClientHeader {
getFinalized(): LightClientHeader {
return this.lightclientSpec.store.finalizedHeader;
}
@@ -293,7 +303,7 @@ export class Lightclient {
* Processes new optimistic header updates in only known synced sync periods.
* This headerUpdate may update the head if there's enough participation.
*/
private processOptimisticUpdate(optimisticUpdate: allForks.LightClientOptimisticUpdate): void {
private processOptimisticUpdate(optimisticUpdate: LightClientOptimisticUpdate): void {
this.lightclientSpec.onOptimisticUpdate(this.currentSlotWithTolerance(), optimisticUpdate);
}
@@ -301,11 +311,11 @@ export class Lightclient {
* Processes new header updates in only known synced sync periods.
* This headerUpdate may update the head if there's enough participation.
*/
private processFinalizedUpdate(finalizedUpdate: allForks.LightClientFinalityUpdate): void {
private processFinalizedUpdate(finalizedUpdate: LightClientFinalityUpdate): void {
this.lightclientSpec.onFinalityUpdate(this.currentSlotWithTolerance(), finalizedUpdate);
}
private processSyncCommitteeUpdate(update: allForks.LightClientUpdate): void {
private processSyncCommitteeUpdate(update: LightClientUpdate): void {
this.lightclientSpec.onUpdate(this.currentSlotWithTolerance(), update);
}

View File

@@ -1,6 +1,12 @@
import {BeaconConfig} from "@lodestar/config";
import {UPDATE_TIMEOUT} from "@lodestar/params";
import {Slot, allForks} from "@lodestar/types";
import {
LightClientBootstrap,
LightClientFinalityUpdate,
LightClientOptimisticUpdate,
LightClientUpdate,
Slot,
} from "@lodestar/types";
import {computeSyncPeriodAtSlot} from "../utils/index.js";
import {getSyncCommitteeAtPeriod, processLightClientUpdate, ProcessUpdateOpts} from "./processLightClientUpdate.js";
import {ILightClientStore, LightClientStore, LightClientStoreEvents} from "./store.js";
@@ -17,17 +23,17 @@ export class LightclientSpec {
constructor(
config: BeaconConfig,
private readonly opts: ProcessUpdateOpts & LightClientStoreEvents,
bootstrap: allForks.LightClientBootstrap
bootstrap: LightClientBootstrap
) {
this.store = new LightClientStore(config, bootstrap, opts);
this.config = config;
}
onUpdate(currentSlot: Slot, update: allForks.LightClientUpdate): void {
onUpdate(currentSlot: Slot, update: LightClientUpdate): void {
processLightClientUpdate(this.config, this.store, currentSlot, this.opts, update);
}
onFinalityUpdate(currentSlot: Slot, finalityUpdate: allForks.LightClientFinalityUpdate): void {
onFinalityUpdate(currentSlot: Slot, finalityUpdate: LightClientFinalityUpdate): void {
this.onUpdate(currentSlot, {
attestedHeader: finalityUpdate.attestedHeader,
nextSyncCommittee: ZERO_SYNC_COMMITTEE,
@@ -39,7 +45,7 @@ export class LightclientSpec {
});
}
onOptimisticUpdate(currentSlot: Slot, optimisticUpdate: allForks.LightClientOptimisticUpdate): void {
onOptimisticUpdate(currentSlot: Slot, optimisticUpdate: LightClientOptimisticUpdate): void {
this.onUpdate(currentSlot, {
attestedHeader: optimisticUpdate.attestedHeader,
nextSyncCommittee: ZERO_SYNC_COMMITTEE,

View File

@@ -1,5 +1,5 @@
import {SYNC_COMMITTEE_SIZE} from "@lodestar/params";
import {Slot, allForks} from "@lodestar/types";
import {LightClientUpdate, Slot} from "@lodestar/types";
import {computeSyncPeriodAtSlot} from "../utils/index.js";
import {isFinalityUpdate, isSyncCommitteeUpdate, sumBits} from "./utils.js";
@@ -82,7 +82,7 @@ export function isSafeLightClientUpdate(update: LightClientUpdateSummary): boole
);
}
export function toLightClientUpdateSummary(update: allForks.LightClientUpdate): LightClientUpdateSummary {
export function toLightClientUpdateSummary(update: LightClientUpdate): LightClientUpdateSummary {
return {
activeParticipants: sumBits(update.syncAggregate.syncCommitteeBits),
attestedHeaderSlot: update.attestedHeader.beacon.slot,

View File

@@ -1,5 +1,5 @@
import {SYNC_COMMITTEE_SIZE} from "@lodestar/params";
import {Slot, SyncPeriod, allForks} from "@lodestar/types";
import {LightClientUpdate, Slot, SyncPeriod} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {pruneSetToMax} from "@lodestar/utils";
import {computeSyncPeriodAtSlot, deserializeSyncCommittee, sumBits} from "../utils/index.js";
@@ -18,7 +18,7 @@ export function processLightClientUpdate(
store: ILightClientStore,
currentSlot: Slot,
opts: ProcessUpdateOpts,
update: allForks.LightClientUpdate
update: LightClientUpdate
): void {
if (update.signatureSlot > currentSlot) {
throw Error(`update slot ${update.signatureSlot} must not be in the future, current slot ${currentSlot}`);

View File

@@ -1,6 +1,6 @@
import type {PublicKey} from "@chainsafe/bls/types";
import {BeaconConfig} from "@lodestar/config";
import {SyncPeriod, allForks} from "@lodestar/types";
import {LightClientBootstrap, LightClientHeader, LightClientUpdate, SyncPeriod} from "@lodestar/types";
import {computeSyncPeriodAtSlot, deserializeSyncCommittee} from "../utils/index.js";
import {LightClientUpdateSummary} from "./isBetterUpdate.js";
@@ -18,29 +18,29 @@ export interface ILightClientStore {
setActiveParticipants(period: SyncPeriod, activeParticipants: number): void;
// Header that is finalized
finalizedHeader: allForks.LightClientHeader;
finalizedHeader: LightClientHeader;
// Most recent available reasonably-safe header
optimisticHeader: allForks.LightClientHeader;
optimisticHeader: LightClientHeader;
}
export interface LightClientStoreEvents {
onSetFinalizedHeader?: (header: allForks.LightClientHeader) => void;
onSetOptimisticHeader?: (header: allForks.LightClientHeader) => void;
onSetFinalizedHeader?: (header: LightClientHeader) => void;
onSetOptimisticHeader?: (header: LightClientHeader) => void;
}
export class LightClientStore implements ILightClientStore {
readonly syncCommittees = new Map<SyncPeriod, SyncCommitteeFast>();
readonly bestValidUpdates = new Map<SyncPeriod, LightClientUpdateWithSummary>();
private _finalizedHeader: allForks.LightClientHeader;
private _optimisticHeader: allForks.LightClientHeader;
private _finalizedHeader: LightClientHeader;
private _optimisticHeader: LightClientHeader;
private readonly maxActiveParticipants = new Map<SyncPeriod, number>();
constructor(
readonly config: BeaconConfig,
bootstrap: allForks.LightClientBootstrap,
bootstrap: LightClientBootstrap,
private readonly events: LightClientStoreEvents
) {
const bootstrapPeriod = computeSyncPeriodAtSlot(bootstrap.header.beacon.slot);
@@ -49,20 +49,20 @@ export class LightClientStore implements ILightClientStore {
this._optimisticHeader = bootstrap.header;
}
get finalizedHeader(): allForks.LightClientHeader {
get finalizedHeader(): LightClientHeader {
return this._finalizedHeader;
}
set finalizedHeader(value: allForks.LightClientHeader) {
set finalizedHeader(value: LightClientHeader) {
this._finalizedHeader = value;
this.events.onSetFinalizedHeader?.(value);
}
get optimisticHeader(): allForks.LightClientHeader {
get optimisticHeader(): LightClientHeader {
return this._optimisticHeader;
}
set optimisticHeader(value: allForks.LightClientHeader) {
set optimisticHeader(value: LightClientHeader) {
this._optimisticHeader = value;
this.events.onSetOptimisticHeader?.(value);
}
@@ -95,7 +95,7 @@ export type SyncCommitteeFast = {
};
export type LightClientUpdateWithSummary = {
update: allForks.LightClientUpdate;
update: LightClientUpdate;
summary: LightClientUpdateSummary;
};

View File

@@ -8,7 +8,16 @@ import {
BLOCK_BODY_EXECUTION_PAYLOAD_DEPTH as EXECUTION_PAYLOAD_DEPTH,
BLOCK_BODY_EXECUTION_PAYLOAD_INDEX as EXECUTION_PAYLOAD_INDEX,
} from "@lodestar/params";
import {altair, phase0, ssz, allForks, capella, deneb, Slot} from "@lodestar/types";
import {
ssz,
Slot,
LightClientFinalityUpdate,
LightClientHeader,
LightClientOptimisticUpdate,
LightClientUpdate,
BeaconBlockHeader,
SyncCommittee,
} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {isValidMerkleBranch, computeEpochAtSlot, computeSyncPeriodAtSlot} from "../utils/index.js";
@@ -32,7 +41,7 @@ export function getSafetyThreshold(maxActiveParticipants: number): number {
return Math.floor(maxActiveParticipants / SAFETY_THRESHOLD_FACTOR);
}
export function isSyncCommitteeUpdate(update: allForks.LightClientUpdate): boolean {
export function isSyncCommitteeUpdate(update: LightClientUpdate): boolean {
return (
// Fast return for when constructing full LightClientUpdate from partial updates
update.nextSyncCommitteeBranch !== ZERO_NEXT_SYNC_COMMITTEE_BRANCH &&
@@ -40,7 +49,7 @@ export function isSyncCommitteeUpdate(update: allForks.LightClientUpdate): boole
);
}
export function isFinalityUpdate(update: allForks.LightClientUpdate): boolean {
export function isFinalityUpdate(update: LightClientUpdate): boolean {
return (
// Fast return for when constructing full LightClientUpdate from partial updates
update.finalityBranch !== ZERO_FINALITY_BRANCH &&
@@ -48,12 +57,12 @@ export function isFinalityUpdate(update: allForks.LightClientUpdate): boolean {
);
}
export function isZeroedHeader(header: phase0.BeaconBlockHeader): boolean {
export function isZeroedHeader(header: BeaconBlockHeader): boolean {
// Fast return for when constructing full LightClientUpdate from partial updates
return header === ZERO_HEADER || byteArrayEquals(header.bodyRoot, ZERO_HASH);
}
export function isZeroedSyncCommittee(syncCommittee: altair.SyncCommittee): boolean {
export function isZeroedSyncCommittee(syncCommittee: SyncCommittee): boolean {
// Fast return for when constructing full LightClientUpdate from partial updates
return syncCommittee === ZERO_SYNC_COMMITTEE || byteArrayEquals(syncCommittee.pubkeys[0], ZERO_PUBKEY);
}
@@ -61,8 +70,8 @@ export function isZeroedSyncCommittee(syncCommittee: altair.SyncCommittee): bool
export function upgradeLightClientHeader(
config: ChainForkConfig,
targetFork: ForkName,
header: altair.LightClientHeader
): allForks.LightClientHeader {
header: LightClientHeader
): LightClientHeader {
const headerFork = config.getForkName(header.beacon.slot);
if (ForkSeq[headerFork] >= ForkSeq[targetFork]) {
throw Error(`Invalid upgrade request from headerFork=${headerFork} to targetFork=${targetFork}`);
@@ -70,7 +79,7 @@ export function upgradeLightClientHeader(
// We are modifying the same header object, may be we could create a copy, but its
// not required as of now
const upgradedHeader = header as allForks.LightClientHeader;
const upgradedHeader = header;
const startUpgradeFromFork = Object.values(ForkName)[ForkSeq[headerFork] + 1];
switch (startUpgradeFromFork) {
@@ -86,9 +95,9 @@ export function upgradeLightClientHeader(
// eslint-disable-next-line no-fallthrough
case ForkName.capella:
(upgradedHeader as capella.LightClientHeader).execution =
(upgradedHeader as LightClientHeader<ForkName.capella>).execution =
ssz.capella.LightClientHeader.fields.execution.defaultValue();
(upgradedHeader as capella.LightClientHeader).executionBranch =
(upgradedHeader as LightClientHeader<ForkName.capella>).executionBranch =
ssz.capella.LightClientHeader.fields.executionBranch.defaultValue();
// Break if no further upgradation is required else fall through
@@ -96,9 +105,9 @@ export function upgradeLightClientHeader(
// eslint-disable-next-line no-fallthrough
case ForkName.deneb:
(upgradedHeader as deneb.LightClientHeader).execution.blobGasUsed =
(upgradedHeader as LightClientHeader<ForkName.deneb>).execution.blobGasUsed =
ssz.deneb.LightClientHeader.fields.execution.fields.blobGasUsed.defaultValue();
(upgradedHeader as deneb.LightClientHeader).execution.excessBlobGas =
(upgradedHeader as LightClientHeader<ForkName.deneb>).execution.excessBlobGas =
ssz.deneb.LightClientHeader.fields.execution.fields.excessBlobGas.defaultValue();
// Break if no further upgradation is required else fall through
@@ -107,30 +116,30 @@ export function upgradeLightClientHeader(
return upgradedHeader;
}
export function isValidLightClientHeader(config: ChainForkConfig, header: allForks.LightClientHeader): boolean {
export function isValidLightClientHeader(config: ChainForkConfig, header: LightClientHeader): boolean {
const epoch = computeEpochAtSlot(header.beacon.slot);
if (epoch < config.CAPELLA_FORK_EPOCH) {
return (
((header as capella.LightClientHeader).execution === undefined ||
((header as LightClientHeader<ForkName.capella>).execution === undefined ||
ssz.capella.ExecutionPayloadHeader.equals(
(header as capella.LightClientHeader).execution,
(header as LightClientHeader<ForkName.capella>).execution,
ssz.capella.LightClientHeader.fields.execution.defaultValue()
)) &&
((header as capella.LightClientHeader).executionBranch === undefined ||
((header as LightClientHeader<ForkName.capella>).executionBranch === undefined ||
ssz.capella.LightClientHeader.fields.executionBranch.equals(
ssz.capella.LightClientHeader.fields.executionBranch.defaultValue(),
(header as capella.LightClientHeader).executionBranch
(header as LightClientHeader<ForkName.capella>).executionBranch
))
);
}
if (epoch < config.DENEB_FORK_EPOCH) {
if (
((header as deneb.LightClientHeader).execution.blobGasUsed &&
(header as deneb.LightClientHeader).execution.blobGasUsed !== BigInt(0)) ||
((header as deneb.LightClientHeader).execution.excessBlobGas &&
(header as deneb.LightClientHeader).execution.excessBlobGas !== BigInt(0))
((header as LightClientHeader<ForkName.deneb>).execution.blobGasUsed &&
(header as LightClientHeader<ForkName.deneb>).execution.blobGasUsed !== BigInt(0)) ||
((header as LightClientHeader<ForkName.deneb>).execution.excessBlobGas &&
(header as LightClientHeader<ForkName.deneb>).execution.excessBlobGas !== BigInt(0))
) {
return false;
}
@@ -139,8 +148,8 @@ export function isValidLightClientHeader(config: ChainForkConfig, header: allFor
return isValidMerkleBranch(
config
.getExecutionForkTypes(header.beacon.slot)
.ExecutionPayloadHeader.hashTreeRoot((header as capella.LightClientHeader).execution),
(header as capella.LightClientHeader).executionBranch,
.ExecutionPayloadHeader.hashTreeRoot((header as LightClientHeader<ForkName.capella>).execution),
(header as LightClientHeader<ForkName.capella>).executionBranch,
EXECUTION_PAYLOAD_DEPTH,
EXECUTION_PAYLOAD_INDEX,
header.beacon.bodyRoot
@@ -150,8 +159,8 @@ export function isValidLightClientHeader(config: ChainForkConfig, header: allFor
export function upgradeLightClientUpdate(
config: ChainForkConfig,
targetFork: ForkName,
update: allForks.LightClientUpdate
): allForks.LightClientUpdate {
update: LightClientUpdate
): LightClientUpdate {
update.attestedHeader = upgradeLightClientHeader(config, targetFork, update.attestedHeader);
update.finalizedHeader = upgradeLightClientHeader(config, targetFork, update.finalizedHeader);
@@ -161,8 +170,8 @@ export function upgradeLightClientUpdate(
export function upgradeLightClientFinalityUpdate(
config: ChainForkConfig,
targetFork: ForkName,
finalityUpdate: allForks.LightClientFinalityUpdate
): allForks.LightClientFinalityUpdate {
finalityUpdate: LightClientFinalityUpdate
): LightClientFinalityUpdate {
finalityUpdate.attestedHeader = upgradeLightClientHeader(config, targetFork, finalityUpdate.attestedHeader);
finalityUpdate.finalizedHeader = upgradeLightClientHeader(config, targetFork, finalityUpdate.finalizedHeader);
@@ -172,8 +181,8 @@ export function upgradeLightClientFinalityUpdate(
export function upgradeLightClientOptimisticUpdate(
config: ChainForkConfig,
targetFork: ForkName,
optimisticUpdate: allForks.LightClientOptimisticUpdate
): allForks.LightClientOptimisticUpdate {
optimisticUpdate: LightClientOptimisticUpdate
): LightClientOptimisticUpdate {
optimisticUpdate.attestedHeader = upgradeLightClientHeader(config, targetFork, optimisticUpdate.attestedHeader);
return optimisticUpdate;

View File

@@ -1,5 +1,5 @@
import {byteArrayEquals} from "@chainsafe/ssz";
import {Root, ssz, allForks} from "@lodestar/types";
import {LightClientBootstrap, Root, ssz} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {toHex} from "@lodestar/utils";
import {isValidMerkleBranch} from "../utils/verifyMerkleBranch.js";
@@ -11,7 +11,7 @@ const CURRENT_SYNC_COMMITTEE_DEPTH = 5;
export function validateLightClientBootstrap(
config: ChainForkConfig,
trustedBlockRoot: Root,
bootstrap: allForks.LightClientBootstrap
bootstrap: LightClientBootstrap
): void {
const headerRoot = ssz.phase0.BeaconBlockHeader.hashTreeRoot(bootstrap.header.beacon);

View File

@@ -1,6 +1,6 @@
import bls from "@chainsafe/bls";
import type {PublicKey, Signature} from "@chainsafe/bls/types";
import {Root, ssz, allForks} from "@lodestar/types";
import {LightClientUpdate, Root, ssz} from "@lodestar/types";
import {ChainForkConfig} from "@lodestar/config";
import {
FINALIZED_ROOT_INDEX,
@@ -27,7 +27,7 @@ import {ILightClientStore} from "./store.js";
export function validateLightClientUpdate(
config: ChainForkConfig,
store: ILightClientStore,
update: allForks.LightClientUpdate,
update: LightClientUpdate,
syncCommittee: SyncCommitteeFast
): void {
// Verify sync committee has sufficient participants

View File

@@ -1,4 +1,10 @@
import {allForks, SyncPeriod} from "@lodestar/types";
import {
LightClientBootstrap,
LightClientFinalityUpdate,
LightClientOptimisticUpdate,
LightClientUpdate,
SyncPeriod,
} from "@lodestar/types";
import {ForkName} from "@lodestar/params";
export interface LightClientTransport {
@@ -8,24 +14,24 @@ export interface LightClientTransport {
): Promise<
{
version: ForkName;
data: allForks.LightClientUpdate;
data: LightClientUpdate;
}[]
>;
/**
* Returns the latest optimistic head update available. Clients should use the SSE type `light_client_optimistic_update`
* unless to get the very first head update after syncing, or if SSE are not supported by the server.
*/
getOptimisticUpdate(): Promise<{version: ForkName; data: allForks.LightClientOptimisticUpdate}>;
getFinalityUpdate(): Promise<{version: ForkName; data: allForks.LightClientFinalityUpdate}>;
getOptimisticUpdate(): Promise<{version: ForkName; data: LightClientOptimisticUpdate}>;
getFinalityUpdate(): Promise<{version: ForkName; data: LightClientFinalityUpdate}>;
/**
* Fetch a bootstrapping state with a proof to a trusted block root.
* The trusted block root should be fetched with similar means to a weak subjectivity checkpoint.
* Only block roots for checkpoints are guaranteed to be available.
*/
getBootstrap(blockRoot: string): Promise<{version: ForkName; data: allForks.LightClientBootstrap}>;
getBootstrap(blockRoot: string): Promise<{version: ForkName; data: LightClientBootstrap}>;
// registers handler for LightClientOptimisticUpdate. This can come either via sse or p2p
onOptimisticUpdate(handler: (optimisticUpdate: allForks.LightClientOptimisticUpdate) => void): void;
onOptimisticUpdate(handler: (optimisticUpdate: LightClientOptimisticUpdate) => void): void;
// registers handler for LightClientFinalityUpdate. This can come either via sse or p2p
onFinalityUpdate(handler: (finalityUpdate: allForks.LightClientFinalityUpdate) => void): void;
onFinalityUpdate(handler: (finalityUpdate: LightClientFinalityUpdate) => void): void;
}

View File

@@ -1,13 +1,19 @@
import mitt from "mitt";
import {type allForks, type SyncPeriod} from "@lodestar/types";
import {
LightClientBootstrap,
LightClientFinalityUpdate,
LightClientOptimisticUpdate,
LightClientUpdate,
type SyncPeriod,
} from "@lodestar/types";
import {type ApiClient, routes} from "@lodestar/api";
import {type ForkName} from "@lodestar/params";
import {MittEmitter} from "../events.js";
import {type LightClientTransport} from "./interface.js";
export type LightClientRestEvents = {
[routes.events.EventType.lightClientFinalityUpdate]: (update: allForks.LightClientFinalityUpdate) => void;
[routes.events.EventType.lightClientOptimisticUpdate]: (update: allForks.LightClientOptimisticUpdate) => void;
[routes.events.EventType.lightClientFinalityUpdate]: (update: LightClientFinalityUpdate) => void;
[routes.events.EventType.lightClientOptimisticUpdate]: (update: LightClientOptimisticUpdate) => void;
};
export type LightClientRestEmitter = MittEmitter<LightClientRestEvents>;
@@ -25,7 +31,7 @@ export class LightClientRestTransport implements LightClientTransport {
): Promise<
{
version: ForkName;
data: allForks.LightClientUpdate;
data: LightClientUpdate;
}[]
> {
const res = await this.api.lightclient.getLightClientUpdatesByRange({startPeriod, count});
@@ -34,27 +40,27 @@ export class LightClientRestTransport implements LightClientTransport {
return updates.map((data, i) => ({data, version: versions[i]}));
}
async getOptimisticUpdate(): Promise<{version: ForkName; data: allForks.LightClientOptimisticUpdate}> {
async getOptimisticUpdate(): Promise<{version: ForkName; data: LightClientOptimisticUpdate}> {
const res = await this.api.lightclient.getLightClientOptimisticUpdate();
return {version: res.meta().version, data: res.value()};
}
async getFinalityUpdate(): Promise<{version: ForkName; data: allForks.LightClientFinalityUpdate}> {
async getFinalityUpdate(): Promise<{version: ForkName; data: LightClientFinalityUpdate}> {
const res = await this.api.lightclient.getLightClientFinalityUpdate();
return {version: res.meta().version, data: res.value()};
}
async getBootstrap(blockRoot: string): Promise<{version: ForkName; data: allForks.LightClientBootstrap}> {
async getBootstrap(blockRoot: string): Promise<{version: ForkName; data: LightClientBootstrap}> {
const res = await this.api.lightclient.getLightClientBootstrap({blockRoot});
return {version: res.meta().version, data: res.value()};
}
onOptimisticUpdate(handler: (optimisticUpdate: allForks.LightClientOptimisticUpdate) => void): void {
onOptimisticUpdate(handler: (optimisticUpdate: LightClientOptimisticUpdate) => void): void {
this.subscribeEventstream();
this.eventEmitter.on(routes.events.EventType.lightClientOptimisticUpdate, handler);
}
onFinalityUpdate(handler: (finalityUpdate: allForks.LightClientFinalityUpdate) => void): void {
onFinalityUpdate(handler: (finalityUpdate: LightClientFinalityUpdate) => void): void {
this.subscribeEventstream();
this.eventEmitter.on(routes.events.EventType.lightClientFinalityUpdate, handler);
}

View File

@@ -1,14 +1,14 @@
import type {PublicKey} from "@chainsafe/bls/types";
import {SyncPeriod, allForks} from "@lodestar/types";
import {LightClientHeader, LightClientUpdate, SyncPeriod} from "@lodestar/types";
export type LightClientStoreFast = {
snapshot: LightClientSnapshotFast;
bestUpdates: Map<SyncPeriod, allForks.LightClientUpdate>;
bestUpdates: Map<SyncPeriod, LightClientUpdate>;
};
export type LightClientSnapshotFast = {
/** Beacon block header */
header: allForks.LightClientHeader;
header: LightClientHeader;
/** Sync committees corresponding to the header */
currentSyncCommittee: SyncCommitteeFast;
nextSyncCommittee: SyncCommitteeFast;

View File

@@ -1,6 +1,6 @@
import bls from "@chainsafe/bls";
import type {PublicKey, Signature} from "@chainsafe/bls/types";
import {altair, Root, Slot, ssz, allForks} from "@lodestar/types";
import {altair, LightClientFinalityUpdate, LightClientUpdate, Root, Slot, ssz} from "@lodestar/types";
import {
FINALIZED_ROOT_INDEX,
FINALIZED_ROOT_DEPTH,
@@ -24,7 +24,7 @@ import {computeSyncPeriodAtSlot} from "./utils/clock.js";
export function assertValidLightClientUpdate(
config: BeaconConfig,
syncCommittee: SyncCommitteeFast,
update: allForks.LightClientUpdate
update: LightClientUpdate
): void {
// DIFF FROM SPEC: An update with the same header.slot can be valid and valuable to the lightclient
// It may have more consensus and result in a better snapshot whilst not advancing the state
@@ -64,7 +64,7 @@ export function assertValidLightClientUpdate(
*
* Where `hashTreeRoot(state) == update.finalityHeader.stateRoot`
*/
export function assertValidFinalityProof(update: allForks.LightClientFinalityUpdate): void {
export function assertValidFinalityProof(update: LightClientFinalityUpdate): void {
if (
!isValidMerkleBranch(
ssz.phase0.BeaconBlockHeader.hashTreeRoot(update.finalizedHeader.beacon),
@@ -94,7 +94,7 @@ export function assertValidFinalityProof(update: allForks.LightClientFinalityUpd
*
* Where `hashTreeRoot(state) == update.header.stateRoot`
*/
export function assertValidSyncCommitteeProof(update: allForks.LightClientUpdate): void {
export function assertValidSyncCommitteeProof(update: LightClientUpdate): void {
if (
!isValidMerkleBranch(
ssz.altair.SyncCommittee.hashTreeRoot(update.nextSyncCommittee),

View File

@@ -1,6 +1,6 @@
import {describe, it, expect} from "vitest";
import {fromHexString} from "@chainsafe/ssz";
import {ssz, allForks} from "@lodestar/types";
import {LightClientHeader, ssz} from "@lodestar/types";
import {createBeaconConfig, createChainForkConfig, defaultChainConfig} from "@lodestar/config";
import {isValidLightClientHeader} from "../../src/spec/utils.js";
@@ -80,7 +80,7 @@ describe("isValidLightClientHeader", function () {
executionBranch: capellaLCHeader.executionBranch,
};
const testCases: [string, allForks.LightClientHeader][] = [
const testCases: [string, LightClientHeader][] = [
["altair LC header", altairLCHeader],
["altair upgraded to capella", altairUpgradedCapellaLCHeader],
["altair upgraded to deneb", altairUpgradedDenebLCHeader],
@@ -88,7 +88,7 @@ describe("isValidLightClientHeader", function () {
["capella upgraded to deneb LC header", capellaUpgradedDenebHeader],
];
testCases.forEach(([name, header]: [string, allForks.LightClientHeader]) => {
testCases.forEach(([name, header]: [string, LightClientHeader]) => {
it(name, function () {
const isValid = isValidLightClientHeader(config, header);
expect(isValid).toBe(true);

View File

@@ -11,7 +11,7 @@ import {
SLOTS_PER_EPOCH,
SYNC_COMMITTEE_SIZE,
} from "@lodestar/params";
import {altair, phase0, Slot, ssz, SyncPeriod, allForks} from "@lodestar/types";
import {altair, LightClientBootstrap, phase0, Slot, ssz, SyncPeriod} from "@lodestar/types";
import {SyncCommitteeFast} from "../../src/types.js";
import {computeSigningRoot} from "../../src/utils/domain.js";
import {getConsoleLogger} from "../../src/utils/logger.js";
@@ -156,7 +156,7 @@ export function computeLightclientUpdate(config: BeaconConfig, period: SyncPerio
* Creates a LightClientBootstrap that passes validation
*/
export function computeLightClientSnapshot(period: SyncPeriod): {
snapshot: allForks.LightClientBootstrap;
snapshot: LightClientBootstrap;
checkpointRoot: Uint8Array;
} {
const currentSyncCommittee = getInteropSyncCommittee(period).syncCommittee;

Some files were not shown because too many files have changed in this diff Show More