From 48dc40eb51ac57fc6d2404183574b8c86d972d7a Mon Sep 17 00:00:00 2001 From: erhant Date: Tue, 1 Oct 2024 14:26:57 +0300 Subject: [PATCH 01/15] uses `eyre` now for errors --- .github/workflows/build_dev_container.yml | 10 +- Cargo.lock | 17 ++++ Cargo.toml | 4 +- src/config/models.rs | 19 ++-- src/errors/mod.rs | 115 ---------------------- src/handlers/mod.rs | 4 +- src/handlers/pingpong.rs | 7 +- src/handlers/workflow.rs | 8 +- src/lib.rs | 1 - src/node.rs | 16 +-- src/p2p/message.rs | 29 +++--- src/utils/payload.rs | 10 +- 12 files changed, 70 insertions(+), 170 deletions(-) delete mode 100644 src/errors/mod.rs diff --git a/.github/workflows/build_dev_container.yml b/.github/workflows/build_dev_container.yml index ebbc8d4..b0290d0 100644 --- a/.github/workflows/build_dev_container.yml +++ b/.github/workflows/build_dev_container.yml @@ -3,11 +3,11 @@ on: push: branches: ["master"] paths: - - 'src/**' - - 'Cargo.lock' - - 'Cargo.toml' - - 'Dockerfile' - - 'compose.yml' + - "src/**" + - "Cargo.lock" + - "Cargo.toml" + - "Dockerfile" + - "compose.yml" jobs: build-and-push: diff --git a/Cargo.lock b/Cargo.lock index e66b588..aa5b7f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1043,6 +1043,7 @@ dependencies = [ "dotenvy", "ecies", "env_logger 0.11.5", + "eyre", "fastbloom-rs", "hex", "hex-literal", @@ -1255,6 +1256,16 @@ dependencies = [ "pin-project-lite 0.2.14", ] +[[package]] +name = "eyre" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" +dependencies = [ + "indenter", + "once_cell", +] + [[package]] name = "fancy-regex" version = "0.12.0" @@ -2195,6 +2206,12 @@ dependencies = [ "xmltree", ] +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + [[package]] name = "indexmap" version = "1.9.3" diff --git a/Cargo.toml b/Cargo.toml index 1e2586e..8992c82 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,9 +33,10 @@ urlencoding = "2.1.3" uuid = { version = "1.8.0", features = ["v4"] } rand = "0.8.5" -# logging +# logging & errors env_logger = "0.11.3" log = "0.4.21" +eyre = "0.6.12" # encryption (ecies) & signatures (ecdsa) & hashing & bloom-filters ecies = { version = "0.2", default-features = false, features = ["pure"] } @@ -69,6 +70,7 @@ libp2p-identity = { version = "0.2.9", features = ["secp256k1"] } tracing = { version = "0.1.40" } tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } + [dependencies.openssl] version = "*" features = ["vendored"] diff --git a/src/config/models.rs b/src/config/models.rs index a871bf2..943a8dc 100644 --- a/src/config/models.rs +++ b/src/config/models.rs @@ -1,4 +1,5 @@ use crate::utils::split_comma_separated; +use eyre::{eyre, Result}; use ollama_workflows::{Model, ModelProvider}; use rand::seq::IteratorRandom; // provides Vec<_>.choose @@ -58,27 +59,27 @@ impl ModelConfig { /// If this is a provider, the first matching model in the node config is returned. /// /// If there are no matching models with this logic, an error is returned. - pub fn get_matching_model( - &self, - model_or_provider: String, - ) -> Result<(ModelProvider, Model), String> { + pub fn get_matching_model(&self, model_or_provider: String) -> Result<(ModelProvider, Model)> { if let Ok(provider) = ModelProvider::try_from(model_or_provider.clone()) { // this is a valid provider, return the first matching model in the config self.models .iter() .find(|(p, _)| *p == provider) - .ok_or_else(|| format!("Provider {} is not supported by this node.", provider)) + .ok_or(eyre!( + "Provider {} is not supported by this node.", + provider + )) .cloned() } else if let Ok(model) = Model::try_from(model_or_provider.clone()) { // this is a valid model, return it if it is supported by the node self.models .iter() .find(|(_, m)| *m == model) - .ok_or_else(|| format!("Model {} is not supported by this node.", model)) + .ok_or(eyre!("Model {} is not supported by this node.", model)) .cloned() } else { // this is neither a valid provider or model for this node - Err(format!( + Err(eyre!( "Given string '{}' is neither a model nor provider.", model_or_provider )) @@ -89,7 +90,7 @@ impl ModelConfig { pub fn get_any_matching_model( &self, list_model_or_provider: Vec, - ) -> Result<(ModelProvider, Model), String> { + ) -> Result<(ModelProvider, Model)> { // filter models w.r.t supported ones let matching_models = list_model_or_provider .into_iter() @@ -109,7 +110,7 @@ impl ModelConfig { matching_models .into_iter() .choose(&mut rand::thread_rng()) - .ok_or_else(|| "No matching models found.".to_string()) + .ok_or(eyre!("No matching models found.")) } /// Returns the list of unique providers in the config. diff --git a/src/errors/mod.rs b/src/errors/mod.rs deleted file mode 100644 index 64d8578..0000000 --- a/src/errors/mod.rs +++ /dev/null @@ -1,115 +0,0 @@ -use ollama_workflows::ollama_rs::error::OllamaError; - -/// Alias for `Result`. -pub type NodeResult = std::result::Result; - -#[derive(serde::Deserialize)] -pub struct NodeError { - #[serde(rename = "error")] - pub message: String, - pub source: String, -} - -impl std::fmt::Display for NodeError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self) // use same as Debug - } -} - -impl std::fmt::Debug for NodeError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{} error: {}", self.source, self.message) - } -} - -impl std::error::Error for NodeError {} - -impl From for NodeError { - fn from(message: String) -> Self { - Self { - message, - source: "self".to_string(), - } - } -} - -impl From<&str> for NodeError { - fn from(message: &str) -> Self { - Self { - message: message.to_string(), - source: "self".to_string(), - } - } -} - -impl From for NodeError { - fn from(value: OllamaError) -> Self { - Self { - message: value.to_string(), - source: "ollama-rs".to_string(), - } - } -} - -impl From for NodeError { - fn from(value: serde_json::Error) -> Self { - Self { - message: value.to_string(), - source: "serde_json".to_string(), - } - } -} - -impl From for NodeError { - fn from(value: base64::DecodeError) -> Self { - Self { - message: value.to_string(), - source: "base64".to_string(), - } - } -} - -impl From for NodeError { - fn from(value: hex::FromHexError) -> Self { - Self { - message: value.to_string(), - source: "hex".to_string(), - } - } -} - -impl From for NodeError { - fn from(value: libsecp256k1::Error) -> Self { - Self { - message: value.to_string(), - source: "secp256k1".to_string(), - } - } -} - -impl From for NodeError { - fn from(value: libp2p::gossipsub::SubscriptionError) -> Self { - Self { - message: value.to_string(), - source: "gossipsub::subscription".to_string(), - } - } -} - -impl From for NodeError { - fn from(value: reqwest::Error) -> Self { - Self { - message: value.to_string(), - source: "reqwest".to_string(), - } - } -} - -impl From for NodeError { - fn from(value: libp2p::gossipsub::PublishError) -> Self { - Self { - message: value.to_string(), - source: "gossipsub::publish".to_string(), - } - } -} diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 8b1a926..0521dee 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -7,7 +7,7 @@ pub use pingpong::PingpongHandler; mod workflow; pub use workflow::WorkflowHandler; -use crate::{errors::NodeResult, p2p::P2PMessage, DriaComputeNode}; +use crate::{p2p::P2PMessage, DriaComputeNode}; #[async_trait] pub trait ComputeHandler { @@ -15,5 +15,5 @@ pub trait ComputeHandler { node: &mut DriaComputeNode, message: P2PMessage, result_topic: &str, - ) -> NodeResult; + ) -> eyre::Result; } diff --git a/src/handlers/pingpong.rs b/src/handlers/pingpong.rs index 2b32537..78c58e1 100644 --- a/src/handlers/pingpong.rs +++ b/src/handlers/pingpong.rs @@ -1,7 +1,6 @@ -use crate::{ - errors::NodeResult, node::DriaComputeNode, p2p::P2PMessage, utils::get_current_time_nanos, -}; +use crate::{node::DriaComputeNode, p2p::P2PMessage, utils::get_current_time_nanos}; use async_trait::async_trait; +use eyre::Result; use libp2p::gossipsub::MessageAcceptance; use ollama_workflows::{Model, ModelProvider}; use serde::{Deserialize, Serialize}; @@ -29,7 +28,7 @@ impl ComputeHandler for PingpongHandler { node: &mut DriaComputeNode, message: P2PMessage, result_topic: &str, - ) -> NodeResult { + ) -> Result { let pingpong = message.parse_payload::(true)?; // check deadline diff --git a/src/handlers/workflow.rs b/src/handlers/workflow.rs index 26555af..e983651 100644 --- a/src/handlers/workflow.rs +++ b/src/handlers/workflow.rs @@ -1,9 +1,9 @@ use async_trait::async_trait; +use eyre::{eyre, Result}; use libp2p::gossipsub::MessageAcceptance; use ollama_workflows::{Entry, Executor, ModelProvider, ProgramMemory, Workflow}; use serde::Deserialize; -use crate::errors::NodeResult; use crate::node::DriaComputeNode; use crate::p2p::P2PMessage; use crate::utils::get_current_time_nanos; @@ -32,7 +32,7 @@ impl ComputeHandler for WorkflowHandler { node: &mut DriaComputeNode, message: P2PMessage, result_topic: &str, - ) -> NodeResult { + ) -> Result { let task = message.parse_payload::>(true)?; // check if deadline is past or not @@ -102,10 +102,10 @@ impl ComputeHandler for WorkflowHandler { exec_result = executor.execute(entry.as_ref(), task.input.workflow, &mut memory) => { match exec_result { Ok(exec_result) => { - result = exec_result; + result = exec_result; } Err(e) => { - return Err(format!("Workflow failed with error {}", e).into()); + return Err(eyre!("Workflow failed with error {}", e)); } } } diff --git a/src/lib.rs b/src/lib.rs index 41b3a55..bfff81a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,7 +2,6 @@ // TODO: this line breaks docker, find a way to ignore during compose? pub(crate) mod config; -pub(crate) mod errors; pub(crate) mod handlers; pub(crate) mod node; pub(crate) mod p2p; diff --git a/src/node.rs b/src/node.rs index 70020a8..385c6e7 100644 --- a/src/node.rs +++ b/src/node.rs @@ -1,10 +1,10 @@ +use eyre::{eyre, Result}; use libp2p::{gossipsub, Multiaddr}; use std::{str::FromStr, time::Duration}; use tokio_util::sync::CancellationToken; use crate::{ config::DriaComputeNodeConfig, - errors::NodeResult, handlers::{ComputeHandler, PingpongHandler, WorkflowHandler}, p2p::{P2PClient, P2PMessage}, utils::{crypto::secret_to_keypair, AvailableNodes}, @@ -66,7 +66,7 @@ impl DriaComputeNode { } /// Subscribe to a certain task with its topic. - pub fn subscribe(&mut self, topic: &str) -> NodeResult<()> { + pub fn subscribe(&mut self, topic: &str) -> Result<()> { let ok = self.p2p.subscribe(topic)?; if ok { log::info!("Subscribed to {}", topic); @@ -77,7 +77,7 @@ impl DriaComputeNode { } /// Unsubscribe from a certain task with its topic. - pub fn unsubscribe(&mut self, topic: &str) -> NodeResult<()> { + pub fn unsubscribe(&mut self, topic: &str) -> Result<()> { let ok = self.p2p.unsubscribe(topic)?; if ok { log::info!("Unsubscribed from {}", topic); @@ -89,7 +89,7 @@ impl DriaComputeNode { /// Publishes a given message to the network. /// The topic is expected to be provided within the message struct. - pub fn publish(&mut self, message: P2PMessage) -> NodeResult<()> { + pub fn publish(&mut self, message: P2PMessage) -> Result<()> { let message_bytes = message.payload.as_bytes().to_vec(); let message_id = self.p2p.publish(&message.topic, message_bytes)?; log::info!("Published message ({}) to {}", message_id, message.topic); @@ -103,7 +103,7 @@ impl DriaComputeNode { /// Launches the main loop of the compute node. /// This method is not expected to return until cancellation occurs. - pub async fn launch(&mut self) -> NodeResult<()> { + pub async fn launch(&mut self) -> Result<()> { const PINGPONG_LISTEN_TOPIC: &str = "ping"; const PINGPONG_RESPONSE_TOPIC: &str = "pong"; const WORKFLOW_LISTEN_TOPIC: &str = "task"; @@ -228,7 +228,7 @@ impl DriaComputeNode { pub fn parse_message_to_prepared_message( &self, message: gossipsub::Message, - ) -> NodeResult { + ) -> Result { // the received message is expected to use IdentHash for the topic, so we can see the name of the topic immediately. log::debug!("Parsing {} message.", message.topic.as_str()); let message = P2PMessage::try_from(message)?; @@ -237,7 +237,7 @@ impl DriaComputeNode { // check dria signature // NOTE: when we have many public keys, we should check the signature against all of them if !message.is_signed(&self.config.admin_public_key)? { - return Err("Invalid signature.".into()); + return Err(eyre!("Invalid signature.")); } Ok(message) @@ -250,7 +250,7 @@ impl DriaComputeNode { public_key: &[u8], task_id: &str, result: R, - ) -> NodeResult<()> { + ) -> Result<()> { let payload = P2PMessage::new_signed_encrypted_payload( result.as_ref(), task_id, diff --git a/src/p2p/message.rs b/src/p2p/message.rs index 47f3f42..336b081 100644 --- a/src/p2p/message.rs +++ b/src/p2p/message.rs @@ -1,15 +1,13 @@ -use crate::{ - errors::NodeResult, - utils::{ - crypto::{sha256hash, sign_bytes_recoverable}, - get_current_time_nanos, - payload::TaskResponsePayload, - }, +use crate::utils::{ + crypto::{sha256hash, sign_bytes_recoverable}, + get_current_time_nanos, + payload::TaskResponsePayload, }; use base64::{prelude::BASE64_STANDARD, Engine}; use core::fmt; use ecies::PublicKey; +use eyre::Result; use libsecp256k1::SecretKey; use serde::{Deserialize, Serialize}; @@ -73,7 +71,7 @@ impl P2PMessage { task_id: &str, encrypting_public_key: &[u8], signing_secret_key: &SecretKey, - ) -> NodeResult { + ) -> Result { // sign payload let mut preimage = Vec::new(); preimage.extend_from_slice(task_id.as_ref()); @@ -100,7 +98,7 @@ impl P2PMessage { } /// Decodes and parses the payload into JSON. - pub fn parse_payload Deserialize<'a>>(&self, signed: bool) -> NodeResult { + pub fn parse_payload Deserialize<'a>>(&self, signed: bool) -> Result { let payload = self.decode_payload()?; let body = if signed { @@ -115,18 +113,19 @@ impl P2PMessage { } /// Checks if the payload is signed by the given public key. - pub fn is_signed(&self, public_key: &PublicKey) -> NodeResult { + pub fn is_signed(&self, public_key: &PublicKey) -> Result { // decode base64 payload let payload = self.decode_payload()?; - // parse signature (64 bytes = 128 hex chars, although the full 65-byte RSV signature is given) - let (signature, body) = ( + // parse signature (64 bytes = 32 (x coord) + 32 (y coord)) + // skip the recovery id (1 byte) + let (signature_hex, body) = ( &payload[..SIGNATURE_SIZE_HEX - 2], &payload[SIGNATURE_SIZE_HEX..], ); - let signature = hex::decode(signature).expect("could not decode"); - let signature = - libsecp256k1::Signature::parse_standard_slice(&signature).expect("could not parse"); + let signature_bytes = hex::decode(signature_hex).expect("could not decode"); + let signature = libsecp256k1::Signature::parse_standard_slice(&signature_bytes) + .expect("could not parse"); // verify signature let digest = libsecp256k1::Message::parse(&sha256hash(body)); diff --git a/src/utils/payload.rs b/src/utils/payload.rs index c7088fb..3795e69 100644 --- a/src/utils/payload.rs +++ b/src/utils/payload.rs @@ -1,11 +1,9 @@ +use eyre::Result; use fastbloom_rs::BloomFilter; use serde::{Deserialize, Serialize}; use uuid::Uuid; -use crate::{ - errors::NodeResult, - utils::{filter::FilterPayload, get_current_time_nanos}, -}; +use crate::utils::{filter::FilterPayload, get_current_time_nanos}; /// A computation task is the task of computing a result from a given input. The result is encrypted with the public key of the requester. /// Plain result is signed by the compute node's private key, and a commitment is computed from the signature and plain result. @@ -26,8 +24,8 @@ pub struct TaskResponsePayload { } impl TaskResponsePayload { - pub fn to_string(&self) -> NodeResult { - serde_json::to_string(&serde_json::json!(self)).map_err(|e| e.into()) + pub fn to_string(&self) -> Result { + serde_json::to_string(&serde_json::json!(self)).map_err(Into::into) } } From a9389968bbc3e1989090fbc7006fbe7434e7b61d Mon Sep 17 00:00:00 2001 From: erhant Date: Tue, 1 Oct 2024 18:13:03 +0300 Subject: [PATCH 02/15] more eyre'ing, slight folder restructures --- src/config/mod.rs | 5 +++-- src/config/ollama.rs | 14 ++++++-------- src/config/openai.rs | 20 ++++++++------------ src/handlers/mod.rs | 5 +++-- src/handlers/pingpong.rs | 7 +++++-- src/handlers/workflow.rs | 3 +-- src/main.rs | 3 ++- src/node.rs | 12 +++++------- src/p2p/client.rs | 32 ++++++++++++++------------------ src/p2p/mod.rs | 4 ---- src/utils/available_nodes.rs | 14 +++++++------- src/utils/crypto.rs | 4 ++-- src/utils/filter.rs | 7 +++++-- src/{p2p => utils}/message.rs | 2 +- src/utils/mod.rs | 3 +++ 15 files changed, 65 insertions(+), 70 deletions(-) rename src/{p2p => utils}/message.rs (99%) diff --git a/src/config/mod.rs b/src/config/mod.rs index 5c90b91..3fa8e89 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -3,6 +3,7 @@ mod ollama; mod openai; use crate::utils::crypto::to_address; +use eyre::{eyre, Result}; use libsecp256k1::{PublicKey, SecretKey}; use models::ModelConfig; use ollama::OllamaConfig; @@ -129,7 +130,7 @@ impl DriaComputeNodeConfig { /// If both type of models are used, both services are checked. /// In the end, bad models are filtered out and we simply check if we are left if any valid models at all. /// If not, an error is returned. - pub async fn check_services(&mut self) -> Result<(), String> { + pub async fn check_services(&mut self) -> Result<()> { log::info!("Checking configured services."); // TODO: can refactor (provider, model) logic here @@ -171,7 +172,7 @@ impl DriaComputeNodeConfig { // update good models if good_models.is_empty() { - Err("No good models found, please check logs for errors.".into()) + Err(eyre!("No good models found, please check logs for errors.")) } else { self.model_config.models = good_models; Ok(()) diff --git a/src/config/ollama.rs b/src/config/ollama.rs index bc43944..425b53d 100644 --- a/src/config/ollama.rs +++ b/src/config/ollama.rs @@ -1,5 +1,6 @@ use std::time::Duration; +use eyre::{eyre, Result}; use ollama_workflows::{ ollama_rs::{ generation::{ @@ -81,7 +82,7 @@ impl OllamaConfig { external_models: Vec, timeout: Duration, min_tps: f64, - ) -> Result, String> { + ) -> Result> { log::info!( "Checking Ollama requirements (auto-pull {}, workflow timeout: {}s)", if self.auto_pull { "on" } else { "off" }, @@ -96,7 +97,7 @@ impl OllamaConfig { Err(e) => { return { log::error!("Could not fetch local models from Ollama, is it online?"); - Err(e.to_string()) + Err(e.into()) } } }; @@ -137,7 +138,7 @@ impl OllamaConfig { } /// Pulls a model if `auto_pull` exists, otherwise returns an error. - async fn try_pull(&self, ollama: &Ollama, model: String) -> Result<(), String> { + async fn try_pull(&self, ollama: &Ollama, model: String) -> Result<()> { log::warn!("Model {} not found in Ollama", model); if self.auto_pull { // if auto-pull is enabled, pull the model @@ -145,17 +146,14 @@ impl OllamaConfig { "Downloading missing model {} (this may take a while)", model ); - let status = ollama - .pull_model(model, false) - .await - .map_err(|e| format!("Error pulling model with Ollama: {}", e))?; + let status = ollama.pull_model(model, false).await?; log::debug!("Pulled model with Ollama, final status: {:#?}", status); Ok(()) } else { // otherwise, give error log::error!("Please download missing model with: ollama pull {}", model); log::error!("Or, set OLLAMA_AUTO_PULL=true to pull automatically."); - Err("Required model not pulled in Ollama.".into()) + Err(eyre!("Required model not pulled in Ollama.")) } } diff --git a/src/config/openai.rs b/src/config/openai.rs index a193dc3..a29819e 100644 --- a/src/config/openai.rs +++ b/src/config/openai.rs @@ -1,5 +1,6 @@ #![allow(unused)] +use eyre::{eyre, Context, Result}; use ollama_workflows::Model; use serde::Deserialize; @@ -39,15 +40,13 @@ impl OpenAIConfig { Self { api_key } } - /// Check if requested models exist & - /// - /// - pub async fn check(&self, models: Vec) -> Result, String> { + /// Check if requested models exist & are available in the OpenAI account. + pub async fn check(&self, models: Vec) -> Result> { log::info!("Checking OpenAI requirements"); // check API key let Some(api_key) = &self.api_key else { - return Err("OpenAI API key not found".into()); + return Err(eyre!("OpenAI API key not found")); }; // fetch models @@ -56,24 +55,21 @@ impl OpenAIConfig { .get(OPENAI_MODELS_API) .header("Authorization", format!("Bearer {}", api_key)) .build() - .map_err(|e| format!("Failed to build request: {}", e))?; + .wrap_err("Failed to build request")?; let response = client .execute(request) .await - .map_err(|e| format!("Failed to send request: {}", e))?; + .wrap_err("Failed to send request")?; // parse response if response.status().is_client_error() { - return Err(format!( + return Err(eyre!( "Failed to fetch OpenAI models:\n{}", response.text().await.unwrap_or_default() )); } - let openai_models = response - .json::() - .await - .map_err(|e| e.to_string())?; + let openai_models = response.json::().await?; // check if models exist and select those that are available let mut available_models = Vec::new(); diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 0521dee..fbad81a 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -1,4 +1,5 @@ use async_trait::async_trait; +use eyre::Result; use libp2p::gossipsub::MessageAcceptance; mod pingpong; @@ -7,7 +8,7 @@ pub use pingpong::PingpongHandler; mod workflow; pub use workflow::WorkflowHandler; -use crate::{p2p::P2PMessage, DriaComputeNode}; +use crate::{utils::P2PMessage, DriaComputeNode}; #[async_trait] pub trait ComputeHandler { @@ -15,5 +16,5 @@ pub trait ComputeHandler { node: &mut DriaComputeNode, message: P2PMessage, result_topic: &str, - ) -> eyre::Result; + ) -> Result; } diff --git a/src/handlers/pingpong.rs b/src/handlers/pingpong.rs index 78c58e1..e875984 100644 --- a/src/handlers/pingpong.rs +++ b/src/handlers/pingpong.rs @@ -1,4 +1,7 @@ -use crate::{node::DriaComputeNode, p2p::P2PMessage, utils::get_current_time_nanos}; +use crate::{ + node::DriaComputeNode, + utils::{get_current_time_nanos, P2PMessage}, +}; use async_trait::async_trait; use eyre::Result; use libp2p::gossipsub::MessageAcceptance; @@ -66,10 +69,10 @@ impl ComputeHandler for PingpongHandler { #[cfg(test)] mod tests { use crate::{ - p2p::P2PMessage, utils::{ crypto::{sha256hash, to_address}, filter::FilterPayload, + P2PMessage, }, DriaComputeNodeConfig, }; diff --git a/src/handlers/workflow.rs b/src/handlers/workflow.rs index e983651..3303de5 100644 --- a/src/handlers/workflow.rs +++ b/src/handlers/workflow.rs @@ -5,9 +5,8 @@ use ollama_workflows::{Entry, Executor, ModelProvider, ProgramMemory, Workflow}; use serde::Deserialize; use crate::node::DriaComputeNode; -use crate::p2p::P2PMessage; -use crate::utils::get_current_time_nanos; use crate::utils::payload::{TaskRequest, TaskRequestPayload}; +use crate::utils::{get_current_time_nanos, P2PMessage}; use super::ComputeHandler; diff --git a/src/main.rs b/src/main.rs index da1326d..2c523d4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,9 @@ use dkn_compute::{DriaComputeNode, DriaComputeNodeConfig}; +use eyre::Result; use tokio_util::sync::CancellationToken; #[tokio::main] -async fn main() -> Result<(), Box> { +async fn main() -> Result<()> { if let Err(e) = dotenvy::dotenv() { log::warn!("Could not load .env file: {}", e); } diff --git a/src/node.rs b/src/node.rs index 385c6e7..476c6dc 100644 --- a/src/node.rs +++ b/src/node.rs @@ -6,8 +6,8 @@ use tokio_util::sync::CancellationToken; use crate::{ config::DriaComputeNodeConfig, handlers::{ComputeHandler, PingpongHandler, WorkflowHandler}, - p2p::{P2PClient, P2PMessage}, - utils::{crypto::secret_to_keypair, AvailableNodes}, + p2p::P2PClient, + utils::{crypto::secret_to_keypair, AvailableNodes, P2PMessage}, }; /// Number of seconds between refreshing the Admin RPC PeerIDs from Dria server. @@ -38,10 +38,9 @@ impl DriaComputeNode { pub async fn new( config: DriaComputeNodeConfig, cancellation: CancellationToken, - ) -> Result { + ) -> Result { let keypair = secret_to_keypair(&config.secret_key); - let listen_addr = - Multiaddr::from_str(config.p2p_listen_addr.as_str()).map_err(|e| e.to_string())?; + let listen_addr = Multiaddr::from_str(config.p2p_listen_addr.as_str())?; // get available nodes (bootstrap, relay, rpc) for p2p let available_nodes = AvailableNodes::default() @@ -266,9 +265,8 @@ impl DriaComputeNode { #[cfg(test)] mod tests { - use crate::{p2p::P2PMessage, DriaComputeNode, DriaComputeNodeConfig}; + use super::*; use std::env; - use tokio_util::sync::CancellationToken; #[tokio::test] #[ignore = "run this manually"] diff --git a/src/p2p/client.rs b/src/p2p/client.rs index 6b35b62..a0b831b 100644 --- a/src/p2p/client.rs +++ b/src/p2p/client.rs @@ -1,3 +1,4 @@ +use eyre::Result; use libp2p::futures::StreamExt; use libp2p::gossipsub::{ Message, MessageAcceptance, MessageId, PublishError, SubscriptionError, TopicHash, @@ -17,6 +18,7 @@ use super::{DriaBehaviour, DriaBehaviourEvent, P2P_KADEMLIA_PROTOCOL, P2P_PROTOC /// Underlying libp2p client. pub struct P2PClient { + /// `Swarm` instance, everything is accesses through this one. swarm: Swarm, /// Peer count for (All, Mesh). peer_count: (usize, usize), @@ -36,7 +38,7 @@ impl P2PClient { keypair: Keypair, listen_addr: Multiaddr, available_nodes: &AvailableNodes, - ) -> Result { + ) -> Result { // this is our peerId let node_peerid = keypair.public().to_peer_id(); log::info!("Compute node peer address: {}", node_peerid); @@ -47,13 +49,10 @@ impl P2PClient { tcp::Config::default(), noise::Config::new, yamux::Config::default, - ) - .map_err(|e| e.to_string())? + )? .with_quic() - .with_relay_client(noise::Config::new, yamux::Config::default) - .map_err(|e| e.to_string())? - .with_behaviour(|key, relay_behavior| Ok(DriaBehaviour::new(key, relay_behavior))) - .map_err(|e| e.to_string())? + .with_relay_client(noise::Config::new, yamux::Config::default)? + .with_behaviour(|key, relay_behavior| Ok(DriaBehaviour::new(key, relay_behavior)))? .with_swarm_config(|c| { c.with_idle_connection_timeout(Duration::from_secs(IDLE_CONNECTION_TIMEOUT_SECS)) }) @@ -76,7 +75,7 @@ impl P2PClient { _ => None, }) { log::info!("Dialling peer: {}", addr); - swarm.dial(addr.clone()).map_err(|e| e.to_string())?; + swarm.dial(addr.clone())?; log::info!("Adding {} to Kademlia routing table", addr); swarm .behaviour_mut() @@ -94,24 +93,18 @@ impl P2PClient { .behaviour_mut() .kademlia .get_closest_peers(random_peer); - swarm - .behaviour_mut() - .kademlia - .bootstrap() - .map_err(|e| e.to_string())?; + swarm.behaviour_mut().kademlia.bootstrap()?; // listen on all interfaces for incoming connections log::info!("Listening p2p network on: {}", listen_addr); - swarm.listen_on(listen_addr).map_err(|e| e.to_string())?; + swarm.listen_on(listen_addr)?; log::info!( "Listening to relay nodes: {:#?}", available_nodes.relay_nodes ); for addr in &available_nodes.relay_nodes { - swarm - .listen_on(addr.clone().with(Protocol::P2pCircuit)) - .map_err(|e| e.to_string())?; + swarm.listen_on(addr.clone().with(Protocol::P2pCircuit))?; } Ok(Self { @@ -138,6 +131,8 @@ impl P2PClient { } /// Publish a message to a topic. + /// + /// Returns the message ID. pub fn publish( &mut self, topic_name: &str, @@ -168,7 +163,7 @@ impl P2PClient { msg_id: &MessageId, propagation_source: &PeerId, acceptance: MessageAcceptance, - ) -> Result<(), PublishError> { + ) -> Result<()> { log::trace!("Validating message ({}): {:?}", msg_id, acceptance); let msg_was_in_cache = self @@ -240,6 +235,7 @@ impl P2PClient { /// - For Kademlia, we check the kademlia protocol and then add the address to the Kademlia routing table. fn handle_identify_event(&mut self, peer_id: PeerId, info: identify::Info) { // we only care about the observed address, although there may be other addresses at `info.listen_addrs` + // TODO: this may be wrong let addr = info.observed_addr; // check protocol string diff --git a/src/p2p/mod.rs b/src/p2p/mod.rs index 960afd5..fda9178 100644 --- a/src/p2p/mod.rs +++ b/src/p2p/mod.rs @@ -37,8 +37,4 @@ pub use behaviour::{DriaBehaviour, DriaBehaviourEvent}; mod client; pub use client::P2PClient; -mod message; - -pub use message::P2PMessage; - mod data_transform; diff --git a/src/utils/available_nodes.rs b/src/utils/available_nodes.rs index 7002b95..2215be1 100644 --- a/src/utils/available_nodes.rs +++ b/src/utils/available_nodes.rs @@ -1,5 +1,6 @@ +use eyre::Result; use libp2p::{Multiaddr, PeerId}; -use std::{fmt::Debug, str::FromStr}; +use std::{env, fmt::Debug, str::FromStr}; use crate::utils::split_comma_separated; @@ -47,7 +48,7 @@ impl AvailableNodes { /// - `DRIA_RELAY_NODES`: comma-separated list of relay nodes pub fn new_from_env() -> Self { // parse bootstrap nodes - let bootstrap_nodes = split_comma_separated(std::env::var("DKN_BOOTSTRAP_NODES").ok()); + let bootstrap_nodes = split_comma_separated(env::var("DKN_BOOTSTRAP_NODES").ok()); if bootstrap_nodes.is_empty() { log::debug!("No additional bootstrap nodes provided."); } else { @@ -55,7 +56,7 @@ impl AvailableNodes { } // parse relay nodes - let relay_nodes = split_comma_separated(std::env::var("DKN_RELAY_NODES").ok()); + let relay_nodes = split_comma_separated(env::var("DKN_RELAY_NODES").ok()); if relay_nodes.is_empty() { log::debug!("No additional relay nodes provided."); } else { @@ -69,6 +70,7 @@ impl AvailableNodes { } } + /// Creates a new `AvailableNodes` struct from the static nodes, hardcoded within the code. pub fn new_from_statics() -> Self { Self { bootstrap_nodes: parse_vec(STATIC_BOOTSTRAP_NODES.to_vec()), @@ -77,7 +79,7 @@ impl AvailableNodes { } } - /// Joins the available nodes from another `AvailableNodes` struct. + /// Joins the struct with another `AvailableNodes` struct. pub fn join(mut self, other: Self) -> Self { self.bootstrap_nodes.extend(other.bootstrap_nodes); self.relay_nodes.extend(other.relay_nodes); @@ -101,9 +103,7 @@ impl AvailableNodes { } /// Refreshes the available nodes for Bootstrap, Relay and RPC nodes. - /// - /// Returns immediately if its too early to do that. - pub async fn get_available_nodes() -> Result { + pub async fn get_available_nodes() -> Result { let response = reqwest::get(RPC_PEER_ID_REFRESH_API_URL).await?; let response_body = response.json::().await?; diff --git a/src/utils/crypto.rs b/src/utils/crypto.rs index a35a672..a6ac28b 100644 --- a/src/utils/crypto.rs +++ b/src/utils/crypto.rs @@ -5,13 +5,13 @@ use sha2::{Digest, Sha256}; use sha3::Keccak256; /// Generic SHA256 function. -#[inline] +#[inline(always)] pub fn sha256hash(data: impl AsRef<[u8]>) -> [u8; 32] { Sha256::digest(data).into() } /// Generic KECCAK256 function. -#[inline] +#[inline(always)] pub fn keccak256hash(data: impl AsRef<[u8]>) -> [u8; 32] { Keccak256::digest(data).into() } diff --git a/src/utils/filter.rs b/src/utils/filter.rs index 131b799..cd30f59 100644 --- a/src/utils/filter.rs +++ b/src/utils/filter.rs @@ -1,3 +1,4 @@ +use eyre::{Context, Result}; use fastbloom_rs::{BloomFilter, Hashes, Membership}; use serde::{Deserialize, Serialize}; use serde_json::{json, to_string}; @@ -14,8 +15,10 @@ pub struct FilterPayload { impl FilterPayload { /// Shorthand function to create the underlying `BloomFilter` and check if it contains the given address. #[inline] - pub fn contains(&self, address: &[u8]) -> Result { - BloomFilter::try_from(self).map(|filter| filter.contains(address)) + pub fn contains(&self, address: &[u8]) -> Result { + BloomFilter::try_from(self) + .map(|filter| filter.contains(address)) + .wrap_err("Could not create filter.") } } diff --git a/src/p2p/message.rs b/src/utils/message.rs similarity index 99% rename from src/p2p/message.rs rename to src/utils/message.rs index 336b081..a9e1067 100644 --- a/src/p2p/message.rs +++ b/src/utils/message.rs @@ -159,7 +159,7 @@ impl TryFrom for P2PMessage { #[cfg(test)] mod tests { use super::*; - use crate::{p2p::P2PMessage, utils::crypto::sha256hash, DriaComputeNodeConfig}; + use crate::{utils::crypto::sha256hash, DriaComputeNodeConfig}; use ecies::decrypt; use libsecp256k1::SecretKey; use libsecp256k1::{verify, Message, PublicKey, RecoveryId, Signature}; diff --git a/src/utils/mod.rs b/src/utils/mod.rs index c72209f..06970d9 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -2,6 +2,9 @@ pub mod crypto; pub mod filter; pub mod payload; +mod message; +pub use message::P2PMessage; + mod available_nodes; pub use available_nodes::AvailableNodes; From d5a272d030c6ea775405e4e8a0c647323cb82c2d Mon Sep 17 00:00:00 2001 From: erhant Date: Tue, 1 Oct 2024 18:14:16 +0300 Subject: [PATCH 03/15] rm examples and clean `Cargo.toml` --- Cargo.lock | 1 - Cargo.toml | 16 +--- examples/benchmarks/ollama.rs | 172 ---------------------------------- examples/common/ollama.rs | 37 -------- examples/prompt.rs | 58 ------------ 5 files changed, 1 insertion(+), 283 deletions(-) delete mode 100644 examples/benchmarks/ollama.rs delete mode 100644 examples/common/ollama.rs delete mode 100644 examples/prompt.rs diff --git a/Cargo.lock b/Cargo.lock index aa5b7f3..386dbc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1039,7 +1039,6 @@ version = "0.2.5" dependencies = [ "async-trait", "base64 0.22.1", - "colored", "dotenvy", "ecies", "env_logger 0.11.5", diff --git a/Cargo.toml b/Cargo.toml index 8992c82..ef0ad23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -70,21 +70,7 @@ libp2p-identity = { version = "0.2.9", features = ["secp256k1"] } tracing = { version = "0.1.40" } tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } - +# Vendor OpenSSL so that its easier to build cross-platform packages [dependencies.openssl] version = "*" features = ["vendored"] - -[dev-dependencies] -colored = "2.1.0" - - -[[example]] -name = "ollama" -path = "./examples/benchmarks/ollama.rs" - -[[example]] -name = "prompt" - - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/examples/benchmarks/ollama.rs b/examples/benchmarks/ollama.rs deleted file mode 100644 index aab675f..0000000 --- a/examples/benchmarks/ollama.rs +++ /dev/null @@ -1,172 +0,0 @@ -use colored::Colorize; -use serde::{Deserialize, Serialize}; -use std::collections::HashMap; -use std::env; -use std::fs::File; -use std::io::Read; - -#[path = "../common/ollama.rs"] -mod common; - -/// A `println!` macro that only prints when the `debug_assertions` flag is set, i.e. it wont print when `--release` is used. -#[allow(unused)] -macro_rules! debug_println { - ($($arg:tt)*) => (if ::std::cfg!(debug_assertions) { ::std::println!($($arg)*); }) -} - -/// Shareable format string to print results. -macro_rules! result_format_str { - () => { - "{:<8} {:<15} {:<18} {:<18} {:<18} {:<18} {:<18} {:<18} {:<18}" - }; -} - -#[inline(always)] -fn print_title() { - println!( - result_format_str!(), - "Prompt".blue(), - "Model".blue(), - "Call (ns)".red(), - "Total (ns)".red(), - "Prompt (t)".yellow(), - "Prompt (ns)".yellow(), - "Result (t)".green(), - "Result (ns)".green(), - "TPS".blue(), - ); -} - -#[tokio::main] -async fn main() { - let models = ["orca-mini", "phi3"]; //, "llama3", "openhermes"]; - let preset_prompts = [ - "Give 3 names of famous scientists, 1 Field Medalist, 1 Turing Award recipient and 1 Nobel laureate. Provide only the names, such as: 1. John Doe, 2. Jane Doe, 3. Foo Bar.", - "What is the name of the first president of Turkish Republic?", - ]; - - // decide on prompts to be used - let prompts: Vec = match env::var("JSON_PATH") { - Ok(path) => { - println!("Reading tasks from: {}", path); - let jobs = read_json_file::>(path.as_str()).unwrap(); - jobs.into_iter().map(|job| job.prompt).collect() - } - Err(_) => { - println!("Using preset prompts."); - preset_prompts - .iter() - .map(|&prompt| prompt.to_string()) - .collect() - } - }; - - print_title(); - let mut results: Vec = Vec::new(); - let mut num_prompts = HashMap::new(); - for (prompt_num, prompt) in prompts.iter().enumerate() { - // println!("{}{}: {}", "Prompt #".blue(), prompt_num, prompt); - for model in models { - let (generation, duration) = common::use_model_with_prompt(model, prompt).await; - - let result = BenchmarkResult { - prompt_num, - model: model.to_string(), - api_duration: duration.as_nanos(), - total_duration: generation.total_duration.unwrap_or_default(), - prompt_eval_count: generation.prompt_eval_count.unwrap_or_default(), - prompt_eval_duration: generation.prompt_eval_duration.unwrap_or(1), - eval_count: generation.eval_count.unwrap_or_default(), - eval_duration: generation.eval_duration.unwrap_or(1), - tokens_per_second: ((generation.eval_count.unwrap_or_default() as f64) - / (generation.eval_duration.unwrap_or(1) as f64) - * 1_000_000_000f64), - }; - - println!("{}", result); - results.push(result); - num_prompts.insert(model, num_prompts.get(model).unwrap_or(&0) + 1); - } - } - - println!("\nAverage {} for each model:", "tokens per second".yellow()); - let mut tps = HashMap::new(); - for result in &results { - tps.insert( - &result.model, - tps.get(&result.model).unwrap_or(&0f64) + result.tokens_per_second, - ); - } - for model in models { - let avg_tps = tps.get(&model.to_string()).unwrap_or(&0f64) - / *num_prompts.get(model).unwrap_or(&1) as f64; - println!("{}: {:.2}", model, avg_tps); - } -} - -/// Reads a JSON file and deserializes it. -fn read_json_file Deserialize<'a>>(file_path: &str) -> Result { - let mut file = File::open(file_path)?; - - let mut contents = String::new(); - file.read_to_string(&mut contents)?; - - let obj = serde_json::from_str(&contents)?; - Ok(obj) -} - -impl std::fmt::Display for BenchmarkResult { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!( - f, - result_format_str!(), - self.prompt_num, - self.model, - self.api_duration, - self.total_duration, - self.prompt_eval_count, - self.prompt_eval_duration, - self.eval_count, - self.eval_duration, - self.tokens_per_second - ) - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -struct BenchmarkResult { - /// Prompt number - pub prompt_num: usize, - /// Model used to generate the result - pub model: String, - /// Time spent making the entire API call to Ollama - pub api_duration: u128, - /// Time spent evaluating the prompt & generating the response - pub total_duration: u64, - /// Number of tokens in the prompt - pub prompt_eval_count: u16, - /// Time spent in nanoseconds evaluating the prompt - pub prompt_eval_duration: u64, - /// Number of tokens in the response - pub eval_count: u16, - /// Time in nanoseconds spent generating the response - pub eval_duration: u64, - /// Tokens per second is calculated by `eval_count / eval_duration * 10^9`, see https://github.com/ollama/ollama/blob/main/docs/api.md#response - pub tokens_per_second: f64, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -struct Job { - purpose: String, - task_type: String, - dataset_format: String, - language: String, - alignment_preferences: Vec, - dataset_size: usize, - id: String, - private_key: String, - public_key: String, - status: String, - prompt: String, - subtask_id: String, -} diff --git a/examples/common/ollama.rs b/examples/common/ollama.rs deleted file mode 100644 index a8ab8ca..0000000 --- a/examples/common/ollama.rs +++ /dev/null @@ -1,37 +0,0 @@ -use std::time::SystemTime; - -use ollama_workflows::ollama_rs::{ - generation::completion::{request::GenerationRequest, GenerationResponse}, - Ollama, -}; - -/// A shorthand function to invoke a prompt using a given model with Ollama. -pub async fn use_model_with_prompt( - model: &str, - prompt: &str, -) -> (GenerationResponse, tokio::time::Duration) { - let ollama = Ollama::default(); - - let time = get_current_time_nanos(); - let prompt = prompt.to_string(); - - log::debug!("Generating with prompt: {}", prompt); - - let gen_req = GenerationRequest::new(model.to_string(), prompt); - let gen_res = ollama.generate(gen_req).await.expect("should generate"); - - log::debug!("Generated response: {}", gen_res.response); - - let time_diff = get_current_time_nanos() - time; - let duration = tokio::time::Duration::from_nanos(time_diff as u64); - - (gen_res, duration) -} - -#[inline(always)] -fn get_current_time_nanos() -> u128 { - SystemTime::now() - .duration_since(SystemTime::UNIX_EPOCH) - .unwrap() - .as_nanos() -} diff --git a/examples/prompt.rs b/examples/prompt.rs deleted file mode 100644 index 69059a2..0000000 --- a/examples/prompt.rs +++ /dev/null @@ -1,58 +0,0 @@ -use colored::Colorize; - -#[path = "./common/ollama.rs"] -mod common; - -#[tokio::main] -async fn main() { - let model = "phi3"; - - let prompt = "You will be generating a synthetic dataset based on the following information: - - -Fine-tuning - - - -The dataset will consist of instructions to generate jokes, followed by the corresponding joke output. - - - - -Include a wide range of jokes, as long as they are funny. -Do not exclude sensitive or insensitive jokes. - - - -['Humor is driven by culture and there are stereotypes about humor among different cultures.', 'There are four different types of humor styles: affiliative, self-enhancing, self-defeating, and aggressive.', 'Comedy Trade School offers a stand-up comedy course taught by professional comedians', 'There are age and cultural differences in humor appreciation, with different groups endorsing some humor styles more than others.', 'Watching the video and taking the quiz can help improve understanding of joke structure'] - - -Please carefully analyze the preference prompt to understand the desired characteristics, structure, and content of the dataset you will be generating. Pay close attention to any specific requirements or constraints mentioned in the prompt. - -Use the provided ground truth examples as a reference for the format, style, and quality of the examples you will generate. Ensure that your generated examples are consistent with the patterns and characteristics observed in the ground truth examples. - -Generate 5 synthetic examples that align with the preference prompt and maintain consistency with the ground truth examples. Each example should be unique and diverse while still adhering to the specified requirements. - -Please ensure that your generated examples are realistic, coherent, and free of any errors or inconsistencies. If the preference prompt specifies any additional constraints or considerations, make sure to incorporate them into your generated examples. - - -[, , ...] - Date: Tue, 1 Oct 2024 18:16:19 +0300 Subject: [PATCH 04/15] removed benchmark imgs, updated relevant issue with images there --- benchmarks/flamegraph_none.svg | 491 --------------------------- benchmarks/flamegraph_permissive.svg | 491 --------------------------- 2 files changed, 982 deletions(-) delete mode 100644 benchmarks/flamegraph_none.svg delete mode 100644 benchmarks/flamegraph_permissive.svg diff --git a/benchmarks/flamegraph_none.svg b/benchmarks/flamegraph_none.svg deleted file mode 100644 index 04c5677..0000000 --- a/benchmarks/flamegraph_none.svg +++ /dev/null @@ -1,491 +0,0 @@ -Flame Graph Reset ZoomSearch dkn-compute`<tokio_util::sync::cancellation_token::WaitForCancellationFuture as core::future::future::Future>::poll (4 samples, 0.01%)dkn-compute`<libp2p_core::transport::map::Map<T,F> as libp2p_core::transport::Transport>::poll (6 samples, 0.02%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::poll (8 samples, 0.02%)dkn-compute`<libp2p_core::transport::map::Map<T,F> as libp2p_core::transport::Transport>::poll (5 samples, 0.01%)dkn-compute`<libp2p_relay::priv_client::transport::Transport as libp2p_core::transport::Transport>::poll (5 samples, 0.01%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::poll (16 samples, 0.04%)dkn-compute`<T as libp2p_core::transport::boxed::Abstract<O>>::poll (17 samples, 0.05%)dkn-compute`<alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter (5 samples, 0.01%)dkn-compute`<dkn_compute::p2p::behaviour::DriaBehaviour as libp2p_swarm::behaviour::NetworkBehaviour>::on_connection_handler_event (6 samples, 0.02%)dkn-compute`<libp2p_kad::behaviour::Behaviour<TStore> as libp2p_swarm::behaviour::NetworkBehaviour>::on_connection_handler_event (6 samples, 0.02%)dkn-compute`<dkn_compute::p2p::behaviour::DriaBehaviour as libp2p_swarm::behaviour::NetworkBehaviour>::on_swarm_event (6 samples, 0.02%)dkn-compute`<futures_ticker::Ticker as futures_core::stream::Stream>::poll_next (4 samples, 0.01%)dkn-compute`<libp2p_request_response::Behaviour<TCodec> as libp2p_swarm::behaviour::NetworkBehaviour>::poll (5 samples, 0.01%)dkn-compute`<libp2p_autonat::behaviour::Behaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (14 samples, 0.04%)dkn-compute`<futures_ticker::Ticker as futures_core::stream::Stream>::poll_next (5 samples, 0.01%)dkn-compute`<futures_timer::native::delay::Delay as core::future::future::Future>::poll (5 samples, 0.01%)dkn-compute`core::ops::function::impls::_<impl core::ops::function::FnMut<A> for &mut F>::call_mut (11 samples, 0.03%)dkn-compute`libp2p_gossipsub::mcache::MessageCache::get_gossip_message_ids (14 samples, 0.04%)dkn-compute`<alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter (14 samples, 0.04%)dkn-compute`libp2p_gossipsub::behaviour::Behaviour<D,F>::heartbeat (24 samples, 0.07%)dkn-compute`<libp2p_gossipsub::behaviour::Behaviour<C,F> as libp2p_swarm::behaviour::NetworkBehaviour>::poll (43 samples, 0.12%)dkn-compute`libp2p_kad::query::QueryPool<TInner>::poll (65 samples, 0.18%)dkn-compute`libp2p_kad::query::peers::closest::ClosestPeersIter::next (52 samples, 0.14%)dkn-compute`<alloc::collections::btree::map::ValuesMut<K,V> as core::iter::traits::iterator::Iterator>::next (28 samples, 0.08%)dkn-compute`tracing::span::Span::log (4 samples, 0.01%)dkn-compute`<libp2p_kad::behaviour::Behaviour<TStore> as libp2p_swarm::behaviour::NetworkBehaviour>::poll (88 samples, 0.24%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (4 samples, 0.01%)dkn-compute`<futures_channel::mpsc::Receiver<T> as futures_core::stream::Stream>::poll_next (5 samples, 0.01%)dkn-compute`<libp2p_relay::priv_client::Behaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (15 samples, 0.04%)dkn-compute`<dkn_compute::p2p::behaviour::DriaBehaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (178 samples, 0.49%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (14 samples, 0.04%)libsystem_malloc.dylib`szone_malloc_should_clear (9 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_should_clear (9 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_from_free_list (6 samples, 0.02%)dkn-compute`<libp2p_gossipsub::types::RawMessage as core::clone::Clone>::clone (21 samples, 0.06%)dkn-compute`<alloc::string::String as core::fmt::Write>::write_str (4 samples, 0.01%)dkn-compute`dkn_compute::p2p::behaviour::create_gossipsub_behavior::_{{closure}} (10 samples, 0.03%)dkn-compute`core::fmt::num::imp::_<impl core::fmt::Display for u64>::fmt (9 samples, 0.02%)dkn-compute`<libp2p_gossipsub::types::RawMessage as core::clone::Clone>::clone (4 samples, 0.01%)libsystem_malloc.dylib`free_tiny (4 samples, 0.01%)dkn-compute`libp2p_gossipsub::behaviour::Behaviour<D,F>::forward_msg (27 samples, 0.07%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::get_mut (10 samples, 0.03%)dkn-compute`libp2p_gossipsub::mcache::MessageCache::observe_duplicate (12 samples, 0.03%)dkn-compute`libp2p_gossipsub::mcache::MessageCache::put (9 samples, 0.02%)dkn-compute`hashbrown::rustc_entry::_<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry (4 samples, 0.01%)dkn-compute`hashbrown::rustc_entry::_<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry (17 samples, 0.05%)dkn-compute`hashbrown::raw::RawTable<T,A>::reserve_rehash (6 samples, 0.02%)dkn-compute`libp2p_gossipsub::time_cache::DuplicateCache<Key>::insert (22 samples, 0.06%)libsystem_malloc.dylib`_nanov2_free (5 samples, 0.01%)libsystem_malloc.dylib`nanov2_malloc (7 samples, 0.02%)dkn-compute`<libp2p_gossipsub::behaviour::Behaviour<C,F> as libp2p_swarm::behaviour::NetworkBehaviour>::on_connection_handler_event (158 samples, 0.43%)dkn-compute`libp2p_tcp::Transport<T>::create_socket (6 samples, 0.02%)libsystem_kernel.dylib`socket (5 samples, 0.01%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::dial (9 samples, 0.02%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::dial (9 samples, 0.02%)dkn-compute`<libp2p_core::transport::map::Map<T,F> as libp2p_core::transport::Transport>::dial (9 samples, 0.02%)dkn-compute`<libp2p_tcp::Transport<T> as libp2p_core::transport::Transport>::dial (9 samples, 0.02%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold (10 samples, 0.03%)dkn-compute`<T as libp2p_core::transport::boxed::Abstract<O>>::dial (10 samples, 0.03%)dkn-compute`alloc::vec::in_place_collect::_<impl alloc::vec::spec_from_iter::SpecFromIter<T,I> for alloc::vec::Vec<T>>::from_iter (11 samples, 0.03%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::task::Schedule for alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>::schedule (5 samples, 0.01%)dkn-compute`tokio::runtime::context::with_scheduler (5 samples, 0.01%)dkn-compute`futures_channel::mpsc::Sender<T>::try_send (6 samples, 0.02%)dkn-compute`tokio::runtime::task::waker::wake_by_val (6 samples, 0.02%)dkn-compute`libp2p_swarm::connection::pool::Pool<THandler>::iter_established_connections_of_peer (9 samples, 0.02%)libsystem_malloc.dylib`tiny_free_no_lock (7 samples, 0.02%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (18 samples, 0.05%)libsystem_malloc.dylib`free_tiny (13 samples, 0.04%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (30 samples, 0.08%)libsystem_platform.dylib`_platform_memmove (4 samples, 0.01%)dkn-compute`futures_util::stream::stream::StreamExt::poll_next_unpin (34 samples, 0.09%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (43 samples, 0.12%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (45 samples, 0.12%)dkn-compute`libp2p_swarm::connection::pool::Pool<THandler>::poll (59 samples, 0.16%)libsystem_platform.dylib`_platform_memmove (5 samples, 0.01%)dkn-compute`tracing::span::Span::log (6 samples, 0.02%)dkn-compute`libp2p_swarm::Swarm<TBehaviour>::poll_next_event (499 samples, 1.37%)dkn-compute`tokio::signal::unix::Signal::recv::_{{closure}} (4 samples, 0.01%)dkn-compute`dkn_compute::main::_{{closure}} (539 samples, 1.48%)dkn-compute`<tokio::future::poll_fn::PollFn<F> as core::future::future::Future>::poll (536 samples, 1.47%)libsystem_kernel.dylib`__psynch_cvwait (40 samples, 0.11%)dkn-compute`tokio::runtime::park::Inner::park (43 samples, 0.12%)dkn-compute`parking_lot::condvar::Condvar::wait_until_internal (43 samples, 0.12%)dkn-compute`tokio::runtime::context::runtime::enter_runtime (584 samples, 1.60%)dkn-compute`tokio::runtime::park::CachedParkThread::block_on (584 samples, 1.60%)dkn-compute`<tokio::sync::notify::Notified as core::ops::drop::Drop>::drop (5 samples, 0.01%)dkn-compute`tokio::sync::notify::Notified::poll_notified (7 samples, 0.02%)dkn-compute`tokio_util::sync::cancellation_token::tree_node::is_cancelled (12 samples, 0.03%)dkn-compute`<tokio_util::sync::cancellation_token::WaitForCancellationFuture as core::future::future::Future>::poll (20 samples, 0.05%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (4 samples, 0.01%)dkn-compute`<libp2p_core::transport::map::Map<T,F> as libp2p_core::transport::Transport>::poll (28 samples, 0.08%)dkn-compute`tracing::span::Span::record_all (6 samples, 0.02%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (7 samples, 0.02%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (4 samples, 0.01%)dkn-compute`<libp2p_quic::transport::GenTransport<P> as libp2p_core::transport::Transport>::poll (8 samples, 0.02%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::poll (43 samples, 0.12%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (4 samples, 0.01%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::poll (69 samples, 0.19%)dkn-compute`<libp2p_core::transport::map::Map<T,F> as libp2p_core::transport::Transport>::poll (21 samples, 0.06%)dkn-compute`<libp2p_relay::priv_client::transport::Transport as libp2p_core::transport::Transport>::poll (11 samples, 0.03%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (5 samples, 0.01%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (4 samples, 0.01%)dkn-compute`<T as libp2p_core::transport::boxed::Abstract<O>>::poll (76 samples, 0.21%)dkn-compute`<libp2p_core::transport::map::Map<T,F> as libp2p_core::transport::Transport>::poll (6 samples, 0.02%)dkn-compute`<alloc::vec::into_iter::IntoIter<T,A> as core::ops::drop::Drop>::drop (4 samples, 0.01%)dkn-compute`<dkn_compute::p2p::behaviour::DriaBehaviour as libp2p_swarm::behaviour::NetworkBehaviour>::handle_pending_outbound_connection (4 samples, 0.01%)dkn-compute`<libp2p_kad::kbucket::ClosestIter<TTarget,TKey,TVal,TMap,TOut> as core::iter::traits::iterator::Iterator>::next (13 samples, 0.04%)dkn-compute`libp2p_kad::kbucket::bucket::KBucket<TKey,TVal>::apply_pending (6 samples, 0.02%)dkn-compute`<alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter (39 samples, 0.11%)libsystem_platform.dylib`_platform_memmove (25 samples, 0.07%)dkn-compute`libp2p_kad::behaviour::Behaviour<TStore>::discovered (4 samples, 0.01%)dkn-compute`<dkn_compute::p2p::behaviour::DriaBehaviour as libp2p_swarm::behaviour::NetworkBehaviour>::on_connection_handler_event (66 samples, 0.18%)dkn-compute`<libp2p_kad::behaviour::Behaviour<TStore> as libp2p_swarm::behaviour::NetworkBehaviour>::on_connection_handler_event (45 samples, 0.12%)dkn-compute`libp2p_kad::behaviour::Behaviour<TStore>::address_failed (5 samples, 0.01%)dkn-compute`<libp2p_kad::behaviour::Behaviour<TStore> as libp2p_swarm::behaviour::NetworkBehaviour>::on_swarm_event (9 samples, 0.02%)dkn-compute`libp2p_kad::query::peers::closest::ClosestPeersIter::on_failure (4 samples, 0.01%)dkn-compute`<dkn_compute::p2p::behaviour::DriaBehaviour as libp2p_swarm::behaviour::NetworkBehaviour>::on_swarm_event (13 samples, 0.04%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (14 samples, 0.04%)dkn-compute`tracing::span::Span::log (16 samples, 0.04%)dkn-compute`tracing::span::Span::record_all (18 samples, 0.05%)dkn-compute`<libp2p_request_response::Behaviour<TCodec> as libp2p_swarm::behaviour::NetworkBehaviour>::poll (83 samples, 0.23%)dkn-compute`tracing_core::span::Record::is_empty (6 samples, 0.02%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (15 samples, 0.04%)dkn-compute`<futures_timer::native::delay::Delay as core::future::future::Future>::poll (24 samples, 0.07%)dkn-compute`tokio::runtime::park::drop_waker (4 samples, 0.01%)dkn-compute`libp2p_autonat::behaviour::as_client::AsClient::poll_auto_probe (28 samples, 0.08%)dkn-compute`tracing::span::Span::log (18 samples, 0.05%)dkn-compute`tracing::span::Span::record_all (11 samples, 0.03%)dkn-compute`tracing::span::Span::log (4 samples, 0.01%)dkn-compute`<libp2p_autonat::behaviour::Behaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (188 samples, 0.52%)dkn-compute`tracing_core::span::Record::is_empty (4 samples, 0.01%)dkn-compute`<futures_timer::native::delay::Delay as core::future::future::Future>::poll (24 samples, 0.07%)dkn-compute`tokio::runtime::park::clone (5 samples, 0.01%)dkn-compute`<futures_ticker::Ticker as futures_core::stream::Stream>::poll_next (30 samples, 0.08%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (29 samples, 0.08%)dkn-compute`tracing::span::Span::log (10 samples, 0.03%)dkn-compute`core::hash::BuildHasher::hash_one (11 samples, 0.03%)dkn-compute`core::ops::function::impls::_<impl core::ops::function::FnMut<A> for &mut F>::call_mut (86 samples, 0.24%)libsystem_malloc.dylib`nanov2_malloc (5 samples, 0.01%)libsystem_platform.dylib`_platform_memcmp (47 samples, 0.13%)dkn-compute`<alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter (144 samples, 0.39%)dkn-compute`libp2p_gossipsub::mcache::MessageCache::get_gossip_message_ids (147 samples, 0.40%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (10 samples, 0.03%)dkn-compute`hashbrown::raw::RawTable<T,A>::remove_entry (15 samples, 0.04%)libsystem_malloc.dylib`_nanov2_free (20 samples, 0.05%)libsystem_malloc.dylib`tiny_free_list_add_ptr (4 samples, 0.01%)libsystem_malloc.dylib`free_tiny (25 samples, 0.07%)libsystem_malloc.dylib`tiny_free_no_lock (16 samples, 0.04%)libsystem_platform.dylib`_platform_memcmp (4 samples, 0.01%)dkn-compute`libp2p_gossipsub::mcache::MessageCache::shift (100 samples, 0.27%)libsystem_platform.dylib`_platform_memset (4 samples, 0.01%)libsystem_malloc.dylib`_nanov2_free (7 samples, 0.02%)dkn-compute`libp2p_gossipsub::behaviour::Behaviour<D,F>::heartbeat (262 samples, 0.72%)dkn-compute`tracing::span::Span::log (34 samples, 0.09%)dkn-compute`tracing::span::Span::record_all (21 samples, 0.06%)dkn-compute`tracing::span::Span::log (10 samples, 0.03%)dkn-compute`tracing_core::span::Record::is_empty (11 samples, 0.03%)dkn-compute`<libp2p_gossipsub::behaviour::Behaviour<C,F> as libp2p_swarm::behaviour::NetworkBehaviour>::poll (437 samples, 1.20%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (11 samples, 0.03%)dkn-compute`tracing::span::Span::log (5 samples, 0.01%)dkn-compute`tracing::span::Span::log (22 samples, 0.06%)dkn-compute`tracing::span::Span::record_all (11 samples, 0.03%)dkn-compute`<libp2p_identify::behaviour::Behaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (75 samples, 0.21%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (10 samples, 0.03%)dkn-compute`<futures_timer::native::delay::Delay as core::future::future::Future>::poll (12 samples, 0.03%)dkn-compute`libp2p_kad::jobs::AddProviderJob::poll (22 samples, 0.06%)dkn-compute`libp2p_kad::jobs::PutRecordJob::poll (44 samples, 0.12%)dkn-compute`<futures_timer::native::delay::Delay as core::future::future::Future>::poll (28 samples, 0.08%)dkn-compute`tokio::runtime::park::drop_waker (8 samples, 0.02%)dkn-compute`<alloc::collections::btree::map::ValuesMut<K,V> as core::iter::traits::iterator::Iterator>::next (39 samples, 0.11%)dkn-compute`<std::time::Instant as core::ops::arith::Sub>::sub (36 samples, 0.10%)dkn-compute`std::sys::pal::unix::time::Timespec::sub_timespec (28 samples, 0.08%)dkn-compute`libp2p_kad::query::QueryPool<TInner>::poll (815 samples, 2.23%)d..dkn-compute`libp2p_kad::query::peers::closest::ClosestPeersIter::next (661 samples, 1.81%)d..dkn-compute`<alloc::collections::btree::map::ValuesMut<K,V> as core::iter::traits::iterator::Iterator>::next (315 samples, 0.86%)dkn-compute`libp2p_kad::query::peers::closest::ClosestPeersIter::next (6 samples, 0.02%)libsystem_c.dylib`clock_gettime_nsec_np (10 samples, 0.03%)libsystem_kernel.dylib`mach_timebase_info (5 samples, 0.01%)libsystem_kernel.dylib`mach_absolute_time (13 samples, 0.04%)dkn-compute`std::sys::pal::unix::time::Timespec::now (52 samples, 0.14%)libsystem_c.dylib`clock_gettime (47 samples, 0.13%)libsystem_kernel.dylib`mach_timebase_info (5 samples, 0.01%)dkn-compute`tracing::span::Span::log (16 samples, 0.04%)dkn-compute`tracing::span::Span::record_all (29 samples, 0.08%)dkn-compute`tracing::span::Span::log (5 samples, 0.01%)dkn-compute`<libp2p_kad::behaviour::Behaviour<TStore> as libp2p_swarm::behaviour::NetworkBehaviour>::poll (1,120 samples, 3.07%)dkn..dkn-compute`tracing_core::span::Record::is_empty (15 samples, 0.04%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (36 samples, 0.10%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (23 samples, 0.06%)dkn-compute`<futures_channel::mpsc::Receiver<T> as futures_core::stream::Stream>::poll_next (78 samples, 0.21%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (33 samples, 0.09%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (27 samples, 0.07%)dkn-compute`tracing::span::Span::log (10 samples, 0.03%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (9 samples, 0.02%)dkn-compute`tracing::span::Span::log (34 samples, 0.09%)dkn-compute`tracing::span::Span::record_all (37 samples, 0.10%)dkn-compute`tracing::span::Span::log (9 samples, 0.02%)dkn-compute`<libp2p_relay::priv_client::Behaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (272 samples, 0.75%)dkn-compute`tracing_core::span::Record::is_empty (12 samples, 0.03%)dkn-compute`core::ptr::drop_in_place<core::option::Option<libp2p_swarm::behaviour::ToSwarm<libp2p_identify::behaviour::Event,libp2p_identify::handler::InEvent>>> (4 samples, 0.01%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (8 samples, 0.02%)dkn-compute`libp2p_autonat::behaviour::as_client::AsClient::poll_auto_probe (4 samples, 0.01%)dkn-compute`libp2p_kad::jobs::AddProviderJob::poll (6 samples, 0.02%)dkn-compute`std::sys::pal::unix::time::Timespec::now (5 samples, 0.01%)dkn-compute`tokio::runtime::park::clone (8 samples, 0.02%)dkn-compute`tracing::span::Span::log (37 samples, 0.10%)dkn-compute`tracing::span::Span::record_all (10 samples, 0.03%)dkn-compute`<dkn_compute::p2p::behaviour::DriaBehaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (2,233 samples, 6.12%)dkn-comp..libsystem_platform.dylib`_platform_memmove (6 samples, 0.02%)dkn-compute`<futures_channel::mpsc::Receiver<T> as futures_core::stream::Stream>::poll_next (4 samples, 0.01%)dkn-compute`<libp2p_autonat::behaviour::Behaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (6 samples, 0.02%)dkn-compute`<libp2p_dcutr::behaviour::Behaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (5 samples, 0.01%)dkn-compute`<alloc::vec::into_iter::IntoIter<T,A> as core::ops::drop::Drop>::drop (12 samples, 0.03%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (223 samples, 0.61%)libsystem_malloc.dylib`_nanov2_free (22 samples, 0.06%)dkn-compute`<libp2p_gossipsub::transform::IdentityTransform as libp2p_gossipsub::transform::DataTransform>::inbound_transform (42 samples, 0.12%)dkn-compute`<alloc::string::String as core::clone::Clone>::clone (11 samples, 0.03%)libsystem_malloc.dylib`nanov2_allocate_outlined (11 samples, 0.03%)libsystem_malloc.dylib`nanov2_find_block_and_allocate (9 samples, 0.02%)libsystem_malloc.dylib`nanov2_malloc (36 samples, 0.10%)libsystem_malloc.dylib`small_malloc_should_clear (5 samples, 0.01%)libsystem_malloc.dylib`small_malloc_from_free_list (4 samples, 0.01%)libsystem_malloc.dylib`set_tiny_meta_header_in_use (5 samples, 0.01%)libsystem_malloc.dylib`_tiny_check_and_zero_inline_meta_from_freelist (10 samples, 0.03%)libsystem_malloc.dylib`szone_malloc_should_clear (112 samples, 0.31%)libsystem_malloc.dylib`tiny_malloc_should_clear (95 samples, 0.26%)libsystem_malloc.dylib`tiny_malloc_from_free_list (75 samples, 0.21%)libsystem_malloc.dylib`tiny_free_list_add_ptr (5 samples, 0.01%)dkn-compute`<libp2p_gossipsub::types::RawMessage as core::clone::Clone>::clone (216 samples, 0.59%)libsystem_platform.dylib`_platform_memmove (6 samples, 0.02%)dkn-compute`DYLD-STUB$$free (15 samples, 0.04%)dkn-compute`core::hash::BuildHasher::hash_one (5 samples, 0.01%)dkn-compute`<alloc::string::String as core::fmt::Write>::write_str (7 samples, 0.02%)dkn-compute`core::fmt::Formatter::pad_integral (5 samples, 0.01%)libsystem_malloc.dylib`_malloc_zone_malloc (6 samples, 0.02%)dkn-compute`alloc::raw_vec::RawVec<T,A>::reserve::do_reserve_and_handle (29 samples, 0.08%)libsystem_malloc.dylib`nanov2_malloc (17 samples, 0.05%)dkn-compute`<alloc::string::String as core::fmt::Write>::write_str (36 samples, 0.10%)dkn-compute`alloc::raw_vec::RawVec<T,A>::reserve::do_reserve_and_handle (5 samples, 0.01%)dkn-compute`core::fmt::Formatter::pad_integral (4 samples, 0.01%)dkn-compute`dkn_compute::p2p::behaviour::create_gossipsub_behavior::_{{closure}} (97 samples, 0.27%)dkn-compute`core::fmt::num::imp::_<impl core::fmt::Display for u64>::fmt (77 samples, 0.21%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::contains_key (11 samples, 0.03%)dkn-compute`hashbrown::rustc_entry::_<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry (4 samples, 0.01%)dkn-compute`<alloc::collections::btree::map::Keys<K,V> as core::iter::traits::iterator::Iterator>::next (6 samples, 0.02%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (60 samples, 0.16%)dkn-compute`<alloc::string::String as core::clone::Clone>::clone (14 samples, 0.04%)libsystem_malloc.dylib`nanov2_allocate_outlined (10 samples, 0.03%)libsystem_malloc.dylib`nanov2_find_block_and_allocate (7 samples, 0.02%)dkn-compute`DYLD-STUB$$memcpy (7 samples, 0.02%)libsystem_malloc.dylib`nanov2_allocate_outlined (40 samples, 0.11%)libsystem_malloc.dylib`nanov2_find_block_and_allocate (30 samples, 0.08%)libsystem_malloc.dylib`nanov2_allocate_from_block (12 samples, 0.03%)libsystem_malloc.dylib`nanov2_malloc (57 samples, 0.16%)libsystem_malloc.dylib`small_malloc_should_clear (4 samples, 0.01%)libsystem_malloc.dylib`set_tiny_meta_header_in_use (16 samples, 0.04%)libsystem_malloc.dylib`_tiny_check_and_zero_inline_meta_from_freelist (40 samples, 0.11%)libsystem_malloc.dylib`szone_malloc_should_clear (149 samples, 0.41%)libsystem_malloc.dylib`tiny_malloc_should_clear (140 samples, 0.38%)libsystem_malloc.dylib`tiny_malloc_from_free_list (96 samples, 0.26%)libsystem_malloc.dylib`tiny_free_list_add_ptr (19 samples, 0.05%)dkn-compute`<libp2p_gossipsub::types::RawMessage as core::clone::Clone>::clone (307 samples, 0.84%)libsystem_platform.dylib`_platform_memmove (6 samples, 0.02%)dkn-compute`core::hash::BuildHasher::hash_one (8 samples, 0.02%)libsystem_malloc.dylib`_nanov2_free (7 samples, 0.02%)libsystem_malloc.dylib`free_tiny (8 samples, 0.02%)libsystem_malloc.dylib`tiny_free_no_lock (5 samples, 0.01%)dkn-compute`core::ptr::drop_in_place<libp2p_gossipsub::types::RpcOut> (17 samples, 0.05%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (47 samples, 0.13%)dkn-compute`core::hash::BuildHasher::hash_one (11 samples, 0.03%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (58 samples, 0.16%)dkn-compute`core::hash::BuildHasher::hash_one (6 samples, 0.02%)libsystem_malloc.dylib`tiny_free_list_add_ptr (4 samples, 0.01%)libsystem_malloc.dylib`free_tiny (17 samples, 0.05%)libsystem_malloc.dylib`tiny_free_no_lock (14 samples, 0.04%)libsystem_malloc.dylib`small_malloc_should_clear (9 samples, 0.02%)libsystem_malloc.dylib`small_malloc_from_free_list (6 samples, 0.02%)libsystem_malloc.dylib`small_free_list_remove_ptr_no_clear (5 samples, 0.01%)libsystem_malloc.dylib`_tiny_check_and_zero_inline_meta_from_freelist (5 samples, 0.01%)libsystem_malloc.dylib`szone_malloc_should_clear (33 samples, 0.09%)libsystem_malloc.dylib`tiny_malloc_should_clear (23 samples, 0.06%)libsystem_malloc.dylib`tiny_malloc_from_free_list (20 samples, 0.05%)libsystem_malloc.dylib`tiny_free_list_add_ptr (4 samples, 0.01%)dkn-compute`hashbrown::raw::RawTable<T,A>::reserve_rehash (152 samples, 0.42%)libsystem_malloc.dylib`free (4 samples, 0.01%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::insert (268 samples, 0.73%)libsystem_platform.dylib`_platform_memset (7 samples, 0.02%)libsystem_malloc.dylib`_malloc_zone_malloc (4 samples, 0.01%)libsystem_malloc.dylib`_nanov2_free (5 samples, 0.01%)libsystem_malloc.dylib`_szone_free (4 samples, 0.01%)libsystem_malloc.dylib`free (4 samples, 0.01%)libsystem_malloc.dylib`free_tiny (11 samples, 0.03%)libsystem_malloc.dylib`tiny_free_no_lock (6 samples, 0.02%)libsystem_malloc.dylib`nanov2_malloc (65 samples, 0.18%)libsystem_platform.dylib`_platform_memmove (59 samples, 0.16%)dkn-compute`libp2p_gossipsub::behaviour::Behaviour<D,F>::forward_msg (1,025 samples, 2.81%)dk..dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (28 samples, 0.08%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::get_mut (232 samples, 0.64%)dkn-compute`core::hash::BuildHasher::hash_one (6 samples, 0.02%)dkn-compute`libp2p_gossipsub::mcache::MessageCache::observe_duplicate (323 samples, 0.89%)libsystem_platform.dylib`_platform_memcmp (84 samples, 0.23%)dkn-compute`hashbrown::raw::RawTable<T,A>::reserve_rehash (7 samples, 0.02%)dkn-compute`core::hash::BuildHasher::hash_one (6 samples, 0.02%)dkn-compute`hashbrown::rustc_entry::_<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry (24 samples, 0.07%)libsystem_malloc.dylib`nanov2_allocate_outlined (4 samples, 0.01%)libsystem_malloc.dylib`nanov2_malloc (8 samples, 0.02%)dkn-compute`libp2p_gossipsub::mcache::MessageCache::put (47 samples, 0.13%)dkn-compute`hashbrown::rustc_entry::_<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry (274 samples, 0.75%)dkn-compute`hashbrown::raw::RawTable<T,A>::reserve_rehash (4 samples, 0.01%)libsystem_c.dylib`clock_gettime_nsec_np (8 samples, 0.02%)libsystem_kernel.dylib`mach_absolute_time (10 samples, 0.03%)libsystem_c.dylib`clock_gettime (39 samples, 0.11%)libsystem_kernel.dylib`mach_timebase_info (8 samples, 0.02%)dkn-compute`std::sys::pal::unix::time::Timespec::now (42 samples, 0.12%)dkn-compute`std::time::Instant::now (9 samples, 0.02%)libsystem_malloc.dylib`_nanov2_free (28 samples, 0.08%)libsystem_platform.dylib`_platform_memcmp (117 samples, 0.32%)dkn-compute`libp2p_gossipsub::time_cache::DuplicateCache<Key>::insert (492 samples, 1.35%)dkn-compute`std::sys::pal::unix::time::Timespec::now (4 samples, 0.01%)libdyld.dylib`tlv_get_addr (4 samples, 0.01%)libsystem_kernel.dylib`__ulock_wake (8 samples, 0.02%)libsystem_malloc.dylib`_malloc_zone_malloc (11 samples, 0.03%)libsystem_malloc.dylib`_nanov2_free (113 samples, 0.31%)libsystem_malloc.dylib`_szone_free (16 samples, 0.04%)libsystem_malloc.dylib`free (15 samples, 0.04%)libsystem_malloc.dylib`free_small (4 samples, 0.01%)libsystem_kernel.dylib`__ulock_wait (12 samples, 0.03%)libsystem_malloc.dylib`get_tiny_previous_free_msize (7 samples, 0.02%)libsystem_malloc.dylib`tiny_free_list_add_ptr (46 samples, 0.13%)libsystem_malloc.dylib`tiny_free_no_lock (87 samples, 0.24%)libsystem_malloc.dylib`tiny_free_list_remove_ptr (10 samples, 0.03%)libsystem_malloc.dylib`free_tiny (136 samples, 0.37%)libsystem_malloc.dylib`nanov2_malloc (44 samples, 0.12%)libsystem_malloc.dylib`szone_malloc (4 samples, 0.01%)libsystem_platform.dylib`__bzero (6 samples, 0.02%)libsystem_platform.dylib`_platform_memcmp (54 samples, 0.15%)libsystem_platform.dylib`_platform_memmove (61 samples, 0.17%)libsystem_platform.dylib`_platform_memset (19 samples, 0.05%)dkn-compute`<libp2p_gossipsub::behaviour::Behaviour<C,F> as libp2p_swarm::behaviour::NetworkBehaviour>::on_connection_handler_event (3,197 samples, 8.76%)dkn-compute`..dkn-compute`<libp2p_identify::behaviour::Behaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (7 samples, 0.02%)dkn-compute`<smallvec::SmallVec<A> as core::iter::traits::collect::Extend<<A as smallvec::Array>::Item>>::extend (10 samples, 0.03%)dkn-compute`DYLD-STUB$$free (4 samples, 0.01%)libsystem_kernel.dylib`__fcntl (4 samples, 0.01%)dkn-compute`socket2::socket::Socket::new (5 samples, 0.01%)dkn-compute`libp2p_tcp::Transport<T>::create_socket (32 samples, 0.09%)libsystem_kernel.dylib`socket (24 samples, 0.07%)dkn-compute`<libp2p_tcp::Transport<T> as libp2p_core::transport::Transport>::dial (47 samples, 0.13%)libsystem_kernel.dylib`__bind (10 samples, 0.03%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::dial (48 samples, 0.13%)dkn-compute`<libp2p_core::transport::map::Map<T,F> as libp2p_core::transport::Transport>::dial (48 samples, 0.13%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::dial (52 samples, 0.14%)dkn-compute`<libp2p_core::transport::map::Map<T,F> as libp2p_core::transport::Transport>::dial (4 samples, 0.01%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold (62 samples, 0.17%)dkn-compute`<T as libp2p_core::transport::boxed::Abstract<O>>::dial (60 samples, 0.16%)dkn-compute`futures_timer::native::delay::Delay::new_handle (7 samples, 0.02%)dkn-compute`futures_timer::native::global::raw_wake (7 samples, 0.02%)libdispatch.dylib`_dispatch_semaphore_signal_slow (6 samples, 0.02%)libsystem_kernel.dylib`semaphore_signal_trap (6 samples, 0.02%)dkn-compute`alloc::vec::in_place_collect::_<impl alloc::vec::spec_from_iter::SpecFromIter<T,I> for alloc::vec::Vec<T>>::from_iter (63 samples, 0.17%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (5 samples, 0.01%)dkn-compute`dkn_compute::p2p::behaviour::create_gossipsub_behavior::_{{closure}} (8 samples, 0.02%)dkn-compute`futures_channel::mpsc::BoundedSenderInner<T>::poll_unparked (11 samples, 0.03%)dkn-compute`tokio::runtime::task::raw::schedule (4 samples, 0.01%)dkn-compute`parking_lot::condvar::Condvar::notify_one_slow (67 samples, 0.18%)libsystem_kernel.dylib`__psynch_cvsignal (66 samples, 0.18%)dkn-compute`tokio::runtime::driver::Handle::unpark (15 samples, 0.04%)libsystem_kernel.dylib`kevent (15 samples, 0.04%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::scheduler::multi_thread::handle::Handle>::notify_parked_remote (10 samples, 0.03%)dkn-compute`tokio::runtime::context::with_scheduler (125 samples, 0.34%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::scheduler::multi_thread::handle::Handle>::push_remote_task (25 samples, 0.07%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::task::Schedule for alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>::schedule (130 samples, 0.36%)dkn-compute`futures_channel::mpsc::Sender<T>::try_send (191 samples, 0.52%)dkn-compute`tokio::runtime::task::waker::wake_by_val (151 samples, 0.41%)dkn-compute`tokio::runtime::task::state::State::transition_to_notified_by_val (19 samples, 0.05%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::wake (29 samples, 0.08%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::contains_key (9 samples, 0.02%)dkn-compute`libp2p_gossipsub::behaviour::Behaviour<D,F>::forward_msg (4 samples, 0.01%)dkn-compute`libp2p_swarm::behaviour::ToSwarm<TOutEvent,TInEventOld>::map_in (17 samples, 0.05%)dkn-compute`libp2p_swarm::connection::pool::Pool<THandler>::add_outgoing (4 samples, 0.01%)dkn-compute`libp2p_swarm::connection::pool::Pool<THandler>::iter_established_connections_of_peer (97 samples, 0.27%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (10 samples, 0.03%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (5 samples, 0.01%)dkn-compute`<futures_channel::mpsc::Receiver<T> as futures_core::stream::Stream>::poll_next (14 samples, 0.04%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (9 samples, 0.02%)dkn-compute`alloc::sync::Arc<T,A>::drop_slow (4 samples, 0.01%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (27 samples, 0.07%)dkn-compute`alloc::sync::Arc<T,A>::drop_slow (5 samples, 0.01%)libsystem_malloc.dylib`_nanov2_free (23 samples, 0.06%)dkn-compute`futures_util::stream::futures_unordered::FuturesUnordered<Fut>::release_task (43 samples, 0.12%)dkn-compute`DYLD-STUB$$free (10 samples, 0.03%)dkn-compute`__rdl_dealloc (14 samples, 0.04%)libsystem_kernel.dylib`__ulock_wake (5 samples, 0.01%)libsystem_malloc.dylib`_nanov2_free (4 samples, 0.01%)libsystem_malloc.dylib`_szone_free (18 samples, 0.05%)libsystem_kernel.dylib`__ulock_wait (11 samples, 0.03%)libsystem_malloc.dylib`tiny_free_list_add_ptr (4 samples, 0.01%)libsystem_malloc.dylib`tiny_free_list_add_ptr (35 samples, 0.10%)libsystem_malloc.dylib`tiny_free_no_lock (83 samples, 0.23%)libsystem_malloc.dylib`tiny_free_list_remove_ptr (13 samples, 0.04%)libsystem_malloc.dylib`free_tiny (133 samples, 0.36%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (251 samples, 0.69%)libsystem_platform.dylib`_platform_memset (10 samples, 0.03%)libsystem_kernel.dylib`__psynch_cvsignal (68 samples, 0.19%)dkn-compute`parking_lot::condvar::Condvar::notify_one_slow (82 samples, 0.22%)dkn-compute`tokio::runtime::driver::Handle::unpark (10 samples, 0.03%)libsystem_kernel.dylib`kevent (10 samples, 0.03%)dkn-compute`tokio::runtime::context::with_scheduler (107 samples, 0.29%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::scheduler::multi_thread::handle::Handle>::push_remote_task (7 samples, 0.02%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::task::Schedule for alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>::schedule (111 samples, 0.30%)dkn-compute`tokio::runtime::task::waker::wake_by_val (112 samples, 0.31%)libsystem_malloc.dylib`_nanov2_free (6 samples, 0.02%)libsystem_malloc.dylib`free (15 samples, 0.04%)libsystem_malloc.dylib`szone_try_free_default (7 samples, 0.02%)libsystem_platform.dylib`_platform_memmove (35 samples, 0.10%)libsystem_pthread.dylib`_pthread_mutex_firstfit_unlock_slow (6 samples, 0.02%)libsystem_kernel.dylib`__psynch_mutexdrop (6 samples, 0.02%)libsystem_pthread.dylib`pthread_mutex_lock (4 samples, 0.01%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (476 samples, 1.30%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (4 samples, 0.01%)dkn-compute`futures_util::stream::stream::StreamExt::poll_next_unpin (519 samples, 1.42%)libsystem_platform.dylib`_platform_memmove (18 samples, 0.05%)libsystem_malloc.dylib`free (11 samples, 0.03%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (692 samples, 1.90%)d..libsystem_platform.dylib`_platform_memmove (18 samples, 0.05%)dkn-compute`futures_util::stream::futures_unordered::FuturesUnordered<Fut>::push (17 samples, 0.05%)libsystem_malloc.dylib`_malloc_zone_malloc (6 samples, 0.02%)libsystem_malloc.dylib`nanov2_malloc (24 samples, 0.07%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (776 samples, 2.13%)d..libsystem_platform.dylib`_platform_memmove (21 samples, 0.06%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (7 samples, 0.02%)dkn-compute`tracing::span::Span::log (23 samples, 0.06%)dkn-compute`tracing::span::Span::record_all (12 samples, 0.03%)dkn-compute`tracing::span::Span::log (4 samples, 0.01%)dkn-compute`tracing_core::span::Record::is_empty (4 samples, 0.01%)dkn-compute`libp2p_swarm::connection::pool::Pool<THandler>::poll (921 samples, 2.52%)dk..libsystem_platform.dylib`_platform_memmove (30 samples, 0.08%)dkn-compute`tracing::span::Span::log (21 samples, 0.06%)dkn-compute`tracing::span::Span::record_all (8 samples, 0.02%)dkn-compute`tracing::span::Span::log (7 samples, 0.02%)libsystem_malloc.dylib`_nanov2_free (15 samples, 0.04%)libsystem_malloc.dylib`_szone_free (11 samples, 0.03%)libsystem_malloc.dylib`free (51 samples, 0.14%)libsystem_malloc.dylib`nanov2_malloc (69 samples, 0.19%)libsystem_platform.dylib`_platform_memcmp (16 samples, 0.04%)dkn-compute`libp2p_swarm::Swarm<TBehaviour>::poll_next_event (7,554 samples, 20.70%)dkn-compute`libp2p_swarm::Swarm<T..libsystem_platform.dylib`_platform_memmove (15 samples, 0.04%)dkn-compute`libp2p_swarm::connection::pool::Pool<THandler>::poll (5 samples, 0.01%)dkn-compute`tokio::macros::support::thread_rng_n (4 samples, 0.01%)dkn-compute`tokio::signal::make_future::_{{closure}} (12 samples, 0.03%)dkn-compute`tokio::sync::notify::Notified::poll_notified (5 samples, 0.01%)dkn-compute`tokio::signal::RxFuture::poll_recv (14 samples, 0.04%)dkn-compute`tokio::signal::unix::Signal::recv::_{{closure}} (21 samples, 0.06%)dkn-compute`tokio::signal::make_future::_{{closure}} (4 samples, 0.01%)dkn-compute`std::sys::pal::unix::time::Timespec::now (11 samples, 0.03%)libsystem_c.dylib`clock_gettime (10 samples, 0.03%)dkn-compute`tokio::time::instant::Instant::elapsed (14 samples, 0.04%)libdyld.dylib`tlv_get_addr (4 samples, 0.01%)libsystem_malloc.dylib`_nanov2_free (4 samples, 0.01%)libsystem_malloc.dylib`free_tiny (7 samples, 0.02%)libsystem_platform.dylib`_platform_memmove (17 samples, 0.05%)dkn-compute`<tokio::future::poll_fn::PollFn<F> as core::future::future::Future>::poll (7,719 samples, 21.16%)dkn-compute`<tokio::future::poll_..Security`SecTrustCopyPublicKey (4 samples, 0.01%)Security`SecCertificateCopyPublicKey$LEGACYMAC (4 samples, 0.01%)Security`Security::KeychainCore::Certificate::publicKey (4 samples, 0.01%)Security`Security::KeychainCore::Certificate::copyFirstFieldValue (4 samples, 0.01%)Security`Security::KeychainCore::Certificate::clHandle (4 samples, 0.01%)Security`Security::CssmClient::AttachmentImpl::activate (4 samples, 0.01%)Security`Security::CssmClient::ModuleImpl::activate (4 samples, 0.01%)Security`CSSM_ModuleLoad (4 samples, 0.01%)Security`Security::CssmClient::Table<Security::MDSClient::Common>::fetch (4 samples, 0.01%)Security`Security::CssmClient::Table<Security::MDSClient::Common>::startQuery (4 samples, 0.01%)Security`Security::MDSClient::Directory::dlGetFirst (4 samples, 0.01%)Security`Security::MDSClient::Directory::cdsa (4 samples, 0.01%)Security`mds_DbOpen(long, char const*, cssm_net_address const*, unsigned int, cssm_access_credentials const*, void const*, long*) (4 samples, 0.01%)Security`Security::MDSSession::DbOpen (4 samples, 0.01%)Security`SSLHandshake (6 samples, 0.02%)Security`SSLHandshakeProceed (6 samples, 0.02%)libcoretls.dylib`tls_handshake_process (5 samples, 0.01%)libcoretls.dylib`SSLProcessHandshakeRecordInner (5 samples, 0.01%)Security`tls_handshake_message_callback (5 samples, 0.01%)libcoretls_cfhelpers.dylib`tls_helper_set_peer_pubkey (5 samples, 0.01%)dkn-compute`<tokio_native_tls::MidHandshake<S> as core::future::future::Future>::poll (7 samples, 0.02%)dkn-compute`native_tls::imp::MidHandshakeTlsStream<S>::handshake (7 samples, 0.02%)dkn-compute`security_framework::secure_transport::MidHandshakeClientBuilder<S>::handshake (7 samples, 0.02%)dkn-compute`<reqwest::async_impl::client::PendingRequest as core::future::future::Future>::poll (8 samples, 0.02%)dkn-compute`hyper_util::client::legacy::client::Client<C,B>::send_request::_{{closure}} (8 samples, 0.02%)dkn-compute`<futures_util::future::select::Select<A,B> as core::future::future::Future>::poll (8 samples, 0.02%)dkn-compute`<futures_util::future::try_future::try_flatten::TryFlatten<Fut,<Fut as futures_core::future::TryFuture>::Ok> as core::future::future::Future>::poll (8 samples, 0.02%)dkn-compute`<futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll (8 samples, 0.02%)dkn-compute`<futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll (8 samples, 0.02%)dkn-compute`<tower::util::oneshot::Oneshot<S,Req> as core::future::future::Future>::poll (8 samples, 0.02%)dkn-compute`reqwest::connect::with_timeout::_{{closure}} (8 samples, 0.02%)dkn-compute`reqwest::connect::Connector::connect_with_maybe_proxy::_{{closure}} (8 samples, 0.02%)dkn-compute`<hyper_tls::client::HttpsConnector<T> as tower_service::Service<http::uri::Uri>>::call::_{{closure}} (8 samples, 0.02%)dkn-compute`dkn_compute::p2p::available_nodes::AvailableNodes::get_available_nodes::_{{closure}} (11 samples, 0.03%)dkn-compute`dkn_compute::p2p::client::P2PClient::new (7 samples, 0.02%)libsystem_malloc.dylib`free (4 samples, 0.01%)dkn-compute`dkn_compute::main::_{{closure}} (7,774 samples, 21.31%)dkn-compute`dkn_compute::main::_{{..libsystem_platform.dylib`_platform_memmove (7 samples, 0.02%)libsystem_kernel.dylib`__psynch_cvwait (422 samples, 1.16%)libsystem_pthread.dylib`_pthread_cond_wait (25 samples, 0.07%)libsystem_pthread.dylib`pthread_testcancel (6 samples, 0.02%)dkn-compute`parking_lot::condvar::Condvar::wait_until_internal (467 samples, 1.28%)dkn-compute`tokio::runtime::park::Inner::park (476 samples, 1.30%)dkn-compute`tokio::runtime::park::CachedParkThread::block_on (8,266 samples, 22.65%)dkn-compute`tokio::runtime::park::Ca..libdyld.dylib`tlv_get_addr (4 samples, 0.01%)dyld`start (8,275 samples, 22.68%)dyld`startdkn-compute`main (8,275 samples, 22.68%)dkn-compute`maindkn-compute`std::rt::lang_start_internal (8,275 samples, 22.68%)dkn-compute`std::rt::lang_start_inte..dkn-compute`std::rt::lang_start::_{{closure}} (8,274 samples, 22.68%)dkn-compute`std::rt::lang_start::_{{..dkn-compute`std::sys_common::backtrace::__rust_begin_short_backtrace (8,274 samples, 22.68%)dkn-compute`std::sys_common::backtra..dkn-compute`dkn_compute::main (8,274 samples, 22.68%)dkn-compute`dkn_compute::maindkn-compute`tokio::runtime::runtime::Runtime::block_on (8,274 samples, 22.68%)dkn-compute`tokio::runtime::runtime:..dkn-compute`tokio::runtime::context::runtime::enter_runtime (8,274 samples, 22.68%)dkn-compute`tokio::runtime::context:..libdyld.dylib`tlv_get_addr (8 samples, 0.02%)dkn-compute`alloc::sync::Arc<T,A>::drop_slow (8 samples, 0.02%)dkn-compute`<futures_timer::native::timer::Timer as core::future::future::Future>::poll (21 samples, 0.06%)libdispatch.dylib`_dispatch_semaphore_wait_slow (50 samples, 0.14%)libsystem_kernel.dylib`semaphore_timedwait_trap (49 samples, 0.13%)dkn-compute`std::thread::park_timeout (52 samples, 0.14%)dkn-compute`futures_timer::native::global::run (81 samples, 0.22%)dkn-compute`__floatuntidf (6 samples, 0.02%)dkn-compute`tokio::runtime::scheduler::multi_thread::idle::Idle::transition_worker_to_parked (7 samples, 0.02%)dkn-compute`tokio::runtime::scheduler::multi_thread::queue::Steal<T>::steal_into (7 samples, 0.02%)dkn-compute`<std::time::Instant as core::ops::arith::Sub>::sub (6 samples, 0.02%)dkn-compute`std::sys::pal::unix::time::Timespec::sub_timespec (4 samples, 0.01%)dkn-compute`parking_lot::raw_mutex::RawMutex::lock_slow (8 samples, 0.02%)libsystem_kernel.dylib`swtch_pri (4 samples, 0.01%)libsystem_c.dylib`clock_gettime_nsec_np (13 samples, 0.04%)libsystem_kernel.dylib`mach_timebase_info (8 samples, 0.02%)libsystem_kernel.dylib`mach_absolute_time (17 samples, 0.05%)dkn-compute`std::sys::pal::unix::time::Timespec::now (92 samples, 0.25%)libsystem_c.dylib`clock_gettime (79 samples, 0.22%)libsystem_kernel.dylib`mach_timebase_info (14 samples, 0.04%)dkn-compute`tokio::runtime::scheduler::multi_thread::idle::Idle::transition_worker_to_parked (20 samples, 0.05%)dkn-compute`tokio::runtime::scheduler::multi_thread::idle::Idle::unpark_worker_by_id (7 samples, 0.02%)dkn-compute`tokio::runtime::scheduler::multi_thread::queue::Steal<T>::steal_into (63 samples, 0.17%)libsystem_kernel.dylib`__psynch_cvsignal (19 samples, 0.05%)dkn-compute`parking_lot::condvar::Condvar::notify_one_slow (22 samples, 0.06%)libsystem_kernel.dylib`__psynch_cvwait (1,585 samples, 4.34%)libsy..libsystem_pthread.dylib`_pthread_mutex_droplock (4 samples, 0.01%)libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_slow (9 samples, 0.02%)libsystem_kernel.dylib`__psynch_mutexwait (9 samples, 0.02%)libsystem_pthread.dylib`pthread_mutex_lock (8 samples, 0.02%)libsystem_pthread.dylib`_pthread_cond_wait (76 samples, 0.21%)libsystem_pthread.dylib`pthread_testcancel (21 samples, 0.06%)libsystem_pthread.dylib`pthread_mutex_lock (4 samples, 0.01%)dkn-compute`parking_lot::condvar::Condvar::wait_until_internal (1,720 samples, 4.71%)dkn-c..libsystem_pthread.dylib`pthread_testcancel (4 samples, 0.01%)dkn-compute`<mio::event::events::Iter as core::iter::traits::iterator::Iterator>::next (5 samples, 0.01%)dkn-compute`mio::poll::Poll::poll (6 samples, 0.02%)dkn-compute`std::sys::pal::unix::time::Timespec::now (8 samples, 0.02%)dkn-compute`std::time::Instant::now (5 samples, 0.01%)dkn-compute`tokio::process::imp::orphan::OrphanQueueImpl<T>::reap_orphans (12 samples, 0.03%)dkn-compute`DYLD-STUB$$kevent (6 samples, 0.02%)dkn-compute`mio::poll::Poll::poll (34 samples, 0.09%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::task::Schedule for alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>::schedule (6 samples, 0.02%)dkn-compute`tokio::runtime::task::raw::schedule (6 samples, 0.02%)dkn-compute`tokio::runtime::context::with_scheduler (4 samples, 0.01%)dkn-compute`tokio::runtime::context::with_scheduler (23 samples, 0.06%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::scheduler::multi_thread::handle::Handle>::schedule_local (5 samples, 0.01%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::task::Schedule for alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>::schedule (38 samples, 0.10%)libdyld.dylib`tlv_get_addr (15 samples, 0.04%)dkn-compute`tokio::runtime::io::scheduled_io::ScheduledIo::wake (81 samples, 0.22%)dkn-compute`tokio::runtime::task::waker::wake_by_val (60 samples, 0.16%)dkn-compute`tokio::runtime::task::state::State::transition_to_notified_by_val (14 samples, 0.04%)dkn-compute`tokio::runtime::task::waker::wake_by_val (10 samples, 0.03%)dkn-compute`tokio::runtime::io::driver::Driver::turn (1,463 samples, 4.01%)dkn-..libsystem_kernel.dylib`kevent (1,301 samples, 3.57%)libs..dkn-compute`DYLD-STUB$$clock_gettime (7 samples, 0.02%)libsystem_c.dylib`clock_gettime_nsec_np (11 samples, 0.03%)libsystem_kernel.dylib`mach_timebase_info (9 samples, 0.02%)libsystem_kernel.dylib`mach_absolute_time (11 samples, 0.03%)dkn-compute`std::sys::pal::unix::time::Timespec::now (48 samples, 0.13%)libsystem_c.dylib`clock_gettime (48 samples, 0.13%)libsystem_kernel.dylib`mach_timebase_info (13 samples, 0.04%)dkn-compute`std::time::Instant::duration_since (11 samples, 0.03%)dkn-compute`std::sys::pal::unix::time::Timespec::sub_timespec (10 samples, 0.03%)dkn-compute`tokio::runtime::time::wheel::Wheel::next_expiration (22 samples, 0.06%)dkn-compute`tokio::runtime::time::_<impl tokio::runtime::time::handle::Handle>::process_at_sharded_time (167 samples, 0.46%)dkn-compute`tokio::runtime::time::wheel::Wheel::poll (101 samples, 0.28%)dkn-compute`tokio::runtime::time::wheel::Wheel::next_expiration (94 samples, 0.26%)dkn-compute`tokio::runtime::time::_<impl tokio::runtime::time::handle::Handle>::process (260 samples, 0.71%)libsystem_c.dylib`clock_gettime (6 samples, 0.02%)dkn-compute`tokio::runtime::time::_<impl tokio::runtime::time::handle::Handle>::process_at_sharded_time (9 samples, 0.02%)dkn-compute`tokio::runtime::time::wheel::Wheel::next_expiration (49 samples, 0.13%)libdyld.dylib`tlv_get_addr (5 samples, 0.01%)dkn-compute`tokio::runtime::time::Driver::park_internal (1,869 samples, 5.12%)dkn-co..libdyld.dylib`tlv_get_addr (4 samples, 0.01%)dkn-compute`tokio::runtime::scheduler::multi_thread::park::Parker::park (3,674 samples, 10.07%)dkn-compute`tok..libsystem_pthread.dylib`pthread_mutex_unlock (10 samples, 0.03%)dkn-compute`tokio::runtime::io::driver::Driver::turn (48 samples, 0.13%)libsystem_kernel.dylib`kevent (48 samples, 0.13%)dkn-compute`tokio::runtime::time::_<impl tokio::runtime::time::handle::Handle>::process (6 samples, 0.02%)dkn-compute`tokio::runtime::time::_<impl tokio::runtime::time::handle::Handle>::process_at_sharded_time (4 samples, 0.01%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::Context::park_timeout (3,798 samples, 10.41%)dkn-compute`tok..dkn-compute`tokio::runtime::time::Driver::park_internal (61 samples, 0.17%)dkn-compute`parking_lot_core::parking_lot::lock_bucket_pair (12 samples, 0.03%)dkn-compute`std::sys::pal::unix::time::Timespec::now (10 samples, 0.03%)libsystem_c.dylib`clock_gettime (8 samples, 0.02%)libsystem_kernel.dylib`__psynch_cvsignal (312 samples, 0.86%)libsystem_pthread.dylib`_pthread_mutex_firstfit_unlock_slow (4 samples, 0.01%)libsystem_kernel.dylib`__psynch_mutexdrop (4 samples, 0.01%)libsystem_pthread.dylib`pthread_cond_signal (6 samples, 0.02%)dkn-compute`parking_lot::condvar::Condvar::notify_one_slow (365 samples, 1.00%)dkn-compute`tokio::runtime::driver::Handle::unpark (124 samples, 0.34%)libsystem_kernel.dylib`kevent (122 samples, 0.33%)dkn-compute`tokio::runtime::scheduler::multi_thread::park::Unparker::unpark (8 samples, 0.02%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::scheduler::multi_thread::handle::Handle>::transition_worker_from_searching (16 samples, 0.04%)dkn-compute`tokio::runtime::task::core::Core<T,S>::poll (8 samples, 0.02%)dkn-compute`<tracing::instrument::Instrumented<T> as core::future::future::Future>::poll (18 samples, 0.05%)dkn-compute`parking_lot_core::parking_lot::lock_bucket_pair (10 samples, 0.03%)libsystem_c.dylib`clock_gettime_nsec_np (4 samples, 0.01%)libsystem_kernel.dylib`mach_timebase_info (4 samples, 0.01%)dkn-compute`std::sys::pal::unix::time::Timespec::now (12 samples, 0.03%)libsystem_c.dylib`clock_gettime (10 samples, 0.03%)libsystem_kernel.dylib`__psynch_cvsignal (246 samples, 0.67%)libsystem_pthread.dylib`_pthread_cond_updateval (4 samples, 0.01%)dkn-compute`parking_lot::condvar::Condvar::notify_one_slow (285 samples, 0.78%)dkn-compute`tokio::runtime::driver::Handle::unpark (116 samples, 0.32%)libsystem_kernel.dylib`kevent (116 samples, 0.32%)dkn-compute`tokio::runtime::scheduler::multi_thread::park::Unparker::unpark (6 samples, 0.02%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::scheduler::multi_thread::handle::Handle>::schedule_local (34 samples, 0.09%)libsystem_pthread.dylib`pthread_cond_signal (4 samples, 0.01%)dkn-compute`tokio::runtime::context::with_scheduler (465 samples, 1.27%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::task::Schedule for alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>::yield_now (471 samples, 1.29%)dkn-compute`<futures_util::future::select::Select<A,B> as core::future::future::Future>::poll (7 samples, 0.02%)dkn-compute`<alloc::vec::into_iter::IntoIter<T,A> as core::iter::traits::iterator::Iterator>::next (4 samples, 0.01%)dkn-compute`<futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll (4 samples, 0.01%)dkn-compute`<libp2p_core::transport::map::MapFuture<T,F> as core::future::future::Future>::poll (4 samples, 0.01%)dkn-compute`<libp2p_core::upgrade::apply::InboundUpgradeApply<C,U> as core::future::future::Future>::poll (4 samples, 0.01%)dkn-compute`<libp2p_noise::Config as libp2p_core::upgrade::InboundConnectionUpgrade<T>>::upgrade_inbound::_{{closure}} (4 samples, 0.01%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (15 samples, 0.04%)dkn-compute`<libp2p_core::muxing::boxed::Wrap<T> as libp2p_core::muxing::StreamMuxer>::poll (13 samples, 0.04%)dkn-compute`<libp2p_core::muxing::boxed::Wrap<T> as libp2p_core::muxing::StreamMuxer>::poll_inbound (8 samples, 0.02%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::handshakestate::HandshakeState> as asynchronous_codec::encoder::Encoder>::encode (8 samples, 0.02%)dkn-compute`snow::handshakestate::HandshakeState::write_message (8 samples, 0.02%)dkn-compute`<libp2p_noise::protocol::Keypair as snow::types::Dh>::generate (8 samples, 0.02%)dkn-compute`x25519_dalek::x25519::x25519 (7 samples, 0.02%)dkn-compute`curve25519_dalek::montgomery::MontgomeryPoint::mul_clamped (7 samples, 0.02%)dkn-compute`<&curve25519_dalek::montgomery::MontgomeryPoint as core::ops::arith::Mul<&curve25519_dalek::scalar::Scalar>>::mul (7 samples, 0.02%)dkn-compute`libsecp256k1_core::ecmult::ECMultContext::ecmult (10 samples, 0.03%)dkn-compute`libsecp256k1_core::field::Field::sqr_in_place (7 samples, 0.02%)dkn-compute`libp2p_identity::keypair::PublicKey::verify (14 samples, 0.04%)dkn-compute`libsecp256k1_core::ecdsa::_<impl libsecp256k1_core::ecmult::ECMultContext>::verify_raw (14 samples, 0.04%)dkn-compute`libp2p_noise::io::handshake::State<T>::finish (15 samples, 0.04%)dkn-compute`<&curve25519_dalek::backend::serial::u64::field::FieldElement51 as core::ops::arith::Mul<&curve25519_dalek::backend::serial::u64::field::FieldElement51>>::mul (5 samples, 0.01%)dkn-compute`curve25519_dalek::backend::serial::u64::field::FieldElement51::pow2k (6 samples, 0.02%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::handshakestate::HandshakeState> as asynchronous_codec::decoder::Decoder>::decode (13 samples, 0.04%)dkn-compute`snow::handshakestate::HandshakeState::read_message (13 samples, 0.04%)dkn-compute`<libp2p_noise::protocol::Keypair as snow::types::Dh>::dh (13 samples, 0.04%)dkn-compute`x25519_dalek::x25519::x25519 (13 samples, 0.04%)dkn-compute`curve25519_dalek::montgomery::MontgomeryPoint::mul_clamped (13 samples, 0.04%)dkn-compute`<&curve25519_dalek::montgomery::MontgomeryPoint as core::ops::arith::Mul<&curve25519_dalek::scalar::Scalar>>::mul (13 samples, 0.04%)dkn-compute`libp2p_noise::io::handshake::recv_identity::_{{closure}} (15 samples, 0.04%)dkn-compute`futures_util::stream::stream::StreamExt::poll_next_unpin (15 samples, 0.04%)dkn-compute`<asynchronous_codec::framed::Framed<T,U> as futures_sink::Sink<<U as asynchronous_codec::encoder::Encoder>::Item>>::poll_flush (4 samples, 0.01%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (4 samples, 0.01%)dkn-compute`<&mio::net::tcp::stream::TcpStream as std::io::Write>::write (4 samples, 0.01%)libsystem_kernel.dylib`__sendto (4 samples, 0.01%)dkn-compute`libp2p_noise::io::handshake::send_identity::_{{closure}} (10 samples, 0.03%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::handshakestate::HandshakeState> as asynchronous_codec::encoder::Encoder>::encode (6 samples, 0.02%)dkn-compute`snow::handshakestate::HandshakeState::write_message (6 samples, 0.02%)dkn-compute`<libp2p_noise::protocol::Keypair as snow::types::Dh>::dh (6 samples, 0.02%)dkn-compute`x25519_dalek::x25519::x25519 (6 samples, 0.02%)dkn-compute`curve25519_dalek::montgomery::MontgomeryPoint::mul_clamped (6 samples, 0.02%)dkn-compute`<&curve25519_dalek::montgomery::MontgomeryPoint as core::ops::arith::Mul<&curve25519_dalek::scalar::Scalar>>::mul (6 samples, 0.02%)dkn-compute`<libp2p_noise::protocol::Keypair as snow::types::Dh>::set (5 samples, 0.01%)dkn-compute`x25519_dalek::x25519::x25519 (5 samples, 0.01%)dkn-compute`curve25519_dalek::montgomery::MontgomeryPoint::mul_clamped (5 samples, 0.01%)dkn-compute`<&curve25519_dalek::montgomery::MontgomeryPoint as core::ops::arith::Mul<&curve25519_dalek::scalar::Scalar>>::mul (5 samples, 0.01%)dkn-compute`<libp2p_noise::Config as libp2p_core::upgrade::OutboundConnectionUpgrade<T>>::upgrade_outbound::_{{closure}} (55 samples, 0.15%)dkn-compute`snow::builder::Builder::build (7 samples, 0.02%)dkn-compute`<libp2p_core::upgrade::apply::OutboundUpgradeApply<C,U> as core::future::future::Future>::poll (57 samples, 0.16%)dkn-compute`<tokio::net::tcp::stream::TcpStream as core::convert::TryFrom<std::net::tcp::TcpStream>>::try_from (4 samples, 0.01%)dkn-compute`tokio::io::poll_evented::PollEvented<E>::new_with_interest (4 samples, 0.01%)dkn-compute`tokio::runtime::io::registration::Registration::new_with_interest_and_handle (4 samples, 0.01%)dkn-compute`tokio::runtime::io::driver::Handle::add_source (4 samples, 0.01%)libsystem_kernel.dylib`kevent (4 samples, 0.01%)dkn-compute`<libp2p_tcp::provider::tokio::Tcp as libp2p_tcp::provider::Provider>::new_stream::_{{closure}} (5 samples, 0.01%)dkn-compute`<libp2p_tcp::Transport<T> as libp2p_core::transport::Transport>::dial::_{{closure}} (96 samples, 0.26%)libsystem_kernel.dylib`__connect (89 samples, 0.24%)dkn-compute`<libp2p_core::transport::map::MapFuture<T,F> as core::future::future::Future>::poll (159 samples, 0.44%)libsystem_kernel.dylib`close (5 samples, 0.01%)dkn-compute`<futures_util::sink::send::Send<Si,Item> as core::future::future::Future>::poll (4 samples, 0.01%)dkn-compute`<libp2p_relay::priv_client::transport::Transport as libp2p_core::transport::Transport>::dial::_{{closure}} (6 samples, 0.02%)dkn-compute`<libp2p_core::transport::map::MapFuture<T,F> as core::future::future::Future>::poll (173 samples, 0.47%)dkn-compute`core::ptr::drop_in_place<core::option::Option<(libp2p_core::transport::upgrade::Builder<libp2p_relay::priv_client::transport::Transport>::authenticate<libp2p_relay::priv_client::Connection,libp2p_noise::io::Output<multistream_select::negotiated::Negotiated<libp2p_relay::priv_client::Connection>>,libp2p_noise::Config,libp2p_noise::Error>::{{closure}},libp2p_core::connection::ConnectedPoint)>> (6 samples, 0.02%)dkn-compute`<tokio::io::poll_evented::PollEvented<E> as core::ops::drop::Drop>::drop (4 samples, 0.01%)dkn-compute`tokio::runtime::io::driver::Handle::deregister_source (4 samples, 0.01%)libsystem_kernel.dylib`kevent (4 samples, 0.01%)dkn-compute`core::ptr::drop_in_place<<libp2p_tcp::Transport<libp2p_tcp::provider::tokio::Tcp> as libp2p_core::transport::Transport>::dial::{{closure}}> (13 samples, 0.04%)dkn-compute`core::ptr::drop_in_place<<libp2p_tcp::provider::tokio::Tcp as libp2p_tcp::provider::Provider>::new_stream::{{closure}}> (13 samples, 0.04%)libsystem_kernel.dylib`close (9 samples, 0.02%)dkn-compute`core::ptr::drop_in_place<either::Either<core::pin::Pin<alloc::boxed::Box<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<libp2p_tcp::provider::tokio::TcpStream,std::io::error::Error>+core::marker::Send>>>>,core::pin::Pin<alloc::boxed::Box<libp2p_core::transport::upgrade::Authenticate<libp2p_tcp::provider::tokio::TcpStream,libp2p_noise::Config>>>>> (14 samples, 0.04%)dkn-compute`core::ptr::drop_in_place$LT$libp2p_core..transport..map..MapFuture$LT$libp2p_core..either..EitherFuture$LT$libp2p_core..transport..map..MapFuture$LT$libp2p_core..transport..and_then..AndThenFuture$LT$libp2p_core..transport..and_then..AndThenFuture$LT$core..pin..Pin$LT$alloc..boxed..Box$LT$dyn$u20$core..future..future..Future$u2b$Output$u20$$u3d$$u20$core..result..Result$LT$libp2p_relay..priv_client..Connection$C$libp2p_relay..priv_client..transport..Error$GT$$u2b$core..marker..Send$GT$$GT$$C$libp2p_core..transport..upgrade..Builder$LT$libp2p_relay..priv_client..transport..Transport$GT$..authenticate$LT$libp2p_relay..priv_client..Connection$C$libp2p_noise..io..Output$LT$multistream_select..negotiated..Negotiated$LT$libp2p_relay..priv_client..Connection$GT$$GT$$C$libp2p_noise..Config$C$libp2p_noise..Error$GT$..$u7b$$u7b$closure$u7d$$u7d$$C$libp2p_core..transport..upgrade..Authenticate$LT$libp2p_relay..priv_client..Connection$C$libp2p_noise..Config$GT$$GT$$C$libp2p_core..transport..upgrade..Authenticated$LT$libp2 (24 samples, 0.07%)dkn-compute`core::ptr::drop_in_place$LT$futures_util..future..try_future..into_future..IntoFuture$LT$libp2p_core..transport..timeout..Timeout$LT$libp2p_core..transport..map..MapFuture$LT$libp2p_core..either..EitherFuture$LT$libp2p_core..transport..map..MapFuture$LT$libp2p_core..transport..and_then..AndThenFuture$LT$libp2p_core..transport..and_then..AndThenFuture$LT$core..pin..Pin$LT$alloc..boxed..Box$LT$dyn$u20$core..future..future..Future$u2b$Output$u20$$u3d$$u20$core..result..Result$LT$libp2p_relay..priv_client..Connection$C$libp2p_relay..priv_client..transport..Error$GT$$u2b$core..marker..Send$GT$$GT$$C$libp2p_core..transport..upgrade..Builder$LT$libp2p_relay..priv_client..transport..Transport$GT$..authenticate$LT$libp2p_relay..priv_client..Connection$C$libp2p_noise..io..Output$LT$multistream_select..negotiated..Negotiated$LT$libp2p_relay..priv_client..Connection$GT$$GT$$C$libp2p_noise..Config$C$libp2p_noise..Error$GT$..$u7b$$u7b$closure$u7d$$u7d$$C$libp2p_core..transport..upgrade..Authenticate$LT$libp2p_relay..priv_c2 (28 samples, 0.08%)dkn-compute`<futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll (204 samples, 0.56%)dkn-compute`<tracing::instrument::Instrumented<T> as core::future::future::Future>::poll (210 samples, 0.58%)dkn-compute`<futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll (207 samples, 0.57%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (212 samples, 0.58%)dkn-compute`<libp2p_swarm::connection::pool::concurrent_dial::ConcurrentDial as core::future::future::Future>::poll (213 samples, 0.58%)dkn-compute`alloc::sync::Arc<T,A>::drop_slow (14 samples, 0.04%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (19 samples, 0.05%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (5 samples, 0.01%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (5 samples, 0.01%)dkn-compute`<T as libp2p_swarm::upgrade::UpgradeInfoSend>::protocol_info (5 samples, 0.01%)dkn-compute`<T as libp2p_swarm::upgrade::InboundUpgradeSend>::upgrade_inbound (4 samples, 0.01%)dkn-compute`<T as libp2p_swarm::upgrade::InboundUpgradeSend>::upgrade_inbound (4 samples, 0.01%)dkn-compute`<core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::try_fold (4 samples, 0.01%)dkn-compute`libp2p_swarm::connection::StreamUpgrade<UserData,TOk,TErr>::new_inbound::_{{closure}} (13 samples, 0.04%)dkn-compute`multistream_select::listener_select::listener_select_proto (5 samples, 0.01%)dkn-compute`<core::iter::adapters::filter_map::FilterMap<I,F> as core::iter::traits::iterator::Iterator>::next (5 samples, 0.01%)dkn-compute`<multistream_select::dialer_select::DialerSelectFuture<R,I> as core::future::future::Future>::poll (17 samples, 0.05%)dkn-compute`<libp2p_swarm::connection::StreamUpgrade<UserData,TOk,TErr> as core::future::future::Future>::poll (50 samples, 0.14%)dkn-compute`libp2p_swarm::connection::StreamUpgrade<UserData,TOk,TErr>::new_outbound::_{{closure}} (30 samples, 0.08%)dkn-compute`<futures_timer::native::delay::Delay as core::ops::drop::Drop>::drop (9 samples, 0.02%)dkn-compute`futures_timer::native::global::raw_wake (9 samples, 0.02%)libdispatch.dylib`_dispatch_semaphore_signal_slow (9 samples, 0.02%)libsystem_kernel.dylib`semaphore_signal_trap (9 samples, 0.02%)dkn-compute`core::ptr::drop_in_place$LT$core..option..Option$LT$libp2p_swarm..connection..StreamUpgrade$LT$either..Either$LT$either..Either$LT$either..Either$LT$either..Either$LT$either..Either$LT$either..Either$LT$$LP$$RP$$C$void..Void$GT$$C$$LP$$RP$$GT$$C$$LP$$RP$$GT$$C$$LP$$RP$$GT$$C$$LP$$RP$$GT$$C$either..Either$LT$$LP$$RP$$C$void..Void$GT$$GT$$C$futures_util..future..either..Either$LT$futures_util..future..either..Either$LT$futures_util..future..either..Either$LT$futures_util..future..either..Either$LT$futures_util..future..either..Either$LT$futures_util..future..either..Either$LT$libp2p_swarm..stream..Stream$C$void..Void$GT$$C$$LP$asynchronous_codec..framed..Framed$LT$libp2p_swarm..stream..Stream$C$libp2p_gossipsub..protocol..GossipsubCodec$GT$$C$libp2p_gossipsub..types..PeerKind$RP$$GT$$C$asynchronous_codec..framed..Framed$LT$libp2p_swarm..stream..Stream$C$libp2p_kad..protocol..Codec$LT$libp2p_kad..protocol..KadRequestMsg$C$libp2p_kad..protocol..KadResponseMsg$GT$$GT$$GT$$C$futures_util..future..either..Either$LT$2 (10 samples, 0.03%)dkn-compute`core::ptr::drop_in_place$LT$$LT$futures_util..stream..futures_unordered..FuturesUnordered$LT$Fut$GT$$u20$as$u20$futures_core..stream..Stream$GT$..poll_next..Bomb$LT$libp2p_swarm..connection..StreamUpgrade$LT$either..Either$LT$either..Either$LT$either..Either$LT$either..Either$LT$either..Either$LT$either..Either$LT$$LP$$RP$$C$void..Void$GT$$C$$LP$$RP$$GT$$C$$LP$$RP$$GT$$C$$LP$$RP$$GT$$C$$LP$$RP$$GT$$C$either..Either$LT$$LP$$RP$$C$void..Void$GT$$GT$$C$futures_util..future..either..Either$LT$futures_util..future..either..Either$LT$futures_util..future..either..Either$LT$futures_util..future..either..Either$LT$futures_util..future..either..Either$LT$futures_util..future..either..Either$LT$libp2p_swarm..stream..Stream$C$void..Void$GT$$C$$LP$asynchronous_codec..framed..Framed$LT$libp2p_swarm..stream..Stream$C$libp2p_gossipsub..protocol..GossipsubCodec$GT$$C$libp2p_gossipsub..types..PeerKind$RP$$GT$$C$asynchronous_codec..framed..Framed$LT$libp2p_swarm..stream..Stream$C$libp2p_kad..protocol..Codec$LT$libp2p_kad..prot2 (11 samples, 0.03%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (232 samples, 0.64%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (123 samples, 0.34%)dkn-compute`<hashbrown::map::HashMap<K,V,S,A> as core::iter::traits::collect::Extend<(K,V)>>::extend (7 samples, 0.02%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (4 samples, 0.01%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_flush (5 samples, 0.01%)dkn-compute`<yamux::frame::io::Io<T> as futures_core::stream::Stream>::poll_next (7 samples, 0.02%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_flush (4 samples, 0.01%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_ready (6 samples, 0.02%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (14 samples, 0.04%)dkn-compute`tracing::span::Span::log (5 samples, 0.01%)dkn-compute`tracing::span::Span::log (25 samples, 0.07%)dkn-compute`tracing::span::Span::record_all (14 samples, 0.04%)dkn-compute`tracing::span::Span::log (5 samples, 0.01%)dkn-compute`tracing_core::span::Record::is_empty (5 samples, 0.01%)libsystem_malloc.dylib`_nanov2_free (6 samples, 0.02%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (26 samples, 0.07%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (35 samples, 0.10%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (4 samples, 0.01%)dkn-compute`<futures_channel::mpsc::Receiver<T> as futures_core::stream::Stream>::poll_next (45 samples, 0.12%)dkn-compute`<futures_util::stream::stream::into_future::StreamFuture<St> as core::future::future::Future>::poll (59 samples, 0.16%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (17 samples, 0.05%)dkn-compute`futures_util::stream::futures_unordered::FuturesUnordered<Fut>::push (9 samples, 0.02%)dkn-compute`futures_util::stream::futures_unordered::FuturesUnordered<Fut>::release_task (26 samples, 0.07%)libsystem_malloc.dylib`_nanov2_free (17 samples, 0.05%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (180 samples, 0.49%)libsystem_malloc.dylib`nanov2_malloc (8 samples, 0.02%)dkn-compute`<&mio::net::tcp::stream::TcpStream as std::io::Write>::write (20 samples, 0.05%)libsystem_kernel.dylib`__sendto (20 samples, 0.05%)dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (10 samples, 0.03%)dkn-compute`tokio::runtime::io::scheduled_io::ScheduledIo::poll_readiness (5 samples, 0.01%)dkn-compute`<asynchronous_codec::framed::Framed<T,U> as futures_sink::Sink<<U as asynchronous_codec::encoder::Encoder>::Item>>::poll_ready (38 samples, 0.10%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (36 samples, 0.10%)libdyld.dylib`tlv_get_addr (5 samples, 0.01%)dkn-compute`<&mio::net::tcp::stream::TcpStream as std::io::Write>::write (393 samples, 1.08%)libsystem_kernel.dylib`__sendto (392 samples, 1.07%)dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (8 samples, 0.02%)dkn-compute`<asynchronous_codec::framed_write::FramedWrite2<T> as futures_sink::Sink<<T as asynchronous_codec::encoder::Encoder>::Item>>::poll_flush (411 samples, 1.13%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (405 samples, 1.11%)dkn-compute`<snow::resolvers::ring::CipherChaChaPoly as snow::types::Cipher>::encrypt (106 samples, 0.29%)dkn-compute`ring::aead::chacha20_poly1305::chacha20_poly1305_seal (102 samples, 0.28%)dkn-compute`ring_core_0_17_8_chacha20_poly1305_seal (100 samples, 0.27%)dkn-compute`snow::transportstate::TransportState::write_message (112 samples, 0.31%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::transportstate::TransportState> as asynchronous_codec::encoder::Encoder>::encode (122 samples, 0.33%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_flush (581 samples, 1.59%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (4 samples, 0.01%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_write (17 samples, 0.05%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncRead>::poll_read (6 samples, 0.02%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncWrite>::poll_write (14 samples, 0.04%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncRead>::poll_read (9 samples, 0.02%)dkn-compute`<asynchronous_codec::framed_read::FramedRead2<T> as futures_core::stream::Stream>::poll_next (7 samples, 0.02%)dkn-compute`<bytes::bytes_mut::BytesMut as core::ops::drop::Drop>::drop (4 samples, 0.01%)dkn-compute`<snow::resolvers::ring::CipherChaChaPoly as snow::types::Cipher>::decrypt (9 samples, 0.02%)dkn-compute`bytes::bytes_mut::BytesMut::advance_unchecked (6 samples, 0.02%)dkn-compute`bytes::bytes_mut::BytesMut::split_to (8 samples, 0.02%)libsystem_malloc.dylib`small_free_list_remove_ptr (5 samples, 0.01%)libsystem_malloc.dylib`small_malloc_should_clear (11 samples, 0.03%)libsystem_malloc.dylib`small_malloc_from_free_list (11 samples, 0.03%)libsystem_malloc.dylib`set_tiny_meta_header_in_use (6 samples, 0.02%)libsystem_malloc.dylib`_tiny_check_and_zero_inline_meta_from_freelist (4 samples, 0.01%)libsystem_malloc.dylib`tiny_malloc_should_clear (85 samples, 0.23%)libsystem_malloc.dylib`tiny_malloc_from_free_list (70 samples, 0.19%)libsystem_malloc.dylib`tiny_free_list_add_ptr (28 samples, 0.08%)libsystem_platform.dylib`__bzero (5 samples, 0.01%)libsystem_malloc.dylib`szone_malloc_should_clear (126 samples, 0.35%)libsystem_platform.dylib`_platform_memset (13 samples, 0.04%)dkn-compute`bytes::bytes_mut::BytesMut::zeroed (147 samples, 0.40%)dkn-compute`bytes::bytes_mut::shared_v_drop (4 samples, 0.01%)dkn-compute`bytes::bytes_mut::BytesMut::advance_unchecked (6 samples, 0.02%)dkn-compute`libp2p_noise::io::framed::decode_length_prefixed (83 samples, 0.23%)dkn-compute`bytes::bytes_mut::BytesMut::split_to (20 samples, 0.05%)dkn-compute`ring::aead::chacha20_poly1305::chacha20_poly1305_open (14 samples, 0.04%)dkn-compute`0x0000000103492600 (4 samples, 0.01%)dkn-compute`ring::aead::chacha20_poly1305::chacha20_poly1305_open (1,231 samples, 3.37%)dkn..dkn-compute`ring_core_0_17_8_chacha20_poly1305_open (1,213 samples, 3.32%)dkn..dkn-compute`ring::aead::less_safe_key::open_within_ (1,260 samples, 3.45%)dkn..dkn-compute`<snow::resolvers::ring::CipherChaChaPoly as snow::types::Cipher>::decrypt (1,303 samples, 3.57%)dkn-..dkn-compute`ring_core_0_17_8_CRYPTO_memcmp (9 samples, 0.02%)dkn-compute`snow::transportstate::TransportState::read_message (1,351 samples, 3.70%)dkn-..libsystem_platform.dylib`_platform_memmove (38 samples, 0.10%)libsystem_malloc.dylib`_malloc_zone_calloc (16 samples, 0.04%)libsystem_malloc.dylib`_malloc_zone_malloc (6 samples, 0.02%)libsystem_malloc.dylib`nanov2_malloc (20 samples, 0.05%)libsystem_malloc.dylib`szone_calloc (10 samples, 0.03%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::transportstate::TransportState> as asynchronous_codec::decoder::Decoder>::decode (1,715 samples, 4.70%)dkn-c..dkn-compute`<libp2p_tcp::provider::tokio::TcpStream as futures_io::if_std::AsyncRead>::poll_read (4 samples, 0.01%)dkn-compute`<&mio::net::tcp::stream::TcpStream as std::io::Read>::read (2,663 samples, 7.30%)dkn-comput..libsystem_kernel.dylib`__recvfrom (2,653 samples, 7.27%)libsystem_..dkn-compute`tokio::runtime::io::scheduled_io::ScheduledIo::poll_readiness (28 samples, 0.08%)dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (51 samples, 0.14%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_read_priv (2,758 samples, 7.56%)dkn-comput..libdyld.dylib`tlv_get_addr (17 samples, 0.05%)dkn-compute`<libp2p_tcp::provider::tokio::TcpStream as futures_io::if_std::AsyncRead>::poll_read (2,771 samples, 7.59%)dkn-comput..dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncRead>::poll_read (2,809 samples, 7.70%)dkn-compute..dkn-compute`tokio::net::tcp::stream::TcpStream::poll_read_priv (7 samples, 0.02%)dkn-compute`bytes::bytes_mut::shared_v_drop (8 samples, 0.02%)dkn-compute`snow::transportstate::TransportState::read_message (11 samples, 0.03%)dkn-compute`<asynchronous_codec::framed_read::FramedRead2<T> as futures_core::stream::Stream>::poll_next (4,588 samples, 12.57%)dkn-compute`<asynch..libsystem_platform.dylib`_platform_memmove (4 samples, 0.01%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::transportstate::TransportState> as asynchronous_codec::decoder::Decoder>::decode (7 samples, 0.02%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncRead>::poll_read (5 samples, 0.01%)dkn-compute`DYLD-STUB$$free (8 samples, 0.02%)dkn-compute`__rdl_dealloc (10 samples, 0.03%)libsystem_malloc.dylib`_nanov2_free (4 samples, 0.01%)libsystem_malloc.dylib`_szone_free (11 samples, 0.03%)libsystem_malloc.dylib`free_small (6 samples, 0.02%)libsystem_malloc.dylib`get_tiny_previous_free_msize (6 samples, 0.02%)libsystem_malloc.dylib`tiny_free_list_add_ptr (16 samples, 0.04%)libsystem_malloc.dylib`free_tiny (62 samples, 0.17%)libsystem_malloc.dylib`tiny_free_no_lock (40 samples, 0.11%)libsystem_malloc.dylib`tiny_free_list_remove_ptr (6 samples, 0.02%)dkn-compute`bytes::bytes_mut::shared_v_drop (142 samples, 0.39%)libsystem_platform.dylib`_platform_memset (6 samples, 0.02%)libsystem_malloc.dylib`_nanov2_free (23 samples, 0.06%)libsystem_malloc.dylib`_szone_free (4 samples, 0.01%)libsystem_malloc.dylib`free (10 samples, 0.03%)libsystem_platform.dylib`__bzero (4 samples, 0.01%)libsystem_platform.dylib`_platform_memmove (82 samples, 0.22%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncRead>::poll_read (5,354 samples, 14.67%)dkn-compute`<libp2p_no..libsystem_platform.dylib`_platform_memset (421 samples, 1.15%)dkn-compute`DYLD-STUB$$free (5 samples, 0.01%)dkn-compute`bytes::bytes::static_drop (5 samples, 0.01%)libsystem_malloc.dylib`free (5 samples, 0.01%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncRead>::poll_read (5,438 samples, 14.90%)dkn-compute`<multistrea..libsystem_platform.dylib`_platform_memmove (38 samples, 0.10%)libsystem_malloc.dylib`small_malloc_should_clear (7 samples, 0.02%)libsystem_malloc.dylib`small_malloc_from_free_list (6 samples, 0.02%)libsystem_malloc.dylib`set_tiny_meta_header_in_use (10 samples, 0.03%)libsystem_malloc.dylib`_tiny_check_and_zero_inline_meta_from_freelist (25 samples, 0.07%)libsystem_malloc.dylib`tiny_malloc_should_clear (146 samples, 0.40%)libsystem_malloc.dylib`tiny_malloc_from_free_list (118 samples, 0.32%)libsystem_malloc.dylib`tiny_free_list_add_ptr (21 samples, 0.06%)libsystem_malloc.dylib`szone_malloc_should_clear (171 samples, 0.47%)libsystem_platform.dylib`_platform_memset (15 samples, 0.04%)dkn-compute`<yamux::frame::io::Io<T> as futures_core::stream::Stream>::poll_next (5,742 samples, 15.74%)dkn-compute`<yamux::fram..dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (31 samples, 0.08%)dkn-compute`tokio::runtime::io::scheduled_io::ScheduledIo::poll_readiness (9 samples, 0.02%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (56 samples, 0.15%)libdyld.dylib`tlv_get_addr (21 samples, 0.06%)dkn-compute`<asynchronous_codec::framed::Framed<T,U> as futures_sink::Sink<<U as asynchronous_codec::encoder::Encoder>::Item>>::poll_ready (68 samples, 0.19%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_write (76 samples, 0.21%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_flush (115 samples, 0.32%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_ready (103 samples, 0.28%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncWrite>::poll_write (4 samples, 0.01%)dkn-compute`<asynchronous_codec::framed::Framed<T,U> as futures_sink::Sink<<U as asynchronous_codec::encoder::Encoder>::Item>>::poll_ready (9 samples, 0.02%)dkn-compute`<&mio::net::tcp::stream::TcpStream as std::io::Write>::write (407 samples, 1.12%)libsystem_kernel.dylib`__sendto (407 samples, 1.12%)dkn-compute`tokio::runtime::io::scheduled_io::ScheduledIo::poll_readiness (32 samples, 0.09%)dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (55 samples, 0.15%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (495 samples, 1.36%)libdyld.dylib`tlv_get_addr (20 samples, 0.05%)dkn-compute`<asynchronous_codec::framed::Framed<T,U> as futures_sink::Sink<<U as asynchronous_codec::encoder::Encoder>::Item>>::poll_ready (514 samples, 1.41%)dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (4 samples, 0.01%)dkn-compute`<snow::resolvers::ring::CipherChaChaPoly as snow::types::Cipher>::encrypt (424 samples, 1.16%)dkn-compute`ring::aead::chacha20_poly1305::chacha20_poly1305_seal (423 samples, 1.16%)dkn-compute`ring_core_0_17_8_chacha20_poly1305_seal (422 samples, 1.16%)dkn-compute`snow::transportstate::TransportState::write_message (444 samples, 1.22%)libsystem_platform.dylib`_platform_memmove (19 samples, 0.05%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::transportstate::TransportState> as asynchronous_codec::encoder::Encoder>::encode (457 samples, 1.25%)libsystem_platform.dylib`_platform_memmove (7 samples, 0.02%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_write (1,024 samples, 2.81%)dk..dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (4 samples, 0.01%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncWrite>::poll_write (19 samples, 0.05%)libsystem_malloc.dylib`_szone_free (9 samples, 0.02%)libsystem_malloc.dylib`tiny_free_list_add_ptr (17 samples, 0.05%)libsystem_malloc.dylib`free_tiny (53 samples, 0.15%)libsystem_malloc.dylib`tiny_free_no_lock (33 samples, 0.09%)libsystem_malloc.dylib`tiny_free_list_remove_ptr (6 samples, 0.02%)libsystem_platform.dylib`_platform_memmove (25 samples, 0.07%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_ready (1,220 samples, 3.34%)dkn..libsystem_platform.dylib`_platform_memset (15 samples, 0.04%)dkn-compute`yamux::chunks::Chunks::push (6 samples, 0.02%)libsystem_c.dylib`clock_gettime_nsec_np (10 samples, 0.03%)libsystem_kernel.dylib`mach_absolute_time (6 samples, 0.02%)dkn-compute`std::sys::pal::unix::time::Timespec::now (58 samples, 0.16%)libsystem_c.dylib`clock_gettime (49 samples, 0.13%)libsystem_kernel.dylib`mach_timebase_info (4 samples, 0.01%)dkn-compute`yamux::connection::rtt::Rtt::next_ping (79 samples, 0.22%)libsystem_malloc.dylib`_nanov2_free (4 samples, 0.01%)libsystem_malloc.dylib`free (6 samples, 0.02%)dkn-compute`yamux::connection::Connection<T>::poll_next_inbound (8,165 samples, 22.38%)dkn-compute`yamux::connection::Conn..dkn-compute`<libp2p_yamux::Muxer<C> as libp2p_core::muxing::StreamMuxer>::poll (8,477 samples, 23.23%)dkn-compute`<libp2p_yamux::Muxer<C> a..libsystem_platform.dylib`_platform_memmove (129 samples, 0.35%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (5 samples, 0.01%)dkn-compute`tracing::span::Span::log (11 samples, 0.03%)dkn-compute`<libp2p_core::muxing::boxed::Wrap<T> as libp2p_core::muxing::StreamMuxer>::poll (8,503 samples, 23.30%)dkn-compute`<libp2p_core::muxing::box..dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (22 samples, 0.06%)dkn-compute`tracing::span::Span::log (10 samples, 0.03%)dkn-compute`tracing::span::Span::log (22 samples, 0.06%)dkn-compute`tracing::span::Span::record_all (25 samples, 0.07%)dkn-compute`tracing::span::Span::log (10 samples, 0.03%)dkn-compute`tracing_core::span::Record::is_empty (5 samples, 0.01%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_flush (7 samples, 0.02%)dkn-compute`libp2p_noise::io::framed::decode_length_prefixed (13 samples, 0.04%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::transportstate::TransportState> as asynchronous_codec::decoder::Decoder>::decode (23 samples, 0.06%)dkn-compute`<&mio::net::tcp::stream::TcpStream as std::io::Read>::read (5 samples, 0.01%)libsystem_kernel.dylib`__recvfrom (5 samples, 0.01%)dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (21 samples, 0.06%)dkn-compute`tokio::runtime::io::scheduled_io::ScheduledIo::poll_readiness (5 samples, 0.01%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_read_priv (40 samples, 0.11%)libdyld.dylib`tlv_get_addr (12 samples, 0.03%)dkn-compute`<libp2p_tcp::provider::tokio::TcpStream as futures_io::if_std::AsyncRead>::poll_read (43 samples, 0.12%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncRead>::poll_read (64 samples, 0.18%)dkn-compute`<asynchronous_codec::framed_read::FramedRead2<T> as futures_core::stream::Stream>::poll_next (104 samples, 0.29%)dkn-compute`<yamux::frame::io::Io<T> as futures_core::stream::Stream>::poll_next (416 samples, 1.14%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncRead>::poll_read (409 samples, 1.12%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncRead>::poll_read (398 samples, 1.09%)libsystem_platform.dylib`_platform_memset (284 samples, 0.78%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_write (4 samples, 0.01%)dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (13 samples, 0.04%)dkn-compute`tokio::runtime::io::scheduled_io::ScheduledIo::poll_readiness (6 samples, 0.02%)dkn-compute`<asynchronous_codec::framed::Framed<T,U> as futures_sink::Sink<<U as asynchronous_codec::encoder::Encoder>::Item>>::poll_ready (25 samples, 0.07%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (23 samples, 0.06%)libdyld.dylib`tlv_get_addr (7 samples, 0.02%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_write (32 samples, 0.09%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_flush (59 samples, 0.16%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_ready (51 samples, 0.14%)dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (19 samples, 0.05%)dkn-compute`tokio::runtime::io::scheduled_io::ScheduledIo::poll_readiness (6 samples, 0.02%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (29 samples, 0.08%)libdyld.dylib`tlv_get_addr (7 samples, 0.02%)dkn-compute`<asynchronous_codec::framed::Framed<T,U> as futures_sink::Sink<<U as asynchronous_codec::encoder::Encoder>::Item>>::poll_ready (34 samples, 0.09%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_write (39 samples, 0.11%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_ready (55 samples, 0.15%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncWrite>::poll_write (4 samples, 0.01%)dkn-compute`yamux::connection::Connection<T>::poll_next_inbound (599 samples, 1.64%)dkn-compute`yamux::connection::rtt::Rtt::next_ping (11 samples, 0.03%)dkn-compute`std::sys::pal::unix::time::Timespec::now (11 samples, 0.03%)libsystem_c.dylib`clock_gettime (11 samples, 0.03%)dkn-compute`<libp2p_yamux::Muxer<C> as libp2p_core::muxing::StreamMuxer>::poll_inbound (821 samples, 2.25%)d..libsystem_platform.dylib`_platform_memmove (94 samples, 0.26%)dkn-compute`tokio::runtime::task::waker::clone_waker (5 samples, 0.01%)dkn-compute`tokio::runtime::task::waker::drop_waker (13 samples, 0.04%)dkn-compute`tracing::span::Span::record_all (4 samples, 0.01%)dkn-compute`<libp2p_core::muxing::boxed::Wrap<T> as libp2p_core::muxing::StreamMuxer>::poll_inbound (850 samples, 2.33%)d..dkn-compute`yamux::connection::Connection<T>::poll_new_outbound (8 samples, 0.02%)dkn-compute`<libp2p_yamux::Muxer<C> as libp2p_core::muxing::StreamMuxer>::poll_outbound (10 samples, 0.03%)dkn-compute`<libp2p_core::muxing::boxed::Wrap<T> as libp2p_core::muxing::StreamMuxer>::poll_outbound (12 samples, 0.03%)dkn-compute`<libp2p_gossipsub::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::poll (5 samples, 0.01%)dkn-compute`<libp2p_kad::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::poll (8 samples, 0.02%)dkn-compute`<libp2p_request_response::handler::Handler<TCodec> as libp2p_swarm::handler::ConnectionHandler>::poll (5 samples, 0.01%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::listen_protocol (4 samples, 0.01%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::on_connection_event (9 samples, 0.02%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::on_connection_event (7 samples, 0.02%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::on_connection_event (4 samples, 0.01%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::on_connection_event (4 samples, 0.01%)dkn-compute`<futures_timer::native::delay::Delay as core::future::future::Future>::poll (5 samples, 0.01%)dkn-compute`<asynchronous_codec::framed_read::FramedRead2<T> as futures_core::stream::Stream>::poll_next (5 samples, 0.01%)dkn-compute`<asynchronous_codec::framed_write::FramedWrite2<T> as futures_sink::Sink<<T as asynchronous_codec::encoder::Encoder>::Item>>::poll_flush (6 samples, 0.02%)dkn-compute`core::ptr::drop_in_place<core::option::Option<libp2p_gossipsub::handler::OutboundSubstreamState>> (5 samples, 0.01%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (22 samples, 0.06%)dkn-compute`tracing::span::Span::log (11 samples, 0.03%)dkn-compute`<alloc::vec::into_iter::IntoIter<T,A> as core::ops::drop::Drop>::drop (4 samples, 0.01%)dkn-compute`<bytes::bytes_mut::BytesMut as core::ops::drop::Drop>::drop (4 samples, 0.01%)dkn-compute`quick_protobuf::reader::BytesReader::read_bytes (38 samples, 0.10%)dkn-compute`quick_protobuf::reader::BytesReader::read_string (33 samples, 0.09%)dkn-compute`core::str::converts::from_utf8 (15 samples, 0.04%)dkn-compute`quick_protobuf::reader::BytesReader::read_varint32 (15 samples, 0.04%)libsystem_malloc.dylib`nanov2_allocate_outlined (39 samples, 0.11%)libsystem_malloc.dylib`nanov2_find_block_and_allocate (35 samples, 0.10%)libsystem_kernel.dylib`__ulock_wait (4 samples, 0.01%)libsystem_kernel.dylib`__ulock_wake (7 samples, 0.02%)libsystem_malloc.dylib`set_tiny_meta_header_in_use (6 samples, 0.02%)libsystem_malloc.dylib`_tiny_check_and_zero_inline_meta_from_freelist (17 samples, 0.05%)libsystem_malloc.dylib`tiny_malloc_from_free_list (56 samples, 0.15%)libsystem_malloc.dylib`tiny_free_list_add_ptr (7 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_should_clear (87 samples, 0.24%)libsystem_malloc.dylib`szone_malloc_should_clear (97 samples, 0.27%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::Message as quick_protobuf::message::MessageRead>::from_reader (353 samples, 0.97%)dkn-compute`__rdl_alloc (6 samples, 0.02%)libsystem_kernel.dylib`__ulock_wait (15 samples, 0.04%)libsystem_malloc.dylib`set_tiny_meta_header_in_use (7 samples, 0.02%)libsystem_malloc.dylib`szone_malloc_should_clear (78 samples, 0.21%)libsystem_malloc.dylib`tiny_malloc_should_clear (74 samples, 0.20%)libsystem_malloc.dylib`tiny_malloc_from_free_list (36 samples, 0.10%)libsystem_malloc.dylib`tiny_free_list_add_ptr (11 samples, 0.03%)dkn-compute`alloc::raw_vec::finish_grow (89 samples, 0.24%)libsystem_malloc.dylib`_malloc_zone_malloc (5 samples, 0.01%)dkn-compute`alloc::raw_vec::RawVec<T,A>::grow_one (103 samples, 0.28%)dkn-compute`quick_protobuf::reader::BytesReader::read_bytes (4 samples, 0.01%)dkn-compute`quick_protobuf::reader::BytesReader::read_varint32 (9 samples, 0.02%)libsystem_malloc.dylib`_malloc_zone_malloc (21 samples, 0.06%)libsystem_malloc.dylib`malloc (5 samples, 0.01%)libsystem_malloc.dylib`nanov2_malloc (136 samples, 0.37%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::RPC as quick_protobuf::message::MessageRead>::from_reader (768 samples, 2.10%)d..libsystem_platform.dylib`_platform_memmove (54 samples, 0.15%)dkn-compute`bytes::bytes_mut::BytesMut::advance_unchecked (6 samples, 0.02%)dkn-compute`bytes::bytes_mut::BytesMut::split_to (14 samples, 0.04%)dkn-compute`quick_protobuf::reader::BytesReader::read_uint32 (5 samples, 0.01%)dkn-compute`<quick_protobuf_codec::Codec<In,Out> as asynchronous_codec::decoder::Decoder>::decode (856 samples, 2.35%)d..dkn-compute`quick_protobuf::reader::BytesReader::read_varint32 (6 samples, 0.02%)dkn-compute`__rdl_dealloc (4 samples, 0.01%)dkn-compute`alloc::vec::in_place_collect::from_iter_in_place (10 samples, 0.03%)libsystem_malloc.dylib`_nanov2_free (35 samples, 0.10%)libsystem_malloc.dylib`_szone_free (6 samples, 0.02%)libsystem_malloc.dylib`get_tiny_previous_free_msize (8 samples, 0.02%)libsystem_malloc.dylib`tiny_free_list_add_ptr (14 samples, 0.04%)libsystem_malloc.dylib`free_tiny (87 samples, 0.24%)libsystem_malloc.dylib`tiny_free_no_lock (53 samples, 0.15%)libsystem_malloc.dylib`tiny_free_list_remove_ptr (6 samples, 0.02%)dkn-compute`<libp2p_gossipsub::protocol::GossipsubCodec as asynchronous_codec::decoder::Decoder>::decode (1,130 samples, 3.10%)dkn..libsystem_platform.dylib`_platform_memset (16 samples, 0.04%)dkn-compute`futures_channel::mpsc::BoundedSenderInner<T>::poll_unparked (4 samples, 0.01%)dkn-compute`yamux::connection::stream::Stream::send_window_update (48 samples, 0.13%)libsystem_malloc.dylib`_szone_free (14 samples, 0.04%)libsystem_kernel.dylib`__ulock_wait (4 samples, 0.01%)libsystem_malloc.dylib`get_tiny_previous_free_msize (5 samples, 0.01%)libsystem_malloc.dylib`tiny_free_list_add_ptr (6 samples, 0.02%)libsystem_malloc.dylib`tiny_free_list_add_ptr (22 samples, 0.06%)libsystem_malloc.dylib`free_tiny (109 samples, 0.30%)libsystem_malloc.dylib`tiny_free_no_lock (75 samples, 0.21%)libsystem_malloc.dylib`tiny_free_list_remove_ptr (14 samples, 0.04%)dkn-compute`<yamux::connection::stream::Stream as futures_io::if_std::AsyncRead>::poll_read (270 samples, 0.74%)dkn-compute`tokio::runtime::task::waker::drop_waker (8 samples, 0.02%)libsystem_malloc.dylib`_szone_free (7 samples, 0.02%)libsystem_malloc.dylib`free (9 samples, 0.02%)dkn-compute`<libp2p_swarm::stream::Stream as futures_io::if_std::AsyncRead>::poll_read (343 samples, 0.94%)libsystem_platform.dylib`_platform_memmove (32 samples, 0.09%)dkn-compute`<libp2p_yamux::Stream as futures_io::if_std::AsyncRead>::poll_read (39 samples, 0.11%)dkn-compute`<quick_protobuf_codec::Codec<In,Out> as asynchronous_codec::decoder::Decoder>::decode (12 samples, 0.03%)dkn-compute`DYLD-STUB$$free (10 samples, 0.03%)libsystem_malloc.dylib`_nanov2_free (5 samples, 0.01%)libsystem_malloc.dylib`_szone_free (9 samples, 0.02%)libsystem_malloc.dylib`free (25 samples, 0.07%)dkn-compute`<asynchronous_codec::framed_read::FramedRead2<T> as futures_core::stream::Stream>::poll_next (1,668 samples, 4.57%)dkn-c..libsystem_malloc.dylib`nanov2_malloc (41 samples, 0.11%)dkn-compute`<libp2p_swarm::stream::Stream as futures_io::if_std::AsyncWrite>::poll_flush (28 samples, 0.08%)dkn-compute`<libp2p_swarm::stream::Stream as futures_io::if_std::AsyncWrite>::poll_write (5 samples, 0.01%)libsystem_pthread.dylib`pthread_mutex_lock (16 samples, 0.04%)dkn-compute`futures_channel::mpsc::BoundedSenderInner<T>::poll_unparked (35 samples, 0.10%)libsystem_pthread.dylib`pthread_mutex_unlock (4 samples, 0.01%)dkn-compute`tokio::runtime::task::waker::drop_waker (16 samples, 0.04%)libsystem_pthread.dylib`pthread_mutex_lock (5 samples, 0.01%)dkn-compute`<yamux::connection::stream::Stream as futures_io::if_std::AsyncWrite>::poll_flush (63 samples, 0.17%)dkn-compute`futures_channel::mpsc::BoundedSenderInner<T>::poll_unparked (8 samples, 0.02%)dkn-compute`futures_channel::mpsc::BoundedSenderInner<T>::poll_unparked (5 samples, 0.01%)dkn-compute`futures_channel::mpsc::Sender<T>::start_send (23 samples, 0.06%)libsystem_malloc.dylib`nanov2_malloc (13 samples, 0.04%)libsystem_malloc.dylib`set_tiny_meta_header_in_use (4 samples, 0.01%)libsystem_malloc.dylib`_tiny_check_and_zero_inline_meta_from_freelist (7 samples, 0.02%)dkn-compute`<yamux::connection::stream::Stream as futures_io::if_std::AsyncWrite>::poll_write (127 samples, 0.35%)libsystem_malloc.dylib`szone_malloc_should_clear (62 samples, 0.17%)libsystem_malloc.dylib`tiny_malloc_should_clear (57 samples, 0.16%)libsystem_malloc.dylib`tiny_malloc_from_free_list (45 samples, 0.12%)libsystem_malloc.dylib`tiny_free_list_add_ptr (15 samples, 0.04%)dkn-compute`futures_channel::mpsc::BoundedSenderInner<T>::poll_unparked (6 samples, 0.02%)dkn-compute`<asynchronous_codec::framed_write::FramedWrite2<T> as futures_sink::Sink<<T as asynchronous_codec::encoder::Encoder>::Item>>::poll_flush (272 samples, 0.75%)libsystem_platform.dylib`_platform_memmove (14 samples, 0.04%)dkn-compute`<asynchronous_codec::framed_write::FramedWrite2<T> as futures_sink::Sink<<T as asynchronous_codec::encoder::Encoder>::Item>>::poll_ready (4 samples, 0.01%)dkn-compute`<libp2p_core::muxing::boxed::SubstreamBox as futures_io::if_std::AsyncWrite>::poll_flush (4 samples, 0.01%)dkn-compute`<libp2p_core::muxing::boxed::SubstreamBox as futures_io::if_std::AsyncWrite>::poll_write (4 samples, 0.01%)dkn-compute`<libp2p_gossipsub::protocol::GossipsubCodec as asynchronous_codec::decoder::Decoder>::decode (16 samples, 0.04%)dkn-compute`<libp2p_swarm::stream::Stream as futures_io::if_std::AsyncRead>::poll_read (4 samples, 0.01%)dkn-compute`<libp2p_yamux::Stream as futures_io::if_std::AsyncWrite>::poll_flush (32 samples, 0.09%)dkn-compute`<libp2p_yamux::Stream as futures_io::if_std::AsyncWrite>::poll_write (5 samples, 0.01%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::Message as quick_protobuf::message::MessageWrite>::get_size (76 samples, 0.21%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::RPC as quick_protobuf::message::MessageWrite>::get_size (86 samples, 0.24%)dkn-compute`quick_protobuf::sizeofs::sizeof_len (5 samples, 0.01%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::ControlMessage as quick_protobuf::message::MessageWrite>::write_message (5 samples, 0.01%)dkn-compute`quick_protobuf::writer::Writer<W>::write_with_tag (5 samples, 0.01%)dkn-compute`<bytes::bytes_mut::BytesMut as bytes::buf::buf_mut::BufMut>::put_slice (12 samples, 0.03%)dkn-compute`<quick_protobuf_codec::BytesMutWriterBackend as quick_protobuf::writer::WriterBackend>::pb_write_all (108 samples, 0.30%)libsystem_platform.dylib`_platform_memmove (61 samples, 0.17%)dkn-compute`<bytes::bytes_mut::BytesMut as bytes::buf::buf_mut::BufMut>::put_slice (7 samples, 0.02%)dkn-compute`<bytes::bytes_mut::BytesMut as bytes::buf::buf_mut::BufMut>::put_slice (13 samples, 0.04%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::Message as quick_protobuf::message::MessageWrite>::write_message (242 samples, 0.66%)dkn-compute`quick_protobuf::writer::Writer<W>::write_with_tag (107 samples, 0.29%)dkn-compute`<quick_protobuf_codec::BytesMutWriterBackend as quick_protobuf::writer::WriterBackend>::pb_write_u8 (28 samples, 0.08%)libsystem_platform.dylib`_platform_memmove (12 samples, 0.03%)dkn-compute`<bytes::bytes_mut::BytesMut as bytes::buf::buf_mut::BufMut>::put_slice (5 samples, 0.01%)dkn-compute`<quick_protobuf_codec::BytesMutWriterBackend as quick_protobuf::writer::WriterBackend>::pb_write_u8 (11 samples, 0.03%)libsystem_platform.dylib`_platform_memmove (5 samples, 0.01%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::RPC as quick_protobuf::message::MessageWrite>::write_message (285 samples, 0.78%)dkn-compute`quick_protobuf::writer::Writer<W>::write_with_tag (32 samples, 0.09%)dkn-compute`core::ptr::drop_in_place<core::option::Option<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::ControlMessage>> (6 samples, 0.02%)dkn-compute`DYLD-STUB$$free (15 samples, 0.04%)libsystem_malloc.dylib`_nanov2_free (39 samples, 0.11%)libsystem_malloc.dylib`_szone_free (5 samples, 0.01%)libsystem_malloc.dylib`free_small (8 samples, 0.02%)libsystem_malloc.dylib`small_free_list_remove_ptr_no_clear (5 samples, 0.01%)libsystem_malloc.dylib`tiny_free_list_add_ptr (9 samples, 0.02%)libsystem_malloc.dylib`tiny_free_list_add_ptr (23 samples, 0.06%)libsystem_malloc.dylib`tiny_free_list_remove_ptr (28 samples, 0.08%)libsystem_malloc.dylib`free_tiny (154 samples, 0.42%)libsystem_malloc.dylib`tiny_free_no_lock (85 samples, 0.23%)dkn-compute`core::ptr::drop_in_place<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::Message> (222 samples, 0.61%)libsystem_malloc.dylib`_nanov2_free (41 samples, 0.11%)libsystem_malloc.dylib`_szone_free (7 samples, 0.02%)libsystem_malloc.dylib`free (52 samples, 0.14%)dkn-compute`core::ptr::drop_in_place<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::RPC> (343 samples, 0.94%)dkn-compute`<quick_protobuf_codec::Codec<In,Out> as asynchronous_codec::encoder::Encoder>::encode (732 samples, 2.01%)d..libsystem_malloc.dylib`free (4 samples, 0.01%)dkn-compute`<yamux::connection::stream::Stream as futures_io::if_std::AsyncWrite>::poll_flush (20 samples, 0.05%)dkn-compute`core::ptr::drop_in_place<core::option::Option<libp2p_gossipsub::handler::OutboundSubstreamState>> (16 samples, 0.04%)libsystem_malloc.dylib`malloc_zone_realloc (17 samples, 0.05%)libsystem_malloc.dylib`szone_realloc (13 samples, 0.04%)libsystem_malloc.dylib`medium_size (6 samples, 0.02%)libsystem_malloc.dylib`nanov2_realloc (9 samples, 0.02%)dkn-compute`smallvec::SmallVec<A>::shrink_to_fit (55 samples, 0.15%)dkn-compute`smallvec::SmallVec<A>::try_grow (55 samples, 0.15%)libsystem_malloc.dylib`realloc (52 samples, 0.14%)libsystem_malloc.dylib`szone_size (14 samples, 0.04%)libsystem_malloc.dylib`tiny_size (7 samples, 0.02%)libsystem_c.dylib`clock_gettime_nsec_np (16 samples, 0.04%)libsystem_kernel.dylib`mach_timebase_info (6 samples, 0.02%)libsystem_kernel.dylib`mach_absolute_time (17 samples, 0.05%)libsystem_c.dylib`clock_gettime (74 samples, 0.20%)libsystem_kernel.dylib`mach_timebase_info (6 samples, 0.02%)dkn-compute`std::sys::pal::unix::time::Timespec::now (87 samples, 0.24%)libsystem_platform.dylib`__bzero (7 samples, 0.02%)libsystem_platform.dylib`_platform_memmove (87 samples, 0.24%)dkn-compute`libp2p_gossipsub::handler::EnabledHandler::poll (3,704 samples, 10.15%)dkn-compute`lib..libsystem_platform.dylib`_platform_memset (446 samples, 1.22%)dkn-compute`tracing::span::Span::log (31 samples, 0.08%)dkn-compute`tracing::span::Span::record_all (35 samples, 0.10%)dkn-compute`tracing::span::Span::log (14 samples, 0.04%)dkn-compute`tracing_core::span::Record::is_empty (9 samples, 0.02%)dkn-compute`<libp2p_gossipsub::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::poll (3,962 samples, 10.86%)dkn-compute`<lib..libsystem_platform.dylib`_platform_memmove (59 samples, 0.16%)dkn-compute`<futures_timer::native::delay::Delay as core::future::future::Future>::poll (27 samples, 0.07%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (4 samples, 0.01%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (20 samples, 0.05%)dkn-compute`tracing::span::Span::log (4 samples, 0.01%)dkn-compute`futures_bounded::futures_map::FuturesMap<ID,O>::poll_unpin (53 samples, 0.15%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (50 samples, 0.14%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (36 samples, 0.10%)dkn-compute`tokio::runtime::task::waker::clone_waker (7 samples, 0.02%)dkn-compute`tokio::runtime::task::waker::drop_waker (45 samples, 0.12%)dkn-compute`tracing::span::Span::log (19 samples, 0.05%)dkn-compute`tracing::span::Span::record_all (20 samples, 0.05%)dkn-compute`tracing::span::Span::log (12 samples, 0.03%)dkn-compute`tracing_core::span::Record::is_empty (4 samples, 0.01%)dkn-compute`<libp2p_identify::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::poll (249 samples, 0.68%)libsystem_platform.dylib`_platform_memmove (7 samples, 0.02%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (15 samples, 0.04%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold (8 samples, 0.02%)libsystem_malloc.dylib`nanov2_malloc (6 samples, 0.02%)dkn-compute`alloc::vec::in_place_collect::_<impl alloc::vec::spec_from_iter::SpecFromIter<T,I> for alloc::vec::Vec<T>>::from_iter (10 samples, 0.03%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::try_fold (12 samples, 0.03%)dkn-compute`<futures_util::stream::stream::into_future::StreamFuture<St> as core::future::future::Future>::poll (22 samples, 0.06%)dkn-compute`<libp2p_kad::handler::InboundSubstreamState as futures_core::stream::Stream>::poll_next (22 samples, 0.06%)dkn-compute`libp2p_kad::protocol::resp_msg_to_proto (13 samples, 0.04%)dkn-compute`alloc::vec::in_place_collect::from_iter_in_place (13 samples, 0.04%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (23 samples, 0.06%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (85 samples, 0.23%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (77 samples, 0.21%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (17 samples, 0.05%)dkn-compute`tracing::span::Span::log (8 samples, 0.02%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (33 samples, 0.09%)dkn-compute`<multiaddr::Multiaddr as core::convert::TryFrom<alloc::vec::Vec<u8>>>::try_from (7 samples, 0.02%)dkn-compute`multiaddr::protocol::Protocol::from_bytes (4 samples, 0.01%)dkn-compute`multiaddr::Multiaddr::with_p2p (7 samples, 0.02%)dkn-compute`multiaddr::protocol::Protocol::from_bytes (6 samples, 0.02%)dkn-compute`<libp2p_kad::protocol::KadResponseMsg as core::convert::TryFrom<libp2p_kad::proto::dht::pb::Message>>::try_from (17 samples, 0.05%)dkn-compute`alloc::vec::in_place_collect::_<impl alloc::vec::spec_from_iter::SpecFromIter<T,I> for alloc::vec::Vec<T>>::from_iter (17 samples, 0.05%)dkn-compute`<libp2p_kad::protocol::KadPeer as core::convert::TryFrom<libp2p_kad::proto::dht::pb::mod_Message::Peer>>::try_from (17 samples, 0.05%)dkn-compute`<libp2p_kad::proto::dht::pb::mod_Message::Peer as quick_protobuf::message::MessageRead>::from_reader (4 samples, 0.01%)dkn-compute`<asynchronous_codec::framed_read::FramedRead2<T> as futures_core::stream::Stream>::poll_next (26 samples, 0.07%)dkn-compute`<quick_protobuf_codec::Codec<In,Out> as asynchronous_codec::decoder::Decoder>::decode (9 samples, 0.02%)dkn-compute`<libp2p_kad::proto::dht::pb::Message as quick_protobuf::message::MessageRead>::from_reader (9 samples, 0.02%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (94 samples, 0.26%)dkn-compute`libp2p_kad::handler::Handler::queue_new_stream::_{{closure}} (28 samples, 0.08%)dkn-compute`futures_bounded::futures_tuple_set::FuturesTupleSet<O,D>::poll_unpin (103 samples, 0.28%)dkn-compute`tokio::runtime::task::waker::clone_waker (8 samples, 0.02%)dkn-compute`tokio::runtime::task::waker::drop_waker (18 samples, 0.05%)dkn-compute`tracing::span::Span::log (11 samples, 0.03%)dkn-compute`tracing::span::Span::record_all (24 samples, 0.07%)dkn-compute`tracing::span::Span::log (13 samples, 0.04%)dkn-compute`<libp2p_kad::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::poll (358 samples, 0.98%)libsystem_platform.dylib`_platform_memmove (13 samples, 0.04%)dkn-compute`<libp2p_relay::priv_client::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::poll (10 samples, 0.03%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (53 samples, 0.15%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (44 samples, 0.12%)dkn-compute`<futures_channel::mpsc::Receiver<T> as futures_core::stream::Stream>::poll_next (77 samples, 0.21%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (21 samples, 0.06%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (50 samples, 0.14%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (26 samples, 0.07%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (17 samples, 0.05%)dkn-compute`tracing::span::Span::log (5 samples, 0.01%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (4 samples, 0.01%)dkn-compute`tracing::span::Span::log (31 samples, 0.08%)dkn-compute`tracing::span::Span::record_all (14 samples, 0.04%)dkn-compute`tracing::span::Span::log (4 samples, 0.01%)dkn-compute`<libp2p_request_response::handler::Handler<TCodec> as libp2p_swarm::handler::ConnectionHandler>::poll (234 samples, 0.64%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (21 samples, 0.06%)dkn-compute`futures_bounded::futures_map::FuturesMap<ID,O>::poll_unpin (4 samples, 0.01%)dkn-compute`futures_bounded::futures_tuple_set::FuturesTupleSet<O,D>::poll_unpin (5 samples, 0.01%)dkn-compute`libp2p_gossipsub::handler::EnabledHandler::poll (5 samples, 0.01%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (5 samples, 0.01%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (94 samples, 0.26%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (55 samples, 0.15%)dkn-compute`core::ptr::drop_in_place<libp2p_relay::priv_client::handler::Reservation> (20 samples, 0.05%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (43 samples, 0.12%)dkn-compute`tracing::span::Span::log (10 samples, 0.03%)dkn-compute`futures_bounded::futures_set::FuturesSet<O>::poll_unpin (95 samples, 0.26%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (88 samples, 0.24%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (69 samples, 0.19%)dkn-compute`<futures_timer::native::delay::Delay as core::ops::drop::Drop>::drop (6 samples, 0.02%)dkn-compute`futures_timer::native::global::raw_wake (5 samples, 0.01%)libdispatch.dylib`_dispatch_semaphore_signal_slow (5 samples, 0.01%)libsystem_kernel.dylib`semaphore_signal_trap (5 samples, 0.01%)dkn-compute`core::ptr::drop_in_place<<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next::Bomb<futures_bounded::futures_map::TaggedFuture<u32,futures_bounded::futures_map::TimeoutFuture<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<libp2p_relay::protocol::outbound_hop::Circuit,libp2p_relay::protocol::outbound_hop::ConnectError>+core::marker::Send>>>>>> (7 samples, 0.02%)dkn-compute`core::ptr::drop_in_place<core::option::Option<futures_bounded::futures_map::TaggedFuture<u32,futures_bounded::futures_map::TimeoutFuture<core::pin::Pin<alloc::boxed::Box<dyn core::future::future::Future+Output = core::result::Result<(),libp2p_relay::protocol::inbound_stop::Error>+core::marker::Send>>>>>> (7 samples, 0.02%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (136 samples, 0.37%)dkn-compute`<asynchronous_codec::framed_read::FramedRead2<T> as futures_core::stream::Stream>::poll_next (6 samples, 0.02%)libsystem_platform.dylib`_platform_memmove (4 samples, 0.01%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (219 samples, 0.60%)dkn-compute`libp2p_relay::priv_client::handler::Handler::establish_new_circuit::_{{closure}} (26 samples, 0.07%)dkn-compute`futures_bounded::futures_tuple_set::FuturesTupleSet<O,D>::poll_unpin (240 samples, 0.66%)dkn-compute`tokio::runtime::task::waker::clone_waker (39 samples, 0.11%)dkn-compute`tokio::runtime::task::waker::drop_waker (86 samples, 0.24%)dkn-compute`tracing::span::Span::log (50 samples, 0.14%)dkn-compute`tracing::span::Span::record_all (66 samples, 0.18%)dkn-compute`tracing::span::Span::log (19 samples, 0.05%)dkn-compute`tracing_core::span::Record::is_empty (12 samples, 0.03%)dkn-compute`<libp2p_relay::priv_client::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::poll (861 samples, 2.36%)d..libsystem_platform.dylib`_platform_memmove (25 samples, 0.07%)dkn-compute`core::ptr::drop_in_place<libp2p_relay::priv_client::handler::Reservation> (6 samples, 0.02%)dkn-compute`futures_bounded::futures_set::FuturesSet<O>::poll_unpin (7 samples, 0.02%)dkn-compute`futures_bounded::futures_tuple_set::FuturesTupleSet<O,D>::poll_unpin (12 samples, 0.03%)dkn-compute`tokio::runtime::task::waker::clone_waker (4 samples, 0.01%)dkn-compute`tokio::runtime::task::waker::drop_waker (25 samples, 0.07%)dkn-compute`libp2p_swarm::handler::either::_<impl libp2p_swarm::handler::ConnectionHandler for either::Either<L,R>>::poll (948 samples, 2.60%)dk..dkn-compute`tracing::span::Span::log (6 samples, 0.02%)dkn-compute`tokio::runtime::task::waker::clone_waker (11 samples, 0.03%)dkn-compute`tokio::runtime::task::waker::drop_waker (11 samples, 0.03%)dkn-compute`tracing::span::Span::log (28 samples, 0.08%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::poll (5,935 samples, 16.27%)dkn-compute`<libp2p_swarm..dkn-compute`<libp2p_yamux::Muxer<C> as libp2p_core::muxing::StreamMuxer>::poll_inbound (4 samples, 0.01%)dkn-compute`core::ptr::drop_in_place<tracing::span::Span> (23 samples, 0.06%)dkn-compute`tracing::span::Span::log (6 samples, 0.02%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::contains_key (14 samples, 0.04%)dkn-compute`<libp2p_gossipsub::protocol::ProtocolConfig as libp2p_core::upgrade::UpgradeInfo>::protocol_info (8 samples, 0.02%)dkn-compute`<libp2p_kad::protocol::ProtocolConfig as libp2p_core::upgrade::UpgradeInfo>::protocol_info (8 samples, 0.02%)libsystem_malloc.dylib`_malloc_zone_malloc (6 samples, 0.02%)dkn-compute`<T as libp2p_swarm::upgrade::UpgradeInfoSend>::protocol_info (96 samples, 0.26%)libsystem_malloc.dylib`nanov2_malloc (54 samples, 0.15%)dkn-compute`<libp2p_kad::protocol::ProtocolConfig as libp2p_core::upgrade::UpgradeInfo>::protocol_info (4 samples, 0.01%)dkn-compute`<T as libp2p_swarm::upgrade::UpgradeInfoSend>::protocol_info (161 samples, 0.44%)dkn-compute`<smallvec::SmallVec<A> as core::iter::traits::collect::Extend<<A as smallvec::Array>::Item>>::extend (14 samples, 0.04%)dkn-compute`<alloc::vec::into_iter::IntoIter<T,A> as core::ops::drop::Drop>::drop (4 samples, 0.01%)dkn-compute`alloc::sync::arcinner_layout_for_value_layout (6 samples, 0.02%)dkn-compute`core::hash::BuildHasher::hash_one (11 samples, 0.03%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (103 samples, 0.28%)dkn-compute`core::hash::BuildHasher::hash_one (19 samples, 0.05%)dkn-compute`hashbrown::raw::RawTable<T,A>::reserve_rehash (26 samples, 0.07%)libsystem_malloc.dylib`_malloc_zone_malloc (6 samples, 0.02%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::insert (315 samples, 0.86%)libsystem_malloc.dylib`nanov2_malloc (44 samples, 0.12%)dkn-compute`hashbrown::raw::RawTable<T,A>::reserve_rehash (6 samples, 0.02%)libsystem_malloc.dylib`_nanov2_free (51 samples, 0.14%)dkn-compute`libp2p_swarm::stream_protocol::StreamProtocol::try_from_owned (87 samples, 0.24%)libsystem_malloc.dylib`_malloc_zone_malloc (32 samples, 0.09%)libsystem_malloc.dylib`_nanov2_free (5 samples, 0.01%)libsystem_malloc.dylib`free (29 samples, 0.08%)libsystem_malloc.dylib`malloc (5 samples, 0.01%)libsystem_malloc.dylib`nanov2_malloc (75 samples, 0.21%)dkn-compute`core::iter::adapters::filter_map::filter_map_fold::_{{closure}} (701 samples, 1.92%)d..libsystem_platform.dylib`_platform_memmove (10 samples, 0.03%)dkn-compute`core::ptr::drop_in_place<either::Either<either::Either<either::Either<either::Either<either::Either<either::Either<libp2p_swarm::stream_protocol::StreamProtocol,&str>,either::Either<libp2p_gossipsub::protocol::ProtocolId,&str>>,either::Either<libp2p_swarm::stream_protocol::StreamProtocol,&str>>,either::Either<libp2p_swarm::stream_protocol::StreamProtocol,libp2p_swarm::stream_protocol::StreamProtocol>>,libp2p_swarm::stream_protocol::StreamProtocol>,either::Either<either::Either<libp2p_swarm::stream_protocol::StreamProtocol,&str>,&str>>> (10 samples, 0.03%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::insert (8 samples, 0.02%)dkn-compute`libp2p_swarm::stream_protocol::StreamProtocol::try_from_owned (10 samples, 0.03%)libsystem_malloc.dylib`_malloc_zone_malloc (4 samples, 0.01%)libsystem_malloc.dylib`_nanov2_free (12 samples, 0.03%)libsystem_malloc.dylib`nanov2_malloc (74 samples, 0.20%)libsystem_platform.dylib`_platform_memmove (13 samples, 0.04%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold (889 samples, 2.44%)dk..dkn-compute`core::iter::adapters::filter_map::filter_map_fold::_{{closure}} (10 samples, 0.03%)dkn-compute`either::Either::Left (51 samples, 0.14%)dkn-compute`<core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold (987 samples, 2.71%)dk..libsystem_malloc.dylib`free (12 samples, 0.03%)dkn-compute`<alloc::vec::into_iter::IntoIter<T,A> as core::ops::drop::Drop>::drop (4 samples, 0.01%)dkn-compute`DYLD-STUB$$free (4 samples, 0.01%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (33 samples, 0.09%)dkn-compute`core::hash::BuildHasher::hash_one (5 samples, 0.01%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (52 samples, 0.14%)dkn-compute`core::hash::BuildHasher::hash_one (22 samples, 0.06%)libsystem_malloc.dylib`_nanov2_free (24 samples, 0.07%)dkn-compute`hashbrown::raw::RawTable<T,A>::reserve_rehash (218 samples, 0.60%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::insert (332 samples, 0.91%)libsystem_malloc.dylib`nanov2_malloc (43 samples, 0.12%)libsystem_malloc.dylib`_nanov2_free (22 samples, 0.06%)dkn-compute`libp2p_swarm::stream_protocol::StreamProtocol::try_from_owned (42 samples, 0.12%)libsystem_malloc.dylib`_malloc_zone_malloc (5 samples, 0.01%)libsystem_malloc.dylib`free (11 samples, 0.03%)libsystem_malloc.dylib`nanov2_malloc (26 samples, 0.07%)dkn-compute`core::iter::adapters::filter_map::filter_map_fold::_{{closure}} (458 samples, 1.26%)libsystem_malloc.dylib`_nanov2_free (20 samples, 0.05%)libsystem_malloc.dylib`nanov2_malloc (19 samples, 0.05%)libsystem_platform.dylib`_platform_memmove (4 samples, 0.01%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold (534 samples, 1.46%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (60 samples, 0.16%)dkn-compute`core::hash::BuildHasher::hash_one (9 samples, 0.02%)dkn-compute`hashbrown::raw::RawTable<T,A>::reserve_rehash (6 samples, 0.02%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::insert (143 samples, 0.39%)libsystem_malloc.dylib`_nanov2_free (44 samples, 0.12%)dkn-compute`libp2p_swarm::stream_protocol::StreamProtocol::try_from_owned (65 samples, 0.18%)libsystem_malloc.dylib`_malloc_zone_malloc (16 samples, 0.04%)libsystem_malloc.dylib`free (17 samples, 0.05%)libsystem_malloc.dylib`nanov2_malloc (35 samples, 0.10%)dkn-compute`core::iter::adapters::filter_map::filter_map_fold::_{{closure}} (345 samples, 0.95%)libsystem_platform.dylib`_platform_memmove (6 samples, 0.02%)dkn-compute`core::ptr::drop_in_place<either::Either<either::Either<either::Either<either::Either<either::Either<either::Either<libp2p_swarm::stream_protocol::StreamProtocol,&str>,either::Either<libp2p_gossipsub::protocol::ProtocolId,&str>>,either::Either<libp2p_swarm::stream_protocol::StreamProtocol,&str>>,either::Either<libp2p_swarm::stream_protocol::StreamProtocol,libp2p_swarm::stream_protocol::StreamProtocol>>,libp2p_swarm::stream_protocol::StreamProtocol>,either::Either<either::Either<libp2p_swarm::stream_protocol::StreamProtocol,&str>,&str>>> (6 samples, 0.02%)dkn-compute`either::Either::Left (11 samples, 0.03%)libsystem_malloc.dylib`free (15 samples, 0.04%)libsystem_malloc.dylib`nanov2_malloc (36 samples, 0.10%)dkn-compute`<core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold (1,993 samples, 5.46%)dkn-com..libsystem_platform.dylib`_platform_memmove (10 samples, 0.03%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold (4 samples, 0.01%)dkn-compute`either::Either::Left (18 samples, 0.05%)dkn-compute`<core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold (2,043 samples, 5.60%)dkn-com..dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (30 samples, 0.08%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::insert (82 samples, 0.22%)dkn-compute`core::hash::BuildHasher::hash_one (9 samples, 0.02%)libsystem_malloc.dylib`_nanov2_free (22 samples, 0.06%)dkn-compute`libp2p_swarm::stream_protocol::StreamProtocol::try_from_owned (43 samples, 0.12%)libsystem_platform.dylib`_platform_memset (5 samples, 0.01%)libsystem_malloc.dylib`_malloc_zone_malloc (4 samples, 0.01%)libsystem_malloc.dylib`free (10 samples, 0.03%)libsystem_malloc.dylib`nanov2_malloc (27 samples, 0.07%)dkn-compute`core::iter::adapters::filter_map::filter_map_fold::_{{closure}} (207 samples, 0.57%)libsystem_platform.dylib`_platform_memmove (6 samples, 0.02%)dkn-compute`core::ptr::drop_in_place<either::Either<either::Either<either::Either<either::Either<either::Either<either::Either<libp2p_swarm::stream_protocol::StreamProtocol,&str>,either::Either<libp2p_gossipsub::protocol::ProtocolId,&str>>,either::Either<libp2p_swarm::stream_protocol::StreamProtocol,&str>>,either::Either<libp2p_swarm::stream_protocol::StreamProtocol,libp2p_swarm::stream_protocol::StreamProtocol>>,libp2p_swarm::stream_protocol::StreamProtocol>,either::Either<either::Either<libp2p_swarm::stream_protocol::StreamProtocol,&str>,&str>>> (4 samples, 0.01%)libsystem_malloc.dylib`nanov2_malloc (19 samples, 0.05%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold (263 samples, 0.72%)libsystem_platform.dylib`_platform_memmove (4 samples, 0.01%)dkn-compute`<core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold (2,343 samples, 6.42%)dkn-comp..dkn-compute`<core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold (2,329 samples, 6.38%)dkn-comp..dkn-compute`<hashbrown::map::HashMap<K,V,S,A> as core::iter::traits::collect::Extend<(K,V)>>::extend (2,355 samples, 6.45%)dkn-comp..libsystem_platform.dylib`_platform_memmove (10 samples, 0.03%)dkn-compute`<libp2p_gossipsub::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::listen_protocol (7 samples, 0.02%)dkn-compute`<libp2p_identify::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::listen_protocol (22 samples, 0.06%)dkn-compute`<libp2p_gossipsub::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::listen_protocol (12 samples, 0.03%)dkn-compute`<libp2p_kad::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::listen_protocol (21 samples, 0.06%)dkn-compute`<smallvec::SmallVec<A> as core::iter::traits::collect::Extend<<A as smallvec::Array>::Item>>::extend (15 samples, 0.04%)dkn-compute`__rdl_alloc (5 samples, 0.01%)libsystem_malloc.dylib`_malloc_zone_malloc (23 samples, 0.06%)libsystem_malloc.dylib`malloc (8 samples, 0.02%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::listen_protocol (241 samples, 0.66%)libsystem_malloc.dylib`nanov2_malloc (90 samples, 0.25%)dkn-compute`DYLD-STUB$$free (6 samples, 0.02%)dkn-compute`<smallvec::SmallVec<A> as core::ops::drop::Drop>::drop (4 samples, 0.01%)libsystem_malloc.dylib`_nanov2_free (30 samples, 0.08%)dkn-compute`core::ptr::drop_in_place$LT$libp2p_core..upgrade..select..SelectUpgrade$LT$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..select..SelectUpgrade$LT$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..select..SelectUpgrade$LT$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..select..SelectUpgrade$LT$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..select..SelectUpgrade$LT$libp2p_swarm..upgrade..SendWrapper$LT$either..Either$LT$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..ready..ReadyUpgrade$LT$libp2p_swarm..stream_protocol..StreamProtocol$GT$$GT$$C$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..denied..DeniedUpgrade$GT$$GT$$GT$$C$libp2p_swarm..upgrade..SendWrapper$LT$either..Either$LT$libp2p_gossipsub..protocol..ProtocolConfig$C$libp2p_core..upgrade..denied..DeniedUpgrade$GT$$GT$$GT$$GT$$C$libp2p_swarm..upgrade..SendWrapper$LT$either..Either$LT$libp2p_kad..protocol..ProtocolConfig$C$libp2p_core..upgrade..denied..DeniedUpgrade$GT$$GT$$GT$$GT$$2 (60 samples, 0.16%)libsystem_platform.dylib`_platform_memset (9 samples, 0.02%)libsystem_malloc.dylib`free (32 samples, 0.09%)dkn-compute`libp2p_swarm::connection::gather_supported_protocols (2,941 samples, 8.06%)dkn-compute..libsystem_platform.dylib`_platform_memmove (16 samples, 0.04%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (252 samples, 0.69%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::contains_key (553 samples, 1.52%)dkn-compute`core::hash::BuildHasher::hash_one (34 samples, 0.09%)dkn-compute`libp2p_swarm::handler::ProtocolsChange::from_full_sets (695 samples, 1.90%)d..libsystem_platform.dylib`_platform_memcmp (77 samples, 0.21%)dkn-compute`libp2p_swarm::handler::either::_<impl libp2p_swarm::handler::ConnectionHandler for either::Either<L,R>>::poll (9 samples, 0.02%)dkn-compute`tracing::span::Span::log (50 samples, 0.14%)dkn-compute`tracing::span::Span::record_all (41 samples, 0.11%)dkn-compute`tracing::span::Span::log (16 samples, 0.04%)dkn-compute`tracing_core::span::Record::is_empty (29 samples, 0.08%)libdyld.dylib`tlv_get_addr (8 samples, 0.02%)libsystem_malloc.dylib`_nanov2_free (192 samples, 0.53%)libsystem_platform.dylib`__bzero (8 samples, 0.02%)libsystem_platform.dylib`_platform_memmove (23 samples, 0.06%)dkn-compute`futures_util::future::future::FutureExt::poll_unpin (19,882 samples, 54.49%)dkn-compute`futures_util::future::future::FutureExt::poll_unpinlibsystem_platform.dylib`_platform_memset (21 samples, 0.06%)libsystem_malloc.dylib`_nanov2_free (25 samples, 0.07%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (251 samples, 0.69%)libsystem_malloc.dylib`free (13 samples, 0.04%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (321 samples, 0.88%)libsystem_platform.dylib`_platform_memmove (11 samples, 0.03%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (13 samples, 0.04%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (50 samples, 0.14%)dkn-compute`futures_util::stream::stream::StreamExt::poll_next_unpin (424 samples, 1.16%)dkn-compute`libp2p_swarm::handler::ProtocolsChange::from_full_sets (8 samples, 0.02%)dkn-compute`tracing::span::Span::log (11 samples, 0.03%)dkn-compute`tracing::span::Span::record_all (8 samples, 0.02%)libsystem_malloc.dylib`_nanov2_free (16 samples, 0.04%)libsystem_malloc.dylib`free (57 samples, 0.16%)dkn-compute`<futures_util::future::select::Select<A,B> as core::future::future::Future>::poll (20,838 samples, 57.11%)dkn-compute`<futures_util::future::select::Select<A,B> as core::future::future::Future>::polllibsystem_platform.dylib`_platform_memmove (7 samples, 0.02%)dkn-compute`__rdl_alloc (11 samples, 0.03%)libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_slow (6 samples, 0.02%)libsystem_kernel.dylib`__psynch_mutexwait (6 samples, 0.02%)dkn-compute`futures_channel::mpsc::BoundedSenderInner<T>::poll_unparked (25 samples, 0.07%)libsystem_pthread.dylib`pthread_mutex_unlock (5 samples, 0.01%)dkn-compute`futures_channel::mpsc::BoundedSenderInner<T>::poll_unparked (6 samples, 0.02%)dkn-compute`parking_lot_core::parking_lot::lock_bucket_pair (4 samples, 0.01%)libsystem_kernel.dylib`__psynch_cvsignal (189 samples, 0.52%)dkn-compute`parking_lot::condvar::Condvar::notify_one_slow (201 samples, 0.55%)dkn-compute`<futures_util::stream::futures_unordered::task::Task<Fut> as futures_task::arc_wake::ArcWake>::wake_by_ref (233 samples, 0.64%)dkn-compute`tokio::runtime::park::wake (216 samples, 0.59%)dkn-compute`futures_task::waker::wake_arc_raw (235 samples, 0.64%)libsystem_kernel.dylib`__ulock_wait (7 samples, 0.02%)libsystem_malloc.dylib`set_tiny_meta_header_in_use (9 samples, 0.02%)libsystem_malloc.dylib`_tiny_check_and_zero_inline_meta_from_freelist (8 samples, 0.02%)libsystem_malloc.dylib`szone_malloc_should_clear (95 samples, 0.26%)libsystem_malloc.dylib`tiny_malloc_should_clear (89 samples, 0.24%)libsystem_malloc.dylib`tiny_malloc_from_free_list (56 samples, 0.15%)libsystem_malloc.dylib`tiny_free_list_add_ptr (18 samples, 0.05%)dkn-compute`futures_channel::mpsc::sink_impl::_<impl futures_sink::Sink<T> for futures_channel::mpsc::Sender<T>>::start_send (373 samples, 1.02%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::wake (33 samples, 0.09%)libsystem_malloc.dylib`_malloc_zone_malloc (12 samples, 0.03%)libsystem_malloc.dylib`malloc (5 samples, 0.01%)libsystem_malloc.dylib`nanov2_malloc (7 samples, 0.02%)libsystem_platform.dylib`_platform_memmove (52 samples, 0.14%)dkn-compute`<futures_util::sink::send::Send<Si,Item> as core::future::future::Future>::poll (578 samples, 1.58%)dkn-compute`<libp2p_swarm::connection::pool::concurrent_dial::ConcurrentDial as core::future::future::Future>::poll (5 samples, 0.01%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (5 samples, 0.01%)dkn-compute`<tracing::instrument::Instrumented<T> as core::future::future::Future>::poll (5 samples, 0.01%)dkn-compute`<futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll (5 samples, 0.01%)dkn-compute`<futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll (5 samples, 0.01%)dkn-compute`<libp2p_core::transport::map::MapFuture<T,F> as core::future::future::Future>::poll (5 samples, 0.01%)dkn-compute`<libp2p_core::transport::map::MapFuture<T,F> as core::future::future::Future>::poll (5 samples, 0.01%)dkn-compute`<libp2p_core::upgrade::apply::OutboundUpgradeApply<C,U> as core::future::future::Future>::poll (5 samples, 0.01%)dkn-compute`<libp2p_noise::Config as libp2p_core::upgrade::OutboundConnectionUpgrade<T>>::upgrade_outbound::_{{closure}} (5 samples, 0.01%)dkn-compute`libp2p_noise::io::handshake::send_identity::_{{closure}} (4 samples, 0.01%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::handshakestate::HandshakeState> as asynchronous_codec::encoder::Encoder>::encode (4 samples, 0.01%)dkn-compute`snow::handshakestate::HandshakeState::write_message (4 samples, 0.01%)dkn-compute`<libp2p_noise::protocol::Keypair as snow::types::Dh>::dh (4 samples, 0.01%)dkn-compute`x25519_dalek::x25519::x25519 (4 samples, 0.01%)dkn-compute`curve25519_dalek::montgomery::MontgomeryPoint::mul_clamped (4 samples, 0.01%)dkn-compute`libp2p_gossipsub::types::_<impl core::convert::From<libp2p_gossipsub::types::RawMessage> for libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::Message>::from (4 samples, 0.01%)dkn-compute`libp2p_gossipsub::types::_<impl core::convert::From<libp2p_gossipsub::types::RpcOut> for libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::RPC>::from (87 samples, 0.24%)libsystem_malloc.dylib`nanov2_allocate_outlined (51 samples, 0.14%)libsystem_malloc.dylib`nanov2_find_block_and_allocate (33 samples, 0.09%)libsystem_malloc.dylib`nanov2_allocate_from_block (6 samples, 0.02%)libsystem_malloc.dylib`malloc_zone_realloc (7 samples, 0.02%)libsystem_platform.dylib`_platform_memmove (6 samples, 0.02%)dkn-compute`smallvec::SmallVec<A>::reserve_one_unchecked (8 samples, 0.02%)dkn-compute`smallvec::SmallVec<A>::try_grow (8 samples, 0.02%)libsystem_malloc.dylib`realloc (8 samples, 0.02%)libsystem_malloc.dylib`_malloc_zone_malloc (5 samples, 0.01%)dkn-compute`<libp2p_gossipsub::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::on_behaviour_event (202 samples, 0.55%)libsystem_malloc.dylib`nanov2_malloc (62 samples, 0.17%)dkn-compute`futures_bounded::futures_map::FuturesMap<ID,O>::try_push (9 samples, 0.02%)dkn-compute`<libp2p_relay::priv_client::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::on_behaviour_event (14 samples, 0.04%)dkn-compute`futures_bounded::futures_tuple_set::FuturesTupleSet<O,D>::try_push (11 samples, 0.03%)dkn-compute`libp2p_gossipsub::types::_<impl core::convert::From<libp2p_gossipsub::types::RpcOut> for libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::RPC>::from (4 samples, 0.01%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::on_behaviour_event (276 samples, 0.76%)libsystem_platform.dylib`_platform_memmove (11 samples, 0.03%)dkn-compute`futures_channel::mpsc::BoundedSenderInner<T>::poll_unparked (4 samples, 0.01%)dkn-compute`futures_util::future::future::FutureExt::poll_unpin (7 samples, 0.02%)dkn-compute`futures_util::stream::stream::StreamExt::poll_next_unpin (7 samples, 0.02%)dkn-compute`tracing::span::Span::log (15 samples, 0.04%)dkn-compute`<tracing::instrument::Instrumented<T> as core::future::future::Future>::poll (21,909 samples, 60.05%)dkn-compute`<tracing::instrument::Instrumented<T> as core::future::future::Future>::polllibsystem_platform.dylib`_platform_memmove (21 samples, 0.06%)dkn-compute`tokio::runtime::task::core::TaskIdGuard::enter (14 samples, 0.04%)dkn-compute`tracing::span::Span::log (7 samples, 0.02%)libdyld.dylib`tlv_get_addr (24 samples, 0.07%)dkn-compute`tokio::runtime::task::core::Core<T,S>::poll (22,041 samples, 60.41%)dkn-compute`tokio::runtime::task::core::Core<T,S>::polllibsystem_platform.dylib`_platform_memmove (56 samples, 0.15%)dkn-compute`tokio::runtime::task::core::TaskIdGuard::enter (7 samples, 0.02%)dkn-compute`tokio::runtime::task::state::State::transition_to_idle (18 samples, 0.05%)dkn-compute`tokio::runtime::task::harness::Harness<T,S>::poll (22,593 samples, 61.92%)dkn-compute`tokio::runtime::task::harness::Harness<T,S>::polldkn-compute`tokio::runtime::task::state::State::transition_to_running (19 samples, 0.05%)dkn-compute`tokio::runtime::task::state::State::ref_dec (4 samples, 0.01%)libsystem_pthread.dylib`pthread_cond_signal (4 samples, 0.01%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::Context::run_task (23,179 samples, 63.53%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::Context::run_taskdkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::scheduler::multi_thread::handle::Handle>::notify_if_work_pending (30 samples, 0.08%)dkn-compute`tokio::runtime::task::harness::Harness<T,S>::poll (6 samples, 0.02%)dkn-compute`tokio::runtime::task::raw::poll (6 samples, 0.02%)libdyld.dylib`tlv_get_addr (16 samples, 0.04%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::Context::run (27,505 samples, 75.38%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::Context::runlibsystem_m.dylib`pow (32 samples, 0.09%)all (36,487 samples, 100%)libsystem_pthread.dylib`thread_start (27,628 samples, 75.72%)libsystem_pthread.dylib`thread_startlibsystem_pthread.dylib`_pthread_start (27,628 samples, 75.72%)libsystem_pthread.dylib`_pthread_startdkn-compute`std::sys::pal::unix::thread::Thread::new::thread_start (27,628 samples, 75.72%)dkn-compute`std::sys::pal::unix::thread::Thread::new::thread_startdkn-compute`core::ops::function::FnOnce::call_once{{vtable.shim}} (27,628 samples, 75.72%)dkn-compute`core::ops::function::FnOnce::call_once{{vtable.shim}}dkn-compute`std::sys_common::backtrace::__rust_begin_short_backtrace (27,628 samples, 75.72%)dkn-compute`std::sys_common::backtrace::__rust_begin_short_backtracedkn-compute`tokio::runtime::blocking::pool::Inner::run (27,545 samples, 75.49%)dkn-compute`tokio::runtime::blocking::pool::Inner::rundkn-compute`tokio::runtime::task::harness::Harness<T,S>::poll (27,545 samples, 75.49%)dkn-compute`tokio::runtime::task::harness::Harness<T,S>::polldkn-compute`tokio::runtime::task::core::Core<T,S>::poll (27,545 samples, 75.49%)dkn-compute`tokio::runtime::task::core::Core<T,S>::polldkn-compute`tokio::runtime::scheduler::multi_thread::worker::run (27,544 samples, 75.49%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::rundkn-compute`tokio::runtime::context::runtime::enter_runtime (27,544 samples, 75.49%)dkn-compute`tokio::runtime::context::runtime::enter_runtimedkn-compute`tokio::runtime::context::set_scheduler (27,544 samples, 75.49%)dkn-compute`tokio::runtime::context::set_schedulerlibsystem_m.dylib`pow (13 samples, 0.04%) \ No newline at end of file diff --git a/benchmarks/flamegraph_permissive.svg b/benchmarks/flamegraph_permissive.svg deleted file mode 100644 index 8791e54..0000000 --- a/benchmarks/flamegraph_permissive.svg +++ /dev/null @@ -1,491 +0,0 @@ -Flame Graph Reset ZoomSearch dkn-compute`<dkn_compute::p2p::behaviour::DriaBehaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (19 samples, 0.01%)dkn-compute`<libp2p_gossipsub::behaviour::Behaviour<C,F> as libp2p_swarm::behaviour::NetworkBehaviour>::on_connection_handler_event (18 samples, 0.01%)dkn-compute`libp2p_swarm::Swarm<TBehaviour>::poll_next_event (55 samples, 0.04%)dkn-compute`dkn_compute::main::_{{closure}} (61 samples, 0.05%)dkn-compute`<tokio::future::poll_fn::PollFn<F> as core::future::future::Future>::poll (60 samples, 0.05%)libsystem_kernel.dylib`__psynch_cvwait (17 samples, 0.01%)dkn-compute`tokio::runtime::context::runtime::enter_runtime (80 samples, 0.06%)dkn-compute`tokio::runtime::park::CachedParkThread::block_on (80 samples, 0.06%)dkn-compute`tokio::runtime::park::Inner::park (19 samples, 0.01%)dkn-compute`parking_lot::condvar::Condvar::wait_until_internal (19 samples, 0.01%)dkn-compute`tokio::sync::notify::Notified::poll_notified (15 samples, 0.01%)dkn-compute`tokio_util::sync::cancellation_token::tree_node::is_cancelled (19 samples, 0.01%)dkn-compute`<tokio_util::sync::cancellation_token::WaitForCancellationFuture as core::future::future::Future>::poll (37 samples, 0.03%)dkn-compute`<libp2p_core::transport::map::Map<T,F> as libp2p_core::transport::Transport>::poll (43 samples, 0.03%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::poll (62 samples, 0.05%)dkn-compute`<libp2p_core::transport::map::Map<T,F> as libp2p_core::transport::Transport>::poll (26 samples, 0.02%)dkn-compute`<libp2p_relay::priv_client::transport::Transport as libp2p_core::transport::Transport>::poll (16 samples, 0.01%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (14 samples, 0.01%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (14 samples, 0.01%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::poll (95 samples, 0.07%)dkn-compute`<T as libp2p_core::transport::boxed::Abstract<O>>::poll (102 samples, 0.08%)dkn-compute`<alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter (24 samples, 0.02%)libsystem_platform.dylib`_platform_memmove (14 samples, 0.01%)dkn-compute`<dkn_compute::p2p::behaviour::DriaBehaviour as libp2p_swarm::behaviour::NetworkBehaviour>::on_connection_handler_event (32 samples, 0.03%)dkn-compute`<libp2p_kad::behaviour::Behaviour<TStore> as libp2p_swarm::behaviour::NetworkBehaviour>::on_connection_handler_event (31 samples, 0.02%)dkn-compute`<libp2p_request_response::Behaviour<TCodec> as libp2p_swarm::behaviour::NetworkBehaviour>::poll (43 samples, 0.03%)dkn-compute`<libp2p_autonat::behaviour::Behaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (93 samples, 0.07%)dkn-compute`<futures_timer::native::delay::Delay as core::future::future::Future>::poll (14 samples, 0.01%)dkn-compute`<futures_ticker::Ticker as futures_core::stream::Stream>::poll_next (16 samples, 0.01%)dkn-compute`core::ops::function::impls::_<impl core::ops::function::FnMut<A> for &mut F>::call_mut (40 samples, 0.03%)dkn-compute`<alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter (70 samples, 0.05%)libsystem_platform.dylib`_platform_memcmp (21 samples, 0.02%)dkn-compute`libp2p_gossipsub::mcache::MessageCache::get_gossip_message_ids (71 samples, 0.06%)dkn-compute`libp2p_gossipsub::mcache::MessageCache::shift (44 samples, 0.03%)dkn-compute`libp2p_gossipsub::behaviour::Behaviour<D,F>::heartbeat (143 samples, 0.11%)dkn-compute`<libp2p_gossipsub::behaviour::Behaviour<C,F> as libp2p_swarm::behaviour::NetworkBehaviour>::poll (232 samples, 0.18%)dkn-compute`<libp2p_identify::behaviour::Behaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (46 samples, 0.04%)dkn-compute`libp2p_kad::jobs::PutRecordJob::poll (17 samples, 0.01%)dkn-compute`<alloc::collections::btree::map::ValuesMut<K,V> as core::iter::traits::iterator::Iterator>::next (53 samples, 0.04%)dkn-compute`libp2p_kad::query::peers::closest::ClosestPeersIter::next (504 samples, 0.39%)dkn-compute`<alloc::collections::btree::map::ValuesMut<K,V> as core::iter::traits::iterator::Iterator>::next (288 samples, 0.23%)dkn-compute`libp2p_kad::query::QueryPool<TInner>::poll (610 samples, 0.48%)libsystem_kernel.dylib`mach_absolute_time (24 samples, 0.02%)libsystem_c.dylib`clock_gettime (41 samples, 0.03%)dkn-compute`std::sys::pal::unix::time::Timespec::now (45 samples, 0.04%)dkn-compute`tracing::span::Span::log (19 samples, 0.01%)dkn-compute`tracing::span::Span::record_all (15 samples, 0.01%)dkn-compute`<libp2p_kad::behaviour::Behaviour<TStore> as libp2p_swarm::behaviour::NetworkBehaviour>::poll (803 samples, 0.63%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (38 samples, 0.03%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (13 samples, 0.01%)dkn-compute`<futures_channel::mpsc::Receiver<T> as futures_core::stream::Stream>::poll_next (47 samples, 0.04%)dkn-compute`tracing::span::Span::log (20 samples, 0.02%)dkn-compute`tracing::span::Span::record_all (37 samples, 0.03%)dkn-compute`<libp2p_relay::priv_client::Behaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (151 samples, 0.12%)dkn-compute`tracing::span::Span::log (15 samples, 0.01%)dkn-compute`<dkn_compute::p2p::behaviour::DriaBehaviour as libp2p_swarm::behaviour::NetworkBehaviour>::poll (1,410 samples, 1.10%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (132 samples, 0.10%)dkn-compute`<libp2p_gossipsub::transform::IdentityTransform as libp2p_gossipsub::transform::DataTransform>::inbound_transform (20 samples, 0.02%)libsystem_malloc.dylib`nanov2_malloc (15 samples, 0.01%)libsystem_malloc.dylib`szone_malloc_should_clear (60 samples, 0.05%)libsystem_malloc.dylib`tiny_malloc_should_clear (49 samples, 0.04%)libsystem_malloc.dylib`tiny_malloc_from_free_list (40 samples, 0.03%)dkn-compute`<libp2p_gossipsub::types::RawMessage as core::clone::Clone>::clone (130 samples, 0.10%)dkn-compute`<alloc::string::String as core::fmt::Write>::write_str (14 samples, 0.01%)dkn-compute`dkn_compute::p2p::behaviour::create_gossipsub_behavior::_{{closure}} (45 samples, 0.04%)dkn-compute`core::fmt::num::imp::_<impl core::fmt::Display for u64>::fmt (41 samples, 0.03%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (15 samples, 0.01%)libsystem_malloc.dylib`nanov2_allocate_outlined (13 samples, 0.01%)libsystem_malloc.dylib`szone_malloc_should_clear (18 samples, 0.01%)libsystem_malloc.dylib`tiny_malloc_should_clear (18 samples, 0.01%)libsystem_malloc.dylib`tiny_malloc_from_free_list (17 samples, 0.01%)dkn-compute`<libp2p_gossipsub::types::RawMessage as core::clone::Clone>::clone (55 samples, 0.04%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (13 samples, 0.01%)libsystem_malloc.dylib`szone_malloc_should_clear (14 samples, 0.01%)libsystem_malloc.dylib`tiny_malloc_should_clear (13 samples, 0.01%)dkn-compute`hashbrown::raw::RawTable<T,A>::reserve_rehash (41 samples, 0.03%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::insert (63 samples, 0.05%)libsystem_platform.dylib`_platform_memmove (17 samples, 0.01%)dkn-compute`libp2p_gossipsub::behaviour::Behaviour<D,F>::forward_msg (265 samples, 0.21%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::get_mut (49 samples, 0.04%)dkn-compute`libp2p_gossipsub::mcache::MessageCache::observe_duplicate (162 samples, 0.13%)libsystem_platform.dylib`_platform_memcmp (108 samples, 0.08%)dkn-compute`hashbrown::rustc_entry::_<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry (27 samples, 0.02%)dkn-compute`libp2p_gossipsub::mcache::MessageCache::put (41 samples, 0.03%)dkn-compute`hashbrown::rustc_entry::_<impl hashbrown::map::HashMap<K,V,S,A>>::rustc_entry (64 samples, 0.05%)dkn-compute`std::sys::pal::unix::time::Timespec::now (20 samples, 0.02%)libsystem_c.dylib`clock_gettime (20 samples, 0.02%)libsystem_malloc.dylib`_nanov2_free (29 samples, 0.02%)libsystem_platform.dylib`_platform_memcmp (14 samples, 0.01%)dkn-compute`libp2p_gossipsub::time_cache::DuplicateCache<Key>::insert (145 samples, 0.11%)libsystem_malloc.dylib`_nanov2_free (32 samples, 0.03%)libsystem_malloc.dylib`tiny_free_list_add_ptr (20 samples, 0.02%)libsystem_malloc.dylib`free_tiny (121 samples, 0.09%)libsystem_malloc.dylib`tiny_free_no_lock (106 samples, 0.08%)libsystem_malloc.dylib`nanov2_malloc (20 samples, 0.02%)libsystem_platform.dylib`_platform_memcmp (28 samples, 0.02%)libsystem_platform.dylib`_platform_memmove (33 samples, 0.03%)dkn-compute`<libp2p_gossipsub::behaviour::Behaviour<C,F> as libp2p_swarm::behaviour::NetworkBehaviour>::on_connection_handler_event (1,333 samples, 1.04%)libsystem_platform.dylib`_platform_memset (13 samples, 0.01%)dkn-compute`libp2p_tcp::Transport<T>::create_socket (20 samples, 0.02%)libsystem_kernel.dylib`socket (14 samples, 0.01%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::dial (31 samples, 0.02%)dkn-compute`<libp2p_core::transport::map::Map<T,F> as libp2p_core::transport::Transport>::dial (31 samples, 0.02%)dkn-compute`<libp2p_tcp::Transport<T> as libp2p_core::transport::Transport>::dial (29 samples, 0.02%)dkn-compute`<libp2p_core::transport::choice::OrTransport<A,B> as libp2p_core::transport::Transport>::dial (35 samples, 0.03%)dkn-compute`<T as libp2p_core::transport::boxed::Abstract<O>>::dial (38 samples, 0.03%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold (40 samples, 0.03%)dkn-compute`alloc::vec::in_place_collect::_<impl alloc::vec::spec_from_iter::SpecFromIter<T,I> for alloc::vec::Vec<T>>::from_iter (42 samples, 0.03%)libsystem_kernel.dylib`__psynch_cvsignal (46 samples, 0.04%)dkn-compute`parking_lot::condvar::Condvar::notify_one_slow (57 samples, 0.04%)dkn-compute`tokio::runtime::driver::Handle::unpark (27 samples, 0.02%)libsystem_kernel.dylib`kevent (27 samples, 0.02%)dkn-compute`tokio::runtime::context::with_scheduler (97 samples, 0.08%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::task::Schedule for alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>::schedule (102 samples, 0.08%)dkn-compute`futures_channel::mpsc::Sender<T>::try_send (112 samples, 0.09%)dkn-compute`tokio::runtime::task::waker::wake_by_val (108 samples, 0.08%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::wake (13 samples, 0.01%)dkn-compute`libp2p_swarm::connection::pool::Pool<THandler>::iter_established_connections_of_peer (22 samples, 0.02%)dkn-compute`<futures_channel::mpsc::Receiver<T> as futures_core::stream::Stream>::poll_next (14 samples, 0.01%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (13 samples, 0.01%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (27 samples, 0.02%)dkn-compute`futures_util::stream::futures_unordered::FuturesUnordered<Fut>::release_task (15 samples, 0.01%)libsystem_malloc.dylib`tiny_free_list_add_ptr (18 samples, 0.01%)libsystem_malloc.dylib`free_tiny (71 samples, 0.06%)libsystem_malloc.dylib`tiny_free_no_lock (49 samples, 0.04%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (131 samples, 0.10%)libsystem_malloc.dylib`free (29 samples, 0.02%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (234 samples, 0.18%)libsystem_platform.dylib`_platform_memmove (31 samples, 0.02%)dkn-compute`futures_util::stream::stream::StreamExt::poll_next_unpin (266 samples, 0.21%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (371 samples, 0.29%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (422 samples, 0.33%)libsystem_platform.dylib`_platform_memmove (26 samples, 0.02%)dkn-compute`tracing::span::Span::record_all (13 samples, 0.01%)dkn-compute`libp2p_swarm::connection::pool::Pool<THandler>::poll (526 samples, 0.41%)libsystem_malloc.dylib`free (16 samples, 0.01%)libsystem_malloc.dylib`nanov2_malloc (21 samples, 0.02%)dkn-compute`libp2p_swarm::Swarm<TBehaviour>::poll_next_event (3,899 samples, 3.05%)dkn..dkn-compute`tokio::signal::make_future::_{{closure}} (19 samples, 0.01%)dkn-compute`tokio::signal::RxFuture::poll_recv (23 samples, 0.02%)dkn-compute`tokio::signal::unix::Signal::recv::_{{closure}} (31 samples, 0.02%)dkn-compute`<tokio::future::poll_fn::PollFn<F> as core::future::future::Future>::poll (4,080 samples, 3.19%)dkn..dkn-compute`dkn_compute::main::_{{closure}} (4,145 samples, 3.24%)dkn..libsystem_kernel.dylib`__psynch_cvwait (1,083 samples, 0.85%)libsystem_kernel.dylib`__psynch_mutexwait (50 samples, 0.04%)libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_slow (53 samples, 0.04%)libsystem_pthread.dylib`_pthread_cond_wait (89 samples, 0.07%)dkn-compute`parking_lot::condvar::Condvar::wait_until_internal (1,224 samples, 0.96%)dkn-compute`tokio::runtime::park::Inner::park (1,268 samples, 0.99%)dkn-compute`tokio::runtime::park::CachedParkThread::block_on (5,436 samples, 4.25%)dkn-c..dyld`start (5,451 samples, 4.26%)dyld`..dkn-compute`main (5,451 samples, 4.26%)dkn-c..dkn-compute`std::rt::lang_start_internal (5,451 samples, 4.26%)dkn-c..dkn-compute`std::rt::lang_start::_{{closure}} (5,451 samples, 4.26%)dkn-c..dkn-compute`std::sys_common::backtrace::__rust_begin_short_backtrace (5,451 samples, 4.26%)dkn-c..dkn-compute`dkn_compute::main (5,451 samples, 4.26%)dkn-c..dkn-compute`tokio::runtime::runtime::Runtime::block_on (5,450 samples, 4.26%)dkn-c..dkn-compute`tokio::runtime::context::runtime::enter_runtime (5,450 samples, 4.26%)dkn-c..libdispatch.dylib`_dispatch_semaphore_wait_slow (28 samples, 0.02%)libsystem_kernel.dylib`semaphore_timedwait_trap (26 samples, 0.02%)dkn-compute`futures_timer::native::global::run (39 samples, 0.03%)dkn-compute`std::thread::park_timeout (30 samples, 0.02%)libsystem_kernel.dylib`mach_absolute_time (39 samples, 0.03%)libsystem_c.dylib`clock_gettime (55 samples, 0.04%)dkn-compute`std::sys::pal::unix::time::Timespec::now (57 samples, 0.04%)dkn-compute`tokio::runtime::scheduler::multi_thread::queue::Steal<T>::steal_into (29 samples, 0.02%)dkn-compute`parking_lot::condvar::Condvar::notify_one_slow (15 samples, 0.01%)libsystem_kernel.dylib`__psynch_cvsignal (13 samples, 0.01%)libsystem_kernel.dylib`__psynch_cvwait (883 samples, 0.69%)libsystem_kernel.dylib`__psynch_mutexwait (37 samples, 0.03%)libsystem_pthread.dylib`_pthread_mutex_firstfit_lock_slow (39 samples, 0.03%)libsystem_pthread.dylib`_pthread_cond_wait (80 samples, 0.06%)dkn-compute`parking_lot::condvar::Condvar::wait_until_internal (990 samples, 0.77%)dkn-compute`tokio::runtime::io::scheduled_io::ScheduledIo::wake (26 samples, 0.02%)dkn-compute`tokio::runtime::task::waker::wake_by_val (14 samples, 0.01%)libsystem_kernel.dylib`kevent (1,027 samples, 0.80%)dkn-compute`tokio::runtime::io::driver::Driver::turn (1,084 samples, 0.85%)libsystem_kernel.dylib`mach_absolute_time (13 samples, 0.01%)dkn-compute`std::sys::pal::unix::time::Timespec::now (32 samples, 0.03%)libsystem_c.dylib`clock_gettime (32 samples, 0.03%)dkn-compute`tokio::runtime::time::wheel::Wheel::next_expiration (18 samples, 0.01%)dkn-compute`tokio::runtime::time::_<impl tokio::runtime::time::handle::Handle>::process_at_sharded_time (78 samples, 0.06%)dkn-compute`tokio::runtime::time::wheel::Wheel::poll (41 samples, 0.03%)dkn-compute`tokio::runtime::time::wheel::Wheel::next_expiration (33 samples, 0.03%)dkn-compute`tokio::runtime::time::_<impl tokio::runtime::time::handle::Handle>::process (131 samples, 0.10%)dkn-compute`tokio::runtime::time::wheel::Wheel::next_expiration (27 samples, 0.02%)dkn-compute`tokio::runtime::time::Driver::park_internal (1,280 samples, 1.00%)dkn-compute`tokio::runtime::scheduler::multi_thread::park::Parker::park (2,329 samples, 1.82%)d..dkn-compute`tokio::runtime::io::driver::Driver::turn (28 samples, 0.02%)libsystem_kernel.dylib`kevent (28 samples, 0.02%)dkn-compute`tokio::runtime::time::Driver::park_internal (39 samples, 0.03%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::Context::park_timeout (2,411 samples, 1.89%)d..libsystem_kernel.dylib`__psynch_cvsignal (211 samples, 0.17%)dkn-compute`parking_lot::condvar::Condvar::notify_one_slow (242 samples, 0.19%)dkn-compute`tokio::runtime::driver::Handle::unpark (60 samples, 0.05%)libsystem_kernel.dylib`kevent (59 samples, 0.05%)libsystem_kernel.dylib`__psynch_cvsignal (133 samples, 0.10%)dkn-compute`parking_lot::condvar::Condvar::notify_one_slow (153 samples, 0.12%)dkn-compute`tokio::runtime::driver::Handle::unpark (57 samples, 0.04%)libsystem_kernel.dylib`kevent (55 samples, 0.04%)dkn-compute`tokio::runtime::context::with_scheduler (236 samples, 0.18%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::_<impl tokio::runtime::task::Schedule for alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>::yield_now (240 samples, 0.19%)dkn-compute`<libp2p_core::upgrade::apply::OutboundUpgradeApply<C,U> as core::future::future::Future>::poll (28 samples, 0.02%)dkn-compute`<libp2p_noise::Config as libp2p_core::upgrade::OutboundConnectionUpgrade<T>>::upgrade_outbound::_{{closure}} (28 samples, 0.02%)dkn-compute`<libp2p_tcp::Transport<T> as libp2p_core::transport::Transport>::dial::_{{closure}} (47 samples, 0.04%)libsystem_kernel.dylib`__connect (41 samples, 0.03%)dkn-compute`<libp2p_core::transport::map::MapFuture<T,F> as core::future::future::Future>::poll (86 samples, 0.07%)dkn-compute`<libp2p_core::transport::map::MapFuture<T,F> as core::future::future::Future>::poll (92 samples, 0.07%)dkn-compute`core::ptr::drop_in_place$LT$futures_util..future..try_future..into_future..IntoFuture$LT$libp2p_core..transport..timeout..Timeout$LT$libp2p_core..transport..map..MapFuture$LT$libp2p_core..either..EitherFuture$LT$libp2p_core..transport..map..MapFuture$LT$libp2p_core..transport..and_then..AndThenFuture$LT$libp2p_core..transport..and_then..AndThenFuture$LT$core..pin..Pin$LT$alloc..boxed..Box$LT$dyn$u20$core..future..future..Future$u2b$Output$u20$$u3d$$u20$core..result..Result$LT$libp2p_relay..priv_client..Connection$C$libp2p_relay..priv_client..transport..Error$GT$$u2b$core..marker..Send$GT$$GT$$C$libp2p_core..transport..upgrade..Builder$LT$libp2p_relay..priv_client..transport..Transport$GT$..authenticate$LT$libp2p_relay..priv_client..Connection$C$libp2p_noise..io..Output$LT$multistream_select..negotiated..Negotiated$LT$libp2p_relay..priv_client..Connection$GT$$GT$$C$libp2p_noise..Config$C$libp2p_noise..Error$GT$..$u7b$$u7b$closure$u7d$$u7d$$C$libp2p_core..transport..upgrade..Authenticate$LT$libp2p_relay..priv_c� (15 samples, 0.01%)dkn-compute`<tracing::instrument::Instrumented<T> as core::future::future::Future>::poll (112 samples, 0.09%)dkn-compute`<futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll (112 samples, 0.09%)dkn-compute`<futures_util::future::future::map::Map<Fut,F> as core::future::future::Future>::poll (112 samples, 0.09%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (115 samples, 0.09%)dkn-compute`<libp2p_swarm::connection::pool::concurrent_dial::ConcurrentDial as core::future::future::Future>::poll (116 samples, 0.09%)dkn-compute`<multistream_select::dialer_select::DialerSelectFuture<R,I> as core::future::future::Future>::poll (18 samples, 0.01%)dkn-compute`<libp2p_swarm::connection::StreamUpgrade<UserData,TOk,TErr> as core::future::future::Future>::poll (24 samples, 0.02%)dkn-compute`libp2p_swarm::connection::StreamUpgrade<UserData,TOk,TErr>::new_outbound::_{{closure}} (22 samples, 0.02%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (98 samples, 0.08%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (42 samples, 0.03%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (18 samples, 0.01%)dkn-compute`<futures_channel::mpsc::Receiver<T> as futures_core::stream::Stream>::poll_next (20 samples, 0.02%)dkn-compute`<futures_util::stream::stream::into_future::StreamFuture<St> as core::future::future::Future>::poll (28 samples, 0.02%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (61 samples, 0.05%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (13 samples, 0.01%)dkn-compute`<asynchronous_codec::framed::Framed<T,U> as futures_sink::Sink<<U as asynchronous_codec::encoder::Encoder>::Item>>::poll_ready (17 samples, 0.01%)dkn-compute`<&mio::net::tcp::stream::TcpStream as std::io::Write>::write (447 samples, 0.35%)libsystem_kernel.dylib`__sendto (445 samples, 0.35%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (462 samples, 0.36%)dkn-compute`<asynchronous_codec::framed_write::FramedWrite2<T> as futures_sink::Sink<<T as asynchronous_codec::encoder::Encoder>::Item>>::poll_flush (472 samples, 0.37%)dkn-compute`<snow::resolvers::ring::CipherChaChaPoly as snow::types::Cipher>::encrypt (109 samples, 0.09%)dkn-compute`ring::aead::chacha20_poly1305::chacha20_poly1305_seal (109 samples, 0.09%)dkn-compute`ring_core_0_17_8_chacha20_poly1305_seal (109 samples, 0.09%)dkn-compute`snow::transportstate::TransportState::write_message (113 samples, 0.09%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::transportstate::TransportState> as asynchronous_codec::encoder::Encoder>::encode (125 samples, 0.10%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_flush (618 samples, 0.48%)libsystem_malloc.dylib`tiny_malloc_should_clear (39 samples, 0.03%)libsystem_malloc.dylib`tiny_malloc_from_free_list (26 samples, 0.02%)libsystem_malloc.dylib`szone_malloc_should_clear (55 samples, 0.04%)dkn-compute`bytes::bytes_mut::BytesMut::zeroed (60 samples, 0.05%)dkn-compute`libp2p_noise::io::framed::decode_length_prefixed (38 samples, 0.03%)dkn-compute`ring::aead::chacha20_poly1305::chacha20_poly1305_open (590 samples, 0.46%)dkn-compute`ring_core_0_17_8_chacha20_poly1305_open (588 samples, 0.46%)dkn-compute`ring::aead::less_safe_key::open_within_ (598 samples, 0.47%)dkn-compute`<snow::resolvers::ring::CipherChaChaPoly as snow::types::Cipher>::decrypt (612 samples, 0.48%)dkn-compute`snow::transportstate::TransportState::read_message (628 samples, 0.49%)libsystem_platform.dylib`_platform_memmove (13 samples, 0.01%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::transportstate::TransportState> as asynchronous_codec::decoder::Decoder>::decode (791 samples, 0.62%)dkn-compute`<&mio::net::tcp::stream::TcpStream as std::io::Read>::read (1,278 samples, 1.00%)libsystem_kernel.dylib`__recvfrom (1,272 samples, 0.99%)dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (25 samples, 0.02%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_read_priv (1,315 samples, 1.03%)dkn-compute`<libp2p_tcp::provider::tokio::TcpStream as futures_io::if_std::AsyncRead>::poll_read (1,322 samples, 1.03%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncRead>::poll_read (1,353 samples, 1.06%)dkn-compute`<asynchronous_codec::framed_read::FramedRead2<T> as futures_core::stream::Stream>::poll_next (2,175 samples, 1.70%)libsystem_malloc.dylib`free_tiny (19 samples, 0.01%)dkn-compute`bytes::bytes_mut::shared_v_drop (35 samples, 0.03%)libsystem_platform.dylib`_platform_memmove (36 samples, 0.03%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncRead>::poll_read (2,464 samples, 1.93%)d..libsystem_platform.dylib`_platform_memset (173 samples, 0.14%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncRead>::poll_read (2,498 samples, 1.95%)d..libsystem_platform.dylib`_platform_memmove (14 samples, 0.01%)libsystem_malloc.dylib`tiny_malloc_should_clear (22 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_from_free_list (15 samples, 0.01%)libsystem_malloc.dylib`szone_malloc_should_clear (30 samples, 0.02%)dkn-compute`<yamux::frame::io::Io<T> as futures_core::stream::Stream>::poll_next (2,568 samples, 2.01%)d..dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (19 samples, 0.01%)dkn-compute`<asynchronous_codec::framed::Framed<T,U> as futures_sink::Sink<<U as asynchronous_codec::encoder::Encoder>::Item>>::poll_ready (20 samples, 0.02%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_write (23 samples, 0.02%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_flush (33 samples, 0.03%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_ready (30 samples, 0.02%)dkn-compute`<&mio::net::tcp::stream::TcpStream as std::io::Write>::write (100 samples, 0.08%)libsystem_kernel.dylib`__sendto (99 samples, 0.08%)dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (16 samples, 0.01%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_write_priv (122 samples, 0.10%)dkn-compute`<asynchronous_codec::framed::Framed<T,U> as futures_sink::Sink<<U as asynchronous_codec::encoder::Encoder>::Item>>::poll_ready (128 samples, 0.10%)dkn-compute`<snow::resolvers::ring::CipherChaChaPoly as snow::types::Cipher>::encrypt (105 samples, 0.08%)dkn-compute`ring::aead::chacha20_poly1305::chacha20_poly1305_seal (105 samples, 0.08%)dkn-compute`ring_core_0_17_8_chacha20_poly1305_seal (105 samples, 0.08%)dkn-compute`snow::transportstate::TransportState::write_message (109 samples, 0.09%)dkn-compute`<libp2p_noise::io::framed::Codec<snow::transportstate::TransportState> as asynchronous_codec::encoder::Encoder>::encode (112 samples, 0.09%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_write (251 samples, 0.20%)libsystem_malloc.dylib`free_tiny (13 samples, 0.01%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_ready (317 samples, 0.25%)libsystem_kernel.dylib`mach_absolute_time (22 samples, 0.02%)dkn-compute`std::sys::pal::unix::time::Timespec::now (36 samples, 0.03%)libsystem_c.dylib`clock_gettime (36 samples, 0.03%)dkn-compute`yamux::connection::rtt::Rtt::next_ping (51 samples, 0.04%)dkn-compute`yamux::connection::Connection<T>::poll_next_inbound (3,741 samples, 2.93%)dk..dkn-compute`<libp2p_yamux::Muxer<C> as libp2p_core::muxing::StreamMuxer>::poll (3,859 samples, 3.02%)dkn..libsystem_platform.dylib`_platform_memmove (38 samples, 0.03%)dkn-compute`<libp2p_core::muxing::boxed::Wrap<T> as libp2p_core::muxing::StreamMuxer>::poll (3,873 samples, 3.03%)dkn..dkn-compute`tokio::runtime::io::registration::Registration::poll_ready (17 samples, 0.01%)dkn-compute`tokio::net::tcp::stream::TcpStream::poll_read_priv (22 samples, 0.02%)dkn-compute`<libp2p_tcp::provider::tokio::TcpStream as futures_io::if_std::AsyncRead>::poll_read (23 samples, 0.02%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncRead>::poll_read (31 samples, 0.02%)dkn-compute`<asynchronous_codec::framed_read::FramedRead2<T> as futures_core::stream::Stream>::poll_next (41 samples, 0.03%)dkn-compute`<yamux::frame::io::Io<T> as futures_core::stream::Stream>::poll_next (158 samples, 0.12%)dkn-compute`<multistream_select::negotiated::Negotiated<TInner> as futures_io::if_std::AsyncRead>::poll_read (155 samples, 0.12%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncRead>::poll_read (153 samples, 0.12%)libsystem_platform.dylib`_platform_memset (104 samples, 0.08%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_flush (14 samples, 0.01%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_ready (14 samples, 0.01%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_write (13 samples, 0.01%)dkn-compute`<asynchronous_codec::framed::Framed<T,U> as futures_sink::Sink<<U as asynchronous_codec::encoder::Encoder>::Item>>::poll_ready (13 samples, 0.01%)dkn-compute`<libp2p_noise::io::Output<T> as futures_io::if_std::AsyncWrite>::poll_write (18 samples, 0.01%)dkn-compute`<yamux::frame::io::Io<T> as futures_sink::Sink<yamux::frame::Frame<()>>>::poll_ready (27 samples, 0.02%)dkn-compute`yamux::connection::Connection<T>::poll_next_inbound (237 samples, 0.19%)dkn-compute`<libp2p_yamux::Muxer<C> as libp2p_core::muxing::StreamMuxer>::poll_inbound (317 samples, 0.25%)libsystem_platform.dylib`_platform_memmove (43 samples, 0.03%)dkn-compute`<libp2p_core::muxing::boxed::Wrap<T> as libp2p_core::muxing::StreamMuxer>::poll_inbound (323 samples, 0.25%)dkn-compute`quick_protobuf::writer::Writer<W>::write_with_tag (16 samples, 0.01%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::Message as quick_protobuf::message::MessageWrite>::write_message (57 samples, 0.04%)libsystem_platform.dylib`_platform_memmove (23 samples, 0.02%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::Message as quick_protobuf::message::MessageRead>::from_reader (84 samples, 0.07%)libsystem_malloc.dylib`szone_malloc_should_clear (26 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_should_clear (26 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_from_free_list (17 samples, 0.01%)libsystem_malloc.dylib`szone_malloc_should_clear (30 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_should_clear (30 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_from_free_list (22 samples, 0.02%)dkn-compute`alloc::raw_vec::finish_grow (32 samples, 0.03%)dkn-compute`alloc::raw_vec::RawVec<T,A>::grow_one (41 samples, 0.03%)libsystem_malloc.dylib`nanov2_malloc (22 samples, 0.02%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::RPC as quick_protobuf::message::MessageRead>::from_reader (210 samples, 0.16%)libsystem_platform.dylib`_platform_memmove (14 samples, 0.01%)dkn-compute`<quick_protobuf_codec::Codec<In,Out> as asynchronous_codec::decoder::Decoder>::decode (256 samples, 0.20%)libsystem_malloc.dylib`nanov2_realloc (26 samples, 0.02%)libsystem_malloc.dylib`szone_malloc_should_clear (22 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_should_clear (20 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_from_free_list (13 samples, 0.01%)libsystem_malloc.dylib`malloc_zone_realloc (31 samples, 0.02%)dkn-compute`alloc::raw_vec::finish_grow (39 samples, 0.03%)libsystem_malloc.dylib`realloc (33 samples, 0.03%)dkn-compute`alloc::raw_vec::RawVec<T,A>::reserve::do_reserve_and_handle (42 samples, 0.03%)libsystem_malloc.dylib`_nanov2_free (15 samples, 0.01%)libsystem_malloc.dylib`free_tiny (19 samples, 0.01%)dkn-compute`core::ptr::drop_in_place<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::Message> (49 samples, 0.04%)dkn-compute`libsecp256k1_core::field::Field::eq_var (17 samples, 0.01%)dkn-compute`libsecp256k1_core::field::Field::mul_in_place (61 samples, 0.05%)dkn-compute`libsecp256k1_core::field::Field::sqr_in_place (51 samples, 0.04%)dkn-compute`libsecp256k1_core::field::Field::mul_in_place (353 samples, 0.28%)dkn-compute`libsecp256k1_core::field::Field::sqr_in_place (5,064 samples, 3.96%)dkn-..dkn-compute`libsecp256k1::PublicKey::parse_slice (5,824 samples, 4.56%)dkn-c..dkn-compute`libsecp256k1_core::group::Affine::set_xo_var (5,677 samples, 4.44%)dkn-c..dkn-compute`libsecp256k1_core::field::Field::sqrt (246 samples, 0.19%)dkn-compute`libp2p_identity::secp256k1::PublicKey::try_from_bytes (5,833 samples, 4.56%)dkn-c..dkn-compute`<libp2p_identity::keypair::PublicKey as core::convert::TryFrom<libp2p_identity::proto::keys_proto::PublicKey>>::try_from (5,857 samples, 4.58%)dkn-c..dkn-compute`libp2p_identity::keypair::PublicKey::try_decode_protobuf (5,877 samples, 4.60%)dkn-c..dkn-compute`<D as digest::digest::Digest>::digest (18 samples, 0.01%)dkn-compute`libsecp256k1::Message::parse_slice (53 samples, 0.04%)dkn-compute`libsecp256k1_core::scalar::Scalar::set_b32 (46 samples, 0.04%)dkn-compute`subtle::black_box (32 samples, 0.03%)dkn-compute`libsecp256k1_core::scalar::Scalar::check_overflow (21 samples, 0.02%)dkn-compute`libsecp256k1_core::scalar::Scalar::set_b32 (63 samples, 0.05%)dkn-compute`subtle::black_box (34 samples, 0.03%)dkn-compute`libsecp256k1_core::der::Decoder::read_integer (87 samples, 0.07%)dkn-compute`libsecp256k1::Signature::parse_der (101 samples, 0.08%)dkn-compute`<libsecp256k1_core::group::Affine as core::convert::From<libsecp256k1_core::group::AffineStorage>>::from (49 samples, 0.04%)dkn-compute`core::array::_<impl core::default::Default for [T (74 samples, 0.06%) _]>::default (74 samples, 0.06%)dkn-compute`libsecp256k1_core::ecmult::ecmult_wnaf (506 samples, 0.40%)dkn-compute`libsecp256k1_core::field::Field::mul_in_place (1,614 samples, 1.26%)dkn-compute`libsecp256k1_core::field::Field::sqr_in_place (417 samples, 0.33%)dkn-compute`libsecp256k1_core::group::Jacobian::add_ge_var_in_place (164 samples, 0.13%)dkn-compute`libsecp256k1_core::ecmult::odd_multiples_table (2,256 samples, 1.76%)dkn-compute`libsecp256k1_core::group::Jacobian::double_var_in_place (13 samples, 0.01%)dkn-compute`libsecp256k1_core::field::Field::mul_in_place (36,647 samples, 28.67%)dkn-compute`libsecp256k1_core::field::Field::m..dkn-compute`libsecp256k1_core::field::Field::sqr_in_place (21,652 samples, 16.94%)dkn-compute`libsecp256k1_c..dkn-compute`libsecp256k1_core::group::Jacobian::add_ge_var_in_place (945 samples, 0.74%)dkn-compute`libsecp256k1_core::group::Jacobian::add_zinv_var_in_place (403 samples, 0.32%)dkn-compute`libsecp256k1_core::group::Jacobian::double_var_in_place (2,074 samples, 1.62%)dkn-compute`libsecp256k1_core::group::globalz_set_table_gej (34 samples, 0.03%)dkn-compute`libsecp256k1_core::ecmult::ECMultContext::ecmult (66,789 samples, 52.24%)dkn-compute`libsecp256k1_core::ecmult::ECMultContext::ecmultlibsystem_platform.dylib`_platform_memset (25 samples, 0.02%)dkn-compute`libsecp256k1_core::field::Field::mul_in_place (53 samples, 0.04%)dkn-compute`libsecp256k1_core::field::Field::sqr_in_place (13 samples, 0.01%)dkn-compute`libsecp256k1_core::group::Jacobian::add_ge_var_in_place (48 samples, 0.04%)dkn-compute`libsecp256k1_core::group::Jacobian::add_zinv_var_in_place (187 samples, 0.15%)dkn-compute`libsecp256k1_core::group::Jacobian::double_var_in_place (572 samples, 0.45%)dkn-compute`libsecp256k1_core::scalar::Scalar::check_overflow (327 samples, 0.26%)dkn-compute`libsecp256k1_core::scalar::Scalar::reduce_512 (1,853 samples, 1.45%)dkn-compute`subtle::black_box (541 samples, 0.42%)dkn-compute`libsecp256k1_core::scalar::Scalar::mul_in_place (4,016 samples, 3.14%)dkn..dkn-compute`subtle::black_box (84 samples, 0.07%)dkn-compute`libsecp256k1_core::scalar::Scalar::reduce_512 (774 samples, 0.61%)dkn-compute`libsecp256k1_core::scalar::Scalar::check_overflow (92 samples, 0.07%)dkn-compute`libsecp256k1_core::scalar::Scalar::check_overflow (2,233 samples, 1.75%)dkn-compute`libsecp256k1_core::scalar::Scalar::reduce_512 (12,673 samples, 9.91%)dkn-compute`li..dkn-compute`subtle::black_box (3,707 samples, 2.90%)dk..dkn-compute`libsecp256k1_core::scalar::Scalar::inv_in_place (32,442 samples, 25.38%)dkn-compute`libsecp256k1_core::scalar::Sc..dkn-compute`libsecp256k1_core::scalar::Scalar::sqr_in_place (27,274 samples, 21.33%)dkn-compute`libsecp256k1_core::sca..dkn-compute`subtle::black_box (738 samples, 0.58%)dkn-compute`libsecp256k1_core::scalar::Scalar::check_overflow (26 samples, 0.02%)dkn-compute`libsecp256k1_core::scalar::Scalar::reduce_512 (108 samples, 0.08%)dkn-compute`subtle::black_box (36 samples, 0.03%)dkn-compute`libsecp256k1_core::scalar::Scalar::mul_in_place (326 samples, 0.25%)dkn-compute`libsecp256k1_core::scalar::Scalar::sqr_in_place (646 samples, 0.51%)dkn-compute`libsecp256k1_core::ecdsa::_<impl libsecp256k1_core::ecmult::ECMultContext>::verify_raw (101,258 samples, 79.20%)dkn-compute`libsecp256k1_core::ecdsa::_<impl libsecp256k1_core::ecmult::ECMultContext>::verify_rawlibsystem_platform.dylib`_platform_memset (20 samples, 0.02%)dkn-compute`sha2::sha256::compress256 (1,338 samples, 1.05%)dkn-compute`libp2p_identity::keypair::PublicKey::verify (102,815 samples, 80.42%)dkn-compute`libp2p_identity::keypair::PublicKey::verifydkn-compute`multihash::multihash::Multihash<_>::from_bytes (30 samples, 0.02%)dkn-compute`libp2p_identity::peer_id::PeerId::from_bytes (51 samples, 0.04%)dkn-compute`libsecp256k1_core::field::Field::normalize_var (25 samples, 0.02%)dkn-compute`libp2p_identity::keypair::PublicKey::encode_protobuf (60 samples, 0.05%)dkn-compute`libp2p_identity::peer_id::PeerId::from_public_key (76 samples, 0.06%)libsystem_malloc.dylib`nanov2_realloc (15 samples, 0.01%)dkn-compute`alloc::raw_vec::finish_grow (34 samples, 0.03%)libsystem_malloc.dylib`realloc (29 samples, 0.02%)libsystem_malloc.dylib`malloc_zone_realloc (24 samples, 0.02%)dkn-compute`multihash::multihash::Multihash<_>::to_bytes (44 samples, 0.03%)dkn-compute`alloc::raw_vec::RawVec<T,A>::reserve::do_reserve_and_handle (39 samples, 0.03%)libsystem_malloc.dylib`_nanov2_free (51 samples, 0.04%)libsystem_malloc.dylib`free (16 samples, 0.01%)libsystem_malloc.dylib`free_tiny (83 samples, 0.06%)libsystem_malloc.dylib`tiny_free_no_lock (52 samples, 0.04%)libsystem_malloc.dylib`nanov2_malloc (13 samples, 0.01%)libsystem_malloc.dylib`set_tiny_meta_header_in_use (14 samples, 0.01%)libsystem_malloc.dylib`tiny_malloc_from_free_list (55 samples, 0.04%)libsystem_malloc.dylib`tiny_free_list_add_ptr (18 samples, 0.01%)libsystem_malloc.dylib`szone_malloc_should_clear (88 samples, 0.07%)libsystem_malloc.dylib`tiny_malloc_should_clear (85 samples, 0.07%)dkn-compute`<libp2p_gossipsub::protocol::GossipsubCodec as asynchronous_codec::decoder::Decoder>::decode (109,689 samples, 85.80%)dkn-compute`<libp2p_gossipsub::protocol::GossipsubCodec as asynchronous_codec::decoder::Decoder>::decodelibsystem_platform.dylib`_platform_memset (23 samples, 0.02%)dkn-compute`futures_channel::mpsc::BoundedSenderInner<T>::poll_unparked (28 samples, 0.02%)dkn-compute`yamux::connection::stream::Stream::send_window_update (17 samples, 0.01%)libsystem_malloc.dylib`free_tiny (39 samples, 0.03%)libsystem_malloc.dylib`tiny_free_no_lock (27 samples, 0.02%)dkn-compute`<yamux::connection::stream::Stream as futures_io::if_std::AsyncRead>::poll_read (121 samples, 0.09%)dkn-compute`<libp2p_swarm::stream::Stream as futures_io::if_std::AsyncRead>::poll_read (148 samples, 0.12%)libsystem_malloc.dylib`free (21 samples, 0.02%)libsystem_malloc.dylib`nanov2_malloc (31 samples, 0.02%)dkn-compute`<asynchronous_codec::framed_read::FramedRead2<T> as futures_core::stream::Stream>::poll_next (110,018 samples, 86.06%)dkn-compute`<asynchronous_codec::framed_read::FramedRead2<T> as futures_core::stream::Stream>::poll_nextlibsystem_platform.dylib`_platform_memmove (40 samples, 0.03%)dkn-compute`futures_channel::mpsc::BoundedSenderInner<T>::poll_unparked (19 samples, 0.01%)dkn-compute`<yamux::connection::stream::Stream as futures_io::if_std::AsyncWrite>::poll_flush (28 samples, 0.02%)dkn-compute`<yamux::connection::stream::Stream as futures_io::if_std::AsyncWrite>::poll_write (53 samples, 0.04%)libsystem_malloc.dylib`szone_malloc_should_clear (24 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_should_clear (22 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_from_free_list (13 samples, 0.01%)dkn-compute`<asynchronous_codec::framed_write::FramedWrite2<T> as futures_sink::Sink<<T as asynchronous_codec::encoder::Encoder>::Item>>::poll_flush (102 samples, 0.08%)dkn-compute`<quick_protobuf_codec::BytesMutWriterBackend as quick_protobuf::writer::WriterBackend>::pb_write_all (26 samples, 0.02%)libsystem_platform.dylib`_platform_memmove (20 samples, 0.02%)dkn-compute`<bytes::bytes_mut::BytesMut as bytes::buf::buf_mut::BufMut>::put_slice (16 samples, 0.01%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::Message as quick_protobuf::message::MessageWrite>::write_message (97 samples, 0.08%)dkn-compute`quick_protobuf::writer::Writer<W>::write_with_tag (57 samples, 0.04%)dkn-compute`<quick_protobuf_codec::BytesMutWriterBackend as quick_protobuf::writer::WriterBackend>::pb_write_u8 (34 samples, 0.03%)dkn-compute`<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::RPC as quick_protobuf::message::MessageWrite>::write_message (129 samples, 0.10%)dkn-compute`quick_protobuf::writer::Writer<W>::write_with_tag (20 samples, 0.02%)libsystem_malloc.dylib`_nanov2_free (18 samples, 0.01%)libsystem_malloc.dylib`free_tiny (29 samples, 0.02%)libsystem_malloc.dylib`tiny_free_no_lock (20 samples, 0.02%)dkn-compute`core::ptr::drop_in_place<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::Message> (56 samples, 0.04%)dkn-compute`core::ptr::drop_in_place<libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::RPC> (73 samples, 0.06%)dkn-compute`<quick_protobuf_codec::Codec<In,Out> as asynchronous_codec::encoder::Encoder>::encode (228 samples, 0.18%)libsystem_c.dylib`clock_gettime (51 samples, 0.04%)libsystem_kernel.dylib`mach_absolute_time (39 samples, 0.03%)dkn-compute`std::sys::pal::unix::time::Timespec::now (53 samples, 0.04%)libsystem_platform.dylib`_platform_memmove (43 samples, 0.03%)dkn-compute`libp2p_gossipsub::handler::EnabledHandler::poll (110,763 samples, 86.64%)dkn-compute`libp2p_gossipsub::handler::EnabledHandler::polllibsystem_platform.dylib`_platform_memset (198 samples, 0.15%)dkn-compute`tracing::span::Span::log (20 samples, 0.02%)dkn-compute`<libp2p_gossipsub::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::poll (110,856 samples, 86.71%)dkn-compute`<libp2p_gossipsub::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::polllibsystem_platform.dylib`_platform_memmove (20 samples, 0.02%)dkn-compute`futures_bounded::futures_map::FuturesMap<ID,O>::poll_unpin (16 samples, 0.01%)dkn-compute`tracing::span::Span::record_all (16 samples, 0.01%)dkn-compute`<libp2p_identify::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::poll (91 samples, 0.07%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (23 samples, 0.02%)dkn-compute`<futures_util::stream::select_all::SelectAll<St> as futures_core::stream::Stream>::poll_next (31 samples, 0.02%)dkn-compute`futures_bounded::futures_tuple_set::FuturesTupleSet<O,D>::poll_unpin (36 samples, 0.03%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (33 samples, 0.03%)dkn-compute`tracing::span::Span::record_all (18 samples, 0.01%)dkn-compute`<libp2p_kad::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::poll (140 samples, 0.11%)dkn-compute`<futures_channel::mpsc::Receiver<T> as futures_core::stream::Stream>::poll_next (17 samples, 0.01%)dkn-compute`<libp2p_request_response::handler::Handler<TCodec> as libp2p_swarm::handler::ConnectionHandler>::poll (89 samples, 0.07%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (35 samples, 0.03%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (18 samples, 0.01%)dkn-compute`futures_bounded::futures_set::FuturesSet<O>::poll_unpin (44 samples, 0.03%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (32 samples, 0.03%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (24 samples, 0.02%)dkn-compute`futures_core::task::__internal::atomic_waker::AtomicWaker::register (36 samples, 0.03%)dkn-compute`<futures_util::stream::futures_unordered::FuturesUnordered<Fut> as futures_core::stream::Stream>::poll_next (81 samples, 0.06%)dkn-compute`futures_bounded::futures_tuple_set::FuturesTupleSet<O,D>::poll_unpin (97 samples, 0.08%)dkn-compute`tokio::runtime::task::waker::drop_waker (33 samples, 0.03%)dkn-compute`tracing::span::Span::log (18 samples, 0.01%)dkn-compute`tracing::span::Span::record_all (18 samples, 0.01%)dkn-compute`<libp2p_relay::priv_client::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::poll (326 samples, 0.25%)dkn-compute`libp2p_swarm::handler::either::_<impl libp2p_swarm::handler::ConnectionHandler for either::Either<L,R>>::poll (365 samples, 0.29%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::poll (111,623 samples, 87.31%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::polldkn-compute`<T as libp2p_swarm::upgrade::UpgradeInfoSend>::protocol_info (24 samples, 0.02%)dkn-compute`<T as libp2p_swarm::upgrade::UpgradeInfoSend>::protocol_info (48 samples, 0.04%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (42 samples, 0.03%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::insert (99 samples, 0.08%)libsystem_malloc.dylib`_nanov2_free (18 samples, 0.01%)dkn-compute`libp2p_swarm::stream_protocol::StreamProtocol::try_from_owned (36 samples, 0.03%)libsystem_malloc.dylib`_malloc_zone_malloc (18 samples, 0.01%)libsystem_malloc.dylib`free (14 samples, 0.01%)libsystem_malloc.dylib`nanov2_malloc (29 samples, 0.02%)dkn-compute`core::iter::adapters::filter_map::filter_map_fold::_{{closure}} (259 samples, 0.20%)libsystem_platform.dylib`_platform_memmove (18 samples, 0.01%)libsystem_malloc.dylib`nanov2_malloc (26 samples, 0.02%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold (362 samples, 0.28%)libsystem_platform.dylib`_platform_memmove (14 samples, 0.01%)dkn-compute`<core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold (384 samples, 0.30%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (15 samples, 0.01%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (37 samples, 0.03%)dkn-compute`core::hash::BuildHasher::hash_one (14 samples, 0.01%)dkn-compute`hashbrown::raw::RawTable<T,A>::reserve_rehash (89 samples, 0.07%)libsystem_malloc.dylib`nanov2_malloc (18 samples, 0.01%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::insert (159 samples, 0.12%)dkn-compute`libp2p_swarm::stream_protocol::StreamProtocol::try_from_owned (13 samples, 0.01%)dkn-compute`core::iter::adapters::filter_map::filter_map_fold::_{{closure}} (185 samples, 0.14%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold (215 samples, 0.17%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (27 samples, 0.02%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::insert (56 samples, 0.04%)libsystem_malloc.dylib`_nanov2_free (15 samples, 0.01%)dkn-compute`libp2p_swarm::stream_protocol::StreamProtocol::try_from_owned (22 samples, 0.02%)dkn-compute`core::iter::adapters::filter_map::filter_map_fold::_{{closure}} (123 samples, 0.10%)dkn-compute`<core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold (786 samples, 0.61%)dkn-compute`<core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold (800 samples, 0.63%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::insert (16 samples, 0.01%)dkn-compute`core::iter::adapters::filter_map::filter_map_fold::_{{closure}} (44 samples, 0.03%)dkn-compute`<core::iter::adapters::map::Map<I,F> as core::iter::traits::iterator::Iterator>::fold (66 samples, 0.05%)dkn-compute`<core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold (878 samples, 0.69%)dkn-compute`<core::iter::adapters::chain::Chain<A,B> as core::iter::traits::iterator::Iterator>::fold (881 samples, 0.69%)dkn-compute`<hashbrown::map::HashMap<K,V,S,A> as core::iter::traits::collect::Extend<(K,V)>>::extend (888 samples, 0.69%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::listen_protocol (105 samples, 0.08%)libsystem_malloc.dylib`nanov2_malloc (18 samples, 0.01%)dkn-compute`core::ptr::drop_in_place$LT$libp2p_core..upgrade..select..SelectUpgrade$LT$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..select..SelectUpgrade$LT$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..select..SelectUpgrade$LT$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..select..SelectUpgrade$LT$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..select..SelectUpgrade$LT$libp2p_swarm..upgrade..SendWrapper$LT$either..Either$LT$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..ready..ReadyUpgrade$LT$libp2p_swarm..stream_protocol..StreamProtocol$GT$$GT$$C$libp2p_swarm..upgrade..SendWrapper$LT$libp2p_core..upgrade..denied..DeniedUpgrade$GT$$GT$$GT$$C$libp2p_swarm..upgrade..SendWrapper$LT$either..Either$LT$libp2p_gossipsub..protocol..ProtocolConfig$C$libp2p_core..upgrade..denied..DeniedUpgrade$GT$$GT$$GT$$GT$$C$libp2p_swarm..upgrade..SendWrapper$LT$either..Either$LT$libp2p_kad..protocol..ProtocolConfig$C$libp2p_core..upgrade..denied..DeniedUpgrade$GT$$GT$$GT$$GT$$� (29 samples, 0.02%)dkn-compute`libp2p_swarm::connection::gather_supported_protocols (1,111 samples, 0.87%)dkn-compute`<core::hash::sip::Hasher<S> as core::hash::Hasher>::write (102 samples, 0.08%)dkn-compute`hashbrown::map::HashMap<K,V,S,A>::contains_key (160 samples, 0.13%)dkn-compute`core::hash::BuildHasher::hash_one (22 samples, 0.02%)dkn-compute`libp2p_swarm::handler::ProtocolsChange::from_full_sets (241 samples, 0.19%)libsystem_platform.dylib`_platform_memcmp (65 samples, 0.05%)dkn-compute`tracing::span::Span::log (16 samples, 0.01%)dkn-compute`tracing::span::Span::record_all (14 samples, 0.01%)libsystem_malloc.dylib`_nanov2_free (51 samples, 0.04%)dkn-compute`futures_util::future::future::FutureExt::poll_unpin (117,518 samples, 91.92%)dkn-compute`futures_util::future::future::FutureExt::poll_unpinlibsystem_platform.dylib`_platform_memset (36 samples, 0.03%)libsystem_malloc.dylib`_nanov2_free (15 samples, 0.01%)dkn-compute`futures_channel::mpsc::queue::Queue<T>::pop_spin (77 samples, 0.06%)dkn-compute`futures_channel::mpsc::Receiver<T>::next_message (116 samples, 0.09%)dkn-compute`futures_util::stream::stream::StreamExt::poll_next_unpin (152 samples, 0.12%)libsystem_malloc.dylib`free (23 samples, 0.02%)dkn-compute`<futures_util::future::select::Select<A,B> as core::future::future::Future>::poll (117,900 samples, 92.22%)dkn-compute`<futures_util::future::select::Select<A,B> as core::future::future::Future>::polllibsystem_kernel.dylib`mach_absolute_time (39 samples, 0.03%)dkn-compute`std::sys::pal::unix::time::Timespec::now (44 samples, 0.03%)libsystem_c.dylib`clock_gettime (44 samples, 0.03%)libsystem_kernel.dylib`__psynch_cvsignal (548 samples, 0.43%)dkn-compute`parking_lot::condvar::Condvar::notify_one_slow (629 samples, 0.49%)dkn-compute`<futures_util::stream::futures_unordered::task::Task<Fut> as futures_task::arc_wake::ArcWake>::wake_by_ref (654 samples, 0.51%)dkn-compute`tokio::runtime::park::wake (643 samples, 0.50%)dkn-compute`futures_task::waker::wake_arc_raw (659 samples, 0.52%)libsystem_malloc.dylib`szone_malloc_should_clear (24 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_should_clear (22 samples, 0.02%)libsystem_malloc.dylib`tiny_malloc_from_free_list (14 samples, 0.01%)dkn-compute`futures_channel::mpsc::sink_impl::_<impl futures_sink::Sink<T> for futures_channel::mpsc::Sender<T>>::start_send (691 samples, 0.54%)dkn-compute`<futures_util::sink::send::Send<Si,Item> as core::future::future::Future>::poll (742 samples, 0.58%)libsystem_platform.dylib`_platform_memmove (24 samples, 0.02%)libsystem_malloc.dylib`nanov2_malloc (22 samples, 0.02%)libsystem_malloc.dylib`malloc_zone_realloc (44 samples, 0.03%)dkn-compute`alloc::raw_vec::finish_grow (58 samples, 0.05%)libsystem_malloc.dylib`realloc (50 samples, 0.04%)dkn-compute`alloc::raw_vec::RawVec<T,A>::reserve::do_reserve_and_handle (63 samples, 0.05%)dkn-compute`multihash::multihash::Multihash<_>::to_bytes (70 samples, 0.05%)dkn-compute`libp2p_gossipsub::types::_<impl core::convert::From<libp2p_gossipsub::types::RawMessage> for libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::Message>::from (90 samples, 0.07%)dkn-compute`libp2p_gossipsub::types::_<impl core::convert::From<libp2p_gossipsub::types::RpcOut> for libp2p_gossipsub::rpc_proto::proto::gossipsub::pb::RPC>::from (123 samples, 0.10%)dkn-compute`<libp2p_gossipsub::handler::Handler as libp2p_swarm::handler::ConnectionHandler>::on_behaviour_event (155 samples, 0.12%)libsystem_malloc.dylib`nanov2_malloc (14 samples, 0.01%)dkn-compute`<libp2p_swarm::handler::select::ConnectionHandlerSelect<TProto1,TProto2> as libp2p_swarm::handler::ConnectionHandler>::on_behaviour_event (183 samples, 0.14%)dkn-compute`tracing::span::Span::log (16 samples, 0.01%)dkn-compute`<tracing::instrument::Instrumented<T> as core::future::future::Future>::poll (118,919 samples, 93.02%)dkn-compute`<tracing::instrument::Instrumented<T> as core::future::future::Future>::polllibsystem_platform.dylib`_platform_memmove (15 samples, 0.01%)dkn-compute`tokio::runtime::task::core::Core<T,S>::poll (118,974 samples, 93.06%)dkn-compute`tokio::runtime::task::core::Core<T,S>::polllibsystem_platform.dylib`_platform_memmove (22 samples, 0.02%)dkn-compute`tokio::runtime::task::harness::Harness<T,S>::poll (119,253 samples, 93.28%)dkn-compute`tokio::runtime::task::harness::Harness<T,S>::polldkn-compute`tokio::runtime::scheduler::multi_thread::worker::Context::run_task (119,592 samples, 93.55%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::Context::run_taskdkn-compute`tokio::runtime::scheduler::multi_thread::worker::Context::run (122,254 samples, 95.63%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::Context::runall (127,844 samples, 100%)libsystem_pthread.dylib`thread_start (122,312 samples, 95.67%)libsystem_pthread.dylib`thread_startlibsystem_pthread.dylib`_pthread_start (122,312 samples, 95.67%)libsystem_pthread.dylib`_pthread_startdkn-compute`std::sys::pal::unix::thread::Thread::new::thread_start (122,312 samples, 95.67%)dkn-compute`std::sys::pal::unix::thread::Thread::new::thread_startdkn-compute`core::ops::function::FnOnce::call_once{{vtable.shim}} (122,312 samples, 95.67%)dkn-compute`core::ops::function::FnOnce::call_once{{vtable.shim}}dkn-compute`std::sys_common::backtrace::__rust_begin_short_backtrace (122,312 samples, 95.67%)dkn-compute`std::sys_common::backtrace::__rust_begin_short_backtracedkn-compute`tokio::runtime::blocking::pool::Inner::run (122,273 samples, 95.64%)dkn-compute`tokio::runtime::blocking::pool::Inner::rundkn-compute`tokio::runtime::task::harness::Harness<T,S>::poll (122,273 samples, 95.64%)dkn-compute`tokio::runtime::task::harness::Harness<T,S>::polldkn-compute`tokio::runtime::task::core::Core<T,S>::poll (122,273 samples, 95.64%)dkn-compute`tokio::runtime::task::core::Core<T,S>::polldkn-compute`tokio::runtime::scheduler::multi_thread::worker::run (122,272 samples, 95.64%)dkn-compute`tokio::runtime::scheduler::multi_thread::worker::rundkn-compute`tokio::runtime::context::runtime::enter_runtime (122,272 samples, 95.64%)dkn-compute`tokio::runtime::context::runtime::enter_runtimedkn-compute`tokio::runtime::context::set_scheduler (122,272 samples, 95.64%)dkn-compute`tokio::runtime::context::set_scheduler \ No newline at end of file From 6de5628fa62e869aeed1425da0c200656f15c872 Mon Sep 17 00:00:00 2001 From: erhant Date: Tue, 1 Oct 2024 18:17:06 +0300 Subject: [PATCH 05/15] removed start.sh, bump minor version --- Cargo.lock | 2 +- Cargo.toml | 2 +- start.sh | 7 ------- 3 files changed, 2 insertions(+), 9 deletions(-) delete mode 100755 start.sh diff --git a/Cargo.lock b/Cargo.lock index 386dbc9..ac7f0de 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1035,7 +1035,7 @@ dependencies = [ [[package]] name = "dkn-compute" -version = "0.2.5" +version = "0.3.0" dependencies = [ "async-trait", "base64 0.22.1", diff --git a/Cargo.toml b/Cargo.toml index ef0ad23..a6b62f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dkn-compute" -version = "0.2.5" +version = "0.3.0" edition = "2021" license = "Apache-2.0" readme = "README.md" diff --git a/start.sh b/start.sh deleted file mode 100755 index 8d1ca90..0000000 --- a/start.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -echo "Start script is deprecated, please see: https://dria.co/guide" -echo "We are using a cross-platform launcher now: https://github.com/firstbatchxyz/dkn-compute-launcher" -echo "After a few releases, this script will be removed all-together." -echo "Exiting..." -exit 1 From d3ca0b817243938a8de7c9d7889c396fdd1149a0 Mon Sep 17 00:00:00 2001 From: erhant Date: Tue, 1 Oct 2024 19:12:38 +0300 Subject: [PATCH 06/15] more tidyups and sanitizations --- Makefile | 6 +----- src/config/ollama.rs | 3 +-- src/handlers/workflow.rs | 13 ++++++++++++- src/main.rs | 5 ++--- src/node.rs | 22 +--------------------- src/p2p/client.rs | 12 +++++++----- src/p2p/data_transform.rs | 1 + src/p2p/mod.rs | 36 +++--------------------------------- src/p2p/versioning.rs | 35 +++++++++++++++++++++++++++++++++++ src/utils/crypto.rs | 6 ++---- src/utils/filter.rs | 27 ++------------------------- src/utils/message.rs | 11 +++++++---- src/utils/payload.rs | 4 ++-- 13 files changed, 76 insertions(+), 105 deletions(-) create mode 100644 src/p2p/versioning.rs diff --git a/Makefile b/Makefile index fd07db0..99eebda 100644 --- a/Makefile +++ b/Makefile @@ -37,10 +37,6 @@ profile-mem: version: @cargo pkgid | cut -d@ -f2 -.PHONY: ollama-cpu # | Run Ollama CPU container -ollama-cpu: - docker run -p=11434:11434 -v=${HOME}/.ollama:/root/.ollama ollama/ollama - ############################################################################### .PHONY: test # | Run tests test: @@ -58,7 +54,7 @@ format: ############################################################################### .PHONY: docs # | Generate & open crate documentation docs: - cargo doc --open --no-deps + cargo doc --open --no-deps --document-private-items .PHONY: env # | Print active environment env: diff --git a/src/config/ollama.rs b/src/config/ollama.rs index 425b53d..e720224 100644 --- a/src/config/ollama.rs +++ b/src/config/ollama.rs @@ -1,5 +1,3 @@ -use std::time::Duration; - use eyre::{eyre, Result}; use ollama_workflows::{ ollama_rs::{ @@ -12,6 +10,7 @@ use ollama_workflows::{ }, Model, }; +use std::time::Duration; const DEFAULT_OLLAMA_HOST: &str = "http://127.0.0.1"; const DEFAULT_OLLAMA_PORT: u16 = 11434; diff --git a/src/handlers/workflow.rs b/src/handlers/workflow.rs index 3303de5..c4c64a7 100644 --- a/src/handlers/workflow.rs +++ b/src/handlers/workflow.rs @@ -92,6 +92,7 @@ impl ComputeHandler for WorkflowHandler { .map(|prompt| Entry::try_value_or_str(&prompt)); // execute workflow with cancellation + // TODO: is there a better way to handle this? let result: String; tokio::select! { _ = node.cancellation.cancelled() => { @@ -111,7 +112,17 @@ impl ComputeHandler for WorkflowHandler { } // publish the result - node.send_result(result_topic, &task.public_key, &task.task_id, result)?; + let payload = P2PMessage::new_signed_encrypted_payload( + result, + &task.task_id, + &task.public_key, + &node.config.secret_key, + )?; + let payload_str = payload.to_string()?; + let message = P2PMessage::new(payload_str, result_topic); + + node.publish(message)?; + Ok(MessageAcceptance::Accept) } } diff --git a/src/main.rs b/src/main.rs index 2c523d4..5732993 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use dkn_compute::{DriaComputeNode, DriaComputeNodeConfig}; +use dkn_compute::*; use eyre::Result; use tokio_util::sync::CancellationToken; @@ -17,12 +17,11 @@ async fn main() -> Result<()> { ██████╗ ██████╗ ██╗ █████╗ ██╔══██╗██╔══██╗██║██╔══██╗ Dria Compute Node -██║ ██║██████╔╝██║███████║ v{} +██║ ██║██████╔╝██║███████║ v{DRIA_COMPUTE_NODE_VERSION} ██║ ██║██╔══██╗██║██╔══██║ https://dria.co ██████╔╝██║ ██║██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═╝ "#, - dkn_compute::DRIA_COMPUTE_NODE_VERSION ); let token = CancellationToken::new(); diff --git a/src/node.rs b/src/node.rs index 476c6dc..a5ef00b 100644 --- a/src/node.rs +++ b/src/node.rs @@ -185,7 +185,6 @@ impl DriaComputeNode { // validate the message based on the result match handle_result { Ok(acceptance) => { - self.p2p.validate_message(&message_id, &peer_id, acceptance)?; }, Err(err) => { @@ -235,32 +234,13 @@ impl DriaComputeNode { // check dria signature // NOTE: when we have many public keys, we should check the signature against all of them + // TODO: public key here will be given dynamically if !message.is_signed(&self.config.admin_public_key)? { return Err(eyre!("Invalid signature.")); } Ok(message) } - - /// Given a task with `id` and respective `public_key`, sign-then-encrypt the result. - pub fn send_result>( - &mut self, - response_topic: &str, - public_key: &[u8], - task_id: &str, - result: R, - ) -> Result<()> { - let payload = P2PMessage::new_signed_encrypted_payload( - result.as_ref(), - task_id, - public_key, - &self.config.secret_key, - )?; - let payload_str = payload.to_string()?; - let message = P2PMessage::new(payload_str, response_topic); - - self.publish(message) - } } #[cfg(test)] diff --git a/src/p2p/client.rs b/src/p2p/client.rs index a0b831b..06c9441 100644 --- a/src/p2p/client.rs +++ b/src/p2p/client.rs @@ -12,15 +12,17 @@ use libp2p_identity::Keypair; use std::time::Duration; use std::time::Instant; +use super::*; use crate::utils::AvailableNodes; -use super::{DriaBehaviour, DriaBehaviourEvent, P2P_KADEMLIA_PROTOCOL, P2P_PROTOCOL_STRING}; - -/// Underlying libp2p client. +/// P2P client, exposes a simple interface to handle P2P communication. pub struct P2PClient { /// `Swarm` instance, everything is accesses through this one. swarm: Swarm, - /// Peer count for (All, Mesh). + /// Peer count for All and Mesh peers. + /// + /// Mesh usually contains much fewer peers than All, as they are the ones + /// used for actual gossipping. peer_count: (usize, usize), /// Last time the peer count was refreshed. peer_last_refreshed: Instant, @@ -253,7 +255,7 @@ impl P2PClient { if let Some(kad_protocol) = info .protocols .iter() - .find(|p| p.to_string().starts_with(P2P_KADEMLIA_PREFIX!())) + .find(|p| p.to_string().starts_with(P2P_KADEMLIA_PREFIX)) { // if it matches our protocol, add it to the Kademlia routing table if *kad_protocol == P2P_KADEMLIA_PROTOCOL { diff --git a/src/p2p/data_transform.rs b/src/p2p/data_transform.rs index f5becac..59012d0 100644 --- a/src/p2p/data_transform.rs +++ b/src/p2p/data_transform.rs @@ -1,3 +1,4 @@ +///! https://docs.rs/libp2p-gossipsub/latest/libp2p_gossipsub/trait.DataTransform.html use libp2p::gossipsub::{DataTransform, Message, RawMessage, TopicHash}; use std::io::{Error, ErrorKind}; use std::time::{SystemTime, UNIX_EPOCH}; diff --git a/src/p2p/mod.rs b/src/p2p/mod.rs index fda9178..1e4c09c 100644 --- a/src/p2p/mod.rs +++ b/src/p2p/mod.rs @@ -1,40 +1,10 @@ -use libp2p::StreamProtocol; - -/// Kademlia protocol prefix, as a macro so that it can be used in const macros. -macro_rules! P2P_KADEMLIA_PREFIX { - () => { - "/dria/kad/" - }; -} - -/// Kademlia protocol prefix, as a macro so that it can be used in const macros. -macro_rules! P2P_IDENTITY_PREFIX { - () => { - "dria/" - }; -} - -/// Kademlia protocol version, in the form of `/dria/kad/`. -/// Notice the `/` at the start. -pub(crate) const P2P_KADEMLIA_PROTOCOL: StreamProtocol = StreamProtocol::new(concat!( - P2P_KADEMLIA_PREFIX!(), - env!("CARGO_PKG_VERSION_MAJOR"), - ".", - env!("CARGO_PKG_VERSION_MINOR") -)); - -/// Protocol string, checked by Identify protocol -pub(crate) const P2P_PROTOCOL_STRING: &str = concat!( - P2P_IDENTITY_PREFIX!(), - env!("CARGO_PKG_VERSION_MAJOR"), - ".", - env!("CARGO_PKG_VERSION_MINOR") -); - mod behaviour; pub use behaviour::{DriaBehaviour, DriaBehaviourEvent}; mod client; pub use client::P2PClient; +mod versioning; +pub use versioning::*; + mod data_transform; diff --git a/src/p2p/versioning.rs b/src/p2p/versioning.rs new file mode 100644 index 0000000..11b2a4d --- /dev/null +++ b/src/p2p/versioning.rs @@ -0,0 +1,35 @@ +use libp2p::StreamProtocol; + +/// Kademlia protocol prefix, as a macro so that it can be used in literal-expecting constants. +macro_rules! P2P_KADEMLIA_PREFIX { + () => { + "/dria/kad/" + }; +} +pub const P2P_KADEMLIA_PREFIX: &str = P2P_KADEMLIA_PREFIX!(); + +/// Identity protocol name prefix, as a macro so that it can be used in literal-expecting constants. +macro_rules! P2P_IDENTITY_PREFIX { + () => { + "dria/" + }; +} + +/// Kademlia protocol version, in the form of `/dria/kad/`, **notice the `/` at the start**. +/// +/// It is important that this protocol matches EXACTLY among the nodes, otherwise there is a protocol-level logic +/// that will prevent peers from finding eachother within the DHT. +pub const P2P_KADEMLIA_PROTOCOL: StreamProtocol = StreamProtocol::new(concat!( + P2P_KADEMLIA_PREFIX!(), + env!("CARGO_PKG_VERSION_MAJOR"), + ".", + env!("CARGO_PKG_VERSION_MINOR") +)); + +/// Protocol string, checked by Identify protocol handlers. +pub const P2P_PROTOCOL_STRING: &str = concat!( + P2P_IDENTITY_PREFIX!(), + env!("CARGO_PKG_VERSION_MAJOR"), + ".", + env!("CARGO_PKG_VERSION_MINOR") +); diff --git a/src/utils/crypto.rs b/src/utils/crypto.rs index a6ac28b..9f835c1 100644 --- a/src/utils/crypto.rs +++ b/src/utils/crypto.rs @@ -22,14 +22,12 @@ pub fn keccak256hash(data: impl AsRef<[u8]>) -> [u8; 32] { /// and then (x || y) is hashed using Keccak256. The last 20 bytes of this hash is taken as the address. #[inline] pub fn to_address(public_key: &PublicKey) -> [u8; 20] { - let public_key_serial = &public_key.serialize()[1..]; + let public_key_xy = &public_key.serialize()[1..]; let mut addr = [0u8; 20]; - addr.copy_from_slice(&keccak256hash(public_key_serial)[12..32]); + addr.copy_from_slice(&keccak256hash(public_key_xy)[12..32]); addr } -// TODO: add peerId - /// Shorthand to sign a digest (bytes) with node's secret key and return signature & recovery id /// serialized to 65 byte hex-string. #[inline] diff --git a/src/utils/filter.rs b/src/utils/filter.rs index cd30f59..ef39730 100644 --- a/src/utils/filter.rs +++ b/src/utils/filter.rs @@ -14,7 +14,6 @@ pub struct FilterPayload { impl FilterPayload { /// Shorthand function to create the underlying `BloomFilter` and check if it contains the given address. - #[inline] pub fn contains(&self, address: &[u8]) -> Result { BloomFilter::try_from(self) .map(|filter| filter.contains(address)) @@ -22,6 +21,8 @@ impl FilterPayload { } } +// FIXME: too many TryFrom's here, simplify in a single function here! + impl TryFrom<&FilterPayload> for String { type Error = serde_json::Error; @@ -109,28 +110,4 @@ mod tests { BloomFilter::try_from(&filter_payload).expect("Should parse filter"); } - - #[test] - fn test_filter_read_3() { - const FILTER_HEX: &str = "e7799ef73dcff3bc"; - let filter_payload = FilterPayload { - hex: FILTER_HEX.to_string(), - hashes: 45, - }; - - let bf = BloomFilter::try_from(&filter_payload).expect("Should parse filter"); - - let addr = "6c460f37b78a2088a71e09dfb1c6238d7a34a346"; - let addr_hex = hex::decode(addr).unwrap(); - println!( - "{} ({}): {}", - addr, - addr_hex.len(), - bf.contains(&hex::decode(addr).unwrap()) - ); - - let addr = "90c010775ffb266bc2136a13c08aa20ef11fe5cb"; - let addr_hex = hex::decode(addr).unwrap(); - println!("{} ({}): {}", addr, addr_hex.len(), bf.contains(&addr_hex)); - } } diff --git a/src/utils/message.rs b/src/utils/message.rs index a9e1067..8eee011 100644 --- a/src/utils/message.rs +++ b/src/utils/message.rs @@ -3,7 +3,6 @@ use crate::utils::{ get_current_time_nanos, payload::TaskResponsePayload, }; - use base64::{prelude::BASE64_STANDARD, Engine}; use core::fmt; use ecies::PublicKey; @@ -62,26 +61,30 @@ impl P2PMessage { Self::new(signed_payload, topic) } - /// Creates the payload of a computation result, as per Dria Whitepaper section 5.1 algorithm 2: + /// Creates the payload of a computation result. /// /// - Sign `task_id || payload` with node `self.secret_key` /// - Encrypt `result` with `task_public_key` + /// TODO: this is not supposed to be here pub fn new_signed_encrypted_payload( payload: impl AsRef<[u8]>, task_id: &str, encrypting_public_key: &[u8], signing_secret_key: &SecretKey, ) -> Result { - // sign payload + // create the message `task_id || payload` let mut preimage = Vec::new(); preimage.extend_from_slice(task_id.as_ref()); preimage.extend_from_slice(payload.as_ref()); + + // sign the message + // TODO: use `sign_recoverable` here instead? let digest = libsecp256k1::Message::parse(&sha256hash(preimage)); let (signature, recid) = libsecp256k1::sign(&digest, signing_secret_key); let signature: [u8; 64] = signature.serialize(); let recid: [u8; 1] = [recid.serialize()]; - // encrypt payload + // encrypt payload itself let ciphertext = ecies::encrypt(encrypting_public_key, payload.as_ref())?; Ok(TaskResponsePayload { diff --git a/src/utils/payload.rs b/src/utils/payload.rs index 3795e69..5f11401 100644 --- a/src/utils/payload.rs +++ b/src/utils/payload.rs @@ -10,7 +10,7 @@ use crate::utils::{filter::FilterPayload, get_current_time_nanos}; /// /// To check the commitment, one must decrypt the ciphertext and parse plaintext from it, /// and compute the digest using SHA256. That digest will then be used for the signature check. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TaskResponsePayload { /// A signature on the digest of plaintext result, prepended with task id. @@ -30,7 +30,7 @@ impl TaskResponsePayload { } /// A generic task request, given by Dria. -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TaskRequestPayload { /// The unique identifier of the task. From 3a2e249cce68e486593dfd1cb7e00f382e2d63f7 Mon Sep 17 00:00:00 2001 From: erhant Date: Tue, 1 Oct 2024 19:32:07 +0300 Subject: [PATCH 07/15] now entire message is published, not just payload --- src/handlers/mod.rs | 4 ++-- src/handlers/pingpong.rs | 13 +++++++------ src/handlers/workflow.rs | 11 ++++++----- src/node.rs | 21 ++++++++++++--------- src/utils/crypto.rs | 12 ++++++------ src/utils/filter.rs | 2 +- src/utils/message.rs | 17 ++++++++--------- src/utils/mod.rs | 2 +- src/utils/payload.rs | 6 ++---- 9 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index fbad81a..a0c5f44 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -8,13 +8,13 @@ pub use pingpong::PingpongHandler; mod workflow; pub use workflow::WorkflowHandler; -use crate::{utils::P2PMessage, DriaComputeNode}; +use crate::{utils::DKNMessage, DriaComputeNode}; #[async_trait] pub trait ComputeHandler { async fn handle_compute( node: &mut DriaComputeNode, - message: P2PMessage, + message: DKNMessage, result_topic: &str, ) -> Result; } diff --git a/src/handlers/pingpong.rs b/src/handlers/pingpong.rs index e875984..9a1e9f9 100644 --- a/src/handlers/pingpong.rs +++ b/src/handlers/pingpong.rs @@ -1,6 +1,6 @@ use crate::{ node::DriaComputeNode, - utils::{get_current_time_nanos, P2PMessage}, + utils::{get_current_time_nanos, DKNMessage}, }; use async_trait::async_trait; use eyre::Result; @@ -29,7 +29,7 @@ struct PingpongResponse { impl ComputeHandler for PingpongHandler { async fn handle_compute( node: &mut DriaComputeNode, - message: P2PMessage, + message: DKNMessage, result_topic: &str, ) -> Result { let pingpong = message.parse_payload::(true)?; @@ -54,12 +54,13 @@ impl ComputeHandler for PingpongHandler { models: node.config.model_config.models.clone(), timestamp: get_current_time_nanos(), }; - let response = P2PMessage::new_signed( + + let message = DKNMessage::new_signed( serde_json::json!(response_body).to_string(), result_topic, &node.config.secret_key, ); - node.publish(response)?; + node.publish(message)?; // accept message, someone else may be included in the filter Ok(MessageAcceptance::Accept) @@ -72,7 +73,7 @@ mod tests { utils::{ crypto::{sha256hash, to_address}, filter::FilterPayload, - P2PMessage, + DKNMessage, }, DriaComputeNodeConfig, }; @@ -87,7 +88,7 @@ mod tests { "0208ef5e65a9c656a6f92fb2c770d5d5e2ecffe02a6aade19207f75110be6ae658" )) .expect("Should parse public key"); - let message = P2PMessage { + let message = DKNMessage { payload: "Y2RmODcyNDlhY2U3YzQ2MDIzYzNkMzBhOTc4ZWY3NjViMWVhZDlmNWJhMDUyY2MxMmY0NzIzMjQyYjc0YmYyODFjMDA1MTdmMGYzM2VkNTgzMzk1YWUzMTY1ODQ3NWQyNDRlODAxYzAxZDE5MjYwMDM1MTRkNzEwMThmYTJkNjEwMXsidXVpZCI6ICI4MWE2M2EzNC05NmM2LTRlNWEtOTliNS02YjI3NGQ5ZGUxNzUiLCAiZGVhZGxpbmUiOiAxNzE0MTI4NzkyfQ==".to_string(), topic: "heartbeat".to_string(), version: "0.0.0".to_string(), diff --git a/src/handlers/workflow.rs b/src/handlers/workflow.rs index c4c64a7..976ad98 100644 --- a/src/handlers/workflow.rs +++ b/src/handlers/workflow.rs @@ -6,7 +6,7 @@ use serde::Deserialize; use crate::node::DriaComputeNode; use crate::utils::payload::{TaskRequest, TaskRequestPayload}; -use crate::utils::{get_current_time_nanos, P2PMessage}; +use crate::utils::{get_current_time_nanos, DKNMessage}; use super::ComputeHandler; @@ -29,7 +29,7 @@ struct WorkflowPayload { impl ComputeHandler for WorkflowHandler { async fn handle_compute( node: &mut DriaComputeNode, - message: P2PMessage, + message: DKNMessage, result_topic: &str, ) -> Result { let task = message.parse_payload::>(true)?; @@ -111,16 +111,17 @@ impl ComputeHandler for WorkflowHandler { } } - // publish the result - let payload = P2PMessage::new_signed_encrypted_payload( + // prepare signed and encrypted payload + let payload = DKNMessage::new_signed_encrypted_payload( result, &task.task_id, &task.public_key, &node.config.secret_key, )?; let payload_str = payload.to_string()?; - let message = P2PMessage::new(payload_str, result_topic); + let message = DKNMessage::new(payload_str, result_topic); + // publish the result node.publish(message)?; Ok(MessageAcceptance::Accept) diff --git a/src/node.rs b/src/node.rs index a5ef00b..8736d71 100644 --- a/src/node.rs +++ b/src/node.rs @@ -7,7 +7,7 @@ use crate::{ config::DriaComputeNodeConfig, handlers::{ComputeHandler, PingpongHandler, WorkflowHandler}, p2p::P2PClient, - utils::{crypto::secret_to_keypair, AvailableNodes, P2PMessage}, + utils::{crypto::secret_to_keypair, AvailableNodes, DKNMessage}, }; /// Number of seconds between refreshing the Admin RPC PeerIDs from Dria server. @@ -56,8 +56,8 @@ impl DriaComputeNode { let p2p = P2PClient::new(keypair, listen_addr, &available_nodes)?; Ok(DriaComputeNode { - config, p2p, + config, cancellation, available_nodes, available_nodes_last_refreshed: tokio::time::Instant::now(), @@ -86,16 +86,18 @@ impl DriaComputeNode { Ok(()) } - /// Publishes a given message to the network. - /// The topic is expected to be provided within the message struct. - pub fn publish(&mut self, message: P2PMessage) -> Result<()> { - let message_bytes = message.payload.as_bytes().to_vec(); + /// Publishes a given message to the network w.r.t the topic of it. + /// + /// Internally, the message is JSON serialized to bytes and then published to the network as is. + pub fn publish(&mut self, message: DKNMessage) -> Result<()> { + let message_bytes = serde_json::to_vec(&message)?; let message_id = self.p2p.publish(&message.topic, message_bytes)?; log::info!("Published message ({}) to {}", message_id, message.topic); Ok(()) } /// Returns the list of connected peers. + #[inline(always)] pub fn peers(&self) -> Vec<(&libp2p_identity::PeerId, Vec<&gossipsub::TopicHash>)> { self.p2p.peers() } @@ -223,13 +225,14 @@ impl DriaComputeNode { /// This prepared message includes the topic, payload, version and timestamp. /// /// This also checks the signature of the message, expecting a valid signature from admin node. + // TODO: move this somewhere? pub fn parse_message_to_prepared_message( &self, message: gossipsub::Message, - ) -> Result { + ) -> Result { // the received message is expected to use IdentHash for the topic, so we can see the name of the topic immediately. log::debug!("Parsing {} message.", message.topic.as_str()); - let message = P2PMessage::try_from(message)?; + let message = DKNMessage::try_from(message)?; log::debug!("Parsed: {}", message); // check dria signature @@ -270,7 +273,7 @@ mod tests { // publish a dummy message let topic = "foo"; - let message = P2PMessage::new("hello from the other side", topic); + let message = DKNMessage::new("hello from the other side", topic); node.subscribe(topic).expect("should subscribe"); node.publish(message).expect("should publish"); node.unsubscribe(topic).expect("should unsubscribe"); diff --git a/src/utils/crypto.rs b/src/utils/crypto.rs index 9f835c1..b84d0b3 100644 --- a/src/utils/crypto.rs +++ b/src/utils/crypto.rs @@ -60,8 +60,8 @@ mod tests { use hex::decode; use libsecp256k1::{recover, sign, verify, Message, PublicKey, SecretKey}; - const DUMMY_KEY: &[u8; 32] = b"driadriadriadriadriadriadriadria"; - const MESSAGE: &[u8] = "hello world".as_bytes(); + const DUMMY_SECRET_KEY: &[u8; 32] = b"driadriadriadriadriadriadriadria"; + const MESSAGE: &[u8] = b"hello world"; #[test] fn test_hash() { @@ -73,7 +73,7 @@ mod tests { #[test] fn test_address() { - let sk = SecretKey::parse_slice(DUMMY_KEY).expect("Should parse key."); + let sk = SecretKey::parse_slice(DUMMY_SECRET_KEY).expect("Should parse key."); let pk = PublicKey::from_secret_key(&sk); let addr = to_address(&pk); assert_eq!( @@ -84,7 +84,7 @@ mod tests { #[test] fn test_encrypt_decrypt() { - let sk = SecretKey::parse_slice(DUMMY_KEY).expect("Should parse private key slice."); + let sk = SecretKey::parse_slice(DUMMY_SECRET_KEY).expect("Should parse private key slice."); let pk = PublicKey::from_secret_key(&sk); let (sk, pk) = (&sk.serialize(), &pk.serialize()); @@ -96,7 +96,7 @@ mod tests { #[test] fn test_sign_verify() { let secret_key = - SecretKey::parse_slice(DUMMY_KEY).expect("Should parse private key slice."); + SecretKey::parse_slice(DUMMY_SECRET_KEY).expect("Should parse private key slice."); // sign the message using the secret key let digest = sha256hash(MESSAGE); @@ -121,7 +121,7 @@ mod tests { #[ignore = "run only with profiler if wanted"] fn test_memory_usage() { let secret_key = - SecretKey::parse_slice(DUMMY_KEY).expect("Should parse private key slice."); + SecretKey::parse_slice(DUMMY_SECRET_KEY).expect("Should parse private key slice."); let public_key = PublicKey::from_secret_key(&secret_key); // sign the message using the secret key diff --git a/src/utils/filter.rs b/src/utils/filter.rs index ef39730..e69cf1b 100644 --- a/src/utils/filter.rs +++ b/src/utils/filter.rs @@ -3,7 +3,7 @@ use fastbloom_rs::{BloomFilter, Hashes, Membership}; use serde::{Deserialize, Serialize}; use serde_json::{json, to_string}; -/// A task filter is used to determine if a node is selected. +/// A task Blfilter is used to determine if a node is selected. /// /// The filter is a Bloom Filter with a set of items and a false positive rate, it is serialized as a hex string. #[derive(Serialize, Deserialize, Debug, Clone)] diff --git a/src/utils/message.rs b/src/utils/message.rs index 8eee011..185282c 100644 --- a/src/utils/message.rs +++ b/src/utils/message.rs @@ -19,7 +19,7 @@ use serde::{Deserialize, Serialize}; /// - version is given within the Identify protocol /// - timestamp is available at protocol level via DataTransform #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct P2PMessage { +pub struct DKNMessage { pub(crate) payload: String, pub(crate) topic: String, pub(crate) version: String, @@ -33,7 +33,7 @@ pub struct P2PMessage { /// and therefore use 128 characters: SIGNATURE_SIZE - 2. const SIGNATURE_SIZE_HEX: usize = 130; -impl P2PMessage { +impl DKNMessage { /// Creates a new message with current timestamp and version equal to the crate version. /// /// - `payload` is gives as bytes. It is to be `base64` encoded internally. @@ -91,7 +91,6 @@ impl P2PMessage { ciphertext: hex::encode(ciphertext), signature: format!("{}{}", hex::encode(signature), hex::encode(recid)), task_id: task_id.to_string(), - timestamp: get_current_time_nanos(), }) } @@ -136,7 +135,7 @@ impl P2PMessage { } } -impl fmt::Display for P2PMessage { +impl fmt::Display for DKNMessage { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let payload_decoded = self .decode_payload() @@ -151,7 +150,7 @@ impl fmt::Display for P2PMessage { } } -impl TryFrom for P2PMessage { +impl TryFrom for DKNMessage { type Error = serde_json::Error; fn try_from(value: libp2p::gossipsub::Message) -> Result { @@ -186,7 +185,7 @@ mod tests { #[test] fn test_display_message() { - let message = P2PMessage::new(b"hello world", "test-topic"); + let message = DKNMessage::new(b"hello world", "test-topic"); println!("{}", message); } @@ -195,7 +194,7 @@ mod tests { // create payload & message let body = TestStruct::default(); let payload = serde_json::to_vec(&json!(body)).expect("Should serialize"); - let message = P2PMessage::new(payload, TOPIC); + let message = DKNMessage::new(payload, TOPIC); // decode message let message_body = message.decode_payload().expect("Should decode"); @@ -221,7 +220,7 @@ mod tests { // create payload & message with signature & body let body = TestStruct::default(); let body_str = serde_json::to_string(&body).unwrap(); - let message = P2PMessage::new_signed(body_str, TOPIC, &sk); + let message = DKNMessage::new_signed(body_str, TOPIC, &sk); // decode message let message_body = message.decode_payload().expect("Should decode"); @@ -253,7 +252,7 @@ mod tests { let task_public_key = PublicKey::from_secret_key(&task_secret_key); // create payload - let payload = P2PMessage::new_signed_encrypted_payload( + let payload = DKNMessage::new_signed_encrypted_payload( RESULT, TASK_ID, &task_public_key.serialize(), diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 06970d9..ef1eee6 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -3,7 +3,7 @@ pub mod filter; pub mod payload; mod message; -pub use message::P2PMessage; +pub use message::DKNMessage; mod available_nodes; pub use available_nodes::AvailableNodes; diff --git a/src/utils/payload.rs b/src/utils/payload.rs index 5f11401..68f7143 100644 --- a/src/utils/payload.rs +++ b/src/utils/payload.rs @@ -13,14 +13,12 @@ use crate::utils::{filter::FilterPayload, get_current_time_nanos}; #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TaskResponsePayload { + /// The unique identifier of the task. + pub task_id: String, /// A signature on the digest of plaintext result, prepended with task id. pub signature: String, /// Computation result encrypted with the public key of the task. pub ciphertext: String, - /// The unique identifier of the task. - pub task_id: String, - /// Timestamp of the response. - pub timestamp: u128, } impl TaskResponsePayload { From 5eed72cf4348279362e686cee7f07836b9e6c8b8 Mon Sep 17 00:00:00 2001 From: erhant Date: Tue, 1 Oct 2024 20:23:31 +0300 Subject: [PATCH 08/15] better message structures --- src/handlers/workflow.rs | 14 +++------- src/utils/message.rs | 56 ++++++++++------------------------------ src/utils/payload.rs | 49 ++++++++++++++++++++++++++--------- 3 files changed, 54 insertions(+), 65 deletions(-) diff --git a/src/handlers/workflow.rs b/src/handlers/workflow.rs index 976ad98..97179b4 100644 --- a/src/handlers/workflow.rs +++ b/src/handlers/workflow.rs @@ -5,7 +5,7 @@ use ollama_workflows::{Entry, Executor, ModelProvider, ProgramMemory, Workflow}; use serde::Deserialize; use crate::node::DriaComputeNode; -use crate::utils::payload::{TaskRequest, TaskRequestPayload}; +use crate::utils::payload::{TaskRequestPayload, TaskResponsePayload}; use crate::utils::{get_current_time_nanos, DKNMessage}; use super::ComputeHandler; @@ -62,12 +62,6 @@ impl ComputeHandler for WorkflowHandler { // obtain public key from the payload let task_public_key = hex::decode(&task.public_key)?; - let task = TaskRequest { - task_id: task.task_id, - input: task.input, - public_key: task_public_key, - }; - // read model / provider from the task let (model_provider, model) = node .config @@ -112,16 +106,16 @@ impl ComputeHandler for WorkflowHandler { } // prepare signed and encrypted payload - let payload = DKNMessage::new_signed_encrypted_payload( + let payload = TaskResponsePayload::new( result, &task.task_id, - &task.public_key, + &task_public_key, &node.config.secret_key, )?; let payload_str = payload.to_string()?; - let message = DKNMessage::new(payload_str, result_topic); // publish the result + let message = DKNMessage::new(payload_str, result_topic); node.publish(message)?; Ok(MessageAcceptance::Accept) diff --git a/src/utils/message.rs b/src/utils/message.rs index 185282c..f1a9090 100644 --- a/src/utils/message.rs +++ b/src/utils/message.rs @@ -1,7 +1,6 @@ use crate::utils::{ crypto::{sha256hash, sign_bytes_recoverable}, get_current_time_nanos, - payload::TaskResponsePayload, }; use base64::{prelude::BASE64_STANDARD, Engine}; use core::fmt; @@ -10,19 +9,22 @@ use eyre::Result; use libsecp256k1::SecretKey; use serde::{Deserialize, Serialize}; -/// A parsed message from gossipsub. When first received, the message data is simply a vector of bytes. -/// We treat that bytearray as a stringified JSON object, and parse it into this struct. -/// -/// TODO: these are all available at protocol level as well -/// - payload is the data itself -/// - topic is available as TopicHash of Gossipsub -/// - version is given within the Identify protocol -/// - timestamp is available at protocol level via DataTransform +/// A message within Dria Knowledge Network. #[derive(Serialize, Deserialize, Debug, Clone)] pub struct DKNMessage { + /// Base64 encoded data pub(crate) payload: String, + /// The topic of the message, derived from `TopicHash` + /// + /// NOTE: This can be obtained via TopicHash in GossipSub pub(crate) topic: String, + /// The version of the Dria Compute Node + /// + /// NOTE: This can be obtained via Identify protocol version pub(crate) version: String, + /// The timestamp of the message, in nanoseconds + /// + /// NOTE: This can be obtained via DataTransform in GossipSub pub(crate) timestamp: u128, } @@ -61,39 +63,6 @@ impl DKNMessage { Self::new(signed_payload, topic) } - /// Creates the payload of a computation result. - /// - /// - Sign `task_id || payload` with node `self.secret_key` - /// - Encrypt `result` with `task_public_key` - /// TODO: this is not supposed to be here - pub fn new_signed_encrypted_payload( - payload: impl AsRef<[u8]>, - task_id: &str, - encrypting_public_key: &[u8], - signing_secret_key: &SecretKey, - ) -> Result { - // create the message `task_id || payload` - let mut preimage = Vec::new(); - preimage.extend_from_slice(task_id.as_ref()); - preimage.extend_from_slice(payload.as_ref()); - - // sign the message - // TODO: use `sign_recoverable` here instead? - let digest = libsecp256k1::Message::parse(&sha256hash(preimage)); - let (signature, recid) = libsecp256k1::sign(&digest, signing_secret_key); - let signature: [u8; 64] = signature.serialize(); - let recid: [u8; 1] = [recid.serialize()]; - - // encrypt payload itself - let ciphertext = ecies::encrypt(encrypting_public_key, payload.as_ref())?; - - Ok(TaskResponsePayload { - ciphertext: hex::encode(ciphertext), - signature: format!("{}{}", hex::encode(signature), hex::encode(recid)), - task_id: task_id.to_string(), - }) - } - /// Decodes the base64 payload into bytes. pub fn decode_payload(&self) -> Result, base64::DecodeError> { BASE64_STANDARD.decode(&self.payload) @@ -161,6 +130,7 @@ impl TryFrom for DKNMessage { #[cfg(test)] mod tests { use super::*; + use crate::utils::payload::TaskResponsePayload; use crate::{utils::crypto::sha256hash, DriaComputeNodeConfig}; use ecies::decrypt; use libsecp256k1::SecretKey; @@ -252,7 +222,7 @@ mod tests { let task_public_key = PublicKey::from_secret_key(&task_secret_key); // create payload - let payload = DKNMessage::new_signed_encrypted_payload( + let payload = TaskResponsePayload::new( RESULT, TASK_ID, &task_public_key.serialize(), diff --git a/src/utils/payload.rs b/src/utils/payload.rs index 68f7143..b0c1fa3 100644 --- a/src/utils/payload.rs +++ b/src/utils/payload.rs @@ -1,10 +1,11 @@ +use super::crypto::sha256hash; +use crate::utils::{filter::FilterPayload, get_current_time_nanos}; use eyre::Result; use fastbloom_rs::BloomFilter; +use libsecp256k1::SecretKey; use serde::{Deserialize, Serialize}; use uuid::Uuid; -use crate::utils::{filter::FilterPayload, get_current_time_nanos}; - /// A computation task is the task of computing a result from a given input. The result is encrypted with the public key of the requester. /// Plain result is signed by the compute node's private key, and a commitment is computed from the signature and plain result. /// @@ -15,9 +16,9 @@ use crate::utils::{filter::FilterPayload, get_current_time_nanos}; pub struct TaskResponsePayload { /// The unique identifier of the task. pub task_id: String, - /// A signature on the digest of plaintext result, prepended with task id. + /// Signature of the payload with task id, hexadecimally encoded. pub signature: String, - /// Computation result encrypted with the public key of the task. + /// Result encrypted with the public key of the task, Hexadecimally encoded. pub ciphertext: String, } @@ -25,6 +26,38 @@ impl TaskResponsePayload { pub fn to_string(&self) -> Result { serde_json::to_string(&serde_json::json!(self)).map_err(Into::into) } + + /// Creates the payload of a computation result. + /// + /// - Sign `task_id || payload` with node `self.secret_key` + /// - Encrypt `result` with `task_public_key` + pub fn new( + payload: impl AsRef<[u8]>, + task_id: &str, + encrypting_public_key: &[u8], + signing_secret_key: &SecretKey, + ) -> Result { + // create the message `task_id || payload` + let mut preimage = Vec::new(); + preimage.extend_from_slice(task_id.as_ref()); + preimage.extend_from_slice(payload.as_ref()); + + // sign the message + // TODO: use `sign_recoverable` here instead? + let digest = libsecp256k1::Message::parse(&sha256hash(preimage)); + let (signature, recid) = libsecp256k1::sign(&digest, signing_secret_key); + let signature: [u8; 64] = signature.serialize(); + let recid: [u8; 1] = [recid.serialize()]; + + // encrypt payload itself + let ciphertext = ecies::encrypt(encrypting_public_key, payload.as_ref())?; + + Ok(TaskResponsePayload { + ciphertext: hex::encode(ciphertext), + signature: format!("{}{}", hex::encode(signature), hex::encode(recid)), + task_id: task_id.to_string(), + }) + } } /// A generic task request, given by Dria. @@ -55,11 +88,3 @@ impl TaskRequestPayload { } } } - -/// A parsed `TaskRequestPayload`. -#[derive(Debug, Clone)] -pub struct TaskRequest { - pub task_id: String, - pub(crate) input: T, - pub(crate) public_key: Vec, -} From 2dc292e64436617b8372a463272b8e878d2d4a30 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 2 Oct 2024 13:49:53 +0300 Subject: [PATCH 09/15] added error reporting --- src/handlers/mod.rs | 5 ++ src/handlers/pingpong.rs | 4 +- src/handlers/topics.rs | 4 + src/handlers/workflow.rs | 81 ++++++++++--------- src/lib.rs | 1 + src/node.rs | 20 ++--- src/payloads/error.rs | 17 ++++ src/payloads/mod.rs | 8 ++ src/payloads/request.rs | 33 ++++++++ .../payload.rs => payloads/response.rs} | 44 +--------- src/utils/message.rs | 2 +- src/utils/mod.rs | 1 - 12 files changed, 125 insertions(+), 95 deletions(-) create mode 100644 src/handlers/topics.rs create mode 100644 src/payloads/error.rs create mode 100644 src/payloads/mod.rs create mode 100644 src/payloads/request.rs rename src/{utils/payload.rs => payloads/response.rs} (59%) diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index a0c5f44..c71e56b 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -2,6 +2,9 @@ use async_trait::async_trait; use eyre::Result; use libp2p::gossipsub::MessageAcceptance; +mod topics; +pub use topics::*; + mod pingpong; pub use pingpong::PingpongHandler; @@ -10,8 +13,10 @@ pub use workflow::WorkflowHandler; use crate::{utils::DKNMessage, DriaComputeNode}; +/// A DKN task is to be handled by the compute node, respecting this trait. #[async_trait] pub trait ComputeHandler { + /// A generic handler for DKN tasks. async fn handle_compute( node: &mut DriaComputeNode, message: DKNMessage, diff --git a/src/handlers/pingpong.rs b/src/handlers/pingpong.rs index 9a1e9f9..1c046e9 100644 --- a/src/handlers/pingpong.rs +++ b/src/handlers/pingpong.rs @@ -1,6 +1,6 @@ use crate::{ - node::DriaComputeNode, utils::{get_current_time_nanos, DKNMessage}, + DriaComputeNode, }; use async_trait::async_trait; use eyre::Result; @@ -55,6 +55,7 @@ impl ComputeHandler for PingpongHandler { timestamp: get_current_time_nanos(), }; + // publish message let message = DKNMessage::new_signed( serde_json::json!(response_body).to_string(), result_topic, @@ -62,7 +63,6 @@ impl ComputeHandler for PingpongHandler { ); node.publish(message)?; - // accept message, someone else may be included in the filter Ok(MessageAcceptance::Accept) } } diff --git a/src/handlers/topics.rs b/src/handlers/topics.rs new file mode 100644 index 0000000..bf83adf --- /dev/null +++ b/src/handlers/topics.rs @@ -0,0 +1,4 @@ +pub const PINGPONG_LISTEN_TOPIC: &str = "ping"; +pub const PINGPONG_RESPONSE_TOPIC: &str = "pong"; +pub const WORKFLOW_LISTEN_TOPIC: &str = "task"; +pub const WORKFLOW_RESPONSE_TOPIC: &str = "results"; diff --git a/src/handlers/workflow.rs b/src/handlers/workflow.rs index 97179b4..e8c9888 100644 --- a/src/handlers/workflow.rs +++ b/src/handlers/workflow.rs @@ -4,9 +4,9 @@ use libp2p::gossipsub::MessageAcceptance; use ollama_workflows::{Entry, Executor, ModelProvider, ProgramMemory, Workflow}; use serde::Deserialize; -use crate::node::DriaComputeNode; -use crate::utils::payload::{TaskRequestPayload, TaskResponsePayload}; +use crate::payloads::{TaskErrorPayload, TaskRequestPayload, TaskResponsePayload}; use crate::utils::{get_current_time_nanos, DKNMessage}; +use crate::DriaComputeNode; use super::ComputeHandler; @@ -32,6 +32,7 @@ impl ComputeHandler for WorkflowHandler { message: DKNMessage, result_topic: &str, ) -> Result { + let config = &node.config; let task = message.parse_payload::>(true)?; // check if deadline is past or not @@ -49,7 +50,7 @@ impl ComputeHandler for WorkflowHandler { } // check task inclusion via the bloom filter - if !task.filter.contains(&node.config.address)? { + if !task.filter.contains(&config.address)? { log::info!( "Task {} does not include this node within the filter.", task.task_id @@ -59,23 +60,15 @@ impl ComputeHandler for WorkflowHandler { return Ok(MessageAcceptance::Accept); } - // obtain public key from the payload - let task_public_key = hex::decode(&task.public_key)?; - // read model / provider from the task - let (model_provider, model) = node - .config + let (model_provider, model) = config .model_config .get_any_matching_model(task.input.model)?; log::info!("Using model {} for task {}", model, task.task_id); // prepare workflow executor let executor = if model_provider == ModelProvider::Ollama { - Executor::new_at( - model, - &node.config.ollama_config.host, - node.config.ollama_config.port, - ) + Executor::new_at(model, &config.ollama_config.host, config.ollama_config.port) } else { Executor::new(model) }; @@ -86,38 +79,52 @@ impl ComputeHandler for WorkflowHandler { .map(|prompt| Entry::try_value_or_str(&prompt)); // execute workflow with cancellation - // TODO: is there a better way to handle this? - let result: String; + let exec_result: Result; tokio::select! { _ = node.cancellation.cancelled() => { log::info!("Received cancellation, quitting all tasks."); - return Ok(MessageAcceptance::Accept) + return Ok(MessageAcceptance::Accept); }, - exec_result = executor.execute(entry.as_ref(), task.input.workflow, &mut memory) => { - match exec_result { - Ok(exec_result) => { - result = exec_result; - } - Err(e) => { - return Err(eyre!("Workflow failed with error {}", e)); - } - } + exec_result_inner = executor.execute(entry.as_ref(), task.input.workflow, &mut memory) => { + exec_result = exec_result_inner.map_err(|e| eyre!("{}", e.to_string())); } } - // prepare signed and encrypted payload - let payload = TaskResponsePayload::new( - result, - &task.task_id, - &task_public_key, - &node.config.secret_key, - )?; - let payload_str = payload.to_string()?; + match exec_result { + Ok(result) => { + // obtain public key from the payload + let task_public_key = hex::decode(&task.public_key)?; + + // prepare signed and encrypted payload + let payload = TaskResponsePayload::new( + result, + &task.task_id, + &task_public_key, + &config.secret_key, + )?; + let payload_str = serde_json::to_string(&payload)?; + + // publish the result + let message = DKNMessage::new(payload_str, result_topic); + node.publish(message)?; + + // accept so that if there are others included in filter they can do the task + Ok(MessageAcceptance::Accept) + } + Err(err) => { + log::error!("Task {} failed: {}", task.task_id, err); + + // prepare error payload + let error_payload = TaskErrorPayload::new(task.task_id, err.to_string()); + let error_payload_str = serde_json::to_string(&error_payload)?; - // publish the result - let message = DKNMessage::new(payload_str, result_topic); - node.publish(message)?; + // publish the error result for diagnostics + let message = DKNMessage::new(error_payload_str, result_topic); + node.publish(message)?; - Ok(MessageAcceptance::Accept) + // ignore just in case, workflow may be bugged + Ok(MessageAcceptance::Ignore) + } + } } } diff --git a/src/lib.rs b/src/lib.rs index bfff81a..adc2b65 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,6 +5,7 @@ pub(crate) mod config; pub(crate) mod handlers; pub(crate) mod node; pub(crate) mod p2p; +pub(crate) mod payloads; pub(crate) mod utils; /// Crate version of the compute node. diff --git a/src/node.rs b/src/node.rs index 8736d71..a603f72 100644 --- a/src/node.rs +++ b/src/node.rs @@ -5,7 +5,7 @@ use tokio_util::sync::CancellationToken; use crate::{ config::DriaComputeNodeConfig, - handlers::{ComputeHandler, PingpongHandler, WorkflowHandler}, + handlers::*, p2p::P2PClient, utils::{crypto::secret_to_keypair, AvailableNodes, DKNMessage}, }; @@ -105,11 +105,6 @@ impl DriaComputeNode { /// Launches the main loop of the compute node. /// This method is not expected to return until cancellation occurs. pub async fn launch(&mut self) -> Result<()> { - const PINGPONG_LISTEN_TOPIC: &str = "ping"; - const PINGPONG_RESPONSE_TOPIC: &str = "pong"; - const WORKFLOW_LISTEN_TOPIC: &str = "task"; - const WORKFLOW_RESPONSE_TOPIC: &str = "results"; - // subscribe to topics self.subscribe(PINGPONG_LISTEN_TOPIC)?; self.subscribe(PINGPONG_RESPONSE_TOPIC)?; @@ -172,7 +167,7 @@ impl DriaComputeNode { }; // then handle the prepared message - let handle_result = match topic_str { + let handler_result = match topic_str { WORKFLOW_LISTEN_TOPIC => { WorkflowHandler::handle_compute(self, message, WORKFLOW_RESPONSE_TOPIC).await } @@ -185,26 +180,23 @@ impl DriaComputeNode { }; // validate the message based on the result - match handle_result { + match handler_result { Ok(acceptance) => { self.p2p.validate_message(&message_id, &peer_id, acceptance)?; }, Err(err) => { log::error!("Error handling {} message: {}", topic_str, err); - self.p2p.validate_message(&message_id, &peer_id, gossipsub::MessageAcceptance::Reject)?; + self.p2p.validate_message(&message_id, &peer_id, gossipsub::MessageAcceptance::Ignore)?; } } } else if std::matches!(topic_str, PINGPONG_RESPONSE_TOPIC | WORKFLOW_RESPONSE_TOPIC) { // since we are responding to these topics, we might receive messages from other compute nodes - // we can gracefully ignore them + // we can gracefully ignore them and propagate it to to others log::debug!("Ignoring message for topic: {}", topic_str); - - // accept this message for propagation self.p2p.validate_message(&message_id, &peer_id, gossipsub::MessageAcceptance::Accept)?; } else { - log::warn!("Received message from unexpected topic: {}", topic_str); - // reject this message as its from a foreign topic + log::warn!("Received message from unexpected topic: {}", topic_str); self.p2p.validate_message(&message_id, &peer_id, gossipsub::MessageAcceptance::Reject)?; } }, diff --git a/src/payloads/error.rs b/src/payloads/error.rs new file mode 100644 index 0000000..6b66409 --- /dev/null +++ b/src/payloads/error.rs @@ -0,0 +1,17 @@ +use serde::{Deserialize, Serialize}; + +/// A generic task request, given by Dria. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TaskErrorPayload { + /// The unique identifier of the task. + pub task_id: String, + /// The stringified error object + pub(crate) error: String, +} + +impl TaskErrorPayload { + pub fn new(task_id: String, error: String) -> Self { + Self { task_id, error } + } +} diff --git a/src/payloads/mod.rs b/src/payloads/mod.rs new file mode 100644 index 0000000..e05948d --- /dev/null +++ b/src/payloads/mod.rs @@ -0,0 +1,8 @@ +mod error; +pub use error::TaskErrorPayload; + +mod request; +pub use request::TaskRequestPayload; + +mod response; +pub use response::TaskResponsePayload; diff --git a/src/payloads/request.rs b/src/payloads/request.rs new file mode 100644 index 0000000..6a9bb3e --- /dev/null +++ b/src/payloads/request.rs @@ -0,0 +1,33 @@ +use crate::utils::{filter::FilterPayload, get_current_time_nanos}; +use fastbloom_rs::BloomFilter; +use serde::{Deserialize, Serialize}; +use uuid::Uuid; + +/// A generic task request, given by Dria. +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "camelCase")] +pub struct TaskRequestPayload { + /// The unique identifier of the task. + pub task_id: String, + /// The deadline of the task in nanoseconds. + pub(crate) deadline: u128, + /// The input to the compute function. + pub(crate) input: T, + /// The Bloom filter of the task. + pub(crate) filter: FilterPayload, + /// The public key of the requester, in hexadecimals. + pub(crate) public_key: String, +} + +impl TaskRequestPayload { + #[allow(unused)] + pub fn new(input: T, filter: BloomFilter, time_ns: u128, public_key: Option) -> Self { + Self { + task_id: Uuid::new_v4().into(), + deadline: get_current_time_nanos() + time_ns, + input, + filter: filter.into(), + public_key: public_key.unwrap_or_default(), + } + } +} diff --git a/src/utils/payload.rs b/src/payloads/response.rs similarity index 59% rename from src/utils/payload.rs rename to src/payloads/response.rs index b0c1fa3..9083cf0 100644 --- a/src/utils/payload.rs +++ b/src/payloads/response.rs @@ -1,10 +1,7 @@ -use super::crypto::sha256hash; -use crate::utils::{filter::FilterPayload, get_current_time_nanos}; +use crate::utils::crypto::sha256hash; use eyre::Result; -use fastbloom_rs::BloomFilter; use libsecp256k1::SecretKey; use serde::{Deserialize, Serialize}; -use uuid::Uuid; /// A computation task is the task of computing a result from a given input. The result is encrypted with the public key of the requester. /// Plain result is signed by the compute node's private key, and a commitment is computed from the signature and plain result. @@ -23,16 +20,12 @@ pub struct TaskResponsePayload { } impl TaskResponsePayload { - pub fn to_string(&self) -> Result { - serde_json::to_string(&serde_json::json!(self)).map_err(Into::into) - } - /// Creates the payload of a computation result. /// /// - Sign `task_id || payload` with node `self.secret_key` /// - Encrypt `result` with `task_public_key` pub fn new( - payload: impl AsRef<[u8]>, + result: impl AsRef<[u8]>, task_id: &str, encrypting_public_key: &[u8], signing_secret_key: &SecretKey, @@ -40,7 +33,7 @@ impl TaskResponsePayload { // create the message `task_id || payload` let mut preimage = Vec::new(); preimage.extend_from_slice(task_id.as_ref()); - preimage.extend_from_slice(payload.as_ref()); + preimage.extend_from_slice(result.as_ref()); // sign the message // TODO: use `sign_recoverable` here instead? @@ -50,7 +43,7 @@ impl TaskResponsePayload { let recid: [u8; 1] = [recid.serialize()]; // encrypt payload itself - let ciphertext = ecies::encrypt(encrypting_public_key, payload.as_ref())?; + let ciphertext = ecies::encrypt(encrypting_public_key, result.as_ref())?; Ok(TaskResponsePayload { ciphertext: hex::encode(ciphertext), @@ -59,32 +52,3 @@ impl TaskResponsePayload { }) } } - -/// A generic task request, given by Dria. -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(rename_all = "camelCase")] -pub struct TaskRequestPayload { - /// The unique identifier of the task. - pub task_id: String, - /// The deadline of the task in nanoseconds. - pub(crate) deadline: u128, - /// The input to the compute function. - pub(crate) input: T, - /// The Bloom filter of the task. - pub(crate) filter: FilterPayload, - /// The public key of the requester. - pub(crate) public_key: String, -} - -impl TaskRequestPayload { - #[allow(unused)] - pub fn new(input: T, filter: BloomFilter, time_ns: u128, public_key: Option) -> Self { - Self { - task_id: Uuid::new_v4().into(), - deadline: get_current_time_nanos() + time_ns, - input, - filter: filter.into(), - public_key: public_key.unwrap_or_default(), - } - } -} diff --git a/src/utils/message.rs b/src/utils/message.rs index f1a9090..ec8954c 100644 --- a/src/utils/message.rs +++ b/src/utils/message.rs @@ -130,7 +130,7 @@ impl TryFrom for DKNMessage { #[cfg(test)] mod tests { use super::*; - use crate::utils::payload::TaskResponsePayload; + use crate::payloads::TaskResponsePayload; use crate::{utils::crypto::sha256hash, DriaComputeNodeConfig}; use ecies::decrypt; use libsecp256k1::SecretKey; diff --git a/src/utils/mod.rs b/src/utils/mod.rs index ef1eee6..1db2ca6 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,6 +1,5 @@ pub mod crypto; pub mod filter; -pub mod payload; mod message; pub use message::DKNMessage; From 52d83fa8564e99ff6fa11b4746626a8c88526e2e Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 2 Oct 2024 14:07:50 +0300 Subject: [PATCH 10/15] better filter name, fix lint, update workflows --- Cargo.lock | 866 +++++++++++++++++--------------------- Cargo.toml | 2 +- Makefile | 11 +- src/handlers/pingpong.rs | 4 +- src/p2p/data_transform.rs | 4 +- src/payloads/request.rs | 4 +- src/utils/filter.rs | 24 +- 7 files changed, 409 insertions(+), 506 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ac7f0de..a77400c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,18 +4,18 @@ version = 3 [[package]] name = "addr2line" -version = "0.22.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[package]] name = "aead" @@ -80,21 +80,6 @@ version = "0.2.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "anstream" version = "0.6.15" @@ -146,21 +131,21 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.86" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" [[package]] name = "arrayref" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d151e35f61089500b617991b791fc8bfd237ae50cd5950803758a179b41e67a" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" [[package]] name = "arrayvec" -version = "0.7.4" +version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "asn1-rs" @@ -186,7 +171,7 @@ checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", "synstructure", ] @@ -198,7 +183,7 @@ checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -258,27 +243,27 @@ dependencies = [ [[package]] name = "async-openai" -version = "0.23.4" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc0e5ff98f9e7c605df4c88783a0439d1dc667ce86bd79e99d4164f8b0c05ccc" +checksum = "c6db3286b4f52b6556ac5208fb575d035eca61a2bf40d7e75d1db2733ffc599f" dependencies = [ "async-convert", "backoff", "base64 0.22.1", - "bytes 1.7.1", + "bytes 1.7.2", "derive_builder", "eventsource-stream", "futures", "rand 0.8.5", - "reqwest 0.12.5", + "reqwest 0.12.8", "reqwest-eventsource", "secrecy", "serde", "serde_json", "thiserror", - "tokio 1.39.2", + "tokio 1.40.0", "tokio-stream", - "tokio-util 0.7.11", + "tokio-util 0.7.12", "tracing", ] @@ -290,14 +275,14 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "async-stream" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +checksum = "0b5a71a6f37880a80d1d7f19efd781e4b5de42c88f0722cc13bcb6cc2cfe8476" dependencies = [ "async-stream-impl", "futures-core", @@ -306,24 +291,24 @@ dependencies = [ [[package]] name = "async-stream-impl" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "async-trait" -version = "0.1.81" +version = "0.1.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" +checksum = "721cae7de5c34fbb2acd27e21e6d2cf7b886dce0c27388d46c4e6c47ea4318dd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -332,7 +317,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a860072022177f903e59730004fb5dc13db9275b79bb2aef7ba8ce831956c233" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-sink", "futures-util", "memchr", @@ -369,21 +354,21 @@ dependencies = [ [[package]] name = "auto_enums" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1899bfcfd9340ceea3533ea157360ba8fa864354eccbceab58e1006ecab35393" +checksum = "459b77b7e855f875fd15f101064825cd79eb83185a961d66e6298560126facfb" dependencies = [ "derive_utils", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "autocfg" -version = "1.3.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backoff" @@ -396,22 +381,22 @@ dependencies = [ "instant", "pin-project-lite 0.2.14", "rand 0.8.5", - "tokio 1.39.2", + "tokio 1.40.0", ] [[package]] name = "backtrace" -version = "0.3.73" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if 1.0.0", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] @@ -514,7 +499,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" dependencies = [ "memchr", - "regex-automata 0.4.7", + "regex-automata 0.4.8", "serde", ] @@ -538,18 +523,18 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38" [[package]] name = "bytes" -version = "1.7.1" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" dependencies = [ "serde", ] [[package]] name = "cc" -version = "1.1.13" +version = "1.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72db2f7947ecee9b03b510377e8bb9077afa27176fdbff55c51027e976fdcc48" +checksum = "812acba72f0a070b003d3697490d2b55b837230ae7c6c6497f05cc2ddbb8d938" dependencies = [ "shlex", ] @@ -590,18 +575,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "chrono" -version = "0.4.38" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "num-traits", - "windows-targets 0.52.6", -] - [[package]] name = "cipher" version = "0.4.4" @@ -677,41 +650,13 @@ dependencies = [ [[package]] name = "cpufeatures" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" +checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" dependencies = [ "libc", ] -[[package]] -name = "crc32fast" -version = "1.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" -dependencies = [ - "cfg-if 1.0.0", -] - -[[package]] -name = "crossbeam-deque" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.20" @@ -782,7 +727,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -850,7 +795,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -874,7 +819,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -885,7 +830,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -949,33 +894,33 @@ dependencies = [ [[package]] name = "derive_builder" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7" +checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" dependencies = [ "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d" +checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "derive_builder_macro" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" +checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" dependencies = [ "derive_builder_core", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -988,18 +933,18 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "derive_utils" -version = "0.14.1" +version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61bb5a1014ce6dfc2a378578509abe775a5aa06bff584a547555d9efdb81b926" +checksum = "65f152f4b8559c4da5d574bafc7af85454d706b4c5fe8b530d508cacbb6807ea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1030,7 +975,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1054,13 +999,13 @@ dependencies = [ "openssl", "parking_lot", "rand 0.8.5", - "reqwest 0.12.5", + "reqwest 0.12.8", "serde", "serde_json", "sha2 0.10.8", "sha3", - "tokio 1.39.2", - "tokio-util 0.7.11", + "tokio 1.40.0", + "tokio-util 0.7.12", "tracing", "tracing-subscriber", "url", @@ -1140,9 +1085,9 @@ dependencies = [ [[package]] name = "ego-tree" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" +checksum = "12a0bb14ac04a9fcf170d0bbbef949b44cc492f4452bd20c095636956f653642" [[package]] name = "either" @@ -1161,14 +1106,14 @@ dependencies = [ [[package]] name = "enum-as-inner" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ - "heck 0.4.1", + "heck", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1295,9 +1240,9 @@ checksum = "2d7e9bc68be4cdabbb8938140b01a8b5bc1191937f2c7e7ecc2fcebbe2d749df" [[package]] name = "fastrand" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "fiat-crypto" @@ -1305,16 +1250,6 @@ version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" -[[package]] -name = "flate2" -version = "1.0.31" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f211bbe8e69bbd0cfdea405084f128ae8b4aaa6b0b522fc8f2b009084797920" -dependencies = [ - "crc32fast", - "miniz_oxide", -] - [[package]] name = "fnv" version = "1.0.7" @@ -1448,7 +1383,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1573,9 +1508,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.29.0" +version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" [[package]] name = "glob" @@ -1609,35 +1544,35 @@ version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "fnv", "futures-core", "futures-sink", "futures-util", "http 0.2.12", - "indexmap 2.4.0", + "indexmap 2.6.0", "slab", - "tokio 1.39.2", - "tokio-util 0.7.11", + "tokio 1.40.0", + "tokio-util 0.7.12", "tracing", ] [[package]] name = "h2" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa82e28a107a8cc405f0839610bdc9b15f1e25ec7d696aa5cf173edbcb1486ab" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ "atomic-waker", - "bytes 1.7.1", + "bytes 1.7.2", "fnv", "futures-core", "futures-sink", "http 1.1.0", - "indexmap 2.4.0", + "indexmap 2.6.0", "slab", - "tokio 1.39.2", - "tokio-util 0.7.11", + "tokio 1.40.0", + "tokio-util 0.7.12", "tracing", ] @@ -1658,10 +1593,10 @@ dependencies = [ ] [[package]] -name = "heck" -version = "0.4.1" +name = "hashbrown" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" [[package]] name = "heck" @@ -1728,7 +1663,7 @@ dependencies = [ "socket2 0.5.7", "thiserror", "tinyvec", - "tokio 1.39.2", + "tokio 1.40.0", "tracing", "url", ] @@ -1750,7 +1685,7 @@ dependencies = [ "resolv-conf", "smallvec", "thiserror", - "tokio 1.39.2", + "tokio 1.40.0", "tracing", ] @@ -1815,9 +1750,9 @@ dependencies = [ [[package]] name = "html2text" -version = "0.12.5" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c66ee488a63a92237d5b48875b7e05bb293be8fb2894641c8118b60c08ab5ef" +checksum = "042a9677c258ac2952dd026bb0cd21972f00f644a5a38f5a215cb22cdaf6834e" dependencies = [ "html5ever 0.27.0", "markup5ever 0.12.1", @@ -1865,7 +1800,7 @@ dependencies = [ "markup5ever 0.12.1", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -1874,7 +1809,7 @@ version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "fnv", "itoa 1.0.11", ] @@ -1885,7 +1820,7 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "fnv", "itoa 1.0.11", ] @@ -1906,7 +1841,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "http 0.2.12", "pin-project-lite 0.2.14", ] @@ -1917,7 +1852,7 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "http 1.1.0", ] @@ -1927,7 +1862,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-util", "http 1.1.0", "http-body 1.0.1", @@ -1936,9 +1871,9 @@ dependencies = [ [[package]] name = "httparse" -version = "1.9.4" +version = "1.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" +checksum = "7d71d3574edd2771538b901e6549113b4006ece66150fb69c0fb6d9a2adae946" [[package]] name = "httpdate" @@ -1988,7 +1923,7 @@ version = "0.14.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a152ddd61dfaec7273fe8419ab357f33aee0d914c5f4efbf0d96fa749eea5ec9" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-channel", "futures-core", "futures-util", @@ -2000,7 +1935,7 @@ dependencies = [ "itoa 1.0.11", "pin-project-lite 0.2.14", "socket2 0.5.7", - "tokio 1.39.2", + "tokio 1.40.0", "tower-service", "tracing", "want", @@ -2012,10 +1947,10 @@ version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-channel", "futures-util", - "h2 0.4.5", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "httparse", @@ -2023,15 +1958,15 @@ dependencies = [ "itoa 1.0.11", "pin-project-lite 0.2.14", "smallvec", - "tokio 1.39.2", + "tokio 1.40.0", "want", ] [[package]] name = "hyper-rustls" -version = "0.27.2" +version = "0.27.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" +checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" dependencies = [ "futures-util", "http 1.1.0", @@ -2040,7 +1975,7 @@ dependencies = [ "rustls", "rustls-native-certs", "rustls-pki-types", - "tokio 1.39.2", + "tokio 1.40.0", "tokio-rustls", "tower-service", "webpki-roots", @@ -2065,10 +2000,10 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "hyper 0.14.30", "native-tls", - "tokio 1.39.2", + "tokio 1.40.0", "tokio-native-tls", ] @@ -2078,23 +2013,23 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "http-body-util", "hyper 1.4.1", "hyper-util", "native-tls", - "tokio 1.39.2", + "tokio 1.40.0", "tokio-native-tls", "tower-service", ] [[package]] name = "hyper-util" -version = "0.1.7" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +checksum = "41296eb09f183ac68eec06e03cdbea2e759633d4067b2f6552fc2e009bcad08b" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-channel", "futures-util", "http 1.1.0", @@ -2102,35 +2037,11 @@ dependencies = [ "hyper 1.4.1", "pin-project-lite 0.2.14", "socket2 0.5.7", - "tokio 1.39.2", - "tower", + "tokio 1.40.0", "tower-service", "tracing", ] -[[package]] -name = "iana-time-zone" -version = "0.1.60" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core 0.52.0", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - [[package]] name = "ident_case" version = "1.0.1" @@ -2181,8 +2092,8 @@ dependencies = [ "ipnet", "log", "rtnetlink", - "system-configuration", - "tokio 1.39.2", + "system-configuration 0.5.1", + "tokio 1.40.0", "windows", ] @@ -2194,13 +2105,13 @@ checksum = "064d90fec10d541084e7b39ead8875a5a80d9114a2b18791565253bae25f49e4" dependencies = [ "async-trait", "attohttpc", - "bytes 1.7.1", + "bytes 1.7.2", "futures", "http 0.2.12", "hyper 0.14.30", "log", "rand 0.8.5", - "tokio 1.39.2", + "tokio 1.40.0", "url", "xmltree", ] @@ -2223,12 +2134,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.4.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.5", + "hashbrown 0.15.0", ] [[package]] @@ -2272,9 +2183,9 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" [[package]] name = "is_terminal_polyfill" @@ -2333,9 +2244,9 @@ dependencies = [ [[package]] name = "langchain-rust" -version = "4.3.0" +version = "4.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba76d56973d29cd1f2631fac617401f4f79a2f1e8e6b1f33e1e52104459873b7" +checksum = "ee1ca7e38544a214bc4363e9ecf0f8a0cb7f785b316827070e43ba151db27eb2" dependencies = [ "async-openai", "async-recursion", @@ -2347,21 +2258,20 @@ dependencies = [ "glob", "html-escape", "log", - "lopdf", "mockito", "readability", "regex", - "reqwest 0.12.5", + "reqwest 0.12.8", "reqwest-eventsource", - "scraper 0.19.1", + "scraper 0.20.0", "secrecy", "serde", "serde_json", "strum_macros", - "text-splitter", + "text-splitter 0.16.1", "thiserror", "tiktoken-rs", - "tokio 1.39.2", + "tokio 1.40.0", "tokio-stream", "url", "urlencoding", @@ -2375,16 +2285,16 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.156" +version = "0.2.159" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5f43f184355eefb8d17fc948dbecf6c13be3c141f20d834ae842193a448c72a" +checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" [[package]] name = "libp2p" version = "0.54.1" source = "git+https://github.com/anilaltuner/rust-libp2p.git?rev=7ce9f9e#7ce9f9e65ddbe1fdac3913f0f3c1d94edc1de25e" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "either", "futures", "futures-timer", @@ -2433,7 +2343,7 @@ source = "git+https://github.com/anilaltuner/rust-libp2p.git?rev=7ce9f9e#7ce9f9e dependencies = [ "async-trait", "asynchronous-codec", - "bytes 1.7.1", + "bytes 1.7.2", "either", "futures", "futures-bounded", @@ -2535,7 +2445,7 @@ dependencies = [ "asynchronous-codec", "base64 0.22.1", "byteorder", - "bytes 1.7.1", + "bytes 1.7.2", "either", "fnv", "futures", @@ -2607,7 +2517,7 @@ source = "git+https://github.com/anilaltuner/rust-libp2p.git?rev=7ce9f9e#7ce9f9e dependencies = [ "arrayvec", "asynchronous-codec", - "bytes 1.7.1", + "bytes 1.7.2", "either", "fnv", "futures", @@ -2643,7 +2553,7 @@ dependencies = [ "rand 0.8.5", "smallvec", "socket2 0.5.7", - "tokio 1.39.2", + "tokio 1.40.0", "tracing", "void", ] @@ -2674,7 +2584,7 @@ version = "0.45.0" source = "git+https://github.com/anilaltuner/rust-libp2p.git?rev=7ce9f9e#7ce9f9e65ddbe1fdac3913f0f3c1d94edc1de25e" dependencies = [ "asynchronous-codec", - "bytes 1.7.1", + "bytes 1.7.2", "curve25519-dalek", "futures", "libp2p-core", @@ -2715,7 +2625,7 @@ name = "libp2p-quic" version = "0.11.1" source = "git+https://github.com/anilaltuner/rust-libp2p.git?rev=7ce9f9e#7ce9f9e65ddbe1fdac3913f0f3c1d94edc1de25e" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures", "futures-timer", "if-watch", @@ -2729,7 +2639,7 @@ dependencies = [ "rustls", "socket2 0.5.7", "thiserror", - "tokio 1.39.2", + "tokio 1.40.0", "tracing", ] @@ -2739,7 +2649,7 @@ version = "0.18.0" source = "git+https://github.com/anilaltuner/rust-libp2p.git?rev=7ce9f9e#7ce9f9e65ddbe1fdac3913f0f3c1d94edc1de25e" dependencies = [ "asynchronous-codec", - "bytes 1.7.1", + "bytes 1.7.2", "either", "futures", "futures-bounded", @@ -2793,7 +2703,7 @@ dependencies = [ "once_cell", "rand 0.8.5", "smallvec", - "tokio 1.39.2", + "tokio 1.40.0", "tracing", "void", "web-time", @@ -2804,10 +2714,10 @@ name = "libp2p-swarm-derive" version = "0.35.0" source = "git+https://github.com/anilaltuner/rust-libp2p.git?rev=7ce9f9e#7ce9f9e65ddbe1fdac3913f0f3c1d94edc1de25e" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -2822,7 +2732,7 @@ dependencies = [ "libp2p-core", "libp2p-identity", "socket2 0.5.7", - "tokio 1.39.2", + "tokio 1.40.0", "tracing", ] @@ -2854,7 +2764,7 @@ dependencies = [ "igd-next", "libp2p-core", "libp2p-swarm", - "tokio 1.39.2", + "tokio 1.40.0", "tracing", "void", ] @@ -2949,26 +2859,6 @@ version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" -[[package]] -name = "lopdf" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e775e4ee264e8a87d50a9efef7b67b4aa988cf94e75630859875fc347e6c872b" -dependencies = [ - "chrono", - "encoding_rs", - "flate2", - "itoa 1.0.11", - "linked-hash-map", - "log", - "md5", - "nom", - "pom", - "rayon", - "time 0.3.36", - "weezl", -] - [[package]] name = "lru" version = "0.12.4" @@ -3086,12 +2976,6 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" -[[package]] -name = "md5" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" - [[package]] name = "memchr" version = "2.7.4" @@ -3122,11 +3006,11 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "adler", + "adler2", ] [[package]] @@ -3179,7 +3063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09b34bd91b9e5c5b06338d392463e1318d683cf82ec3d3af4014609be6e2108d" dependencies = [ "assert-json-diff", - "bytes 1.7.1", + "bytes 1.7.2", "colored", "futures-util", "http 1.1.0", @@ -3193,14 +3077,14 @@ dependencies = [ "serde_json", "serde_urlencoded", "similar", - "tokio 1.39.2", + "tokio 1.40.0", ] [[package]] name = "multiaddr" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b852bc02a2da5feed68cd14fa50d0774b92790a5bdbfa932a813926c8472070" +checksum = "fe6351f60b488e04c1d21bc69e56b89cb3f5e8f5d22557d6e8031bdfd79b6961" dependencies = [ "arrayref", "byteorder", @@ -3211,7 +3095,7 @@ dependencies = [ "percent-encoding", "serde", "static_assertions", - "unsigned-varint 0.7.2", + "unsigned-varint 0.8.0", "url", ] @@ -3241,7 +3125,7 @@ name = "multistream-select" version = "0.13.0" source = "git+https://github.com/anilaltuner/rust-libp2p.git?rev=7ce9f9e#7ce9f9e65ddbe1fdac3913f0f3c1d94edc1de25e" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures", "pin-project", "smallvec", @@ -3321,13 +3205,13 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65b4b14489ab424703c092062176d52ba55485a89c076b4f9db05092b7223aa6" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures", "log", "netlink-packet-core", "netlink-sys", "thiserror", - "tokio 1.39.2", + "tokio 1.40.0", ] [[package]] @@ -3336,11 +3220,11 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416060d346fbaf1f23f9512963e3e878f1a78e707cb699ba9215761754244307" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures", "libc", "log", - "tokio 1.39.2", + "tokio 1.40.0", ] [[package]] @@ -3438,18 +3322,18 @@ dependencies = [ [[package]] name = "object" -version = "0.36.3" +version = "0.36.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" +checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" dependencies = [ "memchr", ] [[package]] name = "oid-registry" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c958dd45046245b9c3c2547369bb634eb461670b2e7e0de552905801a648d1d" +checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" dependencies = [ "asn1-rs", ] @@ -3463,18 +3347,18 @@ dependencies = [ "async-trait", "log", "regex", - "reqwest 0.12.5", + "reqwest 0.12.8", "scraper 0.19.1", "serde", "serde_json", - "text-splitter", + "text-splitter 0.13.3", "url", ] [[package]] name = "ollama-workflows" version = "0.1.0" -source = "git+https://github.com/andthattoo/ollama-workflows?rev=09f8579#09f8579d7cff2ca0a644f82ab0232ae6ba2269c3" +source = "git+https://github.com/andthattoo/ollama-workflows#595591f732bd127cc79ba109d7dc27a1ee1af0e3" dependencies = [ "async-trait", "colored", @@ -3488,22 +3372,25 @@ dependencies = [ "parking_lot", "rand 0.8.5", "regex", - "reqwest 0.12.5", + "reqwest 0.12.8", "scraper 0.19.1", "search_with_google", "serde", "serde_json", "simsimd", - "text-splitter", - "tokio 1.39.2", - "tokio-util 0.7.11", + "text-splitter 0.13.3", + "tokio 1.40.0", + "tokio-util 0.7.12", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "82881c4be219ab5faaf2ad5e5e5ecdff8c66bd7402ca3160975c93b24961afd1" +dependencies = [ + "portable-atomic", +] [[package]] name = "opaque-debug" @@ -3517,13 +3404,13 @@ version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf3d3fe8284533a78c1ab1cf7da0a682f6738c621a3639e55a6e8041901b151a" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "derive_builder", - "reqwest 0.12.5", + "reqwest 0.12.8", "serde", "serde_json", - "tokio 1.39.2", - "tokio-util 0.7.11", + "tokio 1.40.0", + "tokio-util 0.7.12", ] [[package]] @@ -3549,7 +3436,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -3588,9 +3475,9 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" @@ -3751,7 +3638,7 @@ dependencies = [ "phf_shared 0.11.2", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -3798,7 +3685,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -3831,9 +3718,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" [[package]] name = "polling" @@ -3874,13 +3761,10 @@ dependencies = [ ] [[package]] -name = "pom" -version = "3.4.0" +name = "portable-atomic" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c972d8f86e943ad532d0b04e8965a749ad1d18bb981a9c7b3ae72fe7fd7744b" -dependencies = [ - "bstr", -] +checksum = "cc9c68a3f6da06753e9335d63e27f6b9754dd1920d941135b7ea8224f141adb2" [[package]] name = "powerfmt" @@ -3938,14 +3822,14 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "pulldown-cmark" -version = "0.11.2" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb4e75767fbc9d92b90e4d0c011f61358cde9513b31ef07ea3631b15ffc3b4fd" +checksum = "666f0f59e259aea2d72e6012290c09877a780935cc3c18b1ceded41f3890d59c" dependencies = [ "bitflags 2.6.0", "memchr", @@ -3973,7 +3857,7 @@ version = "0.3.1" source = "git+https://github.com/anilaltuner/rust-libp2p.git?rev=7ce9f9e#7ce9f9e65ddbe1fdac3913f0f3c1d94edc1de25e" dependencies = [ "asynchronous-codec", - "bytes 1.7.1", + "bytes 1.7.2", "quick-protobuf", "thiserror", "unsigned-varint 0.8.0", @@ -3981,11 +3865,11 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.3" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b22d8e7369034b9a7132bc2008cac12f2013c8132b45e0554e6e20e2617f2156" +checksum = "8c7c5fdde3cdae7203427dc4f0a68fe0ed09833edc525a03456b153b79828684" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-io", "pin-project-lite 0.2.14", "quinn-proto", @@ -3994,17 +3878,17 @@ dependencies = [ "rustls", "socket2 0.5.7", "thiserror", - "tokio 1.39.2", + "tokio 1.40.0", "tracing", ] [[package]] name = "quinn-proto" -version = "0.11.6" +version = "0.11.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba92fb39ec7ad06ca2582c0ca834dfeadcaf06ddfc8e635c80aa7e1c05315fdd" +checksum = "fadfaed2cd7f389d0161bb73eeb07b7b78f8691047a6f3e73caaeae55310a4a6" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "rand 0.8.5", "ring 0.17.8", "rustc-hash 2.0.0", @@ -4017,22 +3901,22 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.4" +version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" +checksum = "4fe68c2e9e1a1234e218683dbdf9f9dfcb094113c5ac2b938dfcb9bab4c4140b" dependencies = [ "libc", "once_cell", "socket2 0.5.7", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -4118,26 +4002,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rayon" -version = "1.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "rcgen" version = "0.11.3" @@ -4166,23 +4030,23 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.3" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" dependencies = [ "bitflags 2.6.0", ] [[package]] name = "regex" -version = "1.10.6" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" +checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.7", - "regex-syntax 0.8.4", + "regex-automata 0.4.8", + "regex-syntax 0.8.5", ] [[package]] @@ -4196,13 +4060,13 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" dependencies = [ "aho-corasick", "memchr", - "regex-syntax 0.8.4", + "regex-syntax 0.8.5", ] [[package]] @@ -4213,9 +4077,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" @@ -4259,7 +4123,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ "base64 0.21.7", - "bytes 1.7.1", + "bytes 1.7.2", "encoding_rs", "futures-core", "futures-util", @@ -4281,8 +4145,8 @@ dependencies = [ "serde_json", "serde_urlencoded", "sync_wrapper 0.1.2", - "system-configuration", - "tokio 1.39.2", + "system-configuration 0.5.1", + "tokio 1.40.0", "tokio-native-tls", "tower-service", "url", @@ -4294,16 +4158,16 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.5" +version = "0.12.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7d6d2a27d57148378eb5e111173f4276ad26340ecc5c49a4a2152167a2d6a37" +checksum = "f713147fbe92361e52392c73b8c9e48c04c6625bce969ef54dc901e58e042a7b" dependencies = [ "base64 0.22.1", - "bytes 1.7.1", + "bytes 1.7.2", "encoding_rs", "futures-core", "futures-util", - "h2 0.4.5", + "h2 0.4.6", "http 1.1.0", "http-body 1.0.1", "http-body-util", @@ -4323,17 +4187,17 @@ dependencies = [ "quinn", "rustls", "rustls-native-certs", - "rustls-pemfile 2.1.3", + "rustls-pemfile 2.2.0", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper 1.0.1", - "system-configuration", - "tokio 1.39.2", + "system-configuration 0.6.1", + "tokio 1.40.0", "tokio-native-tls", "tokio-rustls", - "tokio-util 0.7.11", + "tokio-util 0.7.12", "tower-service", "url", "wasm-bindgen", @@ -4341,7 +4205,7 @@ dependencies = [ "wasm-streams", "web-sys", "webpki-roots", - "winreg 0.52.0", + "windows-registry", ] [[package]] @@ -4356,7 +4220,7 @@ dependencies = [ "mime", "nom", "pin-project-lite 0.2.14", - "reqwest 0.12.5", + "reqwest 0.12.8", "thiserror", ] @@ -4412,7 +4276,7 @@ dependencies = [ "netlink-proto", "nix", "thiserror", - "tokio 1.39.2", + "tokio 1.40.0", ] [[package]] @@ -4435,9 +4299,9 @@ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] @@ -4453,9 +4317,9 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.34" +version = "0.38.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811" dependencies = [ "bitflags 2.6.0", "errno", @@ -4466,26 +4330,26 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.12" +version = "0.23.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" +checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" dependencies = [ "once_cell", "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.6", + "rustls-webpki 0.102.8", "subtle", "zeroize", ] [[package]] name = "rustls-native-certs" -version = "0.7.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a88d6d420651b496bdd98684116959239430022a115c1240e6c3993be0b15fba" +checksum = "fcaf18a4f2be7326cd874a5fa579fae794320a0f388d365dca7e480e55f83f8a" dependencies = [ "openssl-probe", - "rustls-pemfile 2.1.3", + "rustls-pemfile 2.2.0", "rustls-pki-types", "schannel", "security-framework", @@ -4502,19 +4366,18 @@ dependencies = [ [[package]] name = "rustls-pemfile" -version = "2.1.3" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" dependencies = [ - "base64 0.22.1", "rustls-pki-types", ] [[package]] name = "rustls-pki-types" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" +checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" [[package]] name = "rustls-webpki" @@ -4528,9 +4391,9 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.102.6" +version = "0.102.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" dependencies = [ "ring 0.17.8", "rustls-pki-types", @@ -4561,11 +4424,11 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "e9aaafd5a2b6e3d657ff009d82fbd630b6bd54dd4eb06f21693925cdf80f9b8b" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -4606,6 +4469,22 @@ dependencies = [ "tendril", ] +[[package]] +name = "scraper" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b90460b31bfe1fc07be8262e42c665ad97118d4585869de9345a84d501a9eaf0" +dependencies = [ + "ahash", + "cssparser 0.31.2", + "ego-tree", + "getopts", + "html5ever 0.27.0", + "once_cell", + "selectors 0.25.0", + "tendril", +] + [[package]] name = "search_with_google" version = "0.5.0" @@ -4644,9 +4523,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.11.1" +version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" +checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" dependencies = [ "core-foundation-sys", "libc", @@ -4710,29 +4589,29 @@ checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" [[package]] name = "serde" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff085d2cb684faa248efb494c39b68e522822ac0de72ccf08109abde717cfb2" +checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.208" +version = "1.0.210" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24008e81ff7613ed8e5ba0cfaf24e2c2f1e5b8a0495711e44fcd4882fca62bcf" +checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] name = "serde_json" -version = "1.0.125" +version = "1.0.128" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83c8e735a073ccf5be70aa8066aa984eaf2fa000db6c8d0100ae605b366d31ed" +checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" dependencies = [ "itoa 1.0.11", "memchr", @@ -4993,11 +4872,11 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", "rustversion", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -5019,9 +4898,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.74" +version = "2.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" dependencies = [ "proc-macro2", "quote", @@ -5039,6 +4918,9 @@ name = "sync_wrapper" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" +dependencies = [ + "futures-core", +] [[package]] name = "synstructure" @@ -5048,7 +4930,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -5059,7 +4941,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.6.0", + "core-foundation", + "system-configuration-sys 0.6.0", ] [[package]] @@ -5072,11 +4965,21 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempfile" -version = "3.12.0" +version = "3.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" +checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" dependencies = [ "cfg-if 1.0.0", "fastrand", @@ -5110,6 +5013,23 @@ name = "text-splitter" version = "0.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2ab9dc04b7cf08eb01c07c272bf699fa55679a326ddf7dd075e14094efc80fb9" +dependencies = [ + "ahash", + "auto_enums", + "either", + "itertools", + "once_cell", + "regex", + "strum", + "thiserror", + "unicode-segmentation", +] + +[[package]] +name = "text-splitter" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f280573deec490e745c503ecc1d0e17104e98936eaefd7b0aa4b1422c74b317" dependencies = [ "ahash", "auto_enums", @@ -5132,22 +5052,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "1.0.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -5251,12 +5171,12 @@ dependencies = [ [[package]] name = "tokio" -version = "1.39.2" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", - "bytes 1.7.1", + "bytes 1.7.2", "libc", "mio 1.0.2", "parking_lot", @@ -5275,7 +5195,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -5285,7 +5205,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" dependencies = [ "native-tls", - "tokio 1.39.2", + "tokio 1.40.0", ] [[package]] @@ -5296,18 +5216,18 @@ checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ "rustls", "rustls-pki-types", - "tokio 1.39.2", + "tokio 1.40.0", ] [[package]] name = "tokio-stream" -version = "0.1.15" +version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" dependencies = [ "futures-core", "pin-project-lite 0.2.14", - "tokio 1.39.2", + "tokio 1.40.0", ] [[package]] @@ -5336,40 +5256,19 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.11" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" +checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" dependencies = [ - "bytes 1.7.1", + "bytes 1.7.2", "futures-core", "futures-sink", "futures-util", "hashbrown 0.14.5", "pin-project-lite 0.2.14", - "tokio 1.39.2", -] - -[[package]] -name = "tower" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "pin-project", - "pin-project-lite 0.2.14", - "tokio 1.39.2", - "tower-layer", - "tower-service", + "tokio 1.40.0", ] -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - [[package]] name = "tower-service" version = "0.3.3" @@ -5396,7 +5295,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -5489,24 +5388,24 @@ checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" [[package]] name = "unicode-normalization" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" dependencies = [ "tinyvec", ] [[package]] name = "unicode-segmentation" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" @@ -5667,7 +5566,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", "wasm-bindgen-shared", ] @@ -5701,7 +5600,7 @@ checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5714,9 +5613,9 @@ checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wasm-streams" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" dependencies = [ "futures-util", "js-sys", @@ -5747,19 +5646,13 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.3" +version = "0.26.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" +checksum = "841c67bff177718f1d4dfefde8d8f0e78f9b6589319ba88312f567fc5841a958" dependencies = [ "rustls-pki-types", ] -[[package]] -name = "weezl" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" - [[package]] name = "widestring" version = "1.1.0" @@ -5815,7 +5708,7 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows-core 0.51.1", + "windows-core", "windows-targets 0.48.5", ] @@ -5829,14 +5722,35 @@ dependencies = [ ] [[package]] -name = "windows-core" -version = "0.52.0" +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -6004,16 +5918,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "winreg" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a277a57398d4bfa075df44f501a17cfdf8542d224f0d36095a2adc7aee4ef0a5" -dependencies = [ - "cfg-if 1.0.0", - "windows-sys 0.48.0", -] - [[package]] name = "ws2_32-sys" version = "0.2.1" @@ -6055,9 +5959,9 @@ dependencies = [ [[package]] name = "xml-rs" -version = "0.8.21" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "539a77ee7c0de333dcc6da69b177380a0b81e0dacfa4f7344c465a36871ee601" +checksum = "af4e2e2f7cba5a093896c1e150fbfe177d1883e7448200efb81d40b9d339ef26" [[package]] name = "xml5ever" @@ -6161,7 +6065,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] [[package]] @@ -6181,5 +6085,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.79", ] diff --git a/Cargo.toml b/Cargo.toml index a6b62f0..d57315a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ sha3 = "0.10.8" fastbloom-rs = "0.5.9" # workflows -ollama-workflows = { git = "https://github.com/andthattoo/ollama-workflows", rev = "09f8579" } +ollama-workflows = { git = "https://github.com/andthattoo/ollama-workflows" } # peer-to-peer libp2p = { git = "https://github.com/anilaltuner/rust-libp2p.git", rev = "7ce9f9e", features = [ diff --git a/Makefile b/Makefile index 99eebda..5ec333b 100644 --- a/Makefile +++ b/Makefile @@ -33,10 +33,6 @@ profile-cpu: profile-mem: cargo instruments --profile=profiling --features=profiling -t Allocations -.PHONY: version # | Print version -version: - @cargo pkgid | cut -d@ -f2 - ############################################################################### .PHONY: test # | Run tests test: @@ -51,8 +47,11 @@ lint: format: cargo fmt -v -############################################################################### -.PHONY: docs # | Generate & open crate documentation +.PHONY: version # | Print version +version: + @cargo pkgid | cut -d@ -f2 + +.PHONY: docs # | Generate & open documentation docs: cargo doc --open --no-deps --document-private-items diff --git a/src/handlers/pingpong.rs b/src/handlers/pingpong.rs index 1c046e9..31857e9 100644 --- a/src/handlers/pingpong.rs +++ b/src/handlers/pingpong.rs @@ -72,7 +72,7 @@ mod tests { use crate::{ utils::{ crypto::{sha256hash, to_address}, - filter::FilterPayload, + filter::TaskFilter, DKNMessage, }, DriaComputeNodeConfig, @@ -130,7 +130,7 @@ mod tests { // admin node assigns the task to the compute node via Bloom Filter let mut bloom = FilterBuilder::new(100, 0.01).build_bloom_filter(); bloom.add(&address); - let filter_payload = FilterPayload::from(bloom); + let filter_payload = TaskFilter::from(bloom); // compute node receives the filter and checks if it is tasked assert!( diff --git a/src/p2p/data_transform.rs b/src/p2p/data_transform.rs index 59012d0..7f28e70 100644 --- a/src/p2p/data_transform.rs +++ b/src/p2p/data_transform.rs @@ -1,9 +1,9 @@ -///! https://docs.rs/libp2p-gossipsub/latest/libp2p_gossipsub/trait.DataTransform.html use libp2p::gossipsub::{DataTransform, Message, RawMessage, TopicHash}; use std::io::{Error, ErrorKind}; use std::time::{SystemTime, UNIX_EPOCH}; -/// A `DataTransform` implementation that adds & checks a timestamp to the message. +/// A [DataTransform](https://docs.rs/libp2p-gossipsub/latest/libp2p_gossipsub/trait.DataTransform.html) +/// implementation that adds & checks a timestamp to the message. pub struct TTLDataTransform { /// Time-to-live, e.g. obtained from some `duration.as_secs()`. ttl_secs: u64, diff --git a/src/payloads/request.rs b/src/payloads/request.rs index 6a9bb3e..35e8e50 100644 --- a/src/payloads/request.rs +++ b/src/payloads/request.rs @@ -1,4 +1,4 @@ -use crate::utils::{filter::FilterPayload, get_current_time_nanos}; +use crate::utils::{filter::TaskFilter, get_current_time_nanos}; use fastbloom_rs::BloomFilter; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -14,7 +14,7 @@ pub struct TaskRequestPayload { /// The input to the compute function. pub(crate) input: T, /// The Bloom filter of the task. - pub(crate) filter: FilterPayload, + pub(crate) filter: TaskFilter, /// The public key of the requester, in hexadecimals. pub(crate) public_key: String, } diff --git a/src/utils/filter.rs b/src/utils/filter.rs index e69cf1b..7b4a024 100644 --- a/src/utils/filter.rs +++ b/src/utils/filter.rs @@ -7,12 +7,12 @@ use serde_json::{json, to_string}; /// /// The filter is a Bloom Filter with a set of items and a false positive rate, it is serialized as a hex string. #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct FilterPayload { +pub struct TaskFilter { pub(crate) hex: String, pub(crate) hashes: u32, } -impl FilterPayload { +impl TaskFilter { /// Shorthand function to create the underlying `BloomFilter` and check if it contains the given address. pub fn contains(&self, address: &[u8]) -> Result { BloomFilter::try_from(self) @@ -23,16 +23,16 @@ impl FilterPayload { // FIXME: too many TryFrom's here, simplify in a single function here! -impl TryFrom<&FilterPayload> for String { +impl TryFrom<&TaskFilter> for String { type Error = serde_json::Error; - fn try_from(value: &FilterPayload) -> Result { + fn try_from(value: &TaskFilter) -> Result { let string = to_string(&json!(value))?; Ok(string) } } -impl TryFrom for FilterPayload { +impl TryFrom for TaskFilter { type Error = serde_json::Error; fn try_from(value: String) -> Result { @@ -41,18 +41,18 @@ impl TryFrom for FilterPayload { } } -impl TryFrom<&FilterPayload> for BloomFilter { +impl TryFrom<&TaskFilter> for BloomFilter { type Error = hex::FromHexError; - fn try_from(value: &FilterPayload) -> Result { + fn try_from(value: &TaskFilter) -> Result { let filter = hex::decode(value.hex.as_str())?; Ok(BloomFilter::from_u8_array(&filter, value.hashes)) } } -impl From for FilterPayload { +impl From for TaskFilter { fn from(value: BloomFilter) -> Self { - FilterPayload { + TaskFilter { hex: hex::encode(value.get_u8_array()), hashes: value.hashes(), } @@ -76,7 +76,7 @@ mod tests { fn test_filter_read_1() { // 250 items, 0.01 fp rate (7 hashes), includes b"helloworld" and nothing else const FILTER_HEX: &str = "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000040000000000000400000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000004000000000000040000"; - let filter_payload = FilterPayload { + let filter_payload = TaskFilter { hex: FILTER_HEX.to_string(), hashes: 7, }; @@ -90,7 +90,7 @@ mod tests { fn test_filter_read_2() { // 128 items, 0.01 fp rate (7 hashes), includes b"helloworld" and nothing else const FILTER_HEX: &str = "00000040000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000004000000000000000000000000000000000000000000000040000000000000000000000000004000000000000000000000000000000000000"; - let filter_payload = FilterPayload { + let filter_payload = TaskFilter { hex: FILTER_HEX.to_string(), hashes: 7, }; @@ -103,7 +103,7 @@ mod tests { #[test] #[ignore = "this panics, its a bug within the filter library"] fn test_filter_empty() { - let filter_payload = FilterPayload { + let filter_payload = TaskFilter { hex: "".to_string(), hashes: 0, }; From 1b80f9eed480f62a9fba35ba2fe3eee7a0c072fe Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 2 Oct 2024 15:16:17 +0300 Subject: [PATCH 11/15] change version back --- Cargo.lock | 2 +- Cargo.toml | 2 +- src/utils/message.rs | 19 ++++++++++--------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a77400c..ec05396 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -980,7 +980,7 @@ dependencies = [ [[package]] name = "dkn-compute" -version = "0.3.0" +version = "0.2.6" dependencies = [ "async-trait", "base64 0.22.1", diff --git a/Cargo.toml b/Cargo.toml index d57315a..e4c0253 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "dkn-compute" -version = "0.3.0" +version = "0.2.6" edition = "2021" license = "Apache-2.0" readme = "README.md" diff --git a/src/utils/message.rs b/src/utils/message.rs index ec8954c..4423dc4 100644 --- a/src/utils/message.rs +++ b/src/utils/message.rs @@ -2,6 +2,7 @@ use crate::utils::{ crypto::{sha256hash, sign_bytes_recoverable}, get_current_time_nanos, }; +use crate::DRIA_COMPUTE_NODE_VERSION; use base64::{prelude::BASE64_STANDARD, Engine}; use core::fmt; use ecies::PublicKey; @@ -12,7 +13,7 @@ use serde::{Deserialize, Serialize}; /// A message within Dria Knowledge Network. #[derive(Serialize, Deserialize, Debug, Clone)] pub struct DKNMessage { - /// Base64 encoded data + /// Base64 encoded payload, stores the main result. pub(crate) payload: String, /// The topic of the message, derived from `TopicHash` /// @@ -44,7 +45,7 @@ impl DKNMessage { Self { payload: BASE64_STANDARD.encode(payload), topic: topic.to_string(), - version: crate::DRIA_COMPUTE_NODE_VERSION.to_string(), + version: DRIA_COMPUTE_NODE_VERSION.to_string(), timestamp: get_current_time_nanos(), } } @@ -133,8 +134,7 @@ mod tests { use crate::payloads::TaskResponsePayload; use crate::{utils::crypto::sha256hash, DriaComputeNodeConfig}; use ecies::decrypt; - use libsecp256k1::SecretKey; - use libsecp256k1::{verify, Message, PublicKey, RecoveryId, Signature}; + use libsecp256k1::{verify, Message, PublicKey, RecoveryId, SecretKey, Signature}; use rand::thread_rng; use serde_json::json; @@ -155,7 +155,7 @@ mod tests { #[test] fn test_display_message() { - let message = DKNMessage::new(b"hello world", "test-topic"); + let message = DKNMessage::new(b"hello world", TOPIC); println!("{}", message); } @@ -173,10 +173,11 @@ mod tests { serde_json::to_string(&body).expect("Should stringify"), "{\"hello\":\"world\"}" ); - assert_eq!(message.topic, "test-topic"); - assert_eq!(message.version, crate::DRIA_COMPUTE_NODE_VERSION); + assert_eq!(message.topic, TOPIC); + assert_eq!(message.version, DRIA_COMPUTE_NODE_VERSION); assert!(message.timestamp > 0); + // decode payload without signature let parsed_body = message.parse_payload(false).expect("Should decode"); assert_eq!(body, parsed_body); } @@ -200,8 +201,8 @@ mod tests { serde_json::to_string(&body).expect("Should stringify"), "{\"hello\":\"world\"}" ); - assert_eq!(message.topic, "test-topic"); - assert_eq!(message.version, crate::DRIA_COMPUTE_NODE_VERSION); + assert_eq!(message.topic, TOPIC); + assert_eq!(message.version, DRIA_COMPUTE_NODE_VERSION); assert!(message.timestamp > 0); assert!(message.is_signed(&pk).expect("Should check signature")); From 2030b337b68d660fec43b7f67b7029715e57efe7 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 2 Oct 2024 18:21:31 +0300 Subject: [PATCH 12/15] much better eyre error printing --- Cargo.toml | 1 + src/handlers/mod.rs | 17 ++++++++---- src/handlers/pingpong.rs | 6 ++-- src/handlers/topics.rs | 4 --- src/handlers/workflow.rs | 30 ++++++++++++-------- src/main.rs | 6 ++-- src/node.rs | 60 ++++++++++++++++++++-------------------- src/payloads/error.rs | 3 +- 8 files changed, 70 insertions(+), 57 deletions(-) delete mode 100644 src/handlers/topics.rs diff --git a/Cargo.toml b/Cargo.toml index e4c0253..809bcc3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,6 +4,7 @@ version = "0.2.6" edition = "2021" license = "Apache-2.0" readme = "README.md" +authors = ["Erhan Tezcan "] # profiling build for flamegraphs [profile.profiling] diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index c71e56b..10f37ee 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -1,25 +1,30 @@ +use crate::{utils::DKNMessage, DriaComputeNode}; use async_trait::async_trait; use eyre::Result; use libp2p::gossipsub::MessageAcceptance; -mod topics; -pub use topics::*; - mod pingpong; pub use pingpong::PingpongHandler; mod workflow; pub use workflow::WorkflowHandler; -use crate::{utils::DKNMessage, DriaComputeNode}; - /// A DKN task is to be handled by the compute node, respecting this trait. +/// +/// It is expected for the implemented handler to handle messages coming from `LISTEN_TOPIC`, +/// and then respond back to the `RESPONSE_TOPIC`. #[async_trait] pub trait ComputeHandler { + /// Gossipsub topic name to listen for incoming messages from the network. + const LISTEN_TOPIC: &'static str; + /// Gossipsub topic name to respond with messages to the network. + const RESPONSE_TOPIC: &'static str; + /// A generic handler for DKN tasks. + /// + /// Returns a `MessageAcceptance` value that tells the P2P client to accept the incoming message. async fn handle_compute( node: &mut DriaComputeNode, message: DKNMessage, - result_topic: &str, ) -> Result; } diff --git a/src/handlers/pingpong.rs b/src/handlers/pingpong.rs index 31857e9..2bb1c8e 100644 --- a/src/handlers/pingpong.rs +++ b/src/handlers/pingpong.rs @@ -27,10 +27,12 @@ struct PingpongResponse { #[async_trait] impl ComputeHandler for PingpongHandler { + const LISTEN_TOPIC: &'static str = "ping"; + const RESPONSE_TOPIC: &'static str = "pong"; + async fn handle_compute( node: &mut DriaComputeNode, message: DKNMessage, - result_topic: &str, ) -> Result { let pingpong = message.parse_payload::(true)?; @@ -58,7 +60,7 @@ impl ComputeHandler for PingpongHandler { // publish message let message = DKNMessage::new_signed( serde_json::json!(response_body).to_string(), - result_topic, + Self::RESPONSE_TOPIC, &node.config.secret_key, ); node.publish(message)?; diff --git a/src/handlers/topics.rs b/src/handlers/topics.rs deleted file mode 100644 index bf83adf..0000000 --- a/src/handlers/topics.rs +++ /dev/null @@ -1,4 +0,0 @@ -pub const PINGPONG_LISTEN_TOPIC: &str = "ping"; -pub const PINGPONG_RESPONSE_TOPIC: &str = "pong"; -pub const WORKFLOW_LISTEN_TOPIC: &str = "task"; -pub const WORKFLOW_RESPONSE_TOPIC: &str = "results"; diff --git a/src/handlers/workflow.rs b/src/handlers/workflow.rs index e8c9888..e71b193 100644 --- a/src/handlers/workflow.rs +++ b/src/handlers/workflow.rs @@ -1,5 +1,5 @@ use async_trait::async_trait; -use eyre::{eyre, Result}; +use eyre::{eyre, Context, Result}; use libp2p::gossipsub::MessageAcceptance; use ollama_workflows::{Entry, Executor, ModelProvider, ProgramMemory, Workflow}; use serde::Deserialize; @@ -27,13 +27,17 @@ struct WorkflowPayload { #[async_trait] impl ComputeHandler for WorkflowHandler { + const LISTEN_TOPIC: &'static str = "task"; + const RESPONSE_TOPIC: &'static str = "results"; + async fn handle_compute( node: &mut DriaComputeNode, message: DKNMessage, - result_topic: &str, ) -> Result { let config = &node.config; - let task = message.parse_payload::>(true)?; + let task = message + .parse_payload::>(true) + .wrap_err("Could not parse error")?; // check if deadline is past or not let current_time = get_current_time_nanos(); @@ -56,7 +60,7 @@ impl ComputeHandler for WorkflowHandler { task.task_id ); - // accept the message, someonelse may be included in filter + // accept the message, someone else may be included in filter return Ok(MessageAcceptance::Accept); } @@ -86,14 +90,15 @@ impl ComputeHandler for WorkflowHandler { return Ok(MessageAcceptance::Accept); }, exec_result_inner = executor.execute(entry.as_ref(), task.input.workflow, &mut memory) => { - exec_result = exec_result_inner.map_err(|e| eyre!("{}", e.to_string())); + exec_result = exec_result_inner.map_err(|e| eyre!("Execution error: {}", e.to_string())); } } match exec_result { Ok(result) => { // obtain public key from the payload - let task_public_key = hex::decode(&task.public_key)?; + let task_public_key = + hex::decode(&task.public_key).wrap_err("Could not decode public key")?; // prepare signed and encrypted payload let payload = TaskResponsePayload::new( @@ -102,24 +107,27 @@ impl ComputeHandler for WorkflowHandler { &task_public_key, &config.secret_key, )?; - let payload_str = serde_json::to_string(&payload)?; + let payload_str = + serde_json::to_string(&payload).wrap_err("Could not serialize payload")?; // publish the result - let message = DKNMessage::new(payload_str, result_topic); + let message = DKNMessage::new(payload_str, Self::RESPONSE_TOPIC); node.publish(message)?; // accept so that if there are others included in filter they can do the task Ok(MessageAcceptance::Accept) } Err(err) => { - log::error!("Task {} failed: {}", task.task_id, err); + // use pretty display string for error logging with causes + let err_string = format!("{:#}", err); + log::error!("Task {} failed: {}", task.task_id, err_string); // prepare error payload - let error_payload = TaskErrorPayload::new(task.task_id, err.to_string()); + let error_payload = TaskErrorPayload::new(task.task_id, err_string); let error_payload_str = serde_json::to_string(&error_payload)?; // publish the error result for diagnostics - let message = DKNMessage::new(error_payload_str, result_topic); + let message = DKNMessage::new(error_payload_str, Self::RESPONSE_TOPIC); node.publish(message)?; // ignore just in case, workflow may be bugged diff --git a/src/main.rs b/src/main.rs index 5732993..368e535 100644 --- a/src/main.rs +++ b/src/main.rs @@ -38,7 +38,7 @@ async fn main() -> Result<()> { #[cfg(not(feature = "profiling"))] if let Err(err) = wait_for_termination(cancellation_token.clone()).await { - log::error!("Error waiting for termination: {}", err); + log::error!("Error waiting for termination: {:?}", err); log::error!("Cancelling due to unexpected error."); cancellation_token.cancel(); }; @@ -55,7 +55,7 @@ async fn main() -> Result<()> { } result = config_clone.check_services() => { if let Err(err) = result { - log::error!("Error checking services: {}", err); + log::error!("Error checking services: {:?}", err); panic!("Service check failed.") } } @@ -101,7 +101,7 @@ async fn main() -> Result<()> { /// /// Handles Unix and Windows [target families](https://doc.rust-lang.org/reference/conditional-compilation.html#target_family). #[allow(unused)] -async fn wait_for_termination(cancellation: CancellationToken) -> std::io::Result<()> { +async fn wait_for_termination(cancellation: CancellationToken) -> Result<()> { #[cfg(unix)] { use tokio::signal::unix::{signal, SignalKind}; diff --git a/src/node.rs b/src/node.rs index a603f72..db8bc3a 100644 --- a/src/node.rs +++ b/src/node.rs @@ -4,7 +4,7 @@ use std::{str::FromStr, time::Duration}; use tokio_util::sync::CancellationToken; use crate::{ - config::DriaComputeNodeConfig, + config::*, handlers::*, p2p::P2PClient, utils::{crypto::secret_to_keypair, AvailableNodes, DKNMessage}, @@ -13,6 +13,19 @@ use crate::{ /// Number of seconds between refreshing the Admin RPC PeerIDs from Dria server. const RPC_PEER_ID_REFRESH_INTERVAL_SECS: u64 = 30; +/// **Dria Compute Node** +/// +/// Internally, the node will create a new P2P client with the given secret key. +/// This P2P client, although created synchronously, requires a tokio runtime. +/// +/// ### Example +/// +/// ```rs +/// let config = DriaComputeNodeConfig::new(); +/// let mut node = DriaComputeNode::new(config, CancellationToken::new())?; +/// node.check_services().await?; +/// node.launch().await?; +/// ``` pub struct DriaComputeNode { pub config: DriaComputeNodeConfig, pub p2p: P2PClient, @@ -22,19 +35,6 @@ pub struct DriaComputeNode { } impl DriaComputeNode { - /// Create a new compute node with the given configuration and cancellation token. - /// - /// Internally, the node will create a new P2P client with the given secret key. - /// This P2P client, although created synchronously, requires a tokio runtime. - /// - /// ### Example - /// - /// ```rs - /// let config = DriaComputeNodeConfig::new(); - /// let mut node = DriaComputeNode::new(config, CancellationToken::new())?; - /// node.check_services().await?; - /// node.launch().await?; - /// ``` pub async fn new( config: DriaComputeNodeConfig, cancellation: CancellationToken, @@ -106,10 +106,10 @@ impl DriaComputeNode { /// This method is not expected to return until cancellation occurs. pub async fn launch(&mut self) -> Result<()> { // subscribe to topics - self.subscribe(PINGPONG_LISTEN_TOPIC)?; - self.subscribe(PINGPONG_RESPONSE_TOPIC)?; - self.subscribe(WORKFLOW_LISTEN_TOPIC)?; - self.subscribe(WORKFLOW_RESPONSE_TOPIC)?; + self.subscribe(PingpongHandler::LISTEN_TOPIC)?; + self.subscribe(PingpongHandler::RESPONSE_TOPIC)?; + self.subscribe(WorkflowHandler::LISTEN_TOPIC)?; + self.subscribe(WorkflowHandler::RESPONSE_TOPIC)?; // main loop, listens for message events in particular // the underlying p2p client is expected to handle the rest within its own loop @@ -127,7 +127,7 @@ impl DriaComputeNode { let topic_str = topic.as_str(); // handle message w.r.t topic - if std::matches!(topic_str, PINGPONG_LISTEN_TOPIC | WORKFLOW_LISTEN_TOPIC) { + if std::matches!(topic_str, PingpongHandler::LISTEN_TOPIC | WorkflowHandler::LISTEN_TOPIC) { // ensure that the message is from a valid source (origin) let source_peer_id = match message.source { Some(peer) => peer, @@ -159,7 +159,7 @@ impl DriaComputeNode { let message = match self.parse_message_to_prepared_message(message.clone()) { Ok(message) => message, Err(e) => { - log::error!("Error parsing message: {}", e); + log::error!("Error parsing message: {:?}", e); log::debug!("Message: {}", String::from_utf8_lossy(&message.data)); self.p2p.validate_message(&message_id, &peer_id, gossipsub::MessageAcceptance::Ignore)?; continue; @@ -168,11 +168,11 @@ impl DriaComputeNode { // then handle the prepared message let handler_result = match topic_str { - WORKFLOW_LISTEN_TOPIC => { - WorkflowHandler::handle_compute(self, message, WORKFLOW_RESPONSE_TOPIC).await + WorkflowHandler::LISTEN_TOPIC => { + WorkflowHandler::handle_compute(self, message).await } - PINGPONG_LISTEN_TOPIC => { - PingpongHandler::handle_compute(self, message, PINGPONG_RESPONSE_TOPIC).await + PingpongHandler::LISTEN_TOPIC => { + PingpongHandler::handle_compute(self, message).await } // TODO: can we do this in a nicer way? // TODO: yes, cast to enum above and let type-casting do the work @@ -185,11 +185,11 @@ impl DriaComputeNode { self.p2p.validate_message(&message_id, &peer_id, acceptance)?; }, Err(err) => { - log::error!("Error handling {} message: {}", topic_str, err); + log::error!("Error handling {} message: {:?}", topic_str, err); self.p2p.validate_message(&message_id, &peer_id, gossipsub::MessageAcceptance::Ignore)?; } } - } else if std::matches!(topic_str, PINGPONG_RESPONSE_TOPIC | WORKFLOW_RESPONSE_TOPIC) { + } else if std::matches!(topic_str, PingpongHandler::RESPONSE_TOPIC | WorkflowHandler::RESPONSE_TOPIC) { // since we are responding to these topics, we might receive messages from other compute nodes // we can gracefully ignore them and propagate it to to others log::debug!("Ignoring message for topic: {}", topic_str); @@ -205,10 +205,10 @@ impl DriaComputeNode { } // unsubscribe from topics - self.unsubscribe(PINGPONG_LISTEN_TOPIC)?; - self.unsubscribe(PINGPONG_RESPONSE_TOPIC)?; - self.unsubscribe(WORKFLOW_LISTEN_TOPIC)?; - self.unsubscribe(WORKFLOW_RESPONSE_TOPIC)?; + self.unsubscribe(PingpongHandler::LISTEN_TOPIC)?; + self.unsubscribe(PingpongHandler::RESPONSE_TOPIC)?; + self.unsubscribe(WorkflowHandler::LISTEN_TOPIC)?; + self.unsubscribe(WorkflowHandler::RESPONSE_TOPIC)?; Ok(()) } diff --git a/src/payloads/error.rs b/src/payloads/error.rs index 6b66409..0fbaccf 100644 --- a/src/payloads/error.rs +++ b/src/payloads/error.rs @@ -1,6 +1,7 @@ use serde::{Deserialize, Serialize}; -/// A generic task request, given by Dria. +/// A task error response. +/// Returning this as the payload helps to debug the errors received at client side. #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(rename_all = "camelCase")] pub struct TaskErrorPayload { From 923b805b10992472cea0dd4e00bbda04e69d6309 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 2 Oct 2024 18:37:22 +0300 Subject: [PATCH 13/15] tiny rfk in tests --- src/handlers/pingpong.rs | 21 ++++++++++----------- src/payloads/request.rs | 17 +---------------- 2 files changed, 11 insertions(+), 27 deletions(-) diff --git a/src/handlers/pingpong.rs b/src/handlers/pingpong.rs index 2bb1c8e..44bc5d6 100644 --- a/src/handlers/pingpong.rs +++ b/src/handlers/pingpong.rs @@ -85,14 +85,14 @@ mod tests { use super::PingpongPayload; #[test] - fn test_heartbeat_payload() { + fn test_pingpong_payload() { let pk = PublicKey::parse_compressed(&hex_literal::hex!( "0208ef5e65a9c656a6f92fb2c770d5d5e2ecffe02a6aade19207f75110be6ae658" )) .expect("Should parse public key"); let message = DKNMessage { payload: "Y2RmODcyNDlhY2U3YzQ2MDIzYzNkMzBhOTc4ZWY3NjViMWVhZDlmNWJhMDUyY2MxMmY0NzIzMjQyYjc0YmYyODFjMDA1MTdmMGYzM2VkNTgzMzk1YWUzMTY1ODQ3NWQyNDRlODAxYzAxZDE5MjYwMDM1MTRkNzEwMThmYTJkNjEwMXsidXVpZCI6ICI4MWE2M2EzNC05NmM2LTRlNWEtOTliNS02YjI3NGQ5ZGUxNzUiLCAiZGVhZGxpbmUiOiAxNzE0MTI4NzkyfQ==".to_string(), - topic: "heartbeat".to_string(), + topic: "pingpong".to_string(), version: "0.0.0".to_string(), timestamp: 1714129073557846272, }; @@ -106,22 +106,21 @@ mod tests { assert_eq!(obj.deadline, 1714128792); } - /// This test demonstrates the process of heartbeat & task assignment. + /// This test demonstrates the process of pingpong & task assignment. /// /// A heart-beat message is sent over the network by Admin Node, and compute node responds with a signature. #[test] - fn test_heartbeat_and_task_assignment() { + fn test_pingpong_and_task_assignment() { let config = DriaComputeNodeConfig::default(); - // a heartbeat message is signed and sent to Admin Node over the p2p network - let heartbeat_message = Message::parse(&sha256hash(b"sign-me")); - let (heartbeat_signature, heartbeat_recid) = - libsecp256k1::sign(&heartbeat_message, &config.secret_key); + // a pingpong message is signed and sent to Admin Node over the p2p network + let pingpong_message = Message::parse(&sha256hash(b"sign-me")); + let (pingpong_signature, pingpong_recid) = + libsecp256k1::sign(&pingpong_message, &config.secret_key); // admin recovers the address from the signature - let recovered_public_key = - recover(&heartbeat_message, &heartbeat_signature, &heartbeat_recid) - .expect("Could not recover"); + let recovered_public_key = recover(&pingpong_message, &pingpong_signature, &pingpong_recid) + .expect("Could not recover"); assert_eq!( config.public_key, recovered_public_key, "Public key mismatch" diff --git a/src/payloads/request.rs b/src/payloads/request.rs index 35e8e50..d93e490 100644 --- a/src/payloads/request.rs +++ b/src/payloads/request.rs @@ -1,7 +1,5 @@ -use crate::utils::{filter::TaskFilter, get_current_time_nanos}; -use fastbloom_rs::BloomFilter; +use crate::utils::filter::TaskFilter; use serde::{Deserialize, Serialize}; -use uuid::Uuid; /// A generic task request, given by Dria. #[derive(Debug, Clone, Serialize, Deserialize)] @@ -18,16 +16,3 @@ pub struct TaskRequestPayload { /// The public key of the requester, in hexadecimals. pub(crate) public_key: String, } - -impl TaskRequestPayload { - #[allow(unused)] - pub fn new(input: T, filter: BloomFilter, time_ns: u128, public_key: Option) -> Self { - Self { - task_id: Uuid::new_v4().into(), - deadline: get_current_time_nanos() + time_ns, - input, - filter: filter.into(), - public_key: public_key.unwrap_or_default(), - } - } -} From 1f0e94aec5743e88d941f202910f14f12fa16a5c Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 2 Oct 2024 19:30:51 +0300 Subject: [PATCH 14/15] even more tidying up --- src/handlers/mod.rs | 2 + src/handlers/pingpong.rs | 80 ++--------------------- src/handlers/workflow.rs | 6 +- src/payloads/response.rs | 66 +++++++++++++++---- src/utils/crypto.rs | 14 +++- src/utils/message.rs | 134 +++++++++++---------------------------- 6 files changed, 113 insertions(+), 189 deletions(-) diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 10f37ee..edb018e 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -23,6 +23,8 @@ pub trait ComputeHandler { /// A generic handler for DKN tasks. /// /// Returns a `MessageAcceptance` value that tells the P2P client to accept the incoming message. + /// + /// The handler has mutable reference to the compute node, and therefore can respond within the handler itself in any way it would like. async fn handle_compute( node: &mut DriaComputeNode, message: DKNMessage, diff --git a/src/handlers/pingpong.rs b/src/handlers/pingpong.rs index 44bc5d6..28e9caf 100644 --- a/src/handlers/pingpong.rs +++ b/src/handlers/pingpong.rs @@ -3,7 +3,7 @@ use crate::{ DriaComputeNode, }; use async_trait::async_trait; -use eyre::Result; +use eyre::{Context, Result}; use libp2p::gossipsub::MessageAcceptance; use ollama_workflows::{Model, ModelProvider}; use serde::{Deserialize, Serialize}; @@ -34,7 +34,9 @@ impl ComputeHandler for PingpongHandler { node: &mut DriaComputeNode, message: DKNMessage, ) -> Result { - let pingpong = message.parse_payload::(true)?; + let pingpong = message + .parse_payload::(true) + .wrap_err("Could not parse ping request")?; // check deadline let current_time = get_current_time_nanos(); @@ -68,77 +70,3 @@ impl ComputeHandler for PingpongHandler { Ok(MessageAcceptance::Accept) } } - -#[cfg(test)] -mod tests { - use crate::{ - utils::{ - crypto::{sha256hash, to_address}, - filter::TaskFilter, - DKNMessage, - }, - DriaComputeNodeConfig, - }; - use fastbloom_rs::{FilterBuilder, Membership}; - use libsecp256k1::{recover, Message, PublicKey}; - - use super::PingpongPayload; - - #[test] - fn test_pingpong_payload() { - let pk = PublicKey::parse_compressed(&hex_literal::hex!( - "0208ef5e65a9c656a6f92fb2c770d5d5e2ecffe02a6aade19207f75110be6ae658" - )) - .expect("Should parse public key"); - let message = DKNMessage { - payload: "Y2RmODcyNDlhY2U3YzQ2MDIzYzNkMzBhOTc4ZWY3NjViMWVhZDlmNWJhMDUyY2MxMmY0NzIzMjQyYjc0YmYyODFjMDA1MTdmMGYzM2VkNTgzMzk1YWUzMTY1ODQ3NWQyNDRlODAxYzAxZDE5MjYwMDM1MTRkNzEwMThmYTJkNjEwMXsidXVpZCI6ICI4MWE2M2EzNC05NmM2LTRlNWEtOTliNS02YjI3NGQ5ZGUxNzUiLCAiZGVhZGxpbmUiOiAxNzE0MTI4NzkyfQ==".to_string(), - topic: "pingpong".to_string(), - version: "0.0.0".to_string(), - timestamp: 1714129073557846272, - }; - - assert!(message.is_signed(&pk).expect("Should check signature")); - - let obj = message - .parse_payload::(true) - .expect("Should parse payload"); - assert_eq!(obj.uuid, "81a63a34-96c6-4e5a-99b5-6b274d9de175"); - assert_eq!(obj.deadline, 1714128792); - } - - /// This test demonstrates the process of pingpong & task assignment. - /// - /// A heart-beat message is sent over the network by Admin Node, and compute node responds with a signature. - #[test] - fn test_pingpong_and_task_assignment() { - let config = DriaComputeNodeConfig::default(); - - // a pingpong message is signed and sent to Admin Node over the p2p network - let pingpong_message = Message::parse(&sha256hash(b"sign-me")); - let (pingpong_signature, pingpong_recid) = - libsecp256k1::sign(&pingpong_message, &config.secret_key); - - // admin recovers the address from the signature - let recovered_public_key = recover(&pingpong_message, &pingpong_signature, &pingpong_recid) - .expect("Could not recover"); - assert_eq!( - config.public_key, recovered_public_key, - "Public key mismatch" - ); - let address = to_address(&recovered_public_key); - assert_eq!(address, config.address, "Address mismatch"); - - // admin node assigns the task to the compute node via Bloom Filter - let mut bloom = FilterBuilder::new(100, 0.01).build_bloom_filter(); - bloom.add(&address); - let filter_payload = TaskFilter::from(bloom); - - // compute node receives the filter and checks if it is tasked - assert!( - filter_payload - .contains(&config.address) - .expect("Should check filter"), - "Node should be tasked" - ); - } -} diff --git a/src/handlers/workflow.rs b/src/handlers/workflow.rs index e71b193..392afa2 100644 --- a/src/handlers/workflow.rs +++ b/src/handlers/workflow.rs @@ -1,6 +1,7 @@ use async_trait::async_trait; use eyre::{eyre, Context, Result}; use libp2p::gossipsub::MessageAcceptance; +use libsecp256k1::PublicKey; use ollama_workflows::{Entry, Executor, ModelProvider, ProgramMemory, Workflow}; use serde::Deserialize; @@ -37,7 +38,7 @@ impl ComputeHandler for WorkflowHandler { let config = &node.config; let task = message .parse_payload::>(true) - .wrap_err("Could not parse error")?; + .wrap_err("Could not parse workflow task")?; // check if deadline is past or not let current_time = get_current_time_nanos(); @@ -97,8 +98,9 @@ impl ComputeHandler for WorkflowHandler { match exec_result { Ok(result) => { // obtain public key from the payload - let task_public_key = + let task_public_key_bytes = hex::decode(&task.public_key).wrap_err("Could not decode public key")?; + let task_public_key = PublicKey::parse_slice(&task_public_key_bytes, None)?; // prepare signed and encrypted payload let payload = TaskResponsePayload::new( diff --git a/src/payloads/response.rs b/src/payloads/response.rs index 9083cf0..2a7c029 100644 --- a/src/payloads/response.rs +++ b/src/payloads/response.rs @@ -1,6 +1,6 @@ -use crate::utils::crypto::sha256hash; +use crate::utils::crypto::{encrypt_bytes, sha256hash, sign_bytes_recoverable}; use eyre::Result; -use libsecp256k1::SecretKey; +use libsecp256k1::{PublicKey, SecretKey}; use serde::{Deserialize, Serialize}; /// A computation task is the task of computing a result from a given input. The result is encrypted with the public key of the requester. @@ -27,7 +27,7 @@ impl TaskResponsePayload { pub fn new( result: impl AsRef<[u8]>, task_id: &str, - encrypting_public_key: &[u8], + encrypting_public_key: &PublicKey, signing_secret_key: &SecretKey, ) -> Result { // create the message `task_id || payload` @@ -35,20 +35,60 @@ impl TaskResponsePayload { preimage.extend_from_slice(task_id.as_ref()); preimage.extend_from_slice(result.as_ref()); - // sign the message - // TODO: use `sign_recoverable` here instead? - let digest = libsecp256k1::Message::parse(&sha256hash(preimage)); - let (signature, recid) = libsecp256k1::sign(&digest, signing_secret_key); - let signature: [u8; 64] = signature.serialize(); - let recid: [u8; 1] = [recid.serialize()]; - - // encrypt payload itself - let ciphertext = ecies::encrypt(encrypting_public_key, result.as_ref())?; + let signature = sign_bytes_recoverable(&sha256hash(preimage), signing_secret_key); + let ciphertext = encrypt_bytes(result, encrypting_public_key)?; Ok(TaskResponsePayload { ciphertext: hex::encode(ciphertext), - signature: format!("{}{}", hex::encode(signature), hex::encode(recid)), + signature, task_id: task_id.to_string(), }) } } + +#[cfg(test)] +mod tests { + use super::*; + use ecies::decrypt; + use libsecp256k1::{recover, verify, Message, PublicKey, RecoveryId, Signature}; + use rand::thread_rng; + + #[test] + fn test_task_response_payload() { + // this is the result that we are "sending" + const RESULT: &[u8; 44] = b"hey im an LLM and I came up with this output"; + + // the signer will sign the payload, and it will be verified + let signer_sk = SecretKey::random(&mut thread_rng()); + let signer_pk = PublicKey::from_secret_key(&signer_sk); + + // the payload will be encrypted with this key + let task_sk = SecretKey::random(&mut thread_rng()); + let task_pk = PublicKey::from_secret_key(&task_sk); + let task_id = uuid::Uuid::new_v4().to_string(); + + // creates a signed and encrypted payload + let payload = TaskResponsePayload::new(RESULT, &task_id, &task_pk, &signer_sk) + .expect("Should create payload"); + + // decrypt result and compare it to plaintext + let ciphertext_bytes = hex::decode(payload.ciphertext).unwrap(); + let result = decrypt(&task_sk.serialize(), &ciphertext_bytes).expect("Could not decrypt"); + assert_eq!(result, RESULT, "Result mismatch"); + + // verify signature + let signature_bytes = hex::decode(payload.signature).expect("Should decode"); + let signature = Signature::parse_standard_slice(&signature_bytes[..64]).unwrap(); + let recid = RecoveryId::parse(signature_bytes[64]).unwrap(); + let mut preimage = vec![]; + preimage.extend_from_slice(task_id.as_bytes()); + preimage.extend_from_slice(&result); + let message = Message::parse(&sha256hash(preimage)); + assert!(verify(&message, &signature, &signer_pk), "Could not verify"); + + // recover verifying key (public key) from signature + let recovered_public_key = + recover(&message, &signature, &recid).expect("Could not recover"); + assert_eq!(signer_pk, recovered_public_key, "Public key mismatch"); + } +} diff --git a/src/utils/crypto.rs b/src/utils/crypto.rs index b84d0b3..ac06fa1 100644 --- a/src/utils/crypto.rs +++ b/src/utils/crypto.rs @@ -1,6 +1,7 @@ use ecies::PublicKey; +use eyre::{Context, Result}; use libp2p_identity::Keypair; -use libsecp256k1::{sign, Message, SecretKey}; +use libsecp256k1::{Message, SecretKey}; use sha2::{Digest, Sha256}; use sha3::Keccak256; @@ -33,7 +34,7 @@ pub fn to_address(public_key: &PublicKey) -> [u8; 20] { #[inline] pub fn sign_bytes_recoverable(message: &[u8; 32], secret_key: &SecretKey) -> String { let message = Message::parse(message); - let (signature, recid) = sign(&message, secret_key); + let (signature, recid) = libsecp256k1::sign(&message, secret_key); format!( "{}{}", @@ -42,6 +43,15 @@ pub fn sign_bytes_recoverable(message: &[u8; 32], secret_key: &SecretKey) -> Str ) } +/// Shorthand to encrypt bytes with a given public key. +/// Returns hexadecimal encoded ciphertext. +#[inline] +pub fn encrypt_bytes(data: impl AsRef<[u8]>, public_key: &PublicKey) -> Result { + ecies::encrypt(public_key.serialize().as_slice(), data.as_ref()) + .wrap_err("could not encrypt data") + .map(hex::encode) +} + /// Converts a `libsecp256k1::SecretKey` to a `libp2p_identity::secp256k1::Keypair`. /// To do this, we serialize the secret key and create a new keypair from it. #[inline] diff --git a/src/utils/message.rs b/src/utils/message.rs index 4423dc4..c7613e2 100644 --- a/src/utils/message.rs +++ b/src/utils/message.rs @@ -6,8 +6,8 @@ use crate::DRIA_COMPUTE_NODE_VERSION; use base64::{prelude::BASE64_STANDARD, Engine}; use core::fmt; use ecies::PublicKey; -use eyre::Result; -use libsecp256k1::SecretKey; +use eyre::{Context, Result}; +use libsecp256k1::{verify, Message, SecretKey, Signature}; use serde::{Deserialize, Serialize}; /// A message within Dria Knowledge Network. @@ -39,11 +39,11 @@ const SIGNATURE_SIZE_HEX: usize = 130; impl DKNMessage { /// Creates a new message with current timestamp and version equal to the crate version. /// - /// - `payload` is gives as bytes. It is to be `base64` encoded internally. + /// - `data` is given as bytes, it is encoded into base64 to make up the `payload` within. /// - `topic` is the name of the [gossipsub topic](https://docs.libp2p.io/concepts/pubsub/overview/). - pub fn new(payload: impl AsRef<[u8]>, topic: &str) -> Self { + pub fn new(data: impl AsRef<[u8]>, topic: &str) -> Self { Self { - payload: BASE64_STANDARD.encode(payload), + payload: BASE64_STANDARD.encode(data), topic: topic.to_string(), version: DRIA_COMPUTE_NODE_VERSION.to_string(), timestamp: get_current_time_nanos(), @@ -51,25 +51,26 @@ impl DKNMessage { } /// Creates a new Message by signing the SHA256 of the payload, and prepending the signature. - pub fn new_signed( - payload: impl AsRef<[u8]> + Clone, - topic: &str, - signing_key: &SecretKey, - ) -> Self { - let signature_bytes = sign_bytes_recoverable(&sha256hash(payload.clone()), signing_key); + pub fn new_signed(data: impl AsRef<[u8]>, topic: &str, signing_key: &SecretKey) -> Self { + // sign the SHA256 hash of the data + let signature_bytes = sign_bytes_recoverable(&sha256hash(data.as_ref()), signing_key); - let mut signed_payload = Vec::new(); - signed_payload.extend_from_slice(signature_bytes.as_ref()); - signed_payload.extend_from_slice(payload.as_ref()); - Self::new(signed_payload, topic) + // prepend the signature to the data, to obtain `signature || data` bytes + let mut signed_data = Vec::new(); + signed_data.extend_from_slice(signature_bytes.as_ref()); + signed_data.extend_from_slice(data.as_ref()); + + // create the actual message with this signed data + Self::new(signed_data, topic) } /// Decodes the base64 payload into bytes. + #[inline(always)] pub fn decode_payload(&self) -> Result, base64::DecodeError> { BASE64_STANDARD.decode(&self.payload) } - /// Decodes and parses the payload into JSON. + /// Decodes and parses the base64 payload into JSON for the provided type `T`. pub fn parse_payload Deserialize<'a>>(&self, signed: bool) -> Result { let payload = self.decode_payload()?; @@ -80,28 +81,30 @@ impl DKNMessage { &payload[..] }; - let parsed: T = serde_json::from_slice(body)?; + let parsed = serde_json::from_slice::(body)?; Ok(parsed) } /// Checks if the payload is signed by the given public key. pub fn is_signed(&self, public_key: &PublicKey) -> Result { // decode base64 payload - let payload = self.decode_payload()?; - - // parse signature (64 bytes = 32 (x coord) + 32 (y coord)) - // skip the recovery id (1 byte) - let (signature_hex, body) = ( - &payload[..SIGNATURE_SIZE_HEX - 2], - &payload[SIGNATURE_SIZE_HEX..], - ); - let signature_bytes = hex::decode(signature_hex).expect("could not decode"); - let signature = libsecp256k1::Signature::parse_standard_slice(&signature_bytes) - .expect("could not parse"); - - // verify signature - let digest = libsecp256k1::Message::parse(&sha256hash(body)); - Ok(libsecp256k1::verify(&digest, &signature, public_key)) + let data = self.decode_payload()?; + + // parse signature from the following bytes: + // 32 + 32 + 1 + ... + // ( x || y || rec_id || data + let (signature_hex_bytes, body) = + (&data[..SIGNATURE_SIZE_HEX - 2], &data[SIGNATURE_SIZE_HEX..]); + let signature_bytes = + hex::decode(signature_hex_bytes).wrap_err("Could not decode signature hex")?; + + // now obtain the signature itself + let signature = Signature::parse_standard_slice(&signature_bytes) + .wrap_err("Could not parse signature bytes")?; + + // verify signature w.r.t the body and the given public key + let digest = Message::parse(&sha256hash(body)); + Ok(verify(&digest, &signature, public_key)) } } @@ -131,12 +134,7 @@ impl TryFrom for DKNMessage { #[cfg(test)] mod tests { use super::*; - use crate::payloads::TaskResponsePayload; - use crate::{utils::crypto::sha256hash, DriaComputeNodeConfig}; - use ecies::decrypt; - use libsecp256k1::{verify, Message, PublicKey, RecoveryId, SecretKey, Signature}; use rand::thread_rng; - use serde_json::json; #[derive(Serialize, Deserialize, PartialEq, Debug)] struct TestStruct { @@ -154,6 +152,7 @@ mod tests { const TOPIC: &str = "test-topic"; #[test] + #[ignore = "run manually"] fn test_display_message() { let message = DKNMessage::new(b"hello world", TOPIC); println!("{}", message); @@ -163,8 +162,8 @@ mod tests { fn test_unsigned_message() { // create payload & message let body = TestStruct::default(); - let payload = serde_json::to_vec(&json!(body)).expect("Should serialize"); - let message = DKNMessage::new(payload, TOPIC); + let data = serde_json::to_vec(&body).expect("Should serialize"); + let message = DKNMessage::new(data, TOPIC); // decode message let message_body = message.decode_payload().expect("Should decode"); @@ -210,61 +209,4 @@ mod tests { let parsed_body = message.parse_payload(true).expect("Should decode"); assert_eq!(body, parsed_body); } - - #[test] - fn test_payload_generation_verification() { - const TASK_SECRET_KEY_HEX: &[u8; 32] = b"aaaabbbbccccddddddddccccbbbbaaaa"; - const TASK_ID: &str = "12345678abcdef"; - const RESULT: &[u8; 28] = b"this is some result you know"; - - let config = DriaComputeNodeConfig::default(); - let task_secret_key = - SecretKey::parse(TASK_SECRET_KEY_HEX).expect("Should parse secret key"); - let task_public_key = PublicKey::from_secret_key(&task_secret_key); - - // create payload - let payload = TaskResponsePayload::new( - RESULT, - TASK_ID, - &task_public_key.serialize(), - &config.secret_key, - ) - .expect("Should create payload"); - - // decrypt result - let result = decrypt( - &task_secret_key.serialize(), - hex::decode(payload.ciphertext) - .expect("Should decode") - .as_slice(), - ) - .expect("Could not decrypt"); - assert_eq!(result, RESULT, "Result mismatch"); - - // verify signature - let rsv = hex::decode(payload.signature).expect("Should decode"); - let mut signature_bytes = [0u8; 64]; - signature_bytes.copy_from_slice(&rsv[0..64]); - let recid_bytes: [u8; 1] = [rsv[64]]; - let signature = - Signature::parse_standard(&signature_bytes).expect("Should parse signature"); - let recid = RecoveryId::parse(recid_bytes[0]).expect("Should parse recovery id"); - - let mut preimage = vec![]; - preimage.extend_from_slice(TASK_ID.as_bytes()); - preimage.extend_from_slice(&result); - let message = Message::parse(&sha256hash(preimage)); - assert!( - verify(&message, &signature, &config.public_key), - "Could not verify" - ); - - // recover verifying key (public key) from signature - let recovered_public_key = - libsecp256k1::recover(&message, &signature, &recid).expect("Could not recover"); - assert_eq!( - config.public_key, recovered_public_key, - "Public key mismatch" - ); - } } From 26540661a3371df80489fbb33d52661d941444f0 Mon Sep 17 00:00:00 2001 From: erhant Date: Wed, 2 Oct 2024 20:30:08 +0300 Subject: [PATCH 15/15] better msg id --- src/p2p/behaviour.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/p2p/behaviour.rs b/src/p2p/behaviour.rs index 5263d18..b35127e 100644 --- a/src/p2p/behaviour.rs +++ b/src/p2p/behaviour.rs @@ -121,9 +121,11 @@ fn create_gossipsub_behavior(author: PeerId) -> gossipsub::Behaviour { // message id's are simply hashes of the message data let message_id_fn = |message: &Message| { + // uses siphash by default let mut hasher = hash_map::DefaultHasher::new(); message.data.hash(&mut hasher); - MessageId::from(hasher.finish().to_string()) + let digest = hasher.finish(); + MessageId::from(digest.to_be_bytes()) }; // TODO: add data transform here later