Commit graph

20 commits

Author SHA1 Message Date
Gonza Montiel
7097767021
feat: contracts upgrade command (#463)
## Contracts upgrade command with simple version tracking

This PR aims to take the most minimal changes from #438 to make the
upgrade command available.
So it adds the `bun cli contracts upgrade` command for deploying a new
`DataHavenServiceManager` implementation and upgrading the proxy, and
includes a simple version tracking via a `contracts/VERSION` file.

### Contracts
**`DataHavenServiceManager.sol`**
- Added `_version` storage variable
- Added `DATAHAVEN_VERSION()` view function, 
- Added `updateVersion(string)` function gated by `onlyProxyAdmin`
- Added `VersionUpdated` event
- The version is set at initialization and updated atomically with proxy
upgrades via `upgradeAndCall`.
 
### CLI

**`bun cli contracts upgrade`** works in two modes: _dry-run_ or
_execute_.

**Dry-run (default)**

Deploys the new implementation on-chain (signed by the deployer key),
then prints a ready-to-submit JSON payload for the multisig to execute
the proxy upgrade. No AVS owner key required.

```bash
# Uses version from contracts/VERSION (standard workflow)
bun cli contracts upgrade --chain hoodi

# Override version for this upgrade only (warns if it differs from contracts/VERSION)
bun cli contracts upgrade --chain hoodi --target x.y.z
```

Example output:
```json
{
  "to": "0xProxyAdmin...",
  "value": "0",
  "data": "0x...",
  "description": "Upgrade ServiceManager proxy to 0xNewImpl... and set version to 1.1.0"
}
```

**Execute mode (`--execute`)**

Deploys the implementation and broadcasts the proxy upgrade + version
update in a single atomic `upgradeAndCall` transaction. Requires
`AVS_OWNER_PRIVATE_KEY`. Used mostly for testing.

```bash
  bun cli contracts upgrade --chain anvil --execute
```
---
### Expected flow
- Bump mannually contracts/VERSION (e.g., 1.1.0)
- Run bun cli contracts upgrade --chain anvil|hoodi|mainnet
2026-03-02 21:50:10 +01:00
Ahmad Kaouk
401f646286
feat: automated validator set submission with era targeting (#433)
## Era-targeted validator set submission with dedicated submitter role

> **Note:** This PR includes a detailed specification at
[`specs/validator-set-submission/validator-set-submission.md`](https://github.com/datahaven-xyz/datahaven/blob/feat/validator-set-submitter/specs/validator-set-submission/validator-set-submission.md)
that covers the design rationale, submission lifecycle, era-targeting
rules, and failure modes. Reading the spec first will make the contract,
pallet, and daemon changes easier to follow.

### Summary

- Introduce a dedicated `validatorSetSubmitter` role on
`DataHavenServiceManager`, separating validator set submission authority
from the contract owner
- Replace the unscoped `sendNewValidatorSet` with
`sendNewValidatorSetForEra`, which encodes a `targetEra` into the
Snowbridge message payload
- Add server-side era validation in the `external-validators` pallet to
reject stale, duplicate, or out-of-range submissions
- Add a long-running TypeScript daemon that watches session changes and
automatically submits each era's validator set at the right time

### Contract changes (`contracts/`)

- **New `validatorSetSubmitter` storage slot** — set during `initialize`
and rotatable via `setValidatorSetSubmitter` (owner-only). The storage
gap is decremented accordingly.
- **`sendNewValidatorSet` → `sendNewValidatorSetForEra`** — accepts a
`uint64 targetEra` parameter and is restricted to
`onlyValidatorSetSubmitter` instead of `onlyOwner`.
- **`buildNewValidatorSetMessageForEra`** — the
`NewValidatorSetPayload.externalIndex` is now caller-supplied instead of
hardcoded to `0`.
- **New events** — `ValidatorSetSubmitterUpdated`,
`ValidatorSetMessageSubmitted`.
- **New error** — `OnlyValidatorSetSubmitter`.
- **New test suite** — `ValidatorSetSubmitter.t.sol` covering submitter
set/rotate, access control, era encoding, and legacy function removal.

### Pallet changes (`operator/`)

- **`validate_target_era`** in `external-validators` — enforces
`activeEra < targetEra <= activeEra + 1` and `targetEra > ExternalIndex`
(dedup guard).
- **New errors** — `TargetEraTooOld`, `TargetEraTooNew`,
`DuplicateOrStaleTargetEra`.
- **Tests** — five new test cases for era boundary conditions (next-era
acceptance, old-era rejection, too-new rejection, duplicate rejection,
genesis behavior). Existing `era_hooks_with_external_index` test updated
to use valid target eras.
- **Runtime test fixes** — `external_index: 0` → `1` in
mainnet/stagenet/testnet EigenLayer message processor tests to satisfy
the new validation.

### Validator set submitter daemon
(`test/tools/validator-set-submitter/`)

- Event-driven service that subscribes to finalized
`Session.CurrentIndex` via Polkadot-API `watchValue`.
- Submits once per era during the last session, targeting `ActiveEra +
1`.
- Tracks submitted eras to avoid duplicates; skips if `ExternalIndex`
already covers the target.
- Startup self-checks: Ethereum connectivity, DataHaven connectivity,
on-chain submitter authorization.
- Supports `--dry-run` mode and YAML configuration.
- Graceful shutdown on `SIGINT`/`SIGTERM`.

### Test & tooling updates

- **E2E test** (`validator-set-update.test.ts`) — calls
`sendNewValidatorSetForEra` with a computed `targetEra` and filters the
substrate event by `external_index`.
- **`update-validator-set.ts` script** — accepts `--target-era` flag;
defaults to era 1 for fresh networks.
- **CLI launch** — wires validator set update as an interactive step
after relayer launch.
- **`package.json`** — new `submitter` and `submitter:dry-run` scripts.
- Regenerated contract bindings, PAPI metadata, state-diff, and storage
layout snapshots.

### Test plan

- [x] `forge test` — passes, including new `ValidatorSetSubmitter.t.sol`
- [x] `cargo test` — passes, including new era-validation tests in
`external-validators`
- [x] `bun test:e2e` — validator-set-update suite passes with
era-targeted flow
- [x] Manual: run submitter daemon against local network (`bun
submitter`), verify it submits once per era at the correct session

## ⚠️ Breaking Changes ⚠️

- **`sendNewValidatorSet` removed** — replaced by
`sendNewValidatorSetForEra(uint64 targetEra, ...)`. Callers must now
supply a `targetEra` parameter.
- **Access control changed** — validator set submission is now
restricted to the `validatorSetSubmitter` role instead of the contract
`owner`. The submitter address is set during `initialize` and rotatable
via `setValidatorSetSubmitter` (owner-only).
- **`external-validators` pallet now validates `targetEra`** — messages
with a stale, duplicate, or out-of-range `external_index` are rejected
on-chain. Existing integrations sending `external_index: 0` will fail
validation.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-20 10:31:44 +01:00
Steve Degosserie
46d752da01
feat: Add DH-AVS stagenet/testnet Hoodi deployment support (#422)
## Summary

- Add multi-environment deployment support (stagenet, testnet, mainnet)
to CLI and contracts
- Configure stagenet and testnet runtimes with correct genesis hashes
and Snowbridge Agent IDs
- Add CLI commands for BEEFY checkpoint updates and rewards origin
computation
- Add ETH validator strategies (native beacon chain ETH + LSTs) to all
config files

## Changes

### Runtime Configuration

**Stagenet Runtime:**
- Set `StagenetGenesisHash` to DataHaven stagenet genesis hash
- Configure `RewardsAgentOrigin` with computed Snowbridge Agent ID
- Add tests verifying rewards account derivation and agent ID
computation

**Testnet Runtime:**
- Set `TestnetGenesisHash` to DataHaven testnet genesis hash
- Configure `RewardsAgentOrigin` with computed Snowbridge Agent ID
- Add tests verifying rewards account derivation and agent ID
computation

The Rewards Agent ID is computed following Snowbridge's location
description pattern:
```
blake2_256(SCALE_ENCODE("GlobalConsensus", ByGenesis(genesis), "AccountKey20", rewards_account))
```

### CLI Enhancements

- All contracts subcommands (`status`, `deploy`, `verify`,
`update-metadata`) now accept `--environment` option
- Config and deployment files use environment-prefixed naming (e.g.,
`stagenet-hoodi.json`, `testnet-hoodi.json`)
- New `update-beefy-checkpoint` command that:
  - Connects to a live DataHaven chain via WebSocket RPC
  - Fetches all BEEFY data at the same finalized block for consistency
  - Uses parallel queries with `Promise.all` for better performance
- Computes authority hashes (keccak256 of Ethereum addresses derived
from BEEFY public keys)
- Uses Snowbridge's quorum formula `n - floor((n-1)/3)` for strictly >
2/3 majority
- New `update-rewards-origin` command that computes the Snowbridge Agent
ID for the rewards pallet
- Centralized validation via `contractsPreActionHook` for all contract
commands
- Environment validation against allowlist (`stagenet`, `testnet`,
`mainnet`)

### Contract Changes

- Network validation uses explicit allowlist instead of suffix matching
- Added `initialValidatorSetId` and `nextValidatorSetId` fields to
`SnowbridgeConfig` struct
- `DeployBase.s.sol` now uses config values for validator set IDs
instead of hardcoded 0/1
- `DeployParams.s.sol` loads validator set IDs from config with
backwards compatibility

### Validator Strategies

Added ETH-equivalent strategies to allow validators to stake using
native ETH or LSTs:

**All Networks:**
- `0xbeaC0eeEeeeeEEeEeEEEEeeEEeEeeeEeeEEBEaC0` - Native beacon chain ETH
(virtual strategy)

**Hoodi Testnet:**
- `0xf8a1a66130d614c7360e868576d5e59203475fe0` - stETH
- `0x24579aD4fe83aC53546E5c2D3dF5F85D6383420d` - WETH

**Ethereum Mainnet:**
- `0x93c4b944D05dfe6df7645A86cd2206016c51564D` - stETH
- `0x1BeE69b7dFFfA4E2d53C2a2Df135C388AD25dCD2` - rETH
- `0x54945180dB7943c0ed0FEE7EdaB2Bd24620256bc` - cbETH

### Config Files

- `stagenet-hoodi.json` - Hoodi testnet with stagenet EigenLayer
addresses
- `testnet-hoodi.json` - Hoodi testnet with testnet EigenLayer addresses
- `mainnet-ethereum.json` - Ethereum mainnet with mainnet EigenLayer
addresses
- Removed `hoodi.json` (replaced by environment-prefixed files)

## Usage

```bash
# Deploy to stagenet on Hoodi
bun cli contracts deploy --chain hoodi --environment stagenet

# Update BEEFY checkpoint from live chain
bun cli contracts update-beefy-checkpoint \
  --chain hoodi \
  --environment stagenet \
  --rpc-url wss://services.datahaven-dev.network/stagenet

# Compute rewards origin for a chain
bun cli contracts update-rewards-origin \
  --chain hoodi \
  --environment stagenet \
  --rpc-url wss://services.datahaven-dev.network/stagenet

# Check deployment status
bun cli contracts status --chain hoodi --environment stagenet
```

---------

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 16:41:15 +01:00
Ahmad Kaouk
9be1acc97e
refactor: cleanup old rewards model (#383)
## Summary

This PR removes the old merkle root-based rewards model and completes
the migration to EigenLayer Rewards V2 distribution. The old model
required operators to claim rewards by providing merkle proofs, while
the new model uses `submitRewards` to send rewards directly to
EigenLayer's `RewardsCoordinator`.

### Key Changes

- **Smart Contracts**: Removed `RewardsRegistry`,
`RewardsRegistryStorage`, `IRewardsRegistry`, and `SortedMerkleProof`
contracts along with all merkle claim functions from
`ServiceManagerBase`
- **Substrate Pallets**: Removed merkle proof generation from
`external-validators-rewards` pallet and deleted the entire
`runtime-api` crate (no longer needed)
- **Test Framework**: Removed all RewardsRegistry-related code from
deployment scripts, CLI handlers, and TypeScript bindings
- **Runtimes**: Cleaned up all three runtimes (testnet, stagenet,
mainnet) to remove runtime API implementations and unused imports

### Files Removed

**Contracts:**
- `contracts/src/middleware/RewardsRegistry.sol`
- `contracts/src/middleware/RewardsRegistryStorage.sol`
- `contracts/src/interfaces/IRewardsRegistry.sol`
- `contracts/src/libraries/SortedMerkleProof.sol`
- `contracts/test/RewardsRegistry.t.sol`
- `contracts/test/ServiceManagerRewardsRegistry.t.sol`

**Substrate:**
- `operator/pallets/external-validators-rewards/runtime-api/` (entire
crate)

**Test Framework:**
- `test/suites/rewards-message.test.ts`

### Files Modified

**Contracts:**
- `ServiceManagerBase.sol` - Removed merkle claim functions
- `ServiceManagerBaseStorage.sol` - Removed
`operatorSetToRewardsRegistry` mapping
- `IServiceManager.sol` - Removed interface members

**Substrate:**
- `external-validators-rewards` pallet - Removed merkle proof
generation, simplified `EraRewardsUtils` struct
- All runtime configs - Removed `ExternalValidatorsRewardsApi`
implementations

**Test Framework:**
- Updated deployment scripts, CLI handlers, relayer configs, and
TypeScript bindings

### Stats

```
50 files changed, 966 insertions(+), 4453 deletions(-)
```

## Test plan

- [x] All Rust tests pass (`cargo test`)
- [x] All contract tests pass (`forge test`)
- [x] TypeScript type checking passes (`bun typecheck`)
- [x] Contracts build successfully (`forge build`)
- [x] Operator builds successfully (`cargo build --release --features
fast-runtime`)
- [ ] E2E tests pass (`bun test:e2e`)
2026-01-09 15:25:49 +01:00
Ahmad Kaouk
268427be8d
feat: Implement EigenLayer Rewards V2 distribution (#351)
### Summary

This PR implements the EigenLayer Rewards Distribution V2 model for
DataHaven, replacing the previous merkle-root-based rewards registry
approach with EigenLayer's native `OperatorDirectedRewardsSubmission`
API. This enables direct integration with EigenLayer's
RewardsCoordinator for validator rewards distribution.

### Motivation

EigenLayer's V2 rewards model provides several advantages:
- **Direct integration**: Uses EigenLayer's native
`createOperatorDirectedOperatorSetRewardsSubmission` API
- **Per-operator rewards**: Distributes rewards proportionally to
individual operators based on their earned points
- **Simplified architecture**: Removes the need for a separate
RewardsRegistry contract
- **Better UX**: Operators receive rewards directly through EigenLayer's
established claiming mechanism


### Architecture

```
┌─────────────────────────────────────────────────────────────────┐
│                       DataHaven Substrate                       │
├─────────────────────────────────────────────────────────────────┤
│  Era End                                                        │
│    │                                                            │
│    ▼                                                            │
│  external-validators-rewards pallet                             │
│    │ generate_era_rewards_utils()                               │
│    │   • Calculate individual points per validator              │
│    │   • Compute total inflation amount                         │
│    │                                                            │
│    ▼                                                            │
│  RewardsSubmissionAdapter (runtime_common)                      │
│    │ build() → points_to_rewards() → encode_rewards_calldata()  │
│    │                                                            │
│    ▼                                                            │
│  Snowbridge Outbound Queue                                      │
│    │ CallContract(ServiceManager.submitRewards(...))            │
└────│────────────────────────────────────────────────────────────┘
     │
     ▼ Cross-chain message via Snowbridge
┌─────────────────────────────────────────────────────────────────┐
│                         Ethereum                                │
├─────────────────────────────────────────────────────────────────┤
│  DataHavenServiceManager                                        │
│    │ submitRewards(OperatorDirectedRewardsSubmission)           │
│    │   • Approve wHAVE tokens to RewardsCoordinator             │
│    │                                                            │
│    ▼                                                            │
│  EigenLayer RewardsCoordinator                                  │
│    │ createOperatorDirectedOperatorSetRewardsSubmission()       │
│    │                                                            │
│    ▼                                                            │
│  Operators claim rewards via EigenLayer                         │
└─────────────────────────────────────────────────────────────────┘
```

### Changes Overview

#### Smart Contracts (`contracts/`)

**DataHavenServiceManager.sol**
- Added `submitRewards(OperatorDirectedRewardsSubmission)` function to
submit rewards to EigenLayer's RewardsCoordinator
- Implements `SafeERC20` for secure token approvals
- Uses `onlyRewardsInitiator` modifier for access control (Snowbridge
Agent)
- Emits `RewardsSubmitted` and `RewardsInitiatorSet` events for tracking

**IDataHavenServiceManager.sol**
- Added `submitRewards()` interface for EigenLayer rewards submission
- Added `setRewardsInitiator()` interface for configuring the authorized
caller
- Added new events: `RewardsSubmitted`, `RewardsInitiatorSet`

**New Test: RewardsSubmitter.t.sol**
- Comprehensive test suite covering:
  - Access control (only rewards initiator can submit)
  - Single and multiple operator rewards
  - Multiple consecutive submissions
  - Custom descriptions and different tokens

#### Substrate Runtime (`operator/`)

**New: `runtime/common/src/rewards_adapter.rs` (934 lines)**

A generic, configurable adapter for building EigenLayer rewards
messages:

- **`RewardsSubmissionConfig` trait**: Runtime-agnostic configuration
interface
  - `OutboundQueue`: Snowbridge outbound queue type
  - `rewards_duration()`: Reward period duration (typically 86400s)
  - `whave_token_address()`: wHAVE ERC20 token on Ethereum
  - `service_manager_address()`: ServiceManager contract address
  - `rewards_agent_origin()`: Snowbridge agent origin

- **`RewardsSubmissionAdapter<C>`**: Generic implementation of
`SendMessage` trait

- **`points_to_rewards()`**: Converts validator points to token amounts
  - Proportional distribution based on total points
  - Returns remainder (dust) from integer division
  - Arithmetic overflow/underflow protection

- **`encode_rewards_calldata()`**: ABI-encodes the `submitRewards` call
  - Uses `alloy-core` for type-safe Solidity ABI encoding
  - Validates `uint96` multiplier bounds

- **Comprehensive test suite** covering:
  - Basic and edge-case reward calculations
  - Remainder/dust handling
  - Overflow/underflow protection
  - ABI encoding round-trip verification
  - Message building with various configurations

**Modified: `pallets/external-validators-rewards/`**

- **`types.rs`**: Extended `EraRewardsUtils` struct:
  ```rust
  pub struct EraRewardsUtils {
      pub era_index: u32,                    // NEW
      pub rewards_merkle_root: H256,
      pub leaves: Vec<H256>,
      pub leaf_index: Option<u64>,
      pub total_points: u128,
      pub individual_points: Vec<(H160, u32)>, // NEW
      pub inflation_amount: u128,             // NEW
      pub era_start_timestamp: u32       // NEW
  }
  ```

- **`lib.rs`**: Updated `generate_era_rewards_utils()`:
  - Now accepts `inflation_amount` parameter
  - Extracts `individual_points` as `(H160, u32)` tuples for EigenLayer
- Returns `None` when `total_points` is zero (prevents inflation with no
distribution)

- **`mock.rs`**: Updated test mock to use `H160` as `AccountId`
(matching DataHaven's EVM-compatible account model)

**Modified: Runtime Configurations**

All three runtimes (mainnet, stagenet, testnet) updated:

1. **New runtime parameters** (`runtime_params.rs`):
- `ServiceManagerAddress`: DataHaven ServiceManager contract on Ethereum
   - `WHAVETokenAddress`: wHAVE ERC20 token address
   - `RewardsGenesisTimestamp`: EigenLayer-aligned genesis timestamp
   - `RewardsDuration`: Rewards period (default: 86400 = 1 day)

2. **Refactored `RewardsSendAdapter`**:
- Replaced inline implementation with `RewardsSubmissionAdapter<Config>`
   - Each runtime implements `RewardsSubmissionConfig` trait
   - Cleaner, DRY configuration

## ⚠️ Breaking Changes ⚠️

- **Runtime Parameters**: New parameters must be configured via
governance before rewards submission will work:
  - `ServiceManagerAddress` (replaces `RewardsRegistryAddress`)
  - `WHAVETokenAddress`
  - `RewardsGenesisTimestamp`
  
- **Contract Interface**: `submitRewards()` now accepts a full
`OperatorDirectedRewardsSubmission` struct instead of a merkle root

---------

Co-authored-by: Gonza Montiel <gonzamontiel@users.noreply.github.com>
2026-01-06 23:53:03 +00:00
undercover-cactus
863250d555
misc: remove slasher middleware solidity contracts (#366)
## Summary

This PR remove the middlewares contracts from eigen layer. Instead we
are planning to use the eigne layer contract directly. It also removes
the tests related to the middleware slasher code and the mock contract
used in it.

## Motivation

When slashing an operator in the Dathaven we are going through the
substrate slashing pallet already implemented. It already allow to
configure a slashing window and/or to cancel a slashing. In the future
it will also be compatible with a government pallet. This part of code
is therefore redundant. For the same reason we remove the tests because
we are not using the slashing middleware contracts.

## What changed

* Remove the slasher middleware files
* Remove the tests related to the middleware slasher file
2025-12-29 14:55:21 +01:00
Gonza Montiel
733218ac79
fix: 🛡️ Check origin for validator set messages (#343)
### Context
The function `v2_sendMessage()` on Snowbridge Gateway contract is
**permissionless** (I'm shocked this is the design choice). Any
EOA/contract on Ethereum can build a message and send it through our DH
bridge. While we don't change our Snowbridge fork, then this will
continue to be the case.

### Problem
We use `v2_sendMessage()` to send **permissioned** operations to our
chain. For instance: update our validator set message (coming next,
_slashing-related_ messages). So we do need to restrict the processing
of the incoming messages on the Substrate side.

### Fix
- I've added a check to `EigenLayerMessageProcessor` that enforces
`message.origin` to be only a configured `AuthorisedOrigin`.
- I've added an `AuthorisedOrigin` to
`pallet_external_validators::Config`
- I've configured the `AuthorisedOrigin` to be
`DatahavenServiceManagerAddress` in all three runtimes

### Stages
- [x] Implementation
- [x] Runtime integration tests
- [x] Collect `DatahavenServiceManagerAddress` parameter for e2e tests
to work

Fixes https://github.com/datahaven-xyz/sr-datahaven/issues/12

---------

Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
2025-12-15 14:11:08 +01:00
Gonza Montiel
cb81164f22
feat: enable AVS owner workflow (#332)
# Enable AVS owner workflow

Until now, the deployer of the contracts and the owner of the deployed
contracts where the same account. Even if we allowed a different owner
to be specified, we were using the same. For this reason, a private key
was required, so after the deployment we could execute owned
transactions needed for the CLI.

In this PR we:
- Add a mechanism to the CLI to specify a different owner account other
than the deployer via `--avs-owner-address`
- Add CLI flags `--avs-owner-key` and`--execute-owner-transactions` so
account ownership vs. immediate execution is explicit and deferred. If
both previous parameters are provided, the CLI will execute the
transactions using the private key provided.
- Allow DataHaven AVS deploy scripts to toggle owner-call execution via
an env flag `TX_EXECUTION`
- Add documentation on how the new parameters work in `test/README.md`
and `test/docs/deployment.md`.

---------

Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
2025-12-10 17:38:21 +01:00
Ahmad Kaouk
ffd01d8f1d
Fix: command cli deploy contracts (#319)
## Summary

This PR fixes several issues with the CLI deploy-contracts command to
properly support local Anvil deployments and improves the overall
contract deployment workflow.

  ### Key fixes:
  - Add support for anvil chain in the CLI deploy contracts command
- Rename PRIVATE_KEY to DEPLOYER_PRIVATE_KEY for consistency and clarity
across the deployment flow
- Fix EigenLayer contract status display for local/anvil chains by
reading addresses from the deployments file instead of config
- Fix runShellCommandWithLogger to properly throw errors on command
failure
  - Correct totalSteps in DeployTestnet.s.sol from 2 to 4

  ### Housekeeping:
- Update .gitignore to ignore the entire broadcast/ folder
(autogenerated Foundry artifacts)
- Streamline contracts/README.md with clearer structure and deployment
instructions
2025-11-27 15:06:04 +01:00
undercover-cactus
077cc9ed29
feat: injecting contracts feature for e2e testing (#295)
In this PR, we introduce a way to save Ethereum state into a file. This
saved state can then be injected into Ethereum to speed up e2e initial
test setup.

This is a rewrite of the now closed PR
https://github.com/datahaven-xyz/datahaven/pull/90 .

It uses a an external tool written in rust to save state from the
Ethereum running container : https://github.com/undercover-cactus/Chaos

---------

Co-authored-by: Gonza Montiel <gonzamontiel@users.noreply.github.com>
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
2025-11-20 12:42:12 +01:00
Gonza Montiel
5121ae002b
feat: Datahaven contracts deployment on public testnet (#123)
## Summary
This PR introduces support for deploying Datahaven contracts to
different chains (hoodi, holesky, mainnet), as well as a new cli command
to manage this deployment separately from the regular deployment, while
maintaining compatibility with it.

#### New CLI command
- **`bun cli contracts deploy`** - Deploy contracts to supported chains
(Hoodi, Holesky, Mainnet)
- **`bun cli contracts status`** - Check deployment configuration and
status
- **`bun cli contracts verify`** - Verify contracts on block explorers
- Commands need the chain parameter: `--chain <hoodi | holesky |
mainnet>`
- Right now only `hoodi` and `holesky` are supported

### Deployment

#### Hoodi & Holesky Network Support
- Added **DeployBase.s.sol** as common ground for
**DeployTestnet.s.sol** (also new) and **DeployLocal.s.sol** (existing).
- **Hoodi configuration** (`contracts/config/hoodi.json`) with deployed
EigenLayer contract addresses to reference.
- **Holesky configuration** (`contracts/config/hoodi.json`) with
deployed EigenLayer contract addresses to reference.

#### Contracts being deployed
- **DataHaven**: ServiceManager, VetoableSlasher, RewardsRegistry
- **Snowbridge**: BeefyClient, AgentExecutor, Gateway, RewardsAgent  
- **EigenLayer**: References existing deployed contracts (not
re-deployed)

#### Deployment files
When the deployment is done, a new file under `contracts/deployments` is
generated with the addresses of the deployed contracts, for each chain
(it will be overriden per chain if run multiple times). So we would have
one `anvil.json`, `hoodi.json`, `holesky.json`, etc, with the addresses
of the deployed contracts for reference and for later verification.

#### Todo
- [x] Test compatibility with existing `bun cli launch` and `bun cli
deploy` commands

#### For follow-up PRs
- Fix verification issue with `foundry verify-contracts` when specifying
the `chain` or `chain-id` parameter, needed for hoodi
(https://github.com/foundry-rs/foundry/issues/7466).
- Add `redeploy` feature to only override implementation contract and
leave the proxy address untouched

## Usage Examples
```bash
# Deploy to Hoodi network
bun cli contracts deploy --chain hoodi

# Check deployment status  
bun cli contracts status --chain hoodi

# Verify contracts on block explorer
bun cli contracts verify --chain hoodi
```


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Added deployment and configuration support for new networks "hoodi"
and "holesky", including new configuration and deployment files.
* Introduced a CLI tool for managing contract deployments, status
checks, and verification across supported chains.
* Added example environment configuration and comprehensive deployment
documentation.
* Enabled contract verification and status reporting via the CLI with
support for block explorer integration.

* **Improvements**
* Refactored deployment scripts for modularity, supporting both local
and testnet environments.
* Centralized and extended configuration loading to support additional
contract addresses and network parameters.
* Enhanced deployment utilities and typings to support multi-network
deployments.

* **Bug Fixes**
* Improved input validation and error handling in CLI commands and
deployment scripts.
* Added explicit handling for zero address in operator strategy
retrieval.

* **Chores**
* Updated documentation and configuration templates for easier
onboarding and deployment management.
* Improved logging and output formatting for deployment and verification
processes.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
2025-08-21 10:02:31 +00:00
Tobi Demeco
a205b22532
feat: set rewards info as parameters in runtime (#99)
This PR improves the CLI to get from the deployments the
`RewardsRegistryAddress` (address of the RewardsRegistry contract
deployed), `RewardsAgentOrigin` (origin used for the agent in charge of
updating the rewards merkle root in the RewardsRegistry contract) and
`RewardsUpdateSelector` (function selector of the function that the
agent must execute to do the aforementioned update) and then set these
values in the `parameters` pallet of the runtime.

After these changes the rewards merkle root is being updated on the
Ethereum side. 🎉
2025-06-16 12:20:18 +02:00
Facundo Farall
d2bf185bcc
feat: 🚀 Add deploy command to CLI (#87)
### New Features
1. Add the `deploy` command to our CLI.
1. Conditionally deploys kurtosis eth network if we're in `stagenet`
environment.
    2. Deploys DH nodes.
3. Deploys contracts (all of them). In `mainnet` and `testnet` it
shouldn't deploy EL contracts, but for now that's not implemented.
4. Configures parameters, validators and relayers in the same way as
`launch`.
5. Currently, it only deploys `beefy` and `beacon` relayers, `execution`
and `solochain` relayers are pending for a subsequent PR.
2. Add `waitFor` utility function that receives a lambda.

### Refactors
1. Several common functionalities used both by the `launch` and `deploy`
command have been moved to the `cli/handlers/common` directory, from
where both commands use them. These include
    1. Checks for installed dependencies.
    2. Common constants.
    3. The `LaunchedNetwork` class has been moved to this directory.
    4. DataHaven nodes common functions.
    5. Kurtosis common functions.
    6. Relayer common functions.
7. Kubernetes functions (although only used by `deploy`, it seemed
fitting to have it here still).
8. Remove CLI questions and separator prints from `deploy-contracts.ts`
and `set-datahaven-parameters.ts` scripts. These things should be in the
`cli/launch` folder, which consumes the functions in these scripts.
9. Remove `setParametersFromCollection` from `utils` folder and put it
in `cli`.
10. Create base snowbridge relayer configs for `local` and `stagenet` as
two separate directories.

### Fixes
1. Sets the default time of the `deploy` command to 6s as Lodestar is
slower than Lighthouse.
2. In `runShellCommandWithLogger` only print `stderr` if the command
fails.

### Additional Minor Changes
1. K8s secret key names changed from `dh-beefy-relay-eth-key` to
`dh-beefy-relay-ethereum-key` and `dh-beacon-relay-sub-key` to
`dh-beacon-relay-substrate-key`, for simplicity in the deployment
script.
11. Update suggested configs for `.vscode` configs.

---------

Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
2025-06-12 10:24:03 +02:00
Gonza Montiel
34102c5b92
feat: add runtime parameters to cli (#89)
This PRs extracts [this
commit](74c0c0be0a)
from @TDemeco's PR to add a way to include parameters as part of the
CLI.

### Key changes
- CLI tool to set DataHaven runtime parameters via JSON configuration
- Supports both interactive prompts and command-line flags
- Type-safe parameter parsing and validation
- Already adds the parameters for the `EthereumGatewayAddress`, that
otherwise we would need to add manually to the node using an explorer.

---------

Co-authored-by: TDemeco <tdemeco@itba.edu.ar>
2025-05-27 10:49:53 +02:00
Facundo Farall
c29fc8f06d
fix: 🐛 CLI fixes for independently running parts of it (#85) 2025-05-21 17:01:12 +00:00
Tim B
431d1f7181
test: 🐳 Add Docker relay support to CLI (#74)
## Changes

 - Latest changes to have working relayer 🎉 component
 - Changed spawning snowbridge relayers to docker containers
 - Small logging output changes
 - Refactoring to `LaunchedNetwork` class
- new flag `--bd` `--build-datahaven` which will build a local docker
container which is **much** quicker than the proper CI build (which uses
a controlled build enviroment)
- new bun script `start:e2e:local`, which is everything that
`start:e2e:ci` has, but with building local docker container and
log_level debug set

---
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
- Added support for launching and managing relayer and DataHaven
services using Docker containers and networks.
- Introduced a CLI option to specify the relayer Docker image tag
instead of a binary path.

- **Improvements**
- Enhanced log messages with clearer text and expressive emojis for
better user feedback.
- Improved summary display by removing relayer services from the output.
- Updated build scripts to consistently enable the "fast-runtime"
feature for cross-platform builds.
  - Refined validation and error reporting for checkpoint data parsing.

- **Bug Fixes**
- Improved Docker container cleanup and network management during
service launch and teardown.

- **Chores**
- Updated and refactored npm scripts for Docker operations and
end-to-end test cleanup.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
2025-05-18 23:31:46 +00:00
Facundo Farall
e161accac2
fix: 🧑‍💻 Fix and improve bun cli logging and functionalities (#60)
This PR:
1. Generally improves the logging of the testing CLI, making the logs
more concise and easier to follow, with clearer sections and
separations.
2. Launches DataHaven solochain nodes at the beginning not the end.
3. Prompts the user if they want to launch DataHaven nodes and
Snowbridge Relayers.

---------

Co-authored-by: Tim B <79199034+timbrinded@users.noreply.github.com>
2025-05-08 09:42:45 -03:00
Tim B
3776d80a2e
test: ️ CI Refactor (#59)
Eventually our CI will be required to run two private blockchains
locally plus associated relayers.

This PR is to prepare for this fate by improving run times and
refactoring our existing CIs so they are a bit easier to reason about.

### Refactors
- **_We now run ALL CIs on every PR!_** This is so that we decomplexify
the logic around conditional builds and fetching built binaries from
another source. This reduces the surface area of code we have to
maintain at the cost of execution time
- This penalty is ameliorated by a layered caching system. At best, it
will be less than a minute to complete a build since everything will be
cached. On GH runners this is about 6 minutes sadly.
- We will no longer be at risk of important CIs being skipped
erroneously which hide true failures.
- Caching is a low-risk approach because at worst it has to build from
scratch. A bad cache hit will never imply the wrong thing gets build
since cargo is smart enough to just throw away any inappropriate build
artefacts.
- `setup-rust` action created so we have a unified way of setting up
runner and unifying our approach to caching
- Use a unique caching key for different activities and it will fallback
to shared cache if no matches
- we are using `mainnet` kurtosis config so that it works with relayer
assumptions

### Additions
- We can specify the ethereum block time via a new cli arg `--slot-time
<seconds>`
- We can specify arbitrary network_param args which get passed into the
generated yaml
- e.g. giving `bun cli --kurtosis-network-args="pet=cat food=fish" will
add:

```yml
network_params:
  # existing params...
  pet: cat
  food: fish
```

- We now have the ability to programmatically modify the yaml
- This means we are back down to a single `minimal.yml` kurtosis config
so we dont have to maintain changes between them
- Flow is: `add new cli arg` -> `add if() block which mutates yaml` ->
`profit`

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
2025-05-06 20:20:02 +00:00
Tim B
95171a5e10
test: ⚙️ Parse & Generate Relayer Configs (#54)
## Human Written Description

This PR adds the following to the E2E CLI:

- Relayer config generation for: `beacon-relay` `beefy-relay`
  - The other two relayer types to be added later
  - Relayers don't actually work yet
- By default turned off, this requires a binary to be present in:
`<repo_root>/operator/target/release` dir
- Datahaven network launching
  - DH network is using default `local` network chain spec
- Launched with 5 nodes since our authority set is 6 large (and you need
2/3 + 1 of set size

> [!NOTE]  
> Both the relayer and the DH node binaries are being run as local
processes TEMPORARILY. This means that logging is done in a very
rudimentary way (we pipe to a file whilst the CLI is running).
> 
> This means that when the CLI finishes **the log files will no longer
be written to**.
> This is temporary since spawning binaries is a stop gap solution until
docker images available.


---

> [!IMPORTANT]  
> The following is AI generated slop describing this PR's changes:

**Key Changes:**

*   **CLI Enhancements (`test/cli/index.ts`):**
* Added options `--datahaven` and `--datahaven-bin-path` to enable
launching local DataHaven nodes.
* Added options `--relayer` and `--relayer-bin-path` to enable launching
Snowbridge relayers (Beefy and Beacon).
* Added negation flags (`--no-fund-validators`, `--no-setup-validators`,
`--no-update-validator-set`) for more granular control over validator
setup steps.
* Added `--skip-cleaning` option to preserve Kurtosis state between
runs.
* Added a pre-action hook (`launchPreActionHook`) to validate flag
combinations (e.g., `--verified` requires `--blockscout`).
*   **New CLI Handlers (`test/cli/handlers/launch/`):**
* `datahaven.ts`: Logic for spawning DataHaven node processes using the
specified binary. Manages ports and process cleanup.
* `relayer.ts`: Logic for configuring and spawning Snowbridge relayer
processes (Beefy and Beacon). Reads contract deployment addresses,
updates relayer config templates, and uses specified private keys.
Manages log files and process cleanup.
* `summary.ts`: Generates and displays the table of running services
(including dynamically launched DataHaven nodes) and their endpoints.
* `validator.ts`: Extracted validator funding, setup, and set update
logic into its own handler.
* `index.ts`: Orchestrates the launch sequence based on CLI options,
calling the appropriate handlers. Includes a `LaunchedNetwork` class to
track spawned processes, file descriptors, and node ports for cleanup.
*   **Updated `package.json` Scripts:**
* Added `start:e2e:minrelayer` script for a minimal setup including
relayers and DataHaven nodes.
* Modified `stop:e2e` to include `pkill datahaven` for proper cleanup.
* Added `stop:e2e:quick` to only stop the Kurtosis enclave without full
cleaning.
* **Updated `launch-kurtosis.ts`:** Modified to use new Kurtosis utility
functions and added a `skipCleaning` option.
*   **New Utility Functions:**
* `test/utils/kurtosis.ts`: Functions to inspect Kurtosis services
(`getServiceFromKurtosis`, `getPortFromKurtosis`,
`getServicesFromKurtosis`).
* `test/utils/parser.ts`: Zod schemas and parsing functions for
Snowbridge relayer configurations.
*   **Constants & Minor Updates:**
    *   Added `SUBSTRATE_FUNDED_ACCOUNTS` to `test/utils/constants.ts`.
    *   Updated `tsconfig.json` include paths.
* Refactored `test/utils/docker.ts` (though now largely superseded by
Kurtosis utils).
    *   Updated logging in `test/scripts/send-txn.ts`.

**Reasoning:**

This PR significantly expands the E2E testing capabilities by allowing
developers to easily launch and integrate local DataHaven nodes and
Snowbridge relayers into the test network, facilitating more
comprehensive integration testing. The CLI refactoring makes managing
these complex setups more robust and user-friendly.
2025-04-29 13:24:00 +01:00
Facundo Farall
6310f0d3fc
feat: 🧑‍💻 Turn scripts into an interactive CLI (#41)
WARNING: This PR changes the kurtosis package to use the one from
upstream, not our fork, as it was not working at the moment. This should
be changed when fixed.

In this PR:
1. Turn `launch-kurtosis` script into a CLI, which parses parameters and
can interactively run multiple steps.
2. Separate steps of such CLI into their own scripts.
1. New script created `launch-kurtosis`, which detects if an enclave is
running and prompts to relaunch it if it is.
2. New script created `deploy-contracts` to deploy all contracts. It can
optionally verify them as well.
3. Each step can be interactively opted in/out, or choose whether to run
it via CLI params.
4. The CLI offers a help command as well.
5. Cleanup logs of CLI. Logs of internal commands ran can be printed
with LOG_LEVEL=debug. In case of error, they are always printed out.
2025-04-15 11:01:24 -03:00