revm_bytecode/eof/
body.rs1use super::{CodeInfo, Eof, EofDecodeError, EofHeader};
2use primitives::Bytes;
3use std::vec::Vec;
4
5#[derive(Clone, Debug, Default, PartialEq, Eq, Hash, Ord, PartialOrd)]
11#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
12pub struct EofBody {
13 pub code_info: Vec<CodeInfo>,
15 pub code_section: Vec<usize>,
17 pub code: Bytes,
20 pub code_offset: usize,
22 pub container_section: Vec<Bytes>,
24 pub data_section: Bytes,
26 pub is_data_filled: bool,
33}
34
35impl EofBody {
36 pub fn code(&self, index: usize) -> Option<Bytes> {
38 if index == 0 {
39 return Some(self.code.slice(..self.code_section[0]));
41 }
42 self.code_section
43 .get(index)
44 .map(|end| self.code.slice(self.code_section[index - 1]..*end))
45 }
46
47 pub fn into_eof(self) -> Eof {
49 let mut prev_value = 0;
50 let header = EofHeader {
51 types_size: self.code_info.len() as u16 * 4,
52 code_sizes: self
53 .code_section
54 .iter()
55 .map(|x| {
56 let ret = (x - prev_value) as u16;
57 prev_value = *x;
58 ret
59 })
60 .collect(),
61 container_sizes: self
62 .container_section
63 .iter()
64 .map(|x| x.len() as u32)
65 .collect(),
66 data_size: self.data_section.len() as u16,
67 sum_code_sizes: self.code.len(),
68 sum_container_sizes: self.container_section.iter().map(|x| x.len()).sum(),
69 };
70 let mut buffer = Vec::new();
71 header.encode(&mut buffer);
72 self.encode(&mut buffer);
73 Eof::decode(buffer.into()).expect("Failed to encode EOF")
74 }
75
76 pub fn eof_code_section_start(&self, idx: usize) -> Option<usize> {
80 let code_offset = self.code_offset;
82 if idx == 0 {
83 return Some(code_offset);
84 }
85 self.code_section.get(idx - 1).map(|i| i + code_offset)
86 }
87
88 pub fn encode(&self, buffer: &mut Vec<u8>) {
90 for code_info in &self.code_info {
91 code_info.encode(buffer);
92 }
93
94 buffer.extend_from_slice(&self.code);
95
96 for container_section in &self.container_section {
97 buffer.extend_from_slice(container_section);
98 }
99
100 buffer.extend_from_slice(&self.data_section);
101 }
102
103 pub fn decode(input: &Bytes, header: &EofHeader) -> Result<Self, EofDecodeError> {
105 let header_len = header.size();
106 let partial_body_len = header
107 .sum_code_sizes
108 .saturating_add(header.sum_container_sizes)
109 .saturating_add(header.types_size as usize);
110 let full_body_len = partial_body_len.saturating_add(header.data_size as usize);
111
112 if input.len() < header_len.saturating_add(partial_body_len) {
113 return Err(EofDecodeError::MissingBodyWithoutData);
114 }
115
116 if input.len() > header_len.saturating_add(full_body_len) {
117 return Err(EofDecodeError::DanglingData);
118 }
119
120 let mut body = EofBody::default();
121
122 let mut types_input = &input[header_len..];
123 for _ in 0..header.types_count() {
124 let (code_info, local_input) = CodeInfo::decode(types_input)?;
125 types_input = local_input;
126 body.code_info.push(code_info);
127 }
128
129 let start = header_len + header.types_size as usize;
131 body.code_offset = start;
132 let mut code_end = 0;
133 for size in header.code_sizes.iter().map(|x| *x as usize) {
134 code_end += size;
135 body.code_section.push(code_end);
136 }
137 body.code = input.slice(start..start + header.sum_code_sizes);
138
139 let mut start = start + header.sum_code_sizes;
141 for size in header.container_sizes.iter().map(|x| *x as usize) {
142 body.container_section
143 .push(input.slice(start..start + size));
144 start += size;
145 }
146
147 body.data_section = input.slice(start..);
148 body.is_data_filled = body.data_section.len() == header.data_size as usize;
149
150 Ok(body)
151 }
152}