Refactor chacha cuda to be able to test cuda crate but not in OpenCL (#7685)
* Refactor chacha cuda to be able to test cuda crate but not in OpenCL chacha not implemeted in OpenCL * Get off core::Error
This commit is contained in:
@@ -42,7 +42,6 @@ serde_derive = "1.0.103"
|
||||
serde_json = "1.0.44"
|
||||
solana-budget-program = { path = "../programs/budget", version = "0.23.0" }
|
||||
solana-clap-utils = { path = "../clap-utils", version = "0.23.0" }
|
||||
solana-chacha-sys = { path = "../chacha-sys", version = "0.23.0" }
|
||||
solana-client = { path = "../client", version = "0.23.0" }
|
||||
solana-faucet = { path = "../faucet", version = "0.23.0" }
|
||||
ed25519-dalek = "=1.0.0-pre.1"
|
||||
@@ -52,6 +51,7 @@ solana-merkle-tree = { path = "../merkle-tree", version = "0.23.0" }
|
||||
solana-metrics = { path = "../metrics", version = "0.23.0" }
|
||||
solana-measure = { path = "../measure", version = "0.23.0" }
|
||||
solana-net-utils = { path = "../net-utils", version = "0.23.0" }
|
||||
solana-chacha-cuda = { path = "../chacha-cuda", version = "0.23.0" }
|
||||
solana-perf = { path = "../perf", version = "0.23.0" }
|
||||
solana-runtime = { path = "../runtime", version = "0.23.0" }
|
||||
solana-sdk = { path = "../sdk", version = "0.23.0" }
|
||||
@@ -73,7 +73,6 @@ solana-rayon-threadlimit = { path = "../rayon-threadlimit", version = "0.23.0" }
|
||||
reed-solomon-erasure = { package = "solana-reed-solomon-erasure", version = "4.0.1-3", features = ["simd-accel"] }
|
||||
|
||||
[dev-dependencies]
|
||||
hex-literal = "0.2.1"
|
||||
matches = "0.1.6"
|
||||
reqwest = { version = "0.10.1", default-features = false, features = ["blocking", "rustls-tls"] }
|
||||
serial_test = "0.3.2"
|
||||
|
1066
core/src/archiver.rs
1066
core/src/archiver.rs
File diff suppressed because it is too large
Load Diff
@@ -1,182 +0,0 @@
|
||||
use solana_ledger::blockstore::Blockstore;
|
||||
use solana_sdk::clock::Slot;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
use std::io::{BufWriter, Write};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub use solana_chacha_sys::chacha_cbc_encrypt;
|
||||
|
||||
pub const CHACHA_BLOCK_SIZE: usize = 64;
|
||||
pub const CHACHA_KEY_SIZE: usize = 32;
|
||||
|
||||
pub fn chacha_cbc_encrypt_ledger(
|
||||
blockstore: &Arc<Blockstore>,
|
||||
start_slot: Slot,
|
||||
slots_per_segment: u64,
|
||||
out_path: &Path,
|
||||
ivec: &mut [u8; CHACHA_BLOCK_SIZE],
|
||||
) -> io::Result<usize> {
|
||||
let mut out_file =
|
||||
BufWriter::new(File::create(out_path).expect("Can't open ledger encrypted data file"));
|
||||
const BUFFER_SIZE: usize = 8 * 1024;
|
||||
let mut buffer = [0; BUFFER_SIZE];
|
||||
let mut encrypted_buffer = [0; BUFFER_SIZE];
|
||||
let key = [0; CHACHA_KEY_SIZE];
|
||||
let mut total_size = 0;
|
||||
let mut current_slot = start_slot;
|
||||
let mut start_index = 0;
|
||||
loop {
|
||||
match blockstore.get_data_shreds(current_slot, start_index, std::u64::MAX, &mut buffer) {
|
||||
Ok((last_index, mut size)) => {
|
||||
debug!(
|
||||
"chacha: encrypting slice: {} num_shreds: {} data_len: {}",
|
||||
current_slot,
|
||||
last_index.saturating_sub(start_index),
|
||||
size
|
||||
);
|
||||
debug!("read {} bytes", size);
|
||||
|
||||
if size == 0 {
|
||||
if current_slot.saturating_sub(start_slot) < slots_per_segment {
|
||||
current_slot += 1;
|
||||
start_index = 0;
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if size < BUFFER_SIZE {
|
||||
// round to the nearest key_size boundary
|
||||
size = (size + CHACHA_KEY_SIZE - 1) & !(CHACHA_KEY_SIZE - 1);
|
||||
}
|
||||
total_size += size;
|
||||
|
||||
chacha_cbc_encrypt(&buffer[..size], &mut encrypted_buffer[..size], &key, ivec);
|
||||
if let Err(res) = out_file.write(&encrypted_buffer[..size]) {
|
||||
warn!("Error writing file! {:?}", res);
|
||||
return Err(res);
|
||||
}
|
||||
|
||||
start_index = last_index + 1;
|
||||
}
|
||||
Err(e) => {
|
||||
info!("Error encrypting file: {:?}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(total_size)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::chacha::chacha_cbc_encrypt_ledger;
|
||||
use crate::gen_keys::GenKeys;
|
||||
use solana_ledger::blockstore::Blockstore;
|
||||
use solana_ledger::entry::Entry;
|
||||
use solana_ledger::get_tmp_ledger_path;
|
||||
use solana_sdk::hash::{hash, Hash, Hasher};
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
use solana_sdk::signature::KeypairUtil;
|
||||
use solana_sdk::system_transaction;
|
||||
use std::fs::remove_file;
|
||||
use std::fs::File;
|
||||
use std::io::Read;
|
||||
use std::sync::Arc;
|
||||
|
||||
fn make_tiny_deterministic_test_entries(num: usize) -> Vec<Entry> {
|
||||
let zero = Hash::default();
|
||||
let one = hash(&zero.as_ref());
|
||||
|
||||
let seed = [2u8; 32];
|
||||
let mut rnd = GenKeys::new(seed);
|
||||
let keypair = rnd.gen_keypair();
|
||||
|
||||
let mut id = one;
|
||||
let mut num_hashes = 0;
|
||||
(0..num)
|
||||
.map(|_| {
|
||||
Entry::new_mut(
|
||||
&mut id,
|
||||
&mut num_hashes,
|
||||
vec![system_transaction::transfer(
|
||||
&keypair,
|
||||
&keypair.pubkey(),
|
||||
1,
|
||||
one,
|
||||
)],
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
use std::{env, fs::create_dir_all, path::PathBuf};
|
||||
fn tmp_file_path(name: &str) -> PathBuf {
|
||||
let out_dir = env::var("FARF_DIR").unwrap_or_else(|_| "farf".to_string());
|
||||
let mut path = PathBuf::new();
|
||||
path.push(out_dir);
|
||||
path.push("tmp");
|
||||
create_dir_all(&path).unwrap();
|
||||
|
||||
path.push(format!("{}-{}", name, Pubkey::new_rand()));
|
||||
path
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encrypt_ledger() {
|
||||
solana_logger::setup();
|
||||
let ledger_path = get_tmp_ledger_path!();
|
||||
let ticks_per_slot = 16;
|
||||
let slots_per_segment = 32;
|
||||
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
|
||||
let out_path = tmp_file_path("test_encrypt_ledger");
|
||||
|
||||
let seed = [2u8; 32];
|
||||
let mut rnd = GenKeys::new(seed);
|
||||
let keypair = rnd.gen_keypair();
|
||||
|
||||
let entries = make_tiny_deterministic_test_entries(slots_per_segment);
|
||||
blockstore
|
||||
.write_entries(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
ticks_per_slot,
|
||||
None,
|
||||
true,
|
||||
&Arc::new(keypair),
|
||||
entries,
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let mut key = hex!(
|
||||
"abcd1234abcd1234abcd1234abcd1234 abcd1234abcd1234abcd1234abcd1234
|
||||
abcd1234abcd1234abcd1234abcd1234 abcd1234abcd1234abcd1234abcd1234"
|
||||
);
|
||||
chacha_cbc_encrypt_ledger(
|
||||
&blockstore,
|
||||
0,
|
||||
slots_per_segment as u64,
|
||||
&out_path,
|
||||
&mut key,
|
||||
)
|
||||
.unwrap();
|
||||
let mut out_file = File::open(&out_path).unwrap();
|
||||
let mut buf = vec![];
|
||||
let size = out_file.read_to_end(&mut buf).unwrap();
|
||||
let mut hasher = Hasher::default();
|
||||
hasher.hash(&buf[..size]);
|
||||
|
||||
// golden needs to be updated if shred structure changes....
|
||||
let golden: Hash = "2rq8nR6rns2T5zsbQAGBDZb41NVtacneLgkCH17CVxZm"
|
||||
.parse()
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(hasher.result(), golden);
|
||||
remove_file(&out_path).unwrap();
|
||||
}
|
||||
}
|
@@ -1,280 +0,0 @@
|
||||
// Module used by validators to approve storage mining proofs in parallel using the GPU
|
||||
|
||||
use crate::chacha::{CHACHA_BLOCK_SIZE, CHACHA_KEY_SIZE};
|
||||
use solana_ledger::blockstore::Blockstore;
|
||||
use solana_perf::perf_libs;
|
||||
use solana_sdk::hash::Hash;
|
||||
use std::io;
|
||||
use std::mem::size_of;
|
||||
use std::sync::Arc;
|
||||
|
||||
// Encrypt a file with multiple starting IV states, determined by ivecs.len()
|
||||
//
|
||||
// Then sample each block at the offsets provided by samples argument with sha256
|
||||
// and return the vec of sha states
|
||||
pub fn chacha_cbc_encrypt_file_many_keys(
|
||||
blockstore: &Arc<Blockstore>,
|
||||
segment: u64,
|
||||
slots_per_segment: u64,
|
||||
ivecs: &mut [u8],
|
||||
samples: &[u64],
|
||||
) -> io::Result<Vec<Hash>> {
|
||||
let api = perf_libs::api().expect("no perf libs");
|
||||
if ivecs.len() % CHACHA_BLOCK_SIZE != 0 {
|
||||
return Err(io::Error::new(
|
||||
io::ErrorKind::Other,
|
||||
format!(
|
||||
"bad IV length({}) not divisible by {} ",
|
||||
ivecs.len(),
|
||||
CHACHA_BLOCK_SIZE,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
const BUFFER_SIZE: usize = 8 * 1024;
|
||||
let mut buffer = [0; BUFFER_SIZE];
|
||||
let num_keys = ivecs.len() / CHACHA_BLOCK_SIZE;
|
||||
let mut sha_states = vec![0; num_keys * size_of::<Hash>()];
|
||||
let mut int_sha_states = vec![0; num_keys * 112];
|
||||
let keys: Vec<u8> = vec![0; num_keys * CHACHA_KEY_SIZE]; // keys not used ATM, uniqueness comes from IV
|
||||
let mut current_slot = segment * slots_per_segment;
|
||||
let mut start_index = 0;
|
||||
let start_slot = current_slot;
|
||||
let mut total_size = 0;
|
||||
let mut time: f32 = 0.0;
|
||||
unsafe {
|
||||
(api.chacha_init_sha_state)(int_sha_states.as_mut_ptr(), num_keys as u32);
|
||||
}
|
||||
loop {
|
||||
match blockstore.get_data_shreds(current_slot, start_index, std::u64::MAX, &mut buffer) {
|
||||
Ok((last_index, mut size)) => {
|
||||
debug!(
|
||||
"chacha_cuda: encrypting segment: {} num_shreds: {} data_len: {}",
|
||||
segment,
|
||||
last_index.saturating_sub(start_index),
|
||||
size
|
||||
);
|
||||
|
||||
if size == 0 {
|
||||
if current_slot.saturating_sub(start_slot) < slots_per_segment {
|
||||
current_slot += 1;
|
||||
start_index = 0;
|
||||
continue;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if size < BUFFER_SIZE {
|
||||
// round to the nearest key_size boundary
|
||||
size = (size + CHACHA_KEY_SIZE - 1) & !(CHACHA_KEY_SIZE - 1);
|
||||
}
|
||||
|
||||
unsafe {
|
||||
(api.chacha_cbc_encrypt_many_sample)(
|
||||
buffer[..size].as_ptr(),
|
||||
int_sha_states.as_mut_ptr(),
|
||||
size,
|
||||
keys.as_ptr(),
|
||||
ivecs.as_mut_ptr(),
|
||||
num_keys as u32,
|
||||
samples.as_ptr(),
|
||||
samples.len() as u32,
|
||||
total_size,
|
||||
&mut time,
|
||||
);
|
||||
}
|
||||
|
||||
total_size += size as u64;
|
||||
start_index = last_index + 1;
|
||||
}
|
||||
Err(e) => {
|
||||
info!("Error encrypting file: {:?}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
unsafe {
|
||||
(api.chacha_end_sha_state)(
|
||||
int_sha_states.as_ptr(),
|
||||
sha_states.as_mut_ptr(),
|
||||
num_keys as u32,
|
||||
);
|
||||
}
|
||||
let mut res = Vec::new();
|
||||
for x in 0..num_keys {
|
||||
let start = x * size_of::<Hash>();
|
||||
let end = start + size_of::<Hash>();
|
||||
res.push(Hash::new(&sha_states[start..end]));
|
||||
}
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::archiver::sample_file;
|
||||
use crate::chacha::chacha_cbc_encrypt_ledger;
|
||||
use solana_ledger::entry::create_ticks;
|
||||
use solana_ledger::get_tmp_ledger_path;
|
||||
use solana_sdk::clock::DEFAULT_SLOTS_PER_SEGMENT;
|
||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||
use std::fs::{remove_dir_all, remove_file};
|
||||
use std::path::Path;
|
||||
|
||||
#[test]
|
||||
fn test_encrypt_file_many_keys_single() {
|
||||
solana_logger::setup();
|
||||
if perf_libs::api().is_none() {
|
||||
info!("perf-libs unavailable, skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
let slots_per_segment = 32;
|
||||
let entries = create_ticks(slots_per_segment, 0, Hash::default());
|
||||
let ledger_path = get_tmp_ledger_path!();
|
||||
let ticks_per_slot = 16;
|
||||
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
|
||||
|
||||
blockstore
|
||||
.write_entries(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
ticks_per_slot,
|
||||
Some(0),
|
||||
true,
|
||||
&Arc::new(Keypair::new()),
|
||||
entries,
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let out_path = Path::new("test_chacha_encrypt_file_many_keys_single_output.txt.enc");
|
||||
|
||||
let samples = [0];
|
||||
let mut ivecs = hex!(
|
||||
"abcd1234abcd1234abcd1234abcd1234 abcd1234abcd1234abcd1234abcd1234
|
||||
abcd1234abcd1234abcd1234abcd1234 abcd1234abcd1234abcd1234abcd1234"
|
||||
);
|
||||
|
||||
let mut cpu_iv = ivecs.clone();
|
||||
chacha_cbc_encrypt_ledger(
|
||||
&blockstore,
|
||||
0,
|
||||
slots_per_segment as u64,
|
||||
out_path,
|
||||
&mut cpu_iv,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let ref_hash = sample_file(&out_path, &samples).unwrap();
|
||||
|
||||
let hashes = chacha_cbc_encrypt_file_many_keys(
|
||||
&blockstore,
|
||||
0,
|
||||
slots_per_segment as u64,
|
||||
&mut ivecs,
|
||||
&samples,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(hashes[0], ref_hash);
|
||||
|
||||
let _ignored = remove_dir_all(&ledger_path);
|
||||
let _ignored = remove_file(out_path);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encrypt_file_many_keys_multiple_keys() {
|
||||
solana_logger::setup();
|
||||
if perf_libs::api().is_none() {
|
||||
info!("perf-libs unavailable, skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
let ledger_path = get_tmp_ledger_path!();
|
||||
let ticks_per_slot = 90;
|
||||
let entries = create_ticks(2 * ticks_per_slot, 0, Hash::default());
|
||||
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
|
||||
blockstore
|
||||
.write_entries(
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
ticks_per_slot,
|
||||
Some(0),
|
||||
true,
|
||||
&Arc::new(Keypair::new()),
|
||||
entries,
|
||||
0,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let out_path = Path::new("test_chacha_encrypt_file_many_keys_multiple_output.txt.enc");
|
||||
|
||||
let samples = [0, 1, 3, 4, 5, 150];
|
||||
let mut ivecs = Vec::new();
|
||||
let mut ref_hashes: Vec<Hash> = vec![];
|
||||
for i in 0..2 {
|
||||
let mut ivec = hex!(
|
||||
"abc123abc123abc123abc123abc123abc123abababababababababababababab
|
||||
abc123abc123abc123abc123abc123abc123abababababababababababababab"
|
||||
);
|
||||
ivec[0] = i;
|
||||
ivecs.extend(ivec.clone().iter());
|
||||
chacha_cbc_encrypt_ledger(
|
||||
&blockstore.clone(),
|
||||
0,
|
||||
DEFAULT_SLOTS_PER_SEGMENT,
|
||||
out_path,
|
||||
&mut ivec,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
ref_hashes.push(sample_file(&out_path, &samples).unwrap());
|
||||
info!(
|
||||
"ivec: {:?} hash: {:?} ivecs: {:?}",
|
||||
ivec.to_vec(),
|
||||
ref_hashes.last(),
|
||||
ivecs
|
||||
);
|
||||
}
|
||||
|
||||
let hashes = chacha_cbc_encrypt_file_many_keys(
|
||||
&blockstore,
|
||||
0,
|
||||
DEFAULT_SLOTS_PER_SEGMENT,
|
||||
&mut ivecs,
|
||||
&samples,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(hashes, ref_hashes);
|
||||
|
||||
let _ignored = remove_dir_all(&ledger_path);
|
||||
let _ignored = remove_file(out_path);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_encrypt_file_many_keys_bad_key_length() {
|
||||
solana_logger::setup();
|
||||
if perf_libs::api().is_none() {
|
||||
info!("perf-libs unavailable, skipped");
|
||||
return;
|
||||
}
|
||||
|
||||
let mut keys = hex!("abc123");
|
||||
let ledger_path = get_tmp_ledger_path!();
|
||||
let samples = [0];
|
||||
let blockstore = Arc::new(Blockstore::open(&ledger_path).unwrap());
|
||||
assert!(chacha_cbc_encrypt_file_many_keys(
|
||||
&blockstore,
|
||||
0,
|
||||
DEFAULT_SLOTS_PER_SEGMENT,
|
||||
&mut keys,
|
||||
&samples,
|
||||
)
|
||||
.is_err());
|
||||
}
|
||||
}
|
@@ -7,14 +7,11 @@
|
||||
|
||||
pub mod banking_stage;
|
||||
pub mod broadcast_stage;
|
||||
pub mod chacha;
|
||||
pub mod chacha_cuda;
|
||||
pub mod cluster_info_vote_listener;
|
||||
pub mod commitment;
|
||||
pub mod shred_fetch_stage;
|
||||
#[macro_use]
|
||||
pub mod contact_info;
|
||||
pub mod archiver;
|
||||
pub mod blockstream;
|
||||
pub mod blockstream_service;
|
||||
pub mod cluster_info;
|
||||
@@ -63,10 +60,6 @@ pub mod window_service;
|
||||
#[macro_use]
|
||||
extern crate solana_budget_program;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate hex_literal;
|
||||
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
|
||||
|
@@ -3,13 +3,13 @@
|
||||
// to submit its proof for mining to be rewarded.
|
||||
|
||||
use crate::{
|
||||
chacha_cuda::chacha_cbc_encrypt_file_many_keys,
|
||||
cluster_info::ClusterInfo,
|
||||
contact_info::ContactInfo,
|
||||
result::{Error, Result},
|
||||
};
|
||||
use rand::{Rng, SeedableRng};
|
||||
use rand_chacha::ChaChaRng;
|
||||
use solana_chacha_cuda::chacha_cuda::chacha_cbc_encrypt_file_many_keys;
|
||||
use solana_ledger::{bank_forks::BankForks, blockstore::Blockstore};
|
||||
use solana_runtime::{bank::Bank, storage_utils::archiver_accounts};
|
||||
use solana_sdk::{
|
||||
|
Reference in New Issue
Block a user