## Summary Building on #304, this PR implements two complementary mechanisms to improve validator incentives and network performance: 1. **Performance-Based Validator Rewards** (session-level) 2. **Inflation Scaling** (era-level) ## Reward Model Comparison ### Old Model (main branch) vs New Model | Metric | Old Model (20 pts/block) | New Model (320 pts/block pool) | |--------|--------------------------|--------------------------------| | **Per Block** | Author: 20 pts, Others: 0 | Author: ~196 pts, Others: ~4 pts each | | **Formula** | Direct author reward | 60% authoring + 30% liveness + 10% base | | **Per Session** (600 blocks, 32 validators) | 12,000 total pts | 192,000 total pts | | **Per Validator/Session** (uniform) | ~375 pts | ~6,000 pts | | **Per Validator/Era** (6 sessions) | ~2,250 pts | ~36,000 pts | | **Offline Validator** | 0 pts | ~600 pts/session (base only) | | **Over-performer (150% blocks)** | 150% of fair share | Up to 130% reward (soft cap) | ### Key Differences - **Pool-based**: New model adds 320 points to a shared pool per block, distributed via formula - **Liveness rewarded**: 30% of rewards go to validators who are online (heartbeat OR block authorship) - **Base guarantee**: 10% ensures all active validators receive minimum rewards - **Soft cap**: Prevents extreme over-performance rewards (max 150% of fair share credited) ## Performance-Based Validator Rewards Introduces a **60/30/10 reward formula** that rewards validators based on their contribution during each session: - **60%** based on block production (with soft cap allowing up to 150% of fair share) - **30%** based on liveness (ImOnline heartbeat OR block authorship) - **10%** guaranteed base reward for all active validators ### Key Features - Tracks individual validator block authorship per session - Calculates fair share dynamically: `fair_share = total_blocks / total_validator_count` - Fair share uses **total** validator count (including whitelisted) since all validators occupy block slots - **Soft cap**: Over-performers can earn credit up to 150% of their fair share (configurable via `OperatorRewardsFairShareCap` at 50%) - With 60% BlockAuthoringWeight, this gives over-performers up to **30% bonus reward** - **BasePointsPerBlock**: Defines points added to pool per block produced (default: 320) - Integrates with SessionManager for automatic point awards at session end - Excludes whitelisted validators from rewards (but includes them in fair share calculation) - Slashing check disabled but hook retained for future use - Points accumulate across sessions within an era ### Dynamic Parameters (Governance-Adjustable) - `OperatorRewardsBlockAuthoringWeight`: Weight for block authoring (default: 60%) - `OperatorRewardsLivenessWeight`: Weight for liveness (default: 30%) - `OperatorRewardsFairShareCap`: Soft cap percentage above fair share (default: 50%) ## Inflation Scaling Implements **dynamic inflation scaling** that adjusts total inflation based on network block production: - **Minimum**: 20% of base inflation (network halt protection) - **Maximum**: 100% of base inflation (caps at expected blocks) - **Linear scaling** between minimum and maximum based on performance ### Scaling Examples - 0% blocks produced → 20% inflation (safety floor) - 50% blocks produced → 60% inflation - 100% blocks produced → 100% inflation - >100% blocks produced → capped at 100% ### Configuration - **ExpectedBlocksPerEra**: Computed as `SessionsPerEra × EpochDurationInBlocks` - **MinInflationPercent**: 20% - **MaxInflationPercent**: 100% ## Combined Effect These mechanisms work together to create a comprehensive incentive structure: 1. **Session rewards** encourage individual validator performance and uptime 2. **Era inflation scaling** incentivizes collective network health 3. **Minimum inflation floor** protects against network halt 4. **Soft cap** allows over-performers to earn up to 30% bonus while preventing extreme centralization ## Implementation Details ### Pallet Changes - Add `BlocksAuthoredInSession` storage for per-validator tracking - Add `BlocksProducedInEra` storage for total network tracking (cleaned up with HistoryDepth) - Add `note_block_author()` function called on block production - Add `award_session_performance_points()` function with configurable 60/30/10 formula - Add `calculate_scaled_inflation()` function for era-level scaling - Update `on_era_end()` to use scaled inflation - Integrate with SessionManager via wrapper types - Defensive weight validation: proportionally scales if sum > 100% ### Configuration Parameters - `ValidatorSet`: Provides active validator list - `LivenessCheck`: Uses `ImOnline::is_online()` (heartbeat OR block authorship) - `SlashingCheck`: Integration with slashing pallet (currently disabled) - `BasePointsPerBlock`: Points added to pool per block (default: 320) - `BlockAuthoringWeight`: Dynamic parameter (60%) - `LivenessWeight`: Dynamic parameter (30%) - `FairShareCap`: Dynamic parameter (50%) - `ExpectedBlocksPerEra`: Computed from session/epoch config - `MinInflationPercent`: 20% - `MaxInflationPercent`: 100% ### Runtime Updates - Full configuration added to mainnet, testnet, and stagenet runtimes - Dynamic parameters added to `runtime_params.rs` for governance control - Uses `prod_or_fast!()` macro for environment-specific parameters - `ValidatorIsOnline` uses `ImOnline::is_online()` for accurate liveness detection ## Testing - **76 tests passing** ✅ - Comprehensive coverage of both mechanisms ### Test Coverage - Inflation scaling at 0%, 25%, 50%, 75%, 100%, >100% blocks - Session performance with 60/30/10 formula - Fair share calculations with soft cap (150%) - Whitelisted validator exclusion from rewards (with correct fair share using total count) - Total points verification (sum of individual = total) - Whitelisted over-producer scenarios - Overflow protection (large block counts, near-u32::MAX) - End-to-end session to era flow - MockLivenessCheck mirrors ImOnline behavior (block authorship = online) - Multiple eras with different performance levels - Edge cases (zero participation, single validator, large numbers) - BlocksProducedInEra cleanup on era start ## ⚠️ Breaking Changes ⚠️ ### Reward Distribution Previously, rewards were distributed equally among all validators regardless of their contribution. Now: - **Performance-based**: Validators earn rewards proportional to their block production (60%), liveness (30%), and a guaranteed base (10%) - **Pool-based**: `BasePointsPerBlock` defines points added to pool per block (320), distributed via formula - **Fair share uses total validators**: Ensures non-whitelisted aren't penalized for whitelisted validators' block slots - **Soft cap**: Block production rewards allow up to 150% of fair share (50% cap = 30% bonus with 60% weight) - **Slashing check disabled**: Hook retained for future use, but currently not applied ### Inflation Mechanism Previously, the full calculated inflation was minted each era. Now: - **Scaled by performance**: Total inflation scales between 20%-100% based on actual blocks produced vs expected - **Safety floor**: Even with zero blocks, 20% of inflation is still minted to prevent complete halt - **Network incentive**: Collective block production directly impacts total rewards available ### Pallet Configuration The `pallet-external-validators-rewards` Config now requires additional types: - `BlockAuthoringWeight`, `LivenessWeight`, `FairShareCap` for reward formula - `ValidatorSet`, `LivenessCheck`, `SlashingCheck` for validator tracking - `ExpectedBlocksPerEra`, `MinInflationPercent`, `MaxInflationPercent` for inflation scaling --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com> |
||
|---|---|---|
| .github | ||
| contracts | ||
| deploy | ||
| docker | ||
| operator | ||
| resources | ||
| test | ||
| tools | ||
| .gitignore | ||
| .gitmodules | ||
| biome.json | ||
| CLAUDE.md | ||
| file_header.txt | ||
| LICENSE | ||
| README.md | ||
| taplo.toml | ||
DataHaven 🫎
An EVM-compatible Substrate blockchain secured by EigenLayer, bridging Ethereum and Substrate ecosystems through trustless cross-chain communication.
Overview
DataHaven is an EigenLayer Actively Validated Service (AVS) that combines:
- EVM Compatibility: Full Ethereum support via Frontier pallets for smart contracts and dApps
- EigenLayer Security: Validator set secured by Ethereum's economic security through restaking
- Cross-chain Bridge: Seamless asset and message transfers with Ethereum via Snowbridge
- Dynamic Validators: Operator registry managed on-chain through EigenLayer contracts
- Performance Rewards: Validator incentives distributed cross-chain from Ethereum
Architecture
DataHaven bridges two major blockchain ecosystems:
┌───────────────────────────────────────────────────────────────┐
│ Ethereum (L1) │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ EigenLayer AVS Contracts │ │
│ │ • DataHavenServiceManager (operator lifecycle) │ │
│ │ • RewardsRegistry (performance tracking) │ │
│ │ • VetoableSlasher (misbehavior penalties) │ │
│ └────────────────────────────────────────────────────────┘ │
│ ↕ │
│ Snowbridge Protocol │
└───────────────────────────────────────────────────────────────┘
↕
┌───────────────────────────────────────────────────────────────┐
│ DataHaven (Substrate) │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Custom Pallets │ │
│ │ • External Validators (sync validator set) │ │
│ │ • Native Transfer (cross-chain tokens) │ │
│ │ • Rewards (distribute validator rewards) │ │
│ │ • Frontier (EVM compatibility) │ │
│ └────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
Repository Structure
datahaven/
├── contracts/ # EigenLayer AVS smart contracts
│ ├── src/ # Service Manager, Rewards Registry, Slasher
│ ├── script/ # Deployment scripts
│ └── test/ # Foundry test suites
├── operator/ # Substrate-based DataHaven node
│ ├── node/ # Node implementation & chain spec
│ ├── pallets/ # Custom pallets (validators, rewards, transfers)
│ └── runtime/ # Runtime configurations (mainnet/stagenet/testnet)
├── test/ # E2E testing framework
│ ├── suites/ # Integration test scenarios
│ ├── framework/ # Test utilities and helpers
│ └── launcher/ # Network deployment automation
├── deploy/ # Kubernetes deployment charts
│ ├── charts/ # Helm charts for nodes and relayers
│ └── environments/ # Environment-specific configurations
├── tools/ # GitHub automation and release scripts
└── .github/ # CI/CD workflows
Each directory contains its own README with detailed information. See:
- contracts/README.md - Smart contract development
- operator/README.md - Node building and runtime development
- test/README.md - E2E testing and network deployment
- deploy/README.md - Kubernetes deployment
- tools/README.md - Development tools
Quick Start
Prerequisites
- Kurtosis - Network orchestration
- Bun v1.3.2+ - TypeScript runtime
- Docker - Container management
- Foundry - Solidity toolkit
- Rust - For building the operator
- Helm - Kubernetes deployments (optional)
- Zig - For macOS cross-compilation (macOS only)
Launch Local Network
The fastest way to get started is with the interactive CLI:
cd test
bun i # Install dependencies
bun cli launch # Interactive launcher with prompts
This deploys a complete environment including:
- Ethereum network: 2x EL clients (reth), 2x CL clients (lodestar)
- Block explorers: Blockscout (optional), Dora consensus explorer
- DataHaven node: Single validator with fast block times
- AVS contracts: Deployed and configured on Ethereum
- Snowbridge relayers: Bidirectional message passing
For more options and detailed instructions, see the test README.
Run Tests
cd test
bun test:e2e # Run all integration tests
bun test:e2e:parallel # Run with limited concurrency
NOTES: Adding the environment variable INJECT_CONTRACTS=true will inject the contracts when starting the tests to speed up setup.
Development Workflows
Smart Contract Development:
cd contracts
forge build # Compile contracts
forge test # Run contract tests
Node Development:
cd operator
cargo build --release --features fast-runtime
cargo test
./scripts/run-benchmarks.sh
After Making Changes:
cd test
bun generate:wagmi # Regenerate contract bindings
bun generate:types # Regenerate runtime types
Key Features
EVM Compatibility
Full Ethereum Virtual Machine support via Frontier pallets:
- Deploy Solidity smart contracts
- Use existing Ethereum tooling (MetaMask, Hardhat, etc.)
- Compatible with ERC-20, ERC-721, and other standards
EigenLayer Integration
Validator security anchored to Ethereum:
- Operators register via
DataHavenServiceManagercontract - Economic security through ETH restaking
- Slashing protection with veto period via
VetoableSlasher - Performance-based rewards through
RewardsRegistry
Cross-chain Communication
Trustless bridging via Snowbridge:
- Native token transfers between Ethereum ↔ DataHaven
- Cross-chain message passing
- Finality proofs via BEEFY consensus
- Three specialized relayers (beacon, BEEFY, execution)
Dynamic Validator Set
Validator management synchronized with Ethereum:
- EigenLayer operator registry as source of truth
- On-chain validator set updates via External Validators pallet
- Automatic consensus participation changes
- Cross-chain coordination for validator lifecycle
Docker Images
Production images published to DockerHub.
Build optimizations:
- sccache - Rust compilation caching
- cargo-chef - Dependency layer caching
- BuildKit cache mounts - External cache restoration
Build locally:
cd test
bun build:docker:operator # Creates datahavenxyz/datahaven:local
Development Environment
VS Code Configuration
IDE configurations are excluded from version control for personalization, but these settings are recommended for optimal developer experience. Add to your .vscode/settings.json:
Rust Analyzer:
{
"rust-analyzer.linkedProjects": ["./operator/Cargo.toml"],
"rust-analyzer.cargo.allTargets": true,
"rust-analyzer.procMacro.enable": false,
"rust-analyzer.server.extraEnv": {
"CARGO_TARGET_DIR": "target/.rust-analyzer",
"SKIP_WASM_BUILD": 1
},
"rust-analyzer.diagnostics.disabled": ["unresolved-macro-call"],
"rust-analyzer.cargo.buildScripts.enable": false
}
Optimizations:
- Links
operator/directory as the primary Rust project - Disables proc macros and build scripts for faster analysis (Substrate macros are slow)
- Uses dedicated target directory to avoid conflicts
- Skips WASM builds during development
Solidity (Juan Blanco's extension):
{
"solidity.formatter": "forge",
"solidity.compileUsingRemoteVersion": "v0.8.28+commit.7893614a",
"[solidity]": {
"editor.defaultFormatter": "JuanBlanco.solidity"
}
}
Note: Solidity version must match foundry.toml
TypeScript (Biome):
{
"biome.lsp.bin": "test/node_modules/.bin/biome",
"[typescript]": {
"editor.defaultFormatter": "biomejs.biome",
"editor.codeActionsOnSave": {
"source.organizeImports.biome": "always"
}
}
}
CI/CD
Local CI Testing
Run GitHub Actions workflows locally using act:
# Run E2E workflow
act -W .github/workflows/e2e.yml -s GITHUB_TOKEN="$(gh auth token)"
# Run specific job
act -W .github/workflows/e2e.yml -j test-job-name
Automated Workflows
The repository includes GitHub Actions for:
- E2E Testing: Full integration tests on PR and main branch
- Contract Testing: Foundry test suites for smart contracts
- Rust Testing: Unit and integration tests for operator
- Docker Builds: Multi-platform image builds with caching
- Release Automation: Version tagging and changelog generation
See .github/workflows/ for workflow definitions.
Contributing
Development Cycle
- Make Changes: Edit contracts, runtime, or tests
- Run Tests: Component-specific tests (
forge test,cargo test) - Regenerate Types: Update bindings if contracts/runtime changed
- Integration Test: Run E2E tests to verify cross-component behavior
- Code Quality: Format and lint (
cargo fmt,forge fmt,bun fmt:fix)
Common Pitfalls
- Type mismatches: Regenerate with
bun generate:typesafter runtime changes - Contract changes not reflected: Run
bun generate:wagmiafter modifications - Kurtosis issues: Ensure Docker is running and Kurtosis engine is started
- Slow development: Use
--features fast-runtimefor shorter epochs/eras (block time stays 6s) - Network launch hangs: Check Blockscout - forge output can appear frozen
See CLAUDE.md for detailed development guidance.
License
GPL-3.0 - See LICENSE file for details