1use std::{str::FromStr, sync::Arc};
2
3use mina_p2p_messages::v2::CurrencyFeeStableV1;
4use openmina_core::consensus::ConsensusConstants;
5use serde::{Deserialize, Serialize};
6
7use crate::{
8 account::AccountPublicKey,
9 transition_frontier::{archive::archive_config::ArchiveConfig, genesis::GenesisConfig},
10};
11pub use crate::{
12 block_producer::BlockProducerConfig, ledger::LedgerConfig, p2p::P2pConfig, snark::SnarkConfig,
13 snark_pool::SnarkPoolConfig, transition_frontier::TransitionFrontierConfig,
14};
15pub use mina_p2p_messages::v2::MinaBaseProtocolConstantsCheckedValueStableV1 as ProtocolConstants;
16
17#[derive(Serialize, Deserialize, Debug, Clone)]
20pub struct Config {
21 pub ledger: LedgerConfig,
22 pub snark: SnarkConfig,
23 pub p2p: P2pConfig,
24 pub transition_frontier: TransitionFrontierConfig,
25 pub archive: Option<ArchiveConfig>,
26 pub block_producer: Option<BlockProducerConfig>,
27 pub global: GlobalConfig,
28 pub tx_pool: ledger::transaction_pool::Config,
29}
30
31#[derive(Serialize, Deserialize, Debug, Clone)]
32pub struct GlobalConfig {
33 pub build: Box<BuildEnv>,
34 pub snarker: Option<SnarkerConfig>,
35 pub consensus_constants: ConsensusConstants,
36 pub client_port: Option<u16>,
37 pub testing_run: bool,
38}
39
40#[derive(Serialize, Deserialize, Debug, Clone)]
41pub struct SnarkerConfig {
42 pub public_key: AccountPublicKey,
43 pub fee: CurrencyFeeStableV1,
44 pub strategy: SnarkerStrategy,
45 pub auto_commit: bool,
46}
47
48#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
49pub enum SnarkerStrategy {
50 Sequential,
51 Random,
52}
53
54#[derive(Serialize, Deserialize, Debug, Clone)]
55pub struct BuildEnv {
56 pub time: String,
57 pub version: String,
58 pub git: GitBuildEnv,
59 pub cargo: CargoBuildEnv,
60 pub rustc: RustCBuildEnv,
61}
62
63#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
64pub struct GitBuildEnv {
65 pub commit_time: String,
66 pub commit_hash: String,
67 pub branch: String,
68}
69
70#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
71pub struct CargoBuildEnv {
72 pub features: String,
73 pub opt_level: u8,
74 pub target: String,
75 pub is_debug: bool,
76}
77
78#[derive(Serialize, Deserialize, Debug, Eq, PartialEq, Clone)]
79pub struct RustCBuildEnv {
80 pub channel: String,
81 pub commit_date: String,
82 pub commit_hash: String,
83 pub host: String,
84 pub version: String,
85 pub llvm_version: String,
86}
87
88#[allow(clippy::eq_op)]
89impl BuildEnv {
90 pub fn get() -> Self {
91 Self {
92 time: env!("VERGEN_BUILD_TIMESTAMP").to_owned(),
93 version: env!("VERGEN_GIT_DESCRIBE").to_owned(),
94 git: GitBuildEnv {
95 commit_time: env!("VERGEN_GIT_COMMIT_TIMESTAMP").to_owned(),
96 commit_hash: env!("VERGEN_GIT_SHA").to_owned(),
97 branch: env!("VERGEN_GIT_BRANCH").to_owned(),
98 },
99 cargo: CargoBuildEnv {
100 features: env!("VERGEN_CARGO_FEATURES").to_owned(),
101 opt_level: env!("VERGEN_CARGO_OPT_LEVEL").parse().unwrap(),
102 target: env!("VERGEN_CARGO_TARGET_TRIPLE").to_owned(),
103 is_debug: env!("VERGEN_CARGO_DEBUG") == "true",
104 },
105 rustc: RustCBuildEnv {
106 channel: env!("VERGEN_RUSTC_CHANNEL").to_owned(),
107 commit_date: env!("VERGEN_RUSTC_COMMIT_DATE").to_owned(),
108 commit_hash: env!("VERGEN_RUSTC_COMMIT_HASH").to_owned(),
109 host: env!("VERGEN_RUSTC_HOST_TRIPLE").to_owned(),
110 version: env!("VERGEN_RUSTC_SEMVER").to_owned(),
111 llvm_version: env!("VERGEN_RUSTC_LLVM_VERSION").to_owned(),
112 },
113 }
114 }
115}
116
117#[derive(thiserror::Error, Debug)]
118#[error("invalid strategy: {0}! expected one of: seq/sequential/rand/random")]
119pub struct SnarkerStrategyParseError(String);
120
121impl FromStr for SnarkerStrategy {
122 type Err = SnarkerStrategyParseError;
123
124 fn from_str(s: &str) -> Result<Self, Self::Err> {
125 Ok(match s {
126 "seq" | "sequential" => SnarkerStrategy::Sequential,
127 "rand" | "random" => SnarkerStrategy::Random,
128 other => return Err(SnarkerStrategyParseError(other.to_owned())),
129 })
130 }
131}
132
133lazy_static::lazy_static! {
135 pub static ref DEVNET_CONFIG: Arc<GenesisConfig> = {
136 let bytes = include_bytes!("../../genesis_ledgers/devnet.bin");
137 Arc::new(GenesisConfig::Prebuilt(
138 std::borrow::Cow::Borrowed(bytes)
139 ))
140 };
141}
142
143#[cfg(test)]
144mod tests {
145 use time::{format_description::well_known::Rfc3339, OffsetDateTime};
146
147 use super::DEVNET_CONFIG;
148
149 #[test]
150 fn devnet_config() {
151 let (_mask, config) = DEVNET_CONFIG.load().expect("should be loadable");
152
153 assert_eq!(
154 config.genesis_ledger_hash,
155 "jy1wjiJgTkzXr7yL8r5x4ikaNJuikibsRMnkjdH6uqGCsDmR2sf"
156 .parse()
157 .unwrap()
158 );
159 assert_eq!(
160 config.constants.genesis_state_timestamp,
161 OffsetDateTime::parse("2024-04-09T21:00:00Z", &Rfc3339)
162 .unwrap()
163 .into()
164 );
165 }
166}