debugging

This commit is contained in:
Eitan Seri-Levi
2025-02-15 12:14:58 +02:00
parent 7eb040c70e
commit cdbdb5226d
23 changed files with 252 additions and 157 deletions

View File

@@ -1702,7 +1702,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// non-existing/inactive validators will have `None` values.
pub fn validator_inclusion_list_duties(
&self,
validator_indices: &[u64],
validator_indices_pubkeys: &[(usize, PublicKeyBytes)],
epoch: Epoch,
head_block_root: Hash256,
) -> Result<(Vec<Option<InclusionListDuty>>, Hash256), Error> {
@@ -1732,11 +1732,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
let Some(head_beacon_state) = head_beacon_state else {
return Err(Error::MissingBeaconState(head_block.root));
};
let duties = validator_indices
let duties = validator_indices_pubkeys
.iter()
.map(|&validator_index| {
.map(|(validator_index, pubkey_bytes)| {
head_beacon_state
.get_inclusion_list_duties(validator_index as usize, epoch, &self.spec)
.get_inclusion_list_duties(*pubkey_bytes, *validator_index, epoch, &self.spec)
.map_err(Error::InclusionListDutiesError)
})
.collect::<Result<Vec<_>, _>>()?;
@@ -2124,13 +2124,22 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// Use a blocking task since blocking the core executor on the canonical head read lock can
// block the core tokio executor.
let chain = self.clone();
let (head_slot, head_hash) = self
let (head_slot, parent_hash) = self
.spawn_blocking_handle(
move || {
let cached_head = chain.canonical_head.cached_head();
let head_slot = cached_head.head_slot();
let head_hash = cached_head.head_hash();
(head_slot, head_hash)
// let head_hash = cached_head.head_hash();
if let Ok(execution_payload) = cached_head
.snapshot
.beacon_block
.message()
.execution_payload()
{
(head_slot, Some(execution_payload.parent_hash()))
} else {
(head_slot, None)
}
},
"produce_inclusion_list_head_read",
)
@@ -2138,11 +2147,8 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// NOTE: not sure how to handle scenario where head hash is `None` i.e. pre-bellatrix, which
// is pre-electra.
let Some(head_hash) = head_hash else {
debug!(
self.log,
"Attempted to produce inclusion list pre-bellatrix"
);
let Some(parent_hash) = parent_hash else {
debug!(self.log, "Failed to fetch parent_hash");
return Ok(None);
};
@@ -2172,12 +2178,12 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
return Ok(None);
}
debug!(self.log, "Attempt to fetch IL from EL"; "parent_hash" => %parent_hash, "current_slot" => %current_slot);
// Retrieve the inclusion list from the execution layer.
let inclusion_list = execution_layer
.get_inclusion_list(head_hash.into_root())
.get_inclusion_list(parent_hash.0)
.await
.map_err(|e| Error::ExecutionLayerGetInclusionListFailed(Box::new(e)))?;
debug!(self.log, "Inclusion list fetched from EL"; "tx_count" => inclusion_list.len());
Ok(Some(inclusion_list))
@@ -7364,6 +7370,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
pub async fn set_unsatisfied_inclusion_list_block(
self: &Arc<Self>,
slot: Slot,
block_root: Hash256,
) -> Result<(), Error> {
let chain = self.clone();
@@ -7373,7 +7380,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
chain
.canonical_head
.fork_choice_write_lock()
.on_invalid_inclusion_list_payload(block_root)
.on_invalid_inclusion_list_payload(slot, block_root)
},
"invalid_inclusion_list_payload",
)

View File

@@ -141,7 +141,7 @@ pub struct BeaconForkChoiceStore<E: EthSpec, Hot: ItemStore<E>, Cold: ItemStore<
proposer_boost_root: Hash256,
equivocating_indices: BTreeSet<u64>,
inclusion_list_equivocators: HashMap<(Slot, Hash256), BTreeSet<u64>>,
unsatisfied_inclusion_list_block: Hash256,
unsatisfied_inclusion_list_blocks: HashMap<Slot, Hash256>,
_phantom: PhantomData<E>,
}
@@ -192,7 +192,7 @@ where
proposer_boost_root: Hash256::zero(),
equivocating_indices: BTreeSet::new(),
inclusion_list_equivocators: HashMap::new(),
unsatisfied_inclusion_list_block: Hash256::zero(),
unsatisfied_inclusion_list_blocks: HashMap::new(),
_phantom: PhantomData,
})
}
@@ -210,7 +210,6 @@ where
unrealized_finalized_checkpoint: self.unrealized_finalized_checkpoint,
proposer_boost_root: self.proposer_boost_root,
equivocating_indices: self.equivocating_indices.clone(),
unsatisfied_inclusion_list_block: self.unsatisfied_inclusion_list_block,
}
}
@@ -233,7 +232,7 @@ where
proposer_boost_root: persisted.proposer_boost_root,
equivocating_indices: persisted.equivocating_indices,
inclusion_list_equivocators: HashMap::new(),
unsatisfied_inclusion_list_block: persisted.unsatisfied_inclusion_list_block,
unsatisfied_inclusion_list_blocks: HashMap::new(),
_phantom: PhantomData,
})
}
@@ -352,12 +351,17 @@ where
self.equivocating_indices.extend(indices);
}
fn set_unsatisfied_inclusion_list_block(&mut self, block_root: Hash256) {
self.unsatisfied_inclusion_list_block = block_root;
fn set_unsatisfied_inclusion_list_block(&mut self, slot: Slot, block_root: Hash256) {
self.unsatisfied_inclusion_list_blocks
.insert(slot, block_root);
}
fn unsatisfied_inclusion_list_block(&self) -> &Hash256 {
&self.unsatisfied_inclusion_list_block
fn unsatisfied_inclusion_list_block(&self, slot: Slot) -> Option<&Hash256> {
self.unsatisfied_inclusion_list_blocks.get(&slot)
}
fn unsatisfied_inclusion_list_blocks(&self) -> &HashMap<Slot, Hash256> {
&self.unsatisfied_inclusion_list_blocks
}
}
@@ -375,5 +379,4 @@ pub struct PersistedForkChoiceStore {
pub unrealized_finalized_checkpoint: Checkpoint,
pub proposer_boost_root: Hash256,
pub equivocating_indices: BTreeSet<u64>,
pub unsatisfied_inclusion_list_block: Hash256,
}

View File

@@ -113,7 +113,7 @@ impl<T: BeaconChainTypes> PayloadNotifier<T> {
.get_inclusion_list_transactions(block.slot())
.unwrap_or(vec![].into());
debug!(chain.log, "Adding inclusion list transactions in the Payload Notifier"; "count" => inclusion_list_transactions.len());
debug!(chain.log, "Adding inclusion list transactions in the Payload Notifier"; "count" => inclusion_list_transactions.len(), "slot" => block.slot());
inclusion_list_transactions
} else {
vec![].into()
@@ -215,8 +215,15 @@ async fn notify_new_payload<T: BeaconChainTypes>(
// transactions for this slot, update the fork choice store before processing
// the invalid EL payload.
if *validation_error == Some("INVALID_INCLUSION_LIST".to_string()) {
debug!(
chain.log,
"Unsatisfied inclusion list";
);
chain
.set_unsatisfied_inclusion_list_block(block.tree_hash_root())
.set_unsatisfied_inclusion_list_block(
block.slot(),
block.tree_hash_root(),
)
.await?;
}

View File

@@ -6,13 +6,9 @@ use types::{Domain, EthSpec, SignedInclusionList, SignedRoot, Slot};
#[derive(Debug, AsRefStr)]
pub enum GossipInclusionListError {
FutureSlot {
InvalidSlot {
message_slot: Slot,
latest_permissible_slot: Slot,
},
PastSlot {
message_slot: Slot,
earliest_permissible_slot: Slot,
current_slot: Slot,
},
InvalidCommitteeRoot,
ValidatorNotInCommittee,
@@ -40,24 +36,16 @@ impl<T: BeaconChainTypes> GossipVerifiedInclusionList<T> {
) -> Result<Self, GossipInclusionListError> {
// the slot is equal to the previous slot or the current slot
let message_slot = signed_il.message.slot;
let earliest_permissible_slot = chain
let current_slot = chain
.slot_clock
.now_with_past_tolerance(chain.spec.maximum_gossip_clock_disparity())
.now()
.ok_or(BeaconChainError::UnableToReadSlot)?;
if message_slot < earliest_permissible_slot {
return Err(GossipInclusionListError::PastSlot {
if message_slot != current_slot + 1 {
return Err(GossipInclusionListError::InvalidSlot {
message_slot,
earliest_permissible_slot,
});
}
let latest_permissible_slot = chain
.slot_clock
.now_with_future_tolerance(chain.spec.maximum_gossip_clock_disparity())
.ok_or(BeaconChainError::UnableToReadSlot)?;
if message_slot > latest_permissible_slot {
return Err(GossipInclusionListError::FutureSlot {
message_slot,
latest_permissible_slot,
current_slot,
});
}