diff --git a/Cargo.lock b/Cargo.lock index f4f46bf..98d8bee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1554,16 +1554,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" -[[package]] -name = "pem" -version = "3.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" -dependencies = [ - "base64 0.22.1", - "serde", -] - [[package]] name = "pem-rfc7468" version = "0.6.0" @@ -2213,7 +2203,7 @@ dependencies = [ "bft-json-crdt", "clap", "dirs", - "pem", + "fastcrypto", "serde", "serde_json", "serde_with 3.8.1", diff --git a/side-node/Cargo.toml b/side-node/Cargo.toml index afbec9a..7ec7a46 100644 --- a/side-node/Cargo.toml +++ b/side-node/Cargo.toml @@ -18,8 +18,8 @@ serde_with = "3.8.1" sha256 = "1.5.0" tokio = { version = "1.37.0", features = ["full"] } websockets = "0.3.0" -pem = "3.0.4" toml = "0.8.14" +fastcrypto = "0.1.8" [features] default = ["bft", "logging-list", "logging-json"] diff --git a/side-node/src/cli/mod.rs b/side-node/src/cli/mod.rs index 07f019e..cf50b6f 100644 --- a/side-node/src/cli/mod.rs +++ b/side-node/src/cli/mod.rs @@ -18,7 +18,7 @@ pub(crate) struct Args { #[derive(Subcommand)] pub(crate) enum Commands { /// runs the Side Node - Run {}, + Run { name: String }, /// initializes the Side Node with a new keypair Init { name: String }, diff --git a/side-node/src/init/keys.rs b/side-node/src/init/keys.rs deleted file mode 100644 index e2a486c..0000000 --- a/side-node/src/init/keys.rs +++ /dev/null @@ -1,20 +0,0 @@ -use std::{fs::File, io::Write, path::PathBuf}; - -use bft_json_crdt::keypair::{make_keypair, KeyPair}; -use pem::Pem; - -/// Makes an Ed25519 keypair and returns the public and private keys as a PEM-encoded string. -pub(crate) fn setup() -> String { - let keys = make_keypair(); - - let public_pem = Pem::new("PUBLIC", keys.public().to_string()); - let private_pem = Pem::new("PRIVATE", keys.private().to_string()); - pem::encode_many(&[public_pem, private_pem]) -} - -/// Writes a PEM-encoded string to a file at key_path. -pub(crate) fn write(key_path: PathBuf, pem: String) -> Result<(), std::io::Error> { - let mut file = File::create(key_path)?; - file.write(pem.to_string().as_bytes())?; - Ok(()) -} diff --git a/side-node/src/init/mod.rs b/side-node/src/init/mod.rs index bbad650..06881ab 100644 --- a/side-node/src/init/mod.rs +++ b/side-node/src/init/mod.rs @@ -2,19 +2,16 @@ use std::path::PathBuf; use config::SideNodeConfig; -pub(crate) mod config; -mod keys; +use crate::{keys, utils}; -const KEY_FILE: &str = "keys.pem"; -const CONFIG_FILE: &str = "config.toml"; +pub(crate) mod config; pub(crate) fn init(home: PathBuf, config: SideNodeConfig) -> Result<(), std::io::Error> { ensure_side_directory_exists(&home)?; - let (key_path, config_path) = side_paths(home.clone()); + let (key_path, config_path) = utils::side_paths(home.clone()); println!("Writing key to: {:?}", key_path); - let pem = keys::setup(); - keys::write(key_path, pem)?; + keys::write(key_path)?; println!("Writing config to: {:?}", config_path); config::write(&config, &config_path).expect("unable to write config file"); @@ -28,21 +25,13 @@ fn ensure_side_directory_exists(side_dir: &PathBuf) -> Result<(), std::io::Error if side_dir.exists() { return Ok(()); } - println!("Creating side config directory: {:?}", side_dir); + println!( + "Config directory doesn't exist, creating at: {:?}", + side_dir + ); std::fs::create_dir_all(side_dir) } -/// Returns the path to the key file for this host OS. -fn side_paths(prefix: PathBuf) -> (PathBuf, PathBuf) { - let mut key_path = prefix.clone(); - key_path.push(KEY_FILE); - - let mut config_path = prefix.clone(); - config_path.push(CONFIG_FILE); - - (key_path, config_path) -} - #[cfg(test)] mod tests { use std::{fs, path::Path}; @@ -74,7 +63,7 @@ mod tests { let mut file_path = PathBuf::new(); file_path.push("/tmp/side"); let side_dir = file_path.clone(); - file_path.push(KEY_FILE); + file_path.push(utils::KEY_FILE); let _ = init(side_dir.clone(), default_side_node_config()); assert!(file_path.exists()); @@ -89,7 +78,7 @@ mod tests { let mut file_path = PathBuf::new(); file_path.push("/tmp/side"); let side_dir = file_path.clone(); - file_path.push(CONFIG_FILE); + file_path.push(utils::CONFIG_FILE); let _ = init(side_dir.clone(), default_side_node_config()); assert!(file_path.exists()); diff --git a/side-node/src/keys.rs b/side-node/src/keys.rs new file mode 100644 index 0000000..4f0ef34 --- /dev/null +++ b/side-node/src/keys.rs @@ -0,0 +1,27 @@ +use std::{ + fs::{self, File}, + io::Write, + path::PathBuf, +}; + +use bft_json_crdt::keypair::{make_keypair, Ed25519KeyPair}; +use fastcrypto::traits::EncodeDecodeBase64; + +/// Writes a new Ed25519 keypair to the file at key_path. +pub(crate) fn write(key_path: PathBuf) -> Result<(), std::io::Error> { + let keys = make_keypair(); + + let mut file = File::create(key_path)?; + let out = keys.encode_base64(); + file.write(out.as_bytes())?; + Ok(()) +} + +pub(crate) fn load_from_file(side_dir: PathBuf) -> Ed25519KeyPair { + let key_path = crate::utils::side_paths(side_dir.clone()).0; + + let data = fs::read_to_string(key_path).expect("couldn't read key file"); + println!("data: {:?}", data); + + Ed25519KeyPair::decode_base64(&data).expect("couldn't load keypair from file") +} diff --git a/side-node/src/list_transaction_crdt.rs b/side-node/src/list_transaction_crdt.rs index 8186d8e..b98358b 100644 --- a/side-node/src/list_transaction_crdt.rs +++ b/side-node/src/list_transaction_crdt.rs @@ -1,3 +1,5 @@ +use std::path::PathBuf; + use bft_crdt_derive::add_crdt_fields; use bft_json_crdt::{ @@ -10,6 +12,8 @@ use serde::{Deserialize, Serialize}; use serde_json::{json, Value}; use websockets::WebSocket; +use crate::keys; + #[add_crdt_fields] #[derive(Clone, CrdtNode, Serialize, Deserialize)] pub(crate) struct CrdtList { @@ -25,8 +29,9 @@ pub(crate) struct Transaction { amount: f64, } -pub(crate) fn new() -> (BaseCrdt, Ed25519KeyPair) { - let keys = make_keypair(); +pub(crate) fn new(side_dir: PathBuf) -> (BaseCrdt, Ed25519KeyPair) { + let keys = keys::load_from_file(side_dir); + // let keys = make_keypair(); let bft_crdt = BaseCrdt::::new(&keys); println!("Author is {}", keys.public().to_string()); (bft_crdt, keys) diff --git a/side-node/src/main.rs b/side-node/src/main.rs index 8d18f83..a7c3f65 100644 --- a/side-node/src/main.rs +++ b/side-node/src/main.rs @@ -2,7 +2,9 @@ use cli::{parse_args, Commands}; pub(crate) mod cli; pub(crate) mod init; +pub(crate) mod keys; pub(crate) mod list_transaction_crdt; +pub(crate) mod utils; pub(crate) mod websocket; #[tokio::main] @@ -17,8 +19,9 @@ async fn main() { let _ = init::init(home(name), config); } - Some(Commands::Run {}) => { - let (mut bft_crdt, keys) = list_transaction_crdt::new(); + Some(Commands::Run { name }) => { + let side_dir = home(name); + let (mut bft_crdt, keys) = list_transaction_crdt::new(side_dir); websocket::start(keys, &mut bft_crdt).await.unwrap(); } None => println!("No command provided. Exiting. See --help for more information."), diff --git a/side-node/src/utils.rs b/side-node/src/utils.rs new file mode 100644 index 0000000..652e53f --- /dev/null +++ b/side-node/src/utils.rs @@ -0,0 +1,15 @@ +use std::path::PathBuf; + +pub(crate) const KEY_FILE: &str = "keys.pem"; +pub(crate) const CONFIG_FILE: &str = "config.toml"; + +/// Returns the path to the key file for this host OS. +pub(crate) fn side_paths(prefix: PathBuf) -> (PathBuf, PathBuf) { + let mut key_path = prefix.clone(); + key_path.push(KEY_FILE); + + let mut config_path = prefix.clone(); + config_path.push(CONFIG_FILE); + + (key_path, config_path) +}