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_MAX_CONNECTION_AGE_GRACE: Duration = Duration::from_secs(10);
15const DEFAULT_REPLENISH_N_PER_SECOND_PER_IP: NonZeroU64 = NonZeroU64::new(16).unwrap();
16const DEFAULT_BURST_SIZE: NonZeroU32 = NonZeroU32::new(128).unwrap();
17const DEFAULT_MAX_CONCURRENT_CONNECTIONS: u64 = 1_000;
18
19pub fn duration_to_human_readable_string(duration: Duration) -> &'static str {
22 Box::new(humantime::format_duration(duration).to_string()).leak()
23}
24
25#[derive(clap::Args, Copy, Clone, Debug, PartialEq, Eq)]
26pub struct GrpcOptionsInternal {
27 #[arg(
31 long = "grpc.timeout",
32 default_value = duration_to_human_readable_string(DEFAULT_REQUEST_TIMEOUT),
33 value_parser = humantime::parse_duration,
34 value_name = "DURATION"
35 )]
36 pub request_timeout: Duration,
37}
38
39impl Default for GrpcOptionsInternal {
40 fn default() -> Self {
41 Self { request_timeout: DEFAULT_REQUEST_TIMEOUT }
42 }
43}
44
45impl From<GrpcOptionsExternal> for GrpcOptionsInternal {
46 fn from(value: GrpcOptionsExternal) -> Self {
47 let GrpcOptionsExternal { request_timeout, .. } = value;
48 Self { request_timeout }
49 }
50}
51
52impl GrpcOptionsInternal {
53 pub fn test() -> Self {
54 GrpcOptionsExternal::test().into()
55 }
56 pub fn bench() -> Self {
57 GrpcOptionsExternal::bench().into()
58 }
59}
60
61#[derive(clap::Args, Copy, Clone, Debug, PartialEq, Eq)]
62pub struct GrpcOptionsExternal {
63 #[arg(
67 long = "grpc.timeout",
68 default_value = duration_to_human_readable_string(DEFAULT_REQUEST_TIMEOUT),
69 value_parser = humantime::parse_duration,
70 value_name = "DURATION"
71 )]
72 pub request_timeout: Duration,
73
74 #[arg(
77 long = "grpc.max_connection_age",
78 default_value = duration_to_human_readable_string(DEFAULT_MAX_CONNECTION_AGE),
79 value_parser = humantime::parse_duration,
80 value_name = "MAX_CONNECTION_AGE"
81 )]
82 pub max_connection_age: Duration,
83
84 #[arg(
87 long = "grpc.max_connection_age_grace",
88 default_value = duration_to_human_readable_string(DEFAULT_MAX_CONNECTION_AGE_GRACE),
89 value_parser = humantime::parse_duration,
90 value_name = "MAX_CONNECTION_AGE_GRACE"
91 )]
92 pub max_connection_age_grace: Duration,
93
94 #[arg(
97 long = "grpc.burst_size",
98 default_value_t = DEFAULT_BURST_SIZE,
99 value_name = "BURST_SIZE"
100 )]
101 pub burst_size: NonZeroU32,
102
103 #[arg(
105 long = "grpc.replenish_n_per_second",
106 default_value_t = DEFAULT_REPLENISH_N_PER_SECOND_PER_IP,
107 value_name = "DEFAULT_REPLENISH_N_PER_SECOND"
108 )]
109 pub replenish_n_per_second_per_ip: NonZeroU64,
110
111 #[arg(
113 long = "grpc.max_concurrent_connections",
114 default_value_t = DEFAULT_MAX_CONCURRENT_CONNECTIONS,
115 value_name = "MAX_CONCURRENT_CONNECTIONS"
116 )]
117 pub max_concurrent_connections: u64,
118}
119
120impl Default for GrpcOptionsExternal {
121 fn default() -> Self {
122 Self {
123 request_timeout: DEFAULT_REQUEST_TIMEOUT,
124 max_connection_age: DEFAULT_MAX_CONNECTION_AGE,
125 max_connection_age_grace: DEFAULT_MAX_CONNECTION_AGE_GRACE,
126 burst_size: DEFAULT_BURST_SIZE,
127 replenish_n_per_second_per_ip: DEFAULT_REPLENISH_N_PER_SECOND_PER_IP,
128 max_concurrent_connections: DEFAULT_MAX_CONCURRENT_CONNECTIONS,
129 }
130 }
131}
132
133impl GrpcOptionsExternal {
134 pub fn test() -> Self {
135 Self {
136 request_timeout: TEST_REQUEST_TIMEOUT,
137 ..Default::default()
138 }
139 }
140
141 pub fn bench() -> Self {
143 Self {
144 request_timeout: Duration::from_hours(24),
145 max_connection_age: Duration::from_hours(24),
146 max_connection_age_grace: DEFAULT_MAX_CONNECTION_AGE_GRACE,
147 burst_size: NonZeroU32::new(100_000).unwrap(),
148 replenish_n_per_second_per_ip: NonZeroU64::new(100_000).unwrap(),
149 max_concurrent_connections: u64::MAX,
150 }
151 }
152}
153
154#[derive(clap::Args, Clone, Debug, Default, PartialEq, Eq)]
158pub struct StorageOptions {
159 #[cfg(feature = "rocksdb")]
160 #[clap(flatten)]
161 pub account_tree: AccountTreeRocksDbOptions,
162 #[cfg(feature = "rocksdb")]
163 #[clap(flatten)]
164 pub nullifier_tree: NullifierTreeRocksDbOptions,
165 #[cfg(feature = "rocksdb")]
166 #[clap(flatten)]
167 pub account_state_forest: AccountStateForestRocksDbOptions,
168}
169
170impl StorageOptions {
171 pub fn bench() -> Self {
175 #[cfg(feature = "rocksdb")]
176 {
177 let account_tree = AccountTreeRocksDbOptions {
178 max_open_fds: self::rocksdb::BENCH_ROCKSDB_MAX_OPEN_FDS,
179 cache_size_in_bytes: self::rocksdb::DEFAULT_ROCKSDB_CACHE_SIZE,
180 durability_mode: None,
181 };
182 let nullifier_tree = NullifierTreeRocksDbOptions {
183 max_open_fds: BENCH_ROCKSDB_MAX_OPEN_FDS,
184 cache_size_in_bytes: DEFAULT_ROCKSDB_CACHE_SIZE,
185 durability_mode: None,
186 };
187 let account_state_forest = AccountStateForestRocksDbOptions {
188 max_open_fds: BENCH_ROCKSDB_MAX_OPEN_FDS,
189 cache_size_in_bytes: DEFAULT_ROCKSDB_CACHE_SIZE,
190 durability_mode: None,
191 };
192 Self {
193 account_tree,
194 nullifier_tree,
195 account_state_forest,
196 }
197 }
198 #[cfg(not(feature = "rocksdb"))]
199 Self::default()
200 }
201}