* Add http option for Participant (#123) * Fix redpallas tests for participant phase 2 (#123) * Update participant/src/comms/http.rs * Remove unnecessary session id for participant round 2 (#123) * Fix clippy error (#123) --------- Co-authored-by: Conrado Gouvea <conrado@zfnd.org>
This commit is contained in:
parent
fb6e8f5e9f
commit
06c0c2453d
|
@ -1378,7 +1378,9 @@ dependencies = [
|
|||
"message-io",
|
||||
"rand",
|
||||
"reddsa",
|
||||
"reqwest",
|
||||
"serde_json",
|
||||
"server",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
|
@ -2074,6 +2076,7 @@ dependencies = [
|
|||
"rand",
|
||||
"reddsa",
|
||||
"serde_json",
|
||||
"server",
|
||||
"tokio",
|
||||
"trusted-dealer",
|
||||
]
|
||||
|
|
|
@ -19,10 +19,6 @@ pub struct Config {
|
|||
pub identifier: Identifier,
|
||||
}
|
||||
|
||||
pub trait Logger {
|
||||
fn log(&mut self, value: String);
|
||||
}
|
||||
|
||||
fn validate_inputs(config: &Config) -> Result<(), Error> {
|
||||
if config.min_signers < 2 {
|
||||
return Err(Error::InvalidMinSigners);
|
||||
|
|
|
@ -17,6 +17,8 @@ serde_json = "1.0"
|
|||
clap = { version = "4.5.4", features = ["derive"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
message-io = "0.18"
|
||||
reqwest = { version = "0.11.23", features = ["json"] }
|
||||
server = { path = "../server" }
|
||||
|
||||
[features]
|
||||
redpallas = []
|
||||
|
|
|
@ -9,6 +9,11 @@ pub struct Args {
|
|||
#[arg(long, default_value_t = false)]
|
||||
pub cli: bool,
|
||||
|
||||
/// HTTP mode. If enabled, it will use HTTP communication with a
|
||||
/// FROST server.
|
||||
#[arg(long, default_value_t = false)]
|
||||
pub http: bool,
|
||||
|
||||
/// Public key package to use. Can be a file with a JSON-encoded
|
||||
/// package, or "". If the file does not exist or if "" is specified,
|
||||
/// then it will be read from standard input.
|
||||
|
@ -22,4 +27,8 @@ pub struct Args {
|
|||
/// Port to connect to, if using online comms
|
||||
#[arg(short, long, default_value_t = 2744)]
|
||||
pub port: u16,
|
||||
|
||||
/// Optional Session ID
|
||||
#[arg(short, long, default_value = "")]
|
||||
pub session_id: String,
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use crate::args::Args;
|
||||
|
||||
use crate::comms::cli::CLIComms;
|
||||
use crate::comms::http::HTTPComms;
|
||||
use crate::comms::socket::SocketComms;
|
||||
|
||||
use crate::comms::Comms;
|
||||
|
@ -17,6 +18,8 @@ pub async fn cli(
|
|||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
let mut comms: Box<dyn Comms> = if args.cli {
|
||||
Box::new(CLIComms {})
|
||||
} else if args.http {
|
||||
Box::new(HTTPComms::new(args))
|
||||
} else {
|
||||
Box::new(SocketComms::new(args))
|
||||
};
|
||||
|
@ -45,7 +48,9 @@ pub async fn cli(
|
|||
.await?;
|
||||
let signature = generate_signature(round_2_config, &key_package, &nonces)?;
|
||||
|
||||
comms.send_signature_share(signature).await?;
|
||||
comms
|
||||
.send_signature_share(*key_package.identifier(), signature)
|
||||
.await?;
|
||||
|
||||
print_values_round_2(signature, logger)?;
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
pub mod cli;
|
||||
pub mod http;
|
||||
pub mod socket;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
@ -55,6 +56,7 @@ pub trait Comms {
|
|||
|
||||
async fn send_signature_share(
|
||||
&mut self,
|
||||
identifier: Identifier,
|
||||
signature_share: SignatureShare,
|
||||
) -> Result<(), Box<dyn Error>>;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ impl Comms for CLIComms {
|
|||
|
||||
async fn send_signature_share(
|
||||
&mut self,
|
||||
_identifier: Identifier,
|
||||
_signature_share: SignatureShare,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
Ok(())
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
//! HTTP implementation of the Comms trait.
|
||||
|
||||
use async_trait::async_trait;
|
||||
#[cfg(not(feature = "redpallas"))]
|
||||
use frost_ed25519 as frost;
|
||||
#[cfg(feature = "redpallas")]
|
||||
use reddsa::frost::redpallas as frost;
|
||||
|
||||
use eyre::eyre;
|
||||
|
||||
use frost::{round1::SigningCommitments, round2::SignatureShare, Identifier};
|
||||
|
||||
use super::{Comms, GenericSigningPackage};
|
||||
|
||||
use std::io::{BufRead, Write};
|
||||
|
||||
use std::error::Error;
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use crate::args::Args;
|
||||
|
||||
pub struct HTTPComms {
|
||||
client: reqwest::Client,
|
||||
host_port: String,
|
||||
session_id: Uuid,
|
||||
}
|
||||
|
||||
use server::Uuid;
|
||||
|
||||
// TODO: Improve error handling for invalid session id
|
||||
impl HTTPComms {
|
||||
pub fn new(args: &Args) -> Self {
|
||||
let client = reqwest::Client::new();
|
||||
Self {
|
||||
client,
|
||||
host_port: format!("http://{}:{}", args.ip, args.port),
|
||||
session_id: Uuid::parse_str(&args.session_id).expect("invalid session id"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait(?Send)]
|
||||
impl Comms for HTTPComms {
|
||||
async fn get_signing_package(
|
||||
&mut self,
|
||||
_input: &mut dyn BufRead,
|
||||
_output: &mut dyn Write,
|
||||
commitments: SigningCommitments,
|
||||
identifier: Identifier,
|
||||
) -> Result<GenericSigningPackage, Box<dyn Error>> {
|
||||
// Send Commitments to Server
|
||||
self.client
|
||||
.post(format!("{}/send_commitments", self.host_port))
|
||||
.json(&server::SendCommitmentsArgs {
|
||||
session_id: self.session_id,
|
||||
identifier,
|
||||
commitments: vec![commitments],
|
||||
})
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
eprint!("Waiting for coordinator to send signing package...");
|
||||
|
||||
// Receive SigningPackage from Coordinator
|
||||
|
||||
let r = loop {
|
||||
let r = self
|
||||
.client
|
||||
.post(format!("{}/get_signing_package", self.host_port))
|
||||
.json(&server::GetSigningPackageArgs {
|
||||
session_id: self.session_id,
|
||||
})
|
||||
.send()
|
||||
.await?;
|
||||
if r.status() != 200 {
|
||||
tokio::time::sleep(Duration::from_secs(2)).await;
|
||||
eprint!(".");
|
||||
} else {
|
||||
eprintln!("\nSigning package received");
|
||||
break r.json::<server::GetSigningPackageOutput>().await?;
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(feature = "redpallas")]
|
||||
let signing_package = (
|
||||
r.signing_package
|
||||
.first()
|
||||
.ok_or(eyre!("missing signing package"))
|
||||
.cloned()?,
|
||||
r.randomizer
|
||||
.first()
|
||||
.ok_or(eyre!("missing randomizer"))
|
||||
.cloned()?,
|
||||
);
|
||||
|
||||
#[cfg(not(feature = "redpallas"))]
|
||||
let signing_package = r
|
||||
.signing_package
|
||||
.first()
|
||||
.ok_or(eyre!("missing signing package"))
|
||||
.cloned()?;
|
||||
|
||||
Ok(signing_package)
|
||||
}
|
||||
|
||||
async fn send_signature_share(
|
||||
&mut self,
|
||||
identifier: Identifier,
|
||||
signature_share: SignatureShare,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
// Send signature share to Coordinator
|
||||
|
||||
eprintln!("Sending signature share to coordinator...");
|
||||
|
||||
let _r = self
|
||||
.client
|
||||
.post(format!("{}/send_signature_share", self.host_port))
|
||||
.json(&server::SendSignatureShareArgs {
|
||||
identifier,
|
||||
session_id: self.session_id,
|
||||
signature_share: vec![signature_share],
|
||||
})
|
||||
.send()
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -117,6 +117,7 @@ impl Comms for SocketComms {
|
|||
|
||||
async fn send_signature_share(
|
||||
&mut self,
|
||||
_identifier: Identifier,
|
||||
signature_share: SignatureShare,
|
||||
) -> Result<(), Box<dyn Error>> {
|
||||
// Send signature shares to Coordinator
|
||||
|
|
|
@ -42,8 +42,9 @@ async fn check_valid_round_1_inputs() {
|
|||
key_package: "-".to_string(),
|
||||
ip: "0.0.0.0".to_string(),
|
||||
port: 80,
|
||||
session_id: "session-id".to_string(),
|
||||
http: false,
|
||||
};
|
||||
|
||||
let input = SECRET_SHARE_JSON;
|
||||
let mut valid_input = input.as_bytes();
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::collections::BTreeMap;
|
||||
|
||||
use frost::Identifier;
|
||||
use serde::{Deserialize, Serialize};
|
||||
pub use uuid::Uuid;
|
||||
|
||||
|
@ -75,8 +76,8 @@ pub struct GetSigningPackageOutput {
|
|||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct SendSignatureShareArgs {
|
||||
pub identifier: Identifier,
|
||||
pub session_id: Uuid,
|
||||
pub identifier: frost::Identifier,
|
||||
pub signature_share: Vec<frost::round2::SignatureShare>,
|
||||
}
|
||||
|
||||
|
|
|
@ -176,8 +176,8 @@ async fn test_main_router() -> Result<(), Box<dyn std::error::Error>> {
|
|||
let res = server
|
||||
.post("/send_signature_share")
|
||||
.json(&server::SendSignatureShareArgs {
|
||||
session_id,
|
||||
identifier: *identifier,
|
||||
session_id,
|
||||
signature_share,
|
||||
})
|
||||
.await;
|
||||
|
|
|
@ -18,6 +18,7 @@ dkg = { path = "../dkg"}
|
|||
trusted-dealer = { path = "../trusted-dealer"}
|
||||
participant = { path = "../participant"}
|
||||
coordinator = { path = "../coordinator"}
|
||||
server = { path = "../server"}
|
||||
rand = "0.8"
|
||||
|
||||
[features]
|
||||
|
|
Loading…
Reference in New Issue