@@ -19,6 +19,7 @@ use op_alloy_consensus::{OpDepositReceipt, OpTypedTransaction};
19
19
use reth:: builder:: { components:: PayloadServiceBuilder , node:: FullNodeTypes , BuilderContext } ;
20
20
use reth:: core:: primitives:: InMemorySize ;
21
21
use reth:: payload:: PayloadBuilderHandle ;
22
+ use reth:: tasks:: { TaskExecutor , TaskSpawner } ;
22
23
use reth_basic_payload_builder:: {
23
24
BasicPayloadJobGeneratorConfig , BuildOutcome , BuildOutcomeKind , PayloadConfig ,
24
25
} ;
@@ -73,6 +74,7 @@ use revm::{
73
74
} ;
74
75
use std:: error:: Error as StdError ;
75
76
use std:: { fmt:: Display , sync:: Arc , time:: Instant } ;
77
+ use tokio:: sync:: oneshot;
76
78
use tokio_util:: sync:: CancellationToken ;
77
79
use tracing:: { info, trace, warn} ;
78
80
@@ -101,7 +103,8 @@ where
101
103
+ Unpin
102
104
+ ' static ,
103
105
{
104
- type PayloadBuilder = OpPayloadBuilderVanilla < Pool , Node :: Provider , OpEvmConfig , OpPrimitives > ;
106
+ type PayloadBuilder =
107
+ OpPayloadBuilderVanilla < Pool , Node :: Provider , OpEvmConfig , OpPrimitives , TaskExecutor > ;
105
108
106
109
async fn build_payload_builder (
107
110
& self ,
@@ -114,6 +117,7 @@ where
114
117
pool,
115
118
ctx. provider ( ) . clone ( ) ,
116
119
Arc :: new ( BasicOpReceiptBuilder :: default ( ) ) ,
120
+ ctx. task_executor ( ) . clone ( ) ,
117
121
) )
118
122
}
119
123
@@ -127,7 +131,6 @@ where
127
131
128
132
let payload_generator = BlockPayloadJobGenerator :: with_builder (
129
133
ctx. provider ( ) . clone ( ) ,
130
- ctx. task_executor ( ) . clone ( ) ,
131
134
payload_job_config,
132
135
payload_builder,
133
136
false ,
@@ -145,14 +148,15 @@ where
145
148
}
146
149
}
147
150
148
- impl < Pool , Client , EvmConfig , N , Txs > reth_basic_payload_builder:: PayloadBuilder
149
- for OpPayloadBuilderVanilla < Pool , Client , EvmConfig , N , Txs >
151
+ impl < Pool , Client , EvmConfig , N , Tasks , Txs > reth_basic_payload_builder:: PayloadBuilder
152
+ for OpPayloadBuilderVanilla < Pool , Client , EvmConfig , N , Tasks , Txs >
150
153
where
151
154
Pool : Clone + Send + Sync ,
152
155
Client : Clone + Send + Sync ,
153
156
EvmConfig : Clone + Send + Sync ,
154
157
N : NodePrimitives ,
155
158
Txs : Clone + Send + Sync ,
159
+ Tasks : TaskSpawner + Clone + Unpin + ' static ,
156
160
{
157
161
type Attributes = OpPayloadBuilderAttributes < N :: SignedTx > ;
158
162
type BuiltPayload = OpBuiltPayload < N > ;
@@ -177,7 +181,10 @@ where
177
181
178
182
/// Optimism's payload builder
179
183
#[ derive( Debug , Clone ) ]
180
- pub struct OpPayloadBuilderVanilla < Pool , Client , EvmConfig , N : NodePrimitives , Txs = ( ) > {
184
+ pub struct OpPayloadBuilderVanilla < Pool , Client , EvmConfig , N : NodePrimitives , Tasks , Txs = ( ) >
185
+ where
186
+ Tasks : TaskSpawner + Clone + Unpin + ' static ,
187
+ {
181
188
/// The type responsible for creating the evm.
182
189
pub evm_config : EvmConfig ,
183
190
/// The builder's signer key to use for an end of block tx
@@ -195,10 +202,14 @@ pub struct OpPayloadBuilderVanilla<Pool, Client, EvmConfig, N: NodePrimitives, T
195
202
pub metrics : OpRBuilderMetrics ,
196
203
/// Node primitive types.
197
204
pub receipt_builder : Arc < dyn OpReceiptBuilder < N :: SignedTx , Receipt = N :: Receipt > > ,
205
+ /// Executor to spawn tasks
206
+ pub executor : Tasks ,
198
207
}
199
208
200
- impl < Pool , Client , EvmConfig , N : NodePrimitives >
201
- OpPayloadBuilderVanilla < Pool , Client , EvmConfig , N >
209
+ impl < Pool , Client , EvmConfig , N : NodePrimitives , Tasks >
210
+ OpPayloadBuilderVanilla < Pool , Client , EvmConfig , N , Tasks >
211
+ where
212
+ Tasks : TaskSpawner + Clone + Unpin + ' static ,
202
213
{
203
214
/// `OpPayloadBuilder` constructor.
204
215
pub fn new (
@@ -207,13 +218,15 @@ impl<Pool, Client, EvmConfig, N: NodePrimitives>
207
218
pool : Pool ,
208
219
client : Client ,
209
220
receipt_builder : Arc < dyn OpReceiptBuilder < N :: SignedTx , Receipt = N :: Receipt > > ,
221
+ executor : Tasks ,
210
222
) -> Self {
211
223
Self :: with_builder_config (
212
224
evm_config,
213
225
builder_signer,
214
226
pool,
215
227
client,
216
228
receipt_builder,
229
+ executor,
217
230
Default :: default ( ) ,
218
231
)
219
232
}
@@ -224,6 +237,7 @@ impl<Pool, Client, EvmConfig, N: NodePrimitives>
224
237
pool : Pool ,
225
238
client : Client ,
226
239
receipt_builder : Arc < dyn OpReceiptBuilder < N :: SignedTx , Receipt = N :: Receipt > > ,
240
+ executor : Tasks ,
227
241
config : OpBuilderConfig ,
228
242
) -> Self {
229
243
Self {
@@ -235,18 +249,23 @@ impl<Pool, Client, EvmConfig, N: NodePrimitives>
235
249
best_transactions : ( ) ,
236
250
metrics : Default :: default ( ) ,
237
251
builder_signer,
252
+ executor,
238
253
}
239
254
}
240
255
}
241
256
242
- impl < EvmConfig , Pool , Client , N , Txs > PayloadBuilder
243
- for OpPayloadBuilderVanilla < Pool , Client , EvmConfig , N , Txs >
257
+ impl < EvmConfig , Pool , Client , N , Tasks , Txs > PayloadBuilder
258
+ for OpPayloadBuilderVanilla < Pool , Client , EvmConfig , N , Tasks , Txs >
244
259
where
245
- Client : StateProviderFactory + ChainSpecProvider < ChainSpec : EthChainSpec + OpHardforks > + Clone ,
260
+ Client : StateProviderFactory
261
+ + ChainSpecProvider < ChainSpec : EthChainSpec + OpHardforks >
262
+ + Clone
263
+ + ' static ,
246
264
N : OpPayloadPrimitives < _TX = OpTransactionSigned > ,
247
- Pool : TransactionPool < Transaction : PoolTransaction < Consensus = N :: SignedTx > > ,
265
+ Pool : TransactionPool < Transaction : PoolTransaction < Consensus = N :: SignedTx > > + ' static ,
248
266
EvmConfig : ConfigureEvmFor < N > ,
249
267
Txs : OpPayloadTransactions < Pool :: Transaction > ,
268
+ Tasks : TaskSpawner + Clone + Unpin + ' static ,
250
269
{
251
270
type Attributes = OpPayloadBuilderAttributes < N :: SignedTx > ;
252
271
type BuiltPayload = OpBuiltPayload < N > ;
@@ -258,44 +277,56 @@ where
258
277
) -> Result < ( ) , PayloadBuilderError > {
259
278
let pool = self . pool . clone ( ) ;
260
279
let block_build_start_time = Instant :: now ( ) ;
261
-
262
- match self . build_payload ( args, |attrs| {
263
- #[ allow( clippy:: unit_arg) ]
264
- self . best_transactions . best_transactions ( pool, attrs)
265
- } ) ? {
266
- BuildOutcome :: Better { payload, .. } => {
267
- best_payload. set ( payload) ;
268
- self . metrics
269
- . total_block_built_duration
270
- . record ( block_build_start_time. elapsed ( ) ) ;
271
- self . metrics . block_built_success . increment ( 1 ) ;
272
- Ok ( ( ) )
273
- }
274
- BuildOutcome :: Freeze ( payload) => {
275
- best_payload. set ( payload) ;
276
- self . metrics
277
- . total_block_built_duration
278
- . record ( block_build_start_time. elapsed ( ) ) ;
279
- Ok ( ( ) )
280
- }
281
- BuildOutcome :: Cancelled => {
282
- tracing:: warn!( "Payload build cancelled" ) ;
283
- Err ( PayloadBuilderError :: MissingPayload )
284
- }
285
- _ => {
286
- tracing:: warn!( "No better payload found" ) ;
287
- Err ( PayloadBuilderError :: MissingPayload )
280
+ let ( tx, rx) = oneshot:: channel ( ) ;
281
+ let ctx = self . clone ( ) ;
282
+ self . executor . spawn_blocking ( Box :: pin ( async move {
283
+ match ctx. build_payload ( args, |attrs| {
284
+ #[ allow( clippy:: unit_arg) ]
285
+ ctx. best_transactions . best_transactions ( pool, attrs)
286
+ } ) {
287
+ Ok ( BuildOutcome :: Better { payload, .. } ) => {
288
+ best_payload. set ( payload) ;
289
+ ctx. metrics
290
+ . total_block_built_duration
291
+ . record ( block_build_start_time. elapsed ( ) ) ;
292
+ ctx. metrics . block_built_success . increment ( 1 ) ;
293
+ let _ = tx. send ( Ok ( ( ) ) ) ;
294
+ }
295
+ Ok ( BuildOutcome :: Freeze ( payload) ) => {
296
+ best_payload. set ( payload) ;
297
+ ctx. metrics
298
+ . total_block_built_duration
299
+ . record ( block_build_start_time. elapsed ( ) ) ;
300
+ let _ = tx. send ( Ok ( ( ) ) ) ;
301
+ }
302
+ Ok ( BuildOutcome :: Cancelled ) => {
303
+ tracing:: warn!( "Payload build cancelled" ) ;
304
+ let _ = tx. send ( Err ( PayloadBuilderError :: MissingPayload ) ) ;
305
+ }
306
+ Ok ( _) => {
307
+ tracing:: warn!( "No better payload found" ) ;
308
+ let _ = tx. send ( Err ( PayloadBuilderError :: MissingPayload ) ) ;
309
+ }
310
+ Err ( err) => {
311
+ tracing:: warn!( "Build payload error {}" , err) ;
312
+ let _ = tx. send ( Err ( err) ) ;
313
+ }
288
314
}
289
- }
315
+ } ) ) ;
316
+ rx. blocking_recv ( )
317
+ . map_err ( |err| PayloadBuilderError :: from ( err) ) ?
290
318
}
291
319
}
292
320
293
- impl < Pool , Client , EvmConfig , N , T > OpPayloadBuilderVanilla < Pool , Client , EvmConfig , N , T >
321
+ impl < Pool , Client , EvmConfig , N , Tasks , T >
322
+ OpPayloadBuilderVanilla < Pool , Client , EvmConfig , N , Tasks , T >
294
323
where
295
- Pool : TransactionPool < Transaction : PoolTransaction < Consensus = N :: SignedTx > > ,
296
- Client : StateProviderFactory + ChainSpecProvider < ChainSpec : EthChainSpec + OpHardforks > ,
324
+ Pool : TransactionPool < Transaction : PoolTransaction < Consensus = N :: SignedTx > > + ' static ,
325
+ Client :
326
+ StateProviderFactory + ChainSpecProvider < ChainSpec : EthChainSpec + OpHardforks > + ' static ,
297
327
N : OpPayloadPrimitives < _TX = OpTransactionSigned > ,
298
328
EvmConfig : ConfigureEvmFor < N > ,
329
+ Tasks : TaskSpawner + Clone + Unpin + ' static ,
299
330
{
300
331
/// Constructs an Optimism payload from the transactions sent via the
301
332
/// Payload attributes by the sequencer. If the `no_tx_pool` argument is passed in
0 commit comments