Performance Evaluation¶
Performance certificates measure and certify provider hardware quality. Each provider runs a benchmark on startup, producing a signed certificate with attested timestamps from trusted timekeepers. The certificate is attached to every lease the provider accepts.
Certificate Overview¶
A performance certificate proves a provider's machine completed a known benchmark in a measured amount of time. The start and end times come from network timekeepers, not the provider's clock.
Provider Timekeepers Network
──────── ─────────── ───────
1. Request start attestation
─────────────────►
Attest start timestamp
◄─────────────────
2. Derive seed from start attestation
Run benchmark (~60s):
Phase 1: sequential hash chain (CPU)
Phase 2: memory table + random reads (memory)
3. Request end attestation
─────────────────►
Attest end timestamp
◄─────────────────
4. Assemble certificate:
seed + work proof + merkle roots of attestations
Sign with provider's node key
5. Publish via gossip
──────────────────────────────────────►
All nodes cache
Certificate Structure¶
Certificates use a compact format with attestation merkle roots (~840 bytes) instead of full attestation arrays (~2.6 KB):
type Certificate struct {
Provider string // ed25519 pubkey hex
Seed string // sha256(start_median || provider_pubkey)
WorkloadVersion uint64 // benchmark algorithm version (currently 3)
Iterations uint64 // hash chain length (375,000,000)
WorkProof string // sha256(cpu_hash || memory_proof)
Score float64 // 1.0 / attested_elapsed_seconds
StartAttestationRoot string // merkle root of start attestations
EndAttestationRoot string // merkle root of end attestations
StartMedian int64 // median start timestamp (nanos)
EndMedian int64 // median end timestamp (nanos)
IssuedAt int64 // == StartMedian
ExpiresAt int64 // issued_at + 7 days
Signature string // provider signs all fields
Hash string // sha256 of certificate content
}
Benchmark¶
The benchmark has two phases, both deterministic and sequential.
Phase 1: Sequential Hash Chain (CPU)¶
375 million SHA-256 iterations where each depends on the previous:
Targets ~60 seconds on mid-range hardware. Cannot be parallelised.
Phase 2: Memory Table (Memory)¶
After the hash chain, build a 256 MB lookup table (8,388,608 × 32-byte entries):
table[0] = sha256(cpu_hash || 0)
table[1] = sha256(cpu_hash || 1)
...
table[M-1] = sha256(cpu_hash || M-1)
Then perform 1,000,000 seed-derived random reads with sequential dependency:
The memory proof is the hash of all reads. This requires holding the full table in memory — outsourcing over a network adds round-trip latency per random read, making it ~10,000× slower than local access.
Final Proof¶
Scoring¶
Higher score = faster hardware. The elapsed time comes from the median of timekeeper attestations, not the provider's clock.
Reference scores¶
| Benchmark time | Score | Hardware tier |
|---|---|---|
| 10s | 0.100000 | High-end dedicated |
| 30s | 0.033333 | Fast server |
| 59s | 0.016951 | bm1 testnet (4 vCPU) |
| 62s | 0.016172 | bm2 testnet (8 vCPU) |
| 120s | 0.008333 | Slow / shared hosting |
| 300s | 0.003333 | Extremely slow |
Anti-Cheat Properties¶
| Property | Mechanism |
|---|---|
| No pre-computation | Seed derived from attested start timestamp + provider pubkey. Unknown until attestation received. |
| No parallelisation | Sequential hash chain — each step depends on previous output. |
| No outsourcing | Memory-hard phase requires 256 MB table in local RAM. Network round-trip per random read makes outsourcing 10,000× slower. |
| No time manipulation | Start and end timestamps from trusted timekeepers (threshold 2 of 3). Provider cannot claim faster time. |
| Identity binding | Certificate signed by provider's ed25519 key. Seed includes provider pubkey. |
| Expiry | 7-day validity. Must re-certify to continue accepting leases. |
| Iteration count | Verified: must equal BenchmarkIterations (375M). Cannot run fewer for speed. |
Lease Integration¶
Every lease_accept block includes the provider's certificate_hash. The ledger validates:
certificate_hashis non-empty- Certificate exists in the gossip cache
- Certificate's
Providerfield matches the accepting provider - Certificate is not expired at acceptance time
// In validateAndAddLeaseAccept:
certInfo := l.certificateLookupFn(b.CertificateHash)
if certInfo.Provider != b.Account { reject }
if startTime > certInfo.ExpiresAt { reject }
The lease record stores the certificate hash for audit:
{
"lease_hash": "abc123...",
"provider": "423463...",
"certificate_hash": "69af25...",
"settled": false
}
Certificate Gossip¶
Certificates are broadcast via GossipSub topic xe/certificates. All nodes cache received certificates indexed by provider account.
- Publishing: provider broadcasts after generation
- Validation: signature, expiry, workload version, iteration count checked before caching
- Deduplication: newer
IssuedAttimestamp replaces older certificates - API:
GET /certificate(local provider) andGET /certificate/{provider}(any cached cert)
Constants¶
BenchmarkIterations = 375_000_000 // ~60s on mid-range hardware
MemoryTableSize = 8_388_608 // 256 MB (entries × 32 bytes)
MemoryReads = 1_000_000 // sequential-dependency reads
WorkloadVersion = 3 // algorithm version
CertificateValidity = 7 * 24 * time.Hour // 7 days
File Reference¶
| File | Description |
|---|---|
perf/benchmark.go |
Hash chain + memory-hard benchmark |
perf/certificate.go |
Certificate struct, signing, verification, merkle roots |
node/perf.go |
Certificate generation on provider startup |
net/gossip.go |
CertificateGossip (xe/certificates topic) |
core/ledger.go |
Certificate validation in lease_accept |
api/vm.go |
GET /certificate and GET /certificate/{provider} |
Future Work¶
- Performance-weighted pricing — score × resources × duration (#246)
- Checkpoint spot-checking — verify chain segments without full re-run (#247)
- Heartbeat micro-benchmarks — detect degradation during leases (#249)
- Certificate renewal — automatic re-benchmark before expiry (#250)
- Anti-cheat — outsourcing detection (#213), collusion prevention (#214), boost detection (#215)