Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
333c570
feat: placeholder PR for electra
g11tech Jan 24, 2024
4062f8c
feat: implement EIP-6110 (#6042)
ensi321 Feb 19, 2024
53aeec0
chore: fix CI failure due to recent merge from `unstable` (#6646)
ensi321 Apr 12, 2024
2bca717
feat: implement execution layer exits eip 7002 (#6651)
g11tech Apr 22, 2024
61368f2
chore: update spec test version for electra fork (#6717)
ensi321 May 1, 2024
ffaa950
feat: add presets and ssz types for EIP-7549 (#6715)
ensi321 May 4, 2024
f0e182b
chore: fix the rebase build (#6735)
g11tech May 4, 2024
a08aecb
feat: upgrade 7002 exits to withdrawal request (#6736)
g11tech May 5, 2024
baf40e2
feat: implement maxEB EIP-7251 (#6539)
ensi321 May 7, 2024
4b6952c
feat: beacon node process electra attestations EIP-7549 (#6738)
ensi321 May 7, 2024
ad27b49
feat: handle the EL payload sending data in deposit requests instead …
g11tech May 8, 2024
d586bf2
feat: implement EIP-7549 (#6689)
ensi321 May 8, 2024
1d74606
fix: attestation pool for electra (#6744)
twoeths May 8, 2024
ca75077
feat: update engineapi endpoints to v4 (#6747)
g11tech May 8, 2024
14f33cc
feat: rename deposit receipt to deposit request for Pectra (#6748)
ensi321 May 8, 2024
71d7060
test: enable spec tests related to eip-7549 (#6741)
nazarhussain May 8, 2024
916d0c9
fix: fix e2e test in electra-fork (#6751)
ensi321 May 8, 2024
c56346b
feat: get the basic integration working with the ethereumjs electra b…
g11tech May 8, 2024
8460d55
feat: apply some fixes and hacks to get the single node devnet workin…
g11tech May 9, 2024
1f40812
fix: get aggregate and proofs signature sets (#6757)
twoeths May 10, 2024
05583ec
test(spec): fix attestors slashing specs for electra fork (#6758)
nazarhussain May 10, 2024
504aeb1
chore: fix types and lint (#6750)
g11tech May 13, 2024
4f4f282
fix: fix electra genesis spec test (#6764)
ensi321 May 14, 2024
341d838
feat: support missing electra spec test (#6765)
ensi321 May 14, 2024
3b3dd91
test: fix ssz types in fork_choice spec tests (#6767)
nflaig May 14, 2024
170d2d5
chore: update EffectiveBalanceIncrements type (#6763)
jeluard May 14, 2024
8614094
Fix ssz_static
ensi321 May 14, 2024
2a0cdd0
fix: inline sourcemaps to help with debugging (#6768)
matthewkeil May 14, 2024
6e10ad5
fix: additional epoch calculation logic for consolidation churn (#6770)
nazarhussain May 14, 2024
5c00644
fix: electra fork transition spec tests (#6769)
twoeths May 14, 2024
1ade586
test: fix ssz_static spec tests for all forks (#6771)
nflaig May 14, 2024
e24fa70
chore(spec): remove the skip specs for electra (#6772)
nazarhussain May 14, 2024
e6bb272
fix: use mutable validator object (#6774)
ensi321 May 14, 2024
69a6b84
test: fix balance spec tests (#6777)
matthewkeil May 14, 2024
d0910f8
fix: effective balance cache is not in sync with validator effective …
ensi321 May 14, 2024
7f9d7ed
fix: make electra-fork passes lint and check-types (#6785)
ensi321 May 16, 2024
f794536
fix: update data format of WithdrawalRequestV1 (#6789)
nflaig May 16, 2024
e75aeeb
fix: publish attestations with non-zero committee index (#6790)
ensi321 May 16, 2024
4dfff7b
fix: validator monitor summaries should not render during epoch 0 (#6…
ensi321 May 16, 2024
ed01c34
fix: attestation duty validation (#6792)
ensi321 May 16, 2024
f49b58d
fix: align BeaconBlockBody and BlindedBeaconBlockBody (#6782)
wemeetagain May 16, 2024
5147fb7
test: improve ssz tests consistency (#6776)
jeluard May 16, 2024
e8b096d
fix: batch validation for electra attestations (#6788)
twoeths May 16, 2024
b53660e
fix: update withdrawal request container to match consensus spec (#6797)
nflaig May 16, 2024
4e7661e
fix: get seen AttData key from SignedAggregateAndProof electra (#6802)
twoeths May 17, 2024
c321062
test: only skip ssz_static tests associated to missing type (#6798)
nflaig May 23, 2024
d971d31
chore: types and lint fixes (#6819)
g11tech May 25, 2024
571257e
feat: add engine_getPayloadBodiesByHash and ByRange V2 (#6852)
ensi321 Jun 8, 2024
414f72d
fix: align WithdrawalRequestV1 field names with latest spec (#6877)
nflaig Jun 12, 2024
3cb1cf4
feat: move attestation committee at the end of attestation (#6883)
ensi321 Jun 14, 2024
2a98d3f
rebase fixes
g11tech Jun 19, 2024
76559dd
feat: handle exited/exiting validators during top up (#6880)
ensi321 Jun 21, 2024
b7c2258
feat: add EL triggered consolidation and remove `ExecutionLayer` pref…
ensi321 Jun 21, 2024
ee64bda
feat: support electra devnet-1 (#6892)
ensi321 Jun 25, 2024
5051f66
fix: electra rebase fixes on the new generic typing model
g11tech Jun 25, 2024
7fc5243
feat: add and parse consolidation requests from engine api
g11tech Jul 1, 2024
8302360
feat: make produce block/signed block contents api multifork
g11tech Jul 1, 2024
5b9697e
fix: electra rebase fixes on the allforks type refactor
g11tech Jul 1, 2024
9dd5c07
tests fixes
g11tech Jul 10, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
},
"dependencies": {
"@chainsafe/persistent-merkle-tree": "^0.7.1",
"@chainsafe/ssz": "^0.15.1",
"@chainsafe/ssz": "^0.16.0",
"@lodestar/config": "^1.19.0",
"@lodestar/params": "^1.19.0",
"@lodestar/types": "^1.19.0",
Expand Down
84 changes: 36 additions & 48 deletions packages/api/src/beacon/routes/beacon/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,10 @@ import {
BeaconBlockBody,
SignedBeaconBlockOrContents,
SignedBlindedBeaconBlock,
SignedBlockContents,
sszTypesFor,
} from "@lodestar/types";
import {ForkName, ForkPreExecution, ForkSeq, isForkExecution} from "@lodestar/params";
import {ForkName, ForkPreExecution, isForkBlobs, isForkExecution} from "@lodestar/params";
import {Endpoint, RequestCodec, RouteDefinitions, Schema} from "../../../utils/index.js";
import {EmptyMeta, EmptyResponseCodec, EmptyResponseData, WithVersion} from "../../../utils/codecs.js";
import {
Expand All @@ -37,19 +39,10 @@ export const BlockHeadersResponseType = new ListCompositeType(BlockHeaderRespons
export const RootResponseType = new ContainerType({
root: ssz.Root,
});
export const SignedBlockContentsType = new ContainerType(
{
signedBlock: ssz.deneb.SignedBeaconBlock,
kzgProofs: ssz.deneb.KZGProofs,
blobs: ssz.deneb.Blobs,
},
{jsonCase: "eth2"}
);

export type BlockHeaderResponse = ValueOf<typeof BlockHeaderResponseType>;
export type BlockHeadersResponse = ValueOf<typeof BlockHeadersResponseType>;
export type RootResponse = ValueOf<typeof RootResponseType>;
export type SignedBlockContents = ValueOf<typeof SignedBlockContentsType>;

export type BlockId = RootHex | Slot | "head" | "genesis" | "finalized" | "justified";

Expand Down Expand Up @@ -297,11 +290,12 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
const slot = isSignedBlockContents(signedBlockOrContents)
? signedBlockOrContents.signedBlock.message.slot
: signedBlockOrContents.message.slot;
const fork = config.getForkName(slot);

return {
body:
config.getForkSeq(slot) < ForkSeq.deneb
? config.getForkTypes(slot).SignedBeaconBlock.toJson(signedBlockOrContents as SignedBeaconBlock)
: SignedBlockContentsType.toJson(signedBlockOrContents as SignedBlockContents),
body: isForkBlobs(fork)
? sszTypesFor(fork).SignedBlockContents.toJson(signedBlockOrContents as SignedBlockContents)
: sszTypesFor(fork).SignedBeaconBlock.toJson(signedBlockOrContents as SignedBeaconBlock),
headers: {
[MetaHeader.Version]: config.getForkName(slot),
},
Expand All @@ -321,36 +315,33 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
: (body as SignedBeaconBlock).message.slot
);
}
const forkSeq = config.forks[forkName].seq;
return {
signedBlockOrContents:
forkSeq < ForkSeq.deneb
? ssz[forkName].SignedBeaconBlock.fromJson(body)
: SignedBlockContentsType.fromJson(body),
signedBlockOrContents: isForkBlobs(forkName)
? sszTypesFor(forkName).SignedBlockContents.fromJson(body)
: ssz[forkName].SignedBeaconBlock.fromJson(body),
};
},
writeReqSsz: ({signedBlockOrContents}) => {
const slot = isSignedBlockContents(signedBlockOrContents)
? signedBlockOrContents.signedBlock.message.slot
: signedBlockOrContents.message.slot;
const fork = config.getForkName(slot);

return {
body:
config.getForkSeq(slot) < ForkSeq.deneb
? config.getForkTypes(slot).SignedBeaconBlock.serialize(signedBlockOrContents as SignedBeaconBlock)
: SignedBlockContentsType.serialize(signedBlockOrContents as SignedBlockContents),
body: isForkBlobs(fork)
? sszTypesFor(fork).SignedBlockContents.serialize(signedBlockOrContents as SignedBlockContents)
: sszTypesFor(fork).SignedBeaconBlock.serialize(signedBlockOrContents as SignedBeaconBlock),
headers: {
[MetaHeader.Version]: config.getForkName(slot),
},
};
},
parseReqSsz: ({body, headers}) => {
const forkName = toForkName(fromHeaders(headers, MetaHeader.Version));
const forkSeq = config.forks[forkName].seq;
return {
signedBlockOrContents:
forkSeq < ForkSeq.deneb
? ssz[forkName].SignedBeaconBlock.deserialize(body)
: SignedBlockContentsType.deserialize(body),
signedBlockOrContents: isForkBlobs(forkName)
? sszTypesFor(forkName).SignedBlockContents.deserialize(body)
: ssz[forkName].SignedBeaconBlock.deserialize(body),
};
},
schema: {
Expand All @@ -371,51 +362,48 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
const slot = isSignedBlockContents(signedBlockOrContents)
? signedBlockOrContents.signedBlock.message.slot
: signedBlockOrContents.message.slot;
const fork = config.getForkName(slot);
return {
body:
config.getForkSeq(slot) < ForkSeq.deneb
? config.getForkTypes(slot).SignedBeaconBlock.toJson(signedBlockOrContents as SignedBeaconBlock)
: SignedBlockContentsType.toJson(signedBlockOrContents as SignedBlockContents),
body: isForkBlobs(fork)
? sszTypesFor(fork).SignedBlockContents.toJson(signedBlockOrContents as SignedBlockContents)
: sszTypesFor(fork).SignedBeaconBlock.toJson(signedBlockOrContents as SignedBeaconBlock),
headers: {
[MetaHeader.Version]: config.getForkName(slot),
[MetaHeader.Version]: fork,
},
query: {broadcast_validation: broadcastValidation},
};
},
parseReqJson: ({body, headers, query}) => {
const forkName = toForkName(fromHeaders(headers, MetaHeader.Version));
const forkSeq = config.forks[forkName].seq;
return {
signedBlockOrContents:
forkSeq < ForkSeq.deneb
? ssz[forkName].SignedBeaconBlock.fromJson(body)
: SignedBlockContentsType.fromJson(body),
signedBlockOrContents: isForkBlobs(forkName)
? sszTypesFor(forkName).SignedBlockContents.fromJson(body)
: ssz[forkName].SignedBeaconBlock.fromJson(body),
broadcastValidation: query.broadcast_validation as BroadcastValidation,
};
},
writeReqSsz: ({signedBlockOrContents, broadcastValidation}) => {
const slot = isSignedBlockContents(signedBlockOrContents)
? signedBlockOrContents.signedBlock.message.slot
: signedBlockOrContents.message.slot;
const fork = config.getForkName(slot);

return {
body:
config.getForkSeq(slot) < ForkSeq.deneb
? config.getForkTypes(slot).SignedBeaconBlock.serialize(signedBlockOrContents as SignedBeaconBlock)
: SignedBlockContentsType.serialize(signedBlockOrContents as SignedBlockContents),
body: isForkBlobs(fork)
? sszTypesFor(fork).SignedBlockContents.serialize(signedBlockOrContents as SignedBlockContents)
: sszTypesFor(fork).SignedBeaconBlock.serialize(signedBlockOrContents as SignedBeaconBlock),
headers: {
[MetaHeader.Version]: config.getForkName(slot),
[MetaHeader.Version]: fork,
},
query: {broadcast_validation: broadcastValidation},
};
},
parseReqSsz: ({body, headers, query}) => {
const forkName = toForkName(fromHeaders(headers, MetaHeader.Version));
const forkSeq = config.forks[forkName].seq;
return {
signedBlockOrContents:
forkSeq < ForkSeq.deneb
? ssz[forkName].SignedBeaconBlock.deserialize(body)
: SignedBlockContentsType.deserialize(body),
signedBlockOrContents: isForkBlobs(forkName)
? sszTypesFor(forkName).SignedBlockContents.deserialize(body)
: ssz[forkName].SignedBeaconBlock.deserialize(body),
broadcastValidation: query.broadcast_validation as BroadcastValidation,
};
},
Expand Down
73 changes: 62 additions & 11 deletions packages/api/src/beacon/routes/beacon/pool.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/naming-convention */
import {ValueOf} from "@chainsafe/ssz";
import {ChainForkConfig} from "@lodestar/config";
import {ForkSeq} from "@lodestar/params";
import {phase0, capella, CommitteeIndex, Slot, ssz} from "@lodestar/types";
import {Schema, Endpoint, RouteDefinitions} from "../../../utils/index.js";
import {
Expand All @@ -12,18 +13,25 @@ import {
EmptyRequest,
EmptyResponseCodec,
EmptyResponseData,
WithVersion,
} from "../../../utils/codecs.js";
import {MetaHeader, VersionCodec, VersionMeta} from "../../../utils/metadata.js";
import {toForkName} from "../../../utils/fork.js";
import {fromHeaders} from "../../../utils/headers.js";

// See /packages/api/src/routes/index.ts for reasoning and instructions to add new routes

const AttestationListType = ArrayOf(ssz.phase0.Attestation);
const AttestationListTypePhase0 = ArrayOf(ssz.phase0.Attestation);
const AttestationListTypeElectra = ArrayOf(ssz.electra.Attestation);
const AttesterSlashingListType = ArrayOf(ssz.phase0.AttesterSlashing);
const ProposerSlashingListType = ArrayOf(ssz.phase0.ProposerSlashing);
const SignedVoluntaryExitListType = ArrayOf(ssz.phase0.SignedVoluntaryExit);
const SignedBLSToExecutionChangeListType = ArrayOf(ssz.capella.SignedBLSToExecutionChange);
const SyncCommitteeMessageListType = ArrayOf(ssz.altair.SyncCommitteeMessage);

type AttestationList = ValueOf<typeof AttestationListType>;
type AttestationListPhase0 = ValueOf<typeof AttestationListTypePhase0>;
type AttestationListElectra = ValueOf<typeof AttestationListTypeElectra>;
type AttestationList = AttestationListPhase0 | AttestationListElectra;
type AttesterSlashingList = ValueOf<typeof AttesterSlashingListType>;
type ProposerSlashingList = ValueOf<typeof ProposerSlashingListType>;
type SignedVoluntaryExitList = ValueOf<typeof SignedVoluntaryExitListType>;
Expand All @@ -40,7 +48,7 @@ export type Endpoints = {
{slot?: Slot; committeeIndex?: CommitteeIndex},
{query: {slot?: number; committee_index?: number}},
AttestationList,
EmptyMeta
VersionMeta
>;

/**
Expand Down Expand Up @@ -106,7 +114,7 @@ export type Endpoints = {
submitPoolAttestations: Endpoint<
"POST",
{signedAttestations: AttestationList},
{body: unknown},
{body: unknown; headers: {[MetaHeader.Version]: string}},
EmptyResponseData,
EmptyMeta
>;
Expand Down Expand Up @@ -172,7 +180,7 @@ export type Endpoints = {
>;
};

export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpoints> {
export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoints> {
return {
getPoolAttestations: {
url: "/eth/v1/beacon/pool/attestations",
Expand All @@ -183,8 +191,10 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
schema: {query: {slot: Schema.Uint, committee_index: Schema.Uint}},
},
resp: {
data: AttestationListType,
meta: EmptyMetaCodec,
data: WithVersion((fork) =>
ForkSeq[fork] >= ForkSeq.electra ? AttestationListTypeElectra : AttestationListTypePhase0
),
meta: VersionCodec,
},
},
getPoolAttesterSlashings: {
Expand Down Expand Up @@ -227,12 +237,53 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
url: "/eth/v1/beacon/pool/attestations",
method: "POST",
req: {
writeReqJson: ({signedAttestations}) => ({body: AttestationListType.toJson(signedAttestations)}),
parseReqJson: ({body}) => ({signedAttestations: AttestationListType.fromJson(body)}),
writeReqSsz: ({signedAttestations}) => ({body: AttestationListType.serialize(signedAttestations)}),
parseReqSsz: ({body}) => ({signedAttestations: AttestationListType.deserialize(body)}),
writeReqJson: ({signedAttestations}) => {
const fork = config.getForkName(signedAttestations[0].data.slot);
return {
body:
ForkSeq[fork] >= ForkSeq.electra
? AttestationListTypeElectra.toJson(signedAttestations as AttestationListElectra)
: AttestationListTypePhase0.toJson(signedAttestations as AttestationListPhase0),
headers: {[MetaHeader.Version]: fork},
};
},
parseReqJson: ({body, headers}) => {
const versionHeader = fromHeaders(headers, MetaHeader.Version, false);
const fork =
versionHeader !== undefined
? toForkName(versionHeader)
: config.getForkName(Number((body as {data: {slot: string}}[])[0]?.data.slot ?? 0));

return {
signedAttestations:
ForkSeq[fork] >= ForkSeq.electra
? AttestationListTypeElectra.fromJson(body)
: AttestationListTypePhase0.fromJson(body),
};
},
writeReqSsz: ({signedAttestations}) => {
const fork = config.getForkName(signedAttestations[0].data.slot);
return {
body:
ForkSeq[fork] >= ForkSeq.electra
? AttestationListTypeElectra.serialize(signedAttestations as AttestationListElectra)
: AttestationListTypePhase0.serialize(signedAttestations as AttestationListPhase0),
headers: {[MetaHeader.Version]: fork},
};
},
parseReqSsz: ({body, headers}) => {
const versionHeader = fromHeaders(headers, MetaHeader.Version, true);
const fork = toForkName(versionHeader);
return {
signedAttestations:
ForkSeq[fork] >= ForkSeq.electra
? AttestationListTypeElectra.deserialize(body)
: AttestationListTypePhase0.deserialize(body),
};
},
schema: {
body: Schema.ObjectArray,
headers: {[MetaHeader.Version]: Schema.String},
},
},
resp: EmptyResponseCodec,
Expand Down
11 changes: 7 additions & 4 deletions packages/api/src/beacon/routes/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ import {
LightClientOptimisticUpdate,
LightClientFinalityUpdate,
SSEPayloadAttributes,
Attestation,
AttesterSlashing,
sszTypesFor,
} from "@lodestar/types";
import {ForkName} from "@lodestar/params";

Expand Down Expand Up @@ -104,10 +107,10 @@ export type EventData = {
block: RootHex;
executionOptimistic: boolean;
};
[EventType.attestation]: phase0.Attestation;
[EventType.attestation]: {version: ForkName; data: Attestation};
[EventType.voluntaryExit]: phase0.SignedVoluntaryExit;
[EventType.proposerSlashing]: phase0.ProposerSlashing;
[EventType.attesterSlashing]: phase0.AttesterSlashing;
[EventType.attesterSlashing]: {version: ForkName; data: AttesterSlashing};
[EventType.blsToExecutionChange]: capella.SignedBLSToExecutionChange;
[EventType.finalizedCheckpoint]: {
block: RootHex;
Expand Down Expand Up @@ -225,10 +228,10 @@ export function getTypeByEvent(): {[K in EventType]: TypeJson<EventData[K]>} {
{jsonCase: "eth2"}
),

[EventType.attestation]: ssz.phase0.Attestation,
[EventType.attestation]: WithVersion((fork) => sszTypesFor(fork).Attestation),
[EventType.voluntaryExit]: ssz.phase0.SignedVoluntaryExit,
[EventType.proposerSlashing]: ssz.phase0.ProposerSlashing,
[EventType.attesterSlashing]: ssz.phase0.AttesterSlashing,
[EventType.attesterSlashing]: WithVersion((fork) => sszTypesFor(fork).AttesterSlashing),
[EventType.blsToExecutionChange]: ssz.capella.SignedBLSToExecutionChange,

[EventType.finalizedCheckpoint]: new ContainerType(
Expand Down
Loading