mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-30 12:47:05 +00:00
add IL service to download IL from EL, sign in VC, and publish via BN
add HTTP API to the beacon node to retrieve IL from the EL. add IL service in the validator client to download the IL from the beacon node. add logic to the beacon node to package the IL for the validator client. add HTTP API to the beacon node to gossip signed ILs. the validator client will sign the ILs from the beacon node and resubmit to the beacon node to gossip.
This commit is contained in:
@@ -2044,6 +2044,85 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
)?)
|
||||
}
|
||||
|
||||
/// Produce an `InclusionList` that is valid for the given `slot`.
|
||||
///
|
||||
/// The produced `InclusionList` will not be valid until it has been signed by exactly one
|
||||
/// validator that is in the inclusion list committee for `slot` in the canonical chain.
|
||||
///
|
||||
/// ## Errors
|
||||
///
|
||||
/// May return an error if the `request_slot` is too far behind the head state.
|
||||
pub async fn produce_inclusion_list(
|
||||
self: &Arc<Self>,
|
||||
request_slot: Slot,
|
||||
) -> Result<Option<InclusionListTransactions<T::EthSpec>>, Error> {
|
||||
let execution_layer = self
|
||||
.execution_layer
|
||||
.clone()
|
||||
.ok_or(Error::ExecutionLayerMissing)?;
|
||||
|
||||
// Load the cached head and the associated block hash and slot.
|
||||
//
|
||||
// Use a blocking task since blocking the core executor on the canonical head read lock can
|
||||
// block the core tokio executor.
|
||||
let chain = self.clone();
|
||||
let (head_slot, head_hash) = self
|
||||
.spawn_blocking_handle(
|
||||
move || {
|
||||
let cached_head = chain.canonical_head.cached_head();
|
||||
let head_slot = cached_head.head_slot();
|
||||
let head_hash = cached_head.head_hash();
|
||||
(head_slot, head_hash)
|
||||
},
|
||||
"produce_inclusion_list_head_read",
|
||||
)
|
||||
.await?;
|
||||
|
||||
// NOTE: not sure how to handle scenario where head hash is `None` i.e. pre-bellatrix, which
|
||||
// is pre-electra.
|
||||
let Some(head_hash) = head_hash else {
|
||||
debug!(
|
||||
self.log,
|
||||
"Attempted to produce inclusion list pre-bellatrix"
|
||||
);
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let current_slot = self.slot()?;
|
||||
let next_slot = current_slot.safe_add(1)?;
|
||||
|
||||
// Don't bother with the inclusion list if the head is not the current slot.
|
||||
//
|
||||
// This prevents the routine from running during sync.
|
||||
if head_slot != current_slot {
|
||||
debug!(
|
||||
self.log,
|
||||
"Head too old for inclusion list";
|
||||
"head_slot" => %head_slot,
|
||||
"current_slot" => %current_slot,
|
||||
);
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Don't bother with the inclusion list if the request slot is not the next
|
||||
// slot.
|
||||
//
|
||||
// NOTE: does this represent a critical error? should we return an error here or log crit?
|
||||
// is this check redundant?
|
||||
if request_slot != next_slot {
|
||||
debug!(self.log, "Inclusion list request slot not equal to next slot"; "request_slot" => %request_slot, "next_slot" => %next_slot);
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
// Retrieve the inclusion list from the execution layer.
|
||||
let inclusion_list = execution_layer
|
||||
.get_inclusion_list(head_hash.into_root())
|
||||
.await
|
||||
.map_err(|e| Error::ExecutionLayerGetInclusionListFailed(Box::new(e)))?;
|
||||
|
||||
Ok(Some(inclusion_list))
|
||||
}
|
||||
|
||||
/// Performs the same validation as `Self::verify_unaggregated_attestation_for_gossip`, but for
|
||||
/// multiple attestations using batch BLS verification. Batch verification can provide
|
||||
/// significant CPU-time savings compared to individual verification.
|
||||
|
||||
@@ -139,6 +139,11 @@ impl<E: EthSpec> CachedHead<E> {
|
||||
self.snapshot.beacon_block.slot()
|
||||
}
|
||||
|
||||
/// Returns the `execution_payload.block_hash` of the block at the head of the beacon chain.
|
||||
pub fn head_hash(&self) -> Option<ExecutionBlockHash> {
|
||||
self.head_hash
|
||||
}
|
||||
|
||||
/// Returns the `Fork` from the `BeaconState` at the head of the chain.
|
||||
pub fn head_fork(&self) -> Fork {
|
||||
self.snapshot.beacon_state.fork()
|
||||
|
||||
@@ -149,6 +149,7 @@ pub enum BeaconChainError {
|
||||
EngineGetCapabilititesFailed(Box<execution_layer::Error>),
|
||||
ExecutionLayerGetBlockByNumberFailed(Box<execution_layer::Error>),
|
||||
ExecutionLayerGetBlockByHashFailed(Box<execution_layer::Error>),
|
||||
ExecutionLayerGetInclusionListFailed(Box<execution_layer::Error>),
|
||||
BlockHashMissingFromExecutionLayer(ExecutionBlockHash),
|
||||
InconsistentPayloadReconstructed {
|
||||
slot: Slot,
|
||||
|
||||
Reference in New Issue
Block a user