Merge branch 'unstable' of https://github.com/sigp/lighthouse into single_attestation

This commit is contained in:
Eitan Seri-Levi
2024-12-23 13:45:20 +07:00
223 changed files with 3748 additions and 3102 deletions

View File

@@ -322,7 +322,7 @@ pub async fn consensus_gossip() {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
pub async fn consensus_partial_pass_only_consensus() {
/* this test targets gossip-level validation */
let validation_level: Option<BroadcastValidation> = Some(BroadcastValidation::Consensus);
let validation_level = BroadcastValidation::Consensus;
// Validator count needs to be at least 32 or proposer boost gets set to 0 when computing
// `validator_count // 32`.
@@ -378,7 +378,7 @@ pub async fn consensus_partial_pass_only_consensus() {
tester.harness.chain.clone(),
&channel.0,
test_logger,
validation_level.unwrap(),
validation_level,
StatusCode::ACCEPTED,
network_globals,
)
@@ -615,8 +615,7 @@ pub async fn equivocation_gossip() {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
pub async fn equivocation_consensus_late_equivocation() {
/* this test targets gossip-level validation */
let validation_level: Option<BroadcastValidation> =
Some(BroadcastValidation::ConsensusAndEquivocation);
let validation_level = BroadcastValidation::ConsensusAndEquivocation;
// Validator count needs to be at least 32 or proposer boost gets set to 0 when computing
// `validator_count // 32`.
@@ -671,7 +670,7 @@ pub async fn equivocation_consensus_late_equivocation() {
tester.harness.chain,
&channel.0,
test_logger,
validation_level.unwrap(),
validation_level,
StatusCode::ACCEPTED,
network_globals,
)
@@ -1228,8 +1227,7 @@ pub async fn blinded_equivocation_gossip() {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
pub async fn blinded_equivocation_consensus_late_equivocation() {
/* this test targets gossip-level validation */
let validation_level: Option<BroadcastValidation> =
Some(BroadcastValidation::ConsensusAndEquivocation);
let validation_level = BroadcastValidation::ConsensusAndEquivocation;
// Validator count needs to be at least 32 or proposer boost gets set to 0 when computing
// `validator_count // 32`.
@@ -1311,7 +1309,7 @@ pub async fn blinded_equivocation_consensus_late_equivocation() {
tester.harness.chain,
&channel.0,
test_logger,
validation_level.unwrap(),
validation_level,
StatusCode::ACCEPTED,
network_globals,
)
@@ -1465,8 +1463,8 @@ pub async fn block_seen_on_gossip_with_some_blobs() {
"need at least 2 blobs for partial reveal"
);
let partial_kzg_proofs = vec![blobs.0.get(0).unwrap().clone()];
let partial_blobs = vec![blobs.1.get(0).unwrap().clone()];
let partial_kzg_proofs = vec![*blobs.0.first().unwrap()];
let partial_blobs = vec![blobs.1.first().unwrap().clone()];
// Simulate the block being seen on gossip.
block

View File

@@ -139,7 +139,7 @@ impl ForkChoiceUpdates {
fn insert(&mut self, update: ForkChoiceUpdateMetadata) {
self.updates
.entry(update.state.head_block_hash)
.or_insert_with(Vec::new)
.or_default()
.push(update);
}
@@ -447,9 +447,14 @@ pub async fn proposer_boost_re_org_test(
// Send proposer preparation data for all validators.
let proposer_preparation_data = all_validators
.iter()
.map(|i| ProposerPreparationData {
validator_index: *i as u64,
fee_recipient: Address::from_low_u64_be(*i as u64),
.map(|i| {
(
ProposerPreparationData {
validator_index: *i as u64,
fee_recipient: Address::from_low_u64_be(*i as u64),
},
None,
)
})
.collect::<Vec<_>>();
harness
@@ -459,7 +464,7 @@ pub async fn proposer_boost_re_org_test(
.unwrap()
.update_proposer_preparation(
head_slot.epoch(E::slots_per_epoch()) + 1,
&proposer_preparation_data,
proposer_preparation_data.iter().map(|(a, b)| (a, b)),
)
.await;

View File

@@ -57,18 +57,18 @@ async fn el_syncing_then_synced() {
mock_el.el.upcheck().await;
let api_response = tester.client.get_node_syncing().await.unwrap().data;
assert_eq!(api_response.el_offline, false);
assert_eq!(api_response.is_optimistic, false);
assert_eq!(api_response.is_syncing, false);
assert!(!api_response.el_offline);
assert!(!api_response.is_optimistic);
assert!(!api_response.is_syncing);
// EL synced
mock_el.server.set_syncing_response(Ok(false));
mock_el.el.upcheck().await;
let api_response = tester.client.get_node_syncing().await.unwrap().data;
assert_eq!(api_response.el_offline, false);
assert_eq!(api_response.is_optimistic, false);
assert_eq!(api_response.is_syncing, false);
assert!(!api_response.el_offline);
assert!(!api_response.is_optimistic);
assert!(!api_response.is_syncing);
}
/// Check `syncing` endpoint when the EL is offline (errors on upcheck).
@@ -85,9 +85,9 @@ async fn el_offline() {
mock_el.el.upcheck().await;
let api_response = tester.client.get_node_syncing().await.unwrap().data;
assert_eq!(api_response.el_offline, true);
assert_eq!(api_response.is_optimistic, false);
assert_eq!(api_response.is_syncing, false);
assert!(api_response.el_offline);
assert!(!api_response.is_optimistic);
assert!(!api_response.is_syncing);
}
/// Check `syncing` endpoint when the EL errors on newPaylod but is not fully offline.
@@ -128,9 +128,9 @@ async fn el_error_on_new_payload() {
// The EL should now be *offline* according to the API.
let api_response = tester.client.get_node_syncing().await.unwrap().data;
assert_eq!(api_response.el_offline, true);
assert_eq!(api_response.is_optimistic, false);
assert_eq!(api_response.is_syncing, false);
assert!(api_response.el_offline);
assert!(!api_response.is_optimistic);
assert!(!api_response.is_syncing);
// Processing a block successfully should remove the status.
mock_el.server.set_new_payload_status(
@@ -144,9 +144,9 @@ async fn el_error_on_new_payload() {
harness.process_block_result((block, blobs)).await.unwrap();
let api_response = tester.client.get_node_syncing().await.unwrap().data;
assert_eq!(api_response.el_offline, false);
assert_eq!(api_response.is_optimistic, false);
assert_eq!(api_response.is_syncing, false);
assert!(!api_response.el_offline);
assert!(!api_response.is_optimistic);
assert!(!api_response.is_syncing);
}
/// Check `node health` endpoint when the EL is offline.

View File

@@ -13,8 +13,10 @@ use eth2::{
Error::ServerMessage,
StatusCode, Timeouts,
};
use execution_layer::expected_gas_limit;
use execution_layer::test_utils::{
MockBuilder, Operation, DEFAULT_BUILDER_PAYLOAD_VALUE_WEI, DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI,
mock_builder_extra_data, mock_el_extra_data, MockBuilder, Operation,
DEFAULT_BUILDER_PAYLOAD_VALUE_WEI, DEFAULT_GAS_LIMIT, DEFAULT_MOCK_EL_PAYLOAD_VALUE_WEI,
};
use futures::stream::{Stream, StreamExt};
use futures::FutureExt;
@@ -272,10 +274,10 @@ impl ApiTester {
let mock_builder_server = harness.set_mock_builder(beacon_url.clone());
// Start the mock builder service prior to building the chain out.
harness.runtime.task_executor.spawn(
async move { mock_builder_server.await },
"mock_builder_server",
);
harness
.runtime
.task_executor
.spawn(mock_builder_server, "mock_builder_server");
let mock_builder = harness.mock_builder.clone();
@@ -348,7 +350,6 @@ impl ApiTester {
let bls_to_execution_change = harness.make_bls_to_execution_change(4, Address::zero());
let chain = harness.chain.clone();
let log = test_logger();
let ApiServer {
@@ -640,7 +641,7 @@ impl ApiTester {
self
}
pub async fn test_beacon_blocks_finalized<E: EthSpec>(self) -> Self {
pub async fn test_beacon_blocks_finalized(self) -> Self {
for block_id in self.interesting_block_ids() {
let block_root = block_id.root(&self.chain);
let block = block_id.full_block(&self.chain).await;
@@ -677,7 +678,7 @@ impl ApiTester {
self
}
pub async fn test_beacon_blinded_blocks_finalized<E: EthSpec>(self) -> Self {
pub async fn test_beacon_blinded_blocks_finalized(self) -> Self {
for block_id in self.interesting_block_ids() {
let block_root = block_id.root(&self.chain);
let block = block_id.full_block(&self.chain).await;
@@ -818,7 +819,7 @@ impl ApiTester {
let validator_index_ids = validator_indices
.iter()
.cloned()
.map(|i| ValidatorId::Index(i))
.map(ValidatorId::Index)
.collect::<Vec<ValidatorId>>();
let unsupported_media_response = self
@@ -858,7 +859,7 @@ impl ApiTester {
let validator_index_ids = validator_indices
.iter()
.cloned()
.map(|i| ValidatorId::Index(i))
.map(ValidatorId::Index)
.collect::<Vec<ValidatorId>>();
let validator_pubkey_ids = validator_indices
.iter()
@@ -909,7 +910,7 @@ impl ApiTester {
for i in validator_indices {
if i < state.balances().len() as u64 {
validators.push(ValidatorBalanceData {
index: i as u64,
index: i,
balance: *state.balances().get(i as usize).unwrap(),
});
}
@@ -943,7 +944,7 @@ impl ApiTester {
let validator_index_ids = validator_indices
.iter()
.cloned()
.map(|i| ValidatorId::Index(i))
.map(ValidatorId::Index)
.collect::<Vec<ValidatorId>>();
let validator_pubkey_ids = validator_indices
.iter()
@@ -1011,7 +1012,7 @@ impl ApiTester {
|| statuses.contains(&status.superstatus())
{
validators.push(ValidatorData {
index: i as u64,
index: i,
balance: *state.balances().get(i as usize).unwrap(),
status,
validator,
@@ -1640,11 +1641,7 @@ impl ApiTester {
let (block, _, _) = block_id.full_block(&self.chain).await.unwrap();
let num_blobs = block.num_expected_blobs();
let blob_indices = if use_indices {
Some(
(0..num_blobs.saturating_sub(1) as u64)
.into_iter()
.collect::<Vec<_>>(),
)
Some((0..num_blobs.saturating_sub(1) as u64).collect::<Vec<_>>())
} else {
None
};
@@ -1662,7 +1659,7 @@ impl ApiTester {
blob_indices.map_or(num_blobs, |indices| indices.len())
);
let expected = block.slot();
assert_eq!(result.get(0).unwrap().slot(), expected);
assert_eq!(result.first().unwrap().slot(), expected);
self
}
@@ -1700,9 +1697,9 @@ impl ApiTester {
break;
}
}
let test_slot = test_slot.expect(&format!(
"should be able to find a block matching zero_blobs={zero_blobs}"
));
let test_slot = test_slot.unwrap_or_else(|| {
panic!("should be able to find a block matching zero_blobs={zero_blobs}")
});
match self
.client
@@ -1771,7 +1768,6 @@ impl ApiTester {
.attestations()
.map(|att| att.clone_as_attestation())
.collect::<Vec<_>>()
.into()
},
);
@@ -1908,7 +1904,7 @@ impl ApiTester {
let result = match self
.client
.get_beacon_light_client_updates::<E>(current_sync_committee_period as u64, 1)
.get_beacon_light_client_updates::<E>(current_sync_committee_period, 1)
.await
{
Ok(result) => result,
@@ -1920,7 +1916,7 @@ impl ApiTester {
.light_client_server_cache
.get_light_client_updates(
&self.chain.store,
current_sync_committee_period as u64,
current_sync_committee_period,
1,
&self.chain.spec,
)
@@ -2313,7 +2309,7 @@ impl ApiTester {
.unwrap()
.data
.is_syncing;
assert_eq!(is_syncing, true);
assert!(is_syncing);
// Reset sync state.
*self
@@ -2363,7 +2359,7 @@ impl ApiTester {
pub async fn test_get_node_peers_by_id(self) -> Self {
let result = self
.client
.get_node_peers_by_id(self.external_peer_id.clone())
.get_node_peers_by_id(self.external_peer_id)
.await
.unwrap()
.data;
@@ -3513,6 +3509,7 @@ impl ApiTester {
self
}
#[allow(clippy::await_holding_lock)] // This is a test, so it should be fine.
pub async fn test_get_validator_aggregate_attestation(self) -> Self {
if self
.chain
@@ -3755,7 +3752,11 @@ impl ApiTester {
self
}
pub async fn test_post_validator_register_validator(self) -> Self {
async fn generate_validator_registration_data(
&self,
fee_recipient_generator: impl Fn(usize) -> Address,
gas_limit: u64,
) -> (Vec<SignedValidatorRegistrationData>, Vec<Address>) {
let mut registrations = vec![];
let mut fee_recipients = vec![];
@@ -3766,15 +3767,13 @@ impl ApiTester {
epoch: genesis_epoch,
};
let expected_gas_limit = 11_111_111;
for (val_index, keypair) in self.validator_keypairs().iter().enumerate() {
let pubkey = keypair.pk.compress();
let fee_recipient = Address::from_low_u64_be(val_index as u64);
let fee_recipient = fee_recipient_generator(val_index);
let data = ValidatorRegistrationData {
fee_recipient,
gas_limit: expected_gas_limit,
gas_limit,
timestamp: 0,
pubkey,
};
@@ -3797,6 +3796,17 @@ impl ApiTester {
registrations.push(signed);
}
(registrations, fee_recipients)
}
pub async fn test_post_validator_register_validator(self) -> Self {
let (registrations, fee_recipients) = self
.generate_validator_registration_data(
|val_index| Address::from_low_u64_be(val_index as u64),
DEFAULT_GAS_LIMIT,
)
.await;
self.client
.post_validator_register_validator(&registrations)
.await
@@ -3811,14 +3821,22 @@ impl ApiTester {
.zip(fee_recipients.into_iter())
.enumerate()
{
let actual = self
let actual_fee_recipient = self
.chain
.execution_layer
.as_ref()
.unwrap()
.get_suggested_fee_recipient(val_index as u64)
.await;
assert_eq!(actual, fee_recipient);
let actual_gas_limit = self
.chain
.execution_layer
.as_ref()
.unwrap()
.get_proposer_gas_limit(val_index as u64)
.await;
assert_eq!(actual_fee_recipient, fee_recipient);
assert_eq!(actual_gas_limit, Some(DEFAULT_GAS_LIMIT));
}
self
@@ -3839,46 +3857,12 @@ impl ApiTester {
)
.await;
let mut registrations = vec![];
let mut fee_recipients = vec![];
let genesis_epoch = self.chain.spec.genesis_slot.epoch(E::slots_per_epoch());
let fork = Fork {
current_version: self.chain.spec.genesis_fork_version,
previous_version: self.chain.spec.genesis_fork_version,
epoch: genesis_epoch,
};
let expected_gas_limit = 11_111_111;
for (val_index, keypair) in self.validator_keypairs().iter().enumerate() {
let pubkey = keypair.pk.compress();
let fee_recipient = Address::from_low_u64_be(val_index as u64);
let data = ValidatorRegistrationData {
fee_recipient,
gas_limit: expected_gas_limit,
timestamp: 0,
pubkey,
};
let domain = self.chain.spec.get_domain(
genesis_epoch,
Domain::ApplicationMask(ApplicationDomain::Builder),
&fork,
Hash256::zero(),
);
let message = data.signing_root(domain);
let signature = keypair.sk.sign(message);
let signed = SignedValidatorRegistrationData {
message: data,
signature,
};
fee_recipients.push(fee_recipient);
registrations.push(signed);
}
let (registrations, fee_recipients) = self
.generate_validator_registration_data(
|val_index| Address::from_low_u64_be(val_index as u64),
DEFAULT_GAS_LIMIT,
)
.await;
self.client
.post_validator_register_validator(&registrations)
@@ -3911,6 +3895,47 @@ impl ApiTester {
self
}
pub async fn test_post_validator_register_validator_higher_gas_limit(&self) {
let (registrations, fee_recipients) = self
.generate_validator_registration_data(
|val_index| Address::from_low_u64_be(val_index as u64),
DEFAULT_GAS_LIMIT + 10_000_000,
)
.await;
self.client
.post_validator_register_validator(&registrations)
.await
.unwrap();
for (val_index, (_, fee_recipient)) in self
.chain
.head_snapshot()
.beacon_state
.validators()
.into_iter()
.zip(fee_recipients.into_iter())
.enumerate()
{
let actual_fee_recipient = self
.chain
.execution_layer
.as_ref()
.unwrap()
.get_suggested_fee_recipient(val_index as u64)
.await;
let actual_gas_limit = self
.chain
.execution_layer
.as_ref()
.unwrap()
.get_proposer_gas_limit(val_index as u64)
.await;
assert_eq!(actual_fee_recipient, fee_recipient);
assert_eq!(actual_gas_limit, Some(DEFAULT_GAS_LIMIT + 10_000_000));
}
}
pub async fn test_post_validator_liveness_epoch(self) -> Self {
let epoch = self.chain.epoch().unwrap();
let head_state = self.chain.head_beacon_state_cloned();
@@ -4029,9 +4054,9 @@ impl ApiTester {
ProduceBlockV3Response::Full(_) => panic!("Expecting a blinded payload"),
};
let expected_fee_recipient = Address::from_low_u64_be(proposer_index as u64);
let expected_fee_recipient = Address::from_low_u64_be(proposer_index);
assert_eq!(payload.fee_recipient(), expected_fee_recipient);
assert_eq!(payload.gas_limit(), 11_111_111);
assert_eq!(payload.gas_limit(), DEFAULT_GAS_LIMIT);
self
}
@@ -4056,9 +4081,10 @@ impl ApiTester {
ProduceBlockV3Response::Blinded(_) => panic!("Expecting a full payload"),
};
let expected_fee_recipient = Address::from_low_u64_be(proposer_index as u64);
let expected_fee_recipient = Address::from_low_u64_be(proposer_index);
assert_eq!(payload.fee_recipient(), expected_fee_recipient);
assert_eq!(payload.gas_limit(), 16_384);
// This is the graffiti of the mock execution layer, not the builder.
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
@@ -4083,9 +4109,9 @@ impl ApiTester {
ProduceBlockV3Response::Full(_) => panic!("Expecting a blinded payload"),
};
let expected_fee_recipient = Address::from_low_u64_be(proposer_index as u64);
let expected_fee_recipient = Address::from_low_u64_be(proposer_index);
assert_eq!(payload.fee_recipient(), expected_fee_recipient);
assert_eq!(payload.gas_limit(), 11_111_111);
assert_eq!(payload.gas_limit(), DEFAULT_GAS_LIMIT);
self
}
@@ -4107,9 +4133,9 @@ impl ApiTester {
.unwrap()
.into();
let expected_fee_recipient = Address::from_low_u64_be(proposer_index as u64);
let expected_fee_recipient = Address::from_low_u64_be(proposer_index);
assert_eq!(payload.fee_recipient(), expected_fee_recipient);
assert_eq!(payload.gas_limit(), 11_111_111);
assert_eq!(payload.gas_limit(), DEFAULT_GAS_LIMIT);
// If this cache is empty, it indicates fallback was not used, so the payload came from the
// mock builder.
@@ -4126,10 +4152,16 @@ impl ApiTester {
pub async fn test_payload_accepts_mutated_gas_limit(self) -> Self {
// Mutate gas limit.
let builder_limit = expected_gas_limit(
DEFAULT_GAS_LIMIT,
DEFAULT_GAS_LIMIT + 10_000_000,
self.chain.spec.as_ref(),
)
.expect("calculate expected gas limit");
self.mock_builder
.as_ref()
.unwrap()
.add_operation(Operation::GasLimit(30_000_000));
.add_operation(Operation::GasLimit(builder_limit as usize));
let slot = self.chain.slot().unwrap();
let epoch = self.chain.epoch().unwrap();
@@ -4147,9 +4179,9 @@ impl ApiTester {
.unwrap()
.into();
let expected_fee_recipient = Address::from_low_u64_be(proposer_index as u64);
let expected_fee_recipient = Address::from_low_u64_be(proposer_index);
assert_eq!(payload.fee_recipient(), expected_fee_recipient);
assert_eq!(payload.gas_limit(), 30_000_000);
assert_eq!(payload.gas_limit(), builder_limit);
// This cache should not be populated because fallback should not have been used.
assert!(self
@@ -4159,6 +4191,49 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_none());
// Another way is to check for the extra data of the mock builder
assert_eq!(payload.extra_data(), mock_builder_extra_data::<E>());
self
}
pub async fn test_builder_payload_rejected_when_gas_limit_incorrect(self) -> Self {
self.test_post_validator_register_validator_higher_gas_limit()
.await;
// Mutate gas limit.
self.mock_builder
.as_ref()
.unwrap()
.add_operation(Operation::GasLimit(1));
let slot = self.chain.slot().unwrap();
let epoch = self.chain.epoch().unwrap();
let (_, randao_reveal) = self.get_test_randao(slot, epoch).await;
let payload: BlindedPayload<E> = self
.client
.get_validator_blinded_blocks::<E>(slot, &randao_reveal, None)
.await
.unwrap()
.data
.body()
.execution_payload()
.unwrap()
.into();
// If this cache is populated, it indicates fallback to the local EE was correctly used.
assert!(self
.chain
.execution_layer
.as_ref()
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
@@ -4188,7 +4263,7 @@ impl ApiTester {
ProduceBlockV3Response::Full(_) => panic!("Expecting a blinded payload"),
};
let expected_fee_recipient = Address::from_low_u64_be(proposer_index as u64);
let expected_fee_recipient = Address::from_low_u64_be(proposer_index);
assert_eq!(payload.fee_recipient(), expected_fee_recipient);
assert_eq!(payload.gas_limit(), 30_000_000);
@@ -4232,6 +4307,9 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_none());
// Another way is to check for the extra data of the mock builder
assert_eq!(payload.extra_data(), mock_builder_extra_data::<E>());
self
}
@@ -4315,6 +4393,9 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
@@ -4404,6 +4485,9 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
@@ -4491,6 +4575,9 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
@@ -4577,6 +4664,9 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
@@ -4647,6 +4737,9 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
@@ -4707,6 +4800,9 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
@@ -4780,6 +4876,8 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_none());
// Another way is to check for the extra data of the mock builder
assert_eq!(payload.extra_data(), mock_builder_extra_data::<E>());
// Without proposing, advance into the next slot, this should make us cross the threshold
// number of skips, causing us to use the fallback.
@@ -4809,6 +4907,8 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
@@ -4915,6 +5015,8 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
// Fill another epoch with blocks, should be enough to finalize. (Sneaky plus 1 because this
// scenario starts at an epoch boundary).
@@ -4954,6 +5056,8 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_none());
// Another way is to check for the extra data of the mock builder
assert_eq!(payload.extra_data(), mock_builder_extra_data::<E>());
self
}
@@ -5032,9 +5136,8 @@ impl ApiTester {
pub async fn test_builder_chain_health_optimistic_head(self) -> Self {
// Make sure the next payload verification will return optimistic before advancing the chain.
self.harness.mock_execution_layer.as_ref().map(|el| {
self.harness.mock_execution_layer.as_ref().inspect(|el| {
el.server.all_payloads_syncing(true);
el
});
self.harness
.extend_chain(
@@ -5061,7 +5164,7 @@ impl ApiTester {
.unwrap()
.into();
let expected_fee_recipient = Address::from_low_u64_be(proposer_index as u64);
let expected_fee_recipient = Address::from_low_u64_be(proposer_index);
assert_eq!(payload.fee_recipient(), expected_fee_recipient);
// If this cache is populated, it indicates fallback to the local EE was correctly used.
@@ -5072,15 +5175,16 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
pub async fn test_builder_v3_chain_health_optimistic_head(self) -> Self {
// Make sure the next payload verification will return optimistic before advancing the chain.
self.harness.mock_execution_layer.as_ref().map(|el| {
self.harness.mock_execution_layer.as_ref().inspect(|el| {
el.server.all_payloads_syncing(true);
el
});
self.harness
.extend_chain(
@@ -5110,7 +5214,7 @@ impl ApiTester {
ProduceBlockV3Response::Blinded(_) => panic!("Expecting a full payload"),
};
let expected_fee_recipient = Address::from_low_u64_be(proposer_index as u64);
let expected_fee_recipient = Address::from_low_u64_be(proposer_index);
assert_eq!(payload.fee_recipient(), expected_fee_recipient);
self
@@ -5149,6 +5253,9 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_none());
// Another way is to check for the extra data of the mock builder
assert_eq!(payload.extra_data(), mock_builder_extra_data::<E>());
self
}
@@ -5214,6 +5321,9 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
@@ -5279,6 +5389,9 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_some());
// another way is to check for the extra data of the local EE
assert_eq!(payload.extra_data(), mock_el_extra_data::<E>());
self
}
@@ -5343,6 +5456,9 @@ impl ApiTester {
.unwrap()
.get_payload_by_root(&payload.tree_hash_root())
.is_none());
// Another way is to check for the extra data of the mock builder
assert_eq!(payload.extra_data(), mock_builder_extra_data::<E>());
self
}
@@ -5979,16 +6095,17 @@ impl ApiTester {
assert_eq!(result.execution_optimistic, Some(false));
// Change head to be optimistic.
self.chain
if let Some(head_node) = self
.chain
.canonical_head
.fork_choice_write_lock()
.proto_array_mut()
.core_proto_array_mut()
.nodes
.last_mut()
.map(|head_node| {
head_node.execution_status = ExecutionStatus::Optimistic(ExecutionBlockHash::zero())
});
{
head_node.execution_status = ExecutionStatus::Optimistic(ExecutionBlockHash::zero())
}
// Check responses are now optimistic.
let result = self
@@ -6021,8 +6138,8 @@ async fn poll_events<S: Stream<Item = Result<EventKind<E>, eth2::Error>> + Unpin
};
tokio::select! {
_ = collect_stream_fut => {events}
_ = tokio::time::sleep(timeout) => { return events; }
_ = collect_stream_fut => { events }
_ = tokio::time::sleep(timeout) => { events }
}
}
@@ -6058,31 +6175,31 @@ async fn test_unsupported_media_response() {
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn beacon_get() {
async fn beacon_get_state_hashes() {
ApiTester::new()
.await
.test_beacon_states_root_finalized()
.await
.test_beacon_states_finality_checkpoints_finalized()
.await
.test_beacon_states_root()
.await
.test_beacon_states_finality_checkpoints()
.await;
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn beacon_get_state_info() {
ApiTester::new()
.await
.test_beacon_genesis()
.await
.test_beacon_states_root_finalized()
.await
.test_beacon_states_fork_finalized()
.await
.test_beacon_states_finality_checkpoints_finalized()
.await
.test_beacon_headers_block_id_finalized()
.await
.test_beacon_blocks_finalized::<MainnetEthSpec>()
.await
.test_beacon_blinded_blocks_finalized::<MainnetEthSpec>()
.await
.test_debug_beacon_states_finalized()
.await
.test_beacon_states_root()
.await
.test_beacon_states_fork()
.await
.test_beacon_states_finality_checkpoints()
.await
.test_beacon_states_validators()
.await
.test_beacon_states_validator_balances()
@@ -6092,6 +6209,18 @@ async fn beacon_get() {
.test_beacon_states_validator_id()
.await
.test_beacon_states_randao()
.await;
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn beacon_get_blocks() {
ApiTester::new()
.await
.test_beacon_headers_block_id_finalized()
.await
.test_beacon_blocks_finalized()
.await
.test_beacon_blinded_blocks_finalized()
.await
.test_beacon_headers_all_slots()
.await
@@ -6106,6 +6235,12 @@ async fn beacon_get() {
.test_beacon_blocks_attestations()
.await
.test_beacon_blocks_root()
.await;
}
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn beacon_get_pools() {
ApiTester::new()
.await
.test_get_beacon_pool_attestations()
.await
@@ -6682,6 +6817,8 @@ async fn post_validator_register_valid_v3() {
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn post_validator_register_gas_limit_mutation() {
ApiTester::new_mev_tester()
.await
.test_builder_payload_rejected_when_gas_limit_incorrect()
.await
.test_payload_accepts_mutated_gas_limit()
.await;