mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-18 22:49:34 +00:00
Merge remote-tracking branch 'origin/unstable' into tree-states
This commit is contained in:
@@ -796,7 +796,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
|
||||
if let Some(request_root) = request_root_opt {
|
||||
if let Ok(prev_root) = state.get_block_root(prev_slot) {
|
||||
return Ok(Some((*prev_root != request_root).then(|| request_root)));
|
||||
return Ok(Some((*prev_root != request_root).then_some(request_root)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -818,7 +818,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
slot: curr_slot,
|
||||
});
|
||||
}
|
||||
Ok((curr_root != prev_root).then(|| curr_root))
|
||||
Ok((curr_root != prev_root).then_some(curr_root))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
@@ -1962,60 +1962,75 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
target_epoch: Epoch,
|
||||
state: &BeaconState<T::EthSpec>,
|
||||
) -> bool {
|
||||
let slots_per_epoch = T::EthSpec::slots_per_epoch();
|
||||
let shuffling_lookahead = 1 + self.spec.min_seed_lookahead.as_u64();
|
||||
|
||||
// Shuffling can't have changed if we're in the first few epochs
|
||||
if state.current_epoch() < shuffling_lookahead {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Otherwise the shuffling is determined by the block at the end of the target epoch
|
||||
// minus the shuffling lookahead (usually 2). We call this the "pivot".
|
||||
let pivot_slot =
|
||||
if target_epoch == state.previous_epoch() || target_epoch == state.current_epoch() {
|
||||
(target_epoch - shuffling_lookahead).end_slot(slots_per_epoch)
|
||||
} else {
|
||||
return false;
|
||||
};
|
||||
|
||||
let state_pivot_block_root = match state.get_block_root(pivot_slot) {
|
||||
Ok(root) => *root,
|
||||
Err(e) => {
|
||||
warn!(
|
||||
&self.log,
|
||||
"Missing pivot block root for attestation";
|
||||
"slot" => pivot_slot,
|
||||
"error" => ?e,
|
||||
);
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Use fork choice's view of the block DAG to quickly evaluate whether the attestation's
|
||||
// pivot block is the same as the current state's pivot block. If it is, then the
|
||||
// attestation's shuffling is the same as the current state's.
|
||||
// To account for skipped slots, find the first block at *or before* the pivot slot.
|
||||
let fork_choice_lock = self.canonical_head.fork_choice_read_lock();
|
||||
let pivot_block_root = fork_choice_lock
|
||||
.proto_array()
|
||||
.core_proto_array()
|
||||
.iter_block_roots(block_root)
|
||||
.find(|(_, slot)| *slot <= pivot_slot)
|
||||
.map(|(block_root, _)| block_root);
|
||||
drop(fork_choice_lock);
|
||||
|
||||
match pivot_block_root {
|
||||
Some(root) => root == state_pivot_block_root,
|
||||
None => {
|
||||
self.shuffling_is_compatible_result(block_root, target_epoch, state)
|
||||
.unwrap_or_else(|e| {
|
||||
debug!(
|
||||
&self.log,
|
||||
"Discarding attestation because of missing ancestor";
|
||||
"pivot_slot" => pivot_slot.as_u64(),
|
||||
self.log,
|
||||
"Skipping attestation with incompatible shuffling";
|
||||
"block_root" => ?block_root,
|
||||
"target_epoch" => target_epoch,
|
||||
"reason" => ?e,
|
||||
);
|
||||
false
|
||||
})
|
||||
}
|
||||
|
||||
fn shuffling_is_compatible_result(
|
||||
&self,
|
||||
block_root: &Hash256,
|
||||
target_epoch: Epoch,
|
||||
state: &BeaconState<T::EthSpec>,
|
||||
) -> Result<bool, Error> {
|
||||
// Compute the shuffling ID for the head state in the `target_epoch`.
|
||||
let relative_epoch = RelativeEpoch::from_epoch(state.current_epoch(), target_epoch)
|
||||
.map_err(|e| Error::BeaconStateError(e.into()))?;
|
||||
let head_shuffling_id =
|
||||
AttestationShufflingId::new(self.genesis_block_root, state, relative_epoch)?;
|
||||
|
||||
// Load the block's shuffling ID from fork choice. We use the variant of `get_block` that
|
||||
// checks descent from the finalized block, so there's one case where we'll spuriously
|
||||
// return `false`: where an attestation for the previous epoch nominates the pivot block
|
||||
// which is the parent block of the finalized block. Such attestations are not useful, so
|
||||
// this doesn't matter.
|
||||
let fork_choice_lock = self.canonical_head.fork_choice_read_lock();
|
||||
let block = fork_choice_lock
|
||||
.get_block(block_root)
|
||||
.ok_or(Error::AttestationHeadNotInForkChoice(*block_root))?;
|
||||
drop(fork_choice_lock);
|
||||
|
||||
let block_shuffling_id = if target_epoch == block.current_epoch_shuffling_id.shuffling_epoch
|
||||
{
|
||||
block.current_epoch_shuffling_id
|
||||
} else if target_epoch == block.next_epoch_shuffling_id.shuffling_epoch {
|
||||
block.next_epoch_shuffling_id
|
||||
} else if target_epoch > block.next_epoch_shuffling_id.shuffling_epoch {
|
||||
AttestationShufflingId {
|
||||
shuffling_epoch: target_epoch,
|
||||
shuffling_decision_block: *block_root,
|
||||
}
|
||||
} else {
|
||||
debug!(
|
||||
self.log,
|
||||
"Skipping attestation with incompatible shuffling";
|
||||
"block_root" => ?block_root,
|
||||
"target_epoch" => target_epoch,
|
||||
"reason" => "target epoch less than block epoch"
|
||||
);
|
||||
return Ok(false);
|
||||
};
|
||||
|
||||
if head_shuffling_id == block_shuffling_id {
|
||||
Ok(true)
|
||||
} else {
|
||||
debug!(
|
||||
self.log,
|
||||
"Skipping attestation with incompatible shuffling";
|
||||
"block_root" => ?block_root,
|
||||
"target_epoch" => target_epoch,
|
||||
"head_shuffling_id" => ?head_shuffling_id,
|
||||
"block_shuffling_id" => ?block_shuffling_id,
|
||||
);
|
||||
Ok(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2191,7 +2206,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
}
|
||||
}
|
||||
|
||||
match check_block_relevancy(&block, Some(block_root), self) {
|
||||
match check_block_relevancy(&block, block_root, self) {
|
||||
// If the block is relevant, add it to the filtered chain segment.
|
||||
Ok(_) => filtered_chain_segment.push((block_root, block)),
|
||||
// If the block is already known, simply ignore this block.
|
||||
@@ -2315,7 +2330,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
// Import the blocks into the chain.
|
||||
for signature_verified_block in signature_verified_blocks {
|
||||
match self
|
||||
.process_block(signature_verified_block, count_unrealized)
|
||||
.process_block(
|
||||
signature_verified_block.block_root(),
|
||||
signature_verified_block,
|
||||
count_unrealized,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(_) => imported_blocks += 1,
|
||||
@@ -2358,7 +2377,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
Ok(verified) => {
|
||||
debug!(
|
||||
chain.log,
|
||||
"Successfully processed gossip block";
|
||||
"Successfully verified gossip block";
|
||||
"graffiti" => graffiti_string,
|
||||
"slot" => slot,
|
||||
"root" => ?verified.block_root(),
|
||||
@@ -2400,6 +2419,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
/// verification.
|
||||
pub async fn process_block<B: IntoExecutionPendingBlock<T>>(
|
||||
self: &Arc<Self>,
|
||||
block_root: Hash256,
|
||||
unverified_block: B,
|
||||
count_unrealized: CountUnrealized,
|
||||
) -> Result<Hash256, BlockError<T::EthSpec>> {
|
||||
@@ -2415,7 +2435,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
// A small closure to group the verification and import errors.
|
||||
let chain = self.clone();
|
||||
let import_block = async move {
|
||||
let execution_pending = unverified_block.into_execution_pending_block(&chain)?;
|
||||
let execution_pending =
|
||||
unverified_block.into_execution_pending_block(block_root, &chain)?;
|
||||
chain
|
||||
.import_execution_pending_block(execution_pending, count_unrealized)
|
||||
.await
|
||||
@@ -2842,7 +2863,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
.pubkeys
|
||||
.iter()
|
||||
.zip(sync_aggregate.sync_committee_bits.iter())
|
||||
.filter_map(|(pubkey, bit)| bit.then(|| pubkey))
|
||||
.filter_map(|(pubkey, bit)| bit.then_some(pubkey))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
validator_monitor.register_sync_aggregate_in_block(
|
||||
@@ -3414,7 +3435,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
}
|
||||
|
||||
let slot = state.slot();
|
||||
let proposer_index = state.get_beacon_proposer_index(state.slot(), &self.spec)? as u64;
|
||||
|
||||
let sync_aggregate = if matches!(&state, BeaconState::Base(_)) {
|
||||
None
|
||||
@@ -3561,7 +3581,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
ProduceBlockVerification::VerifyRandao => BlockSignatureStrategy::VerifyRandao,
|
||||
ProduceBlockVerification::NoVerification => BlockSignatureStrategy::NoVerification,
|
||||
};
|
||||
let mut ctxt = ConsensusContext::new(block.slot()).set_proposer_index(proposer_index);
|
||||
// Use a context without block root or proposer index so that both are checked.
|
||||
let mut ctxt = ConsensusContext::new(block.slot());
|
||||
per_block_processing(
|
||||
&mut state,
|
||||
&block,
|
||||
@@ -4376,7 +4397,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
///
|
||||
/// If the committee for `(head_block_root, shuffling_epoch)` isn't found in the
|
||||
/// `shuffling_cache`, we will read a state from disk and then update the `shuffling_cache`.
|
||||
pub(crate) fn with_committee_cache<F, R>(
|
||||
pub fn with_committee_cache<F, R>(
|
||||
&self,
|
||||
head_block_root: Hash256,
|
||||
shuffling_epoch: Epoch,
|
||||
|
||||
@@ -528,7 +528,7 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
|
||||
}
|
||||
|
||||
let (first_root, first_block) = chain_segment.remove(0);
|
||||
let (mut parent, first_block) = load_parent(first_block, chain)?;
|
||||
let (mut parent, first_block) = load_parent(first_root, first_block, chain)?;
|
||||
let slot = first_block.slot();
|
||||
chain_segment.insert(0, (first_root, first_block));
|
||||
|
||||
@@ -548,7 +548,7 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
|
||||
let mut signature_verifier = get_signature_verifier::<T>(&state, &pubkey_cache, &chain.spec);
|
||||
|
||||
for (block_root, block) in &chain_segment {
|
||||
signature_verifier.include_all_signatures(block, Some(*block_root), true)?;
|
||||
signature_verifier.include_all_signatures(block, Some(*block_root), None)?;
|
||||
}
|
||||
|
||||
if signature_verifier.verify().is_err() {
|
||||
@@ -560,8 +560,7 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
|
||||
let mut signature_verified_blocks = chain_segment
|
||||
.into_iter()
|
||||
.map(|(block_root, block)| {
|
||||
// It's safe to include the proposer index here as the signature check also checks that
|
||||
// the block is signed by the correct proposer (see `block_proposal_signature_set`).
|
||||
// Proposer index has already been verified above during signature verification.
|
||||
let consensus_context = ConsensusContext::new(block.slot())
|
||||
.set_current_block_root(block_root)
|
||||
.set_proposer_index(block.message().proposer_index());
|
||||
@@ -631,9 +630,10 @@ pub struct ExecutionPendingBlock<T: BeaconChainTypes> {
|
||||
pub trait IntoExecutionPendingBlock<T: BeaconChainTypes>: Sized {
|
||||
fn into_execution_pending_block(
|
||||
self,
|
||||
block_root: Hash256,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
) -> Result<ExecutionPendingBlock<T>, BlockError<T::EthSpec>> {
|
||||
self.into_execution_pending_block_slashable(chain)
|
||||
self.into_execution_pending_block_slashable(block_root, chain)
|
||||
.map(|execution_pending| {
|
||||
// Supply valid block to slasher.
|
||||
if let Some(slasher) = chain.slasher.as_ref() {
|
||||
@@ -647,6 +647,7 @@ pub trait IntoExecutionPendingBlock<T: BeaconChainTypes>: Sized {
|
||||
/// Convert the block to fully-verified form while producing data to aid checking slashability.
|
||||
fn into_execution_pending_block_slashable(
|
||||
self,
|
||||
block_root: Hash256,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>>;
|
||||
|
||||
@@ -790,7 +791,7 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
|
||||
} else {
|
||||
// The proposer index was *not* cached and we must load the parent in order to determine
|
||||
// the proposer index.
|
||||
let (mut parent, block) = load_parent(block, chain)?;
|
||||
let (mut parent, block) = load_parent(block_root, block, chain)?;
|
||||
|
||||
debug!(
|
||||
chain.log,
|
||||
@@ -892,11 +893,12 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for GossipVerifiedBlock<T
|
||||
/// Completes verification of the wrapped `block`.
|
||||
fn into_execution_pending_block_slashable(
|
||||
self,
|
||||
block_root: Hash256,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
||||
let execution_pending =
|
||||
SignatureVerifiedBlock::from_gossip_verified_block_check_slashable(self, chain)?;
|
||||
execution_pending.into_execution_pending_block_slashable(chain)
|
||||
execution_pending.into_execution_pending_block_slashable(block_root, chain)
|
||||
}
|
||||
|
||||
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
|
||||
@@ -922,7 +924,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
||||
// Check the anchor slot before loading the parent, to avoid spurious lookups.
|
||||
check_block_against_anchor_slot(block.message(), chain)?;
|
||||
|
||||
let (mut parent, block) = load_parent(block, chain)?;
|
||||
let (mut parent, block) = load_parent(block_root, block, chain)?;
|
||||
|
||||
// Reject any block that exceeds our limit on skipped slots.
|
||||
check_block_skip_slots(chain, parent.beacon_block.slot(), block.message())?;
|
||||
@@ -939,7 +941,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
||||
let mut signature_verifier =
|
||||
get_signature_verifier::<T>(&state, &pubkey_cache, &chain.spec);
|
||||
|
||||
signature_verifier.include_all_signatures(&block, Some(block_root), true)?;
|
||||
signature_verifier.include_all_signatures(&block, Some(block_root), None)?;
|
||||
|
||||
if signature_verifier.verify().is_ok() {
|
||||
Ok(Self {
|
||||
@@ -974,7 +976,7 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
||||
let (mut parent, block) = if let Some(parent) = from.parent {
|
||||
(parent, from.block)
|
||||
} else {
|
||||
load_parent(from.block, chain)?
|
||||
load_parent(from.block_root, from.block, chain)?
|
||||
};
|
||||
|
||||
let state = cheap_state_advance_to_obtain_committees(
|
||||
@@ -989,7 +991,11 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
||||
let mut signature_verifier =
|
||||
get_signature_verifier::<T>(&state, &pubkey_cache, &chain.spec);
|
||||
|
||||
signature_verifier.include_all_signatures_except_proposal(&block)?;
|
||||
// Gossip verification has already checked the proposer index. Use it to check the RANDAO
|
||||
// signature.
|
||||
let verified_proposer_index = Some(block.message().proposer_index());
|
||||
signature_verifier
|
||||
.include_all_signatures_except_proposal(&block, verified_proposer_index)?;
|
||||
|
||||
if signature_verifier.verify().is_ok() {
|
||||
Ok(Self {
|
||||
@@ -1012,25 +1018,30 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
|
||||
Self::from_gossip_verified_block(from, chain)
|
||||
.map_err(|e| BlockSlashInfo::from_early_error(header, e))
|
||||
}
|
||||
|
||||
pub fn block_root(&self) -> Hash256 {
|
||||
self.block_root
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for SignatureVerifiedBlock<T> {
|
||||
/// Completes verification of the wrapped `block`.
|
||||
fn into_execution_pending_block_slashable(
|
||||
self,
|
||||
block_root: Hash256,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
||||
let header = self.block.signed_block_header();
|
||||
let (parent, block) = if let Some(parent) = self.parent {
|
||||
(parent, self.block)
|
||||
} else {
|
||||
load_parent(self.block, chain)
|
||||
load_parent(self.block_root, self.block, chain)
|
||||
.map_err(|e| BlockSlashInfo::SignatureValid(header.clone(), e))?
|
||||
};
|
||||
|
||||
ExecutionPendingBlock::from_signature_verified_components(
|
||||
block,
|
||||
self.block_root,
|
||||
block_root,
|
||||
parent,
|
||||
self.consensus_context,
|
||||
chain,
|
||||
@@ -1048,14 +1059,15 @@ impl<T: BeaconChainTypes> IntoExecutionPendingBlock<T> for Arc<SignedBeaconBlock
|
||||
/// and then using that implementation of `IntoExecutionPendingBlock` to complete verification.
|
||||
fn into_execution_pending_block_slashable(
|
||||
self,
|
||||
block_root: Hash256,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
) -> Result<ExecutionPendingBlock<T>, BlockSlashInfo<BlockError<T::EthSpec>>> {
|
||||
// Perform an early check to prevent wasting time on irrelevant blocks.
|
||||
let block_root = check_block_relevancy(&self, None, chain)
|
||||
let block_root = check_block_relevancy(&self, block_root, chain)
|
||||
.map_err(|e| BlockSlashInfo::SignatureNotChecked(self.signed_block_header(), e))?;
|
||||
|
||||
SignatureVerifiedBlock::check_slashable(self, block_root, chain)?
|
||||
.into_execution_pending_block_slashable(chain)
|
||||
.into_execution_pending_block_slashable(block_root, chain)
|
||||
}
|
||||
|
||||
fn block(&self) -> &SignedBeaconBlock<T::EthSpec> {
|
||||
@@ -1111,7 +1123,7 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
|
||||
* Perform cursory checks to see if the block is even worth processing.
|
||||
*/
|
||||
|
||||
check_block_relevancy(&block, Some(block_root), chain)?;
|
||||
check_block_relevancy(&block, block_root, chain)?;
|
||||
|
||||
/*
|
||||
* Advance the given `parent.beacon_state` to the slot of the given `block`.
|
||||
@@ -1504,7 +1516,7 @@ pub fn check_block_is_finalized_descendant<T: BeaconChainTypes>(
|
||||
/// experienced whilst attempting to verify.
|
||||
pub fn check_block_relevancy<T: BeaconChainTypes>(
|
||||
signed_block: &SignedBeaconBlock<T::EthSpec>,
|
||||
block_root: Option<Hash256>,
|
||||
block_root: Hash256,
|
||||
chain: &BeaconChain<T>,
|
||||
) -> Result<Hash256, BlockError<T::EthSpec>> {
|
||||
let block = signed_block.message();
|
||||
@@ -1528,8 +1540,6 @@ pub fn check_block_relevancy<T: BeaconChainTypes>(
|
||||
return Err(BlockError::BlockSlotLimitReached);
|
||||
}
|
||||
|
||||
let block_root = block_root.unwrap_or_else(|| get_block_root(signed_block));
|
||||
|
||||
// Do not process a block from a finalized slot.
|
||||
check_block_against_finalized_slot(block, block_root, chain)?;
|
||||
|
||||
@@ -1583,6 +1593,7 @@ fn verify_parent_block_is_known<T: BeaconChainTypes>(
|
||||
/// whilst attempting the operation.
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn load_parent<T: BeaconChainTypes>(
|
||||
block_root: Hash256,
|
||||
block: Arc<SignedBeaconBlock<T::EthSpec>>,
|
||||
chain: &BeaconChain<T>,
|
||||
) -> Result<
|
||||
|
||||
@@ -911,7 +911,7 @@ where
|
||||
.ok_or("dummy_eth1_backend requires a log")?;
|
||||
|
||||
let backend =
|
||||
CachingEth1Backend::new(Eth1Config::default(), log.clone(), self.spec.clone());
|
||||
CachingEth1Backend::new(Eth1Config::default(), log.clone(), self.spec.clone())?;
|
||||
|
||||
self.eth1_chain = Some(Eth1Chain::new_dummy(backend));
|
||||
|
||||
|
||||
@@ -639,11 +639,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
}
|
||||
};
|
||||
|
||||
// Regardless of where we got the state from, attempt to build the committee
|
||||
// caches.
|
||||
new_snapshot
|
||||
.beacon_state
|
||||
.build_all_committee_caches(&self.spec)?;
|
||||
// Regardless of where we got the state from, attempt to build all the
|
||||
// caches except the tree hash cache.
|
||||
new_snapshot.beacon_state.build_all_caches(&self.spec)?;
|
||||
|
||||
let new_cached_head = CachedHead {
|
||||
snapshot: Arc::new(new_snapshot),
|
||||
|
||||
@@ -431,12 +431,13 @@ impl<T: EthSpec> CachingEth1Backend<T> {
|
||||
/// Instantiates `self` with empty caches.
|
||||
///
|
||||
/// Does not connect to the eth1 node or start any tasks to keep the cache updated.
|
||||
pub fn new(config: Eth1Config, log: Logger, spec: ChainSpec) -> Self {
|
||||
Self {
|
||||
core: HttpService::new(config, log.clone(), spec),
|
||||
pub fn new(config: Eth1Config, log: Logger, spec: ChainSpec) -> Result<Self, String> {
|
||||
Ok(Self {
|
||||
core: HttpService::new(config, log.clone(), spec)
|
||||
.map_err(|e| format!("Failed to create eth1 http service: {:?}", e))?,
|
||||
log,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Starts the routine which connects to the external eth1 node and updates the caches.
|
||||
@@ -730,11 +731,9 @@ mod test {
|
||||
};
|
||||
|
||||
let log = null_logger().unwrap();
|
||||
Eth1Chain::new(CachingEth1Backend::new(
|
||||
eth1_config,
|
||||
log,
|
||||
MainnetEthSpec::default_spec(),
|
||||
))
|
||||
Eth1Chain::new(
|
||||
CachingEth1Backend::new(eth1_config, log, MainnetEthSpec::default_spec()).unwrap(),
|
||||
)
|
||||
}
|
||||
|
||||
fn get_deposit_log(i: u64, spec: &ChainSpec) -> DepositLog {
|
||||
|
||||
@@ -53,7 +53,9 @@ pub use self::errors::{BeaconChainError, BlockProductionError};
|
||||
pub use self::historical_blocks::HistoricalBlockError;
|
||||
pub use attestation_verification::Error as AttestationError;
|
||||
pub use beacon_fork_choice_store::{BeaconForkChoiceStore, Error as ForkChoiceStoreError};
|
||||
pub use block_verification::{BlockError, ExecutionPayloadError, GossipVerifiedBlock};
|
||||
pub use block_verification::{
|
||||
get_block_root, BlockError, ExecutionPayloadError, GossipVerifiedBlock,
|
||||
};
|
||||
pub use canonical_head::{CachedHead, CanonicalHead, CanonicalHeadRwLock};
|
||||
pub use eth1_chain::{Eth1Chain, Eth1ChainBackend};
|
||||
pub use events::ServerSentEventHandler;
|
||||
|
||||
@@ -212,7 +212,7 @@ fn map_relevant_epochs_to_roots<T: BeaconChainTypes>(
|
||||
|
||||
let root = iter
|
||||
.find_map(|next| match next {
|
||||
Ok((root, slot)) => (slot == start_slot).then(|| Ok(root)),
|
||||
Ok((root, slot)) => (slot == start_slot).then_some(Ok(root)),
|
||||
Err(e) => Some(Err(format!("{:?}", e))),
|
||||
})
|
||||
.transpose()?
|
||||
@@ -286,7 +286,7 @@ fn find_finalized_descendant_heads(
|
||||
.filter_map(|(index, node)| {
|
||||
(!nodes_referenced_as_parents.contains(&index)
|
||||
&& fork_choice.is_descendant(finalized_root, node.root))
|
||||
.then(|| HeadInfo {
|
||||
.then_some(HeadInfo {
|
||||
index,
|
||||
root: node.root,
|
||||
slot: node.slot,
|
||||
@@ -306,7 +306,7 @@ fn update_store_justified_checkpoint(
|
||||
.filter_map(|node| {
|
||||
(node.finalized_checkpoint
|
||||
== Some(persisted_fork_choice.fork_choice_store.finalized_checkpoint))
|
||||
.then(|| node.justified_checkpoint)
|
||||
.then_some(node.justified_checkpoint)
|
||||
.flatten()
|
||||
})
|
||||
.max_by_key(|justified_checkpoint| justified_checkpoint.epoch)
|
||||
|
||||
@@ -343,7 +343,7 @@ impl<T: BeaconChainTypes> VerifiedSyncContribution<T> {
|
||||
let participant_pubkeys = sync_subcommittee_pubkeys
|
||||
.into_iter()
|
||||
.zip(contribution.aggregation_bits.iter())
|
||||
.filter_map(|(pubkey, bit)| bit.then(|| pubkey))
|
||||
.filter_map(|(pubkey, bit)| bit.then_some(pubkey))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// Ensure that all signatures are valid.
|
||||
|
||||
@@ -1123,7 +1123,7 @@ where
|
||||
selection_proof
|
||||
.is_aggregator::<E>()
|
||||
.expect("should determine aggregator")
|
||||
.then(|| validator_index)
|
||||
.then_some(validator_index)
|
||||
})?;
|
||||
|
||||
let default = SyncCommitteeContribution::from_message(
|
||||
@@ -1446,12 +1446,13 @@ where
|
||||
pub async fn process_block(
|
||||
&self,
|
||||
slot: Slot,
|
||||
block_root: Hash256,
|
||||
block: SignedBeaconBlock<E>,
|
||||
) -> Result<SignedBeaconBlockHash, BlockError<E>> {
|
||||
self.set_current_slot(slot);
|
||||
let block_hash: SignedBeaconBlockHash = self
|
||||
.chain
|
||||
.process_block(Arc::new(block), CountUnrealized::True)
|
||||
.process_block(block_root, Arc::new(block), CountUnrealized::True)
|
||||
.await?
|
||||
.into();
|
||||
self.chain.recompute_head_at_current_slot().await;
|
||||
@@ -1464,7 +1465,11 @@ where
|
||||
) -> Result<SignedBeaconBlockHash, BlockError<E>> {
|
||||
let block_hash: SignedBeaconBlockHash = self
|
||||
.chain
|
||||
.process_block(Arc::new(block), CountUnrealized::True)
|
||||
.process_block(
|
||||
block.canonical_root(),
|
||||
Arc::new(block),
|
||||
CountUnrealized::True,
|
||||
)
|
||||
.await?
|
||||
.into();
|
||||
self.chain.recompute_head_at_current_slot().await;
|
||||
@@ -1529,7 +1534,9 @@ where
|
||||
) -> Result<(SignedBeaconBlockHash, SignedBeaconBlock<E>, BeaconState<E>), BlockError<E>> {
|
||||
self.set_current_slot(slot);
|
||||
let (block, new_state) = self.make_block(state, slot).await;
|
||||
let block_hash = self.process_block(slot, block.clone()).await?;
|
||||
let block_hash = self
|
||||
.process_block(slot, block.canonical_root(), block.clone())
|
||||
.await?;
|
||||
Ok((block_hash, block, new_state))
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user