From b51aff3b732f54e5b68261f426131c4b891ad376 Mon Sep 17 00:00:00 2001 From: nk_ysg Date: Mon, 15 Jul 2024 23:57:05 +0800 Subject: [PATCH] move HackReceiptFileCodec into reth-optimism-cli (#9499) --- Cargo.lock | 2 + crates/net/downloaders/src/lib.rs | 13 - .../downloaders/src/receipt_file_client.rs | 401 ++++++++++++++++-- crates/optimism/cli/Cargo.toml | 2 + .../cli/src/commands/import_receipts.rs | 2 +- .../cli}/src/file_codec_ovm_receipt.rs | 2 +- crates/optimism/cli/src/lib.rs | 12 + 7 files changed, 380 insertions(+), 54 deletions(-) rename crates/{net/downloaders => optimism/cli}/src/file_codec_ovm_receipt.rs (99%) diff --git a/Cargo.lock b/Cargo.lock index bda76e8ca..867a8cdc6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7765,6 +7765,7 @@ version = "1.0.1" dependencies = [ "alloy-genesis", "alloy-primitives", + "alloy-rlp", "clap", "eyre", "futures-util", @@ -7793,6 +7794,7 @@ dependencies = [ "serde_json", "shellexpand", "tokio", + "tokio-util", "tracing", ] diff --git a/crates/net/downloaders/src/lib.rs b/crates/net/downloaders/src/lib.rs index 0199cc02b..7944a31a5 100644 --- a/crates/net/downloaders/src/lib.rs +++ b/crates/net/downloaders/src/lib.rs @@ -31,14 +31,6 @@ pub mod file_client; /// /// Contains [`ReceiptFileClient`](receipt_file_client::ReceiptFileClient) to read receipt data from /// files, efficiently buffering receipts for retrieval. -/// -/// Currently configured to use codec [`HackReceipt`](file_codec_ovm_receipt::HackReceipt) based on -/// export of below Bedrock data using . Codec can -/// be replaced with regular encoding of receipts for export. -/// -/// NOTE: receipts can be exported using regular op-geth encoding for `Receipt` type, to fit -/// reth's needs for importing. However, this would require patching the diff in to export the `Receipt` and not `HackReceipt` type (originally -/// made for op-erigon's import needs). pub mod receipt_file_client; /// Module with a codec for reading and encoding block bodies in files. @@ -46,10 +38,5 @@ pub mod receipt_file_client; /// Enables decoding and encoding `Block` types within file contexts. pub mod file_codec; -/// Module with a codec for reading and encoding receipts in files. -/// -/// Enables decoding and encoding `HackReceipt` type. See . -pub mod file_codec_ovm_receipt; - #[cfg(any(test, feature = "test-utils"))] pub mod test_utils; diff --git a/crates/net/downloaders/src/receipt_file_client.rs b/crates/net/downloaders/src/receipt_file_client.rs index 9dd23489d..2a18fbde8 100644 --- a/crates/net/downloaders/src/receipt_file_client.rs +++ b/crates/net/downloaders/src/receipt_file_client.rs @@ -220,37 +220,360 @@ pub struct ReceiptWithBlockNumber { #[cfg(test)] mod test { - use reth_primitives::hex; - use reth_tracing::init_test_tracing; - - use crate::file_codec_ovm_receipt::{ - test::{ - receipt_block_1 as op_mainnet_receipt_block_1, - receipt_block_2 as op_mainnet_receipt_block_2, - receipt_block_3 as op_mainnet_receipt_block_3, - HACK_RECEIPT_ENCODED_BLOCK_1 as HACK_RECEIPT_ENCODED_BLOCK_1_OP_MAINNET, - HACK_RECEIPT_ENCODED_BLOCK_2 as HACK_RECEIPT_ENCODED_BLOCK_2_OP_MAINNET, - HACK_RECEIPT_ENCODED_BLOCK_3 as HACK_RECEIPT_ENCODED_BLOCK_3_OP_MAINNET, - }, - HackReceiptFileCodec, + use crate::{ + file_client::{FileClientError, FromReader}, + receipt_file_client::{ReceiptFileClient, ReceiptWithBlockNumber}, }; + use alloy_rlp::{Decodable, RlpDecodable}; + use reth_primitives::{ + hex, Address, Buf, Bytes, BytesMut, Log, LogData, Receipt, TxType, B256, + }; + use reth_tracing::init_test_tracing; + use tokio_util::codec::Decoder; - use super::*; + #[derive(Debug, PartialEq, Eq, RlpDecodable)] + pub struct MockReceipt { + tx_type: u8, + status: u64, + cumulative_gas_used: u64, + logs: Vec, + block_number: u64, + } + + #[derive(Debug, PartialEq, Eq, RlpDecodable)] + #[rlp(trailing)] + struct MockReceiptContainer(Option); + + impl TryFrom for ReceiptWithBlockNumber { + type Error = &'static str; + fn try_from(exported_receipt: MockReceipt) -> Result { + let MockReceipt { tx_type, status, cumulative_gas_used, logs, block_number: number } = + exported_receipt; + + #[allow(clippy::needless_update)] + let receipt = Receipt { + tx_type: TxType::try_from(tx_type.to_be_bytes()[0])?, + success: status != 0, + cumulative_gas_used, + logs, + ..Default::default() + }; + + Ok(Self { receipt, number }) + } + } + + #[derive(Debug, Default)] + struct MockReceiptFileCodec; + + impl Decoder for MockReceiptFileCodec { + type Item = Option; + type Error = FileClientError; + + fn decode(&mut self, src: &mut BytesMut) -> Result, Self::Error> { + if src.is_empty() { + return Ok(None) + } + + let buf_slice = &mut src.as_ref(); + let receipt = MockReceiptContainer::decode(buf_slice) + .map_err(|err| Self::Error::Rlp(err, src.to_vec()))? + .0; + src.advance(src.len() - buf_slice.len()); + + Ok(Some( + receipt + .map(|receipt| receipt.try_into().map_err(FileClientError::from)) + .transpose()?, + )) + } + } + + pub(crate) const MOCK_RECEIPT_ENCODED_BLOCK_1: &[u8] = &hex!("f901a4f901a1800183031843f90197f89b948ce8c13d816fe6daf12d6fd9e4952e1fc88850aef863a00109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac6027ba00000000000000000000000000000000000000000000000000000000000014218a000000000000000000000000070b17c0fe982ab4a7ac17a4c25485643151a1f2da000000000000000000000000000000000000000000000000000000000618d8837f89c948ce8c13d816fe6daf12d6fd9e4952e1fc88850aef884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68ba000000000000000000000000000000000000000000000000000000000d0e3ebf0a00000000000000000000000000000000000000000000000000000000000014218a000000000000000000000000070b17c0fe982ab4a7ac17a4c25485643151a1f2d80f85a948ce8c13d816fe6daf12d6fd9e4952e1fc88850aef842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234fa000000000000000000000000000000000000000000000007edc6ca0bb683480008001"); + + pub(crate) const MOCK_RECEIPT_ENCODED_BLOCK_2: &[u8] = &hex!("f90106f9010380018301c60df8faf89c948ce8c13d816fe6daf12d6fd9e4952e1fc88850aef884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68da000000000000000000000000000000000000000000000000000000000d0ea0e40a00000000000000000000000000000000000000000000000000000000000014218a0000000000000000000000000e5e7492282fd1e3bfac337a0beccd29b15b7b24080f85a948ce8c13d816fe6daf12d6fd9e4952e1fc88850aef842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234ea000000000000000000000000000000000000000000000007eda7867e0c7d480008002"); + + pub(crate) const MOCK_RECEIPT_ENCODED_BLOCK_3: &[u8] = &hex!("f90106f9010380018301c60df8faf89c948ce8c13d816fe6daf12d6fd9e4952e1fc88850aef884a092e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68da000000000000000000000000000000000000000000000000000000000d101e54ba00000000000000000000000000000000000000000000000000000000000014218a0000000000000000000000000fa011d8d6c26f13abe2cefed38226e401b2b8a9980f85a948ce8c13d816fe6daf12d6fd9e4952e1fc88850aef842a0fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234ea000000000000000000000000000000000000000000000007ed8842f06277480008003"); + + fn mock_receipt_1() -> MockReceipt { + let receipt = receipt_block_1(); + MockReceipt { + tx_type: receipt.receipt.tx_type as u8, + status: receipt.receipt.success as u64, + + cumulative_gas_used: receipt.receipt.cumulative_gas_used, + logs: receipt.receipt.logs, + block_number: 1, + } + } + + fn mock_receipt_2() -> MockReceipt { + let receipt = receipt_block_2(); + MockReceipt { + tx_type: receipt.receipt.tx_type as u8, + status: receipt.receipt.success as u64, + + cumulative_gas_used: receipt.receipt.cumulative_gas_used, + logs: receipt.receipt.logs, + block_number: 2, + } + } + + fn mock_receipt_3() -> MockReceipt { + let receipt = receipt_block_3(); + MockReceipt { + tx_type: receipt.receipt.tx_type as u8, + status: receipt.receipt.success as u64, + + cumulative_gas_used: receipt.receipt.cumulative_gas_used, + logs: receipt.receipt.logs, + block_number: 3, + } + } + + pub(crate) fn receipt_block_1() -> ReceiptWithBlockNumber { + let log_1 = Log { + address: Address::from(hex!("8ce8c13d816fe6daf12d6fd9e4952e1fc88850ae")), + data: LogData::new( + vec![ + B256::from(hex!( + "0109fc6f55cf40689f02fbaad7af7fe7bbac8a3d2186600afc7d3e10cac6027b" + )), + B256::from(hex!( + "0000000000000000000000000000000000000000000000000000000000014218" + )), + B256::from(hex!( + "00000000000000000000000070b17c0fe982ab4a7ac17a4c25485643151a1f2d" + )), + ], + Bytes::from(hex!( + "00000000000000000000000000000000000000000000000000000000618d8837" + )), + ) + .unwrap(), + }; + + let log_2 = Log { + address: Address::from(hex!("8ce8c13d816fe6daf12d6fd9e4952e1fc88850ae")), + data: LogData::new( + vec![ + B256::from(hex!( + "92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68b" + )), + B256::from(hex!( + "00000000000000000000000000000000000000000000000000000000d0e3ebf0" + )), + B256::from(hex!( + "0000000000000000000000000000000000000000000000000000000000014218" + )), + B256::from(hex!( + "00000000000000000000000070b17c0fe982ab4a7ac17a4c25485643151a1f2d" + )), + ], + Bytes::default(), + ) + .unwrap(), + }; + + let log_3 = Log { + address: Address::from(hex!("8ce8c13d816fe6daf12d6fd9e4952e1fc88850ae")), + data: LogData::new( + vec![ + B256::from(hex!( + "fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234f" + )), + B256::from(hex!( + "00000000000000000000000000000000000000000000007edc6ca0bb68348000" + )), + ], + Bytes::default(), + ) + .unwrap(), + }; + + let mut receipt = Receipt { + tx_type: TxType::Legacy, + success: true, + cumulative_gas_used: 202819, + ..Default::default() + }; + // #[allow(clippy::needless_update)] not recognised, ..Default::default() needed so optimism + // feature must not be brought into scope + receipt.logs = vec![log_1, log_2, log_3]; + + ReceiptWithBlockNumber { receipt, number: 1 } + } + + pub(crate) fn receipt_block_2() -> ReceiptWithBlockNumber { + let log_1 = Log { + address: Address::from(hex!("8ce8c13d816fe6daf12d6fd9e4952e1fc88850ae")), + data: LogData::new( + vec![ + B256::from(hex!( + "92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68d" + )), + B256::from(hex!( + "00000000000000000000000000000000000000000000000000000000d0ea0e40" + )), + B256::from(hex!( + "0000000000000000000000000000000000000000000000000000000000014218" + )), + B256::from(hex!( + "000000000000000000000000e5e7492282fd1e3bfac337a0beccd29b15b7b240" + )), + ], + Bytes::default(), + ) + .unwrap(), + }; + + let log_2 = Log { + address: Address::from(hex!("8ce8c13d816fe6daf12d6fd9e4952e1fc88850ae")), + data: LogData::new( + vec![ + B256::from(hex!( + "fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234e" + )), + B256::from(hex!( + "00000000000000000000000000000000000000000000007eda7867e0c7d48000" + )), + ], + Bytes::default(), + ) + .unwrap(), + }; + + let mut receipt = Receipt { + tx_type: TxType::Legacy, + success: true, + cumulative_gas_used: 116237, + ..Default::default() + }; + // #[allow(clippy::needless_update)] not recognised, ..Default::default() needed so optimism + // feature must not be brought into scope + receipt.logs = vec![log_1, log_2]; + + ReceiptWithBlockNumber { receipt, number: 2 } + } + + pub(crate) fn receipt_block_3() -> ReceiptWithBlockNumber { + let log_1 = Log { + address: Address::from(hex!("8ce8c13d816fe6daf12d6fd9e4952e1fc88850ae")), + data: LogData::new( + vec![ + B256::from(hex!( + "92e98423f8adac6e64d0608e519fd1cefb861498385c6dee70d58fc926ddc68d" + )), + B256::from(hex!( + "00000000000000000000000000000000000000000000000000000000d101e54b" + )), + B256::from(hex!( + "0000000000000000000000000000000000000000000000000000000000014218" + )), + B256::from(hex!( + "000000000000000000000000fa011d8d6c26f13abe2cefed38226e401b2b8a99" + )), + ], + Bytes::default(), + ) + .unwrap(), + }; + + let log_2 = Log { + address: Address::from(hex!("8ce8c13d816fe6daf12d6fd9e4952e1fc88850ae")), + data: LogData::new( + vec![ + B256::from(hex!( + "fe25c73e3b9089fac37d55c4c7efcba6f04af04cebd2fc4d6d7dbb07e1e5234e" + )), + B256::from(hex!( + "00000000000000000000000000000000000000000000007ed8842f0627748000" + )), + ], + Bytes::default(), + ) + .unwrap(), + }; + + let mut receipt = Receipt { + tx_type: TxType::Legacy, + success: true, + cumulative_gas_used: 116237, + ..Default::default() + }; + // #[allow(clippy::needless_update)] not recognised, ..Default::default() needed so optimism + // feature must not be brought into scope + receipt.logs = vec![log_1, log_2]; + + ReceiptWithBlockNumber { receipt, number: 3 } + } + + #[test] + fn decode_mock_receipt() { + let receipt1 = mock_receipt_1(); + let decoded1 = MockReceiptContainer::decode(&mut &MOCK_RECEIPT_ENCODED_BLOCK_1[..]) + .unwrap() + .0 + .unwrap(); + assert_eq!(receipt1, decoded1); + + let receipt2 = mock_receipt_2(); + let decoded2 = MockReceiptContainer::decode(&mut &MOCK_RECEIPT_ENCODED_BLOCK_2[..]) + .unwrap() + .0 + .unwrap(); + assert_eq!(receipt2, decoded2); + + let receipt3 = mock_receipt_3(); + let decoded3 = MockReceiptContainer::decode(&mut &MOCK_RECEIPT_ENCODED_BLOCK_3[..]) + .unwrap() + .0 + .unwrap(); + assert_eq!(receipt3, decoded3); + } + + #[test] + #[allow(clippy::needless_update)] + fn receipts_codec() { + // rig + + let mut receipt_1_to_3 = MOCK_RECEIPT_ENCODED_BLOCK_1.to_vec(); + receipt_1_to_3.extend_from_slice(MOCK_RECEIPT_ENCODED_BLOCK_2); + receipt_1_to_3.extend_from_slice(MOCK_RECEIPT_ENCODED_BLOCK_3); + + let encoded = &mut BytesMut::from(&receipt_1_to_3[..]); + + let mut codec = MockReceiptFileCodec; + + // test + + let first_decoded_receipt = codec.decode(encoded).unwrap().unwrap().unwrap(); + + assert_eq!(receipt_block_1(), first_decoded_receipt); + + let second_decoded_receipt = codec.decode(encoded).unwrap().unwrap().unwrap(); + + assert_eq!(receipt_block_2(), second_decoded_receipt); + + let third_decoded_receipt = codec.decode(encoded).unwrap().unwrap().unwrap(); + + assert_eq!(receipt_block_3(), third_decoded_receipt); + } /// No receipts for genesis block - const HACK_RECEIPT_BLOCK_NO_TRANSACTIONS: &[u8] = &hex!("c0"); + const MOCK_RECEIPT_BLOCK_NO_TRANSACTIONS: &[u8] = &hex!("c0"); #[tokio::test] async fn receipt_file_client_ovm_codec() { init_test_tracing(); // genesis block has no hack receipts - let mut encoded_receipts = HACK_RECEIPT_BLOCK_NO_TRANSACTIONS.to_vec(); + let mut encoded_receipts = MOCK_RECEIPT_BLOCK_NO_TRANSACTIONS.to_vec(); // one receipt each for block 1 and 2 - encoded_receipts.extend_from_slice(HACK_RECEIPT_ENCODED_BLOCK_1_OP_MAINNET); - encoded_receipts.extend_from_slice(HACK_RECEIPT_ENCODED_BLOCK_2_OP_MAINNET); + encoded_receipts.extend_from_slice(MOCK_RECEIPT_ENCODED_BLOCK_1); + encoded_receipts.extend_from_slice(MOCK_RECEIPT_ENCODED_BLOCK_2); // no receipt for block 4 - encoded_receipts.extend_from_slice(HACK_RECEIPT_BLOCK_NO_TRANSACTIONS); + encoded_receipts.extend_from_slice(MOCK_RECEIPT_BLOCK_NO_TRANSACTIONS); let encoded_byte_len = encoded_receipts.len() as u64; let reader = &mut &encoded_receipts[..]; @@ -258,7 +581,7 @@ mod test { let ( ReceiptFileClient { receipts, first_block, total_receipts, _marker }, _remaining_bytes, - ) = ReceiptFileClient::::from_reader(reader, encoded_byte_len) + ) = ReceiptFileClient::::from_reader(reader, encoded_byte_len) .await .unwrap(); @@ -266,8 +589,8 @@ mod test { assert_eq!(2, total_receipts); assert_eq!(0, first_block); assert!(receipts[0].is_empty()); - assert_eq!(op_mainnet_receipt_block_1().receipt, receipts[1][0].clone().unwrap()); - assert_eq!(op_mainnet_receipt_block_2().receipt, receipts[2][0].clone().unwrap()); + assert_eq!(receipt_block_1().receipt, receipts[1][0].clone().unwrap()); + assert_eq!(receipt_block_2().receipt, receipts[2][0].clone().unwrap()); assert!(receipts[3].is_empty()); } @@ -276,13 +599,13 @@ mod test { init_test_tracing(); // genesis block has no hack receipts - let mut encoded_receipts = HACK_RECEIPT_BLOCK_NO_TRANSACTIONS.to_vec(); + let mut encoded_receipts = MOCK_RECEIPT_BLOCK_NO_TRANSACTIONS.to_vec(); // one receipt each for block 1 - encoded_receipts.extend_from_slice(HACK_RECEIPT_ENCODED_BLOCK_1_OP_MAINNET); + encoded_receipts.extend_from_slice(MOCK_RECEIPT_ENCODED_BLOCK_1); // no receipt for block 2 - encoded_receipts.extend_from_slice(HACK_RECEIPT_BLOCK_NO_TRANSACTIONS); + encoded_receipts.extend_from_slice(MOCK_RECEIPT_BLOCK_NO_TRANSACTIONS); // one receipt for block 3 - encoded_receipts.extend_from_slice(HACK_RECEIPT_ENCODED_BLOCK_3_OP_MAINNET); + encoded_receipts.extend_from_slice(MOCK_RECEIPT_ENCODED_BLOCK_3); let encoded_byte_len = encoded_receipts.len() as u64; let reader = &mut &encoded_receipts[..]; @@ -290,7 +613,7 @@ mod test { let ( ReceiptFileClient { receipts, first_block, total_receipts, _marker }, _remaining_bytes, - ) = ReceiptFileClient::::from_reader(reader, encoded_byte_len) + ) = ReceiptFileClient::::from_reader(reader, encoded_byte_len) .await .unwrap(); @@ -298,9 +621,9 @@ mod test { assert_eq!(2, total_receipts); assert_eq!(0, first_block); assert!(receipts[0].is_empty()); - assert_eq!(op_mainnet_receipt_block_1().receipt, receipts[1][0].clone().unwrap()); + assert_eq!(receipt_block_1().receipt, receipts[1][0].clone().unwrap()); assert!(receipts[2].is_empty()); - assert_eq!(op_mainnet_receipt_block_3().receipt, receipts[3][0].clone().unwrap()); + assert_eq!(receipt_block_3().receipt, receipts[3][0].clone().unwrap()); } #[tokio::test] @@ -308,14 +631,14 @@ mod test { init_test_tracing(); // genesis block has no hack receipts - let mut encoded_receipts = HACK_RECEIPT_BLOCK_NO_TRANSACTIONS.to_vec(); + let mut encoded_receipts = MOCK_RECEIPT_BLOCK_NO_TRANSACTIONS.to_vec(); // one receipt each for block 1 - encoded_receipts.extend_from_slice(HACK_RECEIPT_ENCODED_BLOCK_1_OP_MAINNET); + encoded_receipts.extend_from_slice(MOCK_RECEIPT_ENCODED_BLOCK_1); // two receipts for block 2 - encoded_receipts.extend_from_slice(HACK_RECEIPT_ENCODED_BLOCK_2_OP_MAINNET); - encoded_receipts.extend_from_slice(HACK_RECEIPT_ENCODED_BLOCK_2_OP_MAINNET); + encoded_receipts.extend_from_slice(MOCK_RECEIPT_ENCODED_BLOCK_2); + encoded_receipts.extend_from_slice(MOCK_RECEIPT_ENCODED_BLOCK_2); // one receipt for block 3 - encoded_receipts.extend_from_slice(HACK_RECEIPT_ENCODED_BLOCK_3_OP_MAINNET); + encoded_receipts.extend_from_slice(MOCK_RECEIPT_ENCODED_BLOCK_3); let encoded_byte_len = encoded_receipts.len() as u64; let reader = &mut &encoded_receipts[..]; @@ -323,7 +646,7 @@ mod test { let ( ReceiptFileClient { receipts, first_block, total_receipts, _marker }, _remaining_bytes, - ) = ReceiptFileClient::::from_reader(reader, encoded_byte_len) + ) = ReceiptFileClient::::from_reader(reader, encoded_byte_len) .await .unwrap(); @@ -331,9 +654,9 @@ mod test { assert_eq!(4, total_receipts); assert_eq!(0, first_block); assert!(receipts[0].is_empty()); - assert_eq!(op_mainnet_receipt_block_1().receipt, receipts[1][0].clone().unwrap()); - assert_eq!(op_mainnet_receipt_block_2().receipt, receipts[2][0].clone().unwrap()); - assert_eq!(op_mainnet_receipt_block_2().receipt, receipts[2][1].clone().unwrap()); - assert_eq!(op_mainnet_receipt_block_3().receipt, receipts[3][0].clone().unwrap()); + assert_eq!(receipt_block_1().receipt, receipts[1][0].clone().unwrap()); + assert_eq!(receipt_block_2().receipt, receipts[2][0].clone().unwrap()); + assert_eq!(receipt_block_2().receipt, receipts[2][1].clone().unwrap()); + assert_eq!(receipt_block_3().receipt, receipts[3][0].clone().unwrap()); } } diff --git a/crates/optimism/cli/Cargo.toml b/crates/optimism/cli/Cargo.toml index d17de95b6..fc097ea3a 100644 --- a/crates/optimism/cli/Cargo.toml +++ b/crates/optimism/cli/Cargo.toml @@ -38,6 +38,7 @@ reth-cli.workspace = true # eth alloy-genesis.workspace = true alloy-primitives.workspace = true +alloy-rlp.workspace = true # misc @@ -53,6 +54,7 @@ tokio = { workspace = true, features = [ "time", "rt-multi-thread", ] } +tokio-util = { workspace = true, features = ["codec"] } tracing.workspace = true eyre.workspace = true diff --git a/crates/optimism/cli/src/commands/import_receipts.rs b/crates/optimism/cli/src/commands/import_receipts.rs index e68c76a75..99c7da40e 100644 --- a/crates/optimism/cli/src/commands/import_receipts.rs +++ b/crates/optimism/cli/src/commands/import_receipts.rs @@ -1,13 +1,13 @@ //! Command that imports OP mainnet receipts from Bedrock datadir, exported via //! . +use crate::file_codec_ovm_receipt::HackReceiptFileCodec; use clap::Parser; use reth_cli_commands::common::{AccessRights, Environment, EnvironmentArgs}; use reth_db::tables; use reth_db_api::database::Database; use reth_downloaders::{ file_client::{ChunkedFileReader, DEFAULT_BYTE_LEN_CHUNK_CHAIN_FILE}, - file_codec_ovm_receipt::HackReceiptFileCodec, receipt_file_client::ReceiptFileClient, }; use reth_execution_types::ExecutionOutcome; diff --git a/crates/net/downloaders/src/file_codec_ovm_receipt.rs b/crates/optimism/cli/src/file_codec_ovm_receipt.rs similarity index 99% rename from crates/net/downloaders/src/file_codec_ovm_receipt.rs rename to crates/optimism/cli/src/file_codec_ovm_receipt.rs index 74911c7e3..d452efb1c 100644 --- a/crates/net/downloaders/src/file_codec_ovm_receipt.rs +++ b/crates/optimism/cli/src/file_codec_ovm_receipt.rs @@ -7,7 +7,7 @@ use reth_primitives::{ }; use tokio_util::codec::Decoder; -use crate::{file_client::FileClientError, receipt_file_client::ReceiptWithBlockNumber}; +use reth_downloaders::{file_client::FileClientError, receipt_file_client::ReceiptWithBlockNumber}; /// Codec for reading raw receipts from a file. /// diff --git a/crates/optimism/cli/src/lib.rs b/crates/optimism/cli/src/lib.rs index e8559ebae..1b750bd89 100644 --- a/crates/optimism/cli/src/lib.rs +++ b/crates/optimism/cli/src/lib.rs @@ -26,6 +26,18 @@ use std::{ffi::OsString, fmt, sync::Arc}; pub mod chainspec; /// Optimism CLI commands. pub mod commands; +/// Module with a codec for reading and encoding receipts in files. +/// +/// Enables decoding and encoding `HackReceipt` type. See . +/// +/// Currently configured to use codec [`HackReceipt`](file_codec_ovm_receipt::HackReceipt) based on +/// export of below Bedrock data using . Codec can +/// be replaced with regular encoding of receipts for export. +/// +/// NOTE: receipts can be exported using regular op-geth encoding for `Receipt` type, to fit +/// reth's needs for importing. However, this would require patching the diff in to export the `Receipt` and not `HackReceipt` type (originally +/// made for op-erigon's import needs). +pub mod file_codec_ovm_receipt; pub use commands::{import::ImportOpCommand, import_receipts::ImportReceiptsOpCommand}; /// The main reth cli interface.