From 012c1c96de80df6b838f6225f141f070483cde39 Mon Sep 17 00:00:00 2001 From: cl0w Date: Thu, 16 Apr 2026 14:14:20 +0200 Subject: [PATCH 1/4] Switch node to slot-based collation --- node/src/service.rs | 54 +++++++++++++++++++++++------------ runtime/hydradx/src/lib.rs | 9 ++++++ runtime/hydradx/src/system.rs | 12 ++++++++ 3 files changed, 56 insertions(+), 19 deletions(-) diff --git a/node/src/service.rs b/node/src/service.rs index c746ae900..f42c095b7 100644 --- a/node/src/service.rs +++ b/node/src/service.rs @@ -28,6 +28,7 @@ use std::{sync::Arc, time::Duration}; use cumulus_client_cli::CollatorOptions; use cumulus_client_collator::service::CollatorService; +use cumulus_client_consensus_aura::collators::slot_based::{SlotBasedBlockImport, SlotBasedBlockImportHandle}; use cumulus_client_consensus_common::ParachainBlockImport as TParachainBlockImport; use cumulus_client_consensus_proposer::Proposer; use cumulus_client_service::{ @@ -38,7 +39,7 @@ use cumulus_primitives_core::{ relay_chain::{CollatorPair, ValidationCode}, ParaId, }; -use cumulus_relay_chain_interface::{OverseerHandle, RelayChainInterface}; +use cumulus_relay_chain_interface::RelayChainInterface; use fc_db::kv::Backend as FrontierBackend; use fc_rpc_core::types::{FeeHistoryCache, FilterPool}; @@ -74,7 +75,8 @@ type ParachainClient = TFullClient< type ParachainBackend = TFullBackend; -type ParachainBlockImport = TParachainBlockImport, ParachainBackend>; +type ParachainBlockImport = + TParachainBlockImport, ParachainClient>, ParachainBackend>; pub struct TxDetailProvider; impl TransactionDetailProvider for TxDetailProvider { @@ -136,6 +138,7 @@ pub fn new_partial( sc_transaction_pool::TransactionPoolHandle, ( evm::BlockImport, + SlotBasedBlockImportHandle, Option, Option, Arc>, @@ -237,8 +240,9 @@ pub fn new_partial( let evm_since = chain_spec::Extensions::try_get(&config.chain_spec) .map(|e| e.evm_since) .unwrap_or(1); + let (slot_based_block_import, block_import_handle) = SlotBasedBlockImport::new(client.clone(), client.clone()); let block_import = evm::BlockImport::new( - ParachainBlockImport::new(client.clone(), backend.clone()), + ParachainBlockImport::new(slot_based_block_import, backend.clone()), client.clone(), frontier_backend.clone(), evm_since, @@ -265,6 +269,7 @@ pub fn new_partial( select_chain: (), other: ( block_import, + block_import_handle, telemetry, telemetry_worker_handle, frontier_backend, @@ -290,8 +295,15 @@ async fn start_node_impl( let parachain_config = prepare_node_config(parachain_config); let params = new_partial(¶chain_config, no_tx_priority_override)?; - let (block_import, mut telemetry, telemetry_worker_handle, frontier_backend, filter_pool, fee_history_cache) = - params.other; + let ( + block_import, + block_import_handle, + mut telemetry, + telemetry_worker_handle, + frontier_backend, + filter_pool, + fee_history_cache, + ) = params.other; let prometheus_registry = parachain_config.prometheus_registry().cloned(); let net_config = sc_network::config::FullNetworkConfiguration::<_, _, sc_network::NetworkWorker>::new( @@ -507,6 +519,7 @@ async fn start_node_impl( client.clone(), backend, block_import, + block_import_handle, prometheus_registry.as_ref(), telemetry.as_ref().map(|t| t.handle()), &task_manager, @@ -516,7 +529,6 @@ async fn start_node_impl( relay_chain_slot_duration, para_id, collator_key.expect("Command line arguments do not allow this. qed"), - overseer_handle, announce_block, )?; } @@ -557,6 +569,7 @@ fn start_consensus( client: Arc, backend: Arc, block_import: evm::BlockImport, + block_import_handle: SlotBasedBlockImportHandle, prometheus_registry: Option<&Registry>, telemetry: Option, task_manager: &TaskManager, @@ -566,13 +579,9 @@ fn start_consensus( relay_chain_slot_duration: Duration, para_id: ParaId, collator_key: CollatorPair, - overseer_handle: OverseerHandle, announce_block: Arc>) + Send + Sync>, ) -> Result<(), sc_service::Error> { - use cumulus_client_consensus_aura::collators::lookahead::{self as aura, Params as AuraParams}; - - // NOTE: because we use Aura here explicitly, we can use `CollatorSybilResistance::Resistant` - // when starting the network. + use cumulus_client_consensus_aura::collators::slot_based::{self as slot_based, Params as SlotBasedParams}; let proposer_factory = sc_basic_authorship::ProposerFactory::with_proof_recording( task_manager.spawn_handle(), @@ -591,8 +600,8 @@ fn start_consensus( client.clone(), ); - // let (client_clone, relay_chain_interface_clone) = (client.clone(), relay_chain_interface.clone()); - let params = AuraParams { + let client_for_aura = client.clone(); + let params = SlotBasedParams { create_inherent_data_providers: move |_, ()| async move { Ok(()) }, // FIXME: Disabled due to https://github.com/galacticcouncil/hydration-node/issues/1346 // create_inherent_data_providers: move |parent, ()| { @@ -610,21 +619,28 @@ fn start_consensus( para_client: client.clone(), para_backend: backend.clone(), relay_client: relay_chain_interface, - code_hash_provider: move |block_hash| client.code_at(block_hash).ok().map(|c| ValidationCode::from(c).hash()), + code_hash_provider: move |block_hash| { + client_for_aura + .code_at(block_hash) + .ok() + .map(|c| ValidationCode::from(c).hash()) + }, keystore, collator_key, para_id, - overseer_handle, - relay_chain_slot_duration, proposer, collator_service, authoring_duration: Duration::from_millis(1500), reinitialize: false, - max_pov_percentage: None, // Defaults to 85% of max PoV size (safe default) + slot_offset: Duration::from_secs(1), + block_import_handle, + spawner: task_manager.spawn_handle(), + relay_chain_slot_duration, + export_pov: None, + max_pov_percentage: None, }; - let fut = aura::run::(params); - task_manager.spawn_essential_handle().spawn("aura", None, fut); + slot_based::run::(params); Ok(()) } diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index cfa293f7f..bcbd14c73 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -610,6 +610,15 @@ impl_runtime_apis! { } } + impl cumulus_primitives_core::GetCoreSelectorApi for Runtime { + fn core_selector() -> ( + cumulus_primitives_core::CoreSelector, + cumulus_primitives_core::ClaimQueueOffset, + ) { + ParachainSystem::core_selector() + } + } + #[cfg(feature = "try-runtime")] impl frame_try_runtime::TryRuntime for Runtime { fn on_runtime_upgrade(checks: frame_try_runtime::UpgradeCheckSelect) -> (Weight, Weight) { diff --git a/runtime/hydradx/src/system.rs b/runtime/hydradx/src/system.rs index b82707f2a..16d431926 100644 --- a/runtime/hydradx/src/system.rs +++ b/runtime/hydradx/src/system.rs @@ -286,6 +286,18 @@ pub type ConsensusHook = cumulus_pallet_aura_ext::FixedVelocityConsensusHook< UNINCLUDED_SEGMENT_CAPACITY, >; +pub struct RelayParentOffset; + +impl Get for RelayParentOffset { + fn get() -> u32 { + if Parameters::relay_parent_offset_override() { + 0 + } else { + DEFAULT_RELAY_PARENT_OFFSET + } + } +} + impl cumulus_pallet_parachain_system::Config for Runtime { type RuntimeEvent = RuntimeEvent; type OnSystemEvent = pallet_relaychain_info::OnValidationDataHandler; From 7bbe65d09407011d82a7eaa9852c7d480f17cb75 Mon Sep 17 00:00:00 2001 From: cl0w Date: Thu, 16 Apr 2026 14:14:59 +0200 Subject: [PATCH 2/4] relay parent offset 1 --- node/src/chain_spec/local.rs | 2 ++ node/src/chain_spec/mod.rs | 4 ++++ node/src/chain_spec/rococo.rs | 2 ++ node/src/chain_spec/staging.rs | 2 ++ pallets/parameters/src/lib.rs | 36 +++++++++++++++++++++++++++++++++ pallets/parameters/src/tests.rs | 17 +++++++++++++++- primitives/src/constants.rs | 3 ++- runtime/hydradx/src/lib.rs | 2 +- runtime/hydradx/src/system.rs | 6 +++--- 9 files changed, 68 insertions(+), 6 deletions(-) diff --git a/node/src/chain_spec/local.rs b/node/src/chain_spec/local.rs index c9b4c2789..21c5a69ad 100644 --- a/node/src/chain_spec/local.rs +++ b/node/src/chain_spec/local.rs @@ -107,6 +107,8 @@ pub fn parachain_config() -> Result { create_testnet_claims(), // parachain ID PARA_ID.into(), + // is_testnet + true, DusterConfig { account_whitelist: vec![get_account_id_from_seed::("Duster")], }, diff --git a/node/src/chain_spec/mod.rs b/node/src/chain_spec/mod.rs index d623d6355..d51692d42 100644 --- a/node/src/chain_spec/mod.rs +++ b/node/src/chain_spec/mod.rs @@ -107,6 +107,7 @@ pub fn parachain_genesis( token_balances: Vec<(AccountId, Vec<(AssetId, Balance)>)>, claims_data: Vec<(EthereumAddress, Balance)>, parachain_id: ParaId, + is_testnet: bool, duster: DusterConfig, ) -> serde_json::Value { serde_json::json!({ @@ -157,6 +158,9 @@ pub fn parachain_genesis( "currencies": accepted_assets, "accountCurrencies": Vec::<(AccountId, AssetId)>::new(), }, + "parameters": { + "isTestnet": is_testnet, + }, "tokens": { "balances": if registered_assets.is_empty() { vec![] diff --git a/node/src/chain_spec/rococo.rs b/node/src/chain_spec/rococo.rs index 949dd9966..23efa6b07 100644 --- a/node/src/chain_spec/rococo.rs +++ b/node/src/chain_spec/rococo.rs @@ -78,6 +78,8 @@ pub fn _parachain_config_rococo() -> Result { Default::default(), // parachain ID PARA_ID.into(), + // is_testnet + false, // duster DusterConfig { // treasury diff --git a/node/src/chain_spec/staging.rs b/node/src/chain_spec/staging.rs index cf66a76cc..6edd82158 100644 --- a/node/src/chain_spec/staging.rs +++ b/node/src/chain_spec/staging.rs @@ -72,6 +72,8 @@ pub fn parachain_config() -> Result { Default::default(), // parachain ID PARA_ID.into(), + // is_testnet + false, // duster DusterConfig { // treasury diff --git a/pallets/parameters/src/lib.rs b/pallets/parameters/src/lib.rs index 6c6ec17c3..2d69d9490 100644 --- a/pallets/parameters/src/lib.rs +++ b/pallets/parameters/src/lib.rs @@ -28,6 +28,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![allow(clippy::manual_inspect)] +use core::marker::PhantomData; #[cfg(test)] pub mod mock; #[cfg(test)] @@ -51,11 +52,46 @@ pub mod pallet { #[pallet::getter(fn is_testnet)] pub type IsTestnet = StorageValue<_, bool, ValueQuery>; + #[pallet::storage] + #[pallet::getter(fn relay_parent_offset_override)] + pub type RelayParentOffsetOverride = StorageValue<_, bool, ValueQuery>; + + #[pallet::genesis_config] + pub struct GenesisConfig { + pub is_testnet: bool, + pub relay_parent_offset_override: bool, + pub _phantom: PhantomData, + } + + impl Default for GenesisConfig { + fn default() -> Self { + Self { + is_testnet: false, + relay_parent_offset_override: false, + _phantom: PhantomData, + } + } + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + IsTestnet::::put(self.is_testnet); + RelayParentOffsetOverride::::put(self.relay_parent_offset_override); + } + } + impl Pallet { /// Set the flag. Only used for tests. #[cfg(feature = "std")] pub fn set_testnet_flag(is_testnet: bool) { IsTestnet::::put(is_testnet); } + + /// Set the relay parent offset override. Only used for tests. + #[cfg(feature = "std")] + pub fn set_relay_parent_offset_override(override_enabled: bool) { + RelayParentOffsetOverride::::put(override_enabled); + } } } diff --git a/pallets/parameters/src/tests.rs b/pallets/parameters/src/tests.rs index bad484f7a..6147189dc 100644 --- a/pallets/parameters/src/tests.rs +++ b/pallets/parameters/src/tests.rs @@ -26,7 +26,7 @@ // $$$ use crate::mock::*; -use crate::{IsTestnet, Pallet as Parameters}; +use crate::{IsTestnet, Pallet as Parameters, RelayParentOffsetOverride}; #[test] fn is_testnet_false_by_default() { @@ -42,3 +42,18 @@ fn is_testnet_true_when_set() { assert!(Parameters::::is_testnet()); }); } + +#[test] +fn relay_parent_offset_override_false_by_default() { + ExtBuilder.build().execute_with(|| { + assert!(!Parameters::::relay_parent_offset_override()); + }); +} + +#[test] +fn relay_parent_offset_override_true_when_set() { + ExtBuilder.build().execute_with(|| { + RelayParentOffsetOverride::::put(true); + assert!(Parameters::::relay_parent_offset_override()); + }); +} diff --git a/primitives/src/constants.rs b/primitives/src/constants.rs index 41f965509..585bc07ee 100644 --- a/primitives/src/constants.rs +++ b/primitives/src/constants.rs @@ -84,9 +84,10 @@ pub mod chain { pub const STABLESWAP_SOURCE: [u8; 8] = *b"stablesw"; pub const XYK_SOURCE: [u8; 8] = *b"hydraxyk"; + pub const DEFAULT_RELAY_PARENT_OFFSET: u32 = 1; /// Maximum number of blocks simultaneously accepted by the Runtime, not yet included into the /// relay chain. - pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = 3; + pub const UNINCLUDED_SEGMENT_CAPACITY: u32 = (3 + DEFAULT_RELAY_PARENT_OFFSET) * BLOCK_PROCESSING_VELOCITY; /// How many parachain blocks are processed by the relay chain per parent. Limits the number of /// blocks authored per slot. pub const BLOCK_PROCESSING_VELOCITY: u32 = 1; diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index bcbd14c73..bf3029204 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -129,7 +129,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: Cow::Borrowed("hydradx"), impl_name: Cow::Borrowed("hydradx"), authoring_version: 1, - spec_version: 410, + spec_version: 411, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, diff --git a/runtime/hydradx/src/system.rs b/runtime/hydradx/src/system.rs index 16d431926..c909638aa 100644 --- a/runtime/hydradx/src/system.rs +++ b/runtime/hydradx/src/system.rs @@ -22,8 +22,8 @@ use pallet_transaction_multi_payment::{DepositAll, TransferFees, WeightInfo}; use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; use primitives::constants::{ chain::{ - BLOCK_PROCESSING_VELOCITY, CORE_ASSET_ID, MAXIMUM_BLOCK_WEIGHT, RELAY_CHAIN_SLOT_DURATION_MILLIS, - UNINCLUDED_SEGMENT_CAPACITY, + BLOCK_PROCESSING_VELOCITY, CORE_ASSET_ID, DEFAULT_RELAY_PARENT_OFFSET, MAXIMUM_BLOCK_WEIGHT, + RELAY_CHAIN_SLOT_DURATION_MILLIS, UNINCLUDED_SEGMENT_CAPACITY, }, currency::{deposit, CENTS, DOLLARS, MILLICENTS}, time::{DAYS, HOURS, SLOT_DURATION}, @@ -311,7 +311,7 @@ impl cumulus_pallet_parachain_system::Config for Runtime { type WeightInfo = weights::cumulus_pallet_parachain_system::HydraWeight; type ConsensusHook = ConsensusHook; type SelectCore = cumulus_pallet_parachain_system::DefaultCoreSelector; - type RelayParentOffset = ConstU32<0>; + type RelayParentOffset = RelayParentOffset; } parameter_types! { From 259f42c17a548f6aefdd65ab2eef43680e3996a6 Mon Sep 17 00:00:00 2001 From: cl0w Date: Fri, 17 Apr 2026 14:09:12 +0200 Subject: [PATCH 3/4] add missing runtime api for parent offset --- runtime-mock/src/lib.rs | 1 + runtime/hydradx/src/lib.rs | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/runtime-mock/src/lib.rs b/runtime-mock/src/lib.rs index ebb52f197..78a7714d0 100644 --- a/runtime-mock/src/lib.rs +++ b/runtime-mock/src/lib.rs @@ -123,6 +123,7 @@ pub fn hydradx_mocked_runtime() -> TestExternalities { duster: DusterConfig { account_whitelist: vec![], }, + parameters: Default::default(), omnipool_warehouse_lm: Default::default(), omnipool_liquidity_mining: Default::default(), evm_chain_id: hydradx_runtime::EVMChainIdConfig { diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index bf3029204..7e12327c4 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -1123,6 +1123,12 @@ impl_runtime_apis! { } } + impl cumulus_primitives_core::RelayParentOffsetApi for Runtime { + fn relay_parent_offset() -> u32 { + RelayParentOffset::get() + } + } + impl xcm_runtime_apis::dry_run::DryRunApi for Runtime { fn dry_run_call( origin: OriginCaller, From b4162ed736948c4ab36e137659e236ca62e88eb4 Mon Sep 17 00:00:00 2001 From: cl0w Date: Mon, 27 Apr 2026 15:39:00 +0200 Subject: [PATCH 4/4] add relay_parent_offset_override for integration tests --- integration-tests/src/polkadot_test_net.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/integration-tests/src/polkadot_test_net.rs b/integration-tests/src/polkadot_test_net.rs index 3e8564180..dcbcb250e 100644 --- a/integration-tests/src/polkadot_test_net.rs +++ b/integration-tests/src/polkadot_test_net.rs @@ -657,6 +657,10 @@ pub mod hydra { safe_xcm_version: Some(5), ..Default::default() }, + parameters: hydradx_runtime::ParametersConfig { + relay_parent_offset_override: true, + ..Default::default() + }, multi_transaction_payment: hydradx_runtime::MultiTransactionPaymentConfig { currencies: vec![ (LRNA, Price::from(1)), @@ -711,6 +715,10 @@ pub mod para { safe_xcm_version: Some(5), ..Default::default() }, + parameters: hydradx_runtime::ParametersConfig { + relay_parent_offset_override: true, + ..Default::default() + }, duster: hydradx_runtime::DusterConfig { account_whitelist: vec![Treasury::account_id()], },