Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 51 additions & 2 deletions packages/api/src/beacon/routes/beacon/state.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import {ContainerType, ValueOf} from "@chainsafe/ssz";
import {ChainForkConfig} from "@lodestar/config";
import {MAX_VALIDATORS_PER_COMMITTEE} from "@lodestar/params";
import {CommitteeIndex, Epoch, RootHex, Slot, StringType, ValidatorStatus, phase0, ssz} from "@lodestar/types";
import {CommitteeIndex, Epoch, RootHex, Slot, StringType, ValidatorStatus, electra, phase0, ssz} from "@lodestar/types";
import {ArrayOf, JsonOnlyReq} from "../../../utils/codecs.js";
import {Endpoint, RequestCodec, RouteDefinitions, Schema} from "../../../utils/index.js";
import {ExecutionOptimisticAndFinalizedCodec, ExecutionOptimisticAndFinalizedMeta} from "../../../utils/metadata.js";
import {
ExecutionOptimisticAndFinalizedCodec,
ExecutionOptimisticAndFinalizedMeta,
ExecutionOptimisticFinalizedAndVersionCodec,
ExecutionOptimisticFinalizedAndVersionMeta,
} from "../../../utils/metadata.js";
import {fromValidatorIdsStr, toValidatorIdsStr} from "../../../utils/serdes.js";
import {WireFormat} from "../../../utils/wireFormat.js";
import {RootResponse, RootResponseType} from "./block.js";
Expand Down Expand Up @@ -266,6 +271,32 @@ export type Endpoints = {
EpochSyncCommitteeResponse,
ExecutionOptimisticAndFinalizedMeta
>;

/**
* Get State Pending Deposits
*
* Returns pending deposits for state with given 'stateId'.
*/
getPendingDeposits: Endpoint<
"GET",
StateArgs,
{params: {state_id: string}},
electra.PendingDeposits,
ExecutionOptimisticFinalizedAndVersionMeta
>;

/**
* Get State Pending Partial Withdrawals
*
* Returns pending partial withdrawals for state with given 'stateId'.
*/
getPendingPartialWithdrawals: Endpoint<
"GET",
StateArgs,
{params: {state_id: string}},
electra.PendingPartialWithdrawals,
ExecutionOptimisticFinalizedAndVersionMeta
>;
};

// biome-ignore lint/suspicious/noExplicitAny: <explanation>
Expand Down Expand Up @@ -483,5 +514,23 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
meta: ExecutionOptimisticAndFinalizedCodec,
},
},
getPendingDeposits: {
url: "/eth/v1/beacon/states/{state_id}/pending_deposits",
method: "GET",
req: stateIdOnlyReq,
resp: {
data: ssz.electra.PendingDeposits,
meta: ExecutionOptimisticFinalizedAndVersionCodec,
},
},
getPendingPartialWithdrawals: {
url: "/eth/v1/beacon/states/{state_id}/pending_partial_withdrawals",
method: "GET",
req: stateIdOnlyReq,
resp: {
data: ssz.electra.PendingPartialWithdrawals,
meta: ExecutionOptimisticFinalizedAndVersionCodec,
},
},
};
}
14 changes: 14 additions & 0 deletions packages/api/test/unit/beacon/testData/beacon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,20 @@ export const testData: GenericServerTestCases<Endpoints> = {
meta: {executionOptimistic: true, finalized: false},
},
},
getPendingDeposits: {
args: {stateId: "head"},
res: {
data: [ssz.electra.PendingDeposit.defaultValue()],
meta: {executionOptimistic: true, finalized: false, version: ForkName.electra},
},
},
getPendingPartialWithdrawals: {
args: {stateId: "head"},
res: {
data: [ssz.electra.PendingPartialWithdrawal.defaultValue()],
meta: {executionOptimistic: true, finalized: false, version: ForkName.electra},
},
},

// rewards

Expand Down
35 changes: 34 additions & 1 deletion packages/beacon-node/src/api/impl/beacon/state/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {routes} from "@lodestar/api";
import {ApplicationMethods} from "@lodestar/api/server";
import {EPOCHS_PER_HISTORICAL_VECTOR} from "@lodestar/params";
import {EPOCHS_PER_HISTORICAL_VECTOR, isForkPostElectra} from "@lodestar/params";
import {
BeaconStateAllForks,
BeaconStateElectra,
CachedBeaconStateAltair,
computeEpochAtSlot,
computeStartSlotAtEpoch,
Expand Down Expand Up @@ -296,5 +297,37 @@ export function getBeaconStateApi({
meta: {executionOptimistic, finalized},
};
},

async getPendingDeposits({stateId}, context) {
const {state, executionOptimistic, finalized} = await getState(stateId);
const fork = config.getForkName(state.slot);

if (!isForkPostElectra(fork)) {
throw new ApiError(400, `Cannot retrieve pending deposits for pre-electra state fork=${fork}`);
}

const {pendingDeposits} = state as BeaconStateElectra;

return {
data: context?.returnBytes ? pendingDeposits.serialize() : pendingDeposits.toValue(),
meta: {executionOptimistic, finalized, version: fork},
};
},

async getPendingPartialWithdrawals({stateId}, context) {
const {state, executionOptimistic, finalized} = await getState(stateId);
const fork = config.getForkName(state.slot);

if (!isForkPostElectra(fork)) {
throw new ApiError(400, `Cannot retrieve pending partial withdrawals for pre-electra state fork=${fork}`);
}

const {pendingPartialWithdrawals} = state as BeaconStateElectra;

return {
data: context?.returnBytes ? pendingPartialWithdrawals.serialize() : pendingPartialWithdrawals.toValue(),
meta: {executionOptimistic, finalized, version: fork},
};
},
};
}
11 changes: 9 additions & 2 deletions packages/types/src/electra/sszTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,11 @@ export const PendingPartialWithdrawal = new ContainerType(
{typeName: "PendingPartialWithdrawal", jsonCase: "eth2"}
);

export const PendingPartialWithdrawals = new ListCompositeType(
PendingPartialWithdrawal,
PENDING_PARTIAL_WITHDRAWALS_LIMIT
);

export const PendingConsolidation = new ContainerType(
{
sourceIndex: ValidatorIndex,
Expand All @@ -295,6 +300,8 @@ export const PendingConsolidation = new ContainerType(
{typeName: "PendingConsolidation", jsonCase: "eth2"}
);

export const PendingConsolidations = new ListCompositeType(PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT);

// In EIP-7251, we spread deneb fields as new fields are appended at the end
export const BeaconState = new ContainerType(
{
Expand Down Expand Up @@ -345,8 +352,8 @@ export const BeaconState = new ContainerType(
consolidationBalanceToConsume: Gwei, // New in ELECTRA:EIP7251
earliestConsolidationEpoch: Epoch, // New in ELECTRA:EIP7251
pendingDeposits: PendingDeposits, // New in ELECTRA:EIP7251
pendingPartialWithdrawals: new ListCompositeType(PendingPartialWithdrawal, PENDING_PARTIAL_WITHDRAWALS_LIMIT), // New in ELECTRA:EIP7251
pendingConsolidations: new ListCompositeType(PendingConsolidation, PENDING_CONSOLIDATIONS_LIMIT), // New in ELECTRA:EIP7251
pendingPartialWithdrawals: PendingPartialWithdrawals, // New in ELECTRA:EIP7251
pendingConsolidations: PendingConsolidations, // New in ELECTRA:EIP7251
},
{typeName: "BeaconState", jsonCase: "eth2"}
);
Expand Down
3 changes: 3 additions & 0 deletions packages/types/src/electra/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ export type LightClientOptimisticUpdate = ValueOf<typeof ssz.LightClientOptimist
export type LightClientStore = ValueOf<typeof ssz.LightClientStore>;

export type PendingDeposit = ValueOf<typeof ssz.PendingDeposit>;
export type PendingDeposits = ValueOf<typeof ssz.PendingDeposits>;
export type PendingPartialWithdrawal = ValueOf<typeof ssz.PendingPartialWithdrawal>;
export type PendingPartialWithdrawals = ValueOf<typeof ssz.PendingPartialWithdrawals>;
export type PendingConsolidation = ValueOf<typeof ssz.PendingConsolidation>;
export type PendingConsolidations = ValueOf<typeof ssz.PendingConsolidations>;

export type BlockContents = ValueOf<typeof ssz.BlockContents>;
export type SignedBlockContents = ValueOf<typeof ssz.SignedBlockContents>;
Loading