Compare commits

...

29 Commits

Author SHA1 Message Date
4c4374c812
downgrade state version
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-03-04 17:11:17 +03:00
e7b8cd46e1
add transaction hash to the unique identifier of the bridging tx
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-03-03 22:18:32 +03:00
713cbdfdc1
latest benhcmarking setup for casper runtime
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-03-01 13:26:26 +03:00
5dcc23c996
update pallets weights based on the real benchmarkings
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-03-01 12:39:44 +03:00
562efe5744
apply final changes to casper runtime
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-02-26 21:38:34 +03:00
b0a69493cd
fix benchmarking for slow clap
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-02-26 21:36:14 +03:00
bd8d7145af
more optimized version for try_offend_validators
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-02-26 14:44:36 +03:00
ba7d2a8222
additional function for exposure trait
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2026-02-26 14:42:39 +03:00
cc300fefb0
apply changes to casper runtime; migrations are included
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-24 22:06:54 +03:00
c8f8ea7130
rustfmt of the chain specs
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-24 22:03:45 +03:00
93387218ec
make initialise authorities infallable and fix benchmarking
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-24 22:02:26 +03:00
6a5029017c
use ExternalBlockNumber type everywhere
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-23 19:13:14 +03:00
4c79048b49
migration to new block commitment data type; tests included
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-23 18:56:05 +03:00
24b08a87b1
make max commit deviation to be 1/8 of EpochDuration
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-23 16:55:33 +03:00
06618069e2
avoid commitments check on the beginning of the epoch
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-23 15:17:13 +03:00
028afc089f
use internal block number as last_update for block commitments
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-22 21:56:55 +03:00
f082dfc4e0
ability to iterate over network ids only and get networks lenght without storage read
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-22 21:54:51 +03:00
c963f7816b
slightly optimise try_slow_clap
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-22 13:25:10 +03:00
63c03ad6ce
extend trait with network existence check
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-22 13:14:58 +03:00
4e1a3de6de
prepare benchmarks and update default weights
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-22 11:49:39 +03:00
5dd0c73f7a
move block commitment check to the on_initialize hook
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-21 17:57:49 +03:00
03262539aa
adapt trait; add extra test; fix benchmarking
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-21 17:55:26 +03:00
f524b01b03
make function name more obvious
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-21 17:52:42 +03:00
f99eee2e1a
remove nullification functionality from trait
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-21 14:17:35 +03:00
d3cc3ac1b3
remove unnecessary storage entry in pallet
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-21 14:15:51 +03:00
7a7712df0b
replace custom muldiv with multiply_by_rational_with_rounding from substrate
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-21 12:54:29 +03:00
cce2910cf8
make networks pallet to be indexed storage map; migrations included
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-20 17:15:53 +03:00
5b5e53e6fd
update traits for the network handler
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-20 16:09:54 +03:00
2313bc97ec
user agent added to mimic the curl
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2026-02-19 19:23:50 +03:00
35 changed files with 2074 additions and 1226 deletions

10
Cargo.lock generated
View File

@ -1186,7 +1186,7 @@ dependencies = [
[[package]]
name = "casper-runtime"
version = "3.5.37"
version = "3.5.41"
dependencies = [
"casper-runtime-constants",
"frame-benchmarking",
@ -3650,13 +3650,14 @@ dependencies = [
[[package]]
name = "ghost-networks"
version = "0.1.20"
version = "0.1.26"
dependencies = [
"frame-benchmarking",
"frame-support",
"frame-system",
"ghost-core-primitives",
"ghost-traits",
"log",
"num-traits",
"pallet-balances",
"pallet-staking",
@ -3837,7 +3838,7 @@ dependencies = [
[[package]]
name = "ghost-slow-clap"
version = "0.4.14"
version = "0.4.28"
dependencies = [
"frame-benchmarking",
"frame-support",
@ -3889,10 +3890,11 @@ dependencies = [
[[package]]
name = "ghost-traits"
version = "0.3.26"
version = "0.3.32"
dependencies = [
"frame-support",
"sp-runtime 31.0.1",
"sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.12.0)",
]
[[package]]

View File

@ -1,6 +1,6 @@
[package]
name = "ghost-networks"
version = "0.1.20"
version = "0.1.26"
license.workspace = true
authors.workspace = true
edition.workspace = true
@ -11,6 +11,7 @@ repository.workspace = true
scale-info = { workspace = true, features = ["derive"] }
codec = { workspace = true, features = ["max-encoded-len"] }
num-traits = { workspace = true }
log = { workspace = true }
frame-benchmarking = { workspace = true, optional = true }
frame-support = { workspace = true }
@ -31,6 +32,7 @@ default = ["std"]
std = [
"scale-info/std",
"codec/std",
"log/std",
"num-traits/std",
"frame-support/std",
"frame-system/std",

View File

@ -85,13 +85,15 @@ benchmarks! {
let (chain_id, network) = prepare_network::<T>(i, j, k);
let authority = T::RegisterOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?;
let prev_network = GhostNetworks::<T>::networks(chain_id.clone());
assert_eq!(GhostNetworks::<T>::networks(chain_id.clone()), None);
assert!(GhostNetworks::<T>::network_indexes().is_empty());
}: _<T::RuntimeOrigin>(authority, chain_id.clone(), network.clone())
verify {
assert_last_event::<T>(Event::NetworkRegistered {
chain_id: chain_id.clone(), network,
chain_id: chain_id.clone(), network: network.clone(),
}.into());
assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network);
assert_eq!(GhostNetworks::<T>::networks(chain_id.clone()), Some(network));
assert_eq!(GhostNetworks::<T>::network_indexes(), vec![chain_id]);
}
update_network_name {
@ -251,20 +253,23 @@ benchmarks! {
assert_last_event::<T>(Event::NetworkAvgBlockSpeedUpdated {
chain_id: chain_id.clone(), avg_block_speed,
}.into());
assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network);
assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), None);
}
remove_network {
let (chain_id, network) = prepare_network::<T>(1, 1, 1);
let authority = T::RemoveOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
let _ = create_network::<T>(chain_id.clone(), network.clone())?;
assert_eq!(GhostNetworks::<T>::networks(chain_id.clone()), Some(network));
assert_eq!(GhostNetworks::<T>::network_indexes(), vec![chain_id.clone()]);
}: _<T::RuntimeOrigin>(authority, chain_id.clone())
verify {
assert_last_event::<T>(Event::NetworkRemoved {
chain_id: chain_id.clone(),
}.into());
assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network);
assert_eq!(GhostNetworks::<T>::networks(chain_id.clone()), None);
assert!(GhostNetworks::<T>::network_indexes().is_empty());
}
impl_benchmark_test_suite!(GhostNetworks, crate::mock::ExtBuilder::build(), crate::mock::Test);

View File

@ -12,7 +12,7 @@ use scale_info::TypeInfo;
use sp_runtime::{
curve::PiecewiseLinear,
traits::{AtLeast32BitUnsigned, CheckedAdd, CheckedSub, Member},
traits::{AtLeast32BitUnsigned, CheckedAdd, CheckedSub, Member, UniqueSaturatedInto},
DispatchResult,
};
use sp_std::{convert::TryInto, prelude::*};
@ -21,11 +21,10 @@ pub use ghost_traits::networks::{
NetworkDataBasicHandler, NetworkDataInspectHandler, NetworkDataMutateHandler,
};
mod math;
pub mod migrations;
mod weights;
pub use crate::weights::WeightInfo;
use math::MulDiv;
pub use module::*;
#[cfg(any(feature = "runtime-benchmarks", test))]
@ -35,6 +34,8 @@ mod mock;
#[cfg(all(feature = "std", test))]
mod tests;
const LOG_TARGET: &str = "runtime::ghost-networks";
pub type BalanceOf<T> =
<<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
@ -96,23 +97,26 @@ where
_era_duration_in_millis: u64,
) -> (Balance, Balance) {
let reward_curve = RewardCurve::get();
let bridged_imbalance = BridgedImbalance::<T>::get();
let accumulated_commission = AccumulatedCommission::<T>::get();
let bridged_imbalance = BridgedImbalance::<T>::take();
let accumulated_commission = AccumulatedCommission::<T>::take();
let accumulated_commission: Balance = accumulated_commission.into();
let adjusted_issuance: Balance = total_issuance
.saturating_add(bridged_imbalance.bridged_out.into())
.saturating_sub(bridged_imbalance.bridged_in.into());
NullifyNeeded::<T>::set(true);
let estimated_reward =
reward_curve.calculate_for_fraction_times_denominator(total_staked, adjusted_issuance);
let payout = MulDiv::<Balance>::calculate(
estimated_reward,
accumulated_commission,
adjusted_issuance,
);
let payout: Balance = sp_runtime::helpers_128bit::multiply_by_rational_with_rounding(
estimated_reward.unique_saturated_into(),
accumulated_commission.unique_saturated_into(),
adjusted_issuance.unique_saturated_into(),
sp_runtime::Rounding::NearestPrefUp,
)
.map(|result| result.unique_saturated_into())
.unwrap_or_default();
let rest_payout = accumulated_commission.saturating_sub(payout);
(payout, rest_payout)
@ -123,6 +127,8 @@ where
pub mod module {
use super::*;
const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
#[pallet::config]
pub trait Config: frame_system::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
@ -149,6 +155,9 @@ pub mod module {
/// The origin required to remove network.
type RemoveOrigin: EnsureOrigin<Self::RuntimeOrigin>;
#[pallet::constant]
type MaxNetworks: Get<u32>;
/// Weight information for extrinsics in this module.
type WeightInfo: WeightInfo;
}
@ -163,6 +172,8 @@ pub mod module {
WrongGatekeeperAddress,
/// Topic name length not 66 or prefix `0x` missed.
WrongTopicName,
/// Could not store networks into bounded vector.
TooManyNetworks,
}
#[pallet::event]
@ -230,10 +241,6 @@ pub mod module {
},
}
#[pallet::storage]
#[pallet::getter(fn nullify_needed)]
pub type NullifyNeeded<T: Config> = StorageValue<_, bool, ValueQuery>;
#[pallet::storage]
#[pallet::getter(fn bridged_imbalance)]
pub type BridgedImbalance<T: Config> =
@ -243,6 +250,11 @@ pub mod module {
#[pallet::getter(fn accumulated_commission)]
pub type AccumulatedCommission<T: Config> = StorageValue<_, BalanceOf<T>, ValueQuery>;
#[pallet::storage]
#[pallet::getter(fn network_indexes)]
pub type NetworkIndexes<T: Config> =
StorageValue<_, BoundedVec<T::NetworkId, T::MaxNetworks>, ValueQuery>;
#[pallet::storage]
#[pallet::getter(fn networks)]
pub type Networks<T: Config> =
@ -282,23 +294,10 @@ pub mod module {
}
#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
#[pallet::without_storage_info]
pub struct Pallet<T>(PhantomData<T>);
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(_: BlockNumberFor<T>) -> Weight {
T::DbWeight::get().reads_writes(1, 1)
}
fn on_finalize(_: BlockNumberFor<T>) {
if Self::nullify_needed() {
Self::nullify_commission();
NullifyNeeded::<T>::put(false);
}
}
}
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
@ -470,12 +469,19 @@ impl<T: Config> Pallet<T> {
Ok(())
})?;
NetworkIndexes::<T>::try_mutate(|ids| -> DispatchResult {
ids.try_push(chain_id)
.map_err(|_| Error::<T>::TooManyNetworks)?;
Ok(())
})?;
Self::deposit_event(Event::<T>::NetworkRegistered { chain_id, network });
Ok(())
}
/// Remove existent network.
pub fn do_remove_network(chain_id: T::NetworkId) -> DispatchResult {
NetworkIndexes::<T>::mutate(|ids| ids.retain(|id| id != &chain_id));
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
*maybe_network = None;
@ -723,16 +729,39 @@ impl<T: Config> NetworkDataBasicHandler for Pallet<T> {
}
impl<T: Config> NetworkDataInspectHandler<NetworkData> for Pallet<T> {
fn count() -> u32 {
NetworkIndexes::<T>::decode_len()
.map(|len| len as u32)
.unwrap_or_default()
}
fn contains_key(n: &Self::NetworkId) -> bool {
Networks::<T>::contains_key(n)
}
fn get(n: &Self::NetworkId) -> Option<NetworkData> {
Networks::<T>::get(n)
}
fn network_for_block(block_number: impl Into<usize>) -> Option<(Self::NetworkId, NetworkData)> {
let network_indexes = NetworkIndexes::<T>::get();
block_number
.into()
.checked_rem(network_indexes.len())
.map(|id| {
network_indexes.get(id).copied().and_then(|network_id| {
Self::get(&network_id).map(|network_data| (network_id, network_data))
})
})
.flatten()
}
fn iter() -> PrefixIterator<(Self::NetworkId, NetworkData)> {
Networks::<T>::iter()
}
fn is_nullification_period() -> bool {
NullifyNeeded::<T>::get()
fn iter_indexes() -> impl Iterator<Item = Self::NetworkId> {
NetworkIndexes::<T>::get().into_iter()
}
}
@ -820,18 +849,4 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
}
})
}
fn nullify_commission() {
AccumulatedCommission::<T>::set(Default::default());
BridgedImbalance::<T>::set(Default::default());
}
fn trigger_nullification() {
if NullifyNeeded::<T>::get() {
Self::nullify_commission();
NullifyNeeded::<T>::put(false);
} else {
NullifyNeeded::<T>::put(true);
}
}
}

View File

@ -1,134 +0,0 @@
use crate::AtLeast32BitUnsigned;
pub struct MulDiv<Balance>(core::marker::PhantomData<Balance>);
impl<Balance> MulDiv<Balance>
where
Balance: Copy
+ AtLeast32BitUnsigned
+ num_traits::ops::wrapping::WrappingAdd
+ num_traits::ops::overflowing::OverflowingAdd
+ sp_std::ops::AddAssign
+ sp_std::ops::Not<Output = Balance>
+ sp_std::ops::Shl<Output = Balance>
+ sp_std::ops::Shr<Output = Balance>
+ sp_std::ops::BitAnd<Balance, Output = Balance>,
{
fn zero(&self) -> Balance {
0u32.into()
}
fn one(&self) -> Balance {
1u32.into()
}
fn bit_shift(&self) -> Balance {
let u32_shift: u32 = core::mem::size_of::<Balance>()
.saturating_mul(4)
.try_into()
.unwrap_or_default();
u32_shift.into()
}
fn least_significant_bits(&self, a: Balance) -> Balance {
a & ((self.one() << self.bit_shift()) - self.one())
}
fn most_significant_bits(&self, a: Balance) -> Balance {
a >> self.bit_shift()
}
fn two_complement(&self, a: Balance) -> Balance {
(!a).wrapping_add(&self.one())
}
fn adjusted_ratio(&self, a: Balance) -> Balance {
(self.two_complement(a) / a).wrapping_add(&self.one())
}
fn modulo(&self, a: Balance) -> Balance {
self.two_complement(a) % a
}
fn overflow_resistant_addition(
&self,
a0: Balance,
a1: Balance,
b0: Balance,
b1: Balance,
) -> (Balance, Balance) {
let (r0, overflow) = a0.overflowing_add(&b0);
let overflow: Balance = overflow.then(|| 1u32).unwrap_or_default().into();
let r1 = a1.wrapping_add(&b1).wrapping_add(&overflow);
(r0, r1)
}
fn overflow_resistant_multiplication(&self, a: Balance, b: Balance) -> (Balance, Balance) {
let (a0, a1) = (
self.least_significant_bits(a),
self.most_significant_bits(a),
);
let (b0, b1) = (
self.least_significant_bits(b),
self.most_significant_bits(b),
);
let (x, y) = (a1 * b0, b1 * a0);
let (r0, r1) = (a0 * b0, a1 * b1);
let (r0, r1) = self.overflow_resistant_addition(
r0,
r1,
self.least_significant_bits(x) << self.bit_shift(),
self.most_significant_bits(x),
);
let (r0, r1) = self.overflow_resistant_addition(
r0,
r1,
self.least_significant_bits(y) << self.bit_shift(),
self.most_significant_bits(y),
);
(r0, r1)
}
fn overflow_resistant_division(
&self,
mut a0: Balance,
mut a1: Balance,
b: Balance,
) -> (Balance, Balance) {
if b == self.one() {
return (a0, a1);
}
let zero: Balance = 0u32.into();
let (q, r) = (self.adjusted_ratio(b), self.modulo(b));
let (mut x0, mut x1) = (zero, zero);
while a1 != zero {
let (t0, t1) = self.overflow_resistant_multiplication(a1, q);
let (new_x0, new_x1) = self.overflow_resistant_addition(x0, x1, t0, t1);
x0 = new_x0;
x1 = new_x1;
let (t0, t1) = self.overflow_resistant_multiplication(a1, r);
let (new_a0, new_a1) = self.overflow_resistant_addition(t0, t1, a0, zero);
a0 = new_a0;
a1 = new_a1;
}
self.overflow_resistant_addition(x0, x1, a0 / b, zero)
}
fn mul_div(&self, a: Balance, b: Balance, c: Balance) -> Balance {
let (t0, t1) = self.overflow_resistant_multiplication(a, b);
self.overflow_resistant_division(t0, t1, c).0
}
pub fn calculate(a: Balance, b: Balance, c: Balance) -> Balance {
let inner = MulDiv(core::marker::PhantomData);
if c == inner.zero() {
return c;
}
inner.mul_div(a, b, c)
}
}

View File

@ -0,0 +1,9 @@
pub mod v1;
pub type MigrateV0ToV1<T> = frame_support::migrations::VersionedMigration<
0,
1,
v1::StoreNetworkIdsIntoBoundedVec<T>,
crate::Pallet<T>,
<T as frame_system::Config>::DbWeight,
>;

View File

@ -0,0 +1,59 @@
use frame_support::{
migration::clear_storage_prefix,
traits::{Get, PalletInfoAccess, UncheckedOnRuntimeUpgrade},
weights::Weight,
};
use sp_std::marker::PhantomData;
use crate::{BoundedVec, Config, NetworkIndexes, Networks, Pallet, Vec, LOG_TARGET};
pub struct StoreNetworkIdsIntoBoundedVec<T>(PhantomData<T>);
impl<T: Config> UncheckedOnRuntimeUpgrade for StoreNetworkIdsIntoBoundedVec<T> {
fn on_runtime_upgrade() -> Weight {
let mut weight = T::DbWeight::get().reads(1);
let network_ids: Vec<T::NetworkId> = Networks::<T>::iter_keys().collect();
let networks_count = network_ids.len();
weight = weight.saturating_add(T::DbWeight::get().reads(networks_count as u64));
let clear_results = clear_storage_prefix(
Pallet::<T>::name().as_bytes(),
"NullifyNeeded".as_bytes(),
&[],
Some(1),
None,
);
log::info!(
target: LOG_TARGET,
"⛓️ NullifyNeeded storage succesfully removed: Loops (reads): {}, Unique removed (writes): {}",
clear_results.loops,
clear_results.unique,
);
weight = weight.saturating_add(T::DbWeight::get().reads(clear_results.loops as u64));
weight = weight.saturating_add(T::DbWeight::get().writes(clear_results.unique as u64));
let writes = BoundedVec::<T::NetworkId, T::MaxNetworks>::try_from(network_ids)
.inspect_err(|err| {
log::error!(
target: LOG_TARGET,
"⛓️ Network ids to bounded_vec migration failed: {:?}",
err,
)
})
.ok()
.map(|bounded_networks| {
NetworkIndexes::<T>::put(bounded_networks);
log::info!(
target: LOG_TARGET,
"⛓️ Network ids to bounded_vec migration success: {} networks moved",
networks_count,
);
1u64
})
.unwrap_or_default();
weight.saturating_add(T::DbWeight::get().writes(writes))
}
}

View File

@ -82,6 +82,7 @@ pallet_staking_reward_curve::build! {
parameter_types! {
pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
pub const MaxNetworks: u32 = 3;
}
ord_parameter_types! {
@ -98,6 +99,7 @@ impl ghost_networks::Config for Test {
type RegisterOrigin = EnsureSignedBy<RegistererAccount, AccountId>;
type UpdateOrigin = EnsureSignedBy<UpdaterAccount, AccountId>;
type RemoveOrigin = EnsureSignedBy<RemoverAccount, AccountId>;
type MaxNetworks = MaxNetworks;
type WeightInfo = ();
}

View File

@ -1,8 +1,8 @@
use super::*;
use frame_support::{assert_err, assert_ok};
use mock::{
ExtBuilder, GhostNetworks, RandomAccount, RegistererAccount, RemoverAccount, RewardCurve,
RuntimeEvent, RuntimeOrigin, System, Test, UpdaterAccount,
ExtBuilder, GhostNetworks, MaxNetworks, RandomAccount, RegistererAccount, RemoverAccount,
RewardCurve, RuntimeEvent, RuntimeOrigin, System, Test, UpdaterAccount,
};
use pallet_staking::EraPayout;
use sp_runtime::DispatchError;
@ -36,7 +36,8 @@ fn register_and_check_network(chain_id: u32, network: NetworkData) {
chain_id,
network.clone()
));
assert_eq!(Networks::<Test>::get(chain_id), Some(network.clone()));
assert_eq!(Networks::<Test>::get(chain_id), Some(network));
assert_eq!(NetworkIndexes::<Test>::get(), vec![chain_id]);
}
#[test]
@ -44,6 +45,7 @@ fn could_add_network_from_authority() {
ExtBuilder::build().execute_with(|| {
let (chain_id, network) = prepare_network_data();
assert_eq!(Networks::<Test>::get(chain_id), None);
assert_eq!(NetworkIndexes::<Test>::get(), vec![]);
assert_ok!(GhostNetworks::register_network(
RuntimeOrigin::signed(RegistererAccount::get()),
chain_id,
@ -56,6 +58,7 @@ fn could_add_network_from_authority() {
},
));
assert_eq!(Networks::<Test>::get(chain_id), Some(network));
assert_eq!(NetworkIndexes::<Test>::get(), vec![chain_id]);
});
}
@ -64,6 +67,7 @@ fn could_not_add_network_from_random_account() {
ExtBuilder::build().execute_with(|| {
let (chain_id, network) = prepare_network_data();
assert_eq!(Networks::<Test>::get(chain_id), None);
assert_eq!(NetworkIndexes::<Test>::get(), vec![]);
assert_err!(
GhostNetworks::register_network(
RuntimeOrigin::signed(RandomAccount::get()),
@ -89,6 +93,7 @@ fn could_not_add_network_from_random_account() {
DispatchError::BadOrigin
);
assert_eq!(Networks::<Test>::get(chain_id), None);
assert_eq!(NetworkIndexes::<Test>::get(), vec![]);
});
}
@ -1055,6 +1060,7 @@ fn could_remove_network_from_authority_account() {
chain_id,
));
assert_eq!(Networks::<Test>::get(chain_id), None);
assert_eq!(NetworkIndexes::<Test>::get(), vec![]);
});
}
@ -1079,6 +1085,7 @@ fn could_not_remove_network_from_random_account() {
DispatchError::BadOrigin
);
assert_eq!(Networks::<Test>::get(chain_id), Some(network));
assert_eq!(NetworkIndexes::<Test>::get(), vec![chain_id]);
});
}
@ -1092,6 +1099,7 @@ fn could_not_remove_non_existent_network() {
crate::Error::<Test>::NetworkDoesNotExist
);
assert_eq!(Networks::<Test>::get(chain_id), None);
assert_eq!(NetworkIndexes::<Test>::get(), vec![]);
});
}
@ -1270,7 +1278,7 @@ fn bridged_amount_overflow_and_underflow_emits_error() {
}
#[test]
fn accumulated_commission_could_be_nullified() {
fn accumulated_commission_nullified_after_era_payout() {
ExtBuilder::build().execute_with(|| {
let commission_first: u128 = 420;
let commission_second: u128 = 69;
@ -1284,12 +1292,20 @@ fn accumulated_commission_could_be_nullified() {
GhostNetworks::accumulate_commission(&commission_second,),
commission_first + commission_second
);
assert_eq!(
AccumulatedCommission::<Test>::get(),
commission_first + commission_second
);
GhostNetworks::nullify_commission();
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(1, 1, 1),
(0, commission_first + commission_second)
);
assert_eq!(AccumulatedCommission::<Test>::get(), 0);
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(1, 1, 1),
(0, 0)
);
});
}
@ -1377,7 +1393,6 @@ fn bridged_inlation_reward_works() {
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000,
@ -1386,6 +1401,9 @@ fn bridged_inlation_reward_works() {
),
(commission, 0)
);
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000_000_000_000,
@ -1394,6 +1412,9 @@ fn bridged_inlation_reward_works() {
),
(commission, 0)
);
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000_000_000_000_000_000_000_000,
@ -1403,6 +1424,8 @@ fn bridged_inlation_reward_works() {
(commission, 0)
);
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_not_ideal * 1_000,
@ -1411,6 +1434,9 @@ fn bridged_inlation_reward_works() {
),
(13177472000, 192528000)
);
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
assert_eq!(13177472000 + 192528000, commission);
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
@ -1420,6 +1446,9 @@ fn bridged_inlation_reward_works() {
),
(13177568884, 192431116)
);
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
assert_eq!(13177568884 + 192431116, commission);
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
@ -1429,8 +1458,10 @@ fn bridged_inlation_reward_works() {
),
(13177568884, 192431116)
);
assert_eq!(13177568884 + 192431116, commission);
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
assert_eq!(13177568884 + 192431116, commission);
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
1,
@ -1439,6 +1470,9 @@ fn bridged_inlation_reward_works() {
),
(92386700, 13277613300)
);
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
assert_eq!(92386700 + 13277613300, commission);
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
@ -1448,6 +1482,9 @@ fn bridged_inlation_reward_works() {
),
(92253000, 13277747000)
);
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
assert_eq!(92253000 + 13277747000, commission);
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
@ -1457,10 +1494,8 @@ fn bridged_inlation_reward_works() {
),
(92253000, 13277747000)
);
assert_eq!(92253000 + 13277747000, commission);
GhostNetworks::nullify_commission();
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000,
@ -1539,7 +1574,7 @@ fn bridged_inlation_reward_works() {
}
#[test]
fn bridged_inflation_era_payout_triggers_need_of_nullification() {
fn bridged_inflation_era_payout_clears_storage() {
ExtBuilder::build().execute_with(|| {
let amount_full: u128 = 1337 * 1_000_000_000;
let commission: u128 = amount_full / 100; // 1% commission
@ -1550,7 +1585,13 @@ fn bridged_inflation_era_payout_triggers_need_of_nullification() {
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
assert_eq!(NullifyNeeded::<Test>::get(), false);
let bridged_adjustment = BridgeAdjustment {
bridged_in: amount,
bridged_out: 0,
};
assert_eq!(BridgedImbalance::<Test>::get(), bridged_adjustment);
assert_eq!(AccumulatedCommission::<Test>::get(), commission);
assert_eq!(
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000,
@ -1559,37 +1600,8 @@ fn bridged_inflation_era_payout_triggers_need_of_nullification() {
),
(commission, 0)
);
assert_eq!(NullifyNeeded::<Test>::get(), true);
GhostNetworks::on_finalize(69);
assert_eq!(NullifyNeeded::<Test>::get(), false);
});
}
#[test]
fn trigger_nullification_works_as_expected() {
ExtBuilder::build().execute_with(|| {
let commission: u128 = 69;
let imbalance = BridgeAdjustment {
bridged_in: 1337u128,
bridged_out: 420u128,
};
assert_eq!(AccumulatedCommission::<Test>::get(), 0);
assert_eq!(BridgedImbalance::<Test>::get(), BridgeAdjustment::default());
AccumulatedCommission::<Test>::set(commission);
BridgedImbalance::<Test>::set(imbalance.clone());
assert_eq!(AccumulatedCommission::<Test>::get(), commission);
assert_eq!(BridgedImbalance::<Test>::get(), imbalance);
assert_eq!(NullifyNeeded::<Test>::get(), false);
GhostNetworks::trigger_nullification();
assert_eq!(NullifyNeeded::<Test>::get(), true);
GhostNetworks::trigger_nullification();
assert_eq!(NullifyNeeded::<Test>::get(), false);
assert_eq!(AccumulatedCommission::<Test>::get(), 0);
assert_eq!(BridgedImbalance::<Test>::get(), BridgeAdjustment::default());
assert_eq!(BridgedImbalance::<Test>::get(), Default::default());
assert_eq!(AccumulatedCommission::<Test>::get(), Default::default());
});
}
@ -1665,123 +1677,6 @@ fn check_substrate_guarantees_not_to_overflow_u32() {
});
}
#[test]
fn check_muldiv_guarantees_not_to_overflow_for_u128() {
ExtBuilder::build().execute_with(|| {
let mut a: u128 = 2;
let mut b: u128 = 3;
let mut c: u128 = 6;
let mut result: u128 = 1;
loop {
a = match a.checked_mul(1_000) {
Some(value) => value,
None => break,
};
b = match b.checked_mul(1_000) {
Some(value) => value,
None => break,
};
c = match c.checked_mul(1_000) {
Some(value) => value,
None => break,
};
result = match result.checked_mul(1_000) {
Some(value) => value,
None => break,
};
assert_eq!(MulDiv::<u128>::calculate(a, b, c), result);
}
assert_eq!(
MulDiv::<u128>::calculate(u128::MAX, u128::MAX, u128::MAX),
u128::MAX
);
assert_eq!(MulDiv::<u128>::calculate(u128::MAX, 0, 0), 0);
assert_eq!(MulDiv::<u128>::calculate(0, u128::MAX, 0), 0);
assert_eq!(MulDiv::<u128>::calculate(0, 0, u128::MAX), 0);
});
}
#[test]
fn check_muldiv_guarantees_not_to_overflow_for_u64() {
ExtBuilder::build().execute_with(|| {
let mut a: u64 = 2;
let mut b: u64 = 3;
let mut c: u64 = 6;
let mut result: u64 = 1;
loop {
a = match a.checked_mul(1_000) {
Some(value) => value,
None => break,
};
b = match b.checked_mul(1_000) {
Some(value) => value,
None => break,
};
c = match c.checked_mul(1_000) {
Some(value) => value,
None => break,
};
result = match result.checked_mul(1_000) {
Some(value) => value,
None => break,
};
assert_eq!(MulDiv::<u64>::calculate(a, b, c), result);
}
assert_eq!(
MulDiv::<u64>::calculate(u64::MAX, u64::MAX, u64::MAX),
u64::MAX
);
assert_eq!(MulDiv::<u64>::calculate(u64::MAX, 0, 0), 0);
assert_eq!(MulDiv::<u64>::calculate(0, u64::MAX, 0), 0);
assert_eq!(MulDiv::<u64>::calculate(0, 0, u64::MAX), 0);
});
}
#[test]
fn check_muldiv_guarantees_not_to_overflow_for_u32() {
ExtBuilder::build().execute_with(|| {
let mut a: u32 = 2;
let mut b: u32 = 3;
let mut c: u32 = 6;
let mut result: u32 = 1;
loop {
a = match a.checked_mul(1_000) {
Some(value) => value,
None => break,
};
b = match b.checked_mul(1_000) {
Some(value) => value,
None => break,
};
c = match c.checked_mul(1_000) {
Some(value) => value,
None => break,
};
result = match result.checked_mul(1_000) {
Some(value) => value,
None => break,
};
assert_eq!(MulDiv::<u32>::calculate(a, b, c), result);
}
assert_eq!(
MulDiv::<u32>::calculate(u32::MAX, u32::MAX, u32::MAX),
u32::MAX
);
assert_eq!(MulDiv::<u32>::calculate(u32::MAX, 0, 0), 0);
assert_eq!(MulDiv::<u32>::calculate(0, u32::MAX, 0), 0);
assert_eq!(MulDiv::<u32>::calculate(0, 0, u32::MAX), 0);
});
}
#[test]
fn check_bridged_inflation_curve_for_overflow() {
ExtBuilder::build().execute_with(|| {
@ -1789,7 +1684,6 @@ fn check_bridged_inflation_curve_for_overflow() {
let commission: u128 = amount_full / 100; // 1% commission
let amount: u128 = amount_full - commission;
let tollerance: u128 = commission / 100; // 1% tollerance
let precomputed_payout: u128 = 13177568884;
let precomputed_rest: u128 = 192431116;
assert_eq!(precomputed_payout + precomputed_rest, commission);
@ -1798,10 +1692,10 @@ fn check_bridged_inflation_curve_for_overflow() {
let mut total_staked_not_ideal: u128 = 68_000;
let mut total_issuance: u128 = 100_000;
loop {
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
loop {
total_staked_ideal = match total_staked_ideal.checked_mul(1_000) {
Some(value) => value,
None => break,
@ -1822,27 +1716,6 @@ fn check_bridged_inflation_curve_for_overflow() {
),
(commission, 0)
);
let (payout, rest) = BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_not_ideal,
total_issuance + amount,
0,
);
let payout_deviation = if precomputed_payout > payout {
precomputed_payout - payout
} else {
payout - precomputed_payout
};
let rest_deviation = if precomputed_rest > rest {
precomputed_rest - rest
} else {
rest - precomputed_rest
};
assert!(payout_deviation < tollerance);
assert!(rest_deviation < tollerance);
}
});
}
@ -1898,3 +1771,106 @@ fn check_bridged_inflation_curve_for_big_commissions() {
}
});
}
#[test]
fn migration_from_v0_to_v1_works() {
ExtBuilder::build().execute_with(|| {
let (chain_id, network) = prepare_network_data();
let other_chain_id = chain_id.saturating_add(1);
let removed_pallet_name = <Pallet<Test> as PalletInfoAccess>::name();
let removed_storage = "NullifyNeeded";
let key = [
sp_io::hashing::twox_128(removed_pallet_name.as_bytes()).to_vec(),
sp_io::hashing::twox_128(removed_storage.as_bytes()).to_vec(),
]
.concat();
frame_support::storage::unhashed::put_raw(&key, &true.encode());
assert_eq!(Networks::<Test>::get(chain_id), None);
assert_ok!(GhostNetworks::register_network(
RuntimeOrigin::signed(RegistererAccount::get()),
chain_id,
network.clone(),
));
assert_ok!(GhostNetworks::register_network(
RuntimeOrigin::signed(RegistererAccount::get()),
other_chain_id,
network.clone(),
));
NetworkIndexes::<Test>::kill();
assert!(frame_support::storage::unhashed::exists(&key));
assert_eq!(Networks::<Test>::get(chain_id), Some(network.clone()));
assert_eq!(Networks::<Test>::get(other_chain_id), Some(network));
assert_eq!(NetworkIndexes::<Test>::get(), vec![]);
type Migrate = crate::migrations::MigrateV0ToV1<Test>;
<Migrate as frame_support::traits::OnRuntimeUpgrade>::on_runtime_upgrade();
assert!(!frame_support::storage::unhashed::exists(&key));
assert_eq!(
NetworkIndexes::<Test>::get(),
vec![chain_id, other_chain_id]
);
});
}
#[test]
fn error_on_max_networks_overflow() {
ExtBuilder::build().execute_with(|| {
let (chain_id, network) = prepare_network_data();
let max_networks = MaxNetworks::get();
for index in 0..max_networks {
let other_chain_id = chain_id.saturating_add(index);
assert_ok!(GhostNetworks::register_network(
RuntimeOrigin::signed(RegistererAccount::get()),
other_chain_id,
network.clone(),
));
}
assert_err!(
GhostNetworks::register_network(
RuntimeOrigin::signed(RegistererAccount::get()),
chain_id.saturating_add(max_networks),
network.clone(),
),
crate::Error::<Test>::TooManyNetworks,
);
});
}
#[test]
fn migration_from_v0_to_v1_does_not_run_twice() {
ExtBuilder::build().execute_with(|| {
StorageVersion::new(1).put::<GhostNetworks>();
let (chain_id, network) = prepare_network_data();
let other_chain_id = chain_id.saturating_add(1);
assert_eq!(Networks::<Test>::get(chain_id), None);
assert_ok!(GhostNetworks::register_network(
RuntimeOrigin::signed(RegistererAccount::get()),
chain_id,
network.clone(),
));
assert_ok!(GhostNetworks::register_network(
RuntimeOrigin::signed(RegistererAccount::get()),
other_chain_id,
network.clone(),
));
NetworkIndexes::<Test>::kill();
assert_eq!(Networks::<Test>::get(chain_id), Some(network.clone()));
assert_eq!(Networks::<Test>::get(other_chain_id), Some(network));
assert_eq!(NetworkIndexes::<Test>::get(), vec![]);
type Migrate = crate::migrations::MigrateV0ToV1<Test>;
<Migrate as frame_support::traits::OnRuntimeUpgrade>::on_runtime_upgrade();
assert_eq!(NetworkIndexes::<Test>::get(), vec![]);
});
}

View File

@ -16,7 +16,7 @@
//! Autogenerated weights for `ghost_networks`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2026-02-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
@ -30,7 +30,6 @@
// --repeat=20
// --pallet=ghost_networks
// --extrinsic=*
// --wasm-execution=compiled
// --heap-pages=4096
// --header=./file_header.txt
// --output=./runtime/casper/src/weights/ghost_networks.rs
@ -67,33 +66,35 @@ pub trait WeightInfo {
impl WeightInfo for () {
/// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::NetworkIndexes` (r:1 w:1)
/// Proof: `GhostNetworks::NetworkIndexes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// The range of component `i` is `[1, 20]`.
/// The range of component `j` is `[1, 150]`.
/// The range of component `k` is `[1, 20]`.
fn register_network(_i: u32, _j: u32, k: u32, ) -> Weight {
fn register_network(_i: u32, j: u32, k: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `109`
// Estimated: `3574`
// Minimum execution time: 46_023_000 picoseconds.
Weight::from_parts(97_871_287, 0)
// Minimum execution time: 48_419_000 picoseconds.
Weight::from_parts(35_655_823, 0)
.saturating_add(Weight::from_parts(0, 3574))
// Standard Error: 94_524
.saturating_add(Weight::from_parts(940_486, 0).saturating_mul(k.into()))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
// Standard Error: 1_212
.saturating_add(Weight::from_parts(96_762, 0).saturating_mul(j.into()))
// Standard Error: 9_235
.saturating_add(Weight::from_parts(1_460_410, 0).saturating_mul(k.into()))
.saturating_add(RocksDbWeight::get().reads(2))
.saturating_add(RocksDbWeight::get().writes(2))
}
/// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// The range of component `n` is `[1, 20]`.
fn update_network_name(n: u32, ) -> Weight {
fn update_network_name(_n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 49_906_000 picoseconds.
Weight::from_parts(55_537_587, 0)
.saturating_add(Weight::from_parts(0, 3767))
// Standard Error: 87_704
.saturating_add(Weight::from_parts(92_366, 0).saturating_mul(n.into()))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_422_000 picoseconds.
Weight::from_parts(49_987_541, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
@ -102,13 +103,13 @@ impl WeightInfo for () {
/// The range of component `n` is `[1, 150]`.
fn update_network_endpoint(n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 50_556_000 picoseconds.
Weight::from_parts(57_726_674, 0)
.saturating_add(Weight::from_parts(0, 3767))
// Standard Error: 12_261
.saturating_add(Weight::from_parts(274, 0).saturating_mul(n.into()))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_651_000 picoseconds.
Weight::from_parts(50_776_912, 0)
.saturating_add(Weight::from_parts(0, 3804))
// Standard Error: 1_062
.saturating_add(Weight::from_parts(838, 0).saturating_mul(n.into()))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
@ -116,11 +117,11 @@ impl WeightInfo for () {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_finality_delay() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 49_406_000 picoseconds.
Weight::from_parts(51_256_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_080_000 picoseconds.
Weight::from_parts(51_781_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
@ -128,11 +129,11 @@ impl WeightInfo for () {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_rate_limit_delay() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 49_572_000 picoseconds.
Weight::from_parts(52_584_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 47_950_000 picoseconds.
Weight::from_parts(48_925_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
@ -140,11 +141,11 @@ impl WeightInfo for () {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_block_distance() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 48_880_000 picoseconds.
Weight::from_parts(50_596_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_324_000 picoseconds.
Weight::from_parts(50_801_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
@ -152,11 +153,11 @@ impl WeightInfo for () {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_type() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 48_282_000 picoseconds.
Weight::from_parts(49_137_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 46_962_000 picoseconds.
Weight::from_parts(47_729_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
@ -164,11 +165,11 @@ impl WeightInfo for () {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_gatekeeper() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 50_853_000 picoseconds.
Weight::from_parts(51_982_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_728_000 picoseconds.
Weight::from_parts(53_054_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
@ -176,11 +177,11 @@ impl WeightInfo for () {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_topic_name() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 50_343_000 picoseconds.
Weight::from_parts(52_380_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_632_000 picoseconds.
Weight::from_parts(49_954_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
@ -188,11 +189,11 @@ impl WeightInfo for () {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_incoming_network_fee() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 49_393_000 picoseconds.
Weight::from_parts(80_966_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 47_660_000 picoseconds.
Weight::from_parts(53_763_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
@ -200,11 +201,11 @@ impl WeightInfo for () {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_outgoing_network_fee() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 49_579_000 picoseconds.
Weight::from_parts(51_126_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_164_000 picoseconds.
Weight::from_parts(48_953_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
@ -212,24 +213,26 @@ impl WeightInfo for () {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_avg_block_speed() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 49_579_000 picoseconds.
Weight::from_parts(51_126_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 47_789_000 picoseconds.
Weight::from_parts(52_131_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
/// Storage: `GhostNetworks::NetworkIndexes` (r:1 w:1)
/// Proof: `GhostNetworks::NetworkIndexes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn remove_network() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 44_634_000 picoseconds.
Weight::from_parts(45_815_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 49_720_000 picoseconds.
Weight::from_parts(50_526_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(RocksDbWeight::get().reads(2))
.saturating_add(RocksDbWeight::get().writes(2))
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "ghost-slow-clap"
version = "0.4.14"
version = "0.4.28"
description = "Applause protocol for the EVM bridge"
license.workspace = true
authors.workspace = true

View File

@ -90,11 +90,7 @@ benchmarks! {
session_index,
authority_index,
network_id,
commitment: CommitmentDetails {
last_stored_block: 69,
commits: 420,
last_updated: 1337,
}
};
let authority_id = authorities
@ -102,16 +98,47 @@ benchmarks! {
.expect("first authority should exist");
let signature = authority_id.sign(&block_commitment.encode())
.ok_or("couldn't make signature")?;
}: _(RawOrigin::None, block_commitment, signature)
verify {
let current_block_number = <Pallet<T> as BlockNumberProvider>::current_block_number();
let stored_commitment = BlockCommitments::<T>::get(&network_id)
.get(&authority_index)
.cloned()
.unwrap_or_default();
assert_eq!(stored_commitment.last_stored_block, 69);
assert_eq!(stored_commitment.commits, 1);
assert_eq!(stored_commitment.last_updated, 1337);
assert_eq!(stored_commitment.last_updated, current_block_number);
}
try_offend_validators {
let n in 1 .. T::MaxAuthorities::get();
let d in 0 .. T::MaxAuthorities::get();
let session_index = T::ValidatorSet::session_index();
let mut validators_vec = Vec::new();
for i in 0..T::MaxAuthorities::get() {
let v = account("validator", i, 0);
validators_vec.push(v);
}
let validators = WeakBoundedVec::<ValidatorId<T>, T::MaxAuthorities>::try_from(validators_vec)
.expect("weak bounded vec should be constructed; qed");
let offence_type = OffenceType::CommitmentOffence;
let disabled_bitmap = BitMap::new(T::MaxAuthorities::get());
let mut offence_bitmap = BitMap::new(T::MaxAuthorities::get());
for i in 0..d {
offence_bitmap.set(i);
}
}: {
let _ = Pallet::<T>::try_offend_validators(
&session_index,
&validators,
offence_bitmap,
disabled_bitmap,
offence_type
);
}
impl_benchmark_test_suite!(

View File

@ -8,7 +8,7 @@ where
Ok(Some(s.as_bytes().to_vec()))
}
pub fn de_string_to_u64<'de, D>(de: D) -> Result<Option<u64>, D::Error>
pub fn de_string_to_block_number<'de, D>(de: D) -> Result<Option<u64>, D::Error>
where
D: Deserializer<'de>,
{
@ -17,7 +17,7 @@ where
Ok(u64::from_str_radix(s, 16).ok())
}
pub fn de_string_to_u64_pure<'de, D>(de: D) -> Result<u64, D::Error>
pub fn de_string_to_block_number_pure<'de, D>(de: D) -> Result<u64, D::Error>
where
D: Deserializer<'de>,
{

View File

@ -1,14 +1,14 @@
use sp_runtime::SaturatedConversion;
use sp_runtime::{traits::UniqueSaturatedInto, SaturatedConversion, Saturating};
use sp_staking::SessionIndex;
use crate::{
deserialisations::{
de_string_to_bytes, de_string_to_h256, de_string_to_u64, de_string_to_u64_pure,
de_string_to_vec_of_bytes,
de_string_to_block_number, de_string_to_block_number_pure, de_string_to_bytes,
de_string_to_h256, de_string_to_vec_of_bytes,
},
AuthIndex, BalanceOf, BlockCommitment, BlockCommitments, Call, Clap, CommitmentDetails, Config,
Decode, Deserialize, Encode, NetworkIdOf, RuntimeAppPublic, RuntimeDebug, SubmitTransaction,
Vec, COMMITMENT_DELAY_MILLIS, H256, LOG_TARGET,
AuthIndex, BalanceOf, BlockCommitment, BlockCommitments, BlockNumberFor, Call, Clap, Config,
Decode, Deserialize, Encode, ExternalBlockNumber, NetworkIdOf, RuntimeAppPublic, RuntimeDebug,
SubmitTransaction, Vec, BLOCK_COMMITMENT_DELAY, H256, LOG_TARGET,
};
const NUMBER_OF_TOPICS: usize = 3;
@ -28,8 +28,8 @@ pub struct EvmResponse {
#[derive(RuntimeDebug, Clone, PartialEq, Deserialize, Encode, Decode)]
#[serde(untagged)]
pub enum EvmResponseType {
#[serde(deserialize_with = "de_string_to_u64_pure")]
BlockNumber(u64),
#[serde(deserialize_with = "de_string_to_block_number_pure")]
BlockNumber(ExternalBlockNumber),
TransactionLogs(Vec<Log>),
}
@ -38,34 +38,14 @@ pub enum EvmResponseType {
pub struct Log {
#[serde(default, deserialize_with = "de_string_to_h256")]
pub transaction_hash: Option<H256>,
#[serde(default, deserialize_with = "de_string_to_u64")]
pub block_number: Option<u64>,
#[serde(default, deserialize_with = "de_string_to_block_number")]
pub block_number: Option<ExternalBlockNumber>,
#[serde(default, deserialize_with = "de_string_to_vec_of_bytes")]
pub topics: Vec<Vec<u8>>,
pub removed: bool,
}
impl EvmResponseType {
fn prepare_block_commitment<T: Config>(
&self,
from_block: u64,
authority_index: AuthIndex,
session_index: SessionIndex,
network_id: NetworkIdOf<T>,
) -> BlockCommitment<NetworkIdOf<T>> {
let last_updated = sp_io::offchain::timestamp().unix_millis();
BlockCommitment {
session_index,
authority_index,
network_id,
commitment: CommitmentDetails {
last_stored_block: from_block,
last_updated,
commits: 420,
},
}
}
fn prepare_clap<T: Config>(
&self,
authority_index: AuthIndex,
@ -164,30 +144,30 @@ impl EvmResponseType {
fn sign_and_submit_block_commitment<T: Config>(
&self,
from_block: u64,
block_now: BlockNumberFor<T>,
from_block: ExternalBlockNumber,
authority_index: AuthIndex,
authority_key: T::AuthorityId,
session_index: SessionIndex,
network_id: NetworkIdOf<T>,
) {
let block_commitment = self.prepare_block_commitment::<T>(
from_block,
authority_index,
let block_commitment = BlockCommitment {
session_index,
authority_index,
network_id,
);
last_stored_block: from_block,
};
let stored_last_updated = BlockCommitments::<T>::get(&network_id)
.get(&authority_index)
.map(|details| details.last_updated)
.map(|details| {
details
.last_updated
.saturating_add(BLOCK_COMMITMENT_DELAY.unique_saturated_into())
})
.unwrap_or_default();
let current_last_updated = block_commitment
.commitment
.last_updated
.saturating_sub(COMMITMENT_DELAY_MILLIS);
if current_last_updated < stored_last_updated {
if block_now < stored_last_updated {
return;
}
@ -229,7 +209,8 @@ impl EvmResponseType {
pub fn sign_and_submit<T: Config>(
&self,
from_block: u64,
block_now: BlockNumberFor<T>,
from_block: ExternalBlockNumber,
authority_index: AuthIndex,
authority_key: T::AuthorityId,
session_index: SessionIndex,
@ -243,6 +224,7 @@ impl EvmResponseType {
network_id,
),
EvmResponseType::BlockNumber(_) => self.sign_and_submit_block_commitment::<T>(
block_now,
from_block,
authority_index,
authority_key,

View File

@ -28,7 +28,7 @@ use sp_runtime::{
storage::StorageValueRef,
storage_lock::{StorageLock, Time},
},
traits::{BlockNumberProvider, Convert, Saturating},
traits::{AtLeast32BitUnsigned, BlockNumberProvider, Convert, Saturating, UniqueSaturatedInto},
Perbill, RuntimeAppPublic, RuntimeDebug,
};
use sp_staking::{
@ -43,6 +43,7 @@ use ghost_networks::{
};
use ghost_traits::exposure::ExposureListener;
pub mod migrations;
pub mod weights;
pub use crate::weights::WeightInfo;
mod benchmarking;
@ -78,10 +79,12 @@ const MIN_LOCK_GUARD_PERIOD: u64 = 15_000;
const FETCH_TIMEOUT_PERIOD: u64 = 3_000;
const LOCK_BLOCK_EXPIRATION: u64 = 20;
const COMMITMENT_DELAY_MILLIS: u64 = 600_000;
const ONE_HOUR_MILLIS: u64 = 3_600_000;
const BLOCK_CHECK_CYCLES: u64 = 8;
const BLOCK_COMMITMENT_DELAY: u64 = 100;
pub type AuthIndex = u32;
pub type ExternalBlockNumber = u64;
#[derive(
RuntimeDebug,
@ -97,10 +100,10 @@ pub type AuthIndex = u32;
TypeInfo,
MaxEncodedLen,
)]
pub struct CommitmentDetails {
pub last_stored_block: u64,
pub last_updated: u64,
pub commits: u64,
pub struct CommitmentDetails<BlockNumberFor> {
pub last_stored_block: ExternalBlockNumber,
pub last_updated: BlockNumberFor,
pub commits: u8,
}
#[derive(
@ -110,7 +113,7 @@ pub struct BlockCommitment<NetworkId> {
pub session_index: SessionIndex,
pub authority_index: AuthIndex,
pub network_id: NetworkId,
pub commitment: CommitmentDetails,
pub last_stored_block: ExternalBlockNumber,
}
#[derive(
@ -120,7 +123,7 @@ pub struct Clap<AccountId, NetworkId, Balance> {
pub session_index: SessionIndex,
pub authority_index: AuthIndex,
pub transaction_hash: H256,
pub block_number: u64,
pub block_number: ExternalBlockNumber,
pub removed: bool,
pub network_id: NetworkId,
pub receiver: AccountId,
@ -132,12 +135,16 @@ pub struct ApplauseDetail<NetworkId, Balance> {
pub network_id: NetworkId,
pub authorities: BitMap,
pub clapped_amount: Balance,
pub block_number: u64,
pub block_number: ExternalBlockNumber,
pub finalized: bool,
}
impl<NetworkId, Balance: Default> ApplauseDetail<NetworkId, Balance> {
pub fn new(network_id: NetworkId, block_number: u64, max_authorities: usize) -> Self {
pub fn new(
network_id: NetworkId,
block_number: ExternalBlockNumber,
max_authorities: usize,
) -> Self {
ApplauseDetail {
network_id,
block_number,
@ -153,7 +160,7 @@ pub struct PreparedApplause<AccountId, NetworkId, Balance> {
pub network_id: NetworkId,
pub receiver: AccountId,
pub amount: Balance,
pub block_number: u64,
pub block_number: ExternalBlockNumber,
}
#[cfg_attr(test, derive(PartialEq))]
@ -168,7 +175,11 @@ enum OffchainErr<NetworkId> {
DifferentEvmResponseTypes,
MissingBlockNumber(u32, u32),
ContradictoryTransactionLogs(u32, u32),
ContradictoryBlockMedian(u64, u64, u64),
ContradictoryBlockMedian(
ExternalBlockNumber,
ExternalBlockNumber,
ExternalBlockNumber,
),
UnparsableRequestBody(Vec<u8>),
NoEndpointAvailable(NetworkId),
StorageRetrievalError(NetworkId),
@ -268,7 +279,7 @@ type OffchainResult<T, A> = Result<A, OffchainErr<NetworkIdOf<T>>>;
pub mod pallet {
use super::*;
const STORAGE_VERSION: StorageVersion = StorageVersion::new(2);
const STORAGE_VERSION: StorageVersion = StorageVersion::new(3);
#[pallet::pallet]
#[pallet::storage_version(STORAGE_VERSION)]
@ -314,6 +325,9 @@ pub mod pallet {
#[pallet::constant]
type MinAuthoritiesNumber: Get<u32>;
#[pallet::constant]
type EpochDuration: Get<u64>;
type WeightInfo: WeightInfo;
}
@ -341,12 +355,16 @@ pub mod pallet {
network_id: NetworkIdOf<T>,
receiver: T::AccountId,
received_amount: BalanceOf<T>,
block_number: u64,
block_number: ExternalBlockNumber,
},
BlockCommited {
authority_id: AuthIndex,
network_id: NetworkIdOf<T>,
},
BlockCommitmentsCheck {
network_id: NetworkIdOf<T>,
block_number: BlockNumberFor<T>,
},
}
#[pallet::error]
@ -361,6 +379,7 @@ pub mod pallet {
CouldNotIncreaseGatekeeperAmount,
NonExistentAuthorityIndex,
TimeWentBackwards,
InnerTimeWentBackwards,
DisabledAuthority,
ExecutedBlockIsHigher,
CommitInWrongSession,
@ -373,7 +392,7 @@ pub mod pallet {
#[pallet::storage]
#[pallet::getter(fn latest_executed_block)]
pub(super) type LatestExecutedBlock<T: Config> =
StorageMap<_, Twox64Concat, NetworkIdOf<T>, u64, ValueQuery>;
StorageMap<_, Twox64Concat, NetworkIdOf<T>, ExternalBlockNumber, ValueQuery>;
#[pallet::storage]
#[pallet::getter(fn block_commitments)]
@ -381,7 +400,7 @@ pub mod pallet {
_,
Twox64Concat,
NetworkIdOf<T>,
BTreeMap<AuthIndex, CommitmentDetails>,
BTreeMap<AuthIndex, CommitmentDetails<BlockNumberFor<T>>>,
ValueQuery,
>;
@ -470,6 +489,98 @@ pub mod pallet {
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(current_block: BlockNumberFor<T>) -> Weight {
let mut weight = T::DbWeight::get().reads(1);
let networks_count = T::NetworkDataHandler::count();
let current_block_number: ExternalBlockNumber = current_block.unique_saturated_into();
let check_block_interval = T::EpochDuration::get().saturating_div(BLOCK_CHECK_CYCLES);
if check_block_interval == 0 {
return weight;
}
let cycle_offset = current_block_number % check_block_interval;
let block_in_epoch = current_block_number % T::EpochDuration::get();
if cycle_offset >= networks_count.into() || block_in_epoch < check_block_interval {
return weight;
}
let converted_block: usize = current_block_number.unique_saturated_into();
if let Some((network_id, network_data)) =
T::NetworkDataHandler::network_for_block(converted_block)
{
weight.saturating_accrue(T::DbWeight::get().reads_writes(3, 1));
let session_index = T::ValidatorSet::session_index();
let block_commitments = BlockCommitments::<T>::get(&network_id);
let validators = Validators::<T>::get(&session_index);
let validators_len = validators.len() as u32;
if validators_len == 0 {
return weight;
}
let disabled_bitmap = DisabledAuthorityIndexes::<T>::get(&session_index)
.unwrap_or(BitMap::new(validators.len() as u32));
let max_external_block_deviation = ONE_HOUR_MILLIS
.saturating_mul(6)
.saturating_div(network_data.avg_block_speed);
let max_internal_block_deviation = check_block_interval.unique_saturated_into();
let mut stored_blocks: Vec<(AuthIndex, ExternalBlockNumber)> = Vec::new();
let mut block_updates: Vec<(AuthIndex, BlockNumberFor<T>)> = Vec::new();
for authority_index in 0..validators_len {
let data = block_commitments
.get(&authority_index)
.copied()
.unwrap_or_default();
stored_blocks.push((authority_index, data.last_stored_block));
block_updates.push((authority_index, data.last_updated));
}
let stored_blocks_offence_bitmap = Self::capture_deviation_in_commitments(
&disabled_bitmap,
&mut stored_blocks,
validators_len,
max_external_block_deviation,
);
let block_updates_offence_bitmap = Self::capture_deviation_in_commitments(
&disabled_bitmap,
&mut block_updates,
validators_len,
max_internal_block_deviation,
);
let offence_bitmap =
stored_blocks_offence_bitmap.bitor(block_updates_offence_bitmap);
let offence_type = OffenceType::CommitmentOffence;
let extra_weight = Self::try_offend_validators(
&session_index,
&validators,
offence_bitmap,
disabled_bitmap,
offence_type,
);
Self::deposit_event(Event::<T>::BlockCommitmentsCheck {
block_number: current_block,
network_id,
});
weight.saturating_accrue(extra_weight);
}
weight
}
fn offchain_worker(now: BlockNumberFor<T>) {
match Self::start_slow_clapping(now) {
Ok(_) => {
@ -505,7 +616,7 @@ pub mod pallet {
ValidTransaction::with_tag_prefix("SlowClap")
.priority(T::UnsignedPriority::get())
.and_provides(block_commitment.commitment.encode())
.and_provides(block_commitment.encode())
.longevity(LOCK_BLOCK_EXPIRATION)
.propagate(true)
.build()
@ -559,12 +670,13 @@ impl<T: Config> Pallet<T> {
let mut clap_args_str = clap.receiver.encode();
clap_args_str.extend(&clap.amount.encode());
clap_args_str.extend(&clap.block_number.encode());
clap_args_str.extend(&clap.transaction_hash.encode());
clap_args_str.extend(&clap.network_id.encode());
H256::from_slice(&sp_io::hashing::keccak_256(&clap_args_str)[..])
}
fn u64_to_hexadecimal_bytes(value: u64) -> Vec<u8> {
fn block_number_to_hexadecimal_bytes(value: ExternalBlockNumber) -> Vec<u8> {
let mut hex_str = Vec::new();
hex_str.push(b'0');
hex_str.push(b'x');
@ -595,7 +707,7 @@ impl<T: Config> Pallet<T> {
let clap_unique_hash = Self::generate_unique_hash(&clap);
let session_index =
if ApplauseDetails::<T>::get(&prev_session_index, &clap_unique_hash).is_some() {
if ApplauseDetails::<T>::contains_key(&prev_session_index, &clap_unique_hash) {
prev_session_index
} else {
clap.session_index
@ -607,44 +719,35 @@ impl<T: Config> Pallet<T> {
fn try_slow_clap(clap: &Clap<T::AccountId, NetworkIdOf<T>, BalanceOf<T>>) -> DispatchResult {
let network_id = clap.network_id;
ensure!(
T::NetworkDataHandler::get(&network_id).is_some(),
T::NetworkDataHandler::contains_key(&network_id),
Error::<T>::UnregistedNetwork
);
ensure!(
LatestExecutedBlock::<T>::get(&network_id) <= clap.block_number,
Error::<T>::ExecutedBlockIsHigher,
);
let (session_index, clap_unique_hash) = Self::mended_session_index(&clap);
let authorities = Authorities::<T>::get(&session_index);
let authorities_length = authorities.len();
let is_disabled = DisabledAuthorityIndexes::<T>::get(&session_index)
.map(|bitmap| bitmap.exists(&clap.authority_index))
.unwrap_or(true);
let not_disabled = DisabledAuthorityIndexes::<T>::get(&session_index)
.map(|bitmap| !bitmap.exists(&clap.authority_index))
.unwrap_or_default();
ensure!(!is_disabled, Error::<T>::DisabledAuthority);
ensure!(not_disabled, Error::<T>::DisabledAuthority);
let applause_threshold = Perbill::from_parts(T::ApplauseThreshold::get());
let threshold_amount = applause_threshold.mul_floor(TotalExposure::<T>::get());
let maybe_account_id =
T::ExposureListener::get_account_by_index(clap.authority_index as usize);
ensure!(
maybe_account_id.is_some(),
Error::<T>::NonExistentAuthorityIndex
);
let account_id = maybe_account_id.unwrap();
let account_id = T::ExposureListener::get_account_by_index(clap.authority_index as usize)
.ok_or(Error::<T>::NonExistentAuthorityIndex)?;
let new_clapped_amount = T::ExposureListener::get_validator_exposure(&account_id);
let mut applause_details =
match ApplauseDetails::<T>::take(&session_index, &clap_unique_hash) {
Some(applause_details) => applause_details,
None => {
ensure!(
LatestExecutedBlock::<T>::get(&network_id) <= clap.block_number,
Error::<T>::ExecutedBlockIsHigher,
ApplauseDetails::<T>::try_get(&session_index, &clap_unique_hash).unwrap_or(
ApplauseDetail::new(network_id, clap.block_number, authorities_length),
);
ApplauseDetail::new(network_id, clap.block_number, authorities_length)
}
};
let total_clapped = if clap.removed {
ensure!(
@ -683,9 +786,9 @@ impl<T: Config> Pallet<T> {
.gt(&(authorities_length as u32 / 2));
if total_clapped > threshold_amount && is_enough && !applause_details.finalized {
applause_details.finalized = true;
if let Err(e) = Self::try_applause(&clap) {
sp_runtime::print(e);
match Self::try_applause(&clap) {
Ok(_) => applause_details.finalized = true,
Err(e) => sp_runtime::print(e),
}
}
@ -695,10 +798,6 @@ impl<T: Config> Pallet<T> {
}
fn try_applause(clap: &Clap<T::AccountId, NetworkIdOf<T>, BalanceOf<T>>) -> DispatchResult {
if T::NetworkDataHandler::is_nullification_period() {
return Ok(());
}
let commission = T::NetworkDataHandler::get(&clap.network_id)
.map(|network_data| Perbill::from_parts(network_data.incoming_fee))
.unwrap_or_default()
@ -728,10 +827,12 @@ impl<T: Config> Pallet<T> {
fn try_commit_block(new_commitment: &BlockCommitment<NetworkIdOf<T>>) -> DispatchResult {
let authority_index = new_commitment.authority_index;
let network_id = new_commitment.network_id;
let session_index = T::ValidatorSet::session_index();
let latest_executed_block = LatestExecutedBlock::<T>::get(&network_id);
ensure!(
T::NetworkDataHandler::get(&network_id).is_some(),
T::NetworkDataHandler::contains_key(&network_id),
Error::<T>::UnregistedNetwork
);
@ -740,88 +841,54 @@ impl<T: Config> Pallet<T> {
Error::<T>::CommitInWrongSession,
);
let block_commitments = BlockCommitments::<T>::try_mutate(
&network_id,
|current_commitments| -> Result<BTreeMap<AuthIndex, CommitmentDetails>, DispatchError> {
let mut new_commitment_details = new_commitment.commitment;
BlockCommitments::<T>::try_mutate(&network_id, |current_commitments| -> DispatchResult {
let current_block_number = Self::current_block_number();
let (current_commits, current_last_updated) = current_commitments
.get(&authority_index)
.map(|details| {
(
details.commits.saturating_add(1),
details.last_updated.saturating_add(COMMITMENT_DELAY_MILLIS),
details
.last_updated
.saturating_add(BLOCK_COMMITMENT_DELAY.unique_saturated_into()),
)
})
.unwrap_or((1, 0));
.unwrap_or((1, Default::default()));
ensure!(
new_commitment_details.last_updated > current_last_updated,
Error::<T>::TimeWentBackwards
current_block_number >= current_last_updated,
Error::<T>::TimeWentBackwards,
);
new_commitment_details.commits = current_commits;
ensure!(
new_commitment.last_stored_block > latest_executed_block,
Error::<T>::InnerTimeWentBackwards,
);
let new_commitment_details = CommitmentDetails {
last_stored_block: new_commitment.last_stored_block,
last_updated: Self::current_block_number(),
commits: current_commits,
};
current_commitments.insert(authority_index, new_commitment_details);
Ok(current_commitments.clone())
},
)?;
let current_commits = block_commitments
.get(&authority_index)
.map(|details| details.commits)
.unwrap_or(1);
Ok(())
})?;
Self::deposit_event(Event::<T>::BlockCommited {
network_id,
authority_id: authority_index,
});
let validators = Validators::<T>::get(&session_index);
let disabled_bitmap = DisabledAuthorityIndexes::<T>::get(&session_index)
.unwrap_or(BitMap::new(validators.len() as u32));
let max_block_deviation = T::NetworkDataHandler::get(&network_id)
.map(|network| {
ONE_HOUR_MILLIS
.saturating_mul(6)
.saturating_div(network.avg_block_speed)
})
.unwrap_or_default();
if current_commits % 3 == 0 && validators.len() > 0 {
let offence_bitmap = Self::capture_deviation_in_commitments_and_remove(
&disabled_bitmap,
&block_commitments,
&validators,
max_block_deviation,
);
let offence_type = OffenceType::CommitmentOffence;
Self::try_offend_validators(
&session_index,
&validators,
offence_bitmap,
disabled_bitmap,
offence_type,
);
}
Ok(())
}
fn start_slow_clapping(block_number: BlockNumberFor<T>) -> OffchainResult<T, ()> {
let converted_block: usize = block_number.unique_saturated_into();
let session_index = T::ValidatorSet::session_index();
let networks = T::NetworkDataHandler::iter().collect::<Vec<_>>();
let network_index = block_number
.into()
.as_usize()
.checked_rem(networks.len())
.unwrap_or_default();
let network_in_use = networks
.iter()
.nth(network_index)
let network_in_use = T::NetworkDataHandler::network_for_block(converted_block)
.ok_or(OffchainErr::NoStoredNetworks)?;
log::info!(
@ -879,7 +946,8 @@ impl<T: Config> Pallet<T> {
return Err(OffchainErr::NoEndpointAvailable(network_id));
}
let (from_block, to_block): (u64, u64) = StorageValueRef::persistent(&block_number_key)
let (from_block, to_block): (ExternalBlockNumber, ExternalBlockNumber) =
StorageValueRef::persistent(&block_number_key)
.get()
.map_err(|_| OffchainErr::StorageRetrievalError(network_id))?
.unwrap_or_default();
@ -943,6 +1011,7 @@ impl<T: Config> Pallet<T> {
for (authority_index, authority_key) in Self::local_authorities(&session_index) {
parsed_evm_response.sign_and_submit::<T>(
block_number,
new_block_range.0,
authority_index,
authority_key,
@ -960,7 +1029,7 @@ impl<T: Config> Pallet<T> {
fn local_authorities(
session_index: &SessionIndex,
) -> impl Iterator<Item = (u32, T::AuthorityId)> {
) -> impl Iterator<Item = (AuthIndex, T::AuthorityId)> {
let authorities = Authorities::<T>::get(session_index);
let mut local_authorities = T::AuthorityId::all();
local_authorities.sort();
@ -1003,6 +1072,7 @@ impl<T: Config> Pallet<T> {
match rt_offchain::http::Request::post(&rpc_endpoint_str, vec![request_body_str])
.add_header("Accept", "application/json")
.add_header("Content-Type", "application/json")
.add_header("User-Agent", "curl/8.9.0") // mimic the curl
.deadline(deadline)
.send()
{
@ -1033,7 +1103,7 @@ impl<T: Config> Pallet<T> {
fn get_balanced_evm_response(
parsed_evm_responses: &Vec<EvmResponseType>,
max_block_distance: u64,
max_block_distance: ExternalBlockNumber,
) -> OffchainResult<T, EvmResponseType> {
let first_evm_response = parsed_evm_responses
.first()
@ -1195,8 +1265,8 @@ impl<T: Config> Pallet<T> {
}
fn prepare_evm_request_body_for_latest_transfers(
from_block: u64,
to_block: u64,
from_block: ExternalBlockNumber,
to_block: ExternalBlockNumber,
network_data: &NetworkData,
) -> Vec<u8> {
match network_data.network_type {
@ -1205,9 +1275,9 @@ impl<T: Config> Pallet<T> {
b"{\"id\":0,\"jsonrpc\":\"2.0\",\"method\":\"eth_getLogs\",\"params\":[{"
.to_vec();
body.extend(b"\"fromBlock\":\"".to_vec());
body.extend(Self::u64_to_hexadecimal_bytes(from_block));
body.extend(Self::block_number_to_hexadecimal_bytes(from_block));
body.extend(b"\",\"toBlock\":\"".to_vec());
body.extend(Self::u64_to_hexadecimal_bytes(to_block));
body.extend(Self::block_number_to_hexadecimal_bytes(to_block));
body.extend(b"\",\"address\":\"".to_vec());
body.extend(network_data.gatekeeper.to_vec());
body.extend(b"\",\"topics\":[\"".to_vec());
@ -1243,12 +1313,16 @@ impl<T: Config> Pallet<T> {
);
let authorities_len = authorities.len();
let bounded_authorities = WeakBoundedVec::<_, T::MaxAuthorities>::try_from(authorities)
.expect("more than the maximum number of authorities");
let bounded_authorities = WeakBoundedVec::<_, T::MaxAuthorities>::force_from(
authorities,
Some("slow claps reached maximum number of authorities"),
);
let validators = T::ValidatorSet::validators();
let bounded_validators = WeakBoundedVec::<_, T::MaxAuthorities>::try_from(validators)
.expect("more than the maximum number of validators");
let bounded_validators = WeakBoundedVec::<_, T::MaxAuthorities>::force_from(
validators,
Some("slow claps reached maximum number of validators"),
);
if let Some(target_session_index) = session_index.checked_sub(T::HistoryDepth::get()) {
Self::clear_history(&target_session_index);
@ -1273,73 +1347,47 @@ impl<T: Config> Pallet<T> {
debug_assert!(cursor.maybe_cursor.is_none());
}
fn calculate_median_value(values: &mut Vec<(AuthIndex, u64)>) -> u64 {
fn calculate_median_value<InnerValue>(values: &mut Vec<(AuthIndex, InnerValue)>) -> InnerValue
where
InnerValue: AtLeast32BitUnsigned + Copy,
{
values.sort_by_key(|data| data.1);
let length = values.len();
if length % 2 == 0 {
let mid_left = values[length / 2 - 1].1;
let mid_right = values[length / 2].1;
(mid_left + mid_right) / 2
(mid_left + mid_right) / 2u32.into()
} else {
values[length / 2].1
}
}
fn apply_median_deviation(
bitmap: &mut BitMap,
disabled: &BitMap,
values: &Vec<(AuthIndex, u64)>,
median: u64,
max_deviation: u64,
) {
values.iter().for_each(|(authority_index, value)| {
if !disabled.exists(authority_index) && value.abs_diff(median) > max_deviation {
bitmap.set(*authority_index);
}
})
}
fn capture_deviation_in_commitments_and_remove(
fn capture_deviation_in_commitments<InnerValue>(
disabled_bitmap: &BitMap,
block_commitments: &BTreeMap<AuthIndex, CommitmentDetails>,
validators: &WeakBoundedVec<ValidatorId<T>, T::MaxAuthorities>,
max_block_deviation: u64,
) -> BitMap {
let validators_len = validators.len() as u32;
mut values: &mut Vec<(AuthIndex, InnerValue)>,
validators_len: u32,
max_deviation: InnerValue,
) -> BitMap
where
InnerValue: AtLeast32BitUnsigned + Copy,
{
let mut delayed_bitmap = BitMap::new(validators_len);
let median_value = Self::calculate_median_value(&mut values);
let mut delayed = BitMap::new(validators_len);
let mut stored_blocks: Vec<(AuthIndex, u64)> = Vec::new();
let mut time_updates: Vec<(AuthIndex, u64)> = Vec::new();
values.iter().for_each(|(authority_index, value)| {
let abs_diff = if *value > median_value {
*value - median_value
} else {
median_value - *value
};
for authority_index in 0..validators_len {
let data = block_commitments
.get(&authority_index)
.copied()
.unwrap_or_default();
stored_blocks.push((authority_index, data.last_stored_block));
time_updates.push((authority_index, data.last_updated));
if !disabled_bitmap.exists(authority_index) && abs_diff > max_deviation {
delayed_bitmap.set(*authority_index);
}
});
let stored_block_median = Self::calculate_median_value(&mut stored_blocks);
let time_update_median = Self::calculate_median_value(&mut time_updates);
Self::apply_median_deviation(
&mut delayed,
disabled_bitmap,
&stored_blocks,
stored_block_median,
max_block_deviation,
);
Self::apply_median_deviation(
&mut delayed,
disabled_bitmap,
&time_updates,
time_update_median,
ONE_HOUR_MILLIS,
);
delayed
delayed_bitmap
}
fn get_cumulative_missing_clapped_amount(
@ -1393,41 +1441,54 @@ impl<T: Config> Pallet<T> {
offence_bitmap: BitMap,
disabled_bitmap: BitMap,
offence_type: OffenceType,
) {
let validator_set_count = validators.len() as u32;
) -> Weight {
let mut weight = T::DbWeight::get().reads_writes(1, 1);
let validator_set_count = validators.len();
let offenders = validators
.into_iter()
.enumerate()
.filter_map(|(index, id)| {
(offence_bitmap.exists(&(index as AuthIndex))).then(|| {
<T::ValidatorSet as ValidatorSetWithIdentification<T::AccountId>>::IdentificationOf::convert(
id.clone(),
).map(|full_id| (id.clone(), full_id))
})
.flatten()
})
.collect::<Vec<IdentificationTuple<T>>>();
let mut offenders = Vec::with_capacity(offence_bitmap.count_ones() as usize);
let mut reporter_indexes = Vec::with_capacity(validator_set_count);
let disabled_or_offence_bitmap = disabled_bitmap.bitor(offence_bitmap);
let disabled_or_offence_bitmap = disabled_bitmap.bitor(offence_bitmap.clone());
let validator_set_count = validator_set_count as u32;
for (index, id) in validators.iter().enumerate() {
let authority_index = index as AuthIndex;
if offence_bitmap.exists(&authority_index) {
weight.saturating_accrue(T::DbWeight::get().reads(1));
if let Some(full_id) = <T::ValidatorSet as ValidatorSetWithIdentification<
T::AccountId,
>>::IdentificationOf::convert(id.clone())
{
offenders.push((id.clone(), full_id));
}
} else if !disabled_or_offence_bitmap.exists(&authority_index) {
reporter_indexes.push(index);
}
}
let offenders_len = offenders.len() as u32;
let not_enough_validators_left = validator_set_count
.saturating_sub(disabled_or_offence_bitmap.count_ones())
.lt(&T::MinAuthoritiesNumber::get());
if not_enough_validators_left && offenders.len() > 0 {
if not_enough_validators_left && offenders_len > 0 {
Self::deposit_event(Event::<T>::BlackSwan);
return;
return weight;
}
if offenders.len() == 0 {
if offenders_len == 0 {
let equilibrium_event = match offence_type {
OffenceType::CommitmentOffence => Event::<T>::AuthoritiesCommitmentEquilibrium,
OffenceType::ThrottlingOffence(_) => Event::<T>::AuthoritiesApplauseEquilibrium,
};
Self::deposit_event(equilibrium_event);
return;
return weight;
}
weight.saturating_accrue(T::DbWeight::get().reads(1));
let reporters = T::ExposureListener::get_accounts_by_indexes(reporter_indexes.into_iter());
let offence_event = match offence_type {
OffenceType::CommitmentOffence => Event::<T>::SomeAuthoritiesDelayed {
delayed: offenders.clone(),
@ -1446,19 +1507,13 @@ impl<T: Config> Pallet<T> {
offence_type,
};
let reporters = validators
.into_iter()
.enumerate()
.filter_map(|(index, _)| {
(!disabled_or_offence_bitmap.exists(&(index as AuthIndex)))
.then(|| T::ExposureListener::get_account_by_index(index))
.flatten()
})
.collect();
if let Err(e) = T::ReportUnresponsiveness::report_offence(reporters, offence) {
sp_runtime::print(e);
}
let extra_weight = T::WeightInfo::try_offend_validators(validator_set_count, offenders_len);
weight.saturating_add(extra_weight)
}
}
@ -1488,8 +1543,8 @@ impl<T: Config> OneSessionHandler<T::AccountId> for Pallet<T> {
where
I: Iterator<Item = (&'a T::AccountId, T::AuthorityId)>,
{
for (network_id, _) in BlockCommitments::<T>::iter() {
BlockCommitments::<T>::remove(network_id);
for network_id in T::NetworkDataHandler::iter_indexes() {
BlockCommitments::<T>::remove(&network_id);
}
let total_exposure = T::ExposureListener::get_total_exposure();

View File

@ -0,0 +1,9 @@
pub mod v3;
pub type MigrateV2ToV3<T> = frame_support::migrations::VersionedMigration<
2,
3,
v3::CommitmentDetailsTypesChanged<T>,
crate::Pallet<T>,
<T as frame_system::Config>::DbWeight,
>;

View File

@ -0,0 +1,71 @@
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{
storage,
traits::{Get, UncheckedOnRuntimeUpgrade},
weights::Weight,
};
use ghost_networks::NetworkDataInspectHandler;
use scale_info::TypeInfo;
use sp_runtime::traits::{BlockNumberProvider, UniqueSaturatedInto};
use sp_runtime::RuntimeDebug;
use sp_std::marker::PhantomData;
use crate::{AuthIndex, BTreeMap, BlockCommitments, CommitmentDetails, Config, Pallet, LOG_TARGET};
#[derive(
RuntimeDebug,
Default,
Copy,
Clone,
Eq,
PartialEq,
Ord,
PartialOrd,
Encode,
Decode,
TypeInfo,
MaxEncodedLen,
)]
pub struct OldCommitmentDetails {
pub last_stored_block: u64,
pub last_updated: u64,
pub commits: u64,
}
pub struct CommitmentDetailsTypesChanged<T>(PhantomData<T>);
impl<T: Config> UncheckedOnRuntimeUpgrade for CommitmentDetailsTypesChanged<T> {
fn on_runtime_upgrade() -> Weight {
let mut weight = T::DbWeight::get().reads(3);
let current_block_number = <Pallet<T> as BlockNumberProvider>::current_block_number();
for network_id in T::NetworkDataHandler::iter_indexes() {
let mut new_btree_map = BTreeMap::new();
let key_hash = BlockCommitments::<T>::hashed_key_for(&network_id);
let old_commitments = storage::unhashed::take_or_default::<
BTreeMap<AuthIndex, OldCommitmentDetails>,
>(&key_hash);
for (authority_index, details) in old_commitments.iter() {
new_btree_map.insert(
authority_index,
CommitmentDetails {
last_stored_block: details.last_stored_block,
last_updated: current_block_number,
commits: details.commits.unique_saturated_into(),
},
);
}
BlockCommitments::<T>::insert(&network_id, new_btree_map);
weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 1));
log::info!(
target: LOG_TARGET,
"👻 Block commitments migrated from unix timestamp to internal block for network {:?}",
network_id,
);
}
weight
}
}

View File

@ -130,6 +130,7 @@ parameter_types! {
parameter_types! {
pub static MockAverageSessionLength: Option<u64> = None;
pub const MaxNetworks: u32 = 5;
}
impl ghost_networks::Config for Runtime {
@ -139,6 +140,7 @@ impl ghost_networks::Config for Runtime {
type RegisterOrigin = EnsureRoot<Self::AccountId>;
type UpdateOrigin = EnsureRoot<Self::AccountId>;
type RemoveOrigin = EnsureRoot<Self::AccountId>;
type MaxNetworks = MaxNetworks;
type WeightInfo = ();
}
@ -157,6 +159,7 @@ parameter_types! {
pub static ExistentialDeposit: u64 = 2;
pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
pub const HistoryDepth: u32 = 10;
pub const EpochDuration: u64 = 80;
}
#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
@ -174,6 +177,15 @@ impl ExposureListener<Balance, u64> for TestExposureListener
where
Balance: AtLeast32BitUnsigned + From<u64>,
{
fn get_accounts_by_indexes(
indexes_iterator: impl Iterator<Item = usize>,
) -> sp_std::prelude::Vec<u64> {
let all_validators = FixedValidators::get();
indexes_iterator
.filter_map(|i| all_validators.get(i).copied())
.collect()
}
fn get_account_by_index(index: usize) -> Option<u64> {
FixedValidators::get().get(index).copied()
}
@ -211,6 +223,7 @@ impl Config for Runtime {
type UnsignedPriority = ConstU64<{ 1 << 20 }>;
type HistoryDepth = HistoryDepth;
type MinAuthoritiesNumber = ConstU32<1>;
type EpochDuration = EpochDuration;
type WeightInfo = ();
}

View File

@ -1,10 +1,10 @@
#![cfg(test)]
use std::time::{SystemTime, UNIX_EPOCH};
use std::collections::HashMap;
use super::*;
use crate::evm_types::Log;
use crate::mock::*;
use crate::{evm_types::Log, migrations::v3::OldCommitmentDetails};
use frame_support::{assert_err, assert_ok, dispatch};
use sp_core::offchain::{
@ -822,7 +822,7 @@ fn should_clap_without_applause_on_gatekeeper_amount_overflow() {
let first_receiver: u64 = 1337;
let second_receiver: u64 = 420;
let (network_id, block_number, unique_hash) =
let (network_id, block_number, _) =
generate_unique_hash(None, None, Some(first_receiver), Some(big_amount), None);
new_test_ext().execute_with(|| {
@ -840,13 +840,17 @@ fn should_clap_without_applause_on_gatekeeper_amount_overflow() {
receiver: first_receiver,
amount: big_amount,
};
let unique_hash = SlowClap::generate_unique_hash(&clap);
let authority = UintAuthorityId::from(authority_index as u64);
let signature = authority.sign(&clap.encode()).unwrap();
assert_ok!(SlowClap::slow_clap(RuntimeOrigin::none(), clap, signature));
assert_clapped(&session_index, &unique_hash, authority_index, true);
if authority_index > 2 {
assert_applaused(&session_index, &unique_hash);
}
}
assert_applaused(&session_index, &unique_hash);
assert_eq!(Balances::total_balance(&first_receiver), big_amount);
assert_eq!(Balances::total_balance(&second_receiver), 0);
@ -892,7 +896,6 @@ fn should_nullify_commission_on_finalize() {
assert_ok!(do_clap_from(session_index, network_id, 1, false));
assert_ok!(do_clap_from(session_index, network_id, 2, false));
assert_eq!(Networks::accumulated_commission(), amount);
assert_eq!(Networks::is_nullification_period(), false);
assert_applaused(&session_index, &unique_hash);
assert_eq!(
@ -903,63 +906,13 @@ fn should_nullify_commission_on_finalize() {
),
(amount, 0u64)
); // precomputed values
assert_eq!(Networks::is_nullification_period(), true);
Networks::on_finalize(System::block_number());
assert_eq!(Networks::is_nullification_period(), false);
assert_eq!(Networks::accumulated_commission(), 0);
assert_ok!(do_clap_from(session_index, network_id, 3, false));
assert_eq!(Networks::accumulated_commission(), 0);
});
}
#[test]
fn should_avoid_applause_during_nullification_period() {
let zero: u64 = 0u64;
let total_staked = 69_000_000;
let total_issuance = 100_000_000;
let (network_id, _, unique_hash) = generate_unique_hash(None, None, None, None, None);
let (_, receiver, amount, _) = get_mocked_metadata();
new_test_ext().execute_with(|| {
let _ = prepare_evm_network(None, None);
let session_index = advance_session_and_get_index();
assert_eq!(Networks::is_nullification_period(), false);
assert_eq!(
BridgedInflationCurve::<RewardCurve, Runtime>::era_payout(
total_staked,
total_issuance,
zero
),
(zero, zero)
);
assert_eq!(Networks::is_nullification_period(), true);
assert_ok!(do_clap_from(session_index, network_id, 0, false));
assert_ok!(do_clap_from(session_index, network_id, 1, false));
assert_eq!(Balances::total_balance(&receiver), 0);
assert_clapped(&session_index, &unique_hash, 0, true);
assert_clapped(&session_index, &unique_hash, 1, true);
assert_clapped(&session_index, &unique_hash, 2, false);
assert_clapped(&session_index, &unique_hash, 3, false);
Networks::on_finalize(System::block_number());
assert_eq!(Networks::is_nullification_period(), false);
assert_ok!(do_clap_from(session_index, network_id, 2, false));
assert_ok!(do_clap_from(session_index, network_id, 3, false));
assert_eq!(Balances::total_balance(&receiver), amount);
assert_applaused(&session_index, &unique_hash);
assert_clapped(&session_index, &unique_hash, 0, true);
assert_clapped(&session_index, &unique_hash, 1, true);
assert_clapped(&session_index, &unique_hash, 2, true);
assert_clapped(&session_index, &unique_hash, 3, true);
});
}
#[test]
fn should_avoid_session_overlap_on_mended_session_index() {
let (network_id, _, unique_hash) = generate_unique_hash(None, None, None, None, None);
@ -1112,47 +1065,38 @@ fn should_register_block_commitments() {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
for commitment_details in BlockCommitments::<Runtime>::get(network_id).values() {
assert_eq!(commitment_details.last_stored_block, 0);
assert_eq!(commitment_details.last_updated, 0);
assert_eq!(commitment_details.commits, 0);
}
assert_eq!(BlockCommitments::<Runtime>::get(network_id).len(), 0);
let last_stored_block = 69;
let current_block = SlowClap::current_block_number();
let mut block_commitment = CommitmentDetails {
last_stored_block: 69,
commits: 420,
last_updated: 1337,
};
for i in 0..=3 {
assert_ok!(do_block_commitment(
session_index,
network_id,
i,
&block_commitment
last_stored_block,
));
}
block_commitment.last_updated = 1000;
for i in 0..=3 {
assert_err!(
do_block_commitment(session_index, network_id, i, &block_commitment),
do_block_commitment(session_index, network_id, i, last_stored_block),
Error::<Runtime>::TimeWentBackwards,
);
}
for commitment_details in BlockCommitments::<Runtime>::get(network_id).values() {
assert_eq!(commitment_details.last_stored_block, 69);
assert_eq!(commitment_details.last_updated, 1337);
assert_eq!(commitment_details.commits, 1);
}
let block_commitments = BlockCommitments::<Runtime>::get(network_id);
assert_eq!(block_commitments.len(), 4);
block_commitments.values().for_each(|details| {
assert_eq!(details.last_stored_block, last_stored_block);
assert_eq!(details.last_updated, current_block);
assert_eq!(details.commits, 1);
});
advance_session();
for commitment_details in BlockCommitments::<Runtime>::get(network_id).values() {
assert_eq!(commitment_details.last_stored_block, 0);
assert_eq!(commitment_details.last_updated, 0);
assert_eq!(commitment_details.commits, 0);
}
assert_eq!(BlockCommitments::<Runtime>::get(network_id).len(), 0);
});
}
@ -1164,48 +1108,71 @@ fn should_disable_on_commitment_inactivity() {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
for commitment_details in BlockCommitments::<Runtime>::get(network_id).values() {
assert_eq!(commitment_details.last_stored_block, 0);
assert_eq!(commitment_details.last_updated, 0);
assert_eq!(commitment_details.commits, 0);
}
assert_eq!(BlockCommitments::<Runtime>::get(network_id).len(), 0);
System::set_block_number(5 * EpochDuration::get() / 2);
let last_stored_block = 69;
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
let mut block_commitment = CommitmentDetails {
last_stored_block: 69,
commits: 420,
last_updated: timestamp,
};
// two block commitments
for extra_time in 1..=3 {
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time;
for i in 0..3 {
assert_ok!(do_block_commitment(
session_index,
network_id,
i,
&block_commitment
last_stored_block,
));
}
}
let current_block = System::current_block_number();
SlowClap::on_initialize(current_block);
System::assert_has_event(RuntimeEvent::SlowClap(
crate::Event::SomeAuthoritiesDelayed {
delayed: vec![(3, 3)],
},
));
for commitment_details in BlockCommitments::<Runtime>::get(network_id)
.values()
.take(2)
{
assert_eq!(commitment_details.commits, 3);
let block_commitments = BlockCommitments::<Runtime>::get(network_id);
assert_eq!(block_commitments.get(&3), None);
block_commitments.values().for_each(|details| {
assert_eq!(details.commits, 1);
assert_eq!(details.last_stored_block, last_stored_block);
assert_eq!(details.last_updated, current_block);
})
});
}
#[test]
fn should_ignore_commitments_below_latest_executed_block() {
let (network_id, _, _) = generate_unique_hash(None, None, None, None, None);
let (_, _, _, block_number) = get_mocked_metadata();
new_test_ext().execute_with(|| {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
assert_eq!(LatestExecutedBlock::<Runtime>::get(network_id), 0);
assert_eq!(BlockCommitments::<Runtime>::get(network_id).len(), 0);
assert_ok!(do_clap_from(session_index, network_id, 0, false));
assert_ok!(do_clap_from(session_index, network_id, 1, false));
assert_ok!(do_clap_from(session_index, network_id, 2, false));
assert_ok!(do_clap_from(session_index, network_id, 3, false));
let latest_executed_block = LatestExecutedBlock::<Runtime>::get(&network_id);
assert_eq!(latest_executed_block, block_number);
for low_block in 0..=block_number {
assert_err!(
do_block_commitment(session_index, network_id, 0, low_block),
Error::<Runtime>::InnerTimeWentBackwards,
);
}
let next_block_number = block_number.saturating_add(1);
assert_ok!(do_block_commitment(
session_index,
network_id,
0,
next_block_number,
));
});
}
@ -1217,53 +1184,51 @@ fn should_disable_on_commitment_block_deviation() {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
for commitment_details in BlockCommitments::<Runtime>::get(network_id).values() {
assert_eq!(commitment_details.last_stored_block, 0);
assert_eq!(commitment_details.last_updated, 0);
}
assert_eq!(BlockCommitments::<Runtime>::get(network_id).len(), 0);
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
let good_last_stored_block = 9_500_000;
let bad_last_stored_block = 9_100_000;
let mut block_commitment = CommitmentDetails {
last_stored_block: 9_500_000,
commits: 420,
last_updated: timestamp,
};
let mut bad_block_commitment = CommitmentDetails {
last_stored_block: 9_100_000,
commits: 420,
last_updated: timestamp,
};
// two block commitments
for extra_time in 1..=3 {
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time;
bad_block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time;
let current_block = SlowClap::current_block_number();
for i in 0..3 {
assert_ok!(do_block_commitment(
session_index,
network_id,
i,
&block_commitment
good_last_stored_block,
));
}
assert_ok!(do_block_commitment(
session_index,
network_id,
3,
&bad_block_commitment
bad_last_stored_block,
));
}
let to_initialize = EpochDuration::get()
.saturating_div(BLOCK_CHECK_CYCLES)
.saturating_mul(2);
SlowClap::on_initialize(to_initialize);
System::assert_has_event(RuntimeEvent::SlowClap(
crate::Event::SomeAuthoritiesDelayed {
delayed: vec![(3, 3)],
},
));
BlockCommitments::<Runtime>::get(network_id)
.iter()
.for_each(|(account_id, details)| {
let block_to_be_stored = if *account_id == 3 {
bad_last_stored_block
} else {
good_last_stored_block
};
assert_eq!(details.commits, 1);
assert_eq!(details.last_stored_block, block_to_be_stored);
assert_eq!(details.last_updated, current_block);
})
});
}
@ -1275,106 +1240,50 @@ fn should_throw_error_on_fast_commitments() {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
assert_eq!(BlockCommitments::<Runtime>::get(network_id).len(), 0);
let mut block_commitment = CommitmentDetails {
last_stored_block: 9_500_000,
commits: 420,
last_updated: timestamp,
};
let last_stored_block = 9_500_000;
let next_stored_block = 9_600_000;
let current_block = SlowClap::current_block_number();
assert_ok!(do_block_commitment(
session_index,
network_id,
0,
&block_commitment
last_stored_block,
));
assert_err!(
do_block_commitment(session_index, network_id, 0, &block_commitment),
do_block_commitment(session_index, network_id, 0, next_stored_block),
Error::<Runtime>::TimeWentBackwards,
);
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS / 2;
assert_err!(
do_block_commitment(session_index, network_id, 0, &block_commitment),
Error::<Runtime>::TimeWentBackwards,
);
BlockCommitments::<Runtime>::get(network_id)
.get(&0)
.map(|details| {
assert_eq!(details.last_stored_block, last_stored_block);
assert_eq!(details.last_updated, current_block);
assert_eq!(details.commits, 1);
})
.expect("authority_index 0 has voted; qed");
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS / 2;
assert_err!(
do_block_commitment(session_index, network_id, 0, &block_commitment),
Error::<Runtime>::TimeWentBackwards,
);
System::set_block_number(current_block + BLOCK_COMMITMENT_DELAY);
block_commitment.last_updated += 1;
let new_current_block = SlowClap::current_block_number();
assert_ok!(do_block_commitment(
session_index,
network_id,
0,
&block_commitment
next_stored_block,
));
block_commitment.last_updated = timestamp;
assert_err!(
do_block_commitment(session_index, network_id, 0, &block_commitment),
Error::<Runtime>::TimeWentBackwards,
);
for commitment_details in BlockCommitments::<Runtime>::get(network_id).values() {
assert_eq!(commitment_details.last_stored_block, 9_500_000);
assert_eq!(
commitment_details.last_updated,
timestamp + COMMITMENT_DELAY_MILLIS + 1
);
assert_eq!(commitment_details.commits, 2);
}
});
}
#[test]
fn should_not_offend_disabled_authorities() {
let (network_id, _, _) = generate_unique_hash(None, None, None, None, None);
new_test_ext().execute_with(|| {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
assert_ok!(do_clap_from(session_index, network_id, 0, false));
assert_ok!(do_clap_from(session_index, network_id, 1, false));
assert_ok!(do_clap_from(session_index, network_id, 2, false));
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
let mut block_commitment = CommitmentDetails {
last_stored_block: 9_500_000,
commits: 420,
last_updated: timestamp,
};
Session::disable_index(3);
// two block commitments
for extra_time in 1..=3 {
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time;
for i in 0..3 {
assert_ok!(do_block_commitment(
session_index,
network_id,
i,
&block_commitment
));
}
}
System::assert_has_event(RuntimeEvent::SlowClap(
crate::Event::AuthoritiesCommitmentEquilibrium,
));
BlockCommitments::<Runtime>::get(network_id)
.get(&0)
.map(|details| {
assert_eq!(details.last_stored_block, next_stored_block);
assert_eq!(details.last_updated, new_current_block);
assert_eq!(details.commits, 2);
})
.expect("authority_index 0 has voted; qed");
});
}
@ -1386,82 +1295,91 @@ fn should_not_slash_by_applause_if_disabled_by_commitment() {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
for commitment_details in BlockCommitments::<Runtime>::get(network_id).values() {
assert_eq!(commitment_details.last_stored_block, 0);
assert_eq!(commitment_details.last_updated, 0);
}
assert_eq!(BlockCommitments::<Runtime>::get(network_id).len(), 0);
System::set_block_number(5 * EpochDuration::get() / 2);
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
let mut block_commitment = CommitmentDetails {
last_stored_block: 9_500_000,
commits: 420,
last_updated: timestamp,
};
let last_stored_block = 9_500_000;
let current_block = SlowClap::current_block_number();
let mut disabled_bitmp = BitMap::new(4);
assert_eq!(
DisabledAuthorityIndexes::<Runtime>::get(&session_index),
Some(disabled_bitmp.clone())
);
Session::disable_index(3);
disabled_bitmp.set(3);
assert_eq!(
DisabledAuthorityIndexes::<Runtime>::get(&session_index),
Some(disabled_bitmp.clone())
);
// two block commitments
for extra_time in 1..=3 {
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time;
for i in 0..3 {
for i in 0..=3 {
assert_ok!(do_block_commitment(
session_index,
network_id,
i,
&block_commitment
last_stored_block,
));
}
}
SlowClap::on_initialize(current_block);
System::assert_has_event(RuntimeEvent::SlowClap(
crate::Event::AuthoritiesCommitmentEquilibrium,
));
let block_commitments = BlockCommitments::<Runtime>::get(network_id);
assert_eq!(
DisabledAuthorityIndexes::<Runtime>::get(&session_index),
Some(disabled_bitmp)
);
assert_eq!(block_commitments.len(), 4);
block_commitments.values().for_each(|details| {
assert_eq!(details.last_stored_block, last_stored_block);
assert_eq!(details.last_updated, current_block);
assert_eq!(details.commits, 1);
});
});
}
#[test]
fn should_not_nullify_on_incorrect_block_commitment() {
fn should_not_register_block_commitment_on_old_blocks() {
let (network_id, _, _) = generate_unique_hash(None, None, None, None, None);
new_test_ext().execute_with(|| {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
assert_eq!(BlockCommitments::<Runtime>::get(network_id).len(), 0);
let mut block_commitment = CommitmentDetails {
last_stored_block: 9_500_000,
commits: 420,
last_updated: timestamp,
};
let very_old_block = 9_499_999;
let last_stored_block = 9_500_000;
let current_block = SlowClap::current_block_number();
for i in 0..4 {
assert_ok!(do_block_commitment(
session_index,
network_id,
i,
&block_commitment
last_stored_block,
));
}
block_commitment.last_updated = 0;
assert_err!(
do_block_commitment(session_index, network_id, 3, &block_commitment),
do_block_commitment(session_index, network_id, 3, last_stored_block),
Error::<Runtime>::TimeWentBackwards
);
assert_err!(
do_block_commitment(session_index, network_id, 3, very_old_block),
Error::<Runtime>::TimeWentBackwards
);
for commitment_details in BlockCommitments::<Runtime>::get(network_id).values() {
assert_eq!(commitment_details.last_stored_block, 9_500_000);
assert_eq!(commitment_details.last_updated, timestamp);
assert_eq!(commitment_details.commits, 1);
}
BlockCommitments::<Runtime>::get(network_id)
.values()
.for_each(|details| {
assert_eq!(details.commits, 1);
assert_eq!(details.last_stored_block, last_stored_block);
assert_eq!(details.last_updated, current_block);
})
});
}
@ -1473,34 +1391,24 @@ fn should_split_commit_slash_between_active_validators() {
let session_index = advance_session_and_get_index();
prepare_evm_network(None, None);
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Time went backwards")
.as_millis() as u64;
assert_eq!(BlockCommitments::<Runtime>::get(network_id).len(), 0);
System::set_block_number(5 * EpochDuration::get() / 2);
let last_stored_block = 69;
let mut block_commitment = CommitmentDetails {
last_stored_block: 9_500_000,
commits: 420,
last_updated: timestamp,
};
for extra_time in 1..=3 {
if extra_time < 3 {
let offences = Offences::get();
assert_eq!(offences.len(), 0);
}
block_commitment.last_updated += COMMITMENT_DELAY_MILLIS + extra_time;
for i in 0..3 {
assert_ok!(do_block_commitment(
session_index,
network_id,
i,
&block_commitment
last_stored_block,
));
}
}
let current_block = SlowClap::current_block_number();
let offences = Offences::get();
assert_eq!(offences.len(), 0);
SlowClap::on_initialize(current_block);
System::assert_has_event(RuntimeEvent::SlowClap(
crate::Event::SomeAuthoritiesDelayed {
delayed: vec![(3, 3)],
@ -1508,15 +1416,79 @@ fn should_split_commit_slash_between_active_validators() {
));
let offences = Offences::get();
assert_eq!(offences.len(), 3);
assert_eq!(offences.len(), 1);
for offence in offences {
assert_eq!(offence.0, vec![0, 1, 2]);
assert_eq!(offence.1.session_index, session_index);
assert_eq!(offence.1.validator_set_count, 4);
assert_eq!(offence.1.offenders, vec![(3, 3)]);
assert_eq!(offence.1.validator_set_count, 4);
assert_eq!(offence.1.offence_type, OffenceType::CommitmentOffence);
}
let block_commitments = BlockCommitments::<Runtime>::get(network_id);
assert_eq!(block_commitments.get(&3), None);
block_commitments.values().for_each(|details| {
assert_eq!(details.last_stored_block, last_stored_block);
assert_eq!(details.last_updated, current_block);
assert_eq!(details.commits, 1);
});
});
}
#[test]
fn should_check_different_networks_during_on_initialize() {
let times = 69;
let networks_count = 3;
let mut check_commitment_events = HashMap::new();
new_test_ext().execute_with(|| {
let _ = advance_session_and_get_index();
for network_id in 0..networks_count {
prepare_evm_network(Some(network_id), None);
}
let expected_events_count: u64 = BLOCK_CHECK_CYCLES
.saturating_sub(1)
.saturating_mul(networks_count as u64)
.saturating_mul(times);
let expected_events_count: usize = expected_events_count.try_into().unwrap();
let epochs_passed = times * EpochDuration::get();
for check_block in 0..epochs_passed {
SlowClap::on_initialize(check_block);
}
let binding = System::events();
let total_number_of_events = binding
.iter()
.filter(|x| {
x.event == RuntimeEvent::SlowClap(crate::Event::AuthoritiesCommitmentEquilibrium)
})
.count();
binding
.iter()
.map(|record| record.event.clone())
.for_each(|event| {
if let RuntimeEvent::SlowClap(crate::Event::BlockCommitmentsCheck {
network_id,
..
}) = event
{
*check_commitment_events.entry(network_id).or_insert(0) += 1;
}
});
assert_eq!(total_number_of_events, expected_events_count);
assert_eq!(check_commitment_events.len() as u32, networks_count);
for network_id in 0..networks_count {
let network_id_count = check_commitment_events.get(&network_id).unwrap();
let expected_events_count =
expected_events_count.saturating_div(networks_count as usize);
assert_eq!(*network_id_count, expected_events_count);
}
});
}
@ -1661,6 +1633,64 @@ fn should_get_balanced_responses_correctly() {
});
}
#[test]
fn migration_from_v2_to_v3_works_fine() {
new_test_ext().execute_with(|| {
let network_ids = vec![1, 57232, 232, 775];
StorageVersion::new(2).put::<SlowClap>();
System::set_block_number(69);
for network_id in network_ids.iter() {
prepare_evm_network(Some(*network_id), None);
let mut fake_old_commits = BTreeMap::new();
fake_old_commits.insert(
0,
OldCommitmentDetails {
last_stored_block: (*network_id).into(),
last_updated: 133742069,
commits: 420,
},
);
fake_old_commits.insert(
2,
OldCommitmentDetails {
last_stored_block: (*network_id).into(),
last_updated: 133742069,
commits: 5,
},
);
let key_hash = BlockCommitments::<Runtime>::hashed_key_for(&network_id);
frame_support::storage::unhashed::put(&key_hash, &fake_old_commits);
}
type Migrate = crate::migrations::MigrateV2ToV3<Runtime>;
<Migrate as frame_support::traits::OnRuntimeUpgrade>::on_runtime_upgrade();
let current_block_number = System::current_block_number();
for network_id in network_ids.iter() {
BlockCommitments::<Runtime>::get(&network_id)
.iter()
.for_each(|(authority_id, details)| match authority_id {
0 => {
assert_eq!(details.last_stored_block, *network_id as u64);
assert_eq!(details.last_updated, current_block_number);
assert_eq!(details.commits, u8::MAX);
}
2 => {
assert_eq!(details.last_stored_block, *network_id as u64);
assert_eq!(details.last_updated, current_block_number);
assert_eq!(details.commits, 5);
}
_ => panic!("non registered block commitment exists after migration"),
});
}
});
}
fn assert_clapped_amount(
session_index: &SessionIndex,
unique_hash: &H256,
@ -1714,13 +1744,13 @@ fn do_block_commitment(
session_index: u32,
network_id: u32,
authority_index: u32,
commitment: &CommitmentDetails,
last_stored_block: ExternalBlockNumber,
) -> dispatch::DispatchResult {
let block_commitment = BlockCommitment {
session_index,
authority_index,
network_id,
commitment: *commitment,
last_stored_block,
};
let authority = UintAuthorityId::from(authority_index as u64);
let signature = authority.sign(&block_commitment.encode()).unwrap();
@ -1884,6 +1914,7 @@ fn evm_block_response(state: &mut testing::OffchainState) {
headers: vec![
("Accept".to_string(), "application/json".to_string()),
("Content-Type".to_string(), "application/json".to_string()),
("User-Agent".to_string(), "curl/8.9.0".to_string()),
],
response: Some(b"{\"id\":0,\"jsonrpc\":\"2.0\",\"result\":\"0x1364c81\"}".to_vec()),
body: expected_body.clone(),
@ -1897,6 +1928,7 @@ fn evm_block_response(state: &mut testing::OffchainState) {
headers: vec![
("Accept".to_string(), "application/json".to_string()),
("Content-Type".to_string(), "application/json".to_string()),
("User-Agent".to_string(), "curl/8.9.0".to_string()),
],
response: Some(b"{\"id\":0,\"jsonrpc\":\"2.0\",\"result\":\"0x1364c81\"}".to_vec()),
body: expected_body,
@ -1951,6 +1983,7 @@ fn evm_logs_response(state: &mut testing::OffchainState) {
headers: vec![
("Accept".to_string(), "application/json".to_string()),
("Content-Type".to_string(), "application/json".to_string()),
("User-Agent".to_string(), "curl/8.9.0".to_string()),
],
response_headers: vec![
("Accept".to_string(), "application/json".to_string()),
@ -1968,6 +2001,7 @@ fn evm_logs_response(state: &mut testing::OffchainState) {
headers: vec![
("Accept".to_string(), "application/json".to_string()),
("Content-Type".to_string(), "application/json".to_string()),
("User-Agent".to_string(), "curl/8.9.0".to_string()),
],
response_headers: vec![
("Accept".to_string(), "application/json".to_string()),

View File

@ -16,7 +16,7 @@
//! Autogenerated weights for `ghost_slow_clap`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-11-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2026-02-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
@ -49,21 +49,28 @@ use core::marker::PhantomData;
pub trait WeightInfo {
fn slow_clap() -> Weight;
fn commit_block()-> Weight;
fn try_offend_validators(validators_len: u32, offenders_len: u32) -> Weight;
}
impl WeightInfo for () {
/// Storage: `GhostSlowClaps::Authorities` (r:1 w:0)
/// Proof: `GhostSlowClaps::Authorities` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ReceivedClaps` (r:1 w:1)
/// Proof: `GhostSlowClaps::ReceivedClaps` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ClapsInSession` (r:1 w:1)
/// Proof: `GhostSlowClaps::ClapsInSession` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ApplausesForTransaction` (r:1 w:1)
/// Proof: `GhostSlowClaps::ApplausesForTransaction` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::NullifyNeeded` (r:1 w:0)
/// Proof: `GhostNetworks::NullifyNeeded` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::LatestExecutedBlock` (r:1 w:1)
/// Proof: `GhostSlowClaps::LatestExecutedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ApplauseDetails` (r:1 w:1)
/// Proof: `GhostSlowClaps::ApplauseDetails` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::Authorities` (r:1 w:0)
/// Proof: `GhostSlowClaps::Authorities` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::DisabledAuthorityIndexes` (r:1 w:0)
/// Proof: `GhostSlowClaps::DisabledAuthorityIndexes` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::TotalExposure` (r:1 w:0)
/// Proof: `GhostSlowClaps::TotalExposure` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Session::Validators` (r:1 w:0)
/// Proof: `Session::Validators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Staking::CurrentEra` (r:1 w:0)
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasStakersOverview` (r:1 w:0)
/// Proof: `Staking::ErasStakersOverview` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`)
/// Storage: `GhostNetworks::GatekeeperAmount` (r:1 w:1)
/// Proof: `GhostNetworks::GatekeeperAmount` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::BridgedImbalance` (r:1 w:1)
@ -74,16 +81,70 @@ impl WeightInfo for () {
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn slow_clap() -> Weight {
// Proof Size summary in bytes:
// Measured: `355`
// Estimated: `3820`
// Minimum execution time: 213_817_000 picoseconds.
Weight::from_parts(216_977_000, 0)
.saturating_add(Weight::from_parts(0, 3820))
.saturating_add(RocksDbWeight::get().reads(10))
.saturating_add(RocksDbWeight::get().writes(7))
// Measured: `1417`
// Estimated: `4882`
// Minimum execution time: 305_397_000 picoseconds.
Weight::from_parts(310_207_000, 0)
.saturating_add(Weight::from_parts(0, 4882))
.saturating_add(RocksDbWeight::get().reads(13))
.saturating_add(RocksDbWeight::get().writes(6))
}
fn commit_block()-> Weight {
Default::default()
/// Storage: `Session::CurrentIndex` (r:1 w:0)
/// Proof: `Session::CurrentIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::LatestExecutedBlock` (r:1 w:0)
/// Proof: `GhostSlowClaps::LatestExecutedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::BlockCommitments` (r:1 w:1)
/// Proof: `GhostSlowClaps::BlockCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn commit_block() -> Weight {
// Proof Size summary in bytes:
// Measured: `701`
// Estimated: `4166`
// Minimum execution time: 88_007_000 picoseconds.
Weight::from_parts(89_662_000, 0)
.saturating_add(Weight::from_parts(0, 4166))
.saturating_add(RocksDbWeight::get().reads(4))
.saturating_add(RocksDbWeight::get().writes(1))
}
/// Storage: `Staking::ActiveEra` (r:1 w:0)
/// Proof: `Staking::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasStakersOverview` (r:100000 w:0)
/// Proof: `Staking::ErasStakersOverview` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasStakers` (r:100000 w:0)
/// Proof: `Staking::ErasStakers` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Session::Validators` (r:1 w:0)
/// Proof: `Session::Validators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Offences::ConcurrentReportsIndex` (r:1 w:1)
/// Proof: `Offences::ConcurrentReportsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Offences::Reports` (r:97959 w:97959)
/// Proof: `Offences::Reports` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Staking::SlashRewardFraction` (r:1 w:0)
/// Proof: `Staking::SlashRewardFraction` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasStartSessionIndex` (r:1 w:0)
/// Proof: `Staking::ErasStartSessionIndex` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
/// Storage: `Staking::Invulnerables` (r:1 w:0)
/// Proof: `Staking::Invulnerables` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Staking::SlashingSpans` (r:97959 w:97959)
/// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Staking::DisabledValidators` (r:1 w:1)
/// Proof: `Staking::DisabledValidators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// The range of component `n` is `[1, 100000]`.
/// The range of component `d` is `[0, 100000]`.
fn try_offend_validators(n: u32, d: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `674`
// Estimated: `1886 + d * (2567 ±0)`
// Minimum execution time: 13_294_008_000 picoseconds.
Weight::from_parts(13_307_595_000, 0)
.saturating_add(Weight::from_parts(0, 1886))
// Standard Error: 1_146_439
.saturating_add(Weight::from_parts(29_632_292, 0).saturating_mul(n.into()))
// Standard Error: 1_146_441
.saturating_add(Weight::from_parts(14_654_685, 0).saturating_mul(d.into()))
.saturating_add(RocksDbWeight::get().reads((1_u64).saturating_mul(n.into())))
.saturating_add(RocksDbWeight::get().reads((2_u64).saturating_mul(d.into())))
.saturating_add(RocksDbWeight::get().writes((1_u64).saturating_mul(n.into())))
.saturating_add(Weight::from_parts(0, 2567).saturating_mul(d.into()))
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "ghost-traits"
version = "0.3.26"
version = "0.3.32"
license.workspace = true
authors.workspace = true
edition.workspace = true
@ -10,10 +10,12 @@ repository.workspace = true
[dependencies]
frame-support = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
[features]
default = ["std"]
std = [
"frame-support/std",
"sp-runtime/std",
"sp-std/std",
]

View File

@ -1,6 +1,9 @@
use sp_runtime::traits::AtLeast32BitUnsigned;
pub trait ExposureListener<Balance: AtLeast32BitUnsigned, AccountId> {
fn get_accounts_by_indexes(
indexes: impl Iterator<Item = usize>,
) -> sp_std::prelude::Vec<AccountId>;
fn get_account_by_index(index: usize) -> Option<AccountId>;
fn get_total_exposure() -> Balance;
fn get_validator_exposure(index: &AccountId) -> Balance;

View File

@ -16,9 +16,12 @@ pub trait NetworkDataBasicHandler {
}
pub trait NetworkDataInspectHandler<Network>: NetworkDataBasicHandler {
fn count() -> u32;
fn contains_key(n: &Self::NetworkId) -> bool;
fn network_for_block(b: impl Into<usize>) -> Option<(Self::NetworkId, Network)>;
fn get(n: &Self::NetworkId) -> Option<Network>;
fn iter() -> PrefixIterator<(Self::NetworkId, Network)>;
fn is_nullification_period() -> bool;
fn iter_indexes() -> impl Iterator<Item = Self::NetworkId>;
}
pub trait NetworkDataMutateHandler<Network, Balance>: NetworkDataInspectHandler<Network> {
@ -36,8 +39,5 @@ pub trait NetworkDataMutateHandler<Network, Balance>: NetworkDataInspectHandler<
fn accumulate_outgoing_imbalance(amount: &Balance) -> Result<Balance, ()>;
fn accumulate_incoming_imbalance(amount: &Balance) -> Result<Balance, ()>;
fn accumulate_commission(commission: &Balance) -> Result<Balance, ()>;
fn nullify_commission();
fn trigger_nullification();
}

View File

@ -1,6 +1,6 @@
[package]
name = "casper-runtime"
version = "3.5.37"
version = "3.5.41"
build = "build.rs"
description = "Runtime of the Casper Network"
edition.workspace = true

View File

@ -86,6 +86,20 @@ where
u128: From<T::CurrencyBalance>,
AccountIdOf<T>: From<<T as pallet_session::Config>::ValidatorId>,
{
fn get_accounts_by_indexes(
indexes_iterator: impl Iterator<Item = usize>,
) -> sp_std::prelude::Vec<AccountIdOf<T>> {
let all_validators = pallet_session::Pallet::<T>::validators();
indexes_iterator
.filter_map(|index| {
all_validators.get(index).map(|validator| {
let account_id: AccountIdOf<T> = validator.clone().into();
account_id
})
})
.collect()
}
fn get_account_by_index(index: usize) -> Option<AccountIdOf<T>> {
pallet_session::Pallet::<T>::validators()
.get(index)

View File

@ -25,9 +25,10 @@ use runtime_common::{
CurrencyToVote, SlowAdjustingFeeUpdate,
};
#[cfg(not(feature = "runtime-benchmarks"))]
use frame_support::traits::tokens::pay::PayFromAccount;
#[cfg(feature = "runtime-benchmarks")]
use runtime_common::benchmarking::BenchmarkTreasuryHelper;
use runtime_common::benchmarking::{BenchmarkTreasuryHelper, BenchmarkTreasuryPaymaster};
use codec::{Decode, Encode, MaxEncodedLen};
use ghost_slow_clap::sr25519::AuthorityId as SlowClapId;
@ -82,9 +83,10 @@ pub use impls::{AllianceProposalProvider, EqualOrGreatestRootCmp, StakingExposur
// Governance configuration.
pub mod cult;
#[cfg(not(feature = "runtime-benchmarks"))]
use cult::CultTreasurySpender;
use cult::{
pallet_cult_origins, CultCollectiveInstance, CultTreasurySpender, Degens, Geniuses, Ghosts,
Skeletons, Zombies,
pallet_cult_origins, CultCollectiveInstance, Degens, Geniuses, Ghosts, Skeletons, Zombies,
};
pub const LOG_TARGET: &str = "runtime::casper";
@ -117,8 +119,8 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("casper"),
impl_name: create_runtime_str!("casper-svengali"),
authoring_version: 0,
spec_version: 4,
impl_version: 3,
spec_version: 6,
impl_version: 4,
apis: RUNTIME_API_VERSIONS,
transaction_version: 1,
state_version: 1,
@ -170,7 +172,7 @@ impl frame_system::Config for Runtime {
type SystemWeightInfo = weights::frame_system::WeightInfo<Runtime>;
type SS58Prefix = SS58Prefix;
type OnSetCode = ();
type MaxConsumers = frame_support::traits::ConstU32<16>;
type MaxConsumers = ConstU32<16>;
type SingleBlockMigrations = ();
type MultiBlockMigrator = ();
type PreInherents = ();
@ -218,10 +220,7 @@ impl pallet_preimage::Config for Runtime {
}
parameter_types! {
pub const EpochDuration: u64 = prod_or_fast!(
EPOCH_DURATION_IN_SLOTS as u64,
2 * MINUTES as u64
);
pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS as u64;
pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
pub const ReportLongevity: u64 =
BondingDuration::get() as u64 *
@ -237,7 +236,7 @@ impl pallet_babe::Config for Runtime {
type EpochChangeTrigger = pallet_babe::ExternalTrigger;
type DisabledValidators = Session;
type WeightInfo = ();
type WeightInfo = weights::pallet_babe::WeightInfo<Runtime>;
type MaxAuthorities = MaxAuthorities;
type MaxNominators = MaxNominators;
@ -332,14 +331,8 @@ impl pallet_session::historical::Config for Runtime {
}
parameter_types! {
pub SignedPhase: u32 = prod_or_fast!(
EPOCH_DURATION_IN_SLOTS / 4,
(1 * MINUTES).min(EpochDuration::get().saturated_into::<u32>() / 2)
);
pub UnsignedPhase: u32 = prod_or_fast!(
EPOCH_DURATION_IN_SLOTS / 4,
(1 * MINUTES).min(EpochDuration::get().saturated_into::<u32>() / 2)
);
pub SignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
pub UnsignedPhase: u32 = EPOCH_DURATION_IN_SLOTS / 4;
// signed config
pub const SignedMaxSubmissions: u32 = 16;
@ -567,19 +560,30 @@ impl pallet_identity::Config for Runtime {
parameter_types! {
pub const ProposalBond: Permill = Permill::from_percent(5);
pub const ProposalBondMinimum: Balance = 10 * CSPR;
pub const ProposalBondMaximum: Balance = 50 * CSPR;
pub const SpendPeriod: BlockNumber = 24 * DAYS;
pub const Burn: Permill = Permill::from_percent(0);
pub const MaxBalance: Balance = Balance::MAX;
pub const PayoutPeriod: BlockNumber = 30 * DAYS;
pub const TreasuryPalletId: PalletId = PalletId(*b"py/trsry");
pub const DataDepositPerByte: Balance = 1 * STRH;
pub const MaxApprovals: u32 = 100;
pub const MaxApprovals: u32 = 1000;
pub const MaxAuthorities: u32 = 100_000;
}
#[cfg(not(feature = "runtime-benchmarks"))]
parameter_types! {
pub const ProposalBondMinimum: Balance = 10 * CSPR;
pub const ProposalBondMaximum: Balance = 50 * CSPR;
pub const SpendPeriod: BlockNumber = 6 * DAYS;
}
#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
pub const ProposalBondMinimum: Balance = ExistentialDeposit::get() * 100;
pub const ProposalBondMaximum: Balance = ExistentialDeposit::get() * 500;
pub const SpendPeriod: BlockNumber = 1;
}
impl pallet_treasury::Config for Runtime {
type PalletId = TreasuryPalletId;
type Currency = Balances;
@ -594,30 +598,29 @@ impl pallet_treasury::Config for Runtime {
type OnSlash = Treasury;
type ProposalBond = ProposalBond;
#[cfg(not(feature = "runtime-benchmarks"))]
type ProposalBondMinimum = ProposalBondMinimum;
#[cfg(feature = "runtime-benchmarks")]
type ProposalBondMinimum = ConstU128<{ ExistentialDeposit::get() * 100 }>;
#[cfg(not(feature = "runtime-benchmarks"))]
type ProposalBondMaximum = ProposalBondMaximum;
#[cfg(feature = "runtime-benchmarks")]
type ProposalBondMaximum = ConstU128<{ ExistentialDeposit::get() * 500 }>;
type SpendPeriod = SpendPeriod;
type Burn = Burn;
type BurnDestination = ();
type SpendFunds = Bounties;
type MaxApprovals = MaxApprovals;
type WeightInfo = ();
type WeightInfo = weights::pallet_treasury::WeightInfo<Runtime>;
#[cfg(not(feature = "runtime-benchmarks"))]
type SpendOrigin = EitherOf<EnsureRootWithSuccess<AccountId, MaxBalance>, CultTreasurySpender>;
#[cfg(feature = "runtime-benchmarks")]
type SpendOrigin = EnsureRootWithSuccess<AccountId, MaxBalance>;
type AssetKind = ();
type Beneficiary = AccountId;
type BeneficiaryLookup = IdentityLookup<Self::Beneficiary>;
#[cfg(not(feature = "runtime-benchmarks"))]
type Paymaster = PayFromAccount<Balances, TreasuryAccount>;
#[cfg(feature = "runtime-benchmarks")]
type Paymaster = BenchmarkTreasuryPaymaster;
type BalanceConverter = UnityAssetBalanceConversion;
type PayoutPeriod = PayoutPeriod;
@ -625,30 +628,43 @@ impl pallet_treasury::Config for Runtime {
type BenchmarkHelper = BenchmarkTreasuryHelper;
}
#[cfg(not(feature = "runtime-benchmarks"))]
parameter_types! {
pub const BountyValueMinimum: Balance = 1 * STRH;
pub const CuratorDepositMin: Balance = 10 * CSPR;
}
#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
pub const BountyValueMinimum: Balance = ExistentialDeposit::get() * 10;
pub const CuratorDepositMin: Balance = ExistentialDeposit::get();
}
parameter_types! {
pub const BountyDepositBase: Balance = 10 * CSPR;
pub const BountyDepositPayoutDelay: BlockNumber = DAYS;
pub const BountyUpdatePeriod: BlockNumber = 2 * WEEKS;
pub const MaximumReasonLength: u32 = 16_384;
pub const CuratorDepositMultiplier: Permill = Permill::from_percent(50);
pub const CuratorDepositMin: Balance = 10 * CSPR;
pub const CuratorDepositMax: Balance = 200 * CSPR;
pub const BountyValueMinimum: Balance = 10 * CSPR;
}
impl pallet_bounties::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type BountyDepositBase = BountyDepositBase;
type CuratorDepositMin = CuratorDepositMin;
type DataDepositPerByte = DataDepositPerByte;
type BountyValueMinimum = BountyValueMinimum;
type BountyDepositPayoutDelay = BountyDepositPayoutDelay;
type BountyUpdatePeriod = BountyUpdatePeriod;
type CuratorDepositMultiplier = CuratorDepositMultiplier;
type CuratorDepositMin = CuratorDepositMin;
type CuratorDepositMax = CuratorDepositMax;
type BountyValueMinimum = BountyValueMinimum;
type ChildBountyManager = ChildBounties;
type DataDepositPerByte = DataDepositPerByte;
type MaximumReasonLength = MaximumReasonLength;
type WeightInfo = ();
type WeightInfo = weights::pallet_bounties::WeightInfo<Runtime>;
}
parameter_types! {
@ -660,7 +676,7 @@ impl pallet_child_bounties::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type MaxActiveChildBountyCount = MaxActiveChildBountyCount;
type ChildBountyValueMinimum = ChildBountyValueMinimum;
type WeightInfo = ();
type WeightInfo = weights::pallet_child_bounties::WeightInfo<Runtime>;
}
impl pallet_offences::Config for Runtime {
@ -685,7 +701,7 @@ parameter_types! {
impl pallet_grandpa::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
type WeightInfo = weights::pallet_grandpa::WeightInfo<Runtime>;
type MaxAuthorities = MaxAuthorities;
type MaxNominators = MaxNominators;
@ -978,7 +994,7 @@ impl pallet_collective::Config<AllianceCollective> for Runtime {
type MaxProposals = ConstU32<ALLIANCE_MAX_PROPOSALS>;
type MaxMembers = ConstU32<ALLIANCE_MAX_MEMBERS>;
type DefaultVote = pallet_collective::MoreThanMajorityThenPrimeDefaultVote;
type SetMembersOrigin = EnsureRoot<AccountId>;
type SetMembersOrigin = EnsureRoot<Self::AccountId>;
type MaxProposalWeight = MaxProposalWeight;
type WeightInfo = weights::pallet_collective::WeightInfo<Runtime>;
}
@ -1029,6 +1045,7 @@ impl ghost_networks::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type NetworkId = u64;
type Currency = Balances;
type MaxNetworks = ConstU32<30>;
type RegisterOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Ghosts>;
type UpdateOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Zombies>;
@ -1058,14 +1075,22 @@ impl ghost_claims::Config<CultCollectiveInstance> for Runtime {
}
parameter_types! {
// will be used in `Perbill::from_parts()`
pub const ApplauseThreshold: u32 = 500_000_000;
pub const MinAuthoritiesNumber: u32 = 5;
pub const SlowClapUnsignedPriority: TransactionPriority = TransactionPriority::MAX;
pub const SlowClapHistoryDepth: sp_staking::SessionIndex =
StakingHistoryDepth::get() * SessionsPerEra::get();
}
#[cfg(feature = "runtime-benchmarks")]
parameter_types! {
pub const ApplauseThreshold: u32 = 0;
}
#[cfg(not(feature = "runtime-benchmarks"))]
parameter_types! {
pub const ApplauseThreshold: u32 = 500_000_000;
}
impl ghost_slow_clap::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type AuthorityId = SlowClapId;
@ -1078,11 +1103,13 @@ impl ghost_slow_clap::Config for Runtime {
type DisabledValidators = Session;
type ExposureListener = StakingExposureListener<Runtime>;
type MaxAuthorities = MaxAuthorities;
type ApplauseThreshold = ApplauseThreshold;
type MaxAuthorities = MaxAuthorities;
type UnsignedPriority = SlowClapUnsignedPriority;
type HistoryDepth = SlowClapHistoryDepth;
type MinAuthoritiesNumber = MinAuthoritiesNumber;
type EpochDuration = EpochDuration;
type WeightInfo = weights::ghost_slow_clap::WeightInfo<Runtime>;
}
@ -1185,7 +1212,10 @@ pub type SignedExtra = (
/// All migrations that will run on the next runtime upgrade.
/// Should be cleared after release.
pub type Migrations = ();
pub type Migrations = (
ghost_networks::migrations::MigrateV0ToV1<Runtime>,
ghost_slow_clap::migrations::MigrateV2ToV3<Runtime>,
);
/// Unchecked extrinsic type as expected by this runtime.
pub type UncheckedExtrinsic =

View File

@ -16,7 +16,7 @@
//! Autogenerated weights for `ghost_networks`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-11-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2026-02-26, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
@ -30,7 +30,6 @@
// --repeat=20
// --pallet=ghost_networks
// --extrinsic=*
// --wasm-execution=compiled
// --heap-pages=4096
// --header=./file_header.txt
// --output=./runtime/casper/src/weights/ghost_networks.rs
@ -48,35 +47,35 @@ pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::NetworkIndexes` (r:1 w:1)
/// Proof: `GhostNetworks::NetworkIndexes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// The range of component `i` is `[1, 20]`.
/// The range of component `j` is `[1, 150]`.
/// The range of component `k` is `[1, 20]`.
fn register_network(i: u32, j: u32, k: u32, ) -> Weight {
fn register_network(_i: u32, j: u32, k: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `109`
// Estimated: `3574`
// Minimum execution time: 47_308_000 picoseconds.
Weight::from_parts(32_768_615, 0)
// Minimum execution time: 48_419_000 picoseconds.
Weight::from_parts(35_655_823, 0)
.saturating_add(Weight::from_parts(0, 3574))
// Standard Error: 5_701
.saturating_add(Weight::from_parts(31_258, 0).saturating_mul(i.into()))
// Standard Error: 748
.saturating_add(Weight::from_parts(102_765, 0).saturating_mul(j.into()))
// Standard Error: 5_701
.saturating_add(Weight::from_parts(1_500_633, 0).saturating_mul(k.into()))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
// Standard Error: 1_212
.saturating_add(Weight::from_parts(96_762, 0).saturating_mul(j.into()))
// Standard Error: 9_235
.saturating_add(Weight::from_parts(1_460_410, 0).saturating_mul(k.into()))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(2))
}
/// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// The range of component `n` is `[1, 20]`.
fn update_network_name(_n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 51_079_000 picoseconds.
Weight::from_parts(52_557_946, 0)
.saturating_add(Weight::from_parts(0, 3775))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_422_000 picoseconds.
Weight::from_parts(49_987_541, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
@ -85,13 +84,13 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// The range of component `n` is `[1, 150]`.
fn update_network_endpoint(n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 51_709_000 picoseconds.
Weight::from_parts(53_451_989, 0)
.saturating_add(Weight::from_parts(0, 3775))
// Standard Error: 605
.saturating_add(Weight::from_parts(6_984, 0).saturating_mul(n.into()))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_651_000 picoseconds.
Weight::from_parts(50_776_912, 0)
.saturating_add(Weight::from_parts(0, 3804))
// Standard Error: 1_062
.saturating_add(Weight::from_parts(838, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
@ -99,11 +98,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_finality_delay() -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 50_475_000 picoseconds.
Weight::from_parts(51_344_000, 0)
.saturating_add(Weight::from_parts(0, 3775))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_080_000 picoseconds.
Weight::from_parts(51_781_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
@ -111,11 +110,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_rate_limit_delay() -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 50_467_000 picoseconds.
Weight::from_parts(51_264_000, 0)
.saturating_add(Weight::from_parts(0, 3775))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 47_950_000 picoseconds.
Weight::from_parts(48_925_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
@ -123,11 +122,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_block_distance() -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 50_473_000 picoseconds.
Weight::from_parts(51_107_000, 0)
.saturating_add(Weight::from_parts(0, 3775))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_324_000 picoseconds.
Weight::from_parts(50_801_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
@ -135,11 +134,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_type() -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 49_597_000 picoseconds.
Weight::from_parts(50_283_000, 0)
.saturating_add(Weight::from_parts(0, 3775))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 46_962_000 picoseconds.
Weight::from_parts(47_729_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
@ -147,11 +146,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_gatekeeper() -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 51_083_000 picoseconds.
Weight::from_parts(52_464_000, 0)
.saturating_add(Weight::from_parts(0, 3775))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_728_000 picoseconds.
Weight::from_parts(53_054_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
@ -159,11 +158,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_topic_name() -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 51_270_000 picoseconds.
Weight::from_parts(52_099_000, 0)
.saturating_add(Weight::from_parts(0, 3775))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_632_000 picoseconds.
Weight::from_parts(49_954_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
@ -171,11 +170,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_incoming_network_fee() -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 50_289_000 picoseconds.
Weight::from_parts(50_924_000, 0)
.saturating_add(Weight::from_parts(0, 3775))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 47_660_000 picoseconds.
Weight::from_parts(53_763_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
@ -183,11 +182,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_outgoing_network_fee() -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 49_880_000 picoseconds.
Weight::from_parts(51_277_000, 0)
.saturating_add(Weight::from_parts(0, 3775))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 48_164_000 picoseconds.
Weight::from_parts(48_953_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
@ -195,24 +194,26 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_avg_block_speed() -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 50_612_000 picoseconds.
Weight::from_parts(51_546_000, 0)
.saturating_add(Weight::from_parts(0, 3775))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 47_789_000 picoseconds.
Weight::from_parts(52_131_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `GhostNetworks::NetworkIndexes` (r:1 w:1)
/// Proof: `GhostNetworks::NetworkIndexes` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn remove_network() -> Weight {
// Proof Size summary in bytes:
// Measured: `310`
// Estimated: `3775`
// Minimum execution time: 45_819_000 picoseconds.
Weight::from_parts(46_590_000, 0)
.saturating_add(Weight::from_parts(0, 3775))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
// Measured: `339`
// Estimated: `3804`
// Minimum execution time: 49_720_000 picoseconds.
Weight::from_parts(50_526_000, 0)
.saturating_add(Weight::from_parts(0, 3804))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(2))
}
}

View File

@ -16,7 +16,7 @@
//! Autogenerated weights for `ghost_slow_clap`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-11-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2026-02-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
@ -48,6 +48,8 @@ pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> ghost_slow_clap::WeightInfo for WeightInfo<T> {
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::LatestExecutedBlock` (r:1 w:1)
/// Proof: `GhostSlowClaps::LatestExecutedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ApplauseDetails` (r:1 w:1)
/// Proof: `GhostSlowClaps::ApplauseDetails` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::Authorities` (r:1 w:0)
@ -62,10 +64,6 @@ impl<T: frame_system::Config> ghost_slow_clap::WeightInfo for WeightInfo<T> {
/// Proof: `Staking::CurrentEra` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasStakersOverview` (r:1 w:0)
/// Proof: `Staking::ErasStakersOverview` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`)
/// Storage: `GhostSlowClaps::LatestExecutedBlock` (r:1 w:1)
/// Proof: `GhostSlowClaps::LatestExecutedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::NullifyNeeded` (r:1 w:0)
/// Proof: `GhostNetworks::NullifyNeeded` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::GatekeeperAmount` (r:1 w:1)
/// Proof: `GhostNetworks::GatekeeperAmount` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::BridgedImbalance` (r:1 w:1)
@ -76,32 +74,70 @@ impl<T: frame_system::Config> ghost_slow_clap::WeightInfo for WeightInfo<T> {
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn slow_clap() -> Weight {
// Proof Size summary in bytes:
// Measured: `1388`
// Estimated: `4853`
// Minimum execution time: 261_978_000 picoseconds.
Weight::from_parts(266_289_000, 0)
.saturating_add(Weight::from_parts(0, 4853))
.saturating_add(T::DbWeight::get().reads(14))
// Measured: `1417`
// Estimated: `4882`
// Minimum execution time: 305_397_000 picoseconds.
Weight::from_parts(310_207_000, 0)
.saturating_add(Weight::from_parts(0, 4882))
.saturating_add(T::DbWeight::get().reads(13))
.saturating_add(T::DbWeight::get().writes(6))
}
/// Storage: `Session::CurrentIndex` (r:1 w:0)
/// Proof: `Session::CurrentIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::LatestExecutedBlock` (r:1 w:0)
/// Proof: `GhostSlowClaps::LatestExecutedBlock` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::BlockCommitments` (r:1 w:1)
/// Proof: `GhostSlowClaps::BlockCommitments` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Session::CurrentIndex` (r:1 w:0)
/// Proof: `Session::CurrentIndex` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::Validators` (r:1 w:0)
/// Proof: `GhostSlowClaps::Validators` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::DisabledAuthorityIndexes` (r:1 w:0)
/// Proof: `GhostSlowClaps::DisabledAuthorityIndexes` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn commit_block() -> Weight {
// Proof Size summary in bytes:
// Measured: `859`
// Estimated: `4324`
// Minimum execution time: 108_966_000 picoseconds.
Weight::from_parts(110_454_000, 0)
.saturating_add(Weight::from_parts(0, 4324))
.saturating_add(T::DbWeight::get().reads(5))
// Measured: `701`
// Estimated: `4166`
// Minimum execution time: 88_007_000 picoseconds.
Weight::from_parts(89_662_000, 0)
.saturating_add(Weight::from_parts(0, 4166))
.saturating_add(T::DbWeight::get().reads(4))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Staking::ActiveEra` (r:1 w:0)
/// Proof: `Staking::ActiveEra` (`max_values`: Some(1), `max_size`: Some(13), added: 508, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasStakersOverview` (r:100000 w:0)
/// Proof: `Staking::ErasStakersOverview` (`max_values`: None, `max_size`: Some(92), added: 2567, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasStakers` (r:100000 w:0)
/// Proof: `Staking::ErasStakers` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Session::Validators` (r:1 w:0)
/// Proof: `Session::Validators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Offences::ConcurrentReportsIndex` (r:1 w:1)
/// Proof: `Offences::ConcurrentReportsIndex` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Offences::Reports` (r:97959 w:97959)
/// Proof: `Offences::Reports` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Staking::SlashRewardFraction` (r:1 w:0)
/// Proof: `Staking::SlashRewardFraction` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Staking::ErasStartSessionIndex` (r:1 w:0)
/// Proof: `Staking::ErasStartSessionIndex` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
/// Storage: `Staking::Invulnerables` (r:1 w:0)
/// Proof: `Staking::Invulnerables` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `Staking::SlashingSpans` (r:97959 w:97959)
/// Proof: `Staking::SlashingSpans` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `Staking::DisabledValidators` (r:1 w:1)
/// Proof: `Staking::DisabledValidators` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// The range of component `n` is `[1, 100000]`.
/// The range of component `d` is `[0, 100000]`.
fn try_offend_validators(n: u32, d: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `674`
// Estimated: `1886 + d * (2567 ±0)`
// Minimum execution time: 13_294_008_000 picoseconds.
Weight::from_parts(13_307_595_000, 0)
.saturating_add(Weight::from_parts(0, 1886))
// Standard Error: 1_146_439
.saturating_add(Weight::from_parts(29_632_292, 0).saturating_mul(n.into()))
// Standard Error: 1_146_441
.saturating_add(Weight::from_parts(14_654_685, 0).saturating_mul(d.into()))
.saturating_add(T::DbWeight::get().reads((1_u64).saturating_mul(n.into())))
.saturating_add(T::DbWeight::get().reads((2_u64).saturating_mul(d.into())))
.saturating_add(T::DbWeight::get().writes((1_u64).saturating_mul(n.into())))
.saturating_add(Weight::from_parts(0, 2567).saturating_mul(d.into()))
}
}

View File

@ -5,12 +5,16 @@ pub mod ghost_networks;
pub mod ghost_slow_clap;
pub mod ghost_sudo;
pub mod pallet_alliance;
pub mod pallet_babe;
pub mod pallet_bags_list;
pub mod pallet_balances;
pub mod pallet_bounties;
pub mod pallet_child_bounties;
pub mod pallet_collective;
pub mod pallet_core_fellowship;
pub mod pallet_election_provider_multi_phase;
pub mod pallet_fast_unstake;
pub mod pallet_grandpa;
pub mod pallet_identity;
pub mod pallet_indices;
pub mod pallet_multisig;
@ -24,6 +28,7 @@ pub mod pallet_scheduler;
pub mod pallet_session;
pub mod pallet_staking;
pub mod pallet_timestamp;
pub mod pallet_treasury;
pub mod pallet_utility;
pub mod pallet_vesting;
pub mod pallet_whitelist;

View File

@ -16,7 +16,7 @@
//! Autogenerated weights for `pallet_babe`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-11-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2026-02-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
@ -40,19 +40,52 @@
#![allow(unused_imports)]
#![allow(missing_docs)]
use frame_support::{traits::Get, weights::Weight};
use core::marker::PhantomData;
use frame_support::{
traits::Get,
weights::{
constants::{RocksDbWeight as DbWeight, WEIGHT_REF_TIME_PER_MICROS, WEIGHT_REF_TIME_PER_NANOS},
Weight,
},
};
/// Weight functions for `pallet_babe`.
pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> pallet_babe::WeightInfo for WeightInfo<T> {
/// The range of component `x` is `[0, 1]`.
fn check_equivocation_proof(_x: u32, ) -> Weight {
fn plan_config_change() -> Weight {
DbWeight::get().writes(1)
}
fn report_equivocation(validator_count: u32, max_nominators_per_validator: u32) -> Weight {
// we take the validator set count from the membership proof to
// calculate the weight but we set a floor of 100 validators.
let validator_count = validator_count.max(100) as u64;
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 295_038_000 picoseconds.
Weight::from_parts(298_100_475, 0)
// Minimum execution time: 305_618_000 picoseconds.
let equivocation_check_weight = Weight::from_parts(308_237_602, 0)
.saturating_add(Weight::from_parts(0, 0))
// Standard Error: 899_088
.saturating_add(Weight::from_parts(7_097, 0).saturating_mul(validator_count.into()));
// checking membership proof
Weight::from_parts(88u64 * WEIGHT_REF_TIME_PER_MICROS, 0)
.saturating_add(
Weight::from_parts(438u64 * WEIGHT_REF_TIME_PER_NANOS, 0)
.saturating_mul(validator_count),
)
.saturating_add(DbWeight::get().reads(5))
// check equivocation proof
.saturating_add(equivocation_check_weight)
// report offence
.saturating_add(equivocation_check_weight)
.saturating_add(Weight::from_parts(
63u64 * WEIGHT_REF_TIME_PER_MICROS * max_nominators_per_validator as u64,
0,
))
.saturating_add(DbWeight::get().reads(14 + 3 * max_nominators_per_validator as u64))
.saturating_add(DbWeight::get().writes(10 + 3 * max_nominators_per_validator as u64))
}
}

View File

@ -16,7 +16,7 @@
//! Autogenerated weights for `pallet_bounties`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2024-08-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2026-02-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
@ -29,7 +29,7 @@
// --steps=50
// --repeat=20
// --pallet=pallet_bounties
// --extrinsic=approve_bounty
// --extrinsic=*
// --wasm-execution=compiled
// --heap-pages=4096
// --header=./file_header.txt
@ -46,18 +46,181 @@ use core::marker::PhantomData;
/// Weight functions for `pallet_bounties`.
pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> pallet_bounties::WeightInfo for WeightInfo<T> {
/// Storage: `Bounties::BountyCount` (r:1 w:1)
/// Proof: `Bounties::BountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Bounties::BountyDescriptions` (r:0 w:1)
/// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
/// Storage: `Bounties::Bounties` (r:0 w:1)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// The range of component `d` is `[0, 16384]`.
fn propose_bounty(d: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `210`
// Estimated: `3593`
// Minimum execution time: 125_598_000 picoseconds.
Weight::from_parts(127_962_305, 0)
.saturating_add(Weight::from_parts(0, 3593))
// Standard Error: 21
.saturating_add(Weight::from_parts(1_868, 0).saturating_mul(d.into()))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(4))
}
/// Storage: `Bounties::Bounties` (r:1 w:1)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `Bounties::BountyApprovals` (r:1 w:1)
/// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(402), added: 897, mode: `MaxEncodedLen`)
/// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
fn approve_bounty() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `5487`
// Minimum execution time: 57_515_000 picoseconds.
Weight::from_parts(58_519_000, 0)
.saturating_add(Weight::from_parts(0, 5487))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(2))
}
/// Storage: `Bounties::Bounties` (r:1 w:1)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
fn propose_curator() -> Weight {
// Proof Size summary in bytes:
// Measured: `322`
// Estimated: `3642`
// Minimum execution time: 52_739_000 picoseconds.
Weight::from_parts(53_443_000, 0)
// Minimum execution time: 51_036_000 picoseconds.
Weight::from_parts(51_462_000, 0)
.saturating_add(Weight::from_parts(0, 3642))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Bounties::Bounties` (r:1 w:1)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn unassign_curator() -> Weight {
// Proof Size summary in bytes:
// Measured: `498`
// Estimated: `3642`
// Minimum execution time: 169_646_000 picoseconds.
Weight::from_parts(172_576_000, 0)
.saturating_add(Weight::from_parts(0, 3642))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(2))
}
/// Storage: `Bounties::Bounties` (r:1 w:1)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn accept_curator() -> Weight {
// Proof Size summary in bytes:
// Measured: `494`
// Estimated: `3642`
// Minimum execution time: 125_617_000 picoseconds.
Weight::from_parts(127_448_000, 0)
.saturating_add(Weight::from_parts(0, 3642))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(2))
}
/// Storage: `Bounties::Bounties` (r:1 w:1)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0)
/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
fn award_bounty() -> Weight {
// Proof Size summary in bytes:
// Measured: `401`
// Estimated: `3642`
// Minimum execution time: 65_865_000 picoseconds.
Weight::from_parts(66_641_000, 0)
.saturating_add(Weight::from_parts(0, 3642))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Bounties::Bounties` (r:1 w:1)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:3 w:3)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1)
/// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
/// Storage: `Bounties::BountyDescriptions` (r:0 w:1)
/// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
fn claim_bounty() -> Weight {
// Proof Size summary in bytes:
// Measured: `713`
// Estimated: `8799`
// Minimum execution time: 516_549_000 picoseconds.
Weight::from_parts(520_792_000, 0)
.saturating_add(Weight::from_parts(0, 8799))
.saturating_add(T::DbWeight::get().reads(5))
.saturating_add(T::DbWeight::get().writes(6))
}
/// Storage: `Bounties::Bounties` (r:1 w:1)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0)
/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Bounties::BountyDescriptions` (r:0 w:1)
/// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
fn close_bounty_proposed() -> Weight {
// Proof Size summary in bytes:
// Measured: `445`
// Estimated: `3642`
// Minimum execution time: 185_684_000 picoseconds.
Weight::from_parts(187_810_000, 0)
.saturating_add(Weight::from_parts(0, 3642))
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(3))
}
/// Storage: `Bounties::Bounties` (r:1 w:1)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:0)
/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:2 w:2)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Bounties::BountyDescriptions` (r:0 w:1)
/// Proof: `Bounties::BountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
fn close_bounty_active() -> Weight {
// Proof Size summary in bytes:
// Measured: `681`
// Estimated: `6196`
// Minimum execution time: 342_424_000 picoseconds.
Weight::from_parts(349_225_000, 0)
.saturating_add(Weight::from_parts(0, 6196))
.saturating_add(T::DbWeight::get().reads(4))
.saturating_add(T::DbWeight::get().writes(4))
}
/// Storage: `Bounties::Bounties` (r:1 w:1)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
fn extend_bounty_expiry() -> Weight {
// Proof Size summary in bytes:
// Measured: `358`
// Estimated: `3642`
// Minimum execution time: 52_301_000 picoseconds.
Weight::from_parts(53_018_000, 0)
.saturating_add(Weight::from_parts(0, 3642))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Bounties::BountyApprovals` (r:1 w:1)
/// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
/// Storage: `Bounties::Bounties` (r:100 w:100)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:200 w:200)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// The range of component `b` is `[0, 100]`.
fn spend_funds(b: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `0 + b * (297 ±0)`
// Estimated: `5487 + b * (5206 ±0)`
// Minimum execution time: 14_296_000 picoseconds.
Weight::from_parts(14_433_000, 0)
.saturating_add(Weight::from_parts(0, 5487))
// Standard Error: 25_068
.saturating_add(Weight::from_parts(160_411_223, 0).saturating_mul(b.into()))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(b.into())))
.saturating_add(T::DbWeight::get().writes(1))
.saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(b.into())))
.saturating_add(Weight::from_parts(0, 5206).saturating_mul(b.into()))
}
}

View File

@ -0,0 +1,198 @@
// This file is part of Ghost Network.
// Ghost Network is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Ghost Network is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Ghost Network. If not, see <http://www.gnu.org/licenses/>.
//! Autogenerated weights for `pallet_child_bounties`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2026-02-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
// Executed Command:
// ./target/release/ghost
// benchmark
// pallet
// --chain=casper-dev
// --steps=50
// --repeat=20
// --pallet=pallet_child_bounties
// --extrinsic=*
// --wasm-execution=compiled
// --heap-pages=4096
// --header=./file_header.txt
// --output=./runtime/casper/src/weights/pallet_child_bounties.rs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(missing_docs)]
use frame_support::{traits::Get, weights::Weight};
use core::marker::PhantomData;
/// Weight functions for `pallet_child_bounties`.
pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> pallet_child_bounties::WeightInfo for WeightInfo<T> {
/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1)
/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
/// Storage: `Bounties::Bounties` (r:1 w:0)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:2 w:2)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildBountyCount` (r:1 w:1)
/// Proof: `ChildBounties::ChildBountyCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1)
/// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildBounties` (r:0 w:1)
/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
/// The range of component `d` is `[0, 16384]`.
fn add_child_bounty(d: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `541`
// Estimated: `6196`
// Minimum execution time: 291_192_000 picoseconds.
Weight::from_parts(296_557_773, 0)
.saturating_add(Weight::from_parts(0, 6196))
// Standard Error: 42
.saturating_add(Weight::from_parts(2_090, 0).saturating_mul(d.into()))
.saturating_add(T::DbWeight::get().reads(5))
.saturating_add(T::DbWeight::get().writes(6))
}
/// Storage: `Bounties::Bounties` (r:1 w:0)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1)
/// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
fn propose_curator() -> Weight {
// Proof Size summary in bytes:
// Measured: `595`
// Estimated: `3642`
// Minimum execution time: 69_659_000 picoseconds.
Weight::from_parts(70_289_000, 0)
.saturating_add(Weight::from_parts(0, 3642))
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(2))
}
/// Storage: `Bounties::Bounties` (r:1 w:0)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn accept_curator() -> Weight {
// Proof Size summary in bytes:
// Measured: `741`
// Estimated: `3642`
// Minimum execution time: 135_004_000 picoseconds.
Weight::from_parts(135_738_000, 0)
.saturating_add(Weight::from_parts(0, 3642))
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(2))
}
/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
/// Storage: `Bounties::Bounties` (r:1 w:0)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn unassign_curator() -> Weight {
// Proof Size summary in bytes:
// Measured: `741`
// Estimated: `3642`
// Minimum execution time: 184_496_000 picoseconds.
Weight::from_parts(186_401_000, 0)
.saturating_add(Weight::from_parts(0, 3642))
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(2))
}
/// Storage: `Bounties::Bounties` (r:1 w:0)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
fn award_child_bounty() -> Weight {
// Proof Size summary in bytes:
// Measured: `638`
// Estimated: `3642`
// Minimum execution time: 72_603_000 picoseconds.
Weight::from_parts(73_411_000, 0)
.saturating_add(Weight::from_parts(0, 3642))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:3 w:3)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1)
/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1)
/// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
fn claim_child_bounty() -> Weight {
// Proof Size summary in bytes:
// Measured: `525`
// Estimated: `8799`
// Minimum execution time: 515_024_000 picoseconds.
Weight::from_parts(527_108_000, 0)
.saturating_add(Weight::from_parts(0, 8799))
.saturating_add(T::DbWeight::get().reads(5))
.saturating_add(T::DbWeight::get().writes(6))
}
/// Storage: `Bounties::Bounties` (r:1 w:0)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1)
/// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1)
/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:2 w:2)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1)
/// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
fn close_child_bounty_added() -> Weight {
// Proof Size summary in bytes:
// Measured: `841`
// Estimated: `6196`
// Minimum execution time: 330_763_000 picoseconds.
Weight::from_parts(334_197_000, 0)
.saturating_add(Weight::from_parts(0, 6196))
.saturating_add(T::DbWeight::get().reads(6))
.saturating_add(T::DbWeight::get().writes(6))
}
/// Storage: `Bounties::Bounties` (r:1 w:0)
/// Proof: `Bounties::Bounties` (`max_values`: None, `max_size`: Some(177), added: 2652, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildBounties` (r:1 w:1)
/// Proof: `ChildBounties::ChildBounties` (`max_values`: None, `max_size`: Some(145), added: 2620, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:3 w:3)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildrenCuratorFees` (r:1 w:1)
/// Proof: `ChildBounties::ChildrenCuratorFees` (`max_values`: None, `max_size`: Some(28), added: 2503, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ParentChildBounties` (r:1 w:1)
/// Proof: `ChildBounties::ParentChildBounties` (`max_values`: None, `max_size`: Some(16), added: 2491, mode: `MaxEncodedLen`)
/// Storage: `ChildBounties::ChildBountyDescriptions` (r:0 w:1)
/// Proof: `ChildBounties::ChildBountyDescriptions` (`max_values`: None, `max_size`: Some(16400), added: 18875, mode: `MaxEncodedLen`)
fn close_child_bounty_active() -> Weight {
// Proof Size summary in bytes:
// Measured: `1028`
// Estimated: `8799`
// Minimum execution time: 405_094_000 picoseconds.
Weight::from_parts(416_868_000, 0)
.saturating_add(Weight::from_parts(0, 8799))
.saturating_add(T::DbWeight::get().reads(7))
.saturating_add(T::DbWeight::get().writes(7))
}
}

View File

@ -16,7 +16,7 @@
//! Autogenerated weights for `pallet_grandpa`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-11-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2026-02-27, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
@ -40,20 +40,51 @@
#![allow(unused_imports)]
#![allow(missing_docs)]
use frame_support::{traits::Get, weights::Weight};
use core::marker::PhantomData;
use frame_support::{
traits::Get,
weights::{
constants::{RocksDbWeight as DbWeight, WEIGHT_REF_TIME_PER_MICROS, WEIGHT_REF_TIME_PER_NANOS},
Weight,
},
};
/// Weight functions for `pallet_grandpa`.
pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> pallet_grandpa::WeightInfo for WeightInfo<T> {
/// The range of component `x` is `[0, 1]`.
fn check_equivocation_proof(_x: u32, ) -> Weight {
fn report_equivocation(validator_count: u32, max_nominators_per_validator: u32) -> Weight {
// we take the validator set count from the membership proof to
// calculate the weight but we set a floor of 100 validators.
let validator_count = validator_count.max(100) as u64;
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 271_935_000 picoseconds.
Weight::from_parts(273_848_983, 0)
// Minimum execution time: 272_018_000 picoseconds.
let check_equivocation_proof = Weight::from_parts(275_944_195, 0)
.saturating_add(Weight::from_parts(0, 0))
// Standard Error: 1_232_802
.saturating_add(Weight::from_parts(1_472_404, 0).saturating_mul(validator_count.into()));
// checking membership proof
Weight::from_parts(88u64 * WEIGHT_REF_TIME_PER_MICROS, 0)
.saturating_add(
Weight::from_parts(438u64 * WEIGHT_REF_TIME_PER_NANOS, 0)
.saturating_mul(validator_count),
)
.saturating_add(DbWeight::get().reads(5))
// check equivocation proof
.saturating_add(check_equivocation_proof)
// report offence
.saturating_add(check_equivocation_proof)
.saturating_add(Weight::from_parts(
63u64 * WEIGHT_REF_TIME_PER_MICROS * max_nominators_per_validator as u64,
0,
))
.saturating_add(DbWeight::get().reads(14 + 3 * max_nominators_per_validator as u64))
.saturating_add(DbWeight::get().writes(10 + 3 * max_nominators_per_validator as u64))
// fetching set id -> session index mappings
.saturating_add(DbWeight::get().reads(2))
}
/// Storage: `Grandpa::Stalled` (r:0 w:1)
/// Proof: `Grandpa::Stalled` (`max_values`: Some(1), `max_size`: Some(8), added: 503, mode: `MaxEncodedLen`)
@ -61,8 +92,8 @@ impl<T: frame_system::Config> pallet_grandpa::WeightInfo for WeightInfo<T> {
// Proof Size summary in bytes:
// Measured: `0`
// Estimated: `0`
// Minimum execution time: 11_027_000 picoseconds.
Weight::from_parts(11_341_000, 0)
// Minimum execution time: 12_930_000 picoseconds.
Weight::from_parts(13_281_000, 0)
.saturating_add(Weight::from_parts(0, 0))
.saturating_add(T::DbWeight::get().writes(1))
}

View File

@ -16,7 +16,7 @@
//! Autogenerated weights for `pallet_treasury`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2024-08-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2026-02-28, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
@ -29,7 +29,7 @@
// --steps=50
// --repeat=20
// --pallet=pallet_treasury
// --extrinsic=void_spend
// --extrinsic=*
// --wasm-execution=compiled
// --heap-pages=4096
// --header=./file_header.txt
@ -46,14 +46,151 @@ use core::marker::PhantomData;
/// Weight functions for `pallet_treasury`.
pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> pallet_treasury::WeightInfo for WeightInfo<T> {
/// Storage: `Treasury::ProposalCount` (r:1 w:1)
/// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Treasury::Approvals` (r:1 w:1)
/// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
/// Storage: `Treasury::Proposals` (r:0 w:1)
/// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`)
fn spend_local() -> Weight {
// Proof Size summary in bytes:
// Measured: `6`
// Estimated: `5487`
// Minimum execution time: 52_840_000 picoseconds.
Weight::from_parts(54_220_000, 0)
.saturating_add(Weight::from_parts(0, 5487))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(3))
}
/// Storage: `Treasury::ProposalCount` (r:1 w:1)
/// Proof: `Treasury::ProposalCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Treasury::Proposals` (r:0 w:1)
/// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`)
fn propose_spend() -> Weight {
// Proof Size summary in bytes:
// Measured: `107`
// Estimated: `1489`
// Minimum execution time: 119_927_000 picoseconds.
Weight::from_parts(120_611_000, 0)
.saturating_add(Weight::from_parts(0, 1489))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(2))
}
/// Storage: `Treasury::Proposals` (r:1 w:1)
/// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn reject_proposal() -> Weight {
// Proof Size summary in bytes:
// Measured: `265`
// Estimated: `3593`
// Minimum execution time: 164_605_000 picoseconds.
Weight::from_parts(165_648_000, 0)
.saturating_add(Weight::from_parts(0, 3593))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(2))
}
/// Storage: `Treasury::Proposals` (r:1 w:0)
/// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`)
/// Storage: `Treasury::Approvals` (r:1 w:1)
/// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
/// The range of component `p` is `[0, 999]`.
fn approve_proposal(p: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `800 + p * (4 ±0)`
// Estimated: `5487`
// Minimum execution time: 38_600_000 picoseconds.
Weight::from_parts(54_379_372, 0)
.saturating_add(Weight::from_parts(0, 5487))
// Standard Error: 669
.saturating_add(Weight::from_parts(34_439, 0).saturating_mul(p.into()))
.saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Treasury::Approvals` (r:1 w:1)
/// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
fn remove_approval() -> Weight {
// Proof Size summary in bytes:
// Measured: `90`
// Estimated: `5487`
// Minimum execution time: 28_269_000 picoseconds.
Weight::from_parts(28_811_000, 0)
.saturating_add(Weight::from_parts(0, 5487))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Treasury::Deactivated` (r:1 w:1)
/// Proof: `Treasury::Deactivated` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `Treasury::Approvals` (r:1 w:1)
/// Proof: `Treasury::Approvals` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
/// Storage: `Treasury::Proposals` (r:998 w:998)
/// Proof: `Treasury::Proposals` (`max_values`: None, `max_size`: Some(108), added: 2583, mode: `MaxEncodedLen`)
/// Storage: `System::Account` (r:1996 w:1996)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `Bounties::BountyApprovals` (r:1 w:1)
/// Proof: `Bounties::BountyApprovals` (`max_values`: Some(1), `max_size`: Some(4002), added: 4497, mode: `MaxEncodedLen`)
/// The range of component `p` is `[0, 999]`.
fn on_initialize_proposals(p: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `0 + p * (255 ±0)`
// Estimated: `5487 + p * (5206 ±0)`
// Minimum execution time: 93_001_000 picoseconds.
Weight::from_parts(93_875_000, 0)
.saturating_add(Weight::from_parts(0, 5487))
// Standard Error: 106_483
.saturating_add(Weight::from_parts(173_774_586, 0).saturating_mul(p.into()))
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().reads((3_u64).saturating_mul(p.into())))
.saturating_add(T::DbWeight::get().writes(3))
.saturating_add(T::DbWeight::get().writes((3_u64).saturating_mul(p.into())))
.saturating_add(Weight::from_parts(0, 5206).saturating_mul(p.into()))
}
/// Storage: `Treasury::SpendCount` (r:1 w:1)
/// Proof: `Treasury::SpendCount` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `Treasury::Spends` (r:0 w:1)
/// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
fn spend() -> Weight {
// Proof Size summary in bytes:
// Measured: `6`
// Estimated: `1489`
// Minimum execution time: 47_856_000 picoseconds.
Weight::from_parts(49_457_000, 0)
.saturating_add(Weight::from_parts(0, 1489))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(2))
}
/// Storage: `Treasury::Spends` (r:1 w:1)
/// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
fn payout() -> Weight {
// Proof Size summary in bytes:
// Measured: `124`
// Estimated: `3534`
// Minimum execution time: 54_017_000 picoseconds.
Weight::from_parts(54_712_000, 0)
.saturating_add(Weight::from_parts(0, 3534))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Treasury::Spends` (r:1 w:1)
/// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
fn check_status() -> Weight {
// Proof Size summary in bytes:
// Measured: `124`
// Estimated: `3534`
// Minimum execution time: 53_415_000 picoseconds.
Weight::from_parts(57_185_000, 0)
.saturating_add(Weight::from_parts(0, 3534))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `Treasury::Spends` (r:1 w:1)
/// Proof: `Treasury::Spends` (`max_values`: None, `max_size`: Some(69), added: 2544, mode: `MaxEncodedLen`)
fn void_spend() -> Weight {
// Proof Size summary in bytes:
// Measured: `124`
// Estimated: `3534`
// Minimum execution time: 77_449_000 picoseconds.
Weight::from_parts(88_782_000, 0)
// Minimum execution time: 50_317_000 picoseconds.
Weight::from_parts(51_617_000, 0)
.saturating_add(Weight::from_parts(0, 3534))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))

View File

@ -211,10 +211,12 @@ fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>, u128)> {
avg_block_speed: 12_000,
network_type: ghost_networks::NetworkType::Evm,
gatekeeper: "0xc85129A097773B7F8970a7364c928C05f265E6A1".into(),
topic_name: "0x7ab52ec05c331e6257a3d705d6bea6e4c27277351764ad139209e06b203811a6".into(),
topic_name: "0x7ab52ec05c331e6257a3d705d6bea6e4c27277351764ad139209e06b203811a6"
.into(),
incoming_fee: 69_000_000u32,
outgoing_fee: 0u32,
}.encode(),
}
.encode(),
2048861035254140036511u128,
),
(
@ -232,10 +234,12 @@ fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>, u128)> {
avg_block_speed: 13_000,
network_type: ghost_networks::NetworkType::Evm,
gatekeeper: "0xA59cB4ff90bE2206121aE61eEB68d0AeC7BA095f".into(),
topic_name: "0x7ab52ec05c331e6257a3d705d6bea6e4c27277351764ad139209e06b203811a6".into(),
topic_name: "0x7ab52ec05c331e6257a3d705d6bea6e4c27277351764ad139209e06b203811a6"
.into(),
incoming_fee: 69_000_000u32,
outgoing_fee: 0u32,
}.encode(),
}
.encode(),
5100000000000000000u128,
),
]