From e079cdc40454f5847e20e1c62b1ee98f968ee704 Mon Sep 17 00:00:00 2001 From: Gonza Montiel Date: Thu, 30 Oct 2025 09:38:18 +0100 Subject: [PATCH 01/11] =?UTF-8?q?fix:=20=F0=9F=A9=B9=20add=20mandatory=20e?= =?UTF-8?q?xtrinsics=20to=20safe=20mode=20whitelisted=20calls=20(#265)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # 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](https://github.com/paritytech/polkadot-sdk/blob/bbc435c7667d3283ba280a8fec44676357392753/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. --- operator/runtime/mainnet/src/configs/mod.rs | 4 +++- operator/runtime/stagenet/src/configs/mod.rs | 4 +++- operator/runtime/testnet/src/configs/mod.rs | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/operator/runtime/mainnet/src/configs/mod.rs b/operator/runtime/mainnet/src/configs/mod.rs index 0b8b8a06..3f828e33 100644 --- a/operator/runtime/mainnet/src/configs/mod.rs +++ b/operator/runtime/mainnet/src/configs/mod.rs @@ -236,7 +236,7 @@ impl Contains for NormalCallFilter { } /// Calls that can bypass the safe-mode pallet. -/// These calls are essential for emergency governance and system maintenance. +/// These calls are essential for emergency governance, system maintenance, and basic operation. pub struct SafeModeWhitelistedCalls; impl Contains for SafeModeWhitelistedCalls { fn contains(call: &RuntimeCall) -> bool { @@ -257,6 +257,8 @@ impl Contains for SafeModeWhitelistedCalls { RuntimeCall::Referenda(_) => true, RuntimeCall::TechnicalCommittee(_) => true, RuntimeCall::TreasuryCouncil(_) => true, + // Block production - needed to continue producing blocks in safe mode + RuntimeCall::Randomness(_) => true, _ => false, } } diff --git a/operator/runtime/stagenet/src/configs/mod.rs b/operator/runtime/stagenet/src/configs/mod.rs index f9b31e70..9ab30486 100644 --- a/operator/runtime/stagenet/src/configs/mod.rs +++ b/operator/runtime/stagenet/src/configs/mod.rs @@ -236,7 +236,7 @@ impl Contains for NormalCallFilter { } /// Calls that can bypass the safe-mode pallet. -/// These calls are essential for emergency governance and system maintenance. +/// These calls are essential for emergency governance, system maintenance, and basic operation. pub struct SafeModeWhitelistedCalls; impl Contains for SafeModeWhitelistedCalls { fn contains(call: &RuntimeCall) -> bool { @@ -257,6 +257,8 @@ impl Contains for SafeModeWhitelistedCalls { RuntimeCall::Referenda(_) => true, RuntimeCall::TechnicalCommittee(_) => true, RuntimeCall::TreasuryCouncil(_) => true, + // Block production - needed to continue producing blocks in safe mode + RuntimeCall::Randomness(_) => true, _ => false, } } diff --git a/operator/runtime/testnet/src/configs/mod.rs b/operator/runtime/testnet/src/configs/mod.rs index 7a9dc4b6..5915e31f 100644 --- a/operator/runtime/testnet/src/configs/mod.rs +++ b/operator/runtime/testnet/src/configs/mod.rs @@ -236,7 +236,7 @@ impl Contains for NormalCallFilter { } /// Calls that can bypass the safe-mode pallet. -/// These calls are essential for emergency governance and system maintenance. +/// These calls are essential for emergency governance, system maintenance, and basic operation. pub struct SafeModeWhitelistedCalls; impl Contains for SafeModeWhitelistedCalls { fn contains(call: &RuntimeCall) -> bool { @@ -257,6 +257,8 @@ impl Contains for SafeModeWhitelistedCalls { RuntimeCall::Referenda(_) => true, RuntimeCall::TechnicalCommittee(_) => true, RuntimeCall::TreasuryCouncil(_) => true, + // Block production - needed to continue producing blocks in safe mode + RuntimeCall::Randomness(_) => true, _ => false, } } From 45b5551b2142420a8aa790536c3911afa3f3f02d Mon Sep 17 00:00:00 2001 From: Steve Degosserie <723552+stiiifff@users.noreply.github.com> Date: Thu, 30 Oct 2025 11:30:26 +0200 Subject: [PATCH 02/11] =?UTF-8?q?chore:=20=E2=99=BB=EF=B8=8F=20=20Remove?= =?UTF-8?q?=20unused=20API=20declarations=20in=20Testnet=20runtime=20(#262?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com> --- operator/runtime/testnet/src/apis.rs | 800 --------------------------- 1 file changed, 800 deletions(-) delete mode 100644 operator/runtime/testnet/src/apis.rs diff --git a/operator/runtime/testnet/src/apis.rs b/operator/runtime/testnet/src/apis.rs deleted file mode 100644 index 4487857b..00000000 --- a/operator/runtime/testnet/src/apis.rs +++ /dev/null @@ -1,800 +0,0 @@ -// This is free and unencumbered software released into the public domain. -// -// Anyone is free to copy, modify, publish, use, compile, sell, or -// distribute this software, either in source code form or as a compiled -// binary, for any purpose, commercial or non-commercial, and by any -// means. -// -// In jurisdictions that recognize copyright laws, the author or authors -// of this software dedicate any and all copyright interest in the -// software to the public domain. We make this dedication for the benefit -// of the public at large and to the detriment of our heirs and -// successors. We intend this dedication to be an overt act of -// relinquishment in perpetuity of all present and future rights to this -// software under copyright law. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR -// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -// For more information, please refer to - -// Local module imports -use super::{ - AccountId, Babe, Balance, Beefy, BeefyMmrLeaf, Block, BlockNumber, Ethereum, Executive, - Grandpa, Historical, InherentDataExt, Mmr, Nonce, Runtime, RuntimeCall, RuntimeGenesisConfig, - RuntimeOrigin, SessionKeys, System, TransactionPayment, UncheckedExtrinsic, VERSION, -}; -// External crates imports -use crate::configs::BABE_GENESIS_EPOCH_CONFIG; -use alloc::vec::Vec; -use codec::Encode; -use datahaven_runtime_common::time::EpochDurationInBlocks; -use fp_rpc::TransactionStatus; -use frame_support::traits::OnFinalize; -use pallet_ethereum::Transaction as EthereumTransaction; -use pallet_evm::GasWeightMapping; - -use frame_support::traits::KeyOwnerProofSystem; -use frame_support::{ - genesis_builder_helper::{build_state, get_preset}, - weights::Weight, -}; -use pallet_ethereum::Call::transact; -use pallet_evm::Account as EVMAccount; -use pallet_evm::FeeCalculator; -use pallet_evm::Runner; -use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; -use polkadot_primitives::Hash; -use snowbridge_core::AgentId; -use sp_api::impl_runtime_apis; -use sp_consensus_beefy::{ - ecdsa_crypto::{AuthorityId as BeefyId, Signature as BeefySignature}, - AncestryHelper, -}; -use sp_core::{Get, H256, U256}; -use sp_core::{OpaqueMetadata, H160}; -use sp_runtime::traits::{DispatchInfoOf, Dispatchable, PostDispatchInfoOf}; -use sp_runtime::transaction_validity::TransactionValidityError; -use sp_runtime::{ - traits::Block as BlockT, - transaction_validity::{TransactionSource, TransactionValidity}, - ApplyExtrinsicResult, Permill, -}; -use sp_version::RuntimeVersion; -use xcm::VersionedLocation; -/// MMR helper types. -mod mmr { - use super::Runtime; - pub use pallet_mmr::primitives::*; - - pub type Leaf = <::LeafData as LeafDataProvider>::LeafData; - pub type Hashing = ::Hashing; - pub type Hash = ::Output; -} - -#[derive(Clone)] -pub struct TransactionConverter; - -impl fp_self_contained::SelfContainedCall for RuntimeCall { - type SignedInfo = H160; - - fn is_self_contained(&self) -> bool { - match self { - RuntimeCall::Ethereum(call) => call.is_self_contained(), - _ => false, - } - } - - fn check_self_contained(&self) -> Option> { - match self { - RuntimeCall::Ethereum(call) => call.check_self_contained(), - _ => None, - } - } - - fn validate_self_contained( - &self, - signed_info: &Self::SignedInfo, - dispatch_info: &DispatchInfoOf, - len: usize, - ) -> Option { - match self { - RuntimeCall::Ethereum(call) => { - call.validate_self_contained(signed_info, dispatch_info, len) - } - _ => None, - } - } - - fn pre_dispatch_self_contained( - &self, - info: &Self::SignedInfo, - dispatch_info: &DispatchInfoOf, - len: usize, - ) -> Option> { - match self { - RuntimeCall::Ethereum(call) => { - call.pre_dispatch_self_contained(info, dispatch_info, len) - } - _ => None, - } - } - - fn apply_self_contained( - self, - info: Self::SignedInfo, - ) -> Option>> { - match self { - call @ RuntimeCall::Ethereum(pallet_ethereum::Call::transact { .. }) => { - Some(call.dispatch(RuntimeOrigin::from( - pallet_ethereum::RawOrigin::EthereumTransaction(info), - ))) - } - _ => None, - } - } -} - -impl fp_rpc::ConvertTransaction for TransactionConverter { - fn convert_transaction(&self, transaction: pallet_ethereum::Transaction) -> UncheckedExtrinsic { - UncheckedExtrinsic::new_bare( - pallet_ethereum::Call::::transact { transaction }.into(), - ) - } -} - -impl_runtime_apis! { - impl sp_api::Core for Runtime { - fn version() -> RuntimeVersion { - VERSION - } - - fn execute_block(block: Block) { - Executive::execute_block(block); - } - - fn initialize_block(header: &::Header) -> sp_runtime::ExtrinsicInclusionMode { - Executive::initialize_block(header) - } - } - - impl sp_api::Metadata for Runtime { - fn metadata() -> OpaqueMetadata { - OpaqueMetadata::new(Runtime::metadata().into()) - } - - fn metadata_at_version(version: u32) -> Option { - Runtime::metadata_at_version(version) - } - - fn metadata_versions() -> Vec { - Runtime::metadata_versions() - } - } - - impl sp_block_builder::BlockBuilder for Runtime { - fn apply_extrinsic(extrinsic: ::Extrinsic) -> ApplyExtrinsicResult { - Executive::apply_extrinsic(extrinsic) - } - - fn finalize_block() -> ::Header { - Executive::finalize_block() - } - - fn inherent_extrinsics(data: sp_inherents::InherentData) -> Vec<::Extrinsic> { - data.create_extrinsics() - } - - fn check_inherents( - block: Block, - data: sp_inherents::InherentData, - ) -> sp_inherents::CheckInherentsResult { - data.check_extrinsics(&block) - } - } - - impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime { - fn validate_transaction( - source: TransactionSource, - tx: ::Extrinsic, - block_hash: ::Hash, - ) -> TransactionValidity { - Executive::validate_transaction(source, tx, block_hash) - } - } - - impl sp_offchain::OffchainWorkerApi for Runtime { - fn offchain_worker(header: &::Header) { - Executive::offchain_worker(header) - } - } - - impl sp_session::SessionKeys for Runtime { - fn generate_session_keys(seed: Option>) -> Vec { - SessionKeys::generate(seed) - } - - fn decode_session_keys( - encoded: Vec, - ) -> Option, sp_core::crypto::KeyTypeId)>> { - SessionKeys::decode_into_raw_public_keys(&encoded) - } - } - - impl sp_consensus_babe::BabeApi for Runtime { - fn configuration() -> sp_consensus_babe::BabeConfiguration { - let epoch_config = Babe::epoch_config().unwrap_or(BABE_GENESIS_EPOCH_CONFIG); - sp_consensus_babe::BabeConfiguration { - slot_duration: Babe::slot_duration(), - epoch_length: EpochDurationInBlocks::get().into(), - c: epoch_config.c, - authorities: Babe::authorities().to_vec(), - randomness: Babe::randomness(), - allowed_slots: epoch_config.allowed_slots, - } - } - - fn current_epoch_start() -> sp_consensus_babe::Slot { - Babe::current_epoch_start() - } - - fn current_epoch() -> sp_consensus_babe::Epoch { - Babe::current_epoch() - } - - fn next_epoch() -> sp_consensus_babe::Epoch { - Babe::next_epoch() - } - - fn generate_key_ownership_proof( - _slot: sp_consensus_babe::Slot, - authority_id: sp_consensus_babe::AuthorityId, - ) -> Option { - use codec::Encode; - - Historical::prove((sp_consensus_babe::KEY_TYPE, authority_id)) - .map(|p| p.encode()) - .map(sp_consensus_babe::OpaqueKeyOwnershipProof::new) - } - - fn submit_report_equivocation_unsigned_extrinsic( - equivocation_proof: sp_consensus_babe::EquivocationProof<::Header>, - key_owner_proof: sp_consensus_babe::OpaqueKeyOwnershipProof, - ) -> Option<()> { - let key_owner_proof = key_owner_proof.decode()?; - - Babe::submit_unsigned_equivocation_report( - equivocation_proof, - key_owner_proof, - ) - } - } - - impl sp_consensus_grandpa::GrandpaApi for Runtime { - fn grandpa_authorities() -> Vec<(GrandpaId, u64)> { - Grandpa::grandpa_authorities() - } - - fn current_set_id() -> fg_primitives::SetId { - Grandpa::current_set_id() - } - - fn submit_report_equivocation_unsigned_extrinsic( - equivocation_proof: fg_primitives::EquivocationProof< - ::Hash, - sp_runtime::traits::NumberFor, - >, - key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof, - ) -> Option<()> { - let key_owner_proof = key_owner_proof.decode()?; - - Grandpa::submit_unsigned_equivocation_report( - equivocation_proof, - key_owner_proof, - ) - } - - fn generate_key_ownership_proof( - _set_id: fg_primitives::SetId, - authority_id: fg_primitives::AuthorityId, - ) -> Option { - - Historical::prove((fg_primitives::KEY_TYPE, authority_id)) - .map(|p| p.encode()) - .map(fg_primitives::OpaqueKeyOwnershipProof::new) - } - } - - #[api_version(2)] - impl mmr::MmrApi for Runtime { - fn mmr_root() -> Result { - Ok(pallet_mmr::RootHash::::get()) - } - - fn mmr_leaf_count() -> Result { - Ok(pallet_mmr::NumberOfLeaves::::get()) - } - - fn generate_proof( - block_numbers: Vec, - best_known_block_number: Option, - ) -> Result<(Vec, mmr::LeafProof), mmr::Error> { - Mmr::generate_proof(block_numbers, best_known_block_number).map( - |(leaves, proof)| { - ( - leaves - .into_iter() - .map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf)) - .collect(), - proof, - ) - }, - ) - } - - fn verify_proof(leaves: Vec, proof: mmr::LeafProof) - -> Result<(), mmr::Error> - { - let leaves = leaves.into_iter().map(|leaf| - leaf.into_opaque_leaf() - .try_decode() - .ok_or(mmr::Error::Verify)).collect::, mmr::Error>>()?; - Mmr::verify_leaves(leaves, proof) - } - - fn verify_proof_stateless( - root: mmr::Hash, - leaves: Vec, - proof: mmr::LeafProof - ) -> Result<(), mmr::Error> { - let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect(); - pallet_mmr::verify_leaves_proof::(root, nodes, proof) - } - } - - impl pallet_beefy_mmr::BeefyMmrApi for RuntimeApi { - fn authority_set_proof() -> sp_consensus_beefy::mmr::BeefyAuthoritySet { - BeefyMmrLeaf::authority_set_proof() - } - - fn next_authority_set_proof() -> sp_consensus_beefy::mmr::BeefyNextAuthoritySet { - BeefyMmrLeaf::next_authority_set_proof() - } - } - - #[api_version(5)] - impl sp_consensus_beefy::BeefyApi for Runtime { - fn beefy_genesis() -> Option { - pallet_beefy::GenesisBlock::::get() - } - - fn validator_set() -> Option> { - Beefy::validator_set() - } - - fn submit_report_double_voting_unsigned_extrinsic( - equivocation_proof: sp_consensus_beefy::DoubleVotingProof< - BlockNumber, - BeefyId, - BeefySignature, - >, - key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, - ) -> Option<()> { - let key_owner_proof = key_owner_proof.decode()?; - - Beefy::submit_unsigned_double_voting_report( - equivocation_proof, - key_owner_proof, - ) - } - - fn submit_report_fork_voting_unsigned_extrinsic( - equivocation_proof: - sp_consensus_beefy::ForkVotingProof< - ::Header, - BeefyId, - sp_runtime::OpaqueValue - >, - key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, - ) -> Option<()> { - Beefy::submit_unsigned_fork_voting_report( - equivocation_proof.try_into()?, - key_owner_proof.decode()?, - ) - } - - fn submit_report_future_block_voting_unsigned_extrinsic( - equivocation_proof: sp_consensus_beefy::FutureBlockVotingProof, - key_owner_proof: sp_consensus_beefy::OpaqueKeyOwnershipProof, - ) -> Option<()> { - Beefy::submit_unsigned_future_block_voting_report( - equivocation_proof, - key_owner_proof.decode()?, - ) - } - - fn generate_key_ownership_proof( - _set_id: sp_consensus_beefy::ValidatorSetId, - authority_id: BeefyId, - ) -> Option { - Historical::prove((sp_consensus_beefy::KEY_TYPE, authority_id)) - .map(|p| p.encode()) - .map(sp_consensus_beefy::OpaqueKeyOwnershipProof::new) - } - - fn generate_ancestry_proof( - prev_block_number: BlockNumber, - best_known_block_number: Option, - ) -> Option { - use codec::Encode; - - BeefyMmrLeaf::generate_proof(prev_block_number, best_known_block_number) - .map(|p| p.encode()) - .map(sp_runtime::OpaqueValue::new) - } - } - - impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { - fn account_nonce(account: AccountId) -> Nonce { - System::account_nonce(account) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi for Runtime { - fn query_info( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo { - TransactionPayment::query_info(uxt, len) - } - fn query_fee_details( - uxt: ::Extrinsic, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_fee_details(uxt, len) - } - fn query_weight_to_fee(weight: Weight) -> Balance { - TransactionPayment::weight_to_fee(weight) - } - fn query_length_to_fee(length: u32) -> Balance { - TransactionPayment::length_to_fee(length) - } - } - - impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi - for Runtime - { - fn query_call_info( - call: RuntimeCall, - len: u32, - ) -> pallet_transaction_payment::RuntimeDispatchInfo { - TransactionPayment::query_call_info(call, len) - } - fn query_call_fee_details( - call: RuntimeCall, - len: u32, - ) -> pallet_transaction_payment::FeeDetails { - TransactionPayment::query_call_fee_details(call, len) - } - fn query_weight_to_fee(weight: Weight) -> Balance { - TransactionPayment::weight_to_fee(weight) - } - fn query_length_to_fee(length: u32) -> Balance { - TransactionPayment::length_to_fee(length) - } - } - - impl snowbridge_outbound_queue_v2_runtime_api::OutboundQueueV2Api for Runtime { - fn prove_message(leaf_index: u64) -> Option { - snowbridge_pallet_outbound_queue_v2::api::prove_message::(leaf_index) - } - } - - impl snowbridge_system_v2_runtime_api::ControlV2Api for Runtime { - fn agent_id(location: VersionedLocation) -> Option { - snowbridge_pallet_system_v2::api::agent_id::(location) - } - } - - #[cfg(feature = "runtime-benchmarks")] - impl frame_benchmarking::Benchmark for Runtime { - fn benchmark_metadata(extra: bool) -> ( - Vec, - Vec, - ) { - use frame_benchmarking::{baseline, Benchmarking, BenchmarkList}; - use frame_support::traits::StorageInfoTrait; - use frame_system_benchmarking::Pallet as SystemBench; - use baseline::Pallet as BaselineBench; - use super::*; - - let mut list = Vec::::new(); - list_benchmarks!(list, extra); - - let storage_info = AllPalletsWithSystem::storage_info(); - - (list, storage_info) - } - - #[expect(non_local_definitions)] - fn dispatch_benchmark( - config: frame_benchmarking::BenchmarkConfig - ) -> Result, alloc::string::String> { - use frame_benchmarking::{baseline, Benchmarking, BenchmarkBatch}; - use sp_storage::TrackedStorageKey; - use frame_system_benchmarking::Pallet as SystemBench; - use baseline::Pallet as BaselineBench; - use super::*; - - impl frame_system_benchmarking::Config for Runtime {} - impl baseline::Config for Runtime {} - - use frame_support::traits::WhitelistedStorageKeys; - let whitelist: Vec = AllPalletsWithSystem::whitelisted_storage_keys(); - - let mut batches = Vec::::new(); - let params = (&config, &whitelist); - add_benchmarks!(params, batches); - - Ok(batches) - } - } - - #[cfg(feature = "try-runtime")] - impl frame_try_runtime::TryRuntime for Runtime { - fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { - // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to - // have a backtrace here. If any of the pre/post migration checks fail, we shall stop - // right here and right now. - let weight = Executive::try_runtime_upgrade(checks).unwrap(); - (weight, super::configs::RuntimeBlockWeights::get().max_block) - } - - fn execute_block( - block: Block, - state_root_check: bool, - signature_check: bool, - select: frame_try_runtime::TryStateSelect - ) -> Weight { - // NOTE: intentional unwrap: we don't want to propagate the error backwards, and want to - // have a backtrace here. - Executive::try_execute_block(block, state_root_check, signature_check, select).expect("execute-block failed") - } - } - - impl sp_genesis_builder::GenesisBuilder for Runtime { - fn build_state(config: Vec) -> sp_genesis_builder::Result { - build_state::(config) - } - - fn get_preset(id: &Option) -> Option> { - get_preset::(id, crate::genesis_config_presets::get_preset) - } - - fn preset_names() -> Vec { - crate::genesis_config_presets::preset_names() - } - } - - impl fp_rpc::EthereumRuntimeRPCApi for Runtime { - fn chain_id() -> u64 { - ::ChainId::get() - } - - fn account_basic(address: H160) -> EVMAccount { - let (account, _) = pallet_evm::Pallet::::account_basic(&address); - account - } - - fn gas_price() -> U256 { - let (gas_price, _) = ::FeeCalculator::min_gas_price(); - gas_price - } - - fn account_code_at(address: H160) -> Vec { - pallet_evm::AccountCodes::::get(address) - } - - fn author() -> H160 { - >::find_author() - } - - fn storage_at(address: H160, index: U256) -> H256 { - let tmp = index.to_big_endian(); - pallet_evm::AccountStorages::::get(address, H256::from_slice(&tmp[..])) - } - - fn call( - from: H160, - to: H160, - data: Vec, - value: U256, - gas_limit: U256, - max_fee_per_gas: Option, - max_priority_fee_per_gas: Option, - nonce: Option, - estimate: bool, - access_list: Option)>>, - ) -> Result { - let config = if estimate { - let mut config = ::config().clone(); - config.estimate = true; - Some(config) - } else { - None - }; - let is_transactional = false; - let validate = true; - - // Estimated encoded transaction size must be based on the heaviest transaction - // type (EIP1559Transaction) to be compatible with all transaction types. - let mut estimated_transaction_len = data.len() + - // pallet ethereum index: 1 - // transact call index: 1 - // Transaction enum variant: 1 - // chain_id 8 bytes - // nonce: 32 - // max_priority_fee_per_gas: 32 - // max_fee_per_gas: 32 - // gas_limit: 32 - // action: 21 (enum varianrt + call address) - // value: 32 - // access_list: 1 (empty vec size) - // 65 bytes signature - 258; - - if access_list.is_some() { - estimated_transaction_len += access_list.encoded_size(); - } - - let gas_limit = gas_limit.min(u64::MAX.into()).low_u64(); - let without_base_extrinsic_weight = true; - - let (weight_limit, proof_size_base_cost) = - match ::GasWeightMapping::gas_to_weight( - gas_limit, - without_base_extrinsic_weight - ) { - weight_limit if weight_limit.proof_size() > 0 => { - (Some(weight_limit), Some(estimated_transaction_len as u64)) - } - _ => (None, None), - }; - - ::Runner::call( - from, - to, - data, - value, - gas_limit, - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list.unwrap_or_default(), - is_transactional, - validate, - weight_limit, - proof_size_base_cost, - config.as_ref().unwrap_or(::config()), - ).map_err(|err| err.error.into()) - } - - fn create( - from: H160, - data: Vec, - value: U256, - gas_limit: U256, - max_fee_per_gas: Option, - max_priority_fee_per_gas: Option, - nonce: Option, - estimate: bool, - access_list: Option)>>, - ) -> Result { - let config = if estimate { - let mut config = ::config().clone(); - config.estimate = true; - Some(config) - } else { - None - }; - let is_transactional = false; - let validate = true; - - let gas_limit = if gas_limit > U256::from(u64::MAX) { - u64::MAX - } else { - gas_limit.low_u64() - }; - - let (weight_limit, proof_size_base_cost) = (None, None); - - #[allow(clippy::or_fun_call)] - ::Runner::create( - from, - data, - value, - gas_limit, - max_fee_per_gas, - max_priority_fee_per_gas, - nonce, - access_list.unwrap_or_default(), - is_transactional, - validate, - weight_limit, - proof_size_base_cost, - config.as_ref().unwrap_or(::config()), - ).map_err(|err| err.error.into()) - } - - fn current_transaction_statuses() -> Option> { - pallet_ethereum::CurrentTransactionStatuses::::get() - } - - fn current_block() -> Option { - pallet_ethereum::CurrentBlock::::get() - } - - fn current_receipts() -> Option> { - pallet_ethereum::CurrentReceipts::::get() - } - - fn current_all() -> ( - Option, - Option>, - Option>, - ) { - ( - pallet_ethereum::CurrentBlock::::get(), - pallet_ethereum::CurrentReceipts::::get(), - pallet_ethereum::CurrentTransactionStatuses::::get() - ) - } - - fn extrinsic_filter( - xts: Vec<::Extrinsic>, - ) -> Vec { - xts.into_iter().filter_map(|xt| match xt.0.function { - RuntimeCall::Ethereum(transact { transaction }) => Some(transaction), - _ => None - }).collect::>() - } - - fn elasticity() -> Option { - None - } - - fn gas_limit_multiplier_support() {} - - fn pending_block( - xts: Vec<::Extrinsic>, - ) -> (Option, Option>) { - for ext in xts.into_iter() { - let _ = Executive::apply_extrinsic(ext); - } - - Ethereum::on_finalize(System::block_number() + 1); - - ( - pallet_ethereum::CurrentBlock::::get(), - pallet_ethereum::CurrentTransactionStatuses::::get() - ) - } - - fn initialize_pending_block(header: &::Header) { - Executive::initialize_block(header); - } - } - - impl fp_rpc::ConvertTransactionRuntimeApi for Runtime { - fn convert_transaction(transaction: EthereumTransaction) -> ::Extrinsic { - UncheckedExtrinsic::new_bare( - pallet_ethereum::Call::::transact { transaction }.into(), - ) - } - } -} From 839fe6399f7a7d8e398e106a250a6e51cfb0c213 Mon Sep 17 00:00:00 2001 From: Steve Degosserie <723552+stiiifff@users.noreply.github.com> Date: Thu, 30 Oct 2025 12:10:11 +0200 Subject: [PATCH 03/11] =?UTF-8?q?fix:=20=F0=9F=94=A7=20Fix=20datahaven-dev?= =?UTF-8?q?.Dockerfile=20uid=20issue=20(1000=20is=20ubuntu=20user)=20(#261?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Gonza Montiel Co-authored-by: undercover-cactus Co-authored-by: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com> --- docker/datahaven-dev.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/datahaven-dev.Dockerfile b/docker/datahaven-dev.Dockerfile index cc758c1d..06753777 100644 --- a/docker/datahaven-dev.Dockerfile +++ b/docker/datahaven-dev.Dockerfile @@ -46,7 +46,7 @@ RUN apt-get update && \ find /var/lib/apt/lists/ -type f -not -name lock -delete # Create datahaven user and directories -RUN useradd -m -u 1000 -U -s /bin/sh -d /datahaven datahaven && \ +RUN useradd -m -u 1001 -U -s /bin/sh -d /datahaven datahaven && \ mkdir -p /data /datahaven/.local/share /specs /storage && \ chown -R datahaven:datahaven /data /storage && \ ln -s /data /datahaven/.local/share/datahaven-node From 2f6c6e39c2d210ed1fe206330de324eaf07bb323 Mon Sep 17 00:00:00 2001 From: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com> Date: Thu, 30 Oct 2025 12:19:14 +0100 Subject: [PATCH 04/11] fix: add explicit sovereign account balance check in unlock_tokens (#253) 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. --- .../datahaven-native-transfer/src/lib.rs | 22 ++++++++++----- .../datahaven-native-transfer/src/tests.rs | 26 ++++++++++++++++-- .../mainnet/tests/native_token_transfer.rs | 7 +++-- .../stagenet/tests/native_token_transfer.rs | 7 +++-- .../testnet/tests/native_token_transfer.rs | 7 +++-- test/.papi/descriptors/package.json | 2 +- test/.papi/metadata/datahaven.scale | Bin 620948 -> 621031 bytes 7 files changed, 51 insertions(+), 20 deletions(-) diff --git a/operator/pallets/datahaven-native-transfer/src/lib.rs b/operator/pallets/datahaven-native-transfer/src/lib.rs index 11069a43..01f2f998 100644 --- a/operator/pallets/datahaven-native-transfer/src/lib.rs +++ b/operator/pallets/datahaven-native-transfer/src/lib.rs @@ -26,7 +26,7 @@ use frame_support::{ use snowbridge_core::TokenId; use snowbridge_outbound_queue_primitives::v2::{Command, Message as OutboundMessage, SendMessage}; use sp_core::{H160, H256}; -use sp_runtime::BoundedVec; +use sp_runtime::{traits::Saturating, BoundedVec}; use sp_std::vec; pub use pallet::*; @@ -135,6 +135,8 @@ pub mod pallet { ZeroFee, /// Native token has not been registered on Ethereum yet TokenNotRegistered, + /// Insufficient balance in Ethereum sovereign account + InsufficientSovereignBalance, } #[pallet::call] @@ -275,13 +277,19 @@ pub mod pallet { /// /// Transfers tokens from the Ethereum sovereign account back to user pub fn unlock_tokens(who: &T::AccountId, amount: BalanceOf) -> DispatchResult { + let sovereign = T::EthereumSovereignAccount::get(); + let balance = T::Currency::balance(&sovereign); + let minimum_balance = T::Currency::minimum_balance(); + let available_balance = balance.saturating_sub(minimum_balance); + + // Allow unlocking only from funds that exceed the existential buffer. + ensure!( + available_balance >= amount, + Error::::InsufficientSovereignBalance + ); + // Transfer from the Ethereum sovereign account - T::Currency::transfer( - &T::EthereumSovereignAccount::get(), - who, - amount, - Preservation::Preserve, - )?; + T::Currency::transfer(&sovereign, who, amount, Preservation::Preserve)?; Self::deposit_event(Event::TokensUnlocked { account: who.clone(), diff --git a/operator/pallets/datahaven-native-transfer/src/tests.rs b/operator/pallets/datahaven-native-transfer/src/tests.rs index 6ccad384..da460c3b 100644 --- a/operator/pallets/datahaven-native-transfer/src/tests.rs +++ b/operator/pallets/datahaven-native-transfer/src/tests.rs @@ -243,7 +243,10 @@ fn unlock_tokens_works() { )); assert_eq!(Balances::balance(&BOB), INITIAL_BALANCE + unlock_amount); - assert_eq!(Balances::balance(ÐEREUM_SOVEREIGN), 1); // Existential deposit remains + assert_eq!( + Balances::balance(ÐEREUM_SOVEREIGN), + Balances::minimum_balance() + ); // Existential deposit remains // Check event assert_eq!( @@ -262,7 +265,21 @@ fn unlock_insufficient_sovereign_balance_fails() { // Try to unlock without any locked tokens assert_noop!( DataHavenNativeTransfer::::unlock_tokens(&BOB, 1000), - DispatchError::Token(sp_runtime::TokenError::FundsUnavailable) + Error::::InsufficientSovereignBalance + ); + }); +} + +#[test] +fn unlock_fails_if_existential_deposit_would_be_consumed() { + new_test_ext().execute_with(|| { + let amount = 10u128; + assert_ok!(DataHavenNativeTransfer::::lock_tokens(&ALICE, amount)); + + // Attempt to withdraw the full sovereign balance, which should leave the account below ED + assert_noop!( + DataHavenNativeTransfer::::unlock_tokens(&BOB, amount), + Error::::InsufficientSovereignBalance ); }); } @@ -283,7 +300,10 @@ fn lock_unlock_different_amounts() { &CHARLIE, 2999 )); - assert_eq!(Balances::balance(ÐEREUM_SOVEREIGN), 1); // Existential deposit remains + assert_eq!( + Balances::balance(ÐEREUM_SOVEREIGN), + Balances::minimum_balance() + ); // Existential deposit remains assert_eq!(Balances::balance(&BOB), INITIAL_BALANCE + 2000); assert_eq!(Balances::balance(&CHARLIE), INITIAL_BALANCE + 2999); }); diff --git a/operator/runtime/mainnet/tests/native_token_transfer.rs b/operator/runtime/mainnet/tests/native_token_transfer.rs index 407f83dd..7739b282 100644 --- a/operator/runtime/mainnet/tests/native_token_transfer.rs +++ b/operator/runtime/mainnet/tests/native_token_transfer.rs @@ -374,9 +374,10 @@ fn processing_fails_with_insufficient_sovereign_balance() { setup_sovereign_balance(TRANSFER_AMOUNT / 2); // Insufficient balance - let result = - snowbridge_pallet_inbound_queue_v2::Pallet::::process_message(alice, message); - assert!(result.is_err()); + assert_noop!( + snowbridge_pallet_inbound_queue_v2::Pallet::::process_message(alice, message), + pallet_datahaven_native_transfer::Error::::InsufficientSovereignBalance + ); }); } diff --git a/operator/runtime/stagenet/tests/native_token_transfer.rs b/operator/runtime/stagenet/tests/native_token_transfer.rs index de352f6c..6b96bd88 100644 --- a/operator/runtime/stagenet/tests/native_token_transfer.rs +++ b/operator/runtime/stagenet/tests/native_token_transfer.rs @@ -361,9 +361,10 @@ fn processing_fails_with_insufficient_sovereign_balance() { setup_sovereign_balance(TRANSFER_AMOUNT / 2); // Insufficient balance - let result = - snowbridge_pallet_inbound_queue_v2::Pallet::::process_message(alice, message); - assert!(result.is_err()); + assert_noop!( + snowbridge_pallet_inbound_queue_v2::Pallet::::process_message(alice, message), + pallet_datahaven_native_transfer::Error::::InsufficientSovereignBalance + ); }); } diff --git a/operator/runtime/testnet/tests/native_token_transfer.rs b/operator/runtime/testnet/tests/native_token_transfer.rs index e02fe707..6d5b4234 100644 --- a/operator/runtime/testnet/tests/native_token_transfer.rs +++ b/operator/runtime/testnet/tests/native_token_transfer.rs @@ -361,9 +361,10 @@ fn processing_fails_with_insufficient_sovereign_balance() { setup_sovereign_balance(TRANSFER_AMOUNT / 2); // Insufficient balance - let result = - snowbridge_pallet_inbound_queue_v2::Pallet::::process_message(alice, message); - assert!(result.is_err()); + assert_noop!( + snowbridge_pallet_inbound_queue_v2::Pallet::::process_message(alice, message), + pallet_datahaven_native_transfer::Error::::InsufficientSovereignBalance + ); }); } diff --git a/test/.papi/descriptors/package.json b/test/.papi/descriptors/package.json index 5e04bf6c..f91b756b 100644 --- a/test/.papi/descriptors/package.json +++ b/test/.papi/descriptors/package.json @@ -1,5 +1,5 @@ { - "version": "0.1.0-autogenerated.12568285267841290320", + "version": "0.1.0-autogenerated.2256885919410986602", "name": "@polkadot-api/descriptors", "files": [ "dist" diff --git a/test/.papi/metadata/datahaven.scale b/test/.papi/metadata/datahaven.scale index 2ea69d167bcc542528f4cda5087b32180dc4c38d..4d9188cb45be272e52dc6c5a1ce4257cbfb1dfff 100644 GIT binary patch delta 135 zcmbR8S@rp6)rJFEi69|F{*6;b%>>xF}T1puedZVEi*YYHLoN%zbv&VH8VZW zDKRH8FFBQggXILWyh0L0Tp=@0!L=j1)rJFEi69|F)D2Tb%>>xacUupQv07HEI`Z(#B4y!zWvV;j@MfN DdVU$x From 0b636e0d7986981d4b2ad54468156d5b20d4f1fa Mon Sep 17 00:00:00 2001 From: Ahmad Kaouk <56095276+ahmadkaouk@users.noreply.github.com> Date: Thu, 30 Oct 2025 16:09:15 +0100 Subject: [PATCH 05/11] fix: Fix EVM gas-to-weight handling for call/create (#266) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 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. --- operator/runtime/mainnet/src/lib.rs | 49 +++++-------------- operator/runtime/stagenet/src/lib.rs | 49 +++++-------------- operator/runtime/testnet/src/lib.rs | 49 +++++-------------- .../test-contract/test-contract-creation.ts | 9 ++-- 4 files changed, 42 insertions(+), 114 deletions(-) diff --git a/operator/runtime/mainnet/src/lib.rs b/operator/runtime/mainnet/src/lib.rs index acce1e7c..359a6174 100644 --- a/operator/runtime/mainnet/src/lib.rs +++ b/operator/runtime/mainnet/src/lib.rs @@ -1062,40 +1062,13 @@ impl_runtime_apis! { let is_transactional = false; let validate = true; - // Estimated encoded transaction size must be based on the heaviest transaction - // type (EIP1559Transaction) to be compatible with all transaction types. - let mut estimated_transaction_len = data.len() + - // pallet ethereum index: 1 - // transact call index: 1 - // Transaction enum variant: 1 - // chain_id 8 bytes - // nonce: 32 - // max_priority_fee_per_gas: 32 - // max_fee_per_gas: 32 - // gas_limit: 32 - // action: 21 (enum varianrt + call address) - // value: 32 - // access_list: 1 (empty vec size) - // 65 bytes signature - 258; - - if access_list.is_some() { - estimated_transaction_len += access_list.encoded_size(); - } - let gas_limit = gas_limit.min(u64::MAX.into()).low_u64(); let without_base_extrinsic_weight = true; - let (weight_limit, proof_size_base_cost) = - match ::GasWeightMapping::gas_to_weight( - gas_limit, - without_base_extrinsic_weight - ) { - weight_limit if weight_limit.proof_size() > 0 => { - (Some(weight_limit), Some(estimated_transaction_len as u64)) - } - _ => (None, None), - }; + let weight_limit = ::GasWeightMapping::gas_to_weight( + gas_limit, + without_base_extrinsic_weight + ); ::Runner::call( from, @@ -1109,8 +1082,8 @@ impl_runtime_apis! { access_list.unwrap_or_default(), is_transactional, validate, - weight_limit, - proof_size_base_cost, + Some(weight_limit), + None, config.as_ref().unwrap_or(::config()), ).map_err(|err| err.error.into()) } @@ -1142,7 +1115,11 @@ impl_runtime_apis! { gas_limit.low_u64() }; - let (weight_limit, proof_size_base_cost) = (None, None); + let without_base_extrinsic_weight = true; + let weight_limit = ::GasWeightMapping::gas_to_weight( + gas_limit, + without_base_extrinsic_weight + ); #[allow(clippy::or_fun_call)] ::Runner::create( @@ -1156,8 +1133,8 @@ impl_runtime_apis! { access_list.unwrap_or_default(), is_transactional, validate, - weight_limit, - proof_size_base_cost, + Some(weight_limit), + None, config.as_ref().unwrap_or(::config()), ).map_err(|err| err.error.into()) } diff --git a/operator/runtime/stagenet/src/lib.rs b/operator/runtime/stagenet/src/lib.rs index d42e72c2..b86a2072 100644 --- a/operator/runtime/stagenet/src/lib.rs +++ b/operator/runtime/stagenet/src/lib.rs @@ -1064,40 +1064,13 @@ impl_runtime_apis! { let is_transactional = false; let validate = true; - // Estimated encoded transaction size must be based on the heaviest transaction - // type (EIP1559Transaction) to be compatible with all transaction types. - let mut estimated_transaction_len = data.len() + - // pallet ethereum index: 1 - // transact call index: 1 - // Transaction enum variant: 1 - // chain_id 8 bytes - // nonce: 32 - // max_priority_fee_per_gas: 32 - // max_fee_per_gas: 32 - // gas_limit: 32 - // action: 21 (enum varianrt + call address) - // value: 32 - // access_list: 1 (empty vec size) - // 65 bytes signature - 258; - - if access_list.is_some() { - estimated_transaction_len += access_list.encoded_size(); - } - let gas_limit = gas_limit.min(u64::MAX.into()).low_u64(); let without_base_extrinsic_weight = true; - let (weight_limit, proof_size_base_cost) = - match ::GasWeightMapping::gas_to_weight( - gas_limit, - without_base_extrinsic_weight - ) { - weight_limit if weight_limit.proof_size() > 0 => { - (Some(weight_limit), Some(estimated_transaction_len as u64)) - } - _ => (None, None), - }; + let weight_limit = ::GasWeightMapping::gas_to_weight( + gas_limit, + without_base_extrinsic_weight + ); ::Runner::call( from, @@ -1111,8 +1084,8 @@ impl_runtime_apis! { access_list.unwrap_or_default(), is_transactional, validate, - weight_limit, - proof_size_base_cost, + Some(weight_limit), + None, config.as_ref().unwrap_or(::config()), ).map_err(|err| err.error.into()) } @@ -1144,7 +1117,11 @@ impl_runtime_apis! { gas_limit.low_u64() }; - let (weight_limit, proof_size_base_cost) = (None, None); + let without_base_extrinsic_weight = true; + let weight_limit = ::GasWeightMapping::gas_to_weight( + gas_limit, + without_base_extrinsic_weight + ); #[allow(clippy::or_fun_call)] ::Runner::create( @@ -1158,8 +1135,8 @@ impl_runtime_apis! { access_list.unwrap_or_default(), is_transactional, validate, - weight_limit, - proof_size_base_cost, + Some(weight_limit), + None, config.as_ref().unwrap_or(::config()), ).map_err(|err| err.error.into()) } diff --git a/operator/runtime/testnet/src/lib.rs b/operator/runtime/testnet/src/lib.rs index 8bfca25b..1899a883 100644 --- a/operator/runtime/testnet/src/lib.rs +++ b/operator/runtime/testnet/src/lib.rs @@ -1061,40 +1061,13 @@ impl_runtime_apis! { let is_transactional = false; let validate = true; - // Estimated encoded transaction size must be based on the heaviest transaction - // type (EIP1559Transaction) to be compatible with all transaction types. - let mut estimated_transaction_len = data.len() + - // pallet ethereum index: 1 - // transact call index: 1 - // Transaction enum variant: 1 - // chain_id 8 bytes - // nonce: 32 - // max_priority_fee_per_gas: 32 - // max_fee_per_gas: 32 - // gas_limit: 32 - // action: 21 (enum varianrt + call address) - // value: 32 - // access_list: 1 (empty vec size) - // 65 bytes signature - 258; - - if access_list.is_some() { - estimated_transaction_len += access_list.encoded_size(); - } - let gas_limit = gas_limit.min(u64::MAX.into()).low_u64(); let without_base_extrinsic_weight = true; - let (weight_limit, proof_size_base_cost) = - match ::GasWeightMapping::gas_to_weight( - gas_limit, - without_base_extrinsic_weight - ) { - weight_limit if weight_limit.proof_size() > 0 => { - (Some(weight_limit), Some(estimated_transaction_len as u64)) - } - _ => (None, None), - }; + let weight_limit = ::GasWeightMapping::gas_to_weight( + gas_limit, + without_base_extrinsic_weight + ); ::Runner::call( from, @@ -1108,8 +1081,8 @@ impl_runtime_apis! { access_list.unwrap_or_default(), is_transactional, validate, - weight_limit, - proof_size_base_cost, + Some(weight_limit), + None, config.as_ref().unwrap_or(::config()), ).map_err(|err| err.error.into()) } @@ -1141,7 +1114,11 @@ impl_runtime_apis! { gas_limit.low_u64() }; - let (weight_limit, proof_size_base_cost) = (None, None); + let without_base_extrinsic_weight = true; + let weight_limit = ::GasWeightMapping::gas_to_weight( + gas_limit, + without_base_extrinsic_weight + ); #[allow(clippy::or_fun_call)] ::Runner::create( @@ -1155,8 +1132,8 @@ impl_runtime_apis! { access_list.unwrap_or_default(), is_transactional, validate, - weight_limit, - proof_size_base_cost, + Some(weight_limit), + None, config.as_ref().unwrap_or(::config()), ).map_err(|err| err.error.into()) } diff --git a/test/datahaven/suites/dev/common/test-contract/test-contract-creation.ts b/test/datahaven/suites/dev/common/test-contract/test-contract-creation.ts index 10a69aac..90b8d013 100644 --- a/test/datahaven/suites/dev/common/test-contract/test-contract-creation.ts +++ b/test/datahaven/suites/dev/common/test-contract/test-contract-creation.ts @@ -36,8 +36,7 @@ describeSuite({ const callCode = (await context.viem().call({ data: compiled.bytecode })).data; await context.createBlock(); const { contractAddress } = await deployCreateCompiledContract(context, "MultiplyBy7", { - txnType: txnType as any, - gas: 5_000_000n + txnType: txnType as any }); const deployedCode = await context.viem().getCode({ address: contractAddress! }); expect(callCode).to.be.eq(deployedCode); @@ -49,8 +48,7 @@ describeSuite({ title: `should not contain ${txnType} contract at genesis`, test: async () => { const { contractAddress } = await deployCreateCompiledContract(context, "MultiplyBy7", { - type: txnType as any, - gas: 5_000_000n + type: txnType as any }); expect( await context.viem().getCode({ address: contractAddress!, blockNumber: 0n }) @@ -78,8 +76,7 @@ describeSuite({ await context.viem().sendTransaction({ data: callData, nonce, - txnType: txnType as any, - gas: 5_000_000n + txnType: txnType as any }); const contractAddress = ("0x" + From e860c503c82d8a3a3c93272099ea5183608746c7 Mon Sep 17 00:00:00 2001 From: Steve Degosserie <723552+stiiifff@users.noreply.github.com> Date: Thu, 30 Oct 2025 18:02:25 +0200 Subject: [PATCH 06/11] =?UTF-8?q?feat:=20=E2=9C=A8=20Bump=20client=20versi?= =?UTF-8?q?on=20to=20v0.4.0=20&=20runtime=20version=20to=20RT400=20(#268)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- operator/Cargo.lock | 114 +++++++++++++-------------- operator/Cargo.toml | 2 +- operator/runtime/mainnet/src/lib.rs | 2 +- operator/runtime/stagenet/src/lib.rs | 2 +- operator/runtime/testnet/src/lib.rs | 2 +- test/.papi/metadata/datahaven.scale | Bin 621031 -> 621031 bytes 6 files changed, 61 insertions(+), 61 deletions(-) diff --git a/operator/Cargo.lock b/operator/Cargo.lock index 73cdab03..394ad8e9 100644 --- a/operator/Cargo.lock +++ b/operator/Cargo.lock @@ -1517,7 +1517,7 @@ dependencies = [ "pallet-message-queue", "parity-scale-codec", "scale-info", - "snowbridge-core 0.3.1", + "snowbridge-core 0.4.0", "sp-core", "sp-runtime", "sp-std", @@ -2902,7 +2902,7 @@ dependencies = [ [[package]] name = "datahaven-mainnet-runtime" -version = "0.3.1" +version = "0.4.0" dependencies = [ "bridge-hub-common 0.13.1", "datahaven-runtime-common", @@ -3007,8 +3007,8 @@ dependencies = [ "shp-traits", "shp-treasury-funding", "smallvec", - "snowbridge-beacon-primitives 0.3.1", - "snowbridge-core 0.3.1", + "snowbridge-beacon-primitives 0.4.0", + "snowbridge-core 0.4.0", "snowbridge-inbound-queue-primitives", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", @@ -3050,7 +3050,7 @@ dependencies = [ [[package]] name = "datahaven-node" -version = "0.3.1" +version = "0.4.0" dependencies = [ "async-channel 1.9.0", "clap", @@ -3160,7 +3160,7 @@ dependencies = [ [[package]] name = "datahaven-runtime-common" -version = "0.3.1" +version = "0.4.0" dependencies = [ "fp-account", "frame-support", @@ -3189,7 +3189,7 @@ dependencies = [ [[package]] name = "datahaven-stagenet-runtime" -version = "0.3.1" +version = "0.4.0" dependencies = [ "bridge-hub-common 0.13.1", "datahaven-runtime-common", @@ -3294,8 +3294,8 @@ dependencies = [ "shp-traits", "shp-treasury-funding", "smallvec", - "snowbridge-beacon-primitives 0.3.1", - "snowbridge-core 0.3.1", + "snowbridge-beacon-primitives 0.4.0", + "snowbridge-core 0.4.0", "snowbridge-inbound-queue-primitives", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", @@ -3337,7 +3337,7 @@ dependencies = [ [[package]] name = "datahaven-testnet-runtime" -version = "0.3.1" +version = "0.4.0" dependencies = [ "bridge-hub-common 0.13.1", "datahaven-runtime-common", @@ -3442,8 +3442,8 @@ dependencies = [ "shp-traits", "shp-treasury-funding", "smallvec", - "snowbridge-beacon-primitives 0.3.1", - "snowbridge-core 0.3.1", + "snowbridge-beacon-primitives 0.4.0", + "snowbridge-core 0.4.0", "snowbridge-inbound-queue-primitives", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", @@ -3634,7 +3634,7 @@ dependencies = [ [[package]] name = "dhp-bridge" -version = "0.3.1" +version = "0.4.0" dependencies = [ "frame-support", "frame-system", @@ -3642,7 +3642,7 @@ dependencies = [ "pallet-datahaven-native-transfer", "pallet-external-validators", "parity-scale-codec", - "snowbridge-core 0.3.1", + "snowbridge-core 0.4.0", "snowbridge-inbound-queue-primitives", "sp-core", "sp-std", @@ -9077,7 +9077,7 @@ dependencies = [ [[package]] name = "pallet-datahaven-native-transfer" -version = "0.3.1" +version = "0.4.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -9085,7 +9085,7 @@ dependencies = [ "pallet-balances", "parity-scale-codec", "scale-info", - "snowbridge-core 0.3.1", + "snowbridge-core 0.4.0", "snowbridge-outbound-queue-primitives", "sp-core", "sp-io", @@ -9189,7 +9189,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-balances-erc20" -version = "0.3.1" +version = "0.4.0" dependencies = [ "fp-evm", "frame-support", @@ -9212,7 +9212,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-batch" -version = "0.3.1" +version = "0.4.0" dependencies = [ "evm", "fp-evm", @@ -9251,7 +9251,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-call-permit" -version = "0.3.1" +version = "0.4.0" dependencies = [ "evm", "fp-evm", @@ -9385,7 +9385,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-proxy" -version = "0.3.1" +version = "0.4.0" dependencies = [ "evm", "fp-evm", @@ -9429,7 +9429,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-registry" -version = "0.3.1" +version = "0.4.0" dependencies = [ "fp-evm", "frame-support", @@ -9480,7 +9480,7 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "snowbridge-core 0.3.1", + "snowbridge-core 0.4.0", "snowbridge-outbound-queue-primitives", "sp-core", "sp-io", @@ -9490,7 +9490,7 @@ dependencies = [ [[package]] name = "pallet-external-validators" -version = "0.3.1" +version = "0.4.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -9514,7 +9514,7 @@ dependencies = [ [[package]] name = "pallet-external-validators-rewards" -version = "0.3.1" +version = "0.4.0" dependencies = [ "cumulus-primitives-core", "frame-benchmarking", @@ -9529,7 +9529,7 @@ dependencies = [ "polkadot-primitives", "polkadot-runtime-parachains", "scale-info", - "snowbridge-core 0.3.1", + "snowbridge-core 0.4.0", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", "sp-core", @@ -9541,7 +9541,7 @@ dependencies = [ [[package]] name = "pallet-external-validators-rewards-runtime-api" -version = "0.3.1" +version = "0.4.0" dependencies = [ "parity-scale-codec", "snowbridge-merkle-tree", @@ -9764,7 +9764,7 @@ dependencies = [ [[package]] name = "pallet-outbound-commitment-store" -version = "0.3.1" +version = "0.4.0" dependencies = [ "frame-support", "frame-system", @@ -16087,7 +16087,7 @@ dependencies = [ [[package]] name = "snowbridge-beacon-primitives" -version = "0.3.1" +version = "0.4.0" dependencies = [ "byte-slice-cast", "frame-support", @@ -16131,7 +16131,7 @@ dependencies = [ [[package]] name = "snowbridge-core" -version = "0.3.1" +version = "0.4.0" dependencies = [ "bp-relayers", "ethabi-decode", @@ -16231,8 +16231,8 @@ dependencies = [ "log", "parity-scale-codec", "scale-info", - "snowbridge-beacon-primitives 0.3.1", - "snowbridge-core 0.3.1", + "snowbridge-beacon-primitives 0.4.0", + "snowbridge-core 0.4.0", "snowbridge-verification-primitives", "sp-core", "sp-io", @@ -16245,7 +16245,7 @@ dependencies = [ [[package]] name = "snowbridge-merkle-tree" -version = "0.3.1" +version = "0.4.0" dependencies = [ "array-bytes", "hex", @@ -16286,7 +16286,7 @@ dependencies = [ [[package]] name = "snowbridge-outbound-queue-primitives" -version = "0.3.1" +version = "0.4.0" dependencies = [ "alloy-core", "ethabi-decode", @@ -16298,7 +16298,7 @@ dependencies = [ "parity-scale-codec", "polkadot-parachain-primitives", "scale-info", - "snowbridge-core 0.3.1", + "snowbridge-core 0.4.0", "snowbridge-verification-primitives", "sp-arithmetic", "sp-core", @@ -16312,12 +16312,12 @@ dependencies = [ [[package]] name = "snowbridge-outbound-queue-v2-runtime-api" -version = "0.3.1" +version = "0.4.0" dependencies = [ "frame-support", "parity-scale-codec", "scale-info", - "snowbridge-core 0.3.1", + "snowbridge-core 0.4.0", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", "sp-api", @@ -16327,7 +16327,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-ethereum-client" -version = "0.3.1" +version = "0.4.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -16340,8 +16340,8 @@ dependencies = [ "scale-info", "serde", "serde_json", - "snowbridge-beacon-primitives 0.3.1", - "snowbridge-core 0.3.1", + "snowbridge-beacon-primitives 0.4.0", + "snowbridge-core 0.4.0", "snowbridge-ethereum 0.3.0", "snowbridge-inbound-queue-primitives", "snowbridge-pallet-ethereum-client-fixtures", @@ -16357,8 +16357,8 @@ name = "snowbridge-pallet-ethereum-client-fixtures" version = "0.9.0" dependencies = [ "hex-literal 0.3.4", - "snowbridge-beacon-primitives 0.3.1", - "snowbridge-core 0.3.1", + "snowbridge-beacon-primitives 0.4.0", + "snowbridge-core 0.4.0", "snowbridge-inbound-queue-primitives", "sp-core", "sp-std", @@ -16366,7 +16366,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-inbound-queue-v2" -version = "0.3.1" +version = "0.4.0" dependencies = [ "alloy-core", "bp-relayers", @@ -16380,8 +16380,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "snowbridge-beacon-primitives 0.3.1", - "snowbridge-core 0.3.1", + "snowbridge-beacon-primitives 0.4.0", + "snowbridge-core 0.4.0", "snowbridge-inbound-queue-primitives", "snowbridge-pallet-ethereum-client", "snowbridge-pallet-inbound-queue-v2-fixtures", @@ -16402,8 +16402,8 @@ name = "snowbridge-pallet-inbound-queue-v2-fixtures" version = "0.10.0" dependencies = [ "hex-literal 0.3.4", - "snowbridge-beacon-primitives 0.3.1", - "snowbridge-core 0.3.1", + "snowbridge-beacon-primitives 0.4.0", + "snowbridge-core 0.4.0", "snowbridge-inbound-queue-primitives", "sp-core", "sp-std", @@ -16433,7 +16433,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-outbound-queue-v2" -version = "0.3.1" +version = "0.4.0" dependencies = [ "alloy-core", "bp-relayers", @@ -16447,8 +16447,8 @@ dependencies = [ "parity-scale-codec", "scale-info", "serde", - "snowbridge-beacon-primitives 0.3.1", - "snowbridge-core 0.3.1", + "snowbridge-beacon-primitives 0.4.0", + "snowbridge-core 0.4.0", "snowbridge-inbound-queue-primitives", "snowbridge-merkle-tree", "snowbridge-outbound-queue-primitives", @@ -16479,7 +16479,7 @@ dependencies = [ "parity-scale-codec", "polkadot-primitives", "scale-info", - "snowbridge-core 0.3.1", + "snowbridge-core 0.4.0", "snowbridge-outbound-queue-primitives", "snowbridge-pallet-outbound-queue", "sp-core", @@ -16492,7 +16492,7 @@ dependencies = [ [[package]] name = "snowbridge-pallet-system-v2" -version = "0.3.1" +version = "0.4.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -16504,7 +16504,7 @@ dependencies = [ "parity-scale-codec", "polkadot-primitives", "scale-info", - "snowbridge-core 0.3.1", + "snowbridge-core 0.4.0", "snowbridge-outbound-queue-primitives", "snowbridge-pallet-outbound-queue-v2", "snowbridge-pallet-system", @@ -16520,10 +16520,10 @@ dependencies = [ [[package]] name = "snowbridge-system-v2-runtime-api" -version = "0.3.1" +version = "0.4.0" dependencies = [ "parity-scale-codec", - "snowbridge-core 0.3.1", + "snowbridge-core 0.4.0", "sp-api", "sp-std", "staging-xcm", @@ -16531,7 +16531,7 @@ dependencies = [ [[package]] name = "snowbridge-test-utils" -version = "0.3.1" +version = "0.4.0" dependencies = [ "frame-benchmarking", "frame-support", @@ -16551,12 +16551,12 @@ dependencies = [ [[package]] name = "snowbridge-verification-primitives" -version = "0.3.1" +version = "0.4.0" dependencies = [ "frame-support", "parity-scale-codec", "scale-info", - "snowbridge-beacon-primitives 0.3.1", + "snowbridge-beacon-primitives 0.4.0", "sp-core", "sp-std", ] diff --git a/operator/Cargo.toml b/operator/Cargo.toml index 99565ce4..6502e423 100644 --- a/operator/Cargo.toml +++ b/operator/Cargo.toml @@ -5,7 +5,7 @@ edition = "2021" homepage = "https://datahaven.xyz/" license = "GPL-3" repository = "https://github.com/datahavenxyz/datahaven" -version = "0.3.1" +version = "0.4.0" [workspace] members = [ diff --git a/operator/runtime/mainnet/src/lib.rs b/operator/runtime/mainnet/src/lib.rs index 359a6174..5dfb795d 100644 --- a/operator/runtime/mainnet/src/lib.rs +++ b/operator/runtime/mainnet/src/lib.rs @@ -123,7 +123,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 200 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 310, + spec_version: 400, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/operator/runtime/stagenet/src/lib.rs b/operator/runtime/stagenet/src/lib.rs index b86a2072..69878dd2 100644 --- a/operator/runtime/stagenet/src/lib.rs +++ b/operator/runtime/stagenet/src/lib.rs @@ -126,7 +126,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 200 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 310, + spec_version: 400, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/operator/runtime/testnet/src/lib.rs b/operator/runtime/testnet/src/lib.rs index 1899a883..c20bea53 100644 --- a/operator/runtime/testnet/src/lib.rs +++ b/operator/runtime/testnet/src/lib.rs @@ -122,7 +122,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 200 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 310, + spec_version: 400, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/test/.papi/metadata/datahaven.scale b/test/.papi/metadata/datahaven.scale index 4d9188cb45be272e52dc6c5a1ce4257cbfb1dfff..7898e7484570ca3d0561b33f12dfaffcc7f7bb81 100644 GIT binary patch delta 43 ucmaFF7M3ln(F7M3ln( Date: Sun, 2 Nov 2025 21:50:55 +0100 Subject: [PATCH 07/11] fix: add missing weights (#271) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### 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) --- operator/Cargo.lock | 20 +++ operator/Cargo.toml | 1 + operator/runtime/mainnet/Cargo.toml | 4 + operator/runtime/mainnet/src/benchmarks.rs | 4 + operator/runtime/mainnet/src/configs/mod.rs | 10 +- .../mainnet/src/configs/storagehub/mod.rs | 2 +- operator/runtime/mainnet/src/weights/mod.rs | 4 + .../mainnet/src/weights/pallet_babe.rs | 50 ++++++++ .../pallet_external_validator_slashes.rs | 115 ++++++++++++++++++ .../mainnet/src/weights/pallet_grandpa.rs | 56 +++++++++ .../mainnet/src/weights/pallet_randomness.rs | 77 ++++++++++++ operator/runtime/stagenet/Cargo.toml | 4 + operator/runtime/stagenet/src/benchmarks.rs | 4 + operator/runtime/stagenet/src/configs/mod.rs | 10 +- .../stagenet/src/configs/storagehub/mod.rs | 2 +- operator/runtime/stagenet/src/weights/mod.rs | 4 + .../stagenet/src/weights/pallet_babe.rs | 48 ++++++++ .../pallet_external_validator_slashes.rs | 115 ++++++++++++++++++ .../stagenet/src/weights/pallet_grandpa.rs | 55 +++++++++ .../stagenet/src/weights/pallet_randomness.rs | 77 ++++++++++++ operator/runtime/testnet/Cargo.toml | 4 + operator/runtime/testnet/src/benchmarks.rs | 5 + operator/runtime/testnet/src/configs/mod.rs | 8 +- .../testnet/src/configs/storagehub/mod.rs | 2 +- operator/runtime/testnet/src/weights/mod.rs | 4 + .../testnet/src/weights/pallet_babe.rs | 48 ++++++++ .../pallet_external_validator_slashes.rs | 115 ++++++++++++++++++ .../testnet/src/weights/pallet_grandpa.rs | 55 +++++++++ .../testnet/src/weights/pallet_randomness.rs | 77 ++++++++++++ 29 files changed, 963 insertions(+), 17 deletions(-) create mode 100644 operator/runtime/mainnet/src/weights/pallet_babe.rs create mode 100644 operator/runtime/mainnet/src/weights/pallet_external_validator_slashes.rs create mode 100644 operator/runtime/mainnet/src/weights/pallet_grandpa.rs create mode 100644 operator/runtime/mainnet/src/weights/pallet_randomness.rs create mode 100644 operator/runtime/stagenet/src/weights/pallet_babe.rs create mode 100644 operator/runtime/stagenet/src/weights/pallet_external_validator_slashes.rs create mode 100644 operator/runtime/stagenet/src/weights/pallet_grandpa.rs create mode 100644 operator/runtime/stagenet/src/weights/pallet_randomness.rs create mode 100644 operator/runtime/testnet/src/weights/pallet_babe.rs create mode 100644 operator/runtime/testnet/src/weights/pallet_external_validator_slashes.rs create mode 100644 operator/runtime/testnet/src/weights/pallet_grandpa.rs create mode 100644 operator/runtime/testnet/src/weights/pallet_randomness.rs diff --git a/operator/Cargo.lock b/operator/Cargo.lock index 394ad8e9..3705be6c 100644 --- a/operator/Cargo.lock +++ b/operator/Cargo.lock @@ -2982,6 +2982,7 @@ dependencies = [ "pallet-safe-mode", "pallet-scheduler", "pallet-session", + "pallet-session-benchmarking", "pallet-storage-providers", "pallet-storage-providers-runtime-api", "pallet-sudo", @@ -3269,6 +3270,7 @@ dependencies = [ "pallet-safe-mode", "pallet-scheduler", "pallet-session", + "pallet-session-benchmarking", "pallet-storage-providers", "pallet-storage-providers-runtime-api", "pallet-sudo", @@ -3417,6 +3419,7 @@ dependencies = [ "pallet-safe-mode", "pallet-scheduler", "pallet-session", + "pallet-session-benchmarking", "pallet-storage-providers", "pallet-storage-providers-runtime-api", "pallet-sudo", @@ -9887,6 +9890,7 @@ name = "pallet-randomness" version = "0.1.0" source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" dependencies = [ + "frame-benchmarking", "frame-support", "frame-system", "log", @@ -9975,6 +9979,22 @@ dependencies = [ "sp-trie", ] +[[package]] +name = "pallet-session-benchmarking" +version = "39.1.0" +source = "git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2412-6#bbc435c7667d3283ba280a8fec44676357392753" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-session", + "pallet-staking", + "parity-scale-codec", + "rand 0.8.5", + "sp-runtime", + "sp-session", +] + [[package]] name = "pallet-staking" version = "39.1.0" diff --git a/operator/Cargo.toml b/operator/Cargo.toml index 6502e423..17dfd655 100644 --- a/operator/Cargo.toml +++ b/operator/Cargo.toml @@ -137,6 +137,7 @@ pallet-referenda = { git = "https://github.com/paritytech/polkadot-sdk", tag = " pallet-safe-mode = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-6", default-features = false } pallet-scheduler = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-6", default-features = false } pallet-session = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-6", default-features = false } +pallet-session-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-6", default-features = false } pallet-staking = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-6", default-features = false } pallet-sudo = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-6", default-features = false } pallet-timestamp = { git = "https://github.com/paritytech/polkadot-sdk", tag = "polkadot-stable2412-6", default-features = false } diff --git a/operator/runtime/mainnet/Cargo.toml b/operator/runtime/mainnet/Cargo.toml index 673394af..b65b736b 100644 --- a/operator/runtime/mainnet/Cargo.toml +++ b/operator/runtime/mainnet/Cargo.toml @@ -27,6 +27,7 @@ frame-metadata-hash-extension = { workspace = true } frame-support = { workspace = true, features = ["experimental"] } frame-system = { workspace = true } frame-system-benchmarking = { workspace = true, optional = true } +pallet-session-benchmarking = { workspace = true, optional = true } frame-system-rpc-runtime-api = { workspace = true } frame-try-runtime = { workspace = true, optional = true } hex = { workspace = true } @@ -188,6 +189,7 @@ std = [ "frame-metadata-hash-extension/std", "frame-support/std", "frame-system-benchmarking?/std", + "pallet-session-benchmarking?/std", "frame-system-rpc-runtime-api/std", "frame-system/std", "frame-try-runtime?/std", @@ -331,11 +333,13 @@ runtime-benchmarks = [ "pallet-referenda/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", + "pallet-session-benchmarking/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", "pallet-utility/runtime-benchmarks", "pallet-whitelist/runtime-benchmarks", + "pallet-randomness/runtime-benchmarks", "polkadot-primitives/runtime-benchmarks", "polkadot-runtime-common/runtime-benchmarks", "snowbridge-inbound-queue-primitives/runtime-benchmarks", diff --git a/operator/runtime/mainnet/src/benchmarks.rs b/operator/runtime/mainnet/src/benchmarks.rs index 1354295d..274a41b6 100644 --- a/operator/runtime/mainnet/src/benchmarks.rs +++ b/operator/runtime/mainnet/src/benchmarks.rs @@ -36,6 +36,9 @@ frame_benchmarking::define_benchmarks!( // Consensus pallets [pallet_mmr, Mmr] [pallet_beefy_mmr, BeefyMmrLeaf] + [pallet_babe, Babe] + [pallet_grandpa, Grandpa] + [pallet_randomness, Randomness] // Substrate pallets [pallet_balances, Balances] @@ -69,6 +72,7 @@ frame_benchmarking::define_benchmarks!( // DataHaven custom pallets [pallet_external_validators, ExternalValidators] [pallet_external_validators_rewards, ExternalValidatorsRewards] + [pallet_external_validator_slashes, ExternalValidatorsSlashes] [pallet_datahaven_native_transfer, DataHavenNativeTransfer] // Snowbridge pallets diff --git a/operator/runtime/mainnet/src/configs/mod.rs b/operator/runtime/mainnet/src/configs/mod.rs index 3f828e33..3ba0563b 100644 --- a/operator/runtime/mainnet/src/configs/mod.rs +++ b/operator/runtime/mainnet/src/configs/mod.rs @@ -323,7 +323,7 @@ impl pallet_babe::Config for Runtime { type ExpectedBlockTime = ExpectedBlockTime; type EpochChangeTrigger = pallet_babe::ExternalTrigger; type DisabledValidators = Session; - type WeightInfo = (); + type WeightInfo = mainnet_weights::pallet_babe::WeightInfo; type MaxAuthorities = MaxAuthorities; type MaxNominators = ConstU32<0>; @@ -407,7 +407,7 @@ impl pallet_session::Config for Runtime { type SessionManager = pallet_session::historical::NoteHistoricalRoot; type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; - type WeightInfo = (); + type WeightInfo = pallet_session::weights::SubstrateWeight; } parameter_types! { @@ -436,7 +436,7 @@ parameter_types! { impl pallet_grandpa::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); + type WeightInfo = mainnet_weights::pallet_grandpa::WeightInfo; type MaxAuthorities = MaxAuthorities; type MaxNominators = ConstU32<0>; type MaxSetIdSessionEntries = MaxSetIdSessionEntries; @@ -645,7 +645,7 @@ impl pallet_identity::Config for Runtime { type PendingUsernameExpiration = PendingUsernameExpiration; type MaxSuffixLength = MaxSuffixLength; type MaxUsernameLength = MaxUsernameLength; - type WeightInfo = (); + type WeightInfo = pallet_identity::weights::SubstrateWeight; type UsernameDeposit = (); type UsernameGracePeriod = (); @@ -1633,7 +1633,7 @@ impl pallet_external_validator_slashes::Config for Runtime { type InvulnerablesProvider = ExternalValidators; type ExternalIndexProvider = ExternalValidators; type QueuedSlashesProcessedPerBlock = ConstU32<10>; - type WeightInfo = (); // TODO: calculate weights + type WeightInfo = mainnet_weights::pallet_external_validator_slashes::WeightInfo; type SendMessage = SlashesSendAdapter; } diff --git a/operator/runtime/mainnet/src/configs/storagehub/mod.rs b/operator/runtime/mainnet/src/configs/storagehub/mod.rs index 3c15214d..ff265f5d 100644 --- a/operator/runtime/mainnet/src/configs/storagehub/mod.rs +++ b/operator/runtime/mainnet/src/configs/storagehub/mod.rs @@ -105,7 +105,7 @@ impl pallet_randomness::Config for Runtime { type RuntimeEvent = RuntimeEvent; type BabeDataGetter = BabeDataGetter; type BabeBlockGetter = BlockNumberGetter; - type WeightInfo = (); + type WeightInfo = crate::weights::pallet_randomness::WeightInfo; type BabeDataGetterBlockNumber = BlockNumber; } diff --git a/operator/runtime/mainnet/src/weights/mod.rs b/operator/runtime/mainnet/src/weights/mod.rs index 434d2780..08fcf943 100644 --- a/operator/runtime/mainnet/src/weights/mod.rs +++ b/operator/runtime/mainnet/src/weights/mod.rs @@ -19,6 +19,7 @@ // DataHaven pallets pub mod pallet_datahaven_native_transfer; +pub mod pallet_external_validator_slashes; pub mod pallet_external_validators; pub mod pallet_external_validators_rewards; @@ -31,9 +32,11 @@ pub mod snowbridge_pallet_system_v2; // Substrate pallets pub mod frame_system; +pub mod pallet_babe; pub mod pallet_balances; pub mod pallet_beefy_mmr; pub mod pallet_evm; +pub mod pallet_grandpa; pub mod pallet_im_online; pub mod pallet_message_queue; pub mod pallet_migrations; @@ -42,6 +45,7 @@ pub mod pallet_multisig; pub mod pallet_parameters; pub mod pallet_preimage; pub mod pallet_proxy; +pub mod pallet_randomness; pub mod pallet_safe_mode; pub mod pallet_scheduler; pub mod pallet_sudo; diff --git a/operator/runtime/mainnet/src/weights/pallet_babe.rs b/operator/runtime/mainnet/src/weights/pallet_babe.rs new file mode 100644 index 00000000..8d022002 --- /dev/null +++ b/operator/runtime/mainnet/src/weights/pallet_babe.rs @@ -0,0 +1,50 @@ + + +//! Autogenerated weights for `pallet_babe` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-30, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-mainnet-runtime/datahaven_mainnet_runtime.compact.compressed.wasm +// --pallet +// pallet_babe +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/mainnet/src/weights/pallet_babe.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_babe`. +pub struct WeightInfo(PhantomData); +impl pallet_babe::WeightInfo for WeightInfo { + fn plan_config_change() -> Weight { + // Placeholder constant; re-benchmark to refresh. + Weight::from_parts(5_000_000, 0) + } + + fn report_equivocation(_equivocations: u32, _key_owners: u32) -> Weight { + // Based on previous check_equivocation_proof baseline; re-benchmark to refresh. + Weight::from_parts(89_672_355, 0) + } +} diff --git a/operator/runtime/mainnet/src/weights/pallet_external_validator_slashes.rs b/operator/runtime/mainnet/src/weights/pallet_external_validator_slashes.rs new file mode 100644 index 00000000..964a0ae0 --- /dev/null +++ b/operator/runtime/mainnet/src/weights/pallet_external_validator_slashes.rs @@ -0,0 +1,115 @@ + + +//! Autogenerated weights for `pallet_external_validator_slashes` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-mainnet-runtime/datahaven_mainnet_runtime.compact.compressed.wasm +// --pallet +// pallet_external_validator_slashes +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/mainnet/src/weights/pallet_external_validator_slashes.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_external_validator_slashes`. +pub struct WeightInfo(PhantomData); +impl pallet_external_validator_slashes::weights::WeightInfo for WeightInfo { + /// Storage: `ExternalValidators::ActiveEra` (r:1 w:0) + /// Proof: `ExternalValidators::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::Slashes` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::Slashes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `s` is `[1, 1000]`. + fn cancel_deferred_slash(_s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `38528` + // Estimated: `41993` + // Minimum execution time: 76_582_000 picoseconds. + Weight::from_parts(1_422_088_660, 41993) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `ExternalValidators::ActiveEra` (r:1 w:0) + /// Proof: `ExternalValidators::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidators::ErasStartSessionIndex` (r:1 w:0) + /// Proof: `ExternalValidators::ErasStartSessionIndex` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::NextSlashId` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::NextSlashId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::ValidatorSlashInEra` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::ValidatorSlashInEra` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::Slashes` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::Slashes` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn force_inject_slash() -> Weight { + // Proof Size summary in bytes: + // Measured: `492` + // Estimated: `3957` + // Minimum execution time: 28_199_000 picoseconds. + Weight::from_parts(28_842_000, 3957) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: `ExternalValidators::ActiveEra` (r:1 w:0) + /// Proof: `ExternalValidators::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::UnreportedSlashesQueue` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::UnreportedSlashesQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(136), added: 2611, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:0 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32845), added: 35320, mode: `MaxEncodedLen`) + /// The range of component `s` is `[1, 200]`. + fn process_slashes_queue(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `541 + s * (38 ±0)` + // Estimated: `6044 + s * (38 ±0)` + // Minimum execution time: 50_142_000 picoseconds. + Weight::from_parts(52_116_022, 6044) + // Standard Error: 857 + .saturating_add(Weight::from_parts(45_899, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(Weight::from_parts(0, 38).saturating_mul(s.into())) + } + /// Storage: `ExternalValidatorsSlashes::SlashingMode` (r:0 w:1) + /// Proof: `ExternalValidatorsSlashes::SlashingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + fn set_slashing_mode() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_864_000 picoseconds. + Weight::from_parts(4_014_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + + fn root_test_send_msg_to_eth() -> Weight { + Weight::from_parts(1_015_195_000, 3601) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } +} diff --git a/operator/runtime/mainnet/src/weights/pallet_grandpa.rs b/operator/runtime/mainnet/src/weights/pallet_grandpa.rs new file mode 100644 index 00000000..415ab91e --- /dev/null +++ b/operator/runtime/mainnet/src/weights/pallet_grandpa.rs @@ -0,0 +1,56 @@ + + +//! Autogenerated weights for `pallet_grandpa` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-30, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-mainnet-runtime/datahaven_mainnet_runtime.compact.compressed.wasm +// --pallet +// pallet_grandpa +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/mainnet/src/weights/pallet_grandpa.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_grandpa`. +pub struct WeightInfo(PhantomData); +impl pallet_grandpa::WeightInfo for WeightInfo { + /// Storage: `Grandpa::Stalled` (r:0 w:1) + /// Proof: `Grandpa::Stalled` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + fn note_stalled() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_687_000 picoseconds. + Weight::from_parts(3_903_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + + fn report_equivocation(_equivocations: u32, _key_owners: u32) -> Weight { + // Based on previous check_equivocation_proof baseline; re-benchmark to refresh. + Weight::from_parts(79_601_142, 0) + } +} diff --git a/operator/runtime/mainnet/src/weights/pallet_randomness.rs b/operator/runtime/mainnet/src/weights/pallet_randomness.rs new file mode 100644 index 00000000..5f7fffcd --- /dev/null +++ b/operator/runtime/mainnet/src/weights/pallet_randomness.rs @@ -0,0 +1,77 @@ + + +//! Autogenerated weights for `pallet_randomness` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-mainnet-runtime/datahaven_mainnet_runtime.compact.compressed.wasm +// --pallet +// pallet_randomness +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/mainnet/src/weights/pallet_randomness.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_randomness`. +pub struct WeightInfo(PhantomData); +impl pallet_randomness::weights::WeightInfo for WeightInfo { + /// Storage: `Babe::AuthorVrfRandomness` (r:1 w:0) + /// Proof: `Babe::AuthorVrfRandomness` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `Randomness::RelayEpoch` (r:1 w:1) + /// Proof: `Randomness::RelayEpoch` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Babe::NextRandomness` (r:1 w:0) + /// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `Babe::EpochStart` (r:1 w:0) + /// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Randomness::LastRelayBlockAndParaBlockValidForNextEpoch` (r:1 w:1) + /// Proof: `Randomness::LastRelayBlockAndParaBlockValidForNextEpoch` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Randomness::LatestOneEpochAgoRandomness` (r:0 w:1) + /// Proof: `Randomness::LatestOneEpochAgoRandomness` (`max_values`: Some(1), `max_size`: Some(36), added: 531, mode: `MaxEncodedLen`) + /// Storage: `Randomness::LatestParentBlockRandomness` (r:0 w:1) + /// Proof: `Randomness::LatestParentBlockRandomness` (`max_values`: Some(1), `max_size`: Some(36), added: 531, mode: `MaxEncodedLen`) + /// Storage: `Randomness::InherentIncluded` (r:0 w:1) + /// Proof: `Randomness::InherentIncluded` (`max_values`: Some(1), `max_size`: Some(0), added: 495, mode: `MaxEncodedLen`) + fn set_babe_randomness() -> Weight { + // Proof Size summary in bytes: + // Measured: `348` + // Estimated: `1518` + // Minimum execution time: 26_171_000 picoseconds. + Weight::from_parts(27_041_000, 1518) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } + /// Storage: `Randomness::InherentIncluded` (r:1 w:1) + /// Proof: `Randomness::InherentIncluded` (`max_values`: Some(1), `max_size`: Some(0), added: 495, mode: `MaxEncodedLen`) + fn on_finalize_hook() -> Weight { + // Proof Size summary in bytes: + // Measured: `99` + // Estimated: `1485` + // Minimum execution time: 5_396_000 picoseconds. + Weight::from_parts(5_596_000, 1485) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +} diff --git a/operator/runtime/stagenet/Cargo.toml b/operator/runtime/stagenet/Cargo.toml index cd5b96ab..9e31449c 100644 --- a/operator/runtime/stagenet/Cargo.toml +++ b/operator/runtime/stagenet/Cargo.toml @@ -27,6 +27,7 @@ frame-metadata-hash-extension = { workspace = true } frame-support = { workspace = true, features = ["experimental"] } frame-system = { workspace = true } frame-system-benchmarking = { workspace = true, optional = true } +pallet-session-benchmarking = { workspace = true, optional = true } frame-system-rpc-runtime-api = { workspace = true } frame-try-runtime = { workspace = true, optional = true } hex = { workspace = true } @@ -188,6 +189,7 @@ std = [ "frame-metadata-hash-extension/std", "frame-support/std", "frame-system-benchmarking?/std", + "pallet-session-benchmarking?/std", "frame-system-rpc-runtime-api/std", "frame-system/std", "frame-try-runtime?/std", @@ -328,9 +330,11 @@ runtime-benchmarks = [ "pallet-preimage/runtime-benchmarks", "pallet-safe-mode/runtime-benchmarks", "pallet-tx-pause/runtime-benchmarks", + "pallet-randomness/runtime-benchmarks", "pallet-referenda/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", + "pallet-session-benchmarking/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", diff --git a/operator/runtime/stagenet/src/benchmarks.rs b/operator/runtime/stagenet/src/benchmarks.rs index 6944df0f..aaa16218 100644 --- a/operator/runtime/stagenet/src/benchmarks.rs +++ b/operator/runtime/stagenet/src/benchmarks.rs @@ -36,6 +36,9 @@ frame_benchmarking::define_benchmarks!( // Consensus pallets [pallet_mmr, Mmr] [pallet_beefy_mmr, BeefyMmrLeaf] + [pallet_babe, Babe] + [pallet_grandpa, Grandpa] + [pallet_randomness, Randomness] // Substrate pallets [pallet_balances, Balances] @@ -69,6 +72,7 @@ frame_benchmarking::define_benchmarks!( // DataHaven custom pallets [pallet_external_validators, ExternalValidators] [pallet_external_validators_rewards, ExternalValidatorsRewards] + [pallet_external_validator_slashes, ExternalValidatorsSlashes] [pallet_datahaven_native_transfer, DataHavenNativeTransfer] // Snowbridge pallets diff --git a/operator/runtime/stagenet/src/configs/mod.rs b/operator/runtime/stagenet/src/configs/mod.rs index 9ab30486..c0281aef 100644 --- a/operator/runtime/stagenet/src/configs/mod.rs +++ b/operator/runtime/stagenet/src/configs/mod.rs @@ -323,7 +323,7 @@ impl pallet_babe::Config for Runtime { type ExpectedBlockTime = ExpectedBlockTime; type EpochChangeTrigger = pallet_babe::ExternalTrigger; type DisabledValidators = Session; - type WeightInfo = (); + type WeightInfo = stagenet_weights::pallet_babe::WeightInfo; type MaxAuthorities = MaxAuthorities; type MaxNominators = ConstU32<0>; @@ -406,7 +406,7 @@ impl pallet_session::Config for Runtime { type SessionManager = pallet_session::historical::NoteHistoricalRoot; type SessionHandler = ::KeyTypeIdProviders; type Keys = SessionKeys; - type WeightInfo = (); + type WeightInfo = pallet_session::weights::SubstrateWeight; } parameter_types! { @@ -435,7 +435,7 @@ parameter_types! { impl pallet_grandpa::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); + type WeightInfo = stagenet_weights::pallet_grandpa::WeightInfo; type MaxAuthorities = MaxAuthorities; type MaxNominators = ConstU32<0>; type MaxSetIdSessionEntries = MaxSetIdSessionEntries; @@ -642,7 +642,7 @@ impl pallet_identity::Config for Runtime { type PendingUsernameExpiration = PendingUsernameExpiration; type MaxSuffixLength = MaxSuffixLength; type MaxUsernameLength = MaxUsernameLength; - type WeightInfo = (); + type WeightInfo = pallet_identity::weights::SubstrateWeight; type UsernameDeposit = (); type UsernameGracePeriod = (); @@ -1632,7 +1632,7 @@ impl pallet_external_validator_slashes::Config for Runtime { type InvulnerablesProvider = ExternalValidators; type ExternalIndexProvider = ExternalValidators; type QueuedSlashesProcessedPerBlock = ConstU32<10>; - type WeightInfo = (); // TODO: calculate weights + type WeightInfo = stagenet_weights::pallet_external_validator_slashes::WeightInfo; type SendMessage = SlashesSendAdapter; } diff --git a/operator/runtime/stagenet/src/configs/storagehub/mod.rs b/operator/runtime/stagenet/src/configs/storagehub/mod.rs index 3c15214d..ff265f5d 100644 --- a/operator/runtime/stagenet/src/configs/storagehub/mod.rs +++ b/operator/runtime/stagenet/src/configs/storagehub/mod.rs @@ -105,7 +105,7 @@ impl pallet_randomness::Config for Runtime { type RuntimeEvent = RuntimeEvent; type BabeDataGetter = BabeDataGetter; type BabeBlockGetter = BlockNumberGetter; - type WeightInfo = (); + type WeightInfo = crate::weights::pallet_randomness::WeightInfo; type BabeDataGetterBlockNumber = BlockNumber; } diff --git a/operator/runtime/stagenet/src/weights/mod.rs b/operator/runtime/stagenet/src/weights/mod.rs index a836acce..65c7cce2 100644 --- a/operator/runtime/stagenet/src/weights/mod.rs +++ b/operator/runtime/stagenet/src/weights/mod.rs @@ -19,6 +19,7 @@ // DataHaven pallets pub mod pallet_datahaven_native_transfer; +pub mod pallet_external_validator_slashes; pub mod pallet_external_validators; pub mod pallet_external_validators_rewards; @@ -31,9 +32,12 @@ pub mod snowbridge_pallet_system_v2; // Substrate pallets pub mod frame_system; +pub mod pallet_babe; pub mod pallet_balances; pub mod pallet_beefy_mmr; pub mod pallet_evm; +pub mod pallet_grandpa; +pub mod pallet_randomness; // pub mod pallet_identity; pub mod pallet_im_online; pub mod pallet_message_queue; diff --git a/operator/runtime/stagenet/src/weights/pallet_babe.rs b/operator/runtime/stagenet/src/weights/pallet_babe.rs new file mode 100644 index 00000000..edbc3aa8 --- /dev/null +++ b/operator/runtime/stagenet/src/weights/pallet_babe.rs @@ -0,0 +1,48 @@ + + +//! Autogenerated weights for `pallet_babe` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-30, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-stagenet-runtime/datahaven_stagenet_runtime.compact.compressed.wasm +// --pallet +// pallet_babe +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/stagenet/src/weights/pallet_babe.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_babe`. +pub struct WeightInfo(PhantomData); +impl pallet_babe::WeightInfo for WeightInfo { + fn plan_config_change() -> Weight { + Weight::from_parts(5_000_000, 0) + } + + fn report_equivocation(_equivocations: u32, _key_owners: u32) -> Weight { + Weight::from_parts(89_669_734, 0) + } +} diff --git a/operator/runtime/stagenet/src/weights/pallet_external_validator_slashes.rs b/operator/runtime/stagenet/src/weights/pallet_external_validator_slashes.rs new file mode 100644 index 00000000..4c4b5139 --- /dev/null +++ b/operator/runtime/stagenet/src/weights/pallet_external_validator_slashes.rs @@ -0,0 +1,115 @@ + + +//! Autogenerated weights for `pallet_external_validator_slashes` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-stagenet-runtime/datahaven_stagenet_runtime.compact.compressed.wasm +// --pallet +// pallet_external_validator_slashes +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/stagenet/src/weights/pallet_external_validator_slashes.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_external_validator_slashes`. +pub struct WeightInfo(PhantomData); +impl pallet_external_validator_slashes::WeightInfo for WeightInfo { + /// Storage: `ExternalValidators::ActiveEra` (r:1 w:0) + /// Proof: `ExternalValidators::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::Slashes` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::Slashes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `s` is `[1, 1000]`. + fn cancel_deferred_slash(_s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `38528` + // Estimated: `41993` + // Minimum execution time: 77_237_000 picoseconds. + Weight::from_parts(1_417_731_577, 41993) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `ExternalValidators::ActiveEra` (r:1 w:0) + /// Proof: `ExternalValidators::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidators::ErasStartSessionIndex` (r:1 w:0) + /// Proof: `ExternalValidators::ErasStartSessionIndex` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::NextSlashId` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::NextSlashId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::ValidatorSlashInEra` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::ValidatorSlashInEra` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::Slashes` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::Slashes` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn force_inject_slash() -> Weight { + // Proof Size summary in bytes: + // Measured: `492` + // Estimated: `3957` + // Minimum execution time: 27_206_000 picoseconds. + Weight::from_parts(27_858_000, 3957) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: `ExternalValidators::ActiveEra` (r:1 w:0) + /// Proof: `ExternalValidators::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::UnreportedSlashesQueue` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::UnreportedSlashesQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(136), added: 2611, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:0 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32845), added: 35320, mode: `MaxEncodedLen`) + /// The range of component `s` is `[1, 200]`. + fn process_slashes_queue(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `541 + s * (38 ±0)` + // Estimated: `6044 + s * (38 ±0)` + // Minimum execution time: 49_346_000 picoseconds. + Weight::from_parts(51_048_900, 6044) + // Standard Error: 836 + .saturating_add(Weight::from_parts(47_676, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(Weight::from_parts(0, 38).saturating_mul(s.into())) + } + /// Storage: `ExternalValidatorsSlashes::SlashingMode` (r:0 w:1) + /// Proof: `ExternalValidatorsSlashes::SlashingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + fn set_slashing_mode() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_654_000 picoseconds. + Weight::from_parts(3_892_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + + fn root_test_send_msg_to_eth() -> Weight { + Weight::from_parts(1_015_195_000, 3601) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } +} diff --git a/operator/runtime/stagenet/src/weights/pallet_grandpa.rs b/operator/runtime/stagenet/src/weights/pallet_grandpa.rs new file mode 100644 index 00000000..212e1d18 --- /dev/null +++ b/operator/runtime/stagenet/src/weights/pallet_grandpa.rs @@ -0,0 +1,55 @@ + + +//! Autogenerated weights for `pallet_grandpa` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-30, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-stagenet-runtime/datahaven_stagenet_runtime.compact.compressed.wasm +// --pallet +// pallet_grandpa +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/stagenet/src/weights/pallet_grandpa.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_grandpa`. +pub struct WeightInfo(PhantomData); +impl pallet_grandpa::WeightInfo for WeightInfo { + /// Storage: `Grandpa::Stalled` (r:0 w:1) + /// Proof: `Grandpa::Stalled` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + fn note_stalled() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_681_000 picoseconds. + Weight::from_parts(3_933_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + + fn report_equivocation(_equivocations: u32, _key_owners: u32) -> Weight { + Weight::from_parts(79_233_438, 0) + } +} diff --git a/operator/runtime/stagenet/src/weights/pallet_randomness.rs b/operator/runtime/stagenet/src/weights/pallet_randomness.rs new file mode 100644 index 00000000..477df36c --- /dev/null +++ b/operator/runtime/stagenet/src/weights/pallet_randomness.rs @@ -0,0 +1,77 @@ + + +//! Autogenerated weights for `pallet_randomness` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-stagenet-runtime/datahaven_stagenet_runtime.compact.compressed.wasm +// --pallet +// pallet_randomness +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/stagenet/src/weights/pallet_randomness.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_randomness`. +pub struct WeightInfo(PhantomData); +impl pallet_randomness::weights::WeightInfo for WeightInfo { + /// Storage: `Babe::AuthorVrfRandomness` (r:1 w:0) + /// Proof: `Babe::AuthorVrfRandomness` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `Randomness::RelayEpoch` (r:1 w:1) + /// Proof: `Randomness::RelayEpoch` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Babe::NextRandomness` (r:1 w:0) + /// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `Babe::EpochStart` (r:1 w:0) + /// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Randomness::LastRelayBlockAndParaBlockValidForNextEpoch` (r:1 w:1) + /// Proof: `Randomness::LastRelayBlockAndParaBlockValidForNextEpoch` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Randomness::LatestOneEpochAgoRandomness` (r:0 w:1) + /// Proof: `Randomness::LatestOneEpochAgoRandomness` (`max_values`: Some(1), `max_size`: Some(36), added: 531, mode: `MaxEncodedLen`) + /// Storage: `Randomness::LatestParentBlockRandomness` (r:0 w:1) + /// Proof: `Randomness::LatestParentBlockRandomness` (`max_values`: Some(1), `max_size`: Some(36), added: 531, mode: `MaxEncodedLen`) + /// Storage: `Randomness::InherentIncluded` (r:0 w:1) + /// Proof: `Randomness::InherentIncluded` (`max_values`: Some(1), `max_size`: Some(0), added: 495, mode: `MaxEncodedLen`) + fn set_babe_randomness() -> Weight { + // Proof Size summary in bytes: + // Measured: `348` + // Estimated: `1518` + // Minimum execution time: 26_032_000 picoseconds. + Weight::from_parts(26_849_000, 1518) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } + /// Storage: `Randomness::InherentIncluded` (r:1 w:1) + /// Proof: `Randomness::InherentIncluded` (`max_values`: Some(1), `max_size`: Some(0), added: 495, mode: `MaxEncodedLen`) + fn on_finalize_hook() -> Weight { + // Proof Size summary in bytes: + // Measured: `99` + // Estimated: `1485` + // Minimum execution time: 5_285_000 picoseconds. + Weight::from_parts(5_600_000, 1485) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +} diff --git a/operator/runtime/testnet/Cargo.toml b/operator/runtime/testnet/Cargo.toml index 1d955dc9..f88dbd1b 100644 --- a/operator/runtime/testnet/Cargo.toml +++ b/operator/runtime/testnet/Cargo.toml @@ -27,6 +27,7 @@ frame-metadata-hash-extension = { workspace = true } frame-support = { workspace = true, features = ["experimental"] } frame-system = { workspace = true } frame-system-benchmarking = { workspace = true, optional = true } +pallet-session-benchmarking = { workspace = true, optional = true } frame-system-rpc-runtime-api = { workspace = true } frame-try-runtime = { workspace = true, optional = true } hex = { workspace = true } @@ -188,6 +189,7 @@ std = [ "frame-metadata-hash-extension/std", "frame-support/std", "frame-system-benchmarking?/std", + "pallet-session-benchmarking?/std", "frame-system-rpc-runtime-api/std", "frame-system/std", "frame-try-runtime?/std", @@ -321,12 +323,14 @@ runtime-benchmarks = [ "pallet-multisig/runtime-benchmarks", "pallet-offences/runtime-benchmarks", "pallet-parameters/runtime-benchmarks", + "pallet-randomness/runtime-benchmarks", "pallet-preimage/runtime-benchmarks", "pallet-safe-mode/runtime-benchmarks", "pallet-tx-pause/runtime-benchmarks", "pallet-referenda/runtime-benchmarks", "pallet-proxy/runtime-benchmarks", "pallet-scheduler/runtime-benchmarks", + "pallet-session-benchmarking/runtime-benchmarks", "pallet-sudo/runtime-benchmarks", "pallet-timestamp/runtime-benchmarks", "pallet-treasury/runtime-benchmarks", diff --git a/operator/runtime/testnet/src/benchmarks.rs b/operator/runtime/testnet/src/benchmarks.rs index e6ec2c3d..3d0e6d55 100644 --- a/operator/runtime/testnet/src/benchmarks.rs +++ b/operator/runtime/testnet/src/benchmarks.rs @@ -28,6 +28,7 @@ use pallet_collective as pallet_collective_treasury_council; #[allow(unused_imports)] use pallet_collective as pallet_collective_technical_committee; +use pallet_external_validator_slashes as pallet_external_validators_slashes; frame_benchmarking::define_benchmarks!( // System benchmarks @@ -36,6 +37,9 @@ frame_benchmarking::define_benchmarks!( // Consensus pallets [pallet_mmr, Mmr] [pallet_beefy_mmr, BeefyMmrLeaf] + [pallet_babe, Babe] + [pallet_grandpa, Grandpa] + [pallet_randomness, Randomness] // Substrate pallets [pallet_balances, Balances] @@ -68,6 +72,7 @@ frame_benchmarking::define_benchmarks!( // DataHaven custom pallets [pallet_external_validators, ExternalValidators] [pallet_external_validators_rewards, ExternalValidatorsRewards] + [pallet_external_validator_slashes, ExternalValidatorsSlashes] [pallet_datahaven_native_transfer, DataHavenNativeTransfer] // Snowbridge pallets diff --git a/operator/runtime/testnet/src/configs/mod.rs b/operator/runtime/testnet/src/configs/mod.rs index 5915e31f..7850619f 100644 --- a/operator/runtime/testnet/src/configs/mod.rs +++ b/operator/runtime/testnet/src/configs/mod.rs @@ -323,7 +323,7 @@ impl pallet_babe::Config for Runtime { type ExpectedBlockTime = ExpectedBlockTime; type EpochChangeTrigger = pallet_babe::ExternalTrigger; type DisabledValidators = Session; - type WeightInfo = (); + type WeightInfo = testnet_weights::pallet_babe::WeightInfo; type MaxAuthorities = MaxAuthorities; type MaxNominators = ConstU32<0>; @@ -435,7 +435,7 @@ parameter_types! { impl pallet_grandpa::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type WeightInfo = (); + type WeightInfo = testnet_weights::pallet_grandpa::WeightInfo; type MaxAuthorities = MaxAuthorities; type MaxNominators = ConstU32<0>; type MaxSetIdSessionEntries = MaxSetIdSessionEntries; @@ -645,7 +645,7 @@ impl pallet_identity::Config for Runtime { type PendingUsernameExpiration = PendingUsernameExpiration; type MaxSuffixLength = MaxSuffixLength; type MaxUsernameLength = MaxUsernameLength; - type WeightInfo = (); + type WeightInfo = pallet_identity::weights::SubstrateWeight; type UsernameDeposit = (); type UsernameGracePeriod = (); @@ -1633,7 +1633,7 @@ impl pallet_external_validator_slashes::Config for Runtime { type InvulnerablesProvider = ExternalValidators; type ExternalIndexProvider = ExternalValidators; type QueuedSlashesProcessedPerBlock = ConstU32<10>; - type WeightInfo = (); // TODO: calculate weights + type WeightInfo = testnet_weights::pallet_external_validator_slashes::WeightInfo; type SendMessage = SlashesSendAdapter; } diff --git a/operator/runtime/testnet/src/configs/storagehub/mod.rs b/operator/runtime/testnet/src/configs/storagehub/mod.rs index 3c15214d..ff265f5d 100644 --- a/operator/runtime/testnet/src/configs/storagehub/mod.rs +++ b/operator/runtime/testnet/src/configs/storagehub/mod.rs @@ -105,7 +105,7 @@ impl pallet_randomness::Config for Runtime { type RuntimeEvent = RuntimeEvent; type BabeDataGetter = BabeDataGetter; type BabeBlockGetter = BlockNumberGetter; - type WeightInfo = (); + type WeightInfo = crate::weights::pallet_randomness::WeightInfo; type BabeDataGetterBlockNumber = BlockNumber; } diff --git a/operator/runtime/testnet/src/weights/mod.rs b/operator/runtime/testnet/src/weights/mod.rs index 825aabed..042d203d 100644 --- a/operator/runtime/testnet/src/weights/mod.rs +++ b/operator/runtime/testnet/src/weights/mod.rs @@ -19,6 +19,7 @@ // DataHaven pallets pub mod pallet_datahaven_native_transfer; +pub mod pallet_external_validator_slashes; pub mod pallet_external_validators; pub mod pallet_external_validators_rewards; @@ -31,9 +32,12 @@ pub mod snowbridge_pallet_system_v2; // Substrate pallets pub mod frame_system; +pub mod pallet_babe; pub mod pallet_balances; pub mod pallet_beefy_mmr; pub mod pallet_evm; +pub mod pallet_grandpa; +pub mod pallet_randomness; //pub mod pallet_identity; pub mod pallet_im_online; pub mod pallet_message_queue; diff --git a/operator/runtime/testnet/src/weights/pallet_babe.rs b/operator/runtime/testnet/src/weights/pallet_babe.rs new file mode 100644 index 00000000..bbd5ec48 --- /dev/null +++ b/operator/runtime/testnet/src/weights/pallet_babe.rs @@ -0,0 +1,48 @@ + + +//! Autogenerated weights for `pallet_babe` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-30, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-testnet-runtime/datahaven_testnet_runtime.compact.compressed.wasm +// --pallet +// pallet_babe +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/testnet/src/weights/pallet_babe.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_babe`. +pub struct WeightInfo(PhantomData); +impl pallet_babe::WeightInfo for WeightInfo { + fn plan_config_change() -> Weight { + Weight::from_parts(5_000_000, 0) + } + + fn report_equivocation(_equivocations: u32, _key_owners: u32) -> Weight { + Weight::from_parts(89_841_267, 0) + } +} diff --git a/operator/runtime/testnet/src/weights/pallet_external_validator_slashes.rs b/operator/runtime/testnet/src/weights/pallet_external_validator_slashes.rs new file mode 100644 index 00000000..ae8c13e4 --- /dev/null +++ b/operator/runtime/testnet/src/weights/pallet_external_validator_slashes.rs @@ -0,0 +1,115 @@ + + +//! Autogenerated weights for `pallet_external_validator_slashes` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-testnet-runtime/datahaven_testnet_runtime.compact.compressed.wasm +// --pallet +// pallet_external_validator_slashes +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/testnet/src/weights/pallet_external_validator_slashes.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_external_validator_slashes`. +pub struct WeightInfo(PhantomData); +impl pallet_external_validator_slashes::weights::WeightInfo for WeightInfo { + /// Storage: `ExternalValidators::ActiveEra` (r:1 w:0) + /// Proof: `ExternalValidators::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::Slashes` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::Slashes` (`max_values`: None, `max_size`: None, mode: `Measured`) + /// The range of component `s` is `[1, 1000]`. + fn cancel_deferred_slash(_s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `38528` + // Estimated: `41993` + // Minimum execution time: 77_069_000 picoseconds. + Weight::from_parts(1_419_406_561, 41993) + .saturating_add(T::DbWeight::get().reads(2_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: `ExternalValidators::ActiveEra` (r:1 w:0) + /// Proof: `ExternalValidators::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidators::ErasStartSessionIndex` (r:1 w:0) + /// Proof: `ExternalValidators::ErasStartSessionIndex` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::NextSlashId` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::NextSlashId` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::ValidatorSlashInEra` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::ValidatorSlashInEra` (`max_values`: None, `max_size`: Some(44), added: 2519, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::Slashes` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::Slashes` (`max_values`: None, `max_size`: None, mode: `Measured`) + fn force_inject_slash() -> Weight { + // Proof Size summary in bytes: + // Measured: `492` + // Estimated: `3957` + // Minimum execution time: 27_830_000 picoseconds. + Weight::from_parts(28_371_000, 3957) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(3_u64)) + } + /// Storage: `ExternalValidators::ActiveEra` (r:1 w:0) + /// Proof: `ExternalValidators::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`) + /// Storage: `ExternalValidatorsSlashes::UnreportedSlashesQueue` (r:1 w:1) + /// Proof: `ExternalValidatorsSlashes::UnreportedSlashesQueue` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) + /// Storage: `Parameters::Parameters` (r:2 w:0) + /// Proof: `Parameters::Parameters` (`max_values`: None, `max_size`: Some(52), added: 2527, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::BookStateFor` (r:1 w:1) + /// Proof: `MessageQueue::BookStateFor` (`max_values`: None, `max_size`: Some(136), added: 2611, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::ServiceHead` (r:1 w:1) + /// Proof: `MessageQueue::ServiceHead` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `MessageQueue::Pages` (r:0 w:1) + /// Proof: `MessageQueue::Pages` (`max_values`: None, `max_size`: Some(32845), added: 35320, mode: `MaxEncodedLen`) + /// The range of component `s` is `[1, 200]`. + fn process_slashes_queue(s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `541 + s * (38 ±0)` + // Estimated: `6044 + s * (38 ±0)` + // Minimum execution time: 49_704_000 picoseconds. + Weight::from_parts(51_458_451, 6044) + // Standard Error: 674 + .saturating_add(Weight::from_parts(45_427, 0).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(6_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + .saturating_add(Weight::from_parts(0, 38).saturating_mul(s.into())) + } + /// Storage: `ExternalValidatorsSlashes::SlashingMode` (r:0 w:1) + /// Proof: `ExternalValidatorsSlashes::SlashingMode` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`) + fn set_slashing_mode() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_748_000 picoseconds. + Weight::from_parts(3_946_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + + fn root_test_send_msg_to_eth() -> Weight { + Weight::from_parts(1_015_195_000, 3601) + .saturating_add(T::DbWeight::get().reads(3_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } +} diff --git a/operator/runtime/testnet/src/weights/pallet_grandpa.rs b/operator/runtime/testnet/src/weights/pallet_grandpa.rs new file mode 100644 index 00000000..58d4299d --- /dev/null +++ b/operator/runtime/testnet/src/weights/pallet_grandpa.rs @@ -0,0 +1,55 @@ + + +//! Autogenerated weights for `pallet_grandpa` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-30, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-testnet-runtime/datahaven_testnet_runtime.compact.compressed.wasm +// --pallet +// pallet_grandpa +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/testnet/src/weights/pallet_grandpa.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_grandpa`. +pub struct WeightInfo(PhantomData); +impl pallet_grandpa::WeightInfo for WeightInfo { + /// Storage: `Grandpa::Stalled` (r:0 w:1) + /// Proof: `Grandpa::Stalled` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + fn note_stalled() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_827_000 picoseconds. + Weight::from_parts(3_954_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + + fn report_equivocation(_equivocations: u32, _key_owners: u32) -> Weight { + Weight::from_parts(79_198_467, 0) + } +} diff --git a/operator/runtime/testnet/src/weights/pallet_randomness.rs b/operator/runtime/testnet/src/weights/pallet_randomness.rs new file mode 100644 index 00000000..c206ef94 --- /dev/null +++ b/operator/runtime/testnet/src/weights/pallet_randomness.rs @@ -0,0 +1,77 @@ + + +//! Autogenerated weights for `pallet_randomness` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 51.0.0 +//! DATE: 2025-10-31, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `ip-10-0-0-176`, CPU: `Intel(R) Xeon(R) Platinum 8375C CPU @ 2.90GHz` +//! WASM-EXECUTION: Compiled, CHAIN: None, DB CACHE: 1024 + +// Executed Command: +// frame-omni-bencher +// v1 +// benchmark +// pallet +// --runtime +// target/production/wbuild/datahaven-testnet-runtime/datahaven_testnet_runtime.compact.compressed.wasm +// --pallet +// pallet_randomness +// --extrinsic +// +// --template +// benchmarking/frame-weight-template.hbs +// --output +// runtime/testnet/src/weights/pallet_randomness.rs +// --steps +// 50 +// --repeat +// 20 + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use sp_std::marker::PhantomData; + +/// Weights for `pallet_randomness`. +pub struct WeightInfo(PhantomData); +impl pallet_randomness::weights::WeightInfo for WeightInfo { + /// Storage: `Babe::AuthorVrfRandomness` (r:1 w:0) + /// Proof: `Babe::AuthorVrfRandomness` (`max_values`: Some(1), `max_size`: Some(33), added: 528, mode: `MaxEncodedLen`) + /// Storage: `Randomness::RelayEpoch` (r:1 w:1) + /// Proof: `Randomness::RelayEpoch` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Babe::NextRandomness` (r:1 w:0) + /// Proof: `Babe::NextRandomness` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// Storage: `Babe::EpochStart` (r:1 w:0) + /// Proof: `Babe::EpochStart` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Randomness::LastRelayBlockAndParaBlockValidForNextEpoch` (r:1 w:1) + /// Proof: `Randomness::LastRelayBlockAndParaBlockValidForNextEpoch` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`) + /// Storage: `Randomness::LatestOneEpochAgoRandomness` (r:0 w:1) + /// Proof: `Randomness::LatestOneEpochAgoRandomness` (`max_values`: Some(1), `max_size`: Some(36), added: 531, mode: `MaxEncodedLen`) + /// Storage: `Randomness::LatestParentBlockRandomness` (r:0 w:1) + /// Proof: `Randomness::LatestParentBlockRandomness` (`max_values`: Some(1), `max_size`: Some(36), added: 531, mode: `MaxEncodedLen`) + /// Storage: `Randomness::InherentIncluded` (r:0 w:1) + /// Proof: `Randomness::InherentIncluded` (`max_values`: Some(1), `max_size`: Some(0), added: 495, mode: `MaxEncodedLen`) + fn set_babe_randomness() -> Weight { + // Proof Size summary in bytes: + // Measured: `348` + // Estimated: `1518` + // Minimum execution time: 25_653_000 picoseconds. + Weight::from_parts(26_835_000, 1518) + .saturating_add(T::DbWeight::get().reads(5_u64)) + .saturating_add(T::DbWeight::get().writes(5_u64)) + } + /// Storage: `Randomness::InherentIncluded` (r:1 w:1) + /// Proof: `Randomness::InherentIncluded` (`max_values`: Some(1), `max_size`: Some(0), added: 495, mode: `MaxEncodedLen`) + fn on_finalize_hook() -> Weight { + // Proof Size summary in bytes: + // Measured: `99` + // Estimated: `1485` + // Minimum execution time: 5_406_000 picoseconds. + Weight::from_parts(5_749_000, 1485) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +} From 10a780564884a5b6097957a5b28bf5bee7a579ff Mon Sep 17 00:00:00 2001 From: Steve Degosserie <723552+stiiifff@users.noreply.github.com> Date: Sun, 2 Nov 2025 23:32:59 +0200 Subject: [PATCH 08/11] =?UTF-8?q?feat:=20=E2=9C=A8=20Add=20CI=20license=20?= =?UTF-8?q?check=20(#269)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Adds automated license compliance checking via GitHub Actions CI workflow - Implements a license verification script that validates all Rust dependencies against approved licenses, authors, and packages - Standardizes author metadata across Cargo manifests to "Moonsong Labs" ## Changes **CI Workflow** (`.github/workflows/task-check-licenses.yml`) - Triggers on pull requests and manual dispatch - Installs Rust 1.88.0 toolchain and `cargo-license` tool - Executes license verification script to enforce compliance **License Verification Script** (`operator/scripts/verify-licenses.sh`) - Uses `cargo-license` to extract dependency license information - Maintains three allowlists: - **Licenses**: Apache-2.0, MIT, BSD variants, GPL-3.0, MPL-2.0, and compatible combinations - **Authors**: PureStake, Parity Technologies, Moonsong Labs, Frontier developers, StorageHub Team - **Package Names**: Known safe packages like ring - Fails the build if any dependency has unapproved license/author/name combination **Cargo Manifest Updates** - `operator/Cargo.toml`: Standardized workspace author to "Moonsong Labs" - `operator/precompiles/precompile-registry/Cargo.toml`: Uses workspace author field - `operator/runtime/common/Cargo.toml`: Added workspace author field ## Benefits - **Legal Compliance**: Ensures all dependencies use OSI-approved or compatible licenses - **Supply Chain Security**: Validates dependencies come from trusted sources - **Automated Enforcement**: Catches licensing issues during PR review rather than at release time - **Transparency**: Provides clear audit trail of approved licenses and authors --- .github/workflows/task-check-licenses.yml | 23 ++++++ operator/Cargo.toml | 4 +- .../precompile-registry/Cargo.toml | 2 +- operator/runtime/common/Cargo.toml | 1 + operator/scripts/verify-licenses.sh | 71 +++++++++++++++++++ 5 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/task-check-licenses.yml create mode 100755 operator/scripts/verify-licenses.sh diff --git a/.github/workflows/task-check-licenses.yml b/.github/workflows/task-check-licenses.yml new file mode 100644 index 00000000..117481c4 --- /dev/null +++ b/.github/workflows/task-check-licenses.yml @@ -0,0 +1,23 @@ +name: Check licenses + +on: + pull_request: + workflow_dispatch: + +jobs: + verify: + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v5 + - name: Install Rust toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: 1.88.0 + override: true + - name: Verify Licenses + working-directory: operator + run: | + cargo install cargo-license@0.7.0 + ./scripts/verify-licenses.sh diff --git a/operator/Cargo.toml b/operator/Cargo.toml index 17dfd655..1b5f6551 100644 --- a/operator/Cargo.toml +++ b/operator/Cargo.toml @@ -1,6 +1,6 @@ [workspace.package] -authors = ["MoonsongLabs "] -description = "DataHaven: A decentralized storage network with Ethereum and IPFS integration." +authors = ["Moonsong Labs"] +description = "DataHaven: A decentralized storage network with Ethereum and EigenLayer integration." edition = "2021" homepage = "https://datahaven.xyz/" license = "GPL-3" diff --git a/operator/precompiles/precompile-registry/Cargo.toml b/operator/precompiles/precompile-registry/Cargo.toml index 610982e9..2de466b5 100644 --- a/operator/precompiles/precompile-registry/Cargo.toml +++ b/operator/precompiles/precompile-registry/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-evm-precompile-registry" -authors = ["The DataHaven Team"] +authors = { workspace = true } description = "Registry of active precompiles" edition = "2021" version = { workspace = true } diff --git a/operator/runtime/common/Cargo.toml b/operator/runtime/common/Cargo.toml index 34129282..b9f3268d 100644 --- a/operator/runtime/common/Cargo.toml +++ b/operator/runtime/common/Cargo.toml @@ -1,4 +1,5 @@ [package] +authors = { workspace = true } description = "Common code used through the DataHaven network" edition = { workspace = true } name = "datahaven-runtime-common" diff --git a/operator/scripts/verify-licenses.sh b/operator/scripts/verify-licenses.sh new file mode 100755 index 00000000..7f1bf434 --- /dev/null +++ b/operator/scripts/verify-licenses.sh @@ -0,0 +1,71 @@ +#!/bin/bash + +cargo license --json > licenses.json +LICENSES=( + "(MIT OR Apache-2.0) AND Unicode-DFS-2016" + "(MIT OR Apache-2.0) AND Unicode-3.0" + "0BSD OR Apache-2.0 OR MIT" + "Apache-2.0 AND ISC" + "Apache-2.0 AND MIT" + "Apache-2.0 OR LGPL-2.1-or-later OR MIT" + "Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR MIT" + "Apache-2.0 OR Apache-2.0 WITH LLVM-exception OR CC0-1.0" + "Apache-2.0 OR BSD-1-Clause OR MIT" + "Apache-2.0 OR BSD-2-Clause OR MIT" + "Apache-2.0 OR BSD-3-Clause OR MIT" + "Apache-2.0 OR BSD-3-Clause" + "Apache-2.0 OR BSL-1.0" + "Apache-2.0 OR BSL-1.0 OR MIT" + "Apache-2.0 OR CC0-1.0 OR MIT-0" + "Apache-2.0 OR CC0-1.0" + "Apache-2.0 OR GPL-3.0" + "Apache-2.0 OR ISC OR MIT" + "Apache-2.0 OR MIT OR Zlib" + "Apache-2.0 OR MIT" + "(Apache-2.0 OR MIT) AND Apache-2.0" + "Apache-2.0 WITH LLVM-exception" + "Apache-2.0" + "BSD-2-Clause" + "BSD-3-Clause OR MIT" + "BSD-3-Clause" + "CC0-1.0" + "CDLA-Permissive-2.0" + "GPL-3.0-only" + "GPL-3.0-or-later WITH Classpath-exception-2.0" + "ISC" + "LGPL-3.0 OR MPL-2.0" + "MIT OR Unlicense" + "MIT" + "MPL-2.0" + "Zlib" + "Unicode-3.0" + "(Apache-2.0 OR MIT) AND Unicode-3.0" +) +AUTHORS=( + "PureStake" + "Parity Technologies " + "Moonsong Labs" + "moonbeam-foundation" + "Frontier developers " + "StorageHub Team" +) +NAMES=( + "ring" # v0.16.20 has null license metadata but contains Apache-2.0 AND ISC LICENSE file +) +licenses_filter=$(printf ' .license != "%s" and' "${LICENSES[@]}") +authors_filter=$(printf ' .authors != "%s" and' "${AUTHORS[@]}") +names_filter=$(printf ' .name != "%s" and' "${NAMES[@]}") +# "true" at the end is necessary to close the "and" conditional +filter="${licenses_filter}${authors_filter}${names_filter} true" + +echo -e "checking licenses with filter:\n$filter\n" +RESULT=$(jq "[.[] | select($filter)]" licenses.json) + +if [[ "$RESULT" == "[]" ]]; then + echo "OK !!" + exit 0 +else + echo -en "$RESULT\n" + echo "FAILURE !!" + exit 1 +fi From e248a48385220f742892b8cb367503b173208562 Mon Sep 17 00:00:00 2001 From: undercover-cactus Date: Mon, 3 Nov 2025 10:55:31 +0100 Subject: [PATCH 09/11] feat: add Slashing mode has a runtime configurable parameter (#272) Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com> --- .../external-validator-slashes/src/lib.rs | 9 +++++++++ .../external-validator-slashes/src/mock.rs | 9 +++++++++ operator/runtime/mainnet/src/configs/mod.rs | 3 +++ operator/runtime/stagenet/src/configs/mod.rs | 3 +++ operator/runtime/testnet/src/configs/mod.rs | 4 ++++ test/.papi/metadata/datahaven.scale | Bin 621031 -> 621085 bytes 6 files changed, 28 insertions(+) diff --git a/operator/pallets/external-validator-slashes/src/lib.rs b/operator/pallets/external-validator-slashes/src/lib.rs index e851f993..a730f770 100644 --- a/operator/pallets/external-validator-slashes/src/lib.rs +++ b/operator/pallets/external-validator-slashes/src/lib.rs @@ -159,6 +159,10 @@ pub mod pallet { /// The weight information of this pallet. type WeightInfo: WeightInfo; + + /// Slashing mode option configuration + #[pallet::constant] + type SlashingMode: Get; } #[pallet::error] @@ -362,6 +366,11 @@ pub mod pallet { let processed = Self::process_slashes_queue(T::QueuedSlashesProcessedPerBlock::get()); T::WeightInfo::process_slashes_queue(processed) } + + fn on_runtime_upgrade() -> Weight { + SlashingMode::::put(T::SlashingMode::get()); + T::DbWeight::get().writes(1) + } } } diff --git a/operator/pallets/external-validator-slashes/src/mock.rs b/operator/pallets/external-validator-slashes/src/mock.rs index 4024ca8f..8cda4b4d 100644 --- a/operator/pallets/external-validator-slashes/src/mock.rs +++ b/operator/pallets/external-validator-slashes/src/mock.rs @@ -14,6 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Tanssi. If not, see +use crate::SlashingModeOption; use frame_support::traits::OnInitialize; use pallet_external_validators::traits::ActiveEraInfo; use pallet_external_validators::traits::EraIndex; @@ -261,6 +262,14 @@ impl external_validator_slashes::Config for Test { type QueuedSlashesProcessedPerBlock = ConstU32<20>; type WeightInfo = (); type SendMessage = MockOkOutboundQueue; + type SlashingMode = SlashingMode; +} + +pub struct SlashingMode; +impl Get for SlashingMode { + fn get() -> SlashingModeOption { + SlashingModeOption::Enabled + } } pub struct FullIdentificationOf; diff --git a/operator/runtime/mainnet/src/configs/mod.rs b/operator/runtime/mainnet/src/configs/mod.rs index 3ba0563b..8dc917d3 100644 --- a/operator/runtime/mainnet/src/configs/mod.rs +++ b/operator/runtime/mainnet/src/configs/mod.rs @@ -40,6 +40,7 @@ use super::{ MAXIMUM_BLOCK_WEIGHT, NORMAL_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, VERSION, }; use codec::{Decode, Encode, MaxEncodedLen}; +use pallet_external_validator_slashes::SlashingModeOption; use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; @@ -1635,10 +1636,12 @@ impl pallet_external_validator_slashes::Config for Runtime { type QueuedSlashesProcessedPerBlock = ConstU32<10>; type WeightInfo = mainnet_weights::pallet_external_validator_slashes::WeightInfo; type SendMessage = SlashesSendAdapter; + type SlashingMode = SlashingMode; } parameter_types! { pub const SlashDeferDuration: EraIndex = polkadot_runtime_common::prod_or_fast!(0, 0); + pub const SlashingMode: SlashingModeOption = polkadot_runtime_common::prod_or_fast!(SlashingModeOption::Disabled, SlashingModeOption::Disabled); } #[cfg(test)] diff --git a/operator/runtime/stagenet/src/configs/mod.rs b/operator/runtime/stagenet/src/configs/mod.rs index c0281aef..ee123518 100644 --- a/operator/runtime/stagenet/src/configs/mod.rs +++ b/operator/runtime/stagenet/src/configs/mod.rs @@ -40,6 +40,7 @@ use super::{ MAXIMUM_BLOCK_WEIGHT, NORMAL_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, VERSION, }; use codec::{Decode, Encode, MaxEncodedLen}; +use pallet_external_validator_slashes::SlashingModeOption; use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; @@ -1634,10 +1635,12 @@ impl pallet_external_validator_slashes::Config for Runtime { type QueuedSlashesProcessedPerBlock = ConstU32<10>; type WeightInfo = stagenet_weights::pallet_external_validator_slashes::WeightInfo; type SendMessage = SlashesSendAdapter; + type SlashingMode = SlashingMode; } parameter_types! { pub const SlashDeferDuration: EraIndex = polkadot_runtime_common::prod_or_fast!(0, 0); + pub const SlashingMode: SlashingModeOption = polkadot_runtime_common::prod_or_fast!(SlashingModeOption::LogOnly, SlashingModeOption::LogOnly); } #[cfg(test)] diff --git a/operator/runtime/testnet/src/configs/mod.rs b/operator/runtime/testnet/src/configs/mod.rs index 7850619f..6d10b8e2 100644 --- a/operator/runtime/testnet/src/configs/mod.rs +++ b/operator/runtime/testnet/src/configs/mod.rs @@ -40,6 +40,7 @@ use super::{ MAXIMUM_BLOCK_WEIGHT, NORMAL_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, VERSION, }; use codec::{Decode, Encode, MaxEncodedLen}; +use pallet_external_validator_slashes::SlashingModeOption; use scale_info::TypeInfo; use sp_runtime::RuntimeDebug; @@ -1635,10 +1636,13 @@ impl pallet_external_validator_slashes::Config for Runtime { type QueuedSlashesProcessedPerBlock = ConstU32<10>; type WeightInfo = testnet_weights::pallet_external_validator_slashes::WeightInfo; type SendMessage = SlashesSendAdapter; + type SlashingMode = SlashingMode; } parameter_types! { pub const SlashDeferDuration: EraIndex = polkadot_runtime_common::prod_or_fast!(0, 0); + pub const SlashingMode: SlashingModeOption = polkadot_runtime_common::prod_or_fast!(SlashingModeOption::Disabled, SlashingModeOption::Disabled); + } #[cfg(test)] diff --git a/test/.papi/metadata/datahaven.scale b/test/.papi/metadata/datahaven.scale index 7898e7484570ca3d0561b33f12dfaffcc7f7bb81..bbf4e26cdc5ebb9184e3728c106237381ba092ac 100644 GIT binary patch delta 96 zcmaFF7M2#)7Pc1l7LF~P$;ONV+f$4=XE2%>1m`3cXJqE3`{t*l qcCxWBvh*mxgcNdtVhZ^MC7Jno3d#9-X_@JzMTsEZ_CF?^uU!CF6e6Sm delta 41 xcmbRHMfLe-)rJF7M2#)7Pc1l7LF~P$;OO4+f$4=XE1IzGUa^j0su!$4j=#k From 87eb1c16219d96f71ed9d523d1920c61ad160a7d Mon Sep 17 00:00:00 2001 From: Gonza Montiel Date: Mon, 3 Nov 2025 13:00:04 +0100 Subject: [PATCH 10/11] fix: add timestamp safe mode (#267) 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> --- operator/runtime/mainnet/src/configs/mod.rs | 4 +- operator/runtime/stagenet/src/configs/mod.rs | 4 +- operator/runtime/testnet/src/configs/mod.rs | 4 +- .../common/test-block/test-block-safe-mode.ts | 112 ++++++++++++++++++ 4 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 test/datahaven/suites/dev/common/test-block/test-block-safe-mode.ts diff --git a/operator/runtime/mainnet/src/configs/mod.rs b/operator/runtime/mainnet/src/configs/mod.rs index 8dc917d3..c5975427 100644 --- a/operator/runtime/mainnet/src/configs/mod.rs +++ b/operator/runtime/mainnet/src/configs/mod.rs @@ -244,6 +244,8 @@ impl Contains for SafeModeWhitelistedCalls { match call { // Core system calls RuntimeCall::System(_) => true, + RuntimeCall::Timestamp(_) => true, + RuntimeCall::Randomness(_) => true, // Safe mode management RuntimeCall::SafeMode(_) => true, // Transaction pause management @@ -258,8 +260,6 @@ impl Contains for SafeModeWhitelistedCalls { RuntimeCall::Referenda(_) => true, RuntimeCall::TechnicalCommittee(_) => true, RuntimeCall::TreasuryCouncil(_) => true, - // Block production - needed to continue producing blocks in safe mode - RuntimeCall::Randomness(_) => true, _ => false, } } diff --git a/operator/runtime/stagenet/src/configs/mod.rs b/operator/runtime/stagenet/src/configs/mod.rs index ee123518..8ae2c091 100644 --- a/operator/runtime/stagenet/src/configs/mod.rs +++ b/operator/runtime/stagenet/src/configs/mod.rs @@ -244,6 +244,8 @@ impl Contains for SafeModeWhitelistedCalls { match call { // Core system calls RuntimeCall::System(_) => true, + RuntimeCall::Timestamp(_) => true, + RuntimeCall::Randomness(_) => true, // Safe mode management RuntimeCall::SafeMode(_) => true, // Transaction pause management @@ -258,8 +260,6 @@ impl Contains for SafeModeWhitelistedCalls { RuntimeCall::Referenda(_) => true, RuntimeCall::TechnicalCommittee(_) => true, RuntimeCall::TreasuryCouncil(_) => true, - // Block production - needed to continue producing blocks in safe mode - RuntimeCall::Randomness(_) => true, _ => false, } } diff --git a/operator/runtime/testnet/src/configs/mod.rs b/operator/runtime/testnet/src/configs/mod.rs index 6d10b8e2..af392689 100644 --- a/operator/runtime/testnet/src/configs/mod.rs +++ b/operator/runtime/testnet/src/configs/mod.rs @@ -244,6 +244,8 @@ impl Contains for SafeModeWhitelistedCalls { match call { // Core system calls RuntimeCall::System(_) => true, + RuntimeCall::Timestamp(_) => true, + RuntimeCall::Randomness(_) => true, // Safe mode management RuntimeCall::SafeMode(_) => true, // Transaction pause management @@ -258,8 +260,6 @@ impl Contains for SafeModeWhitelistedCalls { RuntimeCall::Referenda(_) => true, RuntimeCall::TechnicalCommittee(_) => true, RuntimeCall::TreasuryCouncil(_) => true, - // Block production - needed to continue producing blocks in safe mode - RuntimeCall::Randomness(_) => true, _ => false, } } diff --git a/test/datahaven/suites/dev/common/test-block/test-block-safe-mode.ts b/test/datahaven/suites/dev/common/test-block/test-block-safe-mode.ts new file mode 100644 index 00000000..5cde0875 --- /dev/null +++ b/test/datahaven/suites/dev/common/test-block/test-block-safe-mode.ts @@ -0,0 +1,112 @@ +import { beforeAll, beforeEach, describeSuite, expect } from "@moonwall/cli"; +import type { ApiPromise } from "@polkadot/api"; + +describeSuite({ + id: "D010105", + title: "Safe Mode Block Production", + foundationMethods: "dev", + testCases: ({ context, it }) => { + let api: ApiPromise; + + beforeAll(async () => { + api = context.polkadotJs(); + }); + + async function getSubstrateBlockNumber(): Promise { + const blockNumber = await api.query.system.number(); + return blockNumber.toNumber(); + } + + beforeEach(async () => { + // Check if safe mode is already active from genesis + let enteredUntil = (await api.query.safeMode.enteredUntil()) as any; + + if (!enteredUntil.isSome) { + const enterSafeModeCall = api.tx.safeMode.forceEnter(); + const sudoTx = api.tx.sudo.sudo(enterSafeModeCall); + await context.createBlock(sudoTx); + + enteredUntil = (await api.query.safeMode.enteredUntil()) as any; + } + + expect(enteredUntil.isSome, "Safe mode should be active").to.be.true; + }); + + it({ + id: "T01", + title: "should produce blocks while in safe mode", + test: async () => { + const startBlock = await getSubstrateBlockNumber(); + + const blocksToCreate = 5; + for (let i = 0; i < blocksToCreate; i++) { + await context.createBlock(); + } + + const currentBlock = await getSubstrateBlockNumber(); + const blocksProduced = currentBlock - startBlock; + + expect(blocksProduced).to.be.greaterThanOrEqual( + blocksToCreate, + "Blocks should continue to be produced in safe mode" + ); + + const exitBlockBefore = await getSubstrateBlockNumber(); + const exitSafeModeCall = api.tx.safeMode.forceExit(); + const exitSudoTx = api.tx.sudo.sudo(exitSafeModeCall); + + await context.createBlock(exitSudoTx); + + // Verify the exit block was created (ensures state is updated) + const exitBlockAfter = await getSubstrateBlockNumber(); + expect(exitBlockAfter, "Exit block should have been created").to.be.greaterThan( + exitBlockBefore + ); + + const enteredUntilAfterExit = (await api.query.safeMode.enteredUntil()) as any; + expect(!enteredUntilAfterExit.isSome, "Safe mode should be deactivated").to.be.true; + + await context.createBlock(); + const finalBlock = await getSubstrateBlockNumber(); + expect(finalBlock).to.be.greaterThan(currentBlock); + } + }); + + it({ + id: "T02", + title: "should allow timestamp calls in safe mode", + test: async () => { + const startBlock = await getSubstrateBlockNumber(); + + // Create a block - this implicitly includes timestamp extrinsic + // The fact that this succeeds proves Timestamp is whitelisted + await context.createBlock(); + + // Verify the block was created (contains valid timestamp) + const block = await context.viem().getBlock({ blockTag: "latest" }); + expect(Number(block.timestamp)).to.be.greaterThan(0); + + // Verify block number increased + const currentBlock = await getSubstrateBlockNumber(); + expect(currentBlock).to.be.greaterThan(startBlock); + + // Exit safe mode + const exitBlockBefore = await getSubstrateBlockNumber(); + const exitSafeModeCall = api.tx.safeMode.forceExit(); + const exitSudoTx = api.tx.sudo.sudo(exitSafeModeCall); + + await context.createBlock(exitSudoTx); + + // Verify the exit block was created (ensures state is updated) + const exitBlockAfter = await getSubstrateBlockNumber(); + expect(exitBlockAfter, "Exit block should have been created").to.be.greaterThan( + exitBlockBefore + ); + + // Verify we exited safe mode + const enteredUntilAfterExit = (await api.query.safeMode.enteredUntil()) as any; + expect(!enteredUntilAfterExit.isSome, "Safe mode should be deactivated").to.be.true; + } + }); + } +}); From 1fd0abccd779a1f92a84c5664c40faa66d208324 Mon Sep 17 00:00:00 2001 From: Facundo Farall <37149322+ffarall@users.noreply.github.com> Date: Mon, 3 Nov 2025 14:49:30 +0100 Subject: [PATCH 11/11] =?UTF-8?q?build:=20=E2=AC=86=EF=B8=8F=20Upgrade=20t?= =?UTF-8?q?o=20SH=20v0.1.1=20(#273)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Co-authored-by: Steve Degosserie <723552+stiiifff@users.noreply.github.com> --- operator/Cargo.lock | 72 ++++++++-------- operator/Cargo.toml | 79 +++++++++--------- operator/node/src/cli.rs | 16 ++++ operator/node/src/service.rs | 4 +- operator/runtime/mainnet/Cargo.toml | 27 +++--- .../mainnet/src/configs/storagehub/mod.rs | 23 ++++- operator/runtime/mainnet/src/lib.rs | 3 + operator/runtime/stagenet/Cargo.toml | 25 +++--- .../stagenet/src/configs/storagehub/mod.rs | 23 ++++- operator/runtime/stagenet/src/lib.rs | 3 + operator/runtime/testnet/Cargo.toml | 25 +++--- .../testnet/src/configs/storagehub/mod.rs | 23 ++++- operator/runtime/testnet/src/lib.rs | 3 + test/.papi/descriptors/package.json | 2 +- test/.papi/metadata/datahaven.scale | Bin 621085 -> 622477 bytes 15 files changed, 213 insertions(+), 115 deletions(-) diff --git a/operator/Cargo.lock b/operator/Cargo.lock index 3705be6c..61d45ca2 100644 --- a/operator/Cargo.lock +++ b/operator/Cargo.lock @@ -2922,6 +2922,7 @@ dependencies = [ "frame-try-runtime", "hex", "hex-literal 0.3.4", + "itoa", "log", "num-bigint", "num_enum", @@ -3210,6 +3211,7 @@ dependencies = [ "frame-try-runtime", "hex", "hex-literal 0.3.4", + "itoa", "log", "num-bigint", "num_enum", @@ -3359,6 +3361,7 @@ dependencies = [ "frame-try-runtime", "hex", "hex-literal 0.3.4", + "itoa", "log", "num-bigint", "num_enum", @@ -8985,7 +8988,7 @@ dependencies = [ [[package]] name = "pallet-bucket-nfts" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "frame-benchmarking", "frame-support", @@ -9061,7 +9064,7 @@ dependencies = [ [[package]] name = "pallet-cr-randomness" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "frame-support", "frame-system", @@ -9320,7 +9323,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-file-system" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "fp-account", "fp-evm", @@ -9573,7 +9576,7 @@ dependencies = [ [[package]] name = "pallet-file-system" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "frame-benchmarking", "frame-support", @@ -9600,7 +9603,7 @@ dependencies = [ [[package]] name = "pallet-file-system-runtime-api" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "parity-scale-codec", "scale-info", @@ -9796,7 +9799,7 @@ dependencies = [ [[package]] name = "pallet-payment-streams" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "frame-benchmarking", "frame-support", @@ -9816,7 +9819,7 @@ dependencies = [ [[package]] name = "pallet-payment-streams-runtime-api" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "parity-scale-codec", "scale-info", @@ -9844,7 +9847,7 @@ dependencies = [ [[package]] name = "pallet-proofs-dealer" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "frame-benchmarking", "frame-support", @@ -9866,7 +9869,7 @@ dependencies = [ [[package]] name = "pallet-proofs-dealer-runtime-api" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "parity-scale-codec", "scale-info", @@ -9888,7 +9891,7 @@ dependencies = [ [[package]] name = "pallet-randomness" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "frame-benchmarking", "frame-support", @@ -10029,7 +10032,7 @@ dependencies = [ [[package]] name = "pallet-storage-providers" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "frame-benchmarking", "frame-support", @@ -10051,7 +10054,7 @@ dependencies = [ [[package]] name = "pallet-storage-providers-runtime-api" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "parity-scale-codec", "scale-info", @@ -15159,7 +15162,7 @@ dependencies = [ [[package]] name = "shc-actors-derive" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "once_cell", "proc-macro2", @@ -15172,7 +15175,7 @@ dependencies = [ [[package]] name = "shc-actors-framework" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "anyhow", "bincode", @@ -15190,7 +15193,7 @@ dependencies = [ [[package]] name = "shc-blockchain-service" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "anyhow", "array-bytes", @@ -15218,6 +15221,7 @@ dependencies = [ "sc-network-types", "sc-service", "sc-tracing", + "sc-transaction-pool-api", "sc-utils", "serde", "serde_json", @@ -15241,7 +15245,7 @@ dependencies = [ [[package]] name = "shc-client" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "anyhow", "array-bytes", @@ -15307,7 +15311,7 @@ dependencies = [ [[package]] name = "shc-common" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "anyhow", "bigdecimal", @@ -15371,7 +15375,7 @@ dependencies = [ [[package]] name = "shc-file-manager" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "bincode", "hash-db", @@ -15395,7 +15399,7 @@ dependencies = [ [[package]] name = "shc-file-transfer-service" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "anyhow", "array-bytes", @@ -15424,7 +15428,7 @@ dependencies = [ [[package]] name = "shc-fisherman-service" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "async-trait", "diesel", @@ -15454,7 +15458,7 @@ dependencies = [ [[package]] name = "shc-forest-manager" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "async-trait", "bincode", @@ -15479,7 +15483,7 @@ dependencies = [ [[package]] name = "shc-indexer-db" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "bigdecimal", "chrono", @@ -15507,7 +15511,7 @@ dependencies = [ [[package]] name = "shc-indexer-service" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "anyhow", "array-bytes", @@ -15558,7 +15562,7 @@ dependencies = [ [[package]] name = "shc-rpc" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "array-bytes", "async-trait", @@ -15609,7 +15613,7 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "shp-constants" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "sp-core", "sp-runtime", @@ -15618,7 +15622,7 @@ dependencies = [ [[package]] name = "shp-data-price-updater" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "frame-support", "parity-scale-codec", @@ -15633,7 +15637,7 @@ dependencies = [ [[package]] name = "shp-file-key-verifier" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "frame-support", "parity-scale-codec", @@ -15651,7 +15655,7 @@ dependencies = [ [[package]] name = "shp-file-metadata" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "hex", "num-bigint", @@ -15667,7 +15671,7 @@ dependencies = [ [[package]] name = "shp-forest-verifier" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "frame-support", "parity-scale-codec", @@ -15684,7 +15688,7 @@ dependencies = [ [[package]] name = "shp-opaque" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "parachains-common", "sp-runtime", @@ -15693,7 +15697,7 @@ dependencies = [ [[package]] name = "shp-session-keys" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "async-trait", "parity-scale-codec", @@ -15708,7 +15712,7 @@ dependencies = [ [[package]] name = "shp-traits" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "frame-support", "parity-scale-codec", @@ -15722,7 +15726,7 @@ dependencies = [ [[package]] name = "shp-treasury-funding" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "log", "shp-traits", @@ -15733,7 +15737,7 @@ dependencies = [ [[package]] name = "shp-types" version = "0.1.0" -source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.0.6-alpha#05d269a26d11c1ed8a6d917b3e08ff3b5d3d4b22" +source = "git+https://github.com/Moonsong-Labs/storage-hub.git?tag=v0.1.1#73241088333295db001818864a518b8c25896b5a" dependencies = [ "sp-core", "sp-runtime", diff --git a/operator/Cargo.toml b/operator/Cargo.toml index 1b5f6551..21c61287 100644 --- a/operator/Cargo.toml +++ b/operator/Cargo.toml @@ -27,11 +27,6 @@ datahaven-runtime-common = { path = "./runtime/common", default-features = false datahaven-stagenet-runtime = { path = "./runtime/stagenet", default-features = false } datahaven-testnet-runtime = { path = "./runtime/testnet", default-features = false } dhp-bridge = { path = "./primitives/bridge", default-features = false } -pallet-external-validators = { path = "./pallets/external-validators", default-features = false } -pallet-external-validators-rewards = { path = "./pallets/external-validators-rewards", default-features = false } -pallet-external-validators-rewards-runtime-api = { path = "./pallets/external-validators-rewards/runtime-api", default-features = false } -pallet-external-validator-slashes = { path = "./pallets/external-validator-slashes", default-features = false } -pallet-outbound-commitment-store = { path = "./pallets/outbound-commitment-store", default-features = false } pallet-datahaven-native-transfer = { path = "./pallets/datahaven-native-transfer", default-features = false } pallet-evm-precompile-balances-erc20 = { path = "./precompiles/erc20-balances", default-features = false } pallet-evm-precompile-batch = { path = "./precompiles/batch", default-features = false } @@ -43,6 +38,11 @@ pallet-evm-precompile-preimage = { path = "./precompiles/preimage", default-feat pallet-evm-precompile-proxy = { path = "./precompiles/proxy", default-features = false } pallet-evm-precompile-referenda = { path = "./precompiles/referenda", default-features = false } pallet-evm-precompile-registry = { path = "./precompiles/precompile-registry", default-features = false } +pallet-external-validator-slashes = { path = "./pallets/external-validator-slashes", default-features = false } +pallet-external-validators = { path = "./pallets/external-validators", default-features = false } +pallet-external-validators-rewards = { path = "./pallets/external-validators-rewards", default-features = false } +pallet-external-validators-rewards-runtime-api = { path = "./pallets/external-validators-rewards/runtime-api", default-features = false } +pallet-outbound-commitment-store = { path = "./pallets/outbound-commitment-store", default-features = false } # Crates.io (wasm) alloy-core = { version = "0.8.15", default-features = false } @@ -64,6 +64,7 @@ hex = { version = "0.4.3", default-features = false } hex-literal = { version = "0.3.4" } impl-serde = { version = "0.5.0", default-features = false } impl-trait-for-tuples = { version = "0.2.2" } +itoa = { version = "1.0" } jsonrpsee = { version = "0.24.3" } libsecp256k1 = { version = "0.7", default-features = false } log = { version = "0.4.25" } @@ -264,43 +265,43 @@ fc-storage = { git = "https://github.com/polkadot-evm/frontier", branch = "stabl # StorageHub ## Runtime -pallet-bucket-nfts = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -pallet-cr-randomness = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -pallet-file-system = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -pallet-file-system-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -pallet-payment-streams = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -pallet-payment-streams-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -pallet-proofs-dealer = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -pallet-proofs-dealer-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -pallet-randomness = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -pallet-storage-providers = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -pallet-storage-providers-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shp-constants = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shp-data-price-updater = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shp-file-key-verifier = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shp-file-metadata = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shp-forest-verifier = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shp-traits = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shp-treasury-funding = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -storage-hub-runtime = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } +pallet-bucket-nfts = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +pallet-cr-randomness = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +pallet-file-system = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +pallet-file-system-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +pallet-payment-streams = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +pallet-payment-streams-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +pallet-proofs-dealer = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +pallet-proofs-dealer-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +pallet-randomness = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +pallet-storage-providers = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +pallet-storage-providers-runtime-api = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shp-constants = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shp-data-price-updater = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shp-file-key-verifier = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shp-file-metadata = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shp-forest-verifier = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shp-traits = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shp-treasury-funding = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +storage-hub-runtime = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } ## Client cumulus-client-service = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-stable2412-6", default-features = false } -shc-actors-derive = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shc-actors-framework = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shc-blockchain-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shc-client = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shc-common = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shc-file-manager = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shc-file-transfer-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shc-fisherman-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shc-forest-manager = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shc-indexer-db = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shc-indexer-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shc-rpc = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shp-opaque = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } -shp-types = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } +shc-actors-derive = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shc-actors-framework = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shc-blockchain-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shc-client = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shc-common = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shc-file-manager = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shc-file-transfer-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shc-fisherman-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shc-forest-manager = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shc-indexer-db = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shc-indexer-service = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shc-rpc = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shp-opaque = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } +shp-types = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } ## Precompiles -pallet-evm-precompile-file-system = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.0.6-alpha", default-features = false } +pallet-evm-precompile-file-system = { git = "https://github.com/Moonsong-Labs/storage-hub.git", tag = "v0.1.1", default-features = false } # The list of dependencies below (which can be both direct and indirect dependencies) are crates # that are suspected to be CPU-intensive, and that are unlikely to require debugging (as some of diff --git a/operator/node/src/cli.rs b/operator/node/src/cli.rs index 5cca9cde..cd7bf3fb 100644 --- a/operator/node/src/cli.rs +++ b/operator/node/src/cli.rs @@ -600,6 +600,19 @@ pub struct FishermanConfigurations { required_if_eq("fisherman", "true") )] pub fisherman_database_url: Option, + + /// Maximum number of incomplete storage requests to process after the first block processed coming out of syncing mode. + #[arg(long, value_name = "COUNT", default_value = "10000", value_parser = clap::value_parser!(u32).range(1..))] + pub fisherman_incomplete_sync_max: u32, + + /// Page size for incomplete storage request pagination. + /// Must be at least 1. + #[arg(long, value_name = "SIZE", default_value = "256", value_parser = clap::value_parser!(u32).range(1..))] + pub fisherman_incomplete_sync_page_size: u32, + + /// The minimum number of blocks between the last processed block and the current best block to consider the fisherman out of sync. + #[arg(long, default_value = "5")] + pub fisherman_sync_mode_min_blocks_behind: u32, } impl FishermanConfigurations { @@ -610,6 +623,9 @@ impl FishermanConfigurations { .fisherman_database_url .clone() .expect("Fisherman database URL is required"), + incomplete_sync_max: self.fisherman_incomplete_sync_max, + incomplete_sync_page_size: self.fisherman_incomplete_sync_page_size, + sync_mode_min_blocks_behind: self.fisherman_sync_mode_min_blocks_behind, maintenance_mode: false, // Skipping maintenance mode for now }) } else { diff --git a/operator/node/src/service.rs b/operator/node/src/service.rs index fe191f4f..7f3316a2 100644 --- a/operator/node/src/service.rs +++ b/operator/node/src/service.rs @@ -1246,7 +1246,9 @@ async fn configure_and_spawn_fisherman( fisherman_builder.with_indexer_db_pool(Some(db_pool.clone())); // Spawn the fisherman service - fisherman_builder.with_fisherman(client.clone()).await; + fisherman_builder + .with_fisherman(client.clone(), &fisherman_options) + .await; // All variables below are not needed for the fisherman service to operate but required by the StorageHubHandler // TODO: Refactor this once we have a proper setup to support role based StorageHubHandler builder diff --git a/operator/runtime/mainnet/Cargo.toml b/operator/runtime/mainnet/Cargo.toml index b65b736b..30c2d90a 100644 --- a/operator/runtime/mainnet/Cargo.toml +++ b/operator/runtime/mainnet/Cargo.toml @@ -27,11 +27,11 @@ frame-metadata-hash-extension = { workspace = true } frame-support = { workspace = true, features = ["experimental"] } frame-system = { workspace = true } frame-system-benchmarking = { workspace = true, optional = true } -pallet-session-benchmarking = { workspace = true, optional = true } frame-system-rpc-runtime-api = { workspace = true } frame-try-runtime = { workspace = true, optional = true } hex = { workspace = true } hex-literal = { workspace = true } +itoa = { workspace = true } log = { workspace = true } num-bigint = { workspace = true } num_enum = { workspace = true } @@ -42,6 +42,7 @@ pallet-beefy = { workspace = true } pallet-beefy-mmr = { workspace = true } pallet-collective = { workspace = true } pallet-conviction-voting = { workspace = true } +pallet-datahaven-native-transfer = { workspace = true } pallet-ethereum = { workspace = true, features = ["forbid-evm-reentrancy"] } pallet-evm = { workspace = true, features = ["forbid-evm-reentrancy"] } pallet-evm-chain-id = { workspace = true } @@ -50,10 +51,10 @@ pallet-evm-precompile-bn128 = { workspace = true } pallet-evm-precompile-modexp = { workspace = true } pallet-evm-precompile-sha3fips = { workspace = true } pallet-evm-precompile-simple = { workspace = true } +pallet-external-validator-slashes = { workspace = true } pallet-external-validators = { workspace = true } pallet-external-validators-rewards = { workspace = true } pallet-external-validators-rewards-runtime-api = { workspace = true } -pallet-external-validator-slashes = { workspace = true } pallet-grandpa = { workspace = true } pallet-identity = { workspace = true } pallet-im-online = { workspace = true } @@ -63,20 +64,20 @@ pallet-mmr = { workspace = true } pallet-multisig = { workspace = true } pallet-offences = { workspace = true } pallet-outbound-commitment-store = { workspace = true } -pallet-datahaven-native-transfer = { workspace = true } pallet-parameters = { workspace = true } pallet-preimage = { workspace = true } -pallet-safe-mode = { workspace = true } -pallet-tx-pause = { workspace = true } pallet-proxy = { workspace = true } pallet-referenda = { workspace = true } +pallet-safe-mode = { workspace = true } pallet-scheduler = { workspace = true } pallet-session = { workspace = true } +pallet-session-benchmarking = { workspace = true, optional = true } pallet-sudo = { workspace = true } pallet-timestamp = { workspace = true } pallet-transaction-payment = { workspace = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true } pallet-treasury = { workspace = true } +pallet-tx-pause = { workspace = true } pallet-utility = { workspace = true } pallet-whitelist = { workspace = true } polkadot-primitives = { workspace = true } @@ -118,11 +119,11 @@ sp-std = { workspace = true } sp-storage = { workspace = true } sp-transaction-pool = { workspace = true } sp-version = { workspace = true, features = ["serde"] } +strum = { workspace = true } +strum_macros = { workspace = true } xcm = { workspace = true } xcm-builder = { workspace = true } xcm-executor = { workspace = true } -strum = { workspace = true } -strum_macros = { workspace = true } # DataHaven precompiles pallet-evm-precompile-balances-erc20 = { workspace = true } @@ -138,10 +139,11 @@ pallet-evm-precompile-registry = { workspace = true } # StorageHub pallet-bucket-nfts = { workspace = true } -pallet-nfts = { workspace = true } pallet-cr-randomness = { workspace = true } +pallet-evm-precompile-file-system = { workspace = true } pallet-file-system = { workspace = true } pallet-file-system-runtime-api = { workspace = true } +pallet-nfts = { workspace = true } pallet-payment-streams = { workspace = true } pallet-payment-streams-runtime-api = { workspace = true } pallet-proofs-dealer = { workspace = true } @@ -151,14 +153,13 @@ pallet-storage-providers = { workspace = true } pallet-storage-providers-runtime-api = { workspace = true } shc-common = { workspace = true, optional = true } shp-constants = { workspace = true } +shp-data-price-updater = { workspace = true } +shp-file-key-verifier = { workspace = true } shp-file-metadata = { workspace = true } +shp-forest-verifier = { workspace = true } shp-traits = { workspace = true } shp-treasury-funding = { workspace = true } -shp-forest-verifier = { workspace = true } -shp-file-key-verifier = { workspace = true } -shp-data-price-updater = { workspace = true } sp-trie = { workspace = true } -pallet-evm-precompile-file-system = { workspace = true } [build-dependencies] substrate-wasm-builder = { workspace = true, optional = true, default-features = true } @@ -173,9 +174,9 @@ precompile-utils = { workspace = true, features = ["std", "testing"] } # Snowbridge testing snowbridge-core = { workspace = true } +snowbridge-outbound-queue-primitives = { workspace = true } snowbridge-pallet-system = { workspace = true } snowbridge-pallet-system-v2 = { workspace = true } -snowbridge-outbound-queue-primitives = { workspace = true } [features] default = ["std"] diff --git a/operator/runtime/mainnet/src/configs/storagehub/mod.rs b/operator/runtime/mainnet/src/configs/storagehub/mod.rs index ff265f5d..72d42735 100644 --- a/operator/runtime/mainnet/src/configs/storagehub/mod.rs +++ b/operator/runtime/mainnet/src/configs/storagehub/mod.rs @@ -37,7 +37,7 @@ use sp_runtime::traits::Zero; use sp_runtime::SaturatedConversion; use sp_runtime::{traits::BlakeTwo256, Perbill}; use sp_std::convert::{From, Into}; -use sp_std::vec; +use sp_std::{vec, vec::Vec}; use sp_trie::{LayoutV1, TrieConfiguration, TrieLayout}; #[cfg(feature = "std")] @@ -450,6 +450,25 @@ parameter_types! { pub const FileSystemFileDeletionRequestHoldReason: RuntimeHoldReason = RuntimeHoldReason::FileSystem(pallet_file_system::HoldReason::FileDeletionRequestHold); } +// Converts a given signed message in a EIP-191 compliant message bytes to verify. +/// EIP-191: https://eips.ethereum.org/EIPS/eip-191 +/// "\x19Ethereum Signed Message:\n" + len(message) + message" +pub struct Eip191Adapter; +impl shp_traits::MessageAdapter for Eip191Adapter { + fn bytes_to_verify(message: &[u8]) -> Vec { + const PREFIX: &str = "\x19Ethereum Signed Message:\n"; + let len = message.len(); + let mut len_string_buffer = itoa::Buffer::new(); + let len_string = len_string_buffer.format(len); + + let mut eth_message = Vec::with_capacity(PREFIX.len() + len_string.len() + len); + eth_message.extend_from_slice(PREFIX.as_bytes()); + eth_message.extend_from_slice(len_string.as_bytes()); + eth_message.extend_from_slice(message); + eth_message + } +} + impl pallet_file_system::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_file_system::weights::SubstrateWeight; @@ -501,6 +520,8 @@ impl pallet_file_system::Config for Runtime { type TickRangeToMaximumThreshold = runtime_config::TickRangeToMaximumThreshold; type OffchainSignature = Signature; type OffchainPublicKey = ::Signer; + type MaxFileDeletionsPerExtrinsic = ConstU32<100>; + type IntentionMsgAdapter = Eip191Adapter; } impl MostlyStablePriceIndexUpdaterConfig for Runtime { diff --git a/operator/runtime/mainnet/src/lib.rs b/operator/runtime/mainnet/src/lib.rs index 5dfb795d..ee307e30 100644 --- a/operator/runtime/mainnet/src/lib.rs +++ b/operator/runtime/mainnet/src/lib.rs @@ -1245,6 +1245,9 @@ impl_runtime_apis! { fn query_incomplete_storage_request_metadata(file_key: H256) -> Result, StorageDataUnit, H256, BackupStorageProviderId>, QueryIncompleteStorageRequestMetadataError> { FileSystem::query_incomplete_storage_request_metadata(file_key) } + fn list_incomplete_storage_request_keys(start_after: Option, limit: u32) -> Vec { + FileSystem::list_incomplete_storage_request_keys(start_after, limit) + } } impl pallet_payment_streams_runtime_api::PaymentStreamsApi, Balance, AccountId> for Runtime { diff --git a/operator/runtime/stagenet/Cargo.toml b/operator/runtime/stagenet/Cargo.toml index 9e31449c..9cee50bc 100644 --- a/operator/runtime/stagenet/Cargo.toml +++ b/operator/runtime/stagenet/Cargo.toml @@ -27,11 +27,11 @@ frame-metadata-hash-extension = { workspace = true } frame-support = { workspace = true, features = ["experimental"] } frame-system = { workspace = true } frame-system-benchmarking = { workspace = true, optional = true } -pallet-session-benchmarking = { workspace = true, optional = true } frame-system-rpc-runtime-api = { workspace = true } frame-try-runtime = { workspace = true, optional = true } hex = { workspace = true } hex-literal = { workspace = true } +itoa = { workspace = true } log = { workspace = true } num-bigint = { workspace = true } num_enum = { workspace = true } @@ -42,6 +42,7 @@ pallet-beefy = { workspace = true } pallet-beefy-mmr = { workspace = true } pallet-collective = { workspace = true } pallet-conviction-voting = { workspace = true } +pallet-datahaven-native-transfer = { workspace = true } pallet-ethereum = { workspace = true, features = ["forbid-evm-reentrancy"] } pallet-evm = { workspace = true, features = ["forbid-evm-reentrancy"] } pallet-evm-chain-id = { workspace = true } @@ -50,10 +51,10 @@ pallet-evm-precompile-bn128 = { workspace = true } pallet-evm-precompile-modexp = { workspace = true } pallet-evm-precompile-sha3fips = { workspace = true } pallet-evm-precompile-simple = { workspace = true } +pallet-external-validator-slashes = { workspace = true } pallet-external-validators = { workspace = true } pallet-external-validators-rewards = { workspace = true } pallet-external-validators-rewards-runtime-api = { workspace = true } -pallet-external-validator-slashes = { workspace = true } pallet-grandpa = { workspace = true } pallet-identity = { workspace = true } pallet-im-online = { workspace = true } @@ -63,20 +64,20 @@ pallet-mmr = { workspace = true } pallet-multisig = { workspace = true } pallet-offences = { workspace = true } pallet-outbound-commitment-store = { workspace = true } -pallet-datahaven-native-transfer = { workspace = true } pallet-parameters = { workspace = true } pallet-preimage = { workspace = true } -pallet-safe-mode = { workspace = true } -pallet-tx-pause = { workspace = true } pallet-proxy = { workspace = true } pallet-referenda = { workspace = true } +pallet-safe-mode = { workspace = true } pallet-scheduler = { workspace = true } pallet-session = { workspace = true } +pallet-session-benchmarking = { workspace = true, optional = true } pallet-sudo = { workspace = true } pallet-timestamp = { workspace = true } pallet-transaction-payment = { workspace = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true } pallet-treasury = { workspace = true } +pallet-tx-pause = { workspace = true } pallet-utility = { workspace = true } pallet-whitelist = { workspace = true } polkadot-primitives = { workspace = true } @@ -128,20 +129,21 @@ xcm-executor = { workspace = true } pallet-evm-precompile-balances-erc20 = { workspace = true } pallet-evm-precompile-batch = { workspace = true } pallet-evm-precompile-call-permit = { workspace = true } -pallet-evm-precompile-preimage = { workspace = true } pallet-evm-precompile-collective = { workspace = true } pallet-evm-precompile-conviction-voting = { workspace = true } pallet-evm-precompile-identity = { workspace = true } +pallet-evm-precompile-preimage = { workspace = true } pallet-evm-precompile-proxy = { workspace = true } pallet-evm-precompile-referenda = { workspace = true } pallet-evm-precompile-registry = { workspace = true } # StorageHub pallet-bucket-nfts = { workspace = true } -pallet-nfts = { workspace = true } pallet-cr-randomness = { workspace = true } +pallet-evm-precompile-file-system = { workspace = true } pallet-file-system = { workspace = true } pallet-file-system-runtime-api = { workspace = true } +pallet-nfts = { workspace = true } pallet-payment-streams = { workspace = true } pallet-payment-streams-runtime-api = { workspace = true } pallet-proofs-dealer = { workspace = true } @@ -151,14 +153,13 @@ pallet-storage-providers = { workspace = true } pallet-storage-providers-runtime-api = { workspace = true } shc-common = { workspace = true, optional = true } shp-constants = { workspace = true } +shp-data-price-updater = { workspace = true } +shp-file-key-verifier = { workspace = true } shp-file-metadata = { workspace = true } +shp-forest-verifier = { workspace = true } shp-traits = { workspace = true } shp-treasury-funding = { workspace = true } -shp-forest-verifier = { workspace = true } -shp-file-key-verifier = { workspace = true } -shp-data-price-updater = { workspace = true } sp-trie = { workspace = true } -pallet-evm-precompile-file-system = { workspace = true } [build-dependencies] substrate-wasm-builder = { workspace = true, optional = true, default-features = true } @@ -173,9 +174,9 @@ precompile-utils = { workspace = true, features = ["std", "testing"] } # Snowbridge testing snowbridge-core = { workspace = true } +snowbridge-outbound-queue-primitives = { workspace = true } snowbridge-pallet-system = { workspace = true } snowbridge-pallet-system-v2 = { workspace = true } -snowbridge-outbound-queue-primitives = { workspace = true } [features] default = ["std"] diff --git a/operator/runtime/stagenet/src/configs/storagehub/mod.rs b/operator/runtime/stagenet/src/configs/storagehub/mod.rs index ff265f5d..72d42735 100644 --- a/operator/runtime/stagenet/src/configs/storagehub/mod.rs +++ b/operator/runtime/stagenet/src/configs/storagehub/mod.rs @@ -37,7 +37,7 @@ use sp_runtime::traits::Zero; use sp_runtime::SaturatedConversion; use sp_runtime::{traits::BlakeTwo256, Perbill}; use sp_std::convert::{From, Into}; -use sp_std::vec; +use sp_std::{vec, vec::Vec}; use sp_trie::{LayoutV1, TrieConfiguration, TrieLayout}; #[cfg(feature = "std")] @@ -450,6 +450,25 @@ parameter_types! { pub const FileSystemFileDeletionRequestHoldReason: RuntimeHoldReason = RuntimeHoldReason::FileSystem(pallet_file_system::HoldReason::FileDeletionRequestHold); } +// Converts a given signed message in a EIP-191 compliant message bytes to verify. +/// EIP-191: https://eips.ethereum.org/EIPS/eip-191 +/// "\x19Ethereum Signed Message:\n" + len(message) + message" +pub struct Eip191Adapter; +impl shp_traits::MessageAdapter for Eip191Adapter { + fn bytes_to_verify(message: &[u8]) -> Vec { + const PREFIX: &str = "\x19Ethereum Signed Message:\n"; + let len = message.len(); + let mut len_string_buffer = itoa::Buffer::new(); + let len_string = len_string_buffer.format(len); + + let mut eth_message = Vec::with_capacity(PREFIX.len() + len_string.len() + len); + eth_message.extend_from_slice(PREFIX.as_bytes()); + eth_message.extend_from_slice(len_string.as_bytes()); + eth_message.extend_from_slice(message); + eth_message + } +} + impl pallet_file_system::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_file_system::weights::SubstrateWeight; @@ -501,6 +520,8 @@ impl pallet_file_system::Config for Runtime { type TickRangeToMaximumThreshold = runtime_config::TickRangeToMaximumThreshold; type OffchainSignature = Signature; type OffchainPublicKey = ::Signer; + type MaxFileDeletionsPerExtrinsic = ConstU32<100>; + type IntentionMsgAdapter = Eip191Adapter; } impl MostlyStablePriceIndexUpdaterConfig for Runtime { diff --git a/operator/runtime/stagenet/src/lib.rs b/operator/runtime/stagenet/src/lib.rs index 69878dd2..371b9c65 100644 --- a/operator/runtime/stagenet/src/lib.rs +++ b/operator/runtime/stagenet/src/lib.rs @@ -1248,6 +1248,9 @@ impl_runtime_apis! { fn query_incomplete_storage_request_metadata(file_key: H256) -> Result, StorageDataUnit, H256, BackupStorageProviderId>, QueryIncompleteStorageRequestMetadataError> { FileSystem::query_incomplete_storage_request_metadata(file_key) } + fn list_incomplete_storage_request_keys(start_after: Option, limit: u32) -> Vec { + FileSystem::list_incomplete_storage_request_keys(start_after, limit) + } } impl pallet_payment_streams_runtime_api::PaymentStreamsApi, Balance, AccountId> for Runtime { diff --git a/operator/runtime/testnet/Cargo.toml b/operator/runtime/testnet/Cargo.toml index f88dbd1b..9e08f53a 100644 --- a/operator/runtime/testnet/Cargo.toml +++ b/operator/runtime/testnet/Cargo.toml @@ -27,11 +27,11 @@ frame-metadata-hash-extension = { workspace = true } frame-support = { workspace = true, features = ["experimental"] } frame-system = { workspace = true } frame-system-benchmarking = { workspace = true, optional = true } -pallet-session-benchmarking = { workspace = true, optional = true } frame-system-rpc-runtime-api = { workspace = true } frame-try-runtime = { workspace = true, optional = true } hex = { workspace = true } hex-literal = { workspace = true } +itoa = { workspace = true } log = { workspace = true } num-bigint = { workspace = true } num_enum = { workspace = true } @@ -52,10 +52,10 @@ pallet-evm-precompile-conviction-voting = { workspace = true } pallet-evm-precompile-modexp = { workspace = true } pallet-evm-precompile-sha3fips = { workspace = true } pallet-evm-precompile-simple = { workspace = true } +pallet-external-validator-slashes = { workspace = true } pallet-external-validators = { workspace = true } pallet-external-validators-rewards = { workspace = true } pallet-external-validators-rewards-runtime-api = { workspace = true } -pallet-external-validator-slashes = { workspace = true } pallet-grandpa = { workspace = true } pallet-identity = { workspace = true } pallet-im-online = { workspace = true } @@ -67,17 +67,18 @@ pallet-offences = { workspace = true } pallet-outbound-commitment-store = { workspace = true } pallet-parameters = { workspace = true } pallet-preimage = { workspace = true } -pallet-safe-mode = { workspace = true } -pallet-tx-pause = { workspace = true } pallet-proxy = { workspace = true } pallet-referenda = { workspace = true } +pallet-safe-mode = { workspace = true } pallet-scheduler = { workspace = true } pallet-session = { workspace = true } +pallet-session-benchmarking = { workspace = true, optional = true } pallet-sudo = { workspace = true } pallet-timestamp = { workspace = true } pallet-transaction-payment = { workspace = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true } pallet-treasury = { workspace = true } +pallet-tx-pause = { workspace = true } pallet-utility = { workspace = true } pallet-whitelist = { workspace = true } polkadot-primitives = { workspace = true } @@ -119,29 +120,30 @@ sp-std = { workspace = true } sp-storage = { workspace = true } sp-transaction-pool = { workspace = true } sp-version = { workspace = true, features = ["serde"] } +strum = { workspace = true } +strum_macros = { workspace = true } xcm = { workspace = true } xcm-builder = { workspace = true } xcm-executor = { workspace = true } -strum = { workspace = true } -strum_macros = { workspace = true } # DataHaven precompiles pallet-evm-precompile-balances-erc20 = { workspace = true } pallet-evm-precompile-batch = { workspace = true } pallet-evm-precompile-call-permit = { workspace = true } -pallet-evm-precompile-preimage = { workspace = true } pallet-evm-precompile-collective = { workspace = true } pallet-evm-precompile-identity = { workspace = true } +pallet-evm-precompile-preimage = { workspace = true } pallet-evm-precompile-proxy = { workspace = true } pallet-evm-precompile-referenda = { workspace = true } pallet-evm-precompile-registry = { workspace = true } # StorageHub pallet-bucket-nfts = { workspace = true } -pallet-nfts = { workspace = true } pallet-cr-randomness = { workspace = true } +pallet-evm-precompile-file-system = { workspace = true } pallet-file-system = { workspace = true } pallet-file-system-runtime-api = { workspace = true } +pallet-nfts = { workspace = true } pallet-payment-streams = { workspace = true } pallet-payment-streams-runtime-api = { workspace = true } pallet-proofs-dealer = { workspace = true } @@ -151,14 +153,13 @@ pallet-storage-providers = { workspace = true } pallet-storage-providers-runtime-api = { workspace = true } shc-common = { workspace = true, optional = true } shp-constants = { workspace = true } +shp-data-price-updater = { workspace = true } +shp-file-key-verifier = { workspace = true } shp-file-metadata = { workspace = true } +shp-forest-verifier = { workspace = true } shp-traits = { workspace = true } shp-treasury-funding = { workspace = true } -shp-forest-verifier = { workspace = true } -shp-file-key-verifier = { workspace = true } -shp-data-price-updater = { workspace = true } sp-trie = { workspace = true } -pallet-evm-precompile-file-system = { workspace = true } [build-dependencies] substrate-wasm-builder = { workspace = true, optional = true, default-features = true } diff --git a/operator/runtime/testnet/src/configs/storagehub/mod.rs b/operator/runtime/testnet/src/configs/storagehub/mod.rs index ff265f5d..72d42735 100644 --- a/operator/runtime/testnet/src/configs/storagehub/mod.rs +++ b/operator/runtime/testnet/src/configs/storagehub/mod.rs @@ -37,7 +37,7 @@ use sp_runtime::traits::Zero; use sp_runtime::SaturatedConversion; use sp_runtime::{traits::BlakeTwo256, Perbill}; use sp_std::convert::{From, Into}; -use sp_std::vec; +use sp_std::{vec, vec::Vec}; use sp_trie::{LayoutV1, TrieConfiguration, TrieLayout}; #[cfg(feature = "std")] @@ -450,6 +450,25 @@ parameter_types! { pub const FileSystemFileDeletionRequestHoldReason: RuntimeHoldReason = RuntimeHoldReason::FileSystem(pallet_file_system::HoldReason::FileDeletionRequestHold); } +// Converts a given signed message in a EIP-191 compliant message bytes to verify. +/// EIP-191: https://eips.ethereum.org/EIPS/eip-191 +/// "\x19Ethereum Signed Message:\n" + len(message) + message" +pub struct Eip191Adapter; +impl shp_traits::MessageAdapter for Eip191Adapter { + fn bytes_to_verify(message: &[u8]) -> Vec { + const PREFIX: &str = "\x19Ethereum Signed Message:\n"; + let len = message.len(); + let mut len_string_buffer = itoa::Buffer::new(); + let len_string = len_string_buffer.format(len); + + let mut eth_message = Vec::with_capacity(PREFIX.len() + len_string.len() + len); + eth_message.extend_from_slice(PREFIX.as_bytes()); + eth_message.extend_from_slice(len_string.as_bytes()); + eth_message.extend_from_slice(message); + eth_message + } +} + impl pallet_file_system::Config for Runtime { type RuntimeEvent = RuntimeEvent; type WeightInfo = pallet_file_system::weights::SubstrateWeight; @@ -501,6 +520,8 @@ impl pallet_file_system::Config for Runtime { type TickRangeToMaximumThreshold = runtime_config::TickRangeToMaximumThreshold; type OffchainSignature = Signature; type OffchainPublicKey = ::Signer; + type MaxFileDeletionsPerExtrinsic = ConstU32<100>; + type IntentionMsgAdapter = Eip191Adapter; } impl MostlyStablePriceIndexUpdaterConfig for Runtime { diff --git a/operator/runtime/testnet/src/lib.rs b/operator/runtime/testnet/src/lib.rs index c20bea53..6904b82d 100644 --- a/operator/runtime/testnet/src/lib.rs +++ b/operator/runtime/testnet/src/lib.rs @@ -1244,6 +1244,9 @@ impl_runtime_apis! { fn query_incomplete_storage_request_metadata(file_key: H256) -> Result, StorageDataUnit, H256, BackupStorageProviderId>, QueryIncompleteStorageRequestMetadataError> { FileSystem::query_incomplete_storage_request_metadata(file_key) } + fn list_incomplete_storage_request_keys(start_after: Option, limit: u32) -> Vec { + FileSystem::list_incomplete_storage_request_keys(start_after, limit) + } } impl pallet_payment_streams_runtime_api::PaymentStreamsApi, Balance, AccountId> for Runtime { diff --git a/test/.papi/descriptors/package.json b/test/.papi/descriptors/package.json index f91b756b..0e2e9888 100644 --- a/test/.papi/descriptors/package.json +++ b/test/.papi/descriptors/package.json @@ -1,5 +1,5 @@ { - "version": "0.1.0-autogenerated.2256885919410986602", + "version": "0.1.0-autogenerated.40127769317338577", "name": "@polkadot-api/descriptors", "files": [ "dist" diff --git a/test/.papi/metadata/datahaven.scale b/test/.papi/metadata/datahaven.scale index bbf4e26cdc5ebb9184e3728c106237381ba092ac..9668885dd2aace10ccc17306a55632a01840f3cb 100644 GIT binary patch delta 16392 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 aZ@;To3iv(CdL`SEja#To~x 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 JERFM#{vQ#a>T>`9