Skip to content

Commit

Permalink
Merge d9a00d2 into 18dc0c9
Browse files Browse the repository at this point in the history
  • Loading branch information
nflaig authored Oct 23, 2023
2 parents 18dc0c9 + d9a00d2 commit 1b7c750
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 24 deletions.
1 change: 0 additions & 1 deletion packages/api/src/beacon/routes/beacon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export type {AttestationFilters} from "./pool.js";
export type {
StateId,
ValidatorId,
ValidatorStatus,
ValidatorFilters,
CommitteesFilters,
FinalityCheckpoints,
Expand Down
27 changes: 13 additions & 14 deletions packages/api/src/beacon/routes/beacon/state.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import {ContainerType} from "@chainsafe/ssz";
import {phase0, CommitteeIndex, Slot, ValidatorIndex, Epoch, Root, ssz, StringType, RootHex} from "@lodestar/types";
import {
phase0,
CommitteeIndex,
Slot,
ValidatorIndex,
Epoch,
Root,
ssz,
RootHex,
ValidatorStatus,
validatorStatusType,
} from "@lodestar/types";
import {ApiClientResponse} from "../../../interfaces.js";
import {HttpStatusCode} from "../../../utils/client/httpStatusCode.js";
import {
Expand All @@ -23,18 +34,6 @@ export type ValidatorId = string | number;
*/
export type ExecutionOptimistic = boolean;

export type ValidatorStatus =
| "active"
| "pending_initialized"
| "pending_queued"
| "active_ongoing"
| "active_exiting"
| "active_slashed"
| "exited_unslashed"
| "exited_slashed"
| "withdrawal_possible"
| "withdrawal_done";

export type ValidatorFilters = {
id?: ValidatorId[];
status?: ValidatorStatus[];
Expand Down Expand Up @@ -312,7 +311,7 @@ export function getReturnTypes(): ReturnTypes<Api> {
{
index: ssz.ValidatorIndex,
balance: ssz.UintNum64,
status: new StringType<ValidatorStatus>(),
status: validatorStatusType,
validator: ssz.phase0.Validator,
},
{jsonCase: "eth2"}
Expand Down
4 changes: 2 additions & 2 deletions packages/beacon-node/src/api/impl/beacon/state/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {fromHexString} from "@chainsafe/ssz";
import {routes} from "@lodestar/api";
import {FAR_FUTURE_EPOCH, GENESIS_SLOT} from "@lodestar/params";
import {BeaconStateAllForks, PubkeyIndexMap} from "@lodestar/state-transition";
import {BLSPubkey, phase0} from "@lodestar/types";
import {BLSPubkey, ValidatorStatus, phase0} from "@lodestar/types";
import {Epoch, ValidatorIndex} from "@lodestar/types";
import {IBeaconChain, StateGetOpts} from "../../../../chain/index.js";
import {ApiError, ValidationError} from "../../errors.js";
Expand Down Expand Up @@ -66,7 +66,7 @@ async function resolveStateIdOrNull(
* Get the status of the validator
* based on conditions outlined in https://hackmd.io/ofFJ5gOmQpu1jjHilHbdQQ
*/
export function getValidatorStatus(validator: phase0.Validator, currentEpoch: Epoch): routes.beacon.ValidatorStatus {
export function getValidatorStatus(validator: phase0.Validator, currentEpoch: Epoch): ValidatorStatus {
// pending
if (validator.activationEpoch > currentEpoch) {
if (validator.activationEligibilityEpoch === FAR_FUTURE_EPOCH) {
Expand Down
1 change: 0 additions & 1 deletion packages/beacon-node/src/api/impl/validator/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -833,7 +833,6 @@ export function getValidatorApi({
const validator = headState.validators.getReadonly(validatorIndex);
const status = getValidatorStatus(validator, currentEpoch);
return (
status === "active" ||
status === "active_exiting" ||
status === "active_ongoing" ||
status === "active_slashed" ||
Expand Down
2 changes: 2 additions & 0 deletions packages/types/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ export * as ssz from "./sszTypes.js";
export * from "./utils/typeguards.js";
// String type
export {StringType, stringType} from "./utils/StringType.js";
// Validator status type
export {ValidatorStatusType, validatorStatusType} from "./utils/ValidatorStatusType.js";
14 changes: 14 additions & 0 deletions packages/types/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,17 @@ export enum ProducedBlockSource {

export type SlotRootHex = {slot: Slot; root: RootHex};
export type SlotOptionalRoot = {slot: Slot; root?: RootHex};

/**
* [Validator status specification](https://hackmd.io/ofFJ5gOmQpu1jjHilHbdQQ)
*/
export type ValidatorStatus =
| "pending_initialized"
| "pending_queued"
| "active_ongoing"
| "active_exiting"
| "active_slashed"
| "exited_unslashed"
| "exited_slashed"
| "withdrawal_possible"
| "withdrawal_done";
89 changes: 89 additions & 0 deletions packages/types/src/utils/ValidatorStatusType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import {BasicType} from "@chainsafe/ssz";
import {ValidatorStatus} from "../types.js";

// TODO: add spec reference once defined
const statusToByteMapping: Record<ValidatorStatus, number> = {
pending_initialized: 0x01,
pending_queued: 0x02,
active_ongoing: 0x03,
active_exiting: 0x04,
active_slashed: 0x05,
exited_unslashed: 0x06,
exited_slashed: 0x07,
withdrawal_possible: 0x08,
withdrawal_done: 0x09,
};

const byteToStatusMapping = Object.fromEntries(
Object.entries(statusToByteMapping).map(([key, value]) => [value, key])
) as Record<number, ValidatorStatus>;

export class ValidatorStatusType extends BasicType<ValidatorStatus> {
// TODO: review if those parameters are correct
readonly typeName = "ValidatorStatus";
readonly byteLength = 1;
readonly fixedSize = 1;
readonly minSize = 1;
readonly maxSize = 1;

defaultValue(): ValidatorStatus {
return "" as ValidatorStatus;
}

// Serialization + deserialization

value_serializeToBytes(output: ByteViews, offset: number, value: ValidatorStatus): number {
output.uint8Array[offset] = statusToByteMapping[value];
return offset + 1;
}
value_deserializeFromBytes(data: ByteViews, start: number, end: number): ValidatorStatus {
this.assertValidSize(end - start);

const status = byteToStatusMapping[data.uint8Array[start]];

if (status === undefined) {
throw Error(`ValidatorStatus: invalid value: ${data.uint8Array[start]}`);
}

return status;
}
tree_serializeToBytes(): number {
throw Error("Not supported in ValidatorStatus type");
}
tree_deserializeFromBytes(): never {
throw Error("Not supported in ValidatorStatus type");
}

// Fast tree opts

tree_getFromNode(): ValidatorStatus {
throw Error("Not supported in ValidatorStatus type");
}
tree_setToNode(): void {
throw Error("Not supported in ValidatorStatus type");
}
tree_getFromPackedNode(): ValidatorStatus {
throw Error("Not supported in ValidatorStatus type");
}
tree_setToPackedNode(): void {
throw Error("Not supported in ValidatorStatus type");
}

// JSON

fromJson(json: unknown): ValidatorStatus {
return json as ValidatorStatus;
}

toJson(value: ValidatorStatus): ValidatorStatus {
return value;
}
}

// TODO: export from ssz / or move type to ssz?
type ByteViews = {
uint8Array: Uint8Array;
dataView: DataView;
};

export const validatorStatusType = new ValidatorStatusType();
7 changes: 3 additions & 4 deletions packages/validator/src/services/indices.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {toHexString} from "@chainsafe/ssz";
import {ValidatorIndex} from "@lodestar/types";
import {ValidatorIndex, ValidatorStatus} from "@lodestar/types";
import {Logger, MapDef} from "@lodestar/utils";
import {Api, ApiError, routes} from "@lodestar/api";
import {Api, ApiError} from "@lodestar/api";
import {batchItems} from "../util/index.js";
import {Metrics} from "../metrics.js";

Expand All @@ -17,9 +17,8 @@ type PubkeyHex = string;
// To assist with logging statuses, we only log the statuses that are not active_exiting or withdrawal_possible
type SimpleValidatorStatus = "pending" | "active" | "exited" | "withdrawn";

const statusToSimpleStatusMapping = (status: routes.beacon.ValidatorStatus): SimpleValidatorStatus => {
const statusToSimpleStatusMapping = (status: ValidatorStatus): SimpleValidatorStatus => {
switch (status) {
case "active":
case "active_exiting":
case "active_slashed":
case "active_ongoing":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ describe("AttestationDutiesService", function () {
const defaultValidator: routes.beacon.ValidatorResponse = {
index,
balance: 32e9,
status: "active",
status: "active_ongoing",
validator: ssz.phase0.Validator.defaultValue(),
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe("SyncCommitteeDutiesService", function () {
const defaultValidator: routes.beacon.ValidatorResponse = {
index: indices[0],
balance: 32e9,
status: "active",
status: "active_ongoing",
validator: ssz.phase0.Validator.defaultValue(),
};

Expand Down

0 comments on commit 1b7c750

Please sign in to comment.