diff --git a/packages/beacon-node/src/api/impl/validator/index.ts b/packages/beacon-node/src/api/impl/validator/index.ts index 1bf3c4f6f65..b470a58aa19 100644 --- a/packages/beacon-node/src/api/impl/validator/index.ts +++ b/packages/beacon-node/src/api/impl/validator/index.ts @@ -70,6 +70,7 @@ import {validateGossipFnRetryUnknownRoot} from "../../../network/processor/gossi import {SCHEDULER_LOOKAHEAD_FACTOR} from "../../../chain/prepareNextSlot.js"; import {ChainEvent, CheckpointHex, CommonBlockBody} from "../../../chain/index.js"; import {ApiOptions} from "../../options.js"; +import {NoBidReceived} from "../../../execution/builder/http.js"; import {getLodestarClientVersion} from "../../../util/metadata.js"; import {computeSubnetForCommitteesAtSlot, getPubkeysForIndices, selectBlockProductionSource} from "./utils.js"; @@ -661,14 +662,21 @@ export function getValidatorApi( } if (builder.status === "rejected" && isBuilderEnabled) { - logger.warn( - "Builder failed to produce the block", - { + if (builder.reason instanceof NoBidReceived) { + logger.info("Builder did not provide a bid", { ...loggerContext, durationMs: builder.durationMs, - }, - builder.reason - ); + }); + } else { + logger.warn( + "Builder failed to produce the block", + { + ...loggerContext, + durationMs: builder.durationMs, + }, + builder.reason + ); + } } if (builder.status === "rejected" && engine.status === "rejected") { diff --git a/packages/beacon-node/src/execution/builder/http.ts b/packages/beacon-node/src/execution/builder/http.ts index 13f797d1c69..0a6018e5e23 100644 --- a/packages/beacon-node/src/execution/builder/http.ts +++ b/packages/beacon-node/src/execution/builder/http.ts @@ -39,6 +39,17 @@ export const defaultExecutionBuilderHttpOpts: ExecutionBuilderHttpOpts = { timeout: 12000, }; +/** + * Expected error if builder does not provide a bid. Most of the time, this + * is due to `min-bid` setting on the mev-boost side but in rare cases could + * also happen if there are no bids from any of the connected relayers. + */ +export class NoBidReceived extends Error { + constructor() { + super("No bid received"); + } +} + /** * Duration given to the builder to provide a `SignedBuilderBid` before the deadline * is reached, aborting the external builder flow in favor of the local build process. @@ -138,7 +149,7 @@ export class ExecutionBuilderHttp implements IExecutionBuilder { const signedBuilderBid = res.value(); if (!signedBuilderBid) { - throw Error("No bid received"); + throw new NoBidReceived(); } this.sszSupported = res.wireFormat() === WireFormat.ssz;