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: allow configuring broadcast validation on validator for proposals #6151

Merged
merged 4 commits into from
Dec 2, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
16 changes: 16 additions & 0 deletions packages/cli/src/cmds/validator/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ export async function validatorHandler(args: IValidatorCliArgs & GlobalArgs): Pr
valProposerConfig,
distributed: args.distributed,
useProduceBlockV3: args.useProduceBlockV3,
broadcastValidation: parseBroadcastValidation(args.broadcastValidation),
},
metrics
);
Expand Down Expand Up @@ -268,3 +269,18 @@ function parseBuilderSelection(builderSelection?: string): routes.validator.Buil
}
return builderSelection as routes.validator.BuilderSelection;
}

function parseBroadcastValidation(broadcastValidation?: string): routes.beacon.BroadcastValidation | undefined {
if (broadcastValidation) {
switch (broadcastValidation) {
case "gossip":
case "consensus":
case "consensus_and_equivocation":
break;
default:
throw Error("Invalid input for broadcastValidation, check help");
}
}

return broadcastValidation as routes.beacon.BroadcastValidation;
}
7 changes: 7 additions & 0 deletions packages/cli/src/cmds/validator/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export type IValidatorCliArgs = AccountValidatorArgs &
"builder.selection"?: string;

useProduceBlockV3?: boolean;
broadcastValidation?: string;

importKeystores?: string[];
importKeystoresPassword?: string;
Expand Down Expand Up @@ -250,6 +251,12 @@ export const validatorOptions: CliCommandOptions<IValidatorCliArgs> = {
defaultDescription: `${defaultOptions.useProduceBlockV3}`,
},

broadcastValidation: {
type: "string",
description: "Validations to be run by beacon node for the signed block prior to publishing",
defaultDescription: `${defaultOptions.broadcastValidation}`,
},

importKeystores: {
alias: ["keystore"], // Backwards compatibility with old `validator import` cmdx
description: "Path(s) to a directory or single file path to validator keystores, i.e. Launchpad validators",
Expand Down
29 changes: 19 additions & 10 deletions packages/validator/src/services/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class BlockProposingService {
private readonly clock: IClock,
private readonly validatorStore: ValidatorStore,
private readonly metrics: Metrics | null,
private readonly opts: {useProduceBlockV3: boolean}
private readonly opts: {useProduceBlockV3: boolean; broadcastValidation: routes.beacon.BroadcastValidation}
) {
this.dutiesService = new BlockDutiesService(
config,
Expand Down Expand Up @@ -158,7 +158,9 @@ export class BlockProposingService {
signedBlobs = undefined;
}

await this.publishBlockWrapper(signedBlock, signedBlobs).catch((e: Error) => {
await this.publishBlockWrapper(signedBlock, signedBlobs, {
broadcastValidation: this.opts.broadcastValidation,
}).catch((e: Error) => {
this.metrics?.blockProposingErrors.inc({error: "publish"});
throw extendError(e, "Failed to publish block");
});
Expand All @@ -172,22 +174,29 @@ export class BlockProposingService {

private publishBlockWrapper = async (
signedBlock: allForks.FullOrBlindedSignedBeaconBlock,
signedBlobSidecars?: allForks.FullOrBlindedSignedBlobSidecar[]
signedBlobSidecars?: allForks.FullOrBlindedSignedBlobSidecar[],
opts: {broadcastValidation?: routes.beacon.BroadcastValidation} = {}
): Promise<void> => {
if (signedBlobSidecars === undefined) {
ApiError.assert(
isBlindedBeaconBlock(signedBlock.message)
? await this.api.beacon.publishBlindedBlock(signedBlock as allForks.SignedBlindedBeaconBlock)
: await this.api.beacon.publishBlockV2(signedBlock as allForks.SignedBeaconBlock)
? await this.api.beacon.publishBlindedBlockV2(signedBlock as allForks.SignedBlindedBeaconBlock, opts)
: await this.api.beacon.publishBlockV2(signedBlock as allForks.SignedBeaconBlock, opts)
);
} else {
ApiError.assert(
isBlindedBeaconBlock(signedBlock.message)
? await this.api.beacon.publishBlindedBlock({
signedBlindedBlock: signedBlock,
signedBlindedBlobSidecars: signedBlobSidecars,
} as allForks.SignedBlindedBlockContents)
: await this.api.beacon.publishBlockV2({signedBlock, signedBlobSidecars} as allForks.SignedBlockContents)
? await this.api.beacon.publishBlindedBlockV2(
{
signedBlindedBlock: signedBlock,
signedBlindedBlobSidecars: signedBlobSidecars,
} as allForks.SignedBlindedBlockContents,
opts
)
: await this.api.beacon.publishBlockV2(
{signedBlock, signedBlobSidecars} as allForks.SignedBlockContents,
opts
)
);
}
};
Expand Down
2 changes: 2 additions & 0 deletions packages/validator/src/services/validatorStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,8 @@ export const defaultOptions = {
builderAliasSelection: routes.validator.BuilderSelection.MaxProfit,
// turn it off by default, turn it back on once other clients support v3 api
useProduceBlockV3: false,
// spec asks for gossip validation by default
broadcastValidation: routes.beacon.BroadcastValidation.gossip,
};

/**
Expand Down
10 changes: 9 additions & 1 deletion packages/validator/src/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export type ValidatorOptions = {
valProposerConfig?: ValidatorProposerConfig;
distributed?: boolean;
useProduceBlockV3?: boolean;
broadcastValidation?: routes.beacon.BroadcastValidation;
};

// TODO: Extend the timeout, and let it be customizable
Expand Down Expand Up @@ -208,6 +209,7 @@ export class Validator {

const blockProposingService = new BlockProposingService(config, loggerVc, api, clock, validatorStore, metrics, {
useProduceBlockV3: opts.useProduceBlockV3 ?? defaultOptions.useProduceBlockV3,
broadcastValidation: opts.broadcastValidation ?? defaultOptions.broadcastValidation,
});

const attestationService = new AttestationService(
Expand Down Expand Up @@ -285,13 +287,19 @@ export class Validator {
await assertEqualGenesis(opts, genesis);
logger.info("Verified connected beacon node and validator have the same genesisValidatorRoot");

const {useProduceBlockV3 = defaultOptions.useProduceBlockV3, valProposerConfig} = opts;
const {
useProduceBlockV3 = defaultOptions.useProduceBlockV3,
broadcastValidation = defaultOptions.broadcastValidation,
valProposerConfig,
} = opts;
const defaultBuilderSelection =
valProposerConfig?.defaultConfig.builder?.selection ?? defaultOptions.builderSelection;
const strictFeeRecipientCheck = valProposerConfig?.defaultConfig.strictFeeRecipientCheck ?? false;
const suggestedFeeRecipient = valProposerConfig?.defaultConfig.feeRecipient ?? defaultOptions.suggestedFeeRecipient;

logger.info("Initializing validator", {
useProduceBlockV3,
broadcastValidation,
defaultBuilderSelection,
suggestedFeeRecipient,
strictFeeRecipientCheck,
Expand Down
1 change: 1 addition & 0 deletions packages/validator/test/unit/services/block.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ describe("BlockDutiesService", function () {
// use produceBlockV3
const blockService = new BlockProposingService(config, loggerVc, api, clock, validatorStore, null, {
useProduceBlockV3: true,
broadcastValidation: "consensus",
});

const signedBlock = ssz.phase0.SignedBeaconBlock.defaultValue();
Expand Down
Loading