1use crate::{
2 filter::Filter,
3 handler::{callback::EventHandler, retry::RetryPolicy},
4};
5use anyhow::anyhow;
6use core::str::FromStr;
7use oura::{sources::MagicArg, utils::ChainWellKnownInfo};
8use std::fmt;
9use std::fs::File;
10use std::io::BufReader;
11use std::{error::Error, path::PathBuf};
12use strum_macros::Display;
13
14pub struct TxIndexerConfig<H: EventHandler> {
15 pub handler: H,
16 pub source: TxIndexerSource,
18 pub retry_policy: RetryPolicy,
22}
23
24pub enum TxIndexerSource {
25 CardanoNode {
26 node_address: NodeAddress,
27 network: NetworkConfig,
28 since_slot: Option<(u64, String)>,
31 safe_block_depth: usize,
34 event_filter: Filter,
36 },
37 FixtureFiles {
38 dir_path: PathBuf,
39 },
40}
41
42impl<H: EventHandler> TxIndexerConfig<H> {
43 #[allow(clippy::too_many_arguments)]
44 pub fn cardano_node(
45 handler: H,
46 node_address: NodeAddress,
47 network: NetworkConfig,
48 since_slot: Option<(u64, String)>,
49 safe_block_depth: usize,
50 event_filter: Filter,
51 retry_policy: RetryPolicy,
52 ) -> Self {
53 Self {
54 handler,
55 source: TxIndexerSource::CardanoNode {
56 node_address,
57 network,
58 since_slot,
59 safe_block_depth,
60 event_filter,
61 },
62 retry_policy,
63 }
64 }
65
66 pub fn source_from_fixtures(handler: H, dir_path: PathBuf, retry_policy: RetryPolicy) -> Self {
67 Self {
68 handler,
69 source: TxIndexerSource::FixtureFiles { dir_path },
70 retry_policy,
71 }
72 }
73}
74
75pub enum NodeAddress {
78 UnixSocket(String),
80 TcpAddress(String, u16),
82}
83
84#[derive(Clone, Debug, Display)]
86pub enum NetworkName {
87 PREPROD,
88 PREVIEW,
89 MAINNET,
90}
91
92#[derive(Clone, Debug)]
93pub enum NetworkConfig {
94 ConfigPath {
95 node_config_path: String,
96 magic: u64,
97 },
98 WellKnown(NetworkName),
99 Config {
100 chain_info: ChainWellKnownInfo,
101 magic: u64,
102 },
103}
104
105#[derive(Clone, Debug, PartialEq, Eq)]
106pub struct NetworkNameParseErr;
107
108impl fmt::Display for NetworkNameParseErr {
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 "provided string was not `preprod` or `preview` or `mainnet`".fmt(f)
111 }
112}
113impl Error for NetworkNameParseErr {}
114
115impl FromStr for NetworkName {
116 type Err = NetworkNameParseErr;
117 fn from_str(s: &str) -> Result<NetworkName, Self::Err> {
118 match &s.to_lowercase()[..] {
119 "preprod" => Ok(NetworkName::PREPROD),
120 "preview" => Ok(NetworkName::PREVIEW),
121 "mainnet" => Ok(NetworkName::MAINNET),
122 _ => Err(NetworkNameParseErr),
123 }
124 }
125}
126
127impl NetworkConfig {
128 pub fn to_magic_arg(&self) -> MagicArg {
129 MagicArg(match self {
130 NetworkConfig::WellKnown(network_name) => match network_name {
131 NetworkName::PREPROD => pallas::network::miniprotocols::PRE_PRODUCTION_MAGIC,
132 NetworkName::PREVIEW => pallas::network::miniprotocols::PREVIEW_MAGIC,
133 NetworkName::MAINNET => pallas::network::miniprotocols::MAINNET_MAGIC,
134 },
135 NetworkConfig::ConfigPath { magic, .. } => *magic,
136 NetworkConfig::Config { magic, .. } => *magic,
137 })
138 }
139
140 pub fn to_chain_info(&self) -> Result<ChainWellKnownInfo, anyhow::Error> {
141 Ok(match self {
142 NetworkConfig::WellKnown(network_name) => match network_name {
143 NetworkName::PREPROD => ChainWellKnownInfo::preprod(),
144 NetworkName::PREVIEW => ChainWellKnownInfo::preview(),
145 NetworkName::MAINNET => ChainWellKnownInfo::mainnet(),
146 },
147 NetworkConfig::Config { chain_info, .. } => chain_info.clone(),
148 NetworkConfig::ConfigPath {
149 node_config_path, ..
150 } => {
151 let file = File::open(node_config_path.clone())
152 .map_err(|err| anyhow!("Chain Info not found at given path: {}", err))?;
153 let reader = BufReader::new(file);
154 serde_json::from_reader(reader).expect("Invalid JSON format for ChainWellKnownInfo")
155 }
156 })
157 }
158}
159
160pub mod deprecation_usage {
163 #![allow(deprecated)]
164
165 use oura::mapper::Config as MapperConfig;
166 use oura::sources::n2c::Config as N2CConfig;
167 use oura::sources::n2n::Config as N2NConfig;
168 use oura::sources::{AddressArg, IntersectArg, MagicArg, PointArg};
169
170 pub fn n2c_config(
171 addr: AddressArg,
172 magic: MagicArg,
173 since_slot: Option<(u64, String)>,
174 safe_block_depth: usize,
175 ) -> N2CConfig {
176 N2CConfig {
177 address: addr,
178 magic: Some(magic),
179 intersect: since_slot
180 .map(|since_slot| IntersectArg::Point(PointArg(since_slot.0, since_slot.1))),
181 mapper: MapperConfig {
182 include_transaction_details: true,
183 ..Default::default()
184 },
185 min_depth: safe_block_depth,
186 retry_policy: None,
187 finalize: None,
188 since: None,
190 well_known: None,
191 }
192 }
193
194 pub fn n2n_config(
195 addr: AddressArg,
196 magic: MagicArg,
197 since_slot: Option<(u64, String)>,
198 safe_block_depth: usize,
199 ) -> N2NConfig {
200 N2NConfig {
201 address: addr,
202 magic: Some(magic),
203 intersect: since_slot
204 .map(|since_slot| IntersectArg::Point(PointArg(since_slot.0, since_slot.1))),
205 mapper: MapperConfig {
206 include_transaction_details: true,
207 ..Default::default()
208 },
209 min_depth: safe_block_depth,
210 retry_policy: None,
211 finalize: None,
212 since: None,
214 well_known: None,
215 }
216 }
217}
218
219pub use self::deprecation_usage::*;