kabu_core_topology/
topology_config.rs

1use eyre::Result;
2use kabu_broadcast_flashbots::client::RelayConfig;
3use serde::Deserialize;
4use std::collections::HashMap;
5use std::fs;
6use strum_macros::Display;
7
8#[derive(Clone, Debug, Deserialize)]
9pub struct BlockchainConfig {
10    pub chain_id: Option<i64>,
11}
12
13#[derive(Clone, Debug, Default, Deserialize, Display)]
14#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
15#[serde(rename_all = "lowercase")]
16pub enum NodeType {
17    #[default]
18    Geth,
19    Reth,
20}
21
22#[derive(Clone, Debug, Default, Deserialize, Display)]
23#[strum(ascii_case_insensitive, serialize_all = "lowercase")]
24#[serde(rename_all = "lowercase")]
25pub enum TransportType {
26    #[default]
27    #[serde(rename = "ws")]
28    Ws,
29    #[serde(rename = "http")]
30    Http,
31    #[serde(rename = "ipc")]
32    Ipc,
33}
34
35#[derive(Clone, Debug, Default, Deserialize)]
36pub struct InfluxDbConfig {
37    pub url: String,
38    pub database: String,
39    pub tags: HashMap<String, String>,
40}
41
42#[derive(Clone, Debug, Default, Deserialize)]
43pub struct ClientConfig {
44    pub url: String,
45    pub node: NodeType,
46    pub transport: TransportType,
47    pub db_path: Option<String>,
48    pub exex: Option<String>,
49    // #[serde(skip)]
50    // pub provider: Option<P>,
51    // _n: PhantomData<N>,
52}
53
54/*
55impl<P, N> ClientConfig<P, N>
56where
57    N: Network,
58    P: Provider<N> + Send + Sync + Clone + 'static,
59{
60    pub fn client(&self) -> Option<&P> {
61        self.provider.as_ref()
62    }
63}
64
65 */
66/*
67#[derive(Clone, Debug, Deserialize)]
68#[serde(untagged)]
69pub enum ClientConfig {
70    //String(String),
71    Params(ClientConfigParams),
72}
73
74impl ClientConfig {
75    pub fn url(&self) -> String {
76        match &self {
77            Self::String(s) => s.clone(),
78            ClientConfig::Params(p) => p.url.clone(),
79        }
80    }
81
82    pub fn config_params(&self) -> ClientConfigParams {
83        match self {
84            ClientConfig::String(s) => ClientConfigParams { url: s.clone(), ..ClientConfigParams::default() },
85            ClientConfig::Params(p) => p.clone(),
86        }
87    }
88}
89
90 */
91
92#[derive(Clone, Debug, Deserialize)]
93pub struct EnvSingerConfig {
94    #[serde(rename = "bc")]
95    pub blockchain: Option<String>,
96}
97
98#[derive(Clone, Debug, Deserialize)]
99#[serde(tag = "type")]
100pub enum SignersConfig {
101    #[serde(rename = "env")]
102    Env(EnvSingerConfig),
103}
104
105#[derive(Clone, Debug, Deserialize)]
106pub struct PreloaderConfig {
107    pub client: Option<String>,
108    #[serde(rename = "bc")]
109    pub blockchain: Option<String>,
110    pub encoder: Option<String>,
111    pub signers: Option<String>,
112}
113
114#[derive(Clone, Debug, Deserialize)]
115pub struct SwapStepEncoderConfig {
116    pub address: String,
117}
118
119#[derive(Clone, Debug, Deserialize)]
120#[serde(tag = "type")]
121pub enum EncoderConfig {
122    #[serde(rename = "swapstep")]
123    SwapStep(SwapStepEncoderConfig),
124}
125
126#[derive(Clone, Debug, Deserialize)]
127pub struct BlockchainClientConfig {
128    #[serde(rename = "bc")]
129    pub blockchain: Option<String>,
130    pub client: Option<String>,
131}
132#[derive(Clone, Debug, Deserialize)]
133pub struct ExExClientConfig {
134    #[serde(rename = "bc")]
135    pub blockchain: Option<String>,
136    pub url: Option<String>,
137}
138
139#[derive(Clone, Debug, Deserialize)]
140pub struct FlashbotsRelayConfig {
141    id: u16,
142    name: String,
143    url: String,
144    no_sign: Option<bool>,
145}
146
147impl From<FlashbotsRelayConfig> for RelayConfig {
148    fn from(config: FlashbotsRelayConfig) -> Self {
149        RelayConfig { id: config.id, name: config.name, url: config.url, no_sign: config.no_sign }
150    }
151}
152
153#[derive(Clone, Debug, Deserialize)]
154pub struct FlashbotsBroadcasterConfig {
155    #[serde(rename = "bc")]
156    pub blockchain: Option<String>,
157    pub client: Option<String>,
158    pub smart: Option<bool>,
159    pub relays: Option<Vec<FlashbotsRelayConfig>>,
160}
161
162impl FlashbotsBroadcasterConfig {
163    pub fn relays(&self) -> Vec<RelayConfig> {
164        self.relays.as_ref().map(|relays| relays.iter().map(|r| r.clone().into()).collect()).unwrap_or_default()
165    }
166}
167
168#[derive(Clone, Debug, Deserialize)]
169#[serde(tag = "type")]
170pub enum BroadcasterConfig {
171    #[serde(rename = "flashbots")]
172    Flashbots(FlashbotsBroadcasterConfig),
173}
174
175#[derive(Clone, Debug, Deserialize)]
176pub struct EvmEstimatorConfig {
177    pub client: Option<String>,
178    #[serde(rename = "bc")]
179    pub blockchain: Option<String>,
180    pub encoder: Option<String>,
181}
182
183#[derive(Clone, Debug, Deserialize)]
184pub struct GethEstimatorConfig {
185    pub client: Option<String>,
186    #[serde(rename = "bc")]
187    pub blockchain: Option<String>,
188    pub encoder: Option<String>,
189}
190
191#[derive(Clone, Debug, Deserialize)]
192#[serde(tag = "type")]
193pub enum EstimatorConfig {
194    #[serde(rename = "evm")]
195    Evm(EvmEstimatorConfig),
196    #[serde(rename = "geth")]
197    Geth(GethEstimatorConfig),
198}
199
200#[derive(Clone, Debug, Deserialize)]
201pub struct PoolsConfig {
202    #[serde(rename = "bc")]
203    pub blockchain: Option<String>,
204    pub client: Option<String>,
205    pub history: bool,
206    pub new: bool,
207    pub protocol: bool,
208}
209
210#[derive(Clone, Debug, Deserialize)]
211pub struct WebserverConfig {
212    pub host: String,
213}
214
215impl Default for WebserverConfig {
216    fn default() -> Self {
217        WebserverConfig { host: "127.0.0.1:3333".to_string() }
218    }
219}
220
221#[derive(Clone, Debug, Deserialize)]
222pub struct DatabaseConfig {
223    pub url: String,
224}
225
226#[derive(Debug, Clone, Deserialize)]
227pub struct ActorConfig {
228    pub broadcaster: Option<HashMap<String, BroadcasterConfig>>,
229    pub node: Option<HashMap<String, BlockchainClientConfig>>,
230    pub node_exex: Option<HashMap<String, ExExClientConfig>>,
231    pub mempool: Option<HashMap<String, BlockchainClientConfig>>,
232    pub price: Option<HashMap<String, BlockchainClientConfig>>,
233    pub pools: Option<HashMap<String, PoolsConfig>>,
234    pub noncebalance: Option<HashMap<String, BlockchainClientConfig>>,
235    pub estimator: Option<HashMap<String, EstimatorConfig>>,
236}
237
238#[derive(Debug, Clone, Deserialize)]
239pub struct TopologyConfig {
240    pub influxdb: Option<InfluxDbConfig>,
241    pub clients: HashMap<String, ClientConfig>,
242    pub blockchains: HashMap<String, BlockchainConfig>,
243    pub actors: ActorConfig,
244    pub signers: HashMap<String, SignersConfig>,
245    pub encoders: HashMap<String, EncoderConfig>,
246    pub preloaders: Option<HashMap<String, PreloaderConfig>>,
247    pub webserver: Option<WebserverConfig>,
248    pub database: Option<DatabaseConfig>,
249}
250
251impl TopologyConfig {
252    pub fn load_from_file(file_name: String) -> Result<TopologyConfig> {
253        let contents = fs::read_to_string(file_name)?;
254        let config: TopologyConfig = toml::from_str(&contents)?;
255        Ok(config)
256    }
257}
258
259#[cfg(test)]
260mod test {
261    use super::*;
262
263    #[test]
264    fn test_load() {
265        match TopologyConfig::load_from_file("../../config.toml".to_string()) {
266            Ok(c) => {
267                println!("{c:?}");
268            }
269            Err(e) => {
270                println!("Error:{e}")
271            }
272        }
273    }
274}