near_primitives_core/
types.rs

1use std::num::ParseIntError;
2use std::ops::Add;
3use std::str::FromStr;
4
5use crate::hash::CryptoHash;
6
7/// Account identifier. Provides access to user's state.
8pub use crate::account::id::AccountId;
9pub use crate::gas::Gas;
10/// Hash used by a struct implementing the Merkle tree.
11pub type MerkleHash = CryptoHash;
12/// Validator identifier in current group.
13pub type ValidatorId = u64;
14/// Mask which validators participated in multi sign.
15pub type ValidatorMask = Vec<bool>;
16/// StorageUsage is used to count the amount of storage used by a contract.
17pub type StorageUsage = u64;
18/// StorageUsageChange is used to count the storage usage within a single contract call.
19pub type StorageUsageChange = i64;
20/// Nonce for transactions.
21pub type Nonce = u64;
22/// Nonce index for gas keys.
23pub type NonceIndex = u32;
24/// Height of the block.
25pub type BlockHeight = u64;
26/// Height of the epoch.
27pub type EpochHeight = u64;
28/// Balance is type for storing amounts of tokens.
29pub type Balance = near_token::NearToken;
30/// Compute is a type for storing compute time. Measured in femtoseconds (10^-15 seconds).
31pub type Compute = u64;
32
33/// Weight of unused gas to distribute to scheduled function call actions.
34/// Used in `promise_batch_action_function_call_weight` host function.
35#[derive(Clone, Debug, PartialEq, Eq)]
36pub struct GasWeight(pub u64);
37
38/// Number of blocks in current group.
39pub type NumBlocks = u64;
40/// Number of shards in current group.
41pub type NumShards = u64;
42/// Number of seats of validators (block producer or hidden ones) in current group (settlement).
43pub type NumSeats = u64;
44/// Block height delta that measures the difference between `BlockHeight`s.
45pub type BlockHeightDelta = u64;
46
47pub type ReceiptIndex = usize;
48pub type PromiseId = Vec<ReceiptIndex>;
49
50pub type ProtocolVersion = u32;
51
52/// The ShardIndex is the index of the shard in an array of shard data.
53/// Historically the ShardId was always in the range 0..NUM_SHARDS and was used
54/// as the shard index. This is no longer the case, and the ShardIndex should be
55/// used instead.
56pub type ShardIndex = usize;
57
58/// The shard identifier. It may be an arbitrary number - it does not need to be
59/// a number in the range 0..NUM_SHARDS. The shard ids do not need to be
60/// sequential or contiguous.
61///
62/// The shard id is wrapped in a new type to prevent the old pattern of using
63/// indices in range 0..NUM_SHARDS and casting to ShardId. Once the transition
64/// if fully complete it potentially may be simplified to a regular type alias.
65#[derive(
66    arbitrary::Arbitrary,
67    borsh::BorshSerialize,
68    borsh::BorshDeserialize,
69    serde::Serialize,
70    serde::Deserialize,
71    Hash,
72    Clone,
73    Copy,
74    PartialEq,
75    Eq,
76    PartialOrd,
77    Ord,
78)]
79#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
80pub struct ShardId(u64);
81
82impl ShardId {
83    /// Create a new shard id. Please note that this function should not be used
84    /// to convert a shard index (a number in 0..num_shards range) to ShardId.
85    /// Instead the ShardId should be obtained from the shard_layout.
86    ///
87    /// ```rust, ignore
88    /// // BAD USAGE:
89    /// for shard_index in 0..num_shards {
90    ///     let shard_id = ShardId::new(shard_index); // Incorrect!!!
91    /// }
92    /// ```
93    /// ```rust, ignore
94    /// // GOOD USAGE 1:
95    /// for shard_index in 0..num_shards {
96    ///     let shard_id = shard_layout.get_shard_id(shard_index);
97    /// }
98    /// // GOOD USAGE 2:
99    /// for shard_id in shard_layout.shard_ids() {
100    ///     let shard_id = shard_layout.get_shard_id(shard_index);
101    /// }
102    /// ```
103    pub const fn new(id: u64) -> Self {
104        Self(id)
105    }
106
107    pub fn to_le_bytes(self) -> [u8; 8] {
108        self.0.to_le_bytes()
109    }
110
111    pub fn to_be_bytes(self) -> [u8; 8] {
112        self.0.to_be_bytes()
113    }
114
115    pub fn from_le_bytes(bytes: [u8; 8]) -> Self {
116        Self(u64::from_le_bytes(bytes))
117    }
118
119    // TODO This is not great, in ShardUId shard_id is u32.
120    // Currently used for some metrics so kinda ok.
121    pub fn max() -> Self {
122        Self(u64::MAX)
123    }
124}
125
126impl std::fmt::Debug for ShardId {
127    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
128        write!(f, "{}", self.0)
129    }
130}
131
132impl std::fmt::Display for ShardId {
133    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
134        write!(f, "{}", self.0)
135    }
136}
137
138impl From<u64> for ShardId {
139    fn from(id: u64) -> Self {
140        Self(id)
141    }
142}
143
144impl Into<u64> for ShardId {
145    fn into(self) -> u64 {
146        self.0
147    }
148}
149
150impl From<u32> for ShardId {
151    fn from(id: u32) -> Self {
152        Self(id as u64)
153    }
154}
155
156impl Into<u32> for ShardId {
157    fn into(self) -> u32 {
158        self.0 as u32
159    }
160}
161
162impl From<i32> for ShardId {
163    fn from(id: i32) -> Self {
164        Self(id as u64)
165    }
166}
167
168impl From<usize> for ShardId {
169    fn from(id: usize) -> Self {
170        Self(id as u64)
171    }
172}
173
174impl From<u16> for ShardId {
175    fn from(id: u16) -> Self {
176        Self(id as u64)
177    }
178}
179
180impl Into<u16> for ShardId {
181    fn into(self) -> u16 {
182        self.0 as u16
183    }
184}
185
186impl Into<usize> for ShardId {
187    fn into(self) -> usize {
188        self.0 as usize
189    }
190}
191
192impl<T> Add<T> for ShardId
193where
194    T: Add<u64, Output = u64>,
195{
196    type Output = Self;
197
198    fn add(self, rhs: T) -> Self::Output {
199        Self(T::add(rhs, self.0))
200    }
201}
202
203impl PartialEq<u64> for ShardId {
204    fn eq(&self, other: &u64) -> bool {
205        self.0 == *other
206    }
207}
208
209impl FromStr for ShardId {
210    type Err = ParseIntError;
211
212    fn from_str(s: &str) -> Result<Self, Self::Err> {
213        let shard_id = s.parse::<u64>()?;
214        Ok(ShardId(shard_id))
215    }
216}
217
218#[cfg(test)]
219mod tests {
220    use crate::types::ShardId;
221
222    // Check that the ShardId is serialized the same as u64. This is to make
223    // sure that the transition from ShardId being a type alias to being a
224    // new type is not a protocol upgrade.
225    #[test]
226    fn test_shard_id_borsh() {
227        let shard_id_u64 = 42;
228        let shard_id = ShardId::new(shard_id_u64);
229
230        assert_eq!(borsh::to_vec(&shard_id_u64).unwrap(), borsh::to_vec(&shard_id).unwrap());
231    }
232}