cat_gateway/settings/
chain_follower.rs1use std::{cmp::min, time::Duration};
4
5use cardano_chain_follower::{turbo_downloader::DlConfig, ChainSyncConfig, Network};
6use tracing::info;
7
8use super::str_env_var::StringEnvVar;
9
10const DEFAULT_NETWORK: NetworkFromStr = NetworkFromStr::Mainnet;
12
13const DEFAULT_SYNC_TASKS: u16 = 16;
15
16const MAX_SYNC_TASKS: u16 = 256;
18
19const DEFAULT_SYNC_MAX_SLOTS: u64 = 700_000;
22const MIN_SYNC_MAX_SLOTS: u64 = 10_000;
25const MAX_SYNC_MAX_SLOTS: u64 = 100_000_000;
27
28const MAX_DL_CONNECTIONS: usize = 256;
30
31const MAX_DL_CHUNK_SIZE: usize = 256;
33
34const MAX_DL_CHUNK_QUEUE_AHEAD: usize = 256;
36
37const MAX_DL_TIMEOUT: u64 = 300;
39
40const ONE_MEGABYTE: usize = 1_048_576;
42
43#[derive(Clone)]
45pub(crate) struct EnvVars {
46 pub(crate) chain: Network,
48
49 pub(crate) sync_tasks: u16,
51
52 pub(crate) sync_chunk_max_slots: u64,
54
55 pub(crate) dl_config: DlConfig,
57}
58
59#[derive(strum::EnumString, strum::VariantNames, strum::Display)]
60#[strum(ascii_case_insensitive)]
61enum NetworkFromStr {
62 Mainnet,
64 Preprod,
66 Preview,
68 Devnet,
70}
71
72impl From<NetworkFromStr> for Network {
73 fn from(value: NetworkFromStr) -> Self {
74 match value {
75 NetworkFromStr::Mainnet => Self::Mainnet,
76 NetworkFromStr::Preprod => Self::Preprod,
77 NetworkFromStr::Preview => Self::Preview,
78 NetworkFromStr::Devnet => Self::Devnet {
79 genesis_key: "5b33322c3235332c3138362c3230312c3137372c31312c3131372c3133352c3138372c3136372c3138312c3138382c32322c35392c3230362c3130352c3233312c3135302c3231352c33302c37382c3231322c37362c31362c3235322c3138302c37322c3133342c3133372c3234372c3136312c36385d",
80 magic: 42,
81 network_id: 0,
82 byron_epoch_length: 100_000,
83 byron_slot_length: 1000,
84 byron_known_slot: 0,
85 byron_known_time: 1_564_010_416,
86 byron_known_hash: "8f8602837f7c6f8b8867dd1cbc1842cf51a27eaed2c70ef48325d00f8efb320f",
87 shelley_epoch_length: 100,
88 shelley_slot_length: 1,
89 shelley_known_slot: 1_598_400,
90 shelley_known_hash: "02b1c561715da9e540411123a6135ee319b02f60b9a11a603d3305556c04329f",
91 shelley_known_time: 1_595_967_616,
92 },
93 }
94 }
95}
96
97impl EnvVars {
98 pub(super) fn new() -> Self {
100 let chain = StringEnvVar::new_as_enum("CHAIN_NETWORK", DEFAULT_NETWORK, false).into();
101
102 let sync_tasks: u16 = StringEnvVar::new_as_int(
103 "CHAIN_FOLLOWER_SYNC_TASKS",
104 DEFAULT_SYNC_TASKS,
105 1,
106 MAX_SYNC_TASKS,
107 );
108
109 let sync_slots: u64 = StringEnvVar::new_as_int(
110 "CHAIN_FOLLOWER_SYNC_MAX_SLOTS",
111 DEFAULT_SYNC_MAX_SLOTS,
112 MIN_SYNC_MAX_SLOTS,
113 MAX_SYNC_MAX_SLOTS,
114 );
115
116 let cfg = ChainSyncConfig::default_for(chain);
117 let mut dl_config = cfg.mithril_cfg.dl_config.clone().unwrap_or_default();
118
119 let workers = StringEnvVar::new_as_int(
120 "CHAIN_FOLLOWER_DL_CONNECTIONS",
121 dl_config.workers,
122 1,
123 MAX_DL_CONNECTIONS,
124 );
125 dl_config = dl_config.with_workers(workers);
126
127 let default_dl_chunk_size = min(1, dl_config.chunk_size / ONE_MEGABYTE);
128
129 let chunk_size = StringEnvVar::new_as_int(
130 "CHAIN_FOLLOWER_DL_CHUNK_SIZE",
131 default_dl_chunk_size,
132 1,
133 MAX_DL_CHUNK_SIZE,
134 )
135 .checked_mul(ONE_MEGABYTE)
136 .unwrap_or_else(|| {
137 info!("Too big 'CHAIN_FOLLOWER_DL_CHUNK_SIZE' value, default value {default_dl_chunk_size} is used");
138 default_dl_chunk_size
139 });
140 dl_config = dl_config.with_chunk_size(chunk_size);
141
142 let queue_ahead = StringEnvVar::new_as_int(
143 "CHAIN_FOLLOWER_DL_QUEUE_AHEAD",
144 dl_config.queue_ahead,
145 1,
146 MAX_DL_CHUNK_QUEUE_AHEAD,
147 );
148 dl_config = dl_config.with_queue_ahead(queue_ahead);
149
150 let default_dl_connect_timeout = match dl_config.connection_timeout {
151 Some(timeout) => timeout.as_secs(),
152 None => 0,
153 };
154 let dl_connect_timeout = StringEnvVar::new_as_int(
155 "CHAIN_FOLLOWER_DL_CONNECT_TIMEOUT",
156 default_dl_connect_timeout,
157 0,
158 MAX_DL_TIMEOUT,
159 );
160 if dl_connect_timeout == 0 {
161 dl_config.connection_timeout = None;
162 } else {
163 dl_config = dl_config.with_connection_timeout(Duration::from_secs(dl_connect_timeout));
164 }
165
166 let default_dl_data_timeout = match dl_config.data_read_timeout {
167 Some(timeout) => timeout.as_secs(),
168 None => 0,
169 };
170 let dl_data_timeout = StringEnvVar::new_as_int(
171 "CHAIN_FOLLOWER_DL_DATA_TIMEOUT",
172 default_dl_data_timeout,
173 0,
174 MAX_DL_TIMEOUT,
175 );
176 if dl_connect_timeout == 0 {
177 dl_config.data_read_timeout = None;
178 } else {
179 dl_config = dl_config.with_data_read_timeout(Duration::from_secs(dl_data_timeout));
180 }
181
182 Self {
183 chain,
184 sync_tasks,
185 sync_chunk_max_slots: sync_slots,
186 dl_config,
187 }
188 }
189
190 pub(crate) fn log(&self) {
192 info!(
193 chain = self.chain.to_string(),
194 sync_tasks = self.sync_tasks,
195 dl_config = ?self.dl_config,
196 "Chain Follower Configuration"
197 );
198 }
199}