1use super::{error, EvmResult};
18use core::{any::type_name, ops::Range};
19use primitive_types::{H160, H256, U256};
20use std::{convert::TryInto, vec, vec::Vec};
21
22#[derive(Clone, Copy, Debug, Eq, PartialEq)]
26pub struct Address(pub H160);
27
28impl From<H160> for Address {
29 fn from(a: H160) -> Address {
30 Address(a)
31 }
32}
33
34impl From<Address> for H160 {
35 fn from(a: Address) -> H160 {
36 a.0
37 }
38}
39
40#[derive(Clone, Copy, Debug)]
43pub struct EvmDataReader<'a> {
44 input: &'a [u8],
45 cursor: usize,
46}
47
48impl<'a> EvmDataReader<'a> {
49 pub fn new(input: &'a [u8]) -> Self {
51 Self { input, cursor: 0 }
52 }
53
54 pub fn expect_arguments(&self, args: usize) -> EvmResult {
56 if self.input.len() >= self.cursor + args * 32 {
57 Ok(())
58 } else {
59 Err(error("input doesn't match expected length"))
60 }
61 }
62
63 pub fn read<T: EvmData>(&mut self) -> EvmResult<T> {
65 T::read(self)
66 }
67
68 pub fn read_raw_bytes(&mut self, len: usize) -> EvmResult<&[u8]> {
72 let range = self.move_cursor(len)?;
73
74 let data = self
75 .input
76 .get(range)
77 .ok_or_else(|| error("tried to parse raw bytes out of bounds"))?;
78
79 Ok(data)
80 }
81
82 pub fn read_selector<T>(&mut self) -> EvmResult<T>
85 where
86 T: num_enum::TryFromPrimitive<Primitive = u32>,
87 {
88 let mut buffer = [0u8; 4];
89 buffer.copy_from_slice(
90 self.read_raw_bytes(4)
91 .map_err(|_| error("tried to parse selector out of bounds"))?,
92 );
93 T::try_from_primitive(u32::from_be_bytes(buffer)).map_err(|_| {
94 log::trace!(
95 target: "precompile",
96 "Failed to match function selector for {}",
97 type_name::<T>()
98 );
99 error("unknown selector")
100 })
101 }
102
103 fn move_cursor(&mut self, len: usize) -> EvmResult<Range<usize>> {
107 let start = self.cursor;
108 let end = self
109 .cursor
110 .checked_add(len)
111 .ok_or_else(|| error("data reading cursor overflow"))?;
112
113 self.cursor = end;
114
115 Ok(start..end)
116 }
117}
118
119#[derive(Clone, Debug)]
121pub struct EvmDataWriter {
122 pub(crate) data: Vec<u8>,
123 arrays: Vec<Array>,
124}
125
126#[derive(Clone, Debug)]
127struct Array {
128 offset_position: usize,
129 data: Vec<u8>,
130 inner_arrays: Vec<Array>,
131}
132
133impl EvmDataWriter {
134 pub fn new() -> Self {
136 Self {
137 data: vec![],
138 arrays: vec![],
139 }
140 }
141
142 pub fn build(mut self) -> Vec<u8> {
144 Self::build_arrays(&mut self.data, self.arrays, 0);
145
146 self.data
147 }
148
149 fn build_arrays(output: &mut Vec<u8>, arrays: Vec<Array>, global_offset: usize) {
154 for mut array in arrays {
155 let offset_position = array.offset_position;
156 let offset_position_end = offset_position + 32;
157 let free_space_offset = output.len() + global_offset;
158
159 U256::from(free_space_offset)
161 .to_big_endian(&mut output[offset_position..offset_position_end]);
162
163 Self::build_arrays(&mut array.data, array.inner_arrays, free_space_offset);
165
166 output.append(&mut array.data);
168 }
169 }
170
171 pub fn write_raw_bytes(mut self, value: &[u8]) -> Self {
174 self.data.extend_from_slice(value);
175 self
176 }
177
178 pub fn write_selector<T: Into<u32>>(self, value: T) -> Self {
183 self.write_raw_bytes(&value.into().to_be_bytes())
184 }
185
186 pub fn write<T: EvmData>(mut self, value: T) -> Self {
188 T::write(&mut self, value);
189 self
190 }
191}
192
193impl Default for EvmDataWriter {
194 fn default() -> Self {
195 Self::new()
196 }
197}
198
199pub trait EvmData: Sized {
201 fn read(reader: &mut EvmDataReader) -> EvmResult<Self>;
202 fn write(writer: &mut EvmDataWriter, value: Self);
203}
204
205impl EvmData for H256 {
206 fn read(reader: &mut EvmDataReader) -> EvmResult<Self> {
207 let range = reader.move_cursor(32)?;
208
209 let data = reader
210 .input
211 .get(range)
212 .ok_or_else(|| error("tried to parse H256 out of bounds"))?;
213
214 Ok(H256::from_slice(data))
215 }
216
217 fn write(writer: &mut EvmDataWriter, value: Self) {
218 writer.data.extend_from_slice(value.as_bytes());
219 }
220}
221
222impl EvmData for Address {
223 fn read(reader: &mut EvmDataReader) -> EvmResult<Self> {
224 let range = reader.move_cursor(32)?;
225
226 let data = reader
227 .input
228 .get(range)
229 .ok_or_else(|| error("tried to parse H160 out of bounds"))?;
230
231 Ok(H160::from_slice(&data[12..32]).into())
232 }
233
234 fn write(writer: &mut EvmDataWriter, value: Self) {
235 H256::write(writer, value.0.into());
236 }
237}
238
239impl EvmData for U256 {
240 fn read(reader: &mut EvmDataReader) -> EvmResult<Self> {
241 let range = reader.move_cursor(32)?;
242
243 let data = reader
244 .input
245 .get(range)
246 .ok_or_else(|| error("tried to parse U256 out of bounds"))?;
247
248 Ok(U256::from_big_endian(data))
249 }
250
251 fn write(writer: &mut EvmDataWriter, value: Self) {
252 let mut buffer = [0u8; 32];
253 value.to_big_endian(&mut buffer);
254 writer.data.extend_from_slice(&buffer);
255 }
256}
257
258macro_rules! impl_evmdata_for_uints {
259 ($($uint:ty, )*) => {
260 $(
261 impl EvmData for $uint {
262 fn read(reader: &mut EvmDataReader) -> EvmResult<Self> {
263 let range = reader.move_cursor(32)?;
264
265 let data = reader
266 .input
267 .get(range)
268 .ok_or_else(|| error(format!(
269 "tried to parse {} out of bounds", core::any::type_name::<Self>()
270 )))?;
271
272 let mut buffer = [0u8; core::mem::size_of::<Self>()];
273 buffer.copy_from_slice(&data[32 - core::mem::size_of::<Self>()..]);
274 Ok(Self::from_be_bytes(buffer))
275 }
276
277 fn write(writer: &mut EvmDataWriter, value: Self) {
278 let mut buffer = [0u8; 32];
279 buffer[32 - core::mem::size_of::<Self>()..].copy_from_slice(&value.to_be_bytes());
280 writer.data.extend_from_slice(&buffer);
281 }
282 }
283 )*
284 };
285}
286impl_evmdata_for_uints!(u16, u32, u64, u128,);
287
288impl EvmData for u8 {
290 fn read(reader: &mut EvmDataReader) -> EvmResult<Self> {
291 let range = reader.move_cursor(32)?;
292
293 let data = reader
294 .input
295 .get(range)
296 .ok_or_else(|| error("tried to parse u64 out of bounds"))?;
297
298 Ok(data[31])
299 }
300
301 fn write(writer: &mut EvmDataWriter, value: Self) {
302 let mut buffer = [0u8; 32];
303 buffer[31] = value;
304
305 writer.data.extend_from_slice(&buffer);
306 }
307}
308
309impl EvmData for bool {
310 fn read(reader: &mut EvmDataReader) -> EvmResult<Self> {
311 let h256 = H256::read(reader).map_err(|_| error("tried to parse bool out of bounds"))?;
312
313 Ok(!h256.is_zero())
314 }
315
316 fn write(writer: &mut EvmDataWriter, value: Self) {
317 let mut buffer = [0u8; 32];
318 if value {
319 buffer[31] = 1;
320 }
321
322 writer.data.extend_from_slice(&buffer);
323 }
324}
325
326impl<T: EvmData> EvmData for Vec<T> {
327 fn read(reader: &mut EvmDataReader) -> EvmResult<Self> {
328 let array_start: usize = reader
329 .read::<U256>()
330 .map_err(|_| error("tried to parse array offset out of bounds"))?
331 .try_into()
332 .map_err(|_| error("array offset is too large"))?;
333
334 let original_cursor = reader.cursor;
336 reader.cursor = array_start;
337
338 let array_size: usize = reader
339 .read::<U256>()
340 .map_err(|_| error("tried to parse array length out of bounds"))?
341 .try_into()
342 .map_err(|_| error("array length is too large"))?;
343
344 let mut array = vec![];
345
346 for _ in 0..array_size {
347 array.push(reader.read()?);
348 }
349
350 reader.cursor = original_cursor;
352
353 Ok(array)
354 }
355
356 fn write(writer: &mut EvmDataWriter, value: Self) {
357 let offset_position = writer.data.len();
358 H256::write(writer, H256::repeat_byte(0xff));
359 let mut inner_writer = EvmDataWriter::new();
362
363 inner_writer = inner_writer.write(U256::from(value.len()));
365
366 for inner in value {
368 inner_writer = inner_writer.write(inner);
369 }
370
371 let array = Array {
372 offset_position,
373 data: inner_writer.data,
374 inner_arrays: inner_writer.arrays,
375 };
376
377 writer.arrays.push(array);
378 }
379}