Skip to content

Conversation

@d4mr
Copy link
Member

@d4mr d4mr commented Aug 6, 2025

Summary by CodeRabbit

  • New Features

    • Added support for scheduling and detecting manual nonce resets for externally owned accounts (EOAs), including new admin API endpoints and diagnostics.
    • Introduced an authorization cache for efficient EIP-7702 minimal account status checks, improving transaction processing performance.
    • Enhanced concurrency control by dynamically adjusting inflight limits for EOAs based on their delegation status.
  • Improvements

    • Updated transaction data serialization to include submission timestamps, supporting better tracking and compatibility.
    • Streamlined gas bump logic for stalled transactions, prioritizing the most recent submissions.
    • Centralized and shared authorization cache management across components for improved efficiency.
  • Bug Fixes

    • Ensured manual reset indicators are cleared atomically with nonce resets.

@coderabbitai
Copy link

coderabbitai bot commented Aug 6, 2025

Walkthrough

This change introduces a shared EOA authorization cache using the moka crate, centralizes its management, and integrates it into both the execution router and queue manager. It adds support for manual nonce reset scheduling and detection in the EOA executor store, updates transaction serialization to include submission timestamps, and adjusts worker concurrency based on account authorization status. Several public APIs and internal flows are updated to support these new features.

Changes

Cohort / File(s) Change Summary
Authorization Cache Introduction & Integration
executors/src/eoa/authorization_cache.rs, executors/src/eoa/mod.rs, executors/Cargo.toml, executors/src/eoa/worker/mod.rs, server/src/main.rs, server/src/queue/manager.rs, server/src/execution_router/mod.rs
Introduces EoaAuthorizationCache using moka, implements cache keying and async lookup, integrates the cache into worker and router logic, centralizes cache instantiation and sharing, and updates dependencies.
Manual Nonce Reset Feature
executors/src/eoa/store/mod.rs, executors/src/eoa/store/atomic.rs, server/src/http/routes/admin/eoa_diagnostics.rs
Adds manual reset key management, scheduling and detection methods, updates admin diagnostics API to expose and control manual reset state, and ensures atomic reset in Redis includes manual reset key.
Transaction Serialization Update
executors/src/eoa/store/submitted.rs, executors/src/eoa/store/mod.rs
Adds submitted_at timestamp to SubmittedTransactionDehydrated, updates string serialization/deserialization for backward compatibility, and ensures new field is set at submission.
Worker Logic & Concurrency Control
executors/src/eoa/worker/confirm.rs, executors/src/eoa/worker/mod.rs
Modifies nonce reset and stalled nonce gas bumping logic, introduces check for scheduled manual reset, updates concurrency control to use minimal account status from cache, and streamlines transaction selection for gas bumping.
Chain Service Trait Update
core/src/chain.rs
Updates ChainService::get_chain trait method to require returned type to implement both Chain and Clone.

Sequence Diagram(s)

sequenceDiagram
    participant Admin as Admin API Client
    participant Server as Engine Server
    participant Store as EoaExecutorStore (Redis)
    participant Worker as EoaExecutorWorker

    Admin->>Server: POST /admin/executors/eoa/{eoa_chain}/reset
    Server->>Store: schedule_manual_reset()
    Store-->>Server: Set manual_reset_key in Redis
    Server-->>Admin: 200 OK

    Worker->>Store: is_manual_reset_scheduled()
    Store-->>Worker: true/false
    alt If manual reset scheduled
        Worker->>Store: Reset nonces atomically (incl. manual_reset_key)
    end
Loading
sequenceDiagram
    participant Router as ExecutionRouter
    participant Cache as EoaAuthorizationCache
    participant Worker as EoaExecutorJobHandler
    participant Account as DelegatedAccount

    Router->>Cache: is_minimal_account(&DelegatedAccount)
    alt Cache hit
        Cache-->>Router: bool
    else Cache miss
        Cache->>Account: is_minimal_account()
        Account-->>Cache: bool
        Cache-->>Router: bool
    end
    Router->>Worker: Set max_inflight based on bool
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch pb/fix-max-in-flight-for-delegated-eoa

🪧 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.
  • 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.

Support

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

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 generate unit tests to generate unit tests for 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.

@d4mr d4mr requested a review from joaquim-verges August 6, 2025 04:14
Copy link

@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)
executors/src/eoa/store/submitted.rs (1)

105-137: Well-implemented backward compatibility handling.

The code correctly handles both the old 3-part and new 4-part string formats, ensuring smooth migration. Setting submitted_at to 0 for old transactions is a reasonable default.

Consider adding a TODO with a specific date or version for removing the backward compatibility code to ensure it doesn't remain indefinitely.

-                // this exists for backwards compatibility with old transactions
-                // remove after sufficient time for old transactions to be cleaned up
+                // TODO: Remove backward compatibility after 2025-03-01 or version 2.0.0
+                // This handles old 3-part format (hash:id:queued_at) for transactions created before submitted_at was added
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 3af720f and 165a987.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (13)
  • core/src/chain.rs (1 hunks)
  • executors/Cargo.toml (1 hunks)
  • executors/src/eoa/authorization_cache.rs (1 hunks)
  • executors/src/eoa/mod.rs (1 hunks)
  • executors/src/eoa/store/atomic.rs (2 hunks)
  • executors/src/eoa/store/mod.rs (8 hunks)
  • executors/src/eoa/store/submitted.rs (4 hunks)
  • executors/src/eoa/worker/confirm.rs (7 hunks)
  • executors/src/eoa/worker/mod.rs (4 hunks)
  • server/src/execution_router/mod.rs (4 hunks)
  • server/src/http/routes/admin/eoa_diagnostics.rs (5 hunks)
  • server/src/main.rs (3 hunks)
  • server/src/queue/manager.rs (3 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
Learnt from: d4mr
PR: thirdweb-dev/engine-core#5
File: executors/src/eoa/worker.rs:173-176
Timestamp: 2025-07-06T15:44:13.701Z
Learning: The EOA executor store uses comprehensive WATCH-based coordination where every Redis state mutation watches the lock key and validates ownership before proceeding. If the lock is lost during any operation, the transaction fails with LockLost error. This makes aggressive lock acquisition safe because only the actual lock holder can successfully perform state mutations, regardless of who claims the lock.
Learnt from: d4mr
PR: thirdweb-dev/engine-core#5
File: executors/src/eoa/worker.rs:173-176
Timestamp: 2025-07-06T15:44:13.701Z
Learning: In the EOA executor system, aggressive lock acquisition is safe because every Redis state mutation uses WATCH operations on the lock key. If the lock is lost during a transaction, the WATCH causes the transaction to fail and the worker exits gracefully. This provides coordination between workers even when using forceful lock takeover.
📚 Learning: the eoa executor store uses comprehensive watch-based coordination where every redis state mutation ...
Learnt from: d4mr
PR: thirdweb-dev/engine-core#5
File: executors/src/eoa/worker.rs:173-176
Timestamp: 2025-07-06T15:44:13.701Z
Learning: The EOA executor store uses comprehensive WATCH-based coordination where every Redis state mutation watches the lock key and validates ownership before proceeding. If the lock is lost during any operation, the transaction fails with LockLost error. This makes aggressive lock acquisition safe because only the actual lock holder can successfully perform state mutations, regardless of who claims the lock.

Applied to files:

  • executors/src/eoa/store/mod.rs
  • executors/src/eoa/store/atomic.rs
  • server/src/execution_router/mod.rs
  • executors/src/eoa/worker/confirm.rs
📚 Learning: in the eoa executor system, aggressive lock acquisition is safe because every redis state mutation u...
Learnt from: d4mr
PR: thirdweb-dev/engine-core#5
File: executors/src/eoa/worker.rs:173-176
Timestamp: 2025-07-06T15:44:13.701Z
Learning: In the EOA executor system, aggressive lock acquisition is safe because every Redis state mutation uses WATCH operations on the lock key. If the lock is lost during a transaction, the WATCH causes the transaction to fail and the worker exits gracefully. This provides coordination between workers even when using forceful lock takeover.

Applied to files:

  • executors/src/eoa/store/mod.rs
  • executors/src/eoa/worker/mod.rs
  • server/src/execution_router/mod.rs
  • executors/src/eoa/worker/confirm.rs
🧬 Code Graph Analysis (1)
executors/src/eoa/authorization_cache.rs (2)
eip7702-core/src/delegated_account.rs (1)
  • chain (97-99)
server/src/queue/manager.rs (1)
  • new (46-239)
🔇 Additional comments (30)
executors/Cargo.toml (1)

27-27: LGTM! Clean dependency addition for async caching.

The moka dependency with the future feature correctly supports the new EoaAuthorizationCache implementation requiring async cache operations.

executors/src/eoa/mod.rs (1)

1-1: LGTM! Clean module addition for centralized authorization caching.

The new authorization_cache module appropriately encapsulates EOA authorization logic and enables sharing across components.

core/src/chain.rs (1)

263-263: LGTM! Appropriate trait bound addition for caching support.

Adding the Clone constraint enables safe reuse of chain instances across the new authorization cache operations. The existing ThirdwebChain implementation already supports cloning, ensuring backward compatibility.

executors/src/eoa/store/atomic.rs (1)

509-509: LGTM! Proper atomic cleanup of manual reset state.

The addition of manual_reset_key deletion maintains atomicity during nonce resets, ensuring consistent cleanup alongside optimistic nonce, cached nonce, and recycled nonces. This correctly integrates with the new manual reset scheduling feature.

Also applies to: 527-527

server/src/main.rs (2)

57-63: LGTM! Well-configured shared authorization cache.

The cache configuration is appropriate:

  • 1GB capacity provides sufficient space for authorization data
  • 5-minute TTL balances freshness with performance
  • 1-minute TTI keeps active entries cached

71-71: LGTM! Clean centralized cache sharing pattern.

Passing the same EoaAuthorizationCache instance to both QueueManager and ExecutionRouter properly centralizes authorization caching across components, eliminating duplication and ensuring consistency.

Also applies to: 90-90

server/src/queue/manager.rs (2)

8-8: LGTM: Clean import addition

The import of EoaAuthorizationCache follows the established pattern and supports the centralization of authorization cache management.


52-52: LGTM: Proper cache parameter threading

The authorization_cache parameter is correctly added to the constructor signature and properly passed to the EoaExecutorJobHandler. This supports the centralized cache management pattern.

Also applies to: 216-216

executors/src/eoa/worker/mod.rs (3)

10-10: LGTM: Proper imports and field addition

The new imports for DelegatedAccount and EoaAuthorizationCache are correctly added, and the authorization_cache field in EoaExecutorJobHandler supports the delegation-aware concurrency control.

Also applies to: 22-22, 115-115


161-172: LGTM: Sound delegation check with appropriate fallback

The delegation check logic is well-implemented:

  • Creates DelegatedAccount appropriately
  • Uses the authorization cache for efficient lookups
  • Proper error handling with logging and safe fallback to false
  • The fallback behavior (assuming non-minimal on error) is conservative and appropriate

181-185: LGTM: Clear concurrency control logic

The concurrency control implementation is straightforward and correct:

  • Minimal accounts are limited to max_inflight = 1 for safer execution
  • Regular accounts use the configured self.max_inflight value
  • The conditional logic is clear and well-structured
server/src/execution_router/mod.rs (2)

3-3: LGTM: Clean refactoring to encapsulated cache type

The import additions and field type change properly integrate the new EoaAuthorizationCache abstraction, replacing the previous manual cache management.

Also applies to: 24-24, 55-55


408-412: LGTM: Clean cache usage simplification

The refactoring successfully simplifies the cache interaction:

  • Replaces manual cache key construction with encapsulated method call
  • Maintains proper error handling and conversion to EngineError
  • Cleaner, more readable code
server/src/http/routes/admin/eoa_diagnostics.rs (3)

31-31: LGTM: Proper field addition for manual reset status

The manual_reset_scheduled field addition to EoaStateResponse properly exposes the manual reset scheduling status for diagnostic purposes.

Also applies to: 166-166


150-154: LGTM: Consistent error handling pattern

The manual reset status check follows the established pattern for store method calls with proper error handling and conversion to ApiEngineError.


380-409: LGTM: Well-structured new endpoint

The schedule_manual_reset endpoint follows established patterns:

  • Proper authentication and parameter validation
  • Consistent error handling and response format
  • Clean route registration
  • Appropriate HTTP method (POST) for the operation

Also applies to: 457-460

executors/src/eoa/authorization_cache.rs (3)

8-12: LGTM: Well-designed cache key structure

The AuthorizationCacheKey struct is properly designed:

  • Uses appropriate fields (EOA address and chain ID) for unique identification
  • Correct trait implementations (Hash, Eq, PartialEq) for cache key usage
  • Good encapsulation with private fields

14-22: LGTM: Clean cache wrapper design

The EoaAuthorizationCache wrapper is well-designed:

  • Clean encapsulation of moka::future::Cache
  • Clone implementation enables efficient sharing across components
  • Constructor allows external cache configuration

24-38: LGTM: Solid cache-or-compute implementation

The is_minimal_account method is well-implemented:

  • Proper cache-or-compute pattern with try_get_with
  • Correct cache key construction from DelegatedAccount
  • Generic design works with any Chain implementation
  • Appropriate error handling that extracts underlying errors
executors/src/eoa/worker/confirm.rs (4)

47-52: LGTM! Manual reset check is properly placed.

The manual reset check is appropriately positioned at the beginning of the confirm flow, ensuring it executes before any other nonce-related operations. The implementation correctly uses the freshly fetched chain transaction count.


262-274: LGTM! Proper handling of newest transaction selection.

The logic correctly identifies the newest transaction using the submitted_at timestamp when multiple transactions exist for the same nonce. The code handles both single and multiple transaction cases appropriately.


343-345: LGTM! Correct timestamp handling in gas bump attempt.

The submitted_at field is properly set to the current time using EoaExecutorStore::now() for the gas bump attempt, while preserving the original queued_at timestamp from the transaction data.


373-383: LGTM! Appropriate fallback to noop transaction.

The fallback logic correctly handles the edge case where transaction data cannot be found, sending a noop transaction to unstick the stalled nonce. The updated log message accurately describes the situation.

executors/src/eoa/store/mod.rs (5)

278-289: LGTM! Consistent key generation for manual reset.

The manual_reset_key_name method follows the established pattern for key generation in the store, properly handling namespacing and using a clear, descriptive key name.


350-360: LGTM! Proper timestamp initialization in conversion.

The submitted_at field is correctly set to the current time when converting from BorrowedTransactionData to SubmittedTransactionDehydrated, ensuring accurate submission time tracking.


738-745: LGTM! Simple and effective manual reset scheduling.

The schedule_manual_reset method correctly stores the current timestamp to signal that a manual reset has been scheduled, which will be detected and executed by the confirm worker.


778-782: LGTM! Helpful documentation for time utility.

The added documentation clarifies that now() provides the canonical time representation for the store, which is important for consistency across timestamp fields.


867-873: LGTM! Clean implementation for reset status check.

The is_manual_reset_scheduled method provides a simple and efficient way to check if a manual reset is pending by checking for the existence of the timestamp value.

executors/src/eoa/store/submitted.rs (2)

89-97: LGTM! Proper addition of submission timestamp field.

The submitted_at field is appropriately added to track the actual submission time of transactions, distinct from the queued_at time.


160-168: LGTM! Consistent serialization format update.

The to_redis_string_with_nonce method correctly includes the submitted_at field in the serialization format, maintaining consistency with the deserialization logic.

@joaquim-verges joaquim-verges merged commit 9fafe0a into main Aug 6, 2025
3 checks passed
@joaquim-verges joaquim-verges deleted the pb/fix-max-in-flight-for-delegated-eoa branch August 6, 2025 04:33
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.

2 participants