use std::str::FromStr;
use std::sync::Arc;
use std::time::Instant;
use tap_agent::TapAgent;
use tap_msg::message::TapMessageBody;
use tap_msg::message::{Party, Transfer};
use tap_msg::PlainMessage;
use tap_node::message::processor_pool::ProcessorPoolConfig;
use tap_node::{NodeConfig, TapNode};
use criterion::{criterion_group, criterion_main, Criterion};
use std::collections::HashMap;
use tokio::time::Duration;
async fn create_test_message(
from_did: &str,
to_did: &str,
index: usize,
) -> (PlainMessage, Transfer) {
let body = Transfer {
transaction_id: Some(uuid::Uuid::new_v4().to_string()),
asset: tap_caip::AssetId::from_str(
"eip155:1/erc20:0x6b175474e89094c44da98b954eedeac495271d0f",
)
.unwrap(),
originator: Some(Party::new(from_did)),
beneficiary: Some(Party::new(to_did)),
amount: format!("{}.00", index),
agents: vec![],
settlement_id: None,
expiry: None,
transaction_value: None,
memo: Some(format!("Test message {}", index)),
metadata: HashMap::new(),
connection_id: None,
};
let message = body.to_didcomm(from_did).unwrap();
(message, body)
}
fn stress_test(c: &mut Criterion) {
let rt = tokio::runtime::Runtime::new().unwrap();
let pool_config = ProcessorPoolConfig {
workers: 16,
channel_capacity: 1000,
worker_timeout: Duration::from_secs(30),
};
let node_config = NodeConfig {
debug: false,
max_agents: None,
enable_message_logging: false,
log_message_content: false,
processor_pool: Some(pool_config),
event_logger: None,
#[cfg(feature = "storage")]
storage_path: None,
#[cfg(feature = "storage")]
agent_did: None,
#[cfg(feature = "storage")]
tap_root: None,
decision_mode: Default::default(),
};
let mut group = c.benchmark_group("tap_node_stress");
group.sample_size(10);
for &batch_size in &[10, 100, 1000] {
group.bench_function(format!("process_{}_messages", batch_size), |b| {
b.iter(|| {
rt.block_on(async {
let node = TapNode::new(node_config.clone());
let (agent1, agent1_did) = TapAgent::from_ephemeral_key().await.unwrap();
let (agent2, agent2_did) = TapAgent::from_ephemeral_key().await.unwrap();
let agent1 = Arc::new(agent1);
let agent2 = Arc::new(agent2);
node.register_agent(agent1).await.unwrap();
node.register_agent(agent2).await.unwrap();
let start = Instant::now();
let mut futures = Vec::with_capacity(batch_size);
for i in 0..batch_size {
let (message, _) = create_test_message(&agent1_did, &agent2_did, i).await;
let message_value = serde_json::to_value(message).unwrap();
futures.push(node.receive_message(message_value));
}
for future in futures {
let _ = future.await;
}
let duration = start.elapsed();
println!(
"Processed {} messages in {:?} ({:.2} msg/s)",
batch_size,
duration,
batch_size as f64 / duration.as_secs_f64()
);
});
});
});
}
group.finish();
}
criterion_group!(benches, stress_test);
criterion_main!(benches);