2018-05-22 14:26:28 -07:00
|
|
|
//! The `replicate_stage` replicates transactions broadcast by the leader.
|
|
|
|
|
2018-05-22 15:30:46 -07:00
|
|
|
use bank::Bank;
|
|
|
|
use ledger;
|
2018-05-22 14:26:28 -07:00
|
|
|
use packet;
|
2018-05-22 15:30:46 -07:00
|
|
|
use result::Result;
|
2018-05-22 15:18:07 -07:00
|
|
|
use std::sync::atomic::{AtomicBool, Ordering};
|
2018-05-29 20:20:28 -07:00
|
|
|
use std::sync::Arc;
|
2018-05-30 13:38:15 -07:00
|
|
|
use std::thread::{Builder, JoinHandle};
|
2018-05-22 15:30:46 -07:00
|
|
|
use std::time::Duration;
|
2018-05-22 14:26:28 -07:00
|
|
|
use streamer;
|
|
|
|
|
|
|
|
pub struct ReplicateStage {
|
|
|
|
pub thread_hdl: JoinHandle<()>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ReplicateStage {
|
2018-06-15 14:27:06 -07:00
|
|
|
/// Process entry blobs, already in order
|
2018-05-22 15:30:46 -07:00
|
|
|
fn replicate_requests(
|
|
|
|
bank: &Arc<Bank>,
|
2018-06-15 14:27:06 -07:00
|
|
|
blob_receiver: &streamer::BlobReceiver,
|
2018-05-22 15:30:46 -07:00
|
|
|
blob_recycler: &packet::BlobRecycler,
|
|
|
|
) -> Result<()> {
|
|
|
|
let timer = Duration::new(1, 0);
|
2018-06-15 14:27:06 -07:00
|
|
|
let blobs = blob_receiver.recv_timeout(timer)?;
|
2018-06-22 12:20:29 -07:00
|
|
|
let blobs_len = blobs.len();
|
|
|
|
let entries = ledger::reconstruct_entries_from_blobs(blobs, &blob_recycler)?;
|
2018-05-29 08:52:40 -07:00
|
|
|
let res = bank.process_entries(entries);
|
2018-05-22 15:30:46 -07:00
|
|
|
if res.is_err() {
|
2018-06-22 12:20:29 -07:00
|
|
|
error!("process_entries {} {:?}", blobs_len, res);
|
2018-05-22 15:30:46 -07:00
|
|
|
}
|
|
|
|
res?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2018-05-22 15:18:07 -07:00
|
|
|
pub fn new(
|
2018-05-22 15:30:46 -07:00
|
|
|
bank: Arc<Bank>,
|
2018-05-22 15:18:07 -07:00
|
|
|
exit: Arc<AtomicBool>,
|
|
|
|
window_receiver: streamer::BlobReceiver,
|
|
|
|
blob_recycler: packet::BlobRecycler,
|
|
|
|
) -> Self {
|
2018-05-30 13:38:15 -07:00
|
|
|
let thread_hdl = Builder::new()
|
|
|
|
.name("solana-replicate-stage".to_string())
|
|
|
|
.spawn(move || loop {
|
|
|
|
let e = Self::replicate_requests(&bank, &window_receiver, &blob_recycler);
|
|
|
|
if e.is_err() && exit.load(Ordering::Relaxed) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
})
|
|
|
|
.unwrap();
|
2018-05-22 15:18:07 -07:00
|
|
|
ReplicateStage { thread_hdl }
|
2018-05-22 14:26:28 -07:00
|
|
|
}
|
|
|
|
}
|