mirror of
https://github.com/sigp/lighthouse.git
synced 2026-06-29 19:04:27 +00:00
Gloas alpha spec 9 (#9393)
Changes implemented Ensure bids are for a higher slot than their parent (https://github.com/ethereum/consensus-specs/pull/5302) Ignore PTC attestations for empty assigned slots (https://github.com/ethereum/consensus-specs/pull/5281) Limit should_build_on_full checks to the previous slot (https://github.com/ethereum/consensus-specs/pull/5309) Apply proposer boost if dependent roots match (https://github.com/ethereum/consensus-specs/pull/5306) Exclude slashed validators from proposing (EIP-8045) (https://github.com/ethereum/consensus-specs/pull/5115) Force the proposer to reorg late payloads (https://github.com/ethereum/consensus-specs/pull/5210) Remove support for old deposit mechanism in Fulu (https://github.com/ethereum/consensus-specs/pull/4704) Co-Authored-By: Eitan Seri-Levi <eserilev@ucsc.edu> Co-Authored-By: dapplion <35266934+dapplion@users.noreply.github.com> Co-Authored-By: Eitan Seri-Levi <eserilev@gmail.com> Co-Authored-By: Michael Sproul <michael@sigmaprime.io> Co-Authored-By: Michael Sproul <michaelsproul@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# To download/extract nightly tests, run:
|
||||
# CONSENSUS_SPECS_TEST_VERSION=nightly make
|
||||
CONSENSUS_SPECS_TEST_VERSION ?= v1.7.0-alpha.8
|
||||
CONSENSUS_SPECS_TEST_VERSION ?= v1.7.0-alpha.10
|
||||
REPO_NAME := consensus-spec-tests
|
||||
OUTPUT_DIR := ./$(REPO_NAME)
|
||||
|
||||
|
||||
@@ -84,6 +84,8 @@ excluded_paths = [
|
||||
"tests/.*/.*/networking/gossip_sync_committee_message/.*",
|
||||
"tests/.*/.*/networking/gossip_sync_committee_contribution_and_proof/.*",
|
||||
"tests/.*/.*/networking/gossip_blob_sidecar/.*",
|
||||
"tests/.*/.*/networking/gossip_data_column_sidecar/.*",
|
||||
"tests/.*/.*/networking/gossip_partial_data_column_sidecar/.*",
|
||||
# TODO: fast confirmation rule not merged yet
|
||||
"tests/.*/.*/fast_confirmation",
|
||||
]
|
||||
|
||||
@@ -423,6 +423,9 @@ impl<E: EthSpec, T: EpochTransition<E>> Case for EpochProcessing<E, T> {
|
||||
// Processing requires the committee caches.
|
||||
pre_state.build_all_committee_caches(spec).unwrap();
|
||||
|
||||
// Proposer index computation (e.g. proposer lookahead) requires the slashings cache post-Gloas
|
||||
pre_state.build_slashings_cache().unwrap();
|
||||
|
||||
let mut state = pre_state.clone();
|
||||
let mut expected = self.post.clone();
|
||||
|
||||
|
||||
@@ -53,6 +53,9 @@ pub struct PowBlock {
|
||||
pub struct Head {
|
||||
slot: Slot,
|
||||
root: Hash256,
|
||||
// Post-gloas, the head check also asserts the payload status of the head block
|
||||
#[serde(default)]
|
||||
payload_status: Option<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Deserialize)]
|
||||
@@ -132,6 +135,10 @@ pub enum Step<
|
||||
},
|
||||
Attestation {
|
||||
attestation: TAttestation,
|
||||
// Post-Gloas `on_attestation` tests can assert that an attestation is rejected (e.g. an
|
||||
// invalid payload-present index). Defaults to `true` for the pre-Gloas tests that omit it.
|
||||
#[serde(default = "default_true")]
|
||||
valid: bool,
|
||||
},
|
||||
AttesterSlashing {
|
||||
attester_slashing: TAttesterSlashing,
|
||||
@@ -169,8 +176,12 @@ fn default_true() -> bool {
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Meta {
|
||||
#[serde(rename(deserialize = "description"))]
|
||||
_description: String,
|
||||
#[serde(default, rename(deserialize = "description"))]
|
||||
_description: Option<String>,
|
||||
// Some Gloas fork choice tests carry a `bls_setting` instead of a description. We accept and
|
||||
// ignore it: the value is always `1` (BLS required), which matches our default behaviour.
|
||||
#[serde(default, rename(deserialize = "bls_setting"))]
|
||||
_bls_setting: Option<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -240,17 +251,19 @@ impl<E: EthSpec> LoadCase for ForkChoiceTest<E> {
|
||||
valid,
|
||||
})
|
||||
}
|
||||
Step::Attestation { attestation } => {
|
||||
Step::Attestation { attestation, valid } => {
|
||||
if fork_name.electra_enabled() {
|
||||
ssz_decode_file(&path.join(format!("{}.ssz_snappy", attestation))).map(
|
||||
|attestation| Step::Attestation {
|
||||
attestation: Attestation::Electra(attestation),
|
||||
valid,
|
||||
},
|
||||
)
|
||||
} else {
|
||||
ssz_decode_file(&path.join(format!("{}.ssz_snappy", attestation))).map(
|
||||
|attestation| Step::Attestation {
|
||||
attestation: Attestation::Base(attestation),
|
||||
valid,
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -389,7 +402,9 @@ impl<E: EthSpec> Case for ForkChoiceTest<E> {
|
||||
proofs.clone(),
|
||||
*valid,
|
||||
)?,
|
||||
Step::Attestation { attestation } => tester.process_attestation(attestation)?,
|
||||
Step::Attestation { attestation, valid } => {
|
||||
tester.process_attestation(attestation, *valid)?
|
||||
}
|
||||
Step::AttesterSlashing { attester_slashing } => {
|
||||
tester.process_attester_slashing(attester_slashing.to_ref())
|
||||
}
|
||||
@@ -673,7 +688,7 @@ impl<E: EthSpec> Tester<E> {
|
||||
if success {
|
||||
for attestation in block.message().body().attestations() {
|
||||
let att = attestation.clone_as_attestation();
|
||||
let _ = self.process_attestation(&att);
|
||||
let _ = self.process_attestation(&att, true);
|
||||
}
|
||||
for attester_slashing in block.message().body().attester_slashings() {
|
||||
self.process_attester_slashing(attester_slashing);
|
||||
@@ -786,7 +801,7 @@ impl<E: EthSpec> Tester<E> {
|
||||
if success {
|
||||
for attestation in block.message().body().attestations() {
|
||||
let att = attestation.clone_as_attestation();
|
||||
let _ = self.process_attestation(&att);
|
||||
let _ = self.process_attestation(&att, true);
|
||||
}
|
||||
for attester_slashing in block.message().body().attester_slashings() {
|
||||
self.process_attester_slashing(attester_slashing);
|
||||
@@ -848,7 +863,6 @@ impl<E: EthSpec> Tester<E> {
|
||||
block_delay,
|
||||
&state,
|
||||
PayloadVerificationStatus::Irrelevant,
|
||||
block.message().proposer_index(),
|
||||
&self.harness.chain.spec,
|
||||
);
|
||||
|
||||
@@ -863,22 +877,41 @@ impl<E: EthSpec> Tester<E> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn process_attestation(&self, attestation: &Attestation<E>) -> Result<(), Error> {
|
||||
let (indexed_attestation, _) = obtain_indexed_attestation_and_committees_per_slot(
|
||||
pub fn process_attestation(
|
||||
&self,
|
||||
attestation: &Attestation<E>,
|
||||
valid: bool,
|
||||
) -> Result<(), Error> {
|
||||
// Post-Gloas `on_attestation` tests can assert that an attestation is rejected (e.g. an
|
||||
// invalid same-slot/payload-present index). Treat any failure in either indexing or fork
|
||||
// choice application as a rejection so it can be compared against the expected `valid` flag.
|
||||
let result = obtain_indexed_attestation_and_committees_per_slot(
|
||||
&self.harness.chain,
|
||||
attestation.to_ref(),
|
||||
)
|
||||
.map_err(|e| Error::InternalError(format!("attestation indexing failed with {:?}", e)))?;
|
||||
let verified_attestation: ManuallyVerifiedAttestation<EphemeralHarnessType<E>> =
|
||||
ManuallyVerifiedAttestation {
|
||||
attestation,
|
||||
indexed_attestation,
|
||||
};
|
||||
.map_err(|e| format!("attestation indexing failed with {:?}", e))
|
||||
.and_then(|(indexed_attestation, _)| {
|
||||
let verified_attestation: ManuallyVerifiedAttestation<EphemeralHarnessType<E>> =
|
||||
ManuallyVerifiedAttestation {
|
||||
attestation,
|
||||
indexed_attestation,
|
||||
};
|
||||
|
||||
self.harness
|
||||
.chain
|
||||
.apply_attestation_to_fork_choice(&verified_attestation)
|
||||
.map_err(|e| Error::InternalError(format!("attestation import failed with {:?}", e)))
|
||||
self.harness
|
||||
.chain
|
||||
.apply_attestation_to_fork_choice(&verified_attestation)
|
||||
.map_err(|e| format!("attestation import failed with {:?}", e))
|
||||
});
|
||||
|
||||
if valid {
|
||||
result.map_err(Error::InternalError)
|
||||
} else if result.is_ok() {
|
||||
Err(Error::DidntFail(
|
||||
"attestation was valid but the test expects it to be rejected".to_string(),
|
||||
))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn process_attester_slashing(&self, attester_slashing: AttesterSlashingRef<E>) {
|
||||
@@ -909,9 +942,17 @@ impl<E: EthSpec> Tester<E> {
|
||||
let chain_head = Head {
|
||||
slot: head.head_slot(),
|
||||
root: head.head_block_root(),
|
||||
// Compared separately below so the slot/root equality is not affected.
|
||||
payload_status: expected_head.payload_status,
|
||||
};
|
||||
|
||||
check_equal("head", chain_head, expected_head)
|
||||
check_equal("head", chain_head, expected_head)?;
|
||||
|
||||
if let Some(expected_status) = expected_head.payload_status {
|
||||
self.check_head_payload_status(expected_status)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn check_time(&self, expected_time: u64) -> Result<(), Error> {
|
||||
|
||||
@@ -204,7 +204,12 @@ impl<E: EthSpec> Operation<E> for Deposit {
|
||||
ssz_decode_file(path)
|
||||
}
|
||||
|
||||
fn is_enabled_for_fork(_: ForkName) -> bool {
|
||||
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
|
||||
// The standalone `deposit` operation tests were removed in Fulu (deposits are processed
|
||||
// via `deposit_request` from Electra onwards).
|
||||
if fork_name.fulu_enabled() {
|
||||
return false;
|
||||
}
|
||||
// Some deposit tests require signature verification but are not marked as such.
|
||||
cfg!(not(feature = "fake_crypto"))
|
||||
}
|
||||
|
||||
@@ -708,13 +708,6 @@ impl<E: EthSpec + TypeName> Handler for ForkChoiceHandler<E> {
|
||||
return false;
|
||||
}
|
||||
|
||||
// No FCU override tests prior to bellatrix, and removed in Gloas.
|
||||
if self.handler_name == "should_override_forkchoice_update"
|
||||
&& (!fork_name.bellatrix_enabled() || fork_name.gloas_enabled())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Deposit tests exist only for Electra and later.
|
||||
if self.handler_name == "deposit_with_reorg" && !fork_name.electra_enabled() {
|
||||
return false;
|
||||
@@ -725,9 +718,10 @@ impl<E: EthSpec + TypeName> Handler for ForkChoiceHandler<E> {
|
||||
return false;
|
||||
}
|
||||
|
||||
// on_execution_payload_envelope, get_parent_payload_status, and
|
||||
// on_attestation, on_execution_payload_envelope, get_parent_payload_status, and
|
||||
// on_payload_attestation_message tests exist only for Gloas and later.
|
||||
if (self.handler_name == "on_execution_payload_envelope"
|
||||
if (self.handler_name == "on_attestation"
|
||||
|| self.handler_name == "on_execution_payload_envelope"
|
||||
|| self.handler_name == "get_parent_payload_status"
|
||||
|| self.handler_name == "on_payload_attestation_message")
|
||||
&& !fork_name.gloas_enabled()
|
||||
|
||||
@@ -708,14 +708,18 @@ mod ssz_static {
|
||||
|
||||
#[test]
|
||||
fn blob_sidecar() {
|
||||
SszStaticHandler::<BlobSidecar<MinimalEthSpec>, MinimalEthSpec>::deneb_and_later().run();
|
||||
SszStaticHandler::<BlobSidecar<MainnetEthSpec>, MainnetEthSpec>::deneb_and_later().run();
|
||||
SszStaticHandler::<BlobSidecar<MinimalEthSpec>, MinimalEthSpec>::deneb_only().run();
|
||||
SszStaticHandler::<BlobSidecar<MainnetEthSpec>, MainnetEthSpec>::deneb_only().run();
|
||||
SszStaticHandler::<BlobSidecar<MinimalEthSpec>, MinimalEthSpec>::electra_only().run();
|
||||
SszStaticHandler::<BlobSidecar<MainnetEthSpec>, MainnetEthSpec>::electra_only().run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blob_identifier() {
|
||||
SszStaticHandler::<BlobIdentifier, MinimalEthSpec>::deneb_and_later().run();
|
||||
SszStaticHandler::<BlobIdentifier, MainnetEthSpec>::deneb_and_later().run();
|
||||
SszStaticHandler::<BlobIdentifier, MinimalEthSpec>::deneb_only().run();
|
||||
SszStaticHandler::<BlobIdentifier, MainnetEthSpec>::deneb_only().run();
|
||||
SszStaticHandler::<BlobIdentifier, MinimalEthSpec>::electra_only().run();
|
||||
SszStaticHandler::<BlobIdentifier, MainnetEthSpec>::electra_only().run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1025,6 +1029,12 @@ fn fork_choice_get_head() {
|
||||
ForkChoiceHandler::<MainnetEthSpec>::new("get_head").run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fork_choice_on_attestation() {
|
||||
ForkChoiceHandler::<MinimalEthSpec>::new("on_attestation").run();
|
||||
ForkChoiceHandler::<MainnetEthSpec>::new("on_attestation").run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fork_choice_on_block() {
|
||||
ForkChoiceHandler::<MinimalEthSpec>::new("on_block").run();
|
||||
@@ -1049,12 +1059,6 @@ fn fork_choice_withholding() {
|
||||
// There is no mainnet variant for this test.
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fork_choice_should_override_forkchoice_update() {
|
||||
ForkChoiceHandler::<MinimalEthSpec>::new("should_override_forkchoice_update").run();
|
||||
ForkChoiceHandler::<MainnetEthSpec>::new("should_override_forkchoice_update").run();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fork_choice_get_proposer_head() {
|
||||
ForkChoiceHandler::<MinimalEthSpec>::new("get_proposer_head").run();
|
||||
|
||||
Reference in New Issue
Block a user