Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(torii): add eth address to ty and remove usize #2989

Merged
merged 3 commits into from
Feb 5, 2025

Conversation

Larkooo
Copy link
Collaborator

@Larkooo Larkooo commented Feb 4, 2025

Summary by CodeRabbit

  • New Features

    • Introduced enhanced support for Ethereum address handling, including improved conversion, serialization, and integration with storage operations.
    • Added a new EthAddress variant to the Primitive enum, replacing the previous USize variant.
  • Bug Fixes

    • Removed references to the USize type across various functionalities, ensuring consistent handling of primitive types.
  • Tests

    • Updated test suites to validate the new Ethereum address functionality, removing all references to the USize type.

Copy link

coderabbitai bot commented Feb 4, 2025

Ohayo, sensei!

Walkthrough

The changes update the Primitive enum in the codebase by removing the USize variant and introducing the EthAddress variant. New getter (as_eth_address) and setter (set_eth_address) methods have been added to handle this variant. Additionally, methods such as to_numeric, to_sql_type, serialization, and deserialization have been revised to accommodate the new variant. Test cases have been updated to include checks for EthAddress while removing those related to USize.

Changes

File(s) Change Summary
crates/.../primitive.rs - Removed USize variant
- Added EthAddress variant
- Added getter as_eth_address and setter set_eth_address
- Updated to_numeric, to_sql_type, serialization/deserialization routines, and test cases
crates/.../schema.rs - Added EthAddress variant
- Updated to_json_value, from_json_value, and format_member methods
crates/.../schema.proto - Removed usize field
- Added eth_address field
- Reordered existing fields
crates/.../src/types/schema.rs - Added handling for EthAddress in try_from and from implementations
- Removed handling for USize
crates/.../sqlite/src/model.rs - Added handling for EthAddress in map_row_to_ty function
- Removed handling for USize
crates/.../typed-data/src/test.rs - Added tests for EthAddress in test_parse_primitive_to_ty and test_map_ty_to_primitive
- Removed tests for USize
crates/.../typed-data/src/typed_data.rs - Removed handling for Primitive::USize
- Added handling for Primitive::EthAddress

Sequence Diagram(s)

sequenceDiagram
    participant Caller
    participant PrimitiveInstance

    Caller->>PrimitiveInstance: set_eth_address(Some(address))
    PrimitiveInstance-->>Caller: Ok/Result

    Caller->>PrimitiveInstance: as_eth_address()
    PrimitiveInstance-->>Caller: Option(address)
Loading

Possibly related PRs

  • feat(libp2p): multi signature schemes & session signing #2599: The changes in the main PR are related to the addition of the EthAddress variant in the Primitive enum, which is also reflected in the retrieved PR's modifications to the handling of primitive types, specifically the removal of USize and the introduction of EthAddress.
  • fix(torii-grpc): deser from db for grpc enums #2259: The changes in the main PR are related to the addition and handling of the EthAddress variant in the Primitive enum, which is also addressed in the retrieved PR through modifications to the deserialization logic for enums and optional primitives, including Primitive.
  • feat(torii-core): json value for ty for efficient json ser #2730: The changes in the main PR are directly related to the modifications of the Primitive enum, specifically the addition of the EthAddress variant and the removal of the USize variant, which are also reflected in the retrieved PR's updates to the Ty enum in schema.rs.

Suggested reviewers

  • glihm

Tip

🌐 Web search-backed reviews and chat
  • We have enabled web search-based reviews and chat for all users. This feature allows CodeRabbit to access the latest documentation and information on the web.
  • You can disable this feature by setting web_search: false in the knowledge_base settings.
  • Please share any feedback in the Discord discussion.

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4fa9c5a and 533d0c6.

📒 Files selected for processing (1)
  • crates/sozo/ops/src/model.rs (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: build
  • GitHub Check: clippy
🔇 Additional comments (1)
crates/sozo/ops/src/model.rs (1)

199-199: Ohayo! The EthAddress variant looks good, sensei!

The implementation follows the established pattern for primitive types and maintains consistent case style.

Let's verify that this change is consistent with the Primitive enum definition:

✅ Verification successful

Ohayo! The EthAddress variant is represented correctly, sensei!

  • The variant is defined in the Primitive enum (as seen in crates/dojo/types/src/primitive.rs) and its string representation in the match arms follows the established conventions.
  • The pattern matching and naming in crates/sozo/ops/src/model.rs is consistent with its usage in the rest of the codebase.
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the EthAddress variant in the Primitive enum definition
ast-grep --pattern 'enum Primitive {
  $$$
  EthAddress($_)
  $$$
}'

Length of output: 70


Script:

#!/bin/bash
# Let's search for the Primitive enum definition and check for the EthAddress variant across the repository.
echo "Searching for 'enum Primitive' definitions..."
rg -n "enum[[:space:]]+Primitive" .

echo "-------------------------------"

echo "Searching for 'EthAddress' occurrences..."
rg -n "EthAddress" .

Length of output: 11446


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

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.

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: 1

🧹 Nitpick comments (2)
crates/dojo/types/src/primitive.rs (2)

147-162: Consider adding validation for Ethereum address format.

Ohayo sensei! While the numeric mapping is correct, consider adding validation to ensure the Ethereum address follows the standard format (20 bytes).

 impl Primitive {
+    fn validate_eth_address(felt: &Felt) -> Result<(), PrimitiveError> {
+        let bytes = felt.to_bytes_be();
+        if bytes[..12].iter().any(|&b| b != 0) {
+            return Err(PrimitiveError::InvalidByteLength(32, 20));
+        }
+        Ok(())
+    }

482-484: Enhance test coverage for EthAddress validation.

Ohayo sensei! The basic tests are good, but consider adding tests for:

  1. Invalid Ethereum addresses (>20 bytes)
  2. Edge cases (zero address, max value address)
  3. Common Ethereum addresses (e.g., null address 0x0000...0000)
#[test]
fn test_eth_address_validation() {
    // Test invalid address (>20 bytes)
    let mut primitive = Primitive::EthAddress(None);
    let invalid_felt = Felt::from_str("0x1234567890123456789012345678901234567890").unwrap();
    assert!(primitive.set_eth_address(Some(invalid_felt)).is_err());

    // Test zero address
    let zero_felt = Felt::ZERO;
    assert!(primitive.set_eth_address(Some(zero_felt)).is_ok());
}

Also applies to: 510-513

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf0c5ee and d6ca2cb.

📒 Files selected for processing (1)
  • crates/dojo/types/src/primitive.rs (9 hunks)
🧰 Additional context used
🪛 GitHub Actions: ci
crates/dojo/types/src/primitive.rs

[warning] 141-141: Formatting issue detected. Please ensure proper formatting.


[warning] 507-507: Formatting issue detected. Please ensure proper formatting.

🔇 Additional comments (4)
crates/dojo/types/src/primitive.rs (4)

47-48: LGTM! The EthAddress variant is properly defined.

Ohayo! The new EthAddress variant is correctly added with proper attributes and type definition.


126-126: LGTM! Getter and setter macros are properly implemented.

The as_eth_address and set_eth_address macros are correctly generated using the existing macro templates.

Also applies to: 143-143


189-190: LGTM! SQL type mapping is appropriate.

The EthAddress is correctly mapped to SqlType::Text which is appropriate for storing Ethereum addresses.


141-141: Fix formatting issues flagged by CI.

Ohayo! The CI pipeline has flagged formatting issues. Please run cargo fmt to fix them.

Also applies to: 507-507

🧰 Tools
🪛 GitHub Actions: ci

[warning] 141-141: Formatting issue detected. Please ensure proper formatting.

Comment on lines +331 to +333
Primitive::EthAddress(ref mut value) => {
*value = Some(felts.remove(0));
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding address validation in serialization/deserialization.

Ohayo sensei! The serialization/deserialization logic should validate the Ethereum address format.

 Primitive::EthAddress(ref mut value) => {
-    *value = Some(felts.remove(0));
+    let felt = felts.remove(0);
+    Self::validate_eth_address(&felt)?;
+    *value = Some(felt);
 }

Also applies to: 397-399

@Larkooo Larkooo changed the title feat(torii): add eth address to ty feat(torii): add eth address to ty and remove usize Feb 4, 2025
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: 3

🧹 Nitpick comments (2)
crates/torii/typed-data/src/test.rs (1)

65-68: Enhance test coverage with real Ethereum addresses.

Ohayo sensei! The test should include actual Ethereum addresses to ensure proper handling of real-world data.

Add these test cases:

+    // Test with a real Ethereum address
+    let mut ty = Ty::Primitive(Primitive::EthAddress(None));
+    let value = PrimitiveType::String("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045".to_string());
+    parse_value_to_ty(&value, &mut ty).unwrap();
+    assert_eq!(ty, Ty::Primitive(Primitive::EthAddress(Some(Felt::from_hex_be("0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045").unwrap()))));
+
+    // Test with an invalid Ethereum address
+    let mut ty = Ty::Primitive(Primitive::EthAddress(None));
+    let value = PrimitiveType::String("invalid".to_string());
+    assert!(parse_value_to_ty(&value, &mut ty).is_err());
crates/dojo/types/src/primitive.rs (1)

47-48: Document the EthAddress variant.

Ohayo sensei! Consider adding documentation to explain the expected format and validation rules for Ethereum addresses.

Add this documentation:

 #[strum(serialize = "EthAddress")]
+/// Represents an Ethereum address as a Felt.
+/// The address must be 20 bytes (40 hex characters) long.
 EthAddress(Option<Felt>),
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d6ca2cb and 4fa9c5a.

📒 Files selected for processing (7)
  • crates/dojo/types/src/primitive.rs (9 hunks)
  • crates/dojo/types/src/schema.rs (3 hunks)
  • crates/torii/grpc/proto/schema.proto (1 hunks)
  • crates/torii/grpc/src/types/schema.rs (2 hunks)
  • crates/torii/sqlite/src/model.rs (1 hunks)
  • crates/torii/typed-data/src/test.rs (2 hunks)
  • crates/torii/typed-data/src/typed_data.rs (3 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: build
  • GitHub Check: ensure-wasm
  • GitHub Check: clippy
  • GitHub Check: docs
🔇 Additional comments (8)
crates/dojo/types/src/primitive.rs (1)

331-333: Consider adding address validation in serialization/deserialization.

crates/dojo/types/src/schema.rs (3)

364-364: Ohayo! The EthAddress JSON serialization looks good, sensei!

The implementation follows the same pattern as other address types, using hex formatting.


481-485: The EthAddress deserialization is well-implemented, sensei!

The implementation correctly parses the string representation into a Felt value.


742-746: Nice formatting implementation for EthAddress, sensei!

The formatting follows the consistent pattern used for other address types.

crates/torii/typed-data/src/typed_data.rs (3)

610-612: Ohayo! The EthAddress parsing looks good, sensei!

The implementation correctly handles string-to-Felt conversion for Ethereum addresses.


683-685: Clean implementation of EthAddress mapping, sensei!

The conversion to string representation follows the same pattern as other address types.


740-743: Well-structured type mapping for EthAddress, sensei!

The field type is correctly mapped to "EthAddress" string.

crates/torii/grpc/proto/schema.proto (1)

28-32: Ohayo! The protobuf field changes look good, sensei!

The changes maintain backward compatibility by:

  1. Removing the usize field
  2. Shifting subsequent fields (bool, felt252, class_hash, contract_address)
  3. Adding eth_address as the last field

Let's verify that there are no breaking changes in the field numbers:

✅ Verification successful

Ohayo sensei! It looks like our initial inspection hit a snag due to the file type issue. Let's re-run the verification using a revised shell script that avoids the proto file type limitation and directly targets the expected changes.

Please run this script for manual verification. Once confirmed that there are no stray "usize" references and the fields in schema.proto reflect the intended update and ordering, we can conclude that the changes are consistent and maintain backward compatibility.


Ohayo sensei! The schema changes are looking solid. We verified that:

  • There are no stray references to usize in any .proto files.
  • The relevant section of schema.proto (lines 25-35) shows the expected field ordering.
  • The fields have the correct numbering: bool = 12, felt252 = 13, class_hash = 14, contract_address = 15, and eth_address = 16.

Everything checks out as intended.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for any references to the old field numbers
# This helps ensure that all client code has been updated

rg -A 5 "field.*=.*1[2-6]" --type proto

Length of output: 71


Script:

#!/bin/bash
# 1. Check for any residual "usize" references in all .proto files.
echo "Searching for 'usize' in .proto files..."
rg "usize" --glob "**/*.proto"

# 2. Display the relevant section of schema.proto to verify the field ordering and numbering.
echo "Showing lines 25-35 of crates/torii/grpc/proto/schema.proto:"
sed -n '25,35p' crates/torii/grpc/proto/schema.proto

# 3. Verify that the expected field numbers are present in schema.proto.
echo "Verifying field numbering in schema.proto for expected fields:"
rg "bool = 12|felt252 = 13|class_hash = 14|contract_address = 15|eth_address = 16" crates/torii/grpc/proto/schema.proto

Length of output: 955

Comment on lines +236 to +238
Primitive::EthAddress(felt) => proto::types::primitive::PrimitiveType::EthAddress(
felt.unwrap_or_default().to_bytes_be().to_vec(),
),
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add validation for Ethereum address serialization.

The serialization should ensure the address is properly formatted.

Apply this diff to add validation:

 Primitive::EthAddress(felt) => proto::types::primitive::PrimitiveType::EthAddress(
-    felt.unwrap_or_default().to_bytes_be().to_vec(),
+    {
+        let bytes = felt.unwrap_or_default().to_bytes_be();
+        // Take only the last 20 bytes for Ethereum address
+        bytes[12..].to_vec()
+    }
 ),
📝 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
Primitive::EthAddress(felt) => proto::types::primitive::PrimitiveType::EthAddress(
felt.unwrap_or_default().to_bytes_be().to_vec(),
),
Primitive::EthAddress(felt) => proto::types::primitive::PrimitiveType::EthAddress(
{
let bytes = felt.unwrap_or_default().to_bytes_be();
// Take only the last 20 bytes for Ethereum address
bytes[12..].to_vec()
}
),

Comment on lines +177 to +179
proto::types::primitive::PrimitiveType::EthAddress(felt) => {
Primitive::EthAddress(Some(Felt::from_bytes_be_slice(felt.as_slice())))
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding Ethereum address validation.

Ohayo sensei! The conversion from bytes to Ethereum address should validate the address format to prevent invalid addresses.

Apply this diff to add validation:

 proto::types::primitive::PrimitiveType::EthAddress(felt) => {
-    Primitive::EthAddress(Some(Felt::from_bytes_be_slice(felt.as_slice())))
+    let address = Felt::from_bytes_be_slice(felt.as_slice());
+    // Validate that the address is 20 bytes (40 hex chars)
+    if felt.len() != 20 {
+        return Err(SchemaError::InvalidByteLength(felt.len(), 20));
+    }
+    Primitive::EthAddress(Some(address))
 }
📝 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
proto::types::primitive::PrimitiveType::EthAddress(felt) => {
Primitive::EthAddress(Some(Felt::from_bytes_be_slice(felt.as_slice())))
}
proto::types::primitive::PrimitiveType::EthAddress(felt) => {
let address = Felt::from_bytes_be_slice(felt.as_slice());
// Validate that the address is 20 bytes (40 hex chars)
if felt.len() != 20 {
return Err(SchemaError::InvalidByteLength(felt.len(), 20));
}
Primitive::EthAddress(Some(address))
}

Comment on lines +346 to +353
Primitive::EthAddress(_) => {
let value = row.try_get::<String, &str>(column_name)?;
if !value.is_empty() {
primitive.set_eth_address(Some(
Felt::from_str(&value).map_err(ParseError::FromStr)?,
))?;
}
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add Ethereum address validation when mapping from SQL.

Ohayo sensei! The mapping should validate that the string from SQL represents a valid Ethereum address.

Apply this diff to add validation:

 Primitive::EthAddress(_) => {
     let value = row.try_get::<String, &str>(column_name)?;
     if !value.is_empty() {
+        // Validate Ethereum address format (0x followed by 40 hex chars)
+        if !value.starts_with("0x") || value.len() != 42 {
+            return Err(Error::Parse(ParseError::FromStr(
+                "Invalid Ethereum address format".into(),
+            )));
+        }
         primitive.set_eth_address(Some(
             Felt::from_str(&value).map_err(ParseError::FromStr)?,
         ))?;
     }
 }
📝 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
Primitive::EthAddress(_) => {
let value = row.try_get::<String, &str>(column_name)?;
if !value.is_empty() {
primitive.set_eth_address(Some(
Felt::from_str(&value).map_err(ParseError::FromStr)?,
))?;
}
}
Primitive::EthAddress(_) => {
let value = row.try_get::<String, &str>(column_name)?;
if !value.is_empty() {
// Validate Ethereum address format (0x followed by 40 hex chars)
if !value.starts_with("0x") || value.len() != 42 {
return Err(Error::Parse(ParseError::FromStr(
"Invalid Ethereum address format".into(),
)));
}
primitive.set_eth_address(Some(
Felt::from_str(&value).map_err(ParseError::FromStr)?,
))?;
}
}

Copy link

codecov bot commented Feb 4, 2025

Codecov Report

Attention: Patch coverage is 31.25000% with 44 lines in your changes missing coverage. Please review.

Project coverage is 56.96%. Comparing base (bf0c5ee) to head (533d0c6).
Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
crates/dojo/types/src/primitive.rs 29.62% 19 Missing ⚠️
crates/dojo/types/src/schema.rs 0.00% 9 Missing ⚠️
crates/torii/sqlite/src/model.rs 0.00% 6 Missing ⚠️
crates/torii/grpc/src/types/schema.rs 0.00% 5 Missing ⚠️
crates/torii/typed-data/src/typed_data.rs 55.55% 4 Missing ⚠️
crates/sozo/ops/src/model.rs 0.00% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2989      +/-   ##
==========================================
- Coverage   56.97%   56.96%   -0.02%     
==========================================
  Files         426      426              
  Lines       56376    56381       +5     
==========================================
- Hits        32119    32116       -3     
- Misses      24257    24265       +8     

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

@Larkooo Larkooo enabled auto-merge (squash) February 4, 2025 16:54
@Larkooo Larkooo merged commit 1d2381c into dojoengine:main Feb 5, 2025
13 of 15 checks passed
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