Skip to content

Commit

Permalink
feat: add keymanager endpoint to retrieve proposer config (#7210)
Browse files Browse the repository at this point in the history
* feat: add keymanager endpoint to retrieve proposer config

* Do not return empty builder config

* Check all builder proposer config values

* Fix settings builder config if undefined

* Fix builder config parsing

* Use ssz type to handle json serialization

Default parsing can't handle BigInt

* Revert "Use ssz type to handle json serialization"

This reverts commit 01fcea7.

* Fix boost factor json serialization

* Remove unused import

* Update test data

* Update proposer config test
  • Loading branch information
nflaig authored Oct 30, 2024
1 parent 558ec2f commit 99c0dcb
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 8 deletions.
1 change: 1 addition & 0 deletions packages/api/src/keymanager/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export type {
GraffitiData,
GasLimitData,
BuilderBoostFactorData,
ProposerConfigResponse,
} from "./routes.js";

export type {ApiClient};
Expand Down
33 changes: 33 additions & 0 deletions packages/api/src/keymanager/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,17 @@ export type SignerDefinition = {

export type RemoteSignerDefinition = Pick<SignerDefinition, "pubkey" | "url">;

export type ProposerConfigResponse = {
graffiti?: string;
strictFeeRecipientCheck?: boolean;
feeRecipient?: string;
builder?: {
gasLimit?: number;
selection?: string;
boostFactor?: string;
};
};

/**
* JSON serialized representation of a single keystore in EIP-2335: BLS12-381 Keystore format.
* ```
Expand Down Expand Up @@ -356,6 +367,15 @@ export type Endpoints = {
EmptyMeta
>;

getProposerConfig: Endpoint<
// ⏎
"GET",
{pubkey: PubkeyHex},
{params: {pubkey: string}},
ProposerConfigResponse,
EmptyMeta
>;

/**
* Create a signed voluntary exit message for an active validator, identified by a public key known to the validator
* client. This endpoint returns a `SignedVoluntaryExit` object, which can be used to initiate voluntary exit via the
Expand Down Expand Up @@ -635,6 +655,19 @@ export function getDefinitions(_config: ChainForkConfig): RouteDefinitions<Endpo
resp: EmptyResponseCodec,
},

getProposerConfig: {
url: "/eth/v0/validator/{pubkey}/proposer_config",
method: "GET",
req: {
writeReq: ({pubkey}) => ({params: {pubkey}}),
parseReq: ({params: {pubkey}}) => ({pubkey}),
schema: {
params: {pubkey: Schema.StringRequired},
},
},
resp: JsonOnlyResponseCodec,
},

signVoluntaryExit: {
url: "/eth/v1/validator/{pubkey}/voluntary_exit",
method: "POST",
Expand Down
15 changes: 15 additions & 0 deletions packages/api/test/unit/keymanager/testData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,19 @@ export const testData: GenericServerTestCases<Endpoints> = {
args: {pubkey: pubkeyRand},
res: undefined,
},
getProposerConfig: {
args: {pubkey: pubkeyRand},
res: {
data: {
graffiti: graffitiRandUtf8,
strictFeeRecipientCheck: false,
feeRecipient: ethaddressRand,
builder: {
gasLimit: gasLimitRand,
selection: "maxprofit",
boostFactor: builderBoostFactorRand.toString(),
},
},
},
},
};
18 changes: 18 additions & 0 deletions packages/cli/src/cmds/validator/keymanager/impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
GraffitiData,
GasLimitData,
BuilderBoostFactorData,
ProposerConfigResponse,
} from "@lodestar/api/keymanager";
import {KeymanagerApiMethods as Api} from "@lodestar/api/keymanager/server";
import {Interchange, SignerType, Validator} from "@lodestar/validator";
Expand Down Expand Up @@ -364,6 +365,23 @@ export class KeymanagerApi implements Api {
return {status: 204};
}

async getProposerConfig({pubkey}: {pubkey: PubkeyHex}): ReturnType<Api["getProposerConfig"]> {
const config = this.validator.validatorStore.getProposerConfig(pubkey);

const data: ProposerConfigResponse = {
...config,
builder: config?.builder
? {
...config.builder,
// Default JSON serialization can't handle BigInt
boostFactor: config.builder.boostFactor ? config.builder.boostFactor.toString() : undefined,
}
: undefined,
};

return {data};
}

async signVoluntaryExit({pubkey, epoch}: {pubkey: PubkeyHex; epoch?: Epoch}): ReturnType<Api["signVoluntaryExit"]> {
if (!isValidatePubkeyHex(pubkey)) {
throw new ApiError(400, `Invalid pubkey ${pubkey}`);
Expand Down
13 changes: 8 additions & 5 deletions packages/cli/src/util/proposerConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,14 @@ function parseProposerConfigSection(
overrideConfig?.strictFeeRecipientCheck ??
(strict_fee_recipient_check ? stringtoBool(strict_fee_recipient_check) : undefined),
feeRecipient: overrideConfig?.feeRecipient ?? (fee_recipient ? parseFeeRecipient(fee_recipient) : undefined),
builder: {
gasLimit: overrideConfig?.builder?.gasLimit ?? (gas_limit !== undefined ? Number(gas_limit) : undefined),
selection: overrideConfig?.builder?.selection ?? parseBuilderSelection(builderSelection),
boostFactor: overrideConfig?.builder?.boostFactor ?? parseBuilderBoostFactor(boost_factor),
},
builder:
overrideConfig?.builder || builder
? {
gasLimit: overrideConfig?.builder?.gasLimit ?? (gas_limit !== undefined ? Number(gas_limit) : undefined),
selection: overrideConfig?.builder?.selection ?? parseBuilderSelection(builderSelection),
boostFactor: overrideConfig?.builder?.boostFactor ?? parseBuilderBoostFactor(boost_factor),
}
: undefined,
};
}

Expand Down
3 changes: 1 addition & 2 deletions packages/cli/test/unit/validator/parseProposerConfig.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ const testValue = {
builder: {
gasLimit: 35000000,
selection: routes.validator.BuilderSelection.BuilderAlways,
// biome-ignore lint/correctness/noPrecisionLoss: <explanation>
boostFactor: BigInt(18446744073709551616),
boostFactor: 18446744073709551616n,
},
},
},
Expand Down
4 changes: 3 additions & 1 deletion packages/validator/src/services/validatorStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,9 @@ export class ValidatorStore {
graffiti !== undefined ||
strictFeeRecipientCheck !== undefined ||
feeRecipient !== undefined ||
builder?.gasLimit !== undefined
builder?.gasLimit !== undefined ||
builder?.selection !== undefined ||
builder?.boostFactor !== undefined
) {
proposerConfig = {graffiti, strictFeeRecipientCheck, feeRecipient, builder};
}
Expand Down

0 comments on commit 99c0dcb

Please sign in to comment.