diff --git a/sn_node/src/error.rs b/sn_node/src/error.rs index 31e0c3e98d..2eeb5426ac 100644 --- a/sn_node/src/error.rs +++ b/sn_node/src/error.rs @@ -86,4 +86,8 @@ pub enum Error { paid: NanoTokens, expected: NanoTokens, }, + + // ---------- Initialize Errors + #[error("Failed to generate a reward key")] + FailedToGenerateRewardKey, } diff --git a/sn_node/src/node.rs b/sn_node/src/node.rs index 9492030722..dbc5706b91 100644 --- a/sn_node/src/node.rs +++ b/sn_node/src/node.rs @@ -6,7 +6,11 @@ // KIND, either express or implied. Please review the Licences for the specific language governing // permissions and limitations relating to use of the SAFE Network Software. -use super::{error::Result, event::NodeEventsChannel, Marker, NodeEvent}; +use super::{ + error::{Error, Result}, + event::NodeEventsChannel, + Marker, NodeEvent, +}; #[cfg(feature = "open-metrics")] use crate::metrics::NodeMetrics; use crate::RunningNode; @@ -100,8 +104,14 @@ impl NodeBuilder { /// /// Returns an error if there is a problem initializing the `SwarmDriver`. pub fn build_and_run(self) -> Result { - // TODO: Make this key settable, and accessible via API - let reward_key = MainSecretKey::random(); + // Using the signature as the seed of generating the reward_key + let sig_vec = match self.keypair.sign(b"generate reward seed") { + Ok(sig) => sig, + Err(_err) => return Err(Error::FailedToGenerateRewardKey), + }; + let mut rng = sn_transfers::rng::from_vec(&sig_vec); + + let reward_key = MainSecretKey::random_from_rng(&mut rng); let reward_address = reward_key.main_pubkey(); let mut wallet = HotWallet::load_from_main_key(&self.root_dir, reward_key)?; diff --git a/sn_transfers/src/lib.rs b/sn_transfers/src/lib.rs index c118721a09..b132e09ac6 100644 --- a/sn_transfers/src/lib.rs +++ b/sn_transfers/src/lib.rs @@ -48,6 +48,7 @@ pub mod rng { rngs::{StdRng, ThreadRng}, SeedableRng, }; + use tiny_keccak::{Hasher, Sha3}; pub fn thread_rng() -> ThreadRng { crate::rand::thread_rng() @@ -56,4 +57,36 @@ pub mod rng { pub fn from_seed(seed: ::Seed) -> StdRng { StdRng::from_seed(seed) } + + // Using hash to covert `Vec` into `[u8; 32]', + // and using it as seed to generate a determined Rng. + pub fn from_vec(vec: &[u8]) -> StdRng { + let mut sha3 = Sha3::v256(); + sha3.update(vec); + let mut hash = [0u8; 32]; + sha3.finalize(&mut hash); + + from_seed(hash) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::rng::from_vec; + + #[test] + fn confirm_generating_same_key() { + let rng_seed = b"testing generating same key"; + let content = b"some context to try with"; + + let mut rng_1 = from_vec(rng_seed); + let reward_key_1 = MainSecretKey::random_from_rng(&mut rng_1); + let sig = reward_key_1.sign(content); + + let mut rng_2 = from_vec(rng_seed); + let reward_key_2 = MainSecretKey::random_from_rng(&mut rng_2); + + assert!(reward_key_2.main_pubkey().verify(&sig, content)); + } }