mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-08 01:05:47 +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::{
|
payload_envelope_verification::{
|
||||||
EnvelopeError, EnvelopeImportData, EnvelopeProcessingSnapshot, ExecutionPendingEnvelope,
|
EnvelopeError, EnvelopeImportData, EnvelopeProcessingSnapshot, ExecutionPendingEnvelope,
|
||||||
IntoExecutionPendingEnvelope, MaybeAvailableEnvelope, load_snapshot,
|
IntoExecutionPendingEnvelope, MaybeAvailableEnvelope, load_snapshot,
|
||||||
payload_notifier::PayloadNotifier,
|
load_snapshot_from_state_root, payload_notifier::PayloadNotifier,
|
||||||
},
|
},
|
||||||
validator_pubkey_cache::ValidatorPubkeyCache,
|
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 {
|
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.
|
// 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 mut opt_snapshot = None;
|
||||||
let proposer = beacon_proposer_cache::with_proposer_cache(
|
let proposer = beacon_proposer_cache::with_proposer_cache(
|
||||||
ctx.beacon_proposer_cache,
|
ctx.beacon_proposer_cache,
|
||||||
@@ -174,7 +173,11 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
|||||||
%beacon_block_root,
|
%beacon_block_root,
|
||||||
"Proposer shuffling cache miss for envelope verification"
|
"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()));
|
opt_snapshot = Some(Box::new(snapshot.clone()));
|
||||||
Ok::<_, EnvelopeError>((snapshot.state_root, snapshot.pre_state))
|
Ok::<_, EnvelopeError>((snapshot.state_root, snapshot.pre_state))
|
||||||
},
|
},
|
||||||
@@ -205,7 +208,11 @@ impl<T: BeaconChainTypes> GossipVerifiedEnvelope<T> {
|
|||||||
} else {
|
} else {
|
||||||
// TODO(gloas) if we implement a builder pubkey cache, we'll need to use it here.
|
// 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.
|
// 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 =
|
let is_valid =
|
||||||
signed_envelope.verify_signature_with_state(&snapshot.pre_state, ctx.spec)?;
|
signed_envelope.verify_signature_with_state(&snapshot.pre_state, ctx.spec)?;
|
||||||
(is_valid, Some(Box::new(snapshot)))
|
(is_valid, Some(Box::new(snapshot)))
|
||||||
|
|||||||
@@ -291,35 +291,16 @@ impl From<EnvelopeProcessingError> for EnvelopeError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::type_complexity)]
|
#[allow(clippy::type_complexity)]
|
||||||
#[instrument(skip_all, level = "debug", fields(beacon_block_root = %envelope.beacon_block_root()))]
|
#[instrument(skip_all, level = "debug", fields(beacon_block_root = %beacon_block_root))]
|
||||||
pub(crate) fn load_snapshot<T: BeaconChainTypes>(
|
/// Load state from store given a known state root and block root.
|
||||||
envelope: &SignedExecutionPayloadEnvelope<T::EthSpec>,
|
/// Use this when the proto block has already been looked up from fork choice.
|
||||||
canonical_head: &CanonicalHead<T>,
|
pub(crate) fn load_snapshot_from_state_root<T: BeaconChainTypes>(
|
||||||
|
beacon_block_root: Hash256,
|
||||||
|
block_state_root: Hash256,
|
||||||
store: &BeaconStore<T>,
|
store: &BeaconStore<T>,
|
||||||
) -> Result<EnvelopeProcessingSnapshot<T::EthSpec>, EnvelopeError> {
|
) -> 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
|
// 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
|
// 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).
|
// must be from the same slot as its block (so no advance is required).
|
||||||
let cache_state = true;
|
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>
|
impl<T: BeaconChainTypes> IntoExecutionPendingEnvelope<T>
|
||||||
for Arc<SignedExecutionPayloadEnvelope<T::EthSpec>>
|
for Arc<SignedExecutionPayloadEnvelope<T::EthSpec>>
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user