(
&self,
prev_pending_blocks: Option<Arc<PendingBlocks>>,
flashblocks: &[Flashblock],
)
| 834 | |
| 835 | #[instrument(level = "debug", skip_all, fields(num_flashblocks = flashblocks.len()))] |
| 836 | fn build_pending_state( |
| 837 | &self, |
| 838 | prev_pending_blocks: Option<Arc<PendingBlocks>>, |
| 839 | flashblocks: &[Flashblock], |
| 840 | ) -> Result<Option<Arc<PendingBlocks>>> { |
| 841 | // BTreeMap guarantees ascending order of keys while iterating |
| 842 | let mut flashblocks_per_block = BTreeMap::<BlockNumber, Vec<Flashblock>>::new(); |
| 843 | for flashblock in flashblocks { |
| 844 | flashblocks_per_block |
| 845 | .entry(flashblock.metadata.block_number) |
| 846 | .or_default() |
| 847 | .push(flashblock.clone()); |
| 848 | } |
| 849 | |
| 850 | let Some((&earliest_block_number, _)) = flashblocks_per_block.first_key_value() else { |
| 851 | self.clear_live_state(); |
| 852 | return Ok(None); |
| 853 | }; |
| 854 | let canonical_block = |
| 855 | earliest_block_number.checked_sub(1).ok_or(ProtocolError::GenesisFlashblock)?; |
| 856 | let mut last_block_header = self |
| 857 | .client |
| 858 | .header_by_number(canonical_block) |
| 859 | .map_err(|e| ProviderError::StateProvider(e.to_string()))? |
| 860 | .ok_or(ProviderError::MissingCanonicalHeader { block_number: canonical_block })?; |
| 861 | |
| 862 | let evm_config = BaseEvmConfig::base(self.client.chain_spec()); |
| 863 | let state_provider = self |
| 864 | .client |
| 865 | .state_by_block_number_or_tag(BlockNumberOrTag::Number(canonical_block)) |
| 866 | .map_err(|e| ProviderError::StateProvider(e.to_string()))?; |
| 867 | let state_provider_db = StateProviderDatabase::new(state_provider); |
| 868 | let mut pending_blocks_builder = PendingBlocksBuilder::new(); |
| 869 | |
| 870 | // Track state changes across flashblocks, accumulating bundle state |
| 871 | // from previous pending blocks if available. |
| 872 | let mut db = State::builder().with_database(state_provider_db).with_bundle_update().build(); |
| 873 | |
| 874 | let mut state_overrides = |
| 875 | prev_pending_blocks.as_ref().map_or_else(StateOverride::default, |pending_blocks| { |
| 876 | pending_blocks.get_state_overrides().unwrap_or_default() |
| 877 | }); |
| 878 | |
| 879 | let mut total_transaction_count = 0usize; |
| 880 | for (_block_number, flashblocks) in flashblocks_per_block { |
| 881 | // Use BlockAssembler to reconstruct the block from flashblocks |
| 882 | let assembled = BlockAssembler::assemble(&flashblocks)?; |
| 883 | let latest_flashblock_tx_count = |
| 884 | flashblocks.last().map(|latest| latest.diff.transactions.len()).unwrap_or_default(); |
| 885 | let latest_block_base = assembled.base.clone(); |
| 886 | |
| 887 | pending_blocks_builder.with_flashblocks(assembled.flashblocks.clone()); |
| 888 | pending_blocks_builder.with_header(assembled.header.clone()); |
| 889 | |
| 890 | // Extract L1 block info using the AssembledBlock method |
| 891 | let l1_block_info = assembled.l1_block_info()?; |
| 892 | let latest_block_l1_block_info = l1_block_info.clone(); |
| 893 | let latest_block_transaction_count = assembled.block.body.transactions.len(); |
no test coverage detected