1use super::{utils::abi_require, ABIDecodeError, ABIVariable, LinkedBytes};
6use cfx_types::{Address, H256, U256};
7
8impl ABIVariable for Address {
9 const BASIC_TYPE: bool = true;
10 const STATIC_LENGTH: Option<usize> = Some(32);
11
12 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
13 abi_require(data.len() == 32, "Invalid call data length")?;
14 Ok(Address::from_slice(&data[12..32]))
15 }
16
17 fn to_abi(&self) -> LinkedBytes {
18 let mut answer = vec![0u8; 12];
19 answer.extend_from_slice(self.as_bytes());
20 LinkedBytes::from_bytes(answer)
21 }
22
23 fn to_packed_abi(&self) -> LinkedBytes {
24 LinkedBytes::from_bytes(self.to_fixed_bytes().into())
25 }
26}
27
28impl ABIVariable for U256 {
29 const BASIC_TYPE: bool = true;
30 const STATIC_LENGTH: Option<usize> = Some(32);
31
32 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
33 abi_require(data.len() == 32, "Invalid call data length")?;
34 Ok(U256::from_big_endian(&data))
35 }
36
37 fn to_abi(&self) -> LinkedBytes {
38 LinkedBytes::from_bytes(self.to_big_endian().to_vec())
39 }
40
41 fn to_packed_abi(&self) -> LinkedBytes { self.to_abi() }
42}
43
44impl ABIVariable for H256 {
45 const BASIC_TYPE: bool = <[u8; 32]>::BASIC_TYPE;
46 const STATIC_LENGTH: Option<usize> = <[u8; 32]>::STATIC_LENGTH;
47
48 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
49 Ok(H256::from(<[u8; 32]>::from_abi(data)?))
50 }
51
52 fn to_abi(&self) -> LinkedBytes { self.0.to_abi() }
53
54 fn to_packed_abi(&self) -> LinkedBytes { self.0.to_packed_abi() }
55}
56
57impl ABIVariable for bool {
58 const BASIC_TYPE: bool = true;
59 const STATIC_LENGTH: Option<usize> = Some(32);
60
61 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
62 abi_require(data.len() == 32, "Invalid call data length")?;
63 Ok(data[31] != 0)
64 }
65
66 fn to_abi(&self) -> LinkedBytes {
67 let mut answer = vec![0u8; 32];
68 answer[31] = *self as u8;
69 LinkedBytes::from_bytes(answer)
70 }
71
72 fn to_packed_abi(&self) -> LinkedBytes {
73 LinkedBytes::from_bytes(vec![*self as u8])
74 }
75}
76
77macro_rules! impl_abi_variable_for_primitive {
78 () => {};
79 ($ty: ident) => {impl_abi_variable_for_primitive!($ty,);};
80 ($ty: ident, $($rest: ident),*) => {
81 impl ABIVariable for $ty {
82 const BASIC_TYPE: bool = true;
83 const STATIC_LENGTH: Option<usize> = Some(32);
84
85 fn from_abi(data: &[u8]) -> Result<Self, ABIDecodeError> {
106 const BYTES: usize = ($ty::BITS/8) as usize;
107 abi_require(data.len() == 32, "Invalid call data length")?;
108 let mut bytes = [0u8; BYTES];
109 bytes.copy_from_slice(&data[32 - BYTES..]);
110 Ok($ty::from_be_bytes(bytes))
111 }
112
113 fn to_abi(&self) -> LinkedBytes {
114 const BYTES: usize = ($ty::BITS/8) as usize;
115 let mut answer = vec![0u8; 32];
116 answer[32 - BYTES..].copy_from_slice(&self.to_be_bytes());
117 LinkedBytes::from_bytes(answer)
118 }
119
120 fn to_packed_abi(&self) -> LinkedBytes {
121 LinkedBytes::from_bytes(self.to_be_bytes().to_vec())
122 }
123 }
124
125 impl_abi_variable_for_primitive!($($rest),*);
126 }
127}
128
129impl_abi_variable_for_primitive!(U8, u16, u32, u64, u128);
130
131#[allow(dead_code)]
132#[derive(Copy, Clone, Eq, PartialEq)]
133pub struct U8(u8);
134
135impl U8 {
136 #[allow(dead_code)]
137 const BITS: usize = 8;
138
139 #[allow(dead_code)]
140 fn to_be_bytes(self) -> [u8; 1] { [self.0] }
141
142 #[allow(dead_code)]
143 fn from_be_bytes(input: [u8; 1]) -> Self { U8(input[0]) }
144}
145
146#[cfg(test)]
147mod tests_basic {
148 use super::{U8, *};
149 use crate::ABIVariable;
150
151 #[test]
152 fn test_packed_encoding() {
153 let num = 0xDEADBEEFu32;
154 let packed = num.to_packed_abi().to_vec();
155 let expected = num.to_be_bytes().to_vec();
156 assert_eq!(packed, expected);
157 }
158
159 #[test]
160 fn test_u256_abi_basic() {
161 assert!(U256::BASIC_TYPE);
162 assert_eq!(U256::STATIC_LENGTH, Some(32));
163 }
164
165 #[test]
166 fn test_u256_packed_abi_consistency() {
167 let num = U256::max_value();
168 let abi = num.to_abi();
169 let packed_abi = num.to_packed_abi();
170 assert_eq!(abi.to_vec(), packed_abi.to_vec());
171 }
172
173 #[test]
174 fn test_u256_zero_value() {
175 let zero = U256::zero();
176 let encoded = zero.to_abi().to_vec();
177 assert_eq!(encoded, vec![0u8; 32]);
178 }
179
180 #[test]
181 fn test_h256_type_constants() {
182 assert_eq!(H256::BASIC_TYPE, <[u8; 32]>::BASIC_TYPE);
183 assert_eq!(H256::STATIC_LENGTH, <[u8; 32]>::STATIC_LENGTH);
184 }
185
186 #[test]
187 fn test_h256_from_abi_valid() {
188 let input = [42u8; 32];
189 let h256 = H256::from_abi(&input).unwrap();
190 assert_eq!(h256.0, input);
191 }
192
193 #[test]
194 fn test_h256_to_packed_abi() {
195 let h256 = H256([0xBB; 32]);
196 let packed_bytes = h256.to_packed_abi();
197 assert_eq!(packed_bytes.to_vec(), &[0xBB; 32]);
198 }
199
200 #[test]
201 fn test_u8_bits() {
202 assert_eq!(U8::BITS, 8);
203 }
204
205 #[test]
206 fn test_u8_to_be_bytes() {
207 let val = U8::from_be_bytes([123]);
208 assert_eq!(val.to_be_bytes(), [123]);
209 }
210
211 #[test]
212 fn test_u8_from_be_bytes() {
213 let u = U8::from_be_bytes([255]);
214 assert_eq!(u.to_be_bytes(), [255]);
215 }
216
217 #[test]
218 fn test_u8_eq() {
219 let a = U8::from_be_bytes([100]);
220 let b = U8::from_be_bytes([100]);
221 let c = U8::from_be_bytes([200]);
222 assert!(a == b);
223 assert!(a != c);
224 }
225
226 #[test]
227 fn test_u8_boundaries() {
228 let min = U8::from_be_bytes([0]);
229 let max = U8::from_be_bytes([255]);
230 assert_eq!(min.to_be_bytes(), [0]);
231 assert_eq!(max.to_be_bytes(), [255]);
232 }
233
234 #[test]
235 fn test_u8_byte_order_consistency() {
236 let input = [128];
237 let u = U8::from_be_bytes(input);
238 assert_eq!(u.to_be_bytes(), input);
239 }
240
241 fn make_word_with_high_fill(low: &[u8], high_fill: u8) -> [u8; 32] {
260 assert!(low.len() <= 32, "low slice must fit in a 32-byte ABI word");
261 let mut word = [high_fill; 32];
262 let start = 32 - low.len();
263 word[start..].copy_from_slice(low);
264 word
265 }
266
267 #[test]
268 fn test_u8_truncates_high_bytes() {
269 let word = make_word_with_high_fill(&[0xAB], 0xFF);
274 let decoded = U8::from_abi(&word).unwrap();
275 assert_eq!(decoded.to_be_bytes(), [0xAB]);
276 }
277
278 #[test]
279 fn test_u16_truncates_high_bytes() {
280 let word = make_word_with_high_fill(&0x1234u16.to_be_bytes(), 0xFF);
284 let decoded = u16::from_abi(&word).unwrap();
285 assert_eq!(decoded, 0x1234u16);
286 }
287
288 #[test]
289 fn test_u32_truncates_high_bytes() {
290 let word = make_word_with_high_fill(&0xDEADBEEFu32.to_be_bytes(), 0xAA);
291 let decoded = u32::from_abi(&word).unwrap();
292 assert_eq!(decoded, 0xDEADBEEFu32);
293 }
294
295 #[test]
296 fn test_u64_truncates_high_bytes() {
297 let word = make_word_with_high_fill(
298 &0x0123_4567_89AB_CDEFu64.to_be_bytes(),
299 0x01,
300 );
301 let decoded = u64::from_abi(&word).unwrap();
302 assert_eq!(decoded, 0x0123_4567_89AB_CDEFu64);
303 }
304
305 #[test]
306 fn test_u128_truncates_high_bytes() {
307 let low: u128 = 0x0011_2233_4455_6677_8899_AABB_CCDD_EEFFu128;
308 let word = make_word_with_high_fill(&low.to_be_bytes(), 0x77);
309 let decoded = u128::from_abi(&word).unwrap();
310 assert_eq!(decoded, low);
311 }
312
313 #[test]
314 fn test_uintn_accepts_max_low_with_dirty_high_bits() {
315 let word = make_word_with_high_fill(&u64::MAX.to_be_bytes(), 0x5A);
318 let decoded = u64::from_abi(&word).unwrap();
319 assert_eq!(decoded, u64::MAX);
320 }
321
322 #[test]
323 fn test_uintn_decoding_is_non_canonical() {
324 let value: u32 = 0xCAFEBABE;
328 let word_clean = make_word_with_high_fill(&value.to_be_bytes(), 0x00);
329 let word_dirty = make_word_with_high_fill(&value.to_be_bytes(), 0xFF);
330 assert_ne!(word_clean, word_dirty);
331 assert_eq!(
332 u32::from_abi(&word_clean).unwrap(),
333 u32::from_abi(&word_dirty).unwrap(),
334 );
335 }
336
337 #[test]
338 fn test_uintn_rejects_wrong_word_length() {
339 assert!(u16::from_abi(&[0u8; 31]).is_err());
342 assert!(u32::from_abi(&[0u8; 33]).is_err());
343 assert!(u64::from_abi(&[]).is_err());
344 assert!(u128::from_abi(&[0u8; 16]).is_err());
345 }
346
347 #[test]
348 fn test_uintn_roundtrip_zero_high_bytes() {
349 let cases_u16: &[u16] = &[0, 1, 0x1234, u16::MAX];
352 for &v in cases_u16 {
353 let bytes = v.to_abi().to_vec();
354 assert_eq!(bytes.len(), 32);
355 assert!(bytes[..30].iter().all(|&b| b == 0));
356 assert_eq!(u16::from_abi(&bytes).unwrap(), v);
357 }
358
359 let cases_u64: &[u64] = &[0, 1, 0x0123_4567_89AB_CDEF, u64::MAX];
360 for &v in cases_u64 {
361 let bytes = v.to_abi().to_vec();
362 assert_eq!(bytes.len(), 32);
363 assert!(bytes[..24].iter().all(|&b| b == 0));
364 assert_eq!(u64::from_abi(&bytes).unwrap(), v);
365 }
366 }
367}