An EVM compatible Substrate chain, powered by StorageHub and secured by EigenLayer
Find a file
Ahmad Kaouk 41788d56bb
test: refactor e2e tests (#365)
This PR significantly refactors and improves the end-to-end testing
framework and infrastructure. The primary focus was on simplifying the
test suites, improving reliability through better resource management,
and hardening the relayer infrastructure.

All E2E tests are now passing on the CI and demonstrate consistent
reliability when run locally.

### Key Changes

#### 1. E2E Test Suite Refactor & Cleanup
* **Simplified Test Logic**: Heavily refactored the core test suites
(`native-token-transfer.test.ts`, `rewards-message.test.ts`, and
`validator-set-update.test.ts`). The new implementation is much cleaner,
utilizing shared helpers to reduce boilerplate.
* **Utility Consolidation**: Removed redundant utility files
(`storage.ts`, `rewards-helpers.ts`) and simplified `events.ts`. Event
waiting now uses `rxjs` for Substrate and native `viem` watchers for
Ethereum, which is more robust and easier to maintain.
* **Better Connector Management**: Unified the creation and cleanup of
test clients in `ConnectorFactory`. It now handles the lifecycle of
WebSocket connections more gracefully, including clearing the
`socketClientCache` to prevent reconnection noise during teardown.

#### 2. Infrastructure & Stability
* **Relayer Relaunch Policy**: Added a restart policy for Snowbridge
relayer containers. They are now configured with `--restart
on-failure:5`, ensuring that relayers automatically relaunch if they
crash during the sensitive initialization phase.
*   **WebSocket Integration**: 
* Updated the `ConnectorFactory` to prefer **WebSockets** for the
Ethereum public client, which is essential for efficient, event-heavy
E2E testing.
* Enhanced `launchKurtosisNetwork` to correctly identify and register
the Execution Layer's WebSocket endpoint from Kurtosis.
* **Disabled Contract Injection**: This PR temporarily disables the
automatic injection of contracts into the genesis state by default.
* *Reason*: I encountered issues generating a valid `state-diff.json`
for the latest contract versions. Even after applying several
workarounds, the injected state remained unstable. As a result, I've
reverted to manual contract deployment during the launch sequence for
better reliability for now.

#### 3. Documentation & Maintenance
* Removed obsolete documentation (`event-utilities-guide.md`) that no
longer reflects the simplified event-handling API.
* Cleaned up `test/launcher/validators.ts` and moved logic into more
appropriate helpers.

---------

Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
2025-12-24 13:31:40 +01:00
.github test: refactor e2e tests (#365) 2025-12-24 13:31:40 +01:00
contracts test: refactor e2e tests (#365) 2025-12-24 13:31:40 +01:00
deploy fix: 🔨 Fix Kurtosis & Snowbridge relay configs for Fulu fork (#356) 2025-12-18 15:50:09 +01:00
docker Revert "feat: statically build binary (#292)" (#330) 2025-12-02 15:42:43 +01:00
operator test: refactor e2e tests (#365) 2025-12-24 13:31:40 +01:00
resources test: Add E2E Tests (#36) 2025-04-14 16:22:43 -03:00
test test: refactor e2e tests (#365) 2025-12-24 13:31:40 +01:00
tools fix: 🔧 Fix publish runtime draft release (#226) 2025-10-12 23:59:32 +02:00
.gitignore test: Update validator set e2e test (#126) 2025-10-02 11:23:40 +00:00
.gitmodules build: Change Snowbridge contracts dependency from upstream to fork (#18) 2025-03-28 15:49:43 -03:00
biome.json test: port ethereum tests from moonbeam (#278) 2025-11-22 10:02:05 +01:00
CLAUDE.md test: Native token transfer e2e tests (#120) 2025-08-22 18:27:14 +02:00
file_header.txt chore: ♻️ Add missing license header in operator & AVS contracts source code (#285) 2025-11-10 12:56:41 +01:00
LICENSE chore: ♻️ Add missing license header in operator & AVS contracts source code (#285) 2025-11-10 12:56:41 +01:00
README.md test: only inject contracts in e2e tests if INJECT_CONTRACTS env is 'true' (#315) 2025-11-24 12:07:36 +01:00
taplo.toml ci: 🐳 Start Publishing Docker Images (#64) 2025-05-08 20:32:55 -03:00

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:

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 DataHavenServiceManager contract
  • 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:

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

  1. Make Changes: Edit contracts, runtime, or tests
  2. Run Tests: Component-specific tests (forge test, cargo test)
  3. Regenerate Types: Update bindings if contracts/runtime changed
  4. Integration Test: Run E2E tests to verify cross-component behavior
  5. Code Quality: Format and lint (cargo fmt, forge fmt, bun fmt:fix)

Common Pitfalls

  • Type mismatches: Regenerate with bun generate:types after runtime changes
  • Contract changes not reflected: Run bun generate:wagmi after modifications
  • Kurtosis issues: Ensure Docker is running and Kurtosis engine is started
  • Slow development: Use --features fast-runtime for 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