From 3f1cd9e7db2de665731e72495f3d12f2b6769dd1 Mon Sep 17 00:00:00 2001 From: Max Summe Date: Mon, 23 Sep 2024 14:19:15 -0700 Subject: [PATCH] Change signature of random methods to return errors if uninitialized RNG --- rs/nns/governance/benches/scale.rs | 6 +- rs/nns/governance/canister/canister.rs | 10 +- rs/nns/governance/src/governance.rs | 43 +++++-- rs/nns/governance/src/neuron_store.rs | 14 +- rs/nns/governance/src/test_utils.rs | 6 +- rs/nns/governance/tests/degraded_mode.rs | 9 +- rs/nns/governance/tests/fake.rs | 10 +- .../tests/fixtures/environment_fixture.rs | 11 +- rs/nns/governance/tests/fixtures/mod.rs | 11 +- rs/nns/governance/tests/governance.rs | 121 +++++++++++++----- 10 files changed, 162 insertions(+), 79 deletions(-) diff --git a/rs/nns/governance/benches/scale.rs b/rs/nns/governance/benches/scale.rs index 71422d368369..c54d45e7fe77 100644 --- a/rs/nns/governance/benches/scale.rs +++ b/rs/nns/governance/benches/scale.rs @@ -20,7 +20,7 @@ use ic_base_types::{CanisterId, PrincipalId}; use ic_nervous_system_common::{cmc::FakeCmc, ledger::IcpLedger, NervousSystemError}; use ic_nns_common::pb::v1::NeuronId; use ic_nns_governance::{ - governance::{Environment, Governance, HeapGrowthPotential}, + governance::{Environment, Governance, HeapGrowthPotential, RngError}, pb::v1::{ neuron, proposal, ExecuteNnsFunction, Governance as GovernanceProto, GovernanceError, Motion, NetworkEconomics, Neuron, Proposal, Topic, @@ -48,11 +48,11 @@ impl Environment for MockEnvironment { self.secs } - fn random_u64(&mut self) -> u64 { + fn random_u64(&mut self) -> Result { todo!() } - fn random_byte_array(&mut self) -> [u8; 32] { + fn random_byte_array(&mut self) -> Result<[u8; 32], RngError> { todo!() } diff --git a/rs/nns/governance/canister/canister.rs b/rs/nns/governance/canister/canister.rs index 16c83a3a5ff9..cbe4dbf2f39e 100644 --- a/rs/nns/governance/canister/canister.rs +++ b/rs/nns/governance/canister/canister.rs @@ -20,7 +20,7 @@ use ic_nns_common::{ use ic_nns_constants::LEDGER_CANISTER_ID; use ic_nns_governance::{ decoder_config, encode_metrics, - governance::{Environment, Governance, HeapGrowthPotential, TimeWarp as GovTimeWarp}, + governance::{Environment, Governance, HeapGrowthPotential, RngError, TimeWarp as GovTimeWarp}, neuron_data_validation::NeuronDataValidationSummary, pb::v1::{self as gov_pb, Governance as InternalGovernanceProto}, storage::{grow_upgrades_memory_to, validate_stable_storage, with_upgrades_memory}, @@ -206,14 +206,14 @@ impl Environment for CanisterEnv { self.time_warp = new_time_warp; } - fn random_u64(&mut self) -> u64 { - self.rng.next_u64() + fn random_u64(&mut self) -> Result { + Ok(self.rng.next_u64()) } - fn random_byte_array(&mut self) -> [u8; 32] { + fn random_byte_array(&mut self) -> Result<[u8; 32], RngError> { let mut bytes = [0u8; 32]; self.rng.fill_bytes(&mut bytes); - bytes + Ok(bytes) } fn execute_nns_function( diff --git a/rs/nns/governance/src/governance.rs b/rs/nns/governance/src/governance.rs index 3f7b96574314..21c808ef9b68 100644 --- a/rs/nns/governance/src/governance.rs +++ b/rs/nns/governance/src/governance.rs @@ -1451,8 +1451,24 @@ impl fmt::Display for RewardEvent { } } +#[derive(Debug)] +pub enum RngError { + RngNotInitialized, +} + +impl From for GovernanceError { + fn from(e: RngError) -> Self { + match e { + RngError::RngNotInitialized => GovernanceError::new_with_message( + ErrorType::PreconditionFailed, + "Rng not initialized. Try again later.".to_string(), + ), + } + } +} + /// A general trait for the environment in which governance is running. -#[automock] +/// DO NOT MERGE - restore automock annotation #[async_trait] pub trait Environment: Send + Sync { /// Returns the current time, in seconds since the epoch. @@ -1465,12 +1481,12 @@ pub trait Environment: Send + Sync { /// Returns a random number. /// /// This number is the same in all replicas. - fn random_u64(&mut self) -> u64; + fn random_u64(&mut self) -> Result; /// Returns a random byte array with 32 bytes. /// /// This number is the same in all replicas. - fn random_byte_array(&mut self) -> [u8; 32]; + fn random_byte_array(&mut self) -> Result<[u8; 32], RngError>; /// Executes a `ExecuteNnsFunction`. The standard implementation is /// expected to call out to another canister and eventually report the @@ -2617,11 +2633,11 @@ impl Governance { } let created_timestamp_seconds = self.env.now(); - let child_nid = self.neuron_store.new_neuron_id(&mut *self.env); + let child_nid = self.neuron_store.new_neuron_id(&mut *self.env)?; let from_subaccount = parent_neuron.subaccount(); - let to_subaccount = Subaccount(self.env.random_byte_array()); + let to_subaccount = Subaccount(self.env.random_byte_array()?); // Make sure there isn't already a neuron with the same sub-account. if self.neuron_store.has_neuron_with_subaccount(to_subaccount) { @@ -3024,11 +3040,11 @@ impl Governance { )); } - let child_nid = self.neuron_store.new_neuron_id(&mut *self.env); + let child_nid = self.neuron_store.new_neuron_id(&mut *self.env)?; // use provided sub-account if any, otherwise generate a random one. let to_subaccount = match spawn.nonce { - None => Subaccount(self.env.random_byte_array()), + None => Subaccount(self.env.random_byte_array()?), Some(nonce_val) => { ledger::compute_neuron_staking_subaccount(child_controller, nonce_val) } @@ -3305,7 +3321,7 @@ impl Governance { ) })?; - let child_nid = self.neuron_store.new_neuron_id(&mut *self.env); + let child_nid = self.neuron_store.new_neuron_id(&mut *self.env)?; let from_subaccount = parent_neuron.subaccount(); // The account is derived from the new owner's principal so it can be found by @@ -4089,7 +4105,7 @@ impl Governance { "Reward node provider proposal must have a reward mode.", )), Some(RewardMode::RewardToNeuron(reward_to_neuron)) => { - let to_subaccount = Subaccount(self.env.random_byte_array()); + let to_subaccount = Subaccount(self.env.random_byte_array()?); let _block_height = self .ledger .transfer_funds( @@ -4100,7 +4116,7 @@ impl Governance { now, ) .await?; - let nid = self.neuron_store.new_neuron_id(&mut *self.env); + let nid = self.neuron_store.new_neuron_id(&mut *self.env)?; let dissolve_delay_seconds = std::cmp::min( reward_to_neuron.dissolve_delay_seconds, MAX_DISSOLVE_DELAY_SECONDS, @@ -6112,7 +6128,7 @@ impl Governance { controller: PrincipalId, claim_or_refresh: &ClaimOrRefresh, ) -> Result { - let nid = self.neuron_store.new_neuron_id(&mut *self.env); + let nid = self.neuron_store.new_neuron_id(&mut *self.env)?; let now = self.env.now(); let neuron = NeuronBuilder::new( nid, @@ -7816,7 +7832,10 @@ impl Governance { /// Picks a value at random in [00:00, 23:45] that is a multiple of 15 /// minutes past midnight. pub fn randomly_pick_swap_start(&mut self) -> GlobalTimeOfDay { - let time_of_day_seconds = self.env.random_u64() % ONE_DAY_SECONDS; + // It's not critical that we have perfect randomness here, so we can default to a fixed value + // for the edge case where the RNG is not initialized (which should be very rare in the + // context of proposal executions) + let time_of_day_seconds = self.env.random_u64().unwrap_or(10_000) % ONE_DAY_SECONDS; // Round down to nearest multiple of 15 min. let remainder_seconds = time_of_day_seconds % (15 * 60); diff --git a/rs/nns/governance/src/neuron_store.rs b/rs/nns/governance/src/neuron_store.rs index 4d8cd31c7e51..6eb7ba49a471 100644 --- a/rs/nns/governance/src/neuron_store.rs +++ b/rs/nns/governance/src/neuron_store.rs @@ -63,6 +63,7 @@ pub enum NeuronStoreError { principal_id: PrincipalId, neuron_id: NeuronId, }, + NeuronIdGenerationNotAvailable, } impl NeuronStoreError { @@ -160,6 +161,13 @@ impl Display for NeuronStoreError { principal_id, neuron_id ) } + NeuronStoreError::NeuronIdGenerationNotAvailable => { + write!( + f, + "Neuron ID generation is not available currently. \ + Likely due to uninitialized RNG." + ) + } } } } @@ -176,6 +184,7 @@ impl From for GovernanceError { NeuronStoreError::NeuronAlreadyExists(_) => ErrorType::PreconditionFailed, NeuronStoreError::InvalidData { .. } => ErrorType::PreconditionFailed, NeuronStoreError::NotAuthorizedToGetFullNeuron { .. } => ErrorType::NotAuthorized, + NeuronStoreError::NeuronIdGenerationNotAvailable => ErrorType::PreconditionFailed, }; GovernanceError::new_with_message(error_type, value.to_string()) } @@ -384,10 +393,11 @@ impl NeuronStore { self.clock.set_time_warp(new_time_warp); } - pub fn new_neuron_id(&self, env: &mut dyn Environment) -> NeuronId { + pub fn new_neuron_id(&self, env: &mut dyn Environment) -> Result { loop { let id = env .random_u64() + .map_err(|_| NeuronStoreError::NeuronIdGenerationNotAvailable)? // Let there be no question that id was chosen // intentionally, not just 0 by default. .saturating_add(1); @@ -396,7 +406,7 @@ impl NeuronStore { let is_unique = !self.contains(neuron_id); if is_unique { - return neuron_id; + return Ok(neuron_id); } ic_cdk::println!( diff --git a/rs/nns/governance/src/test_utils.rs b/rs/nns/governance/src/test_utils.rs index d35b58877ffa..141b8f4734c2 100644 --- a/rs/nns/governance/src/test_utils.rs +++ b/rs/nns/governance/src/test_utils.rs @@ -1,5 +1,5 @@ use crate::{ - governance::{Environment, HeapGrowthPotential}, + governance::{Environment, HeapGrowthPotential, RngError}, pb::v1::{ExecuteNnsFunction, GovernanceError, OpenSnsTokenSwap}, }; use async_trait::async_trait; @@ -193,11 +193,11 @@ impl Environment for MockEnvironment { *self.now.lock().unwrap() } - fn random_u64(&mut self) -> u64 { + fn random_u64(&mut self) -> Result { unimplemented!(); } - fn random_byte_array(&mut self) -> [u8; 32] { + fn random_byte_array(&mut self) -> Result<[u8; 32], RngError> { unimplemented!(); } diff --git a/rs/nns/governance/tests/degraded_mode.rs b/rs/nns/governance/tests/degraded_mode.rs index 6f0bf6e1e7c2..a95d83253d49 100644 --- a/rs/nns/governance/tests/degraded_mode.rs +++ b/rs/nns/governance/tests/degraded_mode.rs @@ -9,7 +9,8 @@ use ic_nns_common::pb::v1::NeuronId; use ic_nns_constants::GOVERNANCE_CANISTER_ID; use ic_nns_governance::{ governance::{ - Environment, Governance, HeapGrowthPotential, HEAP_SIZE_SOFT_LIMIT_IN_WASM32_PAGES, + Environment, Governance, HeapGrowthPotential, RngError, + HEAP_SIZE_SOFT_LIMIT_IN_WASM32_PAGES, }, pb::v1::{ governance_error::ErrorType, @@ -35,11 +36,11 @@ impl Environment for DegradedEnv { 111000222 } - fn random_u64(&mut self) -> u64 { - 4 // https://xkcd.com/221 + fn random_u64(&mut self) -> Result { + Ok(4) // https://xkcd.com/221 } - fn random_byte_array(&mut self) -> [u8; 32] { + fn random_byte_array(&mut self) -> Result<[u8; 32], RngError> { unimplemented!() } diff --git a/rs/nns/governance/tests/fake.rs b/rs/nns/governance/tests/fake.rs index 6cf00fcc7386..3d7208bd9a68 100644 --- a/rs/nns/governance/tests/fake.rs +++ b/rs/nns/governance/tests/fake.rs @@ -14,7 +14,7 @@ use ic_nns_constants::{ SNS_WASM_CANISTER_ID, }; use ic_nns_governance::{ - governance::{Environment, Governance, HeapGrowthPotential}, + governance::{Environment, Governance, HeapGrowthPotential, RngError}, pb::v1::{ manage_neuron, manage_neuron::NeuronIdOrSubaccount, manage_neuron_response, proposal, ExecuteNnsFunction, GovernanceError, ManageNeuron, ManageNeuronResponse, Motion, @@ -312,14 +312,14 @@ impl Environment for FakeDriver { self.state.try_lock().unwrap().now } - fn random_u64(&mut self) -> u64 { - self.state.try_lock().unwrap().rng.next_u64() + fn random_u64(&mut self) -> Result { + Ok(self.state.try_lock().unwrap().rng.next_u64()) } - fn random_byte_array(&mut self) -> [u8; 32] { + fn random_byte_array(&mut self) -> Result<[u8; 32], RngError> { let mut bytes = [0u8; 32]; self.state.try_lock().unwrap().rng.fill_bytes(&mut bytes); - bytes + Ok(bytes) } fn execute_nns_function( diff --git a/rs/nns/governance/tests/fixtures/environment_fixture.rs b/rs/nns/governance/tests/fixtures/environment_fixture.rs index e74e947339da..72442b217ed6 100644 --- a/rs/nns/governance/tests/fixtures/environment_fixture.rs +++ b/rs/nns/governance/tests/fixtures/environment_fixture.rs @@ -2,7 +2,7 @@ use async_trait::async_trait; use candid::{CandidType, Decode, Encode, Error}; use ic_base_types::CanisterId; use ic_nns_governance::{ - governance::{Environment, HeapGrowthPotential}, + governance::{Environment, HeapGrowthPotential, RngError}, pb::v1::{ExecuteNnsFunction, GovernanceError}, }; use ic_sns_root::GetSnsCanistersSummaryRequest; @@ -145,15 +145,16 @@ impl Environment for EnvironmentFixture { self.environment_fixture_state.try_lock().unwrap().now } - fn random_u64(&mut self) -> u64 { - self.environment_fixture_state + fn random_u64(&mut self) -> Result { + Ok(self + .environment_fixture_state .try_lock() .unwrap() .rng - .next_u64() + .next_u64()) } - fn random_byte_array(&mut self) -> [u8; 32] { + fn random_byte_array(&mut self) -> Result<[u8; 32], RngError> { unimplemented!() } diff --git a/rs/nns/governance/tests/fixtures/mod.rs b/rs/nns/governance/tests/fixtures/mod.rs index 254bb67aae3a..fe86c24b29f8 100755 --- a/rs/nns/governance/tests/fixtures/mod.rs +++ b/rs/nns/governance/tests/fixtures/mod.rs @@ -20,7 +20,8 @@ use ic_nns_common::{ use ic_nns_constants::LEDGER_CANISTER_ID; use ic_nns_governance::{ governance::{ - governance_minting_account, neuron_subaccount, Environment, Governance, HeapGrowthPotential, + governance_minting_account, neuron_subaccount, Environment, Governance, + HeapGrowthPotential, RngError, }, governance_proto_builder::GovernanceProtoBuilder, pb::v1::{ @@ -485,11 +486,11 @@ impl Environment for NNSFixture { self.nns_state.try_lock().unwrap().environment.now() } - fn random_u64(&mut self) -> u64 { + fn random_u64(&mut self) -> Result { self.nns_state.try_lock().unwrap().environment.random_u64() } - fn random_byte_array(&mut self) -> [u8; 32] { + fn random_byte_array(&mut self) -> Result<[u8; 32], RngError> { self.nns_state .try_lock() .unwrap() @@ -942,11 +943,11 @@ impl Environment for NNS { self.fixture.now() } - fn random_u64(&mut self) -> u64 { + fn random_u64(&mut self) -> Result { self.fixture.random_u64() } - fn random_byte_array(&mut self) -> [u8; 32] { + fn random_byte_array(&mut self) -> Result<[u8; 32], RngError> { self.fixture.random_byte_array() } diff --git a/rs/nns/governance/tests/governance.rs b/rs/nns/governance/tests/governance.rs index 56eab0c710e7..d285ea8d4947 100644 --- a/rs/nns/governance/tests/governance.rs +++ b/rs/nns/governance/tests/governance.rs @@ -46,7 +46,7 @@ use ic_nns_governance::{ test_data::{ CREATE_SERVICE_NERVOUS_SYSTEM, CREATE_SERVICE_NERVOUS_SYSTEM_WITH_MATCHED_FUNDING, }, - Environment, Governance, HeapGrowthPotential, + Environment, Governance, HeapGrowthPotential, RngError, EXECUTE_NNS_FUNCTION_PAYLOAD_LISTING_BYTES_MAX, MAX_DISSOLVE_DELAY_SECONDS, MAX_NEURON_AGE_FOR_AGE_BONUS, MAX_NUMBER_OF_PROPOSALS_WITH_BALLOTS, MIN_DISSOLVE_DELAY_FOR_VOTE_ELIGIBILITY_SECONDS, PROPOSAL_MOTION_TEXT_BYTES_MAX, @@ -465,7 +465,10 @@ fn check_proposal_status_after_voting_and_after_expiration( .map(|(neuron, i)| Neuron { id: Some(NeuronId { id: i }), controller: Some(principal(i)), - account: fake_driver.random_byte_array().to_vec(), + account: fake_driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), ..neuron }) .collect(); @@ -1204,7 +1207,10 @@ fn fixture_for_following() -> GovernanceProto { cached_neuron_stake_e8s: 1_000_000_000, // 10 ICP // One year dissolve_state: Some(neuron::DissolveState::DissolveDelaySeconds(31557600)), - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), ..Default::default() }; GovernanceProto { @@ -1985,7 +1991,10 @@ fn fixture_for_manage_neuron() -> GovernanceProto { id: Some(NeuronId { id }), controller: Some(principal(id)), cached_neuron_stake_e8s: 1_000_000_000, // 10 ICP - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -2539,7 +2548,10 @@ fn fixture_two_neurons_second_is_bigger() -> GovernanceProto { id: Some(NeuronId { id: 1 }), controller: Some(principal(1)), cached_neuron_stake_e8s: 23, - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), // One year dissolve_state: Some(neuron::DissolveState::DissolveDelaySeconds(31557600)), ..Default::default() @@ -2548,7 +2560,10 @@ fn fixture_two_neurons_second_is_bigger() -> GovernanceProto { id: Some(NeuronId { id: 2 }), controller: Some(principal(2)), cached_neuron_stake_e8s: 951, - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), // One year dissolve_state: Some(neuron::DissolveState::DissolveDelaySeconds(31557600)), ..Default::default() @@ -3448,7 +3463,10 @@ fn compute_maturities( controller: Some(principal(i as u64)), cached_neuron_stake_e8s: *stake_e8s, dissolve_state: NOTDISSOLVING_MIN_DISSOLVE_DELAY_TO_VOTE, - account: fake_driver.random_byte_array().to_vec(), + account: fake_driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), ..Default::default() }) .collect(); @@ -3910,7 +3928,10 @@ fn fixture_for_approve_kyc() -> GovernanceProto { id: Some(NeuronId { id: 1 }), controller: Some(principal1), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), kyc_verified: false, dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, @@ -3920,7 +3941,10 @@ fn fixture_for_approve_kyc() -> GovernanceProto { id: Some(NeuronId { id: 2 }), controller: Some(principal2), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), kyc_verified: false, dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, @@ -3930,7 +3954,10 @@ fn fixture_for_approve_kyc() -> GovernanceProto { id: Some(NeuronId { id: 3 }), controller: Some(principal2), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), kyc_verified: false, dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, @@ -3940,7 +3967,10 @@ fn fixture_for_approve_kyc() -> GovernanceProto { id: Some(NeuronId { id: 4 }), controller: Some(principal3), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), kyc_verified: false, dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, @@ -4130,7 +4160,10 @@ fn test_get_neuron_ids_by_principal() { let neuron_a = Neuron { id: Some(NeuronId { id: 1 }), controller: Some(principal1), - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -4138,7 +4171,10 @@ fn test_get_neuron_ids_by_principal() { let neuron_b = Neuron { id: Some(NeuronId { id: 2 }), controller: Some(principal2), - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -4146,7 +4182,10 @@ fn test_get_neuron_ids_by_principal() { let neuron_c = Neuron { id: Some(NeuronId { id: 3 }), controller: Some(principal2), - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -4155,7 +4194,10 @@ fn test_get_neuron_ids_by_principal() { id: Some(NeuronId { id: 4 }), controller: Some(principal2), hot_keys: vec![principal4], - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -5656,7 +5698,7 @@ fn test_neuron_spawn_with_subaccount() { driver.advance_time_by(1); // Nonce used for spawn (given as input). - let nonce_spawn = driver.random_u64(); + let nonce_spawn = driver.random_u64().expect("Could not get random number"); let child_nid = gov .spawn_neuron( @@ -7721,7 +7763,7 @@ fn test_filter_proposals_neuron_visibility() { controller: Some(principal1), hot_keys: vec![principal_hot], cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -7730,7 +7772,7 @@ fn test_filter_proposals_neuron_visibility() { id: Some(NeuronId { id: 2 }), controller: Some(principal2), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -7739,7 +7781,7 @@ fn test_filter_proposals_neuron_visibility() { id: Some(NeuronId { id: 3 }), controller: Some(principal(3)), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), followees: hashmap! { Topic::NeuronManagement as i32 => neuron::Followees { followees: vec![NeuronId { id: 1 }], @@ -7815,7 +7857,7 @@ fn test_filter_proposals_include_all_manage_neuron_ignores_visibility() { id: Some(NeuronId { id: 1 }), controller: Some(principal1), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -7824,7 +7866,7 @@ fn test_filter_proposals_include_all_manage_neuron_ignores_visibility() { id: Some(NeuronId { id: 2 }), controller: Some(principal2), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -7833,7 +7875,7 @@ fn test_filter_proposals_include_all_manage_neuron_ignores_visibility() { id: Some(NeuronId { id: 3 }), controller: Some(principal(3)), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), followees: hashmap! { Topic::NeuronManagement as i32 => neuron::Followees { followees: vec![NeuronId { id: 1 }], @@ -7932,7 +7974,7 @@ fn test_filter_proposals_by_status() { id: Some(NeuronId { id: 1 }), controller: Some(principal1), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -8032,7 +8074,7 @@ fn test_filter_proposals_by_reward_status() { id: Some(NeuronId { id: 1 }), controller: Some(principal1), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -8123,7 +8165,7 @@ fn test_filter_proposals_excluding_topics() { id: Some(NeuronId { id: 1 }), controller: Some(principal1), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -8219,7 +8261,7 @@ fn test_filter_proposal_ballots() { controller: Some(principal1), hot_keys: vec![principal_hot], cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -8229,7 +8271,7 @@ fn test_filter_proposal_ballots() { id: Some(NeuronId { id: 2 }), controller: Some(principal2), cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -8325,7 +8367,7 @@ async fn test_make_proposal_message() { controller: Some(principal1), hot_keys: vec![], cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), dissolve_state: Some(DissolveState::DissolveDelaySeconds(MIN_DISSOLVE_DELAY_FOR_VOTE_ELIGIBILITY_SECONDS)), ..Default::default() }, @@ -8408,7 +8450,7 @@ fn test_omit_large_fields() { controller: Some(principal1), hot_keys: vec![], cached_neuron_stake_e8s: 10 * E8, - account: driver.random_byte_array().to_vec(), + account: driver.random_byte_array().expect("Could not get random byte array").to_vec(), dissolve_state: Some(DissolveState::WhenDissolvedTimestampSeconds(0)), aging_since_timestamp_seconds: u64::MAX, ..Default::default() @@ -10895,7 +10937,10 @@ async fn test_known_neurons() { let neurons = vec![ Neuron { id: Some(NeuronId { id: 1 }), - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), controller: Some(principal(1)), cached_neuron_stake_e8s: 100_000_000, dissolve_state: Some(DissolveState::DissolveDelaySeconds( @@ -10905,7 +10950,10 @@ async fn test_known_neurons() { }, Neuron { id: Some(NeuronId { id: 2 }), - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), controller: Some(principal(2)), cached_neuron_stake_e8s: 100_000_000, dissolve_state: Some(DissolveState::DissolveDelaySeconds( @@ -10915,7 +10963,10 @@ async fn test_known_neurons() { }, Neuron { id: Some(NeuronId { id: 3 }), - account: driver.random_byte_array().to_vec(), + account: driver + .random_byte_array() + .expect("Could not get random byte array") + .to_vec(), controller: Some(principal(3)), cached_neuron_stake_e8s: 100_000_000_000, dissolve_state: Some(DissolveState::DissolveDelaySeconds( @@ -11192,11 +11243,11 @@ impl Environment for MockEnvironment<'_> { DEFAULT_TEST_START_TIMESTAMP_SECONDS } - fn random_u64(&mut self) -> u64 { - RANDOM_U64 + fn random_u64(&mut self) -> Result { + Ok(RANDOM_U64) } - fn random_byte_array(&mut self) -> [u8; 32] { + fn random_byte_array(&mut self) -> Result<[u8; 32], RngError> { panic!("Unexpected call to Environment::random_byte_array"); }