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

Multichain #139

Merged
merged 14 commits into from
Oct 8, 2024
Merged

Multichain #139

merged 14 commits into from
Oct 8, 2024

Conversation

ryardley
Copy link
Contributor

@ryardley ryardley commented Oct 7, 2024

Closes: #140
Closes: #75
Closes: #134

  • Simplify evm package
  • Can send unrecovered errors directly to the bus for logging or recovery with bus.err(EnclaveErrorType::Evm, error)
  • Carry chain_id internally
  • Enable multichain args
  • Enable multichain config - here is an example
  • Match on chain_id when writing to chain
  • Integrated rust ABI interfaces with actual EVM contracts here, here and here as suggested by @auryn-macmillan

We should do the following a separate PR

  • Remove println + do logging
  • Support both http and websocket and automatically determine which protocol is required for reading and writing to evm
  • Add default configuration (once we have an actual testnet deployment)

Summary by CodeRabbit

  • New Features

    • Added src_chain_id field to several data structures for enhanced event context.
    • Introduced a centralized configuration management approach for launching ciphernodes.
    • New dependency on config crate for improved configuration handling.
    • New message types and improved error handling in various modules.
    • Enhanced functionality for interacting with Ethereum smart contracts through new structures and methods.
  • Bug Fixes

    • Enhanced error handling in get_committee method of DistanceSortition.
  • Documentation

    • Updated configuration files to reflect new structure and parameters.
  • Tests

    • Updated tests to accommodate the new src_chain_id field in event structures.
  • Chores

    • Refactored scripts for launching ciphernodes to utilize a configuration file.
    • Added new dependency on anyhow crate for improved error handling.

Copy link
Contributor

coderabbitai bot commented Oct 7, 2024

Warning

Rate limit exceeded

@ryardley has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 13 minutes and 52 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Files that changed from the base of the PR and between fdd5d45 and d0290a8.

Walkthrough

The pull request introduces significant changes across multiple files in the ciphernode project, primarily focusing on enhancing event handling and configuration management. Key modifications include the addition of the src_chain_id field in various structs, updates to constructors and methods to accommodate this new field, and the introduction of a centralized configuration management system using the config crate. The changes also involve the restructuring of the EVM module, splitting it into more manageable components aligned with specific smart contracts.

Changes

File Path Change Summary
packages/ciphernode/aggregator/src/plaintext_aggregator.rs Added src_chain_id: u64 to PlaintextAggregator and updated the new method to accept this parameter.
packages/ciphernode/aggregator/src/publickey_aggregator.rs Added src_chain_id: u64 to PublicKeyAggregator and updated ComputeAggregate to handle e3_id.
packages/ciphernode/core/src/eventbus.rs Introduced BusError trait for enhanced error handling.
packages/ciphernode/core/src/events.rs Added src_chain_id to PublicKeyAggregated, E3Requested, and PlaintextAggregated structs.
packages/ciphernode/core/src/ordered_set.rs Added Serialize and Deserialize traits to OrderedSet and introduced new methods for manipulation.
packages/ciphernode/enclave/Cargo.toml Added config crate dependency for configuration management.
packages/ciphernode/enclave/src/bin/aggregator.rs Updated Args struct to include a single config parameter instead of multiple contract addresses.
packages/ciphernode/enclave/src/lib.rs Introduced load_config function for loading application configuration.
packages/ciphernode/enclave/src/main.rs Modified Args struct and updated main function to utilize new configuration handling.
packages/ciphernode/enclave_node/Cargo.toml Added serde as a workspace dependency.
packages/ciphernode/enclave_node/src/aggregator.rs Updated attach method to accept AppConfig instead of multiple parameters.
packages/ciphernode/enclave_node/src/app_config.rs Added ContractAddresses, ChainConfig, and AppConfig structs for configuration management.
packages/ciphernode/enclave_node/src/ciphernode.rs Updated attach method to accept AppConfig and modified connection logic.
packages/ciphernode/evm/Cargo.toml Added tokio crate as a workspace dependency.
packages/ciphernode/evm/src/ciphernode_registry_sol.rs Introduced functionality for interacting with CiphernodeRegistry.sol smart contract.
packages/ciphernode/router/src/committee_meta.rs Added src_chain_id to CommitteeMeta struct.
packages/ciphernode/router/src/hooks.rs Updated create methods in LazyPlaintextAggregator and LazyPublicKeyAggregator to include src_chain_id.
packages/ciphernode/sortition/Cargo.toml Added anyhow crate as a workspace dependency.
packages/ciphernode/sortition/src/distance.rs Updated get_committee method to return Result<Vec<(BigInt, Address)>> for better error handling.
packages/ciphernode/sortition/src/sortition.rs Enhanced error handling in contains method of SortitionModule.
tests/basic_integration/lib/ciphernode_config.yaml Added new configuration section for blockchain settings.
tests/basic_integration/test.sh Updated script to utilize a centralized configuration file for launching ciphernodes.

Assessment against linked issues

Objective Addressed Explanation
Split the evm module into an actor per contract per chain (#140)
Support multiple chains (#75)
Sort out configuration (#134)

Possibly related PRs

Suggested reviewers

  • samepant
  • nginnever
  • hmzakhalid
  • auryn-macmillan

🐰 In the code we hop and play,
New fields and structs brighten the day.
Configs now central, neat and bright,
With chains connected, all feels right!
So let’s code and cheer, with joy we say,
Hooray for changes that come our way! 🐇✨


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

@ryardley ryardley marked this pull request as ready for review October 7, 2024 10:15
auryn-macmillan
auryn-macmillan previously approved these changes Oct 7, 2024
Copy link
Member

@auryn-macmillan auryn-macmillan left a comment

Choose a reason for hiding this comment

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

lgtm

@ryardley ryardley changed the base branch from ry/modularize to main October 8, 2024 00:03
@ryardley ryardley dismissed auryn-macmillan’s stale review October 8, 2024 00:03

The base branch was changed.

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

🧹 Outside diff range and nitpick comments (38)
packages/ciphernode/enclave_node/src/lib.rs (1)

7-8: Consider grouping export statements

For better readability and maintainability, consider grouping all pub use statements together. This can make it easier for developers to quickly see all the public exports in one place.

Here's a suggested reorganization:

 mod aggregator;
 mod app_config;
 mod ciphernode;
 
+pub use app_config::*;
 pub use aggregator::*;
 pub use ciphernode::*;
-
-pub use app_config::*;
tests/basic_integration/lib/ciphernode_config.yaml (1)

2-3: Consider adding more chain-specific information

While the current configuration is sufficient for basic functionality, consider adding more chain-specific information to enhance clarity and support future features. This could include:

  1. chain_id: The numeric identifier for the Hardhat network (typically 31337 for local networks).
  2. currency_symbol: The native currency symbol (e.g., "ETH" for Ethereum).
  3. block_time: The average block time for the network.

Example:

- name: "hardhat"
  chain_id: 31337
  currency_symbol: "ETH"
  block_time: 2
  rpc_url: "ws://localhost:8545"

This additional information could be useful for chain-specific logic and improve the overall robustness of the configuration.

packages/ciphernode/evm/src/lib.rs (1)

1-6: Approve new module structure with a suggestion for documentation.

The new module structure aligns well with the PR objective of improving maintainability through vertical slicing of the EVM module. The granular approach to handling different smart contracts (Enclave.sol, CiphernodeRegistry.sol, NaiveRegistryFilter.sol) is a good step towards better organization.

Consider adding a brief comment above each module declaration to explain its purpose and responsibilities. This will help developers understand the new structure more quickly.

Example:

/// Handles interactions with the CiphernodeRegistry smart contract
mod ciphernode_registry_sol;

/// Manages core Enclave contract functionality
mod enclave_sol;

/// Provides read operations for the Enclave contract
mod enclave_sol_reader;

/// Provides write operations for the Enclave contract
mod enclave_sol_writer;

/// Contains shared utility functions for EVM operations
pub mod helpers;

/// Implements filtering logic for the registry
mod registry_filter_sol;
packages/ciphernode/enclave/src/lib.rs (1)

4-13: LGTM: Well-structured configuration loading function.

The load_config function is well-implemented, using the config crate effectively and providing proper error handling. It correctly loads the configuration from the specified file and deserializes it into an AppConfig instance.

Consider additional error handling for empty or malformed config files.

While the function handles the case where the config file doesn't exist, it might be beneficial to add specific error handling for cases where the file exists but is empty or malformed. This could provide more informative error messages to users.

Consider adding a custom error type that wraps ConfigError and provides more context:

pub enum ConfigLoadError {
    FileNotFound(ConfigError),
    EmptyFile,
    MalformedContent(ConfigError),
    DeserializationError(ConfigError),
}

pub fn load_config(config_path: &str) -> Result<AppConfig, ConfigLoadError> {
    let config_builder = Config::builder()
        .add_source(File::with_name(&config_path).required(true))
        .build()
        .map_err(ConfigLoadError::FileNotFound)?;

    if config_builder.cache.is_empty() {
        return Err(ConfigLoadError::EmptyFile);
    }

    let config: AppConfig = config_builder
        .try_deserialize()
        .map_err(ConfigLoadError::DeserializationError)?;

    Ok(config)
}

Address TODO: Implement Ethereum address validation.

The TODO comment suggests that Ethereum address validation is needed. This is an important security consideration.

Would you like assistance in implementing Ethereum address validation? We could add a validation step after deserialization to ensure all Ethereum addresses in the AppConfig are valid.

packages/ciphernode/enclave/Cargo.toml (1)

16-16: LGTM! Consider using workspace-level dependency management.

The addition of the config crate (v0.14.0) is a good choice for improving configuration management in the project. This aligns well with the PR objectives, particularly addressing the configuration needs outlined in Issue #134.

Consider moving this dependency to the workspace-level Cargo.toml file if it's going to be used across multiple packages. This would ensure consistent versioning across the project. You can then reference it in this file using:

config = { workspace = true }

This approach would be consistent with how other dependencies like alloy and clap are managed in this file.

packages/ciphernode/enclave_node/src/app_config.rs (5)

1-3: Remove unused import

The HashMap import from std::collections is not used in this file. Consider removing it to keep the imports clean and relevant.

Apply this diff to remove the unused import:

-use std::collections::HashMap;

 use serde::Deserialize;

5-10: LGTM! Consider adding documentation

The ContractAddresses struct is well-defined and appropriate for holding contract addresses. The use of String type for addresses and deriving Debug and Deserialize traits are correct choices for configuration purposes.

Consider adding documentation comments to describe the purpose of this struct and its fields. This will improve code readability and maintainability. For example:

/// Holds the addresses of various contracts used in the application
#[derive(Debug, Deserialize)]
pub struct ContractAddresses {
    /// Address of the Enclave contract
    pub enclave: String,
    /// Address of the Ciphernode Registry contract
    pub ciphernode_registry: String,
    /// Address of the Filter Registry contract
    pub filter_registry: String,
}

12-18: LGTM! Consider adding documentation and planning for future enhancements

The ChainConfig struct is well-defined for chain-specific configuration. The use of Option<bool> for the enabled field is a good choice, allowing for explicit enable/disable or default behavior.

  1. Consider adding documentation comments to describe the purpose of this struct and its fields, similar to the suggestion for ContractAddresses.

  2. Regarding the comment about multiple RPC URLs:

    pub rpc_url: String, // We may need multiple per chain for redundancy at a later point

    It's good to plan for future enhancements. Consider creating a GitHub issue to track this potential feature, ensuring it's not forgotten and can be properly designed when needed.

Would you like me to create a GitHub issue for tracking the potential need for multiple RPC URLs per chain?


20-23: LGTM! Consider adding documentation and potential enhancements

The AppConfig struct is well-defined for holding multiple chain configurations. Using Vec<ChainConfig> allows for a flexible number of chain configurations, which aligns well with the multichain objectives of this PR.

  1. Consider adding documentation comments to describe the purpose of this struct and its field, similar to the previous suggestions.

  2. For future enhancements, you might want to consider:

    • Adding a version field to track configuration schema versions.
    • Including global application settings that are not chain-specific.

Here's an example of how you might implement these suggestions:

/// Represents the overall application configuration
#[derive(Debug, Deserialize)]
pub struct AppConfig {
    /// Version of the configuration schema
    pub version: String,
    /// Configurations for individual blockchain chains
    pub chains: Vec<ChainConfig>,
    /// Global application settings
    pub global_settings: GlobalSettings,
}

/// Global application settings
#[derive(Debug, Deserialize)]
pub struct GlobalSettings {
    // Add global settings here
}

Would you like me to propose these enhancements in a separate GitHub issue for future consideration?


1-23: Overall implementation aligns well with PR objectives

The app_config.rs file introduces a well-structured configuration system that aligns closely with the PR objectives and addresses key points from the linked issues:

  1. It supports multichain functionality by allowing multiple ChainConfig instances in AppConfig, addressing the requirement mentioned in Issue Support multiple chains #75.
  2. The configuration structure, using serde's Deserialize, facilitates easy management of both sensitive and non-sensitive data, as discussed in Issue Sort out configuration #134.
  3. The modular design with separate structs for ContractAddresses and ChainConfig contributes to the improved maintainability goal mentioned in Issue Vertically slice evm module for better maintainability #140.

This implementation provides a solid foundation for the multichain support and configuration management required by the project. It's flexible enough to accommodate future enhancements while meeting the current needs outlined in the PR objectives.

As the project evolves, consider the following architectural considerations:

  1. Implement a configuration validation mechanism to ensure all required fields are properly set before the application starts.
  2. Plan for backwards compatibility as the configuration structure evolves over time.
  3. Consider implementing a configuration migration system for seamless upgrades in the future.
packages/ciphernode/evm/src/enclave_sol.rs (3)

9-9: LGTM: Consider if state is needed for EnclaveSol.

The EnclaveSol struct is defined as an empty struct, which suggests it's being used as a namespace for associated functions. This aligns with the PR objective of simplifying the evm package. However, consider if any state (e.g., configuration data) should be associated with this struct to enhance its functionality and reduce parameter passing in methods.


10-21: LGTM: Consider adding chain_id parameter and explicit error handling.

The attach method effectively sets up both reading and writing capabilities for the Enclave contract. The use of Arc<PrivateKeySigner> aligns well with the PR objective of securely handling sensitive data.

However, consider the following improvements:

  1. Add a chain_id parameter to align with the PR objective of internal handling of chain_id.
  2. Implement more explicit error handling to provide clearer context in case of failures.

Here's a suggested modification:

pub async fn attach(
    bus: Addr<EventBus>,
    rpc_url: &str,
    contract_address: &str,
    signer: Arc<PrivateKeySigner>,
    chain_id: u64,
) -> Result<()> {
    EnclaveSolReader::attach(bus.clone(), rpc_url, contract_address, chain_id)
        .await
        .map_err(|e| anyhow::anyhow!("Failed to attach EnclaveSolReader: {}", e))?;
    EnclaveSolWriter::attach(bus, rpc_url, contract_address, signer, chain_id)
        .await
        .map_err(|e| anyhow::anyhow!("Failed to attach EnclaveSolWriter: {}", e))?;
    Ok(())
}

This modification adds the chain_id parameter and provides more context in error messages.


1-21: Overall assessment: Good implementation with room for minor improvements.

The EnclaveSol struct and its attach method provide a clean interface for setting up Enclave contract interactions, aligning well with the PR objectives of simplifying the evm package and enhancing event handling. The implementation effectively modularizes the functionality, separating reader and writer concerns.

Key strengths:

  1. Clear separation of concerns between reader and writer.
  2. Use of Arc<PrivateKeySigner> for secure handling of sensitive data.
  3. Asynchronous implementation for efficient I/O operations.

Suggestions for improvement:

  1. Consider adding state to the EnclaveSol struct if it would reduce parameter passing.
  2. Add a chain_id parameter to the attach method for better multichain support.
  3. Implement more explicit error handling for clearer debugging.

These improvements would further align the implementation with the PR objectives, particularly in terms of multichain support and error handling.

packages/ciphernode/router/src/committee_meta.rs (1)

21-31: LGTM: Proper integration of src_chain_id, consider error handling.

The changes correctly propagate the src_chain_id from the E3Requested event to the CommitteeMeta struct, which is in line with the PR objectives. The implementation is consistent and maintains the existing pattern.

Consider adding error handling in case the E3Requested event doesn't contain src_chain_id. This could be done by using the ? operator or a match statement to handle potential None values. For example:

let E3Requested {
    threshold_m,
    seed,
    src_chain_id,
    ..
} = data else {
    log::error!("E3Requested event is missing required fields");
    return;
};

This would make the code more robust against potential changes in the E3Requested struct.

packages/ciphernode/enclave/src/main.rs (2)

23-27: LGTM: Improved Args struct with centralized configuration

The changes to the Args struct align well with the PR objectives:

  1. Making the struct and address field public improves integration possibilities.
  2. Adding a config field and removing specific contract fields centralizes configuration management, supporting the multi-chain functionality.

These changes enhance flexibility and maintainability.

Consider adding a doc comment to the Args struct to explain its purpose and the expected format of the config field. This would improve code documentation:

/// Command-line arguments for the Ciphernode application
///
/// The `config` field should point to a JSON or YAML file containing
/// chain-specific configurations.
#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
pub struct Args {
    // ... existing fields ...
}

37-37: LGTM: Centralized configuration loading implemented

The use of load_config(&args.config)? successfully implements the centralized configuration loading as outlined in the PR objectives. This approach is more flexible and maintainable than the previous hardcoded contract address parsing.

Consider adding a more descriptive error message to improve debugging in case of configuration loading failures:

let config = load_config(&args.config).map_err(|e| format!("Failed to load config from {}: {}", args.config, e))?;

This will provide more context about which file failed to load and why.

packages/ciphernode/router/src/hooks.rs (2)

73-73: LGTM! Consider updating the method signature.

The addition of meta.src_chain_id when instantiating PlaintextAggregator is correct and aligns with the PR objectives for multichain support.

Consider updating the method signature of LazyPlaintextAggregator::create to include the meta parameter, ensuring consistency with the internal usage:

pub fn create(bus: Addr<EventBus>, sortition: Addr<Sortition>, meta: &Meta) -> EventHook

This change would make the method signature more explicit about its dependencies and improve code clarity.


107-107: LGTM! Consider updating the method signature.

The addition of meta.src_chain_id when instantiating PublicKeyAggregator is correct and aligns with the PR objectives for multichain support.

Similar to the suggestion for LazyPlaintextAggregator, consider updating the method signature of LazyPublicKeyAggregator::create to include the meta parameter:

pub fn create(bus: Addr<EventBus>, sortition: Addr<Sortition>, meta: &Meta) -> EventHook

This change would make the method signature more explicit about its dependencies and improve code clarity.

tests/basic_integration/test.sh (2)

113-113: Approve config file usage for aggregator ciphernode

The update to use a config file for launching the aggregator ciphernode is consistent with the changes made to regular ciphernode launch commands. This change supports the PR's goal of simplifying configuration management and enables multichain support.

Consider moving the PRIVATE_KEY to the config file for better security and consistency. If this is not feasible, ensure that the PRIVATE_KEY environment variable is properly secured and not logged or exposed in any way.


Line range hint 114-130: Approve addition of waiton-files function

The new waiton-files function is a valuable addition to the script. It enhances robustness by ensuring all necessary files exist before proceeding, and includes a timeout mechanism to prevent infinite waiting.

Consider adding a progress indicator to provide feedback during long waits:

 while true; do
   all_exist=true
   for file in "$@"; do
     if [ ! -f "$file" ]; then
       all_exist=false
       break
     fi
   done
   if $all_exist; then
     break
   fi
   if [ $(($(date +%s) - start_time)) -ge $timeout ]; then
     echo "Timeout waiting for files: $@" >&2
     return 1
   fi
+  echo -n "." >&2  # Add a progress indicator
   sleep 1
 done
+echo "" >&2  # Add a newline after the progress indicator
packages/ciphernode/aggregator/src/plaintext_aggregator.rs (1)

41-41: Consider adding error handling for src_chain_id

While the changes to include src_chain_id are correct and consistent with the PR objectives, consider adding error handling or validation for the src_chain_id value. This could include:

  1. Checking if the src_chain_id is valid or supported at the beginning of the new method.
  2. Adding a method to validate or update the src_chain_id if needed.
  3. Implementing error handling in case of mismatched chain IDs during event processing.

These additions would enhance the robustness of the multi-chain support.

Would you like assistance in implementing these error handling suggestions?

Also applies to: 53-53, 60-60, 189-189

packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs (4)

123-123: LGTM: src_chain_id field added to events, but consider parameterizing the chain ID.

The addition of the src_chain_id field to the E3Requested and PublicKeyAggregated events aligns with the PR objective of supporting multiple chains. The test assertions have been correctly updated to include this new field.

However, the src_chain_id is hardcoded to 1 in both instances. Consider parameterizing this value to make the test more flexible and to potentially test multiple chain scenarios in the future.

You could introduce a constant or a test parameter for the chain ID:

const TEST_CHAIN_ID: u64 = 1;

// Then use it in the event creation and assertions
src_chain_id: TEST_CHAIN_ID,

This approach would make it easier to modify the chain ID for different test scenarios in the future.

Also applies to: 145-183


284-284: LGTM: src_chain_id added to PlaintextAggregated events in P2P forwarding test.

The PlaintextAggregated events used in the P2P forwarding test have been correctly updated to include the src_chain_id field, ensuring that the P2P functionality is tested with the new event structure.

To improve the test:

  1. Consider using a parameterized value for src_chain_id as suggested earlier.
  2. It might be beneficial to test P2P forwarding with different src_chain_id values to ensure proper handling of events from multiple chains.

You could enhance the test by creating events with different src_chain_id values:

let evt_1 = EnclaveEvent::from(PlaintextAggregated {
    e3_id: E3id::new("1235"),
    decrypted_output: vec![1, 2, 3, 4],
    src_chain_id: 1,
});

let evt_2 = EnclaveEvent::from(PlaintextAggregated {
    e3_id: E3id::new("1236"),
    decrypted_output: vec![1, 2, 3, 4],
    src_chain_id: 2,
});

This would help verify that the P2P actor correctly handles and forwards events from different chains.

Also applies to: 290-290


339-339: LGTM: src_chain_id added to E3Requested event in P2P to bus forwarding test.

The E3Requested event used in the P2P to bus forwarding test has been correctly updated to include the src_chain_id field, ensuring that this functionality is tested with the new event structure.

To improve the test coverage:

  1. Consider using a parameterized value for src_chain_id as suggested earlier.
  2. It would be beneficial to test forwarding of events with different src_chain_id values to ensure proper handling of events from multiple chains.
  3. Consider adding assertions to verify that the src_chain_id is correctly preserved when the event is forwarded to the bus.

You could enhance the test by creating multiple events with different src_chain_id values and verifying their forwarding:

let chain_ids = vec![1, 2, 3];
for chain_id in chain_ids {
    let event = EnclaveEvent::from(E3Requested {
        e3_id: E3id::new(format!("1235_{}", chain_id)),
        threshold_m: 3,
        seed: seed.clone(),
        params: vec![1, 2, 3, 4],
        src_chain_id: chain_id,
    });

    let _ = input.send(event.to_bytes()?).await;
    
    sleep(Duration::from_millis(1)).await;
    
    let history = bus.send(GetHistory).await?;
    assert_eq!(history.last().unwrap(), &event, "Event with src_chain_id {} was not correctly forwarded", chain_id);
}

This approach would verify that events from multiple chains are correctly forwarded and preserved.


Line range hint 1-353: Overall assessment: Changes align with PR objectives, but test improvements recommended.

The modifications to this test file consistently implement the src_chain_id field across various events, aligning well with the PR objectives of supporting multiple chains and enhancing event handling. The tests cover crucial aspects of the system, including public key aggregation, decryption, and P2P event forwarding.

Recommendations for improvement:

  1. Parameterize the src_chain_id value to make tests more flexible and maintainable.
  2. Extend test coverage to include scenarios with multiple chain IDs, ensuring robust handling of multi-chain events.
  3. Add specific assertions to verify the correct preservation and handling of src_chain_id in forwarded events.

These enhancements would significantly strengthen the test suite, providing greater confidence in the system's ability to handle multi-chain scenarios correctly.

packages/ciphernode/sortition/src/distance.rs (1)

28-28: Add context to the error for better debugging

When parsing the hexadecimal string, adding context to the error can aid in debugging if the conversion fails. Consider mapping the error to include more detailed information.

You can modify the code as follows to add context:

let z = BigInt::from_str_radix(without_prefix, 16)
    .map_err(|e| anyhow!("Failed to parse BigInt from hex '{}': {}", without_prefix, e))?;
packages/ciphernode/enclave_node/src/ciphernode.rs (1)

68-68: Confirm default behavior for enabled chains

Using unwrap_or(true) means that chains without an explicit enabled flag are treated as enabled by default. Ensure this aligns with the intended configuration behavior. If the default should be to disable chains when enabled is unspecified, consider using unwrap_or(false) instead.

packages/ciphernode/enclave_node/src/aggregator.rs (1)

55-55: Security Consideration: Hardcoded Environment Variable

Using a hardcoded environment variable name "PRIVATE_KEY" may limit flexibility and could pose a security risk if not managed correctly.

Consider parameterizing the environment variable name, perhaps by adding it to the AppConfig or ChainConfig. This allows for better configuration management and aligns with best practices for handling sensitive information.

packages/ciphernode/core/src/eventbus.rs (1)

119-122: Add documentation comments to public trait and method

To enhance code maintainability and readability, please add documentation comments to the BusError trait and its err method.

Apply this diff to include the documentation:

+/// Trait to send errors directly to the event bus.
 pub trait BusError {
+    /// Sends an error event to the event bus.
     fn err(&self, err_type: EnclaveErrorType, err: anyhow::Error);
 }
packages/ciphernode/evm/src/enclave_sol_writer.rs (2)

86-90: Avoid unnecessary cloning of variables

In the handle method for PlaintextAggregated (lines 86-90), several variables are cloned:

let e3_id = msg.e3_id.clone();
let decrypted_output = msg.decrypted_output.clone();
let contract_address = self.contract_address.clone();
let provider = self.provider.clone();
let bus = self.bus.clone();

Cloning can be expensive, especially for large data structures. If possible, consider borrowing references or moving ownership if the variables are not needed elsewhere.

Possible refactoring:

- let e3_id = msg.e3_id.clone();
- let decrypted_output = msg.decrypted_output.clone();
- let contract_address = self.contract_address.clone();
- let provider = self.provider.clone();
- let bus = self.bus.clone();
+ let e3_id = msg.e3_id;
+ let decrypted_output = msg.decrypted_output;
+ let contract_address = self.contract_address;
+ let provider = self.provider.clone(); // Clone if needed elsewhere
+ let bus = self.bus.clone();           // Clone if needed elsewhere

Ensure that this change does not affect other parts of the code where these variables are used.


25-30: Document all fields in the EnclaveSolWriter struct

While there is a brief module-level comment, the fields within the EnclaveSolWriter struct (lines 25-30) lack individual documentation.

Providing documentation comments for each field improves code readability and aids future maintenance.

Example:

pub struct EnclaveSolWriter {
+   /// Provider with signer capabilities to interact with the blockchain
    provider: SignerProvider,
+   /// Address of the Enclave smart contract
    contract_address: Address,
+   /// Event bus for handling enclave events
    bus: Addr<EventBus>,
}
packages/ciphernode/evm/src/enclave_sol_reader.rs (3)

105-110: Derive traits for EnclaveSolReader as needed

The EnclaveSolReader struct may benefit from deriving standard traits like Debug to aid in logging and debugging. Ensure that necessary traits are derived to facilitate these activities.

Consider adding #[derive(Debug)]:

+#[derive(Debug)]
 pub struct EnclaveSolReader {
     provider: ReadonlyProvider,
     contract_address: Address,
     bus: Recipient<EnclaveEvent>,
 }

147-147: Consider starting from a configurable block number

Currently, the filter uses BlockNumberOrTag::Latest to start listening for events from the latest block. Depending on the application requirements, it might be necessary to start from a specific block number (e.g., the block when the contract was deployed) to capture all relevant events.

Consider making the starting block number configurable:

 let filter = Filter::new()
     .address(self.contract_address)
-    .from_block(BlockNumberOrTag::Latest);
+    .from_block(starting_block_number);

You can pass starting_block_number as a parameter or fetch it from the configuration.


44-44: Add documentation for E3RequestedWithChainId struct

The E3RequestedWithChainId struct combines an E3Requested event with a chain_id, but it lacks documentation. Adding a doc comment will improve code readability and maintainability.

Add a doc comment:

+/// A wrapper struct combining `E3Requested` event data with the `chain_id`.
 struct E3RequestedWithChainId(pub E3Requested, pub u64);
packages/ciphernode/core/src/ordered_set.rs (1)

213-229: Adjust test to avoid relying on element order

The OrderedSet uses a BTreeSet, which orders elements based on their natural ordering. While your test passes because the elements are sorted lexicographically, relying on this order might lead to brittle tests if the ordering criteria change.

Consider verifying the set contents without assuming order:

assert_eq!(set.len(), 3);
assert!(set.contains(&"apple".to_string()));
assert!(set.contains(&"banana".to_string()));
assert!(set.contains(&"cherry".to_string()));

let expected: BTreeSet<&String> = ["apple", "banana", "cherry"].iter().map(|s| s).collect();
let actual: BTreeSet<&String> = set.iter().collect();
assert_eq!(actual, expected);
packages/ciphernode/aggregator/src/publickey_aggregator.rs (1)

33-37: Add documentation for the new NotifyNetwork message

The NotifyNetwork struct has been introduced to handle network notifications. To maintain code clarity and assist other developers, consider adding Rust doc comments explaining the purpose and usage of this message.

Apply this diff to add documentation:

 #[derive(Message)]
 #[rtype(result = "anyhow::Result<()>")]
 struct NotifyNetwork {
+    /// The aggregated public key to be notified to the network
     pub pubkey: Vec<u8>,
+    /// The identifier for the E3 protocol instance
     pub e3_id: E3id,
 }
packages/ciphernode/core/src/events.rs (2)

48-53: Consider enhancing error handling in TryFrom<E3id> for U256 implementation.

The implementation correctly attempts to convert E3id to U256 using from_str_radix. However, adding context to the ParseError or logging the error may improve debugging in case of conversion failures.


323-327: Address the TODO comments or remove if obsolete.

The E3Requested struct contains several TODO comments for fields like threshold, computation_type, execution_model_type, input_deadline, and availability_duration. Consider implementing these fields if they are required for future functionality, or remove the comments to keep the codebase clean.

Would you like assistance in defining and implementing these fields?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 45cf291 and 805ac1a.

⛔ Files ignored due to path filters (1)
  • packages/ciphernode/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (36)
  • packages/ciphernode/aggregator/src/plaintext_aggregator.rs (3 hunks)
  • packages/ciphernode/aggregator/src/publickey_aggregator.rs (6 hunks)
  • packages/ciphernode/core/src/eventbus.rs (2 hunks)
  • packages/ciphernode/core/src/events.rs (5 hunks)
  • packages/ciphernode/core/src/ordered_set.rs (4 hunks)
  • packages/ciphernode/enclave/Cargo.toml (1 hunks)
  • packages/ciphernode/enclave/src/bin/aggregator.rs (1 hunks)
  • packages/ciphernode/enclave/src/lib.rs (1 hunks)
  • packages/ciphernode/enclave/src/main.rs (3 hunks)
  • packages/ciphernode/enclave_node/Cargo.toml (1 hunks)
  • packages/ciphernode/enclave_node/src/aggregator.rs (3 hunks)
  • packages/ciphernode/enclave_node/src/app_config.rs (1 hunks)
  • packages/ciphernode/enclave_node/src/ciphernode.rs (4 hunks)
  • packages/ciphernode/enclave_node/src/lib.rs (1 hunks)
  • packages/ciphernode/evm/Cargo.toml (1 hunks)
  • packages/ciphernode/evm/src/caller.rs (0 hunks)
  • packages/ciphernode/evm/src/ciphernode_registry.rs (0 hunks)
  • packages/ciphernode/evm/src/ciphernode_registry_sol.rs (1 hunks)
  • packages/ciphernode/evm/src/contracts.rs (0 hunks)
  • packages/ciphernode/evm/src/enclave.rs (0 hunks)
  • packages/ciphernode/evm/src/enclave_sol.rs (1 hunks)
  • packages/ciphernode/evm/src/enclave_sol_reader.rs (1 hunks)
  • packages/ciphernode/evm/src/enclave_sol_writer.rs (1 hunks)
  • packages/ciphernode/evm/src/helpers.rs (1 hunks)
  • packages/ciphernode/evm/src/lib.rs (1 hunks)
  • packages/ciphernode/evm/src/listener.rs (0 hunks)
  • packages/ciphernode/evm/src/manager.rs (0 hunks)
  • packages/ciphernode/evm/src/registry_filter_sol.rs (1 hunks)
  • packages/ciphernode/router/src/committee_meta.rs (2 hunks)
  • packages/ciphernode/router/src/hooks.rs (2 hunks)
  • packages/ciphernode/sortition/Cargo.toml (1 hunks)
  • packages/ciphernode/sortition/src/distance.rs (2 hunks)
  • packages/ciphernode/sortition/src/sortition.rs (3 hunks)
  • packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs (8 hunks)
  • tests/basic_integration/lib/ciphernode_config.yaml (1 hunks)
  • tests/basic_integration/test.sh (2 hunks)
💤 Files with no reviewable changes (6)
  • packages/ciphernode/evm/src/caller.rs
  • packages/ciphernode/evm/src/ciphernode_registry.rs
  • packages/ciphernode/evm/src/contracts.rs
  • packages/ciphernode/evm/src/enclave.rs
  • packages/ciphernode/evm/src/listener.rs
  • packages/ciphernode/evm/src/manager.rs
🧰 Additional context used
📓 Learnings (1)
packages/ciphernode/sortition/src/distance.rs (1)
Learnt from: ryardley
PR: gnosisguild/enclave#107
File: packages/ciphernode/sortition/src/distance.rs:1-1
Timestamp: 2024-09-26T03:11:29.311Z
Learning: In `packages/ciphernode/core/src/events.rs`, the import statements use the correct and updated `alloy::primitives` module.
🔇 Additional comments (45)
packages/ciphernode/enclave_node/src/lib.rs (1)

2-2: LGTM: Addition of app_config module

The introduction of the app_config module aligns well with the PR objectives, particularly addressing the configuration management needs outlined in Issue #134. This addition will likely improve the project's ability to handle both sensitive and non-sensitive configuration data.

tests/basic_integration/lib/ciphernode_config.yaml (1)

1-7: LGTM: Well-structured configuration file

The overall structure of the configuration file is well-organized and follows YAML best practices. The use of a chains array allows for easy extension to multiple chain configurations in the future, which aligns well with the multichain objectives of this PR.

packages/ciphernode/evm/Cargo.toml (1)

14-14: LGTM: Addition of tokio dependency enhances async capabilities.

The addition of the tokio dependency is a positive change that aligns with the PR objectives. It introduces asynchronous programming capabilities to the evm package, which can be beneficial for:

  1. Improving performance in I/O-bound operations, such as network requests to multiple chains.
  2. Enhancing the package's ability to handle concurrent tasks, which is crucial for multichain support.
  3. Better resource utilization, especially when dealing with multiple blockchain interactions.

The use of the workspace specification (tokio = { workspace = true }) ensures consistent versioning across the project, which is a good practice.

packages/ciphernode/enclave/src/lib.rs (1)

1-2: LGTM: Imports are appropriate for the function's needs.

The imports from the config crate and the custom AppConfig from enclave_node are correctly included and necessary for the load_config function.

packages/ciphernode/sortition/Cargo.toml (1)

17-17: Approved: Addition of anyhow dependency enhances error handling capabilities.

The inclusion of the anyhow crate as a workspace dependency is a positive change. This popular error handling library will likely improve error management across the project, aligning with the PR's objective of allowing direct sending of unrecovered errors to the bus for logging or recovery.

Benefits:

  1. Improved error handling and propagation.
  2. Consistent error types across the workspace.
  3. Simplified error conversion and chaining.
packages/ciphernode/evm/src/enclave_sol.rs (1)

1-7: LGTM: Imports are appropriate and aligned with PR objectives.

The imports cover all necessary dependencies for the EnclaveSol implementation, including local modules (enclave_sol_reader and enclave_sol_writer), standard library components, and external crates. These align well with the PR objectives of enhancing event handling and supporting multichain functionality.

packages/ciphernode/router/src/committee_meta.rs (1)

9-9: LGTM: Addition of src_chain_id field aligns with multichain support.

The new src_chain_id field in the CommitteeMeta struct is a good addition that supports the PR's objective of enabling multichain functionality. The u64 type is appropriate for storing chain IDs, and making it public is consistent with the struct's design.

packages/ciphernode/enclave_node/Cargo.toml (1)

30-30: LGTM: Addition of serde dependency is appropriate.

The addition of the serde crate as a workspace dependency is a good choice. This aligns well with the PR objectives, particularly in terms of improving configuration management and event handling. Serde is a powerful serialization/deserialization library that will likely be useful for these purposes.

Using a workspace dependency ensures version consistency across the project, which is a good practice.

packages/ciphernode/enclave/src/main.rs (3)

3-3: LGTM: New import for configuration loading

The addition of use enclave::load_config; aligns well with the PR objectives of improving maintainability and configuration management. This change suggests that configuration loading has been modularized, which is a good practice for code organization.


Line range hint 1-41: Summary: Successful implementation of centralized configuration and multi-chain support

The changes in this file effectively address the PR objectives:

  1. Centralized configuration management is implemented through the new config field and load_config function.
  2. The structure supports multiple chains by removing hardcoded contract addresses and using a flexible configuration approach.
  3. The code is more maintainable and modular, with clear separation of concerns.

These changes lay a solid foundation for the multi-chain functionality and improve the overall architecture of the Ciphernode application. Great job on these improvements!


38-38: LGTM: Updated MainCiphernode::attach with new configuration

The modification to MainCiphernode::attach(config, address) successfully integrates the new configuration approach into the main application logic. This change supports the PR objectives of enabling multi-chain functionality and improving the overall architecture.

To ensure that this change is consistently applied throughout the codebase, please run the following verification script:

This will help identify any locations where the method might still be called with the old argument structure.

✅ Verification successful

LGTM: Updated MainCiphernode::attach with new configuration

The change to MainCiphernode::attach(config, address) has been successfully verified across the codebase. All instances now correctly use the updated arguments, ensuring consistency and supporting multi-chain functionality.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that MainCiphernode::attach is called with the correct arguments across the codebase

# Test: Search for all occurrences of MainCiphernode::attach
# Expect: All calls should use two arguments (config and address)
rg --type rust "MainCiphernode::attach\s*\([^)]*\)" -g '!target/'

Length of output: 177

packages/ciphernode/router/src/hooks.rs (1)

73-73: Verify consistency of multichain changes across the codebase.

The changes to LazyPlaintextAggregator and LazyPublicKeyAggregator are consistent and align with the PR objectives for multichain support. To ensure full implementation:

Run the following script to check for similar patterns across the codebase:

Please review the output to ensure that all necessary components have been updated for multichain support.

Also applies to: 107-107

tests/basic_integration/test.sh (2)

Line range hint 1-180: Summary: Changes align well with PR objectives

The modifications to this integration test script effectively support the PR's goals of simplifying the evm package, enabling multichain support, and improving configuration management. Key improvements include:

  1. Updating the cleanup process to reflect architectural changes.
  2. Introducing a centralized configuration file for ciphernode launches, supporting multichain functionality.
  3. Enhancing script robustness with the new waiton-files function.

These changes contribute to a more maintainable and flexible testing process, which is crucial for supporting the project's evolving architecture and multichain capabilities.


78-79: Approve change in cleanup process

The update from killing "node" to "enclave" processes aligns with the PR's objective of simplifying the evm package. This change reflects the architectural updates in the project.

To ensure no unintended processes are left running, consider adding a verification step:

packages/ciphernode/aggregator/src/plaintext_aggregator.rs (3)

41-41: LGTM: Addition of src_chain_id field

The addition of the src_chain_id: u64 field to the PlaintextAggregator struct is appropriate and aligns with the PR objectives to support multiple chains. The u64 type is suitable for storing chain IDs, and the placement at the end of the struct follows Rust conventions.


53-53: LGTM: Updated new method with src_chain_id

The new method has been correctly updated to include the src_chain_id: u64 parameter, and the field is properly initialized in the struct. These changes are consistent with the addition of the new field and maintain the correct order of parameters.

Also applies to: 60-60


189-189: LGTM: Included src_chain_id in PlaintextAggregated event

The src_chain_id field has been correctly included in the PlaintextAggregated event. This change ensures that the chain ID information is properly propagated through the event system, which is consistent with the PR objectives for supporting multiple chains.

packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs (2)

4-5: LGTM: Import statements updated to include new event types.

The import statements have been appropriately updated to include additional event types (E3Requested, PlaintextAggregated, PublicKeyAggregated). This change aligns with the PR objectives of enhancing event handling and supporting multiple chains.


249-250: LGTM: src_chain_id added to PlaintextAggregated event assertion.

The PlaintextAggregated event assertion has been correctly updated to include the src_chain_id field, maintaining consistency with the other event modifications in this test.

As mentioned earlier, consider using a parameterized value for the src_chain_id instead of hardcoding it to 1. This would improve the test's flexibility and readability.

packages/ciphernode/enclave/src/bin/aggregator.rs (4)

1-2: Approved: Import Statements are Appropriate

The added imports for clap::Parser and enclave::load_config are necessary and correctly included.


8-10: Approved: Added 'config' Argument to Command-Line Interface

The addition of the config argument simplifies the command-line interface and aligns with the move towards centralized configuration management using the config crate.


23-23: Approved: Config Loaded Correctly Using load_config

The configuration is properly loaded from the provided config file path using load_config(&args.config)?, which aligns with the new centralized configuration approach.


25-29: Approved: Updated MainAggregator::attach Call with New Parameters

The MainAggregator::attach method is correctly updated to accept the config and optional paths. The use of as_deref() appropriately converts the Option<String> to Option<&str> as expected by the method.

packages/ciphernode/sortition/src/distance.rs (3)

2-2: Confirm the use of anyhow::Result for error handling

The addition of use anyhow::Result; is appropriate since the function now returns a Result type. This allows for better error propagation and aligns with the error handling conventions in the codebase.


28-32: Proper error propagation enhances robustness

Using the ? operator with BigInt::from_str_radix and collecting results into a Result<Vec<_>> is a good practice. It ensures that any errors during the conversion from hexadecimal string to BigInt are properly propagated, enhancing the robustness of the method.


36-36: Correctly returning the Result

Wrapping the result with Ok(result) aligns with the new return type Result<Vec<(BigInt, Address)>>, ensuring that the method conforms to its signature and properly communicates success to the caller.

packages/ciphernode/enclave_node/src/ciphernode.rs (2)

99-99: Properly wrap the return value in Ok

Wrapping (main_addr, join_handle) in Ok aligns with the new Result return type of the attach method, ensuring correct error propagation.


53-55: Ensure all calls to MainCiphernode::attach are updated to match the new signature

The attach method now accepts config: AppConfig and returns a Result. Please verify that all invocations of this method have been updated to use the new signature and handle the Result appropriately.

✅ Verification successful

All invocations of MainCiphernode::attach have been updated to match the new signature and handle the Result appropriately.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all calls to `MainCiphernode::attach` to verify they match the new signature.

# Search for all invocations of `MainCiphernode::attach`
rg --type rust --line-number "MainCiphernode::attach"

Length of output: 166


Script:

#!/bin/bash
# Description: Extract the specific call to `MainCiphernode::attach` for verification.

# Extract line 38 from packages/ciphernode/enclave/src/main.rs
sed -n '38p' packages/ciphernode/enclave/src/main.rs

Length of output: 122


Script:

#!/bin/bash
# Description: Find the definition of `MainCiphernode::attach` to verify its signature.

# Search for the function definition of `MainCiphernode::attach` in Rust files
rg "fn attach" --type rust

Length of output: 1401


Script:

#!/bin/bash
# Description: Extract the complete definition of `MainCiphernode::attach` to verify its signature.

# Use ast-grep to find the attach function definition in ciphernode.rs
ast-grep --lang rust --pattern 'fn attach($_) -> $_' packages/ciphernode/enclave_node/src/ciphernode.rs

Length of output: 105


Script:

#!/bin/bash
# Description: Extract the complete definition of `MainCiphernode::attach` to verify its signature.

# Search for the start of the `attach` function and include the next 5 lines to capture the full signature
rg -A5 "pub async fn attach" packages/ciphernode/enclave_node/src/ciphernode.rs

Length of output: 332

packages/ciphernode/enclave_node/src/aggregator.rs (1)

4-6: Updated Imports Reflect Refactored EVM Module

The imports now include helpers::pull_eth_signer_from_env and the EVM contract structs CiphernodeRegistrySol, EnclaveSol, and RegistryFilterSol. This aligns with the modularization and multichain support objectives outlined in the PR.

These changes are appropriate and support the new functionality introduced in the refactored EVM module.

packages/ciphernode/evm/src/helpers.rs (1)

42-42: ⚠️ Potential issue

Verify the existence of bus.err method

In line 42, the method bus.err(EnclaveErrorType::Evm, e); is called. However, Recipient<EnclaveEvent> may not have an err method. Please ensure that bus.err is a valid method or consider using bus.do_send to send an error event.

packages/ciphernode/sortition/src/sortition.rs (2)

5-5: Importing Address is appropriate and necessary

The addition of use alloy::primitives::Address; is necessary for parsing node addresses into the Address type.


109-109: Explicitly specifying actix::Context<Self> enhances clarity

Changing type Context = Context<Self>; to type Context = actix::Context<Self>; makes the context type explicit and improves code clarity.

packages/ciphernode/evm/src/enclave_sol_writer.rs (3)

113-113: Handle potential conversion errors when converting E3id to U256

In line 113, you're converting e3_id to U256:

let e3_id: U256 = e3_id.try_into()?;

Ensure that the E3id type properly implements TryInto<U256> and that all possible values of E3id can be converted without errors. If there's a possibility of conversion failure, consider handling it gracefully.

You can verify the implementation with the following script:

#!/bin/bash
# Description: Verify that E3id implements TryInto<U256>

# Test: Search for the implementation of TryInto for E3id
# Expected: Implementation exists without issues

rg --type rust 'impl TryInto<U256> for E3id' -A 5

17-23: Confirm correctness of the Enclave contract interface

The contract definition using the sol! macro (lines 17-23) defines the Enclave contract and its method:

function publishPlaintextOutput(uint256 e3Id, bytes memory plaintextOutput, bytes memory proof) external returns (bool success);

Ensure that this interface matches the actual Enclave.sol smart contract deployed on the blockchain. Any mismatch could lead to runtime errors when invoking the contract.

Consider verifying the contract's ABI or source code to confirm the method signature.

#!/bin/bash
# Description: Verify the Enclave contract interface matches the deployed contract

# Since we can't access the blockchain from here, ensure the local Solidity contract matches

rg --type solidity 'contract Enclave' -A 10

73-75: Verify chain ID comparison logic

In the handle method for EnclaveEvent (lines 70-79), the chain ID comparison is performed as:

if self.provider.get_chain_id() == data.src_chain_id {
    ctx.notify(data);
}

Ensure that the chain IDs are of compatible types and represent the same units (e.g., both are u64 or U256). Mismatched types or units could lead to incorrect behavior.

To verify the types, consider running the following script:

This script searches for the definitions to confirm that the types match.

✅ Verification successful

Chain ID comparison logic verified successfully

The get_chain_id function returns a u64, and data.src_chain_id is also a u64, ensuring type compatibility in the chain ID comparison.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check the definitions and types of get_chain_id() and data.src_chain_id

# Test: Ensure both chain IDs are of the same type
# Expected: Both should be of the same numeric type

ast-grep --lang rust --pattern $'impl SignerProvider {
    pub fn get_chain_id(&self) -> $_ {
        $$$
    }
}'

rg --type rust 'pub struct PlaintextAggregated' -A 10

Length of output: 1101


Script:

#!/bin/bash
# Description: Corrected script to check the return type of get_chain_id() in SignerProvider

# Extract the return type of get_chain_id()
ast-grep --lang rust --pattern 'impl SignerProvider {
    pub fn get_chain_id(&self) -> $_ {
        $$$
    }
}'

# Confirm the type of src_chain_id in PlaintextAggregated
rg --type rust 'pub struct PlaintextAggregated' -A 10

Length of output: 897


Script:

#!/bin/bash
# Description: Search for the definition of get_chain_id() across the entire Rust codebase

# Search for the implementation of get_chain_id()
rg --type rust 'fn get_chain_id'

Length of output: 113

packages/ciphernode/evm/src/enclave_sol_reader.rs (1)

46-56: Ensure all fields are correctly converted in From<E3RequestedWithChainId> implementation

The From trait implementation for converting E3RequestedWithChainId to enclave_core::E3Requested extracts several fields from the nested structures. Verify that all necessary fields are included and correctly mapped. Missing or incorrectly mapped fields might lead to incomplete data being processed downstream.

Run the following script to check the field mappings:

Please ensure that path/to/enclave_core.rs is replaced with the actual path to the enclave_core module.

packages/ciphernode/evm/src/ciphernode_registry_sol.rs (1)

14-30: Avoid code duplication by reusing existing definitions

The Solidity event definitions within the sol! macro may duplicate code present elsewhere in the project.

This concern was previously raised, and it appears to still be applicable. If possible, find a way to inherit or import these definitions directly from the EVM package to maintain a single source of truth.

packages/ciphernode/core/src/ordered_set.rs (2)

232-246: Good addition of tests for extend method

The test_extend function properly verifies the extend method's functionality, ensuring duplicates are handled correctly and the set contains all expected elements.


1-6: Ensure T implements Serialize and Deserialize

By deriving Serialize and Deserialize for OrderedSet<T>, it's important to note that T must also implement these traits. The compiler will enforce this when OrderedSet<T> is used with types that implement Serialize and Deserialize.

Run the following script to check if all usages of OrderedSet<T> use types T that implement Serialize and Deserialize:

✅ Verification successful

All OrderedSet<T> usages correctly implement Serialize and Deserialize.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find all instances where OrderedSet is used with types not implementing Serialize and Deserialize

# Test: Search for OrderedSet usages. Expect: All types used with OrderedSet implement Serialize and Deserialize.
rg --type rust "OrderedSet<[^>]+>" -A 2

Length of output: 5368

packages/ciphernode/aggregator/src/publickey_aggregator.rs (3)

185-185: Update handler signature to match trait definition

The handle method signature in impl Handler<ComputeAggregate> has been updated to include ctx: &mut Self::Context. This change ensures consistency with the expected trait signature and is necessary because ctx is now used within the method.


192-194: 🛠️ Refactor suggestion

Avoid unnecessary cloning of pubkey

The pubkey variable is cloned when passed to NotifyNetwork. Since pubkey is not used elsewhere after this point, you can move it instead of cloning to improve performance.

Apply this diff to move pubkey:

 ctx.notify(NotifyNetwork {
-    pubkey,
+    pubkey: pubkey,
     e3_id: msg.e3_id,
 });

Likely invalid or redundant comment.


30-31: Ensure e3_id is correctly propagated in ComputeAggregate

The addition of e3_id to the ComputeAggregate struct is crucial for maintaining message consistency. Verify that all instances where ComputeAggregate is instantiated include the appropriate e3_id to prevent any mismatches or processing errors.

Run the following script to locate all constructions of ComputeAggregate and check for the e3_id field:

packages/ciphernode/core/src/events.rs (3)

2-5: Imports are correctly added and utilized.

The added imports hex, Uint, and U256 from the alloy crate are required and appropriately used in the code.


14-14: OrderedSet import is necessary and properly used.

The import of OrderedSet is necessary for the updated structures and is correctly included.


312-313: Verify the impact of added fields on equality and hashing.

Adding nodes and src_chain_id to PublicKeyAggregated affects its PartialEq, Eq, and Hash implementations due to the derived traits. Confirm that including these fields in the equality and hash calculations is intended and won't lead to unexpected behavior in collections or comparisons.

You can run the following script to identify where PublicKeyAggregated is used in equality checks or hash-based collections:

✅ Verification successful

Impact of Added Fields on Equality and Hashing Verified

The addition of nodes and src_chain_id to PublicKeyAggregated has been reviewed. Only one equality check involving src_chain_id was identified, and no usages in hash-based collections were found. This indicates that the derived PartialEq, Eq, and Hash implementations are functioning as intended without introducing unexpected behavior.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Find usages of PublicKeyAggregated in equality checks and hash maps.

# Expected: Review these usages to ensure they function correctly with the new fields.
rg --type rust 'PublicKeyAggregated' -A 10 | rg '==|\.contains|HashMap|HashSet'

Length of output: 201

packages/ciphernode/evm/src/lib.rs Outdated Show resolved Hide resolved
tests/basic_integration/test.sh Show resolved Hide resolved
packages/ciphernode/core/src/ordered_set.rs Show resolved Hide resolved
packages/ciphernode/core/src/events.rs Show resolved Hide resolved
packages/ciphernode/core/src/events.rs Show resolved Hide resolved
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: 7

🧹 Outside diff range and nitpick comments (6)
packages/ciphernode/evm/src/lib.rs (2)

1-6: Approve new module structure

The restructured modules align well with the PR objectives, particularly the vertical slicing mentioned in Issue #140. Each module now corresponds to a specific smart contract or functionality, which should improve maintainability and separation of concerns.

Consider documenting the purpose of each module in comments to further enhance maintainability.


8-12: Approve new public API

The new public API provides a clear and focused interface for interacting with specific smart contracts. The naming convention is consistent and descriptive, and the separation of reader and writer functionalities aligns with good design practices.

Consider adding documentation comments for each exposed type to improve the API's usability.

package.json (1)

25-25: LGTM: Addition of preciphernode:build script improves build process.

The new preciphernode:build script is a great addition that ensures the EVM is compiled before building the ciphernode. This aligns well with the PR objectives by improving the build process and handling dependencies correctly.

Consider adding a comment in the package.json file to explain the purpose of this script, especially its relationship with ciphernode:build. This would improve maintainability for future developers. For example:

{
  "scripts": {
    // ... other scripts ...
    "preciphernode:build": "yarn evm:compile", // Ensures EVM is compiled before building ciphernode
    "ciphernode:build": "cd packages/ciphernode && cargo build --release"
  }
}
packages/ciphernode/evm/src/registry_filter_sol.rs (2)

28-58: LGTM: RegistryFilterSolWriter implementation with a minor suggestion.

The implementation of RegistryFilterSolWriter is well-structured with appropriate new and attach methods. The new method correctly initializes the struct, and the attach method properly sets up the actor and event subscription.

Consider adding error handling for the bus.send() call in the attach method:

- let _ = bus
-     .send(Subscribe::new("PublicKeyAggregated", addr.clone().into()))
-     .await;
+ bus.send(Subscribe::new("PublicKeyAggregated", addr.clone().into()))
+     .await
+     .map_err(|e| anyhow::anyhow!("Failed to subscribe to PublicKeyAggregated event: {}", e))?;

This change ensures that any subscription errors are properly propagated and handled.


64-77: LGTM: Handler implementation with a suggestion for improved logging.

The implementation correctly handles PublicKeyAggregated events and checks for matching chain IDs. This ensures that only relevant events are processed.

As suggested in a previous review, consider adding a warning log when chain IDs don't match:

 if self.provider.get_chain_id() == data.src_chain_id {
     ctx.notify(data);
+} else {
+    log::warn!(
+        "Received PublicKeyAggregated event with mismatched chain IDs: provider_chain_id={}, data_src_chain_id={}",
+        self.provider.get_chain_id(),
+        data.src_chain_id
+    );
 }

This will improve visibility into potential issues with mismatched chain IDs.

packages/ciphernode/evm/src/ciphernode_registry_sol.rs (1)

146-152: Consider Consolidating or Renaming attach Methods for Clarity

The CiphernodeRegistrySolReader and CiphernodeRegistrySol structs both have an attach method. This could lead to confusion and potential misuse.

Suggestion: Unify or Clearly Differentiate the attach Methods

  • If both methods serve the same purpose, consider removing one to avoid redundancy.

  • Alternatively, rename one of the methods to more accurately reflect its role. For example:

    pub struct CiphernodeRegistrySol;
    impl CiphernodeRegistrySol {
    -     pub async fn attach(bus: Addr<EventBus>, rpc_url: &str, contract_address: &str) -> Result<()> {
    +     pub async fn register(bus: Addr<EventBus>, rpc_url: &str, contract_address: &str) -> Result<()> {
            CiphernodeRegistrySolReader::attach(bus.clone(), rpc_url, contract_address).await?;
            Ok(())
        }
    }

This improves code readability and helps prevent confusion between methods.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 805ac1a and fdd5d45.

📒 Files selected for processing (6)
  • package.json (1 hunks)
  • packages/ciphernode/evm/src/ciphernode_registry_sol.rs (1 hunks)
  • packages/ciphernode/evm/src/enclave_sol_reader.rs (1 hunks)
  • packages/ciphernode/evm/src/enclave_sol_writer.rs (1 hunks)
  • packages/ciphernode/evm/src/lib.rs (1 hunks)
  • packages/ciphernode/evm/src/registry_filter_sol.rs (1 hunks)
🧰 Additional context used
🔇 Additional comments (27)
packages/ciphernode/evm/src/lib.rs (1)

5-5: Consider making the helpers module private

As mentioned in a previous review comment, if the helpers module is intended for internal use only, consider removing the pub modifier to encapsulate its usage within the crate. This would improve the module's encapsulation and prevent unintended external usage.

To verify the usage of the helpers module, please run the following script:

#!/bin/bash
# Description: Verify the contents and usage of the 'helpers' module

# Check the contents of the helpers module
echo "Contents of the helpers module:"
cat packages/ciphernode/evm/src/helpers.rs

# Check for usage of the helpers module in other files
echo "\nUsage of the helpers module in other files:"
rg --type rust "use (crate|super)::helpers" packages/ciphernode/evm/src

This will help determine if the helpers module should remain public or be made private.

package.json (2)

19-19: LGTM: Addition of ciphernode:lint script enhances code quality.

The new ciphernode:lint script is a valuable addition that introduces linting for the ciphernode package using Rust's cargo fmt tool. This aligns well with the PR objectives by improving code quality and maintainability.


19-25: Summary: Valuable improvements to build and lint processes.

The additions of ciphernode:lint and preciphernode:build scripts are valuable improvements to the project's build and lint processes. These changes align well with the PR objectives by:

  1. Enhancing code quality through linting of the ciphernode package.
  2. Improving the build process by ensuring proper compilation order.

These additions contribute to better maintainability and reliability of the project.

packages/ciphernode/evm/src/enclave_sol_writer.rs (9)

1-21: LGTM: Well-structured imports and contract interface definition

The imports are comprehensive and logically organized. The use of the sol! macro to define the IEnclave contract interface is a good practice for working with Ethereum contracts in Rust.


23-42: LGTM: Well-designed struct and constructor

The EnclaveSolWriter struct and its new method are well-designed. The use of Result for error handling in the constructor is a good practice, allowing for proper error propagation.


61-78: LGTM: Proper implementation of Actor and Handler traits

The implementation of the Actor trait and the Handler<EnclaveEvent> for EnclaveSolWriter is well-done. The chain ID check in the handle method aligns with the multichain objectives mentioned in the PR summary, ensuring that operations match on chain_id when writing to the chain.


96-97: Use a logging framework instead of println!

As mentioned in the previous comment, it's recommended to use a logging framework instead of println! for better control over logging levels and outputs. Consider using the log crate:

- println!("tx:{}", receipt.transaction_hash)
+ log::info!("Transaction hash: {}", receipt.transaction_hash);

Ensure that the logging framework is properly initialized in your application.


98-99: LGTM: Proper error handling using the event bus

The error handling approach aligns with the PR objective of sending unrecovered errors to the bus for logging or recovery. This is a good practice for centralized error management in a distributed system.


105-118: LGTM: Well-implemented publish_plaintext_output function

The publish_plaintext_output function is well-implemented. It correctly prepares the transaction data and sends it to the Enclave contract. The use of Result for error handling is a good practice, allowing for proper error propagation.


53-55: ⚠️ Potential issue

Implement error handling for event bus subscription

The previous comment about handling potential errors during event bus subscription has not been addressed. It's important to handle any errors that may occur during the subscription to ensure robustness.

Consider modifying the code to handle errors appropriately:

- let _ = bus
-     .send(Subscribe::new("PlaintextAggregated", addr.clone().into()))
-     .await;
+ bus
+     .send(Subscribe::new("PlaintextAggregated", addr.clone().into()))
+     .await
+     .map_err(|e| anyhow::anyhow!("Failed to subscribe to PlaintextAggregated event: {}", e))?;

This change will propagate any subscription errors, allowing for proper error handling and logging.


113-113: ⚠️ Potential issue

Replace hardcoded proof with actual proof data

The previous comment about replacing the hardcoded proof with actual proof data has not been addressed. Using a placeholder value for the proof may not be appropriate for production code.

Consider implementing a function to generate or fetch the actual proof:

- let proof = Bytes::from(vec![1]);
+ // TODO: Generate or fetch the actual proof required by the contract
+ let proof = generate_actual_proof(e3_id, decrypted_output).await?;

Implement the generate_actual_proof function to provide the correct proof data required by the smart contract.


1-118: Overall implementation meets PR objectives with minor improvements needed

The EnclaveSolWriter implementation successfully addresses the PR objectives of simplifying the evm package, allowing for direct sending of unrecovered errors to the bus, and introducing internal handling of the chain_id. The code structure and error handling practices are generally good.

However, there are a few minor issues that should be addressed to improve code quality and robustness:

  1. Implement error handling for the event bus subscription in the attach method.
  2. Replace println! with a proper logging framework.
  3. Replace the hardcoded proof with actual proof data in the publish_plaintext_output function.

Addressing these issues will further enhance the reliability and maintainability of the code.

To ensure that the logging framework is properly initialized and used throughout the codebase, run the following script:

packages/ciphernode/evm/src/registry_filter_sol.rs (4)

1-20: LGTM: Imports and smart contract interface definition.

The imports cover all necessary modules and types for the implementation. The smart contract interface for NaiveRegistryFilter is correctly defined using the sol! macro, referencing the appropriate JSON artifact.


22-27: LGTM: RegistryFilterSolWriter struct definition.

The RegistryFilterSolWriter struct is well-defined with appropriate fields for interacting with the smart contract and event bus. The use of SignerProvider, Address, and Addr types is correct for their intended purposes.


60-62: LGTM: Actor implementation for RegistryFilterSolWriter.

The Actor trait is correctly implemented for RegistryFilterSolWriter, setting the appropriate Context type. This implementation is necessary for the struct to function as an actor in the Actix system.


1-134: Overall assessment: Well-structured implementation with room for improvements.

The RegistryFilterSol functionality is generally well-implemented, with appropriate use of Actix actors, smart contract interactions, and event handling. However, several improvements can be made to enhance the code's robustness, maintainability, and adherence to best practices:

  1. Implement proper error handling for the event subscription in the attach method.
  2. Add warning logs for mismatched chain IDs in the Handler<EnclaveEvent> implementation.
  3. Replace println! with structured logging in the Handler<PublicKeyAggregated> implementation.
  4. Enhance error handling with more context in the Handler<PublicKeyAggregated> implementation.
  5. Handle parsing errors explicitly when processing node addresses in the publish_committee function.
  6. Consider removing the redundant RegistryFilterSol struct and its attach method.

Implementing these suggestions will significantly improve the overall quality and maintainability of the code.

packages/ciphernode/evm/src/enclave_sol_reader.rs (8)

1-15: Imports and contract bindings look good.

The imports cover all necessary modules and types for interacting with Ethereum and handling events. The sol! macro usage for generating Rust bindings from the IEnclave contract JSON ABI is correct and follows the project's conventions.


17-36: New struct and implementations align with multichain support objective.

The introduction of E3RequestedWithChainId and its implementations for conversion to enclave_core::E3Requested and EnclaveEvent successfully incorporate the src_chain_id field. This change aligns well with the PR objective of supporting multiple chains and ensures that the chain ID is properly propagated through the event system.


79-97: EnclaveSolReader struct looks good, but improve error handling in the new method.

The EnclaveSolReader struct and its new method align well with the PR objective of simplifying the evm package. However, the error handling in the new method could be improved to provide more context, especially for input parameter validation.

Consider applying this diff to improve error handling:

-        let provider = create_readonly_provider(rpc_url).await?;
+        let provider = create_readonly_provider(rpc_url).await.map_err(|e| {
+            anyhow::anyhow!("Failed to create provider for RPC URL '{}': {}", rpc_url, e)
+        })?;

This change will provide more context in case of an error, making it easier to diagnose issues during initialization.


1-127: Summary: EnclaveSolReader implementation aligns well with PR objectives

The enclave_sol_reader.rs file successfully implements multichain support and simplifies the evm package, addressing the objectives outlined in the PR and linked issues. Key achievements include:

  1. Introduction of the E3RequestedWithChainId struct to support multiple chains.
  2. Simplified and modular structure of the EnclaveSolReader actor.
  3. Implementation of event extraction and conversion logic.

To further improve the code, consider implementing the suggested enhancements to error handling and logging throughout the file. These improvements will significantly increase the robustness, maintainability, and debuggability of the system.

Overall, this implementation is a solid step towards achieving the project's multichain capabilities and improving its architecture.


54-76: ⚠️ Potential issue

Improve error handling and logging in the extractor function.

The extractor function's logic for decoding log data and converting it to EnclaveEvent is correct. However, there are some improvements needed:

  1. Replace println! statements with proper logging using a library like log or tracing. This aligns with a previous review comment and is more suitable for production code.
  2. Provide more detailed error information as indicated by the TODO comments.
  3. Consider using log::warn! for unknown events instead of println!.

Apply this diff to improve error handling and logging:

-                println!("Error parsing event E3Requested"); // TODO: provide more info
+                log::error!("Error parsing E3Requested event: {:?}", data);
 
-                println!("Error parsing event CiphertextOutputPublished"); // TODO: provide more info
+                log::error!("Error parsing CiphertextOutputPublished event: {:?}", data);
 
-            println!("Unknown event");
+            log::warn!("Unknown event with topic: {:?}", topic);

99-111: ⚠️ Potential issue

Improve logging and error handling in the attach method.

The attach method successfully creates and starts a new EnclaveSolReader instance. However, there are some improvements needed:

  1. Replace println! with proper logging using a library like log or tracing. This aligns with a previous review comment and is more suitable for production code.
  2. Improve error handling to provide more context, similar to the suggestion for the new method.

Apply these changes to improve logging and error handling:

-        let addr = EnclaveSolReader::new(bus.clone(), contract_address.parse()?, rpc_url)
+        let contract_addr = contract_address.parse().map_err(|e| {
+            anyhow::anyhow!("Failed to parse contract address '{}': {}", contract_address, e)
+        })?;
+        let addr = EnclaveSolReader::new(bus.clone(), contract_addr, rpc_url)
             .await?
             .start();
 
-        println!("Evm is listening to {}", contract_address);
+        log::info!("EVM is listening to contract address: {}", contract_address);

These changes will provide better error context and use proper logging, improving the overall robustness of the code.


113-127: ⚠️ Potential issue

Improve error handling in the spawned future within the started method.

The Actor implementation for EnclaveSolReader correctly sets up a stream to listen for events from the Ethereum network. However, the error handling in the spawned future could be improved to prevent silent failures.

Consider modifying the code to handle errors explicitly:

 ctx.spawn(
-    async move { helpers::stream_from_evm(provider, filter, bus, extractor).await }
+    async move {
+        if let Err(e) = helpers::stream_from_evm(provider, filter, bus, extractor).await {
+            log::error!("Error in stream_from_evm: {}", e);
+            // Consider implementing a retry mechanism or notifying a supervisor
+        }
+    }
         .into_actor(self),
 );

This change ensures that any errors occurring in the stream_from_evm function are logged and not silently ignored, improving the reliability and debuggability of the system.


38-52: CiphertextOutputPublished event handling looks correct, but verify chain ID requirement.

The implementations for converting IEnclave::CiphertextOutputPublished to enclave_core::CiphertextOutputPublished and EnclaveEvent are logically correct. However, unlike the E3RequestedWithChainId struct, there's no chain ID included in these conversions.

Could you confirm if the chain ID is not required for CiphertextOutputPublished events? If it is needed, we should update these implementations to include it.

packages/ciphernode/evm/src/ciphernode_registry_sol.rs (3)

1-13: Imports and Module Setup Are Correct

The necessary crates and modules are imported, and the code is well-organized. The use of the sol macro is appropriate for interfacing with Solidity contracts.


20-65: Trait Implementations for Event Conversion Are Correct

The From trait implementations for converting Solidity events to Rust structures are correctly defined, facilitating seamless data transformation between the EVM and the enclave.


93-113: Struct Initialization and new Method Are Properly Defined

The CiphernodeRegistrySolReader struct and its new method correctly initialize the provider, contract address, and event bus. The use of asynchronous initialization with proper error handling is appropriate.

@ryardley
Copy link
Contributor Author

ryardley commented Oct 8, 2024

Conversations have been resolved most were around fixing up stuff tabled for future PRs like logging / error handling. This is ready for review / merge. @auryn-macmillan @hmzakhalid @nginnever

Copy link
Member

@auryn-macmillan auryn-macmillan left a comment

Choose a reason for hiding this comment

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

lgtm

@ryardley ryardley merged commit cd71c3f into main Oct 8, 2024
3 checks passed
@ryardley ryardley deleted the ry/multi-chain branch December 5, 2024 06:39
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.

Vertically slice evm module for better maintainability Sort out configuration Support multiple chains
3 participants