fil_actor_evm_shared_state/v10/
uints.rs1#![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); } construct_uint! { pub struct U512(8); } impl 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 #[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 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 return U256::ZERO;
89 }
90
91 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 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 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 return U256::ZERO;
127 }
128
129 let mut first = *self;
130 let mut second = *other;
131
132 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 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 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 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}