revm_bytecode/eof/
code_info.rs1use primitives::STACK_LIMIT;
2
3use super::{
4 decode_helpers::{consume_u16, consume_u8},
5 EofDecodeError,
6};
7use std::vec::Vec;
8
9const EOF_NON_RETURNING_FUNCTION: u8 = 0x80;
11
12#[derive(Debug, Clone, Default, Hash, PartialEq, Eq, Copy, PartialOrd, Ord)]
14#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
15pub struct CodeInfo {
16 pub inputs: u8,
20 pub outputs: u8,
24 pub max_stack_increase: u16,
28}
29
30impl CodeInfo {
31 pub fn new(inputs: u8, outputs: u8, max_stack_increase: u16) -> Self {
33 Self {
34 inputs,
35 outputs,
36 max_stack_increase,
37 }
38 }
39
40 pub fn is_non_returning(&self) -> bool {
42 self.outputs == EOF_NON_RETURNING_FUNCTION
43 }
44
45 #[inline]
47 pub const fn io_diff(&self) -> i32 {
48 self.outputs as i32 - self.inputs as i32
49 }
50
51 #[inline]
53 pub fn encode(&self, buffer: &mut Vec<u8>) {
54 buffer.push(self.inputs);
55 buffer.push(self.outputs);
56 buffer.extend_from_slice(&self.max_stack_increase.to_be_bytes());
57 }
58
59 #[inline]
61 pub fn decode(input: &[u8]) -> Result<(Self, &[u8]), EofDecodeError> {
62 let (input, inputs) = consume_u8(input)?;
63 let (input, outputs) = consume_u8(input)?;
64 let (input, max_stack_increase) = consume_u16(input)?;
65 let section = Self {
66 inputs,
67 outputs,
68 max_stack_increase,
69 };
70 section.validate()?;
71 Ok((section, input))
72 }
73
74 pub fn validate(&self) -> Result<(), EofDecodeError> {
76 if self.inputs > 0x7f {
77 return Err(EofDecodeError::InvalidCodeInfoInputValue { value: self.inputs });
78 }
79
80 if self.outputs > 0x80 {
81 return Err(EofDecodeError::InvalidCodeInfoOutputValue {
82 value: self.outputs,
83 });
84 }
85
86 if self.max_stack_increase > 0x03FF {
87 return Err(EofDecodeError::InvalidCodeInfoMaxIncrementValue {
88 value: self.max_stack_increase,
89 });
90 }
91
92 if self.inputs as usize + self.max_stack_increase as usize > STACK_LIMIT {
93 return Err(EofDecodeError::InvalidCodeInfoStackOverflow {
94 inputs: self.inputs,
95 max_stack_increment: self.max_stack_increase,
96 });
97 }
98
99 Ok(())
100 }
101}