fil_actor_evm_shared_state/v10/
uints.rs

1// Copyright 2019-2022 ChainSafe Systems
2// SPDX-License-Identifier: Apache-2.0, MIT
3
4// to silence construct_uint! clippy warnings
5// see https://github.com/paritytech/parity-common/issues/660
6#![allow(clippy::ptr_offset_with_cast, clippy::assign_op_pattern)]
7
8#[doc(inline)]
9pub use uint::byteorder;
10
11use serde::{Deserialize, Serialize};
12
13use {
14    fvm_shared3::bigint::BigInt, fvm_shared3::econ::TokenAmount, std::cmp::Ordering, std::fmt,
15    uint::construct_uint,
16};
17
18construct_uint! { pub struct U256(4); } // ethereum word size
19construct_uint! { pub struct U512(8); } // used for addmod and mulmod opcodes
20
21// Convenience method for comparing against a small value.
22impl PartialOrd<u64> for U256 {
23    fn partial_cmp(&self, other: &u64) -> Option<Ordering> {
24        if self.0[3] > 0 || self.0[2] > 0 || self.0[1] > 0 {
25            Some(Ordering::Greater)
26        } else {
27            self.0[0].partial_cmp(other)
28        }
29    }
30}
31
32impl PartialEq<u64> for U256 {
33    fn eq(&self, other: &u64) -> bool {
34        self.0[0] == *other && self.0[1] == 0 && self.0[2] == 0 && self.0[3] == 0
35    }
36}
37
38impl U256 {
39    pub const BITS: u32 = 256;
40    pub const ZERO: Self = U256::from_u64(0);
41    pub const ONE: Self = U256::from_u64(1);
42    pub const I128_MIN: Self = U256([0, 0, 0, i64::MIN as u64]);
43
44    #[inline(always)]
45    pub const fn from_u128_words(high: u128, low: u128) -> U256 {
46        U256([
47            low as u64,
48            (low >> u64::BITS) as u64,
49            high as u64,
50            (high >> u64::BITS) as u64,
51        ])
52    }
53
54    #[inline(always)]
55    pub const fn from_u64(value: u64) -> U256 {
56        U256([value, 0, 0, 0])
57    }
58
59    #[inline(always)]
60    pub const fn i256_is_negative(&self) -> bool {
61        (self.0[3] as i64) < 0
62    }
63
64    /// turns a i256 value to negative
65    #[inline(always)]
66    pub fn i256_neg(&self) -> U256 {
67        if self.is_zero() {
68            U256::ZERO
69        } else {
70            !*self + U256::ONE
71        }
72    }
73
74    #[inline(always)]
75    pub fn i256_cmp(&self, other: &U256) -> Ordering {
76        // true > false:
77        // - true < positive:
78        match other.i256_is_negative().cmp(&self.i256_is_negative()) {
79            Ordering::Equal => self.cmp(other),
80            sign_cmp => sign_cmp,
81        }
82    }
83
84    #[inline]
85    pub fn i256_div(&self, other: &U256) -> U256 {
86        if self.is_zero() || other.is_zero() {
87            // EVM defines X/0 to be 0.
88            return U256::ZERO;
89        }
90
91        // min-negative-value can't be represented as a positive value, but we don't need to.
92        // NOTE: we've already checked that 'second' isn't zero above.
93        if (self, other) == (&U256::I128_MIN, &U256::ONE) {
94            return U256::I128_MIN;
95        }
96
97        let mut first = *self;
98        let mut second = *other;
99
100        // Record and strip the signs. We add them back at the end.
101        let first_neg = first.i256_is_negative();
102        let second_neg = second.i256_is_negative();
103
104        if first_neg {
105            first = first.i256_neg()
106        }
107
108        if second_neg {
109            second = second.i256_neg()
110        }
111
112        let d = first / second;
113
114        // Flip the sign back if necessary.
115        if d.is_zero() || first_neg == second_neg {
116            d
117        } else {
118            d.i256_neg()
119        }
120    }
121
122    #[inline]
123    pub fn i256_mod(&self, other: &U256) -> U256 {
124        if self.is_zero() || other.is_zero() {
125            // X % 0  or 0 % X is always 0.
126            return U256::ZERO;
127        }
128
129        let mut first = *self;
130        let mut second = *other;
131
132        // Record and strip the sign.
133        let negative = first.i256_is_negative();
134        if negative {
135            first = first.i256_neg();
136        }
137
138        if second.i256_is_negative() {
139            second = second.i256_neg()
140        }
141
142        let r = first % second;
143
144        // Restore the sign.
145        if negative && !r.is_zero() {
146            r.i256_neg()
147        } else {
148            r
149        }
150    }
151
152    pub fn to_bytes(&self) -> [u8; 32] {
153        let mut buf = [0u8; 32];
154        self.to_big_endian(&mut buf);
155        buf
156    }
157
158    /// Returns the low 64 bits, saturating the value to u64 max if it is larger
159    pub fn to_u64_saturating(&self) -> u64 {
160        if self.bits() > 64 {
161            u64::MAX
162        } else {
163            self.0[0]
164        }
165    }
166}
167
168impl U512 {
169    pub fn low_u256(&self) -> U256 {
170        let [a, b, c, d, ..] = self.0;
171        U256([a, b, c, d])
172    }
173}
174
175impl From<&TokenAmount> for U256 {
176    fn from(amount: &TokenAmount) -> U256 {
177        let (_, bytes) = amount.atto().to_bytes_be();
178        U256::from(bytes.as_slice())
179    }
180}
181
182impl From<U256> for U512 {
183    fn from(v: U256) -> Self {
184        let [a, b, c, d] = v.0;
185        U512([a, b, c, d, 0, 0, 0, 0])
186    }
187}
188
189impl From<&U256> for TokenAmount {
190    fn from(ui: &U256) -> TokenAmount {
191        let mut bits = [0u8; 32];
192        ui.to_big_endian(&mut bits);
193        TokenAmount::from_atto(BigInt::from_bytes_be(
194            fvm_shared3::bigint::Sign::Plus,
195            &bits,
196        ))
197    }
198}
199
200impl Serialize for U256 {
201    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
202    where
203        S: serde::Serializer,
204    {
205        let mut bytes = [0u8; 32];
206        self.to_big_endian(&mut bytes);
207        serializer.serialize_bytes(zeroless_view(&bytes))
208    }
209}
210
211impl<'de> Deserialize<'de> for U256 {
212    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
213    where
214        D: serde::Deserializer<'de>,
215    {
216        struct Visitor;
217        impl<'de> serde::de::Visitor<'de> for Visitor {
218            type Value = U256;
219
220            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
221                write!(formatter, "at most 32 bytes")
222            }
223
224            fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
225            where
226                E: serde::de::Error,
227            {
228                if v.len() > 32 {
229                    return Err(serde::de::Error::invalid_length(v.len(), &self));
230                }
231                Ok(U256::from_big_endian(v))
232            }
233        }
234        deserializer.deserialize_bytes(Visitor)
235    }
236}
237
238fn zeroless_view(v: &impl AsRef<[u8]>) -> &[u8] {
239    let v = v.as_ref();
240    &v[v.iter().take_while(|&&b| b == 0).count()..]
241}
242
243#[cfg(test)]
244mod tests {
245    use fvm_ipld_encoding::{BytesDe, BytesSer, RawBytes};
246
247    use {super::*, core::num::Wrapping};
248
249    #[test]
250    fn div_i256() {
251        assert_eq!(Wrapping(i8::MIN) / Wrapping(-1), Wrapping(i8::MIN));
252        assert_eq!(i8::MAX / -1, -i8::MAX);
253
254        let zero = U256::ZERO;
255        let one = U256::ONE;
256        let one_hundred = U256::from(100);
257        let fifty = U256::from(50);
258        let two = U256::from(2);
259        let neg_one_hundred = U256::from(100);
260        let minus_one = U256::from(1);
261        let max_value = U256::from(2).pow(255.into()) - 1;
262        let neg_max_value = U256::from(2).pow(255.into()) - 1;
263
264        assert_eq!(U256::I128_MIN.i256_div(&minus_one), U256::I128_MIN);
265        assert_eq!(U256::I128_MIN.i256_div(&one), U256::I128_MIN);
266        assert_eq!(one.i256_div(&U256::I128_MIN), zero);
267        assert_eq!(max_value.i256_div(&one), max_value);
268        assert_eq!(max_value.i256_div(&minus_one), neg_max_value);
269        assert_eq!(one_hundred.i256_div(&minus_one), neg_one_hundred);
270        assert_eq!(one_hundred.i256_div(&two), fifty);
271
272        assert_eq!(zero.i256_div(&zero), zero);
273        assert_eq!(one.i256_div(&zero), zero);
274        assert_eq!(zero.i256_div(&one), zero);
275    }
276
277    #[test]
278    fn mod_i256() {
279        let zero = U256::ZERO;
280        let one = U256::ONE;
281        let one_hundred = U256::from(100);
282        let two = U256::from(2);
283        let three = U256::from(3);
284
285        let neg_one_hundred = U256::from(100).i256_neg();
286        let minus_one = U256::from(1).i256_neg();
287        let neg_three = U256::from(3).i256_neg();
288        let max_value = U256::from(2).pow(255.into()) - 1;
289
290        // zero
291        assert_eq!(minus_one.i256_mod(&U256::ZERO), U256::ZERO);
292        assert_eq!(max_value.i256_mod(&U256::ZERO), U256::ZERO);
293        assert_eq!(U256::ZERO.i256_mod(&U256::ZERO), U256::ZERO);
294
295        assert_eq!(minus_one.i256_mod(&two), minus_one);
296        assert_eq!(U256::I128_MIN.i256_mod(&one), 0);
297        assert_eq!(one.i256_mod(&U256::I128_MIN), one);
298        assert_eq!(one.i256_mod(&U256::from(i128::MAX)), one);
299
300        assert_eq!(max_value.i256_mod(&minus_one), zero);
301        assert_eq!(neg_one_hundred.i256_mod(&minus_one), zero);
302        assert_eq!(one_hundred.i256_mod(&two), zero);
303        assert_eq!(one_hundred.i256_mod(&neg_three), one);
304
305        assert_eq!(neg_one_hundred.i256_mod(&three), minus_one);
306
307        let a = U256::from(95).i256_neg();
308        let b = U256::from(256);
309        assert_eq!(a % b, U256::from(161))
310    }
311
312    #[test]
313    fn negative_i256() {
314        assert_eq!(U256::ZERO.i256_neg(), U256::ZERO);
315
316        let one = U256::ONE.i256_neg();
317        assert!(one.i256_is_negative());
318
319        let neg_one = U256::from(&[0xff; 32]);
320        let pos_one = neg_one.i256_neg();
321        assert_eq!(pos_one, U256::ONE);
322    }
323
324    #[test]
325    fn u256_serde() {
326        let encoded = RawBytes::serialize(U256::from(0x4d2)).unwrap();
327        let BytesDe(bytes) = encoded.deserialize().unwrap();
328        assert_eq!(bytes, &[0x04, 0xd2]);
329        let decoded: U256 = encoded.deserialize().unwrap();
330        assert_eq!(decoded, 0x4d2);
331    }
332
333    #[test]
334    fn u256_empty() {
335        let encoded = RawBytes::serialize(U256::from(0)).unwrap();
336        let BytesDe(bytes) = encoded.deserialize().unwrap();
337        assert!(bytes.is_empty());
338    }
339
340    #[test]
341    fn u256_overflow() {
342        let encoded = RawBytes::serialize(BytesSer(&[1; 33])).unwrap();
343        encoded
344            .deserialize::<U256>()
345            .expect_err("should have failed to decode an over-large u256");
346    }
347}