mirror of
https://github.com/sigp/lighthouse.git
synced 2026-05-30 04:37:13 +00:00
Ignore impossible attestation tests
See: https://github.com/ethereum/consensus-specs/issues/5271
This commit is contained in:
@@ -665,6 +665,13 @@ impl<E: EthSpec> Tester<E> {
|
|||||||
columns: Option<DataColumnSidecarList<E>>,
|
columns: Option<DataColumnSidecarList<E>>,
|
||||||
valid: bool,
|
valid: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
// Some fake-crypto EF fixtures contain block attestations that index to different
|
||||||
|
// validators depending on whether they are decoded against the block context or the
|
||||||
|
// attestation target context. Real BLS signatures should make these fixtures impossible.
|
||||||
|
if valid && self.block_attestations_have_divergent_indices(&block)? {
|
||||||
|
return Err(Error::SkippedKnownFailure);
|
||||||
|
}
|
||||||
|
|
||||||
let block_root = block.canonical_root();
|
let block_root = block.canonical_root();
|
||||||
|
|
||||||
let mut data_column_success = true;
|
let mut data_column_success = true;
|
||||||
@@ -720,18 +727,6 @@ impl<E: EthSpec> Tester<E> {
|
|||||||
self.apply_invalid_block(&block)?;
|
self.apply_invalid_block(&block)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per spec test runner: an on_block step implies receiving block's attestations
|
|
||||||
// and attester slashings.
|
|
||||||
if success {
|
|
||||||
for attestation in block.message().body().attestations() {
|
|
||||||
let att = attestation.clone_as_attestation();
|
|
||||||
let _ = self.process_attestation(&att);
|
|
||||||
}
|
|
||||||
for attester_slashing in block.message().body().attester_slashings() {
|
|
||||||
self.process_attester_slashing(attester_slashing)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -742,6 +737,13 @@ impl<E: EthSpec> Tester<E> {
|
|||||||
kzg_proofs: Option<Vec<KzgProof>>,
|
kzg_proofs: Option<Vec<KzgProof>>,
|
||||||
valid: bool,
|
valid: bool,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
|
// Some fake-crypto EF fixtures contain block attestations that index to different
|
||||||
|
// validators depending on whether they are decoded against the block context or the
|
||||||
|
// attestation target context. Real BLS signatures should make these fixtures impossible.
|
||||||
|
if valid && self.block_attestations_have_divergent_indices(&block)? {
|
||||||
|
return Err(Error::SkippedKnownFailure);
|
||||||
|
}
|
||||||
|
|
||||||
let block_root = block.canonical_root();
|
let block_root = block.canonical_root();
|
||||||
|
|
||||||
let mut blob_success = true;
|
let mut blob_success = true;
|
||||||
@@ -824,19 +826,141 @@ impl<E: EthSpec> Tester<E> {
|
|||||||
self.apply_invalid_block(&block)?;
|
self.apply_invalid_block(&block)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Per spec test runner: an on_block step implies receiving block's attestations
|
Ok(())
|
||||||
// and attester slashings.
|
|
||||||
if success {
|
|
||||||
for attestation in block.message().body().attestations() {
|
|
||||||
let att = attestation.clone_as_attestation();
|
|
||||||
let _ = self.process_attestation(&att);
|
|
||||||
}
|
}
|
||||||
for attester_slashing in block.message().body().attester_slashings() {
|
|
||||||
self.process_attester_slashing(attester_slashing)?;
|
fn block_attestations_have_divergent_indices(
|
||||||
|
&self,
|
||||||
|
block: &SignedBeaconBlock<E>,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
let parent_root = block.parent_root();
|
||||||
|
let Some(parent_block) = self
|
||||||
|
.harness
|
||||||
|
.chain
|
||||||
|
.get_blinded_block(&parent_root)
|
||||||
|
.map_err(|e| Error::InternalError(format!("failed to load parent block: {e:?}")))?
|
||||||
|
else {
|
||||||
|
return Ok(false);
|
||||||
|
};
|
||||||
|
let parent_state_root = parent_block.state_root();
|
||||||
|
let Some(mut block_context_state) = self
|
||||||
|
.harness
|
||||||
|
.chain
|
||||||
|
.get_state(
|
||||||
|
&parent_state_root,
|
||||||
|
Some(parent_block.slot()),
|
||||||
|
CACHE_STATE_IN_TESTS,
|
||||||
|
)
|
||||||
|
.map_err(|e| Error::InternalError(format!("failed to load parent state: {e:?}")))?
|
||||||
|
else {
|
||||||
|
return Ok(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
complete_state_advance(
|
||||||
|
&mut block_context_state,
|
||||||
|
Some(parent_state_root),
|
||||||
|
block.slot(),
|
||||||
|
&self.harness.chain.spec,
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
Error::InternalError(format!("failed to advance block context state: {e:?}"))
|
||||||
|
})?;
|
||||||
|
block_context_state
|
||||||
|
.build_all_committee_caches(&self.harness.chain.spec)
|
||||||
|
.map_err(|e| {
|
||||||
|
Error::InternalError(format!(
|
||||||
|
"failed to build block context committee caches: {e:?}"
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
for attestation in block.message().body().attestations() {
|
||||||
|
let attestation = attestation.clone_as_attestation();
|
||||||
|
let Ok(block_context_indexed) =
|
||||||
|
Self::indexed_attestation_from_state(&block_context_state, &attestation)
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let Some(target_context_indexed) =
|
||||||
|
self.indexed_attestation_from_target_state(&attestation)?
|
||||||
|
else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if block_context_indexed.attesting_indices_to_vec()
|
||||||
|
!= target_context_indexed.attesting_indices_to_vec()
|
||||||
|
{
|
||||||
|
return Ok(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn indexed_attestation_from_target_state(
|
||||||
|
&self,
|
||||||
|
attestation: &Attestation<E>,
|
||||||
|
) -> Result<Option<IndexedAttestation<E>>, Error> {
|
||||||
|
let target_root = attestation.data().target.root;
|
||||||
|
let Some(target_block) = self
|
||||||
|
.harness
|
||||||
|
.chain
|
||||||
|
.canonical_head
|
||||||
|
.fork_choice_read_lock()
|
||||||
|
.get_block(&target_root)
|
||||||
|
else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
let Some(mut target_state) = self
|
||||||
|
.harness
|
||||||
|
.chain
|
||||||
|
.store
|
||||||
|
.get_hot_state(&target_block.state_root, CACHE_STATE_IN_TESTS)
|
||||||
|
.map_err(|e| Error::InternalError(format!("failed to load target state: {e:?}")))?
|
||||||
|
else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
let target_epoch_start_slot = attestation
|
||||||
|
.data()
|
||||||
|
.target
|
||||||
|
.epoch
|
||||||
|
.start_slot(E::slots_per_epoch());
|
||||||
|
complete_state_advance(
|
||||||
|
&mut target_state,
|
||||||
|
Some(target_block.state_root),
|
||||||
|
target_epoch_start_slot,
|
||||||
|
&self.harness.chain.spec,
|
||||||
|
)
|
||||||
|
.map_err(|e| {
|
||||||
|
Error::InternalError(format!("failed to advance attestation target state: {e:?}"))
|
||||||
|
})?;
|
||||||
|
|
||||||
|
match Self::indexed_attestation_from_state(&target_state, attestation) {
|
||||||
|
Ok(indexed_attestation) => Ok(Some(indexed_attestation)),
|
||||||
|
Err(_) => Ok(None),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn indexed_attestation_from_state(
|
||||||
|
state: &BeaconState<E>,
|
||||||
|
attestation: &Attestation<E>,
|
||||||
|
) -> Result<IndexedAttestation<E>, Error> {
|
||||||
|
match attestation.to_ref() {
|
||||||
|
AttestationRef::Base(att) => {
|
||||||
|
let committee = state
|
||||||
|
.get_beacon_committee(att.data.slot, att.data.index)
|
||||||
|
.map_err(|e| {
|
||||||
|
Error::InternalError(format!("attestation committee lookup failed: {e:?}"))
|
||||||
|
})?;
|
||||||
|
attesting_indices_base::get_indexed_attestation(committee.committee, att).map_err(
|
||||||
|
|e| Error::InternalError(format!("attestation indexing failed: {e:?}")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
AttestationRef::Electra(att) => {
|
||||||
|
attesting_indices_electra::get_indexed_attestation_from_state(state, att).map_err(
|
||||||
|
|e| Error::InternalError(format!("attestation indexing failed: {e:?}")),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply invalid blocks directly against the fork choice `on_block` function. This ensures
|
// Apply invalid blocks directly against the fork choice `on_block` function. This ensures
|
||||||
@@ -910,61 +1034,14 @@ impl<E: EthSpec> Tester<E> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn process_attestation(&self, attestation: &Attestation<E>) -> Result<(), Error> {
|
pub fn process_attestation(&self, attestation: &Attestation<E>) -> Result<(), Error> {
|
||||||
let target_root = attestation.data().target.root;
|
let indexed_attestation = self
|
||||||
let target_block = self
|
.indexed_attestation_from_target_state(attestation)?
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.canonical_head
|
|
||||||
.fork_choice_read_lock()
|
|
||||||
.get_block(&target_root)
|
|
||||||
.ok_or_else(|| {
|
|
||||||
Error::InternalError(format!("attestation target block {target_root:?} unknown"))
|
|
||||||
})?;
|
|
||||||
let mut target_state = self
|
|
||||||
.harness
|
|
||||||
.chain
|
|
||||||
.store
|
|
||||||
.get_hot_state(&target_block.state_root, CACHE_STATE_IN_TESTS)
|
|
||||||
.map_err(|e| Error::InternalError(format!("failed to load target state: {e:?}")))?
|
|
||||||
.ok_or_else(|| {
|
.ok_or_else(|| {
|
||||||
Error::InternalError(format!(
|
Error::InternalError(format!(
|
||||||
"attestation target state {:?} unknown",
|
"attestation target block {:?} unknown or could not be indexed from target state",
|
||||||
target_block.state_root
|
attestation.data().target.root
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
let target_epoch_start_slot = attestation
|
|
||||||
.data()
|
|
||||||
.target
|
|
||||||
.epoch
|
|
||||||
.start_slot(E::slots_per_epoch());
|
|
||||||
complete_state_advance(
|
|
||||||
&mut target_state,
|
|
||||||
Some(target_block.state_root),
|
|
||||||
target_epoch_start_slot,
|
|
||||||
&self.harness.chain.spec,
|
|
||||||
)
|
|
||||||
.map_err(|e| {
|
|
||||||
Error::InternalError(format!("failed to advance attestation target state: {e:?}"))
|
|
||||||
})?;
|
|
||||||
|
|
||||||
let indexed_attestation = match attestation.to_ref() {
|
|
||||||
AttestationRef::Base(att) => {
|
|
||||||
let committee = target_state
|
|
||||||
.get_beacon_committee(att.data.slot, att.data.index)
|
|
||||||
.map_err(|e| {
|
|
||||||
Error::InternalError(format!("attestation committee lookup failed: {e:?}"))
|
|
||||||
})?;
|
|
||||||
attesting_indices_base::get_indexed_attestation(committee.committee, att).map_err(
|
|
||||||
|e| Error::InternalError(format!("attestation indexing failed: {e:?}")),
|
|
||||||
)?
|
|
||||||
}
|
|
||||||
AttestationRef::Electra(att) => {
|
|
||||||
attesting_indices_electra::get_indexed_attestation_from_state(&target_state, att)
|
|
||||||
.map_err(|e| {
|
|
||||||
Error::InternalError(format!("attestation indexing failed: {e:?}"))
|
|
||||||
})?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let verified_attestation: ManuallyVerifiedAttestation<EphemeralHarnessType<E>> =
|
let verified_attestation: ManuallyVerifiedAttestation<EphemeralHarnessType<E>> =
|
||||||
ManuallyVerifiedAttestation {
|
ManuallyVerifiedAttestation {
|
||||||
attestation,
|
attestation,
|
||||||
|
|||||||
Reference in New Issue
Block a user