From 34427c9df3e8c98482d6607f1e8091bc672849f6 Mon Sep 17 00:00:00 2001 From: Andrew Plaza Date: Wed, 4 Dec 2024 12:44:15 -0500 Subject: [PATCH] native logging for android and ios (#1372) --- .cargo/nextest.toml | 2 + .github/workflows/test-ffi-bindings.yml | 2 +- .github/workflows/test-workspace.yml | 4 +- Cargo.lock | 106 +++++++++++++++++++--- bindings_ffi/Cargo.toml | 10 ++- bindings_ffi/src/lib.rs | 3 +- bindings_ffi/src/logger.rs | 111 +++++++++++++++++------- bindings_ffi/src/mls.rs | 35 ++------ bindings_ffi/src/xmtpv3.udl | 4 - bindings_ffi/tests/test_android.kts | 9 +- dev/release-kotlin | 1 + flake.nix | 37 +++++--- rust-toolchain | 4 - xmtp_proto/Cargo.toml | 2 +- 14 files changed, 225 insertions(+), 105 deletions(-) create mode 100644 .cargo/nextest.toml diff --git a/.cargo/nextest.toml b/.cargo/nextest.toml new file mode 100644 index 000000000..07216b1ff --- /dev/null +++ b/.cargo/nextest.toml @@ -0,0 +1,2 @@ +[profile.default] +retries = 3 diff --git a/.github/workflows/test-ffi-bindings.yml b/.github/workflows/test-ffi-bindings.yml index 43b4cc61e..d23ca46ef 100644 --- a/.github/workflows/test-ffi-bindings.yml +++ b/.github/workflows/test-ffi-bindings.yml @@ -50,4 +50,4 @@ jobs: - name: Run cargo nextest on FFI bindings run: | export CLASSPATH="${{ env.CLASSPATH }}" - cargo nextest run --manifest-path bindings_ffi/Cargo.toml --test-threads 2 + cargo nextest --config-file ".cargo/nextest.toml" run --manifest-path bindings_ffi/Cargo.toml --test-threads 2 diff --git a/.github/workflows/test-workspace.yml b/.github/workflows/test-workspace.yml index e565fe64c..a3fc82477 100644 --- a/.github/workflows/test-workspace.yml +++ b/.github/workflows/test-workspace.yml @@ -43,6 +43,6 @@ jobs: - name: Install nextest uses: taiki-e/install-action@nextest - name: build tests - run: cargo nextest run --no-run --workspace --tests --exclude xmtpv3 --exclude bindings_node --exclude bindings_wasm + run: cargo nextest --config-file ".cargo/nextest.toml" run --no-run --workspace --tests --exclude xmtpv3 --exclude bindings_node --exclude bindings_wasm - name: cargo test - run: cargo nextest run --workspace --test-threads 2 --exclude xmtpv3 --exclude bindings_node --exclude bindings_wasm + run: cargo nextest --config-file ".cargo/nextest.toml" run --workspace --test-threads 2 --exclude xmtpv3 --exclude bindings_node --exclude bindings_wasm diff --git a/Cargo.lock b/Cargo.lock index b19d63c22..084c38557 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -427,6 +427,26 @@ dependencies = [ "serde", ] +[[package]] +name = "bindgen" +version = "0.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f" +dependencies = [ + "bitflags 2.6.0", + "cexpr", + "clang-sys", + "itertools 0.13.0", + "log", + "prettyplease", + "proc-macro2", + "quote", + "regex", + "rustc-hash", + "shlex", + "syn 2.0.87", +] + [[package]] name = "bindings_node" version = "0.1.0" @@ -649,6 +669,15 @@ dependencies = [ "shlex", ] +[[package]] +name = "cexpr" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766" +dependencies = [ + "nom", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -731,6 +760,17 @@ dependencies = [ "zeroize", ] +[[package]] +name = "clang-sys" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4" +dependencies = [ + "glob", + "libc", + "libloading", +] + [[package]] name = "clap" version = "4.5.21" @@ -3040,6 +3080,12 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + [[package]] name = "jobserver" version = "0.1.32" @@ -3617,6 +3663,15 @@ dependencies = [ "tempfile", ] +[[package]] +name = "ndk-sys" +version = "0.5.0+25.2.9519653" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c196769dd60fd4f363e11d948139556a344e79d451aeb2fa2fd040738ef7691" +dependencies = [ + "jni-sys", +] + [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -3949,6 +4004,20 @@ dependencies = [ "primeorder", ] +[[package]] +name = "paranoid-android" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "101795d63d371b43e38d6e7254677657be82f17022f7f7893c268f33ac0caadc" +dependencies = [ + "lazy_static", + "ndk-sys", + "sharded-slab", + "smallvec", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "parity-scale-codec" version = "3.7.0" @@ -4833,6 +4902,12 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + [[package]] name = "rustc-hex" version = "2.1.0" @@ -5678,16 +5753,6 @@ dependencies = [ "syn 2.0.87", ] -[[package]] -name = "thread-id" -version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99043e46c5a15af379c06add30d9c93a6c0e8849de00d244c4a2c417da128d80" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - [[package]] name = "thread_local" version = "1.1.8" @@ -6133,6 +6198,21 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "tracing-oslog" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528bdd1f0e27b5dd9a4ededf154e824b0532731e4af73bb531de46276e0aab1e" +dependencies = [ + "bindgen", + "cc", + "cfg-if", + "once_cell", + "parking_lot 0.12.3", + "tracing-core", + "tracing-subscriber", +] + [[package]] name = "tracing-serde" version = "0.1.3" @@ -7380,12 +7460,14 @@ version = "0.1.0" dependencies = [ "ethers", "futures", - "log", + "paranoid-android", "parking_lot 0.12.3", "rand", "thiserror 2.0.3", - "thread-id", "tokio", + "tracing", + "tracing-oslog", + "tracing-subscriber", "uniffi", "uuid 1.11.0", "xmtp_api_grpc", diff --git a/bindings_ffi/Cargo.toml b/bindings_ffi/Cargo.toml index 00ba44467..938ab78b8 100644 --- a/bindings_ffi/Cargo.toml +++ b/bindings_ffi/Cargo.toml @@ -9,10 +9,10 @@ crate-type = ["lib", "cdylib", "staticlib"] [dependencies] futures.workspace = true -log = { version = "0.4", features = ["std"] } +tracing.workspace = true +tracing-subscriber = { workspace = true, features = ["registry", "env-filter", "fmt", "json"] } parking_lot.workspace = true thiserror.workspace = true -thread-id = "5.0.0" tokio = { workspace = true, features = ["macros"] } uniffi = { version = "0.28.0", default-features = false, features = ["tokio"] } xmtp_api_grpc = { path = "../xmtp_api_grpc" } @@ -23,6 +23,12 @@ xmtp_proto = { path = "../xmtp_proto", features = ["proto_full"] } xmtp_user_preferences = { path = "../xmtp_user_preferences" } xmtp_v2 = { path = "../xmtp_v2" } +[target.'cfg(target_os = "android")'.dependencies] +paranoid-android = "0.2" + +[target.'cfg(target_os = "ios")'.dependencies] +tracing-oslog = "0.2" + [build-dependencies] uniffi = { version = "0.28.0", features = ["build"] } diff --git a/bindings_ffi/src/lib.rs b/bindings_ffi/src/lib.rs index e60e1fe34..670ec176e 100755 --- a/bindings_ffi/src/lib.rs +++ b/bindings_ffi/src/lib.rs @@ -7,10 +7,11 @@ pub mod v2; pub use crate::inbox_owner::SigningError; use inbox_owner::FfiInboxOwner; -use logger::FfiLogger; pub use mls::*; use std::error::Error; +extern crate tracing as log; + pub use ffi::*; #[allow(clippy::all)] mod ffi { diff --git a/bindings_ffi/src/logger.rs b/bindings_ffi/src/logger.rs index 5e9d0c623..c4b00e349 100644 --- a/bindings_ffi/src/logger.rs +++ b/bindings_ffi/src/logger.rs @@ -1,43 +1,96 @@ -use log::{LevelFilter, Metadata, Record}; +use log::Subscriber; use std::sync::Once; +use tracing_subscriber::{ + layer::SubscriberExt, registry::LookupSpan, util::SubscriberInitExt, Layer, +}; -pub trait FfiLogger: Send + Sync { - fn log(&self, level: u32, level_label: String, message: String); +#[cfg(target_os = "android")] +pub use android::*; +#[cfg(target_os = "android")] +mod android { + use super::*; + pub fn native_layer() -> impl Layer + where + S: Subscriber + for<'a> LookupSpan<'a>, + { + paranoid_android::layer(env!("CARGO_PKG_NAME")).with_thread_names(true) + } } -struct RustLogger { - logger: parking_lot::Mutex>, +#[cfg(target_os = "ios")] +pub use ios::*; +#[cfg(target_os = "ios")] +mod ios { + use super::*; + // use tracing_subscriber::Layer; + pub fn native_layer() -> impl Layer + where + S: Subscriber + for<'a> LookupSpan<'a>, + { + use tracing_oslog::OsLogger; + let subsystem = format!("org.xmtp.{}", env!("CARGO_PKG_NAME")); + OsLogger::new(subsystem, "default") + } } -impl log::Log for RustLogger { - fn enabled(&self, _metadata: &Metadata) -> bool { - true - } +#[cfg(not(any(target_os = "ios", target_os = "android")))] +pub use other::*; +#[cfg(not(any(target_os = "ios", target_os = "android")))] +mod other { + use super::*; - fn log(&self, record: &Record) { - if self.enabled(record.metadata()) { - // TODO handle errors - self.logger.lock().log( - record.level() as u32, - record.level().to_string(), - format!("[libxmtp][t:{}] {}", thread_id::get(), record.args()), - ); - } - } + pub fn native_layer() -> impl Layer + where + S: Subscriber + for<'a> LookupSpan<'a>, + { + use tracing_subscriber::{ + fmt::{self, format}, + EnvFilter, Layer, + }; + let structured = std::env::var("STRUCTURED"); + let is_structured = matches!(structured, Ok(s) if s == "true" || s == "1"); - fn flush(&self) {} + let filter = || { + EnvFilter::builder() + .with_default_directive(tracing::metadata::LevelFilter::INFO.into()) + .from_env_lossy() + }; + + vec![ + // structured JSON logger + is_structured + .then(|| { + tracing_subscriber::fmt::layer() + .json() + .flatten_event(true) + .with_level(true) + .with_filter(filter()) + }) + .boxed(), + // default logger + (!is_structured) + .then(|| { + fmt::layer() + .compact() + .fmt_fields({ + format::debug_fn(move |writer, field, value| { + if field.name() == "message" { + write!(writer, "{:?}", value)?; + } + Ok(()) + }) + }) + .with_filter(filter()) + }) + .boxed(), + ] + } } static LOGGER_INIT: Once = Once::new(); -pub fn init_logger(logger: Box) { - // TODO handle errors +pub fn init_logger() { LOGGER_INIT.call_once(|| { - let logger = RustLogger { - logger: parking_lot::Mutex::new(logger), - }; - log::set_boxed_logger(Box::new(logger)) - .map(|()| log::set_max_level(LevelFilter::Info)) - .expect("Failed to initialize logger"); - log::info!("Logger initialized"); + let native_layer = native_layer(); + tracing_subscriber::registry().with(native_layer).init() }); } diff --git a/bindings_ffi/src/mls.rs b/bindings_ffi/src/mls.rs index 93f534aea..e899374bf 100644 --- a/bindings_ffi/src/mls.rs +++ b/bindings_ffi/src/mls.rs @@ -1,6 +1,5 @@ pub use crate::inbox_owner::SigningError; use crate::logger::init_logger; -use crate::logger::FfiLogger; use crate::{FfiSubscribeError, GenericError}; use std::{collections::HashMap, convert::TryInto, sync::Arc}; use tokio::sync::Mutex; @@ -71,7 +70,6 @@ pub type RustXmtpClient = MlsClient; #[allow(clippy::too_many_arguments)] #[uniffi::export(async_runtime = "tokio")] pub async fn create_client( - logger: Box, host: String, is_secure: bool, db: Option, @@ -82,7 +80,7 @@ pub async fn create_client( legacy_signed_private_key_proto: Option>, history_sync_url: Option, ) -> Result, GenericError> { - init_logger(logger); + init_logger(); log::info!( "Creating API client for host: {}, isSecure: {}", host, @@ -142,7 +140,6 @@ pub async fn create_client( #[allow(unused)] #[uniffi::export(async_runtime = "tokio")] pub async fn get_inbox_id_for_address( - logger: Box, host: String, is_secure: bool, account_address: String, @@ -1798,11 +1795,11 @@ impl FfiGroupPermissions { mod tests { use super::{create_client, FfiConsentCallback, FfiMessage, FfiMessageCallback, FfiXmtpClient}; use crate::{ - get_inbox_id_for_address, inbox_owner::SigningError, logger::FfiLogger, FfiConsent, - FfiConsentEntityType, FfiConsentState, FfiConversation, FfiConversationCallback, - FfiConversationMessageKind, FfiCreateGroupOptions, FfiGroupPermissionsOptions, - FfiInboxOwner, FfiListConversationsOptions, FfiListMessagesOptions, FfiMetadataField, - FfiPermissionPolicy, FfiPermissionPolicySet, FfiPermissionUpdateType, FfiSubscribeError, + get_inbox_id_for_address, inbox_owner::SigningError, FfiConsent, FfiConsentEntityType, + FfiConsentState, FfiConversation, FfiConversationCallback, FfiConversationMessageKind, + FfiCreateGroupOptions, FfiGroupPermissionsOptions, FfiInboxOwner, + FfiListConversationsOptions, FfiListMessagesOptions, FfiMetadataField, FfiPermissionPolicy, + FfiPermissionPolicySet, FfiPermissionUpdateType, FfiSubscribeError, }; use ethers::utils::hex; use rand::distributions::{Alphanumeric, DistString}; @@ -1859,14 +1856,6 @@ mod tests { } } - pub struct MockLogger {} - - impl FfiLogger for MockLogger { - fn log(&self, _level: u32, level_label: String, message: String) { - println!("[{}]{}", level_label, message) - } - } - #[derive(Default)] struct RustStreamCallback { num_messages: AtomicU32, @@ -1988,7 +1977,6 @@ mod tests { let inbox_id = generate_inbox_id(&ffi_inbox_owner.get_address(), &nonce).unwrap(); let client = create_client( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(tmp_path()), @@ -2031,7 +2019,6 @@ mod tests { let real_inbox_id = client.inbox_id(); let from_network = get_inbox_id_for_address( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, client.account_address.clone(), @@ -2052,7 +2039,6 @@ mod tests { let inbox_id = generate_inbox_id(&account_address, &nonce).unwrap(); let client = create_client( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(tmp_path()), @@ -2078,7 +2064,6 @@ mod tests { let path = tmp_path(); let client_a = create_client( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path.clone()), @@ -2097,7 +2082,6 @@ mod tests { drop(client_a); let client_b = create_client( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path), @@ -2131,7 +2115,6 @@ mod tests { let key = static_enc_key().to_vec(); let client_a = create_client( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path.clone()), @@ -2151,7 +2134,6 @@ mod tests { other_key[31] = 1; let result_errored = create_client( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path), @@ -2204,7 +2186,6 @@ mod tests { let path = tmp_path(); let key = static_enc_key().to_vec(); let client = create_client( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path.clone()), @@ -2270,7 +2251,6 @@ mod tests { let path = tmp_path(); let key = static_enc_key().to_vec(); let client = create_client( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path.clone()), @@ -2358,7 +2338,6 @@ mod tests { let path = tmp_path(); let client = create_client( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path.clone()), @@ -2386,7 +2365,6 @@ mod tests { let path = tmp_path(); let client_amal = create_client( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path.clone()), @@ -2413,7 +2391,6 @@ mod tests { ); let client_bola = create_client( - Box::new(MockLogger {}), xmtp_api_grpc::LOCALHOST_ADDRESS.to_string(), false, Some(path.clone()), diff --git a/bindings_ffi/src/xmtpv3.udl b/bindings_ffi/src/xmtpv3.udl index fa7fef7a1..635ba512e 100644 --- a/bindings_ffi/src/xmtpv3.udl +++ b/bindings_ffi/src/xmtpv3.udl @@ -12,7 +12,3 @@ callback interface FfiInboxOwner { [Throws=SigningError] bytes sign(string text); }; - -callback interface FfiLogger { - void log(u32 level, string level_label, string message); -}; \ No newline at end of file diff --git a/bindings_ffi/tests/test_android.kts b/bindings_ffi/tests/test_android.kts index 21871d2db..fd787db1d 100644 --- a/bindings_ffi/tests/test_android.kts +++ b/bindings_ffi/tests/test_android.kts @@ -17,20 +17,15 @@ class Web3jInboxOwner(private val credentials: Credentials) : FfiInboxOwner { } } -class MockLogger : FfiLogger { - override fun log(level: UInt, levelLabel: String, message: String) {} -} - val privateKey: ByteArray = SecureRandom().generateSeed(32) val credentials: Credentials = Credentials.create(ECKeyPair.create(privateKey)) val inboxOwner = Web3jInboxOwner(credentials) -var logger = MockLogger() // TODO Tests sometimes hang and never complete // runBlocking { // val apiUrl: String = System.getenv("XMTP_API_URL") ?: "http://localhost:5556" // try { -// val client = uniffi.xmtpv3.createClient(logger, inboxOwner, apiUrl, false) +// val client = uniffi.xmtpv3.createClient(inboxOwner, apiUrl, false) // assert(client.walletAddress() != null) { // "Should be able to get wallet address" // } @@ -43,7 +38,7 @@ var logger = MockLogger() // runBlocking { // try { -// val client = uniffi.xmtpv3.createClient(logger, inboxOwner, "http://malformed:5556", false); +// val client = uniffi.xmtpv3.createClient(inboxOwner, "http://malformed:5556", false); // assert(false) { // "Should throw error with malformed network address" // } diff --git a/dev/release-kotlin b/dev/release-kotlin index 86c1ff670..74e507509 100755 --- a/dev/release-kotlin +++ b/dev/release-kotlin @@ -42,6 +42,7 @@ nix develop . --command cargo ndk -o bindings_ffi/jniLibs/ --manifest-path ./bin -t armv7-linux-androideabi \ -- build --release + for arch in arm64-v8a armeabi-v7a x86 x86_64; do mv "./bindings_ffi/jniLibs/$arch/$LIBRARY_NAME.so" "./bindings_ffi/jniLibs/$arch/$TARGET_NAME.so" done diff --git a/flake.nix b/flake.nix index 006af47ec..df8aaf766 100644 --- a/flake.nix +++ b/flake.nix @@ -41,12 +41,21 @@ includeNDK = true; }; - fenixPkgs = fenix.packages.${system}; + androidTargets = [ + "aarch64-linux-android" + "armv7-linux-androideabi" + "x86_64-linux-android" + "i686-linux-android" + ]; + # Pinned Rust Version - rust-toolchain = fenixPkgs.fromToolchainFile { - file = ./rust-toolchain; - sha256 = "sha256-yMuSb5eQPO/bHv+Bcf/US8LVMbf/G/0MSfiPwBhiPpk="; - }; + rust-toolchain = with fenix.packages.${system}; combine [ + stable.cargo + stable.rustc + (pkgs.lib.forEach + androidTargets + (target: targets."${target}".stable.rust-std)) + ]; # https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/android.section.md androidHome = "${androidComposition.androidsdk}/libexec/android-sdk"; @@ -66,7 +75,8 @@ # System Libraries sqlite openssl - ] ++ lib.optionals isDarwin [ # optional packages if on darwin, in order to check if build passes locally + ] ++ lib.optionals isDarwin [ + # optional packages if on darwin, in order to check if build passes locally libiconv frameworks.CoreServices frameworks.Carbon @@ -74,14 +84,15 @@ frameworks.AppKit darwin.cctools ]; - in { + in + { devShells.default = pkgs.mkShell { - OPENSSL_DIR = "${pkgs.openssl.dev}"; - ANDROID_HOME = androidHome; - ANDROID_SDK_ROOT = androidHome; # ANDROID_SDK_ROOT is deprecated, but some tools may still use it; - ANDROID_NDK_ROOT = "${androidHome}/ndk-bundle"; + OPENSSL_DIR = "${pkgs.openssl.dev}"; + ANDROID_HOME = androidHome; + ANDROID_SDK_ROOT = androidHome; # ANDROID_SDK_ROOT is deprecated, but some tools may still use it; + ANDROID_NDK_ROOT = "${androidHome}/ndk-bundle"; - inherit buildInputs nativeBuildInputs; - }; + inherit buildInputs nativeBuildInputs; + }; }); } diff --git a/rust-toolchain b/rust-toolchain index d408d6b65..d9aa0516c 100644 --- a/rust-toolchain +++ b/rust-toolchain @@ -4,10 +4,6 @@ components = [ "rustc", "cargo", "clippy", "rustfmt", "rust-analyzer" ] targets = [ "wasm32-unknown-unknown", "x86_64-unknown-linux-gnu", - "aarch64-linux-android", - "armv7-linux-androideabi", - "x86_64-linux-android", - "i686-linux-android", "x86_64-apple-ios", "x86_64-apple-darwin", "aarch64-apple-ios" diff --git a/xmtp_proto/Cargo.toml b/xmtp_proto/Cargo.toml index 1a6a2905a..c376941a1 100644 --- a/xmtp_proto/Cargo.toml +++ b/xmtp_proto/Cargo.toml @@ -14,7 +14,7 @@ serde = { workspace = true } async-trait = "0.1" hex.workspace = true openmls_rust_crypto = { workspace = true, optional = true } -tracing.workspace = true +tracing.workspace = true [target.'cfg(not(target_arch = "wasm32"))'.dependencies] tonic = { workspace = true }