// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; contract CodeHashAgentCluster { struct Node { bytes32 codehash; address prev; address next; } mapping(address => Node) private nodes; mapping(bytes32 => address) private heads; event Registered(address indexed agent, bytes32 indexed codehash); event Unregistered(address indexed agent, bytes32 indexed codehash); function register() external { bytes32 h = msg.sender.codehash; require(h != bytes32(0), "NO_CODE"); require(nodes[msg.sender].codehash == bytes32(0), "ALREADY"); Node storage n = nodes[msg.sender]; n.codehash = h; address head = heads[h]; n.next = head; if (head != address(0)) nodes[head].prev = msg.sender; heads[h] = msg.sender; emit Registered(msg.sender, h); } function unregister() external { Node storage n = nodes[msg.sender]; bytes32 h = n.codehash; require(h != bytes32(0), "NOT_REG"); address prev = n.prev; address next = n.next; if (prev != address(0)) nodes[prev].next = next; else heads[h] = next; if (next != address(0)) nodes[next].prev = prev; delete nodes[msg.sender]; emit Unregistered(msg.sender, h); } function lookup(bytes32 h) external view returns (address[] memory) { uint256 count = 0; address cur = heads[h]; while (cur != address(0)) { count++; cur = nodes[cur].next; } address[] memory result = new address[](count); cur = heads[h]; for (uint256 i = 0; i < count; i++) { result[i] = cur; cur = nodes[cur].next; } return result; } }