mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-06 18:21:45 +00:00
Add timeouts to canonical head rwlock (#759)
* Add TimeoutRwLock to BeaconChain * Update network crate * Update rest api * Fix beacon chain tests * Fix rest api tests * Set test back to !debug_assertions
This commit is contained in:
@@ -33,7 +33,7 @@ pub fn get_head<T: BeaconChainTypes>(
|
||||
req: Request<Body>,
|
||||
beacon_chain: Arc<BeaconChain<T>>,
|
||||
) -> ApiResult {
|
||||
let chain_head = beacon_chain.head();
|
||||
let chain_head = beacon_chain.head()?;
|
||||
|
||||
let head = CanonicalHeadResponse {
|
||||
slot: chain_head.beacon_state.slot,
|
||||
@@ -106,7 +106,7 @@ pub fn get_block<T: BeaconChainTypes>(
|
||||
("slot", value) => {
|
||||
let target = parse_slot(&value)?;
|
||||
|
||||
block_root_at_slot(&beacon_chain, target).ok_or_else(|| {
|
||||
block_root_at_slot(&beacon_chain, target)?.ok_or_else(|| {
|
||||
ApiError::NotFound(format!("Unable to find BeaconBlock for slot {:?}", target))
|
||||
})?
|
||||
}
|
||||
@@ -140,7 +140,7 @@ pub fn get_block_root<T: BeaconChainTypes>(
|
||||
let slot_string = UrlQuery::from_request(&req)?.only_one("slot")?;
|
||||
let target = parse_slot(&slot_string)?;
|
||||
|
||||
let root = block_root_at_slot(&beacon_chain, target).ok_or_else(|| {
|
||||
let root = block_root_at_slot(&beacon_chain, target)?.ok_or_else(|| {
|
||||
ApiError::NotFound(format!("Unable to find BeaconBlock for slot {:?}", target))
|
||||
})?;
|
||||
|
||||
@@ -152,7 +152,7 @@ pub fn get_fork<T: BeaconChainTypes>(
|
||||
req: Request<Body>,
|
||||
beacon_chain: Arc<BeaconChain<T>>,
|
||||
) -> ApiResult {
|
||||
ResponseBuilder::new(&req)?.body(&beacon_chain.head().beacon_state.fork)
|
||||
ResponseBuilder::new(&req)?.body(&beacon_chain.head()?.beacon_state.fork)
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Encode, Decode)]
|
||||
@@ -302,7 +302,7 @@ fn get_state_from_root_opt<T: BeaconChainTypes>(
|
||||
})?
|
||||
.ok_or_else(|| ApiError::NotFound(format!("No state exists with root: {}", state_root)))
|
||||
} else {
|
||||
Ok(beacon_chain.head().beacon_state)
|
||||
Ok(beacon_chain.head()?.beacon_state)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,7 +417,7 @@ pub fn get_state<T: BeaconChainTypes>(
|
||||
req: Request<Body>,
|
||||
beacon_chain: Arc<BeaconChain<T>>,
|
||||
) -> ApiResult {
|
||||
let head_state = beacon_chain.head().beacon_state;
|
||||
let head_state = beacon_chain.head()?.beacon_state;
|
||||
|
||||
let (key, value) = match UrlQuery::from_request(&req) {
|
||||
Ok(query) => {
|
||||
@@ -491,5 +491,5 @@ pub fn get_genesis_time<T: BeaconChainTypes>(
|
||||
req: Request<Body>,
|
||||
beacon_chain: Arc<BeaconChain<T>>,
|
||||
) -> ApiResult {
|
||||
ResponseBuilder::new(&req)?.body(&beacon_chain.head().beacon_state.genesis_time)
|
||||
ResponseBuilder::new(&req)?.body(&beacon_chain.head()?.beacon_state.genesis_time)
|
||||
}
|
||||
|
||||
@@ -60,6 +60,12 @@ impl From<types::BeaconStateError> for ApiError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<beacon_chain::BeaconChainError> for ApiError {
|
||||
fn from(e: beacon_chain::BeaconChainError) -> ApiError {
|
||||
ApiError::ServerError(format!("BeaconChainError error: {:?}", e))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<state_processing::per_slot_processing::Error> for ApiError {
|
||||
fn from(e: state_processing::per_slot_processing::Error) -> ApiError {
|
||||
ApiError::ServerError(format!("PerSlotProcessing error: {:?}", e))
|
||||
|
||||
@@ -120,12 +120,12 @@ pub fn parse_pubkey_bytes(string: &str) -> Result<PublicKeyBytes, ApiError> {
|
||||
pub fn block_root_at_slot<T: BeaconChainTypes>(
|
||||
beacon_chain: &BeaconChain<T>,
|
||||
target: Slot,
|
||||
) -> Option<Hash256> {
|
||||
beacon_chain
|
||||
.rev_iter_block_roots()
|
||||
) -> Result<Option<Hash256>, ApiError> {
|
||||
Ok(beacon_chain
|
||||
.rev_iter_block_roots()?
|
||||
.take_while(|(_root, slot)| *slot >= target)
|
||||
.find(|(_root, slot)| *slot == target)
|
||||
.map(|(root, _slot)| root)
|
||||
.map(|(root, _slot)| root))
|
||||
}
|
||||
|
||||
/// Returns a `BeaconState` and it's root in the canonical chain of `beacon_chain` at the given
|
||||
@@ -137,15 +137,15 @@ pub fn state_at_slot<T: BeaconChainTypes>(
|
||||
beacon_chain: &BeaconChain<T>,
|
||||
slot: Slot,
|
||||
) -> Result<(Hash256, BeaconState<T::EthSpec>), ApiError> {
|
||||
let head_state = &beacon_chain.head().beacon_state;
|
||||
let head_state = &beacon_chain.head()?.beacon_state;
|
||||
|
||||
if head_state.slot == slot {
|
||||
// The request slot is the same as the best block (head) slot.
|
||||
|
||||
// I'm not sure if this `.clone()` will be optimized out. If not, it seems unnecessary.
|
||||
Ok((
|
||||
beacon_chain.head().beacon_state_root,
|
||||
beacon_chain.head().beacon_state.clone(),
|
||||
beacon_chain.head()?.beacon_state_root,
|
||||
beacon_chain.head()?.beacon_state.clone(),
|
||||
))
|
||||
} else {
|
||||
let root = state_root_at_slot(beacon_chain, slot)?;
|
||||
@@ -168,7 +168,7 @@ pub fn state_root_at_slot<T: BeaconChainTypes>(
|
||||
beacon_chain: &BeaconChain<T>,
|
||||
slot: Slot,
|
||||
) -> Result<Hash256, ApiError> {
|
||||
let head_state = &beacon_chain.head().beacon_state;
|
||||
let head_state = &beacon_chain.head()?.beacon_state;
|
||||
let current_slot = beacon_chain
|
||||
.slot()
|
||||
.map_err(|_| ApiError::ServerError("Unable to read slot clock".to_string()))?;
|
||||
@@ -192,7 +192,7 @@ pub fn state_root_at_slot<T: BeaconChainTypes>(
|
||||
// 2. The request slot is the same as the best block (head) slot.
|
||||
//
|
||||
// The head state root is stored in memory, return a reference.
|
||||
Ok(beacon_chain.head().beacon_state_root)
|
||||
Ok(beacon_chain.head()?.beacon_state_root)
|
||||
} else if head_state.slot > slot {
|
||||
// 3. The request slot is prior to the head slot.
|
||||
//
|
||||
@@ -209,7 +209,7 @@ pub fn state_root_at_slot<T: BeaconChainTypes>(
|
||||
//
|
||||
// Use `per_slot_processing` to advance the head state to the present slot,
|
||||
// assuming that all slots do not contain a block (i.e., they are skipped slots).
|
||||
let mut state = beacon_chain.head().beacon_state.clone();
|
||||
let mut state = beacon_chain.head()?.beacon_state.clone();
|
||||
let spec = &T::EthSpec::default_spec();
|
||||
|
||||
for _ in state.slot.as_u64()..slot.as_u64() {
|
||||
|
||||
@@ -122,10 +122,10 @@ pub fn get_state_for_epoch<T: BeaconChainTypes>(
|
||||
epoch: Epoch,
|
||||
) -> Result<BeaconState<T::EthSpec>, ApiError> {
|
||||
let slots_per_epoch = T::EthSpec::slots_per_epoch();
|
||||
let head_epoch = beacon_chain.head().beacon_state.current_epoch();
|
||||
let head_epoch = beacon_chain.head()?.beacon_state.current_epoch();
|
||||
|
||||
if RelativeEpoch::from_epoch(head_epoch, epoch).is_ok() {
|
||||
Ok(beacon_chain.head().beacon_state)
|
||||
Ok(beacon_chain.head()?.beacon_state)
|
||||
} else {
|
||||
let slot = if epoch > head_epoch {
|
||||
// Move to the first slot of the epoch prior to the request.
|
||||
@@ -308,7 +308,7 @@ pub fn publish_beacon_block<T: BeaconChainTypes>(
|
||||
// - Excessive time between block produce and publish.
|
||||
// - A validator is using another beacon node to produce blocks and
|
||||
// submitting them here.
|
||||
if beacon_chain.head().beacon_block_root != block_root {
|
||||
if beacon_chain.head()?.beacon_block_root != block_root {
|
||||
warn!(
|
||||
log,
|
||||
"Block from validator is not head";
|
||||
|
||||
@@ -43,7 +43,12 @@ fn get_randao_reveal<T: BeaconChainTypes>(
|
||||
slot: Slot,
|
||||
spec: &ChainSpec,
|
||||
) -> Signature {
|
||||
let fork = beacon_chain.head().beacon_state.fork.clone();
|
||||
let fork = beacon_chain
|
||||
.head()
|
||||
.expect("should get head")
|
||||
.beacon_state
|
||||
.fork
|
||||
.clone();
|
||||
let proposer_index = beacon_chain
|
||||
.block_proposer(slot)
|
||||
.expect("should get proposer index");
|
||||
@@ -60,7 +65,12 @@ fn sign_block<T: BeaconChainTypes>(
|
||||
block: &mut BeaconBlock<T::EthSpec>,
|
||||
spec: &ChainSpec,
|
||||
) {
|
||||
let fork = beacon_chain.head().beacon_state.fork.clone();
|
||||
let fork = beacon_chain
|
||||
.head()
|
||||
.expect("should get head")
|
||||
.beacon_state
|
||||
.fork
|
||||
.clone();
|
||||
let proposer_index = beacon_chain
|
||||
.block_proposer(block.slot)
|
||||
.expect("should get proposer index");
|
||||
@@ -81,7 +91,11 @@ fn validator_produce_attestation() {
|
||||
.client
|
||||
.beacon_chain()
|
||||
.expect("client should have beacon chain");
|
||||
let state = beacon_chain.head().beacon_state.clone();
|
||||
let state = beacon_chain
|
||||
.head()
|
||||
.expect("should get head")
|
||||
.beacon_state
|
||||
.clone();
|
||||
|
||||
let validator_index = 0;
|
||||
let duties = state
|
||||
@@ -182,6 +196,7 @@ fn validator_duties() {
|
||||
|
||||
let validators = beacon_chain
|
||||
.head()
|
||||
.expect("should get head")
|
||||
.beacon_state
|
||||
.validators
|
||||
.iter()
|
||||
@@ -534,6 +549,7 @@ fn genesis_time() {
|
||||
.beacon_chain()
|
||||
.expect("should have beacon chain")
|
||||
.head()
|
||||
.expect("should get head")
|
||||
.beacon_state
|
||||
.genesis_time,
|
||||
genesis_time,
|
||||
@@ -558,6 +574,7 @@ fn fork() {
|
||||
.beacon_chain()
|
||||
.expect("should have beacon chain")
|
||||
.head()
|
||||
.expect("should get head")
|
||||
.beacon_state
|
||||
.fork,
|
||||
fork,
|
||||
@@ -623,6 +640,7 @@ fn get_genesis_state_root() {
|
||||
.beacon_chain()
|
||||
.expect("should have beacon chain")
|
||||
.rev_iter_state_roots()
|
||||
.expect("should get iter")
|
||||
.find(|(_cur_root, cur_slot)| slot == *cur_slot)
|
||||
.map(|(cur_root, _)| cur_root)
|
||||
.expect("chain should have state root at slot");
|
||||
@@ -649,6 +667,7 @@ fn get_genesis_block_root() {
|
||||
.beacon_chain()
|
||||
.expect("should have beacon chain")
|
||||
.rev_iter_block_roots()
|
||||
.expect("should get iter")
|
||||
.find(|(_cur_root, cur_slot)| slot == *cur_slot)
|
||||
.map(|(cur_root, _)| cur_root)
|
||||
.expect("chain should have state root at slot");
|
||||
@@ -666,7 +685,7 @@ fn get_validators() {
|
||||
.client
|
||||
.beacon_chain()
|
||||
.expect("node should have beacon chain");
|
||||
let state = &chain.head().beacon_state;
|
||||
let state = &chain.head().expect("should get head").beacon_state;
|
||||
|
||||
let validators = state.validators.iter().take(2).collect::<Vec<_>>();
|
||||
let pubkeys = validators
|
||||
@@ -695,7 +714,7 @@ fn get_all_validators() {
|
||||
.client
|
||||
.beacon_chain()
|
||||
.expect("node should have beacon chain");
|
||||
let state = &chain.head().beacon_state;
|
||||
let state = &chain.head().expect("should get head").beacon_state;
|
||||
|
||||
let result = env
|
||||
.runtime()
|
||||
@@ -718,7 +737,7 @@ fn get_active_validators() {
|
||||
.client
|
||||
.beacon_chain()
|
||||
.expect("node should have beacon chain");
|
||||
let state = &chain.head().beacon_state;
|
||||
let state = &chain.head().expect("should get head").beacon_state;
|
||||
|
||||
let result = env
|
||||
.runtime()
|
||||
@@ -764,6 +783,7 @@ fn get_committees() {
|
||||
|
||||
let expected = chain
|
||||
.head()
|
||||
.expect("should get head")
|
||||
.beacon_state
|
||||
.get_beacon_committees_at_epoch(RelativeEpoch::Current)
|
||||
.expect("should get committees")
|
||||
|
||||
Reference in New Issue
Block a user