Skip to content

Conversation

@fbac
Copy link
Collaborator

@fbac fbac commented Mar 5, 2025

Summary

Summary by CodeRabbit

  • New Features

    • Streamlined CLI commands for node management by removing outdated health commands and introducing new commands for enabling/disabling nodes and adjusting configurations.
    • Introduced an optional minimum monthly fee during node registration.
    • Expanded administrative capabilities with new options to adjust commission, set active node limits, and update service endpoints.
    • Enhanced transaction execution for smoother blockchain operations.
    • Added new environment variables for improved node registration and management.
    • Introduced new test functions to validate node management functionalities.
  • Refactor

    • Consolidated node data structures and removed legacy versioning for simplified logic.
    • Updated configuration retrieval to ensure consistent contract addressing.
    • Transitioned to a unified nodes contract for improved management and access control.
  • Tests

    • Expanded test coverage to validate new node management functions and transaction handling.
    • Introduced tests for new functionalities related to node operations and configurations.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 5, 2025

Walkthrough

This pull request refactors the node management and command structure. It removes deprecated update commands from the CLI and reorders the command registration flow. The changes update the blockchain registry admin by removing versioning, adding new node management methods, and revising the AddNode signature to include a minimum monthly fee. Test functions, configuration retrieval, and migrator methods are updated for consistency. A new helper function for executing Ethereum transactions is introduced, streamlining transaction handling and event processing.

Changes

File(s) Change Summary
cmd/cli/main.go Removed the UpdateHealth command, introduced new commands for node management, updated command registration logic, and modified the registerNode function to include minMonthlyFee handling.
pkg/blockchain/registryAdmin.go Removed versioning constructs and deprecated methods, updated the AddNode signature to include minMonthlyFee, and added new methods for node management. Centralized transaction execution via an ExecuteTransaction helper.
pkg/blockchain/registryAdmin_test.go Simplified buildRegistry (removed version parameter), introduced an addRandomNode helper, refactored tests to use the new structure, and added tests for new node management methods.
pkg/testutils/config.go Removed the deprecated contractInfo struct and getDeployedTo function; updated GetContractsOptions to retrieve the contract address via the new getContractAddress function with an updated file path.
pkg/blockchain/client.go Introduced a new ExecuteTransaction function that wraps Ethereum transaction execution, validates the signer, and processes events via provided parser and log handler.
pkg/blockchain/migrator/migrator.go
pkg/blockchain/migrator/migrator_test.go
Consolidated separate SerializableNodeV1/V2 types into a single SerializableNode type. Updated functions and test cases to use the new node structure and simplified registration process.
pkg/blockchain/registryCaller.go Removed the versioning for RegistryCaller, consolidating logic into a single nodeRegistryCaller type. Updated methods for retrieving nodes and added methods for active nodes.
pkg/config/cliOptions.go Added new types for node management options, removed deprecated types, and updated RegisterNodeOptions to include an optional MinMonthlyFee field.
dev/baked/Dockerfile
dev/local.env
Updated environment variable assignments to retrieve addresses from XMTPNodeRegistry.json instead of Nodes.json.
dev/register-local-node
dev/register-local-node-2
Introduced a new environment variable NODE_OPERATOR_PRIVATE_KEY and updated the registration process to include enabling API and replication features.
pkg/blockchain/registryCaller_test.go Added new test functions to validate the behavior of the GetAllNodes, GetNode, and OwnerOf methods.

Possibly related PRs

  • Add migration tools for node registry #555: The changes in the main PR are related to those in the retrieved PR as both involve modifications to the cmd/cli/main.go file, specifically in the CLI struct and the parseOptions function, which are updated to accommodate new commands and options for node management and migration.
  • cli: prefix node arguments #318: The changes in the main PR are related to those in the retrieved PR as both involve modifications to the command-line interface (CLI) for node registration, specifically updating argument names to include a node- prefix, which directly affects the same functionality in the cmd/cli/main.go and cmd/cli/cli_test.go files.
  • Prepare migrator for v1 to v2 migration #576: The changes in the main PR and the retrieved PR are related as both involve modifications to the registerNode function in cmd/cli/main.go, specifically in how parameters are handled, including the addition of new parameters for versioning in the retrieved PR.

Suggested reviewers

  • neekolas
  • mkysel

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 golangci-lint (1.62.2)

Error: can't load config: the Go language version (go1.23) used to build golangci-lint is lower than the targeted Go version (1.24)
Failed executing command with error: can't load config: the Go language version (go1.23) used to build golangci-lint is lower than the targeted Go version (1.24)


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between fee6e80 and 1054143.

📒 Files selected for processing (1)
  • pkg/registry/contractRegistry_test.go (5 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/registry/contractRegistry_test.go
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Test (Node)
  • GitHub Check: Build pre-baked anvil-xmtpd

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

@fbac fbac changed the base branch from main to 04-05-use_nodesv2 March 5, 2025 13:46
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.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 8

🧹 Nitpick comments (7)
pkg/blockchain/registryAdmin_test.go (3)

37-57: New helper function addRandomNode
Nice utility for setting up a node with default parameters. Consider parameterizing the minMonthlyFee for more flexible testing in diverse scenarios.


59-71: TestAddNode duplicates some logic in addRandomNode
The direct call here is almost identical to the helper function approach. For consistency, you might reuse addRandomNode to keep test setup DRY.

-func TestAddNode(t *testing.T) {
-  registry, ctx, cleanup := buildRegistry(t)
-  defer cleanup()
-  privateKey := testutils.RandomPrivateKey(t)
-  httpAddress := testutils.RandomString(32)
-  owner := testutils.RandomAddress()
-  require.Eventually(t, func() bool {
-    err := registry.AddNode(ctx, owner.String(), &privateKey.PublicKey, httpAddress, 1000)
-    return err == nil
-  }, 1*time.Second, 50*time.Millisecond)
-}
+func TestAddNode(t *testing.T) {
+  registry, ctx, cleanup := buildRegistry(t)
+  defer cleanup()
+  addRandomNode(t, registry, ctx)
+}

159-164: TestSetBaseURI: sets the URI
Valid test, although you might also verify correctness (e.g., stored URI retrieval and verification).

pkg/blockchain/registryAdmin.go (4)

21-36: Expanded INodeRegistryAdmin interface
Providing methods like DisableNode, EnableNode, and SetBaseURI fosters comprehensive node management. Ensure consistent parameter validation in each method (like in AddNode).


69-116: AddNode method

  1. Negative minMonthlyFee returns an error—a good validation.
  2. If owner is invalid, an error is thrown.
  3. Summarily, logic is sound. Could consider an additional check for empty httpAddress.

154-170: RemoveFromApiNodes: uses RemoveFromApiNodes contract call
Implementation is correct. Might consider verifying the node’s initial state in tests before removal.


240-256: SetBaseURI: sets a string parameter
Implementation is straightforward. Consider trimming trailing spaces or slashes in a future improvement.

🛑 Comments failed to post (8)
pkg/registry/interface.go (2)

13-13: 💡 Verification agent

🧩 Analysis chain

Interface method signature update

The method has been renamed from AllNodes to GetAllNodes and its return type changed to use the new nodesv2 package. This is a breaking change that requires updates to all implementations of this interface.


🏁 Script executed:

#!/bin/bash
# Check for any remaining calls to AllNodes that haven't been updated
rg "AllNodes\(" --type go

# Check implementations of the NodesContract interface
ast-grep --pattern $'type \$_ struct {
  $$$
}

func \($_\) GetAllNodes\(opts \*bind.CallOpts\) \(\[]nodesv2.INodesNodeWithId, error\) {
  $$$
}'

Length of output: 2570


Action Required: Update AllNodes to GetAllNodes Across Implementations

The interface in pkg/registry/interface.go has been correctly updated to use GetAllNodes with the new return type. However, the verification revealed several remaining references to the old AllNodes method (for example, in pkg/blockchain/registryCaller.go and multiple functions in contracts/pkg/nodes/Nodes.go). Since these implementations no longer satisfy the new interface signature, please update all such occurrences accordingly.

  • Ensure that all implementations in contracts/pkg/nodes/Nodes.go are renamed from AllNodes to GetAllNodes and adjust the return types as needed.
  • Verify that all call sites (e.g., in pkg/blockchain/registryCaller.go) consistently use GetAllNodes.

5-5: 💡 Verification agent

🧩 Analysis chain

Package import update

This change shifts from using the nodes package to the nodesv2 package, which aligns with the method signature changes below.

Ensure that all imports throughout the codebase are consistently updated where this package is used.


🏁 Script executed:

#!/bin/bash
# Check for any remaining imports of the old nodes package
rg -l "github.com/xmtp/xmtpd/contracts/pkg/nodes" --type go

Length of output: 289


Attention: Incomplete Package Import Update

You've updated the import in pkg/registry/interface.go to use nodesv2, which aligns with the updated method signatures. However, our search indicates that the old nodes package is still imported in several files. Please update the import in the following files to use github.com/xmtp/xmtpd/contracts/pkg/nodesv2 for consistency:

  • pkg/blockchain/registryAdmin.go
  • pkg/blockchain/registryCaller.go
  • pkg/mocks/registry/mock_NodesContract.go
  • pkg/registry/contractRegistry_test.go
  • pkg/registry/contractRegistry.go
  • pkg/testutils/contracts.go

Once these updates are made, verify that all references to the old package are removed. Thank you!

pkg/registry/node.go (2)

17-25: 💡 Verification agent

🧩 Analysis chain

Enhanced Node struct with more detailed status fields

The Node struct has been expanded with more granular status fields:

  • IsReplicationEnabled - Controls if the node participates in replication
  • IsApiEnabled - Controls if the node's API endpoints are active
  • IsDisabled - Global flag to disable the node
  • MinMonthlyFee - Specified as a big.Int for accurate fee calculation

This replaces the previous simpler IsHealthy boolean, providing more fine-grained control over node behavior.


🏁 Script executed:

#!/bin/bash
# Check for places that might still be using the removed IsHealthy field
rg "\.IsHealthy" --type go

# Check if there are Node initializations that need to set the new fields
ast-grep --pattern 'Node{
  $$$
}'

Length of output: 1100


Action: Update legacy references to the removed IsHealthy field.

The Node struct now features the new status fields (IsReplicationEnabled, IsApiEnabled, IsDisabled, and MinMonthlyFee) to provide more granular control. However, our verification found that the legacy IsHealthy field is still being referenced in the following locations:

  • pkg/blockchain/migrator/migrator.go
    • Line where IsHealthy: node.Node.IsHealthy is still used.
  • pkg/blockchain/migrator/migrator_test.go
    • Lines comparing node1.IsHealthy and node2.IsHealthy with other entries.

Please update these instances to use the appropriate new status fields, ensuring that the legacy IsHealthy field is fully removed from the codebase.


38-42: 🛠️ Refactor suggestion

Updated Equals method to compare new fields

The Equals method has been properly updated to compare the new fields, ensuring correct equality testing.

One potential issue: If either MinMonthlyFee is nil, the .Cmp() method call could lead to a nil pointer panic. Make sure MinMonthlyFee is always initialized when creating a Node.

Add nil check for MinMonthlyFee to avoid potential nil pointer panics:

-		n.MinMonthlyFee.Cmp(other.MinMonthlyFee) == 0 &&
+		((n.MinMonthlyFee == nil && other.MinMonthlyFee == nil) || 
+		 (n.MinMonthlyFee != nil && other.MinMonthlyFee != nil && n.MinMonthlyFee.Cmp(other.MinMonthlyFee) == 0)) &&
📝 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.

		n.IsReplicationEnabled == other.IsReplicationEnabled &&
		n.IsApiEnabled == other.IsApiEnabled &&
		n.IsDisabled == other.IsDisabled &&
		((n.MinMonthlyFee == nil && other.MinMonthlyFee == nil) || 
		 (n.MinMonthlyFee != nil && other.MinMonthlyFee != nil && n.MinMonthlyFee.Cmp(other.MinMonthlyFee) == 0)) &&
		n.IsValidConfig == other.IsValidConfig
pkg/blockchain/registryAdmin_test.go (4)

95-103: ⚠️ Potential issue

TestDisableNode uses hardcoded node ID
Since node IDs are assigned sequentially in the contract, there's no guarantee the node will have ID 100. This test may give a false pass or fail unexpectedly. Consider capturing the newly added node’s actual ID from the event logs or from a contract query.


105-113: ⚠️ Potential issue

TestEnableNode: same hardcoded node ID concern
Similar to TestDisableNode, using a fixed ID is brittle. Retrieve the actual ID from contract events or queries before enabling it.


115-123: ⚠️ Potential issue

TestRemoveFromApiNodes with a fixed ID
This test also needs a dynamic node ID approach. It’s safer to fetch the node ID from the actual add event results.


125-133: ⚠️ Potential issue

TestRemoveFromReplicationNodes with a fixed ID
Same issue as above. Avoid relying on 100 as the node ID.

@fbac fbac force-pushed the 04-05-update_nodes_cli branch from a9ff722 to bcfc232 Compare March 5, 2025 20:11
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.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 2

🧹 Nitpick comments (8)
cmd/cli/main.go (3)

56-58: Inconsistent error message.
The command is "migrate-nodes," but the error message can be misread as "dump nodes command." Consider updating it for clarity:

- return nil, fmt.Errorf("could not add dump nodes command: %s", err)
+ return nil, fmt.Errorf("could not add migrate-nodes command: %s", err)

115-127: Consider avoiding logger.Fatal for improved error handling.
Using logger.Fatal terminates the application, which might limit testability or graceful shutdown. You may consider returning an error or using a warning/log + exit strategy explicitly in main.


257-260: Consider the potential size of logged data.
Logging the entire list of nodes could be large in production. You might want to log just the node count to avoid clutter or potential PII exposure.

pkg/blockchain/client.go (1)

19-66: Event parsing silently ignores parse errors.
The ExecuteTransaction function is well-structured. However, parse errors are swallowed (continue) with no warning or logging. Consider logging or tracking these parse failures for debugging.

- if err != nil {
-     continue
- }
+ if err != nil {
+     logger.Warn("event parsing error", zap.Error(err))
+     continue
+ }
pkg/config/cliOptions.go (1)

8-10: Proposal: Consider environment-based approach for the admin private key
Storing a private key via CLI flags can be risky and might accidentally leak in logs or process snapshots. Consider environment variables, config files with restricted permissions, or other secure storage mechanisms.

pkg/blockchain/registryCaller.go (2)

54-54: Reusing logic
GetActiveReplicationNodes mirrors GetActiveApiNodes. If more similar methods appear, consider refactoring for code reuse.

Also applies to: 57-59


62-62: Potential performance concern
Fetching all nodes at once may become inefficient if the registry grows large. Batching or pagination could improve scalability.

Also applies to: 64-67

pkg/blockchain/migrator/migrator.go (1)

24-53: Careful with large node sets
Looping through and converting all nodes can be slow if the registry is large. Consider concurrency or pagination. Also note any unexpected data, such as invalid fees.

🛑 Comments failed to post (2)
cmd/cli/main.go (2)

72-73: ⚠️ Potential issue

Duplicate addCommand call detected.
The "migrate-nodes" command is being added twice (lines 56-58 and 71-73). This duplication may lead to conflicts or unexpected behavior. Remove one instance to maintain a single registration.

-	if _, err := parser.AddCommand("migrate-nodes", "Migrate nodes from a file", "", &migrateNodesOptions); err != nil {
-		return nil, fmt.Errorf("could not add migrate-nodes command: %s", err)
-	}
📝 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.



194-198: ⚠️ Potential issue

Function migrateNodes is never invoked.
Static analysis indicates this function is “unused.” If you intend to support a “migrate-nodes” command, add it to main’s switch; otherwise, remove the function.

case "migrate-nodes":
+	migrateNodes(logger, options)
	return
🧰 Tools
🪛 GitHub Check: Lint-Go

[failure] 194-194:
func migrateNodes is unused (unused)

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between a9ff722 and bcfc232.

📒 Files selected for processing (7)
  • cmd/cli/main.go (5 hunks)
  • pkg/blockchain/client.go (2 hunks)
  • pkg/blockchain/migrator/migrator.go (4 hunks)
  • pkg/blockchain/migrator/migrator_test.go (4 hunks)
  • pkg/blockchain/registryAdmin.go (1 hunks)
  • pkg/blockchain/registryCaller.go (1 hunks)
  • pkg/config/cliOptions.go (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • pkg/blockchain/client.go
  • pkg/config/cliOptions.go
🧰 Additional context used
🪛 GitHub Check: Lint-Go
cmd/cli/main.go

[failure] 194-194:
func migrateNodes is unused (unused)

🔇 Additional comments (45)
pkg/blockchain/registryCaller.go (9)

15-17: Interface simplification looks good.

The INodeRegistryCaller interface has been effectively simplified to have a single method for retrieving all nodes, which better aligns with the new architecture.


20-24: Clean implementation of caller struct.

The nodeRegistryCaller struct has been simplified to directly utilize the nodesv2.NodesV2Caller, removing the versioning complexity.


26-44: Constructor updated correctly.

The NewNodeRegistryCaller function has been properly updated to use the new structure without versioning, making the code more maintainable.


46-52: Function implementation appears correct.

The GetActiveApiNodes method correctly delegates to the underlying contract caller.


54-60: Function implementation appears correct.

The GetActiveReplicationNodes method correctly delegates to the underlying contract caller.


62-68: Function implementation for the interface method is correct.

The GetAllNodes method correctly implements the interface method and delegates to the contract caller.


70-80: New count method correctly implemented.

The GetAllNodesCount method is a useful addition that correctly converts the big integer to a uint64 for easier consumption.


82-89: New node retrieval method is well implemented.

The GetNode method provides a convenient way to fetch a specific node by ID.


91-98: Owner retrieval method preserved correctly.

The OwnerOf method implementation is maintained correctly.

cmd/cli/main.go (7)

116-127: New generateKey function looks good.

The implementation of the generateKey function correctly generates an ECDSA private key and logs the necessary information.


166-174: Proper handling of minimum monthly fee.

The code correctly handles negative values for the minimum monthly fee by ignoring them and setting the value to 0, with appropriate logging.


176-182: Successfully updated function parameters.

The AddNode call has been correctly updated to include the minMonthlyFee parameter.


196-199: Updated to use ImportNodesFromFile properly.

The function now correctly uses ImportNodesFromFile to read nodes from a file rather than from the registry directly.


206-208: Correctly using admin private key from options.

The signer now correctly uses the private key from the MigrateNodes options.


252-261: All nodes retrieval and logging looks good.

The function properly retrieves all nodes from the registry and logs the results.


263-268: File output handling is well implemented.

The code correctly checks for an output file path and dumps nodes to the file if specified.

pkg/blockchain/migrator/migrator_test.go (6)

16-22: Simplified setupRegistry function signature.

The function has been correctly simplified by removing the version parameters, making it more maintainable.


54-64: Updated registerRandomNode to use new structure.

The function now correctly returns a SerializableNode and includes the additional minMonthlyFee parameter (set to 0) in the AddNode call.


66-73: Updated return value with new fields.

The function now returns a SerializableNode with all the necessary fields, including the new ones for minimum monthly fee and enablement flags.


89-92: Updated test assertions for new fields.

The test now correctly asserts the new fields for minimum monthly fee and enablement flags.


97-99: Updated test assertions for new fields.

The test now correctly asserts the new fields for minimum monthly fee and enablement flags for the second node as well.


153-159: Correct assertions for default values.

The test properly asserts that the default values for the new fields are as expected after writing to the registry.

pkg/blockchain/migrator/migrator.go (6)

14-22: Consolidated SerializableNode structure.

The code now correctly uses a single SerializableNode structure with the appropriate fields, including the new MinMonthlyFee as an int64.


24-32: Simplified ReadFromRegistry function.

The function has been updated to use the new interface method and properly handles errors.


42-50: Updated node serialization to include new fields.

The code correctly maps the node data to the SerializableNode structure, including the new fields for minimum monthly fee and enablement flags.


69-75: Updated AddNode call with new parameter.

The function now correctly includes the MinMonthlyFee parameter in the AddNode call.


84-92: Updated DumpNodesToFile for new structure.

The function has been updated to work with the new SerializableNode structure.


94-101: Updated ImportNodesFromFile for new structure.

The function has been correctly updated to import the new SerializableNode structure.

pkg/blockchain/registryAdmin.go (17)

10-18: Import of core/types is well-placed and appropriate.

The addition of "github.com/ethereum/go-ethereum/core/types" supports the use of Ethereum transaction and log types in the updated code, which is necessary for the transaction execution pattern used throughout the file.


20-35: Interface expansion enhances node management capabilities.

The INodeRegistryAdmin interface has been expanded with several new methods that provide comprehensive node management capabilities. The addition of minMonthlyFee parameter to AddNode and the introduction of methods like DisableNode, EnableNode, etc. align well with the NodesV2 contract functionality.


37-42: Simplified struct structure removes versioning complexity.

The removal of versioning from the struct name (from nodeRegistryAdminV1 to nodeRegistryAdmin) simplifies the codebase and reflects a move to a more stable implementation. The field structure remains appropriate for the contract interaction needs.


44-44: Correct interface implementation assertion.

The interface compliance check has been properly updated to match the new struct name, ensuring type safety.


46-66: Constructor update aligns with simplified struct.

The constructor has been updated to return the new struct type while maintaining the same initialization logic. The code properly handles potential errors during contract initialization.


79-81: Parameter validation is appropriate.

The validation ensures that minMonthlyFee is non-negative, which is a good practice to prevent unexpected behavior in the contract.


90-117: Effective use of ExecuteTransaction pattern.

The implementation leverages the ExecuteTransaction helper function, which centralizes transaction execution and event handling. This pattern is consistently applied across all methods, making the code more maintainable and reducing duplication.


120-139: DisableNode implementation follows consistent pattern.

The method uses the same transaction execution pattern as other methods, ensuring consistency throughout the codebase. It properly calls the contract method and handles the event, with appropriate logging.


141-160: EnableNode implementation follows consistent pattern.

The method shares the same structure as other transaction methods, ensuring code consistency. It properly calls the contract method, handles the event, and logs important information.


162-181: RemoveFromApiNodes implementation follows consistent pattern.

The implementation follows the established pattern for transaction execution, event handling, and logging. This consistency is good for maintainability.


183-202: RemoveFromReplicationNodes implementation follows consistent pattern.

The method maintains the same implementation structure as other methods, ensuring consistent behavior across the codebase.


204-223: SetMaxActiveNodes implementation follows consistent pattern.

This method correctly sets the maximum number of active nodes and follows the same pattern as other methods for transaction execution and event handling.


225-258: SetNodeOperatorCommissionPercent includes proper validation.

The method validates that the commission percentage is between 0 and 10000 (0-100%), which is important to prevent invalid values. The implementation follows the same pattern as other methods for transaction execution.


229-231: Good range validation for commission percentage.

The check ensures that the commission percentage is between 0 and 10000 (0-100% with 2 decimal precision), which prevents invalid values from being sent to the contract.


260-279: SetBaseURI implementation follows consistent pattern.

The method maintains the same structure as other methods for transaction execution, event handling, and logging. This consistency helps with code maintainability.


68-118:

Details

✅ Verification successful

AddNode implementation includes proper validation and uses centralized transaction pattern.

The implementation now validates that minMonthlyFee is non-negative, which is important for preventing unexpected behavior. The use of the ExecuteTransaction helper function centralizes transaction execution logic, making the code more maintainable.

One thing to verify is that all callsites to this function have been updated to include the new parameter.


🏁 Script executed:

#!/bin/bash
# Check if all callsites of AddNode have been updated to include the new minMonthlyFee parameter
rg -A 5 "AddNode\(" --type go | grep -v "pkg/blockchain/registryAdmin.go"

Length of output: 7222


All Call Sites Verified: Changes Consistent Across the Codebase

The AddNode implementation in pkg/blockchain/registryAdmin.go now properly validates its inputs and uses a centralized transaction execution pattern. Verification confirms that callsites in files like:

  • cmd/cli/main.go
  • pkg/blockchain/registryAdmin_test.go
  • pkg/blockchain/migrator/migrator.go (and related migrator tests)

all pass the new minMonthlyFee parameter, ensuring consistency throughout the codebase.


1-280:

Details

❓ Verification inconclusive

Verify the ExecuteTransaction helper function exists and is implemented correctly.

Since all methods now rely on the ExecuteTransaction helper function, it's important to ensure this function is properly implemented and handles transaction execution, confirmation, error handling, and event processing correctly.


🏁 Script executed:

#!/bin/bash
# Check for the ExecuteTransaction function implementation
rg -A 10 "func ExecuteTransaction" --type go

Length of output: 660


Verify ExecuteTransaction Implementation

The ExecuteTransaction helper function is present in pkg/blockchain/client.go as confirmed by the search output. The initial error check (e.g., verifying that a signer is provided) and its basic structure suggest that it was implemented with the necessary concerns in mind. However, since only the first portion of its implementation is visible, please ensure that the remainder of the function correctly handles:

  • Transaction execution and confirmation.
  • Comprehensive error handling (especially for edge cases).
  • Event parsing and log processing.

Kindly review these aspects in the complete implementation to ensure that all intended responsibilities of ExecuteTransaction are fully met.

@fbac fbac changed the title [WIP] Updates Nodes CLI Updates Nodes CLI Mar 6, 2025
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: 3

🧹 Nitpick comments (9)
pkg/blockchain/registryCaller_test.go (1)

9-18: Test coverage for GetAllNodes could be more thorough.

The test correctly verifies basic functionality, but consider enhancing it by:

  1. Checking that the node added is actually in the returned list
  2. Adding tests for empty registry and multiple nodes
  3. Verifying node properties match expected values
 func TestGetAllNodes(t *testing.T) {
 	registry, caller, ctx, cleanup := buildRegistry(t)
 	defer cleanup()
 
-	addRandomNode(t, registry, ctx)
+	node := addRandomNode(t, registry, ctx)
 
 	nodes, err := caller.GetAllNodes(ctx)
 	require.NoError(t, err)
 	require.NotNil(t, nodes)
+	require.Len(t, nodes, 1, "Expected exactly one node")
+	require.Equal(t, node.ID.String(), nodes[0].ID.String(), "Expected node ID to match")
 }
cmd/cli/cli_test.go (1)

24-24: Command line argument structure has changed.

The admin private key flag has been renamed from --admin-private-key to --admin.private-key, using a hierarchical dot notation. This indicates a restructuring of the command-line options to better organize related settings.

cmd/cli/main.go (6)

24-38: Introduce unit tests for newly added CLI struct fields.
These new fields effectively manage different command options. To ensure correctness, add some tests—possibly table-driven—for various CLI argument combinations to confirm these fields are properly populated.


51-63: Consider grouping related options in a subparser or domain-specific grouping.
You’ve introduced multiple option variables (adminOptions, nodeManagerOptions, etc.). While this is valid, it can become unwieldy. Consider grouping related options in subparsers or leveraging hierarchical commands (e.g., “xmtpd admin disable-node …”) to streamline complexity.


66-66: Comment clarity.
This comment strictly says "// Admin commands," but the parser below includes both admin and node operator commands as well. Consider clarifying or relocating it to keep the file documentation consistent.


76-78: Mismatch in error message.
The error message says “could not add dump nodes command,” but the actual command is “migrate-nodes.” Fix the text to avoid confusion.

- return nil, fmt.Errorf("could not add dump nodes command: %s", err)
+ return nil, fmt.Errorf("could not add migrate-nodes command: %s", err)

177-188: Good key generation flow.
The “generateKey" function properly uses utils.GenerateEcdsaPrivateKey and logs results. Consider restricting logging of private keys in production code to bolster security.


502-529: getActiveApiNodes command:
Implementation is correct. Logging node data is valuable for debugging, but be mindful not to leak sensitive info.

pkg/blockchain/registryAdmin.go (1)

237-265: SetMinMonthlyFee missing negative check.
The CLI’s AddNode checks for negative fees, but SetMinMonthlyFee doesn’t—only the contract method is called. For consistency, consider raising an error if the provided fee is negative.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between bcfc232 and b3f79f4.

📒 Files selected for processing (11)
  • cmd/cli/cli_test.go (3 hunks)
  • cmd/cli/main.go (5 hunks)
  • dev/baked/Dockerfile (1 hunks)
  • dev/local.env (1 hunks)
  • dev/register-local-node (1 hunks)
  • dev/register-local-node-2 (1 hunks)
  • pkg/blockchain/registryAdmin.go (1 hunks)
  • pkg/blockchain/registryAdmin_test.go (3 hunks)
  • pkg/blockchain/registryCaller.go (1 hunks)
  • pkg/blockchain/registryCaller_test.go (1 hunks)
  • pkg/config/cliOptions.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Lint-Go
  • GitHub Check: Test (Node)
🔇 Additional comments (71)
dev/register-local-node-2 (4)

9-9: Good addition of NODE_OPERATOR_PRIVATE_KEY environment variable.

This properly sets up the private key needed for node operations in subsequent commands.


11-15: Well-structured command to capture node ID.

The approach of capturing the node ID into a variable for reuse in subsequent commands is a good practice that improves script maintainability.


17-25: Good implementation of node enablement commands.

These new commands complete the node registration workflow by enabling both API and replication functionality, making the script more useful.


27-27: Helpful success message with node details.

The colored success message provides clear feedback to the user about the completed operations and displays the relevant node ID.

dev/baked/Dockerfile (1)

32-32: Updated contract address retrieval to use new registry JSON structure.

This change correctly updates the source for the XMTPD_CONTRACTS_NODES_ADDRESS to use the XMTPNodeRegistry.json file with the new path structure, which aligns with the migration to the new Nodes ABI.

dev/local.env (1)

13-13: Updated contract address retrieval to use new registry JSON structure.

This change correctly updates the XMTPD_CONTRACTS_NODES_ADDRESS to use the XMTPNodeRegistry.json file with the new path structure, maintaining consistency with the similar change in the Dockerfile.

cmd/cli/cli_test.go (2)

34-34: Updated options structure access pattern.

The test now accesses the admin private key through a nested structure: options.RegisterNode.AdminOptions.AdminPrivateKey. This reflects the CLI options restructuring to group admin-related settings together.


44-44: Error message update for consistency.

The error message has been updated to reflect the new flag name --admin.private-key, ensuring consistent feedback to users when required flags are missing.

dev/register-local-node (4)

8-8: Added node operator private key export.

The script now exports the node operator's private key for use in subsequent commands, which is a good practice for script readability and maintenance.


10-14: Improved node registration with ID capture.

The script now captures the node ID from the registration command output using command substitution with jq. This allows the ID to be used in subsequent operations.


16-24: Added node feature enabling commands.

Two new commands have been added to enable API and replication features for the registered node. This enhances the script's functionality to fully configure a node in a single operation.


26-26: Added success message with node ID.

A colorized success message has been added to provide clear feedback about the completed operation, including the node ID for reference. This improves user experience.

pkg/blockchain/registryAdmin_test.go (7)

12-14: Simplified buildRegistry signature.

The version parameter has been removed from the buildRegistry function, and the return signature has been updated to include INodeRegistryCaller. This reflects the move away from versioning in the registry admin.


19-20: Deterministic test setup.

The comment and implementation now force deployment of the NodesV2Contract for all tests, ensuring deterministic behavior. This is a good practice for test stability and reliability.


31-35: Simplified registry instantiation.

The code now creates the registry admin and caller without version checks, reflecting the consolidation around the V2 contract implementation. This simplifies the code and reduces maintenance overhead.


42-62: Added helper function for test setup.

The new addRandomNode helper function centralizes the logic for adding a node during tests, making the test code more maintainable and readable. This follows the DRY principle.


64-76: Refactored TestAddNode for clarity.

The TestAddNode function has been refactored to use explicit variable declarations and the new method signature that includes the minMonthlyFee parameter. This improves test readability.


89-98: Added test for negative min monthly fee.

This test validates that the admin rejects invalid minimum monthly fee values (negative numbers), which is an important input validation check.


100-162: Added comprehensive tests for node management operations.

Several new test functions have been added to cover various node management operations, including disabling/enabling nodes, removing nodes from API/replication nodes, setting max active nodes, and validating commission percentages. This significantly improves test coverage.

pkg/blockchain/registryCaller.go (6)

15-21: Updated INodeRegistryCaller interface.

The interface has been updated to remove version-specific methods and add new methods for retrieving active nodes. This simplifies the API while adding useful functionality for node management.


23-27: Simplified registry caller implementation.

The code has been refactored to use a single nodeRegistryCaller struct instead of separate version-specific implementations. This reduces code duplication and maintenance overhead.


34-47: Streamlined constructor function.

The NewNodeRegistryCaller function has been simplified to create a single implementation without version checks. This makes the code more maintainable and easier to understand.


49-63: Added methods for retrieving active nodes.

New methods for retrieving active API and replication nodes have been implemented. These methods provide valuable functionality for node management in the CLI.


65-81: Added methods for node retrieval.

The implementation now includes methods for retrieving all nodes and a specific node by ID. These are essential operations for node management in the CLI.


82-89: Maintained OwnerOf method.

The OwnerOf method has been preserved but adapted to the new implementation structure. This maintains backward compatibility while aligning with the new code structure.

cmd/cli/main.go (20)

70-72: Looks good.
The “get-pub-key” command registration is straightforward. No issues here.


79-105: No duplicate command registrations observed.
The new admin commands (“disable-node,” “enable-node,” etc.) are each registered once, addressing the previous feedback about duplicates. Implementation looks fine.


107-113: No issues in Node Operator command registration.
These additions (“set-api-enabled,” “set-replication-enabled”) logically match the new node-operator flow.


119-126: Getter commands correctly registered.
No immediate concerns here. This extends coverage for retrieving node data.


142-155: Parser output fields.
The struct construction merges all parsed options into the returned CLI. This is correct. Just ensure future expansions remain consistent to avoid any confusion between admin vs operator roles.


236-256: Disable node command: Implementation looks correct.
The call to “DisableNode” matches the new chain logic. Just ensure usage is tested thoroughly to confirm the node states are updated on-chain.


258-278: Enable node command: Implementation looks correct.
Same approach as disable-node. Looks good.


280-300: removeFromApiNodes command:
No issues identified. The transaction approach with “RemoveFromApiNodes” is consistent.


302-322: removeFromReplicationNodes command:
Implementation mirrors the same pattern, which helps maintain consistency.


324-346: migrateNodes command usage.
Good to see that “migrate-nodes” is now integrated, addressing previous concerns about an unused function. No issues.


348-368: setMaxActiveNodes:
Straightforward logic. No immediate concerns. Just ensure it’s tested under boundary conditions (e.g., 0 or extremely high values).


370-390: setNodeOperatorCommissionPercent with boundary check.
The check for < 0 or > 10000 is good. This effectively enforces a 0–100% range in hundredths of a percent. Implementation aligns with typical fee percentage logic.


398-419: setHttpAddress:
The code reads node manager credentials and calls SetHttpAddress. Implementation is straightforward.


450-471: setApiEnabled:
Checks out. Consider verifying if toggling repeated times (enable->disable->enable) behaves as expected on-chain.


473-494: setReplicationEnabled:
Parallel approach to setApiEnabled. No concerns.


530-556: getActiveReplicationNodes command:
Same structure as getActiveApiNodes. Good for consistency.


558-591: getAllNodes command with optional out-file.
This is helpful for data export. Looks good.


593-618: getNode command:
Implementation is straightforward. Confirm correct usage of options.NodeOperator.NodeId if the command is intended for both admin and operator usage.


656-702: Main switch statement extended with new commands.
All new branches properly call their functions, addressing prior concerns about unused code. Implementation looks good.


704-736: setupRegistryAdmin function.
Centralizes the instantiation of the registry admin. This reduces duplication across commands. Good structure.

pkg/config/cliOptions.go (11)

8-11: AdminOptions structure.
Straightforward fields for admin key and node ID. No issues identified. Consider clarifying if node ID is always required.


13-16: NodeManagerOptions structure.
This mirrors AdminOptions but for a node manager key. Ensure these roles are well-differentiated in user documentation.


18-22: NodeOperatorOptions structure.
The boolean “Enable” field clarifies toggling certain states. This is a clean separation of concerns.


30-31: GetOptions stands empty.
Having an empty struct is fine if it’s intentionally a placeholder for future expansions.


32-35: MigrateNodesOptions with AdminOptions embedded.
This grouping is logical, bundling admin privileges with the file-based node list. No issues.


37-39: GetPubKeyOptions.
Contains only a private key. Straightforward.


41-47: RegisterNodeOptions structure.
Incorporates AdminOptions plus essential node data. The optional “MinMonthlyFee” is consistent with the CLI logic changes.


49-52: SetHttpAddressOptions.
Combines NodeManagerOptions with a new address field. Good approach for a single HTTP address update.


54-57: SetMinMonthlyFeeOptions.
Similar to SetHttpAddressOptions, but for fees. Check negative handling is consistent with the registry.


59-62: SetMaxActiveNodesOptions.
Embeds AdminOptions. Use caution with upper bounds if you suspect large-scale node networks.


64-67: SetNodeOperatorCommissionPercentOptions.
Commission percent is validated in the registry code. Nothing special at the CLI level.

pkg/blockchain/registryAdmin.go (15)

12-12: Additional import for core/types.
Used for transaction logs and parsing. No issues.


26-37: Expanded INodeRegistryAdmin interface.
The interface now supports multiple node-management operations. Good for clarity and feature completeness.


40-44: nodeRegistryAdmin struct fields.
Retains references to the client, signer, logger, and contract. Straightforward design.


47-48: Assertion to ensure nodeRegistryAdmin implements INodeRegistryAdmin.
This check helps catch interface mismatch errors at compile time. Good practice.


49-69: NewNodeRegistryAdmin constructor.
Instantiates nodesv2.NodesV2 and returns nodeRegistryAdmin. Removes version checks for simplicity. Looks correct.


93-119: ExecuteTransaction usage.
This pattern centralizes the transaction flow and event parsing. Implementation is consistent.


123-142: DisableNode method.
Uses the same ExecuteTransaction approach, logging “node disabled.” Implementation is straightforward.


144-163: EnableNode method.
Parallel approach to DisableNode. Straightforward.


165-184: RemoveFromApiNodes method.
Removing a node from active API nodes is consistent with your pattern. Good logging.


186-205: RemoveFromReplicationNodes method.
Mirrors the removeFromApiNodes approach. No issues found.


207-235: SetHttpAddress method.
Parameter usage and event parsing match the rest of the contract interactions.


267-293: SetIsApiEnabled method.
Makes sense. Switches event-parsing logic based on the bool. Implementation is robust.


295-325: SetIsReplicationEnabled method.
Follows the same pattern as SetIsApiEnabled. Straightforward.


327-346: SetMaxActiveNodes method.
No issues. Suitable for capping concurrency.


348-381: SetNodeOperatorCommissionPercent validation.
Exits if outside [0,10000]. Good boundary handling. Implementation looks correct.

@fbac fbac force-pushed the 04-05-update_nodes_cli branch from b3f79f4 to cba4b69 Compare March 6, 2025 13:34
@fbac fbac marked this pull request as ready for review March 6, 2025 13:34
@fbac fbac requested a review from a team as a code owner March 6, 2025 13:34
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: 3

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b3f79f4 and cba4b69.

📒 Files selected for processing (11)
  • cmd/cli/cli_test.go (3 hunks)
  • cmd/cli/main.go (5 hunks)
  • dev/baked/Dockerfile (1 hunks)
  • dev/local.env (1 hunks)
  • dev/register-local-node (1 hunks)
  • dev/register-local-node-2 (1 hunks)
  • pkg/blockchain/registryAdmin.go (1 hunks)
  • pkg/blockchain/registryAdmin_test.go (3 hunks)
  • pkg/blockchain/registryCaller.go (1 hunks)
  • pkg/blockchain/registryCaller_test.go (1 hunks)
  • pkg/config/cliOptions.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • cmd/cli/cli_test.go
  • dev/local.env
  • dev/register-local-node-2
  • dev/register-local-node
  • dev/baked/Dockerfile
  • pkg/blockchain/registryCaller_test.go
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Test (Node)
🔇 Additional comments (53)
pkg/blockchain/registryAdmin_test.go (12)

14-40: Refactored buildRegistry function returning INodeRegistryCaller
This update ensures the tests can verify both admin and caller functionality within a single setup step, improving coverage and consistency. Always deploying the contract for deterministic tests is a solid approach.


42-62: addRandomNode helper function
Extracting node creation logic into a shared helper reduces duplication and clarifies test setup. The use of require.Eventually ensures the on-chain registration completes in time.


64-76: TestAddNode
Straightforward test verifying that a valid node can be added. The chosen minMonthlyFee is sensible, and the eventual check ensures final on-chain registration.


78-87: TestAddNodeBadOwner
Good job validating error handling for invalid addresses. This coverage ensures users cannot accidentally supply malformed inputs.


89-98: TestAddNodeBadMinMonthlyFee
Strong negative-path check for minMonthlyFee ensures graceful handling of invalid fee values.


100-108: TestDisableNode
Validates disabling a node by ID. Future improvements might verify it stays disabled, but overall coverage is sufficient.


110-118: TestEnableNode
Ensures the node can be enabled after creation. This complements the disable test for full lifecycle coverage.


120-128: TestRemoveFromApiNodes
Verifies that a node can be removed from the pool of API nodes. Straightforward test coverage.


130-138: TestRemoveFromReplicationNodes
Checks node removal from replication nodes. Similar to the API removal test, ensuring no unintentional overlap.


140-146: TestSetMaxActiveNodes
Good coverage to validate that setting the maximum allowed active nodes works as expected.


148-154: TestSetNodeOperatorCommissionPercent
Verifies commission percentage can be updated, ensuring the upstream logic accepts valid percentages.


156-162: TestSetNodeOperatorCommissionPercentInvalid
Checks failure mode for invalid commission values, preventing negative or otherwise invalid percentages.

cmd/cli/main.go (25)

24-38: CLI struct expansions
Adding AdminOptions, NodeManagerOptions, and NodeOperatorOptions centralizes parameters for various node commands, making the CLI more cohesive.


51-63: Additional local variables for commands
Creating distinct config objects (e.g., AdminOptions, NodeManagerOptions) clarifies the scope of each command’s inputs, improving maintainability.


66-106: Admin commands registration
Registering additional commands (e.g., disable-node, remove-from-api-nodes) systematically broadens the CLI’s administrative capabilities.


107-115: Node operator commands
Enables toggling API or replication states. Having separate commands ensures a more granular approach to node configuration.


119-127: Getter commands
Includes commands to retrieve nodes in various states (active, replication, etc.). This centralized approach simplifies operator actions.


142-155: parseOptions return with new fields
Integrates the newly introduced Admin, NodeManager, and NodeOperator options in one final CLI struct, ensuring they’re accessible downstream.


177-188: generateKey command
Generates and prints an ECDSA private key along with public key and address. Implementation is concise and user-friendly.


190-230: registerNode command
Properly checks for negative minMonthlyFee and calls AddNode. Good handling of invalid input.


232-252: disableNode command
Calls DisableNode with the specified node ID. Straightforward approach for toggling node availability.


254-274: enableNode command
Symmetric to disableNode, ensures a disabled node can be re-enabled.


276-296: removeFromApiNodes command
Removes a node from API responsibilities, preserving clarity of the node's roles.


298-318: removeFromReplicationNodes command
Mirrors removeFromApiNodes for replication. Straightforward and consistent with prior patterns.


320-342: migrateNodes command
Imports node definitions from a file and writes them to the registry. The usage of WriteToRegistry ensures consistent migration logic.


344-364: setMaxActiveNodes command
Allows administrators to enforce a cap on active nodes. Implementation is simple and maintainable.


366-386: setNodeOperatorCommissionPercent command
Updates the on-chain commission percent. Straightforward approach to handle operator-specific parameters.


394-415: setHttpAddress command
Lets a node manager adjust its own node’s address. Good design for self-service updates.


417-442: setMinMonthlyFee command
Blocks negative values and updates the chain for the chosen node. Nicely validates inputs before the chain call.


450-471: setApiEnabled command
Toggles the node’s API availability. Works in tandem with the replication toggle to manage node roles.


473-494: setReplicationEnabled command
Similar approach to setApiEnabled, ensuring the node manager can update replication roles.


502-528: getActiveApiNodes command
Retrieves and logs active API nodes. The final info logging helps with quick operational checks.


530-556: getActiveReplicationNodes command
Likewise fetches active replication nodes. The uniform style across these getters aids maintainability.


558-591: getAllNodes command
Provides a comprehensive registry snapshot with optional output to a file. Good for backups or audits.


593-618: getNode command
Fetches a node by ID, rounding out the read-side CLI coverage.


647-701: Switch statement updates
Extensive expansion to handle all new CLI commands. The grouping fosters clarity when selecting an action.


704-737: setupRegistryAdmin function
Centralizes the creation of a chain client and a registry admin signer. Good practice for DRY code across commands.

pkg/blockchain/registryCaller.go (8)

16-20: Refactored INodeRegistryCaller interface
Consolidating all node-related read operations here removes the need for version-based calls, simplifying usage.


23-27: nodeRegistryCaller struct
Stores a single NodesV2Caller, reducing complexity by removing older version references.


34-47: NewNodeRegistryCaller
Instantiates a nodeRegistryCaller bound to the deployed V2 contract. Correctly handles errors in contract initialization.


49-55: GetActiveApiNodes
Fetches actively serving API nodes. The call to GetActiveApiNodes ensures the contract call context is properly passed.


57-63: GetActiveReplicationNodes
Similarly retrieves replication nodes in an active state, mirroring API logic.


65-71: GetAllNodes
Calls the unified GetAllNodes function on the contract to list every node. Good coverage for enumerating registry data.


73-80: GetNode
Retrieves details of a specific node by ID. Straightforward mapping to the contract’s single-node lookup.


82-89: OwnerOf
Provides node ownership verification. Helpful for permission checks.

pkg/config/cliOptions.go (3)

8-11: Good addition of AdminOptions struct.

This is a nice improvement for encapsulating admin-related options and promoting code reuse across different commands.


13-16: Well-structured option types for different roles.

The clear separation between NodeManagerOptions and NodeOperatorOptions reflects the different responsibilities in the system and provides appropriate CLI flags for each role.

Also applies to: 18-22


54-57:

Details

✅ Verification successful

Ensure consistency between SetMinMonthlyFee and RegisterNode.

Both options types handle minimum monthly fee, but one is in NodeManagerOptions context and the other in AdminOptions context. Make sure the validation and handling is consistent in both places.


🏁 Script executed:

#!/bin/bash
# Check implementation of both commands to ensure consistent validation
rg "SetMinMonthlyFee" --type go
rg "RegisterNode.*MinMonthlyFee" --type go

Length of output: 2054


Consistency Verified: Minimum Monthly Fee Validation

The verification confirms that both components enforce a consistent check ensuring the fee isn’t negative. Specifically:

  • In cmd/cli/main.go, both options.SetMinMonthlyFee.MinMonthlyFee and options.RegisterNode.MinMonthlyFee are guarded with a < 0 validation.
  • The handling of the minimum monthly fee is consistent across the NodeManager (via SetMinMonthlyFeeOptions) and Admin (via RegisterNode) contexts.

No discrepancies were found. Please continue to maintain this consistency, including any related error messaging or business logic that might depend on these validations.

pkg/blockchain/registryAdmin.go (5)

40-48: Good simplification of registry admin implementation.

Removing the versioning complexity and directly implementing the interface with a single struct makes the code cleaner and easier to maintain.


82-84: AddNode: negative fee validation

Raising an error is appropriate. This is stricter than the CLI approach if the latter only logs negative fees. Consider aligning the CLI logic to fail as well.


93-120: Excellent transaction execution pattern.

The ExecuteTransaction helper function centralization is a great improvement that:

  1. Reduces code duplication
  2. Standardizes error handling
  3. Creates consistent logging patterns
  4. Makes the code more maintainable

This pattern follows the principle of separating transaction execution concerns from business logic.


352-354: Good validation of commission percent.

The validation ensures commission percent is within valid bounds (0-10000). This prevents invalid values from being sent to the blockchain contract.


20-38: Comprehensive interface expansion.

The interface has been significantly expanded with new node management methods, providing a complete API for node administration. This aligns well with the PR objective of updating the Nodes CLI to use the new Nodes ABI.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
pkg/blockchain/registryCaller_test.go (2)

39-47: Enhance OwnerOf test verification.

The test verifies that no error is returned, but doesn't check if the owner address returned matches expectations. Consider adding an assertion to verify the owner matches the expected address.

-	_, err := caller.OwnerOf(ctx, 100)
+	owner, err := caller.OwnerOf(ctx, 100)
 	require.NoError(t, err)
+	// Verify the owner matches expected address
+	require.Equal(t, expectedOwnerAddress, owner)

1-8: Consider adding package documentation.

As this is a new file, it would be helpful to add a package comment explaining the purpose of these tests and how they relate to the overall functionality.

 package blockchain

+// This file contains tests for the registry caller functionality,
+// focusing on node retrieval and ownership verification methods.

 import (
 	"testing"

 	"github.com/stretchr/testify/require"
 )
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between d97d9d1 and 557a1ba.

📒 Files selected for processing (1)
  • pkg/blockchain/registryCaller_test.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Test (Node)
  • GitHub Check: Build pre-baked anvil-xmtpd
🔇 Additional comments (2)
pkg/blockchain/registryCaller_test.go (2)

9-18: Good test structure for GetAllNodes.

The test properly sets up the environment, adds a test node, and verifies the expected behavior. The use of defer cleanup() ensures proper test isolation.


31-37: Good negative test case.

The test properly verifies error handling when attempting to get a non-existent node.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
pkg/blockchain/registryAdmin.go (1)

267-301: Well-implemented SetMinMonthlyFee method

Consider validating that minMonthlyFee is non-negative in this method, similar to how it's done in AddNode.

func (n *nodeRegistryAdmin) SetMinMonthlyFee(
	ctx context.Context,
	nodeId int64,
	minMonthlyFee int64,
) error {
+	if minMonthlyFee < 0 {
+		return fmt.Errorf("invalid min monthly fee provided %d", minMonthlyFee)
+	}
+
	return ExecuteTransaction(
		ctx,
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 557a1ba and 7f8c793.

📒 Files selected for processing (1)
  • pkg/blockchain/registryAdmin.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build pre-baked anvil-xmtpd
  • GitHub Check: Test (Node)
🔇 Additional comments (17)
pkg/blockchain/registryAdmin.go (17)

12-12: Good addition of core/types import

Adding this import is necessary for the new transaction handling functionality introduced in this file.


26-27: LGTM: Added minMonthlyFee parameter

Good addition of the minMonthlyFee parameter to the AddNode method signature, which aligns with the PR objective of updating to the new Nodes ABI.


28-37: Comprehensive node management interface expansion

Excellent addition of new methods that provide granular control over node operations. These methods align with the PR objective of utilizing the new Nodes ABI.


40-45: Clean struct simplification

Good refactoring by removing versioning and simplifying to a single implementation struct that directly uses the NodesV2 contract.


47-47: Good interface compliance check

Explicit interface compliance verification ensures type safety at compile time.


49-69: Constructor simplified appropriately

The constructor has been simplified by removing version checks, making the code more maintainable and focused on the V2 implementation.


71-85: Proper validation of minMonthlyFee

The validation for negative fee values is correctly implemented, addressing the previous review comment.


93-125: Effective use of ExecuteTransaction helper

Good refactoring to use the ExecuteTransaction helper, which centralizes transaction handling and event processing logic, reducing duplication across methods.


127-150: Well-implemented DisableNode method

The DisableNode method follows the established pattern for transaction execution and event handling.


152-175: Well-implemented EnableNode method

The EnableNode method follows the established pattern for transaction execution and event handling.


177-202: Well-implemented RemoveFromApiNodes method

The RemoveFromApiNodes method follows the established pattern for transaction execution and event handling.


204-229: Well-implemented RemoveFromReplicationNodes method

The RemoveFromReplicationNodes method follows the established pattern for transaction execution and event handling.


231-265: Well-implemented SetHttpAddress method

The SetHttpAddress method follows the established pattern for transaction execution and event handling.


303-336: Correctly implemented SetIsApiEnabled

The implementation now properly handles both enabling and disabling scenarios by conditionally parsing the appropriate event type and logging different messages based on the isApiEnabled parameter. This addresses the previous review comment.


338-375: Correctly implemented SetIsReplicationEnabled

The implementation now properly handles both enabling and disabling scenarios by conditionally parsing the appropriate event type and logging different messages based on the isReplicationEnabled parameter. This addresses the previous review comment.


377-402: Well-implemented SetMaxActiveNodes method

The SetMaxActiveNodes method follows the established pattern for transaction execution and event handling.


404-443: Well-implemented SetNodeOperatorCommissionPercent with proper validation

Good implementation with appropriate validation to ensure the commission percent is within valid range (0-10000).

owner string,
signingKeyPub *ecdsa.PublicKey,
httpAddress string,
minMonthlyFee int64,
Copy link
Contributor

Choose a reason for hiding this comment

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

We should make it really clear in comments and/or field names what unit we expect these values to be in. Are they cents, microdollars (the standard USDC contract), or picodollars (many of our internal currency calculations for fees)?

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Enhanced node management functionality with role-based controls and
new options for setting fees and toggling node statuses.
- **Refactor**
- Unified deployment and configuration processes by consolidating legacy
contract variants into a single updated node system.
- **Chores**
- Removed deprecated scripts and outdated configurations while updating
tests and deployment utilities for improved consistency.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (10)
pkg/blockchain/migrator/migrator_test.go (1)

62-62: Added minMonthlyFee parameter to AddNode.

The AddNode method now includes a minMonthlyFee parameter, which is set to 0 in this test case. Consider testing with non-zero values to ensure proper handling of this parameter.

-err := registryAdmin.AddNode(context.Background(), ownerAddress, &publicKey, httpAddress, 0)
+err := registryAdmin.AddNode(context.Background(), ownerAddress, &publicKey, httpAddress, 100) // Use non-zero value
pkg/blockchain/registryAdmin_test.go (1)

100-108: Added test coverage for new node management methods.

New test functions have been added to cover the additional node management methods such as DisableNode, EnableNode, RemoveFromApiNodes, etc. However, these tests only verify that the methods don't return errors without validating their actual effects.

Consider enhancing these tests to verify the effects of the methods by retrieving the node state after calling the methods and asserting the expected changes. For example:

func TestDisableNode(t *testing.T) {
	registry, caller, ctx, cleanup := buildRegistry(t)
	defer cleanup()

	// Add a node and get its ID
	nodeID := addNodeAndGetID(t, registry, ctx)

	// Disable the node
	err := registry.DisableNode(ctx, nodeID)
	require.NoError(t, err)

	// Verify the node is disabled
	nodes, err := caller.GetAllNodes(ctx)
	require.NoError(t, err)
	
	// Find the node and verify its state
	for _, node := range nodes {
		if node.NodeID == nodeID {
			require.False(t, node.IsEnabled)
			return
		}
	}
	
	t.Fatalf("Node with ID %d not found after disabling", nodeID)
}

Also applies to: 110-118, 120-128, 130-138, 140-146, 148-154, 156-162

pkg/blockchain/registryCaller.go (2)

23-26: Use consistent naming for struct values.
The new struct fields logically represent the client, logger, and contract references. Ensure the naming "nodeRegistryCaller" is consistent with usage across the codebase.


65-71: Watch out for large data sets.
GetAllNodes can potentially return a large slice. Ensure that upstream logic or pagination is implemented if the node list grows significantly.

pkg/blockchain/registryAdmin.go (3)

28-37: New administrative methods in the interface.
The interface expansion allows for more comprehensive node management (enable/disable node, set fees, etc.). This improves maintainability but ensure the changes are well-documented.


231-265: SetHttpAddress.
Function ensures node existence and a non-empty address before updating. Check for potential malicious addresses or length limits, if needed.


303-336: SetIsApiEnabled toggling.
This method conditionally parses ApiEnabled or ApiDisabled events. The approach matches the logic found in the contract. Ensure we handle reentrant calls or concurrency carefully if relevant.

contracts/src/Nodes.sol (3)

22-22: AccessControlDefaultAdminRules inheritance.
This approach is more flexible than a simple Ownable pattern, but ensure the admin addresses are carefully managed to avoid accidental privileges.


36-38: Max active nodes as an 8-bit value.
Capping the maximum nodes at 20 is a design choice. If usage grows, consider a more dynamic approach or a higher limit.


229-232: Node count logic.
Returns _nodeCounter. This doesn't reflect how many are disabled or burned, but is consistent with the design.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 7f8c793 and 985f8a0.

📒 Files selected for processing (17)
  • contracts/dev/deploy-local (1 hunks)
  • contracts/dev/generate (1 hunks)
  • contracts/dev/lib/common (2 hunks)
  • contracts/script/DeployNodeRegistry.s.sol (2 hunks)
  • contracts/script/DeployNodeRegistryV1.s.sol (0 hunks)
  • contracts/src/Nodes.sol (1 hunks)
  • contracts/src/NodesV2.sol (0 hunks)
  • contracts/test/Nodes.sol (3 hunks)
  • pkg/blockchain/migrator/migrator_test.go (4 hunks)
  • pkg/blockchain/registryAdmin.go (2 hunks)
  • pkg/blockchain/registryAdmin_test.go (3 hunks)
  • pkg/blockchain/registryCaller.go (2 hunks)
  • pkg/mocks/registry/mock_NodesContract.go (3 hunks)
  • pkg/registry/contractRegistry.go (3 hunks)
  • pkg/registry/contractRegistry_test.go (4 hunks)
  • pkg/registry/interface.go (1 hunks)
  • pkg/testutils/contracts.go (1 hunks)
💤 Files with no reviewable changes (2)
  • contracts/script/DeployNodeRegistryV1.s.sol
  • contracts/src/NodesV2.sol
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: Build pre-baked anvil-xmtpd
  • GitHub Check: Test (Node)
🔇 Additional comments (94)
contracts/dev/deploy-local (1)

32-32: Simplified nodes deployment command.

The deployment command for nodes has been simplified and the explicit specification of the source file and contract name have been removed. This change aligns with the PR objective to update the Nodes CLI to exclusively use the new Nodes ABI.

pkg/testutils/contracts.go (1)

142-142: Updated nodes deployment call.

The contract deployment call has been updated to use only the Nodes contract, removing the previous NodesV2 deployment logic. This change is consistent with the PR objective to deprecate unused test utilities and consolidate on the new Nodes ABI.

contracts/dev/lib/common (3)

35-35: Updated script reference for node registry deployment.

The script reference has been updated from DeployNodeRegistryV2.s.sol to DeployNodeRegistry.s.sol, aligning with the move to use the updated Nodes contract exclusively.


37-37: Updated error and success messages for Nodes contract.

The error and success messages have been appropriately updated to reference the "Nodes" contract instead of the previous "NodesV2" contract. This maintains consistency with the contract terminology used throughout the codebase.

Also applies to: 41-41


56-56: Updated valid options in error message.

The list of valid options in the error message has been updated to remove 'nodes_v2', which is consistent with the removal of this deployment option from the script.

contracts/dev/generate (1)

54-54: Removed NodesV2 from default contracts list.

NodesV2 has been removed from the list of default contracts for bindings generation, and the remaining contracts have been reordered. This change ensures that when no specific contracts are provided as arguments, the script won't attempt to generate bindings for the deprecated NodesV2 contract.

pkg/registry/interface.go (2)

4-5: Updated import path from nodesv2 to nodes

The import has been changed from nodesv2 to nodes package, aligning with the PR objective of using the new Nodes ABI exclusively.


13-13: Updated method signature to use new Node types

The return type of GetAllNodes has been updated to return []nodes.INodesNodeWithId instead of the previous nodesv2 version, maintaining interface consistency with the package changes.

pkg/registry/contractRegistry.go (3)

15-15: Updated import path from nodesv2 to nodes

The import has been changed to use the new Nodes package, consistent with the interface file changes.


60-60: Updated contract instantiation to use new Nodes caller

The contract instantiation now uses nodes.NewNodesCaller instead of the previous versioned caller, aligning with the removal of versioning mentioned in the PR summary.


235-235: Updated function parameter type to use new Nodes types

The convertNode function now accepts a parameter of type nodes.INodesNodeWithId instead of the previous nodesv2 version, maintaining consistency with the package changes.

contracts/script/DeployNodeRegistry.s.sol (3)

8-8: Updated import to use unversioned Nodes contract

Import updated from NodesV2.sol to Nodes.sol, reflecting the transition to the new Nodes contract implementation.


11-11: Changed variable type from NodesV2 to Nodes

The variable type has been updated to use the new unversioned contract type, consistent with the import changes.


26-26: Updated contract instantiation to use new Nodes contract

The contract instantiation now creates a new instance of Nodes instead of NodesV2, completing the transition to the unversioned contract.

contracts/test/Nodes.sol (4)

7-7: Updated import to use unversioned Nodes contract

Import changed from NodesV2 to Nodes, ensuring test consistency with the main contract changes.


17-17: Changed variable type from NodesV2 to Nodes

The test variable type has been updated to use the new unversioned contract type, consistent with the contract implementation changes.


31-31: Updated contract instantiation in test setup

The test setup now instantiates the Nodes contract instead of NodesV2, ensuring tests are running against the updated contract implementation.


1-887:

Details

✅ Verification successful

Verify comprehensive test coverage for new contract functionality

The test file appears to have extensive test coverage for all contract functionality including the minMonthlyFee parameter that was added to the new contract. However, since this is a major contract transition, ensure that any new functionality in the updated Nodes contract has corresponding tests.


🏁 Script executed:

#!/bin/bash
# Verify that all function names in the Nodes contract have corresponding test cases

# 1. Get all public function names from the Nodes contract
echo "Searching for public functions in Nodes contract..."
PUBLIC_FUNCTIONS=$(ast-grep --pattern 'function $func($$$) public' | grep -o 'function [a-zA-Z0-9_]\+' | awk '{print $2}')

# 2. Check if each function has a corresponding test
echo "Checking for test coverage of public functions..."
for func in $PUBLIC_FUNCTIONS; do
  TEST_COUNT=$(rg "test_.*${func}" contracts/test/Nodes.sol --count || echo "0")
  echo "Function ${func}: ${TEST_COUNT} tests found"
  if [ "$TEST_COUNT" -eq "0" ]; then
    echo "WARNING: No tests found for function ${func}"
  fi
done

# 3. Also check that any new events are tested
echo "Checking for event emission tests..."
EVENTS=$(ast-grep --pattern 'emit $event($$$)' contracts/test/Nodes.sol | grep -o 'emit [a-zA-Z0-9_]\+' | awk '{print $2}' | sort | uniq)
for event in $EVENTS; do
  echo "Found test for event: ${event}"
done

Length of output: 577


Tests comprehensively cover the updated Nodes contract functionality

The test file in contracts/test/Nodes.sol provides excellent coverage for all major functionalities—including the newly added minMonthlyFee parameter—as well as thorough checks for public functions and event emissions. Although our automated script didn’t retrieve public functions or events (likely due to Solidity syntax or pattern mismatches), a manual inspection confirms the presence of dedicated tests for each new feature. Please continue to add corresponding tests for any further additions or changes to the Nodes contract.

pkg/mocks/registry/mock_NodesContract.go (2)

9-9: Updated import path from nodesv2 to nodes.

The import path has been updated from nodesv2 to nodes, which is consistent with the changes across the PR to consolidate versioning.


26-26: Updated return types to use nodes package.

The return types have been updated from nodesv2.INodesNodeWithId to nodes.INodesNodeWithId to align with the import change. This is correctly implemented throughout all function signatures and return statements.

Also applies to: 33-33, 35-35, 38-38, 42-42, 73-73, 78-78

pkg/blockchain/migrator/migrator_test.go (4)

22-22: Simplified contract deployment in test setup.

The conditional logic for contract deployment based on version has been removed, simplifying the test setup and making it more deterministic.


57-57: Updated SerializableNode structure with new fields.

The registerRandomNode function now returns a SerializableNode instead of SerializableNodeV1, and includes new fields like MinMonthlyFee, IsReplicationEnabled, and IsApiEnabled.

Also applies to: 66-73


83-83: Test assertions updated for new node fields.

The test assertions have been updated to verify the new fields in the SerializableNode structure. This ensures that the migrator correctly handles these fields when reading from the registry.

Also applies to: 90-92, 97-99


154-155: Testing default values for new parameters.

The test verifies that the default values for the new parameters are correctly set during migration. This is important for backward compatibility.

Also applies to: 157-158

pkg/registry/contractRegistry_test.go (2)

14-14: Updated import path from nodesv2 to nodes.

The import path has been updated from nodesv2 to nodes, which is consistent with the changes across the PR to consolidate versioning.


49-50: Updated node type references to use nodes package.

All references to nodesv2.INodesNodeWithId and nodesv2.INodesNode have been updated to use the corresponding types from the nodes package. This is correctly implemented throughout all test cases.

Also applies to: 52-53, 59-60, 98-99, 105-106, 108-109, 147-148, 151-152

pkg/blockchain/registryAdmin_test.go (3)

14-20: Simplified test setup function signature.

The buildRegistry function has been updated to remove the version parameter and now returns an additional INodeRegistryCaller. This simplifies test setup and aligns with the consolidation of versioning.


42-62: Added helper function for consistent node addition in tests.

The new addRandomNode helper function encapsulates the logic for adding a random node, which improves test consistency and reduces code duplication.


89-98: Added validation test for negative minMonthlyFee.

This test verifies that the AddNode method properly validates the minMonthlyFee parameter, rejecting negative values. This is important for ensuring data integrity.

pkg/blockchain/registryCaller.go (6)

16-19: Add simplified interface for node queries.
The new methods in the interface look consistent with the contract's methods for node retrieval. This should simplify usage by removing version checks.


42-44: Check for potential nil references.
While returning the struct is straightforward, consider verifying that client or logger are not nil, to avoid panics downstream.


49-55: Expose potential contract call failures.
Returning the direct results from n.contract.GetActiveApiNodes is fine, but consider adding logging or context for errors to help with troubleshooting if the call reverts.


57-63: Consistency with GetActiveApiNodes.
The method is analogous to GetActiveApiNodes, and appears consistent.


73-80: Check for non-existent node IDs.
If the node doesn't exist, contract calls might revert or return an empty struct. Confirm that the caller properly handles the error or empty data scenario.


82-89: OwnerOf method consistent with standard NFT.
This method aligns with typical ERC721 ownership checks and looks good.

pkg/blockchain/registryAdmin.go (14)

12-12: New import for Ethereum core types.
This import is necessary for interacting with types.Transaction and event logs.


26-26: Parameter addition for minMonthlyFee.
Including minMonthlyFee as an int64 ensures more flexible fee management. Confirm that negative values are handled properly in the function.


40-44: Private fields for the nodeRegistryAdmin struct.
Storing references to client, signer, and logger is consistent with other parts of the code. Confirm usage of logger.Named("NodeRegistryAdmin") to keep logs distinct.


47-47: Compile-time interface check.
var _ INodeRegistryAdmin = &nodeRegistryAdmin{} ensures that nodeRegistryAdmin implements INodeRegistryAdmin. Good practice.


49-69: NewNodeRegistryAdmin constructor arguments.
You accept a TransactionSigner and ContractsOptions. Make sure any nil checks or invalid addresses are handled prior to contract instantiation.


71-125: Enforce negative fee validation and consistent error handling.
This function checks for negative minMonthlyFee, which is consistent with the prior review comment regarding fee validation. Please ensure CLI-level checks also align with this logic.


127-150: DisableNode with event parsing.
The logic properly calls DisableNode on the contract and handles the NodeDisabled event. Ensure that the node's current state is validated or tested via unit tests.


152-175: EnableNode reactivation flow.
Similar to DisableNode, ensure re-enabling is tested thoroughly, especially if there's unexpected state changes in the contract before re-enabling.


177-202: Removal from API set.
The method calls the contract's RemoveFromApiNodes. Consider potential edge cases where the node might already be removed or disabled, leading to no event.


204-229: Removal from replication set.
Same logic as RemoveFromApiNodes; ensure consistent handling of already-removed or disabled nodes.


267-301: SetMinMonthlyFee logic.
Ensures node existence and sets the new fee. Possibly consider a requirement that the fee cannot be negative. The contract call might handle that, but it's worth verifying.


338-375: SetIsReplicationEnabled toggling.
Similar to SetIsApiEnabled, ensure both ReplicationEnabled and ReplicationDisabled events are handled properly.


377-402: Max active nodes logic.
Updating the contract's maximum limit is straightforward. Consider verifying that the new limit is valid if the contract already has many active nodes.


404-443: Commission percent checks.
The function rejects values below 0 and above 10000. Good. Ensure the client logic or CLI also enforces constraints so that invalid values are never attempted.

contracts/src/Nodes.sol (45)

5-7: Integration with AccessControl and EnumerableSet.
Using AccessControlDefaultAdminRules and EnumerableSet provides robust role management and set operations.


9-21: Enhanced documentation for node registry.
The docstrings are comprehensive and clarify usage for node operators. This is helpful for maintainers and users alike.


23-23: EnumerableSet usage.
Provides a stable approach for tracking set membership of active nodes. Good choice for easy enumeration.


24-25: Role-based separation of concerns.
Defining separate roles for admin and node manager ensures better principle of least privilege.


27-28: BPS-based commission approach.
Using 10,000 basis points for 100% is a standard approach. Ensure that contract logic calculates commissions consistently without integer overflow.


33-34: Base token URI handling.
Storing a private _baseTokenURI is typical for ERC721. Be sure to properly override _baseURI() method for consistent metadata retrieval.


40-44: Node ID auto-increment.
Storing _nodeCounter for the next node ID is straightforward. Consider potential wrap-around if this contract is used for a very large number of nodes.


48-52: Active API nodes tracking.
Using an enumerable set is a neat approach. This ensures O(1) membership checks and enumerations.


54-60: Commission logic.
Storing as BPS is common. Ensure that any external references to this value reflect the same scale (1% = 100 etc.).


61-73: Constructor sets up roles.
The contract ensures an initial admin is assigned and roles are properly set. Confirm that the 2-day admin rule delay is tested if applicable.


75-77: Organized code structure.
Partitioning functions by role-based access is a good pattern for readability.


79-84: Add new node with minMonthlyFee.
The usage of require statements ensures valid addresses and data. Good checks.


85-95: Emitting NodeAdded event.
The newly minted node is assigned the correct ID, and the event includes minMonthlyFee. This is beneficial for transparency and indexing.


99-109: Disabling node logic.
Disabling automatically removes from active sets. This is consistent with the replaced approach of versioning.


111-114: Remove from API nodes.
Essentially the same as disable node from an API perspective.


116-119: Remove from replication nodes.
Similar logic to removeFromApiNodes, straightforward approach.


121-130: Enable node logic.
Removes the disabled flag but doesn't automatically re-add to active sets. This is consistent with the notion that node operator must re-enable.


132-139: Update maximum active nodes.
Reverting if the new limit is below the current active sets is a sensible safety measure. Good checks.


141-146: Commission percent update.
Ensures the newCommissionPercent <= MAX_BPS. Good. No risk of integer overflow.


148-154: Base URI update logic.
Checks for trailing slash. This ensures metadata is resolved properly.


156-158: Node Manager functions grouping.
Again, good code organization.


160-176: Modified transferFrom with forced disable.
This ensures that transferring ownership automatically disables the node. The new owner must re-enable. This is a robust approach for preventing unauthorized usage.


179-184: HTTP address update restricted to NODE_MANAGER_ROLE.
Verifies node existence and new address. Appropriately signals via event.


186-191: Minimum monthly fee setter.
The node operator can set fees. This aligns with the updates in registryAdmin. Ensure thorough testing.


197-205: API enablement by node owner.
This function uses a whenNotDisabled modifier, ensuring no disabled node can become API-enabled automatically. Good approach.


207-215: Replication enablement by node owner.
Same design pattern as setIsApiEnabled, consistent usage of sets.


217-227: Retrieve all nodes with IDs.
The code iterates over _nodeCounter. This is simpler than version-based logic. Ensure that _nodeExists is used to skip any uninitialized or burned nodes.


234-238: Node retrieval.
Reverts if node does not exist. Aligns with typical usage.


240-250: Enumerating active API nodes.
The approach matches _activeApiNodes.values(), returning node structures.


252-255: Retrieve just the IDs.
This saves overhead if the caller doesn't need full node data.


257-260: First-class count retrieval.
Directly returning _activeApiNodes.length().


262-265: Check membership in set.
Returning _activeApiNodes.contains(nodeId). This is straightforward.


267-277: Parallel structure for replication nodes.
Mirrors getActiveApiNodes.


279-282: Retrieve replication node IDs.
Straightforward usage of _activeReplicationNodes.values().


284-287: Replication node count retrieval.
Same approach as getActiveApiNodesCount.


289-292: Check replication node membership.
Mirrors getApiNodeIsActive.


294-297: Public commission percent retrieval.
Exposes nodeOperatorCommissionPercent.


299-304: Prevent actions on disabled nodes.
Ensures the node is not disabled for operations like enabling API/replication.


306-311: Existence check.
Uses _ownerOf(nodeId) instead of _nodes[nodeId].owner. This is consistent with the ERC721 logic.


313-316: Override for base URI.
Returns _baseTokenURI.


318-327: Activate node in API set.
Requires that _activeApiNodes.length() < maxActiveNodes. This prevents new additions if there's no capacity.


330-337: Disable node from API set.
Sets isApiEnabled = false and emits an event.


339-349: Activate node in replication set.
Same pattern as _activateApiNode.


351-357: Disable node from replication set.
Sets isReplicationEnabled = false and emits an event.


361-370: Supports multiple interfaces.
Overriding supportsInterface to handle ERC721 and AccessControl.

@fbac fbac merged commit c14cd2c into 04-05-use_nodesv2 Mar 7, 2025
13 of 14 checks passed
@fbac fbac deleted the 04-05-update_nodes_cli branch March 7, 2025 10:19
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.

Nodes contract: update cli

3 participants