From 783ff100a0bb8b20b1e10cd3a1acf41fb1c36467 Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Thu, 28 Mar 2024 18:29:27 -0700 Subject: [PATCH 1/8] feat(ci): test speed up part 1 --- .github/workflows/rust.yml | 45 +++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 5476db43..6b18cb51 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,9 +2,9 @@ name: Rust on: push: - branches: ['main'] + branches: ["main"] pull_request: - branches: ['main'] + branches: ["main"] env: CARGO_TERM_COLOR: always @@ -39,14 +39,53 @@ jobs: with: components: rustc-codegen-cranelift-preview + - uses: Swatinem/rust-cache@v2 + with: + key: cache-v1 + - name: Build working-directory: ./snarkos-test env: RUSTFLAGS: -Zcodegen-backend=cranelift run: cargo +nightly build --verbose + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + path: snarkos-test + + - name: Checkout snarkOS + uses: actions/checkout@v4 + with: + repository: AleoNet/snarkOS + path: snarkos + + - name: Checkout snarkVM + uses: actions/checkout@v4 + with: + repository: AleoNet/snarkVM + path: snarkvm + + - name: Use mold linker + uses: rui314/setup-mold@v1 + + - name: Install nightly and cranelift + uses: dtolnay/rust-toolchain@nightly + with: + components: rustc-codegen-cranelift-preview + + - uses: Swatinem/rust-cache@v2 + with: + key: cache-v1 + + - uses: taiki-e/install-action@nextest + - name: Run tests working-directory: ./snarkos-test env: RUSTFLAGS: -Zcodegen-backend=cranelift - run: cargo +nightly test --verbose + run: cargo +nightly nextest --all --verbose From 7b3ac1f37557b367f421493ae68a80de8962043b Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Thu, 28 Mar 2024 18:49:31 -0700 Subject: [PATCH 2/8] fix(ci): fix test cmd, cache cmd can't take a dir --- .github/workflows/rust.yml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 6b18cb51..e3de4638 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -16,20 +16,18 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - with: - path: snarkos-test - name: Checkout snarkOS uses: actions/checkout@v4 with: repository: AleoNet/snarkOS - path: snarkos + path: ../snarkos - name: Checkout snarkVM uses: actions/checkout@v4 with: repository: AleoNet/snarkVM - path: snarkvm + path: ../snarkvm - name: Use mold linker uses: rui314/setup-mold@v1 @@ -55,20 +53,18 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 - with: - path: snarkos-test - name: Checkout snarkOS uses: actions/checkout@v4 with: repository: AleoNet/snarkOS - path: snarkos + path: ../snarkos - name: Checkout snarkVM uses: actions/checkout@v4 with: repository: AleoNet/snarkVM - path: snarkvm + path: ../snarkvm - name: Use mold linker uses: rui314/setup-mold@v1 @@ -85,7 +81,6 @@ jobs: - uses: taiki-e/install-action@nextest - name: Run tests - working-directory: ./snarkos-test env: RUSTFLAGS: -Zcodegen-backend=cranelift - run: cargo +nightly nextest --all --verbose + run: cargo +nightly nextest run --all --verbose --fail-fast From 7ed40180fd9401a8909022bea45d6192d3641f03 Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Thu, 28 Mar 2024 19:05:46 -0700 Subject: [PATCH 3/8] fix(ci): try workspaces for caching --- .github/workflows/rust.yml | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index e3de4638..28043e44 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -16,18 +16,20 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + path: snarkos-test - name: Checkout snarkOS uses: actions/checkout@v4 with: repository: AleoNet/snarkOS - path: ../snarkos + path: snarkos - name: Checkout snarkVM uses: actions/checkout@v4 with: repository: AleoNet/snarkVM - path: ../snarkvm + path: snarkvm - name: Use mold linker uses: rui314/setup-mold@v1 @@ -39,6 +41,7 @@ jobs: - uses: Swatinem/rust-cache@v2 with: + workspaces: snarkos-test key: cache-v1 - name: Build @@ -53,18 +56,20 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + path: snarkos-test - name: Checkout snarkOS uses: actions/checkout@v4 with: repository: AleoNet/snarkOS - path: ../snarkos + path: snarkos - name: Checkout snarkVM uses: actions/checkout@v4 with: repository: AleoNet/snarkVM - path: ../snarkvm + path: snarkvm - name: Use mold linker uses: rui314/setup-mold@v1 @@ -76,11 +81,13 @@ jobs: - uses: Swatinem/rust-cache@v2 with: + workspaces: snarkos-test key: cache-v1 - uses: taiki-e/install-action@nextest - name: Run tests + working-directory: ./snarkos-test env: RUSTFLAGS: -Zcodegen-backend=cranelift run: cargo +nightly nextest run --all --verbose --fail-fast From 83c4ef22716bf826202c273b415006c64366e646 Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Thu, 28 Mar 2024 19:24:43 -0700 Subject: [PATCH 4/8] test(ci): menial change to test ci caching --- crates/snot-cli/src/commands/env.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/snot-cli/src/commands/env.rs b/crates/snot-cli/src/commands/env.rs index 9507c9e2..6e409afe 100644 --- a/crates/snot-cli/src/commands/env.rs +++ b/crates/snot-cli/src/commands/env.rs @@ -39,6 +39,7 @@ enum Commands { impl Env { pub fn run(self) -> Result<()> { let client = reqwest::blocking::Client::new(); + println!("testing caching"); use Commands::*; match self.command { From 2d23b5cd98621d12e7159d72fece30ce1957bc3a Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Thu, 28 Mar 2024 20:14:36 -0700 Subject: [PATCH 5/8] fix(snot-cli): fix errors not printing --- crates/snot-cli/src/commands/env.rs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/crates/snot-cli/src/commands/env.rs b/crates/snot-cli/src/commands/env.rs index 6e409afe..360f9b54 100644 --- a/crates/snot-cli/src/commands/env.rs +++ b/crates/snot-cli/src/commands/env.rs @@ -39,32 +39,36 @@ enum Commands { impl Env { pub fn run(self) -> Result<()> { let client = reqwest::blocking::Client::new(); - println!("testing caching"); use Commands::*; - match self.command { + let response = match self.command { Prepare { spec } => { let ep = format!("{}/api/v1/env/prepare", self.url); let file: String = std::fs::read_to_string(spec)?; - let id: Value = client.post(&ep).body(file).send()?.json()?; - println!("{}", serde_json::to_string(&id)?); - Ok(()) + client.post(ep).body(file).send()? } Start { id } => { let ep = format!("{}/api/v1/env/{id}", self.url); - client.post(&ep).send()?; - Ok(()) + client.post(ep).send()? } Stop { id } => { let ep = format!("{}/api/v1/env/{id}", self.url); - client.delete(&ep).send()?; - Ok(()) + client.delete(ep).send()? } - } + }; + + let value = match response.content_length() { + Some(0) | None => None, + _ => response.json::().map(Some)?, + }; + + println!("{}", serde_json::to_string_pretty(&value)?); + + Ok(()) } } From c4dff88c41bba0bd6fb01c8d0926a9e2a429c3dd Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Thu, 28 Mar 2024 21:28:29 -0700 Subject: [PATCH 6/8] feat(snot): request logging details --- crates/snot/src/logging.rs | 93 +++++++++++++++++++++++++++++++++++ crates/snot/src/main.rs | 6 ++- crates/snot/src/server/mod.rs | 30 ++++++----- 3 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 crates/snot/src/logging.rs diff --git a/crates/snot/src/logging.rs b/crates/snot/src/logging.rs new file mode 100644 index 00000000..cbf8373d --- /dev/null +++ b/crates/snot/src/logging.rs @@ -0,0 +1,93 @@ +use axum::{ + async_trait, + extract::{FromRequestParts, Request}, + http::{request::Parts, Method, StatusCode, Uri}, + middleware::Next, + response::Response, +}; +use chrono::{DateTime, Utc}; +use serde::Serialize; +use serde_json::{json, Value}; +use tracing::debug; +use uuid::Uuid; + +#[derive(Debug, Clone)] +pub struct ReqStamp { + pub uuid: Uuid, + pub time_in: DateTime, +} + +pub async fn req_stamp(mut req: Request, next: Next) -> Response { + let time_in = Utc::now(); + let uuid = Uuid::new_v4(); + + req.extensions_mut().insert(ReqStamp { uuid, time_in }); + + next.run(req).await +} + +#[async_trait] +impl FromRequestParts for ReqStamp { + // TODO replace with our own error type that implements IntoResponse + type Rejection = StatusCode; + + async fn from_request_parts( + parts: &mut Parts, + _state: &S, + ) -> core::result::Result { + parts + .extensions + .get::() + .cloned() + .ok_or(StatusCode::INTERNAL_SERVER_ERROR) + } +} + +#[derive(Serialize)] +struct RequestLogLine { + /// Unique request identifier. + uuid: String, + /// Timestamp(rfc3339) of the log line. + timestamp: String, + /// Timestamp(rfc3339) of the request. + time_in: String, + /// Duration of the request in milliseconds. + duration_ms: i64, + + /// HTTP path of the request. + http_path: String, + /// HTTP method of the request. + http_method: String, + + // TODO: error handling + /// The error variant. + error_type: Option, + /// The error data. + error_data: Option, +} + +pub async fn log_request(uri: Uri, method: Method, req_stamp: ReqStamp, res: Response) -> Response { + // TODO: grab error data from response + // something like: + // res.extensions_mut().get::(); + + let ReqStamp { uuid, time_in } = req_stamp; + let now = Utc::now(); + let duration = now - time_in; + + let log_line = RequestLogLine { + uuid: uuid.to_string(), + timestamp: now.to_rfc3339(), + time_in: time_in.to_rfc3339(), + duration_ms: duration.num_milliseconds(), + http_path: uri.to_string(), + http_method: method.to_string(), + error_type: None, + error_data: None, + }; + + // TODO: send to logging services + debug!("REQUEST LOG LINE:\n{}", json!(log_line)); + + res +} diff --git a/crates/snot/src/main.rs b/crates/snot/src/main.rs index 924c6de7..26731f57 100644 --- a/crates/snot/src/main.rs +++ b/crates/snot/src/main.rs @@ -8,6 +8,7 @@ use tracing_subscriber::prelude::*; pub mod cannon; pub mod cli; pub mod env; +pub mod logging; pub mod schema; pub mod server; pub mod state; @@ -21,7 +22,8 @@ async fn main() { }; let env_filter = env_filter - .parse_lossy("") + .with_env_var("SNOT_LOG") + .from_env_lossy() .add_directive("surrealdb_core=off".parse().unwrap()) .add_directive("surrealdb=off".parse().unwrap()) .add_directive("tungstenite=off".parse().unwrap()) @@ -31,6 +33,8 @@ async fn main() { .add_directive("tower_http::trace::on_request=off".parse().unwrap()) .add_directive("tower_http::trace::on_response=off".parse().unwrap()); + dbg!(env_filter.to_string()); + let (stdout, _guard) = tracing_appender::non_blocking(io::stdout()); let output = tracing_subscriber::fmt::layer().with_writer(stdout); diff --git a/crates/snot/src/server/mod.rs b/crates/snot/src/server/mod.rs index 96c4c308..fcd00c7a 100644 --- a/crates/snot/src/server/mod.rs +++ b/crates/snot/src/server/mod.rs @@ -8,6 +8,7 @@ use axum::{ State, WebSocketUpgrade, }, http::HeaderMap, + middleware, response::IntoResponse, routing::get, Router, @@ -20,7 +21,6 @@ use snot_common::{ use surrealdb::Surreal; use tarpc::server::Channel; use tokio::select; -use tower_http::trace::{DefaultMakeSpan, TraceLayer}; use tracing::{info, warn}; use self::{ @@ -29,6 +29,7 @@ use self::{ }; use crate::{ cli::Cli, + logging::{log_request, req_stamp}, server::rpc::{MuxedMessageIncoming, MuxedMessageOutgoing}, state::{Agent, AppState, GlobalState}, }; @@ -57,16 +58,19 @@ pub async fn start(cli: Cli) -> Result<()> { // /env//ledger/* - ledger query service reverse proxying /mainnet/latest/stateRoot .nest("/content", content::init_routes(&state).await) .with_state(Arc::new(state)) - .layer( - TraceLayer::new_for_http().make_span_with(DefaultMakeSpan::new().include_headers(true)), - //.on_request(|request: &Request, _span: &Span| { - // tracing::info!("req {} - {}", request.method(), request.uri()); - //}) - //.on_response(|response: &Response, _latency: Duration, span: &Span| { - // span.record("status_code", &tracing::field::display(response.status())); - // tracing::info!("res {}", response.status()) - //}), - ); + .layer(middleware::map_response(log_request)) + .layer(middleware::from_fn(req_stamp)); + // .layer( + // TraceLayer::new_for_http().make_span_with(DefaultMakeSpan::new(). + // include_headers(true)), + //.on_request(|request: &Request, _span: &Span| { + // tracing::info!("req {} - {}", request.method(), request.uri()); + //}) + //.on_response(|response: &Response, _latency: Duration, span: &Span| { + // span.record("status_code", &tracing::field::display(response.status())); + // tracing::info!("res {}", response.status()) + //}), + // ); let listener = tokio::net::TcpListener::bind("0.0.0.0:1234").await?; axum::serve(listener, app).await?; @@ -225,7 +229,7 @@ async fn handle_socket(mut socket: WebSocket, headers: HeaderMap, state: AppStat msg = client_request_out.recv() => { let msg = msg.expect("internal RPC channel closed"); let bin = bincode::serialize(&MuxedMessageOutgoing::Agent(msg)).expect("failed to serialize request"); - if let Err(_) = socket.send(Message::Binary(bin)).await { + if (socket.send(Message::Binary(bin)).await).is_err() { break; } } @@ -234,7 +238,7 @@ async fn handle_socket(mut socket: WebSocket, headers: HeaderMap, state: AppStat msg = server_response_out.recv() => { let msg = msg.expect("internal RPC channel closed"); let bin = bincode::serialize(&MuxedMessageOutgoing::Control(msg)).expect("failed to serialize response"); - if let Err(_) = socket.send(Message::Binary(bin)).await { + if (socket.send(Message::Binary(bin)).await).is_err() { break; } } From 9ccf2e5c94638ead8a3563a25f22904d74e7007d Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Thu, 28 Mar 2024 21:28:54 -0700 Subject: [PATCH 7/8] fix(snot): clippy warnings --- Cargo.lock | 3 +++ Cargo.toml | 2 ++ crates/snot/Cargo.toml | 2 ++ crates/snot/src/env/mod.rs | 13 ++++--------- crates/snot/src/env/timeline.rs | 10 +++------- crates/snot/src/state.rs | 4 +--- 6 files changed, 15 insertions(+), 19 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4975a693..3090a073 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5350,6 +5350,7 @@ dependencies = [ "axum", "bimap", "bincode", + "chrono", "clap", "duration-str", "futures-util", @@ -5376,6 +5377,7 @@ dependencies = [ "tracing-appender", "tracing-subscriber", "url", + "uuid", "wildmatch 2.3.3", ] @@ -6439,6 +6441,7 @@ checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" dependencies = [ "atomic", "getrandom", + "rand", "serde", "wasm-bindgen", ] diff --git a/Cargo.toml b/Cargo.toml index a33bb326..153b8905 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ axum = "0.7.5" anyhow = "1" bimap = "0.6" bincode = "1.3" +chrono = "0.4" clap = { version = "4.5", features = ["derive"] } colored = "2" futures = "0.3" @@ -39,6 +40,7 @@ tracing = "0.1" tracing-appender = "0.2" tracing-subscriber = { version = "0.3", features = ["env-filter"] } url = "2.5" +uuid = "1.8" nix = { version = "0.28", features = ["process"] } snarkos-account = { path = "../snarkos/account" } diff --git a/crates/snot/Cargo.toml b/crates/snot/Cargo.toml index 92ad4769..2c1e25f6 100644 --- a/crates/snot/Cargo.toml +++ b/crates/snot/Cargo.toml @@ -8,6 +8,7 @@ anyhow.workspace = true axum = { workspace = true, features = ["ws"] } bimap.workspace = true bincode.workspace = true +chrono = { workspace = true, features = ["serde"] } clap.workspace = true duration-str = { version = "0.7", default-features = false } futures-util.workspace = true @@ -36,4 +37,5 @@ tracing-appender.workspace = true tracing.workspace = true tracing-subscriber.workspace = true url = { workspace = true, features = ["serde"] } +uuid = { workspace = true, features = ["v4", "fast-rng"] } wildmatch = "2.3.3" diff --git a/crates/snot/src/env/mod.rs b/crates/snot/src/env/mod.rs index 19145021..4ee99e08 100644 --- a/crates/snot/src/env/mod.rs +++ b/crates/snot/src/env/mod.rs @@ -319,9 +319,7 @@ impl Environment { .filter(|(key, _)| targets.matches(key)) .filter_map(move |(key, value)| match value { EnvPeer::Internal(id) => { - let Some(agent) = pool.get(id) else { - return None; - }; + let agent = pool.get(id)?; Some(AgentPeer::Internal( *id, @@ -390,18 +388,15 @@ pub async fn initial_reconcile(env_id: usize, state: &GlobalState) -> anyhow::Re .as_ref() .and_then(|key| env.storage.lookup_keysource_pk(key)); - let not_me = |agent: &AgentPeer| match agent { - AgentPeer::Internal(candidate_id, _) if *candidate_id == id => false, - _ => true, - }; + let not_me = |agent: &AgentPeer| !matches!(agent, AgentPeer::Internal(candidate_id, _) if *candidate_id == id); node_state.peers = env - .matching_nodes(&node.peers, &*pool_lock, false) + .matching_nodes(&node.peers, &pool_lock, false) .filter(not_me) .collect(); node_state.validators = env - .matching_nodes(&node.validators, &*pool_lock, true) + .matching_nodes(&node.validators, &pool_lock, true) .filter(not_me) .collect(); diff --git a/crates/snot/src/env/timeline.rs b/crates/snot/src/env/timeline.rs index 7685a1de..2ba7bd31 100644 --- a/crates/snot/src/env/timeline.rs +++ b/crates/snot/src/env/timeline.rs @@ -43,7 +43,7 @@ pub async fn reconcile_agents( where I: Iterator, { - use tracing::{info, warn}; + use tracing::warn; let mut handles = vec![]; let mut agent_ids = vec![]; @@ -180,7 +180,7 @@ impl Environment { let online = matches!(action, Action::Online(_)); - for agent in env.matching_agents(targets, &*pool) { + for agent in env.matching_agents(targets, &pool) { set_node_field!(agent, online = online); } } @@ -194,11 +194,7 @@ impl Environment { let task_state = Arc::clone(&state); let reconcile_handle = tokio::spawn(async move { - reconcile_agents( - pending_reconciliations.into_iter().map(|(_, v)| v), - &task_state.pool, - ) - .await + reconcile_agents(pending_reconciliations.into_values(), &task_state.pool).await }); // await the reconciliation if any of the actions were `.await` diff --git a/crates/snot/src/state.rs b/crates/snot/src/state.rs index a8dc6947..104ea808 100644 --- a/crates/snot/src/state.rs +++ b/crates/snot/src/state.rs @@ -238,9 +238,7 @@ pub fn resolve_addrs( } // if the agent has no addresses, skip it - let Some(addrs) = addr_map.get(id) else { - return None; - }; + let addrs = addr_map.get(id)?; // if there are no external addresses in the entire addr map, // use the first internal address From 3cacd945d3c7c18445f244589e7e0cead27248f7 Mon Sep 17 00:00:00 2001 From: gluax <16431709+gluax@users.noreply.github.com> Date: Thu, 28 Mar 2024 21:30:48 -0700 Subject: [PATCH 8/8] fix(agent): fix log var, fix clippy --- crates/snot-agent/src/main.rs | 8 ++++---- crates/snot-agent/src/metrics/mod.rs | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/snot-agent/src/main.rs b/crates/snot-agent/src/main.rs index 8c40a7b2..61e74b33 100644 --- a/crates/snot-agent/src/main.rs +++ b/crates/snot-agent/src/main.rs @@ -57,9 +57,9 @@ async fn main() { tracing_subscriber::registry() .with( tracing_subscriber::EnvFilter::builder() - .with_env_var("RUST_LOG") + .with_env_var("SNOT_AGENT_LOG") .with_default_directive(LevelFilter::TRACE.into()) - .parse_lossy("") + .from_env_lossy() .add_directive("neli=off".parse().unwrap()) .add_directive("hyper_util=off".parse().unwrap()) .add_directive("reqwest=off".parse().unwrap()) @@ -208,7 +208,7 @@ async fn main() { msg = server_response_out.recv() => { let msg = msg.expect("internal RPC channel closed"); let bin = bincode::serialize(&MuxedMessageOutgoing::Agent(msg)).expect("failed to serialize response"); - if let Err(_) = ws_stream.send(tungstenite::Message::Binary(bin)).await { + if (ws_stream.send(tungstenite::Message::Binary(bin)).await).is_err() { error!("The connection to the control plane was interrupted"); break 'event; } @@ -218,7 +218,7 @@ async fn main() { msg = client_request_out.recv() => { let msg = msg.expect("internal RPC channel closed"); let bin = bincode::serialize(&MuxedMessageOutgoing::Control(msg)).expect("failed to serialize request"); - if let Err(_) = ws_stream.send(tungstenite::Message::Binary(bin)).await { + if (ws_stream.send(tungstenite::Message::Binary(bin)).await).is_err() { error!("The connection to the control plane was interrupted"); break 'event; } diff --git a/crates/snot-agent/src/metrics/mod.rs b/crates/snot-agent/src/metrics/mod.rs index b6c119ee..b25f3065 100644 --- a/crates/snot-agent/src/metrics/mod.rs +++ b/crates/snot-agent/src/metrics/mod.rs @@ -67,7 +67,7 @@ pub fn init(state: Arc) { } /// Parse the metrics blob when scraping the snarkOS Prometheus exporter. -fn parse_metrics<'a>(source: &'a str) -> ParsedMetrics<'a> { +fn parse_metrics(source: &str) -> ParsedMetrics<'_> { source .split('\n') .map(str::trim)