mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-06 10:11:44 +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 educe::Educe;
|
||||||
use parking_lot::{Mutex, RwLock};
|
use parking_lot::{Mutex, RwLock};
|
||||||
use slot_clock::SlotClock;
|
|
||||||
use state_processing::{
|
|
||||||
VerifySignatures,
|
|
||||||
envelope_processing::{VerifyStateRoot, process_execution_payload_envelope},
|
|
||||||
};
|
|
||||||
use store::DatabaseBlock;
|
use store::DatabaseBlock;
|
||||||
use tracing::{Span, debug};
|
use tracing::{Span, debug};
|
||||||
use types::{
|
use types::{
|
||||||
@@ -15,14 +10,11 @@ use types::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
BeaconChain, BeaconChainError, BeaconChainTypes, BeaconStore, NotifyExecutionLayer,
|
BeaconChain, BeaconChainError, BeaconChainTypes, BeaconStore,
|
||||||
PayloadVerificationOutcome,
|
|
||||||
beacon_proposer_cache::{self, BeaconProposerCache},
|
beacon_proposer_cache::{self, BeaconProposerCache},
|
||||||
canonical_head::CanonicalHead,
|
canonical_head::CanonicalHead,
|
||||||
payload_envelope_verification::{
|
payload_envelope_verification::{
|
||||||
EnvelopeError, EnvelopeImportData, EnvelopeProcessingSnapshot, ExecutionPendingEnvelope,
|
EnvelopeError, EnvelopeProcessingSnapshot, load_snapshot_from_state_root,
|
||||||
IntoExecutionPendingEnvelope, MaybeAvailableEnvelope, load_snapshot,
|
|
||||||
load_snapshot_from_state_root, payload_notifier::PayloadNotifier,
|
|
||||||
},
|
},
|
||||||
validator_pubkey_cache::ValidatorPubkeyCache,
|
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> {
|
impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||||
/// Build a `GossipVerificationContext` from this `BeaconChain`.
|
/// Build a `GossipVerificationContext` from this `BeaconChain`.
|
||||||
pub fn gossip_verification_context(&self) -> GossipVerificationContext<'_, T> {
|
pub fn gossip_verification_context(&self) -> GossipVerificationContext<'_, T> {
|
||||||
|
|||||||
@@ -39,31 +39,16 @@ use types::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
BeaconChain, BeaconChainError, BeaconChainTypes, BeaconStore, BlockError,
|
BeaconChainError, BeaconChainTypes, BeaconStore, BlockError, ExecutionPayloadError,
|
||||||
ExecutionPayloadError, NotifyExecutionLayer, PayloadVerificationOutcome,
|
PayloadVerificationOutcome, canonical_head::CanonicalHead,
|
||||||
block_verification::PayloadVerificationHandle, canonical_head::CanonicalHead,
|
|
||||||
payload_envelope_verification::gossip_verified_envelope::GossipVerifiedEnvelope,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub mod execution_pending_envelope;
|
||||||
pub mod gossip_verified_envelope;
|
pub mod gossip_verified_envelope;
|
||||||
pub mod import;
|
pub mod import;
|
||||||
mod payload_notifier;
|
mod payload_notifier;
|
||||||
|
|
||||||
pub trait IntoExecutionPendingEnvelope<T: BeaconChainTypes>: Sized {
|
pub use execution_pending_envelope::{ExecutionPendingEnvelope, IntoExecutionPendingEnvelope};
|
||||||
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,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct EnvelopeImportData<E: EthSpec> {
|
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)
|
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