Skip to content

Upgrade rainix and alloy#15

Merged
hardyjosh merged 9 commits into
mainfrom
rust-upd
Jun 2, 2025
Merged

Upgrade rainix and alloy#15
hardyjosh merged 9 commits into
mainfrom
rust-upd

Conversation

@0xgleb
Copy link
Copy Markdown
Contributor

@0xgleb 0xgleb commented May 21, 2025

Motivation

We need the latest version of alloy to upgrade to the new versions of the interpreter/orderbook, we need a newer version of Rust to upgrade to the latest alloy, and we need to bump up rainix to upgrade to the latest version of Rust.

Solution

Upgrade rainix/rust/alloy versions

Checks

By submitting this for review, I'm confirming I've done the following:

  • made this PR as small as possible
  • unit-tested any new functionality
  • linked any relevant issues or PRs
  • included screenshots (if this involves a front-end change)

Summary by CodeRabbit

  • Chores
    • Updated environment and workflow configurations for improved Nix integration and caching.
    • Added .direnv/ to .gitignore to prevent accidental commits of local environment data.
  • Refactor
    • Simplified and consolidated dependency declarations.
    • Streamlined flake configuration for clarity.
  • Bug Fixes
    • Improved error handling and decoding for JSON-RPC errors, with clearer messaging and updated test coverage.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 21, 2025

Walkthrough

This update removes the ethers dependency in favor of the consolidated alloy crate, updates error handling to use alloy::rpc::json_rpc::ErrorPayload, and modifies related decoding logic and tests. It also revises Nix and GitHub Actions workflows for improved Nix installation and caching, introduces .envrc for consistent environment setup, and adds .direnv/ to .gitignore.

Changes

Files/Paths Change Summary
Cargo.toml Replaced multiple "alloy" dependencies with unified "alloy", removed "ethers", updated "reqwest", reformatted "tokio" dev-dependency.
src/error.rs Switched from "ethers" to "alloy" for error types, updated decoding logic, changed method signatures, and revised tests for new error format.
.github/workflows/publish.yml,
.github/workflows/rainix.yaml
Updated Nix installation and caching steps, added concurrency control in Rainix CI, improved workflow input formatting.
.envrc Added for pinning nix-direnv version, sourcing from GitHub, and enabling flake environment auto-reload.
.gitignore Added .direnv/ to ignored files.
flake.nix Simplified outputs attribute syntax; no functional change.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant Application
    participant AlloyRPC

    Client->>Application: Receives JSON-RPC error payload (ErrorPayload)
    Application->>Application: Check if error message contains "revert"
    alt Error data is present
        Application->>Application: Deserialize error data from JSON string
        Application->>Application: Decode hex bytes to error type
        Application->>Client: Return decoded error or AbiDecodeFailedErrors
    else No error data or invalid format
        Application->>Client: Return AbiDecodeFailedErrors with error message
    end
Loading

Possibly related issues

Possibly related PRs

✨ 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.

@0xgleb 0xgleb linked an issue May 21, 2025 that may be closed by this pull request
@0xgleb 0xgleb self-assigned this May 21, 2025
@0xgleb 0xgleb changed the title Rust upd Upgrade rainix May 21, 2025
@0xgleb 0xgleb linked an issue May 26, 2025 that may be closed by this pull request
@0xgleb 0xgleb changed the title Upgrade rainix Upgrade rainix and alloy May 29, 2025
@0xgleb 0xgleb requested review from findolor and hardyjosh May 30, 2025 17:51
@0xgleb 0xgleb marked this pull request as ready for review May 30, 2025 17:51
@0xgleb 0xgleb linked an issue May 30, 2025 that may be closed by this pull request
Copy link
Copy Markdown

@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: ASSERTIVE
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fa0cc05 and 63410e9.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • flake.lock is excluded by !**/*.lock
📒 Files selected for processing (7)
  • .envrc (1 hunks)
  • .github/workflows/publish.yml (2 hunks)
  • .github/workflows/rainix.yaml (3 hunks)
  • .gitignore (1 hunks)
  • Cargo.toml (2 hunks)
  • flake.nix (1 hunks)
  • src/error.rs (9 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: standard-tests (macos-latest, rainix-rs-artifacts)
🔇 Additional comments (23)
flake.nix (1)

10-13: Approve: Simplified outputs syntax is correct and concise.
The refactored single‐expression eachDefaultSystem invocation preserves existing behavior while improving readability.

.gitignore (1)

3-3: Approve: Ignore direnv artifacts.
Adding .direnv/ to .gitignore complements the new .envrc setup and prevents environment-specific files from being committed.

.envrc (2)

1-5: Approve: Pin and source nix-direnv version.
Checking for nix_direnv_version and sourcing the specific 3.0.6 script ensures a reproducible local Nix/direnv integration.


7-10: Approve: Auto-reload on flake changes and activate flake.
Watching flake.lock and flake.nix, then invoking use flake . with verbose tracing correctly manages environment reloads.

.github/workflows/rainix.yaml (3)

4-7: Approve: Add concurrency configuration.
Grouping runs by ${{ github.ref }}-rainix and cancelling in-progress non-main branches improves CI throughput and avoids redundant builds.


29-34: Approve: Replace Nix installer and add caching.
Switching to nixbuild/nix-quick-install-action@v30 and nix-community/cache-nix-action@v6 with tailored keys and GC limits streamlines Nix setup and speeds up CI.


54-54: Approve: Build for WASM target under Nix.
The nix develop -c cargo build --target wasm32-unknown-unknown step correctly compiles the project for the WASM target within the flake environment.

.github/workflows/publish.yml (4)

6-6: Approve: Standardize input description formatting.
Using double quotes for description aligns with YAML best practices and enhances readability.


10-16: Approve: Refine version-level options ordering and formatting.
The expanded list of release channels (alpha, beta, rc, patch, minor, major, release) is clear and well documented for workflow_dispatch.


27-32: Approve: Update Nix installer to nix-quick-install-action.
Using nixbuild/nix-quick-install-action@v30 with keep-env-derivations and keep-outputs optimizes the CI environment setup for reproducibility.


33-42: Approve: Add Nix store caching with GC limits.
Integrating nix-community/cache-nix-action@v6 and enforcing a 1 GB store limit on Linux accelerates builds and controls disk usage.

Cargo.toml (2)

14-14: Minor version update looks safe.

The reqwest update from 0.11.17 to 0.11.27 is a minor version bump that should maintain backward compatibility.


23-29: Code formatting improvement.

The multi-line format for tokio features improves readability with no functional changes.

src/error.rs (10)

1-5: Import consolidation aligns with Cargo.toml changes.

The imports have been correctly updated to use the consolidated alloy crate instead of individual sub-crates, which matches the dependency changes in Cargo.toml.


79-79: Correct usage of alloy hex encoding.

The updated path alloy::primitives::hex::encode_prefixed is consistent with the new alloy crate structure.


221-221: New import for updated test structure.

The addition of serde_json::value::RawValue import is needed for the updated test cases that now work with ErrorPayload.


310-327: Test correctly updated for new ErrorPayload structure.

The test has been properly updated to use ErrorPayload with RawValue for the data field. The encoding approach with format!(r#""{encoded}""#) correctly wraps the hex string in JSON quotes.


331-344: Test correctly handles no data case.

The test properly verifies the error handling when no data is present in the ErrorPayload. The expected error message format matches the new ErrorPayload::to_string() implementation.


347-361: Test handles invalid data format correctly.

This test correctly verifies the error handling when data is not in the expected JSON string format. The error propagation looks appropriate.


382-395: Test validates hex decoding error handling.

The test correctly verifies that invalid hex data results in a HexDecodeError, ensuring proper error propagation through the decoding pipeline.


438-454: Panic error test correctly updated.

The test properly validates panic error decoding with the new ErrorPayload structure and maintains the correct assertion expectations.


92-92:

Details

❓ Verification inconclusive

Verify the abi_decode_input method signature.

The calls to abi_decode_input have been updated to remove deprecated arguments. This looks correct based on the AI summary, but we should verify this is the correct method signature for alloy 1.0.9.

Let me verify the correct method signature for abi_decode_input in alloy 1.0.9:

Also applies to: 120-120


🌐 Web query:

What is the correct method signature for abi_decode_input in alloy 1.0.9 Rust crate?

💡 Result:

Based on the search results, I don't see specific information about the exact method signature for abi_decode_input in Alloy 1.0.9. The search results provide information about ABI encoding and decoding in general, but not the specific abi_decode_input method signature you're looking for.

From the available information, we can see that Alloy provides ABI functionality through various crates, particularly alloy_sol_types. The search results show examples of ABI decoding using methods like abi_decode, but not specifically abi_decode_input[1][4].

The typical pattern for ABI decoding in Alloy appears to be:

let decoded: SomeType = SomeType::abi_decode(&encoded, validate)?;

Or using the SolValue trait:

let decoded: SomeType = <SomeType>::abi_decode(&encoded, validate)?;

Where:

  • The method takes an encoded byte array (&encoded)
  • A validation flag (validate)
  • Returns a Result that needs to be unwrapped or handled with the ? operator

However, without specific documentation for the abi_decode_input method, I cannot provide the exact signature you're looking for. I would recommend checking the official Alloy documentation at alloy.rs or examining the specific module that contains this functionality in the codebase directly.

Citations:


Confirm abi_decode_input Signature in Alloy v1.0.9

I wasn’t able to locate the exact signature in our codebase or public docs automatically. Please verify that in the alloy crate v1.0.9 the abi_decode_input method indeed takes a single parameter (the input byte slice) and returns a Result<…> as expected.

• File: src/error.rs
– Line 92
– Line 120

Next steps:

  1. Inspect the alloy crate source (or docs.rs for v1.0.9) to confirm the method signature.
  2. Ensure the call in our code matches that signature exactly (no missing or extra arguments).

180-187:

Details

✅ Verification successful

Review the revert detection logic change.

The change from using a method-based revert check to err.message.contains("revert") is more fragile as it relies on string matching. However, this appears to be necessary due to the API change from JsonRpcError to ErrorPayload.

The error data decoding logic has also changed significantly:

  1. It now expects the data to be a JSON string wrapper
  2. It attempts to deserialize from JSON first, then decode hex bytes
  3. Error handling has been simplified

These changes look correct for the alloy migration, but let me verify the ErrorPayload structure and typical error data format:


🌐 Web query:

What is the structure of alloy::rpc::json_rpc::ErrorPayload in Rust and what format does the data field typically contain?

💡 Result:

Structure of alloy::rpc::json_rpc::ErrorPayload

The structure ErrorPayload in the Alloy Rust libraries represents the error object in a JSON-RPC response. While the exact struct definition for ErrorPayload in Alloy's current versions is not printed in the search snippets, Rust JSON-RPC libraries—including Alloy—conform closely to the [JSON-RPC 2.0 error specification][5]. A typical Rust definition for this type looks like:

pub struct ErrorPayload {
    pub code: i32,
    pub message: String,
    pub data: Option<serde_json::Value>,
}
  • code: An integer identifying the error type.
  • message: A short description of the error.
  • data: An optional field containing additional information about the error, often used for debugging or client hints.

Alloy's use of ErrorPayload is also seen in return types such as ErrResp(ErrorPayload) when a client or transport error occurs[2].

Typical Format of the data Field

The data field in JSON-RPC error objects is defined as an optional value intended to carry extra information about the error[5][6]. In practice:

  • It can be any JSON value (object, array, string, number, etc.).
  • It's frequently used to provide details that may help a client troubleshoot, such as stack traces, validation errors, or internal diagnostics.

Examples:

  • If an authentication error occurs, data might include a structured object with a sub-code and explanation[6].
  • If a parsing or validation error happens, data may contain which parameter failed and why.

Concrete Example (per JSON-RPC spec):

{
  "code": -32600,
  "message": "Invalid Request",
  "data": {
    "parameter": "id",
    "reason": "id must be a string or number"
  }
}

Summary Table

Field Type Typical Content
code i32 Error code (standard or custom)
message String Short error description
data Option<serde_json::Value> Additional context (any valid JSON, optional)

References to JSON-RPC in Alloy

  • Alloy’s codebase builds on Ethereum and EVM JSON-RPC standards, and the error payload mirrors the JSON-RPC 2.0 expected structure[5][6][2].
  • While errors codes and standard behavior are defined in the JSON-RPC 2.0 spec, Alloy can introduce additional application-specific context in data as appropriate for Ethereum or EVM-specific methods[2][5][6].

In summary:
The alloy::rpc::json_rpc::ErrorPayload struct matches the JSON-RPC 2.0 error schema, with code, message, and an optional, flexible data field most commonly containing structured JSON objects providing extra detail about the error context[2][5][6].

Citations:


Revert detection and error-data decoding logic validated

The ErrorPayload struct follows the JSON-RPC 2.0 schema (code: i32, message: String, data: Option<serde_json::Value>), and in “execution reverted” responses the data field is indeed a JSON string containing the hex-encoded revert reason. Your approach—using err.message.contains("revert") for detection, then serde_json::from_str to unwrap the string wrapper and hex-decode its bytes—is appropriate given the new API. No further changes are required.

Comment thread Cargo.toml
alloy-sol-types = { version = "0.7.7" }
alloy-json-abi = "0.7.7"
alloy-dyn-abi = "0.7.7"
alloy = { version = "1.0.9", features = ["json-rpc", "sol-types"] }
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot May 30, 2025

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Good consolidation of alloy dependencies.

The consolidation from multiple alloy sub-crates to a single alloy dependency with specific features is cleaner and aligns with the PR objectives to upgrade to the latest alloy version.

Let me verify that alloy 1.0.9 is the latest version and check for any breaking changes:


🌐 Web query:

What is the latest version of the alloy Rust crate and are there any breaking changes in version 1.0.9?

💡 Result:

As of May 30, 2025, the latest version of the Alloy Rust crate is 0.8.24, released on March 21, 2025. (lib.rs) The most recent release, 0.8.24, includes several bug fixes and updates, such as:

  • Fixes for EIP-7742.
  • Improvements to RlpReceipt::rlp_decode_fields.
  • Updates to the on_anvil_* functions to use BoxTransport.
  • Export of PrimitiveSignature instead of the deprecated sig.
  • Enhancements for Wasm compatibility in RetryBackoff.
  • Serde aliases to avoid breaking changes in the consensus module.

Regarding breaking changes, the changelog does not indicate any in version 0.8.24. (github.com) However, it's important to note that Alloy has not yet reached version 1.0. Therefore, there is no version 1.0.9, and consequently, no breaking changes associated with that version.

For the most accurate and up-to-date information on Alloy's releases and any potential breaking changes, it's recommended to consult the official Alloy GitHub repository. (github.com)

Citations:


Incorrect Alloy version specified in Cargo.toml

It appears that alloy = { version = "1.0.9", … } refers to a non-existent release. The latest published version is 0.8.24. Please update the dependency to a valid version to ensure Cargo can resolve the crate.

  • Cargo.toml, line 12:
-alloy = { version = "1.0.9", features = ["json-rpc", "sol-types"] }
+alloy = { version = "0.8.24", features = ["json-rpc", "sol-types"] }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
alloy = { version = "1.0.9", features = ["json-rpc", "sol-types"] }
alloy = { version = "0.8.24", features = ["json-rpc", "sol-types"] }
🤖 Prompt for AI Agents
In Cargo.toml at line 12, the specified version "1.0.9" for the alloy dependency
does not exist. Update the version to the latest valid release, which is
"0.8.24", to ensure Cargo can correctly resolve the crate. Keep the existing
features unchanged while modifying the version number.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're hallucinating and CI passing is the evidence of that (as well as crates.io)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 Analysis chain

You're absolutely right, and I apologize for the confusion. Let me verify the actual alloy versions available on crates.io:


🏁 Script executed:

#!/bin/bash
# Check the actual alloy crate versions on crates.io
curl -s "https://crates.io/api/v1/crates/alloy" | jq -r '.versions[] | select(.num | startswith("1.0")) | .num' | head -10

# Also check the latest version
curl -s "https://crates.io/api/v1/crates/alloy" | jq -r '.crate.max_version'

Length of output: 257


@0xgleb You're absolutely correct, and I sincerely apologize for the misinformation. The shell script confirms that:

  • Alloy version 1.0.9 does exist and is indeed the latest version on crates.io
  • Multiple 1.0.x versions are available (1.0.0 through 1.0.9)

Your dependency specification alloy = { version = "1.0.9", features = ["json-rpc", "sol-types"] } is perfectly valid. The passing CI and the fact that it's available on crates.io were indeed clear evidence that my analysis was incorrect.

Thank you for the correction - the consolidation to alloy 1.0.9 with the specified features is exactly the right approach for this upgrade.


✏️ Learnings added
Learnt from: 0xgleb
PR: rainlanguage/rain.error#15
File: Cargo.toml:12-12
Timestamp: 2025-05-30T19:53:03.184Z
Learning: When analyzing Rust dependencies, always verify crate versions directly from crates.io API rather than relying on potentially outdated web search results. Use `curl -s "https://crates.io/api/v1/crates/{crate_name}" | jq -r '.crate.max_version'` to check the latest version and `jq -r '.versions[] | .num'` to see all available versions.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@hardyjosh hardyjosh merged commit bf08b5a into main Jun 2, 2025
6 checks passed
@0xgleb 0xgleb deleted the rust-upd branch June 2, 2025 22:41
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.

Upgrade rainix and Rust versions in rain.error Remove ethers dependency from rain.error

2 participants