Skip to content

refactor(ethexe-consensus): fix some bad places in batch aggregation logic#5366

Open
grishasobol wants to merge 10 commits intomasterfrom
gsobol/ethexe/batch-fix
Open

refactor(ethexe-consensus): fix some bad places in batch aggregation logic#5366
grishasobol wants to merge 10 commits intomasterfrom
gsobol/ethexe/batch-fix

Conversation

@grishasobol
Copy link
Copy Markdown
Member

No description provided.

@semanticdiff-com
Copy link
Copy Markdown

semanticdiff-com Bot commented Apr 21, 2026

@grishasobol grishasobol added the D8-ethexe ethexe-related PR label Apr 21, 2026
@grishasobol grishasobol self-assigned this Apr 21, 2026
grishasobol and others added 8 commits April 21, 2026 12:23
Mirror the shape of aggregate_chain_commitment — caller hands in the
batch filler and the helper takes care of fetching the codes queue,
wrapping each validated code as a commitment, and stopping when the
filler rejects further entries.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…struct

The BatchFiller trait and BatchFillerNoLimits unlimited impl were
introduced speculatively — in practice every caller wants the size
budget, so drop the abstraction and keep only the concrete struct,
renamed from BatchFillerLimiter back to BatchFiller.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- aggregate_code_commitments_for_block: happy path skips pending codes;
  missing codes queue surfaces as an error.
- BatchFiller: size budget rejects commitments once exhausted;
  include_chain_commitment merges transitions and advances head.
- validate_chain_commitment: HeadAnnounceNotComputed rejection path
  (the branch that fired when a peer races an announce ahead of local
  execution).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Both aggregate_chain_commitment and validate_chain_commitment walked
parent pointers into a chronologically-ordered VecDeque. Fold that
into one utility so the two sides can't drift apart on traversal
semantics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@grishasobol grishasobol changed the title fix(ethexe-consensus): fix problems with empty committing refactor(ethexe-consensus): fix some bad places in batch aggregation logic Apr 21, 2026
@grishasobol grishasobol marked this pull request as ready for review April 21, 2026 11:37
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request refactors the batch aggregation logic within the ethexe consensus module. The primary goal is to optimize batch creation by avoiding unnecessary on-chain commitments for empty batches while ensuring that chain commitments are still submitted when the chain deepness threshold is exceeded. It introduces a centralized configuration structure, improves the validation of chain and code commitments, and adds regression tests to verify the new skip-commit behavior.

Highlights

  • Batch Aggregation Logic Refactoring: Refactored batch aggregation logic to improve efficiency and correctness, including the introduction of BatchManagerConfig to centralize configuration.
  • Skip Empty Batch Commits: Implemented logic to skip batch commitments when all parts are empty and the chain deepness threshold has not been reached, reducing unnecessary on-chain activity.
  • Improved Chain Commitment Validation: Enhanced chain commitment validation by correctly collecting pending announces and ensuring the validator mirrors the producer's outcome collection.
  • Code Commitment Aggregation: Streamlined code commitment aggregation to skip non-validated codes and stop processing when size limits are reached.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@grishasobol grishasobol added the A0-pleasereview PR is ready to be reviewed by the team label Apr 21, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request refactors the batch commitment logic within ethexe-consensus, simplifying the BatchFiller and centralizing commitment aggregation and validation. Key changes include renaming BatchLimits to BatchManagerConfig, introducing logic to skip batch creation for short empty chains to reduce on-chain noise, and improving error reporting using anyhow contexts. Feedback suggests enhancing robustness by replacing expect calls with proper error handling in utility functions and adding iteration limits to prevent potential infinite loops when traversing the announce chain.

Comment on lines +150 to +156
debug_assert_eq!(
db.announce(head_announce_hash)
.expect("Announce not found")
.block_hash,
at_block,
"Head announce is not from `at_block`"
);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Avoid using expect for error handling. If an operation can fail, prefer returning a Result and handle the error at the call site. While this is used within a debug assertion, using expect in a library-like utility can be risky if the state is not truly unreachable.

References
  1. Avoid using expect for error handling. If an operation can fail, prefer returning a Result and handle the error at the call site.

Comment on lines +34 to 49
pub fn collect_pending_announces<DB: AnnounceStorageRO>(
db: &DB,
head_announce_hash: HashOf<Announce>,
last_committed_announce_hash: HashOf<Announce>,
announce_hash: HashOf<Announce>,
) -> Result<Vec<HashOf<Announce>>> {
let mut announces = Vec::new();
let mut current_announce = announce_hash;

// Maybe remove this loop to prevent infinite searching
while current_announce != last_committed_announce_hash {
if !db.announce_meta(current_announce).computed {
// All announces till last committed must be computed.
// Even fast-sync guarantees that.
bail!("Not computed announce in chain {current_announce:?}")
}

announces.push(current_announce);
current_announce = db
.announce(current_announce)
.ok_or_else(|| anyhow!("Computed announce {current_announce:?} body not found in db"))?
) -> Result<VecDeque<HashOf<Announce>>> {
let mut announces = VecDeque::new();
let mut current = head_announce_hash;
while current != last_committed_announce_hash {
announces.push_front(current);
current = db
.announce(current)
.with_context(|| format!("Announce {current:?} not found in db"))?
.parent;
}

Ok(announces.into_iter().rev().collect())
Ok(announces)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The loop while current != last_committed_announce_hash in collect_pending_announces could theoretically be infinite if the chain is broken or if last_committed_announce_hash is not an ancestor of head_announce_hash. Although the blockchain structure (hashes) should prevent cycles, adding a safety limit on the number of iterations (e.g., based on a maximum expected chain depth) would make this more robust against database corruption or unexpected states.

@grishasobol grishasobol added A3-gotissues PR occurred to have issues after the review and removed A0-pleasereview PR is ready to be reviewed by the team labels Apr 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A3-gotissues PR occurred to have issues after the review D8-ethexe ethexe-related PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant