2021-08-09 11:32:48 -07:00
|
|
|
use crate::tower_storage::{SavedTower, TowerStorage};
|
2021-07-15 07:35:51 -07:00
|
|
|
use solana_gossip::cluster_info::ClusterInfo;
|
2021-07-22 12:49:58 -07:00
|
|
|
use solana_measure::measure::Measure;
|
2021-07-15 07:35:51 -07:00
|
|
|
use solana_poh::poh_recorder::PohRecorder;
|
|
|
|
use solana_sdk::{clock::Slot, transaction::Transaction};
|
|
|
|
use std::{
|
|
|
|
sync::{mpsc::Receiver, Arc, Mutex},
|
|
|
|
thread::{self, Builder, JoinHandle},
|
|
|
|
};
|
|
|
|
|
|
|
|
pub enum VoteOp {
|
|
|
|
PushVote {
|
|
|
|
tx: Transaction,
|
|
|
|
tower_slots: Vec<Slot>,
|
2021-07-22 12:49:58 -07:00
|
|
|
saved_tower: SavedTower,
|
2021-07-15 07:35:51 -07:00
|
|
|
},
|
|
|
|
RefreshVote {
|
|
|
|
tx: Transaction,
|
|
|
|
last_voted_slot: Slot,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
impl VoteOp {
|
|
|
|
fn tx(&self) -> &Transaction {
|
|
|
|
match self {
|
2021-07-22 12:49:58 -07:00
|
|
|
VoteOp::PushVote { tx, .. } => tx,
|
|
|
|
VoteOp::RefreshVote { tx, .. } => tx,
|
2021-07-15 07:35:51 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub struct VotingService {
|
|
|
|
thread_hdl: JoinHandle<()>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl VotingService {
|
|
|
|
pub fn new(
|
|
|
|
vote_receiver: Receiver<VoteOp>,
|
|
|
|
cluster_info: Arc<ClusterInfo>,
|
|
|
|
poh_recorder: Arc<Mutex<PohRecorder>>,
|
2021-07-22 12:49:58 -07:00
|
|
|
tower_storage: Arc<dyn TowerStorage>,
|
2021-07-15 07:35:51 -07:00
|
|
|
) -> Self {
|
|
|
|
let thread_hdl = Builder::new()
|
|
|
|
.name("sol-vote-service".to_string())
|
|
|
|
.spawn(move || {
|
|
|
|
for vote_op in vote_receiver.iter() {
|
2021-07-22 12:49:58 -07:00
|
|
|
Self::handle_vote(
|
|
|
|
&cluster_info,
|
|
|
|
&poh_recorder,
|
|
|
|
tower_storage.as_ref(),
|
|
|
|
vote_op,
|
|
|
|
);
|
2021-07-15 07:35:51 -07:00
|
|
|
}
|
|
|
|
})
|
|
|
|
.unwrap();
|
|
|
|
Self { thread_hdl }
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn handle_vote(
|
|
|
|
cluster_info: &ClusterInfo,
|
|
|
|
poh_recorder: &Mutex<PohRecorder>,
|
2021-07-22 12:49:58 -07:00
|
|
|
tower_storage: &dyn TowerStorage,
|
2021-07-15 07:35:51 -07:00
|
|
|
vote_op: VoteOp,
|
|
|
|
) {
|
2021-07-22 12:49:58 -07:00
|
|
|
if let VoteOp::PushVote { saved_tower, .. } = &vote_op {
|
|
|
|
let mut measure = Measure::start("tower_save-ms");
|
|
|
|
if let Err(err) = tower_storage.store(saved_tower) {
|
|
|
|
error!("Unable to save tower to storage: {:?}", err);
|
|
|
|
std::process::exit(1);
|
|
|
|
}
|
|
|
|
measure.stop();
|
|
|
|
inc_new_counter_info!("tower_save-ms", measure.as_ms() as usize);
|
|
|
|
}
|
|
|
|
|
2021-07-15 07:35:51 -07:00
|
|
|
let _ = cluster_info.send_transaction(
|
|
|
|
vote_op.tx(),
|
|
|
|
crate::banking_stage::next_leader_tpu(cluster_info, poh_recorder),
|
|
|
|
);
|
|
|
|
|
|
|
|
match vote_op {
|
2021-07-22 12:49:58 -07:00
|
|
|
VoteOp::PushVote {
|
|
|
|
tx, tower_slots, ..
|
|
|
|
} => {
|
2021-07-15 07:35:51 -07:00
|
|
|
cluster_info.push_vote(&tower_slots, tx);
|
|
|
|
}
|
|
|
|
VoteOp::RefreshVote {
|
|
|
|
tx,
|
|
|
|
last_voted_slot,
|
|
|
|
} => {
|
|
|
|
cluster_info.refresh_vote(tx, last_voted_slot);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn join(self) -> thread::Result<()> {
|
|
|
|
self.thread_hdl.join()
|
|
|
|
}
|
|
|
|
}
|