Skip to content

Commit

Permalink
Complete update_all_candidates test.
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmygchen committed Nov 6, 2024
1 parent e87f9b9 commit 9b81cc0
Show file tree
Hide file tree
Showing 2 changed files with 109 additions and 115 deletions.
209 changes: 96 additions & 113 deletions validator_client/src/beacon_node_fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@ impl<E: EthSpec> CandidateBeaconNode<E> {
if let Some(slot_clock) = slot_clock {
match check_node_health(&self.beacon_node, log).await {
Ok((head, is_optimistic, el_offline)) => {
println!("{} {} {}", head, is_optimistic, el_offline);
let Some(slot_clock_head) = slot_clock.now() else {
let e = match slot_clock.is_prior_to_genesis() {
Some(true) => CandidateError::PreGenesis,
Expand Down Expand Up @@ -275,7 +274,6 @@ impl<E: EthSpec> CandidateBeaconNode<E> {
Err(e) => {
// Set the health as `Err` which is sorted last in the list.
*self.health.write().await = Err(e);
println!("{:?}", e);
Err(e)
}
}
Expand Down Expand Up @@ -703,24 +701,22 @@ impl ApiTopic {

#[cfg(test)]
mod tests {
use std::str::FromStr;

use logging::test_logger;
use std::str::FromStr;
use strum::VariantNames;
use types::EmptyBlock;

use eth2::Timeouts;
use slot_clock::TestingSlotClock;
use types::EmptyBlock;
use types::{BeaconBlockDeneb, BlindedBeaconBlock, MainnetEthSpec, Slot};

use super::*;
use crate::beacon_node_health::BeaconNodeHealthTier;
use crate::block_service::{BlockService, BlockServiceBuilder, UnsignedBlock};
use crate::testing::mock_beacon_node::MockBeaconNode;
use crate::testing::validator_test_rig::ValidatorTestRig;
use crate::SensitiveUrl;

use super::*;

type E = MainnetEthSpec;

#[test]
Expand Down Expand Up @@ -846,6 +842,7 @@ mod tests {

#[tokio::test]
async fn update_all_candidates_should_update_sync_status() {
let spec = Arc::new(MainnetEthSpec::default_spec());
let mut mock_beacon_node_one = MockBeaconNode::<E>::new().await;
let mut mock_beacon_node_two = MockBeaconNode::<E>::new().await;
let mut mock_beacon_node_three = MockBeaconNode::<E>::new().await;
Expand All @@ -857,18 +854,29 @@ mod tests {
let beacon_node_three =
CandidateBeaconNode::<E>::new(mock_beacon_node_three.beacon_api_client.clone(), 2);

let beacon_node_fallback: BeaconNodeFallback<TestingSlotClock, E> = BeaconNodeFallback::new(
// Put this out of order to be sorted later
vec![
beacon_node_two.clone(),
beacon_node_three.clone(),
beacon_node_one.clone(),
],
Config::default(),
vec![], // to broadcast blocks to both bns
Arc::new(MainnetEthSpec::default_spec()),
test_logger(),
);
let mut beacon_node_fallback: BeaconNodeFallback<TestingSlotClock, E> =
BeaconNodeFallback::new(
// Put this out of order to be sorted later
vec![
beacon_node_two.clone(),
beacon_node_three.clone(),
beacon_node_one.clone(),
],
Config::default(),
vec![], // to broadcast blocks to both bns
spec.clone(),
test_logger(),
);

beacon_node_fallback.set_slot_clock(TestingSlotClock::new(
Slot::new(1),
Duration::from_secs(0),
Duration::from_secs(12),
));

mock_beacon_node_one.mock_config_spec(&spec);
mock_beacon_node_two.mock_config_spec(&spec);
mock_beacon_node_three.mock_config_spec(&spec);

// BeaconNodeHealthTier 1
mock_beacon_node_one.mock_get_node_syncing(eth2::types::SyncingData {
Expand Down Expand Up @@ -897,100 +905,75 @@ mod tests {

beacon_node_fallback.update_all_candidates().await;

// logging to check health
{
let candidates = beacon_node_fallback.candidates.read().await;
for (i, candidate) in candidates.iter().enumerate() {
println!(
"Candidate {} health: {:?}",
i,
candidate.health.read().await
);
}

assert_eq!(
vec![beacon_node_one, beacon_node_two, beacon_node_three],
*candidates
);
}
let candidates = beacon_node_fallback.candidates.read().await;
assert_eq!(
vec![beacon_node_one, beacon_node_two, beacon_node_three],
*candidates
);
}

// #[tokio::test]
// async fn check_fallback_broadcast_with_bn_delay() {
// let test_rig = ValidatorTestRig::new().await;
// let mut mock_beacon_node_one = MockBeaconNode::<E>::new().await;
// let mut mock_beacon_node_two = MockBeaconNode::<E>::new().await;

// let beacon_node_one =
// CandidateBeaconNode::new(mock_beacon_node_one.beacon_api_client.clone(), 0);
// let beacon_node_two =
// CandidateBeaconNode::new(mock_beacon_node_two.beacon_api_client.clone(), 1);

// let beacon_node_fallback = BeaconNodeFallback::new(
// vec![beacon_node_one, beacon_node_two],
// Config::default(),
// vec![ApiTopic::Blocks], // to broadcast blocks to both bns
// test_rig.spec.clone(),
// test_rig.logger.clone(),
// );

// let mock1 = mock_beacon_node_one.mock_post_beacon_blinded_blocks_v1(Duration::from_secs(0));
// let mock2 = mock_beacon_node_two.mock_post_beacon_blinded_blocks_v1(Duration::from_secs(0));

// // logging to check health
// {
// let candidates = beacon_node_fallback.candidates.read().await;
// for (i, candidate) in candidates.iter().enumerate() {
// println!(
// "Candidate {} health: {:?}",
// i,
// candidate.health.read().await
// );
// }
// }

// let block_service: BlockService<TestingSlotClock, MainnetEthSpec> =
// BlockServiceBuilder::new()
// .slot_clock(test_rig.slot_clock)
// .validator_store(test_rig.validator_store.clone())
// .beacon_nodes(Arc::new(beacon_node_fallback))
// .runtime_context(test_rig.runtime_context)
// .build()
// .unwrap();

// // Update all beacon nodes health
// beacon_node_fallback.update_all_candidates().await;
// let first_beacon_node = {
// let candidates = beacon_node_fallback.candidates.read().await;
// candidates.first().cloned()
// };

// let validators = test_rig.validator_store.initialized_validators();
// let validators = validators.read();
// let first_validator = validators.validator_definitions().first().unwrap();
// let unsigned_block = UnsignedBlock::Blinded(BlindedBeaconBlock::Deneb(
// BeaconBlockDeneb::empty(&test_rig.spec),
// ));
// let voting_pubkey = first_validator.voting_public_key.clone();
// let result = block_service
// .publish_block_for_testing(Slot::new(1), &voting_pubkey.into(), unsigned_block)
// .await;

// mock1.expect(1).assert();
// mock2.expect(1).assert();

// let received_blocks_one = mock_beacon_node_one.received_blocks.lock().unwrap();
// let received_blocks_two = mock_beacon_node_two.received_blocks.lock().unwrap();

// assert_eq!(received_blocks_one.len(), 1);
// assert_eq!(received_blocks_two.len(), 0);

// // first success fn
// // --broadcast
// // request

// if let Err(e) = result {
// panic!("Expected block to be broadcasted to BN, but failed with error: {e:?}");
// }
// }
#[tokio::test]
async fn broadcast_should_send_to_all_bns() {
let test_rig = ValidatorTestRig::new().await;
let mut mock_beacon_node_one = MockBeaconNode::<E>::new().await;
let mut mock_beacon_node_two = MockBeaconNode::<E>::new().await;

let beacon_node_one =
CandidateBeaconNode::new(mock_beacon_node_one.beacon_api_client.clone(), 0);
let beacon_node_two =
CandidateBeaconNode::new(mock_beacon_node_two.beacon_api_client.clone(), 1);

let mut beacon_node_fallback = BeaconNodeFallback::new(
vec![beacon_node_one, beacon_node_two],
Config::default(),
vec![ApiTopic::Blocks], // to broadcast blocks to both bns
test_rig.spec.clone(),
test_rig.logger.clone(),
);

beacon_node_fallback.set_slot_clock(TestingSlotClock::new(
Slot::new(1),
Duration::from_secs(0),
Duration::from_secs(12),
));

mock_beacon_node_one.mock_config_spec(&test_rig.spec);
mock_beacon_node_two.mock_config_spec(&test_rig.spec);

let mock1 = mock_beacon_node_one.mock_post_beacon_blinded_blocks_v1(Duration::from_secs(0));
let mock2 = mock_beacon_node_two.mock_post_beacon_blinded_blocks_v1(Duration::from_secs(0));

let beacon_node_fallback = Arc::new(beacon_node_fallback);
let block_service: BlockService<TestingSlotClock, MainnetEthSpec> =
BlockServiceBuilder::new()
.slot_clock(test_rig.slot_clock)
.validator_store(test_rig.validator_store.clone())
.beacon_nodes(beacon_node_fallback.clone())
.runtime_context(test_rig.runtime_context)
.build()
.unwrap();

beacon_node_fallback.update_all_candidates().await;

let validators = test_rig.validator_store.initialized_validators();
let validators = validators.read();
let first_validator = validators.validator_definitions().first().unwrap();
let unsigned_block = UnsignedBlock::Blinded(BlindedBeaconBlock::Deneb(
BeaconBlockDeneb::empty(&test_rig.spec),
));
let voting_pubkey = first_validator.voting_public_key.clone();
let result = block_service
.publish_block_for_testing(Slot::new(1), &voting_pubkey.into(), unsigned_block)
.await;
assert!(result.is_ok());

mock1.expect(1).assert();
mock2.expect(1).assert();

let received_blocks_one = mock_beacon_node_one.received_blocks.lock().unwrap();
let received_blocks_two = mock_beacon_node_two.received_blocks.lock().unwrap();

assert_eq!(received_blocks_one.len(), 1);
assert_eq!(received_blocks_two.len(), 1);
}
}
15 changes: 13 additions & 2 deletions validator_client/src/testing/mock_beacon_node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ use eth2::{
use logging::test_logger;
use sensitive_url::SensitiveUrl;
use types::{
BeaconBlock, BlobsList, EthSpec, ForkName, ForkVersionedResponse, KzgProofs,
SignedBlindedBeaconBlock, Slot, Uint256,
BeaconBlock, BlobsList, ChainSpec, ConfigAndPreset, EthSpec, ForkName, ForkVersionedResponse,
KzgProofs, SignedBlindedBeaconBlock, Slot, Uint256,
};

pub struct MockBeaconNode<E: EthSpec> {
Expand Down Expand Up @@ -105,6 +105,17 @@ impl<E: EthSpec> MockBeaconNode<E> {
self
}

pub fn mock_config_spec(&mut self, spec: &ChainSpec) {
let path_pattern = Regex::new(r"^/eth/v1/config/spec$").unwrap();
let config_and_preset = ConfigAndPreset::from_chain_spec::<E>(&spec, None);
let data = GenericResponse::from(config_and_preset);
self.server
.mock("GET", Matcher::Regex(path_pattern.to_string()))
.with_status(200)
.with_body(serde_json::to_string(&data).unwrap())
.create();
}

pub fn mock_get_node_syncing(&mut self, response: SyncingData) {
let path_pattern = Regex::new(r"^/eth/v1/node/syncing$").unwrap();

Expand Down

0 comments on commit 9b81cc0

Please sign in to comment.