Skip to content

Commit e747eec

Browse files
authored
identity benchmarks (#1358)
1 parent c27fa03 commit e747eec

File tree

8 files changed

+148
-16
lines changed

8 files changed

+148
-16
lines changed

Cargo.lock

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dev/flamegraph

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@ else
1212
XMTP_FLAMEGRAPH=trace cargo bench --no-fail-fast --features bench -- "$1"
1313
fi
1414

15-
inferno-flamegraph > tracing-flamegraph.svg
15+
cat xmtp_mls/tracing.foldeed | inferno-flamegraph > tracing-flamegraph.svg

xmtp_api_grpc/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ mod utils {
2222
}
2323

2424
async fn create_dev() -> Self {
25-
crate::Client::create("https://grpc.dev.xmtp.network:443", false)
25+
crate::Client::create("https://grpc.dev.xmtp.network:443", true)
2626
.await
2727
.unwrap()
2828
}

xmtp_mls/Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -175,3 +175,9 @@ required-features = ["bench"]
175175
harness = false
176176
name = "crypto"
177177
required-features = ["bench"]
178+
179+
[[bench]]
180+
harness = false
181+
name = "identity"
182+
required-features = ["bench"]
183+

xmtp_mls/benches/group_limit.rs

+5-13
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,16 @@
44
//! may be used to generate a flamegraph of execution from tracing logs.
55
use criterion::{criterion_group, criterion_main, BatchSize, BenchmarkId, Criterion, Throughput};
66
use std::{collections::HashMap, sync::Arc};
7-
use tokio::runtime::{Builder, Handle, Runtime};
7+
use tokio::runtime::{Builder, Runtime};
88
use tracing::{trace_span, Instrument};
99
use xmtp_mls::{
1010
builder::ClientBuilder,
1111
groups::GroupMetadataOptions,
1212
utils::{
13-
bench::{create_identities_if_dont_exist, init_logging, Identity, BENCH_ROOT_SPAN},
13+
bench::{
14+
bench_async_setup, create_identities_if_dont_exist, init_logging, Identity,
15+
BENCH_ROOT_SPAN,
16+
},
1417
test::TestClient,
1518
},
1619
Client,
@@ -52,17 +55,6 @@ fn setup() -> (Arc<BenchClient>, Vec<Identity>, Runtime) {
5255
(client, identities, runtime)
5356
}
5457

55-
/// criterion `batch_iter` surrounds the closure in a `Runtime.block_on` despite being a sync
56-
/// function, even in the async 'to_async` setup. Therefore we do this (only _slightly_) hacky
57-
/// workaround to allow us to async setup some groups.
58-
fn bench_async_setup<F, T, Fut>(fun: F) -> T
59-
where
60-
F: Fn() -> Fut,
61-
Fut: futures::future::Future<Output = T>,
62-
{
63-
tokio::task::block_in_place(move || Handle::current().block_on(async move { fun().await }))
64-
}
65-
6658
fn add_to_empty_group(c: &mut Criterion) {
6759
init_logging();
6860
let mut benchmark_group = c.benchmark_group("add_to_empty_group");

xmtp_mls/benches/identity.rs

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
use crate::tracing::Instrument;
2+
use criterion::{criterion_group, criterion_main, BatchSize, Criterion};
3+
use ethers::signers::LocalWallet;
4+
use tokio::runtime::{Builder, Runtime};
5+
use xmtp_id::{
6+
associations::{
7+
builder::SignatureRequest,
8+
generate_inbox_id,
9+
unverified::{UnverifiedRecoverableEcdsaSignature, UnverifiedSignature},
10+
},
11+
InboxOwner,
12+
};
13+
use xmtp_mls::utils::{bench::init_logging, test::TestClient as TestApiClient};
14+
use xmtp_mls::{
15+
client::Client,
16+
identity::IdentityStrategy,
17+
utils::bench::{bench_async_setup, BENCH_ROOT_SPAN},
18+
};
19+
use xmtp_proto::api_client::XmtpTestClient;
20+
21+
type BenchClient = Client<TestApiClient>;
22+
23+
#[macro_use]
24+
extern crate tracing;
25+
26+
fn setup() -> Runtime {
27+
Builder::new_multi_thread()
28+
.enable_time()
29+
.enable_io()
30+
.thread_name("xmtp-bencher")
31+
.build()
32+
.unwrap()
33+
}
34+
35+
async fn new_client() -> (BenchClient, LocalWallet) {
36+
let nonce = 1;
37+
let wallet = xmtp_cryptography::utils::generate_local_wallet();
38+
let inbox_id = generate_inbox_id(&wallet.get_address(), &nonce).unwrap();
39+
40+
let dev = std::env::var("DEV_GRPC");
41+
let is_dev_network = matches!(dev, Ok(d) if d == "true" || d == "1");
42+
43+
let api_client = if is_dev_network {
44+
tracing::info!("Using Dev GRPC");
45+
<TestApiClient as XmtpTestClient>::create_dev().await
46+
} else {
47+
tracing::info!("Using Local GRPC");
48+
<TestApiClient as XmtpTestClient>::create_local().await
49+
};
50+
51+
let client = BenchClient::builder(IdentityStrategy::new(
52+
inbox_id,
53+
wallet.get_address(),
54+
nonce,
55+
None,
56+
));
57+
58+
let client = client
59+
.temp_store()
60+
.await
61+
.api_client(api_client)
62+
.build()
63+
.await
64+
.unwrap();
65+
66+
(client, wallet)
67+
}
68+
69+
async fn ecdsa_signature(client: &BenchClient, owner: impl InboxOwner) -> SignatureRequest {
70+
let mut signature_request = client.context().signature_request().unwrap();
71+
let signature_text = signature_request.signature_text();
72+
let unverified_signature = UnverifiedSignature::RecoverableEcdsa(
73+
UnverifiedRecoverableEcdsaSignature::new(owner.sign(&signature_text).unwrap().into()),
74+
);
75+
signature_request
76+
.add_signature(unverified_signature, client.scw_verifier())
77+
.await
78+
.unwrap();
79+
80+
signature_request
81+
}
82+
83+
fn register_identity_eoa(c: &mut Criterion) {
84+
init_logging();
85+
86+
let runtime = setup();
87+
88+
let mut benchmark_group = c.benchmark_group("register_identity");
89+
benchmark_group.sample_size(10);
90+
benchmark_group.bench_function("register_identity_eoa", |b| {
91+
let span = trace_span!(BENCH_ROOT_SPAN);
92+
b.to_async(&runtime).iter_batched(
93+
|| {
94+
bench_async_setup(|| async {
95+
let (client, wallet) = new_client().await;
96+
let signature_request = ecdsa_signature(&client, wallet).await;
97+
98+
(client, signature_request, span.clone())
99+
})
100+
},
101+
|(client, request, span)| async move {
102+
client
103+
.register_identity(request)
104+
.instrument(span)
105+
.await
106+
.unwrap()
107+
},
108+
BatchSize::SmallInput,
109+
)
110+
});
111+
112+
benchmark_group.finish();
113+
}
114+
115+
criterion_group!(
116+
name = identity;
117+
config = Criterion::default().sample_size(10);
118+
targets = register_identity_eoa
119+
);
120+
criterion_main!(identity);

xmtp_mls/src/utils/bench.rs

+12
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,18 @@ pub fn init_logging() {
6565
})
6666
}
6767

68+
/// criterion `batch_iter` surrounds the closure in a `Runtime.block_on` despite being a sync
69+
/// function, even in the async 'to_async` setup. Therefore we do this (only _slightly_) hacky
70+
/// workaround to allow us to async setup some groups.
71+
pub fn bench_async_setup<F, T, Fut>(fun: F) -> T
72+
where
73+
F: Fn() -> Fut,
74+
Fut: futures::future::Future<Output = T>,
75+
{
76+
use tokio::runtime::Handle;
77+
tokio::task::block_in_place(move || Handle::current().block_on(async move { fun().await }))
78+
}
79+
6880
/// Filters for only spans where the root span name is "bench"
6981
pub struct BenchFilter;
7082

xmtp_proto/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ serde = { workspace = true }
1414
async-trait = "0.1"
1515
hex.workspace = true
1616
openmls_rust_crypto = { workspace = true, optional = true }
17+
tracing.workspace = true
1718

1819
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
1920
tonic = { workspace = true }
@@ -43,4 +44,4 @@ proto_full = ["xmtp-identity","xmtp-identity-api-v1","xmtp-identity-associations
4344
"xmtp-xmtpv4-envelopes" = ["xmtp-identity-associations","xmtp-mls-api-v1"]
4445
"xmtp-xmtpv4-message_api" = ["xmtp-xmtpv4-envelopes"]
4546
"xmtp-xmtpv4-payer_api" = ["xmtp-xmtpv4-envelopes"]
46-
## @@protoc_insertion_point(features)
47+
## @@protoc_insertion_point(features)

0 commit comments

Comments
 (0)