Further expand last_voted_slot terminology (#10747)

This commit is contained in:
Ryo Onodera
2020-06-23 21:52:45 +09:00
committed by GitHub
parent cabd0a09c3
commit 685becad13
2 changed files with 35 additions and 28 deletions

View File

@ -185,9 +185,9 @@ impl Tower {
} }
let start_root = vote_state.root_slot; let start_root = vote_state.root_slot;
// Add the latest vote to update the `heaviest_subtree_fork_choice` // Add the last vote to update the `heaviest_subtree_fork_choice`
if let Some(latest_vote) = vote_state.votes.back() { if let Some(last_voted_slot) = vote_state.last_voted_slot() {
pubkey_votes.push((key, latest_vote.slot)); pubkey_votes.push((key, last_voted_slot));
} }
vote_state.process_slot_vote_unchecked(bank_slot); vote_state.process_slot_vote_unchecked(bank_slot);
@ -265,45 +265,45 @@ impl Tower {
fn new_vote( fn new_vote(
local_vote_state: &VoteState, local_vote_state: &VoteState,
slot: u64, slot: Slot,
hash: Hash, hash: Hash,
last_bank_slot: Option<Slot>, last_voted_slot_in_bank: Option<Slot>,
) -> (Vote, usize) { ) -> (Vote, usize) {
let mut local_vote_state = local_vote_state.clone(); let mut local_vote_state = local_vote_state.clone();
let vote = Vote::new(vec![slot], hash); let vote = Vote::new(vec![slot], hash);
local_vote_state.process_vote_unchecked(&vote); local_vote_state.process_vote_unchecked(&vote);
let slots = if let Some(last_bank_slot) = last_bank_slot { let slots = if let Some(last_voted_slot_in_bank) = last_voted_slot_in_bank {
local_vote_state local_vote_state
.votes .votes
.iter() .iter()
.map(|v| v.slot) .map(|v| v.slot)
.skip_while(|s| *s <= last_bank_slot) .skip_while(|s| *s <= last_voted_slot_in_bank)
.collect() .collect()
} else { } else {
local_vote_state.votes.iter().map(|v| v.slot).collect() local_vote_state.votes.iter().map(|v| v.slot).collect()
}; };
trace!( trace!(
"new vote with {:?} {:?} {:?}", "new vote with {:?} {:?} {:?}",
last_bank_slot, last_voted_slot_in_bank,
slots, slots,
local_vote_state.votes local_vote_state.votes
); );
(Vote::new(slots, hash), local_vote_state.votes.len() - 1) (Vote::new(slots, hash), local_vote_state.votes.len() - 1)
} }
fn last_bank_vote(bank: &Bank, vote_account_pubkey: &Pubkey) -> Option<Slot> { fn last_voted_slot_in_bank(bank: &Bank, vote_account_pubkey: &Pubkey) -> Option<Slot> {
let vote_account = bank.vote_accounts().get(vote_account_pubkey)?.1.clone(); let vote_account = bank.vote_accounts().get(vote_account_pubkey)?.1.clone();
let bank_vote_state = VoteState::deserialize(&vote_account.data).ok()?; let bank_vote_state = VoteState::deserialize(&vote_account.data).ok()?;
bank_vote_state.votes.iter().map(|v| v.slot).last() bank_vote_state.last_voted_slot()
} }
pub fn new_vote_from_bank(&self, bank: &Bank, vote_account_pubkey: &Pubkey) -> (Vote, usize) { pub fn new_vote_from_bank(&self, bank: &Bank, vote_account_pubkey: &Pubkey) -> (Vote, usize) {
let last_vote = Self::last_bank_vote(bank, vote_account_pubkey); let voted_slot = Self::last_voted_slot_in_bank(bank, vote_account_pubkey);
Self::new_vote(&self.lockouts, bank.slot(), bank.hash(), last_vote) Self::new_vote(&self.lockouts, bank.slot(), bank.hash(), voted_slot)
} }
pub fn record_bank_vote(&mut self, vote: Vote) -> Option<Slot> { pub fn record_bank_vote(&mut self, vote: Vote) -> Option<Slot> {
let slot = *vote.slots.last().unwrap_or(&0); let slot = vote.last_voted_slot().unwrap_or(0);
trace!("{} record_vote for {}", self.node_pubkey, slot); trace!("{} record_vote for {}", self.node_pubkey, slot);
let root_slot = self.lockouts.root_slot; let root_slot = self.lockouts.root_slot;
self.lockouts.process_vote_unchecked(&vote); self.lockouts.process_vote_unchecked(&vote);
@ -344,19 +344,19 @@ impl Tower {
self.lockouts.root_slot self.lockouts.root_slot
} }
// a slot is not recent if it's older than the newest vote we have // a slot is recent if it's newer than the last vote we have
pub fn is_recent(&self, slot: u64) -> bool { pub fn is_recent(&self, slot: Slot) -> bool {
if let Some(last_vote) = self.lockouts.votes.back() { if let Some(last_voted_slot) = self.lockouts.last_voted_slot() {
if slot <= last_vote.slot { if slot <= last_voted_slot {
return false; return false;
} }
} }
true true
} }
pub fn has_voted(&self, slot: u64) -> bool { pub fn has_voted(&self, slot: Slot) -> bool {
for vote in &self.lockouts.votes { for vote in &self.lockouts.votes {
if vote.slot == slot { if slot == vote.slot {
return true; return true;
} }
} }

View File

@ -283,11 +283,10 @@ impl VoteState {
let mut i = 0; // index into the vote's slots let mut i = 0; // index into the vote's slots
let mut j = slot_hashes.len(); // index into the slot_hashes let mut j = slot_hashes.len(); // index into the slot_hashes
while i < vote.slots.len() && j > 0 { while i < vote.slots.len() && j > 0 {
// find the most recent "new" slot in the vote // find the last slot in the vote
if self if self
.votes .last_voted_slot()
.back() .map_or(false, |last_voted_slot| vote.slots[i] <= last_voted_slot)
.map_or(false, |old_vote| old_vote.slot >= vote.slots[i])
{ {
i += 1; i += 1;
continue; continue;
@ -341,9 +340,8 @@ impl VoteState {
pub fn process_slot(&mut self, slot: Slot, epoch: Epoch) { pub fn process_slot(&mut self, slot: Slot, epoch: Epoch) {
// Ignore votes for slots earlier than we already have votes for // Ignore votes for slots earlier than we already have votes for
if self if self
.votes .last_voted_slot()
.back() .map_or(false, |last_voted_slot| slot <= last_voted_slot)
.map_or(false, |old_vote| old_vote.slot >= slot)
{ {
return; return;
} }
@ -410,6 +408,14 @@ impl VoteState {
} }
} }
pub fn last_lockout(&self) -> Option<&Lockout> {
self.votes.back()
}
pub fn last_voted_slot(&self) -> Option<Slot> {
self.last_lockout().map(|v| v.slot)
}
fn current_epoch(&self) -> Epoch { fn current_epoch(&self) -> Epoch {
if self.epoch_credits.is_empty() { if self.epoch_credits.is_empty() {
0 0
@ -513,7 +519,7 @@ impl VoteState {
fn pop_expired_votes(&mut self, slot: Slot) { fn pop_expired_votes(&mut self, slot: Slot) {
loop { loop {
if self.votes.back().map_or(false, |v| v.is_expired(slot)) { if self.last_lockout().map_or(false, |v| v.is_expired(slot)) {
self.votes.pop_back(); self.votes.pop_back();
} else { } else {
break; break;
@ -1279,7 +1285,8 @@ mod tests {
// the root_slot should change to the // the root_slot should change to the
// second vote // second vote
let top_vote = vote_state.votes.front().unwrap().slot; let top_vote = vote_state.votes.front().unwrap().slot;
vote_state.process_slot_vote_unchecked(vote_state.votes.back().unwrap().expiration_slot()); vote_state
.process_slot_vote_unchecked(vote_state.last_lockout().unwrap().expiration_slot());
assert_eq!(Some(top_vote), vote_state.root_slot); assert_eq!(Some(top_vote), vote_state.root_slot);
// Expire everything except the first vote // Expire everything except the first vote