Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions crates/common/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,14 @@ pub static DEPOSIT_TOPIC: LazyLock<H256> = LazyLock::new(|| {
.expect("Failed to decode hex from string")
});

// = Keccak256(RLP([])) as of EIP-7928
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment states "EIP-7928" but this appears to be referencing a hypothetical or future EIP. The EIP number should be verified and corrected if this is not the correct EIP number for Block Access Lists.

Suggested change
// = Keccak256(RLP([])) as of EIP-7928
// = Keccak256(RLP([])), default hash for an empty block access list

Copilot uses AI. Check for mistakes.
pub static EMPTY_BLOCK_ACCESS_LIST_HASH: LazyLock<H256> = LazyLock::new(|| {
H256::from_slice(
&hex::decode("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")
.expect("Failed to decode hex from string"),
)
});
Comment on lines +47 to +52
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The EMPTY_BLOCK_ACCESS_LIST_HASH constant has the same hash value as DEFAULT_OMMERS_HASH (both are "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"). This is the hash of Keccak256(RLP([])), which is correct for an empty list. However, it's redundant to define it separately unless the specification explicitly requires a different constant name. Consider reusing DEFAULT_OMMERS_HASH or documenting why a separate constant is necessary.

Suggested change
pub static EMPTY_BLOCK_ACCESS_LIST_HASH: LazyLock<H256> = LazyLock::new(|| {
H256::from_slice(
&hex::decode("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347")
.expect("Failed to decode hex from string"),
)
});
pub use DEFAULT_OMMERS_HASH as EMPTY_BLOCK_ACCESS_LIST_HASH;

Copilot uses AI. Check for mistakes.

// === EIP-4844 constants ===

/// Gas consumption of a single data blob (== blob byte size).
Expand Down
71 changes: 71 additions & 0 deletions crates/common/serde_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,77 @@ fn parse_duration(input: String) -> Option<Duration> {
Some(res)
}

pub mod block_access_list {

use super::*;
use ethrex_rlp::decode::RLPDecode;
use ethrex_rlp::encode::RLPEncode;

pub mod rlp_str {

use crate::types::block_access_list::BlockAccessList;

use super::*;
pub fn deserialize<'de, D>(d: D) -> Result<BlockAccessList, D::Error>
where
D: Deserializer<'de>,
{
let value = String::deserialize(d)?;
let bytes = hex::decode(value.trim_start_matches("0x"))
.map_err(|e| D::Error::custom(e.to_string()))?;
BlockAccessList::decode(&bytes)
.map_err(|_| D::Error::custom("Failed to RLP decode BAL"))
}

pub fn serialize<S>(value: &BlockAccessList, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let buf = value.encode_to_vec();
serializer.serialize_str(&hex::encode(buf))
Comment on lines +634 to +635
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The serialization function should prepend "0x" to the hex-encoded string for consistency with Ethereum JSON-RPC standards. Currently it only encodes as hex without the prefix, while the deserialization expects and handles the "0x" prefix.

Copilot uses AI. Check for mistakes.
}
}

pub mod rlp_str_opt {

use serde::Serialize;

use crate::types::block_access_list::BlockAccessList;

use super::*;
pub fn deserialize<'de, D>(d: D) -> Result<Option<BlockAccessList>, D::Error>
where
D: Deserializer<'de>,
{
let value = Option::<String>::deserialize(d)?;
match value {
Some(s) if !s.is_empty() => hex::decode(s.trim_start_matches("0x"))
.map_err(|e| D::Error::custom(e.to_string()))
.and_then(|b| {
BlockAccessList::decode(&b)
.map_err(|_| D::Error::custom("Failed to RLP decode BAL"))
})
.map(Some),
_ => Ok(None),
}
}

pub fn serialize<S>(
value: &Option<BlockAccessList>,
serializer: S,
) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let bal = value
.as_ref()
.map(|bal| bal.encode_to_vec())
.map(hex::encode);
Comment on lines +670 to +673
Copy link

Copilot AI Dec 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The serialization function should prepend "0x" to the hex-encoded string for consistency with Ethereum JSON-RPC standards. Currently it only encodes as hex without the prefix, while the deserialization expects and handles the "0x" prefix.

Copilot uses AI. Check for mistakes.
Option::<String>::serialize(&bal, serializer)
}
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
8 changes: 8 additions & 0 deletions crates/common/types/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ pub struct BlockHeader {
#[serde(skip_serializing_if = "Option::is_none", default = "Option::default")]
#[rkyv(with=crate::rkyv_utils::OptionH256Wrapper)]
pub requests_hash: Option<H256>,
#[serde(skip_serializing_if = "Option::is_none", default = "Option::default")]
#[rkyv(with=crate::rkyv_utils::OptionH256Wrapper)]
pub block_access_list_hash: Option<H256>,
}

// Needs a explicit impl due to the hash OnceLock.
Expand Down Expand Up @@ -170,6 +173,7 @@ impl PartialEq for BlockHeader {
excess_blob_gas,
parent_beacon_block_root,
requests_hash,
block_access_list_hash,
} = self;

parent_hash == &other.parent_hash
Expand All @@ -191,6 +195,7 @@ impl PartialEq for BlockHeader {
&& difficulty == &other.difficulty
&& ommers_hash == &other.ommers_hash
&& requests_hash == &other.requests_hash
&& block_access_list_hash == &other.block_access_list_hash
&& logs_bloom == &other.logs_bloom
&& extra_data == &other.extra_data
}
Expand Down Expand Up @@ -220,6 +225,7 @@ impl RLPEncode for BlockHeader {
.encode_optional_field(&self.excess_blob_gas)
.encode_optional_field(&self.parent_beacon_block_root)
.encode_optional_field(&self.requests_hash)
.encode_optional_field(&self.block_access_list_hash)
.finish();
}
}
Expand Down Expand Up @@ -249,6 +255,7 @@ impl RLPDecode for BlockHeader {
let (excess_blob_gas, decoder) = decoder.decode_optional_field();
let (parent_beacon_block_root, decoder) = decoder.decode_optional_field();
let (requests_hash, decoder) = decoder.decode_optional_field();
let (block_access_list_hash, decoder) = decoder.decode_optional_field();

Ok((
BlockHeader {
Expand All @@ -274,6 +281,7 @@ impl RLPDecode for BlockHeader {
excess_blob_gas,
parent_beacon_block_root,
requests_hash,
block_access_list_hash,
},
decoder.finish()?,
))
Expand Down
Loading
Loading