Skip to content

Commit 5dee672

Browse files
authored
feat(rust/cardano-blockchain-types): Added a configurable Devnet option into the Network (#481)
* Update `Network` type, add `Devnet` variant * fix spelling
1 parent 600f846 commit 5dee672

File tree

3 files changed

+121
-80
lines changed

3 files changed

+121
-80
lines changed

.config/dictionaries/project.dic

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ dbsync
6464
dcbor
6565
decompressor
6666
delegators
67+
devnet
6768
direnv
6869
displaydoc
6970
dleq

rust/cardano-blockchain-types/src/metadata/cip36/validation.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,11 @@ impl Cip36 {
8787
return;
8888
};
8989

90-
let valid = match self.network {
90+
let valid = match &self.network {
9191
Network::Mainnet => network_tag.value() == 1,
92-
Network::Preprod | Network::Preview => network_tag.value() == 0,
92+
Network::Preprod | Network::Preview | Network::Devnet { .. } => {
93+
network_tag.value() == 0
94+
},
9395
};
9496

9597
// Report invalid network tag if necessary

rust/cardano-blockchain-types/src/network.rs

Lines changed: 116 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
33
use std::{ffi::OsStr, path::PathBuf};
44

5-
use anyhow::anyhow;
65
use catalyst_types::conversion::from_saturating;
76
use chrono::{DateTime, Utc};
87
use pallas::{
@@ -22,29 +21,46 @@ pub(crate) const ENVVAR_MITHRIL_EXE_NAME: &str = "MITHRIL_EXE_NAME";
2221

2322
/// Enum of possible Cardano networks.
2423
#[derive(
25-
Debug,
26-
Copy,
27-
Clone,
28-
PartialEq,
29-
Eq,
30-
Hash,
31-
PartialOrd,
32-
Ord,
33-
strum::EnumIter,
34-
strum::VariantNames,
35-
strum::EnumString,
36-
strum::Display,
24+
Debug, Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, strum::VariantNames, strum::Display,
3725
)]
38-
#[strum(ascii_case_insensitive)]
3926
#[strum(serialize_all = "snake_case")]
40-
#[repr(usize)]
27+
#[non_exhaustive]
4128
pub enum Network {
4229
/// Cardano mainnet network.
43-
Mainnet = 0,
30+
Mainnet,
4431
/// Cardano pre-production network.
45-
Preprod = 1,
32+
Preprod,
4633
/// Cardano preview network.
47-
Preview = 2,
34+
Preview,
35+
/// Cardano devnet network.
36+
Devnet {
37+
/// Mithril signature genesis key for a blockchain.
38+
genesis_key: &'static str,
39+
/// Cardano blockchain networking magic number genesis block setting
40+
magic: u64,
41+
/// Cardano blockchain network id genesis block setting
42+
network_id: u64,
43+
/// Cardano byron epoch length genesis block setting
44+
byron_epoch_length: u32,
45+
/// Cardano byron slot length genesis block setting
46+
byron_slot_length: u32,
47+
/// Cardano byron known slot genesis block setting
48+
byron_known_slot: u64,
49+
/// Cardano byron known hash genesis block setting
50+
byron_known_hash: &'static str,
51+
/// Cardano byron known time genesis block setting
52+
byron_known_time: u64,
53+
/// Cardano shelley epoch length genesis block setting
54+
shelley_epoch_length: u32,
55+
/// Cardano shelley slot length genesis block setting
56+
shelley_slot_length: u32,
57+
/// Cardano shelley known slot genesis block setting
58+
shelley_known_slot: u64,
59+
/// Cardano shelley known hash genesis block setting
60+
shelley_known_hash: &'static str,
61+
/// Cardano shelley known time genesis block setting
62+
shelley_known_time: u64,
63+
},
4864
}
4965

5066
// Mainnet Defaults.
@@ -74,40 +90,49 @@ const DEFAULT_PREVIEW_MITHRIL_GENESIS_KEY: &str = include_str!("data/preview-gen
7490
const DEFAULT_PREVIEW_MITHRIL_AGGREGATOR: &str =
7591
"https://aggregator.pre-release-preview.api.mithril.network/aggregator";
7692

93+
// Devnet Defaults
94+
/// Devnet Default Cardano Relay.
95+
const DEFAULT_DEVNET_RELAY: &str = "127.0.0.1:3001";
96+
/// Default Mithril Aggregator to use.
97+
const DEFAULT_DEVNET_MITHRIL_AGGREGATOR: &str = "http://127.0.0.1:8080/aggregator";
98+
7799
impl Network {
78100
/// Get the default Relay for a blockchain network.
79101
#[must_use]
80-
pub fn default_relay(self) -> String {
102+
pub fn default_relay(&self) -> String {
81103
match self {
82104
Network::Mainnet => DEFAULT_MAINNET_RELAY.to_string(),
83105
Network::Preprod => DEFAULT_PREPROD_RELAY.to_string(),
84106
Network::Preview => DEFAULT_PREVIEW_RELAY.to_string(),
107+
Network::Devnet { .. } => DEFAULT_DEVNET_RELAY.to_string(),
85108
}
86109
}
87110

88111
/// Get the default aggregator for a blockchain.
89112
#[must_use]
90-
pub fn default_mithril_aggregator(self) -> String {
113+
pub fn default_mithril_aggregator(&self) -> String {
91114
match self {
92115
Network::Mainnet => DEFAULT_MAINNET_MITHRIL_AGGREGATOR.to_string(),
93116
Network::Preprod => DEFAULT_PREPROD_MITHRIL_AGGREGATOR.to_string(),
94117
Network::Preview => DEFAULT_PREVIEW_MITHRIL_AGGREGATOR.to_string(),
118+
Network::Devnet { .. } => DEFAULT_DEVNET_MITHRIL_AGGREGATOR.to_string(),
95119
}
96120
}
97121

98122
/// Get the default Mithril Signature genesis key for a blockchain.
99123
#[must_use]
100-
pub fn default_mithril_genesis_key(self) -> String {
124+
pub fn default_mithril_genesis_key(&self) -> String {
101125
match self {
102126
Network::Mainnet => DEFAULT_MAINNET_MITHRIL_GENESIS_KEY.to_string(),
103127
Network::Preprod => DEFAULT_PREPROD_MITHRIL_GENESIS_KEY.to_string(),
104128
Network::Preview => DEFAULT_PREVIEW_MITHRIL_GENESIS_KEY.to_string(),
129+
Network::Devnet { genesis_key, .. } => (*genesis_key).to_string(),
105130
}
106131
}
107132

108133
/// Get the default storage location for mithril snapshots.
109134
/// Defaults to: `<platform data_local_dir>/<exe name>/mithril/<network>`
110-
pub fn default_mithril_path(self) -> PathBuf {
135+
pub fn default_mithril_path(&self) -> PathBuf {
111136
// Get the base path for storing Data.
112137
// IF the ENV var is set, use that.
113138
// Otherwise use the system default data path for an application.
@@ -150,18 +175,59 @@ impl Network {
150175

151176
/// Return genesis values for given network
152177
#[must_use]
153-
pub fn genesis_values(self) -> GenesisValues {
178+
pub fn genesis_values(&self) -> GenesisValues {
154179
match self {
155180
Network::Mainnet => GenesisValues::mainnet(),
156181
Network::Preprod => GenesisValues::preprod(),
157182
Network::Preview => GenesisValues::preview(),
183+
Network::Devnet {
184+
magic,
185+
network_id,
186+
byron_epoch_length,
187+
byron_slot_length,
188+
byron_known_slot,
189+
byron_known_hash,
190+
byron_known_time,
191+
shelley_epoch_length,
192+
shelley_slot_length,
193+
shelley_known_slot,
194+
shelley_known_hash,
195+
shelley_known_time,
196+
..
197+
} => {
198+
GenesisValues {
199+
magic: *magic,
200+
network_id: *network_id,
201+
byron_epoch_length: *byron_epoch_length,
202+
byron_slot_length: *byron_slot_length,
203+
byron_known_slot: *byron_known_slot,
204+
byron_known_hash: (*byron_known_hash).to_string(),
205+
byron_known_time: *byron_known_time,
206+
shelley_epoch_length: *shelley_epoch_length,
207+
shelley_slot_length: *shelley_slot_length,
208+
shelley_known_slot: *shelley_known_slot,
209+
shelley_known_hash: (*shelley_known_hash).to_string(),
210+
shelley_known_time: *shelley_known_time,
211+
}
212+
},
213+
}
214+
}
215+
216+
/// Return networking magic number.
217+
#[must_use]
218+
pub fn magic_number(&self) -> u64 {
219+
match self {
220+
Network::Mainnet => MAINNET_MAGIC,
221+
Network::Preprod => PRE_PRODUCTION_MAGIC,
222+
Network::Preview => PREVIEW_MAGIC,
223+
Network::Devnet { magic, .. } => *magic,
158224
}
159225
}
160226

161227
/// Convert a given slot# to its Wall Time for a Blockchain network.
162228
#[must_use]
163229
pub fn slot_to_time(
164-
self,
230+
&self,
165231
slot: Slot,
166232
) -> DateTime<Utc> {
167233
let genesis = self.genesis_values();
@@ -178,7 +244,7 @@ impl Network {
178244
/// The Slot does not have to be a valid slot present in the blockchain.
179245
#[must_use]
180246
pub fn time_to_slot(
181-
self,
247+
&self,
182248
time: DateTime<Utc>,
183249
) -> Option<Slot> {
184250
let genesis = self.genesis_values();
@@ -215,82 +281,54 @@ impl Network {
215281
}
216282
}
217283

218-
impl From<Network> for u64 {
219-
fn from(network: Network) -> Self {
220-
match network {
221-
Network::Mainnet => MAINNET_MAGIC,
222-
Network::Preprod => PRE_PRODUCTION_MAGIC,
223-
Network::Preview => PREVIEW_MAGIC,
224-
}
225-
}
226-
}
227-
228284
impl From<Network> for PallasNetwork {
229285
fn from(value: Network) -> Self {
230-
match value {
231-
Network::Mainnet => PallasNetwork::Mainnet,
232-
Network::Preprod | Network::Preview => PallasNetwork::Testnet,
233-
}
286+
PallasNetwork::from(&value)
234287
}
235288
}
236289

237-
impl TryFrom<PallasNetwork> for Network {
238-
type Error = anyhow::Error;
239-
240-
fn try_from(value: PallasNetwork) -> Result<Self, Self::Error> {
290+
impl From<&Network> for PallasNetwork {
291+
fn from(value: &Network) -> Self {
241292
match value {
242-
PallasNetwork::Mainnet => Ok(Network::Mainnet),
243-
PallasNetwork::Testnet => Ok(Network::Preprod),
244-
n @ PallasNetwork::Other(_) => Err(anyhow!("Unsupported network: {n:?}")),
293+
Network::Mainnet => PallasNetwork::Mainnet,
294+
Network::Preprod | Network::Preview | Network::Devnet { .. } => PallasNetwork::Testnet,
245295
}
246296
}
247297
}
248298

249299
#[cfg(test)]
250300
mod tests {
251-
use std::str::FromStr;
252-
253-
use anyhow::Ok;
254301
use chrono::{TimeZone, Utc};
255302
use strum::VariantNames;
256303

257304
use super::*;
258305

259-
#[test]
260-
fn test_from_str() -> anyhow::Result<()> {
261-
let mainnet = Network::from_str("mainnet")?;
262-
let preprod = Network::from_str("preprod")?;
263-
let preview = Network::from_str("preview")?;
264-
265-
assert_eq!(mainnet, Network::Mainnet);
266-
assert_eq!(preprod, Network::Preprod);
267-
assert_eq!(preview, Network::Preview);
268-
269-
let mainnet = Network::from_str("Mainnet")?;
270-
let preprod = Network::from_str("Preprod")?;
271-
let preview = Network::from_str("Preview")?;
272-
273-
assert_eq!(mainnet, Network::Mainnet);
274-
assert_eq!(preprod, Network::Preprod);
275-
assert_eq!(preview, Network::Preview);
276-
277-
Ok(())
278-
}
279-
280-
#[test]
281-
fn test_variant_to_usize() {
282-
assert_eq!(Network::Mainnet as usize, 0);
283-
assert_eq!(Network::Preprod as usize, 1);
284-
assert_eq!(Network::Preview as usize, 2);
285-
}
286-
287306
#[test]
288307
fn test_variant_to_string() {
289308
assert_eq!(Network::Mainnet.to_string(), "mainnet");
290309
assert_eq!(Network::Preprod.to_string(), "preprod");
291310
assert_eq!(Network::Preview.to_string(), "preview");
311+
assert_eq!(
312+
Network::Devnet {
313+
genesis_key: "genesis_key",
314+
magic: 0,
315+
network_id: 0,
316+
byron_epoch_length: 0,
317+
byron_slot_length: 0,
318+
byron_known_slot: 0,
319+
byron_known_hash: "byron_known_hash",
320+
byron_known_time: 0,
321+
shelley_epoch_length: 0,
322+
shelley_slot_length: 0,
323+
shelley_known_slot: 0,
324+
shelley_known_hash: "shelley_known_hash",
325+
shelley_known_time: 0
326+
}
327+
.to_string(),
328+
"devnet"
329+
);
292330

293-
let expected_names = ["mainnet", "preprod", "preview"];
331+
let expected_names = ["mainnet", "preprod", "preview", "devnet"];
294332
assert_eq!(Network::VARIANTS, expected_names);
295333
}
296334

0 commit comments

Comments
 (0)