From dd6cccaf7e7ca684f6aaa08d55f96641fcf6b667 Mon Sep 17 00:00:00 2001 From: carllin Date: Wed, 21 Oct 2020 15:56:50 -0700 Subject: [PATCH] Fix test_optimistic_confirmation_violation_without_tower() (#13043) Co-authored-by: Carl Lin --- local-cluster/tests/local_cluster.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/local-cluster/tests/local_cluster.rs b/local-cluster/tests/local_cluster.rs index 0950dea81..bdb7045e0 100644 --- a/local-cluster/tests/local_cluster.rs +++ b/local-cluster/tests/local_cluster.rs @@ -15,6 +15,7 @@ use solana_core::{ }; use solana_download_utils::download_snapshot; use solana_ledger::{ + ancestor_iterator::AncestorIterator, blockstore::{Blockstore, PurgeType}, blockstore_db::AccessType, leader_schedule::FixedSchedule, @@ -1677,7 +1678,11 @@ fn do_test_optimistic_confirmation_violation_with_or_without_tower(with_tower: b let node_stakes = vec![31, 36, 33, 0]; // Each pubkeys are prefixed with A, B, C and D. - // D is needed to avoid NoPropagatedConfirmation erorrs + // D is needed to: + // 1) Propagate A's votes for S2 to validator C after A shuts down so that + // C can avoid NoPropagatedConfirmation errors and continue to generate blocks + // 2) Provide gossip discovery for `A` when it restarts because `A` will restart + // at a different gossip port than the entrypoint saved in C's gossip table let validator_keys = vec![ "28bN3xyvrP4E8LwEgtLjhnkb7cY4amQb6DrYAbAYjgRV4GAGgkVM2K7wnxnAS7WDneuavza7x21MiafLu1HkwQt4", "2saHBBoTkLMmttmPQP8KfBkcCw45S5cwtV3wTdGCscRC8uxdgvHxpHiWXKx4LvJjNJtnNcbSv5NdheokFFqnNDt8", @@ -1804,17 +1809,28 @@ fn do_test_optimistic_confirmation_violation_with_or_without_tower(with_tower: b // monitor for actual votes from validator A let mut bad_vote_detected = false; + let mut a_votes = vec![]; for _ in 0..100 { sleep(Duration::from_millis(100)); if let Some(last_vote) = last_vote_in_tower(&val_a_ledger_path, &validator_a_pubkey) { - if votes_on_c_fork.contains(&last_vote) { + a_votes.push(last_vote); + let blockstore = Blockstore::open_with_access_type( + &val_a_ledger_path, + AccessType::TryPrimaryThenSecondary, + None, + ) + .unwrap(); + let mut ancestors = AncestorIterator::new(last_vote, &blockstore); + if ancestors.any(|a| votes_on_c_fork.contains(&a)) { bad_vote_detected = true; break; } } } + info!("Observed A's votes on: {:?}", a_votes); + // an elaborate way of assert!(with_tower && !bad_vote_detected || ...) let expects_optimistic_confirmation_violation = !with_tower; if bad_vote_detected != expects_optimistic_confirmation_violation {