# ✨ Implement Dynamic Fee Adjustment Mechanism
## Overview
Implements a dynamic fee adjustment mechanism, replacing the constant
fee multiplier with an adaptive multiplier that responds to network
congestion, following Moonbeam's pattern.
## Changes
- Replaces `ConstFeeMultiplier` with `TargetedFeeAdjustment` across all
runtime configurations (mainnet, stagenet, testnet)
- Implements an EIP-1559-like slow-adjusting fee mechanism that prevents
DoS attacks by adjusting fees based on block fullness
- **Configurable Parameters**:
- Target block fullness: 35%
- Adjustment variable: 4/1000 (responds in ~1 hour at extreme
congestion)
- Two modes:
- `SlowAdjustingFeeUpdate` for mainnet and testnet.
- `FastAdjustingFeeUpdate` for stagenet.
- Adds tests coverage for different fee scenarios
## Technical Details
The fee adjustment algorithm works as follows:
```
diff = (previous_block_weight - target) / maximum_block_weight
next_multiplier = prev_multiplier * (1 + (v * diff) + ((v * diff)^2 / 2))
assert(next_multiplier > min)
```
**Where:**
- `v` = AdjustmentVariable
- `target` = TargetBlockFullness
- `min` = MinimumMultiplier
`SlowAdjustingFeeUpdate` sets a minimum multiplier of `1x` for a
conservative fee adjustment, while `FastAdjustingFeeUpdate` sets it to
`0.1x`, which is mainly used for dev networks / testing.
# Add Referenda Precompile
This PR introduces the referenda precompile from Moonbeam to enable
governance functionality through EVM calls.
## Changes Made
- Added `operator/precompiles/referenda/` with complete implementation
- Updated all runtime configs (mainnet, stagenet, testnet) to include
the referenda precompile
- Adapted track processing logic to work with DataHaven's runtime
configuration
- Adapted tests and mock according to our runtime
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
This PR upgrades the StorageHub dependencies to tag
[v0.0.6-alpha](https://github.com/Moonsong-Labs/storage-hub/releases/tag/v0.0.6-alpha).
This includes the fix to connect through TLS to a Postgres DB (allowing
connecting to an AWS hosted DB for instance), and a fix for a missing
indexer DB migration.
Additionally, it adds a new runtime API.
EDIT (previously breaking changes):
As of the new version, the name of a column in the indexer DB has
changed. This can affect the functionality of nodes running a Postgres
DB with the old schema. A
[migration](05d269a26d)
is included in the new
[tag](https://github.com/Moonsong-Labs/storage-hub/commits/v0.0.6-alpha/),
so no need to mark it as breaking.
---------
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
Co-authored-by: Gonza Montiel <gonzamontiel@users.noreply.github.com>
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
## Summary
- rename the FRAME alias for `pallet_evm` from `Evm` to `EVM` across the
mainnet, stagenet, and testnet runtimes
- adjust benchmarks, configuration modules, genesis builders, and
runtime tests to rely on the new alias
- keep precompile genesis setup and proxy/precompile tests aligned with
the updated names
## Context
Frontier’s `StorageOverrideHandler` (see
`fc_storage::StorageQuerier::account_code`) reads contract bytecode from
`pallet_evm::AccountCodes` using the constant `PALLET_EVM = b"EVM"` to
build the storage key:
`twox_128("EVM") ++ twox_128("AccountCodes") ++ …`
Our runtimes exported `pallet_evm` as `Evm`, so substrate stored
bytecode under the *camel-cased* prefix (`twox_128("Evm")`). Every call
that ultimately hits the storage override—including `eth_getCode`,
`eth_call`, and state queries during replay—therefore failed to locate
code for *any* account (deployed contracts and precompiles alike).
Renaming the alias to `EVM` realigns the storage prefix with Frontier’s
expectations so the override layers can pull bytecode correctly.
## Testing
- `cargo check -p datahaven-node`
- `cargo build --release -p datahaven-node`
- `eth_getCode 0x0000000000000000000000000000000000000802` → returns
`0x60006000fd`
## Storage Migration
Renaming a pallet alias changes the storage prefix for all pallet data.
Without migration, existing EVM data (smart contracts, account codes,
storage) would become inaccessible.
**Migration details:**
- **Type**: Multi-Block Migration (MBM)
- **Storage migrated**: `AccountCodes`, `AccountCodesMetadata`,
`AccountStorages`
- **Migration ID**: `datahaven-evm-mbm` (version 0 → 1)
**Testing the migration:**
```bash
# Build runtime with try-runtime
cargo build --release --features try-runtime -p
datahaven-stagenet-runtime
# Test against stagenet
try-runtime \
--runtime
./target/release/wbuild/datahaven-stagenet-runtime/datahaven_stagenet_runtime.wasm
\
on-runtime-upgrade \
--blocktime 6000 \
--checks all \
--disable-spec-version-check \
live --uri wss://dh-validator-0.datahaven-kt.xyz
```
Test results from stagenet:
- ✅ Migration completes in 1 block
- ✅ PoV size: ~5.3 KB
- ✅ Weight consumption: <0.1% of block capacity
- ✅ All 39 keys successfully migrated
## ⚠️ Breaking Changes ⚠️
If you are manually computing storage keys for the EVM pallet (e.g., directly querying chain state), you must update your code to use the new storage prefix:
- Old prefix: twox128("Evm") = 0x8b90cb...
- New prefix: twox128("EVM") = 0x6a5e91...
All EVM-facing interfaces remain unchanged.
## Add Preimage Precompile
This PR integrates the Preimage precompile from Moonbeam into the
DataHaven runtime across all three environments (mainnet, stagenet,
testnet).
**Key Changes:**
- Added Preimage precompile implementation at address `2067` in all
runtime configurations
- Updated precompile sets in mainnet, stagenet, and testnet runtimes
- Updated `is_governance_precompile()` for the Preimage precompile
## Add Conviction Voting Precompile
This PR introduces a new EVM precompile for conviction voting
functionality, enabling smart contracts to interact with the Substrate
conviction voting pallet.
### Key Changes
- **New Precompile**: Added `ConvictionVotingPrecompile` at address
`0x0000000000000000000000000000000000000812` (2066)
- **Solidity Interface**: Complete Solidity interface
(`ConvictionVoting.sol`) with all conviction voting operations
- **Runtime Integration**: Integrated precompile across all runtime
configurations (mainnet, testnet, stagenet)
- **Comprehensive Testing**: Inherits test suite from Moonbeam
### Features
- Vote casting with different conviction levels (None, Locked1x-6x)
- Vote delegation and undelegation
- Poll management and tallying
- Support for all conviction voting pallet operations
---------
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
## Add Collective Precompile
Adds the pallet collective precompile to `mainnet`, `stagenet`, and
`testnet` according to Moonbeam's configuration.
### Changes:
- Added `pallet-evm-precompile-collective` dependency to workspace
- Configured collective precompile at address `2064` using
`TreasuryCouncilInstanc`
- Configured collective precompile at address `2068` using
`TechnicalCommitteeInstance`
The precompile provides EVM access to collective governance
functionality including proposal execution, voting, and membership
management.
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
## Add Identity Precompile
Adds the pallet Identity precompile to `mainnet`, `stagenet`, and
`testnet` according to Moonbeam's configuration.
### Changes:
- Added `pallet-evm-precompile-identity` dependency to workspace
- Added and configured at address `2072` for all runtimes
The precompile provides a Solidity interface access to the Substrate
Identity pallet functionality.
---------
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
To ensure that the runtime precompiles they can be called from within
contracts, there must be some code deployed at the precompile address.
This PR ensure the simplest bytecode (which reverts) is deployed at
genesis time for all addresses of precompiles present in the runtime.
In this PR we update StorageHub to its latest tage `v0.0.4-alpha`. It
includes so minor changes on the FilesystemAPI.
Its also force to specify the `maintenance_mode` options for fisherman.
For now we are not allowing this mode so we just skip entirely.
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
## Overview
This PR integrates Substrate's `pallet-migrations` into all DataHaven
runtimes (mainnet, stagenet, testnet) to enable robust multi-block
migration capabilities. This infrastructure allows complex runtime
upgrades to be executed across multiple blocks while maintaining chain
stability and providing governance controls.
## What Changed
### Core Integration
- **Added `pallet-migrations` dependency** across all runtime
configurations
- **Integrated migration pallet** as pallet index 39 in all runtimes
- **Created shared migration configuration** in
`datahaven-runtime-common`
### Runtime Configuration
- **Mainnet, Stagenet, and Testnet** now include identical migration
configurations
- **MaxServiceWeight** parameter set to 75% of max block weight for safe
migration execution
- **Migration cursor limits** configured (65KB max cursor, 256B max
identifier)
- **Failure handling** configured to freeze the chain on migration
failures (similar to Moonbeam's maintenance mode)
## Future Work
- [ ] Add custom failure handler (safe mode) to replace chain freeze
- [ ] Generate DataHaven-specific benchmarks for migration weights
---------
Co-authored-by: undercover-cactus <lola@moonsonglabs.com>
## Add proxy call filtering for EVM accounts
This PR implements a `NormalCallFilter` following moonbeam filters.
### Changes
- Added `NormalCallFilter` implementation across all runtime
configurations (mainnet, stagenet, testnet)
- Configured the filter as `BaseCallFilter` in `frame_system::Config`
### Security Improvements
The filter blocks:
- **Proxy calls to EVM accounts** - Prevents proxying to smart contracts
- **Direct EVM pallet calls** - Prevents reentrancy from precompiles
(following Moonbeam's security pattern)
This aligns with best practices from Moonbeam and addresses known
security considerations around EVM/Substrate interaction patterns.
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
Incorporate `pallet-evm-precompile-file-system` into `stagenet`,
`testnet` and `mainnet`.
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
Since we are including Storage Hub pallets and we no longer hide the
compilation behind a feature flag, the tests started to fail because the
nodes where panic!ing on each block finalisation.
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
## Summary
This PR adds Moonbeam's Batch precompile to DataHaven, enabling
efficient batching of multiple EVM transactions in a single call. This
implementation follows Moonbeam's exact architecture and provides
significant gas savings for batch operations.
## Key Features
### Batch Precompile Functions
- **`batchSome(address[], uint256[], bytes[], uint64[])`**: Execute
multiple calls, continuing on failures
- **`batchSomeUntilFailure(address[], uint256[], bytes[], uint64[])`**:
Execute calls until first failure
- **`batchAll(address[], uint256[], bytes[], uint64[])`**: Execute all
calls, reverting if any fail
### Technical Implementation
- **Address**: `0x0808` (2056 in decimal)
- **Access Control**: Restricted nesting with `SubcallWithMaxNesting<2>`
- **Self-recursion**: Only the Batch precompile can call itself
(`OnlyFrom<AddressU64<2056>>`)
- **Gas Management**: Proper gas estimation and refund handling
- **Error Handling**: Comprehensive revert reasons and event logging
Depends on #137
---------
Co-authored-by: Ahmad Kaouk <ahmadkaouk.93@gmail.com>
## Summary
This PR implements a comprehensive EVM precompile registry system for
DataHaven, following Moonbeam's exact architecture and patterns. The
implementation includes:
- **Registry Precompile**: A new precompile at address `0x0815` (2069)
that manages and queries available precompiles
- **Core Ethereum Precompiles**: Standard Ethereum precompiles
(ECRecover, SHA256, RIPEMD160, Identity, ModExp, BN128Add, BN128Mul,
BN128Pairing, Blake2F, SHA3FIPS)
- **Modular Architecture**: Clean separation following Moonbeam's
structure with dedicated precompile modules per runtime
## Key Features
### Registry Precompile Functions
- `isPrecompile(address)`: Check if an address corresponds to any
precompile (active or inactive)
- `isActivePrecompile(address)`: Check if a precompile is currently
active in the runtime
- `updateAccountCode(address)`: Insert dummy EVM bytecode for Solidity
compatibility
### Runtime Integration
- Integrated across all three runtimes (testnet, stagenet, mainnet)
- Uses Moonbeam's `PrecompileSetBuilder` pattern for composable
precompile management
- Proper gas accounting with database read/write operations
- Access control through `CallableByContract` and `CallableByPrecompile`
traits
---------
Co-authored-by: undercover-cactus <lola@moonsonglabs.com>
This PR updates the project dependencies as follows:
- **Polkadot SDK**: from the `stable2412` (moving) branch to the
`polkadot-stable2412-6` (fixed) tag.
- **StorageHub**: to revision
`f8281283b6003a3009a32431ed0f3cd628561d6b`, which also depends on
Polkadot SDK `polkadot-stable2412-6`.
- **Frontier**: revision `75329a2df49e2cc7981485392c31160929d1bd48n`
which, likewise, depends on Polkadot SDK `polkadot-stable2412-6`.
This PR add the storagehub pallets to the `testnet` and `mainnet`
runtime. The storage hub pallets are only build with the runtime if the
`storage-hub` feature is activated.
It is also add minor fixes to the `stagenet` runtime (fix wrong path
dependencies, index collision, etc...).
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
## Summary
This PR integrates the Substrate Proxy pallet into DataHaven runtimes
(testnet, stagenet, mainnet) with comprehensive test coverage. The proxy
pallet enables account delegation functionality, allowing accounts to
authorize other accounts to execute calls on their behalf with
configurable permissions.
## Changes
### Proxy Pallet Integration
- **Added proxy pallet** to all three DataHaven runtimes (testnet,
stagenet, mainnet)
- **Configured custom ProxyType enum** with DataHaven-specific proxy
types:
- `Any` - Unrestricted proxy access
- `NonTransfer` - All calls except balance transfers
- `Governance` - Governance and utility calls only
- `Staking` - Staking operations (placeholder)
- `CancelProxy` - Proxy announcement cancellation
- `Balances` - Balance transfer operations only
- `IdentityJudgement` - Identity judgement operations
- `SudoOnly` - Privileged sudo operations only
### Runtime Configuration
- **Integrated pallet-proxy** into runtime construction macros
- **Configured proxy deposits** (base + per-proxy fees)
- **Set proxy limits** (maximum proxies per account)
- **Implemented InstanceFilter** for call filtering per proxy type
- **Added proxy pallet to runtime APIs** and metadata
### Comprehensive Test Suite
- `operator/runtime/testnet/tests/proxy.rs` - 24 comprehensive proxy
tests
- `operator/runtime/stagenet/tests/proxy.rs` - 24 comprehensive proxy
tests
- `operator/runtime/mainnet/tests/proxy.rs` - 24 comprehensive proxy
tests
- Updated `lib.rs` files in all three runtimes to include proxy test
modules
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- New Features
- Enable account proxies across mainnet, stagenet, and testnet with
configurable types, delays, and per-type call permissions.
- Support anonymous (pure) proxies, proxy announcements with delays, and
deposit/limit parameters for proxy management.
- Tests
- Add comprehensive integration tests covering proxy lifecycle,
filtering, pure proxies, announcements, batching, chaining, multisig,
identity, and sudo paths.
- Test builder now supports optional sudo setup.
- Chores
- Add benchmarking, weights, and try-runtime support for proxies.
- Update internal package metadata version.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Ahmad Kaouk <ahmadkaouk.93@gmail.com>
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
* Add `run_benchmarks.sh` script to run runtime benchmarks
* Sets up benchmark configs and directory structure to store weights
(`operator/runtime/<RUNTIME>/weights`)
* (naive) fixes to some benchmarks:
* `pallet_datahaven_native_transfer`:
* use a mock for `NativeTokenId`
* look at the balance difference of the treasury instead of the total
(this makes the benchmark agnostic to genesis setup)
* `snowbridge_pallet_system` / `snowbridge_pallet_system_v2` use native
token xcm location vs relay chain one. Add missing benchmark methods and
update fixture with valid data.
* `snowbridge_pallet_ethereum_client`: update fixtures with valid data
* `snowbrige_pallet_inbound_queue_v2`: set EthereumGatewayAddress when
initializing storage on benchmark and use a mock message processor ( as
fixture has `CreateAsset` payload which is not supported in the
`EigenLayerMessageProcessor`)
* `snowbridge_pallet_outbound_queue_v2`: add missing
`submit_delivery_receipt` benchmark which required a dedicated fixture
(all copied from the upstream pallet)
* `pallet_treasury`: Use an `ExistentialDeposit` of `1` on benchmark,
else payout fails.
* `pallet_transaction_payment`: Use a custom `WeightToFee` that makes
the Fee small, else account in benchmark cannot pay for fees (It is
funded a multiplier of `ExistentialDeposit` and is expected for that to
be enough, but it's not in our particular setup).
* comment out `pallet_identity` and `pallet_im_online` due to
incompatibilities (to be addressed later)
* Basic benchmark run to set `WeightInfo` from `weights` in configs
(real run should be done later using target hardware)
---------
Co-authored-by: Ahmad Kaouk <ahmadkaouk.93@gmail.com>
Co-authored-by: Tobi Demeco <50408393+TDemeco@users.noreply.github.com>
Co-authored-by: undercover-cactus <lola@moonsonglabs.com>
Co-authored-by: TDemeco <tdemeco@itba.edu.ar>
## Overview
This PR implements the **return path** for DataHaven's native token
bridge, enabling tokens that were previously transferred from DataHaven
to Ethereum to flow back to DataHaven.
**Context**: DataHaven native tokens can be transferred to Ethereum
where they exist as wrapped ERC20 tokens. This PR completes the
bidirectional bridge by implementing the mechanism to transfer these
tokens back from Ethereum to DataHaven, effectively "unwrapping" them
and restoring them to their native form.
## Key Changes
- **Added `NativeTokenTransferMessageProcessor`** , a new message
processor specifically designed to handle native token return transfers
from Ethereum, and extended `InboundQueueV2` processor tuple to include
native token transfer handling alongside existing EigenLayer message
processing
## How It Works
### Detailed Flow: Ethereum → DataHaven
#### 1. **Ethereum Initiation**
- **User Transaction**: User calls `v2_sendMessage` on Snowbridge
Gateway contract:
```solidity
v2_sendMessage(
assets: [{
kind: ForeignToken,
assetId: <registered_native_token_id>, // Must match pre-registered
token ID
amount: <transfer_amount>
}],
claimer: <datahaven_recipient_as_h160>, // 20-byte recipient address
(SCALE-encoded)
message: [], // Empty for native transfers
// ... standard Snowbridge fees
)
```
- **Token Burning**: Gateway burns the wrapped ERC20 tokens on Ethereum
(removing them from circulation)
- **Message Encoding**: Gateway encodes transfer details into
standardized Snowbridge message format
- **Event Emission**: `MessageAccepted` event logged on Ethereum for
relayers to pick up
#### 2. **Cross-Chain Delivery Infrastructure**
- **Relayer Network**: Snowbridge relayers monitor Ethereum events and
submit messages to DataHaven
- **Consensus Verification**: DataHaven's `EthereumBeaconClient` pallet
verifies Ethereum beacon chain consensus
- **Cryptographic Proofs**: Messages include Merkle proofs and execution
receipts for tamper-proof verification
- **Direct Processing**: Relayers submit messages via
`InboundQueueV2::submit()` which processes them immediately
#### 3. **DataHaven Message Processing**
**Immediate Processing Flow:**
When a relayer calls `InboundQueueV2::submit()`, the message is
processed immediately using a tuple-based processor system:
```rust
type MessageProcessor = (
EigenLayerMessageProcessor<Runtime>, // Handles validator operations
NativeTokenTransferMessageProcessor<Runtime>, // Handles native token returns
);
```
**Processing Steps:**
1. **Message Verification**: Cryptographic verification and nonce
checking (prevents replay attacks)
2. **Processor Selection**: Evaluation of processors (First processor
returning `true` handles the message):
- `EigenLayerMessageProcessor::can_process_message()` - returns `false`
for token transfers
- `NativeTokenTransferMessageProcessor::can_process_message()` -
validates:
- Native token is registered via `SnowbridgeSystemV2::register_token()`
(`T::NativeTokenId::get().is_some()`)
- All assets are `ForeignTokenERC20` with matching native token ID
- Assets array is not empty
**Token Unlocking Process:**
1. **Recipient Extraction**: Decodes H160 address from `claimer` field →
converts to DataHaven AccountId (must contain valid SCALE-encoded H160
address)
2. **Sovereign Account Transfer**: Moves tokens from Ethereum sovereign
account to recipient (requires sufficient balance from previous outbound
transfers)
3. **Event Emission**: `TokensUnlocked` event confirms successful
transfer completion
---------
Co-authored-by: Tobi Demeco <50408393+TDemeco@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
This PR integrates the Substrate FRAME Treasury pallet across all three
DataHaven runtime environments (`testnet`, `mainnet`, `stagenet`) with a
custom fee allocation mechanism and comprehensive test coverage.
### Key Changes
#### Treasury Pallet Integration:
- Added Treasury pallet to all three runtimes (testnet, mainnet,
stagenet) with 20% fee allocation and 80% burn mechanism.
- Implemented dynamic fee proportion control via
`FeesTreasuryProportion` runtime parameter.
- Integrated treasury with custom fee handlers:
`DealWithEthereumBaseFees`, `DealWithEthereumPriorityFees`, and
`DealWithSubstrateFeesAndTip`.
#### Comprehensive Testing Infrastructure:
- Created robust test architecture with session management and validator
setup across all runtimes
- Added block author management utilities for treasury testing requiring
pallet_authorship integration
- Implemented 15 total tests (5 tests × 3 runtimes) covering:
- EVM transaction fee allocation with/without priority fees
- Substrate fee and tip handling validation
- Treasury spending functionality via sudo
- Complete fee flow verification with actual network base fee
calculations
#### Technnical Implementation
Fee Allocation Logic:
- Base fees: 20% to treasury, 80% burned
- Priority fees: 100% to block author
- Substrate tips: 100% to block author
The implementation is based on
https://github.com/moonbeam-foundation/moonbeam/pull/3120 in
[Moonbeam](https://github.com/moonbeam-foundation/moonbeam), and
assisted by Claude Code.
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. 🎉
### Summary
- Implement native token transfers from DataHaven to Ethereum using
Snowbridge infrastructure
- Add comprehensive datahaven-native-transfer pallet with lock-and-mint
mechanism for cross-chain token representation
### Key Features
**New Pallet: datahaven-native-transfer**
- Cross-chain transfers: Transfer DataHaven native tokens to Ethereum
addresses via `transfer_to_ethereum extrinsic`
- Token locking mechanism: Secure token storage in deterministic
Ethereum sovereign account during transfers
- Fee management: Required fees for all transfers to compensate relayers
and prevent spam
- Emergency controls: Pause/unpause functionality
- Token registration: Integration with Snowbridge's token registration
for native token identification
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Introduced the DataHaven Native Transfer pallet enabling secure
cross-chain transfers of DataHaven native tokens to and from Ethereum
via Snowbridge.
- Added token locking on DataHaven, minting on Ethereum, and mandatory
fee collection to cover gas costs and incentivize relayers.
- Implemented pause and unpause controls for emergency management of
token transfers.
- **Configuration**
- Integrated the new pallet into mainnet, stagenet, and testnet runtimes
with updated network, account, and treasury settings.
- Added Ethereum sovereign account constants and native token ID support
for optimized cross-chain operations.
- **Documentation**
- Added comprehensive README and inline documentation detailing pallet
features, extrinsics, events, errors, and security considerations.
- **Tests**
- Added extensive unit and integration tests covering token transfers,
native token registration, fee handling, pause functionality, and event
validation across all supported networks.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
This PR fixes a critical issue in which the messages enqueued in the
`MessageQueue` pallet weren't being correctly commited by the
`SnowbridgeOutboundQueueV2` pallet because of a misconfiguration in our
runtimes:
- Before this PR, the `MessageQueue` pallet had a lower index than the
`SnowbridgeOutboundQueueV2` pallet. This means that its `on_initialize`
hook was executed before the `on_initialize` hook of the latter.
- The `MessageQueue` pallets processes messages in its `on_initialize`
hook. In our case, this processing meant calling the
`do_process_message` function of the `SnowbridgeOutboundQueueV2` pallet,
which pushes the message into both its `Messages` and `MessageLeaves`
storage for further processing afterwards, sets a pending order for it
for the relayer and increments the nonce for the next message.
- Then, the `SnowbridgeOutboundQueueV2`'s `on_initialize` hook gets
called, and it completely clears both the `Messages` and `MessageLeaves`
storage to start fresh for the new block. This means it would clear up
the previously processed messages.
- Finally, in the `on_finalize` hook, the messages processed in this
block would get commited from the `MessageLeaves` storage, but since it
would always be empty nothing got commited, which means the Solochain
relayer never found anything to relay and messages weren't getting to
Ethereum.
## This PR includes:
- Running the execution relayer on the CLI
- Modifying the Payload generation in the `DataHavenServiceManager.sol`
- Modified the `EigenLayerMessageProcessor` to work with the
ValidatorSet update message, but for this change we are loosing the
generic message type (it was the only way to make it work so far).
- Adds a `--no-wait` argument to the cli launch and stop commands to
bootstrap faster.
### Testing the Snowbridge message encoding / decoding
- Added`MessageEncoding.t.sol` is documented and explains how to
generate bin data to use in the rust test.
- Added a Rust unit test to `EigenLayerMessageProcessor` to compare the
message encoding/decoding taking the bytes from a file (previously
generated with some mock data).
Specifically, we want that:
3cbca0db6d/contracts/src/libraries/DataHavenSnowbridgeMessages.sol (L78-L85)
Generates the right bytes encoding for
0e2c9cd518/operator/primitives/bridge/src/lib.rs (L51)
If the test passes, it's very likely that the CLI will also pass, if
not, then we might wanna check something else is missing.
### Breaking change ⚠️
For compatibility reasons with Snowbridge contracts (they call specific
extrinsics of specific pallets), I had to rename:
- `InboundQueueV2` -> `EthereumInboundQueueV2`
- `OutboundQueueV2` -> `EthereumOutboundQueueV2`
## For follow up PRs:
- Add an automated way of generating the Solidity bytes fo testing, so
we don't need to maintain the MessageEncoding.t.sol and generate the
binary data manually.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
- **New Features**
- Added support for the "execution" relayer type in relay configuration,
parsing, and CLI launch utilities.
- Introduced a Solidity test contract for encoding and logging validator
set messages.
- Added a comprehensive "start:all" script to streamline launching and
setup processes.
- **Enhancements**
- Improved message encoding for validator set updates, aligning with new
struct field names and message formats.
- Updated relay configuration schema and validation to support execution
relayers and OFAC settings.
- Increased beacon datastore capacity and adjusted relay scheduling
parameters in configuration files.
- **Refactor**
- Renamed runtime type aliases for inbound/outbound queues to more
descriptive names across mainnet, stagenet, and testnet.
- Centralized and streamlined validator set update logic in CLI
utilities.
- Centralized message decoding logic and improved visibility of message
fields in Rust components.
- **Bug Fixes**
- Improved error handling and decoding logic for message processing in
Rust components.
- **Tests**
- Added Rust and Solidity tests for message encoding and processing
validation.
- **Chores**
- Updated dependencies and feature flags in Rust project configuration.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>
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>
This PR replaces `pallet-validator-set` with a new
`pallet-external-validators` pallet from Tanssi.
## Key Changes
- **New ExternalValidators Pallet**
- Supports whitelisted validators (set by governance, not rewarded)
- Manages external validators (can be enabled/disabled)
- Implements era-based rotation (eras change after configurable
sessions)
- **Bridge Integration**
- Updated `EigenLayerMessageProcessor` in
`operator/primitives/bridge/src/lib.rs`
- Replaced the old `SetValidators` command with
```rust
ReceiveValidators { validators, external_index }
```
In this PR:
1. Add [Polkadot API](https://papi.how/) support to `test/` directory
(i.e. the e2e CLI and testing framework) to be able to interact with the
Substrate chain.
1. This allows typed interactions with transactions, constants, storage,
runtime APIs, and non-typed interaction with RPC methods.
2. Types are autogenerated when running `bun i`, from the
`datahaven.scale` file that is part of this repo's version control.
2. Add new utilities file to `papi` related functionalities. For the
time being, generating a new signer from a private key.
3. ~Add a new step to the CLI that sends a transaction to the DataHaven
network. _*THIS SHOULD BE REMOVED SOON, IT'S JUST FOR TESTING
PURPOSES*_~
1. Both steps that send test transactions have been removed from the
CLI, for convenience and being error prone. Their scripts remain usable
for testing purposes if needed.
4. Removes the `apis.rs` files from the runtime definitions. Having them
in a separate file meant that the runtime was not including the Runtime
APIs in the metadata blob, preventing `papi` from creating types from
it. This change can be reapplied after upgrading to `polkadot-sdk`
`stable-2503`. More info
[here](https://github.com/paritytech/polkadot-sdk/issues/6659).
5. Add script to re-generate types, and corresponding docs.
6. Makes logger synchronous to avoid prints happening before logs.
Add support for multiple runtimes: `stagenet`, `testnet` & `mainnet`.
- Moved common types to `datahaven-runtime-common` crate.
- Made the node's command & service code generic over different
runtimes. Each runtime has a `dev` & `local` genesis config preset.
- More types / constants can be moved to the `datahaven-runtime-common`
crate ... this will be done in subsequent PRs.
---------
Co-authored-by: Gonza Montiel <gon.montiel@gmail.com>
Co-authored-by: Gonza Montiel <gonzamontiel@users.noreply.github.com>
Co-authored-by: Facundo Farall <37149322+ffarall@users.noreply.github.com>