Skip to content

Conversation

@randygrok
Copy link
Contributor

@randygrok randygrok commented May 21, 2025

Overview

Fixing IBC on Rollkit Post-Refactor

Following a refactor that extracted execution-specific code, Rollkit needs to operate without direct dependencies on underlying execution layers (e.g., CometBFT for ABCI). While this improves the design, it introduces challenges when Rollkit needs data or hashes whose generation logic is specific to the execution layer.

To address this, Rollkit relies on injected functions provided by the execution layer for implementation-specific operations.

Implementation-Specific Logic and Injected Providers

The following fields or computations require logic from the specific execution layer. This is managed by injecting provider functions:

Header Hash

The calculation of a block header's hash is implementation-dependent. Rollkit's Header type doesn't have a Hash() method (though it contains lastHeaderHash). To obtain the header hash without Rollkit depending directly on the execution layer's hashing logic, a HeaderHasher function is injected:

type HeaderHasher func(header *Header) (Hash, error)

This function is supplied by the execution layer and used by the manager when the header hash is needed.

Validator Hash

The SignedHeader.ValidatorHash is also specific to the execution layer. For instance, CometBFT generates this hash using its ValidatorSet primitive, which is unknown to Rollkit. An injected ValidatorHasher provides this:

type ValidatorHasher func(proposerAddress []byte, pubKey crypto.PubKey) (Hash, error)

SignaturePayloadProvider

The precise data payload that a private key signs for a commit can vary by execution layer. To handle this, a SignaturePayloadProvider is injected:

type SignaturePayloadProvider func(header *Header, data *Data) ([]byte, error)

CommitHashProvider

While the Rollkit Header includes a LastCommitHash, Rollkit itself doesn't know how to generate this hash, as the method is implementation-specific. A CommitHashProvider is injected for this purpose:

type CommitHashProvider func(signature *Signature, header *Header, proposerAddress []byte) (Hash, error)

Header Hash on ExecuteTxs

The original signature for ExecuteTxs in the execution layer interface did not provide a way to access the Header.Hash during transaction processing:

ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight uint64, timestamp time.Time, prevStateRoot []byte) (updatedStateRoot []byte, maxBytes uint64, err error)

Given that the header hash calculation is implementation-dependent, and the Header object itself was neither passed as an argument to ExecuteTxs nor finalized until after this function completed, retrieving the hash at this stage was not possible.

To address this, a metadata map[string]interface{} parameter was added to the ExecuteTxs signature. This serves as a mechanism for the execution layer to return necessary data, such as components required for the header hash or the hash itself, back to Rollkit:

ExecuteTxs(ctx context.Context, txs [][]byte, blockHeight uint64, timestamp time.Time, prevStateRoot []byte, metadata map[string]interface{}) (updatedStateRoot []byte, maxBytes uint64, err error)

While using a generic map means Rollkit might need to be aware of specific keys to retrieve arbitrary data (which is not strictly aligned with the Open/Closed Principle of SOLID), this approach was chosen as a pragmatic compromise to avoid over-engineering the solution solely for obtaining this field. A key benefit of this approach is the ability to return additional data fields in the future without changing the execution.ExecuteTxs interface signature, thereby avoiding breaking changes for other implementations.

Summary by CodeRabbit

  • New Features

    • Added support for customizable cryptographic utilities, allowing injection of custom hashing and signature payload providers.
    • The transaction execution interface now accepts additional metadata, enabling richer context during execution.
    • Improved configurability of node and block manager creation with new options for cryptographic operations.
    • Introduced default implementations for signature payload, commit hash, and validator hash providers used across components.
    • Added a new block protocol version constant aligned with CometBFT for compatibility.
  • Bug Fixes

    • Enhanced error handling and validation in block publishing and signature verification processes.
  • Refactor

    • Refactored block manager logic for better modularity, testability, and dependency injection.
    • Updated tests and mocks to accommodate new interfaces and improved cryptographic utilities.
    • Replaced mock-based tests with integration-style tests using real nodes and executors.
    • Improved signature validation by requiring signature payload providers in validation calls.
  • Chores

    • Updated dependencies and module replacements.
    • Improved Makefile targets for containerized code generation and mock creation.
    • Added autogenerated typed mocks for store and data availability interfaces.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented May 21, 2025

Walkthrough

This update introduces significant refactoring and extensibility to the block manager and execution layers. It adds dependency injection for cryptographic hashing and signature payload generation, updates the executor interface to accept metadata, and propagates these changes throughout the codebase and tests. Numerous mocks, tests, and helper functions are revised for compatibility, and new utilities for hashing and signature payloads are introduced.

Changes

File(s) Change Summary
block/manager.go, block/retriever.go, block/store_test.go, block/sync_test.go, block/manager_test.go, block/publish_block_test.go, block/publish_block2_test.go, block/retriever_test.go, block/da_includer_test.go Major refactor: block manager now supports dependency injection for validator hasher, signature payload provider, and commit hash provider; new helper methods for block data retrieval, modularized block publishing, and updated tests to match new interfaces.
core/execution/execution.go, core/execution/dummy.go, execution/evm/execution.go, apps/testapp/kv/kvexecutor.go, block/publish_block2_test.go, test/mocks/execution.go, apps/testapp/kv/http_server_test.go, apps/testapp/kv/kvexecutor_test.go, core/execution/dummy_test.go, node/execution_test.go, block/sync_test.go Executor interface and all implementations updated: ExecuteTxs now accepts an additional metadata parameter; all usages and tests updated accordingly.
types/hashing.go, types/utils.go, types/signer.go, types/metadata_keys.go, types/state.go New and updated cryptographic utility types and functions: header hasher, validator hasher, commit hash provider, signature payload provider, and associated default implementations; new metadata key; block version updated for IBC compatibility.
types/signed_header.go, types/signed_header_test.go SignedHeader.ValidateBasic now requires a signature payload provider; removed old Validate method; tests updated.
node/node.go, node/full.go, pkg/cmd/run_node.go Node and block manager constructors updated to accept variadic ManagerOption parameters for dependency injection.
node/helpers_test.go Test helpers updated to create and inject default cryptographic utility providers.
test/mocks/Store.go, test/mocks/store.go, test/mocks/da.go Mocks enhanced with typed expectation helpers and new autogenerated mock for Store.
apps/evm/based/go.mod, apps/evm/single/go.mod, execution/evm/go.mod, go.mod Module dependencies updated to latest internal versions; new local module replacement for DA.
scripts/proto.mk, scripts/utils.mk Protobuf and mock generation targets now use Docker for reproducibility and environment consistency.
apps/evm/based/cmd/run.go Removed an outdated comment regarding renamed imports.
core/da/dummy_test.go Added sleep to synchronize with block time in tests.

Sequence Diagram(s)

sequenceDiagram
    participant BlockManager
    participant Executor
    participant Hasher
    participant SignatureProvider

    BlockManager->>Hasher: Compute ValidatorHash/CommitHash
    BlockManager->>SignatureProvider: Get signature payload for header
    BlockManager->>BlockManager: Sign header and validate with payload provider
    BlockManager->>Executor: ExecuteTxs(ctx, txs, height, ts, prevRoot, metadata)
    Executor-->>BlockManager: updatedStateRoot, maxBytes, error
    BlockManager->>BlockManager: Apply block, update state, broadcast
Loading

Possibly related PRs

Suggested reviewers

  • Manav-Aggarwal
  • tac0turtle
  • pthmas

Poem

A rabbit hopped through fields of code,
With hashes, signatures, and tests bestowed.
Now blocks are signed with custom flair,
And metadata travels everywhere!
Mocks are smarter, nodes more spry,
Docker builds, and hashes fly—
Oh what a burrow, neat and new,
This patch brings magic, through and through! 🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (1.64.8)

Error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2
Failed executing command with error: you are using a configuration file for golangci-lint v2 with golangci-lint v1: please use golangci-lint v2


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb91837 and 2872be6.

📒 Files selected for processing (1)
  • block/manager.go (19 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: rollkit-docker / docker-build (GHCR; ghcr.io/rollkit/rollkit)
  • GitHub Check: test / Build All Rollkit Binaries
  • GitHub Check: test / Run Unit Tests
  • GitHub Check: test / Run EVM Execution Tests
  • GitHub Check: Analyze (go)
  • GitHub Check: Summary
🔇 Additional comments (13)
block/manager.go (13)

108-110: LGTM! Clean dependency injection design.

The addition of these provider fields follows good dependency injection principles and enables proper decoupling of cryptographic operations from the block manager.


175-197: LGTM! Well-implemented functional options pattern.

The functional options provide a clean and flexible way to configure the Manager's cryptographic providers. The implementation follows Go best practices.


307-307: LGTM! Constructor properly handles default initialization and options.

Good improvement over the previous nil initialization approach. Setting default implementations first, then applying options ensures safe defaults while maintaining configurability.

Also applies to: 372-372, 394-400, 421-424


501-503: LGTM! Minor readability improvement.

The extraction of dataHash calculation improves code readability without changing the logic.


554-554: LGTM! Consistent with signature payload provider pattern.

The update to use m.signaturePayloadProvider is necessary and consistent with the dependency injection refactor.


557-597: LGTM! Good refactoring for better code organization.

Extracting the block data retrieval logic into a separate method improves readability and maintainability of the publishBlockInternal method.


599-748: LGTM! Excellent refactoring that improves maintainability.

The refactoring of publishBlockInternal into smaller, focused helper methods significantly improves code readability and maintainability. Each method has a clear single responsibility and the overall flow is much easier to follow.


795-795: LGTM! Consistent with signature payload provider pattern.

The update maintains consistency with the dependency injection approach used throughout the refactor.


836-836: LGTM! Improved error messaging.

The more specific error message will help with debugging by providing better context about where the error occurred.


872-872: LGTM! Good improvement using named constant.

Using types.BlockProtocolVersion instead of a hardcoded value improves maintainability and addresses the previous review feedback.


885-885: LGTM! Proper assignment of calculated validator hash.

The assignment is consistent with the validator hash calculation logic implemented above.


926-930: LGTM! Proper metadata passing to ExecuteTxs.

The metadata preparation and passing to ExecuteTxs correctly implements the new interface that allows the execution layer to access the header hash during transaction processing.


1013-1019: LGTM! Good error handling pattern for provider usage.

The nil check for signaturePayloadProvider and appropriate error return demonstrates the correct pattern for provider usage. This could serve as a model for consistent error handling across all providers.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions
Copy link
Contributor

github-actions bot commented May 21, 2025

The latest Buf updates on your PR. Results from workflow CI and Release / buf-check (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed⏩ skipped✅ passed✅ passedJun 6, 2025, 10:34 PM

@tac0turtle
Copy link
Contributor

could you add a description to the pr with reasoning to the design?

@github-actions
Copy link
Contributor

PR Preview Action v1.6.1

🚀 View preview at
https://rollkit.github.io/rollkit/pr-preview/pr-2301/

Built to branch gh-pages at 2025-05-28 21:20 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (3)
block/manager.go (3)

851-861: Inconsistent error handling for missing validatorHasher.

The code logs and continues with a zero hash when validatorHasher is missing, while other providers (like signaturePayloadProvider) return errors. This inconsistency could lead to subtle bugs.


869-869: Avoid hardcoding block version.

The block version should not be hardcoded. Consider making this configurable or deriving it from the state/genesis configuration.


907-912: Add nil check for commitHashProvider.

The code assumes commitHashProvider is always available but doesn't validate this assumption, which could lead to a panic.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5e4aa31 and a54894a.

📒 Files selected for processing (11)
  • apps/evm/based/go.mod (1 hunks)
  • apps/evm/single/go.mod (1 hunks)
  • block/manager.go (19 hunks)
  • block/manager_test.go (5 hunks)
  • block/retriever.go (1 hunks)
  • block/retriever_test.go (1 hunks)
  • core/da/dummy_test.go (1 hunks)
  • core/execution/dummy_test.go (4 hunks)
  • go.mod (1 hunks)
  • node/full.go (4 hunks)
  • pkg/cmd/run_node.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (9)
  • go.mod
  • apps/evm/based/go.mod
  • pkg/cmd/run_node.go
  • apps/evm/single/go.mod
  • core/execution/dummy_test.go
  • core/da/dummy_test.go
  • block/retriever_test.go
  • block/manager_test.go
  • node/full.go
🧰 Additional context used
🧬 Code Graph Analysis (1)
block/manager.go (9)
types/hashing.go (2)
  • ValidatorHasher (64-64)
  • CommitHashProvider (78-78)
types/signer.go (1)
  • SignaturePayloadProvider (9-9)
core/sequencer/sequencing.go (1)
  • Batch (33-35)
types/header.go (2)
  • Hash (14-14)
  • Header (35-62)
types/signed_header.go (1)
  • SignedHeader (22-27)
types/block.go (3)
  • Data (33-36)
  • Signature (46-46)
  • Version (16-19)
block/errors.go (1)
  • ErrNoBatch (16-16)
types/utils.go (1)
  • GetSignature (293-299)
types/metadata_keys.go (1)
  • HeaderHashKey (5-5)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: test / Run Unit Tests
  • GitHub Check: Analyze (go)
  • GitHub Check: Summary
🔇 Additional comments (8)
block/retriever.go (1)

121-121: LGTM! Signature payload provider integration is correct.

The change correctly passes the injected signaturePayloadProvider to ValidateBasic, ensuring consistent signature validation with the new pluggable cryptographic provider design.

block/manager.go (7)

108-110: LGTM! Dependency injection fields are properly defined.

The new cryptographic provider fields enable flexible injection of hashing and signature logic, improving modularity and testability.


175-197: LGTM! Clean functional options pattern implementation.

The ManagerOption pattern provides a clean and extensible way to configure the cryptographic providers during Manager construction.


1010-1015: LGTM! Proper error handling for missing signaturePayloadProvider.

The explicit nil check and clear error message provide good error handling when the required provider is not configured.


556-592: LGTM! Well-structured block data retrieval logic.

The extracted getBlockData method improves code organization and readability by separating concerns for pending blocks and batch retrieval.


594-692: LGTM! Improved block publishing flow with better separation of concerns.

The refactored publishBlockInternal method with helper functions improves readability and maintainability while preserving the core logic.


923-927: LGTM! Metadata integration for ExecuteTxs.

The addition of metadata containing the header hash enables the execution layer to access block-specific information during transaction processing, which is essential for IBC functionality.


792-792: LGTM! Consistent signature payload provider usage.

The updated ValidateBasic calls correctly pass the signaturePayloadProvider, ensuring consistent signature validation across the codebase.

Also applies to: 639-639

Copy link
Member

@julienrbrt julienrbrt left a comment

Choose a reason for hiding this comment

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

utACK

Copy link
Contributor

@tac0turtle tac0turtle left a comment

Choose a reason for hiding this comment

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

Requesting chnages to avoid the merge. I think we will need some changes with the attester system

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
execution/evm/execution_test.go (1)

121-122: Test coverage for metadata functionality could be enhanced.

The metadata parameter is initialized as empty but not tested for any specific behavior. Consider adding test assertions to verify metadata handling if it's critical for IBC functionality.

 metadata := make(map[string]interface{})
 newStateRoot, maxBytes, err := executionClient.ExecuteTxs(ctx, payload, blockHeight, time.Now(), prevStateRoot, metadata)
+// Consider adding assertions to verify metadata population if relevant
+// require.Contains(tt, metadata, "expectedKey", "metadata should contain expected data")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a54894a and 15a6cf2.

📒 Files selected for processing (6)
  • apps/testapp/cmd/run.go (2 hunks)
  • block/manager.go (19 hunks)
  • block/retriever_test.go (1 hunks)
  • execution/evm/execution.go (1 hunks)
  • execution/evm/execution_test.go (2 hunks)
  • pkg/cmd/run_node.go (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • pkg/cmd/run_node.go
  • execution/evm/execution.go
  • block/retriever_test.go
  • block/manager.go
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: rollkit-docker / docker-build (GHCR; ghcr.io/rollkit/rollkit)
  • GitHub Check: lint / golangci-lint
  • GitHub Check: test / Run EVM Execution Tests
  • GitHub Check: test / Run Unit Tests
  • GitHub Check: test / Build All Rollkit Binaries
  • GitHub Check: Analyze (go)
  • GitHub Check: Summary
🔇 Additional comments (3)
apps/testapp/cmd/run.go (2)

13-13: LGTM: Imports added for new functionality.

The new imports for block and types packages are necessary to support the new provider options being passed to StartNode.

Also applies to: 21-21


111-122: LGTM: Default providers properly configured for testapp.

The addition of WithSignaturePayloadProvider and WithCommitHashProvider options with default implementations aligns well with the PR objectives to support IBC functionality through provider injection. Using default implementations is appropriate for a test application.

execution/evm/execution_test.go (1)

182-183: Consistent metadata handling across test phases.

Good consistency with the build chain phase. The empty metadata approach is appropriate for integration testing focused on execution flow rather than metadata-specific behavior.

Copy link
Contributor

@alpe alpe left a comment

Choose a reason for hiding this comment

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

quick feedback. I have not read all the code yet.

return fmt.Errorf("error while getting previous block data: %w", err)
}

if err = m.store.SaveBlockData(ctx, header, data, &signature); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

I could not see where you store the block before applyBlock is called.
When it fails for whatever reason, the data is lost and a new block is created on restart rather than loaded from store as before.


// WithValidatorHasher sets the validator hasher provider
func WithValidatorHasher(hasher types.ValidatorHasher) ManagerOption {
return func(m *Manager) {
Copy link
Contributor

@alpe alpe Jun 5, 2025

Choose a reason for hiding this comment

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

personal preference: this and the other Options: prevent nil values -> fail fast

block/manager.go Outdated

// previousBlockData holds information about the previous block,
// necessary for creating the next block.
type previousBlockData struct {
Copy link
Contributor

Choose a reason for hiding this comment

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

I understand that this represents historic block data but the term "previous" feels a bit too technical to the process. I know naming is hard but maybe you can find a term that is more focused on what this data represents or how it is used?

// - blockHeight: Height of block being created (must be > 0)
// - timestamp: Block creation time in UTC
// - prevStateRoot: Previous block's state root hash
// - metadata: Arbitrary data passed from the block manager (e.g., current header hash)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Arbitrary data sounds very weak. When used, are there any guarantees what data is available?

}

// SetHeaderHasher allows different implementations to override the default header hasher
func SetHeaderHasher(hasher HeaderHasher) {
Copy link
Contributor

Choose a reason for hiding this comment

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

personal preference: I am with Julien on this global. The default hasher is stateless. Can you evaluate why this is needed? I have not found a call to SetHeaderHasher in this project. Is this an extension point? Some context would be great in Godoc as well

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
block/sync.go (1)

119-123: Consistent error handling in data event processing.

The error handling here matches the header event processing, maintaining consistency. The same architectural considerations about error classification apply here as well.

Consider implementing a more sophisticated error handling strategy that:

  1. Categorizes errors by type (recoverable vs. non-recoverable)
  2. Implements exponential backoff for retryable errors
  3. Includes circuit breaker patterns for persistent failures
// Try to sync the next block, as this data event might have completed a block
if err := m.trySyncNextBlock(ctx, dataEvent.DAHeight); err != nil {
    m.logger.Error("error while trying to sync next block", "error", err)
+   // Consider error classification here
+   if isRecoverableError(err) {
+       // Implement retry logic with backoff
+   }
    errCh <- err
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 372dbf1 and cb91837.

📒 Files selected for processing (2)
  • block/sync.go (2 hunks)
  • types/utils.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • types/utils.go
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: rollkit-docker / docker-build (GHCR; ghcr.io/rollkit/rollkit)
  • GitHub Check: test / Run EVM Execution Tests
  • GitHub Check: test / Run Unit Tests
  • GitHub Check: test / Build All Rollkit Binaries
  • GitHub Check: Analyze (go)
  • GitHub Check: Summary

Comment on lines +62 to 66
// Try to sync the next block, in case the corresponding data was already present
if err := m.trySyncNextBlock(ctx, daHeight); err != nil {
m.logger.Error("error while trying to sync next block", "error", err)
errCh <- err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Improved error resilience in header event processing.

The error handling change allows the sync loop to continue processing after trySyncNextBlock failures, which improves system resilience. However, consider whether all error types should be handled uniformly.

Some errors from trySyncNextBlock (like validation failures) might indicate corrupted data that could repeatedly fail, while others (like temporary network issues) might be recoverable. Consider implementing error classification to distinguish between recoverable and non-recoverable errors.


🏁 Script executed:

#!/bin/bash
# Verify what types of errors trySyncNextBlock can return
ast-grep --pattern 'func (m *Manager) trySyncNextBlock($$$) error {
  $$$
}'

Length of output: 2786


Error Classification for trySyncNextBlock Failures

trySyncNextBlock currently returns the following error types:

  • ctx.Err() on context cancellation
  • Storage errors from m.store.Height and m.store.SetHeight
  • nil when header or data aren’t yet in the cache
  • Wrapped fmt.Errorf errors for:
    • validation (failed to validate block)
    • application (failed to apply block)
    • state save (failed to save updated state)
    • block save (failed to save block)

Handling all of these uniformly can lead to infinite retries on non-recoverable failures (e.g. persistent validation errors). To improve robustness, introduce error classification:

  • Define sentinel error variables or custom error types, for example:
    var (
      ErrBlockValidation = errors.New("block validation failed")
      ErrBlockApplication = errors.New("block application failed")
    )
  • Wrap errors in trySyncNextBlock with these sentinels:
    if err := m.Validate(...); err != nil {
      return fmt.Errorf("%w: %v", ErrBlockValidation, err)
    }
  • In the sync loop (lines 62–66 and 119–123), use errors.Is or errors.As to distinguish:
    • Non-recoverable (e.g. ErrBlockValidation): log and skip or terminate
    • Recoverable (e.g. transient storage errors): log and continue

This ensures permanent block errors don’t cause endless retries, while recoverable errors still allow the loop to progress.

🤖 Prompt for AI Agents
In block/sync.go around lines 62 to 66, improve error handling for
trySyncNextBlock by classifying errors into recoverable and non-recoverable
types. Define sentinel error variables for validation and application failures,
wrap corresponding errors in trySyncNextBlock with these sentinels, and then
update the sync loop to check errors using errors.Is or errors.As. For
non-recoverable errors like validation failures, log and skip or terminate
processing to avoid infinite retries; for recoverable errors, log and continue
the loop to maintain resilience.

@julienrbrt
Copy link
Member

Superseded by #2346

@julienrbrt julienrbrt closed this Jun 9, 2025
@github-project-automation github-project-automation bot moved this to Done in Evolve Jun 9, 2025
github-merge-queue bot pushed a commit that referenced this pull request Jun 9, 2025
Superseed #2301

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added support for custom signature verification logic on block
headers, allowing advanced users to specify how header signatures are
verified.
- Enhanced context handling to provide block header information during
transaction execution.

- **Bug Fixes**
- Improved context handling to make block header information available
during transaction execution.

- **Chores**
- Updated the initial block version to 11 for improved compatibility
with external blockchains.
  - Minor test and code cleanups with no impact on functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Manav-Aggarwal pushed a commit that referenced this pull request Jun 10, 2025
Superseed #2301

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added support for custom signature verification logic on block
headers, allowing advanced users to specify how header signatures are
verified.
- Enhanced context handling to provide block header information during
transaction execution.

- **Bug Fixes**
- Improved context handling to make block header information available
during transaction execution.

- **Chores**
- Updated the initial block version to 11 for improved compatibility
with external blockchains.
  - Minor test and code cleanups with no impact on functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Manav-Aggarwal pushed a commit that referenced this pull request Jun 10, 2025
Superseed #2301

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added support for custom signature verification logic on block
headers, allowing advanced users to specify how header signatures are
verified.
- Enhanced context handling to provide block header information during
transaction execution.

- **Bug Fixes**
- Improved context handling to make block header information available
during transaction execution.

- **Chores**
- Updated the initial block version to 11 for improved compatibility
with external blockchains.
  - Minor test and code cleanups with no impact on functionality.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@julienrbrt julienrbrt deleted the feat/fix-block-fields-ibc branch June 11, 2025 09:05
@tac0turtle tac0turtle removed this from Evolve Aug 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

IBC handshake fails due to mismatched header signature after execution-layer split

5 participants