mirror of
https://github.com/ChainSafe/lodestar.git
synced 2026-01-10 08:08:16 -05:00
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:
@@ -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),
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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) => ({
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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}};
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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
|
||||
);
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>({
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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[]>;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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>;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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}`];
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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};
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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),
|
||||
},
|
||||
|
||||
@@ -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];
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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}`);
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user