Skip to main content

amaru_kernel/cardano/
network_magic.rs

1// Copyright 2025 PRAGMA
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::{
16    env,
17    fmt::{Display, Formatter},
18    num::ParseIntError,
19};
20
21use crate::cbor;
22
23#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
24#[repr(transparent)]
25pub struct NetworkMagic(u64);
26
27impl From<u64> for NetworkMagic {
28    fn from(value: u64) -> Self {
29        Self(value)
30    }
31}
32
33impl From<NetworkMagic> for u64 {
34    fn from(value: NetworkMagic) -> Self {
35        value.0
36    }
37}
38
39impl NetworkMagic {
40    pub const TESTNET: Self = Self(1097911063);
41    pub const MAINNET: Self = Self(764824073);
42    pub const PREVIEW: Self = Self(2);
43    pub const PREPROD: Self = Self(1);
44
45    pub fn new(value: u64) -> Self {
46        Self(value)
47    }
48
49    pub fn as_u64(self) -> u64 {
50        self.0
51    }
52
53    pub fn for_testing() -> Self {
54        env::var("NETWORK_MAGIC").ok().and_then(|s| s.parse().ok()).unwrap_or(Self::MAINNET)
55    }
56}
57
58impl Display for NetworkMagic {
59    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
60        match *self {
61            Self::TESTNET => write!(f, "testnet"),
62            Self::MAINNET => write!(f, "mainnet"),
63            Self::PREVIEW => write!(f, "preview"),
64            Self::PREPROD => write!(f, "preprod"),
65            _ => self.0.fmt(f),
66        }
67    }
68}
69
70impl std::str::FromStr for NetworkMagic {
71    type Err = ParseIntError;
72
73    fn from_str(s: &str) -> Result<Self, Self::Err> {
74        match s {
75            "testnet" => Ok(Self::TESTNET),
76            "mainnet" => Ok(Self::MAINNET),
77            "preview" => Ok(Self::PREVIEW),
78            "preprod" => Ok(Self::PREPROD),
79            _ => Ok(Self(s.parse()?)),
80        }
81    }
82}
83
84impl<C> cbor::Encode<C> for NetworkMagic {
85    fn encode<W: cbor::encode::Write>(
86        &self,
87        e: &mut cbor::Encoder<W>,
88        ctx: &mut C,
89    ) -> Result<(), cbor::encode::Error<W::Error>> {
90        self.0.encode(e, ctx)
91    }
92}
93
94impl<'b, C> cbor::Decode<'b, C> for NetworkMagic {
95    fn decode(d: &mut cbor::Decoder<'b>, ctx: &mut C) -> Result<Self, cbor::decode::Error> {
96        u64::decode(d, ctx).map(NetworkMagic)
97    }
98}
99
100#[cfg(any(test, feature = "test-utils"))]
101pub use tests::*;
102
103#[cfg(any(test, feature = "test-utils"))]
104mod tests {
105    use proptest::{
106        prelude::{Just, Strategy},
107        prop_oneof,
108    };
109
110    use super::*;
111    use crate::prop_cbor_roundtrip;
112
113    prop_cbor_roundtrip!(NetworkMagic, any_network_magic());
114
115    pub fn any_network_magic() -> impl Strategy<Value = NetworkMagic> {
116        prop_oneof![
117            1 => Just(NetworkMagic::MAINNET),
118            1 => Just(NetworkMagic::PREVIEW),
119            1 => Just(NetworkMagic::PREPROD),
120            1 => Just(NetworkMagic::TESTNET),
121        ]
122    }
123}