Update the 3 DataHaven environments' chain IDs & native token ticker as
follows:
* **Mainnet**
* **Chain ID**: 55930
* **Ticker**: HAVE
* **TestNet**
* **Chain ID**: 55931
* **Ticker**: MOCK
* **Stagenet**
* **Chain ID**: 55932
* **Ticker**: STAGE
The PR includes a storage migration for the Stagenet & Testnet
environments, that are already live, to update the EVM Chain ID stored
in the `pallet-evm-chain-id` pallet.
Note: the token symbol will only be updated with the genesis config
presets or newly generated chain specs. For already live networks, the
existing chain spec must be updated (i.e. the tokenSymbol property
changed) and used by all nodes in the network. This change in the chain
spec will not alter the chain genesis so it safe to do (in the very
early stages of the chain obviously).
---------
Co-authored-by: Claude <noreply@anthropic.com>
(cherry picked from commit a97f0547a9)
Upgrade to SH release
[v0.1.1](https://github.com/Moonsong-Labs/storage-hub/releases/tag/v0.1.1)
---------
Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com>
Co-authored-by: Ahmad Kaouk <ahmadkaouk.93@gmail.com>
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
Following up https://github.com/datahaven-xyz/datahaven/pull/265, we
also need to add Timestamp to the whitelisted Runtime calls.
- [x] Add `RuntimeCall::Timestamp` to `SafeModeWhitelistedCalls`
- [x] Add safe mode test to check it produces blocks
---------
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
### Add missing weights for BABE, GRANDPA, and Randomness
#### Summary
Adds generated weights and wires them into the runtime for the BABE,
GRANDPA, and Randomness pallets to replace defaults and ensure accurate
execution costs across networks.
#### What’s changed
- **New weights added** for `pallet_grandpa`, `pallet_babe` and
`pallet_randomness`
- **Runtime configs updated to use new weights**
- `operator/runtime/mainnet/src/configs/mod.rs`
- `operator/runtime/stagenet/src/configs/mod.rs`
- `operator/runtime/testnet/src/configs/mod.rs`
#### For follow-up PRS
- fix `pallet_identity` failure at running benchmarks
- fix `pallet_collective` benchmarking missmatch (related to
https://github.com/paritytech/polkadot-sdk/pull/6435)
- add `pallet_session_benchmarking` without including `pallet_staking`
(or some workaround)
- add StorageHub weights to our benchmarked pallets (`pallet_nfts`,
`pallet_storage_providers`, `pallet_payment_streams`,
`pallet_proofs_dealer`, `pallet_file_system`, `pallet_bucket_nfts`, etc)
## Summary
- Replace the legacy “estimated transaction length” heuristic in the EVM
`call` runtime API across mainnet, stagenet, and testnet with a direct
`GasWeightMapping::gas_to_weight` lookup. The resulting weight is now
always forwarded to the runner (`Some(weight_limit)`), so zero-gas
requests no longer slip through without a cap.
- Update the EVM `create` runtime API the same way. Previously it always
passed `None` for `weight_limit`, effectively running contract-deploy
dry-runs without any weight ceiling; we now map the gas limit and pass
the explicit weight instead.
- For both `call` and `create`, set the proof-size base cost to `None`
to match our solo-chain assumption that PoV size isn’t budgeted in these
simulated paths.
## Why
We use these runtime APIs when serving `eth_call` and `eth_estimateGas`.
The old behavior meant a zero gas limit (or any `create` dry-run) ran
with unlimited weight, diverging from what the extrinsic path enforces.
Passing the mapped weight—zero included—keeps RPC simulations aligned
with real execution, while dropping the proof-size estimate removes a
guessy value we don’t charge on-chain.
Add defensive validation to ensure the Ethereum sovereign account has
sufficient balance before unlocking tokens. This addresses an audit
finding where the lack of explicit balance checking created an
unreliable security control that depended on implicit runtime behavior.
Changes:
- Add InsufficientSovereignBalance error variant for clear error
messaging
- Add explicit balance check in unlock_tokens before transfer
- Update tests across all runtimes (testnet, stagenet, mainnet) to
validate the specific error is returned when sovereign account has
insufficient funds
The explicit check provides better error messages that can propagate
through the Ethereum bridge and makes debugging sovereign account
balance issues easier.
# Fix: Safe Mode Whitelisted Calls - enable block production
## Problem
The safe mode whitelist was missing critical runtime calls needed for
block production, generating this error:
```
2025-10-29 17:29:48 Proposing failed: Import failed: Extrinsic is not valid: TransactionValidityError::Invalid(InvalidTransaction::BadMandatory)
```
The SafeMode filter needs to include all RuntimeCalls that have
inherents marked as `DispatchClass::Mandatory`, as you can see
[here](bbc435c766/substrate/frame/executive/src/lib.rs (L806)).
If a single inherent is missing the whole block will not be valid,
causing the chain to stall.
## Solution
Bisect all the calls to find the culprit, until find it was the pallet
Randomness. I included it in `SafeModeWhitelistedCalls` and blocks are
being produced in SafeMode.
In this PR we set the slashing mode value in the genesis config. For the
3 different runtime we specify the slashing mode : `mainnet/testnet` is
set to `Disabled` and for `stagenet` to `LogOnly`.
Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com>
## 🔨 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>
# ✨ 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>