From f74159031576c76ed3dab00b3accdc7bbdba0d55 Mon Sep 17 00:00:00 2001 From: gusto Date: Tue, 23 Jan 2024 18:17:05 +0200 Subject: [PATCH] Disseminate app file input (#565) * Accept file option in dissemination app * File dissemination tests --- nomos-cli/src/cmds/disseminate/mod.rs | 17 ++++- nomos-cli/src/da/disseminate.rs | 7 +- tests/src/tests/cli.rs | 94 +++++++++++++++++---------- 3 files changed, 77 insertions(+), 41 deletions(-) diff --git a/nomos-cli/src/cmds/disseminate/mod.rs b/nomos-cli/src/cmds/disseminate/mod.rs index 27f511fe..8e560fee 100644 --- a/nomos-cli/src/cmds/disseminate/mod.rs +++ b/nomos-cli/src/cmds/disseminate/mod.rs @@ -9,11 +9,11 @@ use reqwest::Url; use std::{path::PathBuf, sync::Arc, time::Duration}; use tokio::sync::Mutex; -#[derive(Args, Debug)] +#[derive(Args, Debug, Default)] pub struct Disseminate { // TODO: accept bytes #[clap(short, long)] - pub data: String, + pub data: Option, /// Path to the network config file #[clap(short, long)] pub network_config: PathBuf, @@ -30,6 +30,9 @@ pub struct Disseminate { /// File to write the certificate to, if present. #[clap(long)] pub output: Option, + /// File to disseminate + #[clap(short, long)] + pub file: Option, } impl Disseminate { @@ -41,7 +44,15 @@ impl Disseminate { as ServiceData>::Settings, >(std::fs::File::open(&self.network_config)?)?; let (status_updates, rx) = std::sync::mpsc::channel(); - let bytes: Box<[u8]> = self.data.clone().as_bytes().into(); + let bytes: Box<[u8]> = match (&self.data, &self.file) { + (Some(data), None) => data.clone().as_bytes().into(), + (None, Some(file_path)) => { + let file_bytes = std::fs::read(file_path)?; + file_bytes.into_boxed_slice() + } + (Some(_), Some(_)) => return Err("Cannot specify both data and file".into()), + (None, None) => return Err("Either data or file must be specified".into()), + }; let timeout = Duration::from_secs(self.timeout); let da_protocol = self.da_protocol.clone(); let node_addr = self.node_addr.clone(); diff --git a/nomos-cli/src/da/disseminate.rs b/nomos-cli/src/da/disseminate.rs index 5386496f..b28c704f 100644 --- a/nomos-cli/src/da/disseminate.rs +++ b/nomos-cli/src/da/disseminate.rs @@ -205,7 +205,7 @@ impl ServiceCore for DisseminateService { // protocols, but only the one chosen will be used. // We can enforce only sensible combinations of protocol/settings // are specified by using special clap directives -#[derive(Clone, Debug, Args)] +#[derive(Clone, Debug, Args, Default)] pub struct DaProtocolChoice { #[clap(long, default_value = "full-replication")] pub da_protocol: Protocol, @@ -227,14 +227,15 @@ impl TryFrom for FullReplication c.args(["--data", &data]), + (None, Some(file)) => c.args(["--file", file.as_os_str().to_str().unwrap()]), + (_, _) => panic!("Either data or file needs to be provided, but not both"), + }; + + c.status().expect("failed to execute nomos cli"); } -async fn disseminate(data: String) { +async fn disseminate(config: &mut Disseminate) { let (_mixnodes, mixnet_config) = MixNode::spawn_nodes(2).await; let mut nodes = NomosNode::spawn_nodes(SpawnConfig::chain_happy(2, mixnet_config)).await; @@ -58,21 +61,18 @@ async fn disseminate(data: String) { let da = >>::try_from(da_protocol.clone()) .unwrap(); - let config = Disseminate { - data: data.clone(), - timeout: 20, - network_config: config_path, - da_protocol, - node_addr: Some( - format!( - "http://{}", - nodes[0].config().http.backend_settings.address.clone() - ) - .parse() - .unwrap(), - ), - output: None, - }; + + config.timeout = 20; + config.network_config = config_path; + config.da_protocol = da_protocol; + config.node_addr = Some( + format!( + "http://{}", + nodes[0].config().http.backend_settings.address.clone() + ) + .parse() + .unwrap(), + ); run_disseminate(&config); // let thread = std::thread::spawn(move || cmd.run().unwrap()); @@ -84,29 +84,53 @@ async fn disseminate(data: String) { .await .unwrap(); - let blob = da.encode(data.as_bytes().to_vec())[0].hash(); + let (blob, bytes) = if let Some(data) = &config.data { + let bytes = data.as_bytes().to_vec(); + (da.encode(bytes.clone())[0].hash(), bytes) + } else { + let bytes = std::fs::read(&config.file.as_ref().unwrap()).unwrap(); + (da.encode(bytes.clone())[0].hash(), bytes) + }; assert_eq!( get_blobs(&nodes[0].url(), vec![blob]).await.unwrap()[0].as_bytes(), - data.as_bytes() + bytes.clone() ); } #[tokio::test] async fn disseminate_blob() { - disseminate("hello world".to_string()).await; + let mut config = Disseminate { + data: Some("hello world".to_string()), + ..Default::default() + }; + disseminate(&mut config).await; } #[tokio::test] async fn disseminate_big_blob() { const MSG_SIZE: usize = 1024; - disseminate( - std::iter::repeat(String::from("X")) + let mut config = Disseminate { + data: std::iter::repeat(String::from("X")) .take(MSG_SIZE) .collect::>() - .join(""), - ) - .await; + .join("") + .into(), + ..Default::default() + }; + disseminate(&mut config).await; +} + +#[tokio::test] +async fn disseminate_blob_from_file() { + let mut file = NamedTempFile::new().unwrap(); + file.write_all("hello world".as_bytes()).unwrap(); + + let mut config = Disseminate { + file: Some(file.path().to_path_buf()), + ..Default::default() + }; + disseminate(&mut config).await; } async fn wait_for_cert_in_mempool(node: &NomosNode) {