mirror of
https://github.com/datahaven-xyz/datahaven
synced 2026-05-24 01:38:32 +00:00
10 commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
162247bfbd
|
refactor(rewards): Optimize reward calculation (#408)
### Summary
Optimizes `award_session_performance_points` by batching all validator
rewards into a single storage mutation instead of performing individual
mutations inside the loop.
### Problem
The `award_session_performance_points` function, called during session
rotation via `SessionManager::end_session`, was calling `reward_by_ids`
inside the validator loop for each validator individually:
```rust
for validator in validators.iter() {
// ... calculate points ...
Self::reward_by_ids([(validator.clone(), points)].into_iter());
}
```
Each call to `reward_by_ids` performs a `StorageMap::mutate` on
`RewardPointsForEra`, which reads and writes the entire
`EraRewardPoints` structure (a `BTreeMap` containing up to N validator
entries). With N validators, this results in N separate
read-modify-write cycles of an O(N)-sized structure, leading to O(N²)
total storage I/O.
### Solution
Collect all reward points first, then perform a single batched call to
`reward_by_ids`:
```rust
let mut rewards = Vec::new();
for validator in validators.iter() {
// ... calculate points ...
rewards.push((validator.clone(), points));
}
if !rewards.is_empty() {
Self::reward_by_ids(rewards.into_iter());
}
```
This reduces the complexity from O(N²) to O(N) by performing only one
storage mutation that processes all validators at once.
### Why This Matters
Session rotation hooks are mandatory—they execute regardless of block
weight limits. While `pallet_session::on_initialize` returns `max_block`
weight during rotation (preventing user transactions), the actual
execution time still matters. With a large validator set, O(N²) storage
operations could exceed the block time target, potentially causing block
production delays.
### Test Plan
- [x] Existing unit tests pass (`cargo test -p
pallet-external-validators-rewards`)
|
||
|
|
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`) |
||
|
|
9bca5c467b
|
fix: Use block authorship as liveness indicator for validator rewards (#367)
## Summary
Use block authorship as direct proof of liveness for the 30% liveness
component of validator rewards. Validators who author at least one block
in a session are considered online and receive the full liveness bonus.
## Problem
The rewards pallet was checking validator liveness via ImOnline
**after** the session had rotated - at which point ImOnline had already
cleared its `AuthoredBlocks` storage. This caused all validators to
appear offline, resulting in only ~70% of expected rewards being
allocated (missing the 30% liveness bonus).
## Solution
Use **block authorship as the proxy for liveness**:
- A validator who authored at least one block is definitively online
- Liveness is determined directly in `award_session_performance_points`
via `blocks_authored > 0`
- No dependency on external liveness checks (ImOnline)
### Rewards Formula
- **60%** Block authorship (proportional to blocks produced)
- **30%** Liveness (full bonus if authored ≥1 block, zero otherwise)
- **10%** Base reward (for being in the validator set)
### Files Changed
- `pallets/external-validators-rewards/src/lib.rs` - Core logic changes
- `pallets/external-validators-rewards/src/mock.rs` - Test mock updates
- `pallets/external-validators-rewards/src/tests.rs` - Test updates
- `runtime/{mainnet,testnet,stagenet}/src/configs/mod.rs` - Config
updates
## Testing
- All 76 pallet tests pass
- Local testing should show correct points per session (e.g., 3200
points for 2 validators with 10 blocks)
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
|
||
|
|
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>
|
||
|
|
67f375860b
|
feat: ✨ Performance-Based Validator Rewards and Inflation Scaling (#306)
## 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> |
||
|
|
7f09949e64
|
feat: ✨ Implement inflation mechanism for validator rewards (#304)
## Summary This PR introduces a configurable inflation system for validator rewards with an annual target rate and optional treasury allocation. ## Changes ### Inflation Mechanism - **Annual inflation rate runtime parameter**: Set to 5% default - **EraInflationProvider**: Calculates per-era inflation based on total issuance and annual rate - Formula: `per_era_inflation = (total_issuance × annual_rate) / eras_per_year` ### Treasury Allocation - **InflationTreasuryProportion parameter**: Set to 20% default - **ExternalRewardsInflationHandler**: Mints inflation and distributes between: - 80% to rewards account (for validator rewards) - 20% to treasury account - Treasury receives allocation via `mul_floor()`, with remainder going to rewards to ensure no tokens lost to rounding ### Runtime Integration - Configured across all three runtimes: mainnet, testnet, and stagenet - Consistent parameters across all environments ### Testing - Updated all tests to account for 80/20 split between rewards and treasury - Added precision tolerance (±1 unit) for Perbill rounding edge cases --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
5a7983f0d8
|
chore: ♻️ Add missing license header in operator & AVS contracts source code (#285)
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com> |
||
|
|
f0896907ae
|
feat: add slashing support (#242)
## 🔨 Add Slashing Support for Runtime
This PR introduces the slashing functionality for the DataHaven runtime,
enabling punitive measures against misbehaving validators.
### Features
- Deferred slashing with configurable veto periods
- Cross-chain slashing message delivery trough Snowbridge
- Governance controls for slashing parameters and emergency cancellation
We introduced the `external-validator-slashes` pallet, which allows to
slash validators that misbehave. The slashing is triggered when an
offence is reported via the offence pallet (which is already
implemented). The message is sent through Snowbrige's outbound queue and
the real slashing happens in the contracts side, which will come in a
follow up PR.
There is a configurable window of time between the time the validator is
being reported, and the time the slash is triggered. This allows that in
case of an error we are still able to cancel the slashing, using a sudo
account.
For convenience, we also have extrinsics for corner cases:
- **`force_inject_slash`**: Root-only function to manually inject
slashes for specific validators with custom percentages. Useful for
emergency situations or governance-directed slashing outside normal
offence detection
- **`cancel_deferred_slash`**: Allows governance to cancel pending
slashes during the defer period by specifying era and slash indices.
Provides safety mechanism against false positives or malicious slash
reports
- **`set_slashing_mode`**: Configurable slashing behavior with three
modes - `Enabled` (normal operation), `LogOnly` (track offences without
applying slashes), and `Disabled` (completely halt slashing). Critical
for emergency response and testing
---------
Co-authored-by: Gonza Montiel <gon.montiel@gmail.com>
Co-authored-by: Gonza Montiel <gonzamontiel@users.noreply.github.com>
|
||
|
|
91e29700a3
|
feat: ✨ Bump client version to v0.2.0 & runtime spec_version to 200 (#194) | ||
|
|
d76f70686e
|
feat(operator): Add External Validators Rewards Pallet (#72)
This PR introduces and integrates the new
`pallet-external-validators-rewards` into the operator runtimes. This
pallet is responsible for managing and distributing rewards to external
validators. The pallet was originally introduced by Tanssi. It was
heavily modified to abstract the message building and sending with
Snowbridge.
### Key Changes Related to `pallet-external-validators-rewards`:
* **Pallet and Runtime API Addition:**
* The `pallet-external-validators-rewards` has been added to `mainnet`,
`stagenet`, and `testnet` runtimes
* **Runtime Configuration
(`operator/runtime/{mainnet,stagenet,testnet}/src/configs/mod.rs`):**
* **`RewardsRegistryAddress` Parameter:** A new dynamic runtime
parameter `RewardsRegistryAddress` (type `H160`) has been added to
`runtime_params.rs`. This will hold the Ethereum address of the Rewards
Registry contract.
* **Author Rewards with `RewardsPoints`:**
* A new struct `RewardsPoints` implements
`pallet_authorship::EventHandler`.
* Its `note_author` function rewards block authors (if they are not
whitelisted validators) by calling
`ExternalValidatorsRewards::reward_by_ids`.
* The `EventHandler` in `pallet_authorship::Config` is updated to
`(RewardsPoints, ImOnline)`.
* **Integration with `pallet-external-validators`:**
* The `OnEraStart` and `OnEraEnd` hooks in
`pallet_external_validators::Config` are now set to
`ExternalValidatorsRewards`, allowing the rewards pallet to react to era
changes.
* **`RewardsSendAdapter` for Ethereum Communication:**
* A new struct `RewardsSendAdapter` implements
`pallet_external_validators_rewards::types::SendMessage`.
* `build()`: Constructs an `OutboundMessage` to call the
`updateRewardsMerkleRoot(bytes32)` function on the
`RewardsRegistryAddress` on Ethereum. The calldata includes the selector
(hashed from `UpdateRewardsMerkleRootSignature`) and the
`rewards_merkle_root`.
* `validate()` and `deliver()`: Utilize `OutboundQueueV2` for message
validation and delivery.
* A constant `UpdateRewardsMerkleRootSignature` (
`b"updateRewardsMerkleRoot(bytes32)"`) is defined for this purpose.
* **Runtime API
(`operator/runtime/{mainnet,stagenet,testnet}/src/lib.rs`):**
* The runtime implements
`pallet_external_validators_rewards_runtime_api::ExternalValidatorsRewardsApi`.
* This exposes two functions:
* `generate_rewards_merkle_proof(account_id: AccountId, era_index:
EraIndex) -> Option<MerkleProof>`
* `verify_rewards_merkle_proof(merkle_proof: MerkleProof) -> bool`
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced a rewards system for external validators with era-based
tracking, Merkle proof generation, and verification.
- Added runtime APIs to generate and verify validator rewards Merkle
proofs.
- Enabled rewards distribution via outbound messaging to an external
registry contract.
- Configured runtime parameters for the rewards registry address.
- Added fixed author reward points and integrated rewards logic into
block authorship events.
- Provided a mock runtime environment and benchmarking support for the
rewards pallet.
- **Tests**
- Added comprehensive tests and benchmarks for validator rewards
distribution and Merkle proof functionality.
- **Chores**
- Integrated new pallets and runtime APIs into mainnet, stagenet, and
testnet configurations.
- Updated dependencies and feature groups to include new rewards-related
pallets.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
|