1use std::num::{NonZeroU32, NonZeroU64};
4use std::time::Duration;
5
6#[cfg(feature = "rocksdb")]
7mod rocksdb;
8#[cfg(feature = "rocksdb")]
9pub use rocksdb::*;
10
11const DEFAULT_REQUEST_TIMEOUT: Duration = Duration::from_secs(10);
12const TEST_REQUEST_TIMEOUT: Duration = Duration::from_secs(5);
13const DEFAULT_MAX_CONNECTION_AGE: Duration = Duration::from_mins(30);
14const DEFAULT_REPLENISH_N_PER_SECOND_PER_IP: NonZeroU64 = NonZeroU64::new(16).unwrap();
15const DEFAULT_BURST_SIZE: NonZeroU32 = NonZeroU32::new(128).unwrap();
16const DEFAULT_MAX_CONCURRENT_CONNECTIONS: u64 = 1_000;
17
18pub fn duration_to_human_readable_string(duration: Duration) -> &'static str {
21 Box::new(humantime::format_duration(duration).to_string()).leak()
22}
23
24#[derive(clap::Args, Copy, Clone, Debug, PartialEq, Eq)]
25pub struct GrpcOptionsInternal {
26 #[arg(
30 long = "grpc.timeout",
31 default_value = duration_to_human_readable_string(DEFAULT_REQUEST_TIMEOUT),
32 value_parser = humantime::parse_duration,
33 value_name = "DURATION"
34 )]
35 pub request_timeout: Duration,
36}
37
38impl Default for GrpcOptionsInternal {
39 fn default() -> Self {
40 Self { request_timeout: DEFAULT_REQUEST_TIMEOUT }
41 }
42}
43
44impl From<GrpcOptionsExternal> for GrpcOptionsInternal {
45 fn from(value: GrpcOptionsExternal) -> Self {
46 let GrpcOptionsExternal { request_timeout, .. } = value;
47 Self { request_timeout }
48 }
49}
50
51impl GrpcOptionsInternal {
52 pub fn test() -> Self {
53 GrpcOptionsExternal::test().into()
54 }
55 pub fn bench() -> Self {
56 GrpcOptionsExternal::bench().into()
57 }
58}
59
60#[derive(clap::Args, Copy, Clone, Debug, PartialEq, Eq)]
61pub struct GrpcOptionsExternal {
62 #[arg(
66 long = "grpc.timeout",
67 default_value = duration_to_human_readable_string(DEFAULT_REQUEST_TIMEOUT),
68 value_parser = humantime::parse_duration,
69 value_name = "DURATION"
70 )]
71 pub request_timeout: Duration,
72
73 #[arg(
76 long = "grpc.max_connection_age",
77 default_value = duration_to_human_readable_string(DEFAULT_MAX_CONNECTION_AGE),
78 value_parser = humantime::parse_duration,
79 value_name = "MAX_CONNECTION_AGE"
80 )]
81 pub max_connection_age: Duration,
82
83 #[arg(
86 long = "grpc.burst_size",
87 default_value_t = DEFAULT_BURST_SIZE,
88 value_name = "BURST_SIZE"
89 )]
90 pub burst_size: NonZeroU32,
91
92 #[arg(
94 long = "grpc.replenish_n_per_second",
95 default_value_t = DEFAULT_REPLENISH_N_PER_SECOND_PER_IP,
96 value_name = "DEFAULT_REPLENISH_N_PER_SECOND"
97 )]
98 pub replenish_n_per_second_per_ip: NonZeroU64,
99
100 #[arg(
102 long = "grpc.max_concurrent_connections",
103 default_value_t = DEFAULT_MAX_CONCURRENT_CONNECTIONS,
104 value_name = "MAX_CONCURRENT_CONNECTIONS"
105 )]
106 pub max_concurrent_connections: u64,
107}
108
109impl Default for GrpcOptionsExternal {
110 fn default() -> Self {
111 Self {
112 request_timeout: DEFAULT_REQUEST_TIMEOUT,
113 max_connection_age: DEFAULT_MAX_CONNECTION_AGE,
114 burst_size: DEFAULT_BURST_SIZE,
115 replenish_n_per_second_per_ip: DEFAULT_REPLENISH_N_PER_SECOND_PER_IP,
116 max_concurrent_connections: DEFAULT_MAX_CONCURRENT_CONNECTIONS,
117 }
118 }
119}
120
121impl GrpcOptionsExternal {
122 pub fn test() -> Self {
123 Self {
124 request_timeout: TEST_REQUEST_TIMEOUT,
125 ..Default::default()
126 }
127 }
128
129 pub fn bench() -> Self {
131 Self {
132 request_timeout: Duration::from_hours(24),
133 max_connection_age: Duration::from_hours(24),
134 burst_size: NonZeroU32::new(100_000).unwrap(),
135 replenish_n_per_second_per_ip: NonZeroU64::new(100_000).unwrap(),
136 max_concurrent_connections: u64::MAX,
137 }
138 }
139}
140
141#[derive(clap::Args, Clone, Debug, Default, PartialEq, Eq)]
145pub struct StorageOptions {
146 #[cfg(feature = "rocksdb")]
147 #[clap(flatten)]
148 pub account_tree: AccountTreeRocksDbOptions,
149 #[cfg(feature = "rocksdb")]
150 #[clap(flatten)]
151 pub nullifier_tree: NullifierTreeRocksDbOptions,
152}
153
154impl StorageOptions {
155 pub fn bench() -> Self {
159 #[cfg(feature = "rocksdb")]
160 {
161 let account_tree = AccountTreeRocksDbOptions {
162 max_open_fds: self::rocksdb::BENCH_ROCKSDB_MAX_OPEN_FDS,
163 cache_size_in_bytes: self::rocksdb::DEFAULT_ROCKSDB_CACHE_SIZE,
164 };
165 let nullifier_tree = NullifierTreeRocksDbOptions {
166 max_open_fds: BENCH_ROCKSDB_MAX_OPEN_FDS,
167 cache_size_in_bytes: DEFAULT_ROCKSDB_CACHE_SIZE,
168 };
169 Self { account_tree, nullifier_tree }
170 }
171 #[cfg(not(feature = "rocksdb"))]
172 Self::default()
173 }
174}