diff --git a/src/cfg.rs b/src/cfg.rs index 05a7f80..9a2a13f 100644 --- a/src/cfg.rs +++ b/src/cfg.rs @@ -27,6 +27,9 @@ pub struct CommandLineArgs { #[arg(short = 'c', long)] celestia_client: Option, + #[arg(short = 'r', long)] + redis_client: Option, + /// Celestia Namespace ID #[arg(short = 'n', long)] celestia_namespace_id: Option, @@ -35,11 +38,11 @@ pub struct CommandLineArgs { #[arg(short, long)] epoch_time: Option, - /// IP address + /// IP address for the webserver to listen on #[arg(short, long)] - ip: Option, + host: Option, - /// Port number + /// Port number for the webserver to listen on #[arg(short, long)] port: Option, @@ -52,12 +55,15 @@ pub struct CommandLineArgs { #[derive(Debug, Deserialize, Clone)] pub struct Config { - pub log_level: String, #[serde(skip_serializing_if = "Option::is_none")] pub webserver: Option, - pub da_layer: DALayerOption, #[serde(skip_serializing_if = "Option::is_none")] pub celestia_config: Option, + #[serde(skip_serializing_if = "Option::is_none")] + + pub log_level: String, + pub da_layer: DALayerOption, + pub redis_config: Option, pub epoch_time: u64, pub public_key: Option, } @@ -73,23 +79,36 @@ pub enum DALayerOption { #[derive(Debug, Deserialize, Clone)] pub struct WebServerConfig { - pub ip: String, + pub host: String, pub port: u16, } impl Default for WebServerConfig { fn default() -> Self { WebServerConfig { - ip: "127.0.0.1".to_string(), + host: "127.0.0.1".to_string(), port: 8080, } } } +#[derive(Debug, Deserialize, Clone)] +pub struct RedisConfig { + pub connection_string: String +} + +impl Default for RedisConfig { + fn default() -> Self { + RedisConfig{ + connection_string: "redis://127.0.0.1/".to_string() + } + } +} + #[derive(Debug, Deserialize, Clone)] pub struct CelestiaConfig { - connection_string: String, - namespace_id: String, + pub connection_string: String, + pub namespace_id: String, } impl Default for CelestiaConfig { @@ -108,6 +127,7 @@ impl Default for Config { log_level: "DEBUG".to_string(), da_layer: DALayerOption::default(), celestia_config: Some(CelestiaConfig::default()), + redis_config: Some(RedisConfig::default()), epoch_time: 60, public_key: None, } @@ -129,14 +149,19 @@ pub fn load_config(args: CommandLineArgs) -> Result Ok(Config { log_level: args.log_level.unwrap_or(default_config.log_level), webserver: Some(WebServerConfig { - ip: args - .ip - .unwrap_or(default_config.webserver.as_ref().unwrap().ip.clone()), + host: args + .host + .unwrap_or(default_config.webserver.as_ref().unwrap().host.clone()), port: args .port .unwrap_or(default_config.webserver.as_ref().unwrap().port), }), da_layer: DALayerOption::default(), + redis_config: Some(RedisConfig { + connection_string: args.redis_client.unwrap_or( + default_config.redis_config.as_ref().unwrap().connection_string.clone() + ) + }), celestia_config: Some(CelestiaConfig { connection_string: args.celestia_client.unwrap_or( default_config @@ -181,6 +206,6 @@ pub async fn initialize_da_layer(config: &Config) -> Arc Arc::new(LocalDataAvailabilityLayer::new()) as Arc, - DALayerOption::None => panic!("No DALayer"), + DALayerOption::None => panic!("No DA Layer"), } } \ No newline at end of file diff --git a/src/da.rs b/src/da.rs index 4b5723c..ab9b372 100644 --- a/src/da.rs +++ b/src/da.rs @@ -262,7 +262,7 @@ impl DataAvailabilityLayer for CelestiaConnection { let height = extended_header.header.height.value(); match synctarget_buffer.send(height).await { Ok(_) => { - debug!("Sent sync target update to height {}", height); + debug!("sent sync target update for height {}", height); } Err(_) => { DataAvailabilityError::SyncTargetError( @@ -337,7 +337,7 @@ impl DataAvailabilityLayer for LocalDataAvailabilityLayer { let mut contents = String::new(); file.lock_exclusive().expect("Unable to lock file"); - info!("File locked"); + info!("file locked"); file.read_to_string(&mut contents) .expect("Unable to read file"); @@ -364,7 +364,7 @@ impl DataAvailabilityLayer for LocalDataAvailabilityLayer { .expect("Unable to set file length"); file.unlock().expect("Unable to unlock file"); - info!("File unlocked"); + info!("file unlocked"); Ok(epoch.height) } @@ -487,12 +487,12 @@ mod da_tests { #[tokio::test] async fn test_sequencer_and_light_client() { if let Err(e) = clear_file("data.json") { - debug!("Fehler beim Löschen der Datei: {}", e); + error!("deleting file: {}", e); } // simulate sequencer start let sequencer = tokio::spawn(async { - let mut sequencer_layer = LocalDataAvailabilityLayer::new(); + let sequencer_layer = LocalDataAvailabilityLayer::new(); // write all 60 seconds proofs and commitments // create a new tree let mut tree = build_empty_tree(); diff --git a/src/lib.rs b/src/lib.rs index d941211..6be8729 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -mod cfg; +pub mod cfg; pub mod consts; pub mod da; pub mod error; diff --git a/src/main.rs b/src/main.rs index cbe9f0f..3404c25 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,7 +39,7 @@ async fn main() -> std::io::Result<()> { Commands::LightClient {} => Arc::new(LightClient::new(da, config.public_key)), Commands::Sequencer {} => Arc::new(Sequencer::new( Arc::new( - RedisConnections::new() + RedisConnections::new(&config.clone().redis_config.unwrap()) .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e.to_string()))?, ), da, diff --git a/src/node_types.rs b/src/node_types.rs index f5f3feb..b53c32c 100644 --- a/src/node_types.rs +++ b/src/node_types.rs @@ -70,7 +70,6 @@ impl NodeType for Sequencer { } } Err(e) => { - // TODO: custom error error!("sequencer_loop: getting derived keys: {}", e); } } @@ -101,7 +100,7 @@ impl NodeType for LightClient { loop { // target is updated when a new header is received let target = self.da.get_message().await.unwrap(); - debug!("Updated sync target to height {}", target); + debug!("updated sync target to height {}", target); for i in current_position..target { trace!("processing height: {}", i); match self.da.get(i + 1).await { @@ -122,12 +121,12 @@ impl NodeType for LightClient { ) .is_ok() { - debug!("Signature is valid"); + trace!("valid signature for height {}", i); } else { - panic!("Invalid signature"); + panic!("invalid signature in retrieved epoch on height {}", i); } } else { - warn!("No public key found"); + error!("epoch on height {} was not signed", i); } match validate_epoch( @@ -417,11 +416,16 @@ impl Sequencer { /// * `false` if the operation was unsuccessful, e.g., due to an invalid signature or other errors. /// pub fn update_entry(&self, signature: &UpdateEntryJson) -> bool { - info!("Updating entry..."); + debug!("updating entry for uid {} with msg {}", signature.id, signature.signed_message); let signed_content = match verify_signature(signature, Some(signature.public_key.clone())) { Ok(content) => content, Err(_) => { - info!("Signature is invalid"); + error!( + "updating entry for uid {}: invalid signature with pubkey {} on msg {}", + signature.id, + signature.public_key, + signature.signed_message + ); return false; } }; @@ -429,7 +433,7 @@ impl Sequencer { let message_obj: IncomingEntry = match serde_json::from_str(&signed_content) { Ok(obj) => obj, Err(e) => { - error!("Failed to parse signed content: {}", e); + error!("parsing signed content: {}", e); return false; } }; diff --git a/src/storage.rs b/src/storage.rs index b26692a..bb4ac65 100644 --- a/src/storage.rs +++ b/src/storage.rs @@ -11,6 +11,7 @@ use std::thread::sleep; use std::time::Duration; use std::{self, fmt::Display, sync::Mutex}; +use crate::cfg::RedisConfig; use crate::utils::Signable; use crate::{ error::{DatabaseError, DeimosError, GeneralError}, @@ -165,17 +166,17 @@ pub trait Database: Send + Sync { } impl RedisConnections { - pub fn new() -> Result> { - let try_client = Client::open("redis://127.0.0.1/")?; + pub fn new(cfg: &RedisConfig) -> Result> { + let try_client = Client::open(cfg.clone().connection_string)?; let try_connection = try_client.get_connection(); if try_connection.is_err() { - debug!("Starting redis-server..."); + debug!("starting redis-server..."); let _child = Command::new("redis-server").spawn()?; sleep(Duration::from_secs(5)); - debug!("Redis-server started."); + debug!("redis-server started"); } let client = Client::open("redis://127.0.0.1/")?; @@ -466,7 +467,7 @@ impl Database for RedisConnections { "empty hash as first entry in the derived dictionary" )) })?; - debug!("Added empty hash to derived dict"); + debug!("added empty hash to derived dict"); // add the empty hash to the input order as first node input_con @@ -474,7 +475,7 @@ impl Database for RedisConnections { .map_err(|_| { DatabaseError::WriteError(format!("empty hash as first entry in input order")) })?; - debug!("Added empty hash to input order"); + debug!("added empty hash to input order"); Ok(()) } @@ -518,7 +519,7 @@ mod tests { // set up redis connection and flush database before each test fn setup() -> RedisConnections { - let redis_connections = RedisConnections::new().unwrap(); + let redis_connections = RedisConnections::new(&RedisConfig::default()).unwrap(); redis_connections.flush_database().unwrap(); redis_connections } diff --git a/src/utils.rs b/src/utils.rs index 4bf0c1f..4dca2fb 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -91,15 +91,15 @@ pub fn create_and_verify_snark( ) -> Result<(groth16::Proof, VerifyingKey), DeimosError> { let rng = &mut OsRng; - trace!("Creating parameters with BLS12-381 pairing-friendly elliptic curve construction...."); + trace!("creating parameters with BLS12-381 pairing-friendly elliptic curve construction...."); let params = groth16::generate_random_parameters::(circuit.clone(), rng) .map_err(|_| DeimosError::Proof(ProofError::ProofUnpackError))?; - trace!("Creating proof for zkSNARK..."); + trace!("creating proof for zkSNARK..."); let proof = groth16::create_random_proof(circuit, ¶ms, rng) .map_err(|_| DeimosError::Proof(ProofError::GenerationError))?; - trace!("Preparing verifying key for zkSNARK..."); + trace!("preparing verifying key for zkSNARK..."); let pvk = groth16::prepare_verifying_key(¶ms.vk); groth16::verify_proof(&pvk, &proof, &scalars) diff --git a/src/webserver.rs b/src/webserver.rs index 50ef750..f455faa 100644 --- a/src/webserver.rs +++ b/src/webserver.rs @@ -37,9 +37,9 @@ impl WebServer { /* let mut builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap(); builder.set_private_key_file(env.key_path, SslFiletype::PEM).unwrap(); builder.set_certificate_chain_file(env.cert_path).unwrap(); */ - info!("starting webserver on {}:{}", self.cfg.ip, self.cfg.port); + info!("starting webserver on {}:{}", self.cfg.host, self.cfg.port); let ctx = Data::new(session.clone()); - let (ip, port) = (self.cfg.ip.clone(), self.cfg.port); + let (ip, port) = (self.cfg.host.clone(), self.cfg.port); HttpServer::new(move || { let cors = Cors::default() @@ -376,7 +376,7 @@ async fn handle_validate_proof(con: web::Data>, req_body: String) // Returns an HTTP response containing either a confirmation of successful validation or an error. #[post("/validate-epoch")] async fn handle_validate_epoch(con: web::Data>, req_body: String) -> impl Responder { - debug!("Validating epoch {}", req_body); + debug!("validating epoch {}", req_body); let epoch: String = match serde_json::from_str(&req_body) { Ok(epoch) => epoch, Err(_) => return HttpResponse::BadRequest().body("Invalid epoch"), @@ -450,20 +450,20 @@ async fn handle_validate_hashchain_proof( let circuit = match HashChainEntryCircuit::create(&incoming_value.value, hashchain) { Ok(circuit) => circuit, Err(e) => { - error!("Error creating circuit: {}", e); + error!("creating circuit: {}", e); return HttpResponse::BadRequest().json("Could not create circuit"); } }; let rng = &mut OsRng; - // debug!("Creating parameters with BLS12-381 pairing-friendly elliptic curve construction...."); + trace!("creating parameters with BLS12-381 pairing-friendly elliptic curve construction"); let params = groth16::generate_random_parameters::(circuit.clone(), rng).unwrap(); - // debug!("Creating proof for zkSNARK..."); + trace!("creating proof for zkSNARK"); let proof = groth16::create_random_proof(circuit.clone(), ¶ms, rng).unwrap(); - // debug!("Prepare verifying key for zkSNARK..."); + trace!("prepare verifying key for zkSNARK"); let pvk = groth16::prepare_verifying_key(¶ms.vk); let public_param = match HashChainEntryCircuit::create_public_parameter(&incoming_value.value) { @@ -473,7 +473,7 @@ async fn handle_validate_hashchain_proof( } }; - // debug!("Verifying zkSNARK proof..."); + trace!("verifying zkSNARK proof"); match groth16::verify_proof(&pvk, &proof, &[public_param]) { Ok(_) => { info!("proof successfully verified with: {:?}", public_param);