mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-09 11:41:51 +00:00
Merge branch 'unstable' of https://github.com/sigp/lighthouse into merge-unstable-deneb-aug-24
This commit is contained in:
72
beacon_node/http_api/src/builder_states.rs
Normal file
72
beacon_node/http_api/src/builder_states.rs
Normal file
@@ -0,0 +1,72 @@
|
||||
use crate::StateId;
|
||||
use beacon_chain::{BeaconChain, BeaconChainTypes};
|
||||
use safe_arith::SafeArith;
|
||||
use state_processing::per_block_processing::get_expected_withdrawals;
|
||||
use state_processing::state_advance::partial_state_advance;
|
||||
use std::sync::Arc;
|
||||
use types::{BeaconState, EthSpec, ForkName, Slot, Withdrawals};
|
||||
|
||||
const MAX_EPOCH_LOOKAHEAD: u64 = 2;
|
||||
|
||||
/// Get the withdrawals computed from the specified state, that will be included in the block
|
||||
/// that gets built on the specified state.
|
||||
pub fn get_next_withdrawals<T: BeaconChainTypes>(
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
mut state: BeaconState<T::EthSpec>,
|
||||
state_id: StateId,
|
||||
proposal_slot: Slot,
|
||||
) -> Result<Withdrawals<T::EthSpec>, warp::Rejection> {
|
||||
get_next_withdrawals_sanity_checks(chain, &state, proposal_slot)?;
|
||||
|
||||
// advance the state to the epoch of the proposal slot.
|
||||
let proposal_epoch = proposal_slot.epoch(T::EthSpec::slots_per_epoch());
|
||||
let (state_root, _, _) = state_id.root(chain)?;
|
||||
if proposal_epoch != state.current_epoch() {
|
||||
if let Err(e) =
|
||||
partial_state_advance(&mut state, Some(state_root), proposal_slot, &chain.spec)
|
||||
{
|
||||
return Err(warp_utils::reject::custom_server_error(format!(
|
||||
"failed to advance to the epoch of the proposal slot: {:?}",
|
||||
e
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
match get_expected_withdrawals(&state, &chain.spec) {
|
||||
Ok(withdrawals) => Ok(withdrawals),
|
||||
Err(e) => Err(warp_utils::reject::custom_server_error(format!(
|
||||
"failed to get expected withdrawal: {:?}",
|
||||
e
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_next_withdrawals_sanity_checks<T: BeaconChainTypes>(
|
||||
chain: &BeaconChain<T>,
|
||||
state: &BeaconState<T::EthSpec>,
|
||||
proposal_slot: Slot,
|
||||
) -> Result<(), warp::Rejection> {
|
||||
if proposal_slot <= state.slot() {
|
||||
return Err(warp_utils::reject::custom_bad_request(
|
||||
"proposal slot must be greater than the pre-state slot".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let fork = chain.spec.fork_name_at_slot::<T::EthSpec>(proposal_slot);
|
||||
if let ForkName::Base | ForkName::Altair | ForkName::Merge = fork {
|
||||
return Err(warp_utils::reject::custom_bad_request(
|
||||
"the specified state is a pre-capella state.".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let look_ahead_limit = MAX_EPOCH_LOOKAHEAD
|
||||
.safe_mul(T::EthSpec::slots_per_epoch())
|
||||
.map_err(warp_utils::reject::arith_error)?;
|
||||
if proposal_slot >= state.slot() + look_ahead_limit {
|
||||
return Err(warp_utils::reject::custom_bad_request(format!(
|
||||
"proposal slot is greater than or equal to the look ahead limit: {look_ahead_limit}"
|
||||
)));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -11,6 +11,7 @@ mod block_id;
|
||||
mod block_packing_efficiency;
|
||||
mod block_rewards;
|
||||
mod build_block_contents;
|
||||
mod builder_states;
|
||||
mod database;
|
||||
mod metrics;
|
||||
mod proposer_duties;
|
||||
@@ -33,6 +34,7 @@ use beacon_chain::{
|
||||
};
|
||||
use beacon_processor::BeaconProcessorSend;
|
||||
pub use block_id::BlockId;
|
||||
use builder_states::get_next_withdrawals;
|
||||
use bytes::Bytes;
|
||||
use directory::DEFAULT_ROOT_DIR;
|
||||
use eth2::types::{
|
||||
@@ -2332,6 +2334,60 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
},
|
||||
);
|
||||
|
||||
/*
|
||||
* builder/states
|
||||
*/
|
||||
|
||||
let builder_states_path = eth_v1
|
||||
.and(warp::path("builder"))
|
||||
.and(warp::path("states"))
|
||||
.and(chain_filter.clone());
|
||||
|
||||
// GET builder/states/{state_id}/expected_withdrawals
|
||||
let get_expected_withdrawals = builder_states_path
|
||||
.clone()
|
||||
.and(task_spawner_filter.clone())
|
||||
.and(warp::path::param::<StateId>())
|
||||
.and(warp::path("expected_withdrawals"))
|
||||
.and(warp::query::<api_types::ExpectedWithdrawalsQuery>())
|
||||
.and(warp::path::end())
|
||||
.and(warp::header::optional::<api_types::Accept>("accept"))
|
||||
.then(
|
||||
|chain: Arc<BeaconChain<T>>,
|
||||
task_spawner: TaskSpawner<T::EthSpec>,
|
||||
state_id: StateId,
|
||||
query: api_types::ExpectedWithdrawalsQuery,
|
||||
accept_header: Option<api_types::Accept>| {
|
||||
task_spawner.blocking_response_task(Priority::P1, move || {
|
||||
let (state, execution_optimistic, finalized) = state_id.state(&chain)?;
|
||||
let proposal_slot = query.proposal_slot.unwrap_or(state.slot() + 1);
|
||||
let withdrawals =
|
||||
get_next_withdrawals::<T>(&chain, state, state_id, proposal_slot)?;
|
||||
|
||||
match accept_header {
|
||||
Some(api_types::Accept::Ssz) => Response::builder()
|
||||
.status(200)
|
||||
.header("Content-Type", "application/octet-stream")
|
||||
.body(withdrawals.as_ssz_bytes().into())
|
||||
.map_err(|e| {
|
||||
warp_utils::reject::custom_server_error(format!(
|
||||
"failed to create response: {}",
|
||||
e
|
||||
))
|
||||
}),
|
||||
_ => Ok(warp::reply::json(
|
||||
&api_types::ExecutionOptimisticFinalizedResponse {
|
||||
data: withdrawals,
|
||||
execution_optimistic: Some(execution_optimistic),
|
||||
finalized: Some(finalized),
|
||||
},
|
||||
)
|
||||
.into_response()),
|
||||
}
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
/*
|
||||
* beacon/rewards
|
||||
*/
|
||||
@@ -4529,6 +4585,7 @@ pub fn serve<T: BeaconChainTypes>(
|
||||
.uor(get_lighthouse_block_packing_efficiency)
|
||||
.uor(get_lighthouse_merge_readiness)
|
||||
.uor(get_events)
|
||||
.uor(get_expected_withdrawals)
|
||||
.uor(lighthouse_log_events.boxed())
|
||||
.recover(warp_utils::reject::handle_rejection),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user