1use crate::config::model::dfinity::{ReplicaLogLevel, ReplicaSubnetType};
2use candid::Principal;
3use serde::{Deserialize, Serialize};
4use std::borrow::Cow;
5use std::default::Default;
6use std::path::{Path, PathBuf};
7
8#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
9pub struct HttpHandlerConfig {
10 pub port: Option<u16>,
12
13 pub write_port_to: Option<PathBuf>,
18}
19
20#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
21pub struct BtcAdapterConfig {
22 pub enabled: bool,
23 pub socket_path: Option<PathBuf>,
24}
25
26#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
27pub struct CanisterHttpAdapterConfig {
28 pub enabled: bool,
29 pub socket_path: Option<PathBuf>,
30}
31
32#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
33pub struct ArtifactPoolConfig {
34 pub consensus_pool_path: PathBuf,
35}
36
37#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
38pub struct CryptoConfig {
39 pub crypto_root: PathBuf,
40}
41
42#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
43pub struct StateManagerConfig {
44 pub state_root: PathBuf,
45}
46
47#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
48pub struct ReplicaConfig {
49 pub http_handler: HttpHandlerConfig,
50 pub state_manager: StateManagerConfig,
51 pub crypto: CryptoConfig,
52 pub artifact_pool: ArtifactPoolConfig,
53 pub subnet_type: ReplicaSubnetType,
54 pub btc_adapter: BtcAdapterConfig,
55 pub canister_http_adapter: CanisterHttpAdapterConfig,
56 pub log_level: ReplicaLogLevel,
57 pub artificial_delay: u32,
58 pub system_canisters: bool,
59}
60
61impl ReplicaConfig {
62 pub fn new(
63 state_root: &Path,
64 subnet_type: ReplicaSubnetType,
65 log_level: ReplicaLogLevel,
66 artificial_delay: u32,
67 ) -> Self {
68 ReplicaConfig {
69 http_handler: HttpHandlerConfig {
70 write_port_to: None,
71 port: None,
72 },
73 state_manager: StateManagerConfig {
74 state_root: state_root.join("replicated_state"),
75 },
76 crypto: CryptoConfig {
77 crypto_root: state_root.join("crypto_store"),
78 },
79 artifact_pool: ArtifactPoolConfig {
80 consensus_pool_path: state_root.join("consensus_pool"),
81 },
82 subnet_type,
83 btc_adapter: BtcAdapterConfig {
84 enabled: false,
85 socket_path: None,
86 },
87 canister_http_adapter: CanisterHttpAdapterConfig {
88 enabled: false,
89 socket_path: None,
90 },
91 log_level,
92 artificial_delay,
93 system_canisters: false,
94 }
95 }
96
97 pub fn with_port(self, port: u16) -> Self {
98 ReplicaConfig {
99 http_handler: self.http_handler.with_port(port),
100 ..self
101 }
102 }
103
104 pub fn with_random_port(self, write_port_to: &Path) -> Self {
105 ReplicaConfig {
106 http_handler: self.http_handler.with_random_port(write_port_to),
107 ..self
108 }
109 }
110
111 pub fn with_btc_adapter_enabled(self) -> Self {
112 ReplicaConfig {
113 btc_adapter: self.btc_adapter.with_enabled(),
114 ..self
115 }
116 }
117
118 pub fn with_btc_adapter_socket(self, socket_path: PathBuf) -> Self {
119 ReplicaConfig {
120 btc_adapter: self.btc_adapter.with_socket_path(socket_path),
121 ..self
122 }
123 }
124
125 pub fn with_canister_http_adapter_enabled(self) -> Self {
126 ReplicaConfig {
127 canister_http_adapter: self.canister_http_adapter.with_enabled(),
128 ..self
129 }
130 }
131 pub fn with_canister_http_adapter_socket(self, socket_path: PathBuf) -> Self {
132 ReplicaConfig {
133 canister_http_adapter: self.canister_http_adapter.with_socket_path(socket_path),
134 ..self
135 }
136 }
137
138 pub fn with_system_canisters(self) -> Self {
139 ReplicaConfig {
140 system_canisters: true,
141 ..self
142 }
143 }
144}
145
146impl BtcAdapterConfig {
147 pub fn with_enabled(self) -> Self {
148 BtcAdapterConfig {
149 enabled: true,
150 ..self
151 }
152 }
153
154 pub fn with_socket_path(self, socket_path: PathBuf) -> Self {
155 BtcAdapterConfig {
156 socket_path: Some(socket_path),
157 ..self
158 }
159 }
160}
161
162impl CanisterHttpAdapterConfig {
163 pub fn with_enabled(self) -> Self {
164 CanisterHttpAdapterConfig {
165 enabled: true,
166 ..self
167 }
168 }
169
170 pub fn with_socket_path(self, socket_path: PathBuf) -> Self {
171 CanisterHttpAdapterConfig {
172 socket_path: Some(socket_path),
173 ..self
174 }
175 }
176}
177
178impl HttpHandlerConfig {
179 pub fn with_port(self, port: u16) -> Self {
180 HttpHandlerConfig {
181 port: Some(port),
182 write_port_to: None,
183 }
184 }
185
186 pub fn with_random_port(self, write_port_to: &Path) -> Self {
187 HttpHandlerConfig {
188 port: None,
189 write_port_to: Some(write_port_to.to_path_buf()),
190 }
191 }
192}
193
194#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
195#[serde(tag = "type", rename_all = "snake_case")]
196#[allow(clippy::large_enum_variant)]
197pub enum CachedReplicaConfig<'a> {
198 Replica { config: Cow<'a, ReplicaConfig> },
199 PocketIc { config: Cow<'a, ReplicaConfig> },
200}
201
202#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
203pub struct CachedConfig<'a> {
204 pub replica_rev: String,
205 pub effective_canister_id: Option<Principal>,
206 #[serde(flatten)]
207 pub config: CachedReplicaConfig<'a>,
208}
209
210impl<'a> CachedConfig<'a> {
211 pub fn replica(config: &'a ReplicaConfig, replica_rev: String) -> Self {
212 Self {
213 replica_rev,
214 effective_canister_id: None,
215 config: CachedReplicaConfig::Replica {
216 config: Cow::Borrowed(config),
217 },
218 }
219 }
220 pub fn pocketic(
221 config: &'a ReplicaConfig,
222 replica_rev: String,
223 effective_canister_id: Option<Principal>,
224 ) -> Self {
225 Self {
226 replica_rev,
227 effective_canister_id,
228 config: CachedReplicaConfig::PocketIc {
229 config: Cow::Borrowed(config),
230 },
231 }
232 }
233 pub fn can_share_state(&self, other: &Self) -> bool {
234 self.replica_rev == other.replica_rev && self.config == other.config
236 }
237 pub fn get_effective_canister_id(&self) -> Option<Principal> {
238 self.effective_canister_id
239 }
240}