Skip to content

Fix P2P message validation and host parameter#64

Open
quickquickcode wants to merge 1 commit intoStabilityNexus:mainfrom
quickquickcode:quickquickcode/fix_run_code
Open

Fix P2P message validation and host parameter#64
quickquickcode wants to merge 1 commit intoStabilityNexus:mainfrom
quickquickcode:quickquickcode/fix_run_code

Conversation

@quickquickcode
Copy link

@quickquickcode quickquickcode commented Mar 21, 2026

Problem

When starting a second MiniChain node and connecting to the first node, the following issues occurred:

  1. AttributeError: 'P2PNetwork' object has no attribute 'set_on_peer_connected'
  2. OSError: Missing host parameter in run_node function
  3. Invalid message schema warnings: The _validate_message method strictly checked for {"type", "data"} fields, but _listen_to_peer adds _peer_addr field, causing validation to fail

Solution

  1. Added missing host parameter to run_node function in main.py
  2. Changed network.set_on_peer_connected() to network._on_peer_connected = on_peer_connected
  3. Updated P2PNetwork.start() method to accept host parameter
  4. Modified _validate_message to allow _peer_addr field in addition to type and data

Testing

  • All 41 existing tests pass
  • Manual testing shows nodes can now connect without validation errors

Changes

  • main.py: Fixed function signature and method call
  • minichain/p2p.py: Added host parameter and fixed message validation logic

Summary by CodeRabbit

  • New Features

    • Network nodes can now bind to configurable host addresses instead of only localhost.
  • Improvements

    • Enhanced peer message validation to support additional metadata while maintaining protocol integrity.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 21, 2026

Walkthrough

The pull request adds configurable host binding to the P2P network initialization, updating run_node and P2PNetwork.start to accept a host parameter. Message validation is relaxed to allow peer address metadata attachment, and callback registration uses direct assignment instead of a setter method.

Changes

Cohort / File(s) Summary
Node Startup Configuration
main.py
Updated run_node signature to accept host: str parameter; passes configured host to asyncio.run(). Changed peer-connection callback registration from network.set_on_peer_connected() to direct _on_peer_connected assignment.
P2P Network Host Binding & Validation
minichain/p2p.py
Extended P2PNetwork.start to accept host: str parameter with default "127.0.0.1", passing it to asyncio.start_server(). Relaxed message schema validation to allow optional _peer_addr field while maintaining required type and data fields.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

Python Lang

Suggested reviewers

  • Zahnentferner

Poem

🐰 A node now blooms with configurable grace,
Binding to hosts in its chosen place,
Peer addresses flow through messages with ease,
Direct callbacks dance on the networking breeze,
Validation relaxes to let metadata through! 🌐✨

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main changes: adding a missing host parameter and fixing P2P message validation schema.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Tip

You can disable poems in the walkthrough.

Disable the reviews.poem setting to disable the poems in the walkthrough.

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@main.py`:
- Line 329: Replace the direct assignment to the private attribute
network._on_peer_connected by adding a public registration method on the
P2PNetwork class (e.g., register_on_peer_connected or
add_peer_connected_handler) that accepts the callback and sets/updates the
internal handler, then call that method from main.py instead of writing to
network._on_peer_connected; modify P2PNetwork to store the handler and invoke it
where peers connect, and update main.py to call the new public method with
on_peer_connected.

In `@minichain/p2p.py`:
- Around line 209-215: The current validator is allowing `_peer_addr` in the
on‑wire schema; instead validate the raw envelope first by checking
required_fields = {"type","data"} against the incoming message (ensure issubset
of set(message)) and reject any extra fields immediately (i.e. ensure
set(message).issubset({"type","data"})) before attaching transport metadata;
remove `_peer_addr` from allowed_fields validation and only add `_peer_addr`
after the message passes validation (the place where `_listen_to_peer` attaches
`_peer_addr` should perform that attachment post‑validation).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 95a741f2-3b3e-41b0-8eba-b6f1edbbfcf3

📥 Commits

Reviewing files that changed from the base of the PR and between 1b61cae and 195f09d.

📒 Files selected for processing (2)
  • main.py
  • minichain/p2p.py

logger.info("🔄 Sent state sync to new peer")

network.set_on_peer_connected(on_peer_connected)
network._on_peer_connected = on_peer_connected
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Prefer a public callback registration method over writing P2PNetwork internals.

Assigning network._on_peer_connected directly fixes the immediate error, but it hard-codes a private field name into main.py. A small public registration method in P2PNetwork would keep this contract centralized and easier to evolve.

Suggested API shape
# minichain/p2p.py
+    def register_on_peer_connected(self, callback):
+        if not callable(callback):
+            raise ValueError("callback must be callable")
+        self._on_peer_connected = callback
# main.py
-    network._on_peer_connected = on_peer_connected
+    network.register_on_peer_connected(on_peer_connected)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@main.py` at line 329, Replace the direct assignment to the private attribute
network._on_peer_connected by adding a public registration method on the
P2PNetwork class (e.g., register_on_peer_connected or
add_peer_connected_handler) that accepts the callback and sets/updates the
internal handler, then call that method from main.py instead of writing to
network._on_peer_connected; modify P2PNetwork to store the handler and invoke it
where peers connect, and update main.py to call the new public method with
on_peer_connected.

Comment on lines +209 to +215
# Allow _peer_addr field added by _listen_to_peer
required_fields = {"type", "data"}
if not required_fields.issubset(set(message)):
return False
# Reject messages with unexpected fields (except _peer_addr)
allowed_fields = {"type", "data", "_peer_addr"}
if not set(message).issubset(allowed_fields):
Copy link
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Keep _peer_addr out of the wire-schema validator.

_peer_addr is local transport metadata, not part of the documented on-the-wire message shape. A tighter fix is to validate the raw {"type", "data"} envelope first, then attach _peer_addr only after it passes.

Suggested fix
     def _validate_message(self, message):
         if not isinstance(message, dict):
             return False
-        # Allow _peer_addr field added by _listen_to_peer
-        required_fields = {"type", "data"}
-        if not required_fields.issubset(set(message)):
-            return False
-        # Reject messages with unexpected fields (except _peer_addr)
-        allowed_fields = {"type", "data", "_peer_addr"}
-        if not set(message).issubset(allowed_fields):
+        if set(message) != {"type", "data"}:
             return False
-                if isinstance(data, dict):
-                    data["_peer_addr"] = addr
-
                 if not self._validate_message(data):
                     logger.warning("Network: Invalid message schema from %s", addr)
                     continue
+
+                data["_peer_addr"] = addr
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@minichain/p2p.py` around lines 209 - 215, The current validator is allowing
`_peer_addr` in the on‑wire schema; instead validate the raw envelope first by
checking required_fields = {"type","data"} against the incoming message (ensure
issubset of set(message)) and reject any extra fields immediately (i.e. ensure
set(message).issubset({"type","data"})) before attaching transport metadata;
remove `_peer_addr` from allowed_fields validation and only add `_peer_addr`
after the message passes validation (the place where `_listen_to_peer` attaches
`_peer_addr` should perform that attachment post‑validation).

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.

1 participant