mirror of
https://github.com/sigp/lighthouse.git
synced 2026-04-26 17:23:41 +00:00
implement scoring mechanisms and plumbing
This commit is contained in:
@@ -1441,7 +1441,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
.proto_array()
|
||||
.heads_descended_from_finalization::<T::EthSpec>(fork_choice.finalized_checkpoint())
|
||||
.iter()
|
||||
.map(|node| (node.root, node.slot))
|
||||
.map(|node| (node.root(), node.slot()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -4776,7 +4776,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
|
||||
// The slot of our potential re-org block is always 1 greater than the head block because we
|
||||
// only attempt single-slot re-orgs.
|
||||
let head_slot = info.head_node.slot;
|
||||
let head_slot = info.head_node.slot();
|
||||
let re_org_block_slot = head_slot + 1;
|
||||
let fork_choice_slot = info.current_slot;
|
||||
|
||||
@@ -4811,9 +4811,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
.fork_name_at_slot::<T::EthSpec>(re_org_block_slot)
|
||||
.fulu_enabled()
|
||||
{
|
||||
info.head_node.current_epoch_shuffling_id
|
||||
info.head_node.current_epoch_shuffling_id()
|
||||
} else {
|
||||
info.head_node.next_epoch_shuffling_id
|
||||
info.head_node.next_epoch_shuffling_id()
|
||||
}
|
||||
.shuffling_decision_block;
|
||||
let proposer_index = self
|
||||
@@ -4844,8 +4844,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
// and the actual weight of the parent against the parent re-org threshold.
|
||||
let (head_weak, parent_strong) = if fork_choice_slot == re_org_block_slot {
|
||||
(
|
||||
info.head_node.weight < info.re_org_head_weight_threshold,
|
||||
info.parent_node.weight > info.re_org_parent_weight_threshold,
|
||||
info.head_node.weight() < info.re_org_head_weight_threshold,
|
||||
info.parent_node.weight() > info.re_org_parent_weight_threshold,
|
||||
)
|
||||
} else {
|
||||
(true, true)
|
||||
@@ -4853,7 +4853,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
if !head_weak {
|
||||
return Err(Box::new(
|
||||
DoNotReOrg::HeadNotWeak {
|
||||
head_weight: info.head_node.weight,
|
||||
head_weight: info.head_node.weight(),
|
||||
re_org_head_weight_threshold: info.re_org_head_weight_threshold,
|
||||
}
|
||||
.into(),
|
||||
@@ -4862,7 +4862,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
if !parent_strong {
|
||||
return Err(Box::new(
|
||||
DoNotReOrg::ParentNotStrong {
|
||||
parent_weight: info.parent_node.weight,
|
||||
parent_weight: info.parent_node.weight(),
|
||||
re_org_parent_weight_threshold: info.re_org_parent_weight_threshold,
|
||||
}
|
||||
.into(),
|
||||
@@ -4880,9 +4880,13 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
return Err(Box::new(DoNotReOrg::HeadNotLate.into()));
|
||||
}
|
||||
|
||||
let parent_head_hash = info.parent_node.execution_status.block_hash();
|
||||
let parent_head_hash = info
|
||||
.parent_node
|
||||
.execution_status()
|
||||
.ok()
|
||||
.and_then(|execution_status| execution_status.block_hash());
|
||||
let forkchoice_update_params = ForkchoiceUpdateParameters {
|
||||
head_root: info.parent_node.root,
|
||||
head_root: info.parent_node.root(),
|
||||
head_hash: parent_head_hash,
|
||||
justified_hash: canonical_forkchoice_params.justified_hash,
|
||||
finalized_hash: canonical_forkchoice_params.finalized_hash,
|
||||
@@ -4890,7 +4894,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
|
||||
debug!(
|
||||
canonical_head = ?head_block_root,
|
||||
?info.parent_node.root,
|
||||
parent_root = ?info.parent_node.root(),
|
||||
slot = %fork_choice_slot,
|
||||
"Fork choice update overridden"
|
||||
);
|
||||
|
||||
@@ -200,7 +200,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
})
|
||||
.ok()?;
|
||||
drop(proposer_head_timer);
|
||||
let re_org_parent_block = proposer_head.parent_node.root;
|
||||
let re_org_parent_block = proposer_head.parent_node.root();
|
||||
|
||||
let (state_root, state) = self
|
||||
.store
|
||||
@@ -213,7 +213,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
|
||||
info!(
|
||||
weak_head = ?canonical_head,
|
||||
parent = ?re_org_parent_block,
|
||||
head_weight = proposer_head.head_node.weight,
|
||||
head_weight = proposer_head.head_node.weight(),
|
||||
threshold_weight = proposer_head.re_org_head_weight_threshold,
|
||||
"Attempting re-org due to weak head"
|
||||
);
|
||||
|
||||
@@ -1683,6 +1683,26 @@ impl<T: BeaconChainTypes> ExecutionPendingBlock<T> {
|
||||
Err(e) => Err(BlockError::BeaconChainError(Box::new(e.into()))),
|
||||
}?;
|
||||
}
|
||||
|
||||
// Register each payload attestation in the block with fork choice.
|
||||
if let Ok(payload_attestations) = block.message().body().payload_attestations() {
|
||||
for (i, payload_attestation) in payload_attestations.iter().enumerate() {
|
||||
let indexed_payload_attestation = consensus_context
|
||||
.get_indexed_payload_attestation(&state, payload_attestation, &chain.spec)
|
||||
.map_err(|e| BlockError::PerBlockProcessingError(e.into_with_index(i)))?;
|
||||
|
||||
match fork_choice.on_payload_attestation(
|
||||
current_slot,
|
||||
indexed_payload_attestation,
|
||||
AttestationFromBlock::True,
|
||||
) {
|
||||
Ok(()) => Ok(()),
|
||||
// Ignore invalid payload attestations whilst importing from a block.
|
||||
Err(ForkChoiceError::InvalidAttestation(_)) => Ok(()),
|
||||
Err(e) => Err(BlockError::BeaconChainError(Box::new(e.into()))),
|
||||
}?;
|
||||
}
|
||||
}
|
||||
drop(fork_choice);
|
||||
|
||||
Ok(Self {
|
||||
|
||||
@@ -9,10 +9,10 @@ use superstruct::superstruct;
|
||||
use types::Hash256;
|
||||
|
||||
// If adding a new version you should update this type alias and fix the breakages.
|
||||
pub type PersistedForkChoice = PersistedForkChoiceV28;
|
||||
pub type PersistedForkChoice = PersistedForkChoiceV29;
|
||||
|
||||
#[superstruct(
|
||||
variants(V17, V28),
|
||||
variants(V17, V28, V29),
|
||||
variant_attributes(derive(Encode, Decode)),
|
||||
no_enum
|
||||
)]
|
||||
@@ -20,10 +20,12 @@ pub struct PersistedForkChoice {
|
||||
#[superstruct(only(V17))]
|
||||
pub fork_choice_v17: fork_choice::PersistedForkChoiceV17,
|
||||
#[superstruct(only(V28))]
|
||||
pub fork_choice: fork_choice::PersistedForkChoiceV28,
|
||||
pub fork_choice_v28: fork_choice::PersistedForkChoiceV28,
|
||||
#[superstruct(only(V29))]
|
||||
pub fork_choice: fork_choice::PersistedForkChoiceV29,
|
||||
#[superstruct(only(V17))]
|
||||
pub fork_choice_store_v17: PersistedForkChoiceStoreV17,
|
||||
#[superstruct(only(V28))]
|
||||
#[superstruct(only(V28, V29))]
|
||||
pub fork_choice_store: PersistedForkChoiceStoreV28,
|
||||
}
|
||||
|
||||
@@ -47,7 +49,7 @@ macro_rules! impl_store_item {
|
||||
|
||||
impl_store_item!(PersistedForkChoiceV17);
|
||||
|
||||
impl PersistedForkChoiceV28 {
|
||||
impl PersistedForkChoiceV29 {
|
||||
pub fn from_bytes(bytes: &[u8], store_config: &StoreConfig) -> Result<Self, Error> {
|
||||
let decompressed_bytes = store_config
|
||||
.decompress_bytes(bytes)
|
||||
@@ -78,3 +80,12 @@ impl PersistedForkChoiceV28 {
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<PersistedForkChoiceV28> for PersistedForkChoiceV29 {
|
||||
fn from(v28: PersistedForkChoiceV28) -> Self {
|
||||
Self {
|
||||
fork_choice: v28.fork_choice_v28.into(),
|
||||
fork_choice_store: v28.fork_choice_store,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,22 +110,21 @@ pub fn downgrade_from_v23<T: BeaconChainTypes>(
|
||||
// Doesn't matter what policy we use for invalid payloads, as our head calculation just
|
||||
// considers descent from finalization.
|
||||
let reset_payload_statuses = ResetPayloadStatuses::OnlyWithInvalidPayload;
|
||||
let fork_choice = ForkChoice::from_persisted(
|
||||
persisted_fork_choice.fork_choice_v17.try_into()?,
|
||||
reset_payload_statuses,
|
||||
fc_store,
|
||||
&db.spec,
|
||||
)
|
||||
.map_err(|e| {
|
||||
Error::MigrationError(format!("Error loading fork choice from persisted: {e:?}"))
|
||||
})?;
|
||||
let persisted_fc_v28: fork_choice::PersistedForkChoiceV28 =
|
||||
persisted_fork_choice.fork_choice_v17.try_into()?;
|
||||
let persisted_fc_v29: fork_choice::PersistedForkChoiceV29 = persisted_fc_v28.into();
|
||||
let fork_choice =
|
||||
ForkChoice::from_persisted(persisted_fc_v29, reset_payload_statuses, fc_store, &db.spec)
|
||||
.map_err(|e| {
|
||||
Error::MigrationError(format!("Error loading fork choice from persisted: {e:?}"))
|
||||
})?;
|
||||
|
||||
let heads = fork_choice
|
||||
.proto_array()
|
||||
.heads_descended_from_finalization::<T::EthSpec>(fork_choice.finalized_checkpoint());
|
||||
|
||||
let head_roots = heads.iter().map(|node| node.root).collect();
|
||||
let head_slots = heads.iter().map(|node| node.slot).collect();
|
||||
let head_roots = heads.iter().map(|node| node.root()).collect();
|
||||
let head_slots = heads.iter().map(|node| node.slot()).collect();
|
||||
|
||||
let persisted_beacon_chain_v22 = PersistedBeaconChainV22 {
|
||||
_canonical_head_block_root: DUMMY_CANONICAL_HEAD_BLOCK_ROOT,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::{
|
||||
BeaconChain, BeaconChainTypes, BeaconForkChoiceStore, PersistedForkChoiceStoreV17,
|
||||
beacon_chain::FORK_CHOICE_DB_KEY,
|
||||
persisted_fork_choice::{PersistedForkChoiceV17, PersistedForkChoiceV28},
|
||||
persisted_fork_choice::PersistedForkChoiceV17,
|
||||
summaries_dag::{DAGStateSummary, StateSummariesDAG},
|
||||
};
|
||||
use fork_choice::{ForkChoice, ForkChoiceStore, ResetPayloadStatuses};
|
||||
@@ -88,8 +88,11 @@ pub fn upgrade_to_v28<T: BeaconChainTypes>(
|
||||
// Construct top-level ForkChoice struct using the patched fork choice store, and the converted
|
||||
// proto array.
|
||||
let reset_payload_statuses = ResetPayloadStatuses::OnlyWithInvalidPayload;
|
||||
let persisted_fc_v28: fork_choice::PersistedForkChoiceV28 =
|
||||
persisted_fork_choice_v17.fork_choice_v17.try_into()?;
|
||||
let persisted_fc_v29: fork_choice::PersistedForkChoiceV29 = persisted_fc_v28.into();
|
||||
let fork_choice = ForkChoice::from_persisted(
|
||||
persisted_fork_choice_v17.fork_choice_v17.try_into()?,
|
||||
persisted_fc_v29,
|
||||
reset_payload_statuses,
|
||||
fc_store,
|
||||
db.get_chain_spec(),
|
||||
@@ -118,26 +121,22 @@ pub fn downgrade_from_v28<T: BeaconChainTypes>(
|
||||
return Ok(vec![]);
|
||||
};
|
||||
|
||||
// Recreate V28 persisted fork choice, then convert each field back to its V17 version.
|
||||
let persisted_fork_choice = PersistedForkChoiceV28 {
|
||||
fork_choice: fork_choice.to_persisted(),
|
||||
fork_choice_store: fork_choice.fc_store().to_persisted(),
|
||||
};
|
||||
|
||||
let persisted_v29 = fork_choice.to_persisted();
|
||||
let fc_store_v28 = fork_choice.fc_store().to_persisted();
|
||||
let justified_balances = fork_choice.fc_store().justified_balances();
|
||||
|
||||
// 1. Create `proto_array::PersistedForkChoiceV17`.
|
||||
let fork_choice_v17: fork_choice::PersistedForkChoiceV17 = (
|
||||
persisted_fork_choice.fork_choice,
|
||||
justified_balances.clone(),
|
||||
)
|
||||
.into();
|
||||
// Convert V29 proto_array back to legacy V28 for downgrade.
|
||||
let persisted_fork_choice_v28 = fork_choice::PersistedForkChoiceV28 {
|
||||
proto_array_v28: persisted_v29.proto_array.into(),
|
||||
queued_attestations: persisted_v29.queued_attestations,
|
||||
};
|
||||
|
||||
let fork_choice_store_v17: PersistedForkChoiceStoreV17 = (
|
||||
persisted_fork_choice.fork_choice_store,
|
||||
justified_balances.clone(),
|
||||
)
|
||||
.into();
|
||||
// 1. Create `proto_array::PersistedForkChoiceV17`.
|
||||
let fork_choice_v17: fork_choice::PersistedForkChoiceV17 =
|
||||
(persisted_fork_choice_v28, justified_balances.clone()).into();
|
||||
|
||||
let fork_choice_store_v17: PersistedForkChoiceStoreV17 =
|
||||
(fc_store_v28, justified_balances.clone()).into();
|
||||
|
||||
let persisted_fork_choice_v17 = PersistedForkChoiceV17 {
|
||||
fork_choice_v17,
|
||||
|
||||
Reference in New Issue
Block a user