Skip to content

Conversation

@faheelsattar
Copy link
Contributor

πŸ“ Summary

  • lays ground work for epbs builder server.
  • get_bids endpoint for retrieving bids for the proposer

πŸ’‘ Motivation and Context


βœ… I have completed the following steps:

  • Run make lint
  • Run make test
  • Added tests (if applicable)

@ZanCorDX ZanCorDX marked this pull request as draft January 13, 2026 20:02
@ZanCorDX
Copy link
Collaborator

I would be great to normalize to use either get_bid or get_execution_payload_bid (I like this most since it matched the protocol)

@ZanCorDX
Copy link
Collaborator

ZanCorDX commented Jan 13, 2026

eyre::Result should only be used at top level eg: reading the cfg before starting), I commented some but there might be more.


/// Fetch genesis data from the beacon chain.
/// Returns the genesis time, genesis validators root, and genesis fork version.
pub async fn get_genesis(&self) -> eyre::Result<GenesisData> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't use eyre::Result

async fn generate_bid(
&self,
params: &GetBidParams,
) -> eyre::Result<Option<SignedExecutionPayloadBid>>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't use eyre::Result

/// The `validator_id` can be either:
/// - A hex encoded BLS public key
/// - A validator index as a string
pub async fn get_validator(&self, validator_id: &str) -> eyre::Result<ValidatorData> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't make this pub. Make 2 other funcs (calling this one), one taking BlsPublicKey and the other taking int.

///
/// Implementations can use these notifications to:
/// - Generate EPBS bids
pub trait BlockObserver: Send + Sync + std::fmt::Debug {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we have to think if we can unify with BlockBuildingSink.

let relay_set = relay_set.clone();
let last_finalize_command = last_finalize_command.clone();
let block_sink = block_sink.clone();
let block_observer = self.block_observer.clone();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we bid to serveral relays with specific bids so hooking the block_observer makes no sense since in ePBS there is no relay concept.
The whole bidding core will have to change.

let state_clone = self.state.clone();
let cancel_clone = cancel.clone();
tokio::spawn(async move {
let mut interval = tokio::time::interval(Duration::from_secs(60));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to a constant and justify/explain the value in a comment.

Comment on lines +155 to +165
if should_update {
info!(
slot,
?parent_hash,
block_hash = ?block.sealed_block.hash(),
bid_value = %block.trace.bid_value,
cached_blocks = best_blocks.len() + 1,
"EPBS: Cached new best block for slot"
);
best_blocks.insert(key, cached);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you put this in the match above?

Comment on lines +150 to +165
let should_update = match best_blocks.get(&key) {
Some(existing) => block.trace.bid_value > existing.block.trace.bid_value,
None => true,
};

if should_update {
info!(
slot,
?parent_hash,
block_hash = ?block.sealed_block.hash(),
bid_value = %block.trace.bid_value,
cached_blocks = best_blocks.len() + 1,
"EPBS: Cached new best block for slot"
);
best_blocks.insert(key, cached);
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should always use the last bid, not the best since bids can go down because of a cancellation and we should honor that.

/// EPBS Builder API server port.
#[serde(default = "default_epbs_server_port")]
pub epbs_server_port: u16,
/// Secret key for the builder's validator (for signing EPBS bids).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the relay key as default makes no sense. This should be mandatory.

/// GET /eth/v1/builder/execution_payload_bid/{slot}/{parent_hash}/{parent_root}/{proposer_index}
///
/// returns a SignedExecutionPayloadBid for the given slot.
pub async fn get_bid_handler(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we check SignedBidRequestAuth in the body?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants