2019-06-19 00:13:19 -07:00
|
|
|
use super::*;
|
2019-10-18 09:28:51 -07:00
|
|
|
use solana_ledger::shred::{Shredder, RECOMMENDED_FEC_RATE};
|
2019-06-19 00:13:19 -07:00
|
|
|
use solana_sdk::hash::Hash;
|
2019-12-16 17:11:18 -08:00
|
|
|
use solana_sdk::signature::Keypair;
|
2019-06-19 00:13:19 -07:00
|
|
|
|
2019-12-16 17:11:18 -08:00
|
|
|
#[derive(Clone)]
|
2019-11-18 18:05:02 -08:00
|
|
|
pub(super) struct FailEntryVerificationBroadcastRun {
|
|
|
|
shred_version: u16,
|
2019-12-16 17:11:18 -08:00
|
|
|
keypair: Arc<Keypair>,
|
2019-11-18 18:05:02 -08:00
|
|
|
}
|
2019-06-19 00:13:19 -07:00
|
|
|
|
|
|
|
impl FailEntryVerificationBroadcastRun {
|
2019-12-16 17:11:18 -08:00
|
|
|
pub(super) fn new(keypair: Arc<Keypair>, shred_version: u16) -> Self {
|
|
|
|
Self {
|
|
|
|
shred_version,
|
|
|
|
keypair,
|
|
|
|
}
|
2019-06-19 00:13:19 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl BroadcastRun for FailEntryVerificationBroadcastRun {
|
|
|
|
fn run(
|
|
|
|
&mut self,
|
2020-01-13 13:13:52 -08:00
|
|
|
blockstore: &Arc<Blockstore>,
|
2019-12-16 17:11:18 -08:00
|
|
|
receiver: &Receiver<WorkingBankEntry>,
|
|
|
|
socket_sender: &Sender<TransmitShreds>,
|
2020-01-13 13:13:52 -08:00
|
|
|
blockstore_sender: &Sender<Arc<Vec<Shred>>>,
|
2019-06-19 00:13:19 -07:00
|
|
|
) -> Result<()> {
|
|
|
|
// 1) Pull entries from banking stage
|
2019-09-18 12:16:22 -07:00
|
|
|
let mut receive_results = broadcast_utils::recv_slot_entries(receiver)?;
|
2019-06-19 00:13:19 -07:00
|
|
|
let bank = receive_results.bank.clone();
|
2019-10-16 12:53:11 -07:00
|
|
|
let last_tick_height = receive_results.last_tick_height;
|
2019-06-19 00:13:19 -07:00
|
|
|
|
2019-11-14 11:49:31 -08:00
|
|
|
// 2) Convert entries to shreds + generate coding shreds. Set a garbage PoH on the last entry
|
2019-06-19 00:13:19 -07:00
|
|
|
// in the slot to make verification fail on validators
|
2019-10-16 12:53:11 -07:00
|
|
|
if last_tick_height == bank.max_tick_height() {
|
2019-09-18 12:16:22 -07:00
|
|
|
let mut last_entry = receive_results.entries.last_mut().unwrap();
|
|
|
|
last_entry.hash = Hash::default();
|
2019-06-19 00:13:19 -07:00
|
|
|
}
|
|
|
|
|
2020-01-13 13:13:52 -08:00
|
|
|
let next_shred_index = blockstore
|
2019-06-19 00:13:19 -07:00
|
|
|
.meta(bank.slot())
|
|
|
|
.expect("Database error")
|
|
|
|
.map(|meta| meta.consumed)
|
2019-10-08 00:42:51 -07:00
|
|
|
.unwrap_or(0) as u32;
|
2019-06-19 00:13:19 -07:00
|
|
|
|
2019-10-08 00:42:51 -07:00
|
|
|
let shredder = Shredder::new(
|
2019-09-18 12:16:22 -07:00
|
|
|
bank.slot(),
|
2019-09-03 21:32:51 -07:00
|
|
|
bank.parent().unwrap().slot(),
|
2019-10-08 00:42:51 -07:00
|
|
|
RECOMMENDED_FEC_RATE,
|
2019-12-16 17:11:18 -08:00
|
|
|
self.keypair.clone(),
|
2019-11-06 13:27:58 -08:00
|
|
|
(bank.tick_height() % bank.ticks_per_slot()) as u8,
|
2019-11-18 18:05:02 -08:00
|
|
|
self.shred_version,
|
2019-10-08 00:42:51 -07:00
|
|
|
)
|
|
|
|
.expect("Expected to create a new shredder");
|
2019-06-19 00:13:19 -07:00
|
|
|
|
2019-10-08 00:42:51 -07:00
|
|
|
let (data_shreds, coding_shreds, _) = shredder.entries_to_shreds(
|
|
|
|
&receive_results.entries,
|
2019-10-16 12:53:11 -07:00
|
|
|
last_tick_height == bank.max_tick_height(),
|
2019-10-08 00:42:51 -07:00
|
|
|
next_shred_index,
|
|
|
|
);
|
2019-09-03 21:32:51 -07:00
|
|
|
|
2019-12-16 17:11:18 -08:00
|
|
|
let data_shreds = Arc::new(data_shreds);
|
2020-01-13 13:13:52 -08:00
|
|
|
blockstore_sender.send(data_shreds.clone())?;
|
2019-06-19 00:13:19 -07:00
|
|
|
// 3) Start broadcast step
|
2019-10-08 22:34:26 -07:00
|
|
|
let bank_epoch = bank.get_leader_schedule_epoch(bank.slot());
|
2019-06-19 00:13:19 -07:00
|
|
|
let stakes = staking_utils::staked_nodes_at_epoch(&bank, bank_epoch);
|
|
|
|
|
2019-12-16 17:11:18 -08:00
|
|
|
let stakes = stakes.map(Arc::new);
|
|
|
|
socket_sender.send((stakes.clone(), data_shreds))?;
|
|
|
|
socket_sender.send((stakes, Arc::new(coding_shreds)))?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
fn transmit(
|
|
|
|
&self,
|
|
|
|
receiver: &Arc<Mutex<Receiver<TransmitShreds>>>,
|
|
|
|
cluster_info: &Arc<RwLock<ClusterInfo>>,
|
|
|
|
sock: &UdpSocket,
|
|
|
|
) -> Result<()> {
|
|
|
|
let (stakes, shreds) = receiver.lock().unwrap().recv()?;
|
|
|
|
let all_seeds: Vec<[u8; 32]> = shreds.iter().map(|s| s.seed()).collect();
|
2019-10-08 00:42:51 -07:00
|
|
|
// Broadcast data
|
2019-12-16 17:11:18 -08:00
|
|
|
let all_shred_bufs: Vec<Vec<u8>> = shreds.to_vec().into_iter().map(|s| s.payload).collect();
|
|
|
|
cluster_info
|
2020-02-21 13:41:49 -08:00
|
|
|
.write()
|
2019-12-16 17:11:18 -08:00
|
|
|
.unwrap()
|
|
|
|
.broadcast_shreds(sock, all_shred_bufs, &all_seeds, stakes)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
fn record(
|
|
|
|
&self,
|
|
|
|
receiver: &Arc<Mutex<Receiver<Arc<Vec<Shred>>>>>,
|
2020-01-13 13:13:52 -08:00
|
|
|
blockstore: &Arc<Blockstore>,
|
2019-12-16 17:11:18 -08:00
|
|
|
) -> Result<()> {
|
|
|
|
let all_shreds = receiver.lock().unwrap().recv()?;
|
2020-01-13 13:13:52 -08:00
|
|
|
blockstore
|
2019-12-16 17:11:18 -08:00
|
|
|
.insert_shreds(all_shreds.to_vec(), None, true)
|
2020-01-13 13:13:52 -08:00
|
|
|
.expect("Failed to insert shreds in blockstore");
|
2019-06-19 00:13:19 -07:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|