Skip to content

Commit

Permalink
Refactor Taiko specific re-exports for improved code readability and …
Browse files Browse the repository at this point in the history
…maintainability
  • Loading branch information
johntaiko committed Jul 8, 2024
1 parent 9af48a3 commit 6f1219b
Show file tree
Hide file tree
Showing 14 changed files with 249 additions and 6 deletions.
3 changes: 3 additions & 0 deletions Cargo.lock

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

1 change: 0 additions & 1 deletion bin/reth/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ reth-node-ethereum.workspace = true
reth-node-optimism = { workspace = true, optional = true, features = [
"optimism",
] }
# reth-node-taiko = { workspace = true, optional = true }
reth-node-core.workspace = true
reth-db-common.workspace = true
reth-node-builder.workspace = true
Expand Down
5 changes: 4 additions & 1 deletion crates/engine-primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,7 @@ reth-chainspec.workspace = true
reth-payload-primitives.workspace = true

# misc
serde.workspace = true
serde.workspace = true

[features]
taiko = ["reth-payload-primitives/taiko"]
5 changes: 4 additions & 1 deletion crates/payload/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ tokio = { workspace = true, features = ["sync"] }

# misc
thiserror.workspace = true
serde.workspace = true
serde.workspace = true

[features]
taiko = ["reth-transaction-pool/taiko"]
8 changes: 8 additions & 0 deletions crates/rpc/rpc-api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ reth-rpc-types.workspace = true
reth-engine-primitives.workspace = true
reth-network-peers.workspace = true

# taiko
taiko-reth-primitives = { workspace = true, optional = true }

# misc
alloy-dyn-abi = { workspace = true, features = ["eip712"] }
jsonrpsee = { workspace = true, features = ["server", "macros"] }
Expand All @@ -28,3 +31,8 @@ serde_json.workspace = true

[features]
client = ["jsonrpsee/client", "jsonrpsee/async-client"]
taiko = [
"reth-primitives/taiko",
"reth-engine-primitives/taiko",
"dep:taiko-reth-primitives",
]
9 changes: 9 additions & 0 deletions crates/rpc/rpc-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ pub mod servers {
validation::BlockSubmissionValidationApiServer,
web3::Web3ApiServer,
};

#[cfg(feature = "taiko")]
pub use crate::taiko::TaikoApiServer;
}

/// re-export of all client traits
Expand Down Expand Up @@ -86,4 +89,10 @@ pub mod clients {
validation::BlockSubmissionValidationApiClient,
web3::Web3ApiClient,
};

#[cfg(feature = "taiko")]
pub use crate::taiko::TaikoApiClient;
}

#[cfg(feature = "taiko")]
mod taiko;
37 changes: 37 additions & 0 deletions crates/rpc/rpc-api/src/taiko.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use jsonrpsee::{core::RpcResult, proc_macros::rpc};
use reth_primitives::Address;
use reth_rpc_types::Transaction;
use taiko_reth_primitives::L1Origin;

/// Taiko rpc interface.
#[cfg_attr(not(feature = "client"), rpc(server, namespace = "taiko"))]
#[cfg_attr(feature = "client", rpc(server, client, namespace = "taiko"))]
pub trait TaikoApi {
/// HeadL1Origin returns the latest L2 block's corresponding L1 origin.
#[method(name = "headL1Origin")]
async fn head_l1_origin(&self) -> RpcResult<Option<u64>>;

/// L1OriginByID returns the L2 block's corresponding L1 origin.
#[method(name = "l1OriginByID")]
async fn l1_origin_by_id(&self, block_id: u64) -> RpcResult<Option<L1Origin>>;

/// GetL2ParentHeaders
#[method(name = "getL2ParentHeaders")]
async fn get_l2_parent_headers(&self, block_id: u64)
-> RpcResult<Vec<reth_primitives::Header>>;

/// Returns the details of all transactions currently pending for inclusion in the next
/// block(s), as well as the ones that are being scheduled for future execution only.
///
/// See [here](https://geth.ethereum.org/docs/rpc/ns-txpool#txpool_content) for more details
#[method(name = "content")]
async fn txpool_content(
&self,
beneficiary: Address,
base_fee: u64,
block_max_gas_limit: u64,
max_bytes_per_tx_list: u64,
locals: Vec<String>,
max_transactions_lists: u64,
) -> RpcResult<Vec<Vec<Transaction>>>;
}
7 changes: 7 additions & 0 deletions crates/rpc/rpc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ reth-execution-types.workspace = true

reth-evm-optimism = { workspace = true, optional = true }

# taiko
taiko-reth-provider = { workspace = true, optional = true }
taiko-reth-primitives = { workspace = true, optional = true }

# eth
alloy-rlp.workspace = true
alloy-dyn-abi = { workspace = true, features = ["eip712"] }
Expand Down Expand Up @@ -104,5 +108,8 @@ optimism = [
taiko = [
"reth-primitives/taiko",
"reth-revm/taiko",
"reth-rpc-api/taiko",
"reth-rpc-engine-api/taiko",
"dep:taiko-reth-provider",
"dep:taiko-reth-primitives",
]
5 changes: 5 additions & 0 deletions crates/rpc/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,8 @@ pub use trace::TraceApi;
pub use txpool::TxPoolApi;
pub use web3::Web3Api;
pub mod result;

#[cfg(feature = "taiko")]
mod taiko;
#[cfg(feature = "taiko")]
pub use taiko::TaikoApi;
163 changes: 163 additions & 0 deletions crates/rpc/rpc/src/taiko.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
use std::collections::BTreeMap;

use crate::result::internal_rpc_err;
use alloy_primitives::Address;
use async_trait::async_trait;
use jsonrpsee::core::RpcResult;
use reth_provider::BlockReader;
use reth_rpc_api::TaikoApiServer;
use reth_rpc_types::{txpool::TxpoolContent, Transaction};
use reth_transaction_pool::{AllPoolTransactions, PoolTransaction, TransactionPool};
use taiko_reth_primitives::L1Origin;
use taiko_reth_provider::L1OriginReader;

/// Taiko API.
#[derive(Debug)]
pub struct TaikoApi<Provider, Pool> {
provider: Provider,
pool: Pool,
}

impl<Provider, Pool> TaikoApi<Provider, Pool> {
/// Creates a new instance of `Taiko`.
pub const fn new(provider: Provider, pool: Pool) -> Self {
Self { provider, pool }
}
}

impl<Provider, Pool> TaikoApi<Provider, Pool>
where
Provider: BlockReader + L1OriginReader + 'static,
Pool: TransactionPool + 'static,
{
fn content(&self) -> TxpoolContent {
#[inline]
fn insert<T: PoolTransaction>(
tx: &T,
content: &mut BTreeMap<Address, BTreeMap<String, Transaction>>,
) {
content.entry(tx.sender()).or_default().insert(
tx.nonce().to_string(),
reth_rpc_types_compat::transaction::from_recovered(tx.to_recovered_transaction()),
);
}

let AllPoolTransactions { pending, queued } = self.pool.all_transactions();

let mut content = TxpoolContent::default();
for pending in pending {
insert(&pending.transaction, &mut content.pending);
}
for queued in queued {
insert(&queued.transaction, &mut content.queued);
}

content
}

fn get_txs(
&self,
locals: &[String],
) -> (
BTreeMap<Address, BTreeMap<String, Transaction>>,
BTreeMap<Address, BTreeMap<String, Transaction>>,
) {
self.content()
.pending
.into_iter()
.map(|(address, txs)| (address, txs, locals.contains(&address.to_string())))
.fold(
(
BTreeMap::<Address, BTreeMap<String, Transaction>>::new(),
BTreeMap::<Address, BTreeMap<String, Transaction>>::new(),
),
|(mut l, mut r), (address, txs, is_local)| {
if is_local {
l.insert(address, txs);
} else {
r.insert(address, txs);
}

(l, r)
},
)
}

async fn commit_txs(&self, locals: &[String]) -> RpcResult<Vec<Transaction>> {
let (_local_txs, _remote_txs) = self.get_txs(&locals);
Ok(vec![])
}
}

#[async_trait]
impl<Provider, Pool> TaikoApiServer for TaikoApi<Provider, Pool>
where
Provider: BlockReader + L1OriginReader + 'static,
Pool: TransactionPool + 'static,
{
/// HeadL1Origin returns the latest L2 block's corresponding L1 origin.
// #[cfg(feature = "taiko")]
async fn head_l1_origin(&self) -> RpcResult<Option<u64>> {
self.provider.get_head_l1_origin().map_err(|_| {
internal_rpc_err("taiko_headL1Origin failed to read latest l2 block's L1 origin")
})
}

/// L1OriginByID returns the L2 block's corresponding L1 origin.
// #[cfg(feature = "taiko")]
async fn l1_origin_by_id(&self, block_id: u64) -> RpcResult<Option<L1Origin>> {
self.provider.get_l1_origin(block_id).map_err(|_| {
internal_rpc_err("taiko_l1OriginByID failed to read L1 origin by block id")
})
}

/// GetL2ParentHeaders
// #[cfg(feature = "taiko")]
async fn get_l2_parent_headers(
&self,
block_id: u64,
) -> RpcResult<Vec<reth_primitives::Header>> {
let start = if block_id > 256 { block_id - 255 } else { 0 };
let mut headers = Vec::with_capacity(256);

for id in start..=block_id {
let option = self.provider.header_by_number(id).map_err(|_| {
internal_rpc_err("taiko_getL2ParentHeaders failed to read header by number")
})?;
let Some(header) = option else {
return Err(internal_rpc_err(
"taiko_getL2ParentHeaders failed to find parent header by number",
));
};
headers.push(header);
}

Ok(headers)
}

// TODO:(petar) implement this function
/// TxPoolContent retrieves the transaction pool content with the given upper limits.
async fn txpool_content(
&self,
beneficiary: Address,
base_fee: u64,
block_max_gas_limit: u64,
max_bytes_per_tx_list: u64,
locals: Vec<String>,
max_transactions_lists: u64,
) -> RpcResult<Vec<Vec<Transaction>>> {
let mut tx_lists = Vec::with_capacity(max_transactions_lists as usize);

for _ in 0..max_transactions_lists {
let tx_list = self.commit_txs(&locals).await?;

if tx_list.is_empty() {
break;
}

tx_lists.push(tx_list);
}

Ok(tx_lists)
}
}
1 change: 1 addition & 0 deletions crates/storage/provider/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,6 @@ rand.workspace = true

[features]
optimism = ["reth-primitives/optimism", "reth-execution-types/optimism"]
taiko = ["reth-evm/taiko"]
serde = ["reth-execution-types/serde"]
test-utils = ["alloy-rlp", "reth-db/test-utils", "reth-nippy-jar/test-utils"]
2 changes: 1 addition & 1 deletion crates/taiko/payload/builder/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use taiko_reth_evm::{
eip6110::parse_deposits_from_receipts,
};
use taiko_reth_primitives::L1Origin;
use taiko_reth_provider::l1_origin::L1OriginWriter;
use taiko_reth_provider::L1OriginWriter;
use tracing::{debug, trace, warn};

/// Taiko's payload builder
Expand Down
2 changes: 1 addition & 1 deletion crates/taiko/storage/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
//! Collection of traits and trait implementations for taiko database operations.
pub mod l1_origin;
// Compare this snippet from crates/taiko/storage/src/lib.rs:
pub use l1_origin::*;
7 changes: 6 additions & 1 deletion crates/transaction-pool/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,12 @@ serde_json.workspace = true
default = ["serde"]
serde = ["dep:serde"]
test-utils = ["rand", "paste", "serde"]
arbitrary = ["proptest", "reth-primitives/arbitrary", "proptest-arbitrary-interop"]
arbitrary = [
"proptest",
"reth-primitives/arbitrary",
"proptest-arbitrary-interop",
]
taiko = ["reth-provider/taiko"]

[[bench]]
name = "truncate"
Expand Down

0 comments on commit 6f1219b

Please sign in to comment.