Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: implement EIP-7549 #6689

Merged
merged 13 commits into from
May 8, 2024
4 changes: 2 additions & 2 deletions packages/api/src/beacon/routes/beacon/pool.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {phase0, altair, capella, CommitteeIndex, Slot, ssz} from "@lodestar/types";
import {phase0, altair, capella, CommitteeIndex, Slot, ssz, allForks} from "@lodestar/types";
import {ApiClientResponse} from "../../../interfaces.js";
import {HttpStatusCode} from "../../../utils/client/httpStatusCode.js";
import {
Expand Down Expand Up @@ -80,7 +80,7 @@ export type Api = {
* @throws ApiError
*/
submitPoolAttestations(
attestations: phase0.Attestation[]
attestations: allForks.Attestation[]
): Promise<ApiClientResponse<{[HttpStatusCode.OK]: void}, HttpStatusCode.BAD_REQUEST>>;

/**
Expand Down
8 changes: 4 additions & 4 deletions packages/api/src/beacon/routes/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,10 @@ export type EventData = {
block: RootHex;
executionOptimistic: boolean;
};
[EventType.attestation]: phase0.Attestation;
[EventType.attestation]: {version: ForkName; data: allForks.Attestation};
[EventType.voluntaryExit]: phase0.SignedVoluntaryExit;
[EventType.proposerSlashing]: phase0.ProposerSlashing;
[EventType.attesterSlashing]: phase0.AttesterSlashing;
[EventType.attesterSlashing]: {version: ForkName; data: allForks.AttesterSlashing};
[EventType.blsToExecutionChange]: capella.SignedBLSToExecutionChange;
[EventType.finalizedCheckpoint]: {
block: RootHex;
Expand Down Expand Up @@ -180,10 +180,10 @@ export function getTypeByEvent(): {[K in EventType]: TypeJson<EventData[K]>} {
{jsonCase: "eth2"}
),

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

[EventType.finalizedCheckpoint]: new ContainerType(
Expand Down
6 changes: 3 additions & 3 deletions packages/api/src/beacon/routes/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ export type Api = {
slot: Slot
): Promise<
ApiClientResponse<
{[HttpStatusCode.OK]: {data: phase0.Attestation}},
{[HttpStatusCode.OK]: {data: allForks.Attestation; version: ForkName}},
HttpStatusCode.BAD_REQUEST | HttpStatusCode.NOT_FOUND
>
>;
Expand All @@ -354,7 +354,7 @@ export type Api = {
* @throws ApiError
*/
publishAggregateAndProofs(
signedAggregateAndProofs: phase0.SignedAggregateAndProof[]
signedAggregateAndProofs: allForks.SignedAggregateAndProof[] // TODO Electra: Add version
): Promise<ApiClientResponse<{[HttpStatusCode.OK]: void}, HttpStatusCode.BAD_REQUEST>>;

publishContributionAndProofs(
Expand Down Expand Up @@ -786,7 +786,7 @@ export function getReturnTypes(): ReturnTypes<Api> {

produceAttestationData: ContainerData(ssz.phase0.AttestationData),
produceSyncCommitteeContribution: ContainerData(ssz.altair.SyncCommitteeContribution),
getAggregatedAttestation: ContainerData(ssz.phase0.Attestation),
getAggregatedAttestation: WithVersion((fork) => ssz.allForks[fork].Attestation),
submitBeaconCommitteeSelections: ContainerData(ArrayOf(BeaconCommitteeSelection)),
submitSyncCommitteeSelections: ContainerData(ArrayOf(SyncCommitteeSelection)),
getLiveness: jsonType("snake"),
Expand Down
4 changes: 2 additions & 2 deletions packages/beacon-node/src/api/impl/beacon/pool/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {routes, ServerApi} from "@lodestar/api";
import {Epoch, ssz} from "@lodestar/types";
import {SYNC_COMMITTEE_SUBNET_SIZE} from "@lodestar/params";
import {ForkName, SYNC_COMMITTEE_SUBNET_SIZE} from "@lodestar/params";
import {validateApiAttestation} from "../../../../chain/validation/index.js";
import {validateApiAttesterSlashing} from "../../../../chain/validation/attesterSlashing.js";
import {validateApiProposerSlashing} from "../../../../chain/validation/proposerSlashing.js";
Expand Down Expand Up @@ -77,7 +77,7 @@ export function getBeaconPoolApi({
metrics?.opPool.attestationPoolInsertOutcome.inc({insertOutcome});
}

chain.emitter.emit(routes.events.EventType.attestation, attestation);
chain.emitter.emit(routes.events.EventType.attestation, {data: attestation, version: ForkName.phase0});

const sentPeers = await network.publishBeaconAttestation(attestation, subnet);
metrics?.onPoolSubmitUnaggregatedAttestation(seenTimestampSec, indexedAttestation, subnet, sentPeers);
Expand Down
4 changes: 3 additions & 1 deletion packages/beacon-node/src/api/impl/validator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,7 @@ export function getValidatorApi({
const attEpoch = computeEpochAtSlot(slot);
const headBlockRootHex = chain.forkChoice.getHead().blockRoot;
const headBlockRoot = fromHexString(headBlockRootHex);
const fork = config.getForkSeq(slot);

const beaconBlockRoot =
slot >= headSlot
Expand Down Expand Up @@ -846,7 +847,7 @@ export function getValidatorApi({
return {
data: {
slot,
index: committeeIndex,
index: fork >= ForkSeq.electra ? 0 : committeeIndex,
beaconBlockRoot,
source: attEpochState.currentJustifiedCheckpoint,
target: {epoch: attEpoch, root: targetRoot},
Expand Down Expand Up @@ -1078,6 +1079,7 @@ export function getValidatorApi({

return {
data: aggregate,
version: config.getForkName(slot),
};
},

Expand Down
10 changes: 8 additions & 2 deletions packages/beacon-node/src/chain/blocks/importBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -426,12 +426,18 @@ export async function importBlock(
}
if (this.emitter.listenerCount(routes.events.EventType.attestation)) {
for (const attestation of block.message.body.attestations) {
this.emitter.emit(routes.events.EventType.attestation, attestation);
this.emitter.emit(routes.events.EventType.attestation, {
version: this.config.getForkName(blockSlot),
data: attestation,
});
}
}
if (this.emitter.listenerCount(routes.events.EventType.attesterSlashing)) {
for (const attesterSlashing of block.message.body.attesterSlashings) {
this.emitter.emit(routes.events.EventType.attesterSlashing, attesterSlashing);
this.emitter.emit(routes.events.EventType.attesterSlashing, {
version: this.config.getForkName(blockSlot),
data: attesterSlashing,
});
}
}
if (this.emitter.listenerCount(routes.events.EventType.proposerSlashing)) {
Expand Down
12 changes: 11 additions & 1 deletion packages/beacon-node/src/chain/errors/attestationError.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,14 @@ export enum AttestationErrorCode {
INVALID_SERIALIZED_BYTES = "ATTESTATION_ERROR_INVALID_SERIALIZED_BYTES",
/** Too many skipped slots. */
TOO_MANY_SKIPPED_SLOTS = "ATTESTATION_ERROR_TOO_MANY_SKIPPED_SLOTS",
/**
* Electra: The aggregated attestation doesn't have only one committee bit set.
*/
NOT_EXACTLY_ONE_COMMITTEE_BIT_SET = "ATTESTATION_ERROR_NOT_EXACTLY_ONE_COMMITTEE_BIT_SET",
/**
* Electra: Invalid attestationData index: is non-zero
*/
NON_ZERO_ATTESTATION_DATA_INDEX = "ATTESTATION_ERROR_NON_ZERO_ATTESTATION_DATA_INDEX",
}

export type AttestationErrorType =
Expand Down Expand Up @@ -160,7 +168,9 @@ export type AttestationErrorType =
| {code: AttestationErrorCode.INVALID_AGGREGATOR}
| {code: AttestationErrorCode.INVALID_INDEXED_ATTESTATION}
| {code: AttestationErrorCode.INVALID_SERIALIZED_BYTES}
| {code: AttestationErrorCode.TOO_MANY_SKIPPED_SLOTS; headBlockSlot: Slot; attestationSlot: Slot};
| {code: AttestationErrorCode.TOO_MANY_SKIPPED_SLOTS; headBlockSlot: Slot; attestationSlot: Slot}
| {code: AttestationErrorCode.NOT_EXACTLY_ONE_COMMITTEE_BIT_SET}
| {code: AttestationErrorCode.NON_ZERO_ATTESTATION_DATA_INDEX};

export class AttestationError extends GossipActionError<AttestationErrorType> {
getMetadata(): Record<string, string | number | null> {
Expand Down
Loading
Loading