fn compute_historic_attester_duties<T: BeaconChainTypes>(
    request_epoch: Epoch,
    request_indices: &[u64],
    chain: &BeaconChain<T>,
) -> Result<ApiDuties, warp::reject::Rejection> {
    // If the head is quite old then it might still be relevant for a historical request.
    //
    // Use the `with_head` function to read & clone in a single call to avoid race conditions.
    let state_opt = chain
        .with_head(|head| {
            if head.beacon_state.current_epoch() <= request_epoch {
                Ok(Some((
                    head.beacon_state_root(),
                    head.beacon_state
                        .clone_with(CloneConfig::committee_caches_only()),
                )))
            } else {
                Ok(None)
            }
        })
        .map_err(warp_utils::reject::beacon_chain_error)?;

    let mut state = if let Some((state_root, mut state)) = state_opt {
        // If we've loaded the head state it might be from a previous epoch, ensure it's in a
        // suitable epoch.
        ensure_state_knows_attester_duties_for_epoch(
            &mut state,
            state_root,
            request_epoch,
            &chain.spec,
        )?;
        state
    } else {
        StateId::slot(request_epoch.start_slot(T::EthSpec::slots_per_epoch())).state(&chain)?
    };

    // Sanity-check the state lookup.
    if !(state.current_epoch() == request_epoch || state.current_epoch() + 1 == request_epoch) {
        return Err(warp_utils::reject::custom_server_error(format!(
            "state epoch {} not suitable for request epoch {}",
            state.current_epoch(),
            request_epoch
        )));
    }

    let relative_epoch =
        RelativeEpoch::from_epoch(state.current_epoch(), request_epoch).map_err(|e| {
            warp_utils::reject::custom_server_error(format!("invalid epoch for state: {:?}", e))
        })?;

    state
        .build_committee_cache(relative_epoch, &chain.spec)
        .map_err(BeaconChainError::from)
        .map_err(warp_utils::reject::beacon_chain_error)?;

    let dependent_root = state
        // The only block which decides its own shuffling is the genesis block.
        .attester_shuffling_decision_root(chain.genesis_block_root, relative_epoch)
        .map_err(BeaconChainError::from)
        .map_err(warp_utils::reject::beacon_chain_error)?;

    let duties = request_indices
        .iter()
        .map(|&validator_index| {
            state
                .get_attestation_duties(validator_index as usize, relative_epoch)
                .map_err(BeaconChainError::from)
        })
        .collect::<Result<_, _>>()
        .map_err(warp_utils::reject::beacon_chain_error)?;

    convert_to_api_response(duties, request_indices, dependent_root, chain)
}
/// Compute some attester duties by reading a `BeaconState` from disk, completely ignoring the
/// shuffling cache.
Compute some attester duties by reading a `BeaconState` from disk, completely ignoring the
shuffling cache.
Compute some attester duties by reading a ` BeaconState ` from disk completely ignoring the shuffling cache .
fn compute_historic_attester_duties<T: BeaconChainTypes>(
    request_epoch: Epoch,
    request_indices: &[u64],
    chain: &BeaconChain<T>,
) -> Result<ApiDuties, warp::reject::Rejection> {
    // If the head is quite old then it might still be relevant for a historical request.
    //
    // Use the `with_head` function to read & clone in a single call to avoid race conditions.
    let state_opt = chain
        .with_head(|head| {
            if head.beacon_state.current_epoch() <= request_epoch {
                Ok(Some((
                    head.beacon_state_root(),
                    head.beacon_state
                        .clone_with(CloneConfig::committee_caches_only()),
                )))
            } else {
                Ok(None)
            }
        })
        .map_err(warp_utils::reject::beacon_chain_error)?;
    let mut state = if let Some((state_root, mut state)) = state_opt {
        // If we've loaded the head state it might be from a previous epoch, ensure it's in a
        // suitable epoch.
        ensure_state_knows_attester_duties_for_epoch(
            &mut state,
            state_root,
            request_epoch,
            &chain.spec,
        )?;
        state
    } else {
        StateId::slot(request_epoch.start_slot(T::EthSpec::slots_per_epoch())).state(&chain)?
    };
    // Sanity-check the state lookup.
    if !(state.current_epoch() == request_epoch || state.current_epoch() + 1 == request_epoch) {
        return Err(warp_utils::reject::custom_server_error(format!(
            "state epoch {} not suitable for request epoch {}",
            state.current_epoch(),
            request_epoch
        )));
    }
    let relative_epoch =
        RelativeEpoch::from_epoch(state.current_epoch(), request_epoch).map_err(|e| {
            warp_utils::reject::custom_server_error(format!("invalid epoch for state: {:?}", e))
        })?;
    state
        .build_committee_cache(relative_epoch, &chain.spec)
        .map_err(BeaconChainError::from)
        .map_err(warp_utils::reject::beacon_chain_error)?;
    let dependent_root = state
        // The only block which decides its own shuffling is the genesis block.
        .attester_shuffling_decision_root(chain.genesis_block_root, relative_epoch)
        .map_err(BeaconChainError::from)
        .map_err(warp_utils::reject::beacon_chain_error)?;
    let duties = request_indices
        .iter()
        .map(|&validator_index| {
            state
                .get_attestation_duties(validator_index as usize, relative_epoch)
                .map_err(BeaconChainError::from)
        })
        .collect::<Result<_, _>>()
        .map_err(warp_utils::reject::beacon_chain_error)?;
    convert_to_api_response(duties, request_indices, dependent_root, chain)
}
fn compute_historic_attester_duties < T : BeaconChainTypes > ( request_epoch : Epoch , request_indices : & [ u64 ] , chain : & BeaconChain < T > , ) -> Result < ApiDuties , warp :: reject :: Rejection > { // If the head is quite old then it might still be relevant for a historical request. // // Use the `with_head` function to read & clone in a single call to avoid race conditions. let state_opt = chain . with_head ( | head | { if head . beacon_state . current_epoch ( ) <= request_epoch { Ok ( Some ( ( head . beacon_state_root ( ) , head . beacon_state . clone_with ( CloneConfig :: committee_caches_only ( ) ) , ) ) ) } else { Ok ( None ) } } ) . map_err ( warp_utils :: reject :: beacon_chain_error ) ? ; let mut state = if let Some ( ( state_root , mut state ) ) = state_opt { // If we've loaded the head state it might be from a previous epoch, ensure it's in a // suitable epoch. ensure_state_knows_attester_duties_for_epoch ( & mut state , state_root , request_epoch , & chain . spec , ) ? ; state } else { StateId :: slot ( request_epoch . start_slot ( T :: EthSpec :: slots_per_epoch ( ) ) ) . state ( & chain ) ? } ; // Sanity-check the state lookup. if ! ( state . current_epoch ( ) == request_epoch || state . current_epoch ( ) + 1 == request_epoch ) { return Err ( warp_utils :: reject :: custom_server_error ( format ! ( " " state current_epoch ( ) request_epoch ) ) ) ; } let relative_epoch = RelativeEpoch :: from_epoch ( state . current_epoch ( ) , request_epoch ) . map_err ( | e | { warp_utils :: reject :: custom_server_error ( format ! ( " " e ) ) } ) ? ; state . build_committee_cache ( relative_epoch , & chain . spec ) . map_err ( BeaconChainError :: from ) . map_err ( warp_utils :: reject :: beacon_chain_error ) ? ; let dependent_root = state // The only block which decides its own shuffling is the genesis block. . attester_shuffling_decision_root ( chain . genesis_block_root , relative_epoch ) . map_err ( BeaconChainError :: from ) . map_err ( warp_utils :: reject :: beacon_chain_error ) ? ; let duties = request_indices . iter ( ) . map ( | & validator_index | { state . get_attestation_duties ( validator_index as usize , relative_epoch ) . map_err ( BeaconChainError :: from ) } ) . collect :: < Result < _ , _ > > ( ) . map_err ( warp_utils :: reject :: beacon_chain_error ) ? ; convert_to_api_response ( duties , request_indices , dependent_root , chain ) }
Compute some attester duties by reading a `BeaconState` from disk, completely ignoring the
shuffling cache.
Compute some attester duties by reading a ` BeaconState ` from disk completely ignoring the shuffling cache .
request_epoch
Epoch
request_indices
&[u64]
chain
&BeaconChain<T>