Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Dockerfile.reth-erc8004-indexer
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM rust:1.93-bookworm AS builder

WORKDIR /build

COPY reth-erc8004-indexer/Cargo.toml reth-erc8004-indexer/Cargo.toml
COPY reth-erc8004-indexer/src reth-erc8004-indexer/src

RUN cargo build --release --manifest-path reth-erc8004-indexer/Cargo.toml

FROM ghcr.io/paradigmxyz/reth:v1.11.1

COPY --from=builder /build/target/release/reth /usr/local/bin/reth
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ obol network sync --all

**Ethereum options:** `--network` (mainnet, sepolia, hoodi), `--execution-client` (reth, geth, nethermind, besu, erigon, ethereumjs), `--consensus-client` (lighthouse, prysm, teku, nimbus, lodestar, grandine)

**Reth indexer options:** when `--execution-client reth` is selected, the Ethereum network template can also expose the embedded ERC-8004 indexer with `--reth-indexer-enabled=true`, `--reth-image-repository=<image>`, `--reth-image-tag=<tag>`, `--reth-indexer-port=8088`, `--reth-indexer-db-path=/data/erc8004-indexer/indexer.db`, `--reth-indexer-registry-address=0x8004A818BFB912233c491871b3d84c89A494BD9e`, and `--reth-indexer-backfill-from-block=0`. The custom image is built from [Dockerfile.reth-erc8004-indexer](/Users/bussyjd/Development/Obol_Workbench/obol-stack/.codex/worktrees/reth-indexer/Dockerfile.reth-erc8004-indexer) and exposes `/health` plus `/api/v1/public/*` from the same Reth pod.

```bash
# View installed deployments
obol kubectl get namespaces | grep -E "ethereum|aztec"
Expand Down
33 changes: 32 additions & 1 deletion internal/embed/networks/ethereum/helmfile.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ releases:
enabled: true
image:
{{- if eq .Values.executionClient "reth" }}
tag: v1.11.1
repository: '{{ if .Values.rethImageRepository }}{{ .Values.rethImageRepository }}{{ else }}ghcr.io/paradigmxyz/reth{{ end }}'
tag: '{{ if .Values.rethImageTag }}{{ .Values.rethImageTag }}{{ else }}v1.11.1{{ end }}'
{{- else if eq .Values.executionClient "geth" }}
tag: v1.17.0
{{- else if eq .Values.executionClient "nethermind" }}
Expand All @@ -56,6 +57,22 @@ releases:
enabled: true
size: 500Gi
existingClaim: execution-{{ .Values.executionClient }}-{{ .Values.network }}
{{- if and (eq .Values.executionClient "reth") .Values.rethIndexerEnabled }}
extraArgs:
- --erc8004-indexer-http-addr=0.0.0.0:{{ .Values.rethIndexerPort }}
- --erc8004-indexer-db-path={{ .Values.rethIndexerDbPath }}
- --erc8004-registry-address={{ .Values.rethIndexerRegistryAddress }}
- --erc8004-backfill-from-block={{ .Values.rethIndexerBackfillFromBlock }}
extraContainerPorts:
- name: erc8004-indexer
containerPort: {{ .Values.rethIndexerPort }}
protocol: TCP
extraPorts:
- name: erc8004-indexer
port: {{ .Values.rethIndexerPort }}
targetPort: erc8004-indexer
protocol: TCP
{{- end }}

# Consensus client (pinned versions — update periodically)
# The upstream chart wires --execution-endpoint and --network automatically.
Expand Down Expand Up @@ -113,5 +130,19 @@ releases:
"internal": "http://ethereum-beacon.ethereum-{{ .Values.id }}.svc.cluster.local:5052"
}
}
}{{ if and (eq .Values.executionClient "reth") .Values.rethIndexerEnabled }},{{ end }}
{{- if and (eq .Values.executionClient "reth") .Values.rethIndexerEnabled }}
"indexer": {
"kind": "erc8004",
"registryAddress": "{{ .Values.rethIndexerRegistryAddress }}",
"endpoints": {
"health": {
"internal": "http://ethereum-execution.ethereum-{{ .Values.id }}.svc.cluster.local:{{ .Values.rethIndexerPort }}/health"
},
"public": {
"internal": "http://ethereum-execution.ethereum-{{ .Values.id }}.svc.cluster.local:{{ .Values.rethIndexerPort }}/api/v1/public"
}
}
}
{{- end }}
}
28 changes: 28 additions & 0 deletions internal/embed/networks/ethereum/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,31 @@ executionClient: {{.ExecutionClient}}
# @default lighthouse
# @description Consensus layer client
consensusClient: {{.ConsensusClient}}

# @default
# @description Custom Reth image repository for ERC-8004 indexer deployments
rethImageRepository: {{.RethImageRepository}}

# @default
# @description Custom Reth image tag for ERC-8004 indexer deployments
rethImageTag: {{.RethImageTag}}

# @default false
# @description Enable the embedded ERC-8004 indexer HTTP API in the Reth pod
rethIndexerEnabled: {{.RethIndexerEnabled}}

# @default 8088
# @description Service port for the embedded ERC-8004 indexer API
rethIndexerPort: {{.RethIndexerPort}}

# @default /data/erc8004-indexer/indexer.db
# @description SQLite path for the embedded ERC-8004 indexer
rethIndexerDbPath: {{.RethIndexerDbPath}}

# @default 0x8004A818BFB912233c491871b3d84c89A494BD9e
# @description ERC-8004 identity registry address indexed by the custom Reth binary
rethIndexerRegistryAddress: {{.RethIndexerRegistryAddress}}

# @default 0
# @description Historical start block for the initial ERC-8004 backfill
rethIndexerBackfillFromBlock: {{.RethIndexerBackfillFromBlock}}
11 changes: 6 additions & 5 deletions internal/embed/skills/autoresearch-coordinator/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ Coordinate distributed autoresearch experiments across GPU workers discovered on

## When to Use

- Discovering GPU workers advertising `machine_learning/model_optimization` capabilities via 8004scan
- Discovering GPU workers advertising `machine_learning/model_optimization` capabilities via the preferred public index API (internal Reth indexer first, then 8004scan fallback)
- Probing worker endpoints for x402 pricing before submitting experiments
- Submitting `train.py` experiments to remote GPU workers through x402 payment gates
- Running the continuous THINK/CLAIM/RUN/PUBLISH experiment loop
Expand All @@ -28,7 +28,7 @@ Coordinate distributed autoresearch experiments across GPU workers discovered on
## Quick Start

```bash
# Discover available GPU workers on 8004scan
# Discover available GPU workers from the preferred public index API
python3 scripts/coordinate.py discover

# Discover with custom limit
Expand Down Expand Up @@ -58,7 +58,7 @@ python3 scripts/coordinate.py loop train.py --prefer https://worker.example.com/

| Command | Description |
|---------|-------------|
| `discover [--limit N]` | Query 8004scan for GPU workers with `machine_learning/model_optimization` skill |
| `discover [--limit N]` | Query the preferred public index API for GPU workers with `machine_learning/model_optimization` skill |
| `probe <endpoint>` | Send unauthenticated request to parse 402 pricing from the worker |
| `submit <endpoint> <train.py> [--config JSON]` | Submit experiment with x402 payment (pre-sign ERC-3009, attach X-PAYMENT) |
| `leaderboard [--limit N]` | Query 8004scan for all autoresearch workers, rank by best `val_bpb` |
Expand All @@ -77,7 +77,7 @@ Each step is atomic and idempotent. If a worker fails mid-experiment, the coordi

## How Discovery Works

Workers register on-chain via ERC-8004 and advertise capabilities through OASF (Open Agent Skills Framework) metadata. The coordinator queries the 8004scan public API:
Workers register on-chain via ERC-8004 and advertise capabilities through OASF (Open Agent Skills Framework) metadata. The coordinator prefers an internal Reth-backed indexer when `OBOL_INDEXER_API_URL` is healthy and otherwise falls back to the public 8004scan API:

```
GET https://www.8004scan.io/api/v1/public/agents
Expand Down Expand Up @@ -127,7 +127,8 @@ Results are appended to `$DATA_DIR/autoresearch/results.jsonl` (one JSON object

| Variable | Default | Description |
|----------|---------|-------------|
| `SCAN_API_URL` | `https://www.8004scan.io/api/v1/public` | 8004scan public API base URL; the coordinator queries `/agents` under this base |
| `OBOL_INDEXER_API_URL` | `` | Preferred internal index API base URL. Accepts either the service root or `/api/v1/public`; `/health` must report ready before it will be used |
| `SCAN_API_URL` | `https://www.8004scan.io/api/v1/public` | Fallback public API base URL used when the preferred internal indexer is unavailable or unhealthy |
| `REMOTE_SIGNER_URL` | `http://remote-signer:9000` | Remote-signer REST API for payment signing |
| `ERPC_URL` | `http://erpc.erpc.svc.cluster.local:4000/rpc` | eRPC gateway base URL |
| `ERPC_NETWORK` | `base-sepolia` | Default chain for payment |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ How the autoresearch coordinator maps from the original Ensue-based shared-memor

| Ensue Concept | obol-stack Equivalent | Notes |
|---|---|---|
| Shared memory (Redis/filesystem) | ERC-8004 on-chain registry + 8004scan API | Workers register capabilities on-chain; coordinator discovers via API |
| Shared memory (Redis/filesystem) | ERC-8004 on-chain registry + public index API | Workers register capabilities on-chain; coordinator prefers the internal Reth indexer and falls back to 8004scan |
| Task queue (Ensue scheduler) | Direct HTTP POST to worker `/experiment` endpoint | No central queue; coordinator submits directly to chosen worker |
| Worker discovery (static config) | 8004scan OASF query (`machine_learning/model_optimization`) | Dynamic discovery; workers join/leave without coordinator restart |
| Payment (none / trust-based) | x402 micropayments (USDC via ERC-3009 pre-signed auths) | Per-experiment payment; no credit accounts or invoicing |
Expand All @@ -18,7 +18,10 @@ How the autoresearch coordinator maps from the original Ensue-based shared-memor
## Discovery Flow

```
Coordinator 8004scan Worker
Coordinator Internal Indexer / 8004scan Worker
| | |
|-- GET /health -------------------->| |
|<-- 200 ready / 503 unhealthy ------| |
| | |
|-- GET /api/v1/public/agents ------>| |
| ?protocol=OASF | |
Expand All @@ -37,7 +40,7 @@ Coordinator 8004scan Worker
| (extract endpoint, verify x402 + OASF service entry) |
```

### 8004scan API Parameters
### Public Index API Parameters

| Parameter | Type | Description |
|---|---|---|
Expand All @@ -48,6 +51,8 @@ Coordinator 8004scan Worker
| `sortBy` | string | Sort field (e.g., `registeredAt`) |
| `limit` | int | Max results to return |

The coordinator uses the same query contract against both the internal Reth-backed indexer and the public 8004scan API. The preferred base is `OBOL_INDEXER_API_URL`; `SCAN_API_URL` remains the fallback when `/health` is unavailable, non-200, or reports `ready: false`.

### Worker Registration JSON

Workers advertise capabilities in their `.well-known/agent-registration.json`:
Expand Down
Loading