From 86c99309d4d31644689b4794cc2970e7c72a1ee4 Mon Sep 17 00:00:00 2001 From: Michael Sovereign Date: Mon, 20 Apr 2026 00:14:46 +0100 Subject: [PATCH] fix: resolve _handle_get_state arity mismatch (#2288) - Fix TypeError in _handle_get_state by adding msg_id and ttl to _signed_content call. - Synchronize signature verification with p2p_identity.unpack_signature 3-arg return. - Ensure state response includes msg_id/ttl for peer verification. --- node/rustchain_p2p_gossip.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/node/rustchain_p2p_gossip.py b/node/rustchain_p2p_gossip.py index 268526f50..36f5e7760 100644 --- a/node/rustchain_p2p_gossip.py +++ b/node/rustchain_p2p_gossip.py @@ -399,7 +399,7 @@ def _verify_signature(self, content: str, signature: str, timestamp: int) -> boo mode = self._signing_mode from p2p_identity import unpack_signature, verify_ed25519 - hmac_sig, ed25519_sig = unpack_signature(signature) + hmac_sig, ed25519_sig, _v = unpack_signature(signature) # "strict" mode: only Ed25519 accepted. HMAC-only sigs are rejected # even if valid (flag-day enforcement). @@ -480,7 +480,7 @@ def verify_message(self, msg: GossipMessage) -> bool: mode = self._signing_mode from p2p_identity import unpack_signature, verify_ed25519 - hmac_sig, ed25519_sig = unpack_signature(msg.signature) + hmac_sig, ed25519_sig, _v = unpack_signature(msg.signature) # 1) Try Ed25519 if available AND peer is registered. if ed25519_sig and self._peer_registry is not None: @@ -880,16 +880,22 @@ def _handle_get_state(self, msg: GossipMessage) -> Dict: "balances": self.balance_crdt.to_dict() } # Sign the state response so the requester can verify authenticity. - # Uses the Phase A signed-content shape (msg_type:sender_id:payload) - # so verify_message() on the requester side accepts it. + # SECURITY (#2272): must include msg_id and ttl for arity compliance. payload = {"state": state_data} - content = self._signed_content(MessageType.STATE.value, self.node_id, payload) + + # Generate synthetic msg_id for the response (non-forwarded, ttl=0) + import hashlib, time + state_msg_id = hashlib.sha256(f"STATE:{self.node_id}:{time.time()}".encode()).hexdigest()[:24] + + content = self._signed_content(MessageType.STATE.value, self.node_id, state_msg_id, 0, payload) signature, timestamp = self._sign_message(content) return { "status": "ok", "state": state_data, "signature": signature, "timestamp": timestamp, + "msg_id": state_msg_id, + "ttl": 0, "sender_id": self.node_id }