Merge remote-tracking branch 'origin/unstable' into tree-states

This commit is contained in:
Michael Sproul
2022-10-19 13:21:47 +11:00
152 changed files with 3788 additions and 3067 deletions

View File

@@ -668,9 +668,10 @@ pub fn serve<T: BeaconChainTypes>(
"Invalid validator ID".to_string(),
))
}))
.and(log_filter.clone())
.and(warp::path::end())
.and_then(
|state_id: StateId, chain: Arc<BeaconChain<T>>, validator_id: ValidatorId| {
|state_id: StateId, chain: Arc<BeaconChain<T>>, validator_id: ValidatorId, log| {
blocking_json_task(move || {
let (data, execution_optimistic) = state_id
.map_state_and_execution_optimistic(
@@ -678,7 +679,23 @@ pub fn serve<T: BeaconChainTypes>(
|state, execution_optimistic| {
let index_opt = match &validator_id {
ValidatorId::PublicKey(pubkey) => {
state.validators().iter().position(|v| v.pubkey() == pubkey)
// Fast path: use the pubkey cache which is probably
// initialised at the head.
match state.get_validator_index_read_only(pubkey) {
Ok(result) => result,
Err(e) => {
// Slow path, fall back to iteration.
debug!(
log,
"Validator look-up cache miss";
"reason" => ?e,
);
state
.validators()
.iter()
.position(|v| v.pubkey() == pubkey)
}
}
}
ValidatorId::Index(index) => Some(*index as usize),
};
@@ -1046,7 +1063,7 @@ pub fn serve<T: BeaconChainTypes>(
chain: Arc<BeaconChain<T>>,
network_tx: UnboundedSender<NetworkMessage<T::EthSpec>>,
log: Logger| async move {
publish_blocks::publish_block(block, chain, &network_tx, log)
publish_blocks::publish_block(None, block, chain, &network_tx, log)
.await
.map(|()| warp::reply())
},
@@ -2531,7 +2548,7 @@ pub fn serve<T: BeaconChainTypes>(
|| matches!(validator_status, ValidatorStatus::Active);
// Filter out validators who are not 'active' or 'pending'.
is_active_or_pending.then(|| {
is_active_or_pending.then_some({
(
ProposerPreparationData {
validator_index: validator_index as u64,

View File

@@ -9,13 +9,14 @@ use std::sync::Arc;
use tokio::sync::mpsc::UnboundedSender;
use tree_hash::TreeHash;
use types::{
BlindedPayload, ExecPayload, ExecutionBlockHash, ExecutionPayload, FullPayload,
BlindedPayload, ExecPayload, ExecutionBlockHash, ExecutionPayload, FullPayload, Hash256,
SignedBeaconBlock,
};
use warp::Rejection;
/// Handles a request from the HTTP API for full blocks.
pub async fn publish_block<T: BeaconChainTypes>(
block_root: Option<Hash256>,
block: Arc<SignedBeaconBlock<T::EthSpec>>,
chain: Arc<BeaconChain<T>>,
network_tx: &UnboundedSender<NetworkMessage<T::EthSpec>>,
@@ -31,8 +32,10 @@ pub async fn publish_block<T: BeaconChainTypes>(
let delay = get_block_delay_ms(seen_timestamp, block.message(), &chain.slot_clock);
metrics::observe_duration(&metrics::HTTP_API_BLOCK_BROADCAST_DELAY_TIMES, delay);
let block_root = block_root.unwrap_or_else(|| block.canonical_root());
match chain
.process_block(block.clone(), CountUnrealized::True)
.process_block(block_root, block.clone(), CountUnrealized::True)
.await
{
Ok(root) => {
@@ -127,8 +130,16 @@ pub async fn publish_blinded_block<T: BeaconChainTypes>(
network_tx: &UnboundedSender<NetworkMessage<T::EthSpec>>,
log: Logger,
) -> Result<(), Rejection> {
let full_block = reconstruct_block(chain.clone(), block, log.clone()).await?;
publish_block::<T>(Arc::new(full_block), chain, network_tx, log).await
let block_root = block.canonical_root();
let full_block = reconstruct_block(chain.clone(), block_root, block, log.clone()).await?;
publish_block::<T>(
Some(block_root),
Arc::new(full_block),
chain,
network_tx,
log,
)
.await
}
/// Deconstruct the given blinded block, and construct a full block. This attempts to use the
@@ -136,6 +147,7 @@ pub async fn publish_blinded_block<T: BeaconChainTypes>(
/// the full payload.
async fn reconstruct_block<T: BeaconChainTypes>(
chain: Arc<BeaconChain<T>>,
block_root: Hash256,
block: SignedBeaconBlock<T::EthSpec, BlindedPayload<T::EthSpec>>,
log: Logger,
) -> Result<SignedBeaconBlock<T::EthSpec, FullPayload<T::EthSpec>>, Rejection> {
@@ -155,12 +167,15 @@ async fn reconstruct_block<T: BeaconChainTypes>(
cached_payload
// Otherwise, this means we are attempting a blind block proposal.
} else {
let full_payload = el.propose_blinded_beacon_block(&block).await.map_err(|e| {
warp_utils::reject::custom_server_error(format!(
"Blind block proposal failed: {:?}",
e
))
})?;
let full_payload = el
.propose_blinded_beacon_block(block_root, &block)
.await
.map_err(|e| {
warp_utils::reject::custom_server_error(format!(
"Blind block proposal failed: {:?}",
e
))
})?;
info!(log, "Successfully published a block to the builder network"; "block_hash" => ?full_payload.block_hash);
full_payload
};

View File

@@ -152,33 +152,12 @@ impl StateId {
Ok((state, execution_optimistic))
}
/*
/// Map a function across the `BeaconState` identified by `self`.
///
/// The optimistic status of the requested state is also provided to the `func` closure.
///
/// This function will avoid instantiating/copying a new state when `self` points to the head
/// of the chain.
#[allow(dead_code)]
pub fn map_state<T: BeaconChainTypes, F, U>(
&self,
chain: &BeaconChain<T>,
func: F,
) -> Result<U, warp::Rejection>
where
F: Fn(&BeaconState<T::EthSpec>) -> Result<U, warp::Rejection>,
{
match &self.0 {
CoreStateId::Head => chain
.with_head(|snapshot| Ok(func(&snapshot.beacon_state)))
.map_err(warp_utils::reject::beacon_chain_error)?,
_ => func(&self.state(chain)?),
}
}
*/
/// Functions the same as `map_state` but additionally computes the value of
/// `execution_optimistic` of the state identified by `self`.
///
/// This is to avoid re-instantiating `state` unnecessarily.
pub fn map_state_and_execution_optimistic<T: BeaconChainTypes, F, U>(
&self,
chain: &BeaconChain<T>,

View File

@@ -118,9 +118,7 @@ pub async fn create_api_server_on_port<T: BeaconChainTypes>(
// Only a peer manager can add peers, so we create a dummy manager.
let config = lighthouse_network::peer_manager::config::Config::default();
let mut pm = PeerManager::new(config, network_globals.clone(), &log)
.await
.unwrap();
let mut pm = PeerManager::new(config, network_globals.clone(), &log).unwrap();
// add a peer
let peer_id = PeerId::random();
@@ -133,7 +131,8 @@ pub async fn create_api_server_on_port<T: BeaconChainTypes>(
pm.inject_connection_established(&peer_id, &con_id, &connected_point, None, 0);
*network_globals.sync_state.write() = SyncState::Synced;
let eth1_service = eth1::Service::new(eth1::Config::default(), log.clone(), chain.spec.clone());
let eth1_service =
eth1::Service::new(eth1::Config::default(), log.clone(), chain.spec.clone()).unwrap();
let context = Arc::new(Context {
config: Config {

View File

@@ -67,7 +67,10 @@ pub async fn fork_choice_before_proposal() {
let state_a = harness.get_current_state();
let (block_b, state_b) = harness.make_block(state_a.clone(), slot_b).await;
let block_root_b = harness.process_block(slot_b, block_b).await.unwrap();
let block_root_b = harness
.process_block(slot_b, block_b.canonical_root(), block_b)
.await
.unwrap();
// Create attestations to B but keep them in reserve until after C has been processed.
let attestations_b = harness.make_attestations(
@@ -80,7 +83,7 @@ pub async fn fork_choice_before_proposal() {
let (block_c, state_c) = harness.make_block(state_a, slot_c).await;
let block_root_c = harness
.process_block(slot_c, block_c.clone())
.process_block(slot_c, block_c.canonical_root(), block_c.clone())
.await
.unwrap();