MCPcopy Create free account
hub / github.com/base/base / step

Method step

crates/batcher/encoder/src/encoder.rs:551–689  ·  view source on GitHub ↗
(&mut self)

Source from the content-addressed store, hash-verified

549 }
550
551 fn step(&mut self) -> Result<StepResult, StepError> {
552 if let Some(error) = self.deferred_step_error.take() {
553 return Err(error);
554 }
555
556 // Check for channel timeout first.
557 if self.check_channel_timeout()? {
558 return Ok(StepResult::ChannelClosed);
559 }
560
561 // If there are no blocks to encode, we're idle.
562 if self.block_cursor >= self.blocks.len() {
563 if self.config.batch_type == BatchType::Span
564 && let Some(max_blocks_per_span_batch) = self.config.max_blocks_per_span_batch
565 && self.span_accumulator.len() >= max_blocks_per_span_batch
566 {
567 if !self.try_flush_span_or_close("size_full")? {
568 return Ok(StepResult::ChannelClosed);
569 }
570 return Ok(StepResult::SpanFlushed);
571 }
572
573 return Ok(StepResult::Idle);
574 }
575
576 // Get the block at the cursor.
577 let block = &self.blocks[self.block_cursor];
578 let block_da_backlog_bytes = Self::block_da_backlog_bytes(block);
579
580 // Convert block to a SingleBatch. Failure here is fatal: skipping the block
581 // would produce a gap in the L2 block sequence submitted to L1.
582 let (single_batch, l1_info) = BatchComposer::block_to_single_batch(block)
583 .map_err(|source| StepError::CompositionFailed { cursor: self.block_cursor, source })?;
584
585 match self.config.batch_type {
586 BatchType::Span => {
587 // In Span mode blocks are accumulated in memory; the span batch is
588 // written to the channel only when a span-batch or channel boundary is reached.
589 let seq_num = l1_info.sequence_number();
590 // Maintain a running byte counter so the size check below is O(1) per
591 // step rather than O(N·M) over the entire accumulator.
592 let block_raw_bytes = Self::SPAN_BATCH_PER_BLOCK_OVERHEAD
593 + single_batch.transactions.iter().map(|tx| tx.len()).sum::<usize>();
594 self.span_raw_bytes += block_raw_bytes;
595 self.span_da_backlog_bytes += block_da_backlog_bytes;
596 self.span_accumulator.push((single_batch, seq_num));
597 self.block_cursor += 1;
598
599 // Track the L1 head at which the first block of this span was accumulated.
600 // `check_channel_timeout()` uses this to detect when the span has been open
601 // too long even though `current_channel` is None between flushes.
602 if self.span_opened_at_l1.is_none() {
603 self.span_opened_at_l1 = Some(self.l1_head);
604 }
605
606 // Estimate the compressed size of the accumulated span batch and close
607 // the channel when it would exceed the configured size budget. This mirrors
608 // the reference batcher's `SpanChannelOut`, which triggers closure based on estimated

Calls 13

check_channel_timeoutMethod · 0.80
close_current_channelMethod · 0.80
open_new_channelMethod · 0.80
as_mutMethod · 0.80
input_bytesMethod · 0.80
takeMethod · 0.45
lenMethod · 0.45
sequence_numberMethod · 0.45
iterMethod · 0.45
pushMethod · 0.45
add_batchMethod · 0.45