mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-02 16:21:42 +00:00
move execution pending envelolpe logic to its own file
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use slot_clock::SlotClock;
|
||||
use state_processing::{
|
||||
VerifySignatures,
|
||||
envelope_processing::{VerifyStateRoot, process_execution_payload_envelope},
|
||||
};
|
||||
use types::{EthSpec, SignedExecutionPayloadEnvelope};
|
||||
|
||||
use crate::{
|
||||
BeaconChain, BeaconChainError, BeaconChainTypes, NotifyExecutionLayer,
|
||||
PayloadVerificationOutcome,
|
||||
block_verification::PayloadVerificationHandle,
|
||||
payload_envelope_verification::{
|
||||
EnvelopeError, EnvelopeImportData, MaybeAvailableEnvelope,
|
||||
gossip_verified_envelope::GossipVerifiedEnvelope, load_snapshot,
|
||||
payload_notifier::PayloadNotifier,
|
||||
},
|
||||
};
|
||||
|
||||
pub trait IntoExecutionPendingEnvelope<T: BeaconChainTypes>: Sized {
|
||||
fn into_execution_pending_envelope(
|
||||
self,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
notify_execution_layer: NotifyExecutionLayer,
|
||||
) -> Result<ExecutionPendingEnvelope<T::EthSpec>, EnvelopeError>;
|
||||
|
||||
fn envelope(&self) -> &Arc<SignedExecutionPayloadEnvelope<T::EthSpec>>;
|
||||
}
|
||||
|
||||
pub struct ExecutionPendingEnvelope<E: EthSpec> {
|
||||
pub signed_envelope: MaybeAvailableEnvelope<E>,
|
||||
pub import_data: EnvelopeImportData<E>,
|
||||
pub payload_verification_handle: PayloadVerificationHandle,
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> IntoExecutionPendingEnvelope<T> for GossipVerifiedEnvelope<T> {
|
||||
fn into_execution_pending_envelope(
|
||||
self,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
notify_execution_layer: NotifyExecutionLayer,
|
||||
) -> Result<ExecutionPendingEnvelope<T::EthSpec>, EnvelopeError> {
|
||||
let signed_envelope = self.signed_envelope;
|
||||
let envelope = &signed_envelope.message;
|
||||
let payload = &envelope.payload;
|
||||
|
||||
// Verify the execution payload is valid
|
||||
let payload_notifier = PayloadNotifier::new(
|
||||
chain.clone(),
|
||||
signed_envelope.clone(),
|
||||
self.block.clone(),
|
||||
notify_execution_layer,
|
||||
)?;
|
||||
let block_root = envelope.beacon_block_root;
|
||||
let slot = self.block.slot();
|
||||
|
||||
let payload_verification_future = async move {
|
||||
let chain = payload_notifier.chain.clone();
|
||||
if let Some(started_execution) = chain.slot_clock.now_duration() {
|
||||
chain
|
||||
.envelope_times_cache
|
||||
.write()
|
||||
.set_time_started_execution(block_root, slot, started_execution);
|
||||
}
|
||||
|
||||
let payload_verification_status = payload_notifier.notify_new_payload().await?;
|
||||
Ok(PayloadVerificationOutcome {
|
||||
payload_verification_status,
|
||||
// This fork is after the merge so it'll never be the merge transition block
|
||||
is_valid_merge_transition_block: false,
|
||||
})
|
||||
};
|
||||
// Spawn the payload verification future as a new task, but don't wait for it to complete.
|
||||
// The `payload_verification_future` will be awaited later to ensure verification completed
|
||||
// successfully.
|
||||
let payload_verification_handle = chain
|
||||
.task_executor
|
||||
.spawn_handle(
|
||||
payload_verification_future,
|
||||
"execution_payload_verification",
|
||||
)
|
||||
.ok_or(BeaconChainError::RuntimeShutdown)?;
|
||||
|
||||
let snapshot = if let Some(snapshot) = self.snapshot {
|
||||
*snapshot
|
||||
} else {
|
||||
load_snapshot(
|
||||
signed_envelope.as_ref(),
|
||||
&chain.canonical_head,
|
||||
&chain.store,
|
||||
)?
|
||||
};
|
||||
let mut state = snapshot.pre_state;
|
||||
|
||||
// All the state modifications are done in envelope_processing
|
||||
process_execution_payload_envelope(
|
||||
&mut state,
|
||||
Some(snapshot.state_root),
|
||||
&signed_envelope,
|
||||
// verify signature already done for GossipVerifiedEnvelope
|
||||
VerifySignatures::False,
|
||||
VerifyStateRoot::True,
|
||||
&chain.spec,
|
||||
)?;
|
||||
|
||||
Ok(ExecutionPendingEnvelope {
|
||||
signed_envelope: MaybeAvailableEnvelope::AvailabilityPending {
|
||||
block_hash: payload.block_hash,
|
||||
envelope: signed_envelope,
|
||||
},
|
||||
import_data: EnvelopeImportData {
|
||||
block_root,
|
||||
block: self.block,
|
||||
post_state: Box::new(state),
|
||||
},
|
||||
payload_verification_handle,
|
||||
})
|
||||
}
|
||||
|
||||
fn envelope(&self) -> &Arc<SignedExecutionPayloadEnvelope<T::EthSpec>> {
|
||||
&self.signed_envelope
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> IntoExecutionPendingEnvelope<T>
|
||||
for Arc<SignedExecutionPayloadEnvelope<T::EthSpec>>
|
||||
{
|
||||
fn into_execution_pending_envelope(
|
||||
self,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
notify_execution_layer: NotifyExecutionLayer,
|
||||
) -> Result<ExecutionPendingEnvelope<T::EthSpec>, EnvelopeError> {
|
||||
GossipVerifiedEnvelope::new(self, &chain.gossip_verification_context())?
|
||||
.into_execution_pending_envelope(chain, notify_execution_layer)
|
||||
}
|
||||
|
||||
fn envelope(&self) -> &Arc<SignedExecutionPayloadEnvelope<T::EthSpec>> {
|
||||
self
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,6 @@ use std::sync::Arc;
|
||||
|
||||
use educe::Educe;
|
||||
use parking_lot::{Mutex, RwLock};
|
||||
use slot_clock::SlotClock;
|
||||
use state_processing::{
|
||||
VerifySignatures,
|
||||
envelope_processing::{VerifyStateRoot, process_execution_payload_envelope},
|
||||
};
|
||||
use store::DatabaseBlock;
|
||||
use tracing::{Span, debug};
|
||||
use types::{
|
||||
@@ -15,14 +10,11 @@ use types::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
BeaconChain, BeaconChainError, BeaconChainTypes, BeaconStore, NotifyExecutionLayer,
|
||||
PayloadVerificationOutcome,
|
||||
BeaconChain, BeaconChainError, BeaconChainTypes, BeaconStore,
|
||||
beacon_proposer_cache::{self, BeaconProposerCache},
|
||||
canonical_head::CanonicalHead,
|
||||
payload_envelope_verification::{
|
||||
EnvelopeError, EnvelopeImportData, EnvelopeProcessingSnapshot, ExecutionPendingEnvelope,
|
||||
IntoExecutionPendingEnvelope, MaybeAvailableEnvelope, load_snapshot,
|
||||
load_snapshot_from_state_root, payload_notifier::PayloadNotifier,
|
||||
EnvelopeError, EnvelopeProcessingSnapshot, load_snapshot_from_state_root,
|
||||
},
|
||||
validator_pubkey_cache::ValidatorPubkeyCache,
|
||||
};
|
||||
@@ -234,94 +226,6 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> IntoExecutionPendingEnvelope<T> for GossipVerifiedEnvelope<T> {
|
||||
fn into_execution_pending_envelope(
|
||||
self,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
notify_execution_layer: NotifyExecutionLayer,
|
||||
) -> Result<ExecutionPendingEnvelope<T::EthSpec>, EnvelopeError> {
|
||||
let signed_envelope = self.signed_envelope;
|
||||
let envelope = &signed_envelope.message;
|
||||
let payload = &envelope.payload;
|
||||
|
||||
// Verify the execution payload is valid
|
||||
let payload_notifier = PayloadNotifier::new(
|
||||
chain.clone(),
|
||||
signed_envelope.clone(),
|
||||
self.block.clone(),
|
||||
notify_execution_layer,
|
||||
)?;
|
||||
let block_root = envelope.beacon_block_root;
|
||||
let slot = self.block.slot();
|
||||
|
||||
let payload_verification_future = async move {
|
||||
let chain = payload_notifier.chain.clone();
|
||||
if let Some(started_execution) = chain.slot_clock.now_duration() {
|
||||
chain
|
||||
.envelope_times_cache
|
||||
.write()
|
||||
.set_time_started_execution(block_root, slot, started_execution);
|
||||
}
|
||||
|
||||
let payload_verification_status = payload_notifier.notify_new_payload().await?;
|
||||
Ok(PayloadVerificationOutcome {
|
||||
payload_verification_status,
|
||||
// This fork is after the merge so it'll never be the merge transition block
|
||||
is_valid_merge_transition_block: false,
|
||||
})
|
||||
};
|
||||
// Spawn the payload verification future as a new task, but don't wait for it to complete.
|
||||
// The `payload_verification_future` will be awaited later to ensure verification completed
|
||||
// successfully.
|
||||
let payload_verification_handle = chain
|
||||
.task_executor
|
||||
.spawn_handle(
|
||||
payload_verification_future,
|
||||
"execution_payload_verification",
|
||||
)
|
||||
.ok_or(BeaconChainError::RuntimeShutdown)?;
|
||||
|
||||
let snapshot = if let Some(snapshot) = self.snapshot {
|
||||
*snapshot
|
||||
} else {
|
||||
load_snapshot(
|
||||
signed_envelope.as_ref(),
|
||||
&chain.canonical_head,
|
||||
&chain.store,
|
||||
)?
|
||||
};
|
||||
let mut state = snapshot.pre_state;
|
||||
|
||||
// All the state modifications are done in envelope_processing
|
||||
process_execution_payload_envelope(
|
||||
&mut state,
|
||||
Some(snapshot.state_root),
|
||||
&signed_envelope,
|
||||
// verify signature already done for GossipVerifiedEnvelope
|
||||
VerifySignatures::False,
|
||||
VerifyStateRoot::True,
|
||||
&chain.spec,
|
||||
)?;
|
||||
|
||||
Ok(ExecutionPendingEnvelope {
|
||||
signed_envelope: MaybeAvailableEnvelope::AvailabilityPending {
|
||||
block_hash: payload.block_hash,
|
||||
envelope: signed_envelope,
|
||||
},
|
||||
import_data: EnvelopeImportData {
|
||||
block_root,
|
||||
block: self.block,
|
||||
post_state: Box::new(state),
|
||||
},
|
||||
payload_verification_handle,
|
||||
})
|
||||
}
|
||||
|
||||
fn envelope(&self) -> &Arc<SignedExecutionPayloadEnvelope<T::EthSpec>> {
|
||||
&self.signed_envelope
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
/// Build a `GossipVerificationContext` from this `BeaconChain`.
|
||||
pub fn gossip_verification_context(&self) -> GossipVerificationContext<'_, T> {
|
||||
|
||||
@@ -39,31 +39,16 @@ use types::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
BeaconChain, BeaconChainError, BeaconChainTypes, BeaconStore, BlockError,
|
||||
ExecutionPayloadError, NotifyExecutionLayer, PayloadVerificationOutcome,
|
||||
block_verification::PayloadVerificationHandle, canonical_head::CanonicalHead,
|
||||
payload_envelope_verification::gossip_verified_envelope::GossipVerifiedEnvelope,
|
||||
BeaconChainError, BeaconChainTypes, BeaconStore, BlockError, ExecutionPayloadError,
|
||||
PayloadVerificationOutcome, canonical_head::CanonicalHead,
|
||||
};
|
||||
|
||||
pub mod execution_pending_envelope;
|
||||
pub mod gossip_verified_envelope;
|
||||
pub mod import;
|
||||
mod payload_notifier;
|
||||
|
||||
pub trait IntoExecutionPendingEnvelope<T: BeaconChainTypes>: Sized {
|
||||
fn into_execution_pending_envelope(
|
||||
self,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
notify_execution_layer: NotifyExecutionLayer,
|
||||
) -> Result<ExecutionPendingEnvelope<T::EthSpec>, EnvelopeError>;
|
||||
|
||||
fn envelope(&self) -> &Arc<SignedExecutionPayloadEnvelope<T::EthSpec>>;
|
||||
}
|
||||
|
||||
pub struct ExecutionPendingEnvelope<E: EthSpec> {
|
||||
pub signed_envelope: MaybeAvailableEnvelope<E>,
|
||||
pub import_data: EnvelopeImportData<E>,
|
||||
pub payload_verification_handle: PayloadVerificationHandle,
|
||||
}
|
||||
pub use execution_pending_envelope::{ExecutionPendingEnvelope, IntoExecutionPendingEnvelope};
|
||||
|
||||
#[derive(PartialEq)]
|
||||
pub struct EnvelopeImportData<E: EthSpec> {
|
||||
@@ -348,20 +333,3 @@ pub(crate) fn load_snapshot<T: BeaconChainTypes>(
|
||||
|
||||
load_snapshot_from_state_root::<T>(beacon_block_root, proto_beacon_block.state_root, store)
|
||||
}
|
||||
|
||||
impl<T: BeaconChainTypes> IntoExecutionPendingEnvelope<T>
|
||||
for Arc<SignedExecutionPayloadEnvelope<T::EthSpec>>
|
||||
{
|
||||
fn into_execution_pending_envelope(
|
||||
self,
|
||||
chain: &Arc<BeaconChain<T>>,
|
||||
notify_execution_layer: NotifyExecutionLayer,
|
||||
) -> Result<ExecutionPendingEnvelope<T::EthSpec>, EnvelopeError> {
|
||||
GossipVerifiedEnvelope::new(self, &chain.gossip_verification_context())?
|
||||
.into_execution_pending_envelope(chain, notify_execution_layer)
|
||||
}
|
||||
|
||||
fn envelope(&self) -> &Arc<SignedExecutionPayloadEnvelope<T::EthSpec>> {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user