Skip to content

Commit 9894d25

Browse files
authored
feat!: replace our header,body,receipt types with alloy types (#1721)
1 parent c3cff03 commit 9894d25

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+909
-2854
lines changed

Cargo.lock

Lines changed: 248 additions & 76 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ rust-version = "1.85.0"
3636
version = "0.2.1"
3737

3838
[workspace.dependencies]
39-
alloy = { version = "0.11.1", default-features = false, features = ["std"] }
39+
alloy = { version = "0.12", default-features = false, features = ["std"] }
4040
alloy-rlp = { version = "0.3.8", default-features = false, features = ["derive"] }
4141
anyhow = "1.0.68"
4242
async-trait = "0.1.68"

bin/portal-bridge/src/api/execution.rs

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
use std::sync::Arc;
22

3-
use alloy::primitives::B256;
3+
use alloy::{
4+
consensus::{BlockBody as AlloyBlockBody, Header},
5+
eips::eip4895::Withdrawals,
6+
primitives::B256,
7+
};
48
use anyhow::{anyhow, bail};
59
use ethportal_api::{
610
types::{
711
execution::{
812
accumulator::EpochAccumulator,
9-
block_body::{
10-
BlockBody, BlockBodyLegacy, BlockBodyMerge, BlockBodyShanghai, MERGE_TIMESTAMP,
11-
SHANGHAI_TIMESTAMP,
12-
},
13+
block_body::{BlockBody, MERGE_TIMESTAMP, SHANGHAI_TIMESTAMP},
1314
header_with_proof::{BlockHeaderProof, HeaderWithProof},
1415
},
1516
jsonrpc::{params::Params, request::JsonRequest},
1617
},
1718
utils::bytes::{hex_decode, hex_encode},
18-
Header, HistoryContentKey, HistoryContentValue, Receipts,
19+
HistoryContentKey, HistoryContentValue, Receipts,
1920
};
2021
use futures::future::join_all;
2122
use serde_json::{json, Value};
@@ -108,7 +109,7 @@ impl ExecutionApi {
108109
};
109110
// Construct header by hash content key / value pair.
110111
let header_by_hash_content_key =
111-
HistoryContentKey::new_block_header_by_hash(full_header.header.hash());
112+
HistoryContentKey::new_block_header_by_hash(full_header.header.hash_slow());
112113
// Construct header by number content key / value pair.
113114
let header_by_number_content_key =
114115
HistoryContentKey::new_block_header_by_number(full_header.header.number);
@@ -141,34 +142,46 @@ impl ExecutionApi {
141142
) -> anyhow::Result<(HistoryContentKey, HistoryContentValue)> {
142143
let block_body = self.get_trusted_block_body(full_header).await?;
143144
block_body.validate_against_header(&full_header.header)?;
144-
let content_key = HistoryContentKey::new_block_body(full_header.header.hash());
145+
let content_key = HistoryContentKey::new_block_body(full_header.header.hash_slow());
145146
let content_value = HistoryContentValue::BlockBody(block_body);
146147
Ok((content_key, content_value))
147148
}
148149

149150
/// Return an unvalidated block body for the given FullHeader.
150151
async fn get_trusted_block_body(&self, full_header: &FullHeader) -> anyhow::Result<BlockBody> {
151-
let txs = full_header.txs.clone();
152+
let transactions = full_header.txs.clone();
152153
if full_header.header.timestamp > SHANGHAI_TIMESTAMP {
153154
if !full_header.uncles.is_empty() {
154155
bail!("Invalid block: Shanghai block contains uncles");
155156
}
156157
let withdrawals = match full_header.withdrawals.clone() {
157-
Some(val) => val,
158+
Some(val) => Some(Withdrawals(val)),
158159
None => bail!("Invalid block: Shanghai block missing withdrawals"),
159160
};
160-
Ok(BlockBody::Shanghai(BlockBodyShanghai { txs, withdrawals }))
161+
Ok(BlockBody(AlloyBlockBody {
162+
transactions,
163+
ommers: vec![],
164+
withdrawals,
165+
}))
161166
} else if full_header.header.timestamp > MERGE_TIMESTAMP {
162167
if !full_header.uncles.is_empty() {
163168
bail!("Invalid block: Merge block contains uncles");
164169
}
165-
Ok(BlockBody::Merge(BlockBodyMerge { txs }))
170+
Ok(BlockBody(AlloyBlockBody {
171+
transactions,
172+
ommers: vec![],
173+
withdrawals: None,
174+
}))
166175
} else {
167-
let uncles = match full_header.uncles.len() {
176+
let ommers = match full_header.uncles.len() {
168177
0 => vec![],
169178
_ => self.get_trusted_uncles(&full_header.uncles).await?,
170179
};
171-
Ok(BlockBody::Legacy(BlockBodyLegacy { txs, uncles }))
180+
Ok(BlockBody(AlloyBlockBody {
181+
transactions,
182+
ommers,
183+
withdrawals: None,
184+
}))
172185
}
173186
}
174187

@@ -205,21 +218,19 @@ impl ExecutionApi {
205218
) -> anyhow::Result<(HistoryContentKey, HistoryContentValue)> {
206219
// Build receipts
207220
let receipts = match full_header.txs.len() {
208-
0 => Receipts {
209-
receipt_list: vec![],
210-
},
221+
0 => Receipts(vec![]),
211222
_ => self.get_trusted_receipts(full_header.header.number).await?,
212223
};
213224

214225
// Validate Receipts
215-
let receipts_root = receipts.root()?;
226+
let receipts_root = receipts.root();
216227
if receipts_root != full_header.header.receipts_root {
217228
bail!(
218229
"Receipts root doesn't match header receipts root: {receipts_root:?} - {:?}",
219230
full_header.header.receipts_root
220231
);
221232
}
222-
let content_key = HistoryContentKey::new_block_receipts(full_header.header.hash());
233+
let content_key = HistoryContentKey::new_block_receipts(full_header.header.hash_slow());
223234
let content_value = HistoryContentValue::Receipts(receipts);
224235
Ok((content_key, content_value))
225236
}

bin/portal-bridge/src/bridge/era1.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ impl Era1Bridge {
364364
);
365365
let mut gossip_header_by_hash = true;
366366
if hunt {
367-
let header_hash = block_tuple.header.header.hash();
367+
let header_hash = block_tuple.header.header.hash_slow();
368368
let header_content_key = HistoryContentKey::new_block_header_by_hash(header_hash);
369369
let header_content_info = portal_client.get_content(header_content_key.clone()).await;
370370
if header_content_info.is_ok() {
@@ -456,7 +456,7 @@ impl Era1Bridge {
456456
}
457457
let mut gossip_body = true;
458458
if hunt {
459-
let body_hash = block_tuple.header.header.hash();
459+
let body_hash = block_tuple.header.header.hash_slow();
460460
let body_content_key = HistoryContentKey::new_block_body(body_hash);
461461
let body_content_info = portal_client.get_content(body_content_key.clone()).await;
462462
if body_content_info.is_ok() {
@@ -495,7 +495,7 @@ impl Era1Bridge {
495495
}
496496
let mut gossip_receipts = true;
497497
if hunt {
498-
let receipts_hash = block_tuple.header.header.hash();
498+
let receipts_hash = block_tuple.header.header.hash_slow();
499499
let receipts_content_key = HistoryContentKey::new_block_receipts(receipts_hash);
500500
let receipts_content_info = portal_client
501501
.get_content(receipts_content_key.clone())
@@ -554,7 +554,7 @@ impl Era1Bridge {
554554
let header_record = &epoch_acc[header_index as usize];
555555

556556
// Validate Header
557-
let actual_header_hash = header.hash();
557+
let actual_header_hash = header.hash_slow();
558558

559559
ensure!(
560560
header_record.block_hash == actual_header_hash,
@@ -570,7 +570,7 @@ impl Era1Bridge {
570570
// Construct HistoryContentValue
571571
let content_value = HistoryContentValue::BlockHeaderWithProof(header_with_proof);
572572
// Construct HistoryContentKey for block header by hash and gossip it
573-
let content_key = HistoryContentKey::new_block_header_by_hash(header.hash());
573+
let content_key = HistoryContentKey::new_block_header_by_hash(header.hash_slow());
574574
gossip_history_content(portal_client, content_key, content_value, block_stats).await?;
575575

576576
Ok(())
@@ -593,7 +593,7 @@ impl Era1Bridge {
593593
let header_record = &epoch_acc[header_index as usize];
594594

595595
// Validate Header
596-
let actual_header_hash = header.hash();
596+
let actual_header_hash = header.hash_slow();
597597

598598
ensure!(
599599
header_record.block_hash == actual_header_hash,
@@ -626,7 +626,7 @@ impl Era1Bridge {
626626
);
627627
let header = block_tuple.header.header;
628628
// Construct HistoryContentKey
629-
let content_key = HistoryContentKey::new_block_body(header.hash());
629+
let content_key = HistoryContentKey::new_block_body(header.hash_slow());
630630
// Construct HistoryContentValue
631631
let content_value = HistoryContentValue::BlockBody(block_tuple.body.body);
632632
gossip_history_content(portal_client, content_key, content_value, block_stats).await
@@ -643,7 +643,7 @@ impl Era1Bridge {
643643
);
644644
let header = block_tuple.header.header;
645645
// Construct HistoryContentKey
646-
let content_key = HistoryContentKey::new_block_receipts(header.hash());
646+
let content_key = HistoryContentKey::new_block_receipts(header.hash_slow());
647647
// Construct HistoryContentValue
648648
let content_value = HistoryContentValue::Receipts(block_tuple.receipts.receipts);
649649
gossip_history_content(portal_client, content_key, content_value, block_stats).await

bin/portal-bridge/src/bridge/state.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ impl StateBridge {
268268
.last_fetched_block()
269269
.await?
270270
.header
271-
.hash();
271+
.hash_slow();
272272

273273
let walk_diff =
274274
TrieWalker::new_partial_trie(root_with_trie_diff.root, root_with_trie_diff.trie_diff)?;

bin/portal-bridge/src/types/full_header.rs

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
use std::sync::Arc;
22

3-
use alloy::primitives::B256;
4-
use anyhow::{anyhow, ensure};
5-
use ethportal_api::types::execution::{
6-
accumulator::EpochAccumulator,
7-
header::{Header, TxHashes},
8-
transaction::Transaction,
9-
withdrawal::Withdrawal,
3+
use alloy::{
4+
consensus::{Header, TxEnvelope},
5+
eips::eip4895::Withdrawal,
6+
primitives::B256,
107
};
8+
use anyhow::{anyhow, ensure};
9+
use ethportal_api::types::execution::accumulator::EpochAccumulator;
1110
use serde::{Deserialize, Deserializer};
1211
use serde_json::Value;
1312
use trin_validation::constants::{EPOCH_SIZE, MERGE_BLOCK_NUMBER};
@@ -44,8 +43,8 @@ impl<'de> Deserialize<'de> for FullHeaderBatch {
4443
#[derive(Debug, Clone, PartialEq, Eq)]
4544
pub struct FullHeader {
4645
pub header: Header,
47-
pub txs: Vec<Transaction>,
48-
pub tx_hashes: TxHashes,
46+
pub txs: Vec<TxEnvelope>,
47+
pub tx_hashes: Vec<B256>,
4948
pub uncles: Vec<B256>,
5049
pub epoch_acc: Option<Arc<EpochAccumulator>>,
5150
pub withdrawals: Option<Vec<Withdrawal>>,
@@ -59,8 +58,8 @@ impl TryFrom<Value> for FullHeader {
5958
fn try_from(val: Value) -> anyhow::Result<Self> {
6059
let header: Header = serde_json::from_value(val.clone())?;
6160
let uncles: Vec<B256> = serde_json::from_value(val["uncles"].clone())?;
62-
let tx_hashes: TxHashes = serde_json::from_value(val["transactions"].clone())?;
63-
let txs: Vec<Transaction> = serde_json::from_value(val["transactions"].clone())?;
61+
let txs: Vec<TxEnvelope> = serde_json::from_value(val["transactions"].clone())?;
62+
let tx_hashes: Vec<B256> = txs.iter().map(|tx| *tx.hash()).collect();
6463
let withdrawals = match val["withdrawals"].clone() {
6564
Value::Null => None,
6665
_ => serde_json::from_value(val["withdrawals"].clone())?,
@@ -90,7 +89,7 @@ impl FullHeader {
9089
let header_record = &epoch_acc[header_index as usize];
9190

9291
// Validate Header
93-
let actual_header_hash = self.header.hash();
92+
let actual_header_hash = self.header.hash_slow();
9493

9594
ensure!(
9695
header_record.block_hash == actual_header_hash,
@@ -100,20 +99,19 @@ impl FullHeader {
10099
);
101100
}
102101
ensure!(
103-
self.txs.len() == self.tx_hashes.hashes.len(),
102+
self.txs.len() == self.tx_hashes.len(),
104103
"txs.len() != tx_hashes.hashes.len(): {} != {}",
105104
self.txs.len(),
106-
self.tx_hashes.hashes.len()
105+
self.tx_hashes.len()
107106
);
108107
Ok(())
109108
}
110109
}
111110

112111
#[cfg(test)]
113112
mod tests {
114-
use ethportal_api::types::execution::block_body::{
115-
BlockBody, BlockBodyLegacy, BlockBodyShanghai,
116-
};
113+
use alloy::{consensus::BlockBody as AlloyBlockBody, eips::eip4895::Withdrawals};
114+
use ethportal_api::types::execution::block_body::BlockBody;
117115
use serde_json::Value;
118116
use ssz::{Decode, Encode};
119117

@@ -127,7 +125,7 @@ mod tests {
127125
let full_header = FullHeader::try_from(body["result"].clone()).unwrap();
128126
let header: Header = serde_json::from_value(body["result"].clone()).unwrap();
129127
assert_eq!(full_header.txs.len(), 19);
130-
assert_eq!(full_header.tx_hashes.hashes.len(), 19);
128+
assert_eq!(full_header.tx_hashes.len(), 19);
131129
assert_eq!(full_header.uncles.len(), 1);
132130
assert_eq!(full_header.header, header);
133131
}
@@ -138,9 +136,10 @@ mod tests {
138136
std::fs::read_to_string("../../test_assets/mainnet/block_17034871_value.json").unwrap();
139137
let body: Value = serde_json::from_str(&body).unwrap();
140138
let full_header = FullHeader::try_from(body["result"].clone()).unwrap();
141-
let block_body = BlockBody::Shanghai(BlockBodyShanghai {
142-
txs: full_header.txs.clone(),
143-
withdrawals: full_header.withdrawals.unwrap(),
139+
let block_body = BlockBody(AlloyBlockBody {
140+
transactions: full_header.txs.clone(),
141+
ommers: vec![],
142+
withdrawals: full_header.withdrawals.map(Withdrawals),
144143
});
145144
let header: Header = serde_json::from_value(body["result"].clone()).unwrap();
146145
block_body.validate_against_header(&header).unwrap();
@@ -152,9 +151,10 @@ mod tests {
152151
std::fs::read_to_string("../../test_assets/mainnet/block_17034873_value.json").unwrap();
153152
let body: Value = serde_json::from_str(&body).unwrap();
154153
let full_header = FullHeader::try_from(body["result"].clone()).unwrap();
155-
let block_body = BlockBody::Shanghai(BlockBodyShanghai {
156-
txs: full_header.txs.clone(),
157-
withdrawals: full_header.withdrawals.unwrap(),
154+
let block_body = BlockBody(AlloyBlockBody {
155+
transactions: full_header.txs.clone(),
156+
ommers: vec![],
157+
withdrawals: full_header.withdrawals.map(Withdrawals),
158158
});
159159
let header: Header = serde_json::from_value(body["result"].clone()).unwrap();
160160
block_body.validate_against_header(&header).unwrap();
@@ -172,9 +172,10 @@ mod tests {
172172
let body: Value = serde_json::from_str(&body).unwrap();
173173
let full_header = FullHeader::try_from(body["result"].clone()).unwrap();
174174
let header: Header = serde_json::from_value(body["result"].clone()).unwrap();
175-
let block_body = BlockBody::Shanghai(BlockBodyShanghai {
176-
txs: full_header.txs.clone(),
177-
withdrawals: full_header.withdrawals.unwrap(),
175+
let block_body = BlockBody(AlloyBlockBody {
176+
transactions: full_header.txs.clone(),
177+
ommers: vec![],
178+
withdrawals: full_header.withdrawals.map(Withdrawals),
178179
});
179180
block_body.validate_against_header(&header).unwrap();
180181
// test ssz roundtrip
@@ -191,19 +192,23 @@ mod tests {
191192
std::fs::read_to_string("../../test_assets/geth_batch/headers.json").unwrap();
192193
let full_headers: FullHeaderBatch = serde_json::from_str(&expected).unwrap();
193194
for full_header in full_headers.headers {
194-
let block_body = BlockBody::Legacy(BlockBodyLegacy {
195-
txs: full_header.txs,
196-
uncles: vec![],
195+
let block_body = BlockBody(AlloyBlockBody {
196+
transactions: full_header.txs,
197+
ommers: vec![],
198+
withdrawals: None,
197199
});
198200
// test that txs are properly deserialized if tx root is properly calculated
199201
assert_eq!(
200-
block_body.transactions_root().unwrap(),
202+
block_body.transactions_root(),
201203
full_header.header.transactions_root
202204
);
203205
// this block has no uncles, aka an empty uncles root is calculated.
204206
// there's no need to validate deserialization of uncles, since they're just a
205207
// vector of Header, which are already tested above
206-
assert_eq!(block_body.uncles_root(), full_header.header.uncles_hash);
208+
assert_eq!(
209+
block_body.calculate_ommers_root(),
210+
full_header.header.ommers_hash
211+
);
207212
}
208213
}
209214
}

0 commit comments

Comments
 (0)