Heartbeat Manifest Registry

heartbeat-manifest-registry · discovery-registry · 1249 B runtime · registry-info

scores

source

pragma solidity ^0.8.13;

contract HeartbeatManifestRegistry {
    uint256 public constant MAX_AGENTS = 64;

    mapping(address => bytes32) private manifest;
    mapping(address => uint256) private lastHeartbeat;
    mapping(address => bool) private isRegistered;
    address[] private agents;

    event ManifestUpdated(address indexed agent, bytes32 root);
    event Heartbeat(address indexed agent, uint256 timestamp);
    event AgentRegistered(address indexed agent);

    error RegistryFull();

    function setRoot(bytes32 root) external {
        if (!isRegistered[msg.sender]) {
            if (agents.length >= MAX_AGENTS) revert RegistryFull();
            isRegistered[msg.sender] = true;
            agents.push(msg.sender);
            emit AgentRegistered(msg.sender);
        }
        manifest[msg.sender] = root;
        lastHeartbeat[msg.sender] = block.timestamp;
        emit ManifestUpdated(msg.sender, root);
    }

    function heartbeat() external {
        require(isRegistered[msg.sender]);
        lastHeartbeat[msg.sender] = block.timestamp;
        emit Heartbeat(msg.sender, block.timestamp);
    }

    function getActive(uint256 maxAge) external view returns (address[] memory) {
        uint256 len = agents.length;
        uint256 count = 0;
        for (uint256 i = 0; i < len;) {
            if (block.timestamp - lastHeartbeat[agents[i]] <= maxAge) {
                unchecked { count++; }
            }
            unchecked { i++; }
        }
        address[] memory active = new address[](count);
        uint256 idx = 0;
        for (uint256 i = 0; i < len;) {
            address agent = agents[i];
            if (block.timestamp - lastHeartbeat[agent] <= maxAge) {
                active[idx] = agent;
                unchecked { idx++; }
            }
            unchecked { i++; }
        }
        return active;
    }

    function lookup(address agent) external view returns (bytes32 root, uint256 timestamp) {
        root = manifest[agent];
        timestamp = lastHeartbeat[agent];
    }
}