mirror of
https://github.com/sigp/lighthouse.git
synced 2026-03-21 13:54:44 +00:00
add load_snapshot_from_state_root that can be used when we've already aquired a
This commit is contained in:
@@ -22,7 +22,7 @@ use crate::{
|
||||
payload_envelope_verification::{
|
||||
EnvelopeError, EnvelopeImportData, EnvelopeProcessingSnapshot, ExecutionPendingEnvelope,
|
||||
IntoExecutionPendingEnvelope, MaybeAvailableEnvelope, load_snapshot,
|
||||
payload_notifier::PayloadNotifier,
|
||||
load_snapshot_from_state_root, payload_notifier::PayloadNotifier,
|
||||
},
|
||||
validator_pubkey_cache::ValidatorPubkeyCache,
|
||||
};
|
||||
@@ -161,7 +161,6 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
||||
|
||||
let (signature_is_valid, opt_snapshot) = if builder_index == BUILDER_INDEX_SELF_BUILD {
|
||||
// Fast path: self-built envelopes can be verified without loading the state.
|
||||
let envelope_ref = signed_envelope.as_ref();
|
||||
let mut opt_snapshot = None;
|
||||
let proposer = beacon_proposer_cache::with_proposer_cache(
|
||||
ctx.beacon_proposer_cache,
|
||||
@@ -174,7 +173,11 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
||||
%beacon_block_root,
|
||||
"Proposer shuffling cache miss for envelope verification"
|
||||
);
|
||||
let snapshot = load_snapshot(envelope_ref, ctx.canonical_head, ctx.store)?;
|
||||
let snapshot = load_snapshot_from_state_root::<T>(
|
||||
beacon_block_root,
|
||||
proto_block.state_root,
|
||||
ctx.store,
|
||||
)?;
|
||||
opt_snapshot = Some(Box::new(snapshot.clone()));
|
||||
Ok::<_, EnvelopeError>((snapshot.state_root, snapshot.pre_state))
|
||||
},
|
||||
@@ -205,7 +208,11 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
||||
} else {
|
||||
// TODO(gloas) if we implement a builder pubkey cache, we'll need to use it here.
|
||||
// External builder: must load the state to get the builder pubkey.
|
||||
let snapshot = load_snapshot(signed_envelope.as_ref(), ctx.canonical_head, ctx.store)?;
|
||||
let snapshot = load_snapshot_from_state_root::<T>(
|
||||
beacon_block_root,
|
||||
proto_block.state_root,
|
||||
ctx.store,
|
||||
)?;
|
||||
let is_valid =
|
||||
signed_envelope.verify_signature_with_state(&snapshot.pre_state, ctx.spec)?;
|
||||
(is_valid, Some(Box::new(snapshot)))
|
||||
|
||||
@@ -291,35 +291,16 @@ impl From<EnvelopeProcessingError> for EnvelopeError {
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
#[instrument(skip_all, level = "debug", fields(beacon_block_root = %envelope.beacon_block_root()))]
|
||||
pub(crate) fn load_snapshot<T: BeaconChainTypes>(
|
||||
envelope: &SignedExecutionPayloadEnvelope<T::EthSpec>,
|
||||
canonical_head: &CanonicalHead<T>,
|
||||
#[instrument(skip_all, level = "debug", fields(beacon_block_root = %beacon_block_root))]
|
||||
/// Load state from store given a known state root and block root.
|
||||
/// Use this when the proto block has already been looked up from fork choice.
|
||||
pub(crate) fn load_snapshot_from_state_root<T: BeaconChainTypes>(
|
||||
beacon_block_root: Hash256,
|
||||
block_state_root: Hash256,
|
||||
store: &BeaconStore<T>,
|
||||
) -> Result<EnvelopeProcessingSnapshot<T::EthSpec>, EnvelopeError> {
|
||||
// Reject any envelope if its block is not known to fork choice.
|
||||
//
|
||||
// A block that is not in fork choice is either:
|
||||
//
|
||||
// - Not yet imported: we should reject this envelope because we should only import it after its parent block
|
||||
// has been fully imported.
|
||||
// - Pre-finalized: if the parent block is _prior_ to finalization, we should ignore the envelope
|
||||
// because it will revert finalization. Note that the finalized block is stored in fork
|
||||
// choice, so we will not reject any child of the finalized block (this is relevant during
|
||||
// genesis).
|
||||
|
||||
let fork_choice_read_lock = canonical_head.fork_choice_read_lock();
|
||||
let beacon_block_root = envelope.beacon_block_root();
|
||||
let Some(proto_beacon_block) = fork_choice_read_lock.get_block(&beacon_block_root) else {
|
||||
return Err(EnvelopeError::BlockRootUnknown {
|
||||
block_root: beacon_block_root,
|
||||
});
|
||||
};
|
||||
drop(fork_choice_read_lock);
|
||||
|
||||
// TODO(EIP-7732): add metrics here
|
||||
|
||||
let block_state_root = proto_beacon_block.state_root;
|
||||
// We can use `get_hot_state` here rather than `get_advanced_hot_state` because the envelope
|
||||
// must be from the same slot as its block (so no advance is required).
|
||||
let cache_state = true;
|
||||
@@ -339,6 +320,35 @@ pub(crate) fn load_snapshot<T: BeaconChainTypes>(
|
||||
})
|
||||
}
|
||||
|
||||
#[instrument(skip_all, level = "debug", fields(beacon_block_root = %envelope.beacon_block_root()))]
|
||||
pub(crate) fn load_snapshot<T: BeaconChainTypes>(
|
||||
envelope: &SignedExecutionPayloadEnvelope<T::EthSpec>,
|
||||
canonical_head: &CanonicalHead<T>,
|
||||
store: &BeaconStore<T>,
|
||||
) -> Result<EnvelopeProcessingSnapshot<T::EthSpec>, EnvelopeError> {
|
||||
// Reject any envelope if its block is not known to fork choice.
|
||||
//
|
||||
// A block that is not in fork choice is either:
|
||||
//
|
||||
// - Not yet imported: we should reject this envelope because we should only import it after
|
||||
// its parent block has been fully imported.
|
||||
// - Pre-finalized: if the parent block is _prior_ to finalization, we should ignore the
|
||||
// envelope because it will revert finalization. Note that the finalized block is stored in
|
||||
// fork choice, so we will not reject any child of the finalized block (this is relevant
|
||||
// during genesis).
|
||||
|
||||
let fork_choice_read_lock = canonical_head.fork_choice_read_lock();
|
||||
let beacon_block_root = envelope.beacon_block_root();
|
||||
let Some(proto_beacon_block) = fork_choice_read_lock.get_block(&beacon_block_root) else {
|
||||
return Err(EnvelopeError::BlockRootUnknown {
|
||||
block_root: beacon_block_root,
|
||||
});
|
||||
};
|
||||
drop(fork_choice_read_lock);
|
||||
|
||||
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>>
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user