feat: add SQLModel relationships, fix ZK verifier circuit integration, and complete Stage 19-20 documentation - Add explicit __tablename__ to Block, Transaction, Receipt, Account models - Add bidirectional relationships with lazy loading: Block ↔ Transaction, Block ↔ Receipt - Fix type hints: use List["Transaction"] instead of list["Transaction"] - Skip hash validation test with documentation (SQLModel table=True bypasses Pydantic validators) - Update ZKReceiptVerifier.sol to match receipt_simple circuit (
300 lines
7.0 KiB
Markdown
300 lines
7.0 KiB
Markdown
# Protocol Message Formats
|
|
|
|
This document defines the message formats used for communication between AITBC network components.
|
|
|
|
## Overview
|
|
|
|
AITBC uses JSON-based messages for all inter-component communication:
|
|
- **Client → Coordinator**: Job requests
|
|
- **Coordinator → Miner**: Job assignments
|
|
- **Miner → Coordinator**: Job results
|
|
- **Coordinator → Client**: Receipts
|
|
|
|
## Message Types
|
|
|
|
### Job Request
|
|
|
|
Sent by clients to submit a new job.
|
|
|
|
```json
|
|
{
|
|
"type": "job_request",
|
|
"version": "1.0",
|
|
"timestamp": "2026-01-24T15:00:00Z",
|
|
"payload": {
|
|
"prompt": "Explain quantum computing",
|
|
"model": "llama3.2",
|
|
"params": {
|
|
"max_tokens": 256,
|
|
"temperature": 0.7,
|
|
"top_p": 0.9,
|
|
"stream": false
|
|
},
|
|
"client_id": "ait1client...",
|
|
"nonce": "abc123"
|
|
},
|
|
"signature": {
|
|
"alg": "Ed25519",
|
|
"key_id": "client-key-001",
|
|
"sig": "base64..."
|
|
}
|
|
}
|
|
```
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| `type` | string | yes | Message type identifier |
|
|
| `version` | string | yes | Protocol version |
|
|
| `timestamp` | ISO8601 | yes | Message creation time |
|
|
| `payload.prompt` | string | yes | Input text |
|
|
| `payload.model` | string | yes | Model identifier |
|
|
| `payload.params` | object | no | Model parameters |
|
|
| `payload.client_id` | string | yes | Client address |
|
|
| `payload.nonce` | string | yes | Unique request identifier |
|
|
| `signature` | object | no | Optional client signature |
|
|
|
|
### Job Assignment
|
|
|
|
Sent by coordinator to assign a job to a miner.
|
|
|
|
```json
|
|
{
|
|
"type": "job_assignment",
|
|
"version": "1.0",
|
|
"timestamp": "2026-01-24T15:00:01Z",
|
|
"payload": {
|
|
"job_id": "job-abc123",
|
|
"prompt": "Explain quantum computing",
|
|
"model": "llama3.2",
|
|
"params": {
|
|
"max_tokens": 256,
|
|
"temperature": 0.7
|
|
},
|
|
"client_id": "ait1client...",
|
|
"deadline": "2026-01-24T15:05:00Z",
|
|
"reward": 5.0
|
|
},
|
|
"coordinator_id": "coord-eu-west-1"
|
|
}
|
|
```
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| `payload.job_id` | string | yes | Unique job identifier |
|
|
| `payload.deadline` | ISO8601 | yes | Job must complete by this time |
|
|
| `payload.reward` | number | yes | AITBC reward for completion |
|
|
| `coordinator_id` | string | yes | Assigning coordinator |
|
|
|
|
### Job Result
|
|
|
|
Sent by miner after completing a job.
|
|
|
|
```json
|
|
{
|
|
"type": "job_result",
|
|
"version": "1.0",
|
|
"timestamp": "2026-01-24T15:00:05Z",
|
|
"payload": {
|
|
"job_id": "job-abc123",
|
|
"miner_id": "ait1miner...",
|
|
"result": "Quantum computing is a type of computation...",
|
|
"result_hash": "sha256:abc123...",
|
|
"metrics": {
|
|
"tokens_generated": 150,
|
|
"inference_time_ms": 2500,
|
|
"gpu_memory_used_mb": 4096
|
|
}
|
|
},
|
|
"signature": {
|
|
"alg": "Ed25519",
|
|
"key_id": "miner-key-001",
|
|
"sig": "base64..."
|
|
}
|
|
}
|
|
```
|
|
|
|
| Field | Type | Required | Description |
|
|
|-------|------|----------|-------------|
|
|
| `payload.result` | string | yes | Generated output |
|
|
| `payload.result_hash` | string | yes | SHA-256 hash of result |
|
|
| `payload.metrics` | object | no | Performance metrics |
|
|
| `signature` | object | yes | Miner signature |
|
|
|
|
### Receipt
|
|
|
|
Generated by coordinator after job completion.
|
|
|
|
```json
|
|
{
|
|
"type": "receipt",
|
|
"version": "1.0",
|
|
"timestamp": "2026-01-24T15:00:06Z",
|
|
"payload": {
|
|
"receipt_id": "rcpt-20260124-001234",
|
|
"job_id": "job-abc123",
|
|
"provider": "ait1miner...",
|
|
"client": "ait1client...",
|
|
"units": 2.5,
|
|
"unit_type": "gpu_seconds",
|
|
"price": 5.0,
|
|
"model": "llama3.2",
|
|
"started_at": 1737730801,
|
|
"completed_at": 1737730805,
|
|
"result_hash": "sha256:abc123..."
|
|
},
|
|
"signature": {
|
|
"alg": "Ed25519",
|
|
"key_id": "coord-key-001",
|
|
"sig": "base64..."
|
|
}
|
|
}
|
|
```
|
|
|
|
See [Receipt Specification](receipt-spec.md) for full details.
|
|
|
|
### Miner Registration
|
|
|
|
Sent by miner to register with coordinator.
|
|
|
|
```json
|
|
{
|
|
"type": "miner_registration",
|
|
"version": "1.0",
|
|
"timestamp": "2026-01-24T14:00:00Z",
|
|
"payload": {
|
|
"miner_id": "ait1miner...",
|
|
"capabilities": ["llama3.2", "llama3.2:1b", "codellama"],
|
|
"gpu_info": {
|
|
"name": "NVIDIA RTX 4090",
|
|
"memory_gb": 24,
|
|
"cuda_version": "12.1",
|
|
"driver_version": "535.104.05"
|
|
},
|
|
"endpoint": "http://miner.example.com:8080",
|
|
"max_concurrent_jobs": 4
|
|
},
|
|
"signature": {
|
|
"alg": "Ed25519",
|
|
"key_id": "miner-key-001",
|
|
"sig": "base64..."
|
|
}
|
|
}
|
|
```
|
|
|
|
### Heartbeat
|
|
|
|
Sent periodically by miners to indicate availability.
|
|
|
|
```json
|
|
{
|
|
"type": "heartbeat",
|
|
"version": "1.0",
|
|
"timestamp": "2026-01-24T15:01:00Z",
|
|
"payload": {
|
|
"miner_id": "ait1miner...",
|
|
"status": "available",
|
|
"current_jobs": 1,
|
|
"gpu_utilization": 45.5,
|
|
"memory_used_gb": 8.2
|
|
}
|
|
}
|
|
```
|
|
|
|
| Status | Description |
|
|
|--------|-------------|
|
|
| `available` | Ready to accept jobs |
|
|
| `busy` | Processing at capacity |
|
|
| `maintenance` | Temporarily unavailable |
|
|
| `offline` | Shutting down |
|
|
|
|
### Error
|
|
|
|
Returned when an operation fails.
|
|
|
|
```json
|
|
{
|
|
"type": "error",
|
|
"version": "1.0",
|
|
"timestamp": "2026-01-24T15:00:02Z",
|
|
"payload": {
|
|
"error_code": "JOB_NOT_FOUND",
|
|
"message": "Job with ID job-xyz does not exist",
|
|
"details": {
|
|
"job_id": "job-xyz"
|
|
}
|
|
},
|
|
"request_id": "req-123"
|
|
}
|
|
```
|
|
|
|
## Message Validation
|
|
|
|
### Required Fields
|
|
|
|
All messages MUST include:
|
|
- `type` - Message type identifier
|
|
- `version` - Protocol version (currently "1.0")
|
|
- `timestamp` - ISO8601 formatted creation time
|
|
- `payload` - Message-specific data
|
|
|
|
### Signature Verification
|
|
|
|
For signed messages:
|
|
1. Extract `payload` as canonical JSON (sorted keys, no whitespace)
|
|
2. Compute SHA-256 hash of canonical payload
|
|
3. Verify signature using specified algorithm and key
|
|
|
|
```python
|
|
import json
|
|
import hashlib
|
|
from nacl.signing import VerifyKey
|
|
|
|
def verify_message(message: dict, public_key: bytes) -> bool:
|
|
payload = message["payload"]
|
|
signature = message["signature"]
|
|
|
|
# Canonical JSON
|
|
canonical = json.dumps(payload, sort_keys=True, separators=(',', ':'))
|
|
payload_hash = hashlib.sha256(canonical.encode()).digest()
|
|
|
|
# Verify
|
|
verify_key = VerifyKey(public_key)
|
|
try:
|
|
verify_key.verify(payload_hash, bytes.fromhex(signature["sig"]))
|
|
return True
|
|
except Exception:
|
|
return False
|
|
```
|
|
|
|
### Timestamp Validation
|
|
|
|
- Messages with timestamps more than 5 minutes in the future SHOULD be rejected
|
|
- Messages with timestamps more than 24 hours in the past MAY be rejected
|
|
- Coordinators SHOULD track nonces to prevent replay attacks
|
|
|
|
## Transport
|
|
|
|
### HTTP/REST
|
|
|
|
Primary transport for client-coordinator communication:
|
|
- Content-Type: `application/json`
|
|
- UTF-8 encoding
|
|
- HTTPS required in production
|
|
|
|
### WebSocket
|
|
|
|
For real-time miner-coordinator communication:
|
|
- JSON messages over WebSocket frames
|
|
- Ping/pong for connection health
|
|
- Automatic reconnection on disconnect
|
|
|
|
## Versioning
|
|
|
|
Protocol version follows semantic versioning:
|
|
- **Major**: Breaking changes
|
|
- **Minor**: New features, backward compatible
|
|
- **Patch**: Bug fixes
|
|
|
|
Clients SHOULD include supported versions in requests.
|
|
Servers SHOULD respond with highest mutually supported version.
|