diff --git a/Cargo.lock b/Cargo.lock index fb30ccee2..ada1812f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4919,7 +4919,7 @@ dependencies = [ [[package]] name = "hydradx-runtime" -version = "281.0.2" +version = "282.0.0" dependencies = [ "cumulus-pallet-aura-ext", "cumulus-pallet-parachain-system", @@ -4975,6 +4975,7 @@ dependencies = [ "pallet-currencies-rpc-runtime-api", "pallet-dca", "pallet-democracy 4.3.2", + "pallet-dispatcher", "pallet-duster", "pallet-dynamic-evm-fee", "pallet-dynamic-fees", @@ -8086,6 +8087,25 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-dispatcher" +version = "1.0.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "hydradx-traits", + "orml-tokens", + "orml-traits", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", + "sp-std", + "test-utils", +] + [[package]] name = "pallet-duster" version = "3.2.7" @@ -8804,7 +8824,7 @@ dependencies = [ [[package]] name = "pallet-omnipool" -version = "4.5.0" +version = "4.5.1" dependencies = [ "bitflags 1.3.2", "frame-benchmarking", @@ -12327,6 +12347,7 @@ dependencies = [ "pallet-currencies", "pallet-dca", "pallet-democracy 4.3.2", + "pallet-dispatcher", "pallet-dynamic-evm-fee", "pallet-dynamic-fees", "pallet-elections-phragmen", diff --git a/Cargo.toml b/Cargo.toml index f50982653..027540b55 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -119,6 +119,7 @@ pallet-collator-rewards = { path = "pallets/collator-rewards", default-features pallet-currencies = { path = "pallets/currencies", default-features = false } pallet-currencies-rpc-runtime-api = { path = "pallets/currencies/rpc/runtime-api", default-features = false } pallet-dca = { path = "pallets/dca", default-features = false } +pallet-dispatcher = { path = "pallets/dispatcher", default-features = false } pallet-duster = { path = "pallets/duster", default-features = false } pallet-dynamic-fees = { path = "pallets/dynamic-fees", default-features = false } pallet-dynamic-evm-fee = { path = "pallets/dynamic-evm-fee", default-features = false } diff --git a/Makefile b/Makefile index 418452650..4518d1905 100644 --- a/Makefile +++ b/Makefile @@ -41,11 +41,11 @@ coverage: .PHONY: clippy clippy: - $(cargo) clippy --release --locked --all-targets -- -D warnings -A deprecated + $(cargo) clippy --release --locked --all-targets -- -A deprecated .PHONY: clippy-all clippy-all: - $(cargo) clippy --release --locked --all-targets --all-features -- -D warnings -A deprecated + $(cargo) clippy --release --locked --all-targets --all-features -- -A deprecated .PHONY: format format: diff --git a/integration-tests/Cargo.toml b/integration-tests/Cargo.toml index f1370176f..b2e1c84e7 100644 --- a/integration-tests/Cargo.toml +++ b/integration-tests/Cargo.toml @@ -51,6 +51,7 @@ pallet-elections-phragmen = { workspace = true } pallet-tips = { workspace = true } pallet-referenda = { workspace = true } pallet-conviction-voting = { workspace = true } +pallet-dispatcher = { workspace = true } # collator support pallet-collator-selection = { workspace = true } @@ -215,6 +216,7 @@ std = [ "pallet-transaction-pause/std", "pallet-liquidation/std", "pallet-broadcast/std", + "pallet-dispatcher/std", ] # we don't include integration tests when benchmarking feature is enabled diff --git a/integration-tests/src/dispatcher.rs b/integration-tests/src/dispatcher.rs new file mode 100644 index 000000000..00395a842 --- /dev/null +++ b/integration-tests/src/dispatcher.rs @@ -0,0 +1,84 @@ +use crate::polkadot_test_net::*; +use frame_support::assert_ok; +use hydradx_runtime::evm::WethAssetId; +use hydradx_runtime::*; +use primitives::EvmAddress; +use sp_core::Get; +use sp_core::{ByteArray, U256}; +use test_utils::last_events; +use xcm_emulator::TestExt; + +fn testnet_manager_address() -> EvmAddress { + hex!["52341e77341788Ebda44C8BcB4C8BD1B1913B204"].into() +} + +fn pad_to_32_bytes(bytes: &[u8]) -> [u8; 32] { + let mut padded = [0u8; 32]; + padded[..bytes.len()].copy_from_slice(bytes); + padded +} + +fn testnet_manager() -> AccountId { + pad_to_32_bytes(testnet_manager_address().as_bytes()).into() +} + +#[test] +fn testnet_aave_manager_can_be_set_as_dispatcher() { + TestNet::reset(); + Hydra::execute_with(|| { + assert_eq!( + hydradx_runtime::Dispatcher::aave_manager_account(), + pad_to_32_bytes(hex!["aa7e0000000000000000000000000000000aa7e0"].as_ref()).into() + ); + assert_ok!(hydradx_runtime::Dispatcher::note_aave_manager( + hydradx_runtime::RuntimeOrigin::root(), + testnet_manager() + )); + assert_eq!(hydradx_runtime::Dispatcher::aave_manager_account(), testnet_manager()); + }); +} + +#[test] +fn dispatch_as_aave_admin_can_modify_supply_cap_on_testnet() { + TestNet::reset(); + Hydra::execute_with(|| { + assert_ok!(hydradx_runtime::Dispatcher::note_aave_manager( + hydradx_runtime::RuntimeOrigin::root(), + testnet_manager() + )); + assert_ok!(hydradx_runtime::Tokens::set_balance( + hydradx_runtime::RuntimeOrigin::root(), + EVMAccounts::account_id(testnet_manager_address()), + WethAssetId::get(), + 1_000_000_000_000_000_000u128, + 0 + )); + let set_cap_data = hex!["571f03e50000000000000000000000000000000000000000000000000000000100000005000000000000000000000000000000000000000000000000000000000006c81c"].into(); + let call = Box::new(RuntimeCall::EVM(pallet_evm::Call::call { + source: EvmAddress::from_slice(&testnet_manager().as_slice()[0..20]), + target: hex!["5AFf8be73B6AA6890DaCe9483a6AE9CEfA002795"].into(), + input: set_cap_data, + gas_limit: 100_000, + value: U256::zero(), + max_fee_per_gas: U256::from(233_460_000), + max_priority_fee_per_gas: None, + nonce: None, + access_list: vec![], + })); + assert_ok!(Dispatcher::dispatch_as_aave_manager( + RuntimeOrigin::root(), + call.clone() + )); + let event = last_events::(1) + .into_iter() + .take(1) + .next() + .unwrap(); + match event { + RuntimeEvent::Dispatcher(pallet_dispatcher::Event::AaveManagerCallDispatched { + result: Ok(..), .. + }) => {} + _ => panic!("Unexpected event: {:?}", event), + } + }); +} diff --git a/integration-tests/src/exchange_asset.rs b/integration-tests/src/exchange_asset.rs index b9ed4f7d4..d38fae6b7 100644 --- a/integration-tests/src/exchange_asset.rs +++ b/integration-tests/src/exchange_asset.rs @@ -8,12 +8,9 @@ use frame_support::traits::fungible::Balanced; use frame_support::traits::tokens::Precision; use frame_support::weights::Weight; use frame_support::{assert_ok, pallet_prelude::*}; -use hydradx_runtime::Omnipool; +use hydradx_runtime::AssetRegistry; use hydradx_runtime::Router; -use hydradx_runtime::RuntimeEvent; use hydradx_runtime::RuntimeOrigin; -use hydradx_runtime::TempAccountForXcmAssetExchange; -use hydradx_runtime::{AssetRegistry, LRNA}; use hydradx_traits::AssetKind; use hydradx_traits::Create; use orml_traits::currency::MultiCurrency; @@ -157,7 +154,7 @@ fn hydra_should_swap_assets_when_receiving_from_acala_with_sell() { RuntimeOrigin::signed(ALICE.into()), HDX, ACA, - 1 * UNITS, + UNITS, 0, vec![], )); @@ -1193,7 +1190,7 @@ fn half(asset: &Asset) -> Asset { id: asset.clone().id, } } -use pallet_broadcast::types::{ExecutionType, Fee}; +use pallet_broadcast::types::ExecutionType; use rococo_runtime::xcm_config::BaseXcmWeight; use xcm_builder::FixedWeightBounds; use xcm_executor::traits::WeightBounds; diff --git a/integration-tests/src/lib.rs b/integration-tests/src/lib.rs index 30898014b..880295074 100644 --- a/integration-tests/src/lib.rs +++ b/integration-tests/src/lib.rs @@ -8,6 +8,7 @@ mod circuit_breaker; mod contracts; mod cross_chain_transfer; mod dca; +mod dispatcher; mod driver; mod dust; mod dust_removal_whitelist; diff --git a/integration-tests/src/referrals.rs b/integration-tests/src/referrals.rs index e319e2e7d..b52faa2be 100644 --- a/integration-tests/src/referrals.rs +++ b/integration-tests/src/referrals.rs @@ -340,8 +340,7 @@ fn trading_in_omnipool_should_use_asset_rewards_when_set() { outputs: vec![Asset::new(LRNA, 1205768843)], fees: vec![Fee::new(LRNA, 602884, Destination::Burned)], operation_stack: vec![ExecutionType::Omnipool(0)], - } - .into(), + }, pallet_broadcast::Event::Swapped { swapper: BOB.into(), filler: Omnipool::protocol_account(), @@ -354,8 +353,7 @@ fn trading_in_omnipool_should_use_asset_rewards_when_set() { Fee::new(DAI, 9168140377593, Destination::Account(Referrals::pot_account_id())) ], operation_stack: vec![ExecutionType::Omnipool(0)], - } - .into(), + }, ] ); }); diff --git a/integration-tests/src/utility.rs b/integration-tests/src/utility.rs index 24c11f8fb..726edd45c 100644 --- a/integration-tests/src/utility.rs +++ b/integration-tests/src/utility.rs @@ -7,7 +7,7 @@ use pallet_broadcast::types::Destination; use crate::assert_balance; use hydradx_runtime::LBP; use hydradx_runtime::XYK; -use hydradx_runtime::{Currencies, Omnipool, Runtime, RuntimeEvent}; +use hydradx_runtime::{Currencies, Omnipool, Runtime}; use hydradx_runtime::{RuntimeCall, Utility}; use hydradx_traits::router::PoolType; use pallet_broadcast::types::Asset; diff --git a/integration-tests/src/xcm.rs b/integration-tests/src/xcm.rs index fda89e7c5..ce379644e 100644 --- a/integration-tests/src/xcm.rs +++ b/integration-tests/src/xcm.rs @@ -6,8 +6,6 @@ use sp_runtime::codec::Encode; use crate::assert_operation_stack; use frame_support::dispatch::GetDispatchInfo; -use hydradx_runtime::Omnipool; -use hydradx_runtime::RuntimeEvent; use orml_traits::MultiCurrency; use pallet_broadcast::types::ExecutionType; use polkadot_xcm::v4::prelude::*; diff --git a/pallets/dispatcher/Cargo.toml b/pallets/dispatcher/Cargo.toml new file mode 100644 index 000000000..8b429912c --- /dev/null +++ b/pallets/dispatcher/Cargo.toml @@ -0,0 +1,56 @@ +[package] +name = "pallet-dispatcher" +version = "1.0.0" +authors = ['GalacticCouncil'] +edition = "2021" +license = "Apache-2.0" +homepage = 'https://github.com/galacticcouncil/hydration-node' +repository = 'https://github.com/galacticcouncil/hydration-node' +description = "Pallet for dispatching calls as specific origins" +readme = "README.md" + +[dependencies] +# parity +codec = { workspace = true, features = ["derive", "max-encoded-len"] } +scale-info = { workspace = true } + +# primitives +sp-runtime = { workspace = true } +sp-std = { workspace = true } +sp-core = { workspace = true } + +# FRAME +frame-support = { workspace = true } +frame-system = { workspace = true } + +# Optional imports for benchmarking +frame-benchmarking = { workspace = true, optional = true } + +[dev-dependencies] +sp-io = { workspace = true } +hydradx-traits = { workspace = true } +orml-tokens = { workspace = true } +orml-traits = { workspace = true } +test-utils = { workspace = true } + +[features] +default = ['std'] +std = [ + 'codec/std', + 'scale-info/std', + 'sp-runtime/std', + 'sp-core/std', + 'sp-io/std', + 'sp-std/std', + 'frame-benchmarking/std', + 'hydradx-traits/std', + 'orml-tokens/std', + 'orml-traits/std', +] + +runtime-benchmarks = [ + "frame-benchmarking", + "frame-system/runtime-benchmarks", + "frame-support/runtime-benchmarks", +] +try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/dispatcher/README.md b/pallets/dispatcher/README.md new file mode 100644 index 000000000..4c95775fc --- /dev/null +++ b/pallets/dispatcher/README.md @@ -0,0 +1,6 @@ +# Dispatcher Pallet +This pallet enables specific OpenGov tracks to dispatch Runtime calls as predefined origins. + +The pallet supports the following dispatchables: +* `dispatch_as_treasury` - allows the `Treasury` track to dispatch calls as the Treasury account on Hydration (`7L53bUTBopuwFt3mKUfmkzgGLayYa1Yvn1hAg9v5UMrQzTfh`) +* `dispatch_as_aave_manager` - allows the `EconomicParameters` track to dispatch calls as the Money Market authority on Hydration (`add addr`) diff --git a/pallets/dispatcher/src/benchmarking.rs b/pallets/dispatcher/src/benchmarking.rs new file mode 100644 index 000000000..ed4519c12 --- /dev/null +++ b/pallets/dispatcher/src/benchmarking.rs @@ -0,0 +1,57 @@ +// This file is part of https://github.com/galacticcouncil/* +// +// $$$$$$$ Licensed under the Apache License, Version 2.0 (the "License") +// $$$$$$$$$$$$$ you may only use this file in compliance with the License +// $$$$$$$$$$$$$$$$$$$ +// $$$$$$$$$ Copyright (C) 2021-2024 Intergalactic, Limited (GIB) +// $$$$$$$$$$$ $$$$$$$$$$ SPDX-License-Identifier: Apache-2.0 +// $$$$$$$$$$$$$$$$$$$$$$$$$$ +// $$$$$$$$$$$$$$$$$$$$$$$ $ Built with <3 for decentralisation +// $$$$$$$$$$$$$$$$$$$ $$$$$$$ +// $$$$$$$ $$$$$$$$$$$$$$$$$$ Unless required by applicable law or agreed to in +// $ $$$$$$$$$$$$$$$$$$$$$$$ writing, software distributed under the License is +// $$$$$$$$$$$$$$$$$$$$$$$$$$ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES +// $$$$$$$$$ $$$$$$$$$$$ OR CONDITIONS OF ANY KIND, either express or implied. +// $$$$$$$$ +// $$$$$$$$$$$$$$$$$$ See the License for the specific language governing +// $$$$$$$$$$$$$ permissions and limitations under the License. +// $$$$$$$ +// $$ +// $$$$$ $$$$$ $$ $ +// $$$ $$$ $$$ $$ $$$$$ $$ $$$ $$$$ $$$$$$$ $$$$ $$$ $$$$$$ $$ $$$$$$ +// $$$ $$$ $$$ $$ $$$ $$$ $$$ $ $$ $$ $$ $$ $$ $$ $$$ $$$ +// $$$$$$$$$$$ $$ $$ $$$ $$ $$ $$$$$$$ $$ $$ $$ $$$ $$ $$ +// $$$ $$$ $$$$ $$$ $$ $$ $$$ $$ $$ $$ $$ $$ $$ $$ +// $$$$$ $$$$$ $$ $$$$$$$$ $ $$$ $$$$$$$$ $$$ $$$$ $$$$$$$ $$$$ $$$$ +// $$$ + +use super::*; + +use frame_benchmarking::benchmarks; +use frame_system::RawOrigin; +use sp_std::boxed::Box; + +benchmarks! { + where_clause { where + T: crate::Config, + } + + dispatch_as_treasury { + let n in 1 .. 10_000; + let remark = sp_std::vec![1u8; n as usize]; + + let call: ::RuntimeCall = frame_system::Call::remark { remark }.into(); + }: _(RawOrigin::Root, Box::new(call)) + + dispatch_as_aave_manager { + let n in 1 .. 10_000; + let remark = sp_std::vec![1u8; n as usize]; + + let call: ::RuntimeCall = frame_system::Call::remark { remark }.into(); + }: _(RawOrigin::Root, Box::new(call)) + + note_aave_manager { + }: _(RawOrigin::Root, Pallet::::aave_manager_account()) + + impl_benchmark_test_suite!(Pallet, crate::mock::ExtBuilder::default().build(), crate::mock::Test); +} diff --git a/pallets/dispatcher/src/lib.rs b/pallets/dispatcher/src/lib.rs new file mode 100644 index 000000000..5db4688ce --- /dev/null +++ b/pallets/dispatcher/src/lib.rs @@ -0,0 +1,191 @@ +// This file is part of https://github.com/galacticcouncil/* +// +// $$$$$$$ Licensed under the Apache License, Version 2.0 (the "License") +// $$$$$$$$$$$$$ you may only use this file in compliance with the License +// $$$$$$$$$$$$$$$$$$$ +// $$$$$$$$$ Copyright (C) 2021-2024 Intergalactic, Limited (GIB) +// $$$$$$$$$$$ $$$$$$$$$$ SPDX-License-Identifier: Apache-2.0 +// $$$$$$$$$$$$$$$$$$$$$$$$$$ +// $$$$$$$$$$$$$$$$$$$$$$$ $ Built with <3 for decentralisation +// $$$$$$$$$$$$$$$$$$$ $$$$$$$ +// $$$$$$$ $$$$$$$$$$$$$$$$$$ Unless required by applicable law or agreed to in +// $ $$$$$$$$$$$$$$$$$$$$$$$ writing, software distributed under the License is +// $$$$$$$$$$$$$$$$$$$$$$$$$$ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES +// $$$$$$$$$ $$$$$$$$$$$ OR CONDITIONS OF ANY KIND, either express or implied. +// $$$$$$$$ +// $$$$$$$$$$$$$$$$$$ See the License for the specific language governing +// $$$$$$$$$$$$$ permissions and limitations under the License. +// $$$$$$$ +// $$ +// $$$$$ $$$$$ $$ $ +// $$$ $$$ $$$ $$ $$$$$ $$ $$$ $$$$ $$$$$$$ $$$$ $$$ $$$$$$ $$ $$$$$$ +// $$$ $$$ $$$ $$ $$$ $$$ $$$ $ $$ $$ $$ $$ $$ $$ $$$ $$$ +// $$$$$$$$$$$ $$ $$ $$$ $$ $$ $$$$$$$ $$ $$ $$ $$$ $$ $$ +// $$$ $$$ $$$$ $$$ $$ $$ $$$ $$ $$ $$ $$ $$ $$ $$ +// $$$$$ $$$$$ $$ $$$$$$$$ $ $$$ $$$$$$$$ $$$ $$$$ $$$$$$$ $$$$ $$$$ +// $$$ + +#![cfg_attr(not(feature = "std"), no_std)] + +#[cfg(test)] +pub mod mock; +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +pub mod weights; + +use frame_support::dispatch::PostDispatchInfo; +use sp_runtime::{traits::Dispatchable, DispatchResultWithInfo}; +pub use weights::WeightInfo; + +// Re-export pallet items so that they can be accessed from the crate namespace. +use frame_support::pallet_prelude::Weight; +pub use pallet::*; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + use codec::FullCodec; + use frame_support::{ + dispatch::{GetDispatchInfo, PostDispatchInfo}, + pallet_prelude::*, + }; + use frame_system::pallet_prelude::*; + use sp_runtime::traits::{Dispatchable, Hash}; + use sp_std::boxed::Box; + + pub type AccountId = u64; + + #[pallet::config] + pub trait Config: frame_system::Config { + /// The overarching event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + + /// The overarching call type. + type RuntimeCall: IsType<::RuntimeCall> + + Dispatchable + + GetDispatchInfo + + FullCodec + + TypeInfo + + From> + + Parameter; + + type TreasuryManagerOrigin: EnsureOrigin; + type AaveManagerOrigin: EnsureOrigin; + + type TreasuryAccount: Get; + type DefaultAaveManagerAccount: Get; + + /// The weight information for this pallet. + type WeightInfo: WeightInfo; + } + + #[pallet::pallet] + pub struct Pallet(_); + + #[pallet::storage] + #[pallet::getter(fn aave_manager_account)] + pub type AaveManagerAccount = StorageValue<_, T::AccountId, ValueQuery, T::DefaultAaveManagerAccount>; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + TreasuryManagerCallDispatched { + call_hash: T::Hash, + result: DispatchResultWithPostInfo, + }, + AaveManagerCallDispatched { + call_hash: T::Hash, + result: DispatchResultWithPostInfo, + }, + } + + #[pallet::call] + impl Pallet { + #[pallet::call_index(0)] + #[pallet::weight({ + let call_weight = call.get_dispatch_info().weight; + let call_len = call.encoded_size() as u32; + + T::WeightInfo::dispatch_as_treasury(call_len) + .saturating_add(call_weight) + })] + pub fn dispatch_as_treasury( + origin: OriginFor, + call: Box<::RuntimeCall>, + ) -> DispatchResultWithPostInfo { + T::TreasuryManagerOrigin::ensure_origin(origin)?; + + let call_hash = T::Hashing::hash_of(&call); + let call_len = call.encoded_size() as u32; + + let (result, actual_weight) = Self::do_dispatch(T::TreasuryAccount::get(), *call); + actual_weight.map(|w| w.saturating_add(T::WeightInfo::dispatch_as_treasury(call_len))); + + Self::deposit_event(Event::::TreasuryManagerCallDispatched { call_hash, result }); + + Ok(actual_weight.into()) + } + + #[pallet::call_index(1)] + #[pallet::weight({ + let call_weight = call.get_dispatch_info().weight; + let call_len = call.encoded_size() as u32; + + T::WeightInfo::dispatch_as_aave_manager(call_len) + .saturating_add(call_weight) + })] + pub fn dispatch_as_aave_manager( + origin: OriginFor, + call: Box<::RuntimeCall>, + ) -> DispatchResultWithPostInfo { + T::AaveManagerOrigin::ensure_origin(origin)?; + + let call_hash = T::Hashing::hash_of(&call); + let call_len = call.encoded_size() as u32; + + let (result, actual_weight) = Self::do_dispatch(AaveManagerAccount::::get(), *call); + actual_weight.map(|w| w.saturating_add(T::WeightInfo::dispatch_as_aave_manager(call_len))); + + Self::deposit_event(Event::::AaveManagerCallDispatched { call_hash, result }); + + Ok(actual_weight.into()) + } + + /// Sets the Aave manager account to be used as origin for dispatching calls. + /// + /// This doesn't actually changes any ACL in the pool. + /// + /// This is intented to be mainly used in testnet environments, where the manager account + /// can be different. + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::note_aave_manager())] + pub fn note_aave_manager(origin: OriginFor, account: T::AccountId) -> DispatchResult { + ensure_root(origin)?; + AaveManagerAccount::::put(account); + Ok(()) + } + } +} + +impl Pallet { + /// Dispatch the call from the specified account as Signed Origin. + /// + /// Return the result and the actual weight of the dispatched call if there is some. + fn do_dispatch( + account: T::AccountId, + call: ::RuntimeCall, + ) -> (DispatchResultWithInfo, Option) { + let result = call.dispatch(frame_system::Origin::::Signed(account).into()); + + let call_actual_weight = match result { + Ok(call_post_info) => call_post_info.actual_weight, + Err(call_err) => call_err.post_info.actual_weight, + }; + + (result, call_actual_weight) + } +} diff --git a/pallets/dispatcher/src/mock.rs b/pallets/dispatcher/src/mock.rs new file mode 100644 index 000000000..b185aecb6 --- /dev/null +++ b/pallets/dispatcher/src/mock.rs @@ -0,0 +1,329 @@ +// This file is part of https://github.com/galacticcouncil/* +// +// $$$$$$$ Licensed under the Apache License, Version 2.0 (the "License") +// $$$$$$$$$$$$$ you may only use this file in compliance with the License +// $$$$$$$$$$$$$$$$$$$ +// $$$$$$$$$ Copyright (C) 2021-2024 Intergalactic, Limited (GIB) +// $$$$$$$$$$$ $$$$$$$$$$ SPDX-License-Identifier: Apache-2.0 +// $$$$$$$$$$$$$$$$$$$$$$$$$$ +// $$$$$$$$$$$$$$$$$$$$$$$ $ Built with <3 for decentralisation +// $$$$$$$$$$$$$$$$$$$ $$$$$$$ +// $$$$$$$ $$$$$$$$$$$$$$$$$$ Unless required by applicable law or agreed to in +// $ $$$$$$$$$$$$$$$$$$$$$$$ writing, software distributed under the License is +// $$$$$$$$$$$$$$$$$$$$$$$$$$ distributed on an "AS IS" BASIS, WITHOUT WARRANTIES +// $$$$$$$$$ $$$$$$$$$$$ OR CONDITIONS OF ANY KIND, either express or implied. +// $$$$$$$$ +// $$$$$$$$$$$$$$$$$$ See the License for the specific language governing +// $$$$$$$$$$$$$ permissions and limitations under the License. +// $$$$$$$ +// $$ +// $$$$$ $$$$$ $$ $ +// $$$ $$$ $$$ $$ $$$$$ $$ $$$ $$$$ $$$$$$$ $$$$ $$$ $$$$$$ $$ $$$$$$ +// $$$ $$$ $$$ $$ $$$ $$$ $$$ $ $$ $$ $$ $$ $$ $$ $$$ $$$ +// $$$$$$$$$$$ $$ $$ $$$ $$ $$ $$$$$$$ $$ $$ $$ $$$ $$ $$ +// $$$ $$$ $$$$ $$$ $$ $$ $$$ $$ $$ $$ $$ $$ $$ $$ +// $$$$$ $$$$$ $$ $$$$$$$$ $ $$$ $$$$$$$$ $$$ $$$$ $$$$$$$ $$$$ $$$$ +// $$$ + +use crate as dispatcher; +use crate::Config; +use frame_support::{ + parameter_types, + traits::{Everything, Nothing}, + PalletId, +}; +use frame_system as system; +use frame_system::EnsureRoot; +use hydradx_traits::{registry::Inspect, AssetKind}; +use orml_tokens::AccountData; +use orml_traits::parameter_type_with_key; +use sp_core::H256; +use sp_runtime::{ + traits::{AccountIdConversion, BlakeTwo256, IdentityLookup}, + BuildStorage, Permill, +}; +use std::{cell::RefCell, collections::HashMap}; + +type Block = frame_system::mocking::MockBlock; + +pub type AccountId = u64; +pub type Amount = i128; +pub type AssetId = u32; +pub type Balance = u128; +pub type NamedReserveIdentifier = [u8; 8]; + +pub const HDX: AssetId = 0; +pub const DAI: AssetId = 2; +pub const DOGE: AssetId = 333; +pub const REGISTERED_ASSET: AssetId = 1000; + +pub const ONE: Balance = 1_000_000_000_000; + +pub const ALICE: AccountId = 1; +pub const BOB: AccountId = 2; + +pub const TREASURY_INITIAL_BALANCE: Balance = 1_000_000 * ONE; + +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + Dispatcher: dispatcher, + Tokens: orml_tokens, + } +); + +thread_local! { + pub static REGISTERED_ASSETS: RefCell> = RefCell::new(HashMap::default()); + pub static EXISTENTIAL_DEPOSIT: RefCell>= RefCell::new(HashMap::default()); + pub static PRECISIONS: RefCell>= RefCell::new(HashMap::default()); +} + +parameter_types! { + pub NativeCurrencyId: AssetId = HDX; + pub ExistentialDepositMultiplier: u8 = 5; + pub OtcFee: Permill = Permill::from_percent(1u32); + pub const TreasuryPalletId: PalletId = PalletId(*b"aca/trsy"); + pub TreasuryAccount: AccountId = TreasuryPalletId::get().into_account_truncating(); +} + +parameter_type_with_key! { + pub ExistentialDeposits: |currency_id: AssetId| -> Balance { + EXISTENTIAL_DEPOSIT.with(|v| *v.borrow().get(currency_id).unwrap_or(&(ONE / 10))) + }; +} + +impl dispatcher::Config for Test { + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type TreasuryManagerOrigin = EnsureRoot; + type AaveManagerOrigin = EnsureRoot; + type TreasuryAccount = TreasuryAccount; + type DefaultAaveManagerAccount = TreasuryAccount; + type WeightInfo = (); +} + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 63; + pub const MaxReserves: u32 = 50; +} + +impl system::Config for Test { + type BaseCallFilter = Everything; + type BlockWeights = (); + type BlockLength = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type RuntimeTask = RuntimeTask; + type Nonce = u64; + type Block = Block; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type DbWeight = (); + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; + type SingleBlockMigrations = (); + type MultiBlockMigrator = (); + type PreInherents = (); + type PostInherents = (); + type PostTransactions = (); +} + +impl orml_tokens::Config for Test { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type Amount = Amount; + type CurrencyId = AssetId; + type WeightInfo = (); + type ExistentialDeposits = ExistentialDeposits; + type MaxLocks = (); + type DustRemovalWhitelist = Nothing; + type ReserveIdentifier = NamedReserveIdentifier; + type MaxReserves = MaxReserves; + type CurrencyHooks = (); +} + +pub struct DummyRegistry(sp_std::marker::PhantomData); + +impl Inspect for DummyRegistry { + type AssetId = AssetId; + type Location = u8; + + fn asset_type(_id: Self::AssetId) -> Option { + unimplemented!() + } + + fn decimals(_id: Self::AssetId) -> Option { + unimplemented!() + } + + fn is_sufficient(_id: Self::AssetId) -> bool { + unimplemented!() + } + + fn exists(asset_id: AssetId) -> bool { + let asset = REGISTERED_ASSETS.with(|v| v.borrow().get(&(asset_id)).copied()); + asset.is_some() + } + + fn is_banned(_id: Self::AssetId) -> bool { + unimplemented!() + } + + fn asset_name(_id: Self::AssetId) -> Option> { + unimplemented!() + } + + fn asset_symbol(_id: Self::AssetId) -> Option> { + unimplemented!() + } + + fn existential_deposit(_id: Self::AssetId) -> Option { + unimplemented!() + } +} + +#[cfg(feature = "runtime-benchmarks")] +use hydradx_traits::Create as CreateRegistry; +#[cfg(feature = "runtime-benchmarks")] +use sp_runtime::DispatchError; +#[cfg(feature = "runtime-benchmarks")] +impl CreateRegistry for DummyRegistry { + type Error = DispatchError; + type Name = sp_runtime::BoundedVec>; + type Symbol = sp_runtime::BoundedVec>; + + fn register_asset( + _asset_id: Option, + _name: Option, + _kind: AssetKind, + _existential_deposit: Option, + _symbol: Option, + _decimals: Option, + _location: Option, + _xcm_rate_limit: Option, + _is_sufficient: bool, + ) -> Result { + let assigned = REGISTERED_ASSETS.with(|v| { + //NOTE: This is to have same ids as real AssetRegistry which is used in the benchmarks. + //1_000_000 - offset of the reals AssetRegistry + // - 3 - remove assets reagistered by default for the vec.len() + // +1 - first reg asset start with 1 not 0 + // => 1-th asset id == 1_000_001 + let l = 1_000_000 - 3 + 1 + v.borrow().len(); + v.borrow_mut().insert(l as u32, l as u32); + l as u32 + }); + Ok(assigned) + } + + fn get_or_register_asset( + _name: Self::Name, + _kind: AssetKind, + _existential_deposit: Option, + _symbol: Option, + _decimals: Option, + _location: Option, + _xcm_rate_limit: Option, + _is_sufficient: bool, + ) -> Result { + unimplemented!() + } +} + +pub struct ExtBuilder { + endowed_accounts: Vec<(u64, AssetId, Balance)>, + registered_assets: Vec, +} + +impl Default for ExtBuilder { + fn default() -> Self { + // If eg. tests running on one thread only, this thread local is shared. + // let's make sure that it is empty for each test case + // or set to original default value + REGISTERED_ASSETS.with(|v| { + v.borrow_mut().clear(); + }); + EXISTENTIAL_DEPOSIT.with(|v| { + v.borrow_mut().clear(); + }); + + Self { + endowed_accounts: vec![ + (ALICE, HDX, 10_000), + (BOB, HDX, 10_000), + (ALICE, DAI, 100), + (BOB, DAI, 100), + (TreasuryAccount::get(), HDX, 1_000_000), + ], + registered_assets: vec![HDX, DAI], + } + } +} + +impl ExtBuilder { + pub fn with_existential_deposit(self, asset_id: AssetId, precision: u32) -> Self { + EXISTENTIAL_DEPOSIT.with(|v| { + v.borrow_mut().insert(asset_id, 10u128.pow(precision)); + }); + PRECISIONS.with(|v| { + v.borrow_mut().insert(asset_id, precision); + }); + + self + } + pub fn build(self) -> sp_io::TestExternalities { + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + // Add DAI and HDX as pre-registered assets + REGISTERED_ASSETS.with(|v| { + v.borrow_mut().insert(HDX, HDX); + v.borrow_mut().insert(REGISTERED_ASSET, REGISTERED_ASSET); + self.registered_assets.iter().for_each(|asset| { + v.borrow_mut().insert(*asset, *asset); + }); + }); + + orml_tokens::GenesisConfig:: { + balances: self + .endowed_accounts + .iter() + .flat_map(|(x, asset, amount)| vec![(*x, *asset, *amount * 10u128.pow(precision(*asset)))]) + .collect(), + } + .assimilate_storage(&mut t) + .unwrap(); + + let mut r: sp_io::TestExternalities = t.into(); + + r.execute_with(|| { + System::set_block_number(1); + }); + + r + } +} + +// thread_local! { +// pub static DUMMYTHREADLOCAL: RefCell = const { RefCell::new(100) }; +// } + +pub fn expect_events(e: Vec) { + test_utils::expect_events::(e); +} + +pub fn precision(asset_id: AssetId) -> u32 { + PRECISIONS.with(|v| *v.borrow().get(&asset_id).unwrap_or(&12)) +} diff --git a/pallets/dispatcher/src/tests.rs b/pallets/dispatcher/src/tests.rs new file mode 100644 index 000000000..81c0e37de --- /dev/null +++ b/pallets/dispatcher/src/tests.rs @@ -0,0 +1,55 @@ +use crate::mock::*; +use crate::Event; +use frame_support::dispatch::Pays; +use frame_support::{assert_noop, assert_ok, dispatch::PostDispatchInfo}; +use orml_traits::MultiCurrency; +use sp_runtime::{ + traits::{BlakeTwo256, Hash}, + DispatchError, +}; + +#[test] +fn dispatch_as_treasury_should_work() { + ExtBuilder::default().build().execute_with(|| { + // Arrange + let call = Box::new(RuntimeCall::Tokens(orml_tokens::Call::transfer { + dest: ALICE, + currency_id: HDX, + amount: 1_000, + })); + + let call_hash = BlakeTwo256::hash_of(&call); + let treasury_balance_before = Tokens::free_balance(HDX, &TreasuryAccount::get()); + + assert_ok!(Dispatcher::dispatch_as_treasury(RuntimeOrigin::root(), call)); + + let treasury_balance_after = Tokens::free_balance(HDX, &TreasuryAccount::get()); + + assert_eq!(treasury_balance_after, treasury_balance_before - 1_000); + + expect_events(vec![Event::TreasuryManagerCallDispatched { + call_hash, + result: Ok(PostDispatchInfo { + actual_weight: None, + pays_fee: Pays::Yes, + }), + } + .into()]); + }); +} + +#[test] +fn dispatch_as_treasury_should_fail_when_bad_origin() { + ExtBuilder::default().build().execute_with(|| { + // Arrange + let call = Box::new(RuntimeCall::System(frame_system::Call::remark_with_event { + remark: vec![1], + })); + + assert_noop!( + Dispatcher::dispatch_as_treasury(RuntimeOrigin::signed(ALICE), call), + DispatchError::BadOrigin + ); + expect_events(vec![]); + }); +} diff --git a/pallets/dispatcher/src/weights.rs b/pallets/dispatcher/src/weights.rs new file mode 100644 index 000000000..2cb264353 --- /dev/null +++ b/pallets/dispatcher/src/weights.rs @@ -0,0 +1,92 @@ +// This file is part of HydraDX. + +// Copyright (C) 2020-2023 Intergalactic, Limited (GIB). +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +//! Autogenerated weights for `pallet_dispatcher` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-12-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bench-bot`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024` + +// Executed Command: +// target/release/hydradx +// benchmark +// pallet +// --chain=dev +// --steps=50 +// --repeat=20 +// --wasm-execution=compiled +// --heap-pages=4096 +// --template=scripts/pallet-weight-template.hbs +// --pallet=pallet-dispatcher +// --output=dispatcher.rs +// --extrinsic=* + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for duster. +pub trait WeightInfo { + fn dispatch_as_treasury(n: u32) -> Weight; + fn dispatch_as_aave_manager(n: u32) -> Weight; + fn note_aave_manager() -> Weight; +} + +/// Weights for `pallet_dispatcher` using the HydraDX node and recommended hardware. +pub struct HydraWeight(PhantomData); +impl WeightInfo for () { + /// The range of component `n` is `[1, 10000]`. + fn dispatch_as_treasury(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 11_217_000 picoseconds. + Weight::from_parts(11_608_545, 0) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_288, 0).saturating_mul(n.into())) + } + /// Storage: `Dispatcher::AaveManagerAccount` (r:1 w:0) + /// Proof: `Dispatcher::AaveManagerAccount` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 10000]`. + fn dispatch_as_aave_manager(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `142` + // Estimated: `1517` + // Minimum execution time: 13_303_000 picoseconds. + Weight::from_parts(13_660_881, 1517) + // Standard Error: 2 + .saturating_add(Weight::from_parts(1_302, 0).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + } + /// Storage: `Dispatcher::AaveManagerAccount` (r:0 w:1) + /// Proof: `Dispatcher::AaveManagerAccount` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + fn note_aave_manager() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_628_000 picoseconds. + Weight::from_parts(3_864_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} diff --git a/pallets/omnipool/Cargo.toml b/pallets/omnipool/Cargo.toml index d0bb4d8f7..3e852e165 100644 --- a/pallets/omnipool/Cargo.toml +++ b/pallets/omnipool/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-omnipool" -version = "4.5.0" +version = "4.5.1" authors = ['GalacticCouncil'] edition = "2021" license = "Apache-2.0" diff --git a/runtime/hydradx/Cargo.toml b/runtime/hydradx/Cargo.toml index c192875db..0013ae70f 100644 --- a/runtime/hydradx/Cargo.toml +++ b/runtime/hydradx/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "hydradx-runtime" -version = "281.0.2" +version = "282.0.0" authors = ["GalacticCouncil"] edition = "2021" license = "Apache 2.0" @@ -64,6 +64,7 @@ pallet-liquidation = { workspace = true } pallet-bags-list = { workspace = true } pallet-balances = { workspace = true } pallet-conviction-voting = { workspace = true } +pallet-dispatcher = { workspace = true } pallet-transaction-payment = { workspace = true } pallet-transaction-payment-rpc-runtime-api = { workspace = true } pallet-treasury = { workspace = true } @@ -226,6 +227,7 @@ runtime-benchmarks = [ "pallet-conviction-voting/runtime-benchmarks", "pallet-referenda/runtime-benchmarks", "pallet-whitelist/runtime-benchmarks", + "pallet-dispatcher/runtime-benchmarks", ] std = [ "codec/std", @@ -343,6 +345,7 @@ std = [ "pallet-referenda/std", "pallet-whitelist/std", "pallet-broadcast/std", + "pallet-dispatcher/std", ] try-runtime = [ "frame-try-runtime", @@ -419,6 +422,7 @@ try-runtime = [ "pallet-referenda/try-runtime", "pallet-whitelist/try-runtime", "pallet-broadcast/try-runtime", + "pallet-dispatcher/try-runtime", ] metadata-hash = [ diff --git a/runtime/hydradx/src/governance/mod.rs b/runtime/hydradx/src/governance/mod.rs index 1b0f2cca0..0d8e411f0 100644 --- a/runtime/hydradx/src/governance/mod.rs +++ b/runtime/hydradx/src/governance/mod.rs @@ -33,7 +33,9 @@ pub mod tracks; use super::*; use crate::governance::{ - origins::{GeneralAdmin, ReferendumCanceller, ReferendumKiller, Spender, Treasurer, WhitelistedCaller}, + origins::{ + EconomicParameters, GeneralAdmin, ReferendumCanceller, ReferendumKiller, Spender, Treasurer, WhitelistedCaller, + }, tracks::TracksInfo, }; use frame_support::{ @@ -229,3 +231,17 @@ impl pallet_referenda::Config for Runtime { } impl origins::pallet_custom_origins::Config for Runtime {} + +parameter_types! { + pub const AaveManagerAccount: AccountId = AccountId::new(hex!("aa7e0000000000000000000000000000000aa7e0000000000000000000000000")); +} + +impl pallet_dispatcher::Config for Runtime { + type WeightInfo = weights::pallet_dispatcher::HydraWeight; + type RuntimeCall = RuntimeCall; + type RuntimeEvent = RuntimeEvent; + type TreasuryManagerOrigin = EitherOf, Treasurer>; + type AaveManagerOrigin = EitherOf, EconomicParameters>; + type TreasuryAccount = TreasuryAccount; + type DefaultAaveManagerAccount = AaveManagerAccount; +} diff --git a/runtime/hydradx/src/governance/origins.rs b/runtime/hydradx/src/governance/origins.rs index dc65f901e..d8881eb2b 100644 --- a/runtime/hydradx/src/governance/origins.rs +++ b/runtime/hydradx/src/governance/origins.rs @@ -61,6 +61,7 @@ pub mod pallet_custom_origins { Spender, /// Origin able to spend up to roughly $500 from the treasury at once. Tipper, + EconomicParameters, } macro_rules! decl_unit_ensures { @@ -100,6 +101,7 @@ pub mod pallet_custom_origins { ReferendumCanceller, ReferendumKiller, Treasurer, + EconomicParameters, ); macro_rules! decl_ensure { diff --git a/runtime/hydradx/src/governance/tracks.rs b/runtime/hydradx/src/governance/tracks.rs index dc7eda242..1b5463a50 100644 --- a/runtime/hydradx/src/governance/tracks.rs +++ b/runtime/hydradx/src/governance/tracks.rs @@ -46,7 +46,7 @@ const SUP_RECIP: Curve = Curve::make_reciprocal(5, 7, percent(1), percent(0), pe const SUP_FAST_RECIP: Curve = Curve::make_reciprocal(3, 7, percent(1), percent(0), percent(50)); const SUP_WHITELISTED_CALLER: Curve = Curve::make_reciprocal(1, 28, percent(3), percent(2), percent(50)); -const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] = [ +const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 10] = [ ( 0, pallet_referenda::TrackInfo { @@ -173,6 +173,20 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo); 9] min_support: SUP_RECIP, }, ), + ( + 9, + pallet_referenda::TrackInfo { + name: "economic_parameters", + max_deciding: 3, + decision_deposit: 750_000 * UNITS, + prepare_period: 60 * MINUTES, + decision_period: 7 * DAYS, + confirm_period: 12 * HOURS, + min_enactment_period: 10 * MINUTES, + min_approval: APP_RECIP, + min_support: SUP_LINEAR_FROM_25, + }, + ), ]; pub struct TracksInfo; @@ -198,6 +212,7 @@ impl pallet_referenda::TracksInfo for TracksInfo { origins::Origin::Spender => Ok(6), origins::Origin::Tipper => Ok(7), origins::Origin::OmnipoolAdmin => Ok(8), + origins::Origin::EconomicParameters => Ok(9), } } else { Err(()) diff --git a/runtime/hydradx/src/lib.rs b/runtime/hydradx/src/lib.rs index a06938c9d..0ecd894d1 100644 --- a/runtime/hydradx/src/lib.rs +++ b/runtime/hydradx/src/lib.rs @@ -113,7 +113,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_name: create_runtime_str!("hydradx"), impl_name: create_runtime_str!("hydradx"), authoring_version: 1, - spec_version: 281, + spec_version: 282, impl_version: 0, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -168,6 +168,7 @@ construct_runtime!( Referenda: pallet_referenda = 37, Origins: pallet_custom_origins = 38, Whitelist: pallet_whitelist = 39, + Dispatcher: pallet_dispatcher = 40, // HydraDX related modules AssetRegistry: pallet_asset_registry = 51, @@ -334,6 +335,7 @@ mod benches { [pallet_conviction_voting, ConvictionVoting] [pallet_referenda, Referenda] [pallet_whitelist, Whitelist] + [pallet_dispatcher, Dispatcher] ); } diff --git a/runtime/hydradx/src/weights/mod.rs b/runtime/hydradx/src/weights/mod.rs index 669c5e9b1..4cdc14c55 100644 --- a/runtime/hydradx/src/weights/mod.rs +++ b/runtime/hydradx/src/weights/mod.rs @@ -15,6 +15,7 @@ pub mod pallet_conviction_voting; pub mod pallet_currencies; pub mod pallet_dca; pub mod pallet_democracy; +pub mod pallet_dispatcher; pub mod pallet_duster; pub mod pallet_dynamic_evm_fee; pub mod pallet_elections_phragmen; diff --git a/runtime/hydradx/src/weights/pallet_dispatcher.rs b/runtime/hydradx/src/weights/pallet_dispatcher.rs new file mode 100644 index 000000000..0133999c3 --- /dev/null +++ b/runtime/hydradx/src/weights/pallet_dispatcher.rs @@ -0,0 +1,93 @@ +// This file is part of HydraDX. + +// Copyright (C) 2020-2023 Intergalactic, Limited (GIB). +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +//! Autogenerated weights for `pallet_dispatcher` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2025-01-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `bench-bot`, CPU: `Intel(R) Core(TM) i7-7700K CPU @ 4.20GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `None`, DB CACHE: `1024` + +// Executed Command: +// ./target/release/hydradx +// benchmark +// pallet +// --wasm-execution=compiled +// --pallet +// pallet-dispatcher +// --extrinsic +// * +// --heap-pages +// 4096 +// --steps +// 50 +// --repeat +// 20 +// --template=scripts/pallet-weight-template.hbs +// --output +// weights.rs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] +#![allow(missing_docs)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weights for `pallet_dispatcher`. +pub struct WeightInfo(PhantomData); + +/// Weights for `pallet_dispatcher` using the HydraDX node and recommended hardware. +pub struct HydraWeight(PhantomData); +impl pallet_dispatcher::WeightInfo for HydraWeight { + /// The range of component `n` is `[1, 10000]`. + fn dispatch_as_treasury(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 11_217_000 picoseconds. + Weight::from_parts(11_608_545, 0) + // Standard Error: 1 + .saturating_add(Weight::from_parts(1_288, 0).saturating_mul(n.into())) + } + /// Storage: `Dispatcher::AaveManagerAccount` (r:1 w:0) + /// Proof: `Dispatcher::AaveManagerAccount` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + /// The range of component `n` is `[1, 10000]`. + fn dispatch_as_aave_manager(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `142` + // Estimated: `1517` + // Minimum execution time: 13_303_000 picoseconds. + Weight::from_parts(13_660_881, 1517) + // Standard Error: 2 + .saturating_add(Weight::from_parts(1_302, 0).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(1_u64)) + } + /// Storage: `Dispatcher::AaveManagerAccount` (r:0 w:1) + /// Proof: `Dispatcher::AaveManagerAccount` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`) + fn note_aave_manager() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 3_628_000 picoseconds. + Weight::from_parts(3_864_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +}