evm_interpreter/uint/
mod.rs

1//! Re-export of uint type that is currently use.
2//!
3//! Depending on the feature flag, different underlying crate may be used.
4//! * Default (no feature flag): use `primitive-types` crate.
5//! * `ruint` feature flag: use `ruint` crate.
6
7// H256 and H160 are pretty standardized, and there's no performance difference
8// in different implementations, so we always only use the one from
9// `primitive-types`.
10pub use ::primitive_types::{H160, H256};
11
12/// Extension for specialized U256 operations.
13// Note on name resolution: when trait and struct itself defines functions of
14// identical name, then Rust would by default calls the implementation on the
15// struct directly. We take advantage of this for the extension trait.
16#[doc(hidden)]
17pub trait U256Ext: Sealed + Sized + Eq + PartialEq + Ord + PartialOrd + Clone + Copy {
18	/// Zero value.
19	const ZERO: Self;
20	/// One value.
21	const ONE: Self;
22	/// Value 32.
23	const VALUE_32: Self;
24	/// Value 64.
25	const VALUE_64: Self;
26	/// Value 256.
27	const VALUE_256: Self;
28	/// Usize max.
29	const USIZE_MAX: Self;
30	/// U64 max.
31	const U64_MAX: Self;
32	/// U32 max.
33	const U32_MAX: Self;
34	/// Sign bit mask.
35	const SIGN_BIT_MASK: Self;
36
37	/// An ADDMOD operation for U256.
38	fn add_mod(self, op2: Self, op3: Self) -> Self;
39	/// An MULMOD operation for U256.
40	fn mul_mod(self, op2: Self, op3: Self) -> Self;
41
42	/// Conversion to usize with overflow checking.
43	/// Should panic if the number is larger than usize::MAX.
44	fn to_usize(&self) -> usize {
45		assert!(*self <= Self::USIZE_MAX);
46		self.low_usize()
47	}
48	/// Conversion to u64 with overflow checking.
49	/// Should panic if the number is larger than u64::MAX.
50	fn to_u64(&self) -> u64 {
51		assert!(*self <= Self::U64_MAX);
52		self.low_u64()
53	}
54	/// Conversion to u32 with overflow checking.
55	/// Should panic if the number is larger than u32::MAX.
56	fn to_u32(&self) -> u32 {
57		assert!(*self <= Self::U32_MAX);
58		self.low_u32()
59	}
60
61	/// Lower word of u64.
62	fn low_u64(&self) -> u64;
63	/// Lower word of u32.
64	fn low_u32(&self) -> u32;
65	/// Lower word of usize.
66	fn low_usize(&self) -> usize;
67
68	/// Conversion from u32.
69	fn from_u32(v: u32) -> Self;
70	/// Conversion from u64.
71	fn from_u64(v: u64) -> Self;
72	/// Conversion from usize.
73	fn from_usize(v: usize) -> Self;
74
75	/// Conversion to H256 big-endian.
76	fn to_h256(self) -> H256;
77	/// Conversion from H256 big-endian.
78	fn from_h256(v: H256) -> Self;
79	/// Conversion to H160 big-endian, discard leading bits.
80	fn to_h160(self) -> H160 {
81		self.to_h256().into()
82	}
83	/// Conversion from H160 big-endian, with leading bits as zero.
84	fn from_h160(v: H160) -> Self {
85		Self::from_h256(v.into())
86	}
87
88	/// Whether the value is zero.
89	fn is_zero(&self) -> bool {
90		*self == Self::ZERO
91	}
92	/// Whether a specific bit is set.
93	fn bit(&self, index: usize) -> bool;
94	/// Least number of bits needed to represent the number.
95	fn bits(&self) -> usize;
96	/// Log2 of the value, rounded down.
97	fn log2floor(&self) -> u64;
98	/// Append the value to RLP stream.
99	fn append_to_rlp_stream(&self, rlp: &mut rlp::RlpStream);
100}
101
102// Use default primitive-types U256 implementation.
103#[cfg(not(feature = "ruint"))]
104mod primitive_types;
105#[cfg(not(feature = "ruint"))]
106use self::primitive_types::Sealed;
107#[cfg(not(feature = "ruint"))]
108pub use self::primitive_types::U256;
109
110// Use ruint U256 implementation.
111#[cfg(feature = "ruint")]
112mod ruint;
113#[cfg(feature = "ruint")]
114use self::ruint::Sealed;
115#[cfg(feature = "ruint")]
116pub use self::ruint::U256;
117
118#[cfg(test)]
119mod tests {
120	#[allow(unused_imports)]
121	use super::{U256, U256Ext};
122
123	#[test]
124	fn shl_overflowing() {
125		assert_eq!(U256::ONE << 257, U256::ZERO);
126	}
127}