builder_api: add Gloas Staked Builder API client - #819
Conversation
|
cc @hangleang |
Thanks for the contributions, I was occupy by other urgent tasks so I won't be able to review within this week or two |
|
FYI: clients have agreed to implement the spec PR ethereum/builder-specs#165 even it still unmerged (see https://forkcast.org/calls/acdt/090/?breakout=cl#t=70 on decisions), could you update the PR accordingly? |
|
@hangleang Updated with ethereum/builder-specs#165 as requested:
Tests updated; |
| .builder_submit_builder_preferences_times | ||
| .start_timer() | ||
| }); | ||
|
|
There was a problem hiding this comment.
why won't check slot like get_execution_payload_bid does?
There was a problem hiding this comment.
Done in e5ba389
auth.message.slot is treated as the proposal slot and rejected if it has already passed.
| }) | ||
| } | ||
|
|
||
| async fn parse_gloas_response<T: DeserializeOwned + SszRead<Phase>>( |
There was a problem hiding this comment.
this function almost identical to parse_response below, can we reuse the function?
There was a problem hiding this comment.
Done in 0e01a9c. JSON/SSZ decoding was extracted into decode_ssz_or_json_response and reused. parse_response remains a wrapper for legacy builder responses because it also updates the separate supports_block_ssz cache.
| let request = self | ||
| .client | ||
| .post(url.into_url()) | ||
| .timeout(remaining_time) |
There was a problem hiding this comment.
this might be the wrong deadline for this endpoint. I guess this is copied from post_blinded_block pre-Gloas path which proposer require builder to response before attestation deadline, so it has the payload to construct and publish beacon block before deadline. but now builder is responsible to publish their payload, and this endpoint is just notify them to publish payload envelope by themselves through beacon node
There was a problem hiding this comment.
Fixed in a5867d4. The signed-block notification now uses the fixed request timeout instead of the attestation-interval deadline.
| let request = self | ||
| .client | ||
| .post(url.into_url()) | ||
| .timeout(REQUEST_TIMEOUT) |
There was a problem hiding this comment.
the interval timeout should be put on this endpoint instead, as now proposer request bid from builder to choose on proposal hot path
There was a problem hiding this comment.
Done in 25b73d3
The bid request is bounded by the remaining time before the next interval, capped at one second.
| .header(DATE_MS_HEADER, format!("{date_ms}")) | ||
| .header( | ||
| X_TIMEOUT_MS_HEADER, | ||
| format!("{}", REQUEST_TIMEOUT.as_millis()), |
There was a problem hiding this comment.
Done in same 25b73d3. X-Timeout-Ms and the reqwest timeout use the same computed millisecond value.
| "/eth/v1/builder/execution_payload_bid/{slot}/{parent_hash:?}/{parent_root:?}/{pubkey:?}" | ||
| ))?; | ||
|
|
||
| let use_json = self.config.builder_api_format == BuilderApiFormat::Json; |
There was a problem hiding this comment.
should have fallback to json format if builder doesn't support SSZ, same as other two endpoints
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
…inguish skipped bids from 204 Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
42285f3 to
0e01a9c
Compare
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
Signed-off-by: Nikhil Sharma <nikhilsharma230303@gmail.com>
|
@hangleang, I have resolved the reviews. Let me know if there are any issues or improvements required. |
Part of #769. Client side of the Gloas Staked Builder API (ethereum/builder-specs#138), aligned with the clarifications in ethereum/builder-specs#165 (ACDT CL guidance: implement before merge).
Changes
DOMAIN_REQUEST_AUTH(0x0B000001) and the Gloas builder containers (RequestAuthV1,SignedRequestAuthV1,BuilderPreferencesV1,BuilderPreferencesRequestV1) tobuilder_apiget_execution_payload_bid— POST/eth/v1/builder/execution_payload_bid/{slot}/{parent_hash}/{parent_root}/{proposer_pubkey}with a requiredSignedRequestAuthV1body (JSON or SSZ), requiredDate-MillisecondsandX-Timeout-Msheaders (timeout matches the reqwest timeout), and alwaysEth-Consensus-Version. 200 returns a bid, 204 means no bid. Gloas+ only; rejects earlier phases andauth.message.slot≠ pathslotbefore the request.submit_builder_preferences— POST/eth/v1/builder/builder_preferences/{validator_pubkey}withBuilderPreferencesRequestV1(SSZ field order:auththenpreferences), expects 202submit_signed_beacon_block— POST/eth/v1/builder/beacon_blocks, expects 202RequestAuthV1(SignForAllForks, genesis fork + zero genesis validators root, per speccompute_domain(DOMAIN_REQUEST_AUTH))Notes
state.builders()bybuilder_index).submitSignedBeaconBlockthe proposer must still gossip the beacon block; the builder publishes the payload envelope.V1suffix; Rust keeps*V1to match otherbuilder_apicontainers. Wire format follows Clarifications on builder spec ethereum/builder-specs#165.Tests
cargo test -p builder_api --features blst— httpmock coverage for all three endpoints (200/204/400/500, required auth body + timing / consensus-version headers, auth slot mismatch, non-2xx handling, pre-Gloas rejection),DOMAIN_REQUEST_AUTHsigning-root check, and SSZ field-order lock forBuilderPreferencesRequestV1