1use clap::Parser;
2use revm::{
3 bytecode::eof::{self, validate_eof_inner, CodeType, Eof, EofError},
4 primitives::{hex, Bytes},
5 specification::constants::MAX_INITCODE_SIZE,
6};
7use std::io;
8
9#[derive(Parser, Debug)]
11pub struct Cmd {
12 #[arg(long)]
14 eof_initcode: bool,
15 #[arg(long)]
17 eof_runtime: bool,
18 #[arg()]
24 bytes: Option<String>,
25}
26
27#[inline]
28fn trim_decode(input: &str) -> Option<Bytes> {
29 let trimmed = input.trim().trim_start_matches("0x");
30 let decoded = hex::decode(trimmed).ok().map(Into::into);
31 if decoded.is_none() {
32 eprintln!("Invalid hex string");
33 return None;
34 }
35 decoded
36}
37
38impl Cmd {
39 pub fn run(&self) {
41 let container_kind = if self.eof_initcode {
42 Some(CodeType::ReturnContract)
43 } else if self.eof_runtime {
44 Some(CodeType::ReturnOrStop)
45 } else {
46 None
47 };
48
49 if let Some(input_bytes) = &self.bytes {
50 let Some(bytes) = trim_decode(input_bytes) else {
51 return;
52 };
53
54 if bytes[0] == 0xEF {
55 match Eof::decode(bytes) {
56 Ok(eof) => {
57 println!("Decoding: {:#?}", eof);
58 let res = validate_eof_inner(&eof, container_kind);
59 println!("Validation: {:#?}", res);
60 }
61 Err(e) => eprintln!("Decoding Error: {:#?}", e),
62 }
63 } else {
64 eof::printer::print(&bytes)
65 }
66 return;
67 }
68
69 loop {
71 let mut input = String::new();
72 io::stdin().read_line(&mut input).expect("Input Error");
73 if input.len() == 1 {
74 return;
76 }
77 let Some(bytes) = trim_decode(&input) else {
78 return;
79 };
80
81 if bytes.len() > MAX_INITCODE_SIZE {
82 println!(
83 "err: bytes exceeds max code size {} > {}",
84 bytes.len(),
85 MAX_INITCODE_SIZE
86 );
87 continue;
88 }
89 match Eof::decode(bytes) {
90 Ok(eof) => match validate_eof_inner(&eof, container_kind) {
91 Ok(_) => {
92 println!(
93 "OK {}/{}/{}",
94 eof.body.code_section.len(),
95 eof.body.container_section.len(),
96 eof.body.data_section.len()
97 );
98 }
99 Err(eof_error) => match eof_error {
100 EofError::Decode(e) => println!("err decode: {}", e),
101 EofError::Validation(e) => println!("err validation: {}", e),
102 },
103 },
104 Err(e) => println!("err: {:#?}", e),
105 }
106 }
107 }
108}