Builds the payload on top of the state.
(
self,
db: impl Database<Error = ProviderError>,
state_provider: impl StateProvider,
ctx: BasePayloadBuilderCtx<Evm, ChainSpec, Attrs>,
)
| 328 | impl<Txs> Builder<'_, Txs> { |
| 329 | /// Builds the payload on top of the state. |
| 330 | pub fn build<Evm, ChainSpec, N, Attrs>( |
| 331 | self, |
| 332 | db: impl Database<Error = ProviderError>, |
| 333 | state_provider: impl StateProvider, |
| 334 | ctx: BasePayloadBuilderCtx<Evm, ChainSpec, Attrs>, |
| 335 | ) -> Result<BuildOutcomeKind<BaseBuiltPayload<N>>, PayloadBuilderError> |
| 336 | where |
| 337 | Evm: ConfigureEvm< |
| 338 | Primitives = N, |
| 339 | NextBlockEnvCtx: BuildNextEnv<Attrs, N::BlockHeader, ChainSpec>, |
| 340 | >, |
| 341 | ChainSpec: EthChainSpec + Upgrades, |
| 342 | N: PayloadPrimitives, |
| 343 | Txs: PayloadTransactions< |
| 344 | Transaction: PoolTransaction<Consensus = N::SignedTx> + BasePooledTx, |
| 345 | >, |
| 346 | Attrs: Attributes<Transaction = N::SignedTx>, |
| 347 | { |
| 348 | let Self { best } = self; |
| 349 | debug!(target: "payload_builder", id=%ctx.payload_id(), parent_header = ?ctx.parent().hash(), parent_number = ctx.parent().number(), "building new payload"); |
| 350 | |
| 351 | let mut db = State::builder().with_database(db).with_bundle_update().build(); |
| 352 | |
| 353 | // Load the L1 block contract into the database cache. If the L1 block contract is not |
| 354 | // pre-loaded the database will panic when trying to fetch the DA footprint gas |
| 355 | // scalar. |
| 356 | db.load_cache_account(Predeploys::L1_BLOCK_INFO).map_err(BlockExecutionError::other)?; |
| 357 | |
| 358 | let mut builder = ctx.block_builder(&mut db)?; |
| 359 | |
| 360 | // 1. apply pre-execution changes |
| 361 | builder.apply_pre_execution_changes().map_err(|err| { |
| 362 | warn!(target: "payload_builder", %err, "failed to apply pre-execution changes"); |
| 363 | PayloadBuilderError::Internal(err.into()) |
| 364 | })?; |
| 365 | |
| 366 | // 2. execute sequencer transactions |
| 367 | let mut info = ctx.execute_sequencer_transactions(&mut builder)?; |
| 368 | |
| 369 | // 3. if mem pool transactions are requested we execute them |
| 370 | if !ctx.attributes().no_tx_pool() { |
| 371 | let best_txs = best(ctx.best_transaction_attributes(builder.evm_mut().block())); |
| 372 | if ctx.execute_best_transactions(&mut info, &mut builder, best_txs)?.is_some() { |
| 373 | return Ok(BuildOutcomeKind::Cancelled); |
| 374 | } |
| 375 | |
| 376 | // check if the new payload is even more valuable |
| 377 | if !ctx.is_better_payload(info.total_fees) { |
| 378 | // can skip building the block |
| 379 | return Ok(BuildOutcomeKind::Aborted { fees: info.total_fees }); |
| 380 | } |
| 381 | } |
| 382 | |
| 383 | let block_num = ctx.parent().number().saturating_add(1); |
| 384 | let BlockBuilderOutcome { |
| 385 | execution_result, |
| 386 | hashed_state, |
| 387 | trie_updates, |
no test coverage detected