bee_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::{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(
14    feature = "serde",
15    derive(serde::Serialize, serde::Deserialize),
16    serde(rename_all = "camelCase")
17)]
18#[packable(unpack_error = Error)]
19pub struct ProtocolParameters {
20    // The version of the protocol running.
21    protocol_version: u8,
22    // The human friendly name of the network.
23    #[packable(unpack_error_with = |err| Error::InvalidNetworkName(err.into_item_err()))]
24    network_name: StringPrefix<u8>,
25    // The HRP prefix used for Bech32 addresses in the network.
26    #[packable(unpack_error_with = |err| Error::InvalidBech32Hrp(err.into_item_err()))]
27    bech32_hrp: StringPrefix<u8>,
28    // The minimum pow score of the network.
29    min_pow_score: u32,
30    // The below max depth parameter of the network.
31    below_max_depth: u8,
32    // The rent structure used by given node/network.
33    rent_structure: RentStructure,
34    // TokenSupply defines the current token supply on the network.
35    token_supply: u64,
36}
37
38// This implementation is required to make [`ProtocolParameters`] a [`Packable`] visitor.
39impl Borrow<()> for ProtocolParameters {
40    fn borrow(&self) -> &() {
41        &()
42    }
43}
44
45impl Default for ProtocolParameters {
46    fn default() -> Self {
47        // PANIC: These values are known to be correct.
48        Self::new(
49            PROTOCOL_VERSION,
50            String::from("shimmer"),
51            String::from("smr"),
52            1500,
53            15,
54            RentStructure::default(),
55            1_813_620_509_061_365,
56        )
57        .unwrap()
58    }
59}
60
61impl ProtocolParameters {
62    /// Creates a new [`ProtocolParameters`].
63    pub fn new(
64        protocol_version: u8,
65        network_name: String,
66        bech32_hrp: String,
67        min_pow_score: u32,
68        below_max_depth: u8,
69        rent_structure: RentStructure,
70        token_supply: u64,
71    ) -> Result<ProtocolParameters, Error> {
72        Ok(ProtocolParameters {
73            protocol_version,
74            network_name: <StringPrefix<u8>>::try_from(network_name).map_err(Error::InvalidStringPrefix)?,
75            bech32_hrp: <StringPrefix<u8>>::try_from(bech32_hrp).map_err(Error::InvalidStringPrefix)?,
76            min_pow_score,
77            below_max_depth,
78            rent_structure,
79            token_supply,
80        })
81    }
82
83    /// Returns the protocol version of the [`ProtocolParameters`].
84    pub fn protocol_version(&self) -> u8 {
85        self.protocol_version
86    }
87
88    /// Returns the network name of the [`ProtocolParameters`].
89    pub fn network_name(&self) -> &str {
90        &self.network_name
91    }
92
93    /// Returns the network ID of the [`ProtocolParameters`].
94    pub fn network_id(&self) -> u64 {
95        network_name_to_id(&self.network_name)
96    }
97
98    /// Returns the bech32 HRP of the [`ProtocolParameters`].
99    pub fn bech32_hrp(&self) -> &str {
100        &self.bech32_hrp
101    }
102
103    /// Returns the minimum PoW score of the [`ProtocolParameters`].
104    pub fn min_pow_score(&self) -> u32 {
105        self.min_pow_score
106    }
107
108    /// Returns the below max depth of the [`ProtocolParameters`].
109    pub fn below_max_depth(&self) -> u8 {
110        self.below_max_depth
111    }
112
113    /// Returns the rent structure of the [`ProtocolParameters`].
114    pub fn rent_structure(&self) -> &RentStructure {
115        &self.rent_structure
116    }
117
118    /// Returns the token supply of the [`ProtocolParameters`].
119    pub fn token_supply(&self) -> u64 {
120        self.token_supply
121    }
122}
123
124/// Returns a [`ProtocolParameters`] for testing purposes.
125#[cfg(any(feature = "test", feature = "rand"))]
126pub fn protocol_parameters() -> ProtocolParameters {
127    ProtocolParameters::new(
128        2,
129        String::from("testnet"),
130        String::from("rms"),
131        1500,
132        15,
133        crate::output::RentStructure::build()
134            .byte_cost(500)
135            .key_factor(10)
136            .data_factor(1)
137            .finish(),
138        1_813_620_509_061_365,
139    )
140    .unwrap()
141}
142
143#[cfg(feature = "inx")]
144mod inx {
145    use packable::PackableExt;
146
147    use super::*;
148    use crate::InxError;
149
150    impl TryFrom<::inx::proto::RawProtocolParameters> for ProtocolParameters {
151        type Error = crate::error::inx::InxError;
152
153        fn try_from(value: ::inx::proto::RawProtocolParameters) -> Result<Self, Self::Error> {
154            Self::unpack_verified(value.params, &()).map_err(|e| InxError::InvalidRawBytes(format!("{:?}", e)))
155        }
156    }
157
158    impl From<ProtocolParameters> for ::inx::proto::RawProtocolParameters {
159        fn from(value: ProtocolParameters) -> Self {
160            Self {
161                protocol_version: value.protocol_version() as u32,
162                params: value.pack_to_vec(),
163            }
164        }
165    }
166}