From 35ec7a5156c67040ce0bf8b33b805dcb5c159258 Mon Sep 17 00:00:00 2001 From: Sagar Dhawan Date: Wed, 10 Jul 2019 13:33:29 -0700 Subject: [PATCH] Decouple turns from segments in PoRep (#5004) * Decouple Segments from Turns in Storage * Get replicator local cluster tests running in a reasonable amount of time * Fix unused imports * Document new RPC APIs * Check for exit while polling --- book/src/jsonrpc-api.md | 44 +++++++++++++++++- client/src/rpc_request.rs | 8 ++-- core/src/local_cluster.rs | 9 ++-- core/src/replicator.rs | 97 +++++++++++++++++++++++++-------------- core/src/rpc.rs | 27 ++++++----- core/src/storage_stage.rs | 40 ++++++++++------ core/src/tvu.rs | 4 -- core/src/validator.rs | 17 ++++--- core/tests/replicator.rs | 29 ++++++------ core/tests/tvu.rs | 2 - sdk/src/timing.rs | 5 +- 11 files changed, 183 insertions(+), 99 deletions(-) diff --git a/book/src/jsonrpc-api.md b/book/src/jsonrpc-api.md index 90d9681c8..be72fc938 100644 --- a/book/src/jsonrpc-api.md +++ b/book/src/jsonrpc-api.md @@ -30,6 +30,8 @@ Methods * [getSignatureStatus](#getsignaturestatus) * [getSlotLeader](#getslotleader) * [getSlotsPerSegment](#getslotspersegment) +* [getStorageTurn](#getstorageturn) +* [getStorageTurnRate](#getstorageturnrate) * [getNumBlocksSinceSignatureConfirmation](#getnumblockssincesignatureconfirmation) * [getTransactionCount](#gettransactioncount) * [getTotalSupply](#gettotalsupply) @@ -278,13 +280,53 @@ None ```bash // Request curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getSlotsPerSegment"}' http://localhost:8899 - // Result {"jsonrpc":"2.0","result":"1024","id":1} ``` ---- +### getStorageTurn +Returns the current storage turn's blockhash and slot + +##### Parameters: +None + +##### Results: +An array consisting of +* `string` - a Hash as base-58 encoded string indicating the blockhash of the turn slot +* `u64` - the current storage turn slot + +##### Example: +```bash +// Request +curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getStorageTurn"}' http://localhost:8899 + // Result +{"jsonrpc":"2.0","result":["GH7ome3EiwEr7tu9JuTh2dpYWBJK3z69Xm1ZE3MEE6JC", "2048"],"id":1} +``` + +---- + +### getStorageTurnRate +Returns the current storage turn rate in terms of slots per turn + +##### Parameters: +None + +##### Results: +* `u64` - Number of slots in storage turn + +##### Example: +```bash +// Request +curl -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","id":1, "method":"getStorageTurnRate"}' http://localhost:8899 + // Result +{"jsonrpc":"2.0","result":"1024","id":1} + +``` + +---- + ### getNumBlocksSinceSignatureConfirmation Returns the current number of blocks since signature has been confirmed. diff --git a/client/src/rpc_request.rs b/client/src/rpc_request.rs index 43240b17b..a4d7d6de8 100644 --- a/client/src/rpc_request.rs +++ b/client/src/rpc_request.rs @@ -15,8 +15,8 @@ pub enum RpcRequest { GetSlot, GetSlotLeader, GetEpochVoteAccounts, - GetStorageBlockhash, - GetStorageSlot, + GetStorageTurn, + GetStorageTurnRate, GetSlotsPerSegment, GetStoragePubkeysForSlot, GetTransactionCount, @@ -44,8 +44,8 @@ impl RpcRequest { RpcRequest::GetSlot => "getSlot", RpcRequest::GetSlotLeader => "getSlotLeader", RpcRequest::GetEpochVoteAccounts => "getEpochVoteAccounts", - RpcRequest::GetStorageBlockhash => "getStorageBlockhash", - RpcRequest::GetStorageSlot => "getStorageSlot", + RpcRequest::GetStorageTurn => "getStorageTurn", + RpcRequest::GetStorageTurnRate => "getStorageTurnRate", RpcRequest::GetSlotsPerSegment => "getSlotsPerSegment", RpcRequest::GetStoragePubkeysForSlot => "getStoragePubkeysForSlot", RpcRequest::GetTransactionCount => "getTransactionCount", diff --git a/core/src/local_cluster.rs b/core/src/local_cluster.rs index bca4c7885..0f144c00d 100644 --- a/core/src/local_cluster.rs +++ b/core/src/local_cluster.rs @@ -16,8 +16,8 @@ use solana_sdk::poh_config::PohConfig; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; use solana_sdk::system_transaction; -use solana_sdk::timing::DEFAULT_SLOTS_PER_EPOCH; use solana_sdk::timing::DEFAULT_TICKS_PER_SLOT; +use solana_sdk::timing::{DEFAULT_SLOTS_PER_EPOCH, DEFAULT_SLOTS_PER_SEGMENT}; use solana_sdk::transaction::Transaction; use solana_stake_api::stake_instruction; use solana_storage_api::storage_contract; @@ -80,6 +80,7 @@ pub struct ClusterConfig { pub cluster_lamports: u64, pub ticks_per_slot: u64, pub slots_per_epoch: u64, + pub slots_per_segment: u64, pub stakers_slot_offset: u64, pub native_instruction_processors: Vec<(String, Pubkey)>, pub poh_config: PohConfig, @@ -95,6 +96,7 @@ impl Default for ClusterConfig { cluster_lamports: 0, ticks_per_slot: DEFAULT_TICKS_PER_SLOT, slots_per_epoch: DEFAULT_SLOTS_PER_EPOCH, + slots_per_segment: DEFAULT_SLOTS_PER_SEGMENT, stakers_slot_offset: DEFAULT_SLOTS_PER_EPOCH, native_instruction_processors: vec![], poh_config: PohConfig::default(), @@ -147,6 +149,7 @@ impl LocalCluster { ); genesis_block.ticks_per_slot = config.ticks_per_slot; genesis_block.slots_per_epoch = config.slots_per_epoch; + genesis_block.slots_per_segment = config.slots_per_segment; genesis_block.stakers_slot_offset = config.stakers_slot_offset; genesis_block.poh_config = config.poh_config.clone(); genesis_block @@ -574,7 +577,7 @@ impl Drop for LocalCluster { #[cfg(test)] mod test { use super::*; - use crate::storage_stage::STORAGE_ROTATE_TEST_COUNT; + use crate::storage_stage::SLOTS_PER_TURN_TEST; use solana_runtime::epoch_schedule::MINIMUM_SLOTS_PER_EPOCH; #[test] @@ -591,7 +594,7 @@ mod test { solana_logger::setup(); let mut validator_config = ValidatorConfig::default(); validator_config.rpc_config.enable_fullnode_exit = true; - validator_config.storage_rotate_count = STORAGE_ROTATE_TEST_COUNT; + validator_config.storage_slots_per_turn = SLOTS_PER_TURN_TEST; const NUM_NODES: usize = 1; let num_replicators = 1; let config = ClusterConfig { diff --git a/core/src/replicator.rs b/core/src/replicator.rs index 6229f73e5..58fd26a4a 100644 --- a/core/src/replicator.rs +++ b/core/src/replicator.rs @@ -104,7 +104,7 @@ pub(crate) fn sample_file(in_path: &Path, sample_offsets: &[u64]) -> io::Result< Ok(hasher.result()) } -fn get_slot_from_blockhash( +fn get_slot_from_signature( signature: &ed25519_dalek::Signature, storage_turn: u64, slots_per_segment: u64, @@ -265,7 +265,7 @@ impl Replicator { }; spawn(move || { // setup replicator - let window_service = Self::setup( + let window_service = match Self::setup( &mut meta, cluster_info.clone(), &blocktree, @@ -275,8 +275,21 @@ impl Replicator { repair_socket, blob_fetch_receiver, slot_sender, - ) - .ok(); + ) { + Ok(window_service) => window_service, + Err(e) => { + //shutdown services before exiting + error!("setup failed {:?}; replicator thread exiting...", e); + exit.store(true, Ordering::Relaxed); + request_processor + .into_iter() + .for_each(|t| t.join().unwrap()); + fetch_stage.join().unwrap(); + gossip_service.join().unwrap(); + return; + } + }; + info!("setup complete"); // run replicator Self::run( @@ -293,9 +306,7 @@ impl Replicator { .for_each(|t| t.join().unwrap()); fetch_stage.join().unwrap(); gossip_service.join().unwrap(); - if let Some(window) = window_service { - window.join().unwrap() - } + window_service.join().unwrap() }) }; @@ -342,6 +353,7 @@ impl Replicator { &cluster_info, meta.slots_per_segment, &meta.blockhash, + exit, ) { Ok(blockhash_and_slot) => blockhash_and_slot, Err(e) => { @@ -410,27 +422,27 @@ impl Replicator { return Err(e); } }; - let (storage_blockhash, storage_slot) = match Self::poll_for_blockhash_and_slot( + let (segment_blockhash, segment_slot) = match Self::poll_for_segment( &cluster_info, slots_per_segment, &Hash::default(), + exit, ) { Ok(blockhash_and_slot) => blockhash_and_slot, Err(e) => { - error!("unable to get turn status, exiting..."); //shutdown services before exiting exit.store(true, Ordering::Relaxed); return Err(e); } }; - let signature = storage_keypair.sign(storage_blockhash.as_ref()); - let slot = get_slot_from_blockhash(&signature, storage_slot, slots_per_segment); + let signature = storage_keypair.sign(segment_blockhash.as_ref()); + let slot = get_slot_from_signature(&signature, segment_slot, slots_per_segment); info!("replicating slot: {}", slot); slot_sender.send(slot)?; meta.slot = slot; meta.slots_per_segment = slots_per_segment; meta.signature = Signature::new(&signature.to_bytes()); - meta.blockhash = storage_blockhash; + meta.blockhash = segment_blockhash; let mut repair_slot_range = RepairSlotRange::default(); repair_slot_range.end = slot + slots_per_segment; @@ -682,13 +694,35 @@ impl Replicator { } } + /// Waits until the first segment is ready, and returns the current segment + fn poll_for_segment( + cluster_info: &Arc>, + slots_per_segment: u64, + previous_blockhash: &Hash, + exit: &Arc, + ) -> result::Result<(Hash, u64), Error> { + loop { + let (blockhash, turn_slot) = Self::poll_for_blockhash_and_slot( + cluster_info, + slots_per_segment, + previous_blockhash, + exit, + )?; + if get_segment_from_slot(turn_slot, slots_per_segment) != 0 { + return Ok((blockhash, turn_slot)); + } + } + } + /// Poll for a different blockhash and associated max_slot than `previous_blockhash` fn poll_for_blockhash_and_slot( cluster_info: &Arc>, slots_per_segment: u64, previous_blockhash: &Hash, + exit: &Arc, ) -> result::Result<(Hash, u64), Error> { - for _ in 0..10 { + info!("waiting for the next turn..."); + loop { let rpc_peers = { let cluster_info = cluster_info.read().unwrap(); cluster_info.rpc_peers() @@ -700,19 +734,19 @@ impl Replicator { RpcClient::new_socket(rpc_peers[node_index].rpc) }; let response = rpc_client - .retry_make_rpc_request(&RpcRequest::GetStorageBlockhash, None, 0) + .retry_make_rpc_request(&RpcRequest::GetStorageTurn, None, 0) .map_err(|err| { warn!("Error while making rpc request {:?}", err); Error::IO(io::Error::new(ErrorKind::Other, "rpc error")) })?; - let storage_blockhash = - serde_json::from_value::<(String)>(response).map_err(|err| { + let (storage_blockhash, turn_slot) = + serde_json::from_value::<((String, u64))>(response).map_err(|err| { io::Error::new( io::ErrorKind::Other, format!("Couldn't parse response: {:?}", err), ) })?; - let storage_blockhash = storage_blockhash.parse().map_err(|err| { + let turn_blockhash = storage_blockhash.parse().map_err(|err| { io::Error::new( io::ErrorKind::Other, format!( @@ -721,28 +755,21 @@ impl Replicator { ), ) })?; - if storage_blockhash != *previous_blockhash { - let storage_slot = rpc_client - .retry_make_rpc_request(&RpcRequest::GetStorageSlot, None, 0) - .map_err(|err| { - warn!("Error while making rpc request {:?}", err); - Error::IO(io::Error::new(ErrorKind::Other, "rpc error")) - })? - .as_u64() - .unwrap(); - info!("storage slot: {}", storage_slot); - if get_segment_from_slot(storage_slot, slots_per_segment) != 0 { - return Ok((storage_blockhash, storage_slot)); + if turn_blockhash != *previous_blockhash { + info!("turn slot: {}", turn_slot); + if get_segment_from_slot(turn_slot, slots_per_segment) != 0 { + return Ok((turn_blockhash, turn_slot)); } } } - info!("waiting for segment..."); + if exit.load(Ordering::Relaxed) { + return Err(Error::IO(io::Error::new( + ErrorKind::Other, + "exit signalled...", + ))); + } sleep(Duration::from_secs(5)); } - Err(io::Error::new( - ErrorKind::Other, - "Couldn't get blockhash or slot", - ))? } /// Ask a replicator to populate a given blocktree with its segment. @@ -867,7 +894,7 @@ impl Replicator { } sleep(Duration::from_millis(500)); } - panic!("Couldn't get slot height!"); + panic!("Couldn't get segment slot from replicator!"); } } diff --git a/core/src/rpc.rs b/core/src/rpc.rs index 0b6c3b975..9ae1be115 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -139,12 +139,15 @@ impl JsonRpcRequestProcessor { .collect::>()) } - fn get_storage_blockhash(&self) -> Result { - Ok(self.storage_state.get_storage_blockhash().to_string()) + fn get_storage_turn_rate(&self) -> Result { + Ok(self.storage_state.get_storage_turn_rate()) } - fn get_storage_slot(&self) -> Result { - Ok(self.storage_state.get_slot()) + fn get_storage_turn(&self) -> Result<(String, u64)> { + Ok(( + self.storage_state.get_storage_blockhash().to_string(), + self.storage_state.get_slot(), + )) } fn get_slots_per_segment(&self) -> Result { @@ -267,11 +270,11 @@ pub trait RpcSol { #[rpc(meta, name = "getEpochVoteAccounts")] fn get_epoch_vote_accounts(&self, _: Self::Metadata) -> Result>; - #[rpc(meta, name = "getStorageBlockhash")] - fn get_storage_blockhash(&self, _: Self::Metadata) -> Result; + #[rpc(meta, name = "getStorageTurnRate")] + fn get_storage_turn_rate(&self, _: Self::Metadata) -> Result; - #[rpc(meta, name = "getStorageSlot")] - fn get_storage_slot(&self, _: Self::Metadata) -> Result; + #[rpc(meta, name = "getStorageTurn")] + fn get_storage_turn(&self, _: Self::Metadata) -> Result<(String, u64)>; #[rpc(meta, name = "getSlotsPerSegment")] fn get_slots_per_segment(&self, _: Self::Metadata) -> Result; @@ -526,15 +529,15 @@ impl RpcSol for RpcSolImpl { .get_epoch_vote_accounts() } - fn get_storage_blockhash(&self, meta: Self::Metadata) -> Result { + fn get_storage_turn_rate(&self, meta: Self::Metadata) -> Result { meta.request_processor .read() .unwrap() - .get_storage_blockhash() + .get_storage_turn_rate() } - fn get_storage_slot(&self, meta: Self::Metadata) -> Result { - meta.request_processor.read().unwrap().get_storage_slot() + fn get_storage_turn(&self, meta: Self::Metadata) -> Result<(String, u64)> { + meta.request_processor.read().unwrap().get_storage_turn() } fn get_slots_per_segment(&self, meta: Self::Metadata) -> Result { diff --git a/core/src/storage_stage.rs b/core/src/storage_stage.rs index d4ba1ab9a..7cab2762d 100644 --- a/core/src/storage_stage.rs +++ b/core/src/storage_stage.rs @@ -49,6 +49,7 @@ pub struct StorageStateInner { storage_blockhash: Hash, slot: u64, slots_per_segment: u64, + slots_per_turn: u64, } // Used to track root slots in storage stage @@ -69,7 +70,7 @@ pub struct StorageStage { t_storage_create_accounts: JoinHandle<()>, } -pub const STORAGE_ROTATE_TEST_COUNT: u64 = 2; +pub const SLOTS_PER_TURN_TEST: u64 = 2; // TODO: some way to dynamically size NUM_IDENTITIES const NUM_IDENTITIES: usize = 1024; pub const NUM_STORAGE_SAMPLES: usize = 4; @@ -88,7 +89,7 @@ fn get_identity_index_from_signature(key: &Signature) -> usize { } impl StorageState { - pub fn new(hash: &Hash, slots_per_segment: u64) -> Self { + pub fn new(hash: &Hash, slots_per_turn: u64, slots_per_segment: u64) -> Self { let storage_keys = vec![0u8; KEY_SIZE * NUM_IDENTITIES]; let storage_results = vec![Hash::default(); NUM_IDENTITIES]; let replicator_map = vec![]; @@ -97,6 +98,7 @@ impl StorageState { storage_keys, storage_results, replicator_map, + slots_per_turn, slot: 0, slots_per_segment, storage_blockhash: *hash, @@ -121,6 +123,10 @@ impl StorageState { self.state.read().unwrap().storage_blockhash } + pub fn get_storage_turn_rate(&self) -> u64 { + self.state.read().unwrap().slots_per_turn + } + pub fn get_slot(&self) -> u64 { self.state.read().unwrap().slot } @@ -171,12 +177,12 @@ impl StorageStage { storage_keypair: &Arc, exit: &Arc, bank_forks: &Arc>, - storage_rotate_count: u64, cluster_info: &Arc>, ) -> Self { let (instruction_sender, instruction_receiver) = channel(); let t_storage_mining_verifier = { + let slots_per_turn = storage_state.state.read().unwrap().slots_per_turn; let storage_state_inner = storage_state.state.clone(); let exit = exit.clone(); let storage_keypair = storage_keypair.clone(); @@ -194,7 +200,7 @@ impl StorageStage { &some_blocktree, &mut storage_slots, &mut current_key, - storage_rotate_count, + slots_per_turn, &instruction_sender, ) { match e { @@ -488,7 +494,7 @@ impl StorageStage { blocktree: &Arc, storage_slots: &mut StorageSlots, current_key_idx: &mut usize, - storage_rotate_count: u64, + slots_per_turn: u64, instruction_sender: &InstructionSender, ) -> Result<()> { let timeout = Duration::new(1, 0); @@ -503,8 +509,7 @@ impl StorageStage { if bank.slot() > storage_slots.last_root { storage_slots.slot_count += 1; storage_slots.last_root = bank.slot(); - - if storage_slots.slot_count % storage_rotate_count == 0 { + if storage_slots.slot_count % slots_per_turn == 0 { // load all the replicator accounts in the bank. collect all their proofs at the current slot let replicator_accounts = replicator_accounts(bank.as_ref()); // find proofs, and use them to update @@ -656,7 +661,11 @@ mod tests { let bank = Arc::new(Bank::new(&genesis_block)); let bank_forks = Arc::new(RwLock::new(BankForks::new_from_banks(&[bank.clone()], 0))); let (_slot_sender, slot_receiver) = channel(); - let storage_state = StorageState::new(&bank.last_blockhash(), bank.slots_per_segment()); + let storage_state = StorageState::new( + &bank.last_blockhash(), + SLOTS_PER_TURN_TEST, + bank.slots_per_segment(), + ); let storage_stage = StorageStage::new( &storage_state, slot_receiver, @@ -665,7 +674,6 @@ mod tests { &storage_keypair, &exit.clone(), &bank_forks, - STORAGE_ROTATE_TEST_COUNT, &cluster_info, ); exit.store(true, Ordering::Relaxed); @@ -695,7 +703,11 @@ mod tests { let cluster_info = test_cluster_info(&keypair.pubkey()); let (bank_sender, bank_receiver) = channel(); - let storage_state = StorageState::new(&bank.last_blockhash(), bank.slots_per_segment()); + let storage_state = StorageState::new( + &bank.last_blockhash(), + SLOTS_PER_TURN_TEST, + bank.slots_per_segment(), + ); let storage_stage = StorageStage::new( &storage_state, bank_receiver, @@ -704,7 +716,6 @@ mod tests { &storage_keypair, &exit.clone(), &bank_forks, - STORAGE_ROTATE_TEST_COUNT, &cluster_info, ); bank_sender.send(vec![bank.clone()]).unwrap(); @@ -784,7 +795,11 @@ mod tests { let cluster_info = test_cluster_info(&keypair.pubkey()); let (bank_sender, bank_receiver) = channel(); - let storage_state = StorageState::new(&bank.last_blockhash(), bank.slots_per_segment()); + let storage_state = StorageState::new( + &bank.last_blockhash(), + SLOTS_PER_TURN_TEST, + bank.slots_per_segment(), + ); let storage_stage = StorageStage::new( &storage_state, bank_receiver, @@ -793,7 +808,6 @@ mod tests { &storage_keypair, &exit.clone(), &bank_forks, - STORAGE_ROTATE_TEST_COUNT, &cluster_info, ); bank_sender.send(vec![bank.clone()]).unwrap(); diff --git a/core/src/tvu.rs b/core/src/tvu.rs index 1d7977d78..a3abf2b72 100644 --- a/core/src/tvu.rs +++ b/core/src/tvu.rs @@ -62,7 +62,6 @@ impl Tvu { cluster_info: &Arc>, sockets: Sockets, blocktree: Arc, - storage_rotate_count: u64, storage_state: &StorageState, blockstream: Option<&String>, ledger_signal_receiver: Receiver, @@ -145,7 +144,6 @@ impl Tvu { storage_keypair, &exit, &bank_forks, - storage_rotate_count, &cluster_info, ); @@ -181,7 +179,6 @@ pub mod tests { use crate::blocktree::get_tmp_ledger_path; use crate::cluster_info::{ClusterInfo, Node}; use crate::genesis_utils::{create_genesis_block, GenesisBlockInfo}; - use crate::storage_stage::STORAGE_ROTATE_TEST_COUNT; use solana_runtime::bank::Bank; use std::sync::atomic::Ordering; @@ -227,7 +224,6 @@ pub mod tests { } }, blocktree, - STORAGE_ROTATE_TEST_COUNT, &StorageState::default(), None, l_receiver, diff --git a/core/src/validator.rs b/core/src/validator.rs index 8268aa827..f08ebbb76 100644 --- a/core/src/validator.rs +++ b/core/src/validator.rs @@ -23,7 +23,7 @@ use solana_sdk::genesis_block::GenesisBlock; use solana_sdk::poh_config::PohConfig; use solana_sdk::pubkey::Pubkey; use solana_sdk::signature::{Keypair, KeypairUtil}; -use solana_sdk::timing::{timestamp, DEFAULT_SLOTS_PER_SEGMENT}; +use solana_sdk::timing::{timestamp, DEFAULT_SLOTS_PER_TURN}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::mpsc::Receiver; @@ -35,7 +35,7 @@ pub struct ValidatorConfig { pub sigverify_disabled: bool, pub voting_disabled: bool, pub blockstream: Option, - pub storage_rotate_count: u64, + pub storage_slots_per_turn: u64, pub account_paths: Option, pub rpc_config: JsonRpcConfig, pub snapshot_path: Option, @@ -44,15 +44,11 @@ pub struct ValidatorConfig { impl Default for ValidatorConfig { fn default() -> Self { - // TODO: remove this, temporary parameter to configure - // storage amount differently for test configurations - // so tests don't take forever to run. - const NUM_HASHES_FOR_STORAGE_ROTATE: u64 = DEFAULT_SLOTS_PER_SEGMENT; Self { sigverify_disabled: false, voting_disabled: false, blockstream: None, - storage_rotate_count: NUM_HASHES_FOR_STORAGE_ROTATE, + storage_slots_per_turn: DEFAULT_SLOTS_PER_TURN, account_paths: None, rpc_config: JsonRpcConfig::default(), snapshot_path: None, @@ -157,7 +153,11 @@ impl Validator { keypair.clone(), ))); - let storage_state = StorageState::new(&bank.last_blockhash(), bank.slots_per_segment()); + let storage_state = StorageState::new( + &bank.last_blockhash(), + config.storage_slots_per_turn, + bank.slots_per_segment(), + ); let rpc_service = if node.info.rpc.port() == 0 { None @@ -240,7 +240,6 @@ impl Validator { &cluster_info, sockets, blocktree.clone(), - config.storage_rotate_count, &storage_state, config.blockstream.as_ref(), ledger_signal_receiver, diff --git a/core/tests/replicator.rs b/core/tests/replicator.rs index 0964467fa..854c3deb0 100644 --- a/core/tests/replicator.rs +++ b/core/tests/replicator.rs @@ -11,12 +11,11 @@ use solana::contact_info::ContactInfo; use solana::gossip_service::discover_cluster; use solana::local_cluster::{ClusterConfig, LocalCluster}; use solana::replicator::Replicator; -use solana::storage_stage::STORAGE_ROTATE_TEST_COUNT; +use solana::storage_stage::SLOTS_PER_TURN_TEST; use solana::validator::ValidatorConfig; use solana_client::thin_client::create_client; use solana_sdk::genesis_block::create_genesis_block; use solana_sdk::signature::{Keypair, KeypairUtil}; -use solana_sdk::timing::DEFAULT_SLOTS_PER_SEGMENT; use std::fs::remove_dir_all; use std::sync::{Arc, RwLock}; @@ -27,12 +26,15 @@ fn run_replicator_startup_basic(num_nodes: usize, num_replicators: usize) { info!("starting replicator test"); let mut validator_config = ValidatorConfig::default(); - validator_config.storage_rotate_count = STORAGE_ROTATE_TEST_COUNT; + let slots_per_segment = 8; + validator_config.storage_slots_per_turn = SLOTS_PER_TURN_TEST; let config = ClusterConfig { validator_configs: vec![validator_config; num_nodes], num_replicators, node_stakes: vec![100; num_nodes], cluster_lamports: 10_000, + // keep a low slot/segment count to speed up the test + slots_per_segment, ..ClusterConfig::default() }; let cluster = LocalCluster::new(&config); @@ -62,16 +64,13 @@ fn run_replicator_startup_basic(num_nodes: usize, num_replicators: usize) { ))); let path = get_tmp_ledger_path("test"); let blocktree = Arc::new(Blocktree::open(&path).unwrap()); - assert_eq!( - Replicator::download_from_replicator( - &cluster_info, - &replicator_info, - &blocktree, - DEFAULT_SLOTS_PER_SEGMENT, - ) - .unwrap(), - 0 - ); + Replicator::download_from_replicator( + &cluster_info, + &replicator_info, + &blocktree, + slots_per_segment, + ) + .unwrap(); } #[test] @@ -131,7 +130,7 @@ fn test_replicator_startup_ledger_hang() { solana_logger::setup(); info!("starting replicator test"); let mut validator_config = ValidatorConfig::default(); - validator_config.storage_rotate_count = STORAGE_ROTATE_TEST_COUNT; + validator_config.storage_slots_per_turn = SLOTS_PER_TURN_TEST; let cluster = LocalCluster::new_with_equal_stakes(2, 10_000, 100);; info!("starting replicator node"); @@ -160,7 +159,7 @@ fn test_account_setup() { let num_nodes = 1; let num_replicators = 1; let mut validator_config = ValidatorConfig::default(); - validator_config.storage_rotate_count = STORAGE_ROTATE_TEST_COUNT; + validator_config.storage_slots_per_turn = SLOTS_PER_TURN_TEST; let config = ClusterConfig { validator_configs: vec![ValidatorConfig::default(); num_nodes], num_replicators, diff --git a/core/tests/tvu.rs b/core/tests/tvu.rs index f93b64c19..3ea3c9e45 100644 --- a/core/tests/tvu.rs +++ b/core/tests/tvu.rs @@ -13,7 +13,6 @@ use solana::packet::index_blobs; use solana::rpc_subscriptions::RpcSubscriptions; use solana::service::Service; use solana::storage_stage::StorageState; -use solana::storage_stage::STORAGE_ROTATE_TEST_COUNT; use solana::streamer; use solana::tvu::{Sockets, Tvu}; use solana::validator; @@ -133,7 +132,6 @@ fn test_replay() { } }, blocktree, - STORAGE_ROTATE_TEST_COUNT, &StorageState::default(), None, ledger_signal_receiver, diff --git a/sdk/src/timing.rs b/sdk/src/timing.rs index 4d53c7495..5055151ad 100644 --- a/sdk/src/timing.rs +++ b/sdk/src/timing.rs @@ -14,7 +14,10 @@ pub const DEFAULT_TICKS_PER_SLOT: u64 = 4; pub const DEFAULT_SLOTS_PER_EPOCH: u64 = 8192; // Storage segment configuration -pub const DEFAULT_SLOTS_PER_SEGMENT: u64 = 16; +pub const DEFAULT_SLOTS_PER_SEGMENT: u64 = 1024; + +// 4 times longer than the max_lockout to allow enough time for PoRep (128 slots) +pub const DEFAULT_SLOTS_PER_TURN: u64 = 32 * 4; pub const NUM_CONSECUTIVE_LEADER_SLOTS: u64 = 4;