(
&self,
prev_pending_blocks: Option<Arc<PendingBlocks>>,
flashblocks: &[Flashblock],
)
| 685 | |
| 686 | #[instrument(level = "debug", skip_all, fields(num_flashblocks = flashblocks.len()))] |
| 687 | fn build_pending_state( |
| 688 | &self, |
| 689 | prev_pending_blocks: Option<Arc<PendingBlocks>>, |
| 690 | flashblocks: &[Flashblock], |
| 691 | ) -> Result<Option<Arc<PendingBlocks>>> { |
| 692 | // BTreeMap guarantees ascending order of keys while iterating |
| 693 | let mut flashblocks_per_block = BTreeMap::<BlockNumber, Vec<Flashblock>>::new(); |
| 694 | for flashblock in flashblocks { |
| 695 | flashblocks_per_block |
| 696 | .entry(flashblock.metadata.block_number) |
| 697 | .or_default() |
| 698 | .push(flashblock.clone()); |
| 699 | } |
| 700 | |
| 701 | let earliest_block_number = flashblocks_per_block.keys().min().unwrap(); |
| 702 | let canonical_block = earliest_block_number - 1; |
| 703 | let mut last_block_header = self |
| 704 | .client |
| 705 | .header_by_number(canonical_block) |
| 706 | .map_err(|e| ProviderError::StateProvider(e.to_string()))? |
| 707 | .ok_or(ProviderError::MissingCanonicalHeader { block_number: canonical_block })?; |
| 708 | |
| 709 | let evm_config = BaseEvmConfig::base(self.client.chain_spec()); |
| 710 | let state_provider = self |
| 711 | .client |
| 712 | .state_by_block_number_or_tag(BlockNumberOrTag::Number(canonical_block)) |
| 713 | .map_err(|e| ProviderError::StateProvider(e.to_string()))?; |
| 714 | let state_provider_db = StateProviderDatabase::new(state_provider); |
| 715 | let mut pending_blocks_builder = PendingBlocksBuilder::new(); |
| 716 | |
| 717 | // Track state changes across flashblocks, accumulating bundle state |
| 718 | // from previous pending blocks if available. |
| 719 | let mut db = State::builder().with_database(state_provider_db).with_bundle_update().build(); |
| 720 | |
| 721 | let mut state_overrides = |
| 722 | prev_pending_blocks.as_ref().map_or_else(StateOverride::default, |pending_blocks| { |
| 723 | pending_blocks.get_state_overrides().unwrap_or_default() |
| 724 | }); |
| 725 | |
| 726 | let mut total_transaction_count = 0usize; |
| 727 | for (_block_number, flashblocks) in flashblocks_per_block { |
| 728 | // Use BlockAssembler to reconstruct the block from flashblocks |
| 729 | let assembled = BlockAssembler::assemble(&flashblocks)?; |
| 730 | let latest_flashblock_tx_count = |
| 731 | flashblocks.last().map(|latest| latest.diff.transactions.len()).unwrap_or_default(); |
| 732 | let latest_block_base = assembled.base.clone(); |
| 733 | |
| 734 | pending_blocks_builder.with_flashblocks(assembled.flashblocks.clone()); |
| 735 | pending_blocks_builder.with_header(assembled.header.clone()); |
| 736 | |
| 737 | // Extract L1 block info using the AssembledBlock method |
| 738 | let l1_block_info = assembled.l1_block_info()?; |
| 739 | let latest_block_l1_block_info = l1_block_info.clone(); |
| 740 | let latest_block_transaction_count = assembled.block.body.transactions.len(); |
| 741 | |
| 742 | let block_env_attributes = BaseNextBlockEnvAttributes { |
| 743 | timestamp: assembled.base.timestamp, |
| 744 | suggested_fee_recipient: assembled.base.fee_recipient, |
no test coverage detected