Skip to content

Conversation

@tzdybal
Copy link
Member

@tzdybal tzdybal commented Jan 13, 2025

Overview

Resolves #1931.

Summary by CodeRabbit

  • Documentation

    • Updated Markdown linting configuration to enforce stricter rules for nested lists.
    • Added Architecture Decision Record (ADR) for Rollkit's new Execution API, defining methods for blockchain initialization, transaction processing, and block finalization.
  • New Features

    • Introduced a generic Execution API with four core methods to enhance Rollkit's interoperability and execution environment flexibility.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 13, 2025

Walkthrough

The pull request introduces a new Execution API for Rollkit, designed to enhance interoperability by removing ABCI-centric code and creating a generic interface for various execution environments. Key changes include an update to the .markdownlint.yaml configuration and the addition of a new Architecture Decision Record (ADR) that outlines four primary methods in the Executor interface: InitChain, GetTxs, ExecuteTxs, and SetFinal. This transition simplifies Rollkit's architecture and improves its functionality.

Changes

File Change Summary
.markdownlint.yaml Updated MD024 rule configuration from allow_different_nesting: true to siblings_only: true
specs/lazy-adr/adr-010-exec-api.md Added new Executor interface with methods: InitChain, GetTxs, ExecuteTxs, and SetFinal

Assessment against linked issues

Objective Addressed Explanation
Create ADR describing Execution API [#1931]

Possibly related issues

  • [EPIC] Execution API #1802 (EPIC: Execution API): This PR directly contributes to the epic by defining the Execution API interface and its methods.

Poem

🐰 In the realm of code, a new path unfurls,
Execution API, where flexibility swirls.
ABCI constraints, now gently unwound,
A rabbit's dance of interfaces profound!
Rollkit evolves, with methods so bright 🚀


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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. (Beta)
  • @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

PR Preview Action v1.6.0

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

Built to branch gh-pages at 2025-01-13 12:36 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@codecov
Copy link

codecov bot commented Jan 13, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 42.61%. Comparing base (f5d91ca) to head (ac1c1af).
Report is 29 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1947      +/-   ##
==========================================
- Coverage   42.70%   42.61%   -0.09%     
==========================================
  Files          79       79              
  Lines       12765    12765              
==========================================
- Hits         5451     5440      -11     
- Misses       6589     6599      +10     
- Partials      725      726       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tzdybal tzdybal marked this pull request as ready for review January 15, 2025 11:13
@RollkitBot RollkitBot requested review from a team, MSevey, tuxcanfly and yarikbratashchuk and removed request for a team January 15, 2025 11:14
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: 2

🧹 Nitpick comments (4)
specs/lazy-adr/adr-010-exec-api.md (4)

29-44: Consider defining specific error types for common failure scenarios.

The interface is well-structured, but could benefit from defining specific error types for common failure scenarios (e.g., InvalidStateError, TimeoutError) to help implementers handle errors consistently.

Also, consider documenting recommended timeout values for the context parameter in each method's documentation.


134-137: Enhance error specification for SetFinal.

The error output specification should detail specific error cases that implementers need to handle, such as:

  • Block height not found
  • Block already finalized
  • Attempting to finalize future blocks

153-176: Enhance sequence diagram with error handling flows.

The block production sequence diagram should include error handling paths, showing how the system behaves when:

  • ExecuteTxs fails
  • DA layer submission fails
  • SetFinal fails

201-204: Consider documenting migration strategy.

As Rollkit transitions from an ABCI client to an orchestrator, consider documenting:

  1. Step-by-step migration path for existing implementations
  2. Backward compatibility considerations
  3. Required changes for dependent projects
🧰 Tools
🪛 LanguageTool

[uncategorized] ~202-~202: The hyphen in fully-fledged is redundant.
Context: ...ed from rollkit. Rollkit will turn from fully-fledged ABCI client to kind of orchestrator, gl...

(ADVERB_LY_HYPHEN_FIX)

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 82321d6 and 72921b6.

📒 Files selected for processing (2)
  • .markdownlint.yaml (1 hunks)
  • specs/lazy-adr/adr-010-exec-api.md (1 hunks)
🧰 Additional context used
🪛 GitHub Check: lint / yamllint
.markdownlint.yaml

[failure] 7-7:
7:1 [empty-lines] too many blank lines (1 > 0)

🪛 GitHub Actions: CI and Release
.markdownlint.yaml

[error] 7-7: Too many blank lines (1 > 0)

🪛 LanguageTool
specs/lazy-adr/adr-010-exec-api.md

[uncategorized] ~16-~16: Possible missing article found.
Context: ...on. 2. Migrate to Engine API. 3. Create new API generic enough to handle any arbitr...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~202-~202: The hyphen in fully-fledged is redundant.
Context: ...ed from rollkit. Rollkit will turn from fully-fledged ABCI client to kind of orchestrator, gl...

(ADVERB_LY_HYPHEN_FIX)


[style] ~261-~261: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...execution environment. ### Neutral 1. Need to introduce new API exposed by rollkit. ...

(REP_NEED_TO_VB)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Summary
🔇 Additional comments (2)
.markdownlint.yaml (1)

6-6: LGTM! Configuration update looks good.

The change from allow_different_nesting to siblings_only for MD024 rule is valid and will help maintain consistent header uniqueness within the same nesting level.

specs/lazy-adr/adr-010-exec-api.md (1)

115-122: Clarify transaction ordering requirements.

The expected behavior mentions "Respect the ordering of transactions" but doesn't specify if this is the exact order provided in the input slice or if there's flexibility for the execution environment to reorder transactions based on certain criteria (e.g., nonce ordering for account-based systems).

Copy link
Contributor

@yarikbratashchuk yarikbratashchuk left a comment

Choose a reason for hiding this comment

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

Look good

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

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 72921b6 and 5ac7d33.

📒 Files selected for processing (1)
  • .markdownlint.yaml (1 hunks)
🧰 Additional context used
🪛 yamllint (1.35.1)
.markdownlint.yaml

[error] 6-6: no new line character at the end of file

(new-line-at-end-of-file)

🪛 GitHub Check: lint / yamllint
.markdownlint.yaml

[failure] 6-6:
6:22 [new-line-at-end-of-file] no new line character at the end of file

⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: rollkit-docker / docker-build (GHCR; ghcr.io/rollkit/rollkit)
  • GitHub Check: test / Run Unit Tests
  • GitHub Check: Test CLI (windows-latest)
  • GitHub Check: Analyze (go)
  • GitHub Check: Summary
🔇 Additional comments (1)
.markdownlint.yaml (1)

6-6: LGTM! The configuration change looks good.

The change to siblings_only: true for the MD024 rule is appropriate for ADR documentation as it allows duplicate headings at different nesting levels while still preventing duplicate sibling headings.

🧰 Tools
🪛 yamllint (1.35.1)

[error] 6-6: no new line character at the end of file

(new-line-at-end-of-file)

🪛 GitHub Check: lint / yamllint

[failure] 6-6:
6:22 [new-line-at-end-of-file] no new line character at the end of file

Copy link
Member

@gupadhyaya gupadhyaya left a comment

Choose a reason for hiding this comment

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

i feel like maxBytes is confusing and may be we should get rid of it altogether and go with the assumption that:

  • sequencer will make fast batches of smaller sizes such that the batch will likely never exceed the execution client's block gas limits.

i am recommending this because, maxBytes is kind of useless. what do you think?

@tzdybal
Copy link
Member Author

tzdybal commented Jan 16, 2025

The maxBytes is definitely confusing. I agree that sequencer should make small enough batches, but on the other hand, maxBytes was one of the ways to signal sequencer that expected block size is increased in execution layer.

Another idea for consideration - return maxBytes from GetTxs. Or even return it as optional parameter, only when it changes. Transaction related logic will be grouped together, and ability to signal sequencer will be maintained.

As a result rollkit would pass maxBytes from executor to sequencer, along with mempool contents. Sequencer will know current limit, and will be able to safely add transactions (submitted directly or forcefully included from DA).

Yet another idea - remove explicit maxBytes, but assume that sequencer will not produce batches bigger than size of transactions returned by GetTxs.

@gupadhyaya
Copy link
Member

The maxBytes is definitely confusing. I agree that sequencer should make small enough batches, but on the other hand, maxBytes was one of the ways to signal sequencer that expected block size is increased in execution layer.

Another idea for consideration - return maxBytes from GetTxs. Or even return it as optional parameter, only when it changes. Transaction related logic will be grouped together, and ability to signal sequencer will be maintained.

As a result rollkit would pass maxBytes from executor to sequencer, along with mempool contents. Sequencer will know current limit, and will be able to safely add transactions (submitted directly or forcefully included from DA).

Yet another idea - remove explicit maxBytes, but assume that sequencer will not produce batches bigger than size of transactions returned by GetTxs.

got another idea. how about,

  • GetTxs return []TxWithGas{} where TxWithGas{Tx, Gas}. the execution clients can pool txs from their mempool, run a quick gas estimator on them and return? do you see any issue here?
  • ExecuteTxs would still send maxGas (let's use gas instead of bytes, as bytes does not necessarily translate to gas requirements, its just part of gas estimation) indicating if there requirements have changed for the future.
  • rollkit will relay TxWithGas along with maxGas to sequencer to avoid any over the gas limit batches.

##### Inputs

- `ctx` (`context.Context`): Context for managing request timeouts and cancellations.
- `txs` (`[]types.Tx`): A slice of transactions to be executed.
Copy link
Contributor

Choose a reason for hiding this comment

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

what is the type here?

Copy link
Member Author

Choose a reason for hiding this comment

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

types.Tx is just []byte, as it's not interpreted by rollkit in any way. I'll include information about types in ADR.

Copy link
Contributor

Choose a reason for hiding this comment

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

why not use []byte? what is the type preventing here?

Copy link
Member Author

Choose a reason for hiding this comment

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

TBH there is no good reason for this. ADR was reflecting code. We should change this in docs and code. Especially after evstack/go-sequencing#35

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.

makes sense, it seems there are a few assumptions being made on the execution environment. Like verifying txs needs to be handled in the state machine. it could be good to mention these allowing readers to understand what is needed by them

Copy link
Contributor

@facundomedica facundomedica left a comment

Choose a reason for hiding this comment

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

A couple of questions:

  1. Why do we need to return maxBytes in InitChain and ExecTxs?
  2. I'm not sure what this means: "More difficult deployment (another binary is needed)."

@tzdybal
Copy link
Member Author

tzdybal commented Jan 29, 2025

1. Why do we need to return maxBytes in InitChain and ExecTxs?

Max bytes should be defined in genesis file, and possibly can be changed during execution. So the max bytes is inherently defined by execution client, but sequencer also needs to know this, so it can build batches according to the limit.

2. I'm not sure what this means: "More difficult deployment (another binary is needed)."

Before ADR-010 introduction, rollkit and app can be in the same binary, and this is kind of "default" option. With separate executor, node operators always have to run separate node for rollkit, and separate for execution client.

@gupadhyaya
Copy link
Member

just referencing here: evstack/go-execution-evm#25, we may need further modification to the a couple of apis.

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 (4)
specs/lazy-adr/adr-010-exec-api.md (4)

64-64: Clarify maxBytes behavior across methods.

The maxBytes parameter appears in both InitChain and ExecuteTxs outputs. Based on the PR objectives, there's confusion about its purpose and behavior. Consider adding explicit documentation about:

  1. When and why maxBytes might change during execution
  2. How the sequencer should handle changes to maxBytes
  3. Whether the sequencer must respect this limit strictly

Also applies to: 112-113


145-147: Enhance error handling documentation.

While the general notes mention "robust error handling practices", consider adding:

  1. Specific error types or codes for common failure scenarios
  2. Error recovery strategies
  3. Guidelines for error propagation
  4. Examples of meaningful error messages

162-185: Document error paths in sequence diagrams.

The sequence diagrams effectively show the happy path but should also illustrate:

  1. Error handling flows
  2. Retry mechanisms
  3. Timeout scenarios
  4. Recovery procedures

Also applies to: 189-206


219-238: Document migration strategy for existing users.

The package changes are significant. Consider adding:

  1. Migration guide for existing ABCI implementations
  2. Backward compatibility strategy
  3. Deprecation timeline for removed functionality
  4. Example upgrade paths
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between cfbdaa9 and ac1c1af.

📒 Files selected for processing (2)
  • .markdownlint.yaml (1 hunks)
  • specs/lazy-adr/adr-010-exec-api.md (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • .markdownlint.yaml
🧰 Additional context used
🪛 LanguageTool
specs/lazy-adr/adr-010-exec-api.md

[uncategorized] ~16-~16: Possible missing article found.
Context: ...on. 2. Migrate to Engine API. 3. Create new API generic enough to handle any arbitr...

(AI_HYDRA_LEO_MISSING_A)


[uncategorized] ~211-~211: The hyphen in fully-fledged is redundant.
Context: ...ed from rollkit. Rollkit will turn from fully-fledged ABCI client to kind of orchestrator, gl...

(ADVERB_LY_HYPHEN_FIX)


[uncategorized] ~217-~217: Possible missing comma found.
Context: ...ollkit enables further refactoring, for example removing all CometBFT dependencies. ##...

(AI_HYDRA_LEO_MISSING_COMMA)


[uncategorized] ~245-~245: Possible missing article found.
Context: ...sts should be introduced to ensure that entire flow (from InitChain to SetFinal) w...

(AI_HYDRA_LEO_MISSING_THE)


[style] ~270-~270: You have already used this phrasing in nearby sentences. Consider replacing it to add variety to your writing.
Context: ...execution environment. ### Neutral 1. Need to introduce new API exposed by rollkit. ...

(REP_NEED_TO_VB)

⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: rollkit-docker / docker-build (GHCR; ghcr.io/rollkit/rollkit)
  • GitHub Check: test / Run Unit Tests
  • GitHub Check: Test CLI (windows-latest)
  • GitHub Check: Analyze (go)
  • GitHub Check: Summary
🔇 Additional comments (1)
specs/lazy-adr/adr-010-exec-api.md (1)

241-246: Expand testing strategy section.

The testing section should include:

  1. Specific test scenarios for each API method
  2. Performance testing requirements
  3. Compatibility testing with different execution environments
  4. Error scenario testing
🧰 Tools
🪛 LanguageTool

[uncategorized] ~245-~245: Possible missing article found.
Context: ...sts should be introduced to ensure that entire flow (from InitChain to SetFinal) w...

(AI_HYDRA_LEO_MISSING_THE)

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

// SetFinal marks a block at the given height as final.
SetFinal(ctx context.Context, blockHeight uint64) error
Copy link
Contributor

Choose a reason for hiding this comment

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

how come we cant assume execution is this step? is there a scenario in which an app would not set final after executetxs?

Copy link
Member

Choose a reason for hiding this comment

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

if VerifyBatch call from rollkit/app to sequencer fails then the header producer may decide to not call setFinal. This is not implemented yet. Idea is to continue execution as soon as sequencer batch is available and not wait for the sequencer hard confirmation of the batch (GetNextBatch is only the soft confirmation from the sequencer).

##### Outputs

- `stateRoot` (`types.Hash`): The resulting state root after initializing the chain.
- `maxBytes` (`uint64`): Maximum block size in bytes, as defined by the execution client's genesis configuration.
Copy link
Contributor

Choose a reason for hiding this comment

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

why does this need to be passed back?

Copy link
Member Author

Choose a reason for hiding this comment

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

To separate concerns - maxBytes as a genesis parameter is strictly related to execution layer. Sequencer needs to know maxBytes, but we don't want to parse execution layer genesis file in sequencer, and keeping this in API makes it more error prone (no need to match sequencer config with param in genesis).


##### Inputs

- `ctx` (`context.Context`): Context for managing request timeouts and cancellations.
Copy link
Contributor

Choose a reason for hiding this comment

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

where is the block created and how does the app know how many txs to return? does it return the whole mempool?

Copy link
Member Author

Choose a reason for hiding this comment

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

Entire mempool contents should be returned. Sequencer should peek the best transactions that fits in single block (maxBytes) and send them back. Transactions included in block must be removed from mempool.

##### Outputs

- `updatedStateRoot` (`types.Hash`): The resulting state root after applying the transactions.
- `maxBytes` (`uint64`): Maximum block size in bytes, as allowed for the block being produced.
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto, may be good to have a larger explainer as to why this is needed

Copy link
Member

Choose a reason for hiding this comment

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

this is to update rollkit/sequencer if the maxbytes requirement has changed for the next block. execution layer may have congestion etc and needs to reduce the txs then it can be done via returning maxbytes for the next block.

@tac0turtle
Copy link
Contributor

as i look into the code i get more confused on this api. i think it may need to be redesigned or the adr isnt explaining things deeply enough

@MSevey MSevey removed their request for review February 26, 2025 18:06
@Manav-Aggarwal Manav-Aggarwal moved this to Todo in Evolve Mar 6, 2025
@Manav-Aggarwal Manav-Aggarwal moved this from Todo to For Review in Evolve Mar 28, 2025
@Manav-Aggarwal Manav-Aggarwal moved this from For Review to In Progress in Evolve Mar 28, 2025
@tzdybal tzdybal added this pull request to the merge queue Apr 22, 2025
Merged via the queue into main with commit 368ee48 Apr 22, 2025
27 of 28 checks passed
@tzdybal tzdybal deleted the tzdybal/adr-010 branch April 22, 2025 10:18
@github-project-automation github-project-automation bot moved this from In Progress to Done in Evolve Apr 22, 2025
@tac0turtle tac0turtle removed this from Evolve Apr 24, 2025
@coderabbitai coderabbitai bot mentioned this pull request May 6, 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.

docs: Create ADR describing Execution API

6 participants