Skip to main content

evm_state_diff/
primitives.rs

1use std::cmp::Ordering;
2use std::fmt;
3use std::str::FromStr;
4
5use serde::de::{self, Visitor};
6use serde::{Deserialize, Deserializer, Serialize, Serializer};
7
8#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
9pub enum ParseError {
10    #[error("missing 0x prefix in `{0}`")]
11    MissingPrefix(String),
12    #[error("invalid hex in `{0}`")]
13    InvalidHex(String),
14    #[error("`{input}` is not {expected} bytes")]
15    WrongLength { input: String, expected: usize },
16    #[error("`{0}` does not fit in 256 bits")]
17    Overflow(String),
18    #[error("invalid decimal number `{0}`")]
19    InvalidDecimal(String),
20}
21
22pub(crate) fn decode_hex(s: &str) -> Result<Vec<u8>, ParseError> {
23    let digits = s
24        .strip_prefix("0x")
25        .or_else(|| s.strip_prefix("0X"))
26        .ok_or_else(|| ParseError::MissingPrefix(s.into()))?;
27    let padded;
28    let digits = if digits.len() % 2 == 1 {
29        padded = format!("0{digits}");
30        padded.as_str()
31    } else {
32        digits
33    };
34    digits
35        .as_bytes()
36        .chunks(2)
37        .map(|pair| {
38            let hi = (pair[0] as char).to_digit(16);
39            let lo = (pair[1] as char).to_digit(16);
40            match (hi, lo) {
41                (Some(h), Some(l)) => Ok((h * 16 + l) as u8),
42                _ => Err(ParseError::InvalidHex(s.into())),
43            }
44        })
45        .collect()
46}
47
48pub(crate) fn encode_hex(bytes: &[u8]) -> String {
49    const DIGITS: &[u8; 16] = b"0123456789abcdef";
50    let mut out = String::with_capacity(2 + bytes.len() * 2);
51    out.push_str("0x");
52    for b in bytes {
53        out.push(DIGITS[(b >> 4) as usize] as char);
54        out.push(DIGITS[(b & 0xf) as usize] as char);
55    }
56    out
57}
58
59macro_rules! fixed_bytes {
60    ($name:ident, $len:expr) => {
61        #[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
62        pub struct $name(pub [u8; $len]);
63
64        impl $name {
65            pub const ZERO: Self = Self([0; $len]);
66
67            pub fn is_zero(&self) -> bool {
68                self.0 == [0; $len]
69            }
70        }
71
72        impl FromStr for $name {
73            type Err = ParseError;
74
75            fn from_str(s: &str) -> Result<Self, ParseError> {
76                let bytes = decode_hex(s)?;
77                let array = bytes
78                    .try_into()
79                    .map_err(|_| ParseError::WrongLength { input: s.into(), expected: $len })?;
80                Ok(Self(array))
81            }
82        }
83
84        impl fmt::Display for $name {
85            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
86                f.write_str(&encode_hex(&self.0))
87            }
88        }
89
90        impl fmt::Debug for $name {
91            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
92                fmt::Display::fmt(self, f)
93            }
94        }
95
96        impl Serialize for $name {
97            fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
98                s.serialize_str(&self.to_string())
99            }
100        }
101
102        impl<'de> Deserialize<'de> for $name {
103            fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
104                let s = String::deserialize(d)?;
105                s.parse().map_err(de::Error::custom)
106            }
107        }
108    };
109}
110
111fixed_bytes!(Address, 20);
112fixed_bytes!(B256, 32);
113
114impl B256 {
115    /// Storage values are 32-byte words, but geth may print them left-trimmed.
116    pub fn from_word(s: &str) -> Result<Self, ParseError> {
117        let bytes = decode_hex(s)?;
118        if bytes.len() > 32 {
119            return Err(ParseError::WrongLength { input: s.into(), expected: 32 });
120        }
121        let mut out = [0u8; 32];
122        out[32 - bytes.len()..].copy_from_slice(&bytes);
123        Ok(Self(out))
124    }
125}
126
127/// keccak256 of empty code.
128pub const EMPTY_CODE_HASH: B256 = B256([
129    0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c, 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, 0xc0, 0xe5,
130    0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, 0xa4, 0x70,
131]);
132
133/// Contract code as raw bytes.
134#[derive(Clone, Default, PartialEq, Eq, Hash)]
135pub struct Bytes(pub Vec<u8>);
136
137impl Bytes {
138    pub fn len(&self) -> usize {
139        self.0.len()
140    }
141
142    pub fn is_empty(&self) -> bool {
143        self.0.is_empty()
144    }
145}
146
147impl fmt::Display for Bytes {
148    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
149        f.write_str(&encode_hex(&self.0))
150    }
151}
152
153impl fmt::Debug for Bytes {
154    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
155        write!(f, "Bytes({} bytes)", self.0.len())
156    }
157}
158
159impl Serialize for Bytes {
160    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
161        s.serialize_str(&self.to_string())
162    }
163}
164
165impl<'de> Deserialize<'de> for Bytes {
166    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
167        let s = String::deserialize(d)?;
168        decode_hex(&s).map(Bytes).map_err(de::Error::custom)
169    }
170}
171
172/// 256-bit unsigned integer (wei amounts), little-endian 64-bit limbs.
173#[derive(Clone, Copy, Default, PartialEq, Eq, Hash)]
174pub struct U256([u64; 4]);
175
176impl U256 {
177    pub const ZERO: Self = Self([0; 4]);
178    pub const MAX: Self = Self([u64::MAX; 4]);
179
180    pub fn from_u128(v: u128) -> Self {
181        Self([v as u64, (v >> 64) as u64, 0, 0])
182    }
183
184    pub fn is_zero(&self) -> bool {
185        self.0 == [0; 4]
186    }
187
188    pub fn from_be_slice(bytes: &[u8]) -> Option<Self> {
189        let trimmed = &bytes[bytes.iter().position(|&b| b != 0).unwrap_or(bytes.len())..];
190        if trimmed.len() > 32 {
191            return None;
192        }
193        let mut word = [0u8; 32];
194        word[32 - trimmed.len()..].copy_from_slice(trimmed);
195        let mut limbs = [0u64; 4];
196        for (i, limb) in limbs.iter_mut().enumerate() {
197            let start = 32 - 8 * (i + 1);
198            *limb = u64::from_be_bytes(word[start..start + 8].try_into().expect("8 bytes"));
199        }
200        Some(Self(limbs))
201    }
202
203    pub fn to_be_bytes(self) -> [u8; 32] {
204        let mut out = [0u8; 32];
205        for (i, limb) in self.0.iter().enumerate() {
206            let start = 32 - 8 * (i + 1);
207            out[start..start + 8].copy_from_slice(&limb.to_be_bytes());
208        }
209        out
210    }
211
212    pub fn from_hex(s: &str) -> Result<Self, ParseError> {
213        let bytes = decode_hex(s)?;
214        Self::from_be_slice(&bytes).ok_or_else(|| ParseError::Overflow(s.into()))
215    }
216
217    pub fn from_dec(s: &str) -> Result<Self, ParseError> {
218        if s.is_empty() || !s.bytes().all(|b| b.is_ascii_digit()) {
219            return Err(ParseError::InvalidDecimal(s.into()));
220        }
221        let mut out = Self::ZERO;
222        for b in s.bytes() {
223            out = out
224                .checked_mul_small(10)
225                .and_then(|v| v.checked_add(Self::from_u128(u128::from(b - b'0'))))
226                .ok_or_else(|| ParseError::Overflow(s.into()))?;
227        }
228        Ok(out)
229    }
230
231    pub fn checked_add(self, rhs: Self) -> Option<Self> {
232        let mut out = [0u64; 4];
233        let mut carry = false;
234        for (o, (a, b)) in out.iter_mut().zip(self.0.iter().zip(rhs.0)) {
235            let (s1, c1) = a.overflowing_add(b);
236            let (s2, c2) = s1.overflowing_add(u64::from(carry));
237            *o = s2;
238            carry = c1 || c2;
239        }
240        (!carry).then_some(Self(out))
241    }
242
243    pub fn checked_sub(self, rhs: Self) -> Option<Self> {
244        let mut out = [0u64; 4];
245        let mut borrow = false;
246        for (o, (a, b)) in out.iter_mut().zip(self.0.iter().zip(rhs.0)) {
247            let (d1, b1) = a.overflowing_sub(b);
248            let (d2, b2) = d1.overflowing_sub(u64::from(borrow));
249            *o = d2;
250            borrow = b1 || b2;
251        }
252        (!borrow).then_some(Self(out))
253    }
254
255    fn checked_mul_small(self, m: u64) -> Option<Self> {
256        let mut out = [0u64; 4];
257        let mut carry = 0u128;
258        for (o, a) in out.iter_mut().zip(self.0) {
259            let v = u128::from(a) * u128::from(m) + carry;
260            *o = v as u64;
261            carry = v >> 64;
262        }
263        (carry == 0).then_some(Self(out))
264    }
265
266    fn div_rem_small(self, d: u64) -> (Self, u64) {
267        let mut out = [0u64; 4];
268        let mut rem = 0u128;
269        for i in (0..4).rev() {
270            let v = (rem << 64) | u128::from(self.0[i]);
271            out[i] = (v / u128::from(d)) as u64;
272            rem = v % u128::from(d);
273        }
274        (Self(out), rem as u64)
275    }
276
277    pub fn to_hex_quantity(self) -> String {
278        if self.is_zero() {
279            return "0x0".into();
280        }
281        let hex = encode_hex(&self.to_be_bytes());
282        format!("0x{}", hex[2..].trim_start_matches('0'))
283    }
284
285    /// Formats a wei amount in ether with up to 18 decimals, trailing zeros removed.
286    pub fn format_ether(self) -> String {
287        let s = self.to_string();
288        let (int, frac) = if s.len() > 18 { s.split_at(s.len() - 18) } else { ("0", s.as_str()) };
289        let frac = format!("{frac:0>18}");
290        let frac = frac.trim_end_matches('0');
291        if frac.is_empty() { int.to_string() } else { format!("{int}.{frac}") }
292    }
293}
294
295impl Ord for U256 {
296    fn cmp(&self, other: &Self) -> Ordering {
297        self.0.iter().rev().cmp(other.0.iter().rev())
298    }
299}
300
301impl PartialOrd for U256 {
302    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
303        Some(self.cmp(other))
304    }
305}
306
307impl fmt::Display for U256 {
308    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
309        if self.is_zero() {
310            return f.write_str("0");
311        }
312        let mut digits = Vec::new();
313        let mut v = *self;
314        while !v.is_zero() {
315            let (q, r) = v.div_rem_small(10);
316            digits.push(b'0' + r as u8);
317            v = q;
318        }
319        digits.reverse();
320        f.write_str(std::str::from_utf8(&digits).expect("ascii"))
321    }
322}
323
324impl fmt::Debug for U256 {
325    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
326        fmt::Display::fmt(self, f)
327    }
328}
329
330impl FromStr for U256 {
331    type Err = ParseError;
332
333    /// Accepts `0x` hex quantities and plain decimals.
334    fn from_str(s: &str) -> Result<Self, ParseError> {
335        if s.starts_with("0x") || s.starts_with("0X") { Self::from_hex(s) } else { Self::from_dec(s) }
336    }
337}
338
339impl Serialize for U256 {
340    fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
341        s.serialize_str(&self.to_string())
342    }
343}
344
345/// Accepts hex strings, decimal strings and JSON numbers, since clients differ.
346impl<'de> Deserialize<'de> for U256 {
347    fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
348        struct V;
349        impl Visitor<'_> for V {
350            type Value = U256;
351
352            fn expecting(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
353                f.write_str("a hex or decimal quantity")
354            }
355
356            fn visit_u64<E: de::Error>(self, v: u64) -> Result<U256, E> {
357                Ok(U256::from_u128(u128::from(v)))
358            }
359
360            fn visit_str<E: de::Error>(self, v: &str) -> Result<U256, E> {
361                v.parse().map_err(E::custom)
362            }
363        }
364        d.deserialize_any(V)
365    }
366}
367
368/// Deserializes a `u64` given as a JSON number or a hex/decimal string.
369pub(crate) fn de_quantity_u64<'de, D: Deserializer<'de>>(d: D) -> Result<Option<u64>, D::Error> {
370    let v = Option::<U256>::deserialize(d)?;
371    v.map(|v| {
372        let limbs = v.0;
373        if limbs[1..] == [0, 0, 0] { Ok(limbs[0]) } else { Err(de::Error::custom("nonce exceeds 64 bits")) }
374    })
375    .transpose()
376}
377
378/// A signed difference between two `U256` values.
379#[derive(Clone, Copy, Debug, PartialEq, Eq)]
380pub struct Delta {
381    pub negative: bool,
382    pub magnitude: U256,
383}
384
385impl Delta {
386    pub fn between(from: U256, to: U256) -> Self {
387        match to.checked_sub(from) {
388            Some(m) => Self { negative: false, magnitude: m },
389            None => Self { negative: true, magnitude: from.checked_sub(to).expect("from > to") },
390        }
391    }
392
393    fn sign(&self) -> &'static str {
394        if self.magnitude.is_zero() {
395            ""
396        } else if self.negative {
397            "-"
398        } else {
399            "+"
400        }
401    }
402
403    pub fn format_ether(&self) -> String {
404        format!("{}{}", self.sign(), self.magnitude.format_ether())
405    }
406}
407
408impl fmt::Display for Delta {
409    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
410        write!(f, "{}{}", self.sign(), self.magnitude)
411    }
412}
413
414#[cfg(test)]
415mod tests {
416    use super::*;
417
418    #[test]
419    fn address_round_trip() {
420        let a: Address = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8".parse().unwrap();
421        assert_eq!(a.to_string(), "0x70997970c51812dc3a010c7d01b50e0d17dc79c8");
422        assert!("70997970c51812dc3a010c7d01b50e0d17dc79c8".parse::<Address>().is_err());
423        assert!("0x1234".parse::<Address>().is_err());
424        assert!("0xzz997970c51812dc3a010c7d01b50e0d17dc79c8".parse::<Address>().is_err());
425    }
426
427    #[test]
428    fn u256_parsing_and_display() {
429        let max = "115792089237316195423570985008687907853269984665640564039457584007913129639935";
430        assert_eq!(U256::from_dec(max).unwrap(), U256::MAX);
431        assert_eq!(U256::MAX.to_string(), max);
432        assert_eq!(U256::from_hex(&U256::MAX.to_hex_quantity()).unwrap(), U256::MAX);
433        assert_eq!("0x0".parse::<U256>().unwrap(), U256::ZERO);
434        assert_eq!("0xde0b6b3a7640000".parse::<U256>().unwrap().to_string(), "1000000000000000000");
435        assert!(U256::from_dec(&format!("{max}0")).is_err());
436        assert!(U256::from_hex(&format!("0x1{}", "0".repeat(64))).is_err());
437        assert_eq!(U256::ZERO.to_hex_quantity(), "0x0");
438        assert_eq!(U256::from_u128(255).to_hex_quantity(), "0xff");
439    }
440
441    #[test]
442    fn ether_formatting() {
443        assert_eq!(U256::from_dec("1000000000000000000").unwrap().format_ether(), "1");
444        assert_eq!(U256::from_dec("1500000000000000000").unwrap().format_ether(), "1.5");
445        assert_eq!(U256::from_u128(21000).format_ether(), "0.000000000000021");
446        assert_eq!(U256::ZERO.format_ether(), "0");
447    }
448
449    #[test]
450    fn deltas() {
451        let a = U256::from_u128(10);
452        let b = U256::from_u128(3);
453        assert_eq!(Delta::between(a, b).to_string(), "-7");
454        assert_eq!(Delta::between(b, a).to_string(), "+7");
455        assert_eq!(Delta::between(a, a).to_string(), "0");
456        assert!(U256::MAX.checked_add(U256::from_u128(1)).is_none());
457        assert!(U256::ZERO.checked_sub(U256::from_u128(1)).is_none());
458        assert!(U256::from_u128(1 << 64) > U256::from_u128(u64::MAX as u128));
459    }
460
461    #[test]
462    fn storage_words() {
463        assert_eq!(B256::from_word("0x7").unwrap().0[31], 7);
464        assert!(B256::from_word(&format!("0x{}", "11".repeat(33))).is_err());
465    }
466}