Skip to content

Commit 6d9b444

Browse files
refactor(taiko-client-rs): consolidate shared assembly and collapse single-impl abstractions (#21776)
1 parent c9d6207 commit 6d9b444

66 files changed

Lines changed: 1335 additions & 2419 deletions

Some content is hidden

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

packages/taiko-client-rs/Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,5 @@
1-
use alloy_consensus::BlobTransactionSidecar;
2-
use alloy_primitives::B256;
3-
use async_trait::async_trait;
4-
use rpc::{
5-
blob::{BlobDataError, BlobDataSource},
6-
error::RpcClientError,
7-
};
1+
use rpc::{blob::BlobDataError, error::RpcClientError};
82
use thiserror::Error;
9-
use tracing::{debug, error};
103

114
/// Shasta manifest fetcher implementation.
125
pub mod shasta;
@@ -40,60 +33,3 @@ pub enum ManifestFetcherError {
4033
#[error("invalid shasta manifest: {0}")]
4134
Invalid(String),
4235
}
43-
44-
/// Trait describing manifest fetch behaviour for different forks.
45-
#[async_trait]
46-
pub trait ManifestFetcher: Send + Sync {
47-
/// Fork-specific manifest type produced by the decoder.
48-
type Manifest;
49-
50-
/// Access the blob data source used by this fetcher.
51-
fn blob_source(&self) -> &BlobDataSource;
52-
53-
/// Fetch blobs from the provided source for the given blob hashes.
54-
async fn fetch_blobs(
55-
&self,
56-
timestamp: u64,
57-
blob_hashes: &[B256],
58-
) -> Result<Vec<BlobTransactionSidecar>, ManifestFetcherError> {
59-
if blob_hashes.is_empty() {
60-
return Err(ManifestFetcherError::EmptyBlobHashes);
61-
}
62-
63-
debug!(hash_count = blob_hashes.len(), timestamp, "fetching blob sidecars");
64-
let sidecars = self.blob_source().get_blobs(timestamp, blob_hashes).await?;
65-
if sidecars.len() != blob_hashes.len() {
66-
error!(
67-
expected = blob_hashes.len(),
68-
actual = sidecars.len(),
69-
"blob response count mismatch"
70-
);
71-
return Err(ManifestFetcherError::BlobCountMismatch {
72-
expected: blob_hashes.len(),
73-
actual: sidecars.len(),
74-
});
75-
}
76-
77-
Ok(sidecars)
78-
}
79-
80-
/// Decode the manifest for the given sidecars.
81-
async fn decode_manifest(
82-
&self,
83-
sidecars: &[BlobTransactionSidecar],
84-
offset: usize,
85-
max_blocks: usize,
86-
) -> Result<Self::Manifest, ManifestFetcherError>;
87-
88-
/// Fetch and decode the manifest for the given blob hashes.
89-
async fn fetch_and_decode_manifest(
90-
&self,
91-
timestamp: u64,
92-
blob_hashes: &[B256],
93-
offset: usize,
94-
max_blocks: usize,
95-
) -> Result<Self::Manifest, ManifestFetcherError> {
96-
let sidecars = self.fetch_blobs(timestamp, blob_hashes).await?;
97-
self.decode_manifest(&sidecars, offset, max_blocks).await
98-
}
99-
}

packages/taiko-client-rs/crates/driver/src/derivation/manifest/fetcher/shasta.rs

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

33
use alloy_consensus::BlobTransactionSidecar;
4-
use async_trait::async_trait;
4+
use alloy_primitives::B256;
55
use protocol::shasta::{BlobCoder, manifest::DerivationSourceManifest};
66
use rpc::blob::BlobDataSource;
7-
use tracing::{debug, instrument};
7+
use tracing::{debug, error, instrument};
88

9-
use super::{ManifestFetcher, ManifestFetcherError};
9+
use super::ManifestFetcherError;
1010

1111
/// Decode a Shasta derivation-source manifest from blob sidecars.
1212
fn decode_manifest_from_sidecars(
@@ -49,27 +49,45 @@ impl ShastaSourceManifestFetcher {
4949
pub fn new(blob_source: Arc<BlobDataSource>) -> Self {
5050
Self { blob_source }
5151
}
52-
}
5352

54-
#[async_trait]
55-
impl ManifestFetcher for ShastaSourceManifestFetcher {
56-
/// The type of manifest produced by this fetcher.
57-
type Manifest = DerivationSourceManifest;
53+
/// Fetch blob sidecars for the given blob hashes.
54+
async fn fetch_blobs(
55+
&self,
56+
timestamp: u64,
57+
blob_hashes: &[B256],
58+
) -> Result<Vec<BlobTransactionSidecar>, ManifestFetcherError> {
59+
if blob_hashes.is_empty() {
60+
return Err(ManifestFetcherError::EmptyBlobHashes);
61+
}
62+
63+
debug!(hash_count = blob_hashes.len(), timestamp, "fetching blob sidecars");
64+
let sidecars = self.blob_source.get_blobs(timestamp, blob_hashes).await?;
65+
if sidecars.len() != blob_hashes.len() {
66+
error!(
67+
expected = blob_hashes.len(),
68+
actual = sidecars.len(),
69+
"blob response count mismatch"
70+
);
71+
return Err(ManifestFetcherError::BlobCountMismatch {
72+
expected: blob_hashes.len(),
73+
actual: sidecars.len(),
74+
});
75+
}
5876

59-
/// Access the underlying blob data source.
60-
fn blob_source(&self) -> &BlobDataSource {
61-
&self.blob_source
77+
Ok(sidecars)
6278
}
6379

64-
/// Decode a manifest from the provided sidecars and offset.
65-
#[instrument(skip(self, sidecars), fields(sidecar_count = sidecars.len(), offset))]
66-
async fn decode_manifest(
80+
/// Fetch and decode the manifest for the given blob hashes.
81+
#[instrument(skip(self, blob_hashes), fields(hash_count = blob_hashes.len(), offset))]
82+
pub async fn fetch_and_decode_manifest(
6783
&self,
68-
sidecars: &[BlobTransactionSidecar],
84+
timestamp: u64,
85+
blob_hashes: &[B256],
6986
offset: usize,
7087
max_blocks: usize,
71-
) -> Result<Self::Manifest, ManifestFetcherError> {
72-
let manifest = decode_manifest_from_sidecars(sidecars, offset, max_blocks)?;
88+
) -> Result<DerivationSourceManifest, ManifestFetcherError> {
89+
let sidecars = self.fetch_blobs(timestamp, blob_hashes).await?;
90+
let manifest = decode_manifest_from_sidecars(&sidecars, offset, max_blocks)?;
7391
debug!(offset, max_blocks, "decoded shasta manifest from blob sidecars");
7492
Ok(manifest)
7593
}

packages/taiko-client-rs/crates/driver/src/derivation/manifest/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
/// Manifest fetchers and decoding helpers per fork.
44
pub mod fetcher;
55

6-
pub use fetcher::{ManifestFetcher, ManifestFetcherError, ShastaSourceManifestFetcher};
6+
pub use fetcher::{ManifestFetcherError, ShastaSourceManifestFetcher};
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
pub mod manifest;
22
pub mod pipeline;
33

4-
pub use pipeline::{DerivationError, DerivationPipeline, ShastaDerivationPipeline};
4+
pub use pipeline::{DerivationError, ShastaDerivationPipeline};
Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
//! Derivation pipeline abstractions shared across protocol forks.
2-
3-
use alloy::rpc::types::Log;
4-
use async_trait::async_trait;
1+
//! Derivation pipeline implementations per protocol fork.
52
63
/// Shared derivation error type.
74
mod error;
@@ -10,33 +7,3 @@ pub mod shasta;
107

118
pub use error::DerivationError;
129
pub use shasta::ShastaDerivationPipeline;
13-
14-
use crate::sync::engine::{EngineBlockOutcome, PayloadApplier};
15-
16-
/// Trait implemented by derivation pipelines for different protocol forks.
17-
#[async_trait]
18-
pub trait DerivationPipeline: Send + Sync {
19-
/// Fork-specific manifest types.
20-
type Manifest: Send;
21-
22-
/// Convert a proposal log into a manifest for processing.
23-
async fn log_to_manifest(&self, log: &Log) -> Result<Self::Manifest, DerivationError>;
24-
25-
/// Convert a manifest into execution engine blocks for block production.
26-
async fn manifest_to_engine_blocks(
27-
&self,
28-
manifest: Self::Manifest,
29-
applier: &(dyn PayloadApplier + Send + Sync),
30-
) -> Result<Vec<EngineBlockOutcome>, DerivationError>;
31-
32-
/// Process the provided proposal log, materialising the derived blocks in the execution
33-
/// engine.
34-
async fn process_proposal(
35-
&self,
36-
log: &Log,
37-
applier: &(dyn PayloadApplier + Send + Sync),
38-
) -> Result<Vec<EngineBlockOutcome>, DerivationError> {
39-
let manifest = self.log_to_manifest(log).await?;
40-
self.manifest_to_engine_blocks(manifest, applier).await
41-
}
42-
}

packages/taiko-client-rs/crates/driver/src/derivation/pipeline/shasta/pipeline/mod.rs

Lines changed: 19 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ use alloy_consensus::{Transaction, TxEnvelope};
1212
use alloy_provider::RootProvider;
1313
use alloy_rpc_types::{Transaction as RpcTransaction, eth::Block as RpcBlock};
1414
use anyhow::anyhow;
15-
use async_trait::async_trait;
1615
use bindings::inbox::{IInbox::DerivationSource, Inbox::Proposed};
1716
use protocol::shasta::{
1817
constants::{
@@ -26,13 +25,13 @@ use rpc::{blob::BlobDataSource, client::Client};
2625
use tracing::{debug, info, instrument, warn};
2726

2827
use crate::{
29-
derivation::manifest::{ManifestFetcher, fetcher::shasta::ShastaSourceManifestFetcher},
28+
derivation::manifest::fetcher::shasta::ShastaSourceManifestFetcher,
3029
metrics::DriverMetrics,
3130
sync::engine::{EngineBlockOutcome, PayloadApplier},
3231
};
3332
use protocol::shasta::AnchorTxConstructor;
3433

35-
use super::super::{DerivationError, DerivationPipeline};
34+
use super::super::DerivationError;
3635

3736
/// Decoded Shasta `Proposed` event enriched with the containing L1 block metadata.
3837
#[derive(Debug, Clone)]
@@ -200,8 +199,7 @@ where
200199
/// Builder for Shasta anchor transactions.
201200
anchor_constructor: AnchorTxConstructor<RootProvider>,
202201
/// Manifest fetcher used to resolve derivation-source blobs.
203-
derivation_source_manifest_fetcher:
204-
Arc<dyn ManifestFetcher<Manifest = DerivationSourceManifest>>,
202+
derivation_source_manifest_fetcher: ShastaSourceManifestFetcher,
205203
/// Activation timestamp for the Shasta fork on this chain.
206204
shasta_fork_timestamp: u64,
207205
/// Minimum base-fee clamp to use for EIP-4396 calculations on this chain.
@@ -226,8 +224,7 @@ where
226224
blob_source: Arc<BlobDataSource>,
227225
initial_proposal_id: U256,
228226
) -> Result<Self, DerivationError> {
229-
let source_manifest_fetcher: Arc<dyn ManifestFetcher<Manifest = DerivationSourceManifest>> =
230-
Arc::new(ShastaSourceManifestFetcher::new(blob_source.clone()));
227+
let source_manifest_fetcher = ShastaSourceManifestFetcher::new(blob_source.clone());
231228
let anchor_address = *rpc.shasta.anchor.address();
232229
let anchor_constructor =
233230
AnchorTxConstructor::new(rpc.l2_provider.clone(), anchor_address).await?;
@@ -351,19 +348,12 @@ where
351348
Ok(ProposedEventContext { event, l1_block_number, l1_block_hash, l1_timestamp })
352349
}
353350

354-
/// Fetch and decode a single manifest from the blob store.
355-
///
356-
/// The caller is responsible for providing the correct fetcher implementation for
357-
/// the manifest type.
358-
async fn fetch_and_decode_manifest<M>(
351+
/// Fetch and decode a single derivation-source manifest from the blob store.
352+
async fn fetch_and_decode_manifest(
359353
&self,
360-
fetcher: &dyn ManifestFetcher<Manifest = M>,
361354
source: &DerivationSource,
362355
proposal_timestamp: u64,
363-
) -> Result<M, DerivationError>
364-
where
365-
M: Send,
366-
{
356+
) -> Result<DerivationSourceManifest, DerivationError> {
367357
let hashes = derivation_source_to_blob_hashes(source);
368358
let offset = source.blobSlice.offset.to::<u64>() as usize;
369359
let timestamp = source.blobSlice.timestamp.to::<u64>();
@@ -373,8 +363,10 @@ where
373363
hash_count = hashes.len(),
374364
offset, timestamp, proposal_timestamp, max_blocks, "fetching manifest sidecars"
375365
);
376-
let manifest =
377-
fetcher.fetch_and_decode_manifest(timestamp, &hashes, offset, max_blocks).await?;
366+
let manifest = self
367+
.derivation_source_manifest_fetcher
368+
.fetch_and_decode_manifest(timestamp, &hashes, offset, max_blocks)
369+
.await?;
378370
Ok(manifest)
379371
}
380372

@@ -404,13 +396,7 @@ where
404396
let manifest = if !is_source_offset_valid(source) {
405397
DerivationSourceManifest::default()
406398
} else {
407-
let manifest = self
408-
.fetch_and_decode_manifest(
409-
self.derivation_source_manifest_fetcher.as_ref(),
410-
source,
411-
event.l1_timestamp,
412-
)
413-
.await?;
399+
let manifest = self.fetch_and_decode_manifest(source, event.l1_timestamp).await?;
414400
validate_forced_inclusion_manifest(proposal_id, source, manifest)
415401
};
416402
manifest_segments.push(SourceManifestSegment {
@@ -485,25 +471,15 @@ where
485471
}
486472
}
487473

488-
#[async_trait]
489-
impl<P> DerivationPipeline for ShastaDerivationPipeline<P>
474+
impl<P> ShastaDerivationPipeline<P>
490475
where
491476
P: Provider + Clone + Send + Sync + 'static,
492477
{
493-
type Manifest = ShastaProposalBundle;
494-
495-
// Convert a proposal log into a manifest for processing.
496-
#[instrument(skip(self, log), name = "shasta_manifest_from_log")]
497-
async fn log_to_manifest(&self, log: &Log) -> Result<Self::Manifest, DerivationError> {
498-
let event = self.decode_log_to_event_context(log).await?;
499-
self.event_to_manifest(&event).await
500-
}
501-
502-
// Convert a manifest into execution engine blocks for block production.
478+
/// Convert a manifest into execution engine blocks for block production.
503479
#[instrument(skip(self, manifest, applier), name = "shasta_manifest_to_blocks")]
504480
async fn manifest_to_engine_blocks(
505481
&self,
506-
manifest: Self::Manifest,
482+
manifest: ShastaProposalBundle,
507483
applier: &(dyn PayloadApplier + Send + Sync),
508484
) -> Result<Vec<EngineBlockOutcome>, DerivationError> {
509485
let ShastaProposalBundle { meta, sources, .. } = manifest;
@@ -549,8 +525,10 @@ where
549525
Ok(outcomes)
550526
}
551527

528+
/// Process the provided proposal log, materialising the derived blocks in the execution
529+
/// engine.
552530
#[instrument(skip(self, log, applier), name = "shasta_process_proposal")]
553-
async fn process_proposal(
531+
pub async fn process_proposal(
554532
&self,
555533
log: &Log,
556534
applier: &(dyn PayloadApplier + Send + Sync),
@@ -823,9 +801,7 @@ mod tests {
823801
let pipeline = ShastaDerivationPipeline {
824802
rpc: client,
825803
anchor_constructor,
826-
derivation_source_manifest_fetcher: Arc::new(ShastaSourceManifestFetcher::new(
827-
blob_source,
828-
)),
804+
derivation_source_manifest_fetcher: ShastaSourceManifestFetcher::new(blob_source),
829805
shasta_fork_timestamp: 0,
830806
min_base_fee_to_clamp: min_base_fee_for_chain(TAIKO_MAINNET_CHAIN_ID),
831807
chain_id: TAIKO_MAINNET_CHAIN_ID,

0 commit comments

Comments
 (0)