Skip to content

Oracle System

dev-mondoshawan edited this page Jul 1, 2026 · 1 revision

Oracle System

**Referenced Files in This Document** - [README.md](file://README.md) - [docs/reputation-model.md](file://docs/reputation-model.md) - [docs/quickstart.md](file://docs/quickstart.md) - [oracle/index.js](file://oracle/index.js) - [oracle/scoring.js](file://oracle/scoring.js) - [oracle/chain.js](file://oracle/chain.js) - [oracle/Dockerfile](file://oracle/Dockerfile) - [docker-compose.oracle.yml](file://docker-compose.oracle.yml) - [oracle/package.json](file://oracle/package.json) - [src/CountersigReputation.sol](file://src/CountersigReputation.sol) - [src/CountersigIdentity.sol](file://src/CountersigIdentity.sol) - [test/CountersigReputation.t.sol](file://test/CountersigReputation.t.sol)

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Detailed Component Analysis
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion
  10. Appendices

Introduction

This document describes the Countersig Network oracle system that computes and distributes the 6-factor reputation score for registered AI agents. It explains the off-chain oracle architecture, HTTP API endpoints, event-driven epoch processing, the scoring algorithm, on-chain integration, and operational guidance for oracle operators.

The oracle reads on-chain agent registrations, aggregates off-chain signals (attestations and flags), computes a 6-factor score per agent, and writes the result to the on-chain reputation contract. Slashing events cause immediate score resets on-chain.

Project Structure

The oracle system is implemented as a small Node.js service with a Docker image and orchestration via docker-compose. Off-chain computation feeds into on-chain contracts that store and serve reputation.

graph TB
subgraph "Oracle Service"
IDX["index.js<br/>HTTP API + epoch scheduler"]
CHAIN["chain.js<br/>EVM interactions"]
SCORE["scoring.js<br/>6-factor scoring"]
end
subgraph "On-Chain"
ID["CountersigIdentity.sol<br/>Agent registry + status"]
REP["CountersigReputation.sol<br/>Reputation store + thresholds"]
end
IDX --> CHAIN
IDX --> SCORE
CHAIN --> ID
CHAIN --> REP
CHAIN -. "slash resets" .-> REP
Loading

Diagram sources

  • oracle/index.js:1-178
  • oracle/chain.js:1-85
  • oracle/scoring.js:1-50
  • src/CountersigIdentity.sol:1-227
  • src/CountersigReputation.sol:1-181

Section sources

  • README.md:20-51
  • docs/reputation-model.md:141-149
  • oracle/Dockerfile:1-11
  • docker-compose.oracle.yml:1-11

Core Components

  • HTTP API server: Provides health, manual epoch trigger, attestation submission, flag submission, and score preview endpoints.
  • Chain integration: Connects to RPC, scans AgentRegistered events, reads agent info, and writes reputation updates.
  • Scoring module: Implements the 6-factor reputation computation (Fee Activity, Success Rate, Age, External Trust, Community, Propagation).
  • On-chain contracts: CountersigIdentity manages agent registration and status; CountersigReputation stores and validates scores.

Section sources

  • oracle/index.js:78-171
  • oracle/chain.js:24-84
  • oracle/scoring.js:36-47
  • src/CountersigReputation.sol:24-181
  • src/CountersigIdentity.sol:18-101

Architecture Overview

The oracle operates in epochs. During each epoch:

  • Scan for newly registered agents by querying AgentRegistered events in chunks.
  • For each agent, fetch registration metadata and current status.
  • Aggregate off-chain signals (attestations and flags) from the HTTP API.
  • Compute the 6-factor score and write it on-chain via updateReputation.
  • Slashed agents are skipped; their score was zeroed by staking.
sequenceDiagram
participant Cron as "Scheduler"
participant Oracle as "index.js"
participant Chain as "chain.js"
participant ID as "CountersigIdentity"
participant REP as "CountersigReputation"
Cron->>Oracle : runEpoch()
Oracle->>Chain : getRegisteredAgents()
Chain-->>Oracle : agent list
loop for each agent
Oracle->>Chain : getAgentInfo(didHash)
Chain-->>Oracle : {registeredAt,status}
Oracle->>Oracle : computeScore(...)
Oracle->>Chain : writeReputation(didHash, scores)
Chain->>REP : updateReputation(...)
REP-->>Chain : ReputationUpdated
end
Loading

Diagram sources

  • oracle/index.js:41-76
  • oracle/chain.js:36-82
  • src/CountersigReputation.sol:107-129

Detailed Component Analysis

HTTP API Endpoints

  • GET /health
    • Returns health status and configured epoch interval.
  • POST /epoch
    • Triggers a manual epoch run (202 Accepted).
  • POST /attest
    • Body: { didHash, success }
    • Authorized by optional admin token; increments attestation counters.
  • POST /flag
    • Body: { didHash }
    • Authorized by optional admin token; increments unresolved flag count.
  • GET /score/:didHash
    • Returns computed scores and current counters without writing to chain.

Security:

  • Authorization is optional; if ORACLE_ADMIN_TOKEN is unset, all requests are allowed. Configure the token to restrict administrative endpoints.

Operational notes:

  • Request body size is bounded (~1MB).
  • Endpoints return JSON with appropriate HTTP status codes.

Section sources

  • oracle/index.js:115-171
  • oracle/index.js:105-109
  • oracle/index.js:87-103

Event Processing and Epoch Logic

  • Epoch scheduling:
    • Starts immediately on boot and repeats every EPOCH_HOURS (default 24 hours).
  • Agent discovery:
    • Scans AgentRegistered events in chunks sized by LOG_CHUNK_SIZE (default 2000) to respect RPC limits.
    • Maintains a local cache of known agents and scans only new blocks since last scan.
  • Per-agent processing:
    • Skips agents with Slashed status.
    • Reads registration timestamp and status.
    • Uses in-memory maps for attestations and flags.
    • Writes ReputationUpdated events on-chain.
flowchart TD
Start(["Epoch Start"]) --> FetchAgents["Fetch registered agents<br/>scan new logs in chunks"]
FetchAgents --> Loop{"More agents?"}
Loop --> |Yes| ReadMeta["Read agent info<br/>(registeredAt,status)"]
ReadMeta --> StatusCheck{"Status == Slashed?"}
StatusCheck --> |Yes| Skip["Skip agent"]
StatusCheck --> |No| Compute["Compute scores<br/>(attestations, flags)"]
Compute --> Write["Write to CountersigReputation"]
Write --> Loop
Loop --> |No| Done(["Epoch End"])
Skip --> Loop
Loading

Diagram sources

  • oracle/index.js:41-76
  • oracle/chain.js:36-60
  • oracle/chain.js:62-68

Section sources

  • oracle/index.js:41-76
  • oracle/chain.js:36-60

6-Factor Reputation Scoring

Factors and caps:

  • Fee Activity: up to 30
  • Success Rate: up to 25
  • Age: up to 20
  • External Trust: up to 15
  • Community: up to 5
  • Propagation: up to 5
  • Total: up to 100

Implementation highlights:

  • Fee Activity: increases with transaction volume (proxy metric).
  • Success Rate: ratio of successful to total attestations.
  • Age: logarithmic curve reaching maximum around day 31.
  • Community: penalized by unresolved flags.
  • External Trust and Propagation: stubs returning 0 until Phase 2.
flowchart TD
In(["Inputs"]) --> FS["Fee Activity<br/>min(30, floor(total/10))"]
In --> SR["Success Rate<br/>floor(success/total * 25)"]
In --> AGE["Age<br/>min(20, floor(log2(days+1)*4))"]
In --> EXT["External Trust<br/>stub = 0"]
In --> COMM["Community<br/>max(0, 5 - flags*2)"]
In --> PROP["Propagation<br/>stub = 0"]
FS --> SUM["Sum factors"]
SR --> SUM
AGE --> SUM
EXT --> SUM
COMM --> SUM
PROP --> SUM
SUM --> Out(["Scores + total"])
Loading

Diagram sources

  • oracle/scoring.js:9-47

Section sources

  • oracle/scoring.js:9-47
  • docs/reputation-model.md:9-82

On-Chain Integration and Validation

  • CountersigIdentity:
    • Stores operator, agent address, Ed25519 public key, status, and registration timestamp.
    • Supports status transitions and key rotation with safeguards.
  • CountersigReputation:
    • Stores per-agent factor scores and lastUpdated.
    • Validates each factor against its cap during updateReputation.
    • Provides getTotalScore and meetsThreshold for on-chain consumers.
    • zeroReputation is callable by STAKING_CORE_ROLE to reset scores after slashing.
classDiagram
class CountersigIdentity {
+registerAgent(agentAddress, ed25519PubKey)
+getIdentity(didHash)
+updateStatus(didHash, status)
+rotatePublicKey(didHash, newKey)
}
class CountersigReputation {
+updateReputation(didHash, data)
+zeroReputation(didHash)
+getReputation(didHash)
+getTotalScore(didHash) uint8
+meetsThreshold(didHash, threshold) bool
}
CountersigReputation --> CountersigIdentity : "consumes status"
Loading

Diagram sources

  • src/CountersigIdentity.sol:107-179
  • src/CountersigReputation.sol:107-173

Section sources

  • src/CountersigIdentity.sol:18-101
  • src/CountersigReputation.sol:24-181
  • test/CountersigReputation.t.sol:38-115

Consensus, Aggregation, and Distribution

  • Current oracle:
    • Single-operator, in-memory aggregation, writes to on-chain.
    • Epoch interval is configurable (default 24 hours).
  • Future (Phase 2):
    • Decentralized oracle network governs epoch consensus.
    • External data sources (SAID, Gitcoin Passport) and propagation graph integrated.

Operational impact:

  • Operators should monitor epoch cadence and ensure reliable RPC connectivity.
  • Administrative endpoints are protected by an optional bearer token.

Section sources

  • docs/reputation-model.md:141-149
  • oracle/index.js:11-21
  • oracle/index.js:105-109

Dependency Analysis

Internal dependencies:

  • index.js depends on chain.js for EVM interactions and scoring.js for score computation.
  • chain.js depends on environment-configured RPC and contract ABIs.

External dependencies:

  • ethers.js for EVM interactions.
  • dotenv for environment variable loading.
graph LR
IDX["index.js"] --> CHAIN["chain.js"]
IDX --> SCORE["scoring.js"]
CHAIN --> ETH["ethers.js"]
IDX --> DOT["dotenv"]
Loading

Diagram sources

  • oracle/index.js:5-7
  • oracle/chain.js:3
  • oracle/package.json:10-12

Section sources

  • oracle/package.json:10-12
  • oracle/index.js:3

Performance Considerations

  • Epoch cadence: Tune EPOCH_HOURS to balance freshness vs. RPC costs.
  • Log scanning: LOG_CHUNK_SIZE bounds RPC query sizes; adjust for provider rate limits.
  • Memory footprint: In-memory maps suffice for testnet; production should persist to disk or DB to avoid recomputation on restart.
  • Throughput: The scoring functions are O(1); bottlenecks are typically RPC latency and gas costs.

[No sources needed since this section provides general guidance]

Troubleshooting Guide

Common issues and remedies:

  • Missing environment variables:
    • Ensure RPC_URL, ORACLE_PRIVATE_KEY, IDENTITY_ADDRESS, REPUTATION_ADDRESS are set.
  • Unauthorized administrative endpoints:
    • Set ORACLE_ADMIN_TOKEN and use Authorization: Bearer .
  • Epoch errors:
    • Check RPC connectivity and provider rate limits.
    • Review logs for per-agent failures during writeReputation.
  • Slashed agents:
    • Slashed agents are skipped; their score was zeroed on-chain by staking.
  • Score validation failures:
    • On-chain updateReputation reverts if any factor exceeds its cap.

Section sources

  • oracle/index.js:23-26
  • oracle/index.js:105-109
  • oracle/chain.js:70-82
  • src/CountersigReputation.sol:111-116

Conclusion

The Countersig oracle is a compact, event-driven system that computes and publishes 6-factor reputation scores to the blockchain. Its modular design separates concerns cleanly: HTTP API for ingestion, chain integration for on-chain writes, and scoring for computation. Operators should configure secure credentials, monitor epoch health, and prepare for Phase 2’s decentralized consensus and expanded data sources.

[No sources needed since this section summarizes without analyzing specific files]

Appendices

Setup Instructions for Oracle Operators

  • Environment:
    • Copy .env.example to .env and set RPC_URL, ORACLE_PRIVATE_KEY, IDENTITY_ADDRESS, REPUTATION_ADDRESS, optionally ORACLE_ADMIN_TOKEN.
  • Local run:
    • Install dependencies and start with node index.js.
  • Docker deployment:
    • Build and run the service using docker-compose.oracle.yml.
    • The container exposes port 3030 and mounts the .env file.

Section sources

  • docs/quickstart.md:17-32
  • docker-compose.oracle.yml:1-11
  • oracle/Dockerfile:1-11
  • oracle/package.json:6-8

Monitoring Requirements

  • Health endpoint: GET /health to confirm uptime and epoch interval.
  • Manual trigger: POST /epoch to validate end-to-end operation.
  • Score preview: GET /score/:didHash to inspect computed scores before on-chain writes.
  • Logs: Monitor epoch start/end, per-agent successes/failures, and writeReputation outcomes.

Section sources

  • oracle/index.js:115-118
  • oracle/index.js:120-124
  • oracle/index.js:155-168

Relationship Between Oracle Operations and On-Chain Updates

  • Oracle writes ReputationUpdated events via updateReputation.
  • Slashing triggers zeroReputation, resetting all scores to zero.
  • On-chain consumers query meetsThreshold or getTotalScore for trust decisions.

Section sources

  • src/CountersigReputation.sol:107-129
  • src/CountersigReputation.sol:135-146
  • README.md:234-249

Clone this wiki locally