Compare commits

...

24 Commits

Author SHA1 Message Date
573e57dfb4
new tests based on new ghost-network functinality
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2025-06-03 20:41:51 +03:00
46d4716f67
merge extended ghost-networks with ability to nullify accumulated commission
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2025-06-03 19:48:23 +03:00
9cb7f3c782
replacing the average claps in session with median to determine a harmful authority
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2025-06-03 19:38:07 +03:00
c55d9a05d9
auto nullification during finalization and appropriate tests
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-06-03 19:06:50 +03:00
5847097e94
extend network inspect handler trait with additional function
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-06-03 18:58:21 +03:00
04a63e234d
tests updated and small tweaks of the lib
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2025-06-02 19:20:14 +03:00
2b738c009b
merge latest ghost-network version
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2025-06-02 19:17:16 +03:00
f3d8ee3ab2
make bridge imbalance fields accesible aka public
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-06-02 19:11:11 +03:00
2da07d7b24
chmod 644 Cargo.toml for ghost-slow-claps
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-31 14:55:30 +03:00
9ba25d6b3d
friendly merge for ghost-claims weights
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2025-05-31 14:51:53 +03:00
3234341fed
use benchmarked weights as a default weights for ghost-claims pallet
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-31 14:48:08 +03:00
fa2cb811a8
update for slow-claps: remove companions, updgrade block range storage, new way of commission accumulation
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2025-05-31 14:30:15 +03:00
561d4430b4
another indention fix in main Cargo.toml
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-31 14:21:21 +03:00
b64700fb42
fix indentation in TOML files
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-31 13:12:48 +03:00
b3f85f426c
extend pallet ghost-networks and create BridgedInflationCurve
Signed-off-by: Uncle Stinky <uncle.stinky@ghostchain.io>
2025-05-30 19:03:50 +03:00
ddec108ced
chmod 644 files in runtime
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-29 13:09:54 +03:00
cd8ad50ac3
chmod 644 utils
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-29 13:04:55 +03:00
e09ce03836
chmod 644 tests
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-29 13:01:30 +03:00
9f6f4953f7
chmod 644 service
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-29 12:59:25 +03:00
40aba0e3af
chmod 644 files in rpc
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-29 12:58:09 +03:00
596d9a6ca7
chmod 644 files in core-primitives
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-29 12:57:26 +03:00
39279697f2
chmod 644 files in cli
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-29 12:56:11 +03:00
d3a18e298a
chmod 644 files in project root
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-29 12:54:26 +03:00
aede9e6e2e
change access permissions of files in pallets folder
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
2025-05-29 12:52:37 +03:00
68 changed files with 1721 additions and 1551 deletions

12
Cargo.lock generated
View File

@ -3504,7 +3504,7 @@ dependencies = [
[[package]]
name = "ghost-claims"
version = "0.2.2"
version = "0.2.3"
dependencies = [
"frame-benchmarking",
"frame-support",
@ -3648,7 +3648,7 @@ dependencies = [
[[package]]
name = "ghost-networks"
version = "0.7.197"
version = "0.1.4"
dependencies = [
"frame-benchmarking",
"frame-support",
@ -3656,6 +3656,8 @@ dependencies = [
"ghost-core-primitives",
"ghost-traits",
"pallet-balances",
"pallet-staking",
"pallet-staking-reward-curve",
"parity-scale-codec",
"scale-info",
"sp-io 30.0.0",
@ -3832,7 +3834,7 @@ dependencies = [
[[package]]
name = "ghost-slow-clap"
version = "0.3.15"
version = "0.3.19"
dependencies = [
"frame-benchmarking",
"frame-support",
@ -3841,6 +3843,8 @@ dependencies = [
"log",
"pallet-balances",
"pallet-session",
"pallet-staking",
"pallet-staking-reward-curve",
"parity-scale-codec",
"scale-info",
"serde",
@ -3866,7 +3870,7 @@ dependencies = [
[[package]]
name = "ghost-traits"
version = "0.3.19"
version = "0.3.20"
dependencies = [
"frame-support",
"sp-runtime 31.0.1",

View File

@ -258,24 +258,24 @@ substrate-build-script-utils = { workspace = true }
resolver = "2"
members = [
"core-primitives",
"core-primitives",
"cli",
"rpc",
"service",
"rpc",
"service",
"metrics",
"client/cli",
"primitives/machine",
"runtime/common",
"runtime/casper",
"runtime/casper/constants",
"pallets/networks",
"pallets/claims",
"pallets/slow-clap",
"utils/bags-list",
"utils/chain-spec-builder",
"utils/generate-bags",
"runtime/common",
"runtime/casper",
"runtime/casper/constants",
"pallets/networks",
"pallets/claims",
"pallets/slow-clap",
"utils/bags-list",
"utils/chain-spec-builder",
"utils/generate-bags",
"utils/ghostkey",
"utils/staking-miner",
"utils/staking-miner",
]
[badges]

0
LICENSE.md Executable file → Normal file
View File

0
README.md Executable file → Normal file
View File

14
cli/Cargo.toml Executable file → Normal file
View File

@ -52,14 +52,14 @@ substrate-build-script-utils = { workspace = true }
default = ["cli", "db", "full-node"]
db = ["service/db"]
cli = [
"clap",
"clap",
"frame-benchmarking-cli",
"sc-cli",
"sc-service",
"sc-tracing",
"service",
"ghost-client-cli",
"ghost-machine-primitives",
"sc-cli",
"sc-service",
"sc-tracing",
"service",
"ghost-client-cli",
"ghost-machine-primitives",
]
runtime-benchmarks = [
"frame-benchmarking-cli?/runtime-benchmarks",

0
cli/build.rs Executable file → Normal file
View File

0
cli/src/cli.rs Executable file → Normal file
View File

0
cli/src/command.rs Executable file → Normal file
View File

0
cli/src/error.rs Executable file → Normal file
View File

0
cli/src/lib.rs Executable file → Normal file
View File

6
core-primitives/Cargo.toml Executable file → Normal file
View File

@ -15,7 +15,7 @@ sp-runtime = { workspace = true }
[features]
default = ["std"]
std = [
"sp-core/std",
"sp-runtime/std",
"sp-std/std",
"sp-core/std",
"sp-runtime/std",
"sp-std/std",
]

0
core-primitives/src/lib.rs Executable file → Normal file
View File

0
file_header.txt Executable file → Normal file
View File

View File

@ -1,6 +1,6 @@
[package]
name = "ghost-claims"
version = "0.2.2"
version = "0.2.3"
description = "Ghost balance and rank claims based on EVM actions"
license.workspace = true
authors.workspace = true
@ -37,17 +37,17 @@ serde_json = { workspace = true, default-features = true }
[features]
default = ["std"]
std = [
"frame-benchmarking?/std",
"frame-benchmarking?/std",
"serde/std",
"codec/std",
"codec/std",
"scale-info/std",
"libsecp256k1/std",
"frame-support/std",
"frame-system/std",
"sp-core/std",
"sp-runtime/std",
"sp-io/std",
"sp-std/std",
"libsecp256k1/std",
"frame-support/std",
"frame-system/std",
"sp-core/std",
"sp-runtime/std",
"sp-io/std",
"sp-std/std",
"pallet-ranked-collective/std",
"pallet-vesting/std",
"pallet-balances/std",
@ -56,19 +56,19 @@ std = [
runtime-benchmarks = [
"libsecp256k1/hmac",
"libsecp256k1/static-context",
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-ranked-collective/runtime-benchmarks",
"pallet-vesting/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-ranked-collective/runtime-benchmarks",
"pallet-vesting/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"pallet-ranked-collective/try-runtime",
"pallet-vesting/try-runtime",
"pallet-balances/try-runtime",
"sp-runtime/try-runtime",
"frame-support/try-runtime",
"frame-system/try-runtime",
"pallet-ranked-collective/try-runtime",
"pallet-vesting/try-runtime",
"pallet-balances/try-runtime",
"sp-runtime/try-runtime",
]

View File

@ -20,8 +20,9 @@ extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::{format, string::String};
pub mod weights;
mod weights;
pub use crate::weights::WeightInfo;
mod tests;
mod mock;
mod benchmarking;

View File

@ -1,9 +1,104 @@
use frame_support::weights::Weight;
// 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 `ghost_claims`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2024-08-02, 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=ghost_claims
// --extrinsic=*
// --wasm-execution=compiled
// --heap-pages=4096
// --header=./file_header.txt
// --output=./runtime/casper/src/weights/ghost_claims.rs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(missing_docs)]
use frame_support::{
traits::Get,
weights::{Weight, constants::RocksDbWeight},
};
use core::marker::PhantomData;
/// Weight functions needed for `ghost_claims`.
pub trait WeightInfo {
fn claim() -> Weight;
fn claim() -> Weight;
}
/// Weight for ghost_claims using the Substrate node and recommended hardware.
pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
/// Storage: `System::Account` (r:2 w:2)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `GhostClaims::Total` (r:1 w:1)
/// Proof: `GhostClaims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `CultCollective::Members` (r:2 w:2)
/// Proof: `CultCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`)
/// Storage: `CultCollective::MemberCount` (r:6 w:6)
/// Proof: `CultCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
/// Storage: `CultCollective::IdToIndex` (r:6 w:12)
/// Proof: `CultCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`)
/// Storage: `CultCollective::IndexToId` (r:0 w:6)
/// Proof: `CultCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`)
fn claim() -> Weight {
// Proof Size summary in bytes:
// Measured: `896`
// Estimated: `16164`
// Minimum execution time: 754_086_000 picoseconds.
Weight::from_parts(756_147_000, 0)
.saturating_add(Weight::from_parts(0, 16164))
.saturating_add(T::DbWeight::get().reads(17))
.saturating_add(T::DbWeight::get().writes(29))
}
}
impl WeightInfo for () {
fn claim() -> Weight { Weight::zero() }
/// Storage: `System::Account` (r:2 w:2)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
/// Storage: `GhostClaims::Total` (r:1 w:1)
/// Proof: `GhostClaims::Total` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `CultCollective::Members` (r:2 w:2)
/// Proof: `CultCollective::Members` (`max_values`: None, `max_size`: Some(42), added: 2517, mode: `MaxEncodedLen`)
/// Storage: `CultCollective::MemberCount` (r:6 w:6)
/// Proof: `CultCollective::MemberCount` (`max_values`: None, `max_size`: Some(14), added: 2489, mode: `MaxEncodedLen`)
/// Storage: `CultCollective::IdToIndex` (r:6 w:12)
/// Proof: `CultCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`)
/// Storage: `CultCollective::IndexToId` (r:0 w:6)
/// Proof: `CultCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`)
fn claim() -> Weight {
// Proof Size summary in bytes:
// Measured: `896`
// Estimated: `16164`
// Minimum execution time: 754_086_000 picoseconds.
Weight::from_parts(756_147_000, 0)
.saturating_add(Weight::from_parts(0, 16164))
.saturating_add(RocksDbWeight::get().reads(17))
.saturating_add(RocksDbWeight::get().writes(29))
}
}

42
pallets/networks/Cargo.toml Executable file → Normal file
View File

@ -1,8 +1,8 @@
[package]
name = "ghost-networks"
version = "0.1.4"
license.workspace = true
authors.workspace = true
version.workspace = true
edition.workspace = true
homepage.workspace = true
repository.workspace = true
@ -14,36 +14,42 @@ codec = { workspace = true, features = ["max-encoded-len"] }
frame-benchmarking = { workspace = true, optional = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
pallet-staking = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
ghost-traits = { workspace = true }
[dev-dependencies]
primitives = { workspace = true }
pallet-balances = { workspace = true }
sp-io = { workspace = true }
pallet-balances = { workspace = true }
pallet-staking-reward-curve = { workspace = true }
[features]
default = ["std"]
std = [
"scale-info/std",
"codec/std",
"frame-support/std",
"frame-system/std",
"frame-benchmarking?/std",
"sp-runtime/std",
"sp-std/std",
"sp-io/std",
"ghost-traits/std",
"pallet-balances/std",
"scale-info/std",
"codec/std",
"frame-support/std",
"frame-system/std",
"frame-benchmarking?/std",
"sp-runtime/std",
"sp-std/std",
"sp-io/std",
"ghost-traits/std",
"pallet-staking/std",
"pallet-balances/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"pallet-staking/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"frame-support/try-runtime",
"frame-system/try-runtime",
"pallet-staking/try-runtime",
"pallet-balances/try-runtime",
]

0
pallets/networks/src/benchmarking.rs Executable file → Normal file
View File

172
pallets/networks/src/lib.rs Executable file → Normal file
View File

@ -4,15 +4,17 @@
use frame_support::{
pallet_prelude::*,
storage::PrefixIterator, traits::EnsureOrigin,
storage::PrefixIterator, traits::{tokens::fungible::Inspect, EnsureOrigin},
};
use frame_system::pallet_prelude::*;
use scale_info::TypeInfo;
use sp_runtime::{
traits::{AtLeast32BitUnsigned, Member},
traits::{CheckedSub, CheckedAdd, AtLeast32BitUnsigned, Member},
curve::PiecewiseLinear,
DispatchResult,
};
use sp_std::prelude::*;
use sp_std::{prelude::*, convert::TryInto};
pub use ghost_traits::networks::{
NetworkDataBasicHandler, NetworkDataInspectHandler,
@ -31,6 +33,10 @@ mod mock;
#[cfg(all(feature = "std", test))]
mod tests;
pub type BalanceOf<T> = <<T as Config>::Currency as Inspect<
<T as frame_system::Config>::AccountId,
>>::Balance;
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
pub enum NetworkType {
Evm = 0,
@ -55,6 +61,50 @@ pub struct NetworkData {
pub outgoing_fee: u32,
}
#[derive(Default, Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
pub struct BridgeAdjustment<Balance> {
pub bridged_out: Balance,
pub bridged_in: Balance,
}
pub struct BridgedInflationCurve<RewardCurve, T>(core::marker::PhantomData<(RewardCurve, T)>);
impl<Balance, RewardCurve, T> pallet_staking::EraPayout<Balance> for BridgedInflationCurve<RewardCurve, T>
where
Balance: Default + AtLeast32BitUnsigned + Clone + Copy + From<u128>,
RewardCurve: Get<&'static PiecewiseLinear<'static>>,
T: Config,
{
fn era_payout(
total_staked: Balance,
total_issuance: Balance,
_era_duration_in_millis: u64,
) -> (Balance, Balance) {
let piecewise_linear = RewardCurve::get();
let bridge_adjustment = BridgedImbalance::<T>::get();
let accumulated_commission = AccumulatedCommission::<T>::get();
let bridged_out: u128 = bridge_adjustment.bridged_out.try_into().unwrap_or_default();
let bridged_in: u128 = bridge_adjustment.bridged_in.try_into().unwrap_or_default();
let accumulated_commission: u128 = accumulated_commission.try_into().unwrap_or_default();
let accumulated_balance = Balance::from(accumulated_commission);
let adjusted_issuance = match bridged_out > bridged_in {
true => total_issuance.saturating_add(Balance::from(bridged_out - bridged_in)),
false => total_issuance.saturating_sub(Balance::from(bridged_in - bridged_out)),
};
NullifyNeeded::<T>::set(true);
match piecewise_linear
.calculate_for_fraction_times_denominator(total_staked, adjusted_issuance)
.checked_mul(&accumulated_balance)
.and_then(|product| product.checked_div(&adjusted_issuance)) {
Some(payout) => (payout, accumulated_balance.saturating_sub(payout)),
None => (Balance::default(), Balance::default()),
}
}
}
#[frame_support::pallet]
pub mod module {
use super::*;
@ -63,6 +113,9 @@ pub mod module {
pub trait Config: frame_system::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
/// The type used for the internal balance storage.
type Currency: Inspect<Self::AccountId>;
/// The type used as a unique network id.
type NetworkId: Parameter
+ Member
@ -114,11 +167,35 @@ pub mod module {
NetworkRemoved { chain_id: T::NetworkId },
}
#[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> =
StorageValue<_, BridgeAdjustment<BalanceOf<T>>, ValueQuery>;
#[pallet::storage]
#[pallet::getter(fn accumulated_commission)]
pub type AccumulatedCommission<T: Config> =
StorageValue<_, BalanceOf<T>, ValueQuery>;
#[pallet::storage]
#[pallet::getter(fn networks)]
pub type Networks<T: Config> =
StorageMap<_, Twox64Concat, T::NetworkId, NetworkData, OptionQuery>;
#[pallet::storage]
#[pallet::getter(fn gatekeeper_amount)]
pub type GatekeeperAmount<T: Config> = StorageMap<
_,
Twox64Concat,
T::NetworkId,
BalanceOf<T>,
ValueQuery,
>;
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
pub networks: Vec<(T::NetworkId, Vec<u8>)>,
@ -150,7 +227,18 @@ pub mod module {
pub struct Pallet<T>(PhantomData<T>);
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
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> {
@ -525,9 +613,13 @@ impl<T: Config> NetworkDataInspectHandler<NetworkData> for Pallet<T> {
fn iter() -> PrefixIterator<(Self::NetworkId, NetworkData)> {
Networks::<T>::iter()
}
fn is_nullification_period() -> bool {
NullifyNeeded::<T>::get()
}
}
impl<T: Config> NetworkDataMutateHandler<NetworkData> for Pallet<T> {
impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T> {
fn register(chain_id: Self::NetworkId, network: NetworkData) -> DispatchResult {
Self::do_register_network(chain_id, network)
}
@ -535,4 +627,74 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData> for Pallet<T> {
fn remove(chain_id: Self::NetworkId) -> DispatchResult {
Self::do_remove_network(chain_id)
}
fn increase_gatekeeper_amount(
network_id: &T::NetworkId,
amount: &BalanceOf<T>,
) -> Result<(BalanceOf<T>, BalanceOf<T>), ()> {
let new_bridged_in_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
match bridged_imbalance.bridged_in.checked_add(amount) {
Some(value) => {
(*bridged_imbalance).bridged_in = value;
Ok(value)
},
None => Err(())
}
})?;
let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
match gatekeeper_amount.checked_add(amount) {
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
},
None => Err(())
}
})?;
Ok((new_gatekeeper_amount, new_bridged_in_amount))
}
fn decrease_gatekeeper_amount(
network_id: &T::NetworkId,
amount: &BalanceOf<T>,
) -> Result<(BalanceOf<T>, BalanceOf<T>), ()> {
let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
match gatekeeper_amount.checked_sub(amount) {
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
},
None => Err(())
}
})?;
let new_bridged_out_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
match bridged_imbalance.bridged_out.checked_add(amount) {
Some(value) => {
(*bridged_imbalance).bridged_out = value;
Ok(value)
},
None => Err(())
}
})?;
Ok((new_gatekeeper_amount, new_bridged_out_amount))
}
fn accumulate_commission(commission: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
AccumulatedCommission::<T>::mutate(|accumulated| {
match accumulated.checked_add(commission) {
Some(value) => {
*accumulated = value;
Ok(value)
},
None => Err(()),
}
})
}
fn nullify_commission() {
AccumulatedCommission::<T>::set(Default::default());
}
}

32
pallets/networks/src/mock.rs Executable file → Normal file
View File

@ -1,19 +1,25 @@
use crate as ghost_networks;
use crate::{self as ghost_networks};
use frame_system::EnsureSignedBy;
use frame_support::{
construct_runtime, ord_parameter_types, parameter_types, traits::{ConstU128, ConstU32, Everything}
construct_runtime, ord_parameter_types, parameter_types,
traits::{ConstU128, ConstU32, Everything},
};
pub use primitives::{
AccountId, Balance, Nonce, BlockNumber, Hash,
ReserveIdentifier, FreezeIdentifier,
};
use sp_runtime::{
traits::{BlakeTwo256, AccountIdLookup},
BuildStorage,
curve::PiecewiseLinear,
traits::{AccountIdLookup, BlakeTwo256},
BuildStorage
};
parameter_types! {
pub const BlockHashCount: BlockNumber = 250;
pub static SlashDeferDuration: u32 = 0;
pub static Period: BlockNumber = 5;
pub static Offset: BlockNumber = 0;
pub static MaxControllersInDeprecationBatch: u32 = 5_000;
}
impl frame_system::Config for Test {
@ -64,6 +70,21 @@ impl pallet_balances::Config for Test {
type MaxFreezes = ConstU32<50>;
}
pallet_staking_reward_curve::build! {
const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
min_inflation: 0_006_900,
max_inflation: 1_000_000,
ideal_stake: 0_690_000,
falloff: 0_050_000,
max_piece_count: 100,
test_precision: 0_005_000,
);
}
parameter_types! {
pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
}
ord_parameter_types! {
pub const RegistererAccount: AccountId = AccountId::from([1u8; 32]);
pub const UpdaterAccount: AccountId = AccountId::from([2u8; 32]);
@ -73,6 +94,7 @@ ord_parameter_types! {
impl ghost_networks::Config for Test {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type NetworkId = u32;
type RegisterOrigin = EnsureSignedBy::<RegistererAccount, AccountId>;
type UpdateOrigin = EnsureSignedBy::<UpdaterAccount, AccountId>;
@ -80,7 +102,7 @@ impl ghost_networks::Config for Test {
type WeightInfo = crate::weights::SubstrateWeight<Test>;
}
type Block = frame_system::mocking::MockBlockU32<Test>;
type Block = frame_system::mocking::MockBlock<Test>;
construct_runtime!(
pub enum Test {

306
pallets/networks/src/tests.rs Executable file → Normal file
View File

@ -1,16 +1,16 @@
use mock::{
ExtBuilder, System, RegistererAccount, UpdaterAccount, RemoverAccount,
RandomAccount, GhostNetworks, Test, RuntimeEvent, RuntimeOrigin,
RandomAccount, GhostNetworks, Test, RuntimeEvent, RuntimeOrigin, RewardCurve,
};
use frame_support::{assert_err, assert_ok};
use sp_runtime::DispatchError;
use pallet_staking::EraPayout;
use super::*;
fn prepare_network_data() -> (u32, NetworkData) {
(1u32, NetworkData {
chain_name: "Ethereum".into(),
default_endpoint:
"https:://some-endpoint.my-server.com/v1/my-super-secret-key".into(),
default_endpoint: "https:://some-endpoint.my-server.com/v1/my-super-secret-key".into(),
finality_delay: Some(69),
release_delay: Some(69),
network_type: NetworkType::Evm,
@ -635,3 +635,303 @@ fn could_not_remove_non_existent_network() {
assert_eq!(Networks::<Test>::get(chain_id), None);
});
}
#[test]
fn bridge_storage_is_empty_by_default() {
ExtBuilder::build()
.execute_with(|| {
assert_eq!(AccumulatedCommission::<Test>::get(), 0);
assert_eq!(BridgedImbalance::<Test>::get(),
BridgeAdjustment::default());
});
}
#[test]
fn gatekeeper_amount_changes_correctly() {
ExtBuilder::build()
.execute_with(|| {
let chain_id: u32 = 1;
let amount_in: u128 = 420;
let amount_out: u128 = 69;
let result = amount_in - 3 * amount_out;
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), 0);
assert_eq!(BridgedImbalance::<Test>::get(),
BridgeAdjustment::default());
assert_ok!(GhostNetworks::increase_gatekeeper_amount(&chain_id, &amount_in));
assert_ok!(GhostNetworks::decrease_gatekeeper_amount(&chain_id, &amount_out));
assert_ok!(GhostNetworks::decrease_gatekeeper_amount(&chain_id, &amount_out));
assert_ok!(GhostNetworks::decrease_gatekeeper_amount(&chain_id, &amount_out));
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), result);
assert_eq!(BridgedImbalance::<Test>::get(), BridgeAdjustment {
bridged_out: 3 * amount_out,
bridged_in: amount_in });
});
}
#[test]
fn commission_accumulation_is_correct() {
ExtBuilder::build()
.execute_with(|| {
let commission_first: u128 = 420;
let commission_second: u128 = 69;
let result = commission_first + commission_second;
assert_eq!(AccumulatedCommission::<Test>::get(), 0);
assert_ok!(GhostNetworks::accumulate_commission(&commission_first));
assert_ok!(GhostNetworks::accumulate_commission(&commission_second));
assert_eq!(AccumulatedCommission::<Test>::get(), result);
});
}
#[test]
fn commission_overflow_and_underflow_emits_error() {
ExtBuilder::build()
.execute_with(|| {
let commission: u128 = u128::MAX - 69;
assert_eq!(AccumulatedCommission::<Test>::get(), 0);
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_err!(GhostNetworks::accumulate_commission(&commission), ());
assert_eq!(AccumulatedCommission::<Test>::get(), commission);
});
}
#[test]
fn gatekeeper_amount_overflow_and_underflow_emits_error() {
ExtBuilder::build()
.execute_with(|| {
let chain_id: u32 = 1;
let commission: u128 = u128::MAX - 69;
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), 0);
assert_ok!(GhostNetworks::increase_gatekeeper_amount(
&chain_id,
&commission,
), (commission, commission));
assert_err!(GhostNetworks::increase_gatekeeper_amount(
&chain_id,
&commission,
), ());
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), commission);
assert_ok!(GhostNetworks::decrease_gatekeeper_amount(
&chain_id,
&commission,
), (0, commission));
assert_err!(GhostNetworks::decrease_gatekeeper_amount(
&chain_id,
&commission,
), ());
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id), 0);
assert_eq!(BridgedImbalance::<Test>::get(), BridgeAdjustment {
bridged_out: commission,
bridged_in: commission,
});
});
}
#[test]
fn bridged_amount_overflow_and_underflow_emits_error() {
ExtBuilder::build()
.execute_with(|| {
let chain_id_first: u32 = 1;
let chain_id_second: u32 = 2;
let commission: u128 = u128::MAX - 69;
assert_eq!(BridgedImbalance::<Test>::get(), BridgeAdjustment {
bridged_out: 0,
bridged_in: 0,
});
assert_ok!(GhostNetworks::increase_gatekeeper_amount(
&chain_id_first,
&commission,
), (commission, commission));
assert_err!(GhostNetworks::increase_gatekeeper_amount(
&chain_id_second,
&commission,
), ());
assert_err!(GhostNetworks::increase_gatekeeper_amount(
&chain_id_first,
&u128::MAX,
), ());
assert_err!(GhostNetworks::increase_gatekeeper_amount(
&chain_id_first,
&commission,
), ());
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id_first), commission);
assert_eq!(GatekeeperAmount::<Test>::get(&chain_id_second), 0);
assert_err!(GhostNetworks::decrease_gatekeeper_amount(
&chain_id_second,
&commission,
), ());
});
}
#[test]
fn accumulated_commission_could_be_nullified() {
ExtBuilder::build()
.execute_with(|| {
let commission_first: u128 = 420;
let commission_second: u128 = 69;
assert_eq!(AccumulatedCommission::<Test>::get(), 0);
assert_ok!(GhostNetworks::accumulate_commission(
&commission_first
), commission_first);
assert_ok!(GhostNetworks::accumulate_commission(
&commission_second,
), commission_first + commission_second);
assert_eq!(AccumulatedCommission::<Test>::get(),
commission_first + commission_second);
GhostNetworks::nullify_commission();
assert_eq!(AccumulatedCommission::<Test>::get(), 0);
});
}
#[test]
fn bridged_inlation_reward_works() {
ExtBuilder::build()
.execute_with(|| {
let chain_id: u32 = 1;
let amount: u128 = 1337 * 1_000_000_000;
let commission: u128 = amount / 100; // 1% commission
let total_staked_ideal: u128 = 69;
let total_staked_not_ideal: u128 = 68;
let total_issuance: u128 = 100;
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000,
total_issuance * 1_000,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000_000_000_000,
total_issuance * 1_000_000_000_000,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000_000_000_000_000_000_000_000,
total_issuance * 1_000_000_000_000_000_000_000_000,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_not_ideal * 1_000,
total_issuance * 1_000,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_not_ideal * 1_000_000_000_000,
total_issuance * 1_000_000_000_000,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_not_ideal * 1_000_000_000_000_000_000_000_000,
total_issuance * 1_000_000_000_000_000_000_000_000,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
1, total_issuance * 1_000, 0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
1, total_issuance * 1_000_000_000_000, 0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
1, total_issuance * 1_000_000_000_000_000_000_000_000, 0), (0, 0));
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::increase_gatekeeper_amount(&chain_id, &amount));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000,
total_issuance * 1_000 + amount,
0), (commission, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000_000_000_000,
total_issuance * 1_000_000_000_000 + amount,
0), (commission, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000_000_000_000_000_000_000_000,
total_issuance * 1_000_000_000_000_000_000_000_000 + amount,
0), (commission, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_not_ideal * 1_000,
total_issuance * 1_000 + amount,
0), (13177472000, 192528000));
assert_eq!(13177472000 + 192528000, commission);
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_not_ideal * 1_000_000_000_000,
total_issuance * 1_000_000_000_000 + amount,
0), (13177568884, 192431116));
assert_eq!(13177568884 + 192431116, commission);
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_not_ideal * 1_000_000_000_000_000_000_000_000,
total_issuance * 1_000_000_000_000_000_000_000_000 + amount,
0), (13177568884, 192431116));
assert_eq!(13177568884 + 192431116, commission);
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
1, total_issuance * 1_000 + amount, 0),
(92386700, 13277613300));
assert_eq!(92386700 + 13277613300, commission);
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
1, total_issuance * 1_000_000_000_000 + amount, 0),
(92253000, 13277747000));
assert_eq!(92253000 + 13277747000, commission);
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
1, total_issuance * 1_000_000_000_000_000_000_000_000 + amount, 0),
(92253000, 13277747000));
assert_eq!(92253000 + 13277747000, commission);
GhostNetworks::nullify_commission();
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000,
total_issuance * 1_000 + amount,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000_000_000_000,
total_issuance * 1_000_000_000_000 + amount,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000_000_000_000_000_000_000_000,
total_issuance * 1_000_000_000_000_000_000_000_000 + amount,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_not_ideal * 1_000,
total_issuance * 1_000 + amount,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_not_ideal * 1_000_000_000_000,
total_issuance * 1_000_000_000_000 + amount,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_not_ideal * 1_000_000_000_000_000_000_000_000,
total_issuance * 1_000_000_000_000_000_000_000_000 + amount,
0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
1, total_issuance * 1_000 + amount, 0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
1, total_issuance * 1_000_000_000_000 + amount, 0), (0, 0));
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
1, total_issuance * 1_000_000_000_000_000_000_000_000 + amount, 0), (0, 0));
});
}
#[test]
fn bridged_inflation_era_payout_triggers_need_of_nullification() {
ExtBuilder::build()
.execute_with(|| {
let chain_id: u32 = 1;
let amount: u128 = 1337 * 1_000_000_000;
let commission: u128 = amount / 100; // 1% commission
let total_staked_ideal: u128 = 69;
let total_issuance: u128 = 100;
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::increase_gatekeeper_amount(&chain_id, &amount));
assert_eq!(NullifyNeeded::<Test>::get(), false);
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000,
total_issuance * 1_000 + amount,
0), (commission, 0));
assert_eq!(NullifyNeeded::<Test>::get(), true);
GhostNetworks::on_finalize(69);
assert_eq!(NullifyNeeded::<Test>::get(), false);
});
}

0
pallets/networks/src/weights.rs Executable file → Normal file
View File

9
pallets/slow-clap/Cargo.toml Executable file → Normal file
View File

@ -1,6 +1,6 @@
[package]
name = "ghost-slow-clap"
version = "0.3.15"
version = "0.3.19"
description = "Applause protocol for the EVM bridge"
license.workspace = true
authors.workspace = true
@ -27,11 +27,13 @@ sp-staking = { workspace = true }
sp-io = { workspace = true }
sp-std = { workspace = true }
pallet-balances = { workspace = true }
ghost-networks = { workspace = true }
[dev-dependencies]
pallet-session = { workspace = true, default-features = true }
pallet-balances = { workspace = true }
pallet-session = { workspace = true }
pallet-staking = { workspace = true }
pallet-staking-reward-curve = { workspace = true }
[features]
default = ["std"]
@ -49,6 +51,7 @@ std = [
"sp-io/std",
"sp-std/std",
"pallet-session/std",
"pallet-staking/std",
"pallet-balances/std",
"ghost-networks/std",
]

View File

@ -4,12 +4,7 @@ use super::*;
use frame_benchmarking::v1::*;
use frame_system::RawOrigin;
use frame_support::traits::fungible::{Inspect, Mutate};
use crate::Pallet as SlowClap;
const MAX_CLAPS: u32 = 100;
const MAX_COMPANIONS: u32 = 20;
use frame_support::traits::fungible::Inspect;
pub fn create_account<T: Config>() -> T::AccountId {
let account_bytes = Vec::from([1u8; 32]);
@ -17,184 +12,40 @@ pub fn create_account<T: Config>() -> T::AccountId {
.expect("32 bytes always construct an AccountId32")
}
pub fn create_companions<T: Config>(
total: usize,
network_id: NetworkIdOf<T>,
user_account: T::AccountId,
fee: H256,
receiver: H160,
) -> Result<CompanionId, &'static str> {
T::NetworkDataHandler::register(network_id.into(), NetworkData {
chain_name: "Ethereum".into(),
default_endpoint:
"https://base-mainnet.core.chainstack.com/2fc1de7f08c0465f6a28e3c355e0cb14/".into(),
finality_delay: Some(0),
release_delay: Some(0),
network_type: Default::default(),
gatekeeper: b"0x1234567891234567891234567891234567891234".to_vec(),
topic_name: b"0x12345678912345678912345678912345678912345678912345678912345678".to_vec(),
incoming_fee: 0,
outgoing_fee: 0,
}).map_err(|_| BenchmarkError::Weightless)?;
let mut last_companion_id = 0;
for _ in 0..total {
let minimum_balance = <<T as pallet::Config>::Currency>::minimum_balance();
let balance = minimum_balance + minimum_balance;
let companion = Companion::<NetworkIdOf::<T>, BalanceOf::<T>> {
network_id: network_id.into(), receiver,
fee, amount: balance,
};
let _ = <<T as pallet::Config>::Currency>::mint_into(&user_account, balance);
let companion_id = SlowClap::<T>::current_companion_id();
let _ = SlowClap::<T>::propose_companion(
RawOrigin::Signed(user_account.clone()).into(),
network_id,
companion,
)?;
last_companion_id = companion_id;
}
Ok(last_companion_id)
}
pub fn create_claps<T: Config>(i: u32, j: u32) -> Result<
(
Vec<crate::Clap<T::AccountId, NetworkIdOf<T>, BalanceOf<T>>>,
<T::AuthorityId as RuntimeAppPublic>::Signature,
),
&'static str,
> {
let minimum_balance = <<T as pallet::Config>::Currency>::minimum_balance();
let amount = minimum_balance + minimum_balance;
let total_amount = amount.saturating_mul(j.into());
let network_id = NetworkIdOf::<T>::default();
let mut claps = Vec::new();
let mut companions = BTreeMap::new();
let authorities = vec![T::AuthorityId::generate_pair(None)];
let bounded_authorities =
WeakBoundedVec::<_, T::MaxAuthorities>::try_from(authorities.clone())
.map_err(|()| "more than the maximum number of keys provided")?;
Authorities::<T>::put(bounded_authorities);
for index in 0..j {
companions.insert(
index.into(),
amount,
);
}
for _ in 0..i {
claps.push(Clap {
session_index: 1,
authority_index: 0,
network_id,
transaction_hash: H256::repeat_byte(1u8),
block_number: 69,
removed: true,
receiver: create_account::<T>(),
amount: total_amount,
companions: companions.clone(),
});
}
let authority_id = authorities
.get(0usize)
.expect("first authority should exist");
let encoded_claps = claps.encode();
let signature = authority_id.sign(&encoded_claps)
.ok_or("couldn't make signature")?;
Ok((claps, signature))
}
benchmarks! {
slow_clap {
let k in 1 .. MAX_CLAPS;
let j in 1 .. MAX_COMPANIONS;
let receiver = H160::repeat_byte(69u8);
let fee = H256::repeat_byte(0u8);
let user_account: T::AccountId = whitelisted_caller();
let network_id = <<T as pallet::Config>::NetworkDataHandler as NetworkDataBasicHandler>::NetworkId::default();
let (claps, signature) = create_claps::<T>(k, j)?;
let _ = create_companions::<T>(j as usize, network_id, user_account, fee, receiver)?;
}: _(RawOrigin::None, claps, signature)
verify {
let minimum_balance = <<T as pallet::Config>::Currency>::minimum_balance();
let total_amount = (minimum_balance + minimum_balance).saturating_mul(j.into());
}
let receiver = create_account::<T>();
let amount = minimum_balance + minimum_balance;
let network_id = NetworkIdOf::<T>::default();
propose_companion {
let receiver = H160::repeat_byte(69u8);
let fee = H256::repeat_byte(0u8);
let user_account: T::AccountId = whitelisted_caller();
let network_id = <<T as pallet::Config>::NetworkDataHandler as NetworkDataBasicHandler>::NetworkId::default();
// T::NetworkDataHandler::register(network_id.into(), NetworkData {
// chain_name: "Ethereum".into(),
// // https://nd-422-757-666.p2pify.com/0a9d79d93fb2f4a4b1e04695da2b77a7/
// default_endpoint:
// "https://base-mainnet.core.chainstack.com/2fc1de7f08c0465f6a28e3c355e0cb14/".into(),
// finality_delay: Some(50),
// release_delay: Some(100),
// network_type: Default::default(),
// gatekeeper: b"0x1234567891234567891234567891234567891234".to_vec(),
// topic_name: b"0x12345678912345678912345678912345678912345678912345678912345678".to_vec(),
// incoming_fee: 0,
// outgoing_fee: 0,
// }).map_err(|_| BenchmarkError::Weightless)?;
let companion_id = create_companions::<T>(1, network_id, user_account.clone(), fee, receiver)?;
let companion_id = SlowClap::<T>::current_companion_id();
let minimum_balance = <<T as pallet::Config>::Currency>::minimum_balance();
let balance = minimum_balance + minimum_balance;
let companion = Companion::<NetworkIdOf::<T>, BalanceOf::<T>> {
network_id: network_id.into(), receiver,
fee, amount: balance,
let authorities = vec![T::AuthorityId::generate_pair(None)];
let bounded_authorities =
WeakBoundedVec::<_, T::MaxAuthorities>::try_from(authorities.clone())
.map_err(|()| "more than the maximum number of keys provided")?;
Authorities::<T>::put(bounded_authorities);
let clap = Clap {
session_index: 0,
authority_index: 0,
transaction_hash: H256::repeat_byte(1u8),
block_number: 69,
removed: false,
network_id,
receiver: receiver.clone(),
amount,
};
let _ = <<T as pallet::Config>::Currency>::mint_into(&user_account, balance);
assert_eq!(SlowClap::<T>::current_companion_id(), companion_id);
}: _(RawOrigin::Signed(user_account), network_id.into(), companion)
verify {
assert_eq!(SlowClap::<T>::current_companion_id(), companion_id + 1);
}
release_companion {
let receiver = H160::repeat_byte(69u8);
let fee = H256::repeat_byte(0u8);
let user_account: T::AccountId = whitelisted_caller();
let network_id = <<T as pallet::Config>::NetworkDataHandler as NetworkDataBasicHandler>::NetworkId::default();
let companion_id = create_companions::<T>(1, network_id, user_account.clone(), fee, receiver)?;
assert_eq!(SlowClap::<T>::release_blocks(companion_id), BlockNumberFor::<T>::default());
}: _(RawOrigin::Signed(user_account), network_id.into(), companion_id)
verify {
assert_ne!(SlowClap::<T>::release_blocks(companion_id), BlockNumberFor::<T>::default());
}
let authority_id = authorities
.get(0usize)
.expect("first authority should exist");
let encoded_clap = clap.encode();
let signature = authority_id.sign(&encoded_clap)
.ok_or("couldn't make signature")?;
kill_companion {
let receiver = H160::repeat_byte(69u8);
let fee = H256::repeat_byte(0u8);
let user_account: T::AccountId = whitelisted_caller();
let network_id = <<T as pallet::Config>::NetworkDataHandler as NetworkDataBasicHandler>::NetworkId::default();
let companion_id = create_companions::<T>(1, network_id, user_account.clone(), fee, receiver)?;
SlowClap::<T>::release_companion(
RawOrigin::Signed(user_account.clone()).into(),
network_id,
companion_id,
)?;
let block_shift =
<<T as pallet::Config>::NetworkDataHandler as NetworkDataInspectHandler<NetworkData>>::get(&network_id)
.unwrap()
.release_delay
.unwrap();
frame_system::Pallet::<T>::set_block_number((block_shift + 1).saturated_into());
}: _(RawOrigin::Signed(user_account), network_id.into(), companion_id)
}: _(RawOrigin::None, clap, signature)
verify {
assert_eq!(SlowClap::<T>::companions(network_id, companion_id), None);
assert_eq!(SlowClap::<T>::companion_details(companion_id), None);
assert_eq!(SlowClap::<T>::current_companion_id(), companion_id + 1);
assert_eq!(<<T as pallet::Config>::Currency>::total_balance(&receiver), amount);
}
impl_benchmark_test_suite!(

1059
pallets/slow-clap/src/lib.rs Executable file → Normal file

File diff suppressed because it is too large Load Diff

View File

@ -2,22 +2,23 @@
use frame_support::{
derive_impl, parameter_types,
traits::{ConstU32, ConstU64},
weights::Weight,
PalletId,
traits::{ConstU32, ConstU64}, weights::Weight,
};
use frame_system::EnsureRoot;
use pallet_session::historical as pallet_session_historical;
use sp_runtime::{
testing::{TestXt, UintAuthorityId},
traits::ConvertInto,
BuildStorage, Permill,
traits::ConvertInto, curve::PiecewiseLinear,
Permill,
};
use sp_staking::{
offence::{OffenceError, ReportOffence},
SessionIndex,
};
#[cfg(feature = "runtime-benchmarks")]
use sp_runtime::BuildStorage;
use crate as slow_clap;
use crate::Config;
@ -84,24 +85,22 @@ impl ReportOffence<u64, IdentificationTuple, Offence> for OffenceHandler {
}
}
pub fn alice_account_id() -> <Runtime as frame_system::Config>::AccountId { 69 }
pub fn eve_account_id() -> <Runtime as frame_system::Config>::AccountId { 1337 }
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::<Runtime>::default()
let t = frame_system::GenesisConfig::<Runtime>::default()
.build_storage()
.unwrap();
pallet_balances::GenesisConfig::<Runtime> {
balances: vec![ (alice_account_id(), 100) ],
}
.assimilate_storage(&mut t)
.unwrap();
let mut result = sp_io::TestExternalities::new(t);
result.execute_with(|| {
System::set_block_number(1);
for i in 1..=3 {
System::inc_providers(&i);
assert_eq!(Session::set_keys(
RuntimeOrigin::signed(i),
i.into(),
vec![],
), Ok(()));
}
});
result
@ -167,6 +166,7 @@ impl frame_support::traits::EstimateNextSessionRotation<u64> for TestNextSession
impl ghost_networks::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type NetworkId = u32;
type RegisterOrigin = EnsureRoot<Self::AccountId>;
type UpdateOrigin = EnsureRoot<Self::AccountId>;
@ -174,9 +174,20 @@ impl ghost_networks::Config for Runtime {
type WeightInfo = ();
}
pallet_staking_reward_curve::build! {
const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
min_inflation: 0_006_000,
max_inflation: 1_000_000,
ideal_stake: 0_690_000,
falloff: 0_050_000,
max_piece_count: 100,
test_precision: 0_005_000,
);
}
parameter_types! {
pub static ExistentialDeposit: u64 = 2;
pub const TreasuryPalletId: PalletId = PalletId(*b"mck/test");
pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
}
#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
@ -199,23 +210,15 @@ impl Config for Runtime {
type ReportUnresponsiveness = OffenceHandler;
type MaxAuthorities = ConstU32<5>;
type MaxNumberOfClaps = ConstU32<100>;
type ApplauseThreshold = ConstU32<0>;
type MaxAuthorityInfoInSession = ConstU32<5_000>;
type OffenceThreshold = ConstU32<40>;
type ApplauseThreshold = ConstU32<50>;
type OffenceThreshold = ConstU32<75>;
type UnsignedPriority = ConstU64<{ 1 << 20 }>;
type TreasuryPalletId = TreasuryPalletId;
type WeightInfo = ();
}
pub type Extrinsic = TestXt<RuntimeCall, ()>;
// impl frame_system::offchain::SigningTypes for Runtime {
// type Public = <Signature as Verify>::Signer;
// type Signature = Signature;
// }
impl<LocalCall> frame_system::offchain::SendTransactionTypes<LocalCall> for Runtime
where
RuntimeCall: From<LocalCall>,
@ -224,30 +227,16 @@ where
type Extrinsic = Extrinsic;
}
// impl<LocalCall> frame_system::offchain::CreateSignedTransaction<LocalCall> for Runtime
// where
// RuntimeCall: From<LocalCall>,
// {
// fn create_transaction<C: frame_system::offchain::AppCrypto<Self::Public, Self::Signature>>(
// call: Self::OverarchingCall,
// _public: Self::Public,
// _account: Self::AccountId,
// nonce: Self::Nonce,
// ) -> Option<(RuntimeCall, <Extrinsic as ExtrinsicT>::SignaturePayload)> {
// Some((call, (nonce.into(), ())))
// }
// }
pub fn advance_session() {
let now = System::block_number().max(1);
System::set_block_number(now + 1);
Session::rotate_session();
// pub fn advance_session() {
// let now = System::block_number().max(1);
// System::set_block_number(now + 1);
// Session::rotate_session();
//
// let authorities = Session::validators()
// .into_iter()
// .map(UintAuthorityId)
// .collect();
//
// SlowClap::set_authorities(authorities);
// assert_eq!(Session::current_index(), (now / Period::get()) as u32);
// }
let authorities = Session::validators()
.into_iter()
.map(UintAuthorityId)
.collect();
SlowClap::set_test_authorities(authorities);
assert_eq!(Session::current_index(), (now / Period::get()) as u32);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,11 @@
use frame_support::weights::Weight;
pub trait WeightInfo {
fn slow_clap(claps_len: u32, companions_len: u32) -> Weight;
fn propose_companion() -> Weight;
fn release_companion() -> Weight;
fn kill_companion() -> Weight;
fn slow_clap() -> Weight;
fn applause()-> Weight;
}
impl WeightInfo for () {
fn slow_clap(
_claps_len: u32,
_companions_len: u32,
) -> Weight { Weight::zero() }
fn propose_companion() -> Weight { Weight::zero() }
fn release_companion() -> Weight { Weight::zero() }
fn kill_companion() -> Weight { Weight::zero() }
fn slow_clap()-> Weight { Weight::zero() }
fn applause()-> Weight { Weight::zero() }
}

6
pallets/traits/Cargo.toml Executable file → Normal file
View File

@ -1,6 +1,6 @@
[package]
name = "ghost-traits"
version = "0.3.19"
version = "0.3.20"
license.workspace = true
authors.workspace = true
edition.workspace = true
@ -14,6 +14,6 @@ sp-runtime = { workspace = true }
[features]
default = ["std"]
std = [
"frame-support/std",
"sp-runtime/std",
"frame-support/std",
"sp-runtime/std",
]

0
pallets/traits/src/lib.rs Executable file → Normal file
View File

14
pallets/traits/src/networks.rs Executable file → Normal file
View File

@ -21,9 +21,21 @@ pub trait NetworkDataBasicHandler {
pub trait NetworkDataInspectHandler<Network>: NetworkDataBasicHandler {
fn get(n: &Self::NetworkId) -> Option<Network>;
fn iter() -> PrefixIterator<(Self::NetworkId, Network)>;
fn is_nullification_period() -> bool;
}
pub trait NetworkDataMutateHandler<Network>: NetworkDataInspectHandler<Network> {
pub trait NetworkDataMutateHandler<Network, Balance>: NetworkDataInspectHandler<Network> {
fn register(chain_id: Self::NetworkId, network: Network) -> DispatchResult;
fn remove(chain_id: Self::NetworkId) -> DispatchResult;
fn increase_gatekeeper_amount(
chain_id: &Self::NetworkId,
amount: &Balance,
) -> Result<(Balance, Balance), ()>;
fn decrease_gatekeeper_amount(
chain_id: &Self::NetworkId,
amount: &Balance,
) -> Result<(Balance, Balance), ()>;
fn accumulate_commission(commission: &Balance) -> Result<Balance, ()>;
fn nullify_commission();
}

0
rpc/Cargo.toml Executable file → Normal file
View File

0
rpc/src/lib.rs Executable file → Normal file
View File

0
runtime/casper/Cargo.toml Executable file → Normal file
View File

0
runtime/casper/build.rs Executable file → Normal file
View File

0
runtime/casper/constants/Cargo.toml Executable file → Normal file
View File

0
runtime/casper/constants/src/lib.rs Executable file → Normal file
View File

0
runtime/casper/src/cult/mod.rs Executable file → Normal file
View File

0
runtime/casper/src/cult/origins.rs Executable file → Normal file
View File

0
runtime/casper/src/cult/tracks.rs Executable file → Normal file
View File

0
runtime/casper/src/lib.rs Executable file → Normal file
View File

48
runtime/common/Cargo.toml Executable file → Normal file
View File

@ -31,21 +31,21 @@ primitives = { workspace = true }
default = ["std"]
no_std = []
std = [
"sp-core/std",
"sp-std/std",
"sp-io/std",
"sp-core/std",
"sp-std/std",
"sp-io/std",
"sp-runtime/std",
"sp-staking/std",
"frame-support/std",
"frame-support/std",
"frame-system/std",
"pallet-authorship/std",
"pallet-balances/std",
"pallet-staking/std",
"pallet-staking-reward-fn/std",
"pallet-timestamp/std",
"pallet-transaction-payment/std",
"pallet-treasury/std",
"pallet-election-provider-multi-phase/std",
"pallet-authorship/std",
"pallet-balances/std",
"pallet-staking/std",
"pallet-staking-reward-fn/std",
"pallet-timestamp/std",
"pallet-transaction-payment/std",
"pallet-treasury/std",
"pallet-election-provider-multi-phase/std",
"primitives/std",
]
runtime-benchmarks = [
@ -53,21 +53,21 @@ runtime-benchmarks = [
"sp-staking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-staking/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"pallet-treasury/runtime-benchmarks",
"pallet-election-provider-multi-phase/runtime-benchmarks",
"pallet-balances/runtime-benchmarks",
"pallet-staking/runtime-benchmarks",
"pallet-timestamp/runtime-benchmarks",
"pallet-treasury/runtime-benchmarks",
"pallet-election-provider-multi-phase/runtime-benchmarks",
]
try-runtime = [
"sp-runtime/try-runtime",
"frame-support/try-runtime",
"frame-system/try-runtime",
"pallet-authorship/try-runtime",
"pallet-balances/try-runtime",
"pallet-staking/try-runtime",
"pallet-timestamp/try-runtime",
"pallet-transaction-payment/try-runtime",
"pallet-treasury/try-runtime",
"pallet-election-provider-multi-phase/try-runtime",
"pallet-authorship/try-runtime",
"pallet-balances/try-runtime",
"pallet-staking/try-runtime",
"pallet-timestamp/try-runtime",
"pallet-transaction-payment/try-runtime",
"pallet-treasury/try-runtime",
"pallet-election-provider-multi-phase/try-runtime",
]

0
runtime/common/src/impls.rs Executable file → Normal file
View File

0
runtime/common/src/lib.rs Executable file → Normal file
View File

0
runtime/common/src/weights/block_weights.rs Executable file → Normal file
View File

0
runtime/common/src/weights/extrinsic.rs Executable file → Normal file
View File

0
runtime/common/src/weights/mod.rs Executable file → Normal file
View File

20
service/Cargo.toml Executable file → Normal file
View File

@ -107,16 +107,16 @@ default = ["db", "full-node"]
db = ["sc-service/rocksdb"]
full-node = ["kvdb-rocksdb", "parity-db"]
runtime-benchmarks = [
"frame-benchmarking-cli/runtime-benchmarks",
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-babe/runtime-benchmarks",
"pallet-staking/runtime-benchmarks",
"casper-runtime?/runtime-benchmarks",
"sc-client-db/runtime-benchmarks",
"sc-service/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
"frame-benchmarking-cli/runtime-benchmarks",
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"pallet-babe/runtime-benchmarks",
"pallet-staking/runtime-benchmarks",
"casper-runtime?/runtime-benchmarks",
"sc-client-db/runtime-benchmarks",
"sc-service/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",

0
service/src/chain_spec.rs Executable file → Normal file
View File

0
service/src/lib.rs Executable file → Normal file
View File

0
src/main.rs Executable file → Normal file
View File

0
tests/benchmark_block.rs Executable file → Normal file
View File

0
tests/benchmark_extrinsic.rs Executable file → Normal file
View File

0
tests/benchmark_overhead.rs Executable file → Normal file
View File

0
tests/benchmark_storage_works.rs Executable file → Normal file
View File

0
tests/common.rs Executable file → Normal file
View File

0
tests/invalid_order_arguments.rs Executable file → Normal file
View File

0
tests/purge_chain_works.rs Executable file → Normal file
View File

0
tests/running_the_node_and_interrupt.rs Executable file → Normal file
View File

0
utils/generate-bags/Cargo.toml Executable file → Normal file
View File

0
utils/generate-bags/src/main.rs Executable file → Normal file
View File

0
utils/ghostkey/Cargo.toml Executable file → Normal file
View File

0
utils/ghostkey/src/lib.rs Executable file → Normal file
View File

0
utils/ghostkey/src/main.rs Executable file → Normal file
View File

0
utils/staking-miner/Cargo.toml Executable file → Normal file
View File

View File

0
utils/staking-miner/src/main.rs Executable file → Normal file
View File

0
utils/staking-miner/tests/cli.rs Executable file → Normal file
View File