VDF Anti-Spam

The Spam Problem

Standard Messages have no bid and require a VDF proof for spam resistance. Without some mechanism, bots could flood the network with free messages.

What is a VDF?

A Verifiable Delay Function is a computation that:

  1. Takes a minimum amount of sequential time to compute

  2. Cannot be parallelized (no GPU speedup)

  3. Can be verified quickly (much cheaper than computing)

This creates a natural rate limit: users must expend real-world time to submit messages, preventing spam floods without requiring monetary fees.

How Obsidian Uses VDF

Before submitting a free (SM) message, you must:

  1. Get the challenge parameters from the network

  2. Compute a sequential hash chain with checkpoints

  3. Submit the proof with your message

spinner
Step
RPC/Action
Details

1

eth_getMessageWork

Get iterations + checkpoint interval

2

Compute VDF

Sequential hash chain with checkpoints

3

eth_sendMessageBlob

Include checkpoints array

4

Verify

Node checks 3 random segments (Fiat-Shamir)

The Algorithm (Checkpointed Hash-Chain)

Obsidian's VDF is a checkpoint-based sequential hash chain (algorithm version VdfAlgHashChain = 1).

Step 1: Compute Challenge

The challenge binds the VDF proof to the specific message content.

Step 2: Compute Hash Chain

Each iteration depends on the previous one; you cannot skip ahead or parallelize.

Step 3: Store Checkpoints

  • Target checkpoint count: 10 (configurable via checkpointCount)

  • Checkpoint interval: floor(iterations / checkpointCount) (minimum 1)

  • Store intermediate values at each interval

  • Always include the final value

Example: With 11,000 iterations and 10 checkpoints:

  • Interval = 1,100

  • Checkpoints at iterations: 1100, 2200, 3300, ..., 10999

Step 4: Submit Proof

Include with your message:

  • vdfCheckpoints[] - Array of checkpoint hashes

  • vdfCheckpointInterval - Spacing between checkpoints

  • vdfIterations - Total iterations computed

  • vdfAlgVersion - Algorithm version (currently 1)

Iteration Scaling

Larger messages require more work:

Where payloadKB = floor(payloadBytes / 1024) (integer division).

Payload Size
Iterations (default config)

0 KB

100,000

1 KB

110,000

4 KB

140,000

8 KB (max)

180,000

Default config: baseIterations = 100000, scalingIterationsPerKB = 10000

Performance estimates:

  • Browser JS: ~50,000–100,000 iterations/second

  • Native Go: ~500,000 iterations/second

Verification (Fiat-Shamir Selection)

Nodes don't recompute the entire hash chain. Instead:

  1. Build Fiat-Shamir seed:

  2. Select 3 checkpoints deterministically:

  3. Verify each selected segment by recomputing from the previous checkpoint

This is a spot check: verifying 3 random segments from ~10 checkpoints gives cheat probability of (1/10)³ = 0.1% per attempt.

Security constant: NumCheckpointsToVerify = 3 is hardcoded and not configurable for security reasons.

Code Example

JavaScript (Browser/Node)

Why It Stops Spam

Actor
Capability
Result

Normal user

1 device

~1 msg/sec - totally fine

Bot with 1 CPU

Sequential only

~1 msg/sec - same as user

Bot with 1000 CPUs

Still sequential

~1 msg/sec per CPU - expensive

Bot with GPUs

Can't parallelize

No advantage

The key insight: time cannot be bought. Even with unlimited hardware, each message takes minimum ~1 second.

Priority Messages Skip VDF

PM messages (with bids >= network MinPMBid) don't require VDF:

  • They pay real money, which is its own spam deterrent

  • Time-sensitive messages shouldn't wait for VDF computation

  • Economic cost replaces computational cost

Configuration

Networks configure VDF via genesis messageConfig.vdfConfig:

Example genesis config:

Verification Errors

Error
Cause

ErrVdfDisabled

VDF disabled but proof submitted

ErrVdfVersionMismatch

Algorithm version doesn't match network config

ErrVdfInsufficientWork

Submitted iterations < required for payload

ErrVdfNoCheckpoints

Empty checkpoints array

ErrVdfInvalidInterval

Checkpoint interval is 0 or doesn't match expected

ErrVdfCheckpointMismatch

Fiat-Shamir verification of segments failed

Source Files

File
Purpose

messaging/vdf.go

VDF computation and verification

params/config.go

MessageVdfConfig struct

internal/ethapi/api_message.go

eth_getMessageWork RPC


Next: Permanent On-Chain Data - Why Obsidian data lasts forever

Last updated