Skip to main content

ethrex_common/
utils.rs

1use crate::H256;
2use ethereum_types::U256;
3use ethrex_crypto::keccak::keccak_hash;
4use hex::FromHexError;
5
6pub const ZERO_U256: U256 = U256([0, 0, 0, 0]);
7
8/// Converts a big endian slice to a u256, faster than `u256::from_big_endian`.
9pub fn u256_from_big_endian(slice: &[u8]) -> U256 {
10    let mut padded = [0u8; 32];
11    padded[32 - slice.len()..32].copy_from_slice(slice);
12
13    let mut ret = [0; 4];
14
15    let mut u64_bytes = [0u8; 8];
16    for i in 0..4 {
17        u64_bytes.copy_from_slice(&padded[8 * i..(8 * i + 8)]);
18        ret[4 - i - 1] = u64::from_be_bytes(u64_bytes);
19    }
20
21    U256(ret)
22}
23
24/// Converts a constant big endian slice to a u256, faster than `u256::from_big_endian` and `u256_from_big_endian`.
25///
26/// Note: N should not exceed 32.
27pub fn u256_from_big_endian_const<const N: usize>(slice: [u8; N]) -> U256 {
28    const { assert!(N <= 32, "N must be less or equal to 32") };
29
30    let mut padded = [0u8; 32];
31    padded[32 - N..32].copy_from_slice(&slice);
32
33    let mut ret = [0u64; 4];
34
35    let mut u64_bytes = [0u8; 8];
36    for i in 0..4 {
37        u64_bytes.copy_from_slice(&padded[8 * i..(8 * i + 8)]);
38        ret[4 - i - 1] = u64::from_be_bytes(u64_bytes);
39    }
40
41    U256(ret)
42}
43
44/// Converts a U256 to a big endian slice.
45#[inline(always)]
46pub fn u256_to_big_endian(value: U256) -> [u8; 32] {
47    let mut bytes = [0u8; 32];
48
49    for i in 0..4 {
50        let u64_be = value.0[4 - i - 1].to_be_bytes();
51        bytes[8 * i..(8 * i + 8)].copy_from_slice(&u64_be);
52    }
53
54    bytes
55}
56
57#[inline(always)]
58pub fn u256_to_h256(value: U256) -> H256 {
59    H256(u256_to_big_endian(value))
60}
61
62pub fn decode_hex(hex: &str) -> Result<Vec<u8>, FromHexError> {
63    let trimmed = hex.strip_prefix("0x").unwrap_or(hex);
64    hex::decode(trimmed)
65}
66
67pub fn keccak(data: impl AsRef<[u8]>) -> H256 {
68    H256(keccak_hash(data))
69}
70
71// Allocation-free operations on arrays.
72///
73/// Truncates an array of size N to size M.
74/// Fails compilation if N < M.
75pub fn truncate_array<const N: usize, const M: usize>(data: [u8; N]) -> [u8; M] {
76    const { assert!(M <= N) };
77    let mut res = [0u8; M];
78    res.copy_from_slice(&data[..M]);
79    res
80}