Skip to main content

iota_types/block/
protocol.rs

1// Copyright 2022 IOTA Stiftung
2// SPDX-License-Identifier: Apache-2.0
3
4use alloc::string::String;
5use core::borrow::Borrow;
6
7use packable::{prefix::StringPrefix, Packable};
8
9use crate::block::{helper::network_name_to_id, output::RentStructure, Error, PROTOCOL_VERSION};
10
11/// Defines the parameters of the protocol.
12#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Packable)]
13#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
14#[packable(unpack_error = Error)]
15pub struct ProtocolParameters {
16    // The version of the protocol running.
17    #[cfg_attr(feature = "serde", serde(alias = "protocolVersion"))]
18    protocol_version: u8,
19    // The human friendly name of the network.
20    #[packable(unpack_error_with = |err| Error::InvalidNetworkName(err.into_item_err()))]
21    #[cfg_attr(feature = "serde", serde(alias = "networkName"))]
22    network_name: StringPrefix<u8>,
23    // The HRP prefix used for Bech32 addresses in the network.
24    #[packable(unpack_error_with = |err| Error::InvalidBech32Hrp(err.into_item_err()))]
25    #[cfg_attr(feature = "serde", serde(alias = "bech32Hrp"))]
26    bech32_hrp: StringPrefix<u8>,
27    // The minimum pow score of the network.
28    #[cfg_attr(feature = "serde", serde(alias = "minPowScore"))]
29    min_pow_score: u32,
30    // The below max depth parameter of the network.
31    #[cfg_attr(feature = "serde", serde(alias = "belowMaxDepth"))]
32    below_max_depth: u8,
33    // The rent structure used by given node/network.
34    #[cfg_attr(feature = "serde", serde(alias = "rentStructure"))]
35    rent_structure: RentStructure,
36    // TokenSupply defines the current token supply on the network.
37    #[cfg_attr(feature = "serde", serde(alias = "tokenSupply"))]
38    token_supply: u64,
39}
40
41// This implementation is required to make [`ProtocolParameters`] a [`Packable`] visitor.
42impl Borrow<()> for ProtocolParameters {
43    fn borrow(&self) -> &() {
44        &()
45    }
46}
47
48impl Default for ProtocolParameters {
49    fn default() -> Self {
50        // PANIC: These values are known to be correct.
51        Self::new(
52            PROTOCOL_VERSION,
53            String::from("shimmer"),
54            String::from("smr"),
55            1500,
56            15,
57            RentStructure::default(),
58            1_813_620_509_061_365,
59        )
60        .unwrap()
61    }
62}
63
64impl ProtocolParameters {
65    /// Creates a new [`ProtocolParameters`].
66    pub fn new(
67        protocol_version: u8,
68        network_name: String,
69        bech32_hrp: String,
70        min_pow_score: u32,
71        below_max_depth: u8,
72        rent_structure: RentStructure,
73        token_supply: u64,
74    ) -> Result<Self, Error> {
75        Ok(Self {
76            protocol_version,
77            network_name: <StringPrefix<u8>>::try_from(network_name).map_err(Error::InvalidStringPrefix)?,
78            bech32_hrp: <StringPrefix<u8>>::try_from(bech32_hrp).map_err(Error::InvalidStringPrefix)?,
79            min_pow_score,
80            below_max_depth,
81            rent_structure,
82            token_supply,
83        })
84    }
85
86    /// Returns the protocol version of the [`ProtocolParameters`].
87    pub fn protocol_version(&self) -> u8 {
88        self.protocol_version
89    }
90
91    /// Returns the network name of the [`ProtocolParameters`].
92    pub fn network_name(&self) -> &str {
93        &self.network_name
94    }
95
96    /// Returns the network ID of the [`ProtocolParameters`].
97    pub fn network_id(&self) -> u64 {
98        network_name_to_id(&self.network_name)
99    }
100
101    /// Returns the bech32 HRP of the [`ProtocolParameters`].
102    pub fn bech32_hrp(&self) -> &str {
103        &self.bech32_hrp
104    }
105
106    /// Returns the minimum PoW score of the [`ProtocolParameters`].
107    pub fn min_pow_score(&self) -> u32 {
108        self.min_pow_score
109    }
110
111    /// Returns the below max depth of the [`ProtocolParameters`].
112    pub fn below_max_depth(&self) -> u8 {
113        self.below_max_depth
114    }
115
116    /// Returns the rent structure of the [`ProtocolParameters`].
117    pub fn rent_structure(&self) -> &RentStructure {
118        &self.rent_structure
119    }
120
121    /// Returns the token supply of the [`ProtocolParameters`].
122    pub fn token_supply(&self) -> u64 {
123        self.token_supply
124    }
125}
126
127/// Returns a [`ProtocolParameters`] for testing purposes.
128#[cfg(any(feature = "test", feature = "rand"))]
129pub fn protocol_parameters() -> ProtocolParameters {
130    ProtocolParameters::new(
131        2,
132        String::from("testnet"),
133        String::from("rms"),
134        1500,
135        15,
136        crate::block::output::RentStructure::new(500, 10, 1),
137        1_813_620_509_061_365,
138    )
139    .unwrap()
140}
141
142#[cfg(feature = "dto")]
143#[allow(missing_docs)]
144pub mod dto {
145
146    use super::*;
147    use crate::block::{error::dto::DtoError, output::dto::RentStructureDto};
148
149    #[derive(Clone, Debug, Eq, PartialEq)]
150    #[cfg_attr(
151        feature = "serde",
152        derive(serde::Serialize, serde::Deserialize),
153        serde(rename_all = "camelCase")
154    )]
155    pub struct ProtocolParametersDto {
156        #[cfg_attr(feature = "serde", serde(rename = "version"))]
157        pub protocol_version: u8,
158        pub network_name: String,
159        pub bech32_hrp: String,
160        pub min_pow_score: u32,
161        pub below_max_depth: u8,
162        pub rent_structure: RentStructureDto,
163        pub token_supply: String,
164    }
165
166    impl TryFrom<ProtocolParametersDto> for ProtocolParameters {
167        type Error = DtoError;
168
169        fn try_from(value: ProtocolParametersDto) -> Result<Self, Self::Error> {
170            Ok(Self::new(
171                value.protocol_version,
172                value.network_name,
173                value.bech32_hrp,
174                value.min_pow_score,
175                value.below_max_depth,
176                value.rent_structure.into(),
177                value
178                    .token_supply
179                    .parse()
180                    .map_err(|_| DtoError::InvalidField("token_supply"))?,
181            )?)
182        }
183    }
184}