use crate::task_spawner::{Priority, TaskSpawner}; use crate::utils::{ ChainFilter, EthV1Filter, NetworkTxFilter, ResponseFilter, TaskSpawnerFilter, publish_pubsub_message, }; use beacon_chain::{BeaconChain, BeaconChainTypes}; use bytes::Bytes; use lighthouse_network::PubsubMessage; use network::NetworkMessage; use ssz::Decode; use std::sync::Arc; use tokio::sync::mpsc::UnboundedSender; use tracing::{debug, warn}; use types::SignedExecutionPayloadBid; use warp::{ Filter, Rejection, reply::{Reply, Response}, }; // POST /eth/v1/beacon/execution_payload_bids (SSZ) pub(crate) fn post_beacon_execution_payload_bids_ssz( eth_v1: EthV1Filter, task_spawner_filter: TaskSpawnerFilter, chain_filter: ChainFilter, network_tx_filter: NetworkTxFilter, ) -> ResponseFilter { eth_v1 .and(warp::path("beacon")) .and(warp::path("execution_payload_bids")) .and(warp::path::end()) .and(warp::body::bytes()) .and(task_spawner_filter) .and(chain_filter) .and(network_tx_filter) .then( |body_bytes: Bytes, task_spawner: TaskSpawner, chain: Arc>, network_tx: UnboundedSender>| { task_spawner.blocking_response_task(Priority::P0, move || { let bid = SignedExecutionPayloadBid::::from_ssz_bytes(&body_bytes) .map_err(|e| { warp_utils::reject::custom_bad_request(format!("invalid SSZ: {e:?}")) })?; publish_execution_payload_bid(bid, &chain, &network_tx) }) }, ) .boxed() } // POST /eth/v1/beacon/execution_payload_bids pub(crate) fn post_beacon_execution_payload_bids( eth_v1: EthV1Filter, task_spawner_filter: TaskSpawnerFilter, chain_filter: ChainFilter, network_tx_filter: NetworkTxFilter, ) -> ResponseFilter { eth_v1 .and(warp::path("beacon")) .and(warp::path("execution_payload_bids")) .and(warp::path::end()) .and(warp::body::json()) .and(task_spawner_filter) .and(chain_filter) .and(network_tx_filter) .then( |bid: SignedExecutionPayloadBid, task_spawner: TaskSpawner, chain: Arc>, network_tx: UnboundedSender>| { task_spawner.blocking_response_task(Priority::P0, move || { publish_execution_payload_bid(bid, &chain, &network_tx) }) }, ) .boxed() } pub fn publish_execution_payload_bid( bid: SignedExecutionPayloadBid, chain: &Arc>, network_tx: &UnboundedSender>, ) -> Result { let slot = bid.slot(); let builder_index = bid.message.builder_index; if !chain.spec.is_gloas_scheduled() { return Err(warp_utils::reject::custom_bad_request( "Execution payload bids are not supported before the Gloas fork".into(), )); } debug!( %slot, builder_index, "Publishing signed execution payload bid to network" ); let gossip_verified_bid = chain .verify_payload_bid_for_gossip(Arc::new(bid)) .map_err(|e| { warn!(%slot, error = ?e, "Execution payload bid failed gossip verification"); warp_utils::reject::custom_bad_request(format!("bid failed gossip verification: {e}")) })?; let bid_for_gossip = gossip_verified_bid.signed_bid.as_ref().clone(); publish_pubsub_message( network_tx, PubsubMessage::ExecutionPayloadBid(Box::new(bid_for_gossip)), )?; Ok(warp::reply().into_response()) }