diff --git a/Cargo.lock b/Cargo.lock index ac61c8b9d..7ae5884c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6455,6 +6455,23 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-cardano-config" +version = "1.7.0" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "parity-scale-codec", + "pretty_assertions", + "scale-info", + "sidechain-domain", + "sp-core", + "sp-io", + "sp-runtime", +] + [[package]] name = "pallet-governed-map" version = "1.7.0" diff --git a/Cargo.toml b/Cargo.toml index 2a7304470..35eb8056b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ members = [ "toolkit/utils/db-sync-sqlx", "toolkit/governed-map/primitives", "toolkit/governed-map/pallet", + "toolkit/cardano-config/pallet", ] resolver = "2" @@ -329,5 +330,8 @@ partner-chains-mock-data-sources = { path = "toolkit/data-sources/mock", default sp-governed-map = { path = "toolkit/governed-map/primitives", default-features = false } pallet-governed-map = { path = "toolkit/governed-map/pallet", default-features = false } +# Cardano Config +pallet-cardano-config = { path = "toolkit/cardano-config/pallet", default-features = false } + # demo node partner-chains-demo-runtime = { path = "demo/runtime" } diff --git a/toolkit/cardano-config/pallet/Cargo.toml b/toolkit/cardano-config/pallet/Cargo.toml new file mode 100644 index 000000000..b5095368d --- /dev/null +++ b/toolkit/cardano-config/pallet/Cargo.toml @@ -0,0 +1,52 @@ +[package] +name = "pallet-cardano-config" +authors.workspace = true +edition.workspace = true +homepage.workspace = true +repository.workspace = true +version.workspace = true +license = "Apache-2.0" +description = "Pallet for storing Cardano configuration parameters in runtime storage" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[lints] +workspace = true + +[dependencies] +frame-benchmarking = { workspace = true, optional = true } +frame-support = { workspace = true } +frame-system = { workspace = true } +log = { workspace = true } +parity-scale-codec = { workspace = true } +scale-info = { workspace = true } +sidechain-domain = { workspace = true } +sp-core = { workspace = true } +sp-runtime = { workspace = true } + +[dev-dependencies] +pretty_assertions = { workspace = true } +sp-core = { workspace = true } +sp-io = { workspace = true } +sp-runtime = { workspace = true } + +[features] +default = ["std"] +std = [ + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "log/std", + "parity-scale-codec/std", + "scale-info/std", + "sidechain-domain/std", + "sp-core/std", + "sp-runtime/std" +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", +] +mock = [] diff --git a/toolkit/cardano-config/pallet/src/benchmarking.rs b/toolkit/cardano-config/pallet/src/benchmarking.rs new file mode 100644 index 000000000..8d6cf39d2 --- /dev/null +++ b/toolkit/cardano-config/pallet/src/benchmarking.rs @@ -0,0 +1,51 @@ +//! Benchmarking setup for pallet-cardano-config + +#![cfg(feature = "runtime-benchmarks")] + +use super::*; +use frame_benchmarking::v2::*; +use frame_support::{assert_ok, traits::Get}; +use sidechain_domain::{CardanoConfig, MainchainEpochConfig}; +use sp_core::offchain::{Duration, Timestamp}; + +/// Helper trait for benchmarking +pub trait BenchmarkHelper { + /// Returns a sample CardanoConfig for benchmarking + fn cardano_config() -> CardanoConfig; +} + +impl BenchmarkHelper for () { + fn cardano_config() -> CardanoConfig { + CardanoConfig { + epoch_config: MainchainEpochConfig { + epoch_duration_millis: Duration::from_millis(432000000), // 5 days + slot_duration_millis: Duration::from_millis(1000), // 1 second + first_epoch_timestamp_millis: Timestamp::from_unix_millis(1596059091000), + first_epoch_number: 208, + first_slot_number: 4492800, + }, + cardano_security_parameter: 432, + cardano_active_slots_coeff: 0.05, + } + } +} + +#[benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn set_cardano_config() { + let config = T::BenchmarkHelper::cardano_config(); + + #[extrinsic_call] + _(RawOrigin::Root, config.clone()); + + assert_eq!(CardanoConfiguration::::get(), Some(config.clone())); + assert_eq!(MainchainEpochConfiguration::::get(), Some(config.epoch_config)); + assert_eq!(CardanoSecurityParameter::::get(), Some(config.cardano_security_parameter)); + assert_eq!(CardanoActiveSlotsCoeff::::get(), Some(config.cardano_active_slots_coeff)); + } + + impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/toolkit/cardano-config/pallet/src/lib.rs b/toolkit/cardano-config/pallet/src/lib.rs new file mode 100644 index 000000000..0d0b1890f --- /dev/null +++ b/toolkit/cardano-config/pallet/src/lib.rs @@ -0,0 +1,212 @@ +//! Pallet for storing Cardano configuration parameters in runtime storage. +//! +//! # Purpose of this pallet +//! +//! This pallet stores Cardano configuration parameters that are essential for Partner Chain operation, +//! including mainchain epoch configuration and consensus parameters. By storing these parameters in +//! runtime storage rather than relying on environment variables, we ensure all nodes have consistent +//! configuration as part of the chain state. + +#![cfg_attr(not(feature = "std"), no_std)] +#![deny(missing_docs)] + +extern crate alloc; + +pub use pallet::*; + +use crate::weights::WeightInfo; +use core::marker::PhantomData; +use frame_support::pallet_prelude::*; +use frame_system::pallet_prelude::*; +use sidechain_domain::{ + cardano_config::CardanoConfig, + mainchain_epoch::MainchainEpochConfig, +}; +use sp_runtime::Perbill; +use sp_core::offchain::{Duration, Timestamp}; + +pub mod weights; + +#[cfg(test)] +mod tests; + +#[cfg(test)] +mod mock; + +#[cfg(feature = "runtime-benchmarks")] +pub mod benchmarking; + +#[frame_support::pallet] +pub mod pallet { + use super::*; + + #[pallet::pallet] + pub struct Pallet(_); + + /// Current pallet version + pub const PALLET_VERSION: u32 = 1; + + #[pallet::config] + pub trait Config: frame_system::Config { + /// Weight functions for the pallet's extrinsics + type WeightInfo: weights::WeightInfo; + + /// Helper functions required by the pallet's benchmarks to construct realistic input data. + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper: crate::benchmarking::BenchmarkHelper; + } + + /// Error type used by this pallet's extrinsics + #[pallet::error] + pub enum Error { + /// Configuration has already been set and cannot be changed + ConfigurationAlreadySet, + } + + /// Stores the epoch duration in milliseconds + #[pallet::storage] + #[pallet::getter(fn epoch_duration_millis)] + pub type EpochDurationMillis = StorageValue<_, u64, OptionQuery>; + + /// Stores the slot duration in milliseconds + #[pallet::storage] + #[pallet::getter(fn slot_duration_millis)] + pub type SlotDurationMillis = StorageValue<_, u64, OptionQuery>; + + /// Stores the first epoch timestamp in milliseconds + #[pallet::storage] + #[pallet::getter(fn first_epoch_timestamp_millis)] + pub type FirstEpochTimestampMillis = StorageValue<_, u64, OptionQuery>; + + /// Stores the first epoch number + #[pallet::storage] + #[pallet::getter(fn first_epoch_number)] + pub type FirstEpochNumber = StorageValue<_, u32, OptionQuery>; + + /// Stores the first slot number + #[pallet::storage] + #[pallet::getter(fn first_slot_number)] + pub type FirstSlotNumber = StorageValue<_, u64, OptionQuery>; + + /// Stores the Cardano security parameter (k) + #[pallet::storage] + #[pallet::getter(fn cardano_security_parameter)] + pub type CardanoSecurityParameter = StorageValue<_, u32, OptionQuery>; + + /// Stores the Cardano active slots coefficient (f) as parts per billion + #[pallet::storage] + #[pallet::getter(fn cardano_active_slots_coeff)] + pub type CardanoActiveSlotsCoeff = StorageValue<_, Perbill, OptionQuery>; + + #[pallet::genesis_config] + #[derive(frame_support::DefaultNoBound)] + pub struct GenesisConfig { + /// Initial Cardano configuration. + pub cardano_config: Option, + /// Phantom data marker + pub _marker: PhantomData, + } + + #[pallet::genesis_build] + impl BuildGenesisConfig for GenesisConfig { + fn build(&self) { + if let Some(config) = &self.cardano_config { + EpochDurationMillis::::put(config.epoch_config.epoch_duration_millis.as_millis()); + SlotDurationMillis::::put(config.epoch_config.slot_duration_millis.as_millis()); + FirstEpochTimestampMillis::::put(config.epoch_config.first_epoch_timestamp_millis.as_unix_millis()); + FirstEpochNumber::::put(config.epoch_config.first_epoch_number); + FirstSlotNumber::::put(config.epoch_config.first_slot_number); + CardanoSecurityParameter::::put(config.cardano_security_parameter); + CardanoActiveSlotsCoeff::::put(Perbill::from_float(config.cardano_active_slots_coeff as f64)); + } + } + } + + #[pallet::call] + impl Pallet { + /// Set the Cardano configuration. This can only be called once. + #[pallet::call_index(0)] + #[pallet::weight(T::WeightInfo::set_cardano_config())] + pub fn set_cardano_config( + origin: OriginFor, + config: CardanoConfig, + ) -> DispatchResult { + ensure_root(origin)?; + + ensure!( + !Self::is_configured(), + Error::::ConfigurationAlreadySet + ); + + EpochDurationMillis::::put(config.epoch_config.epoch_duration_millis.0); + SlotDurationMillis::::put(config.epoch_config.slot_duration_millis.0); + FirstEpochTimestampMillis::::put(config.epoch_config.first_epoch_timestamp_millis.0); + FirstEpochNumber::::put(config.epoch_config.first_epoch_number); + FirstSlotNumber::::put(config.epoch_config.first_slot_number); + CardanoSecurityParameter::::put(config.cardano_security_parameter); + CardanoActiveSlotsCoeff::::put(Perbill::from_float(config.cardano_active_slots_coeff)); + + log::info!("🔧 Cardano configuration set"); + Ok(()) + } + } + + impl Pallet { + /// Returns the complete Cardano configuration + pub fn get_cardano_config() -> Option { + let epoch_config = Self::get_mainchain_epoch_config()?; + let security_parameter = CardanoSecurityParameter::::get()?; + let active_slots_coeff = CardanoActiveSlotsCoeff::::get()?; + + Some(CardanoConfig { + epoch_config, + cardano_security_parameter: security_parameter, + cardano_active_slots_coeff: active_slots_coeff.deconstruct() as f32 / 1_000_000_000.0, + }) + } + + /// Returns the mainchain epoch configuration + pub fn get_mainchain_epoch_config() -> Option { + let epoch_duration_millis = EpochDurationMillis::::get()?; + let slot_duration_millis = SlotDurationMillis::::get()?; + let first_epoch_timestamp_millis = FirstEpochTimestampMillis::::get()?; + let first_epoch_number = FirstEpochNumber::::get()?; + let first_slot_number = FirstSlotNumber::::get()?; + + Some(MainchainEpochConfig { + epoch_duration_millis: Duration::from_millis(epoch_duration_millis), + slot_duration_millis: Duration::from_millis(slot_duration_millis), + first_epoch_timestamp_millis: Timestamp::from_unix_millis(first_epoch_timestamp_millis), + first_epoch_number, + first_slot_number, + }) + } + + /// Returns the Cardano security parameter (k) + pub fn get_cardano_security_parameter() -> Option { + CardanoSecurityParameter::::get() + } + + /// Returns the Cardano active slots coefficient (f) + pub fn get_cardano_active_slots_coeff() -> Option { + CardanoActiveSlotsCoeff::::get() + .map(|perbill| perbill.deconstruct() as f32 / 1_000_000_000.0) + } + + /// Returns whether the configuration has been set + pub fn is_configured() -> bool { + EpochDurationMillis::::exists() && + SlotDurationMillis::::exists() && + FirstEpochTimestampMillis::::exists() && + FirstEpochNumber::::exists() && + FirstSlotNumber::::exists() && + CardanoSecurityParameter::::exists() && + CardanoActiveSlotsCoeff::::exists() + } + + /// Returns current pallet version + pub fn get_version() -> u32 { + PALLET_VERSION + } + } +} diff --git a/toolkit/cardano-config/pallet/src/mock.rs b/toolkit/cardano-config/pallet/src/mock.rs new file mode 100644 index 000000000..d46a2b80f --- /dev/null +++ b/toolkit/cardano-config/pallet/src/mock.rs @@ -0,0 +1,94 @@ +//! Mock runtime for pallet-cardano-config tests + +use crate as pallet_cardano_config; +use frame_support::{ + derive_impl, parameter_types, + traits::{ConstU16, ConstU32, ConstU64}, +}; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + BuildStorage, +}; + +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + CardanoConfig: pallet_cardano_config, + } +); + +parameter_types! { + pub const BlockHashCount: u64 = 250; + pub const SS58Prefix: u8 = 42; +} + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = sp_core::H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = BlockHashCount; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = SS58Prefix; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +impl pallet_cardano_config::Config for Test { + type WeightInfo = (); + #[cfg(feature = "runtime-benchmarks")] + type BenchmarkHelper = (); +} + +// Build genesis storage according to the mock runtime. +pub fn new_test_ext() -> sp_io::TestExternalities { + frame_system::GenesisConfig::::default().build_storage().unwrap().into() +} + +// Build genesis storage with CardanoConfig preset +pub fn new_test_ext_with_config() -> sp_io::TestExternalities { + use sidechain_domain::{CardanoConfig, MainchainEpochConfig}; + use sp_core::offchain::{Duration, Timestamp}; + + let config = CardanoConfig { + epoch_config: MainchainEpochConfig { + epoch_duration_millis: Duration::from_millis(432000000), // 5 days + slot_duration_millis: Duration::from_millis(1000), // 1 second + first_epoch_timestamp_millis: Timestamp::from_unix_millis(1596059091000), + first_epoch_number: 208, + first_slot_number: 4492800, + }, + cardano_security_parameter: 432, + cardano_active_slots_coeff: 0.05, + }; + + let mut t = frame_system::GenesisConfig::::default().build_storage().unwrap(); + + pallet_cardano_config::GenesisConfig:: { + cardano_config: Some(config), + _marker: Default::default(), + } + .assimilate_storage(&mut t) + .unwrap(); + + t.into() +} diff --git a/toolkit/cardano-config/pallet/src/tests.rs b/toolkit/cardano-config/pallet/src/tests.rs new file mode 100644 index 000000000..0e110b8ab --- /dev/null +++ b/toolkit/cardano-config/pallet/src/tests.rs @@ -0,0 +1,147 @@ +//! Tests for pallet-cardano-config + +use crate::{mock::*, Error}; +use frame_support::{assert_noop, assert_ok, dispatch::DispatchError}; +use sidechain_domain::{CardanoConfig, MainchainEpochConfig}; +use sp_core::offchain::{Duration, Timestamp}; + +fn sample_cardano_config() -> CardanoConfig { + CardanoConfig { + epoch_config: MainchainEpochConfig { + epoch_duration_millis: Duration::from_millis(432000000), // 5 days + slot_duration_millis: Duration::from_millis(1000), // 1 second + first_epoch_timestamp_millis: Timestamp::from_unix_millis(1596059091000), + first_epoch_number: 208, + first_slot_number: 4492800, + }, + cardano_security_parameter: 432, + cardano_active_slots_coeff: 0.05, + } +} + +#[test] +fn genesis_config_works() { + new_test_ext_with_config().execute_with(|| { + let expected_config = sample_cardano_config(); + + // Check that configuration was set at genesis + assert!(CardanoConfig::is_configured()); + assert_eq!(CardanoConfig::get_cardano_config(), Some(expected_config.clone())); + assert_eq!(CardanoConfig::get_mainchain_epoch_config(), Some(expected_config.epoch_config)); + assert_eq!(CardanoConfig::get_cardano_security_parameter(), Some(expected_config.cardano_security_parameter)); + assert_eq!(CardanoConfig::get_cardano_active_slots_coeff(), Some(expected_config.cardano_active_slots_coeff)); + }); +} + +#[test] +fn set_cardano_config_works() { + new_test_ext().execute_with(|| { + let config = sample_cardano_config(); + + // Initially not configured + assert!(!CardanoConfig::is_configured()); + assert_eq!(CardanoConfig::get_cardano_config(), None); + + // Set configuration + assert_ok!(CardanoConfig::set_cardano_config(RuntimeOrigin::root(), config.clone())); + + // Check that configuration was set + assert!(CardanoConfig::is_configured()); + assert_eq!(CardanoConfig::get_cardano_config(), Some(config.clone())); + assert_eq!(CardanoConfig::get_mainchain_epoch_config(), Some(config.epoch_config)); + assert_eq!(CardanoConfig::get_cardano_security_parameter(), Some(config.cardano_security_parameter)); + assert_eq!(CardanoConfig::get_cardano_active_slots_coeff(), Some(config.cardano_active_slots_coeff)); + }); +} + +#[test] +fn set_cardano_config_requires_root() { + new_test_ext().execute_with(|| { + let config = sample_cardano_config(); + + // Non-root origin should fail + assert_noop!( + CardanoConfig::set_cardano_config(RuntimeOrigin::signed(1), config), + DispatchError::BadOrigin + ); + + // Configuration should not be set + assert!(!CardanoConfig::is_configured()); + }); +} + +#[test] +fn set_cardano_config_only_once() { + new_test_ext().execute_with(|| { + let config = sample_cardano_config(); + + // Set configuration first time + assert_ok!(CardanoConfig::set_cardano_config(RuntimeOrigin::root(), config.clone())); + + // Try to set again - should fail + assert_noop!( + CardanoConfig::set_cardano_config(RuntimeOrigin::root(), config), + Error::::ConfigurationAlreadySet + ); + }); +} + +#[test] +fn set_cardano_config_fails_if_already_set_at_genesis() { + new_test_ext_with_config().execute_with(|| { + let config = sample_cardano_config(); + + // Configuration already set at genesis + assert!(CardanoConfig::is_configured()); + + // Try to set again - should fail + assert_noop!( + CardanoConfig::set_cardano_config(RuntimeOrigin::root(), config), + Error::::ConfigurationAlreadySet + ); + }); +} + +#[test] +fn getters_work_correctly() { + new_test_ext().execute_with(|| { + // Initially nothing set + assert_eq!(CardanoConfig::get_cardano_config(), None); + assert_eq!(CardanoConfig::get_mainchain_epoch_config(), None); + assert_eq!(CardanoConfig::get_cardano_security_parameter(), None); + assert_eq!(CardanoConfig::get_cardano_active_slots_coeff(), None); + assert!(!CardanoConfig::is_configured()); + + let config = sample_cardano_config(); + assert_ok!(CardanoConfig::set_cardano_config(RuntimeOrigin::root(), config.clone())); + + // All getters should return correct values + assert_eq!(CardanoConfig::get_cardano_config(), Some(config.clone())); + assert_eq!(CardanoConfig::get_mainchain_epoch_config(), Some(config.epoch_config)); + assert_eq!(CardanoConfig::get_cardano_security_parameter(), Some(config.cardano_security_parameter)); + assert_eq!(CardanoConfig::get_cardano_active_slots_coeff(), Some(config.cardano_active_slots_coeff)); + assert!(CardanoConfig::is_configured()); + }); +} + +#[test] +fn version_is_correct() { + assert_eq!(CardanoConfig::get_version(), 1); +} + +#[test] +fn different_configs_work() { + new_test_ext().execute_with(|| { + let mut config = sample_cardano_config(); + config.cardano_security_parameter = 100; + config.cardano_active_slots_coeff = 0.1; + config.epoch_config.epoch_duration_millis = Duration::from_millis(86400000); // 1 day + + assert_ok!(CardanoConfig::set_cardano_config(RuntimeOrigin::root(), config.clone())); + + assert_eq!(CardanoConfig::get_cardano_config(), Some(config.clone())); + assert_eq!(CardanoConfig::get_cardano_security_parameter(), Some(100)); + assert_eq!(CardanoConfig::get_cardano_active_slots_coeff(), Some(0.1)); + assert_eq!(CardanoConfig::get_mainchain_epoch_config(), Some(config.epoch_config)); + }); +} diff --git a/toolkit/cardano-config/pallet/src/weights.rs b/toolkit/cardano-config/pallet/src/weights.rs new file mode 100644 index 000000000..6f7fd3c2d --- /dev/null +++ b/toolkit/cardano-config/pallet/src/weights.rs @@ -0,0 +1,76 @@ +//! Autogenerated weights for `pallet_cardano_config` +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 +//! DATE: 2024-01-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `substrate-benchmark`, CPU: `Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz` +//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: 1024 + +// Executed Command: +// ./target/production/substrate-node +// benchmark +// pallet +// --chain=dev +// --steps=50 +// --repeat=20 +// --pallet=pallet_cardano_config +// --extrinsic=* +// --wasm-execution=compiled +// --heap-pages=4096 +// --output=./pallets/cardano-config/src/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; + +/// Weight functions needed for `pallet_cardano_config`. +pub trait WeightInfo { + fn set_cardano_config() -> Weight; +} + +/// Weights for `pallet_cardano_config` using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + /// Storage: `CardanoConfig::CardanoConfiguration` (r:1 w:1) + /// Proof: `CardanoConfig::CardanoConfiguration` (`max_values`: Some(1), `max_size`: Some(128), added: 623, mode: `MaxEncodedLen`) + /// Storage: `CardanoConfig::MainchainEpochConfiguration` (r:0 w:1) + /// Proof: `CardanoConfig::MainchainEpochConfiguration` (`max_values`: Some(1), `max_size`: Some(64), added: 559, mode: `MaxEncodedLen`) + /// Storage: `CardanoConfig::CardanoSecurityParameter` (r:0 w:1) + /// Proof: `CardanoConfig::CardanoSecurityParameter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `CardanoConfig::CardanoActiveSlotsCoeff` (r:0 w:1) + /// Proof: `CardanoConfig::CardanoActiveSlotsCoeff` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn set_cardano_config() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1613` + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 1613) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(4_u64)) + } +} + +// For backwards compatibility and tests. +impl WeightInfo for () { + /// Storage: `CardanoConfig::CardanoConfiguration` (r:1 w:1) + /// Proof: `CardanoConfig::CardanoConfiguration` (`max_values`: Some(1), `max_size`: Some(128), added: 623, mode: `MaxEncodedLen`) + /// Storage: `CardanoConfig::MainchainEpochConfiguration` (r:0 w:1) + /// Proof: `CardanoConfig::MainchainEpochConfiguration` (`max_values`: Some(1), `max_size`: Some(64), added: 559, mode: `MaxEncodedLen`) + /// Storage: `CardanoConfig::CardanoSecurityParameter` (r:0 w:1) + /// Proof: `CardanoConfig::CardanoSecurityParameter` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + /// Storage: `CardanoConfig::CardanoActiveSlotsCoeff` (r:0 w:1) + /// Proof: `CardanoConfig::CardanoActiveSlotsCoeff` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`) + fn set_cardano_config() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `1613` + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 1613) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(4_u64)) + } +}