Performance Evaluation
How provider performance is evaluated
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:
h[0] = sha256(seed)h[1] = sha256(h[0])...h[N] = sha256(h[N-1])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:
idx[0] = cpu_hash mod Mread[0] = table[idx[0]]idx[1] = read[0] mod Mread[1] = table[idx[1]]...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
work_proof = sha256(cpu_hash || memory_proof)#Scoring
score = 1.0 / attested_elapsed_secondsHigher 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 hardwareMemoryTableSize = 8_388_608 // 256 MB (entries × 32 bytes)MemoryReads = 1_000_000 // sequential-dependency readsWorkloadVersion = 3 // algorithm versionCertificateValidity = 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)