1use std::collections::BTreeMap;
2use std::sync::{Arc, LazyLock};
3
4use bytes::{BufMut, Bytes, BytesMut};
5use ethereum_types::{H256, U256};
6use ethrex_crypto::{Crypto, NativeCrypto};
7use ethrex_trie::Trie;
8use rustc_hash::FxHashMap;
9use serde::{Deserialize, Serialize};
10
11use ethrex_rlp::{
12 decode::RLPDecode,
13 encode::RLPEncode,
14 error::RLPDecodeError,
15 structs::{Decoder, Encoder},
16};
17
18use super::GenesisAccount;
19use crate::constants::{EMPTY_KECCAK_HASH, EMPTY_TRIE_HASH};
20
21static EMPTY_JUMPDESTS: LazyLock<Arc<[u8]>> = LazyLock::new(|| Arc::from(Vec::new()));
26
27#[derive(Debug, Default)]
32pub struct InitcodeBuffer {
33 bytecode: BytesMut,
34 jumpdests: Option<Arc<[u8]>>,
35}
36
37impl InitcodeBuffer {
38 pub fn set(&mut self, initcode: &[u8]) {
41 let needed = initcode.len().saturating_add(BYTECODE_PADDING);
42 let capacity = self.bytecode.capacity();
43 if capacity < needed {
44 self.bytecode = BytesMut::with_capacity(needed.max(capacity.saturating_mul(2)));
48 } else {
49 self.bytecode.clear();
50 }
51 self.bytecode.extend_from_slice(initcode);
52 }
53
54 pub fn clear(&mut self) {
56 self.bytecode.clear();
57 }
58
59 pub fn initcode(&self) -> &[u8] {
61 &self.bytecode
62 }
63
64 pub fn capacity(&self) -> usize {
66 self.bytecode.capacity()
67 }
68
69 pub fn is_allocated(&self) -> bool {
71 self.bytecode.capacity() > 0 || self.jumpdests.is_some()
72 }
73}
74
75fn zeroed_bitmap(len: usize) -> Arc<[u8]> {
78 std::iter::repeat_n(0, len).collect()
79}
80
81fn zeroed_bitmap_in(scratch: Option<Arc<[u8]>>, len: usize) -> Arc<[u8]> {
86 let outgrown = match scratch {
87 Some(mut bitmap) if bitmap.len() >= len => {
88 if let Some(bits) = Arc::get_mut(&mut bitmap) {
89 bits.fill(0);
93 return bitmap;
94 }
95 0
96 }
97 Some(bitmap) => bitmap.len(),
98 None => 0,
99 };
100 zeroed_bitmap(len.max(outgrown.saturating_mul(2)))
101}
102
103fn mark_jumpdests(code: &[u8], bitmap: &mut [u8]) -> bool {
107 #[cfg(any(
108 target_arch = "aarch64",
109 all(target_arch = "x86_64", target_feature = "ssse3")
110 ))]
111 let any = by_block::jumpdests(code, bitmap);
112 #[cfg(not(any(
113 target_arch = "aarch64",
114 all(target_arch = "x86_64", target_feature = "ssse3")
115 )))]
116 let any = jumpdests_by_opcode(code, bitmap);
117 any
118}
119
120pub const BYTECODE_PADDING: usize = 33;
125
126#[derive(Clone, Debug, PartialEq, Eq, Hash)]
127pub struct Code {
128 pub hash: H256,
134 bytecode: Bytes,
136 bytecode_len: usize,
138 jumpdests: Arc<[u8]>,
153}
154
155impl Code {
156 pub fn from_bytecode_unchecked(code: Bytes, hash: H256) -> Self {
163 let jumpdests = Self::compute_jumpdests(&code);
164 Self::from_parts_unchecked(hash, &code, jumpdests)
165 }
166
167 pub fn from_bytecode(code: Bytes, crypto: &dyn Crypto) -> Self {
170 let jumpdests = Self::compute_jumpdests(&code);
171 let hash = H256(crypto.keccak256(code.as_ref()));
172 Self::from_parts_unchecked(hash, &code, jumpdests)
173 }
174
175 pub fn from_parts_unchecked(hash: H256, code: &[u8], jumpdests: Arc<[u8]>) -> Self {
183 let bytecode_len = code.len();
184 let mut padded_code = Vec::with_capacity(bytecode_len + BYTECODE_PADDING);
185 padded_code.extend_from_slice(code);
186 padded_code.extend_from_slice(&[0u8; BYTECODE_PADDING]);
187 Self {
188 hash,
189 bytecode: Bytes::from_owner(padded_code),
190 bytecode_len,
191 jumpdests,
192 }
193 }
194
195 pub fn from_initcode_buffer(buffer: InitcodeBuffer) -> Self {
205 let InitcodeBuffer {
206 mut bytecode,
207 jumpdests,
208 } = buffer;
209 let bytecode_len = bytecode.len();
210 let bitmap_len = bytecode_len.div_ceil(8);
211 let mut jumpdests = zeroed_bitmap_in(jumpdests, bitmap_len);
212 mark_jumpdests(&bytecode, &mut Arc::make_mut(&mut jumpdests)[..bitmap_len]);
215 bytecode.extend_from_slice(&[0u8; BYTECODE_PADDING]);
216 Self {
217 hash: H256::zero(),
218 bytecode: bytecode.freeze(),
219 bytecode_len,
220 jumpdests,
221 }
222 }
223
224 pub fn into_initcode_buffer(self) -> InitcodeBuffer {
228 let mut bytecode = self.bytecode.try_into_mut().unwrap_or_default();
229 bytecode.clear();
230 let mut jumpdests = self.jumpdests;
231 let unique = Arc::get_mut(&mut jumpdests).is_some();
232 InitcodeBuffer {
233 bytecode,
234 jumpdests: unique.then_some(jumpdests),
235 }
236 }
237
238 pub fn compute_jumpdests(code: &[u8]) -> Arc<[u8]> {
248 if code.is_empty() {
250 return EMPTY_JUMPDESTS.clone();
251 }
252 let mut bitmap = zeroed_bitmap(code.len().div_ceil(8));
253 let any = mark_jumpdests(code, Arc::make_mut(&mut bitmap));
254 if any { bitmap } else { EMPTY_JUMPDESTS.clone() }
258 }
259
260 #[inline]
263 pub fn is_valid_jumpdest(&self, offset: usize) -> bool {
264 self.jumpdests
265 .get(offset / 8)
266 .is_some_and(|byte| byte & (1 << (offset % 8)) != 0)
267 }
268
269 #[inline]
271 pub fn jumpdests(&self) -> &[u8] {
272 &self.jumpdests
273 }
274
275 #[inline]
276 pub fn code(&self) -> &[u8] {
277 self.bytecode.get(..self.bytecode_len).unwrap_or_default()
278 }
279
280 #[inline]
281 pub fn code_bytes(&self) -> Bytes {
282 self.bytecode.slice(..self.bytecode_len)
283 }
284
285 #[inline]
286 pub fn len(&self) -> usize {
287 self.bytecode_len
288 }
289
290 #[inline]
291 pub fn is_empty(&self) -> bool {
292 self.bytecode_len == 0
293 }
294
295 #[inline]
299 pub fn dispatch_buf(&self) -> &[u8] {
300 &self.bytecode
301 }
302
303 pub fn size(&self) -> usize {
314 let hash_size = size_of::<H256>();
315 let bytes_size = size_of::<Bytes>() + self.bytecode.len();
316 let bitmap_size = size_of::<Arc<[u8]>>() + self.jumpdests.len();
317 hash_size + bytes_size + bitmap_size
318 }
319}
320
321const OP_JUMPDEST: u8 = 0x5B;
324const OP_PUSH1: u8 = 0x60;
325const OP_PUSH32: u8 = 0x7F;
326
327#[cfg_attr(
335 any(
336 target_arch = "aarch64",
337 all(target_arch = "x86_64", target_feature = "ssse3")
338 ),
339 allow(dead_code)
340)]
341fn jumpdests_by_opcode(code: &[u8], bitmap: &mut [u8]) -> bool {
342 let mut any = false;
343 let mut current_byte = usize::MAX;
344 let mut bits = 0u8;
345 let mut i = 0;
346 while i < code.len() {
347 match code[i] {
348 OP_JUMPDEST => {
349 if i / 8 != current_byte {
350 if let Some(byte) = bitmap.get_mut(current_byte) {
351 *byte = bits;
352 }
353 current_byte = i / 8;
354 bits = 0;
355 }
356 bits |= 1 << (i % 8);
357 any = true;
358 }
359 c @ OP_PUSH1..=OP_PUSH32 => i += usize::from(c - OP_PUSH1) + 1,
361 _ => (),
362 }
363 i += 1;
364 }
365 if let Some(byte) = bitmap.get_mut(current_byte) {
366 *byte = bits;
367 }
368 any
369}
370
371#[cfg(any(
383 target_arch = "aarch64",
384 all(target_arch = "x86_64", target_feature = "ssse3")
385))]
386mod by_block {
387 use super::{OP_JUMPDEST, OP_PUSH1};
388 use lanes::Lanes;
389
390 const BLOCK: usize = 64;
392 const GROUP: usize = 16;
394
395 pub(super) fn jumpdests(code: &[u8], bitmap: &mut [u8]) -> bool {
397 let mut walks = Walks::new();
398 let (blocks, tail) = code.as_chunks::<BLOCK>();
399 let mut carry = 0;
400 let mut any = 0;
401 for (block, word) in blocks.iter().zip(bitmap.as_chunks_mut::<8>().0) {
403 let valid = block_jumpdests(block, &mut carry, &mut walks);
404 *word = valid.to_le_bytes();
405 any |= valid;
406 }
407 if !tail.is_empty() {
408 let mut padded = [0; BLOCK];
410 padded[..tail.len()].copy_from_slice(tail);
411 let valid = block_jumpdests(&padded, &mut carry, &mut walks);
412 let rest = &mut bitmap[blocks.len() * 8..];
413 rest.copy_from_slice(&valid.to_le_bytes()[..rest.len()]);
414 any |= valid;
415 }
416 any != 0
417 }
418
419 struct Walks {
426 exits: [u8; 2 * BLOCK],
427 low_stops: [u8; 2 * BLOCK],
428 high_stops: [u8; 2 * BLOCK],
429 }
430
431 impl Walks {
432 fn new() -> Self {
433 Self {
434 exits: core::array::from_fn(|i| i as u8),
435 low_stops: [0; 2 * BLOCK],
436 high_stops: [0; 2 * BLOCK],
437 }
438 }
439 }
440
441 #[inline(always)]
446 fn block_jumpdests(block: &[u8; BLOCK], carry: &mut usize, walks: &mut Walks) -> u64 {
447 let groups = block.as_chunks::<GROUP>().0;
448 let groups: [Lanes; BLOCK / GROUP] = core::array::from_fn(|g| Lanes::load(&groups[g]));
449 let jumpdests = Lanes::bits(groups.map(|bytes| bytes.eq(Lanes::splat(OP_JUMPDEST))));
450 for (g, bytes) in groups.into_iter().enumerate() {
451 let (exits, low_stops, high_stops) = group_walks(bytes);
452 let exits = exits.add(Lanes::splat((g * GROUP) as u8));
454 exits.store(&mut walks.exits.as_chunks_mut::<GROUP>().0[g]);
455 low_stops.store(&mut walks.low_stops.as_chunks_mut::<GROUP>().0[g]);
456 high_stops.store(&mut walks.high_stops.as_chunks_mut::<GROUP>().0[g]);
457 }
458 let mut at = *carry;
459 let mut opcodes = 0;
460 for _ in 0..BLOCK / GROUP {
461 let i = at % (2 * BLOCK);
463 let stops = u64::from(walks.low_stops[i]) | (u64::from(walks.high_stops[i]) << 8);
464 let group_start = i & (BLOCK - GROUP);
466 opcodes |= stops << group_start;
467 at = usize::from(walks.exits[i]);
468 }
469 *carry = at - BLOCK;
472 jumpdests & opcodes
473 }
474
475 #[inline(always)]
486 fn group_walks(bytes: Lanes) -> (Lanes, Lanes, Lanes) {
487 const POSITIONS_PLUS_ONE: [u8; GROUP] =
488 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16];
489 const LOW_POSITION_BITS: [u8; GROUP] =
490 [1, 2, 4, 8, 16, 32, 64, 128, 0, 0, 0, 0, 0, 0, 0, 0];
491 const HIGH_POSITION_BITS: [u8; GROUP] =
492 [0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 8, 16, 32, 64, 128];
493 let is_push = bytes.and(Lanes::splat(0xE0)).eq(Lanes::splat(OP_PUSH1));
496 let immediates = is_push.and(bytes.sub(Lanes::splat(OP_PUSH1 - 1)));
497 let mut exits = Lanes::load(&POSITIONS_PLUS_ONE).add(immediates);
499 let mut low_stops = Lanes::load(&LOW_POSITION_BITS);
500 let mut high_stops = Lanes::load(&HIGH_POSITION_BITS);
501 for round in 0..4 {
506 if round < 3 {
507 low_stops = low_stops.or(low_stops.lookup(exits));
508 }
509 high_stops = high_stops.or(high_stops.lookup(exits));
510 exits = exits.max(exits.lookup(exits));
511 }
512 (exits, low_stops, high_stops)
513 }
514
515 #[cfg(target_arch = "aarch64")]
516 mod lanes {
517 use core::arch::aarch64::*;
518
519 #[derive(Clone, Copy)]
521 pub(super) struct Lanes(uint8x16_t);
522
523 impl Lanes {
527 #[inline(always)]
528 pub(super) fn load(bytes: &[u8; 16]) -> Self {
529 unsafe { Self(vld1q_u8(bytes.as_ptr())) }
530 }
531
532 #[inline(always)]
533 pub(super) fn store(self, out: &mut [u8; 16]) {
534 unsafe { vst1q_u8(out.as_mut_ptr(), self.0) }
535 }
536
537 #[inline(always)]
538 pub(super) fn splat(byte: u8) -> Self {
539 unsafe { Self(vdupq_n_u8(byte)) }
540 }
541
542 #[inline(always)]
543 pub(super) fn and(self, other: Self) -> Self {
544 unsafe { Self(vandq_u8(self.0, other.0)) }
545 }
546
547 #[inline(always)]
548 pub(super) fn or(self, other: Self) -> Self {
549 unsafe { Self(vorrq_u8(self.0, other.0)) }
550 }
551
552 #[inline(always)]
553 pub(super) fn add(self, other: Self) -> Self {
554 unsafe { Self(vaddq_u8(self.0, other.0)) }
555 }
556
557 #[inline(always)]
558 pub(super) fn sub(self, other: Self) -> Self {
559 unsafe { Self(vsubq_u8(self.0, other.0)) }
560 }
561
562 #[inline(always)]
564 pub(super) fn eq(self, other: Self) -> Self {
565 unsafe { Self(vceqq_u8(self.0, other.0)) }
566 }
567
568 #[inline(always)]
569 pub(super) fn max(self, other: Self) -> Self {
570 unsafe { Self(vmaxq_u8(self.0, other.0)) }
571 }
572
573 #[inline(always)]
575 pub(super) fn lookup(self, indices: Self) -> Self {
576 unsafe { Self(vqtbl1q_u8(self.0, indices.0)) }
577 }
578
579 #[inline(always)]
585 pub(super) fn bits(masks: [Self; 4]) -> u64 {
586 unsafe {
587 let position_bits = vreinterpretq_u8_u64(vdupq_n_u64(0x8040_2010_0804_0201));
588 let [a, b, c, d] = masks.map(|m| vandq_u8(m.0, position_bits));
589 let quarters = vpaddq_u8(vpaddq_u8(a, b), vpaddq_u8(c, d));
590 vgetq_lane_u64::<0>(vreinterpretq_u64_u8(vpaddq_u8(quarters, quarters)))
591 }
592 }
593 }
594 }
595
596 #[cfg(target_arch = "x86_64")]
597 mod lanes {
598 use core::arch::x86_64::*;
599
600 #[derive(Clone, Copy)]
602 pub(super) struct Lanes(__m128i);
603
604 impl Lanes {
608 #[inline(always)]
609 pub(super) fn load(bytes: &[u8; 16]) -> Self {
610 unsafe { Self(_mm_loadu_si128(bytes.as_ptr().cast())) }
611 }
612
613 #[inline(always)]
614 pub(super) fn store(self, out: &mut [u8; 16]) {
615 unsafe { _mm_storeu_si128(out.as_mut_ptr().cast(), self.0) }
616 }
617
618 #[inline(always)]
619 pub(super) fn splat(byte: u8) -> Self {
620 unsafe { Self(_mm_set1_epi8(byte as i8)) }
621 }
622
623 #[inline(always)]
624 pub(super) fn and(self, other: Self) -> Self {
625 unsafe { Self(_mm_and_si128(self.0, other.0)) }
626 }
627
628 #[inline(always)]
629 pub(super) fn or(self, other: Self) -> Self {
630 unsafe { Self(_mm_or_si128(self.0, other.0)) }
631 }
632
633 #[inline(always)]
634 pub(super) fn add(self, other: Self) -> Self {
635 unsafe { Self(_mm_add_epi8(self.0, other.0)) }
636 }
637
638 #[inline(always)]
639 pub(super) fn sub(self, other: Self) -> Self {
640 unsafe { Self(_mm_sub_epi8(self.0, other.0)) }
641 }
642
643 #[inline(always)]
645 pub(super) fn eq(self, other: Self) -> Self {
646 unsafe { Self(_mm_cmpeq_epi8(self.0, other.0)) }
647 }
648
649 #[inline(always)]
650 pub(super) fn max(self, other: Self) -> Self {
651 unsafe { Self(_mm_max_epu8(self.0, other.0)) }
652 }
653
654 #[inline(always)]
657 pub(super) fn lookup(self, indices: Self) -> Self {
658 unsafe {
662 let indices = _mm_add_epi8(indices.0, _mm_set1_epi8(0x70));
663 Self(_mm_shuffle_epi8(self.0, indices))
664 }
665 }
666
667 #[inline(always)]
669 pub(super) fn bits(masks: [Self; 4]) -> u64 {
670 masks.iter().enumerate().fold(0, |bits, (i, m)| {
671 let lanes = unsafe { _mm_movemask_epi8(m.0) } as u16;
672 bits | (u64::from(lanes) << (16 * i))
673 })
674 }
675 }
676 }
677}
678
679#[derive(Serialize, Deserialize)]
697struct CodeSerde {
698 hash: H256,
699 code: Bytes,
700 jump_targets: Arc<[u32]>,
701}
702
703impl Serialize for Code {
704 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
705 CodeSerde {
706 hash: self.hash,
707 code: self.code_bytes(),
708 jump_targets: Arc::from([]),
709 }
710 .serialize(serializer)
711 }
712}
713
714impl<'de> Deserialize<'de> for Code {
715 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
716 let CodeSerde {
719 hash,
720 code,
721 jump_targets: _,
722 } = CodeSerde::deserialize(deserializer)?;
723 Ok(Self::from_parts_unchecked(
724 hash,
725 &code,
726 Self::compute_jumpdests(&code),
727 ))
728 }
729}
730
731#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
732pub struct CodeMetadata {
733 pub length: u64,
734}
735
736#[derive(Clone, Default, Debug, PartialEq, Eq, Serialize, Deserialize)]
737pub struct Account {
738 pub info: AccountInfo,
739 pub code: Code,
740 pub storage: FxHashMap<H256, U256>,
741}
742
743#[derive(Clone, Debug, PartialEq, Serialize, Deserialize, Eq, Hash)]
744pub struct AccountInfo {
745 pub code_hash: H256,
746 pub balance: U256,
747 pub nonce: u64,
748}
749
750#[derive(Clone, Copy, Debug, PartialEq, Serialize, Deserialize)]
751pub struct AccountState {
752 pub nonce: u64,
753 pub balance: U256,
754 pub storage_root: H256,
755 pub code_hash: H256,
756}
757
758#[derive(Clone, Copy, Debug, Default, PartialEq)]
766pub struct AccountStateSlimCodec(pub AccountState);
767
768impl Default for AccountInfo {
769 fn default() -> Self {
770 Self {
771 code_hash: *EMPTY_KECCAK_HASH,
772 balance: Default::default(),
773 nonce: Default::default(),
774 }
775 }
776}
777
778impl Default for AccountState {
779 fn default() -> Self {
780 Self {
781 nonce: Default::default(),
782 balance: Default::default(),
783 storage_root: *EMPTY_TRIE_HASH,
784 code_hash: *EMPTY_KECCAK_HASH,
785 }
786 }
787}
788
789impl Default for Code {
790 fn default() -> Self {
791 Self {
792 bytecode: Bytes::from_static(&[0u8; BYTECODE_PADDING]),
793 bytecode_len: 0,
794 hash: *EMPTY_KECCAK_HASH,
795 jumpdests: EMPTY_JUMPDESTS.clone(),
796 }
797 }
798}
799
800impl From<GenesisAccount> for Account {
801 fn from(genesis: GenesisAccount) -> Self {
802 let code = Code::from_bytecode(genesis.code, &NativeCrypto);
803 Self {
804 info: AccountInfo {
805 code_hash: code.hash,
806 balance: genesis.balance,
807 nonce: genesis.nonce,
808 },
809 code,
810 storage: genesis
811 .storage
812 .iter()
813 .map(|(k, v)| (H256(k.to_big_endian()), *v))
814 .collect(),
815 }
816 }
817}
818
819pub fn code_hash(code: &Bytes, crypto: &dyn Crypto) -> H256 {
820 H256(crypto.keccak256(code.as_ref()))
821}
822
823pub const EIP7702_DELEGATION_PREFIX: [u8; 3] = [0xef, 0x01, 0x00];
826pub const EIP7702_DELEGATED_CODE_LEN: usize = 23;
829
830pub fn is_eip7702_delegation(code: &[u8]) -> bool {
833 code.len() == EIP7702_DELEGATED_CODE_LEN && code.starts_with(&EIP7702_DELEGATION_PREFIX)
834}
835
836impl RLPEncode for AccountInfo {
837 fn encode(&self, buf: &mut dyn bytes::BufMut) {
838 Encoder::new(buf)
839 .encode_field(&self.code_hash)
840 .encode_field(&self.balance)
841 .encode_field(&self.nonce)
842 .finish();
843 }
844}
845
846impl RLPDecode for AccountInfo {
847 fn decode_unfinished(rlp: &[u8]) -> Result<(AccountInfo, &[u8]), RLPDecodeError> {
848 let decoder = Decoder::new(rlp)?;
849 let (code_hash, decoder) = decoder.decode_field("code_hash")?;
850 let (balance, decoder) = decoder.decode_field("balance")?;
851 let (nonce, decoder) = decoder.decode_field("nonce")?;
852 let account_info = AccountInfo {
853 code_hash,
854 balance,
855 nonce,
856 };
857 Ok((account_info, decoder.finish()?))
858 }
859}
860
861impl RLPEncode for AccountState {
862 fn encode(&self, buf: &mut dyn bytes::BufMut) {
863 Encoder::new(buf)
864 .encode_field(&self.nonce)
865 .encode_field(&self.balance)
866 .encode_field(&self.storage_root)
867 .encode_field(&self.code_hash)
868 .finish();
869 }
870}
871
872impl RLPDecode for AccountState {
873 fn decode_unfinished(rlp: &[u8]) -> Result<(AccountState, &[u8]), RLPDecodeError> {
874 let decoder = Decoder::new(rlp)?;
875 let (nonce, decoder) = decoder.decode_field("nonce")?;
876 let (balance, decoder) = decoder.decode_field("balance")?;
877 let (storage_root, decoder) = decoder.decode_field("storage_root")?;
878 let (code_hash, decoder) = decoder.decode_field("code_hash")?;
879 let state = AccountState {
880 nonce,
881 balance,
882 storage_root,
883 code_hash,
884 };
885 Ok((state, decoder.finish()?))
886 }
887}
888
889impl RLPEncode for AccountStateSlimCodec {
890 fn encode(&self, buf: &mut dyn BufMut) {
891 struct StorageRootCodec<'a>(&'a H256);
892 impl RLPEncode for StorageRootCodec<'_> {
893 fn encode(&self, buf: &mut dyn BufMut) {
894 let data = if *self.0 != *EMPTY_TRIE_HASH {
895 self.0.as_bytes()
896 } else {
897 &[]
898 };
899
900 data.encode(buf);
901 }
902 }
903
904 struct CodeHashCodec<'a>(&'a H256);
905 impl RLPEncode for CodeHashCodec<'_> {
906 fn encode(&self, buf: &mut dyn BufMut) {
907 let data = if *self.0 != *EMPTY_KECCAK_HASH {
908 self.0.as_bytes()
909 } else {
910 &[]
911 };
912
913 data.encode(buf);
914 }
915 }
916
917 Encoder::new(buf)
918 .encode_field(&self.0.nonce)
919 .encode_field(&self.0.balance)
920 .encode_field(&StorageRootCodec(&self.0.storage_root))
921 .encode_field(&CodeHashCodec(&self.0.code_hash))
922 .finish();
923 }
924}
925
926impl RLPDecode for AccountStateSlimCodec {
927 fn decode_unfinished(rlp: &[u8]) -> Result<(Self, &[u8]), RLPDecodeError> {
928 struct StorageRootCodec(H256);
929 impl RLPDecode for StorageRootCodec {
930 fn decode_unfinished(mut rlp: &[u8]) -> Result<(Self, &[u8]), RLPDecodeError> {
931 let value = match rlp.split_off_first() {
932 Some(0x80) => *EMPTY_TRIE_HASH,
933 Some(0xA0) => {
934 let data;
935 (data, rlp) = rlp
936 .split_first_chunk::<32>()
937 .ok_or(RLPDecodeError::InvalidLength)?;
938 H256(*data)
939 }
940 _ => return Err(RLPDecodeError::InvalidLength),
941 };
942
943 Ok((Self(value), rlp))
944 }
945 }
946
947 struct CodeHashCodec(H256);
948 impl RLPDecode for CodeHashCodec {
949 fn decode_unfinished(mut rlp: &[u8]) -> Result<(Self, &[u8]), RLPDecodeError> {
950 let value = match rlp.split_off_first() {
951 Some(0x80) => *EMPTY_KECCAK_HASH,
952 Some(0xA0) => {
953 let data;
954 (data, rlp) = rlp
955 .split_first_chunk::<32>()
956 .ok_or(RLPDecodeError::InvalidLength)?;
957 H256(*data)
958 }
959 _ => return Err(RLPDecodeError::InvalidLength),
960 };
961
962 Ok((Self(value), rlp))
963 }
964 }
965
966 let decoder = Decoder::new(rlp)?;
967 let (nonce, decoder) = decoder.decode_field("nonce")?;
968 let (balance, decoder) = decoder.decode_field("balance")?;
969 let (StorageRootCodec(storage_root), decoder) = decoder.decode_field("storage_root")?;
970 let (CodeHashCodec(code_hash), decoder) = decoder.decode_field("code_hash")?;
971
972 Ok((
973 Self(AccountState {
974 nonce,
975 balance,
976 storage_root,
977 code_hash,
978 }),
979 decoder.finish()?,
980 ))
981 }
982}
983
984pub fn compute_storage_root(storage: &BTreeMap<U256, U256>, crypto: &dyn Crypto) -> H256 {
985 let iter = storage.iter().filter_map(|(k, v)| {
986 (!v.is_zero()).then_some((
987 crypto.keccak256(&k.to_big_endian()).to_vec(),
988 v.encode_to_vec(),
989 ))
990 });
991 Trie::compute_hash_from_unsorted_iter(iter, crypto)
992}
993
994impl From<&GenesisAccount> for AccountState {
995 fn from(value: &GenesisAccount) -> Self {
996 AccountState {
997 nonce: value.nonce,
998 balance: value.balance,
999 storage_root: compute_storage_root(&value.storage, &NativeCrypto),
1000 code_hash: code_hash(&value.code, &NativeCrypto),
1001 }
1002 }
1003}
1004
1005impl Account {
1006 pub fn new(balance: U256, code: Code, nonce: u64, storage: FxHashMap<H256, U256>) -> Self {
1007 Self {
1008 info: AccountInfo {
1009 balance,
1010 code_hash: code.hash,
1011 nonce,
1012 },
1013 code,
1014 storage,
1015 }
1016 }
1017}
1018
1019impl AccountInfo {
1020 pub fn is_empty(&self) -> bool {
1021 self.balance.is_zero() && self.nonce == 0 && self.code_hash == *EMPTY_KECCAK_HASH
1022 }
1023}
1024
1025#[cfg(test)]
1026mod test {
1027 use std::str::FromStr;
1028
1029 use super::*;
1030
1031 #[derive(serde::Serialize)]
1035 struct OldCodeSerde {
1036 hash: H256,
1037 code: Bytes,
1038 jump_targets: Vec<u32>,
1039 }
1040
1041 #[derive(serde::Serialize)]
1046 struct OldWrap {
1047 code: OldCodeSerde,
1048 tail: u64,
1049 }
1050 #[derive(serde::Deserialize)]
1051 struct NewWrap {
1052 code: Code,
1053 tail: u64,
1054 }
1055
1056 #[test]
1062 fn embedded_code_decodes_an_old_layout_bincode_row() {
1063 let bytecode = Bytes::from(vec![0x60, 0x00, 0x5b, 0x00]);
1065 let hash = H256::from_low_u64_be(0xabc);
1066 const SENTINEL: u64 = 0x0123_4567_89ab_cdef;
1067 let old = OldWrap {
1068 code: OldCodeSerde {
1069 hash,
1070 code: bytecode.clone(),
1071 jump_targets: vec![2], },
1073 tail: SENTINEL,
1074 };
1075 let bytes = bincode::serialize(&old).expect("serialize old layout");
1076
1077 let decoded: NewWrap = bincode::deserialize(&bytes).expect("decode old row under new Code");
1078 assert_eq!(decoded.code.hash, hash);
1079 assert_eq!(decoded.code.code_bytes(), bytecode);
1080 assert_eq!(
1082 decoded.tail, SENTINEL,
1083 "field after Code corrupted by layout shift"
1084 );
1085 assert!(decoded.code.is_valid_jumpdest(2));
1087 assert!(!decoded.code.is_valid_jumpdest(1));
1088 }
1089
1090 #[test]
1091 fn test_code_hash() {
1092 let empty_code = Bytes::new();
1093 let hash = code_hash(&empty_code, &NativeCrypto);
1094 assert_eq!(
1095 hash,
1096 H256::from_str("c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470")
1097 .unwrap()
1098 )
1099 }
1100
1101 #[test]
1102 fn test_is_eip7702_delegation_valid() {
1103 let mut code = Vec::with_capacity(23);
1105 code.extend_from_slice(&EIP7702_DELEGATION_PREFIX);
1106 code.extend_from_slice(&[0x42; 20]);
1107 assert!(is_eip7702_delegation(&code));
1108 }
1109
1110 #[test]
1111 fn test_is_eip7702_delegation_rejects_empty() {
1112 assert!(!is_eip7702_delegation(&[]));
1113 }
1114
1115 #[test]
1116 fn test_is_eip7702_delegation_rejects_short() {
1117 assert!(!is_eip7702_delegation(&EIP7702_DELEGATION_PREFIX));
1119 }
1120
1121 #[test]
1122 fn test_is_eip7702_delegation_rejects_long() {
1123 let mut code = Vec::with_capacity(24);
1125 code.extend_from_slice(&EIP7702_DELEGATION_PREFIX);
1126 code.extend_from_slice(&[0x42; 21]);
1127 assert!(!is_eip7702_delegation(&code));
1128 }
1129
1130 #[test]
1131 fn test_is_eip7702_delegation_rejects_wrong_prefix() {
1132 let mut code = Vec::with_capacity(23);
1134 code.extend_from_slice(&[0xef, 0x01, 0x01]); code.extend_from_slice(&[0x42; 20]);
1136 assert!(!is_eip7702_delegation(&code));
1137 }
1138
1139 #[test]
1140 fn test_is_eip7702_delegation_rejects_arbitrary_contract_code() {
1141 let code = vec![0x60, 0x60, 0x60, 0x40, 0x52 ];
1143 assert!(!is_eip7702_delegation(&code));
1144 }
1145
1146 #[cfg(any(
1149 target_arch = "aarch64",
1150 all(target_arch = "x86_64", target_feature = "ssse3")
1151 ))]
1152 mod by_block_against_the_scan {
1153 use super::*;
1154
1155 fn assert_same_jumpdests(code: &[u8]) {
1156 let mut want = vec![0; code.len().div_ceil(8)];
1157 let mut got = want.clone();
1158 let want_any = jumpdests_by_opcode(code, &mut want);
1159 let got_any = by_block::jumpdests(code, &mut got);
1160 assert_eq!((got_any, got), (want_any, want), "code {code:02x?}");
1161 }
1162
1163 #[test]
1167 fn matches_around_group_and_block_boundaries() {
1168 const BYTES: [u8; 9] = [
1171 0x00,
1172 OP_JUMPDEST,
1173 OP_PUSH1,
1174 OP_PUSH1 + 1,
1175 OP_PUSH1 + 14,
1176 OP_PUSH1 + 15,
1177 OP_PUSH1 + 16,
1178 OP_PUSH32 - 1,
1179 OP_PUSH32,
1180 ];
1181 let lengths = [
1182 1, 15, 16, 17, 31, 32, 33, 63, 64, 65, 96, 127, 128, 129, 193,
1183 ];
1184 for filler in [OP_JUMPDEST, OP_PUSH1] {
1188 for len in lengths {
1189 for at in 0..len {
1190 for first in BYTES {
1191 for second in [None].into_iter().chain(BYTES.map(Some)) {
1192 let mut code = vec![filler; len];
1193 code[at] = first;
1194 if let (Some(second), Some(byte)) = (second, code.get_mut(at + 1)) {
1195 *byte = second;
1196 }
1197 assert_same_jumpdests(&code);
1198 }
1199 }
1200 }
1201 }
1202 }
1203 }
1204
1205 #[test]
1208 fn matches_on_random_code() {
1209 let mut state = 0x9E37_79B9_7F4A_7C15_u64;
1211 let mut next = move || {
1212 state ^= state << 13;
1213 state ^= state >> 7;
1214 state ^= state << 17;
1215 state
1216 };
1217 let jumpdest_and_pushes: Vec<u8> = std::iter::once(OP_JUMPDEST)
1218 .chain(OP_PUSH1..=OP_PUSH32)
1219 .collect();
1220 let all_bytes: Vec<u8> = (0..=u8::MAX).collect();
1221 let mixes: [&[u8]; 4] = [
1222 &[0x00, OP_JUMPDEST, OP_PUSH1],
1223 &[OP_JUMPDEST, OP_PUSH1, OP_PUSH1 + 1],
1224 &jumpdest_and_pushes,
1225 &all_bytes,
1226 ];
1227 for mix in mixes {
1228 for _ in 0..200 {
1229 let len = (next() % 4096) as usize;
1230 let code: Vec<u8> = (0..len)
1231 .map(|_| mix[(next() % mix.len() as u64) as usize])
1232 .collect();
1233 assert_same_jumpdests(&code);
1234 }
1235 }
1236 }
1237 }
1238
1239 #[test]
1240 fn a_reused_jump_destination_bitmap_keeps_nothing_of_the_initcode_before() {
1241 let mut first_initcode = [0u8; 16];
1247 first_initcode[8] = 0x5b;
1248 let mut second_initcode = [0u8; 16];
1249 second_initcode[0] = 0x5b;
1250 let mut buffer = InitcodeBuffer::default();
1251 buffer.set(&first_initcode);
1252 let first = Code::from_initcode_buffer(buffer);
1253
1254 let mut buffer = first.into_initcode_buffer();
1255 buffer.set(&second_initcode);
1256 let second = Code::from_initcode_buffer(buffer);
1257
1258 assert!(second.is_valid_jumpdest(0));
1259 assert!(!second.is_valid_jumpdest(8));
1260 }
1261
1262 #[test]
1263 fn shorter_initcode_has_no_jump_destination_past_its_end_in_a_reused_bitmap() {
1264 let mut buffer = InitcodeBuffer::default();
1269 buffer.set(&[0x5b; 64]);
1270 let first = Code::from_initcode_buffer(buffer);
1271
1272 let mut buffer = first.into_initcode_buffer();
1273 buffer.set(&[0x00, 0x5b]); let second = Code::from_initcode_buffer(buffer);
1275
1276 assert!(second.is_valid_jumpdest(1));
1277 assert!(
1278 (0..64)
1279 .filter(|&offset| offset != 1)
1280 .all(|offset| !second.is_valid_jumpdest(offset))
1281 );
1282 }
1283
1284 #[test]
1285 fn a_longer_bitmap_is_reused_whole_and_zeroed() {
1286 let scratch: Arc<[u8]> = Arc::from(vec![0xff; 8]);
1287
1288 let bitmap = zeroed_bitmap_in(Some(scratch), 4);
1289
1290 assert_eq!(&*bitmap, &[0; 8]);
1293 }
1294
1295 #[test]
1296 fn a_buffer_outgrown_by_initcode_at_least_doubles() {
1297 let mut buffer = InitcodeBuffer::default();
1298 buffer.set(&[0; 1000]);
1299
1300 buffer.set(&[0; 1001]);
1301
1302 assert!(buffer.capacity() >= 2 * (1000 + BYTECODE_PADDING));
1305 }
1306
1307 #[test]
1308 fn an_outgrown_bitmap_at_least_doubles() {
1309 let scratch: Arc<[u8]> = Arc::from(vec![0; 4]);
1310
1311 let bitmap = zeroed_bitmap_in(Some(scratch), 5);
1312
1313 assert!(bitmap.len() >= 8);
1314 assert!(bitmap.iter().all(|&byte| byte == 0));
1315 }
1316
1317 #[test]
1318 fn a_handed_back_initcode_buffer_holds_no_bytecode() {
1319 let mut buffer = InitcodeBuffer::default();
1322 buffer.set(&[0x60, 0x01]); let code = Code::from_initcode_buffer(buffer);
1324
1325 let rebuilt = Code::from_initcode_buffer(code.into_initcode_buffer());
1326
1327 assert!(rebuilt.is_empty());
1328 }
1329}