Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
3983cd2
feat: implement gloas builder api
nflaig Aug 15, 2026
adc7843
fix(api): preserve request content length
nflaig Aug 15, 2026
65616ad
Revert "fix(api): preserve request content length"
nflaig Aug 15, 2026
4270c6f
docs: fix builder option spellcheck
nflaig Aug 15, 2026
67282d8
docs: preserve builder payment terminology
nflaig Aug 15, 2026
630636e
include execution payment in payload value
nflaig Aug 16, 2026
3c8d674
review
nflaig Aug 16, 2026
95bd6cc
prefer max boost builder bids
nflaig Aug 16, 2026
05de82d
handle invalid builder urls per entry
nflaig Aug 16, 2026
a581cd1
log invalid builder urls
nflaig Aug 16, 2026
c80b4ee
enforce builder url byte limit
nflaig Aug 16, 2026
6f456e0
validate builder request headers
nflaig Aug 16, 2026
c8fc9e7
honor per-key builder boost post-gloas
nflaig Aug 16, 2026
e76769a
validate builder api bids against proposer preferences
nflaig Aug 16, 2026
c0f3b54
support auth data in builder urls
nflaig Aug 17, 2026
4182e2b
validate bid fee recipient against proposer preferences only
nflaig Aug 17, 2026
787c408
Merge branch 'unstable' into nflaig/builder-api-2
nflaig Aug 17, 2026
b6677e3
update wordlist
nflaig Aug 17, 2026
9b69725
Merge branch 'unstable' into nflaig/builder-api-2
nflaig Aug 17, 2026
d173c24
Merge branch 'unstable' into nflaig/builder-api-2
nflaig Aug 18, 2026
0d34409
read builder url header when publishing a block
nflaig Aug 18, 2026
d0537e7
publish already known block succeeds without republishing it
nflaig Aug 18, 2026
2c46bf2
only forward signed block to builder url echoed by validator client
nflaig Aug 18, 2026
64344b5
log selected bid source and details when producing a block
nflaig Aug 18, 2026
1584302
wording
nflaig Aug 18, 2026
82438dc
naming nits
nflaig Aug 18, 2026
05f03f9
rename keymanager builders endpoints to builder config
nflaig Aug 18, 2026
286d828
update keymanager api spec tests to v1.2.0-alpha.0
nflaig Aug 19, 2026
9c31ef5
validate builder configuration uint64 values
nflaig Aug 19, 2026
c88dcb4
return 403 when proposer configuration writes are disabled
nflaig Aug 19, 2026
fe3a6b0
Merge branch 'unstable' into nflaig/builder-api-2
nflaig Aug 19, 2026
caf48fc
serialize builder config in proposer response
nflaig Aug 22, 2026
64eaaa1
Merge remote-tracking branch 'origin/unstable' into nflaig/builder-api-2
nflaig Aug 22, 2026
8f6b649
rename request auth to builder request auth
nflaig Aug 22, 2026
24eb511
rename auth data constants to builder auth data
nflaig Aug 22, 2026
cf54405
use builder constants for keymanager config bounds
nflaig Aug 22, 2026
e05cd06
count builder bid execution payment up to the entry cap
nflaig Aug 22, 2026
3bccfac
preserve precision when comparing boosted bids
nflaig Aug 23, 2026
2a5c93a
call it boostedValue
nflaig Aug 23, 2026
2d557dd
fix block publication result indexing
nflaig Aug 23, 2026
74f6be8
read builder URL from response header
nflaig Aug 23, 2026
d75428a
verify builder auth before creating clients
nflaig Aug 23, 2026
d7cef5e
disable redirects when forwarding blocks to builders
nflaig Aug 23, 2026
877bfd5
no retries
nflaig Aug 23, 2026
3d2df07
validate builder URLs before use
nflaig Aug 23, 2026
acc26a3
reject empty builder request auth data
nflaig Aug 23, 2026
574496b
Merge branch 'unstable' into nflaig/builder-api-2
nflaig Aug 24, 2026
f93c268
Merge branch 'unstable' into nflaig/builder-api-2
nflaig Aug 26, 2026
5d4a13c
saturate builder bid values before weighting
nflaig Aug 26, 2026
f56ba27
align builder documentation with bid selection behavior
nflaig Aug 26, 2026
23a1a8e
update min bid description
nflaig Aug 26, 2026
4f25c45
update wordlist
nflaig Aug 26, 2026
05e8cac
move builder api bid validation next to the builder client
nflaig Aug 26, 2026
265fc04
builder api client owns the bid request timeout
nflaig Aug 26, 2026
9f9e023
apply configured builder timeout to builder api requests
nflaig Aug 26, 2026
37e81ba
select p2p bid after the builder bid deadline
nflaig Aug 26, 2026
36d2b9f
forward publish request body bytes to the builder
nflaig Aug 26, 2026
6fc5f06
address builder config review comments
nflaig Aug 26, 2026
e9bc9d8
clarify gloas builder settings
nflaig Aug 26, 2026
0343ca6
consolidate upfront builder bid condition
nflaig Aug 26, 2026
45d0661
track when builder api bids are received
nflaig Aug 26, 2026
17f4181
track when p2p bids are received
nflaig Aug 26, 2026
9bbcf99
log local block value in gloas block selection
nflaig Aug 26, 2026
123a598
honor censorship override for late received bids
nflaig Aug 26, 2026
b2b496e
log builder and selection bid totals
nflaig Aug 26, 2026
1d0fc63
log successful signed block submission to builder
nflaig Aug 26, 2026
0c00b31
floor p2p bid received time
nflaig Aug 27, 2026
6d01676
print bid values in ETH
nflaig Aug 27, 2026
16d4f48
rename bid block promise and result
nflaig Aug 27, 2026
6a5d5db
add prettyGweiToEth helper
nflaig Aug 27, 2026
340801b
cover builder api bids under active circuit breaker
nflaig Aug 27, 2026
ad70776
Merge branch 'unstable' into nflaig/builder-api-2
nflaig Aug 27, 2026
fd5bdce
Merge branch 'unstable' into nflaig/builder-api-2
nflaig Aug 27, 2026
a8e2182
reword builder forward comments
nflaig Aug 27, 2026
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
5 changes: 5 additions & 0 deletions .wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ APIs
Andreas
Antonopoulos
AssemblyScript
Auth
BLS
BeaconNode
Besu
Expand Down Expand Up @@ -51,6 +52,7 @@ Golang
Gossipsub
Grafana
Grandine
Gwei
HTTPS
HackMD
Hashicorp
Expand Down Expand Up @@ -119,6 +121,7 @@ addons
api
args
async
auth
backfill
beaconcha
blockRoot
Expand Down Expand Up @@ -246,8 +249,10 @@ tcp
testnet
testnets
todo
trustless
typesafe
udp
uint
unpkg
util
utils
Expand Down
18 changes: 18 additions & 0 deletions docs/pages/run/validator-management/proposer-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ proposer_config:
gas_limit: "45000000"
selection: "maxprofit"
boost_factor: "100"
min_bid: "10000000"
max_execution_payment: "0"
default_config:
graffiti: "default graffiti"
strict_fee_recipient_check: true
Expand All @@ -36,6 +38,22 @@ default_config:
boost_factor: "90"
```

Starting with Gloas, the builder section additionally supports `min_bid` (floor in Gwei on the counted total payment from a builder bid) and `max_execution_payment` (ceiling in Gwei on the execution layer payment counted toward a builder bid, values above `0` require `--allowDangerousTrustedPayments`).

Post-Gloas, an explicitly configured per-validator `boost_factor` takes precedence over `selection`.

The builder section also supports a `builders` list with the same per-builder entries as the keymanager builder config API. Each entry has a required `url` and optional `auth_data`, `builder_pubkeys`, `max_execution_payment`, `min_bid` and `builder_boost_factor`. Multiple entries may share a `url` only if they have distinct `auth_data`. Per-key entries replace the builders the validator client is configured with; setting both `--builder.urls` and `builders` in `default_config` is an error.

```yaml
builder:
min_bid: "10000000"
builders:
- url: "https://builder-a.example.com"
- url: "https://builder-b.example.com"
auth_data: "0x0123"
builder_boost_factor: "200"
```

### Enable Proposer Configuration

After you have configured your proposer configuration YAML file, you can start Lodestar with an additional CLI flag option pointing to the file: `--proposerSettingsFile /path/to/proposer_config.yaml`.
Expand Down
11 changes: 11 additions & 0 deletions docs/pages/run/validator-management/vc-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,17 @@ Example 2: Setting a `--builder.boostFactor=0` will always prefer the local exec

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.

### Configure external builders (Gloas)

Starting with Gloas, external builders are configured on the validator client and the beacon node requests bids on its behalf. Use [`--builder.urls`](./validator-cli.md#--builderurls) to name the builders to request bids from. Viable bids received over p2p are considered alongside them unless the builder circuit breaker is active, governed by the same selection settings. These are additional settings, the pre-Gloas builder flags still apply.

Every bid request is authenticated with data the builder expects, by default the UTF-8 bytes of the builder URL exactly as configured. If a builder requires different auth data agreed out of band, append it as a hex fragment to its URL, e.g. `--builder.urls https://builder.example.com#0x0123`. The fragment is stripped before the URL is used and never sent to the builder. Auth data that must stay secret is better kept in the [proposer configuration file](./proposer-config.md), as command line arguments are visible to other processes.

- [`--builder.minBid`](./validator-cli.md#--builderminbid): minimum counted total payment in Gwei accepted from a builder bid. The total is `value + min(execution_payment, max_execution_payment)`, capped at max uint64. Bids below the floor are discarded.
- [`--builder.maxExecutionPayment`](./validator-cli.md#--buildermaxexecutionpayment): maximum execution layer payment in Gwei counted from a builder bid, any payment above it adds nothing to the bid when comparing it with other bids. The default of `0` only counts trustless payments backed by the builder's staked collateral. An execution layer payment is only a promise by the builder to pay as part of the block, so values above `0` require the explicit [`--allowDangerousTrustedPayments`](./validator-cli.md#--allowdangeroustrustedpayments) opt-in.

Builders can also be configured per validator key with per-builder overrides via the [builder config keymanager endpoint](https://ethereum.github.io/keymanager-APIs/#/Builder%20Config) or the [proposer configuration file](./proposer-config.md).

### Submit a validator deposit

Please use the official Ethereum Launchpad to perform your deposits. Ensure your deposits are sent to the proper beacon chain deposit address on the correct network.
Expand Down
22 changes: 18 additions & 4 deletions packages/api/src/beacon/routes/beacon/block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,18 @@ export type Endpoints = {
{
signedBlockContents: SignedBlockContents;
broadcastValidation?: BroadcastValidation;
/**
* The url of the winning builder as returned by `produceBlockV4`. The beacon node forwards
* the signed block to this builder so it can help disseminate the block and learn that
* its bid won without waiting for gossip.
*/
builderUrl?: string;
},
{
body: unknown;
headers: {[MetaHeader.Version]: string; [MetaHeader.BuilderUrl]?: string};
query: {broadcast_validation?: string};
},
{body: unknown; headers: {[MetaHeader.Version]: string}; query: {broadcast_validation?: string}},
EmptyResponseData,
EmptyMeta
>;
Expand Down Expand Up @@ -345,7 +355,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
url: "/eth/v2/beacon/blocks",
method: "POST",
req: {
writeReqJson: ({signedBlockContents, broadcastValidation}) => {
writeReqJson: ({signedBlockContents, broadcastValidation, builderUrl}) => {
const slot = signedBlockContents.signedBlock.message.slot;
const fork = config.getForkName(slot);
return {
Expand All @@ -359,6 +369,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
),
headers: {
[MetaHeader.Version]: fork,
...(builderUrl !== undefined ? {[MetaHeader.BuilderUrl]: builderUrl} : {}),
},
query: {broadcast_validation: broadcastValidation},
};
Expand All @@ -371,9 +382,10 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
? sszTypesFor(forkName).SignedBlockContents.fromJson(body)
: {signedBlock: ssz[forkName].SignedBeaconBlock.fromJson(body)},
broadcastValidation: query.broadcast_validation as BroadcastValidation,
builderUrl: fromHeaders(headers, MetaHeader.BuilderUrl, false),
};
},
writeReqSsz: ({signedBlockContents, broadcastValidation}) => {
writeReqSsz: ({signedBlockContents, broadcastValidation, builderUrl}) => {
const slot = signedBlockContents.signedBlock.message.slot;
const fork = config.getForkName(slot);

Expand All @@ -388,6 +400,7 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
),
headers: {
[MetaHeader.Version]: fork,
...(builderUrl !== undefined ? {[MetaHeader.BuilderUrl]: builderUrl} : {}),
},
query: {broadcast_validation: broadcastValidation},
};
Expand All @@ -400,12 +413,13 @@ export function getDefinitions(config: ChainForkConfig): RouteDefinitions<Endpoi
? sszTypesFor(forkName).SignedBlockContents.deserialize(body)
: {signedBlock: ssz[forkName].SignedBeaconBlock.deserialize(body)},
broadcastValidation: query.broadcast_validation as BroadcastValidation,
builderUrl: fromHeaders(headers, MetaHeader.BuilderUrl, false),
};
},
schema: {
body: Schema.Object,
query: {broadcast_validation: Schema.String},
headers: {[MetaHeader.Version]: Schema.String},
headers: {[MetaHeader.Version]: Schema.String, [MetaHeader.BuilderUrl]: Schema.String},
},
},
resp: EmptyResponseCodec,
Expand Down
Loading
Loading