revm_rwasm_bytecode/
metadata.rs1use std::vec;
2use primitives::{keccak256, Bytes, B256};
3
4mod bytecode;
5pub use bytecode::{AnalyzedBytecode, LegacyBytecode};
6
7#[derive(Debug)]
9pub enum EthereumMetadata {
10 Legacy(LegacyBytecode),
12 Analyzed(AnalyzedBytecode),
14}
15
16pub const ETHEREUM_METADATA_VERSION_ANALYZED: B256 = B256::with_last_byte(0x01);
18
19impl EthereumMetadata {
20 pub fn new_analyzed(bytecode: Bytes) -> Self {
22 let code_hash = keccak256(bytecode.as_ref());
23 Self::Analyzed(AnalyzedBytecode::new(bytecode, code_hash))
24 }
25
26 pub fn new_legacy(bytecode: Bytes) -> Self {
28 let hash = keccak256(bytecode.as_ref());
29 Self::Legacy(LegacyBytecode { hash, bytecode })
30 }
31
32 pub fn read_from_bytes(metadata: &Bytes) -> Option<Self> {
34 if metadata.len() < 32 {
35 return None;
36 }
37 Some(match B256::from_slice(&metadata[0..32]) {
38 ETHEREUM_METADATA_VERSION_ANALYZED => Self::Analyzed(
39 AnalyzedBytecode::deserialize(&metadata[32..])
40 .unwrap_or_else(|_| unreachable!("failed to deserialize analyzed bytecode")),
41 ),
42 hash => {
43 let bytecode = metadata.slice(32..);
44 Self::Legacy(LegacyBytecode { hash, bytecode })
45 }
46 })
47 }
48
49 pub fn write_to_bytes(&self) -> Bytes {
51 match self {
52 EthereumMetadata::Legacy(legacy_bytecode) => {
53 let mut result = vec![];
54 result.extend_from_slice(&legacy_bytecode.hash[..]);
55 result.extend_from_slice(&legacy_bytecode.bytecode[..]);
56 result.into()
57 }
58 EthereumMetadata::Analyzed(analyzed_bytecode) => {
59 let hint_size = analyzed_bytecode.hint_size();
60 let mut result = vec![0u8; B256::len_bytes() + hint_size];
61 result[0..B256::len_bytes()]
62 .copy_from_slice(ÐEREUM_METADATA_VERSION_ANALYZED[..]);
63 analyzed_bytecode
64 .serialize(&mut result[B256::len_bytes()..])
65 .unwrap_or_else(|_| unreachable!("evm: failed to serialize analyzed bytecode"));
66 result.into()
67 }
68 }
69 }
70
71 pub fn code_size(&self) -> usize {
73 match self {
74 EthereumMetadata::Legacy(bytecode) => bytecode.bytecode.len(),
75 EthereumMetadata::Analyzed(bytecode) => bytecode.len(),
76 }
77 }
78
79 pub fn code_hash(&self) -> B256 {
81 match self {
82 EthereumMetadata::Legacy(bytecode) => bytecode.hash,
83 EthereumMetadata::Analyzed(bytecode) => bytecode.hash,
84 }
85 }
86
87 pub fn code_copy(&self) -> Bytes {
89 match self {
90 EthereumMetadata::Legacy(bytecode) => bytecode.bytecode.clone(),
91 EthereumMetadata::Analyzed(bytecode) => bytecode.bytecode.slice(0..bytecode.len()),
92 }
93 }
94}