-
Notifications
You must be signed in to change notification settings - Fork 24
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
794 additions
and
40 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
[package] | ||
name = "certifier" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
axum = "0.6.20" | ||
serde = { version = "1.0.190", features = ["derive"] } | ||
tokio = { version = "1.0", features = [ | ||
"rt-multi-thread", | ||
"macros", | ||
"sync", | ||
"time", | ||
] } | ||
post-rs = { path = "../" } | ||
serde_with = { version = "3.4.0", features = ["base64", "hex"] } | ||
ed25519-dalek = { version = "2.0.0", features = ["rand_core"] } | ||
clap = { version = "4.4.7", features = ["derive", "env"] } | ||
hex = "0.4.3" | ||
config = "0.13.3" | ||
secrecy = { version = "0.8.0", features = ["serde"] } | ||
tracing = { version = "0.1.40", features = ["log"] } | ||
tracing-log = "0.2.0" | ||
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] } | ||
rand = "0.8.5" | ||
serde_json = "1.0.108" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
FROM rust:1 AS chef | ||
|
||
RUN cargo install cargo-chef | ||
RUN apt-get update && apt-get install -y\ | ||
llvm-dev \ | ||
libclang-dev \ | ||
clang \ | ||
cmake \ | ||
protobuf-compiler \ | ||
&& rm -rf /var/lib/apt/lists/* | ||
|
||
WORKDIR /certifier | ||
|
||
FROM chef AS planner | ||
COPY . . | ||
RUN cargo chef prepare --recipe-path recipe.json | ||
|
||
FROM chef AS builder | ||
COPY --from=planner /certifier/recipe.json recipe.json | ||
RUN cargo chef cook --release -p certifier --recipe-path recipe.json | ||
|
||
COPY . . | ||
RUN cargo build --release -p certifier --bin certifier | ||
|
||
FROM debian:bookworm-slim AS runtime | ||
WORKDIR /certifier | ||
COPY --from=builder /certifier/target/release/certifier /usr/local/bin | ||
ENTRYPOINT ["/usr/local/bin/certifier"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# Mainnet configuration | ||
listen: "0.0.0.0:80" | ||
post_cfg: | ||
k1: 26 | ||
k2: 37 | ||
k3: 37 | ||
pow_difficulty: "000dfb23b0979b4b000000000000000000000000000000000000000000000000" | ||
scrypt: | ||
n: 8192 | ||
r: 1 | ||
p: 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
{ | ||
"proof": { | ||
"nonce": 77, | ||
"pow": 1234, | ||
"indices": "hBGTHs44tav7YR87sRVafuzZwObCZnK1Z/exYpxwqSQ=" | ||
}, | ||
"metadata": { | ||
"node_id": "hBGTHs44tav7YR87sRVafuzZwObCZnK1Z/exYpxwqSQ=", | ||
"challenge": "hBGTHs44tav7YR87sRVafuzZwObCZnK1Z/exYpxwqSQ=", | ||
"commitment_atx_id": "ZuxocVjIYWfv7A/K1Lmm8+mNsHzAZaWVpbl5+KINx+I=", | ||
"num_units": 1, | ||
"labels_per_unit": 65536 | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
use std::sync::Arc; | ||
|
||
use axum::{extract::State, Json}; | ||
use axum::{routing::post, Router}; | ||
use ed25519_dalek::{Signer, SigningKey}; | ||
use post::pow::randomx::{PoW, RandomXFlag}; | ||
use post::verification::{Verifier, VerifyingParams}; | ||
use serde::{Deserialize, Serialize}; | ||
use serde_with::{base64::Base64, serde_as}; | ||
use tracing::instrument; | ||
|
||
#[derive(Debug, Deserialize)] | ||
struct CertifyRequest { | ||
proof: post::prove::Proof<'static>, | ||
metadata: post::metadata::ProofMetadata, | ||
} | ||
|
||
#[serde_as] | ||
#[derive(Debug, Serialize)] | ||
struct CertifyResponse { | ||
#[serde_as(as = "Base64")] | ||
signature: Vec<u8>, | ||
#[serde_as(as = "Base64")] | ||
pub_key: Vec<u8>, | ||
} | ||
|
||
#[instrument(skip(state))] | ||
async fn certify( | ||
State(state): State<Arc<AppState>>, | ||
Json(request): Json<CertifyRequest>, | ||
) -> Result<Json<CertifyResponse>, String> { | ||
tracing::debug!("certifying"); | ||
|
||
let pub_key = request.metadata.node_id; | ||
let s = state.clone(); | ||
let result = tokio::task::spawn_blocking(move || { | ||
s.verifier.verify( | ||
&request.proof, | ||
&request.metadata, | ||
VerifyingParams::new(&request.metadata, &s.cfg).unwrap(), | ||
) | ||
}) | ||
.await; | ||
match result { | ||
Err(e) => return Err(format!("internal error verifying proof: {e:?}")), | ||
Ok(Err(e)) => return Err(format!("invalid proof: {e:?}")), | ||
_ => {} | ||
} | ||
|
||
// Sign the nodeID | ||
let response = CertifyResponse { | ||
signature: state.signer.sign(&pub_key).to_vec(), | ||
pub_key: state.signer.verifying_key().to_bytes().to_vec(), | ||
}; | ||
Ok(Json(response)) | ||
} | ||
|
||
struct AppState { | ||
verifier: Verifier, | ||
cfg: post::config::Config, | ||
signer: SigningKey, | ||
} | ||
|
||
pub fn new(cfg: post::config::Config, signer: SigningKey) -> Router { | ||
let state = AppState { | ||
verifier: Verifier::new(Box::new( | ||
PoW::new(RandomXFlag::get_recommended_flags()).expect("creating RandomX PoW verifier"), | ||
)), | ||
cfg, | ||
signer, | ||
}; | ||
|
||
Router::new() | ||
.route("/certify", post(certify)) | ||
.with_state(Arc::new(state)) | ||
} | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
use std::path::Path; | ||
|
||
use ed25519_dalek::SecretKey; | ||
use serde_with::{base64::Base64, serde_as}; | ||
use tracing::info; | ||
|
||
#[serde_as] | ||
#[derive(serde::Deserialize, Clone)] | ||
pub struct Config { | ||
pub listen: std::net::SocketAddr, | ||
#[serde_as(as = "Base64")] | ||
pub signing_key: SecretKey, | ||
pub post_cfg: post::config::Config, | ||
} | ||
|
||
pub fn get_configuration(config_path: &Path) -> Result<Config, config::ConfigError> { | ||
info!("loading configuration from {config_path:?}"); | ||
|
||
let config = config::Config::builder() | ||
.add_source(config::File::from(config_path).required(true)) | ||
.add_source(config::Environment::with_prefix("CERTIFIER").try_parsing(true)) | ||
.build()?; | ||
|
||
config.try_deserialize() | ||
} | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod certifier; | ||
pub mod configuration; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use std::path::PathBuf; | ||
|
||
use clap::{arg, Parser, Subcommand}; | ||
use ed25519_dalek::SigningKey; | ||
use tracing::info; | ||
use tracing_log::LogTracer; | ||
use tracing_subscriber::{EnvFilter, FmtSubscriber}; | ||
|
||
#[derive(Parser, Debug)] | ||
#[command(version)] | ||
struct Cli { | ||
#[arg( | ||
short, | ||
long, | ||
default_value = "config.yml", | ||
env("CERTIFIER_CONFIG_PATH") | ||
)] | ||
config_path: PathBuf, | ||
|
||
#[command(subcommand)] | ||
cmd: Option<Commands>, | ||
} | ||
|
||
#[derive(Subcommand, Debug)] | ||
enum Commands { | ||
/// generate keypair and write it to standard out. | ||
/// the keypair is encoded as json | ||
GenerateKeys, | ||
} | ||
|
||
fn generate_keys() -> Result<(), Box<dyn std::error::Error>> { | ||
let signing_key: SigningKey = SigningKey::generate(&mut rand::rngs::OsRng); | ||
|
||
#[serde_with::serde_as] | ||
#[derive(serde::Serialize)] | ||
struct KeyPair { | ||
#[serde_as(as = "serde_with::base64::Base64")] | ||
public_key: [u8; ed25519_dalek::PUBLIC_KEY_LENGTH], | ||
#[serde_as(as = "serde_with::base64::Base64")] | ||
secret_key: [u8; ed25519_dalek::SECRET_KEY_LENGTH], | ||
} | ||
|
||
let keypair = KeyPair { | ||
public_key: signing_key.verifying_key().to_bytes(), | ||
secret_key: signing_key.to_bytes(), | ||
}; | ||
|
||
serde_json::to_writer_pretty(std::io::stdout(), &keypair)?; | ||
Ok(()) | ||
} | ||
|
||
#[tokio::main] | ||
async fn main() -> Result<(), Box<dyn std::error::Error>> { | ||
let args = Cli::parse(); | ||
|
||
if let Some(Commands::GenerateKeys) = args.cmd { | ||
return generate_keys(); | ||
} | ||
|
||
LogTracer::init()?; | ||
let env_filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new("INFO")); | ||
let subscriber = FmtSubscriber::builder() | ||
.with_env_filter(env_filter) | ||
.finish(); | ||
tracing::subscriber::set_global_default(subscriber)?; | ||
|
||
let config = certifier::configuration::get_configuration(&args.config_path)?; | ||
let signer = SigningKey::from_bytes(&config.signing_key); | ||
|
||
info!( | ||
"listening on: {:?}, pubkey: {:?}", | ||
config.listen, | ||
signer.verifying_key() | ||
); | ||
info!("using POST configuration: {:?}", config.post_cfg); | ||
|
||
let app: axum::Router = certifier::certifier::new(config.post_cfg, signer); | ||
|
||
axum::Server::bind(&config.listen) | ||
.serve(app.into_make_service()) | ||
.await?; | ||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters