This commit is contained in:
Mark Sinclair
2025-07-31 20:09:38 +01:00
parent 33339c085d
commit 18f7ba92bb
13 changed files with 409 additions and 21 deletions
Generated
+177 -11
View File
@@ -1447,7 +1447,7 @@ checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e"
dependencies = [
"prost 0.11.9",
"prost-types",
"tonic",
"tonic 0.9.2",
"tracing-core",
]
@@ -1469,7 +1469,7 @@ dependencies = [
"thread_local",
"tokio",
"tokio-stream",
"tonic",
"tonic 0.9.2",
"tracing",
"tracing-core",
"tracing-subscriber",
@@ -3580,6 +3580,7 @@ dependencies = [
"bytes",
"futures-channel",
"futures-util",
"h2 0.4.11",
"http 1.3.1",
"http-body 1.0.1",
"httparse",
@@ -3634,6 +3635,19 @@ dependencies = [
"tokio-io-timeout",
]
[[package]]
name = "hyper-timeout"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
dependencies = [
"hyper 1.6.0",
"hyper-util",
"pin-project-lite",
"tokio",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.15"
@@ -5157,13 +5171,13 @@ dependencies = [
"clap_complete_fig",
"const-str",
"log",
"opentelemetry",
"opentelemetry 0.19.0",
"opentelemetry-jaeger",
"schemars 0.8.22",
"serde",
"serde_json",
"tracing",
"tracing-opentelemetry",
"tracing-opentelemetry 0.19.0",
"tracing-subscriber",
"tracing-tree",
"utoipa",
@@ -7060,6 +7074,11 @@ dependencies = [
"nym-task 0.1.0",
"nym-topology 0.1.0",
"nym-validator-client 0.1.0",
"opentelemetry 0.30.0",
"opentelemetry-otlp",
"opentelemetry-semantic-conventions 0.30.0",
"opentelemetry-stdout",
"opentelemetry_sdk 0.30.0",
"parking_lot",
"rand 0.8.5",
"reqwest 0.12.22",
@@ -7072,7 +7091,10 @@ dependencies = [
"tokio-stream",
"tokio-util",
"toml 0.8.23",
"tonic 0.13.1",
"tracing",
"tracing-core",
"tracing-opentelemetry 0.31.0",
"tracing-subscriber",
"url",
"uuid",
@@ -8239,7 +8261,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f4b8347cc26099d3aeee044065ecc3ae11469796b4d65d065a23a584ed92a6f"
dependencies = [
"opentelemetry_api",
"opentelemetry_sdk",
"opentelemetry_sdk 0.19.0",
]
[[package]]
name = "opentelemetry"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aaf416e4cb72756655126f7dd7bb0af49c674f4c1b9903e80c009e0c37e552e6"
dependencies = [
"futures-core",
"futures-sink",
"js-sys",
"pin-project-lite",
"thiserror 2.0.12",
"tracing",
]
[[package]]
@@ -8255,6 +8291,19 @@ dependencies = [
"opentelemetry_api",
]
[[package]]
name = "opentelemetry-http"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f6639e842a97dbea8886e3439710ae463120091e2e064518ba8e716e6ac36d"
dependencies = [
"async-trait",
"bytes",
"http 1.3.1",
"opentelemetry 0.30.0",
"reqwest 0.12.22",
]
[[package]]
name = "opentelemetry-jaeger"
version = "0.18.0"
@@ -8267,21 +8316,69 @@ dependencies = [
"http 0.2.12",
"isahc",
"once_cell",
"opentelemetry",
"opentelemetry-http",
"opentelemetry-semantic-conventions",
"opentelemetry 0.19.0",
"opentelemetry-http 0.8.0",
"opentelemetry-semantic-conventions 0.11.0",
"thiserror 1.0.69",
"thrift",
"tokio",
]
[[package]]
name = "opentelemetry-otlp"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbee664a43e07615731afc539ca60c6d9f1a9425e25ca09c57bc36c87c55852b"
dependencies = [
"http 1.3.1",
"opentelemetry 0.30.0",
"opentelemetry-http 0.30.0",
"opentelemetry-proto",
"opentelemetry_sdk 0.30.0",
"prost 0.13.5",
"reqwest 0.12.22",
"thiserror 2.0.12",
"tokio",
"tonic 0.13.1",
"tracing",
]
[[package]]
name = "opentelemetry-proto"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e046fd7660710fe5a05e8748e70d9058dc15c94ba914e7c4faa7c728f0e8ddc"
dependencies = [
"opentelemetry 0.30.0",
"opentelemetry_sdk 0.30.0",
"prost 0.13.5",
"tonic 0.13.1",
]
[[package]]
name = "opentelemetry-semantic-conventions"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24e33428e6bf08c6f7fcea4ddb8e358fab0fe48ab877a87c70c6ebe20f673ce5"
dependencies = [
"opentelemetry",
"opentelemetry 0.19.0",
]
[[package]]
name = "opentelemetry-semantic-conventions"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83d059a296a47436748557a353c5e6c5705b9470ef6c95cfc52c21a8814ddac2"
[[package]]
name = "opentelemetry-stdout"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "447191061af41c3943e082ea359ab8b64ff27d6d34d30d327df309ddef1eef6f"
dependencies = [
"chrono",
"opentelemetry 0.30.0",
"opentelemetry_sdk 0.30.0",
]
[[package]]
@@ -8322,6 +8419,22 @@ dependencies = [
"tokio-stream",
]
[[package]]
name = "opentelemetry_sdk"
version = "0.30.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11f644aa9e5e31d11896e024305d7e3c98a88884d9f8919dbf37a9991bc47a4b"
dependencies = [
"futures-channel",
"futures-executor",
"futures-util",
"opentelemetry 0.30.0",
"percent-encoding",
"rand 0.9.2",
"serde_json",
"thiserror 2.0.12",
]
[[package]]
name = "option-ext"
version = "0.2.0"
@@ -9254,6 +9367,7 @@ dependencies = [
"async-compression",
"base64 0.22.1",
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"http 1.3.1",
@@ -11337,7 +11451,7 @@ dependencies = [
"http 0.2.12",
"http-body 0.4.6",
"hyper 0.14.32",
"hyper-timeout",
"hyper-timeout 0.4.1",
"percent-encoding",
"pin-project",
"prost 0.11.9",
@@ -11349,6 +11463,37 @@ dependencies = [
"tracing",
]
[[package]]
name = "tonic"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e581ba15a835f4d9ea06c55ab1bd4dce26fc53752c69a04aac00703bfb49ba9"
dependencies = [
"async-trait",
"axum 0.8.4",
"base64 0.22.1",
"bytes",
"h2 0.4.11",
"http 1.3.1",
"http-body 1.0.1",
"http-body-util",
"hyper 1.6.0",
"hyper-timeout 0.5.2",
"hyper-util",
"percent-encoding",
"pin-project",
"prost 0.13.5",
"socket2",
"tokio",
"tokio-rustls 0.26.2",
"tokio-stream",
"tower 0.5.2",
"tower-layer",
"tower-service",
"tracing",
"webpki-roots 0.26.11",
]
[[package]]
name = "tower"
version = "0.4.13"
@@ -11377,9 +11522,12 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
"futures-core",
"futures-util",
"indexmap 2.10.0",
"pin-project-lite",
"slab",
"sync_wrapper 1.0.2",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
@@ -11526,13 +11674,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00a39dcf9bfc1742fa4d6215253b33a6e474be78275884c216fc2a06267b3600"
dependencies = [
"once_cell",
"opentelemetry",
"opentelemetry 0.19.0",
"tracing",
"tracing-core",
"tracing-log 0.1.4",
"tracing-subscriber",
]
[[package]]
name = "tracing-opentelemetry"
version = "0.31.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddcf5959f39507d0d04d6413119c04f33b623f4f951ebcbdddddfad2d0623a9c"
dependencies = [
"js-sys",
"once_cell",
"opentelemetry 0.30.0",
"opentelemetry_sdk 0.30.0",
"smallvec",
"tracing",
"tracing-core",
"tracing-log 0.2.0",
"tracing-subscriber",
"web-time",
]
[[package]]
name = "tracing-subscriber"
version = "0.3.19"
@@ -65,7 +65,7 @@ pub trait MixnetClientStorage {
fn gateway_details_store(&self) -> &Self::GatewaysDetailsStore;
}
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct Ephemeral {
key_store: InMemEphemeralKeys,
reply_store: reply_storage::Empty,
@@ -22,7 +22,7 @@ mod test;
// use the old key after new one was issued.
// Remember that Arc<T> has Deref implementation for T
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct ClientKeys {
/// identity key associated with the client instance.
identity_keypair: Arc<ed25519::KeyPair>,
@@ -196,7 +196,7 @@ impl KeyStore for OnDiskKeys {
}
}
#[derive(Clone)]
#[derive(Clone, Debug)]
pub struct InMemEphemeralKeys {
keys: Arc<Mutex<ClientKeys>>,
}
+7 -1
View File
@@ -53,7 +53,7 @@ pub enum Ed25519RecoveryError {
}
/// Keypair for usage in ed25519 EdDSA.
#[derive(Debug, Zeroize, ZeroizeOnDrop)]
#[derive(Zeroize, ZeroizeOnDrop)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct KeyPair {
private_key: PrivateKey,
@@ -66,6 +66,12 @@ pub struct KeyPair {
index: u32,
}
impl Debug for KeyPair {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.public_key.to_base58_string(), f)
}
}
/// All keys will always have an index field populated this is to prevent anyone from figuring out if
/// the keys are derived or random, and alter their behaviour based on that.
impl KeyPair {
@@ -55,6 +55,12 @@ pub struct KeyPair {
pub(crate) public_key: PublicKey,
}
impl Debug for KeyPair {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
Display::fmt(&self.public_key.to_base58_string(), f)
}
}
impl KeyPair {
#[cfg(feature = "rand")]
pub fn new<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
@@ -227,6 +233,12 @@ impl AsRef<[u8]> for PublicKey {
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct PrivateKey(x25519_dalek::StaticSecret);
impl Debug for PrivateKey {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.to_base58_string())
}
}
impl Display for PrivateKey {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.to_base58_string())
+1 -1
View File
@@ -12,7 +12,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop};
use serde::{Deserialize, Serialize};
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Zeroize, ZeroizeOnDrop)]
#[derive(Debug, Zeroize, ZeroizeOnDrop)]
pub struct AckKey(CipherKey<AckEncryptionAlgorithm>);
#[derive(Debug)]
+16 -2
View File
@@ -70,10 +70,18 @@ tokio-util.workspace = true
uuid = { workspace = true, features = ["v4", "serde"] }
bincode = { workspace = true }
serde = { workspace = true, features = ["derive"] }
tracing.workspace = true
tracing-subscriber = { workspace = true, features = ["env-filter"] }
#tracing.workspace = true
#tracing-subscriber = { workspace = true, features = ["env-filter", "registry", "std"] }
dirs.workspace = true
opentelemetry = { version = "0.30.0", default-features = true }
opentelemetry_sdk = { version = "0.30.0", default-features = true }
tracing = { version = "0.1.35", default-features = false, features = ["std"] }
tracing-subscriber = { version = "0.3.0", default-features = false, features = ["registry", "std"] }
tracing-core = "0.1.28"
tonic = { version = "0.13.1", features = ["tls-webpki-roots"] }
tracing-opentelemetry = "0.31.0"
[dev-dependencies]
anyhow = { workspace = true }
dotenvy = { workspace = true }
@@ -83,6 +91,11 @@ tokio = { workspace = true, features = ["full"] }
time = { workspace = true }
nym-bin-common = { path = "../../../common/bin-common", features = ["basic_tracing"] }
opentelemetry-semantic-conventions = { version = "0.30.0", features = ["semconv_experimental"] }
opentelemetry-otlp = { version = "0.30.0", features = ["metrics", "grpc-tonic", "tls",
"tls-webpki-roots", ] }
opentelemetry-stdout = { version = "0.30.0", features = ["trace", "metrics"] }
# extra dependencies for libp2p examples
#libp2p = { git = "https://github.com/ChainSafe/rust-libp2p.git", rev = "e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6", features = [ "identify", "macros", "ping", "tokio", "tcp", "dns", "websocket", "noise", "mplex", "yamux", "gossipsub" ]}
tokio-stream = { workspace = true }
@@ -92,3 +105,4 @@ hex = { workspace = true }
[features]
libp2p-vanilla = []
+145 -2
View File
@@ -1,3 +1,4 @@
use dotenvy::dotenv;
use nym_sdk::mixnet::{
AnonymousSenderTag, MixnetClientBuilder, MixnetMessageSender, ReconstructedMessage,
StoragePaths,
@@ -5,9 +6,149 @@ use nym_sdk::mixnet::{
use std::path::PathBuf;
use tempfile::TempDir;
use opentelemetry::trace::TracerProvider;
use opentelemetry::{global, KeyValue};
use opentelemetry_otlp::tonic_types::metadata::MetadataMap;
use opentelemetry_otlp::tonic_types::transport::ClientTlsConfig;
use opentelemetry_otlp::{WithExportConfig, WithTonicConfig};
use opentelemetry_sdk::metrics::{MeterProviderBuilder, PeriodicReader, SdkMeterProvider};
use opentelemetry_sdk::trace::{RandomIdGenerator, SdkTracerProvider};
use opentelemetry_sdk::{trace::Sampler, Resource};
use opentelemetry_semantic_conventions::{
attribute::{DEPLOYMENT_ENVIRONMENT_NAME, SERVICE_VERSION},
SCHEMA_URL,
};
use tracing_core::Level;
use tracing_opentelemetry::{MetricsLayer, OpenTelemetryLayer};
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};
fn resource() -> Resource {
Resource::builder()
.with_service_name("sdk-example-surb-reply")
.with_schema_url(
[
KeyValue::new(SERVICE_VERSION, env!("CARGO_PKG_VERSION")),
KeyValue::new(DEPLOYMENT_ENVIRONMENT_NAME, "develop"),
],
SCHEMA_URL,
)
.build()
}
fn init_tracer_provider(metadata: MetadataMap) -> anyhow::Result<SdkTracerProvider> {
let endpoint = std::env::var("SIGNOZ_ENDPOINT").expect("SIGNOZ_ENDPOINT not set");
println!("SIGNOZ_ENDPOINT = {}", endpoint);
// Configure OTLP exporter with metadata
let mut exporter_builder = opentelemetry_otlp::SpanExporter::builder()
.with_tonic()
.with_metadata(metadata)
.with_endpoint(&endpoint);
// Try with TLS - seems to work
if endpoint.starts_with("https://") {
exporter_builder =
exporter_builder.with_tls_config(ClientTlsConfig::new().with_enabled_roots());
}
let exporter = exporter_builder.build()?;
let tracer = SdkTracerProvider::builder()
// Customize sampling strategy
.with_sampler(Sampler::ParentBased(Box::new(Sampler::TraceIdRatioBased(
1.0,
))))
// If export trace to AWS X-Ray, you can use XrayIdGenerator
.with_id_generator(RandomIdGenerator::default())
.with_resource(resource())
.with_batch_exporter(exporter)
.build();
Ok(tracer)
}
fn init_meter_provider() -> SdkMeterProvider {
let exporter = opentelemetry_otlp::MetricExporter::builder()
.with_tonic()
.with_temporality(opentelemetry_sdk::metrics::Temporality::default())
.build()
.unwrap();
let reader = PeriodicReader::builder(exporter)
.with_interval(std::time::Duration::from_secs(30))
.build();
// For debugging in development
let stdout_reader =
PeriodicReader::builder(opentelemetry_stdout::MetricExporter::default()).build();
let meter_provider = MeterProviderBuilder::default()
.with_resource(resource())
.with_reader(reader)
.with_reader(stdout_reader)
.build();
global::set_meter_provider(meter_provider.clone());
meter_provider
}
fn init_tracing_subscriber(metadata: MetadataMap) -> OtelGuard {
let tracer_provider = init_tracer_provider(metadata).expect("Initializing tracer failed");
let meter_provider = init_meter_provider();
let tracer = tracer_provider.tracer("tracing-otel-subscriber");
tracing_subscriber::registry()
// The global level filter prevents the exporter network stack
// from reentering the globally installed OpenTelemetryLayer with
// its own spans while exporting, as the libraries should not use
// tracing levels below DEBUG. If the OpenTelemetry layer needs to
// trace spans and events with higher verbosity levels, consider using
// per-layer filtering to target the telemetry layer specifically,
// e.g. by target matching.
.with(tracing_subscriber::filter::LevelFilter::from_level(
Level::DEBUG,
))
.with(tracing_subscriber::fmt::layer())
.with(MetricsLayer::new(meter_provider.clone()))
.with(OpenTelemetryLayer::new(tracer))
.init();
OtelGuard {
tracer_provider,
meter_provider,
}
}
struct OtelGuard {
tracer_provider: SdkTracerProvider,
meter_provider: SdkMeterProvider,
}
impl Drop for OtelGuard {
fn drop(&mut self) {
if let Err(err) = self.tracer_provider.shutdown() {
eprintln!("{err:?}");
}
if let Err(err) = self.meter_provider.shutdown() {
eprintln!("{err:?}");
}
}
}
#[tokio::main]
async fn main() {
nym_bin_common::logging::setup_tracing_logger();
async fn main() -> anyhow::Result<()> {
// nym_bin_common::logging::setup_tracing_logger();
dotenv().ok();
let key = std::env::var("SIGNOZ_INGESTION_KEY").expect("SIGNOZ_INGESTION_KEY not set");
println!("SIGNOZ_INGESTION_KEY = {}", key);
let mut metadata = MetadataMap::new();
metadata.insert("signoz-ingestion-key", key.parse()?);
let _guard = init_tracing_subscriber(metadata);
// Specify some config options
let config_dir: PathBuf = TempDir::new().unwrap().path().to_path_buf();
@@ -69,4 +210,6 @@ async fn main() {
client
.on_messages(|msg| println!("\nReceived: {}", String::from_utf8_lossy(&msg.message)))
.await;
Ok(())
}
+19
View File
@@ -396,6 +396,21 @@ where
derivation_material: Option<DerivationMaterial>,
}
impl<S> std::fmt::Debug for DisconnectedMixnetClient<S>
where
S: MixnetClientStorage + Clone + 'static,
S::ReplyStore: Send + Sync,
S::GatewaysDetailsStore: Sync,
<S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send,
<S::CredentialStore as CredentialStorage>::StorageError: Send + Sync,
<S::KeyStore as KeyStore>::StorageError: Send + Sync,
<S::GatewaysDetailsStore as GatewaysDetailsStore>::StorageError: Send + Sync,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("DisconnectedMixnetClient").finish()
}
}
impl<S> DisconnectedMixnetClient<S>
where
S: MixnetClientStorage + Clone + 'static,
@@ -474,6 +489,7 @@ where
.collect()
}
#[tracing::instrument]
async fn setup_client_keys(&self) -> Result<()> {
let mut rng = OsRng;
let key_store = self.storage.key_store();
@@ -571,6 +587,7 @@ where
///
/// This function will return an error if you try to re-register when in an already registered
/// state.
#[tracing::instrument]
pub async fn setup_gateway(&mut self) -> Result<()> {
if !matches!(self.state, BuilderState::New) {
return Err(Error::ReregisteringGatewayNotSupported);
@@ -661,6 +678,7 @@ where
)
}
#[tracing::instrument]
async fn connect_to_mixnet_common(mut self) -> Result<(BaseClient, Recipient)> {
self.setup_client_keys().await?;
self.setup_gateway().await?;
@@ -811,6 +829,7 @@ where
/// let client = client.connect_to_mixnet().await.unwrap();
/// }
/// ```
#[tracing::instrument]
pub async fn connect_to_mixnet(self) -> Result<MixnetClient> {
if self.socks5_config.is_some() {
return Err(Error::Socks5Config { set: true });
+1 -1
View File
@@ -6,7 +6,7 @@ use url::Url;
const DEFAULT_SDK_CLIENT_ID: &str = "_default-nym-sdk-client";
/// Config struct for [`crate::mixnet::MixnetClient`]
#[derive(Default)]
#[derive(Default, Debug)]
pub struct Config {
/// If the user has explicitly specified a gateway.
pub user_chosen_gateway: Option<String>,
@@ -22,6 +22,8 @@ use nym_task::{
TaskHandle,
};
use nym_topology::{NymRouteProvider, NymTopology};
use std::fmt;
use std::fmt::{Debug, Formatter};
use std::pin::Pin;
use std::sync::Arc;
use std::task::{Context, Poll};
@@ -64,6 +66,14 @@ pub struct MixnetClient {
pub(crate) remember_me: RememberMe,
}
impl Debug for MixnetClient {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("MixnetClient")
.field("address", &self.nym_address)
.finish()
}
}
impl MixnetClient {
#[allow(clippy::too_many_arguments)]
pub(crate) fn new(
@@ -194,7 +204,15 @@ impl MixnetClient {
}
/// Wait for messages from the mixnet
#[tracing::instrument]
pub async fn wait_for_messages(&mut self) -> Option<Vec<ReconstructedMessage>> {
let span = tracing::info_span!(
"wait_for_messages",
"address = {}",
self.nym_address.to_string()
);
let _enter = span.enter();
self.reconstructed_receiver.next().await
}
+10
View File
@@ -69,6 +69,9 @@ pub trait MixnetMessageSender {
where
M: AsRef<[u8]> + Send,
{
let span = tracing::info_span!("send_message", "address = {}", address.to_string());
let _enter = span.enter();
let lane = TransmissionLane::General;
let input_msg = match surbs {
IncludedSurbs::Amount(surbs) => InputMessage::new_anonymous(
@@ -107,6 +110,13 @@ pub trait MixnetMessageSender {
where
M: AsRef<[u8]> + Send,
{
let span = tracing::info_span!(
"send_reply",
"recipient_tag = {}",
recipient_tag.to_string()
);
let _enter = span.enter();
let lane = TransmissionLane::General;
let input_msg = InputMessage::new_reply(
recipient_tag,