Save RNG for generating random storage sampling offsets (#4450)
* Save RNG for generating random storage sampling offsets * fix clippy * fix stable-perf * fix chacha
This commit is contained in:
		@@ -14,6 +14,10 @@ use crate::window_service::WindowService;
 | 
				
			|||||||
use bincode::deserialize;
 | 
					use bincode::deserialize;
 | 
				
			||||||
use rand::thread_rng;
 | 
					use rand::thread_rng;
 | 
				
			||||||
use rand::Rng;
 | 
					use rand::Rng;
 | 
				
			||||||
 | 
					#[cfg(feature = "chacha")]
 | 
				
			||||||
 | 
					use rand::SeedableRng;
 | 
				
			||||||
 | 
					#[cfg(feature = "chacha")]
 | 
				
			||||||
 | 
					use rand_chacha::ChaChaRng;
 | 
				
			||||||
use solana_client::rpc_client::RpcClient;
 | 
					use solana_client::rpc_client::RpcClient;
 | 
				
			||||||
use solana_client::rpc_request::RpcRequest;
 | 
					use solana_client::rpc_request::RpcRequest;
 | 
				
			||||||
use solana_client::thin_client::ThinClient;
 | 
					use solana_client::thin_client::ThinClient;
 | 
				
			||||||
@@ -64,6 +68,8 @@ pub struct Replicator {
 | 
				
			|||||||
    num_chacha_blocks: usize,
 | 
					    num_chacha_blocks: usize,
 | 
				
			||||||
    #[cfg(feature = "chacha")]
 | 
					    #[cfg(feature = "chacha")]
 | 
				
			||||||
    blocktree: Arc<Blocktree>,
 | 
					    blocktree: Arc<Blocktree>,
 | 
				
			||||||
 | 
					    #[cfg(feature = "chacha")]
 | 
				
			||||||
 | 
					    rng: ChaChaRng,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub(crate) fn sample_file(in_path: &Path, sample_offsets: &[u64]) -> io::Result<Hash> {
 | 
					pub(crate) fn sample_file(in_path: &Path, sample_offsets: &[u64]) -> io::Result<Hash> {
 | 
				
			||||||
@@ -261,6 +267,11 @@ impl Replicator {
 | 
				
			|||||||
        //always push this last
 | 
					        //always push this last
 | 
				
			||||||
        thread_handles.push(t_replicate);
 | 
					        thread_handles.push(t_replicate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut rng_seed = [0u8; 32];
 | 
				
			||||||
 | 
					        rng_seed.copy_from_slice(&signature.to_bytes()[0..32]);
 | 
				
			||||||
 | 
					        #[cfg(feature = "chacha")]
 | 
				
			||||||
 | 
					        let rng = ChaChaRng::from_seed(rng_seed);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(Self {
 | 
					        Ok(Self {
 | 
				
			||||||
            gossip_service,
 | 
					            gossip_service,
 | 
				
			||||||
            fetch_stage,
 | 
					            fetch_stage,
 | 
				
			||||||
@@ -280,6 +291,8 @@ impl Replicator {
 | 
				
			|||||||
            num_chacha_blocks: 0,
 | 
					            num_chacha_blocks: 0,
 | 
				
			||||||
            #[cfg(feature = "chacha")]
 | 
					            #[cfg(feature = "chacha")]
 | 
				
			||||||
            blocktree,
 | 
					            blocktree,
 | 
				
			||||||
 | 
					            #[cfg(feature = "chacha")]
 | 
				
			||||||
 | 
					            rng,
 | 
				
			||||||
        })
 | 
					        })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -288,13 +301,15 @@ impl Replicator {
 | 
				
			|||||||
        self.thread_handles.pop().unwrap().join().unwrap();
 | 
					        self.thread_handles.pop().unwrap().join().unwrap();
 | 
				
			||||||
        self.encrypt_ledger()
 | 
					        self.encrypt_ledger()
 | 
				
			||||||
            .expect("ledger encrypt not successful");
 | 
					            .expect("ledger encrypt not successful");
 | 
				
			||||||
 | 
					        let mut proof_index = 0;
 | 
				
			||||||
        loop {
 | 
					        loop {
 | 
				
			||||||
            self.create_sampling_offsets();
 | 
					            self.create_sampling_offsets();
 | 
				
			||||||
 | 
					            proof_index += 1;
 | 
				
			||||||
            if let Err(err) = self.sample_file_to_create_mining_hash() {
 | 
					            if let Err(err) = self.sample_file_to_create_mining_hash() {
 | 
				
			||||||
                warn!("Error sampling file, exiting: {:?}", err);
 | 
					                warn!("Error sampling file, exiting: {:?}", err);
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            self.submit_mining_proof();
 | 
					            self.submit_mining_proof(proof_index);
 | 
				
			||||||
            // TODO: Replicators should be submitting proofs as fast as possible
 | 
					            // TODO: Replicators should be submitting proofs as fast as possible
 | 
				
			||||||
            sleep(Duration::from_secs(2));
 | 
					            sleep(Duration::from_secs(2));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -381,15 +396,9 @@ impl Replicator {
 | 
				
			|||||||
        #[cfg(feature = "chacha")]
 | 
					        #[cfg(feature = "chacha")]
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            use crate::storage_stage::NUM_STORAGE_SAMPLES;
 | 
					            use crate::storage_stage::NUM_STORAGE_SAMPLES;
 | 
				
			||||||
            use rand::{Rng, SeedableRng};
 | 
					 | 
				
			||||||
            use rand_chacha::ChaChaRng;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            let mut rng_seed = [0u8; 32];
 | 
					 | 
				
			||||||
            rng_seed.copy_from_slice(&self.signature.to_bytes()[0..32]);
 | 
					 | 
				
			||||||
            let mut rng = ChaChaRng::from_seed(rng_seed);
 | 
					 | 
				
			||||||
            for _ in 0..NUM_STORAGE_SAMPLES {
 | 
					            for _ in 0..NUM_STORAGE_SAMPLES {
 | 
				
			||||||
                self.sampling_offsets
 | 
					                self.sampling_offsets
 | 
				
			||||||
                    .push(rng.gen_range(0, self.num_chacha_blocks) as u64);
 | 
					                    .push(self.rng.gen_range(0, self.num_chacha_blocks) as u64);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -438,7 +447,7 @@ impl Replicator {
 | 
				
			|||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn submit_mining_proof(&self) {
 | 
					    fn submit_mining_proof(&self, proof_index: u64) {
 | 
				
			||||||
        // No point if we've got no storage account...
 | 
					        // No point if we've got no storage account...
 | 
				
			||||||
        let nodes = self.cluster_info.read().unwrap().tvu_peers();
 | 
					        let nodes = self.cluster_info.read().unwrap().tvu_peers();
 | 
				
			||||||
        let client = crate::gossip_service::get_client(&nodes);
 | 
					        let client = crate::gossip_service::get_client(&nodes);
 | 
				
			||||||
@@ -457,6 +466,7 @@ impl Replicator {
 | 
				
			|||||||
            self.hash,
 | 
					            self.hash,
 | 
				
			||||||
            self.slot,
 | 
					            self.slot,
 | 
				
			||||||
            Signature::new(&self.signature.to_bytes()),
 | 
					            Signature::new(&self.signature.to_bytes()),
 | 
				
			||||||
 | 
					            proof_index,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        let message = Message::new_with_payer(vec![instruction], Some(&self.keypair.pubkey()));
 | 
					        let message = Message::new_with_payer(vec![instruction], Some(&self.keypair.pubkey()));
 | 
				
			||||||
        let mut transaction = Transaction::new(
 | 
					        let mut transaction = Transaction::new(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -366,6 +366,7 @@ impl StorageStage {
 | 
				
			|||||||
                slot: proof_slot,
 | 
					                slot: proof_slot,
 | 
				
			||||||
                signature,
 | 
					                signature,
 | 
				
			||||||
                sha_state,
 | 
					                sha_state,
 | 
				
			||||||
 | 
					                ..
 | 
				
			||||||
            }) => {
 | 
					            }) => {
 | 
				
			||||||
                if proof_slot < slot {
 | 
					                if proof_slot < slot {
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
@@ -701,6 +702,7 @@ mod tests {
 | 
				
			|||||||
            Hash::default(),
 | 
					            Hash::default(),
 | 
				
			||||||
            0,
 | 
					            0,
 | 
				
			||||||
            keypair.sign_message(b"test"),
 | 
					            keypair.sign_message(b"test"),
 | 
				
			||||||
 | 
					            0,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        let mining_proof_tx = Transaction::new_unsigned_instructions(vec![mining_proof_ix]);
 | 
					        let mining_proof_tx = Transaction::new_unsigned_instructions(vec![mining_proof_ix]);
 | 
				
			||||||
        let mining_txs = vec![mining_proof_tx];
 | 
					        let mining_txs = vec![mining_proof_tx];
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,6 +22,7 @@ pub enum StorageInstruction {
 | 
				
			|||||||
        sha_state: Hash,
 | 
					        sha_state: Hash,
 | 
				
			||||||
        slot: u64,
 | 
					        slot: u64,
 | 
				
			||||||
        signature: Signature,
 | 
					        signature: Signature,
 | 
				
			||||||
 | 
					        proof_index: u64,
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    AdvertiseStorageRecentBlockhash {
 | 
					    AdvertiseStorageRecentBlockhash {
 | 
				
			||||||
        hash: Hash,
 | 
					        hash: Hash,
 | 
				
			||||||
@@ -109,11 +110,13 @@ pub fn mining_proof(
 | 
				
			|||||||
    sha_state: Hash,
 | 
					    sha_state: Hash,
 | 
				
			||||||
    slot: u64,
 | 
					    slot: u64,
 | 
				
			||||||
    signature: Signature,
 | 
					    signature: Signature,
 | 
				
			||||||
 | 
					    proof_index: u64,
 | 
				
			||||||
) -> Instruction {
 | 
					) -> Instruction {
 | 
				
			||||||
    let storage_instruction = StorageInstruction::SubmitMiningProof {
 | 
					    let storage_instruction = StorageInstruction::SubmitMiningProof {
 | 
				
			||||||
        sha_state,
 | 
					        sha_state,
 | 
				
			||||||
        slot,
 | 
					        slot,
 | 
				
			||||||
        signature,
 | 
					        signature,
 | 
				
			||||||
 | 
					        proof_index,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
    let account_metas = vec![AccountMeta::new(*storage_pubkey, true)];
 | 
					    let account_metas = vec![AccountMeta::new(*storage_pubkey, true)];
 | 
				
			||||||
    Instruction::new(id(), &storage_instruction, account_metas)
 | 
					    Instruction::new(id(), &storage_instruction, account_metas)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,6 +43,7 @@ pub fn process_instruction(
 | 
				
			|||||||
            sha_state,
 | 
					            sha_state,
 | 
				
			||||||
            slot,
 | 
					            slot,
 | 
				
			||||||
            signature,
 | 
					            signature,
 | 
				
			||||||
 | 
					            ..
 | 
				
			||||||
        } => {
 | 
					        } => {
 | 
				
			||||||
            if me_unsigned || !rest.is_empty() {
 | 
					            if me_unsigned || !rest.is_empty() {
 | 
				
			||||||
                // This instruction must be signed by `me`
 | 
					                // This instruction must be signed by `me`
 | 
				
			||||||
@@ -154,6 +155,7 @@ mod tests {
 | 
				
			|||||||
            Hash::default(),
 | 
					            Hash::default(),
 | 
				
			||||||
            SLOTS_PER_SEGMENT,
 | 
					            SLOTS_PER_SEGMENT,
 | 
				
			||||||
            Signature::default(),
 | 
					            Signature::default(),
 | 
				
			||||||
 | 
					            0,
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
        // the proof is for slot 16, which is in segment 0, need to move the tick height into segment 2
 | 
					        // the proof is for slot 16, which is in segment 0, need to move the tick height into segment 2
 | 
				
			||||||
        let ticks_till_next_segment = TICKS_IN_SEGMENT * 2;
 | 
					        let ticks_till_next_segment = TICKS_IN_SEGMENT * 2;
 | 
				
			||||||
@@ -197,7 +199,7 @@ mod tests {
 | 
				
			|||||||
        let mut accounts = [Account::default()];
 | 
					        let mut accounts = [Account::default()];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let ix =
 | 
					        let ix =
 | 
				
			||||||
            storage_instruction::mining_proof(&pubkey, Hash::default(), 0, Signature::default());
 | 
					            storage_instruction::mining_proof(&pubkey, Hash::default(), 0, Signature::default(), 0);
 | 
				
			||||||
        // move tick height into segment 1
 | 
					        // move tick height into segment 1
 | 
				
			||||||
        let ticks_till_next_segment = TICKS_IN_SEGMENT + 1;
 | 
					        let ticks_till_next_segment = TICKS_IN_SEGMENT + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -217,7 +219,7 @@ mod tests {
 | 
				
			|||||||
        accounts[1].data.resize(STORAGE_ACCOUNT_SPACE as usize, 0);
 | 
					        accounts[1].data.resize(STORAGE_ACCOUNT_SPACE as usize, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let ix =
 | 
					        let ix =
 | 
				
			||||||
            storage_instruction::mining_proof(&pubkey, Hash::default(), 0, Signature::default());
 | 
					            storage_instruction::mining_proof(&pubkey, Hash::default(), 0, Signature::default(), 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // submitting a proof for a slot in the past, so this should fail
 | 
					        // submitting a proof for a slot in the past, so this should fail
 | 
				
			||||||
        assert!(test_instruction(&ix, &mut accounts, 0).is_err());
 | 
					        assert!(test_instruction(&ix, &mut accounts, 0).is_err());
 | 
				
			||||||
@@ -235,7 +237,7 @@ mod tests {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let ix =
 | 
					        let ix =
 | 
				
			||||||
            storage_instruction::mining_proof(&pubkey, Hash::default(), 0, Signature::default());
 | 
					            storage_instruction::mining_proof(&pubkey, Hash::default(), 0, Signature::default(), 0);
 | 
				
			||||||
        // move tick height into segment 1
 | 
					        // move tick height into segment 1
 | 
				
			||||||
        let ticks_till_next_segment = TICKS_IN_SEGMENT + 1;
 | 
					        let ticks_till_next_segment = TICKS_IN_SEGMENT + 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -493,6 +495,7 @@ mod tests {
 | 
				
			|||||||
                sha_state,
 | 
					                sha_state,
 | 
				
			||||||
                slot,
 | 
					                slot,
 | 
				
			||||||
                Signature::default(),
 | 
					                Signature::default(),
 | 
				
			||||||
 | 
					                0,
 | 
				
			||||||
            )],
 | 
					            )],
 | 
				
			||||||
            Some(&mint_keypair.pubkey()),
 | 
					            Some(&mint_keypair.pubkey()),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
@@ -586,6 +589,7 @@ mod tests {
 | 
				
			|||||||
                Hash::default(),
 | 
					                Hash::default(),
 | 
				
			||||||
                slot,
 | 
					                slot,
 | 
				
			||||||
                Signature::default(),
 | 
					                Signature::default(),
 | 
				
			||||||
 | 
					                0,
 | 
				
			||||||
            )],
 | 
					            )],
 | 
				
			||||||
            Some(&mint_pubkey),
 | 
					            Some(&mint_pubkey),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user