Disseminate app file input (#565)
* Accept file option in dissemination app * File dissemination tests
This commit is contained in:
parent
aa06080baa
commit
f741590315
|
@ -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<String>,
|
||||
/// 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<PathBuf>,
|
||||
/// File to disseminate
|
||||
#[clap(short, long)]
|
||||
pub file: Option<PathBuf>,
|
||||
}
|
||||
|
||||
impl Disseminate {
|
||||
|
@ -41,7 +44,15 @@ impl Disseminate {
|
|||
<NetworkService<Libp2p> 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();
|
||||
|
|
|
@ -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<DaProtocolChoice> for FullReplication<AbsoluteNumber<Attestation, C
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Args)]
|
||||
#[derive(Clone, Debug, Args, Default)]
|
||||
pub struct ProtocolSettings {
|
||||
#[clap(flatten)]
|
||||
pub full_replication: FullReplicationSettings,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, ValueEnum)]
|
||||
#[derive(Clone, Debug, ValueEnum, Default)]
|
||||
pub enum Protocol {
|
||||
#[default]
|
||||
FullReplication,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,11 @@
|
|||
use full_replication::{AbsoluteNumber, Attestation, Blob, Certificate, FullReplication};
|
||||
use full_replication::{AbsoluteNumber, Attestation, Certificate, FullReplication};
|
||||
use nomos_cli::{
|
||||
api::da::get_blobs,
|
||||
cmds::disseminate::{self, Disseminate},
|
||||
cmds::disseminate::Disseminate,
|
||||
da::disseminate::{DaProtocolChoice, FullReplicationSettings, Protocol, ProtocolSettings},
|
||||
};
|
||||
use nomos_core::da::{blob::Blob as _, DaProtocol};
|
||||
use std::{
|
||||
path::{self, PathBuf},
|
||||
time::Duration,
|
||||
};
|
||||
use std::{io::Write, time::Duration};
|
||||
use tempfile::NamedTempFile;
|
||||
use tests::{
|
||||
adjust_timeout, get_available_port, nodes::nomos::Pool, MixNode, Node, NomosNode, SpawnConfig,
|
||||
|
@ -21,17 +18,23 @@ use std::process::Command;
|
|||
const TIMEOUT_SECS: u64 = 20;
|
||||
|
||||
fn run_disseminate(disseminate: &Disseminate) {
|
||||
Command::new(CLI_BIN)
|
||||
let mut binding = Command::new(CLI_BIN);
|
||||
let c = binding
|
||||
.args(["disseminate", "--network-config"])
|
||||
.arg(disseminate.network_config.as_os_str())
|
||||
.args(["--data", &disseminate.data])
|
||||
.arg("--node-addr")
|
||||
.arg(disseminate.node_addr.as_ref().unwrap().as_str())
|
||||
.status()
|
||||
.expect("failed to execute nomos cli");
|
||||
.arg(disseminate.node_addr.as_ref().unwrap().as_str());
|
||||
|
||||
match (&disseminate.data, &disseminate.file) {
|
||||
(Some(data), None) => 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 =
|
||||
<FullReplication<AbsoluteNumber<Attestation, Certificate>>>::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::<Vec<_>>()
|
||||
.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) {
|
||||
|
|
Loading…
Reference in New Issue