2021-12-03 09:00:31 -08:00
|
|
|
use {
|
|
|
|
solana_ledger::{
|
|
|
|
blockstore::Blockstore,
|
|
|
|
shred::{Nonce, SIZE_OF_NONCE},
|
|
|
|
},
|
|
|
|
solana_sdk::{clock::Slot, packet::Packet},
|
|
|
|
std::{io, net::SocketAddr},
|
2020-05-19 12:38:18 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
pub fn repair_response_packet(
|
|
|
|
blockstore: &Blockstore,
|
|
|
|
slot: Slot,
|
|
|
|
shred_index: u64,
|
|
|
|
dest: &SocketAddr,
|
|
|
|
nonce: Nonce,
|
|
|
|
) -> Option<Packet> {
|
|
|
|
let shred = blockstore
|
|
|
|
.get_data_shred(slot, shred_index)
|
|
|
|
.expect("Blockstore could not get data shred");
|
|
|
|
shred
|
2021-07-15 19:29:53 -07:00
|
|
|
.map(|shred| repair_response_packet_from_bytes(shred, dest, nonce))
|
2020-05-19 12:38:18 -07:00
|
|
|
.unwrap_or(None)
|
|
|
|
}
|
|
|
|
|
2021-07-15 19:29:53 -07:00
|
|
|
pub fn repair_response_packet_from_bytes(
|
|
|
|
bytes: Vec<u8>,
|
2020-05-19 12:38:18 -07:00
|
|
|
dest: &SocketAddr,
|
|
|
|
nonce: Nonce,
|
|
|
|
) -> Option<Packet> {
|
|
|
|
let mut packet = Packet::default();
|
2022-05-25 09:52:54 -07:00
|
|
|
let size = bytes.len() + SIZE_OF_NONCE;
|
|
|
|
if size > packet.buffer_mut().len() {
|
2020-05-19 12:38:18 -07:00
|
|
|
return None;
|
|
|
|
}
|
2022-05-25 09:52:54 -07:00
|
|
|
packet.meta.size = size;
|
2022-05-23 08:48:59 -07:00
|
|
|
packet.meta.set_socket_addr(dest);
|
2022-05-25 09:52:54 -07:00
|
|
|
packet.buffer_mut()[..bytes.len()].copy_from_slice(&bytes);
|
|
|
|
let mut wr = io::Cursor::new(&mut packet.buffer_mut()[bytes.len()..]);
|
2020-05-19 12:38:18 -07:00
|
|
|
bincode::serialize_into(&mut wr, &nonce).expect("Buffer not large enough to fit nonce");
|
|
|
|
Some(packet)
|
|
|
|
}
|
|
|
|
|
2022-05-23 20:15:20 -07:00
|
|
|
pub fn nonce(packet: &Packet) -> Option<Nonce> {
|
|
|
|
let nonce_start = packet.meta.size.checked_sub(SIZE_OF_NONCE)?;
|
|
|
|
packet.deserialize_slice(nonce_start..).ok()
|
2020-05-19 12:38:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod test {
|
2021-12-03 09:00:31 -08:00
|
|
|
use {
|
|
|
|
super::*,
|
2022-05-02 16:33:53 -07:00
|
|
|
solana_ledger::{
|
|
|
|
shred::{Shred, ShredFlags},
|
|
|
|
sigverify_shreds::verify_shred_cpu,
|
|
|
|
},
|
2022-01-02 09:10:32 -08:00
|
|
|
solana_sdk::{
|
|
|
|
packet::PacketFlags,
|
|
|
|
signature::{Keypair, Signer},
|
|
|
|
},
|
2021-12-03 09:00:31 -08:00
|
|
|
std::{
|
|
|
|
collections::HashMap,
|
|
|
|
net::{IpAddr, Ipv4Addr},
|
|
|
|
},
|
2020-05-19 12:38:18 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
fn run_test_sigverify_shred_cpu_repair(slot: Slot) {
|
|
|
|
solana_logger::setup();
|
|
|
|
let mut shred = Shred::new_from_data(
|
|
|
|
slot,
|
|
|
|
0xc0de,
|
|
|
|
0xdead,
|
2022-04-27 11:04:10 -07:00
|
|
|
&[1, 2, 3, 4],
|
2022-05-02 16:33:53 -07:00
|
|
|
ShredFlags::LAST_SHRED_IN_SLOT,
|
2020-05-19 12:38:18 -07:00
|
|
|
0,
|
|
|
|
0,
|
|
|
|
0xc0de,
|
|
|
|
);
|
|
|
|
assert_eq!(shred.slot(), slot);
|
|
|
|
let keypair = Keypair::new();
|
2022-04-19 13:00:05 -07:00
|
|
|
shred.sign(&keypair);
|
2022-04-25 05:43:22 -07:00
|
|
|
trace!("signature {}", shred.signature());
|
2020-05-19 12:38:18 -07:00
|
|
|
let nonce = 9;
|
2021-07-15 19:29:53 -07:00
|
|
|
let mut packet = repair_response_packet_from_bytes(
|
2022-04-25 05:43:22 -07:00
|
|
|
shred.into_payload(),
|
2020-05-19 12:38:18 -07:00
|
|
|
&SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080),
|
|
|
|
nonce,
|
|
|
|
)
|
|
|
|
.unwrap();
|
2022-01-02 09:10:32 -08:00
|
|
|
packet.meta.flags |= PacketFlags::REPAIR;
|
2020-05-19 12:38:18 -07:00
|
|
|
|
|
|
|
let leader_slots = [(slot, keypair.pubkey().to_bytes())]
|
|
|
|
.iter()
|
|
|
|
.cloned()
|
|
|
|
.collect();
|
2022-05-26 06:06:27 -07:00
|
|
|
assert!(verify_shred_cpu(&packet, &leader_slots));
|
2020-05-19 12:38:18 -07:00
|
|
|
|
|
|
|
let wrong_keypair = Keypair::new();
|
|
|
|
let leader_slots = [(slot, wrong_keypair.pubkey().to_bytes())]
|
|
|
|
.iter()
|
|
|
|
.cloned()
|
|
|
|
.collect();
|
2022-05-26 06:06:27 -07:00
|
|
|
assert!(!verify_shred_cpu(&packet, &leader_slots));
|
2020-05-19 12:38:18 -07:00
|
|
|
|
|
|
|
let leader_slots = HashMap::new();
|
2022-05-26 06:06:27 -07:00
|
|
|
assert!(!verify_shred_cpu(&packet, &leader_slots));
|
2020-05-19 12:38:18 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn test_sigverify_shred_cpu_repair() {
|
|
|
|
run_test_sigverify_shred_cpu_repair(0xdead_c0de);
|
|
|
|
}
|
|
|
|
}
|