11use alloy:: {
22 consensus:: SidecarBuilder ,
3+ eips:: eip7594:: BlobTransactionSidecarEip7594 ,
34 network:: { TransactionBuilder , TransactionBuilder7594 } ,
45 primitives:: {
56 Address , Bytes ,
@@ -12,36 +13,91 @@ use alloy_json_rpc::RpcError;
1213use anyhow:: { Context , Error } ;
1314use common:: l1:: { fees_per_gas:: FeesPerGas , tools, transaction_error:: TransactionError } ;
1415use common:: shared:: l2_block_v2:: L2BlockV2 ;
16+ use common:: shared:: transaction_monitor:: TransactionRequestBuilder ;
1517use taiko_bindings:: inbox:: { IInbox :: ProposeInput , Inbox , LibBlobs :: BlobReference } ;
1618use taiko_protocol:: shasta:: {
1719 BlobCoder ,
1820 manifest:: { BlockManifest , DerivationSourceManifest } ,
1921} ;
20- use tracing:: warn;
22+ use tracing:: { info, warn} ;
23+
24+ /// Build the EIP-7594 blob sidecar from L2 blocks. This is a CPU-intensive operation
25+ /// (KZG commitment + cell proof computation).
26+ fn build_sidecar_from_l2_blocks (
27+ l2_blocks : & [ L2BlockV2 ] ,
28+ ) -> Result < BlobTransactionSidecarEip7594 , Error > {
29+ let start = std:: time:: Instant :: now ( ) ;
30+
31+ let mut block_manifests = Vec :: with_capacity ( l2_blocks. len ( ) ) ;
32+ for l2_block in l2_blocks {
33+ block_manifests. push ( BlockManifest {
34+ timestamp : l2_block. timestamp_sec ,
35+ coinbase : l2_block. coinbase ,
36+ anchor_block_number : l2_block. anchor_block_number ,
37+ gas_limit : l2_block. gas_limit_without_anchor ,
38+ transactions : l2_block
39+ . prebuilt_tx_list
40+ . tx_list
41+ . iter ( )
42+ . map ( |tx| tx. clone ( ) . into ( ) )
43+ . collect ( ) ,
44+ } ) ;
45+ }
46+
47+ let manifest = DerivationSourceManifest {
48+ blocks : block_manifests,
49+ } ;
50+
51+ let manifest_data = manifest
52+ . encode_and_compress ( )
53+ . map_err ( |e| Error :: msg ( format ! ( "Can't encode and compress manifest: {e}" ) ) ) ?;
54+
55+ let sidecar_builder: SidecarBuilder < BlobCoder > = SidecarBuilder :: from_slice ( & manifest_data) ;
56+ let sidecar = sidecar_builder
57+ . build_7594 ( )
58+ . map_err ( |e| Error :: msg ( format ! ( "sidecar builder build_7594 failed: {e}" ) ) ) ?;
59+
60+ info ! (
61+ "⏱️ build_sidecar_from_l2_blocks ({} blocks, {} bytes compressed) took {:?}" ,
62+ l2_blocks. len( ) ,
63+ manifest_data. len( ) ,
64+ start. elapsed( )
65+ ) ;
66+
67+ Ok ( sidecar)
68+ }
2169
2270pub struct ProposalTxBuilder {
2371 provider : DynProvider ,
2472 extra_gas_percentage : u64 ,
73+ l2_blocks : Vec < L2BlockV2 > ,
74+ from : Address ,
75+ to : Address ,
76+ num_forced_inclusion : u16 ,
2577}
2678
2779impl ProposalTxBuilder {
28- pub fn new ( provider : DynProvider , extra_gas_percentage : u64 ) -> Self {
80+ pub fn new (
81+ provider : DynProvider ,
82+ extra_gas_percentage : u64 ,
83+ l2_blocks : Vec < L2BlockV2 > ,
84+ from : Address ,
85+ to : Address ,
86+ num_forced_inclusion : u16 ,
87+ ) -> Self {
2988 Self {
3089 provider,
3190 extra_gas_percentage,
91+ l2_blocks,
92+ from,
93+ to,
94+ num_forced_inclusion,
3295 }
3396 }
3497
35- #[ allow( clippy:: too_many_arguments) ]
36- pub async fn build_propose_tx (
37- & self ,
38- l2_blocks : Vec < L2BlockV2 > ,
39- from : Address ,
40- to : Address ,
41- num_forced_inclusion : u16 ,
42- ) -> Result < TransactionRequest , Error > {
98+ async fn build_propose_tx ( & self ) -> Result < TransactionRequest , Error > {
4399 let tx_blob = self
44- . build_propose_blob ( l2_blocks , from , to , num_forced_inclusion )
100+ . build_propose_blob ( )
45101 . await
46102 . map_err ( |e| Error :: msg ( format ! ( "build_propose_blob failed: {e}" ) ) ) ?;
47103 let tx_blob_gas = match self . provider . estimate_gas ( tx_blob. clone ( ) ) . await {
@@ -80,44 +136,8 @@ impl ProposalTxBuilder {
80136 Ok ( tx_blob)
81137 }
82138
83- #[ allow( clippy:: too_many_arguments) ]
84- pub async fn build_propose_blob (
85- & self ,
86- l2_blocks : Vec < L2BlockV2 > ,
87- from : Address ,
88- to : Address ,
89- num_forced_inclusion : u16 ,
90- ) -> Result < TransactionRequest , Error > {
91- let mut block_manifests = <Vec < BlockManifest > >:: with_capacity ( l2_blocks. len ( ) ) ;
92- for l2_block in & l2_blocks {
93- // Build the block manifests.
94- block_manifests. push ( BlockManifest {
95- timestamp : l2_block. timestamp_sec ,
96- coinbase : l2_block. coinbase ,
97- anchor_block_number : l2_block. anchor_block_number ,
98- gas_limit : l2_block. gas_limit_without_anchor ,
99- transactions : l2_block
100- . prebuilt_tx_list
101- . tx_list
102- . iter ( )
103- . map ( |tx| tx. clone ( ) . into ( ) )
104- . collect ( ) ,
105- } ) ;
106- }
107-
108- // Build the proposal manifest.
109- let manifest = DerivationSourceManifest {
110- blocks : block_manifests,
111- } ;
112-
113- let manifest_data = manifest
114- . encode_and_compress ( )
115- . map_err ( |e| Error :: msg ( format ! ( "Can't encode and compress manifest: {e}" ) ) ) ?;
116-
117- let sidecar_builder: SidecarBuilder < BlobCoder > = SidecarBuilder :: from_slice ( & manifest_data) ;
118- let sidecar = sidecar_builder
119- . build_7594 ( )
120- . map_err ( |e| Error :: msg ( format ! ( "sidecar builder build_7594 failed: {e}" ) ) ) ?;
139+ async fn build_propose_blob ( & self ) -> Result < TransactionRequest , Error > {
140+ let sidecar = build_sidecar_from_l2_blocks ( & self . l2_blocks ) ?;
121141
122142 // Build the propose input.
123143 let input = ProposeInput {
@@ -131,19 +151,19 @@ impl ProposalTxBuilder {
131151 . context ( "blobs len try_into" ) ?,
132152 offset : U24 :: ZERO ,
133153 } ,
134- numForcedInclusions : num_forced_inclusion,
154+ numForcedInclusions : self . num_forced_inclusion ,
135155 } ;
136156
137- let inbox = Inbox :: new ( to, self . provider . clone ( ) ) ;
157+ let inbox = Inbox :: new ( self . to , self . provider . clone ( ) ) ;
138158 let encoded_proposal_input = inbox
139159 . encodeProposeInput ( input)
140160 . call ( )
141161 . await
142162 . map_err ( |e| Error :: msg ( format ! ( "inbox encodeProposeInput failed: {e}" ) ) ) ?;
143163
144164 let tx = TransactionRequest :: default ( )
145- . with_from ( from)
146- . with_to ( to)
165+ . with_from ( self . from )
166+ . with_to ( self . to )
147167 . with_blob_sidecar ( sidecar)
148168 . with_call ( & Inbox :: proposeCall {
149169 _lookahead : Bytes :: new ( ) ,
@@ -153,3 +173,12 @@ impl ProposalTxBuilder {
153173 Ok ( tx)
154174 }
155175}
176+
177+ impl TransactionRequestBuilder for ProposalTxBuilder {
178+ async fn build ( self ) -> Result < TransactionRequest , TransactionError > {
179+ self . build_propose_tx ( ) . await . map_err ( |e| {
180+ e. downcast :: < TransactionError > ( )
181+ . unwrap_or ( TransactionError :: BuildFailed )
182+ } )
183+ }
184+ }
0 commit comments