1extern crate alloc;
2use alloc::vec::Vec;
3
4pub const MAINNET_GENESIS_HASH: &[u8] = &[
6 74u8, 88, 123, 241, 122, 64, 78, 53, 114, 116, 122, 221, 122, 171, 123, 190, 86, 232, 5, 165,
7 71, 156, 108, 67, 111, 7, 243, 111, 204, 141, 58, 225,
8];
9
10pub const TESTNET_ON_PASEO_GENESIS_HASH: &[u8] = &[
12 32, 60, 104, 56, 252, 120, 234, 54, 96, 162, 242, 152, 165, 141, 133, 149, 25, 199, 42, 94,
13 253, 192, 241, 148, 171, 214, 240, 213, 206, 24, 56, 224,
14];
15
16pub const TESTNET_ON_WESTEND_GENESIS_HASH: &[u8] = &[
18 225, 67, 242, 56, 3, 172, 80, 232, 246, 248, 230, 38, 149, 209, 206, 158, 78, 29, 104, 170, 54,
19 193, 205, 44, 253, 21, 52, 2, 19, 243, 66, 62,
20];
21
22#[derive(Debug, Clone, PartialEq)]
24pub enum DetectedChainType {
25 Unknown,
27 FrequencyMainNet,
29 FrequencyPaseoTestNet,
31 FrequencyWestendTestNet,
33}
34
35pub fn get_chain_type_by_genesis_hash(genesis_hash: &[u8]) -> DetectedChainType {
37 match genesis_hash {
38 MAINNET_GENESIS_HASH => DetectedChainType::FrequencyMainNet,
39 TESTNET_ON_PASEO_GENESIS_HASH => DetectedChainType::FrequencyPaseoTestNet,
40 TESTNET_ON_WESTEND_GENESIS_HASH => DetectedChainType::FrequencyWestendTestNet,
41 _ => DetectedChainType::Unknown,
42 }
43}
44
45pub fn to_abi_compatible_number<T: Into<u128>>(value: T) -> [u8; 32] {
47 let value_u128: u128 = value.into();
48 let bytes = value_u128.to_be_bytes();
49 let start_idx = 32 - bytes.len();
50 let mut result = [0u8; 32];
51 result[start_idx..].copy_from_slice(&bytes);
52 result
53}
54
55#[cfg(feature = "std")]
57pub mod as_hex {
58 use serde::{Deserializer, Serializer};
59
60 pub fn serialize<S>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
62 where
63 S: Serializer,
64 {
65 impl_serde::serialize::serialize(bytes.as_slice(), serializer)
66 }
67
68 pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
70 impl_serde::serialize::deserialize(deserializer)
71 }
72}
73
74#[cfg(feature = "std")]
76pub mod as_hex_option {
77 use serde::{Deserializer, Serializer};
78
79 pub fn serialize<S>(bytes: &Option<Vec<u8>>, serializer: S) -> Result<S::Ok, S::Error>
81 where
82 S: Serializer,
83 {
84 match bytes {
85 Some(bytes) => impl_serde::serialize::serialize(bytes.as_slice(), serializer),
86 None => serializer.serialize_none(),
87 }
88 }
89
90 pub fn deserialize<'de, D>(deserializer: D) -> Result<Option<Vec<u8>>, D::Error>
92 where
93 D: Deserializer<'de>,
94 {
95 impl_serde::serialize::deserialize(deserializer).map(Some)
96 }
97}
98#[cfg(feature = "std")]
100pub mod as_string {
101 use super::*;
102 use serde::{ser::Error, Deserialize, Deserializer, Serialize, Serializer};
103
104 pub fn serialize<S: Serializer>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> {
106 std::str::from_utf8(bytes)
107 .map_err(|e| S::Error::custom(format!("Debug buffer contains invalid UTF8: {e:?}")))?
108 .serialize(serializer)
109 }
110
111 pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> {
113 Ok(String::deserialize(deserializer)?.into_bytes())
114 }
115}
116
117#[cfg(feature = "std")]
119pub mod as_string_option {
120 use super::*;
121 use serde::{ser::Error, Deserialize, Deserializer, Serialize, Serializer};
122
123 pub fn serialize<S: Serializer>(
125 bytes: &Option<Vec<u8>>,
126 serializer: S,
127 ) -> Result<S::Ok, S::Error> {
128 match bytes {
129 Some(bytes) => std::str::from_utf8(bytes)
130 .map_err(|e| {
131 S::Error::custom(format!("Debug buffer contains invalid UTF8: {e:?}"))
132 })?
133 .serialize(serializer),
134 None => serializer.serialize_none(),
135 }
136 }
137
138 pub fn deserialize<'de, D: Deserializer<'de>>(
140 deserializer: D,
141 ) -> Result<Option<Vec<u8>>, D::Error> {
142 let bytes = String::deserialize(deserializer)?.into_bytes();
143 Ok(match bytes.len() {
144 0 => None,
145 _ => Some(bytes),
146 })
147 }
148}
149
150const PREFIX: &str = "<Bytes>";
151const POSTFIX: &str = "</Bytes>";
152
153pub fn wrap_binary_data(data: Vec<u8>) -> Vec<u8> {
156 let mut encapsuled = PREFIX.as_bytes().to_vec();
157 encapsuled.append(&mut data.clone());
158 encapsuled.append(&mut POSTFIX.as_bytes().to_vec());
159 encapsuled
160}
161
162#[cfg(any(test, feature = "runtime-benchmarks"))]
165pub struct XorRng {
166 state: u64,
167}
168
169#[cfg(any(test, feature = "runtime-benchmarks"))]
170impl XorRng {
171 pub fn new(seed: u64) -> Self {
173 Self { state: if seed == 0 { 1 } else { seed } }
174 }
175
176 pub fn gen_u8(&mut self) -> u8 {
178 self.state ^= self.state << 13;
180 self.state ^= self.state >> 7;
181 self.state ^= self.state << 17;
182 self.state as u8
183 }
184}
185
186#[cfg(test)]
187mod tests {
188 use super::*;
189 use impl_serde::serialize::from_hex;
190 use parity_scale_codec::{Decode, Encode};
191 use scale_info::TypeInfo;
192 use serde::{Deserialize, Serialize};
193 use sp_core::U256;
194
195 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
196 #[derive(Default, Clone, Encode, Decode, PartialEq, Debug, TypeInfo, Eq)]
197 struct TestAsHex {
198 #[cfg_attr(feature = "std", serde(with = "as_hex",))]
199 pub data: Vec<u8>,
200 }
201
202 #[test]
203 fn as_hex_can_serialize() {
204 let test_data = TestAsHex { data: vec![1, 2, 3, 4] };
205 let result = serde_json::to_string(&test_data);
206 assert!(result.is_ok());
207 assert_eq!("{\"data\":\"0x01020304\"}", result.unwrap());
208 }
209
210 #[test]
211 fn as_hex_can_deserialize() {
212 let result: Result<TestAsHex, serde_json::Error> =
213 serde_json::from_str("{\"data\":\"0x01020304\"}");
214 assert!(result.is_ok());
215 assert_eq!(vec![1, 2, 3, 4], result.unwrap().data);
216 }
217
218 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
219 #[derive(Default, Clone, Encode, Decode, PartialEq, Debug, TypeInfo, Eq)]
220 struct TestAsHexOption {
221 #[cfg_attr(
222 feature = "std",
223 serde(with = "as_hex_option", skip_serializing_if = "Option::is_none", default)
224 )]
225 pub data: Option<Vec<u8>>,
226 }
227
228 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
229 #[derive(Default, Clone, Encode, Decode, PartialEq, Debug, TypeInfo, Eq)]
230 struct TestAsHexOptionNull {
231 #[cfg_attr(feature = "std", serde(with = "as_hex_option", default))]
232 pub data: Option<Vec<u8>>,
233 }
234
235 #[test]
236 fn as_hex_option_can_serialize() {
237 let test_data = TestAsHexOption { data: Some(vec![1, 2, 3, 4]) };
238 let result = serde_json::to_string(&test_data);
239 assert!(result.is_ok());
240 assert_eq!("{\"data\":\"0x01020304\"}", result.unwrap());
241 }
242
243 #[test]
244 fn as_hex_option_can_deserialize() {
245 let result: Result<TestAsHexOption, serde_json::Error> =
246 serde_json::from_str("{\"data\":\"0x01020304\"}");
247 assert!(result.is_ok());
248 assert_eq!(Some(vec![1, 2, 3, 4]), result.unwrap().data);
249 }
250
251 #[test]
252 fn as_hex_option_can_serialize_nothing_with_skip() {
253 let test_data = TestAsHexOption { data: None };
254 let result = serde_json::to_string(&test_data);
255 assert!(result.is_ok());
256 assert_eq!("{}", result.unwrap());
257 }
258
259 #[test]
260 fn as_hex_option_can_serialize_nothing_as_null() {
261 let test_data = TestAsHexOptionNull { data: None };
262 let result = serde_json::to_string(&test_data);
263 assert!(result.is_ok());
264 assert_eq!("{\"data\":null}", result.unwrap());
265 }
266
267 #[test]
268 fn as_hex_option_can_deserialize_nothing() {
269 let result: Result<TestAsHexOption, serde_json::Error> = serde_json::from_str("{}");
270 assert!(result.is_ok());
271 assert_eq!(None, result.unwrap().data);
272 }
273
274 #[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
275 #[derive(Default, Clone, Encode, Decode, PartialEq, Debug, TypeInfo, Eq)]
276 struct TestAsString {
277 #[cfg_attr(feature = "std", serde(with = "as_string"))]
278 pub data: Vec<u8>,
279 }
280
281 #[test]
282 fn as_string_can_serialize() {
283 let test_data = TestAsString {
284 data: vec![
285 0xe8, 0x95, 0x99, 0x49, 0xdd, 0x9d, 0xcd, 0x99, 0xe0, 0xbc, 0x8d, 0x4c, 0xd0, 0xbc,
286 ],
287 };
288 let result = serde_json::to_string(&test_data);
289 assert!(result.is_ok());
290 assert_eq!("{\"data\":\"蕙Iݝ͙།Lм\"}", result.unwrap());
291 }
292
293 #[test]
294 fn as_string_can_deserialize() {
295 let result: Result<TestAsString, serde_json::Error> =
296 serde_json::from_str("{\"data\":\"蕙Iݝ͙།Lм\"}");
297 assert!(result.is_ok());
298 assert_eq!(
299 vec![
300 0xe8, 0x95, 0x99, 0x49, 0xdd, 0x9d, 0xcd, 0x99, 0xe0, 0xbc, 0x8d, 0x4c, 0xd0, 0xbc
301 ],
302 result.unwrap().data
303 );
304 }
305
306 #[test]
307 fn as_string_errors_for_bad_utf8_vec() {
308 let test_data = TestAsString { data: vec![0xc3, 0x28] };
309 let result = serde_json::to_string(&test_data);
310 assert!(result.is_err());
311 }
312
313 #[test]
314 fn as_string_errors_for_bad_utf8_str() {
315 let result: Result<TestAsString, serde_json::Error> =
316 serde_json::from_str("{\"data\":\"\\xa0\\xa1\"}");
317 assert!(result.is_err());
318 }
319
320 #[test]
321 fn get_chain_type_by_genesis_hash_with_mainnet_genesis_should_get_mainnet() {
322 let known_genesis =
324 from_hex("4a587bf17a404e3572747add7aab7bbe56e805a5479c6c436f07f36fcc8d3ae1").unwrap();
325
326 let detected = get_chain_type_by_genesis_hash(&known_genesis);
328
329 assert_eq!(detected, DetectedChainType::FrequencyMainNet);
331 }
332
333 #[test]
334 fn get_chain_type_by_genesis_hash_with_paseo_genesis_should_get_paseo() {
335 let known_genesis =
337 from_hex("203c6838fc78ea3660a2f298a58d859519c72a5efdc0f194abd6f0d5ce1838e0").unwrap();
338
339 let detected = get_chain_type_by_genesis_hash(&known_genesis);
341
342 assert_eq!(detected, DetectedChainType::FrequencyPaseoTestNet);
344 }
345
346 #[test]
347 fn abi_compatible_number_should_work_with_different_types() {
348 let u8_val: u8 = 42;
350 let coded_u8_val = to_abi_compatible_number(u8_val);
351 let u8_val: U256 = u8_val.into();
352 assert_eq!(
353 coded_u8_val.to_vec(),
354 sp_core::bytes::from_hex(&format!("0x{:064x}", u8_val)).unwrap()
355 );
356
357 let u16_val: u16 = 12345;
359 let coded_u16_val = to_abi_compatible_number(u16_val);
360 let u16_val: U256 = u16_val.into();
361 assert_eq!(
362 coded_u16_val.to_vec(),
363 sp_core::bytes::from_hex(&format!("0x{:064x}", u16_val)).unwrap()
364 );
365
366 let u32_val: u32 = 305419896;
368 let coded_u32_val = to_abi_compatible_number(u32_val);
369 let u32_val: U256 = u32_val.into();
370 assert_eq!(
371 coded_u32_val.to_vec(),
372 sp_core::bytes::from_hex(&format!("0x{:064x}", u32_val)).unwrap()
373 );
374
375 let u64_val: u64 = 1234567890123456789;
377 let coded_u64_val = to_abi_compatible_number(u64_val);
378 let u64_val: U256 = u64_val.into();
379 assert_eq!(
380 coded_u64_val.to_vec(),
381 sp_core::bytes::from_hex(&format!("0x{:064x}", u64_val)).unwrap()
382 );
383
384 let u128_val: u128 = 340282366920938463463374607431768211455; let coded_u128_val = to_abi_compatible_number(u128_val);
387 let u128_val: U256 = u128_val.into();
388 assert_eq!(
389 coded_u128_val.to_vec(),
390 sp_core::bytes::from_hex(&format!("0x{:064x}", u128_val)).unwrap()
391 );
392 }
393
394 #[test]
395 fn get_chain_type_by_genesis_hash_with_westend_genesis_should_get_westend() {
396 let known_genesis =
398 from_hex("e143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e").unwrap();
399
400 let detected = get_chain_type_by_genesis_hash(&known_genesis);
402
403 assert_eq!(detected, DetectedChainType::FrequencyWestendTestNet);
405 }
406}