Skip to content

Commit

Permalink
chore: move Bytecode, Requests and Withdrawals to `reth-primiti…
Browse files Browse the repository at this point in the history
…ves-traits` (paradigmxyz#8954)
  • Loading branch information
joshieDo authored Jun 19, 2024
1 parent 590356b commit 32500aa
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 175 deletions.
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions crates/primitives-traits/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,20 @@ workspace = true
[dependencies]
reth-codecs.workspace = true

alloy-consensus.workspace = true
alloy-consensus = { workspace = true, features = ["serde"] }
alloy-eips.workspace = true
alloy-genesis.workspace = true
alloy-primitives.workspace = true
alloy-rlp.workspace = true
alloy-rpc-types-eth = { workspace = true, optional = true }

derive_more.workspace = true
revm-primitives.workspace = true
revm-primitives = { workspace = true, features = ["serde"] }

# misc
thiserror-no-std = { workspace = true, default-features = false }
roaring = "0.10.2"
byteorder = "1"

# required by reth-codecs
modular-bitfield.workspace = true
Expand All @@ -51,6 +52,7 @@ default = ["std"]
std = ["thiserror-no-std/std"]
test-utils = ["arbitrary"]
arbitrary = [
"alloy-consensus/arbitrary",
"dep:arbitrary",
"dep:proptest",
"dep:proptest-derive"
Expand Down
152 changes: 151 additions & 1 deletion crates/primitives-traits/src/account.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
use alloy_consensus::constants::KECCAK_EMPTY;
use alloy_genesis::GenesisAccount;
use alloy_primitives::{keccak256, B256, U256};
use alloy_primitives::{keccak256, Bytes, B256, U256};
use byteorder::{BigEndian, ReadBytesExt};
use bytes::Buf;
use derive_more::Deref;
use reth_codecs::{main_codec, Compact};
use revm_primitives::{Bytecode as RevmBytecode, JumpTable};
use serde::{Deserialize, Serialize};

/// An Ethereum account.
#[main_codec]
Expand Down Expand Up @@ -45,3 +50,148 @@ impl Account {
self.bytecode_hash.unwrap_or(KECCAK_EMPTY)
}
}

/// Bytecode for an account.
///
/// A wrapper around [`revm::primitives::Bytecode`][RevmBytecode] with encoding/decoding support.
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, Deref)]
pub struct Bytecode(pub RevmBytecode);

impl Bytecode {
/// Create new bytecode from raw bytes.
///
/// No analysis will be performed.
pub fn new_raw(bytes: Bytes) -> Self {
Self(RevmBytecode::new_raw(bytes))
}
}

impl Compact for Bytecode {
fn to_compact<B>(self, buf: &mut B) -> usize
where
B: bytes::BufMut + AsMut<[u8]>,
{
let bytecode = &self.0.bytecode()[..];
buf.put_u32(bytecode.len() as u32);
buf.put_slice(bytecode);
let len = match &self.0 {
RevmBytecode::LegacyRaw(_) => {
buf.put_u8(0);
1
}
// `1` has been removed.
RevmBytecode::LegacyAnalyzed(analyzed) => {
buf.put_u8(2);
buf.put_u64(analyzed.original_len() as u64);
let map = analyzed.jump_table().as_slice();
buf.put_slice(map);
1 + 8 + map.len()
}
RevmBytecode::Eof(_) => {
// buf.put_u8(3);
// TODO(EOF)
todo!("EOF")
}
};
len + bytecode.len() + 4
}

// # Panics
//
// A panic will be triggered if a bytecode variant of 1 or greater than 2 is passed from the
// database.
fn from_compact(mut buf: &[u8], _: usize) -> (Self, &[u8]) {
let len = buf.read_u32::<BigEndian>().expect("could not read bytecode length");
let bytes = Bytes::from(buf.copy_to_bytes(len as usize));
let variant = buf.read_u8().expect("could not read bytecode variant");
let decoded = match variant {
0 => Self(RevmBytecode::new_raw(bytes)),
1 => unreachable!("Junk data in database: checked Bytecode variant was removed"),
2 => Self(unsafe {
RevmBytecode::new_analyzed(
bytes,
buf.read_u64::<BigEndian>().unwrap() as usize,
JumpTable::from_slice(buf),
)
}),
// TODO(EOF)
3 => todo!("EOF"),
_ => unreachable!("Junk data in database: unknown Bytecode variant"),
};
(decoded, &[])
}
}

#[cfg(test)]
mod tests {
use super::*;
use alloy_primitives::{hex_literal::hex, B256, U256};
use revm_primitives::LegacyAnalyzedBytecode;

#[test]
fn test_account() {
let mut buf = vec![];
let mut acc = Account::default();
let len = acc.to_compact(&mut buf);
assert_eq!(len, 2);

acc.balance = U256::from(2);
let len = acc.to_compact(&mut buf);
assert_eq!(len, 3);

acc.nonce = 2;
let len = acc.to_compact(&mut buf);
assert_eq!(len, 4);
}

#[test]
fn test_empty_account() {
let mut acc = Account { nonce: 0, balance: U256::ZERO, bytecode_hash: None };
// Nonce 0, balance 0, and bytecode hash set to None is considered empty.
assert!(acc.is_empty());

acc.bytecode_hash = Some(KECCAK_EMPTY);
// Nonce 0, balance 0, and bytecode hash set to KECCAK_EMPTY is considered empty.
assert!(acc.is_empty());

acc.balance = U256::from(2);
// Non-zero balance makes it non-empty.
assert!(!acc.is_empty());

acc.balance = U256::ZERO;
acc.nonce = 10;
// Non-zero nonce makes it non-empty.
assert!(!acc.is_empty());

acc.nonce = 0;
acc.bytecode_hash = Some(B256::from(U256::ZERO));
// Non-empty bytecode hash makes it non-empty.
assert!(!acc.is_empty());
}

#[test]
fn test_bytecode() {
let mut buf = vec![];
let bytecode = Bytecode::new_raw(Bytes::default());
let len = bytecode.to_compact(&mut buf);
assert_eq!(len, 5);

let mut buf = vec![];
let bytecode = Bytecode::new_raw(Bytes::from(&hex!("ffff")));
let len = bytecode.to_compact(&mut buf);
assert_eq!(len, 7);

let mut buf = vec![];
let bytecode = Bytecode(RevmBytecode::LegacyAnalyzed(LegacyAnalyzedBytecode::new(
Bytes::from(&hex!("ffff")),
2,
JumpTable::from_slice(&[0]),
)));
let len = bytecode.clone().to_compact(&mut buf);
assert_eq!(len, 16);

let (decoded, remainder) = Bytecode::from_compact(&buf, len);
assert_eq!(decoded, bytecode);
assert!(remainder.is_empty());
}
}
8 changes: 7 additions & 1 deletion crates/primitives-traits/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,17 @@ pub mod constants;

/// Minimal account
pub mod account;
pub use account::Account;
pub use account::{Account, Bytecode};

mod integer_list;
pub use integer_list::IntegerList;

pub mod request;
pub use request::{Request, Requests};

mod withdrawal;
pub use withdrawal::{Withdrawal, Withdrawals};

/// Common header types
pub mod header;
#[cfg(any(test, feature = "arbitrary", feature = "test-utils"))]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! EIP-7685 requests.
use crate::Request;
pub use alloy_consensus::Request;
use alloy_eips::eip7685::{Decodable7685, Encodable7685};
use alloy_rlp::{Decodable, Encodable};
use derive_more::{Deref, DerefMut, From, IntoIterator};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl Withdrawals {
#[cfg(test)]
mod tests {
use super::*;
use crate::Address;
use alloy_primitives::Address;
use alloy_rlp::{RlpDecodable, RlpEncodable};
use proptest::proptest;

Expand Down
4 changes: 0 additions & 4 deletions crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ reth-chainspec.workspace = true
revm-primitives = { workspace = true, features = ["serde"] }

# ethereum
alloy-consensus = { workspace = true, features = ["serde"] }
alloy-primitives = { workspace = true, features = ["rand", "rlp"] }
alloy-rlp = { workspace = true, features = ["arrayvec"] }
alloy-rpc-types = { workspace = true, optional = true }
Expand All @@ -40,7 +39,6 @@ c-kzg = { workspace = true, features = ["serde"], optional = true }

# misc
bytes.workspace = true
byteorder = "1"
derive_more.workspace = true
modular-bitfield.workspace = true
once_cell.workspace = true
Expand All @@ -62,7 +60,6 @@ revm-primitives = { workspace = true, features = ["arbitrary"] }
nybbles = { workspace = true, features = ["arbitrary"] }
alloy-trie = { workspace = true, features = ["arbitrary"] }
alloy-eips = { workspace = true, features = ["arbitrary"] }
alloy-consensus = { workspace = true, features = ["arbitrary"] }

assert_matches.workspace = true
arbitrary = { workspace = true, features = ["derive"] }
Expand Down Expand Up @@ -94,7 +91,6 @@ arbitrary = [
"reth-ethereum-forks/arbitrary",
"nybbles/arbitrary",
"alloy-trie/arbitrary",
"alloy-consensus/arbitrary",
"alloy-eips/arbitrary",
"dep:arbitrary",
"dep:proptest",
Expand Down
Loading

0 comments on commit 32500aa

Please sign in to comment.