From 7dbe996d0f1fbf62b7e5384bb5ac2d16fa8848cc Mon Sep 17 00:00:00 2001 From: Fredrik Svantes Date: Tue, 19 Mar 2024 21:17:22 +0100 Subject: [PATCH 1/8] Set default builderBoostFactor to 90 --- packages/validator/src/services/validatorStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/validator/src/services/validatorStore.ts b/packages/validator/src/services/validatorStore.ts index d1474e7fdd28..2b29fbfdd8ae 100644 --- a/packages/validator/src/services/validatorStore.ts +++ b/packages/validator/src/services/validatorStore.ts @@ -125,7 +125,7 @@ export const defaultOptions = { defaultGasLimit: 30_000_000, builderSelection: routes.validator.BuilderSelection.ExecutionOnly, builderAliasSelection: routes.validator.BuilderSelection.MaxProfit, - builderBoostFactor: BigInt(100), + builderBoostFactor: BigInt(90), // spec asks for gossip validation by default broadcastValidation: routes.beacon.BroadcastValidation.gossip, // should request fetching the locally produced block in blinded format From b9c2d78f422df65d0b302ae5a030cb56c1e00946 Mon Sep 17 00:00:00 2001 From: Fredrik Svantes Date: Fri, 22 Mar 2024 10:31:08 +0100 Subject: [PATCH 2/8] Changing "MaxProfit" to "Default" --- .../pages/validator-management/vc-configuration.md | 6 +++--- packages/api/src/beacon/routes/validator.ts | 2 +- packages/api/test/unit/keymanager/testData.ts | 2 +- .../beacon-node/src/api/impl/validator/index.ts | 6 +++--- .../beacon-node/src/api/impl/validator/utils.ts | 4 ++-- .../unit/api/impl/validator/produceBlockV3.test.ts | 14 +++++++------- packages/cli/src/cmds/validator/options.ts | 4 ++-- packages/cli/src/util/proposerConfig.ts | 2 +- packages/cli/test/sim/multi_fork.test.ts | 6 +++--- .../unit/validator/parseProposerConfig.test.ts | 2 +- .../unit/validator/proposerConfigs/validData.yaml | 4 ++-- packages/validator/src/services/validatorStore.ts | 4 ++-- .../validator/test/unit/services/block.test.ts | 8 ++++---- 13 files changed, 32 insertions(+), 32 deletions(-) diff --git a/docs/pages/validator-management/vc-configuration.md b/docs/pages/validator-management/vc-configuration.md index 30b3cb5c7883..0ac9eec91dd6 100644 --- a/docs/pages/validator-management/vc-configuration.md +++ b/docs/pages/validator-management/vc-configuration.md @@ -78,11 +78,11 @@ You may choose to use the `--strictFeeRecipientCheck` flag to enable a strict ch If you are running a beacon node with connected builder relays, you may use these validator configurations to signal which block (builder vs. local execution) the beacon node should produce. -With produceBlockV3 (enabled automatically after the Deneb hard fork), the `--builder.boostFactor` is a percentage multiplier the block producing beacon node must apply to boost (>100) or dampen (<100) builder block value for selection against execution block. The multiplier is ignored if `--builder.selection` is set to anything other than `maxprofit`. Even though this is set on the validator client, the calculation is requested and applied on the beacon node itself. For more information, see the [produceBlockV3 Beacon API](https://ethereum.github.io/beacon-APIs/#/ValidatorRequiredApi/produceBlockV3). +With produceBlockV3 (enabled automatically after the Deneb hard fork), the `--builder.boostFactor` is a percentage multiplier the block producing beacon node must apply to boost (>100) or dampen (<100) builder block value for selection against execution block. The multiplier is ignored if `--builder.selection` is set to anything other than `default`. Even though this is set on the validator client, the calculation is requested and applied on the beacon node itself. For more information, see the [produceBlockV3 Beacon API](https://ethereum.github.io/beacon-APIs/#/ValidatorRequiredApi/produceBlockV3). With Lodestar's `--builder.selection` validator options, you can select: -- `maxprofit`: Default setting for Lodestar set at `--builder.boostFactor=100`. This default setting will always choose the more profitable block. Using this option, you may customize your `--builder.boostFactor` to your preference. Examples of its usage are below. +- `default`: Default setting for Lodestar set at `--builder.boostFactor=90`. This default setting will have a local block boost of ~10%. Using this option, you may customize your `--builder.boostFactor` to your preference. Examples of its usage are below. - `executionalways`: An alias of `--builder.boostFactor=0`, which will select the local execution block, unless it fails to produce due to an error or a delay in the response from the execution client. - `executiononly`: Beacon node will be requested to produce local execution block even if builder relays are configured. This option will always select the local execution block and will error if it couldn't produce one. - `builderalways`: An alias of `--builder.boostFactor=18446744073709551615` (2**64 - 1), which will select the builder block, unless the builder block fails to produce. The builder block may fail to produce if it's not available, not timely or there is an indication of censorship via `shouldOverrideBuilder` from the execution payload response. @@ -100,7 +100,7 @@ Therefore, `--builder.boostFactor=80`. Example 2: Setting a `--builder.boostFactor=0` will always prefer the local execution block, but will produce an available builder block if the local execution block fails. -Example 3: Setting a `--builder.boostFactor=100` is the same as signaling `--builder.selection maxprofit` where the validator will always select the most profitable block between the local execution engine and the builder block from the relay. +Example 3: Setting a `--builder.boostFactor=100` will always select the most profitable block between the local execution engine and the builder block from the relay. ### Submit a validator deposit diff --git a/packages/api/src/beacon/routes/validator.ts b/packages/api/src/beacon/routes/validator.ts index 5b6fa7797d88..0fff20e1a547 100644 --- a/packages/api/src/beacon/routes/validator.ts +++ b/packages/api/src/beacon/routes/validator.ts @@ -44,7 +44,7 @@ import {ExecutionOptimistic} from "./beacon/block.js"; export enum BuilderSelection { BuilderAlways = "builderalways", ExecutionAlways = "executionalways", - MaxProfit = "maxprofit", + Default = "default", /** Only activate builder flow for DVT block proposal protocols */ BuilderOnly = "builderonly", /** Only builds execution block*/ diff --git a/packages/api/test/unit/keymanager/testData.ts b/packages/api/test/unit/keymanager/testData.ts index 2c66610c8733..8484f29a5eaa 100644 --- a/packages/api/test/unit/keymanager/testData.ts +++ b/packages/api/test/unit/keymanager/testData.ts @@ -13,7 +13,7 @@ const pubkeyRand = "0x84105a985058fc8740a48bf1ede9d223ef09e8c6b1735ba0a55cf4a9ff const ethaddressRand = "0xabcf8e0d4e9587369b2301d0790347320302cc09"; const graffitiRandUtf8 = "636861696e736166652f6c6f64657374"; const gasLimitRand = 30_000_000; -const builderBoostFactorRand = BigInt(100); +const builderBoostFactorRand = BigInt(90); export const testData: GenericServerTestCases = { listKeys: { diff --git a/packages/beacon-node/src/api/impl/validator/index.ts b/packages/beacon-node/src/api/impl/validator/index.ts index 2aef56169112..e114d0b79c05 100644 --- a/packages/beacon-node/src/api/impl/validator/index.ts +++ b/packages/beacon-node/src/api/impl/validator/index.ts @@ -488,10 +488,10 @@ export function getValidatorApi({ const fork = config.getForkName(slot); // set some sensible opts - // builderSelection will be deprecated and will run in mode MaxProfit if builder is enabled + // builderSelection will be deprecated and will run in mode Default if builder is enabled // and the actual selection will be determined using builderBoostFactor passed by the validator - builderSelection = builderSelection ?? routes.validator.BuilderSelection.MaxProfit; - builderBoostFactor = builderBoostFactor ?? BigInt(100); + builderSelection = builderSelection ?? routes.validator.BuilderSelection.Default; + builderBoostFactor = builderBoostFactor ?? BigInt(90); if (builderBoostFactor > MAX_BUILDER_BOOST_FACTOR) { throw new ApiError(400, `Invalid builderBoostFactor=${builderBoostFactor} > MAX_BUILDER_BOOST_FACTOR`); } diff --git a/packages/beacon-node/src/api/impl/validator/utils.ts b/packages/beacon-node/src/api/impl/validator/utils.ts index 8932f8951cf4..013b28176107 100644 --- a/packages/beacon-node/src/api/impl/validator/utils.ts +++ b/packages/beacon-node/src/api/impl/validator/utils.ts @@ -60,9 +60,9 @@ export function selectBlockProductionSource({ case routes.validator.BuilderSelection.ExecutionOnly: return ProducedBlockSource.engine; - case routes.validator.BuilderSelection.MaxProfit: + case routes.validator.BuilderSelection.Default: return builderBoostFactor !== MAX_BUILDER_BOOST_FACTOR && - (builderBoostFactor === BigInt(0) || engineBlockValue >= (builderBlockValue * builderBoostFactor) / BigInt(100)) + (builderBoostFactor === BigInt(0) || engineBlockValue >= (builderBlockValue * builderBoostFactor) / BigInt(90)) ? ProducedBlockSource.engine : ProducedBlockSource.builder; diff --git a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts index ba0267fc5810..6e6c62fc0cad 100644 --- a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts +++ b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts @@ -33,13 +33,13 @@ describe("api/validator - produceBlockV3", function () { }); const testCases: [routes.validator.BuilderSelection, number | null, number | null, number, boolean, string][] = [ - [routes.validator.BuilderSelection.MaxProfit, 1, 0, 0, false, "builder"], - [routes.validator.BuilderSelection.MaxProfit, 1, 2, 1, false, "engine"], - [routes.validator.BuilderSelection.MaxProfit, null, 0, 0, false, "engine"], - [routes.validator.BuilderSelection.MaxProfit, 0, null, 1, false, "builder"], - [routes.validator.BuilderSelection.MaxProfit, 0, null, 1, true, "builder"], - [routes.validator.BuilderSelection.MaxProfit, 1, 1, 1, true, "engine"], - [routes.validator.BuilderSelection.MaxProfit, 2, 1, 1, true, "engine"], + [routes.validator.BuilderSelection.Default, 1, 0, 0, false, "builder"], + [routes.validator.BuilderSelection.Default, 1, 2, 1, false, "engine"], + [routes.validator.BuilderSelection.Default, null, 0, 0, false, "engine"], + [routes.validator.BuilderSelection.Default, 0, null, 1, false, "builder"], + [routes.validator.BuilderSelection.Default, 0, null, 1, true, "builder"], + [routes.validator.BuilderSelection.Default, 1, 1, 1, true, "engine"], + [routes.validator.BuilderSelection.Default, 2, 1, 1, true, "engine"], [routes.validator.BuilderSelection.BuilderAlways, 1, 2, 0, false, "builder"], [routes.validator.BuilderSelection.BuilderAlways, 1, 0, 1, false, "builder"], diff --git a/packages/cli/src/cmds/validator/options.ts b/packages/cli/src/cmds/validator/options.ts index 7fdcdec59e86..208f6b06078f 100644 --- a/packages/cli/src/cmds/validator/options.ts +++ b/packages/cli/src/cmds/validator/options.ts @@ -244,7 +244,7 @@ export const validatorOptions: CliCommandOptions = { "builder.selection": { type: "string", description: - "Builder block selection strategy `maxprofit`, `builderalways`, `builderonly`, `executionalways`, or `executiononly`", + "Builder block selection strategy `default`, `builderalways`, `builderonly`, `executionalways`, or `executiononly`", defaultDescription: `${defaultOptions.builderSelection}`, group: "builder", }, @@ -252,7 +252,7 @@ export const validatorOptions: CliCommandOptions = { "builder.boostFactor": { type: "string", description: - "Percentage multiplier the block producing beacon node must apply to boost (>100) or dampen (<100) builder block value for selection against execution block. The multiplier is ignored if `--builder.selection` is set to anything other than `maxprofit`", + "Percentage multiplier the block producing beacon node must apply to boost (>100) or dampen (<100) builder block value for selection against execution block. The multiplier is ignored if `--builder.selection` is set to anything other than `default`", defaultDescription: `${defaultOptions.builderBoostFactor}`, group: "builder", }, diff --git a/packages/cli/src/util/proposerConfig.ts b/packages/cli/src/util/proposerConfig.ts index ae56cc45513a..942c5274c914 100644 --- a/packages/cli/src/util/proposerConfig.ts +++ b/packages/cli/src/util/proposerConfig.ts @@ -107,7 +107,7 @@ export function readProposerConfigDir(filepath: string, filename: string): Propo export function parseBuilderSelection(builderSelection?: string): routes.validator.BuilderSelection | undefined { if (builderSelection) { switch (builderSelection) { - case "maxprofit": + case "default": break; case "builderalways": break; diff --git a/packages/cli/test/sim/multi_fork.test.ts b/packages/cli/test/sim/multi_fork.test.ts index f57d3a397955..417cf6076c42 100644 --- a/packages/cli/test/sim/multi_fork.test.ts +++ b/packages/cli/test/sim/multi_fork.test.ts @@ -53,7 +53,7 @@ const env = await SimulationEnvironment.initWithDefaults( // return with engine full block and publish via publishBlockV2 clientOptions: { useProduceBlockV3: true, - "builder.selection": "maxprofit", + "builder.selection": "default", }, }, }, @@ -71,7 +71,7 @@ const env = await SimulationEnvironment.initWithDefaults( // builder is attached to beacon, and publish via publishBlindedBlockV2 clientOptions: { useProduceBlockV3: true, - "builder.selection": "maxprofit", + "builder.selection": "default", blindedLocal: true, }, }, @@ -106,7 +106,7 @@ const env = await SimulationEnvironment.initWithDefaults( // of local block and subsequent publishing via publishBlindedBlock clientOptions: { useProduceBlockV3: false, - "builder.selection": "maxprofit", + "builder.selection": "default", }, }, }, diff --git a/packages/cli/test/unit/validator/parseProposerConfig.test.ts b/packages/cli/test/unit/validator/parseProposerConfig.test.ts index 993d9640e47c..dee260761d21 100644 --- a/packages/cli/test/unit/validator/parseProposerConfig.test.ts +++ b/packages/cli/test/unit/validator/parseProposerConfig.test.ts @@ -26,7 +26,7 @@ const testValue = { feeRecipient: "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", builder: { gasLimit: 35000000, - selection: routes.validator.BuilderSelection.MaxProfit, + selection: routes.validator.BuilderSelection.Default, boostFactor: BigInt(18446744073709551616), }, }, diff --git a/packages/cli/test/unit/validator/proposerConfigs/validData.yaml b/packages/cli/test/unit/validator/proposerConfigs/validData.yaml index 5ea7e1bebea7..d05a55e4c669 100644 --- a/packages/cli/test/unit/validator/proposerConfigs/validData.yaml +++ b/packages/cli/test/unit/validator/proposerConfigs/validData.yaml @@ -9,7 +9,7 @@ proposer_config: fee_recipient: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' builder: gas_limit: "35000000" - selection: "maxprofit" + selection: "default" boost_factor: "18446744073709551616" default_config: graffiti: 'default graffiti' @@ -18,4 +18,4 @@ default_config: builder: gas_limit: "30000000" selection: "builderalways" - boost_factor: "100" + boost_factor: "90" diff --git a/packages/validator/src/services/validatorStore.ts b/packages/validator/src/services/validatorStore.ts index 2b29fbfdd8ae..f739fe6f9926 100644 --- a/packages/validator/src/services/validatorStore.ts +++ b/packages/validator/src/services/validatorStore.ts @@ -124,7 +124,7 @@ export const defaultOptions = { suggestedFeeRecipient: "0x0000000000000000000000000000000000000000", defaultGasLimit: 30_000_000, builderSelection: routes.validator.BuilderSelection.ExecutionOnly, - builderAliasSelection: routes.validator.BuilderSelection.MaxProfit, + builderAliasSelection: routes.validator.BuilderSelection.Default, builderBoostFactor: BigInt(90), // spec asks for gossip validation by default broadcastValidation: routes.beacon.BroadcastValidation.gossip, @@ -267,7 +267,7 @@ export class ValidatorStore { let boostFactor; switch (selection) { - case routes.validator.BuilderSelection.MaxProfit: + case routes.validator.BuilderSelection.Default: boostFactor = (this.validators.get(pubkeyHex)?.builder || {}).boostFactor ?? this.defaultProposerConfig.builder.boostFactor; break; diff --git a/packages/validator/test/unit/services/block.test.ts b/packages/validator/test/unit/services/block.test.ts index bcfc57eb8674..4aad0325fa34 100644 --- a/packages/validator/test/unit/services/block.test.ts +++ b/packages/validator/test/unit/services/block.test.ts @@ -64,8 +64,8 @@ describe("BlockDutiesService", function () { signature: signedBlock.signature, })); validatorStore.getBuilderSelectionParams.mockReturnValue({ - selection: routes.validator.BuilderSelection.MaxProfit, - boostFactor: BigInt(100), + selection: routes.validator.BuilderSelection.Default, + boostFactor: BigInt(90), }); validatorStore.getGraffiti.mockReturnValue("aaaa"); validatorStore.getFeeRecipient.mockReturnValue("0x00"); @@ -107,10 +107,10 @@ describe("BlockDutiesService", function () { false, { feeRecipient: "0x00", - builderSelection: routes.validator.BuilderSelection.MaxProfit, + builderSelection: routes.validator.BuilderSelection.Default, strictFeeRecipientCheck: false, blindedLocal: false, - builderBoostFactor: BigInt(100), + builderBoostFactor: BigInt(90), }, ]); }); From 72712739762726cabe22f79f7de0588f9dbd3059 Mon Sep 17 00:00:00 2001 From: Fredrik Svantes Date: Fri, 22 Mar 2024 10:59:25 +0100 Subject: [PATCH 3/8] Update tests --- packages/api/test/unit/beacon/testData/validator.ts | 8 ++++---- .../cli/test/unit/validator/parseProposerConfig.test.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/api/test/unit/beacon/testData/validator.ts b/packages/api/test/unit/beacon/testData/validator.ts index 0769fbc47d9b..24e12424b06b 100644 --- a/packages/api/test/unit/beacon/testData/validator.ts +++ b/packages/api/test/unit/beacon/testData/validator.ts @@ -55,7 +55,7 @@ export const testData: GenericServerTestCases = { builderSelection: undefined, strictFeeRecipientCheck: undefined, blindedLocal: undefined, - builderBoostFactor: 100n, + builderBoostFactor: 90n, }, ] as unknown as GenericServerTestCases["produceBlock"]["args"], res: {data: ssz.phase0.BeaconBlock.defaultValue()}, @@ -71,7 +71,7 @@ export const testData: GenericServerTestCases = { builderSelection: undefined, strictFeeRecipientCheck: undefined, blindedLocal: undefined, - builderBoostFactor: 100n, + builderBoostFactor: 90n, }, ] as unknown as GenericServerTestCases["produceBlockV2"]["args"], res: { @@ -92,7 +92,7 @@ export const testData: GenericServerTestCases = { builderSelection: undefined, strictFeeRecipientCheck: undefined, blindedLocal: undefined, - builderBoostFactor: 100n, + builderBoostFactor: 90n, }, ], res: { @@ -115,7 +115,7 @@ export const testData: GenericServerTestCases = { builderSelection: undefined, strictFeeRecipientCheck: undefined, blindedLocal: undefined, - builderBoostFactor: 100n, + builderBoostFactor: 90n, }, ] as unknown as GenericServerTestCases["produceBlindedBlock"]["args"], res: { diff --git a/packages/cli/test/unit/validator/parseProposerConfig.test.ts b/packages/cli/test/unit/validator/parseProposerConfig.test.ts index dee260761d21..4d6a51bc2449 100644 --- a/packages/cli/test/unit/validator/parseProposerConfig.test.ts +++ b/packages/cli/test/unit/validator/parseProposerConfig.test.ts @@ -38,7 +38,7 @@ const testValue = { builder: { gasLimit: 30000000, selection: routes.validator.BuilderSelection.BuilderAlways, - boostFactor: BigInt(100), + boostFactor: BigInt(90), }, }, }; From be18ef25fde781355a2e24c79ae71e81b8449941 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Sun, 7 Apr 2024 20:01:00 +0100 Subject: [PATCH 4/8] Add default as new builder selection option --- .../pages/validator-management/vc-configuration.md | 5 +++-- packages/api/src/beacon/routes/validator.ts | 3 ++- .../api/test/unit/beacon/testData/validator.ts | 8 ++++---- packages/api/test/unit/keymanager/testData.ts | 2 +- .../beacon-node/src/api/impl/validator/index.ts | 6 +++--- .../beacon-node/src/api/impl/validator/utils.ts | 3 ++- .../unit/api/impl/validator/produceBlockV3.test.ts | 14 +++++++------- packages/cli/src/cmds/validator/options.ts | 4 ++-- packages/cli/src/util/proposerConfig.ts | 2 ++ .../unit/validator/parseProposerConfig.test.ts | 4 ++-- .../unit/validator/proposerConfigs/validData.yaml | 6 +++--- packages/validator/src/services/validatorStore.ts | 4 ++++ 12 files changed, 35 insertions(+), 26 deletions(-) diff --git a/docs/pages/validator-management/vc-configuration.md b/docs/pages/validator-management/vc-configuration.md index b6005c514fdd..798268fe36eb 100644 --- a/docs/pages/validator-management/vc-configuration.md +++ b/docs/pages/validator-management/vc-configuration.md @@ -82,7 +82,8 @@ With produceBlockV3 (enabled automatically after the Deneb hard fork), the `--bu With Lodestar's `--builder.selection` validator options, you can select: -- `default`: Default setting for Lodestar set at `--builder.boostFactor=90`. This default setting will have a local block boost of ~10%. Using this option, you may customize your `--builder.boostFactor` to your preference. Examples of its usage are below. +- `default`: Default setting for Lodestar set at `--builder.boostFactor=90`. This default setting will have a local block boost of ~10%. Note that this value might change in the future depending on what we think is the most appropriate value to help increase censorship resistance. +- `maxprofit`: An alias of `--builder.boostFactor=100`, which will always choose the more profitable block. Using this option, you may customize your `--builder.boostFactor` to your preference. Examples of its usage are below. - `executionalways`: An alias of `--builder.boostFactor=0`, which will select the local execution block, unless it fails to produce due to an error or a delay in the response from the execution client. - `executiononly`: Beacon node will be requested to produce local execution block even if builder relays are configured. This option will always select the local execution block and will error if it couldn't produce one. - `builderalways`: An alias of `--builder.boostFactor=18446744073709551615` (2\*\*64 - 1), which will select the builder block, unless the builder block fails to produce. The builder block may fail to produce if it's not available, not timely or there is an indication of censorship via `shouldOverrideBuilder` from the execution payload response. @@ -102,7 +103,7 @@ Therefore, `--builder.boostFactor=80`. Example 2: Setting a `--builder.boostFactor=0` will always prefer the local execution block, but will produce an available builder block if the local execution block fails. -Example 3: Setting a `--builder.boostFactor=100` will always select the most profitable block between the local execution engine and the builder block from the relay. +Example 3: Setting a `--builder.boostFactor=100` is the same as signaling `--builder.selection maxprofit` where the validator will always select the most profitable block between the local execution engine and the builder block from the relay. ### Submit a validator deposit diff --git a/packages/api/src/beacon/routes/validator.ts b/packages/api/src/beacon/routes/validator.ts index d303b6b79138..1d6b8b80551c 100644 --- a/packages/api/src/beacon/routes/validator.ts +++ b/packages/api/src/beacon/routes/validator.ts @@ -42,9 +42,10 @@ import {allForksBlockContentsResSerializer} from "../../utils/routes.js"; import {ExecutionOptimistic} from "./beacon/block.js"; export enum BuilderSelection { + Default = "default", BuilderAlways = "builderalways", ExecutionAlways = "executionalways", - Default = "default", + MaxProfit = "maxprofit", /** Only activate builder flow for DVT block proposal protocols */ BuilderOnly = "builderonly", /** Only builds execution block*/ diff --git a/packages/api/test/unit/beacon/testData/validator.ts b/packages/api/test/unit/beacon/testData/validator.ts index 9e43998a6137..6b410b724e4f 100644 --- a/packages/api/test/unit/beacon/testData/validator.ts +++ b/packages/api/test/unit/beacon/testData/validator.ts @@ -55,7 +55,7 @@ export const testData: GenericServerTestCases = { builderSelection: undefined, strictFeeRecipientCheck: undefined, blindedLocal: undefined, - builderBoostFactor: 90n, + builderBoostFactor: 100n, }, ] as unknown as GenericServerTestCases["produceBlock"]["args"], res: {data: ssz.phase0.BeaconBlock.defaultValue()}, @@ -71,7 +71,7 @@ export const testData: GenericServerTestCases = { builderSelection: undefined, strictFeeRecipientCheck: undefined, blindedLocal: undefined, - builderBoostFactor: 90n, + builderBoostFactor: 100n, }, ] as unknown as GenericServerTestCases["produceBlockV2"]["args"], res: { @@ -92,7 +92,7 @@ export const testData: GenericServerTestCases = { builderSelection: undefined, strictFeeRecipientCheck: undefined, blindedLocal: undefined, - builderBoostFactor: 90n, + builderBoostFactor: 100n, }, ], res: { @@ -115,7 +115,7 @@ export const testData: GenericServerTestCases = { builderSelection: undefined, strictFeeRecipientCheck: undefined, blindedLocal: undefined, - builderBoostFactor: 90n, + builderBoostFactor: 100n, }, ] as unknown as GenericServerTestCases["produceBlindedBlock"]["args"], res: { diff --git a/packages/api/test/unit/keymanager/testData.ts b/packages/api/test/unit/keymanager/testData.ts index 8484f29a5eaa..2c66610c8733 100644 --- a/packages/api/test/unit/keymanager/testData.ts +++ b/packages/api/test/unit/keymanager/testData.ts @@ -13,7 +13,7 @@ const pubkeyRand = "0x84105a985058fc8740a48bf1ede9d223ef09e8c6b1735ba0a55cf4a9ff const ethaddressRand = "0xabcf8e0d4e9587369b2301d0790347320302cc09"; const graffitiRandUtf8 = "636861696e736166652f6c6f64657374"; const gasLimitRand = 30_000_000; -const builderBoostFactorRand = BigInt(90); +const builderBoostFactorRand = BigInt(100); export const testData: GenericServerTestCases = { listKeys: { diff --git a/packages/beacon-node/src/api/impl/validator/index.ts b/packages/beacon-node/src/api/impl/validator/index.ts index f21aaa739c77..658c86b905ff 100644 --- a/packages/beacon-node/src/api/impl/validator/index.ts +++ b/packages/beacon-node/src/api/impl/validator/index.ts @@ -512,10 +512,10 @@ export function getValidatorApi({ const fork = config.getForkName(slot); // set some sensible opts - // builderSelection will be deprecated and will run in mode Default if builder is enabled + // builderSelection will be deprecated and will run in mode MaxProfit if builder is enabled // and the actual selection will be determined using builderBoostFactor passed by the validator - builderSelection = builderSelection ?? routes.validator.BuilderSelection.Default; - builderBoostFactor = builderBoostFactor ?? BigInt(90); + builderSelection = builderSelection ?? routes.validator.BuilderSelection.MaxProfit; + builderBoostFactor = builderBoostFactor ?? BigInt(100); if (builderBoostFactor > MAX_BUILDER_BOOST_FACTOR) { throw new ApiError(400, `Invalid builderBoostFactor=${builderBoostFactor} > MAX_BUILDER_BOOST_FACTOR`); } diff --git a/packages/beacon-node/src/api/impl/validator/utils.ts b/packages/beacon-node/src/api/impl/validator/utils.ts index 013b28176107..418e0a052787 100644 --- a/packages/beacon-node/src/api/impl/validator/utils.ts +++ b/packages/beacon-node/src/api/impl/validator/utils.ts @@ -61,8 +61,9 @@ export function selectBlockProductionSource({ return ProducedBlockSource.engine; case routes.validator.BuilderSelection.Default: + case routes.validator.BuilderSelection.MaxProfit: return builderBoostFactor !== MAX_BUILDER_BOOST_FACTOR && - (builderBoostFactor === BigInt(0) || engineBlockValue >= (builderBlockValue * builderBoostFactor) / BigInt(90)) + (builderBoostFactor === BigInt(0) || engineBlockValue >= (builderBlockValue * builderBoostFactor) / BigInt(100)) ? ProducedBlockSource.engine : ProducedBlockSource.builder; diff --git a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts index 9e07a679cf81..d182cfeb537e 100644 --- a/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts +++ b/packages/beacon-node/test/unit/api/impl/validator/produceBlockV3.test.ts @@ -35,13 +35,13 @@ describe("api/validator - produceBlockV3", function () { }); const testCases: [routes.validator.BuilderSelection, number | null, number | null, number, boolean, string][] = [ - [routes.validator.BuilderSelection.Default, 1, 0, 0, false, "builder"], - [routes.validator.BuilderSelection.Default, 1, 2, 1, false, "engine"], - [routes.validator.BuilderSelection.Default, null, 0, 0, false, "engine"], - [routes.validator.BuilderSelection.Default, 0, null, 1, false, "builder"], - [routes.validator.BuilderSelection.Default, 0, null, 1, true, "builder"], - [routes.validator.BuilderSelection.Default, 1, 1, 1, true, "engine"], - [routes.validator.BuilderSelection.Default, 2, 1, 1, true, "engine"], + [routes.validator.BuilderSelection.MaxProfit, 1, 0, 0, false, "builder"], + [routes.validator.BuilderSelection.MaxProfit, 1, 2, 1, false, "engine"], + [routes.validator.BuilderSelection.MaxProfit, null, 0, 0, false, "engine"], + [routes.validator.BuilderSelection.MaxProfit, 0, null, 1, false, "builder"], + [routes.validator.BuilderSelection.MaxProfit, 0, null, 1, true, "builder"], + [routes.validator.BuilderSelection.MaxProfit, 1, 1, 1, true, "engine"], + [routes.validator.BuilderSelection.MaxProfit, 2, 1, 1, true, "engine"], [routes.validator.BuilderSelection.BuilderAlways, 1, 2, 0, false, "builder"], [routes.validator.BuilderSelection.BuilderAlways, 1, 0, 1, false, "builder"], diff --git a/packages/cli/src/cmds/validator/options.ts b/packages/cli/src/cmds/validator/options.ts index 8120bb19c805..0047cee9f8e1 100644 --- a/packages/cli/src/cmds/validator/options.ts +++ b/packages/cli/src/cmds/validator/options.ts @@ -252,7 +252,7 @@ export const validatorOptions: CliCommandOptions = { "builder.selection": { type: "string", description: - "Builder block selection strategy `default`, `builderalways`, `builderonly`, `executionalways`, or `executiononly`", + "Builder block selection strategy `default`, `maxprofit`, `builderalways`, `builderonly`, `executionalways`, or `executiononly`", defaultDescription: `${defaultOptions.builderSelection}`, group: "builder", }, @@ -260,7 +260,7 @@ export const validatorOptions: CliCommandOptions = { "builder.boostFactor": { type: "string", description: - "Percentage multiplier the block producing beacon node must apply to boost (>100) or dampen (<100) builder block value for selection against execution block. The multiplier is ignored if `--builder.selection` is set to anything other than `default`", + "Percentage multiplier the block producing beacon node must apply to boost (>100) or dampen (<100) builder block value for selection against execution block. The multiplier is ignored if `--builder.selection` is set to anything other than `default` or `maxprofit`", defaultDescription: `${defaultOptions.builderBoostFactor}`, group: "builder", }, diff --git a/packages/cli/src/util/proposerConfig.ts b/packages/cli/src/util/proposerConfig.ts index 942c5274c914..509dc8213df1 100644 --- a/packages/cli/src/util/proposerConfig.ts +++ b/packages/cli/src/util/proposerConfig.ts @@ -109,6 +109,8 @@ export function parseBuilderSelection(builderSelection?: string): routes.validat switch (builderSelection) { case "default": break; + case "maxprofit": + break; case "builderalways": break; case "builderonly": diff --git a/packages/cli/test/unit/validator/parseProposerConfig.test.ts b/packages/cli/test/unit/validator/parseProposerConfig.test.ts index 4d6a51bc2449..537799cc8630 100644 --- a/packages/cli/test/unit/validator/parseProposerConfig.test.ts +++ b/packages/cli/test/unit/validator/parseProposerConfig.test.ts @@ -26,7 +26,7 @@ const testValue = { feeRecipient: "0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb", builder: { gasLimit: 35000000, - selection: routes.validator.BuilderSelection.Default, + selection: routes.validator.BuilderSelection.BuilderAlways, boostFactor: BigInt(18446744073709551616), }, }, @@ -37,7 +37,7 @@ const testValue = { feeRecipient: "0xcccccccccccccccccccccccccccccccccccccccc", builder: { gasLimit: 30000000, - selection: routes.validator.BuilderSelection.BuilderAlways, + selection: routes.validator.BuilderSelection.Default, boostFactor: BigInt(90), }, }, diff --git a/packages/cli/test/unit/validator/proposerConfigs/validData.yaml b/packages/cli/test/unit/validator/proposerConfigs/validData.yaml index d05a55e4c669..dec7930d06b5 100644 --- a/packages/cli/test/unit/validator/proposerConfigs/validData.yaml +++ b/packages/cli/test/unit/validator/proposerConfigs/validData.yaml @@ -9,8 +9,8 @@ proposer_config: fee_recipient: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' builder: gas_limit: "35000000" - selection: "default" - boost_factor: "18446744073709551616" + selection: "maxprofit" + boost_factor: "50" default_config: graffiti: 'default graffiti' strict_fee_recipient_check: "true" @@ -18,4 +18,4 @@ default_config: builder: gas_limit: "30000000" selection: "builderalways" - boost_factor: "90" + boost_factor: "18446744073709551616" diff --git a/packages/validator/src/services/validatorStore.ts b/packages/validator/src/services/validatorStore.ts index f739fe6f9926..71639efbf474 100644 --- a/packages/validator/src/services/validatorStore.ts +++ b/packages/validator/src/services/validatorStore.ts @@ -272,6 +272,10 @@ export class ValidatorStore { (this.validators.get(pubkeyHex)?.builder || {}).boostFactor ?? this.defaultProposerConfig.builder.boostFactor; break; + case routes.validator.BuilderSelection.MaxProfit: + boostFactor = (this.validators.get(pubkeyHex)?.builder || {}).boostFactor ?? BigInt(100); + break; + case routes.validator.BuilderSelection.BuilderAlways: case routes.validator.BuilderSelection.BuilderOnly: boostFactor = MAX_BUILDER_BOOST_FACTOR; From e13afe68c4fe68a1255950a1be444909c17b2988 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Sun, 7 Apr 2024 20:18:50 +0100 Subject: [PATCH 5/8] Ignore manually set boost factor if selection is default --- docs/pages/validator-management/vc-configuration.md | 4 ++-- packages/cli/src/cmds/validator/options.ts | 2 +- .../cli/test/unit/validator/parseProposerConfig.test.ts | 4 ++-- packages/validator/src/services/validatorStore.ts | 8 ++++---- packages/validator/test/unit/services/block.test.ts | 8 ++++---- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/pages/validator-management/vc-configuration.md b/docs/pages/validator-management/vc-configuration.md index 798268fe36eb..d86edb465c1c 100644 --- a/docs/pages/validator-management/vc-configuration.md +++ b/docs/pages/validator-management/vc-configuration.md @@ -78,11 +78,11 @@ You may choose to use the `--strictFeeRecipientCheck` flag to enable a strict ch If you are running a beacon node with connected builder relays, you may use these validator configurations to signal which block (builder vs. local execution) the beacon node should produce. -With produceBlockV3 (enabled automatically after the Deneb hard fork), the `--builder.boostFactor` is a percentage multiplier the block producing beacon node must apply to boost (>100) or dampen (<100) builder block value for selection against execution block. The multiplier is ignored if `--builder.selection` is set to anything other than `default`. Even though this is set on the validator client, the calculation is requested and applied on the beacon node itself. For more information, see the [produceBlockV3 Beacon API](https://ethereum.github.io/beacon-APIs/#/ValidatorRequiredApi/produceBlockV3). +With produceBlockV3 (enabled automatically after the Deneb hard fork), the `--builder.boostFactor` is a percentage multiplier the block producing beacon node must apply to boost (>100) or dampen (<100) builder block value for selection against execution block. The multiplier is ignored if `--builder.selection` is set to anything other than `maxprofit`. Even though this is set on the validator client, the calculation is requested and applied on the beacon node itself. For more information, see the [produceBlockV3 Beacon API](https://ethereum.github.io/beacon-APIs/#/ValidatorRequiredApi/produceBlockV3). With Lodestar's `--builder.selection` validator options, you can select: -- `default`: Default setting for Lodestar set at `--builder.boostFactor=90`. This default setting will have a local block boost of ~10%. Note that this value might change in the future depending on what we think is the most appropriate value to help increase censorship resistance. +- `default`: Default setting for Lodestar set at `--builder.boostFactor=90`. This default setting will have a local block boost of ~10%. Note that this value might change in the future depending on what we think is the most appropriate value to help improve censorship resistance of Ethereum. - `maxprofit`: An alias of `--builder.boostFactor=100`, which will always choose the more profitable block. Using this option, you may customize your `--builder.boostFactor` to your preference. Examples of its usage are below. - `executionalways`: An alias of `--builder.boostFactor=0`, which will select the local execution block, unless it fails to produce due to an error or a delay in the response from the execution client. - `executiononly`: Beacon node will be requested to produce local execution block even if builder relays are configured. This option will always select the local execution block and will error if it couldn't produce one. diff --git a/packages/cli/src/cmds/validator/options.ts b/packages/cli/src/cmds/validator/options.ts index 0047cee9f8e1..5ca59280250f 100644 --- a/packages/cli/src/cmds/validator/options.ts +++ b/packages/cli/src/cmds/validator/options.ts @@ -260,7 +260,7 @@ export const validatorOptions: CliCommandOptions = { "builder.boostFactor": { type: "string", description: - "Percentage multiplier the block producing beacon node must apply to boost (>100) or dampen (<100) builder block value for selection against execution block. The multiplier is ignored if `--builder.selection` is set to anything other than `default` or `maxprofit`", + "Percentage multiplier the block producing beacon node must apply to boost (>100) or dampen (<100) builder block value for selection against execution block. The multiplier is ignored if `--builder.selection` is set to anything other than `maxprofit`", defaultDescription: `${defaultOptions.builderBoostFactor}`, group: "builder", }, diff --git a/packages/cli/test/unit/validator/parseProposerConfig.test.ts b/packages/cli/test/unit/validator/parseProposerConfig.test.ts index 537799cc8630..66220ca3329a 100644 --- a/packages/cli/test/unit/validator/parseProposerConfig.test.ts +++ b/packages/cli/test/unit/validator/parseProposerConfig.test.ts @@ -37,8 +37,8 @@ const testValue = { feeRecipient: "0xcccccccccccccccccccccccccccccccccccccccc", builder: { gasLimit: 30000000, - selection: routes.validator.BuilderSelection.Default, - boostFactor: BigInt(90), + selection: routes.validator.BuilderSelection.MaxProfit, + boostFactor: BigInt(50), }, }, }; diff --git a/packages/validator/src/services/validatorStore.ts b/packages/validator/src/services/validatorStore.ts index 71639efbf474..8bcd49d9fbe0 100644 --- a/packages/validator/src/services/validatorStore.ts +++ b/packages/validator/src/services/validatorStore.ts @@ -125,7 +125,7 @@ export const defaultOptions = { defaultGasLimit: 30_000_000, builderSelection: routes.validator.BuilderSelection.ExecutionOnly, builderAliasSelection: routes.validator.BuilderSelection.Default, - builderBoostFactor: BigInt(90), + builderBoostFactor: BigInt(100), // spec asks for gossip validation by default broadcastValidation: routes.beacon.BroadcastValidation.gossip, // should request fetching the locally produced block in blinded format @@ -268,12 +268,12 @@ export class ValidatorStore { let boostFactor; switch (selection) { case routes.validator.BuilderSelection.Default: - boostFactor = - (this.validators.get(pubkeyHex)?.builder || {}).boostFactor ?? this.defaultProposerConfig.builder.boostFactor; + boostFactor = BigInt(90); break; case routes.validator.BuilderSelection.MaxProfit: - boostFactor = (this.validators.get(pubkeyHex)?.builder || {}).boostFactor ?? BigInt(100); + boostFactor = + (this.validators.get(pubkeyHex)?.builder || {}).boostFactor ?? this.defaultProposerConfig.builder.boostFactor; break; case routes.validator.BuilderSelection.BuilderAlways: diff --git a/packages/validator/test/unit/services/block.test.ts b/packages/validator/test/unit/services/block.test.ts index 4aad0325fa34..bcfc57eb8674 100644 --- a/packages/validator/test/unit/services/block.test.ts +++ b/packages/validator/test/unit/services/block.test.ts @@ -64,8 +64,8 @@ describe("BlockDutiesService", function () { signature: signedBlock.signature, })); validatorStore.getBuilderSelectionParams.mockReturnValue({ - selection: routes.validator.BuilderSelection.Default, - boostFactor: BigInt(90), + selection: routes.validator.BuilderSelection.MaxProfit, + boostFactor: BigInt(100), }); validatorStore.getGraffiti.mockReturnValue("aaaa"); validatorStore.getFeeRecipient.mockReturnValue("0x00"); @@ -107,10 +107,10 @@ describe("BlockDutiesService", function () { false, { feeRecipient: "0x00", - builderSelection: routes.validator.BuilderSelection.Default, + builderSelection: routes.validator.BuilderSelection.MaxProfit, strictFeeRecipientCheck: false, blindedLocal: false, - builderBoostFactor: BigInt(90), + builderBoostFactor: BigInt(100), }, ]); }); From bcdc830550cc0fe9b993a5665a3a6be60e44ffdc Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Sun, 7 Apr 2024 20:36:31 +0100 Subject: [PATCH 6/8] Add ref to twitter thread --- packages/validator/src/services/validatorStore.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/validator/src/services/validatorStore.ts b/packages/validator/src/services/validatorStore.ts index 8bcd49d9fbe0..adf887e93d33 100644 --- a/packages/validator/src/services/validatorStore.ts +++ b/packages/validator/src/services/validatorStore.ts @@ -268,6 +268,8 @@ export class ValidatorStore { let boostFactor; switch (selection) { case routes.validator.BuilderSelection.Default: + // Default value slightly favors local block to improve censorship resistance + // The people have spoken and so it shall be https://x.com/lodestar_eth/status/1772679499928191044 boostFactor = BigInt(90); break; From 0a4da17d8a50fd80d6d6f8159b4c8891b9b4ea7d Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Sun, 7 Apr 2024 21:06:21 +0100 Subject: [PATCH 7/8] Fix parse proposer config test --- .../test/unit/validator/proposerConfigs/validData.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/cli/test/unit/validator/proposerConfigs/validData.yaml b/packages/cli/test/unit/validator/proposerConfigs/validData.yaml index dec7930d06b5..71dabb9d900d 100644 --- a/packages/cli/test/unit/validator/proposerConfigs/validData.yaml +++ b/packages/cli/test/unit/validator/proposerConfigs/validData.yaml @@ -9,13 +9,13 @@ proposer_config: fee_recipient: '0xbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' builder: gas_limit: "35000000" - selection: "maxprofit" - boost_factor: "50" + selection: "builderalways" + boost_factor: "18446744073709551616" default_config: graffiti: 'default graffiti' strict_fee_recipient_check: "true" fee_recipient: '0xcccccccccccccccccccccccccccccccccccccccc' builder: gas_limit: "30000000" - selection: "builderalways" - boost_factor: "18446744073709551616" + selection: "maxprofit" + boost_factor: "50" From 1a5612e510eb89e1b5fa8706b491ca8fdbad10c2 Mon Sep 17 00:00:00 2001 From: Nico Flaig Date: Sun, 7 Apr 2024 21:12:14 +0100 Subject: [PATCH 8/8] Update comment --- packages/validator/src/services/validatorStore.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/validator/src/services/validatorStore.ts b/packages/validator/src/services/validatorStore.ts index adf887e93d33..0c3c0b33cea8 100644 --- a/packages/validator/src/services/validatorStore.ts +++ b/packages/validator/src/services/validatorStore.ts @@ -268,7 +268,7 @@ export class ValidatorStore { let boostFactor; switch (selection) { case routes.validator.BuilderSelection.Default: - // Default value slightly favors local block to improve censorship resistance + // Default value slightly favors local block to improve censorship resistance of Ethereum // The people have spoken and so it shall be https://x.com/lodestar_eth/status/1772679499928191044 boostFactor = BigInt(90); break;