`solana-validator set-identity` now works for voting validators

This commit is contained in:
Michael Vines 2021-07-13 11:32:45 -07:00
parent 62d864559f
commit b30b32300d
2 changed files with 38 additions and 22 deletions

View File

@ -119,6 +119,8 @@ pub struct Tower {
last_vote_tx_blockhash: Hash, last_vote_tx_blockhash: Hash,
last_timestamp: BlockTimestamp, last_timestamp: BlockTimestamp,
#[serde(skip)] #[serde(skip)]
ledger_path: PathBuf,
#[serde(skip)]
path: PathBuf, path: PathBuf,
#[serde(skip)] #[serde(skip)]
tmp_path: PathBuf, // used before atomic fs::rename() tmp_path: PathBuf, // used before atomic fs::rename()
@ -144,6 +146,7 @@ impl Default for Tower {
last_vote: Vote::default(), last_vote: Vote::default(),
last_timestamp: BlockTimestamp::default(), last_timestamp: BlockTimestamp::default(),
last_vote_tx_blockhash: Hash::default(), last_vote_tx_blockhash: Hash::default(),
ledger_path: PathBuf::default(),
path: PathBuf::default(), path: PathBuf::default(),
tmp_path: PathBuf::default(), tmp_path: PathBuf::default(),
stray_restored_slot: Option::default(), stray_restored_slot: Option::default(),
@ -161,21 +164,25 @@ impl Tower {
vote_account_pubkey: &Pubkey, vote_account_pubkey: &Pubkey,
root: Slot, root: Slot,
bank: &Bank, bank: &Bank,
path: &Path, ledger_path: &Path,
) -> Self { ) -> Self {
let path = Self::get_filename(path, node_pubkey); let mut tower = Tower {
let tmp_path = Self::get_tmp_filename(&path); ledger_path: ledger_path.into(),
let mut tower = Self {
node_pubkey: *node_pubkey,
path,
tmp_path,
..Tower::default() ..Tower::default()
}; };
tower.set_identity(*node_pubkey);
tower.initialize_lockouts_from_bank(vote_account_pubkey, root, bank); tower.initialize_lockouts_from_bank(vote_account_pubkey, root, bank);
tower tower
} }
pub(crate) fn set_identity(&mut self, node_pubkey: Pubkey) {
let path = Self::get_filename(&self.ledger_path, &node_pubkey);
let tmp_path = Self::get_tmp_filename(&path);
self.node_pubkey = node_pubkey;
self.path = path;
self.tmp_path = tmp_path;
}
#[cfg(test)] #[cfg(test)]
pub fn new_for_tests(threshold_depth: usize, threshold_size: f64) -> Self { pub fn new_for_tests(threshold_depth: usize, threshold_size: f64) -> Self {
Self { Self {
@ -188,7 +195,7 @@ impl Tower {
pub fn new_from_bankforks( pub fn new_from_bankforks(
bank_forks: &BankForks, bank_forks: &BankForks,
ledger_path: &Path, ledger_path: &Path,
my_pubkey: &Pubkey, node_pubkey: &Pubkey,
vote_account: &Pubkey, vote_account: &Pubkey,
) -> Self { ) -> Self {
let root_bank = bank_forks.root_bank(); let root_bank = bank_forks.root_bank();
@ -196,7 +203,7 @@ impl Tower {
crate::replay_stage::ReplayStage::initialize_progress_and_fork_choice( crate::replay_stage::ReplayStage::initialize_progress_and_fork_choice(
root_bank.deref(), root_bank.deref(),
bank_forks.frozen_banks().values().cloned().collect(), bank_forks.frozen_banks().values().cloned().collect(),
my_pubkey, node_pubkey,
vote_account, vote_account,
); );
let root = root_bank.slot(); let root = root_bank.slot();
@ -209,7 +216,7 @@ impl Tower {
) )
.clone(); .clone();
Self::new(my_pubkey, vote_account, root, &heaviest_bank, ledger_path) Self::new(node_pubkey, vote_account, root, &heaviest_bank, ledger_path)
} }
pub(crate) fn collect_vote_lockouts<F>( pub(crate) fn collect_vote_lockouts<F>(
@ -1165,13 +1172,9 @@ impl Tower {
self.initialize_lockouts(|v| v.slot > root); self.initialize_lockouts(|v| v.slot > root);
trace!( trace!(
"Lockouts in tower for {} is initialized using bank {}", "Lockouts in tower for {} is initialized using bank {}",
self.node_pubkey, self.vote_state.node_pubkey,
bank.slot(), bank.slot(),
); );
assert_eq!(
self.vote_state.node_pubkey, self.node_pubkey,
"vote account's node_pubkey doesn't match",
);
} else { } else {
self.initialize_root(root); self.initialize_root(root);
info!( info!(
@ -1231,8 +1234,8 @@ impl Tower {
Ok(()) Ok(())
} }
pub fn restore(path: &Path, node_pubkey: &Pubkey) -> Result<Self> { pub fn restore(ledger_path: &Path, node_pubkey: &Pubkey) -> Result<Self> {
let filename = Self::get_filename(path, node_pubkey); let filename = Self::get_filename(ledger_path, node_pubkey);
// Ensure to create parent dir here, because restore() precedes save() always // Ensure to create parent dir here, because restore() precedes save() always
fs::create_dir_all(&filename.parent().unwrap())?; fs::create_dir_all(&filename.parent().unwrap())?;
@ -1245,6 +1248,7 @@ impl Tower {
return Err(TowerError::InvalidSignature); return Err(TowerError::InvalidSignature);
} }
let mut tower = saved_tower.deserialize()?; let mut tower = saved_tower.deserialize()?;
tower.ledger_path = ledger_path.into();
tower.path = filename; tower.path = filename;
tower.tmp_path = Self::get_tmp_filename(&tower.path); tower.tmp_path = Self::get_tmp_filename(&tower.path);
@ -1925,7 +1929,7 @@ pub mod test {
fn test_switch_threshold_votes() { fn test_switch_threshold_votes() {
// Init state // Init state
let mut vote_simulator = VoteSimulator::new(4); let mut vote_simulator = VoteSimulator::new(4);
let my_pubkey = vote_simulator.node_pubkeys[0]; let node_pubkey = vote_simulator.node_pubkeys[0];
let mut tower = Tower::default(); let mut tower = Tower::default();
let forks = tr(0) let forks = tr(0)
/ (tr(1) / (tr(1)
@ -1947,7 +1951,7 @@ pub mod test {
// Vote on the first minor fork at slot 14, should succeed // Vote on the first minor fork at slot 14, should succeed
assert!(vote_simulator assert!(vote_simulator
.simulate_vote(14, &my_pubkey, &mut tower,) .simulate_vote(14, &node_pubkey, &mut tower,)
.is_empty()); .is_empty());
// The other two validators voted at slots 46, 47, which // The other two validators voted at slots 46, 47, which
@ -1960,7 +1964,7 @@ pub mod test {
48, 48,
&cluster_votes, &cluster_votes,
&votes_to_simulate, &votes_to_simulate,
&my_pubkey, &node_pubkey,
&mut tower, &mut tower,
); );
for slot in 46..=48 { for slot in 46..=48 {
@ -2519,7 +2523,8 @@ pub mod test {
// Use values that will not match the default derived from BankForks // Use values that will not match the default derived from BankForks
let mut tower = Tower::new_for_tests(10, 0.9); let mut tower = Tower::new_for_tests(10, 0.9);
tower.path = Tower::get_filename(&dir.path().to_path_buf(), &identity_keypair.pubkey()); tower.ledger_path = dir.path().to_path_buf();
tower.path = Tower::get_filename(&tower.ledger_path, &identity_keypair.pubkey());
tower.tmp_path = Tower::get_tmp_filename(&tower.path); tower.tmp_path = Tower::get_tmp_filename(&tower.path);
modify_original(&mut tower, &identity_keypair.pubkey()); modify_original(&mut tower, &identity_keypair.pubkey());

View File

@ -635,6 +635,7 @@ impl ReplayStage {
identity_keypair = cluster_info.keypair().clone(); identity_keypair = cluster_info.keypair().clone();
let my_old_pubkey = my_pubkey; let my_old_pubkey = my_pubkey;
my_pubkey = identity_keypair.pubkey(); my_pubkey = identity_keypair.pubkey();
tower.set_identity(my_pubkey);
warn!("Identity changed from {} to {}", my_old_pubkey, my_pubkey); warn!("Identity changed from {} to {}", my_old_pubkey, my_pubkey);
} }
@ -1576,6 +1577,16 @@ impl ReplayStage {
} }
Ok(vote_state) => vote_state, Ok(vote_state) => vote_state,
}; };
if vote_state.node_pubkey != node_keypair.pubkey() {
info!(
"Vote account node_pubkey mismatch: {} (expected: {}). Unable to vote",
vote_state.node_pubkey,
node_keypair.pubkey()
);
return None;
}
let authorized_voter_pubkey = let authorized_voter_pubkey =
if let Some(authorized_voter_pubkey) = vote_state.get_authorized_voter(bank.epoch()) { if let Some(authorized_voter_pubkey) = vote_state.get_authorized_voter(bank.epoch()) {
authorized_voter_pubkey authorized_voter_pubkey