Skip to content

feat(l1): implement eth/69 #2860

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 70 commits into from
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
70 commits
Select commit Hold shift + click to select a range
ce7a635
Cap mock
Mechanix97 May 15, 2025
c08a153
Fix capability struct
Mechanix97 May 15, 2025
8bf6d4c
Merge branch 'main' into refactor/capability-struct-instead-of-tuple
Mechanix97 May 15, 2025
74eaad7
fix forgotten capability
Mechanix97 May 15, 2025
f606799
Merge branch 'refactor/capability-struct-instead-of-tuple' of github.…
Mechanix97 May 15, 2025
2188f89
Merge branch 'main' into refactor/capability-struct-instead-of-tuple
Mechanix97 May 15, 2025
5e360bd
Fix lint
Mechanix97 May 15, 2025
e23fd22
Merge branch 'refactor/capability-struct-instead-of-tuple' of github.…
Mechanix97 May 15, 2025
899fdd6
Use constants now
Mechanix97 May 15, 2025
d2b8022
Status version 68
Mechanix97 May 16, 2025
2c7dd3a
fix CAP_SNAP_1
Mechanix97 May 16, 2025
2b00b99
Merge branch 'main' into refactor/capability-struct-instead-of-tuple
Mechanix97 May 16, 2025
f567433
Add eth 69
Mechanix97 May 16, 2025
352d92c
Add receipt logic
Mechanix97 May 16, 2025
c302e06
Merge branch 'main' into refactor/capability-struct-instead-of-tuple
Mechanix97 May 16, 2025
0a349d5
temp
Mechanix97 May 16, 2025
ea5d2cf
Go back receipts
Mechanix97 May 19, 2025
cf4d358
Fix correct capabilities settings
Mechanix97 May 19, 2025
637ecc2
Merge branch 'main' into feat/capability-negotation
Mechanix97 May 19, 2025
551bdea
Fix merge
Mechanix97 May 19, 2025
c98a398
Not eth 69 supported yet
Mechanix97 May 19, 2025
36d73df
Fix lint
Mechanix97 May 19, 2025
16f6ed5
Merge branch 'main' into feat/capability-negotation
Mechanix97 May 19, 2025
52ece3a
Fix if
Mechanix97 May 19, 2025
c03eccd
Merge branch 'feat/capability-negotation' into feat/backward-cap-comp…
Mechanix97 May 19, 2025
60fd8fb
Fix test
Mechanix97 May 19, 2025
0d979d9
new has_bloom fn
Mechanix97 May 20, 2025
eaad8d9
new bloom filter
Mechanix97 May 20, 2025
7acd82f
Merge branch 'main' into feat/backward-cap-compatibility
Mechanix97 May 20, 2025
e4b3e4a
Add receipt69
Mechanix97 May 20, 2025
2e3e62d
remove eth/69 calls
Mechanix97 May 20, 2025
64de71c
empty to true
Mechanix97 May 20, 2025
0fe49af
unsync
Mechanix97 May 20, 2025
92a50db
Merge branch 'main' into feat/implement-eth/69
Mechanix97 May 20, 2025
3278ab4
Status message 69
Mechanix97 May 20, 2025
4b8c5b6
encode receipt68
Mechanix97 May 20, 2025
6022f07
Remove bloom
Mechanix97 May 21, 2025
5a2c0c8
Add comments
Mechanix97 May 21, 2025
ee96809
Receipt encode69
Mechanix97 May 21, 2025
9ca211b
Merge branch 'main' into feat/implement-eth/69
Mechanix97 May 21, 2025
e2da4d7
fix lint
Mechanix97 May 21, 2025
ab299e0
Fix tests
Mechanix97 May 21, 2025
bb8a0b4
remove eth/69 cap
Mechanix97 May 21, 2025
f628ee8
New Receipt68 struct
Mechanix97 May 21, 2025
51a79e5
CI with eth68 only
Mechanix97 May 21, 2025
de55189
Fix merkle root receipts
Mechanix97 May 21, 2025
7017646
Fix has_bloom
Mechanix97 May 21, 2025
261ab9c
Merge branch 'main' into feat/implement-eth/69
Mechanix97 May 21, 2025
a1b5ec5
Fix log blooms
Mechanix97 May 22, 2025
342c436
Fix receipt encoding
Mechanix97 May 22, 2025
66f4854
rangeblockupdate message
Mechanix97 May 22, 2025
5e0264d
Merge branch 'main' into feat/implement-eth/69
Mechanix97 May 23, 2025
9fb0b30
Add msg decode to BlockRangeUpdate
Mechanix97 May 23, 2025
b577c60
Fix code in eth68 and eth69
Mechanix97 May 23, 2025
794dd07
Send update msg periodically
Mechanix97 May 23, 2025
3a30b1f
Remove dep
Mechanix97 May 23, 2025
2f65c04
Add from to receipt
Mechanix97 May 26, 2025
11e7a73
Move log placement
Mechanix97 May 26, 2025
68ff774
Fix test
Mechanix97 May 26, 2025
2bc26eb
Change range update trigger
Mechanix97 May 26, 2025
0c3d8d6
Merge branch 'main' into feat/implement-eth/69
Mechanix97 May 27, 2025
83df7f5
Fix update code
Mechanix97 May 27, 2025
66b7f97
Merge branch 'main' into feat/implement-eth/69
Mechanix97 Jun 2, 2025
bcd366b
Fix hash fn
Mechanix97 Jun 2, 2025
15ef5f8
Update fix hash
Mechanix97 Jun 2, 2025
b0015a1
Merge branch 'main' into feat/implement-eth/69
Mechanix97 Jun 3, 2025
8889f58
Merge branch 'main' into feat/implement-eth/69
Mechanix97 Jun 3, 2025
bb49f14
Fix snap offset for eth68
Mechanix97 Jun 3, 2025
11e19f2
Desactivate eth/69
Mechanix97 Jun 3, 2025
9edef2f
Merge branch 'main' into feat/implement-eth/69
Mechanix97 Jun 3, 2025
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
2 changes: 2 additions & 0 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion crates/common/rlp/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,7 @@ pub fn decode_bytes(data: &[u8]) -> Result<(&[u8], &[u8]), RLPDecodeError> {
/// Pads a slice of bytes with zeros on the left to make it a fixed size slice.
/// The size of the data must be less than or equal to the size of the output array.
#[inline]
pub(crate) fn static_left_pad<const N: usize>(data: &[u8]) -> Result<[u8; N], RLPDecodeError> {
pub fn static_left_pad<const N: usize>(data: &[u8]) -> Result<[u8; N], RLPDecodeError> {
let mut result = [0; N];

if data.is_empty() {
Expand Down
2 changes: 1 addition & 1 deletion crates/common/rlp/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ impl<T: RLPEncode> RLPEncode for Vec<T> {
}
}

pub(crate) fn encode_length(total_len: usize, buf: &mut dyn BufMut) {
pub fn encode_length(total_len: usize, buf: &mut dyn BufMut) {
if total_len < 56 {
buf.put_u8(0xc0 + total_len as u8);
} else {
Expand Down
2 changes: 2 additions & 0 deletions crates/common/rlp/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ pub enum RLPDecodeError {
UnexpectedString,
#[error("InvalidCompression")]
InvalidCompression(#[from] snap::Error),
#[error("IncompatibleProtocol")]
IncompatibleProtocol,
#[error("{0}")]
Custom(String),
}
Expand Down
2 changes: 1 addition & 1 deletion crates/common/types/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ pub fn compute_receipts_root(receipts: &[Receipt]) -> H256 {
let iter = receipts
.iter()
.enumerate()
.map(|(idx, receipt)| (idx.encode_to_vec(), receipt.encode_inner()));
.map(|(idx, receipt)| (idx.encode_to_vec(), receipt.encode_inner_with_bloom()));
Trie::compute_hash_from_unsorted_iter(iter)
}

Expand Down
159 changes: 135 additions & 24 deletions crates/common/types/receipt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,106 @@ pub struct Receipt {
pub tx_type: TxType,
pub succeeded: bool,
pub cumulative_gas_used: u64,
pub bloom: Bloom,
pub logs: Vec<Log>,
}

impl Receipt {
pub fn new(tx_type: TxType, succeeded: bool, cumulative_gas_used: u64, logs: Vec<Log>) -> Self {
Self {
tx_type,
succeeded,
cumulative_gas_used,
logs,
}
}

pub fn encode_inner(&self) -> Vec<u8> {
let mut encoded_data = vec![];
let tx_type: u8 = self.tx_type as u8;
Encoder::new(&mut encoded_data)
.encode_field(&tx_type)
.encode_field(&self.succeeded)
.encode_field(&self.cumulative_gas_used)
.encode_field(&self.logs)
.finish();
encoded_data
}

pub fn encode_inner_with_bloom(&self) -> Vec<u8> {
let mut encode_buff = match self.tx_type {
TxType::Legacy => {
vec![]
}
_ => {
vec![self.tx_type as u8]
}
};
let bloom = bloom_from_logs(&self.logs);
Encoder::new(&mut encode_buff)
.encode_field(&self.succeeded)
.encode_field(&self.cumulative_gas_used)
.encode_field(&bloom)
.encode_field(&self.logs)
.finish();
encode_buff
}
}

pub fn bloom_from_logs(logs: &[Log]) -> Bloom {
let mut bloom = Bloom::zero();
for log in logs {
bloom.accrue(BloomInput::Raw(log.address.as_ref()));
for topic in log.topics.iter() {
bloom.accrue(BloomInput::Raw(topic.as_ref()));
}
}
bloom
}

impl RLPEncode for Receipt {
fn encode(&self, buf: &mut dyn bytes::BufMut) {
let encoded_inner = self.encode_inner();
buf.put_slice(&encoded_inner);
}
}

impl RLPDecode for Receipt {
fn decode_unfinished(rlp: &[u8]) -> Result<(Self, &[u8]), RLPDecodeError> {
let decoder = Decoder::new(rlp)?;
let (tx_type, decoder): (u8, _) = decoder.decode_field("tx-type")?;
let (succeeded, decoder) = decoder.decode_field("succeeded")?;
let (cumulative_gas_used, decoder) = decoder.decode_field("cumulative_gas_used")?;
let (logs, decoder) = decoder.decode_field("logs")?;

let Some(tx_type) = TxType::from_u8(tx_type) else {
return Err(RLPDecodeError::Custom(
"Invalid transaction type".to_string(),
));
};

Ok((
Receipt {
tx_type,
succeeded,
cumulative_gas_used,
logs,
},
decoder.finish()?,
))
}
}

/// Result of a transaction
#[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct ReceiptWithBloom {
pub tx_type: TxType,
pub succeeded: bool,
pub cumulative_gas_used: u64,
pub bloom: Bloom,
pub logs: Vec<Log>,
}

impl ReceiptWithBloom {
pub fn new(tx_type: TxType, succeeded: bool, cumulative_gas_used: u64, logs: Vec<Log>) -> Self {
Self {
tx_type,
Expand All @@ -31,6 +126,7 @@ impl Receipt {
logs,
}
}

// By reading the typed transactions EIP, and some geth code:
// - https://eips.ethereum.org/EIPS/eip-2718
// - https://github.com/ethereum/go-ethereum/blob/330190e476e2a2de4aac712551629a4134f802d5/core/types/receipt.go#L143
Expand Down Expand Up @@ -69,7 +165,7 @@ impl Receipt {
/// Decodes Receipts in the following formats:
/// A) Legacy receipts: rlp(receipt)
/// B) Non legacy receipts: tx_type | rlp(receipt).
pub fn decode_inner(rlp: &[u8]) -> Result<Receipt, RLPDecodeError> {
pub fn decode_inner(rlp: &[u8]) -> Result<Self, RLPDecodeError> {
// Obtain TxType
let (tx_type, rlp) = match rlp.first() {
Some(tx_type) if *tx_type < 0x7f => {
Expand Down Expand Up @@ -97,7 +193,7 @@ impl Receipt {
let (logs, decoder) = decoder.decode_field("logs")?;
decoder.finish()?;

Ok(Receipt {
Ok(Self {
tx_type,
succeeded,
cumulative_gas_used,
Expand All @@ -107,18 +203,7 @@ impl Receipt {
}
}

fn bloom_from_logs(logs: &[Log]) -> Bloom {
let mut bloom = Bloom::zero();
for log in logs {
bloom.accrue(BloomInput::Raw(log.address.as_ref()));
for topic in log.topics.iter() {
bloom.accrue(BloomInput::Raw(topic.as_ref()));
}
}
bloom
}

impl RLPEncode for Receipt {
impl RLPEncode for ReceiptWithBloom {
/// Receipts can be encoded in the following formats:
/// A) Legacy receipts: rlp(receipt)
/// B) Non legacy receipts: rlp(Bytes(tx_type | rlp(receipt))).
Expand All @@ -137,7 +222,7 @@ impl RLPEncode for Receipt {
}
}

impl RLPDecode for Receipt {
impl RLPDecode for ReceiptWithBloom {
/// Receipts can be encoded in the following formats:
/// A) Legacy receipts: rlp(receipt)
/// B) Non legacy receipts: rlp(Bytes(tx_type | rlp(receipt))).
Expand Down Expand Up @@ -169,7 +254,7 @@ impl RLPDecode for Receipt {
let (logs, decoder) = decoder.decode_field("logs")?;

Ok((
Receipt {
ReceiptWithBloom {
tx_type,
succeeded,
cumulative_gas_used,
Expand All @@ -181,6 +266,29 @@ impl RLPDecode for Receipt {
}
}

impl From<&Receipt> for ReceiptWithBloom {
fn from(receipt: &Receipt) -> Self {
Self {
tx_type: receipt.tx_type,
succeeded: receipt.succeeded,
cumulative_gas_used: receipt.cumulative_gas_used,
bloom: bloom_from_logs(&receipt.logs),
logs: receipt.logs.clone(),
}
}
}

impl From<&ReceiptWithBloom> for Receipt {
fn from(receipt: &ReceiptWithBloom) -> Self {
Self {
tx_type: receipt.tx_type,
succeeded: receipt.succeeded,
cumulative_gas_used: receipt.cumulative_gas_used,
logs: receipt.logs.clone(),
}
}
}

/// Data record produced during the execution of a transaction.
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Log {
Expand Down Expand Up @@ -224,7 +332,6 @@ mod test {
tx_type: TxType::Legacy,
succeeded: true,
cumulative_gas_used: 1200,
bloom: Bloom::random(),
logs: vec![Log {
address: Address::random(),
topics: vec![],
Expand All @@ -241,7 +348,6 @@ mod test {
tx_type: TxType::EIP4844,
succeeded: true,
cumulative_gas_used: 1500,
bloom: Bloom::random(),
logs: vec![Log {
address: Address::random(),
topics: vec![],
Expand All @@ -251,10 +357,9 @@ mod test {
let encoded_receipt = receipt.encode_to_vec();
assert_eq!(receipt, Receipt::decode(&encoded_receipt).unwrap())
}

#[test]
fn test_encode_decode_inner_receipt_legacy() {
let receipt = Receipt {
let receipt = ReceiptWithBloom {
tx_type: TxType::Legacy,
succeeded: true,
cumulative_gas_used: 1200,
Expand All @@ -266,12 +371,15 @@ mod test {
}],
};
let encoded_receipt = receipt.encode_inner();
assert_eq!(receipt, Receipt::decode_inner(&encoded_receipt).unwrap())
assert_eq!(
receipt,
ReceiptWithBloom::decode_inner(&encoded_receipt).unwrap()
)
}

#[test]
fn test_encode_decode_receipt_inner_non_legacy() {
let receipt = Receipt {
let receipt = ReceiptWithBloom {
tx_type: TxType::EIP4844,
succeeded: true,
cumulative_gas_used: 1500,
Expand All @@ -283,6 +391,9 @@ mod test {
}],
};
let encoded_receipt = receipt.encode_inner();
assert_eq!(receipt, Receipt::decode_inner(&encoded_receipt).unwrap())
assert_eq!(
receipt,
ReceiptWithBloom::decode_inner(&encoded_receipt).unwrap()
)
}
}
2 changes: 1 addition & 1 deletion crates/networking/p2p/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ ethrex-blockchain.workspace = true
ethrex-rlp.workspace = true
ethrex-storage.workspace = true
ethrex-trie.workspace = true

ethereum-types.workspace = true
tracing.workspace = true
tokio.workspace = true
tokio-util.workspace = true
Expand Down
11 changes: 6 additions & 5 deletions crates/networking/p2p/peer_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use crate::{
blocks::{
BlockBodies, BlockHeaders, GetBlockBodies, GetBlockHeaders, BLOCK_HEADER_LIMIT,
},
receipts::{GetReceipts, Receipts},
receipts::GetReceipts,
},
message::Message as RLPxMessage,
p2p::{Capability, SUPPORTED_ETH_CAPABILITIES, SUPPORTED_SNAP_CAPABILITIES},
Expand Down Expand Up @@ -280,10 +280,11 @@ impl PeerHandler {
if let Some(receipts) = tokio::time::timeout(PEER_REPLY_TIMEOUT, async move {
loop {
match receiver.recv().await {
Some(RLPxMessage::Receipts(Receipts { id, receipts }))
if id == request_id =>
{
return Some(receipts)
Some(RLPxMessage::Receipts(receipts)) => {
if receipts.get_id() == request_id {
return Some(receipts.get_receipts());
}
return None;
}
// Ignore replies that don't match the expected id (such as late responses)
Some(_) => continue,
Expand Down
Loading