diff --git a/ci/test-checks.sh b/ci/test-checks.sh index 7f6901130..29a610d66 100755 --- a/ci/test-checks.sh +++ b/ci/test-checks.sh @@ -19,7 +19,7 @@ _ cargo +"$rust_stable" clippy --all --exclude solana-sdk-c -- --deny=warnings _ cargo +"$rust_stable" clippy --manifest-path sdk-c/Cargo.toml -- --deny=warnings _ cargo +"$rust_stable" audit --version -_ cargo +"$rust_stable" audit --ignore RUSTSEC-2019-0013 +_ cargo +"$rust_stable" audit --ignore RUSTSEC-2019-0013 --ignore RUSTSEC-2018-0015 _ ci/nits.sh _ ci/order-crates-for-publishing.py _ book/build.sh diff --git a/core/src/blocktree.rs b/core/src/blocktree.rs index 314a41037..34dde3bed 100644 --- a/core/src/blocktree.rs +++ b/core/src/blocktree.rs @@ -36,28 +36,19 @@ mod db; mod meta; mod rooted_slot_iterator; -macro_rules! db_imports { - { $mod:ident, $db:ident, $db_path:expr } => { - mod $mod; +pub use db::columns; +use db::{columns as cf, IteratorDirection, IteratorMode}; - use $mod::$db; - use db::{columns as cf, IteratorMode, IteratorDirection}; - pub use db::columns; +pub type Database = db::Database; +pub type Cursor = db::Cursor; +pub type LedgerColumn = db::LedgerColumn; +pub type WriteBatch = db::WriteBatch; +type BatchProcessor = db::BatchProcessor; - pub type Database = db::Database<$db>; - pub type Cursor = db::Cursor<$db, C>; - pub type LedgerColumn = db::LedgerColumn<$db, C>; - pub type WriteBatch = db::WriteBatch<$db>; - type BatchProcessor = db::BatchProcessor<$db>; +pub trait Column: db::Column {} +impl Column for C {} - pub trait Column: db::Column<$db> {} - impl> Column for C {} - - pub const BLOCKTREE_DIRECTORY: &str = $db_path; - }; -} - -db_imports! {rocks, Rocks, "rocksdb"} +pub const BLOCKTREE_DIRECTORY: &str = "rocksdb"; pub const MAX_COMPLETED_SLOTS_IN_CHANNEL: usize = 100_000; diff --git a/core/src/blocktree/db.rs b/core/src/blocktree/db.rs index 87f41acfa..7e2b06a92 100644 --- a/core/src/blocktree/db.rs +++ b/core/src/blocktree/db.rs @@ -1,6 +1,7 @@ use crate::blocktree::{BlocktreeError, Result}; use bincode::{deserialize, serialize}; +use byteorder::{BigEndian, ByteOrder}; use serde::de::DeserializeOwned; use serde::Serialize; @@ -8,10 +9,21 @@ use serde::Serialize; use solana_sdk::clock::Slot; use std::borrow::Borrow; use std::collections::HashMap; +use std::fs; use std::marker::PhantomData; use std::path::Path; use std::sync::Arc; +use rocksdb::{ + self, ColumnFamily, ColumnFamilyDescriptor, DBIterator, DBRawIterator, Direction, + IteratorMode as RocksIteratorMode, Options, WriteBatch as RWriteBatch, DB, +}; + +// A good value for this is the number of cores on the machine +const TOTAL_THREADS: i32 = 8; +const MAX_WRITE_BUFFER_SIZE: u64 = 256 * 1024 * 1024; // 256MB +const MIN_WRITE_BUFFER_SIZE: u64 = 64 * 1024; // 64KB + pub enum IteratorMode { Start, End, @@ -57,153 +69,434 @@ pub mod columns { pub struct ShredCode; } -pub trait Backend: Sized + Send + Sync { - type Key: ?Sized + ToOwned; - type OwnedKey: Borrow; - type ColumnFamily: Clone; - type Cursor: DbCursor; - type Iter: Iterator, Box<[u8]>)>; - type WriteBatch: IWriteBatch; - type Error: Into; +#[derive(Debug)] +pub struct Rocks(rocksdb::DB); - fn open(path: &Path) -> Result; +impl Rocks { + fn open(path: &Path) -> Result { + use crate::blocktree::db::columns::{ + DeadSlots, ErasureMeta, Index, Orphans, Root, ShredCode, ShredData, SlotMeta, + }; - fn columns(&self) -> Vec<&'static str>; + fs::create_dir_all(&path)?; - fn destroy(path: &Path) -> Result<()>; + // Use default database options + let db_options = get_db_options(); - fn cf_handle(&self, cf: &str) -> Self::ColumnFamily; + // Column family names + let meta_cf_descriptor = + ColumnFamilyDescriptor::new(SlotMeta::NAME, get_cf_options(SlotMeta::NAME)); + let dead_slots_cf_descriptor = + ColumnFamilyDescriptor::new(DeadSlots::NAME, get_cf_options(DeadSlots::NAME)); + let erasure_meta_cf_descriptor = + ColumnFamilyDescriptor::new(ErasureMeta::NAME, get_cf_options(ErasureMeta::NAME)); + let orphans_cf_descriptor = + ColumnFamilyDescriptor::new(Orphans::NAME, get_cf_options(Orphans::NAME)); + let root_cf_descriptor = + ColumnFamilyDescriptor::new(Root::NAME, get_cf_options(Root::NAME)); + let index_cf_descriptor = + ColumnFamilyDescriptor::new(Index::NAME, get_cf_options(Index::NAME)); + let shred_data_cf_descriptor = + ColumnFamilyDescriptor::new(ShredData::NAME, get_cf_options(ShredData::NAME)); + let shred_code_cf_descriptor = + ColumnFamilyDescriptor::new(ShredCode::NAME, get_cf_options(ShredCode::NAME)); - fn get_cf(&self, cf: Self::ColumnFamily, key: &Self::Key) -> Result>>; + let cfs = vec![ + meta_cf_descriptor, + dead_slots_cf_descriptor, + erasure_meta_cf_descriptor, + orphans_cf_descriptor, + root_cf_descriptor, + index_cf_descriptor, + shred_data_cf_descriptor, + shred_code_cf_descriptor, + ]; - fn put_cf(&self, cf: Self::ColumnFamily, key: &Self::Key, value: &[u8]) -> Result<()>; + // Open the database + let db = Rocks(DB::open_cf_descriptors(&db_options, path, cfs)?); - fn delete_cf(&self, cf: Self::ColumnFamily, key: &Self::Key) -> Result<()>; + Ok(db) + } + + fn columns(&self) -> Vec<&'static str> { + use crate::blocktree::db::columns::{ + DeadSlots, ErasureMeta, Index, Orphans, Root, ShredCode, ShredData, SlotMeta, + }; + + vec![ + ErasureMeta::NAME, + DeadSlots::NAME, + Index::NAME, + Orphans::NAME, + Root::NAME, + SlotMeta::NAME, + ShredData::NAME, + ShredCode::NAME, + ] + } + + fn destroy(path: &Path) -> Result<()> { + DB::destroy(&Options::default(), path)?; + + Ok(()) + } + + fn cf_handle(&self, cf: &str) -> ColumnFamily { + self.0 + .cf_handle(cf) + .expect("should never get an unknown column") + } + + fn get_cf(&self, cf: ColumnFamily, key: &[u8]) -> Result>> { + let opt = self.0.get_cf(cf, key)?.map(|db_vec| db_vec.to_vec()); + Ok(opt) + } + + fn put_cf(&self, cf: ColumnFamily, key: &[u8], value: &[u8]) -> Result<()> { + self.0.put_cf(cf, key, value)?; + Ok(()) + } + + fn delete_cf(&self, cf: ColumnFamily, key: &[u8]) -> Result<()> { + self.0.delete_cf(cf, key)?; + Ok(()) + } fn iterator_cf( &self, - cf: Self::ColumnFamily, - iterator_mode: IteratorMode<&Self::Key>, - ) -> Result; + cf: ColumnFamily, + iterator_mode: IteratorMode<&[u8]>, + ) -> Result { + let iter = { + match iterator_mode { + IteratorMode::Start => self.0.iterator_cf(cf, RocksIteratorMode::Start)?, + IteratorMode::End => self.0.iterator_cf(cf, RocksIteratorMode::End)?, + IteratorMode::From(start_from, direction) => { + let rocks_direction = match direction { + IteratorDirection::Forward => Direction::Forward, + IteratorDirection::Reverse => Direction::Reverse, + }; + self.0 + .iterator_cf(cf, RocksIteratorMode::From(start_from, rocks_direction))? + } + } + }; - fn raw_iterator_cf(&self, cf: Self::ColumnFamily) -> Result; + Ok(iter) + } - fn write(&self, batch: Self::WriteBatch) -> Result<()>; + fn raw_iterator_cf(&self, cf: ColumnFamily) -> Result { + let raw_iter = self.0.raw_iterator_cf(cf)?; - fn batch(&self) -> Result; + Ok(raw_iter) + } + + fn batch(&self) -> Result { + Ok(RWriteBatch::default()) + } + + fn write(&self, batch: RWriteBatch) -> Result<()> { + self.0.write(batch)?; + Ok(()) + } } -pub trait Column -where - B: Backend, -{ +pub trait Column { const NAME: &'static str; type Index; - fn key(index: Self::Index) -> B::OwnedKey; - fn index(key: &B::Key) -> Self::Index; + fn key(index: Self::Index) -> Vec; + fn index(key: &[u8]) -> Self::Index; fn slot(index: Self::Index) -> Slot; fn as_index(slot: Slot) -> Self::Index; } -pub trait DbCursor -where - B: Backend, -{ +pub trait DbCursor { fn valid(&self) -> bool; - fn seek(&mut self, key: &B::Key); + fn seek(&mut self, key: &[u8]); fn seek_to_first(&mut self); fn next(&mut self); - fn key(&self) -> Option; + fn key(&self) -> Option>; fn value(&self) -> Option>; } -pub trait IWriteBatch -where - B: Backend, -{ - fn put_cf(&mut self, cf: B::ColumnFamily, key: &B::Key, value: &[u8]) -> Result<()>; - fn delete_cf(&mut self, cf: B::ColumnFamily, key: &B::Key) -> Result<()>; +pub trait IWriteBatch { + fn put_cf(&mut self, cf: ColumnFamily, key: &[u8], value: &[u8]) -> Result<()>; + fn delete_cf(&mut self, cf: ColumnFamily, key: &[u8]) -> Result<()>; } -pub trait TypedColumn: Column -where - B: Backend, -{ +pub trait TypedColumn: Column { type Type: Serialize + DeserializeOwned; } -#[derive(Debug, Clone)] -pub struct Database -where - B: Backend, -{ - backend: Arc, +impl Column for columns::ShredCode { + const NAME: &'static str = super::CODE_SHRED_CF; + type Index = (u64, u64); + + fn key(index: (u64, u64)) -> Vec { + columns::ShredData::key(index) + } + + fn index(key: &[u8]) -> (u64, u64) { + columns::ShredData::index(key) + } + + fn slot(index: Self::Index) -> Slot { + index.0 + } + + fn as_index(slot: Slot) -> Self::Index { + (slot, 0) + } +} + +impl Column for columns::ShredData { + const NAME: &'static str = super::DATA_SHRED_CF; + type Index = (u64, u64); + + fn key((slot, index): (u64, u64)) -> Vec { + let mut key = vec![0; 16]; + BigEndian::write_u64(&mut key[..8], slot); + BigEndian::write_u64(&mut key[8..16], index); + key + } + + fn index(key: &[u8]) -> (u64, u64) { + let slot = BigEndian::read_u64(&key[..8]); + let index = BigEndian::read_u64(&key[8..16]); + (slot, index) + } + + fn slot(index: Self::Index) -> Slot { + index.0 + } + + fn as_index(slot: Slot) -> Self::Index { + (slot, 0) + } +} + +impl Column for columns::Index { + const NAME: &'static str = super::INDEX_CF; + type Index = u64; + + fn key(slot: u64) -> Vec { + let mut key = vec![0; 8]; + BigEndian::write_u64(&mut key[..], slot); + key + } + + fn index(key: &[u8]) -> u64 { + BigEndian::read_u64(&key[..8]) + } + + fn slot(index: Self::Index) -> Slot { + index + } + + fn as_index(slot: Slot) -> Self::Index { + slot + } +} + +impl TypedColumn for columns::Index { + type Type = crate::blocktree::meta::Index; +} + +impl Column for columns::DeadSlots { + const NAME: &'static str = super::DEAD_SLOTS_CF; + type Index = u64; + + fn key(slot: u64) -> Vec { + let mut key = vec![0; 8]; + BigEndian::write_u64(&mut key[..], slot); + key + } + + fn index(key: &[u8]) -> u64 { + BigEndian::read_u64(&key[..8]) + } + + fn slot(index: Self::Index) -> Slot { + index + } + + fn as_index(slot: Slot) -> Self::Index { + slot + } +} + +impl TypedColumn for columns::DeadSlots { + type Type = bool; +} + +impl Column for columns::Orphans { + const NAME: &'static str = super::ORPHANS_CF; + type Index = u64; + + fn key(slot: u64) -> Vec { + let mut key = vec![0; 8]; + BigEndian::write_u64(&mut key[..], slot); + key + } + + fn index(key: &[u8]) -> u64 { + BigEndian::read_u64(&key[..8]) + } + + fn slot(index: Self::Index) -> Slot { + index + } + + fn as_index(slot: Slot) -> Self::Index { + slot + } +} + +impl TypedColumn for columns::Orphans { + type Type = bool; +} + +impl Column for columns::Root { + const NAME: &'static str = super::ROOT_CF; + type Index = u64; + + fn key(slot: u64) -> Vec { + let mut key = vec![0; 8]; + BigEndian::write_u64(&mut key[..], slot); + key + } + + fn index(key: &[u8]) -> u64 { + BigEndian::read_u64(&key[..8]) + } + + fn slot(index: Self::Index) -> Slot { + index + } + + fn as_index(slot: Slot) -> Self::Index { + slot + } +} + +impl TypedColumn for columns::Root { + type Type = bool; +} + +impl Column for columns::SlotMeta { + const NAME: &'static str = super::META_CF; + type Index = u64; + + fn key(slot: u64) -> Vec { + let mut key = vec![0; 8]; + BigEndian::write_u64(&mut key[..], slot); + key + } + + fn index(key: &[u8]) -> u64 { + BigEndian::read_u64(&key[..8]) + } + + fn slot(index: Self::Index) -> Slot { + index + } + + fn as_index(slot: Slot) -> Self::Index { + slot + } +} + +impl TypedColumn for columns::SlotMeta { + type Type = super::SlotMeta; +} + +impl Column for columns::ErasureMeta { + const NAME: &'static str = super::ERASURE_META_CF; + type Index = (u64, u64); + + fn index(key: &[u8]) -> (u64, u64) { + let slot = BigEndian::read_u64(&key[..8]); + let set_index = BigEndian::read_u64(&key[8..]); + + (slot, set_index) + } + + fn key((slot, set_index): (u64, u64)) -> Vec { + let mut key = vec![0; 16]; + BigEndian::write_u64(&mut key[..8], slot); + BigEndian::write_u64(&mut key[8..], set_index); + key + } + + fn slot(index: Self::Index) -> Slot { + index.0 + } + + fn as_index(slot: Slot) -> Self::Index { + (slot, 0) + } +} + +impl TypedColumn for columns::ErasureMeta { + type Type = super::ErasureMeta; } #[derive(Debug, Clone)] -pub struct BatchProcessor -where - B: Backend, -{ - backend: Arc, +pub struct Database { + backend: Arc, } #[derive(Debug, Clone)] -pub struct Cursor +pub struct BatchProcessor { + backend: Arc, +} + +pub struct Cursor where - B: Backend, - C: Column, + C: Column, { - db_cursor: B::Cursor, + db_cursor: DBRawIterator, column: PhantomData, - backend: PhantomData, + backend: PhantomData, } #[derive(Debug, Clone)] -pub struct LedgerColumn +pub struct LedgerColumn where - B: Backend, - C: Column, + C: Column, { - backend: Arc, + backend: Arc, column: PhantomData, } -#[derive(Debug)] -pub struct WriteBatch -where - B: Backend, -{ - write_batch: B::WriteBatch, - backend: PhantomData, - map: HashMap<&'static str, B::ColumnFamily>, +pub struct WriteBatch { + write_batch: RWriteBatch, + backend: PhantomData, + map: HashMap<&'static str, ColumnFamily>, } -impl Database -where - B: Backend, -{ +impl Database { pub fn open(path: &Path) -> Result { - let backend = Arc::new(B::open(path)?); + let backend = Arc::new(Rocks::open(path)?); Ok(Database { backend }) } pub fn destroy(path: &Path) -> Result<()> { - B::destroy(path)?; + Rocks::destroy(path)?; Ok(()) } pub fn get_bytes(&self, key: C::Index) -> Result>> where - C: Column, + C: Column, { self.backend .get_cf(self.cf_handle::(), C::key(key).borrow()) @@ -211,7 +504,7 @@ where pub fn put_bytes(&self, key: C::Index, data: &[u8]) -> Result<()> where - C: Column, + C: Column, { self.backend .put_cf(self.cf_handle::(), C::key(key).borrow(), data) @@ -219,7 +512,7 @@ where pub fn delete(&self, key: C::Index) -> Result<()> where - C: Column, + C: Column, { self.backend .delete_cf(self.cf_handle::(), C::key(key).borrow()) @@ -227,7 +520,7 @@ where pub fn get(&self, key: C::Index) -> Result> where - C: TypedColumn, + C: TypedColumn, { if let Some(serialized_value) = self .backend @@ -243,7 +536,7 @@ where pub fn put(&self, key: C::Index, value: &C::Type) -> Result<()> where - C: TypedColumn, + C: TypedColumn, { let serialized_value = serialize(value)?; @@ -254,9 +547,9 @@ where ) } - pub fn cursor(&self) -> Result> + pub fn cursor(&self) -> Result> where - C: Column, + C: Column, { let db_cursor = self.backend.raw_iterator_cf(self.cf_handle::())?; @@ -272,7 +565,7 @@ where iterator_mode: IteratorMode, ) -> Result)>> where - C: Column, + C: Column, { let iter = { match iterator_mode { @@ -296,16 +589,16 @@ where } #[inline] - pub fn cf_handle(&self) -> B::ColumnFamily + pub fn cf_handle(&self) -> ColumnFamily where - C: Column, + C: Column, { - self.backend.cf_handle(C::NAME).clone() + self.backend.cf_handle(C::NAME) } - pub fn column(&self) -> LedgerColumn + pub fn column(&self) -> LedgerColumn where - C: Column, + C: Column, { LedgerColumn { backend: Arc::clone(&self.backend), @@ -318,18 +611,15 @@ where // blocktree.batch_processor, so this API should only be used if the caller is sure they // are writing to data in columns that will not be corrupted by any simultaneous blocktree // operations. - pub unsafe fn batch_processor(&self) -> BatchProcessor { + pub unsafe fn batch_processor(&self) -> BatchProcessor { BatchProcessor { backend: Arc::clone(&self.backend), } } } -impl BatchProcessor -where - B: Backend, -{ - pub fn batch(&mut self) -> Result> { +impl BatchProcessor { + pub fn batch(&mut self) -> Result { let db_write_batch = self.backend.batch()?; let map = self .backend @@ -345,15 +635,14 @@ where }) } - pub fn write(&mut self, batch: WriteBatch) -> Result<()> { + pub fn write(&mut self, batch: WriteBatch) -> Result<()> { self.backend.write(batch.write_batch) } } -impl Cursor +impl Cursor where - B: Backend, - C: Column, + C: Column, { pub fn valid(&self) -> bool { self.db_cursor.valid() @@ -384,10 +673,9 @@ where } } -impl Cursor +impl Cursor where - B: Backend, - C: TypedColumn, + C: TypedColumn, { pub fn value(&self) -> Option { if let Some(bytes) = self.db_cursor.value() { @@ -399,16 +687,15 @@ where } } -impl LedgerColumn +impl LedgerColumn where - B: Backend, - C: Column, + C: Column, { pub fn get_bytes(&self, key: C::Index) -> Result>> { self.backend.get_cf(self.handle(), C::key(key).borrow()) } - pub fn cursor(&self) -> Result> { + pub fn cursor(&self) -> Result> { let db_cursor = self.backend.raw_iterator_cf(self.handle())?; Ok(Cursor { @@ -441,7 +728,7 @@ where pub fn delete_slot( &self, - batch: &mut WriteBatch, + batch: &mut WriteBatch, from: Option, to: Option, ) -> Result @@ -474,8 +761,8 @@ where } #[inline] - pub fn handle(&self) -> B::ColumnFamily { - self.backend.cf_handle(C::NAME).clone() + pub fn handle(&self) -> ColumnFamily { + self.backend.cf_handle(C::NAME) } pub fn is_empty(&self) -> Result { @@ -494,10 +781,9 @@ where } } -impl LedgerColumn +impl LedgerColumn where - B: Backend, - C: TypedColumn, + C: TypedColumn, { pub fn get(&self, key: C::Index) -> Result> { if let Some(serialized_value) = self.backend.get_cf(self.handle(), C::key(key).borrow())? { @@ -517,28 +803,106 @@ where } } -impl WriteBatch -where - B: Backend, -{ - pub fn put_bytes>(&mut self, key: C::Index, bytes: &[u8]) -> Result<()> { +impl WriteBatch { + pub fn put_bytes(&mut self, key: C::Index, bytes: &[u8]) -> Result<()> { self.write_batch .put_cf(self.get_cf::(), C::key(key).borrow(), bytes) + .map_err(|e| e.into()) } - pub fn delete>(&mut self, key: C::Index) -> Result<()> { + pub fn delete(&mut self, key: C::Index) -> Result<()> { self.write_batch .delete_cf(self.get_cf::(), C::key(key).borrow()) + .map_err(|e| e.into()) } - pub fn put>(&mut self, key: C::Index, value: &C::Type) -> Result<()> { + pub fn put(&mut self, key: C::Index, value: &C::Type) -> Result<()> { let serialized_value = serialize(&value)?; self.write_batch .put_cf(self.get_cf::(), C::key(key).borrow(), &serialized_value) + .map_err(|e| e.into()) } #[inline] - fn get_cf>(&self) -> B::ColumnFamily { - self.map[C::NAME].clone() + fn get_cf(&self) -> ColumnFamily { + self.map[C::NAME] } } + +impl DbCursor for DBRawIterator { + fn valid(&self) -> bool { + DBRawIterator::valid(self) + } + + fn seek(&mut self, key: &[u8]) { + DBRawIterator::seek(self, key); + } + + fn seek_to_first(&mut self) { + DBRawIterator::seek_to_first(self); + } + + fn next(&mut self) { + DBRawIterator::next(self); + } + + fn key(&self) -> Option> { + DBRawIterator::key(self) + } + + fn value(&self) -> Option> { + DBRawIterator::value(self) + } +} + +impl IWriteBatch for RWriteBatch { + fn put_cf(&mut self, cf: ColumnFamily, key: &[u8], value: &[u8]) -> Result<()> { + RWriteBatch::put_cf(self, cf, key, value)?; + Ok(()) + } + + fn delete_cf(&mut self, cf: ColumnFamily, key: &[u8]) -> Result<()> { + RWriteBatch::delete_cf(self, cf, key)?; + Ok(()) + } +} + +impl std::convert::From for BlocktreeError { + fn from(e: rocksdb::Error) -> BlocktreeError { + BlocktreeError::RocksDb(e) + } +} + +fn get_cf_options(name: &'static str) -> Options { + use crate::blocktree::db::columns::{ErasureMeta, Index, ShredCode, ShredData}; + + let mut options = Options::default(); + match name { + ShredCode::NAME | ShredData::NAME | Index::NAME | ErasureMeta::NAME => { + // 512MB * 8 = 4GB. 2 of these columns should take no more than 8GB of RAM + options.set_max_write_buffer_number(8); + options.set_write_buffer_size(MAX_WRITE_BUFFER_SIZE as usize); + options.set_target_file_size_base(MAX_WRITE_BUFFER_SIZE / 10); + options.set_max_bytes_for_level_base(MAX_WRITE_BUFFER_SIZE); + } + _ => { + // We want smaller CFs to flush faster. This results in more WAL files but lowers + // overall WAL space utilization and increases flush frequency + options.set_write_buffer_size(MIN_WRITE_BUFFER_SIZE as usize); + options.set_target_file_size_base(MIN_WRITE_BUFFER_SIZE); + options.set_max_bytes_for_level_base(MIN_WRITE_BUFFER_SIZE); + options.set_level_zero_file_num_compaction_trigger(1); + } + } + options +} + +fn get_db_options() -> Options { + let mut options = Options::default(); + options.create_if_missing(true); + options.create_missing_column_families(true); + options.increase_parallelism(TOTAL_THREADS); + options.set_max_background_flushes(4); + options.set_max_background_compactions(4); + options +} diff --git a/core/src/blocktree/rocks.rs b/core/src/blocktree/rocks.rs deleted file mode 100644 index 020f998c4..000000000 --- a/core/src/blocktree/rocks.rs +++ /dev/null @@ -1,452 +0,0 @@ -use crate::blocktree::db::columns as cf; -use crate::blocktree::db::{ - Backend, Column, DbCursor, IWriteBatch, IteratorDirection, IteratorMode, TypedColumn, -}; -use crate::blocktree::{BlocktreeError, Result}; -use solana_sdk::clock::Slot; - -use byteorder::{BigEndian, ByteOrder}; - -use rocksdb::{ - self, ColumnFamily, ColumnFamilyDescriptor, DBIterator, DBRawIterator, Direction, - IteratorMode as RocksIteratorMode, Options, WriteBatch as RWriteBatch, DB, -}; - -use std::fs; -use std::path::Path; - -// A good value for this is the number of cores on the machine -const TOTAL_THREADS: i32 = 8; -const MAX_WRITE_BUFFER_SIZE: u64 = 256 * 1024 * 1024; // 256MB -const MIN_WRITE_BUFFER_SIZE: u64 = 64 * 1024; // 64KB - -#[derive(Debug)] -pub struct Rocks(rocksdb::DB); - -impl Backend for Rocks { - type Key = [u8]; - type OwnedKey = Vec; - type ColumnFamily = ColumnFamily; - type Cursor = DBRawIterator; - type Iter = DBIterator; - type WriteBatch = RWriteBatch; - type Error = rocksdb::Error; - - fn open(path: &Path) -> Result { - use crate::blocktree::db::columns::{ - DeadSlots, ErasureMeta, Index, Orphans, Root, ShredCode, ShredData, SlotMeta, - }; - - fs::create_dir_all(&path)?; - - // Use default database options - let db_options = get_db_options(); - - // Column family names - let meta_cf_descriptor = - ColumnFamilyDescriptor::new(SlotMeta::NAME, get_cf_options(SlotMeta::NAME)); - let dead_slots_cf_descriptor = - ColumnFamilyDescriptor::new(DeadSlots::NAME, get_cf_options(DeadSlots::NAME)); - let erasure_meta_cf_descriptor = - ColumnFamilyDescriptor::new(ErasureMeta::NAME, get_cf_options(ErasureMeta::NAME)); - let orphans_cf_descriptor = - ColumnFamilyDescriptor::new(Orphans::NAME, get_cf_options(Orphans::NAME)); - let root_cf_descriptor = - ColumnFamilyDescriptor::new(Root::NAME, get_cf_options(Root::NAME)); - let index_cf_descriptor = - ColumnFamilyDescriptor::new(Index::NAME, get_cf_options(Index::NAME)); - let shred_data_cf_descriptor = - ColumnFamilyDescriptor::new(ShredData::NAME, get_cf_options(ShredData::NAME)); - let shred_code_cf_descriptor = - ColumnFamilyDescriptor::new(ShredCode::NAME, get_cf_options(ShredCode::NAME)); - - let cfs = vec![ - meta_cf_descriptor, - dead_slots_cf_descriptor, - erasure_meta_cf_descriptor, - orphans_cf_descriptor, - root_cf_descriptor, - index_cf_descriptor, - shred_data_cf_descriptor, - shred_code_cf_descriptor, - ]; - - // Open the database - let db = Rocks(DB::open_cf_descriptors(&db_options, path, cfs)?); - - Ok(db) - } - - fn columns(&self) -> Vec<&'static str> { - use crate::blocktree::db::columns::{ - DeadSlots, ErasureMeta, Index, Orphans, Root, ShredCode, ShredData, SlotMeta, - }; - - vec![ - ErasureMeta::NAME, - DeadSlots::NAME, - Index::NAME, - Orphans::NAME, - Root::NAME, - SlotMeta::NAME, - ShredData::NAME, - ShredCode::NAME, - ] - } - - fn destroy(path: &Path) -> Result<()> { - DB::destroy(&Options::default(), path)?; - - Ok(()) - } - - fn cf_handle(&self, cf: &str) -> ColumnFamily { - self.0 - .cf_handle(cf) - .expect("should never get an unknown column") - } - - fn get_cf(&self, cf: ColumnFamily, key: &[u8]) -> Result>> { - let opt = self.0.get_cf(cf, key)?.map(|db_vec| db_vec.to_vec()); - Ok(opt) - } - - fn put_cf(&self, cf: ColumnFamily, key: &[u8], value: &[u8]) -> Result<()> { - self.0.put_cf(cf, key, value)?; - Ok(()) - } - - fn delete_cf(&self, cf: ColumnFamily, key: &[u8]) -> Result<()> { - self.0.delete_cf(cf, key)?; - Ok(()) - } - - fn iterator_cf( - &self, - cf: ColumnFamily, - iterator_mode: IteratorMode<&[u8]>, - ) -> Result { - let iter = { - match iterator_mode { - IteratorMode::Start => self.0.iterator_cf(cf, RocksIteratorMode::Start)?, - IteratorMode::End => self.0.iterator_cf(cf, RocksIteratorMode::End)?, - IteratorMode::From(start_from, direction) => { - let rocks_direction = match direction { - IteratorDirection::Forward => Direction::Forward, - IteratorDirection::Reverse => Direction::Reverse, - }; - self.0 - .iterator_cf(cf, RocksIteratorMode::From(start_from, rocks_direction))? - } - } - }; - - Ok(iter) - } - - fn raw_iterator_cf(&self, cf: ColumnFamily) -> Result { - let raw_iter = self.0.raw_iterator_cf(cf)?; - - Ok(raw_iter) - } - - fn batch(&self) -> Result { - Ok(RWriteBatch::default()) - } - - fn write(&self, batch: RWriteBatch) -> Result<()> { - self.0.write(batch)?; - Ok(()) - } -} - -impl Column for cf::ShredCode { - const NAME: &'static str = super::CODE_SHRED_CF; - type Index = (u64, u64); - - fn key(index: (u64, u64)) -> Vec { - cf::ShredData::key(index) - } - - fn index(key: &[u8]) -> (u64, u64) { - cf::ShredData::index(key) - } - - fn slot(index: Self::Index) -> Slot { - index.0 - } - - fn as_index(slot: Slot) -> Self::Index { - (slot, 0) - } -} - -impl Column for cf::ShredData { - const NAME: &'static str = super::DATA_SHRED_CF; - type Index = (u64, u64); - - fn key((slot, index): (u64, u64)) -> Vec { - let mut key = vec![0; 16]; - BigEndian::write_u64(&mut key[..8], slot); - BigEndian::write_u64(&mut key[8..16], index); - key - } - - fn index(key: &[u8]) -> (u64, u64) { - let slot = BigEndian::read_u64(&key[..8]); - let index = BigEndian::read_u64(&key[8..16]); - (slot, index) - } - - fn slot(index: Self::Index) -> Slot { - index.0 - } - - fn as_index(slot: Slot) -> Self::Index { - (slot, 0) - } -} - -impl Column for cf::Index { - const NAME: &'static str = super::INDEX_CF; - type Index = u64; - - fn key(slot: u64) -> Vec { - let mut key = vec![0; 8]; - BigEndian::write_u64(&mut key[..], slot); - key - } - - fn index(key: &[u8]) -> u64 { - BigEndian::read_u64(&key[..8]) - } - - fn slot(index: Self::Index) -> Slot { - index - } - - fn as_index(slot: Slot) -> Self::Index { - slot - } -} - -impl TypedColumn for cf::Index { - type Type = crate::blocktree::meta::Index; -} - -impl Column for cf::DeadSlots { - const NAME: &'static str = super::DEAD_SLOTS_CF; - type Index = u64; - - fn key(slot: u64) -> Vec { - let mut key = vec![0; 8]; - BigEndian::write_u64(&mut key[..], slot); - key - } - - fn index(key: &[u8]) -> u64 { - BigEndian::read_u64(&key[..8]) - } - - fn slot(index: Self::Index) -> Slot { - index - } - - fn as_index(slot: Slot) -> Self::Index { - slot - } -} - -impl TypedColumn for cf::DeadSlots { - type Type = bool; -} - -impl Column for cf::Orphans { - const NAME: &'static str = super::ORPHANS_CF; - type Index = u64; - - fn key(slot: u64) -> Vec { - let mut key = vec![0; 8]; - BigEndian::write_u64(&mut key[..], slot); - key - } - - fn index(key: &[u8]) -> u64 { - BigEndian::read_u64(&key[..8]) - } - - fn slot(index: Self::Index) -> Slot { - index - } - - fn as_index(slot: Slot) -> Self::Index { - slot - } -} - -impl TypedColumn for cf::Orphans { - type Type = bool; -} - -impl Column for cf::Root { - const NAME: &'static str = super::ROOT_CF; - type Index = u64; - - fn key(slot: u64) -> Vec { - let mut key = vec![0; 8]; - BigEndian::write_u64(&mut key[..], slot); - key - } - - fn index(key: &[u8]) -> u64 { - BigEndian::read_u64(&key[..8]) - } - - fn slot(index: Self::Index) -> Slot { - index - } - - fn as_index(slot: Slot) -> Self::Index { - slot - } -} - -impl TypedColumn for cf::Root { - type Type = bool; -} - -impl Column for cf::SlotMeta { - const NAME: &'static str = super::META_CF; - type Index = u64; - - fn key(slot: u64) -> Vec { - let mut key = vec![0; 8]; - BigEndian::write_u64(&mut key[..], slot); - key - } - - fn index(key: &[u8]) -> u64 { - BigEndian::read_u64(&key[..8]) - } - - fn slot(index: Self::Index) -> Slot { - index - } - - fn as_index(slot: Slot) -> Self::Index { - slot - } -} - -impl TypedColumn for cf::SlotMeta { - type Type = super::SlotMeta; -} - -impl Column for cf::ErasureMeta { - const NAME: &'static str = super::ERASURE_META_CF; - type Index = (u64, u64); - - fn index(key: &[u8]) -> (u64, u64) { - let slot = BigEndian::read_u64(&key[..8]); - let set_index = BigEndian::read_u64(&key[8..]); - - (slot, set_index) - } - - fn key((slot, set_index): (u64, u64)) -> Vec { - let mut key = vec![0; 16]; - BigEndian::write_u64(&mut key[..8], slot); - BigEndian::write_u64(&mut key[8..], set_index); - key - } - - fn slot(index: Self::Index) -> Slot { - index.0 - } - - fn as_index(slot: Slot) -> Self::Index { - (slot, 0) - } -} - -impl TypedColumn for cf::ErasureMeta { - type Type = super::ErasureMeta; -} - -impl DbCursor for DBRawIterator { - fn valid(&self) -> bool { - DBRawIterator::valid(self) - } - - fn seek(&mut self, key: &[u8]) { - DBRawIterator::seek(self, key); - } - - fn seek_to_first(&mut self) { - DBRawIterator::seek_to_first(self); - } - - fn next(&mut self) { - DBRawIterator::next(self); - } - - fn key(&self) -> Option> { - DBRawIterator::key(self) - } - - fn value(&self) -> Option> { - DBRawIterator::value(self) - } -} - -impl IWriteBatch for RWriteBatch { - fn put_cf(&mut self, cf: ColumnFamily, key: &[u8], value: &[u8]) -> Result<()> { - RWriteBatch::put_cf(self, cf, key, value)?; - Ok(()) - } - - fn delete_cf(&mut self, cf: ColumnFamily, key: &[u8]) -> Result<()> { - RWriteBatch::delete_cf(self, cf, key)?; - Ok(()) - } -} - -impl std::convert::From for BlocktreeError { - fn from(e: rocksdb::Error) -> BlocktreeError { - BlocktreeError::RocksDb(e) - } -} - -fn get_cf_options(name: &'static str) -> Options { - use crate::blocktree::db::columns::{ErasureMeta, Index, ShredCode, ShredData}; - - let mut options = Options::default(); - match name { - ShredCode::NAME | ShredData::NAME | Index::NAME | ErasureMeta::NAME => { - // 512MB * 8 = 4GB. 2 of these columns should take no more than 8GB of RAM - options.set_max_write_buffer_number(8); - options.set_write_buffer_size(MAX_WRITE_BUFFER_SIZE as usize); - options.set_target_file_size_base(MAX_WRITE_BUFFER_SIZE / 10); - options.set_max_bytes_for_level_base(MAX_WRITE_BUFFER_SIZE); - } - _ => { - // We want smaller CFs to flush faster. This results in more WAL files but lowers - // overall WAL space utilization and increases flush frequency - options.set_write_buffer_size(MIN_WRITE_BUFFER_SIZE as usize); - options.set_target_file_size_base(MIN_WRITE_BUFFER_SIZE); - options.set_max_bytes_for_level_base(MIN_WRITE_BUFFER_SIZE); - options.set_level_zero_file_num_compaction_trigger(1); - } - } - options -} - -fn get_db_options() -> Options { - let mut options = Options::default(); - options.create_if_missing(true); - options.create_missing_column_families(true); - options.increase_parallelism(TOTAL_THREADS); - options.set_max_background_flushes(4); - options.set_max_background_compactions(4); - options -} diff --git a/core/src/crds.rs b/core/src/crds.rs index 7fbe119f0..5da93525b 100644 --- a/core/src/crds.rs +++ b/core/src/crds.rs @@ -157,7 +157,7 @@ impl Crds { } pub fn remove(&mut self, key: &CrdsValueLabel) { - self.table.remove(key); + self.table.swap_remove(key); } } diff --git a/core/src/crds_gossip_push.rs b/core/src/crds_gossip_push.rs index 90a0866db..8f583212e 100644 --- a/core/src/crds_gossip_push.rs +++ b/core/src/crds_gossip_push.rs @@ -270,7 +270,7 @@ impl CrdsGossipPush { keys.shuffle(&mut rand::thread_rng()); let num = keys.len() / ratio; for k in &keys[..num] { - self.active_set.remove(k); + self.active_set.swap_remove(k); } for (k, v) in new_items { self.active_set.insert(k, v); diff --git a/programs/bpf/Cargo.lock b/programs/bpf/Cargo.lock index 8c52d14f5..a042bcc43 100644 --- a/programs/bpf/Cargo.lock +++ b/programs/bpf/Cargo.lock @@ -62,7 +62,7 @@ name = "atty" version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -78,7 +78,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "backtrace-sys 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)", "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -89,7 +89,7 @@ version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -248,7 +248,7 @@ name = "chrono" version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "num-integer 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", @@ -543,7 +543,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "crc32fast 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -621,7 +621,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "wasi 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -777,7 +777,7 @@ name = "iovec" version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -808,7 +808,7 @@ version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -839,7 +839,7 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.62" +version = "0.2.64" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -883,7 +883,7 @@ name = "memmap" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -926,7 +926,7 @@ dependencies = [ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)", @@ -951,7 +951,7 @@ version = "0.2.33" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1009,7 +1009,7 @@ name = "num_cpus" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1039,7 +1039,7 @@ name = "parking_lot_core" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1132,7 +1132,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1144,7 +1144,7 @@ version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1162,7 +1162,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "getrandom 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", "rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1236,7 +1236,7 @@ name = "rand_jitter" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1248,7 +1248,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "rand_core 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1377,7 +1377,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "untrusted 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", "web-sys 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1531,7 +1531,7 @@ version = "0.20.0" dependencies = [ "bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", "solana-logger 0.20.0", @@ -1694,7 +1694,7 @@ dependencies = [ "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", "reqwest 0.9.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1764,7 +1764,7 @@ dependencies = [ "fs_extra 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "memmap 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1900,7 +1900,7 @@ dependencies = [ "combine 2.5.2 (registry+https://github.com/rust-lang/crates.io-index)", "elfkit 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "hash32 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.42 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1994,7 +1994,7 @@ version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cc 1.0.45 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2003,7 +2003,7 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "remove_dir_all 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2039,7 +2039,7 @@ name = "time" version = "0.1.42" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)", "redox_syscall 0.1.56 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2589,7 +2589,7 @@ dependencies = [ "checksum js-sys 0.3.27 (registry+https://github.com/rust-lang/crates.io-index)" = "1efc4f2a556c58e79c5500912e221dd826bec64ff4aabd8ce71ccef6da02d7d4" "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -"checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" +"checksum libc 0.2.64 (registry+https://github.com/rust-lang/crates.io-index)" = "74dfca3d9957906e8d1e6a0b641dc9a59848e793f1da2165889fd4f62d10d79c" "checksum libloading 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753" "checksum lock_api 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "62ebf1391f6acad60e5c8b43706dde4582df75c06698ab44511d15016bc2442c" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"