Compare commits

..

No commits in common. "0375bd1434be17ef096a6fb9dd2a57091489a906" and "0c3636fe79482510590da48e514862ed31115f84" have entirely different histories.

36 changed files with 1740 additions and 3714 deletions

20
Cargo.lock generated
View File

@ -3504,7 +3504,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-claims" name = "ghost-claims"
version = "0.2.4" version = "0.2.3"
dependencies = [ dependencies = [
"frame-benchmarking", "frame-benchmarking",
"frame-support", "frame-support",
@ -3528,7 +3528,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-cli" name = "ghost-cli"
version = "0.7.201" version = "0.7.200"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"clap 4.5.4", "clap 4.5.4",
@ -3584,7 +3584,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-machine-primitives" name = "ghost-machine-primitives"
version = "0.7.201" version = "0.7.200"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
"sc-sysinfo", "sc-sysinfo",
@ -3593,7 +3593,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-metrics" name = "ghost-metrics"
version = "0.7.201" version = "0.7.200"
dependencies = [ dependencies = [
"assert_cmd", "assert_cmd",
"bs58 0.5.1", "bs58 0.5.1",
@ -3648,7 +3648,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-networks" name = "ghost-networks"
version = "0.1.11" version = "0.1.10"
dependencies = [ dependencies = [
"frame-benchmarking", "frame-benchmarking",
"frame-support", "frame-support",
@ -3667,7 +3667,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-node" name = "ghost-node"
version = "0.7.201" version = "0.7.200"
dependencies = [ dependencies = [
"assert_cmd", "assert_cmd",
"color-eyre", "color-eyre",
@ -3698,7 +3698,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-rpc" name = "ghost-rpc"
version = "0.7.201" version = "0.7.200"
dependencies = [ dependencies = [
"ghost-core-primitives", "ghost-core-primitives",
"jsonrpsee", "jsonrpsee",
@ -3750,7 +3750,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-service" name = "ghost-service"
version = "0.7.201" version = "0.7.200"
dependencies = [ dependencies = [
"assert_matches", "assert_matches",
"async-trait", "async-trait",
@ -3834,7 +3834,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-slow-clap" name = "ghost-slow-clap"
version = "0.3.33" version = "0.3.30"
dependencies = [ dependencies = [
"frame-benchmarking", "frame-benchmarking",
"frame-support", "frame-support",
@ -3870,7 +3870,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-traits" name = "ghost-traits"
version = "0.3.23" version = "0.3.22"
dependencies = [ dependencies = [
"frame-support", "frame-support",
"sp-runtime 31.0.1", "sp-runtime 31.0.1",

View File

@ -17,7 +17,7 @@ homepage.workspace = true
[workspace.package] [workspace.package]
license = "GPL-3.0-only" license = "GPL-3.0-only"
authors = ["571nky", "57r37ch", "f4750"] authors = ["571nky", "57r37ch", "f4750"]
version = "0.7.203" version = "0.7.200"
edition = "2021" edition = "2021"
homepage = "https://ghostchain.io" homepage = "https://ghostchain.io"
repository = "https://git.ghostchain.io/ghostchain/ghost-node" repository = "https://git.ghostchain.io/ghostchain/ghost-node"
@ -229,7 +229,6 @@ ghost-traits = { path = "pallets/traits", default-features = false }
ghost-networks = { path = "pallets/networks", default-features = false } ghost-networks = { path = "pallets/networks", default-features = false }
ghost-claims = { path = "pallets/claims", default-features = false } ghost-claims = { path = "pallets/claims", default-features = false }
ghost-slow-clap = { path = "pallets/slow-clap", default-features = false } ghost-slow-clap = { path = "pallets/slow-clap", default-features = false }
ghost-sudo = { path = "pallets/sudo", default-features = false }
ghost-runtime-constants = { package = "ghost-runtime-constants", path = "runtime/ghost/constants", default-features = false } ghost-runtime-constants = { package = "ghost-runtime-constants", path = "runtime/ghost/constants", default-features = false }
casper-runtime = { path = "runtime/casper", default-features = false } casper-runtime = { path = "runtime/casper", default-features = false }
casper-runtime-constants = { package = "casper-runtime-constants", path = "runtime/casper/constants", default-features = false } casper-runtime-constants = { package = "casper-runtime-constants", path = "runtime/casper/constants", default-features = false }
@ -272,7 +271,6 @@ members = [
"pallets/networks", "pallets/networks",
"pallets/claims", "pallets/claims",
"pallets/slow-clap", "pallets/slow-clap",
"pallets/sudo",
"utils/bags-list", "utils/bags-list",
"utils/chain-spec-builder", "utils/chain-spec-builder",
"utils/generate-bags", "utils/generate-bags",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-claims" name = "ghost-claims"
version = "0.2.4" version = "0.2.3"
description = "Ghost balance and rank claims based on EVM actions" description = "Ghost balance and rank claims based on EVM actions"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -6,14 +6,14 @@ use frame_benchmarking::v2::*;
#[instance_benchmarks] #[instance_benchmarks]
mod benchmarks { mod benchmarks {
use super::*; use super::*;
use frame_support::dispatch::RawOrigin;
use pallet_ranked_collective::Pallet as Club; use pallet_ranked_collective::Pallet as Club;
use frame_support::dispatch::RawOrigin;
#[benchmark] #[benchmark]
fn claim() { fn claim() {
let i = 1337u32; let i = 1337u32;
let ethereum_secret_key = let ethereum_secret_key = libsecp256k1::SecretKey::parse(
libsecp256k1::SecretKey::parse(&keccak_256(&i.to_le_bytes())).unwrap(); &keccak_256(&i.to_le_bytes())).unwrap();
let eth_address = crate::secp_utils::eth(&ethereum_secret_key); let eth_address = crate::secp_utils::eth(&ethereum_secret_key);
let balance = CurrencyOf::<T, I>::minimum_balance(); let balance = CurrencyOf::<T, I>::minimum_balance();
@ -22,30 +22,23 @@ mod benchmarks {
Total::<T, I>::put(balance); Total::<T, I>::put(balance);
let pseudo_rank = 5u16; let pseudo_rank = 5u16;
let _ = Club::<T, I>::do_add_member_to_rank(pseudo_account.clone(), pseudo_rank, false); let _ = Club::<T, I>::do_add_member_to_rank(
pseudo_account.clone(),
pseudo_rank,
false,
);
let user_account: T::AccountId = account("user", i, 0); let user_account: T::AccountId = account("user", i, 0);
let signature = let signature = crate::secp_utils::sig::<T, I>(&ethereum_secret_key, &user_account.encode());
crate::secp_utils::sig::<T, I>(&ethereum_secret_key, &user_account.encode());
let prev_balance = CurrencyOf::<T, I>::free_balance(&user_account); let prev_balance = CurrencyOf::<T, I>::free_balance(&user_account);
let prev_rank = Club::<T, I>::rank_of(&user_account); let prev_rank = Club::<T, I>::rank_of(&user_account);
#[extrinsic_call] #[extrinsic_call]
claim( claim(RawOrigin::Signed(user_account.clone()), eth_address, signature);
RawOrigin::Signed(user_account.clone()),
eth_address,
signature,
);
assert_eq!( assert_eq!(CurrencyOf::<T, I>::free_balance(&user_account), prev_balance + balance);
CurrencyOf::<T, I>::free_balance(&user_account), assert_eq!(CurrencyOf::<T, I>::free_balance(&pseudo_account), balance - balance);
prev_balance + balance
);
assert_eq!(
CurrencyOf::<T, I>::free_balance(&pseudo_account),
balance - balance
);
let rank = match prev_rank { let rank = match prev_rank {
Some(current_rank) if pseudo_rank <= current_rank => Some(current_rank), Some(current_rank) if pseudo_rank <= current_rank => Some(current_rank),
@ -55,5 +48,9 @@ mod benchmarks {
assert_eq!(Club::<T, I>::rank_of(&pseudo_account), None); assert_eq!(Club::<T, I>::rank_of(&pseudo_account), None);
} }
impl_benchmark_test_suite!(Pallet, crate::mock::new_test_ext(), crate::mock::Test,); impl_benchmark_test_suite!(
Pallet,
crate::mock::new_test_ext(),
crate::mock::Test,
);
} }

View File

@ -1,20 +1,19 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use frame_support::{ use frame_support::{
ensure, ensure, pallet_prelude::*,
pallet_prelude::*,
traits::{ traits::{
Currency, ExistenceRequirement, Get, RankedMembers, RankedMembersSwapHandler, Currency, ExistenceRequirement, Get, RankedMembers,
VestingSchedule, RankedMembersSwapHandler, VestingSchedule,
}, },
DefaultNoBound, DefaultNoBound,
}; };
use frame_system::pallet_prelude::*; use frame_system::pallet_prelude::*;
pub use pallet::*;
use serde::{self, Deserialize, Deserializer, Serialize, Serializer}; use serde::{self, Deserialize, Deserializer, Serialize, Serializer};
pub use pallet::*;
use sp_io::{crypto::secp256k1_ecdsa_recover, hashing::keccak_256}; use sp_io::{crypto::secp256k1_ecdsa_recover, hashing::keccak_256};
use sp_runtime::traits::{BlockNumberProvider, CheckedDiv, CheckedSub}; use sp_runtime::traits::{CheckedSub, CheckedDiv, BlockNumberProvider};
use sp_std::prelude::*; use sp_std::prelude::*;
extern crate alloc; extern crate alloc;
@ -24,10 +23,10 @@ use alloc::{format, string::String};
mod weights; mod weights;
pub use crate::weights::WeightInfo; pub use crate::weights::WeightInfo;
mod benchmarking;
mod mock;
mod secp_utils;
mod tests; mod tests;
mod mock;
mod benchmarking;
mod secp_utils;
/// An ethereum address (i.e. 20 bytes, used to represent an Ethereum account). /// An ethereum address (i.e. 20 bytes, used to represent an Ethereum account).
/// ///
@ -57,7 +56,7 @@ impl<'de> Deserialize<'de> for EthereumAddress {
Err(serde::de::Error::custom( Err(serde::de::Error::custom(
"Bad length of Ethereum address (should be 42 including `0x`)", "Bad length of Ethereum address (should be 42 including `0x`)",
))?; ))?;
} }
let raw: Vec<u8> = rustc_hex::FromHex::from_hex(s) let raw: Vec<u8> = rustc_hex::FromHex::from_hex(s)
.map_err(|e| serde::de::Error::custom(format!("{:?}", e)))?; .map_err(|e| serde::de::Error::custom(format!("{:?}", e)))?;
let mut r = Self::default(); let mut r = Self::default();
@ -82,14 +81,15 @@ impl sp_std::fmt::Debug for EcdsaSignature {
} }
type CurrencyOf<T, I> = <<T as Config<I>>::VestingSchedule as VestingSchedule< type CurrencyOf<T, I> = <<T as Config<I>>::VestingSchedule as VestingSchedule<
<T as frame_system::Config>::AccountId, <T as frame_system::Config>::AccountId
>>::Currency; >>::Currency;
type BalanceOf<T, I> = type BalanceOf<T, I> = <CurrencyOf<T, I> as Currency<
<CurrencyOf<T, I> as Currency<<T as frame_system::Config>::AccountId>>::Balance; <T as frame_system::Config>::AccountId>
>::Balance;
type RankOf<T, I> = <pallet_ranked_collective::Pallet<T, I> as RankedMembers>::Rank; type RankOf<T, I> = <pallet_ranked_collective::Pallet::<T, I> as RankedMembers>::Rank;
type AccountIdOf<T, I> = <pallet_ranked_collective::Pallet<T, I> as RankedMembers>::AccountId; type AccountIdOf<T, I> = <pallet_ranked_collective::Pallet::<T, I> as RankedMembers>::AccountId;
#[frame_support::pallet] #[frame_support::pallet]
pub mod pallet { pub mod pallet {
@ -100,11 +100,8 @@ pub mod pallet {
pub struct Pallet<T, I = ()>(_); pub struct Pallet<T, I = ()>(_);
#[pallet::config] #[pallet::config]
pub trait Config<I: 'static = ()>: pub trait Config<I: 'static = ()>: frame_system::Config + pallet_ranked_collective::Config<I> {
frame_system::Config + pallet_ranked_collective::Config<I> type RuntimeEvent: From<Event<Self, I>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
{
type RuntimeEvent: From<Event<Self, I>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>;
type VestingSchedule: VestingSchedule<Self::AccountId, Moment = BlockNumberFor<Self>>; type VestingSchedule: VestingSchedule<Self::AccountId, Moment = BlockNumberFor<Self>>;
type BlockNumberProvider: BlockNumberProvider<BlockNumber = BlockNumberFor<Self>>; type BlockNumberProvider: BlockNumberProvider<BlockNumber = BlockNumberFor<Self>>;
@ -121,13 +118,13 @@ pub mod pallet {
type WeightInfo: WeightInfo; type WeightInfo: WeightInfo;
} }
#[pallet::event] #[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)] #[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config<I>, I: 'static = ()> { pub enum Event<T: Config<I>, I: 'static = ()> {
Claimed { Claimed {
receiver: T::AccountId, receiver: T::AccountId,
donor: T::AccountId, donor: T::AccountId,
amount: BalanceOf<T, I>, amount: BalanceOf<T, I>,
rank: Option<RankOf<T, I>>, rank: Option<RankOf<T, I>>,
}, },
@ -162,16 +159,12 @@ pub mod pallet {
.map(|(account_id, rank)| { .map(|(account_id, rank)| {
assert!( assert!(
pallet_ranked_collective::Pallet::<T, I>::do_add_member_to_rank( pallet_ranked_collective::Pallet::<T, I>::do_add_member_to_rank(
account_id.clone(), account_id.clone(), *rank, false).is_ok(),
*rank, "error during adding and promotion"
false
)
.is_ok(),
"error during adding and promotion"
); );
account_id account_id
}) })
.collect(); .collect();
assert!( assert!(
self.members_and_ranks.len() == cult_accounts.len(), self.members_and_ranks.len() == cult_accounts.len(),
@ -193,13 +186,13 @@ pub mod pallet {
) -> DispatchResult { ) -> DispatchResult {
let who = ensure_signed(origin)?; let who = ensure_signed(origin)?;
let data = who.using_encoded(to_ascii_hex); let data = who.using_encoded(to_ascii_hex);
let recovered_address = Self::recover_ethereum_address(&ethereum_signature, &data) let recovered_address = Self::recover_ethereum_address(
.ok_or(Error::<T, I>::InvalidEthereumSignature)?; &ethereum_signature,
&data,
).ok_or(Error::<T, I>::InvalidEthereumSignature)?;
ensure!( ensure!(recovered_address == ethereum_address,
recovered_address == ethereum_address, Error::<T, I>::InvalidEthereumAddress);
Error::<T, I>::InvalidEthereumAddress
);
Self::do_claim(who, ethereum_address) Self::do_claim(who, ethereum_address)
} }
@ -207,37 +200,37 @@ pub mod pallet {
} }
fn to_ascii_hex(data: &[u8]) -> Vec<u8> { fn to_ascii_hex(data: &[u8]) -> Vec<u8> {
let mut r = Vec::with_capacity(data.len() * 2); let mut r = Vec::with_capacity(data.len() * 2);
let mut push_nibble = |n| r.push(if n < 10 { b'0' + n } else { b'a' - 10 + n }); let mut push_nibble = |n| r.push(if n < 10 { b'0' + n } else { b'a' - 10 + n });
for &b in data.iter() { for &b in data.iter() {
push_nibble(b / 16); push_nibble(b / 16);
push_nibble(b % 16); push_nibble(b % 16);
} }
r r
} }
impl<T: Config<I>, I: 'static> Pallet<T, I> { impl<T: Config<I>, I: 'static> Pallet<T, I> {
fn ethereum_signable_message(what: &[u8]) -> Vec<u8> { fn ethereum_signable_message(what: &[u8]) -> Vec<u8> {
let prefix = T::Prefix::get(); let prefix = T::Prefix::get();
let mut l = prefix.len() + what.len(); let mut l = prefix.len() + what.len();
let mut rev = Vec::new(); let mut rev = Vec::new();
while l > 0 { while l > 0 {
rev.push(b'0' + (l % 10) as u8); rev.push(b'0' + (l % 10) as u8);
l /= 10; l /= 10;
} }
let mut v = b"\x19Ethereum Signed Message:\n".to_vec(); let mut v = b"\x19Ethereum Signed Message:\n".to_vec();
v.extend(rev.into_iter().rev()); v.extend(rev.into_iter().rev());
v.extend_from_slice(prefix); v.extend_from_slice(prefix);
v.extend_from_slice(what); v.extend_from_slice(what);
v v
} }
fn recover_ethereum_address(s: &EcdsaSignature, what: &[u8]) -> Option<EthereumAddress> { fn recover_ethereum_address(s: &EcdsaSignature, what: &[u8]) -> Option<EthereumAddress> {
let msg = keccak_256(&Self::ethereum_signable_message(what)); let msg = keccak_256(&Self::ethereum_signable_message(what));
let mut res = EthereumAddress::default(); let mut res = EthereumAddress::default();
res.0 res.0
.copy_from_slice(&keccak_256(&secp256k1_ecdsa_recover(&s.0, &msg).ok()?[..])[12..]); .copy_from_slice(&keccak_256(&secp256k1_ecdsa_recover(&s.0, &msg).ok()?[..])[12..]);
Some(res) Some(res)
} }
fn into_account_id(address: EthereumAddress) -> Result<T::AccountId, codec::Error> { fn into_account_id(address: EthereumAddress) -> Result<T::AccountId, codec::Error> {
@ -250,24 +243,21 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
} }
fn do_claim(receiver: T::AccountId, ethereum_address: EthereumAddress) -> DispatchResult { fn do_claim(receiver: T::AccountId, ethereum_address: EthereumAddress) -> DispatchResult {
let donor = Self::into_account_id(ethereum_address) let donor = Self::into_account_id(ethereum_address).ok()
.ok()
.ok_or(Error::<T, I>::AddressDecodingFailed)?; .ok_or(Error::<T, I>::AddressDecodingFailed)?;
let balance_due = CurrencyOf::<T, I>::free_balance(&donor); let balance_due = CurrencyOf::<T, I>::free_balance(&donor);
ensure!( ensure!(balance_due >= CurrencyOf::<T, I>::minimum_balance(),
balance_due >= CurrencyOf::<T, I>::minimum_balance(), Error::<T, I>::NoBalanceToClaim);
Error::<T, I>::NoBalanceToClaim
);
let new_total = Total::<T, I>::get() let new_total = Total::<T, I>::get()
.checked_sub(&balance_due) .checked_sub(&balance_due)
.ok_or(Error::<T, I>::PotUnderflow)?; .ok_or(Error::<T, I>::PotUnderflow)?;
CurrencyOf::<T, I>::transfer( CurrencyOf::<T, I>::transfer(
&donor, &donor,
&receiver, &receiver,
balance_due, balance_due,
ExistenceRequirement::AllowDeath, ExistenceRequirement::AllowDeath,
)?; )?;
@ -283,40 +273,28 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
.ok_or(Error::<T, I>::ArithmeticError)?; .ok_or(Error::<T, I>::ArithmeticError)?;
T::VestingSchedule::add_vesting_schedule( T::VestingSchedule::add_vesting_schedule(
&receiver, &receiver,
vesting_balance, vesting_balance,
per_block_balance, per_block_balance,
T::BlockNumberProvider::current_block_number(), T::BlockNumberProvider::current_block_number(),
)?; )?;
} }
let rank = if let Some(rank) = let rank = if let Some(rank) = <pallet_ranked_collective::Pallet::<T, I> as RankedMembers>::rank_of(&donor) {
<pallet_ranked_collective::Pallet<T, I> as RankedMembers>::rank_of(&donor)
{
pallet_ranked_collective::Pallet::<T, I>::do_remove_member_from_rank(&donor, rank)?; pallet_ranked_collective::Pallet::<T, I>::do_remove_member_from_rank(&donor, rank)?;
let new_rank = let new_rank = match <pallet_ranked_collective::Pallet::<T, I> as RankedMembers>::rank_of(&receiver) {
match <pallet_ranked_collective::Pallet<T, I> as RankedMembers>::rank_of(&receiver) Some(current_rank) if current_rank >= rank => current_rank,
{ Some(current_rank) if current_rank < rank => {
Some(current_rank) if current_rank >= rank => current_rank, for _ in 0..rank - current_rank {
Some(current_rank) if current_rank < rank => { pallet_ranked_collective::Pallet::<T, I>::do_promote_member(receiver.clone(), None, false)?;
for _ in 0..rank - current_rank {
pallet_ranked_collective::Pallet::<T, I>::do_promote_member(
receiver.clone(),
None,
false,
)?;
}
rank
} }
_ => { rank
pallet_ranked_collective::Pallet::<T, I>::do_add_member_to_rank( },
receiver.clone(), _ => {
rank, pallet_ranked_collective::Pallet::<T, I>::do_add_member_to_rank(receiver.clone(), rank, false)?;
false, rank
)?; },
rank };
}
};
<T as pallet::Config<I>>::MemberSwappedHandler::swapped(&donor, &receiver, new_rank); <T as pallet::Config<I>>::MemberSwappedHandler::swapped(&donor, &receiver, new_rank);
Some(new_rank) Some(new_rank)
} else { } else {
@ -325,7 +303,7 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
Total::<T, I>::put(new_total); Total::<T, I>::put(new_total);
Self::deposit_event(Event::<T, I>::Claimed { Self::deposit_event(Event::<T, I>::Claimed {
receiver, receiver,
donor, donor,
amount: balance_due, amount: balance_due,
rank, rank,

View File

@ -4,113 +4,51 @@ use super::*;
pub use crate as ghost_claims; pub use crate as ghost_claims;
use frame_support::{ use frame_support::{
derive_impl, parameter_types, parameter_types, derive_impl,
traits::{ConstU16, ConstU64, PollStatus, Polling, WithdrawReasons}, traits::{PollStatus, Polling, WithdrawReasons, ConstU16, ConstU64},
}; };
use frame_system::EnsureRootWithSuccess; use frame_system::EnsureRootWithSuccess;
pub use pallet_ranked_collective::{Rank, TallyOf}; use sp_runtime::{BuildStorage, traits::Convert};
use sp_runtime::{traits::Convert, BuildStorage}; pub use pallet_ranked_collective::{TallyOf, Rank};
pub mod eth_keys { pub mod eth_keys {
use crate::{mock::Test, EcdsaSignature, EthereumAddress}; use crate::{
use codec::Encode; mock::Test,
EcdsaSignature, EthereumAddress,
};
use hex_literal::hex; use hex_literal::hex;
use codec::Encode;
pub fn total_claims() -> u64 { pub fn total_claims() -> u64 { 10 + 100 + 1000 }
10 + 100 + 1000 pub fn alice_account_id() -> <Test as frame_system::Config>::AccountId { 69 }
} pub fn bob_account_id() -> <Test as frame_system::Config>::AccountId { 1337 }
pub fn alice_account_id() -> <Test as frame_system::Config>::AccountId {
69
}
pub fn bob_account_id() -> <Test as frame_system::Config>::AccountId {
1337
}
pub fn first_eth_public_known() -> EthereumAddress { pub fn first_eth_public_known() -> EthereumAddress { EthereumAddress(hex!("1A69d2D5568D1878023EeB121a73d33B9116A760")) }
EthereumAddress(hex!("1A69d2D5568D1878023EeB121a73d33B9116A760")) pub fn second_eth_public_known() -> EthereumAddress { EthereumAddress(hex!("2f86cfBED3fbc1eCf2989B9aE5fc019a837A9C12")) }
} pub fn third_eth_public_known() -> EthereumAddress { EthereumAddress(hex!("e83f67361Ac74D42A48E2DAfb6706eb047D8218D")) }
pub fn second_eth_public_known() -> EthereumAddress { pub fn fourth_eth_public_known() -> EthereumAddress { EthereumAddress(hex!("827ee4ad9b259b6fa1390ed60921508c78befd63")) }
EthereumAddress(hex!("2f86cfBED3fbc1eCf2989B9aE5fc019a837A9C12"))
}
pub fn third_eth_public_known() -> EthereumAddress {
EthereumAddress(hex!("e83f67361Ac74D42A48E2DAfb6706eb047D8218D"))
}
pub fn fourth_eth_public_known() -> EthereumAddress {
EthereumAddress(hex!("827ee4ad9b259b6fa1390ed60921508c78befd63"))
}
fn first_eth_private_key() -> libsecp256k1::SecretKey { fn first_eth_private_key() -> libsecp256k1::SecretKey { libsecp256k1::SecretKey::parse(&hex!("01c928771aea942a1e7ac06adf2b73dfbc9a25d9eaa516e3673116af7f345198")).unwrap() }
libsecp256k1::SecretKey::parse(&hex!( fn second_eth_private_key() -> libsecp256k1::SecretKey { libsecp256k1::SecretKey::parse(&hex!("b19a435901872f817185f7234a1484eae837613f9d10cf21927a23c2d8cb9139")).unwrap() }
"01c928771aea942a1e7ac06adf2b73dfbc9a25d9eaa516e3673116af7f345198" fn third_eth_private_key() -> libsecp256k1::SecretKey { libsecp256k1::SecretKey::parse(&hex!("d3baf57b74d65719b2dc33f5a464176022d0cc5edbca002234229f3e733875fc")).unwrap() }
)) fn fourth_eth_private_key() -> libsecp256k1::SecretKey { libsecp256k1::SecretKey::parse(&hex!("c4683d566436af6b58b4a59c8f501319226e85b21869bf93d5eeb4596d4791d4")).unwrap() }
.unwrap() fn wrong_eth_private_key() -> libsecp256k1::SecretKey { libsecp256k1::SecretKey::parse(&hex!("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")).unwrap() }
}
fn second_eth_private_key() -> libsecp256k1::SecretKey {
libsecp256k1::SecretKey::parse(&hex!(
"b19a435901872f817185f7234a1484eae837613f9d10cf21927a23c2d8cb9139"
))
.unwrap()
}
fn third_eth_private_key() -> libsecp256k1::SecretKey {
libsecp256k1::SecretKey::parse(&hex!(
"d3baf57b74d65719b2dc33f5a464176022d0cc5edbca002234229f3e733875fc"
))
.unwrap()
}
fn fourth_eth_private_key() -> libsecp256k1::SecretKey {
libsecp256k1::SecretKey::parse(&hex!(
"c4683d566436af6b58b4a59c8f501319226e85b21869bf93d5eeb4596d4791d4"
))
.unwrap()
}
fn wrong_eth_private_key() -> libsecp256k1::SecretKey {
libsecp256k1::SecretKey::parse(&hex!(
"deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef"
))
.unwrap()
}
pub fn first_eth_public_key() -> EthereumAddress { pub fn first_eth_public_key() -> EthereumAddress { crate::secp_utils::eth(&first_eth_private_key()) }
crate::secp_utils::eth(&first_eth_private_key()) pub fn second_eth_public_key() -> EthereumAddress { crate::secp_utils::eth(&second_eth_private_key()) }
} pub fn third_eth_public_key() -> EthereumAddress { crate::secp_utils::eth(&third_eth_private_key()) }
pub fn second_eth_public_key() -> EthereumAddress { pub fn fourth_eth_public_key() -> EthereumAddress { crate::secp_utils::eth(&fourth_eth_private_key()) }
crate::secp_utils::eth(&second_eth_private_key())
}
pub fn third_eth_public_key() -> EthereumAddress {
crate::secp_utils::eth(&third_eth_private_key())
}
pub fn fourth_eth_public_key() -> EthereumAddress {
crate::secp_utils::eth(&fourth_eth_private_key())
}
pub fn first_account_id() -> <Test as frame_system::Config>::AccountId { pub fn first_account_id() -> <Test as frame_system::Config>::AccountId { crate::secp_utils::into_account_id::<Test, ()>(first_eth_public_key()) }
crate::secp_utils::into_account_id::<Test, ()>(first_eth_public_key()) pub fn second_account_id() -> <Test as frame_system::Config>::AccountId { crate::secp_utils::into_account_id::<Test, ()>(second_eth_public_key()) }
} pub fn third_account_id() -> <Test as frame_system::Config>::AccountId { crate::secp_utils::into_account_id::<Test, ()>(third_eth_public_key()) }
pub fn second_account_id() -> <Test as frame_system::Config>::AccountId { pub fn fourth_account_id() -> <Test as frame_system::Config>::AccountId { crate::secp_utils::into_account_id::<Test, ()>(fourth_eth_public_key()) }
crate::secp_utils::into_account_id::<Test, ()>(second_eth_public_key())
}
pub fn third_account_id() -> <Test as frame_system::Config>::AccountId {
crate::secp_utils::into_account_id::<Test, ()>(third_eth_public_key())
}
pub fn fourth_account_id() -> <Test as frame_system::Config>::AccountId {
crate::secp_utils::into_account_id::<Test, ()>(fourth_eth_public_key())
}
pub fn first_signature() -> EcdsaSignature { pub fn first_signature() -> EcdsaSignature { crate::secp_utils::sig::<Test, ()>(&first_eth_private_key(), &alice_account_id().encode()) }
crate::secp_utils::sig::<Test, ()>(&first_eth_private_key(), &alice_account_id().encode()) pub fn second_signature() -> EcdsaSignature { crate::secp_utils::sig::<Test, ()>(&second_eth_private_key(), &alice_account_id().encode()) }
} pub fn third_signature() -> EcdsaSignature { crate::secp_utils::sig::<Test, ()>(&third_eth_private_key(), &alice_account_id().encode()) }
pub fn second_signature() -> EcdsaSignature { pub fn fourth_signature() -> EcdsaSignature { crate::secp_utils::sig::<Test, ()>(&fourth_eth_private_key(), &bob_account_id().encode()) }
crate::secp_utils::sig::<Test, ()>(&second_eth_private_key(), &alice_account_id().encode()) pub fn wrong_signature() -> EcdsaSignature { crate::secp_utils::sig::<Test, ()>(&wrong_eth_private_key(), &alice_account_id().encode()) }
}
pub fn third_signature() -> EcdsaSignature {
crate::secp_utils::sig::<Test, ()>(&third_eth_private_key(), &alice_account_id().encode())
}
pub fn fourth_signature() -> EcdsaSignature {
crate::secp_utils::sig::<Test, ()>(&fourth_eth_private_key(), &bob_account_id().encode())
}
pub fn wrong_signature() -> EcdsaSignature {
crate::secp_utils::sig::<Test, ()>(&wrong_eth_private_key(), &alice_account_id().encode())
}
} }
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)] #[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
@ -128,9 +66,10 @@ impl pallet_balances::Config for Test {
type AccountStore = System; type AccountStore = System;
} }
parameter_types! { parameter_types! {
pub const MinVestedTransfer: u64 = 1; pub const MinVestedTransfer: u64 = 1;
pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons = pub UnvestedFundsAllowedWithdrawReasons: WithdrawReasons =
WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE); WithdrawReasons::except(WithdrawReasons::TRANSFER | WithdrawReasons::RESERVE);
} }
@ -140,8 +79,9 @@ impl pallet_vesting::Config for Test {
type BlockNumberToBalance = sp_runtime::traits::ConvertInto; type BlockNumberToBalance = sp_runtime::traits::ConvertInto;
type MinVestedTransfer = MinVestedTransfer; type MinVestedTransfer = MinVestedTransfer;
type WeightInfo = (); type WeightInfo = ();
type UnvestedFundsAllowedWithdrawReasons = UnvestedFundsAllowedWithdrawReasons; type UnvestedFundsAllowedWithdrawReasons =
UnvestedFundsAllowedWithdrawReasons;
type BlockNumberProvider = System; type BlockNumberProvider = System;
const MAX_VESTING_SCHEDULES: u32 = 28; const MAX_VESTING_SCHEDULES: u32 = 28;
} }
@ -208,7 +148,7 @@ impl pallet_ranked_collective::Config for Test {
type PromoteOrigin = EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>; type PromoteOrigin = EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>;
type DemoteOrigin = EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>; type DemoteOrigin = EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>;
type ExchangeOrigin = EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>; type ExchangeOrigin = EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>;
type Polls = TestPolls; type Polls = TestPolls;
type MemberSwappedHandler = (); type MemberSwappedHandler = ();
type MinRankOfClass = MinRankOfClass<MinRankOfClassDelta>; type MinRankOfClass = MinRankOfClass<MinRankOfClassDelta>;
@ -260,8 +200,8 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
(crate::mock::eth_keys::third_account_id(), 1000), (crate::mock::eth_keys::third_account_id(), 1000),
], ],
} }
.assimilate_storage(&mut t) .assimilate_storage(&mut t)
.unwrap(); .unwrap();
ghost_claims::GenesisConfig::<Test> { ghost_claims::GenesisConfig::<Test> {
total: crate::mock::eth_keys::total_claims(), total: crate::mock::eth_keys::total_claims(),
@ -270,8 +210,8 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
(crate::mock::eth_keys::third_account_id(), 3), (crate::mock::eth_keys::third_account_id(), 3),
], ],
} }
.assimilate_storage(&mut t) .assimilate_storage(&mut t)
.unwrap(); .unwrap();
let mut ext = sp_io::TestExternalities::new(t); let mut ext = sp_io::TestExternalities::new(t);
ext.execute_with(|| { ext.execute_with(|| {

View File

@ -8,8 +8,7 @@ pub fn public(secret: &libsecp256k1::SecretKey) -> libsecp256k1::PublicKey {
pub fn eth(secret: &libsecp256k1::SecretKey) -> EthereumAddress { pub fn eth(secret: &libsecp256k1::SecretKey) -> EthereumAddress {
let mut res = EthereumAddress::default(); let mut res = EthereumAddress::default();
res.0 res.0.copy_from_slice(&keccak_256(&public(secret).serialize()[1..65])[12..]);
.copy_from_slice(&keccak_256(&public(secret).serialize()[1..65])[12..]);
res res
} }
@ -19,14 +18,17 @@ pub fn into_account_id<T: Config<I>, I: 'static>(address: EthereumAddress) -> T:
} }
pub fn sig<T: Config<I>, I: 'static>( pub fn sig<T: Config<I>, I: 'static>(
secret: &libsecp256k1::SecretKey, secret: &libsecp256k1::SecretKey,
what: &[u8], what: &[u8],
) -> EcdsaSignature { ) -> EcdsaSignature {
let msg = keccak_256(&super::Pallet::<T, I>::ethereum_signable_message( let msg = keccak_256(&super::Pallet::<T, I>::ethereum_signable_message(
&crate::to_ascii_hex(what)[..], &crate::to_ascii_hex(what)[..],
)); ));
let (sig, recovery_id) = libsecp256k1::sign(&libsecp256k1::Message::parse(&msg), secret); let (sig, recovery_id) = libsecp256k1::sign(
&libsecp256k1::Message::parse(&msg),
secret,
);
let mut r = [0u8; 65]; let mut r = [0u8; 65];
r[0..64].copy_from_slice(&sig.serialize()[..]); r[0..64].copy_from_slice(&sig.serialize()[..]);

View File

@ -1,19 +1,21 @@
#![cfg(test)] #![cfg(test)]
use super::*;
use frame_support::{assert_err, assert_ok};
use hex_literal::hex;
use mock::{ use mock::{
new_test_ext, ghost_claims,
Test, System, Balances, Club, Vesting, Claims, RuntimeOrigin, RuntimeEvent,
eth_keys::{ eth_keys::{
alice_account_id, bob_account_id, first_account_id, first_eth_public_key, alice_account_id, total_claims, first_eth_public_known,
first_eth_public_known, first_signature, fourth_account_id, fourth_eth_public_key, first_eth_public_key, first_account_id, first_signature,
fourth_eth_public_known, fourth_signature, second_account_id, second_eth_public_key, second_eth_public_known, second_eth_public_key, second_account_id,
second_eth_public_known, second_signature, third_account_id, third_eth_public_key, second_signature, third_eth_public_known, third_eth_public_key,
third_eth_public_known, third_signature, total_claims, wrong_signature, third_account_id, third_signature, fourth_eth_public_known,
}, fourth_eth_public_key, fourth_account_id, fourth_signature,
ghost_claims, new_test_ext, Balances, Claims, Club, RuntimeEvent, RuntimeOrigin, System, Test, wrong_signature, bob_account_id,
Vesting, }
}; };
use hex_literal::hex;
use frame_support::{assert_err, assert_ok};
use super::*;
#[test] #[test]
fn serde_works() { fn serde_works() {
@ -39,12 +41,12 @@ fn basic_setup_works() {
assert_eq!(Balances::usable_balance(&first_account_id()), 10); assert_eq!(Balances::usable_balance(&first_account_id()), 10);
assert_eq!(Balances::usable_balance(&second_account_id()), 100); assert_eq!(Balances::usable_balance(&second_account_id()), 100);
assert_eq!(Balances::usable_balance(&third_account_id()), 1000); assert_eq!(Balances::usable_balance(&third_account_id()), 1000);
assert_eq!(Club::rank_of(&alice_account_id()), None); assert_eq!(Club::rank_of(&alice_account_id()), None);
assert_eq!(Club::rank_of(&first_account_id()), None); assert_eq!(Club::rank_of(&first_account_id()), None);
assert_eq!(Club::rank_of(&second_account_id()), Some(1)); assert_eq!(Club::rank_of(&second_account_id()), Some(1));
assert_eq!(Club::rank_of(&third_account_id()), Some(3)); assert_eq!(Club::rank_of(&third_account_id()), Some(3));
assert_eq!(Vesting::vesting_balance(&alice_account_id()), None); assert_eq!(Vesting::vesting_balance(&alice_account_id()), None);
assert_eq!(ghost_claims::Total::<Test, ()>::get(), total_claims()); assert_eq!(ghost_claims::Total::<Test, ()>::get(), total_claims());
}); });
@ -54,10 +56,9 @@ fn basic_setup_works() {
fn small_claiming_works() { fn small_claiming_works() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_ok!(Claims::claim( assert_ok!(Claims::claim(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
first_eth_public_key(), first_eth_public_key(),
first_signature() first_signature()));
));
assert_eq!(Balances::usable_balance(&alice_account_id()), 10); assert_eq!(Balances::usable_balance(&alice_account_id()), 10);
assert_eq!(Balances::usable_balance(&first_account_id()), 0); assert_eq!(Balances::usable_balance(&first_account_id()), 0);
@ -76,9 +77,9 @@ fn small_claiming_works() {
fn medium_claiming_works() { fn medium_claiming_works() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_ok!(Claims::claim( assert_ok!(Claims::claim(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
second_eth_public_key(), second_eth_public_key(),
second_signature(), second_signature(),
)); ));
assert_eq!(Balances::usable_balance(&alice_account_id()), 100); assert_eq!(Balances::usable_balance(&alice_account_id()), 100);
@ -98,9 +99,9 @@ fn medium_claiming_works() {
fn big_claiming_works() { fn big_claiming_works() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_ok!(Claims::claim( assert_ok!(Claims::claim(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
third_eth_public_key(), third_eth_public_key(),
third_signature(), third_signature(),
)); ));
assert_eq!(Balances::usable_balance(&alice_account_id()), 200); assert_eq!(Balances::usable_balance(&alice_account_id()), 200);
@ -112,15 +113,11 @@ fn big_claiming_works() {
assert_eq!(Club::rank_of(&third_account_id()), None); assert_eq!(Club::rank_of(&third_account_id()), None);
assert_eq!(Vesting::vesting_balance(&alice_account_id()), Some(800)); assert_eq!(Vesting::vesting_balance(&alice_account_id()), Some(800));
assert_eq!( assert_eq!(ghost_claims::Total::<Test, ()>::get(), total_claims() - 1000);
ghost_claims::Total::<Test, ()>::get(),
total_claims() - 1000
);
assert_ok!(Balances::transfer_allow_death( assert_ok!(Balances::transfer_allow_death(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
bob_account_id(), bob_account_id(),
200 200));
));
}) })
} }
@ -128,19 +125,19 @@ fn big_claiming_works() {
fn multiple_accounts_claiming_works() { fn multiple_accounts_claiming_works() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_ok!(Claims::claim( assert_ok!(Claims::claim(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
first_eth_public_key(), first_eth_public_key(),
first_signature(), first_signature(),
)); ));
assert_ok!(Claims::claim( assert_ok!(Claims::claim(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
second_eth_public_key(), second_eth_public_key(),
second_signature(), second_signature(),
)); ));
assert_ok!(Claims::claim( assert_ok!(Claims::claim(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
third_eth_public_key(), third_eth_public_key(),
third_signature(), third_signature(),
)); ));
assert_eq!(Balances::usable_balance(&alice_account_id()), 310); assert_eq!(Balances::usable_balance(&alice_account_id()), 310);
@ -160,19 +157,19 @@ fn multiple_accounts_claiming_works() {
fn multiple_accounts_reverese_claiming_works() { fn multiple_accounts_reverese_claiming_works() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_ok!(Claims::claim( assert_ok!(Claims::claim(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
third_eth_public_key(), third_eth_public_key(),
third_signature(), third_signature(),
)); ));
assert_ok!(Claims::claim( assert_ok!(Claims::claim(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
second_eth_public_key(), second_eth_public_key(),
second_signature(), second_signature(),
)); ));
assert_ok!(Claims::claim( assert_ok!(Claims::claim(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
first_eth_public_key(), first_eth_public_key(),
first_signature(), first_signature(),
)); ));
assert_eq!(Balances::usable_balance(&alice_account_id()), 310); assert_eq!(Balances::usable_balance(&alice_account_id()), 310);
@ -191,14 +188,11 @@ fn multiple_accounts_reverese_claiming_works() {
#[test] #[test]
fn cannot_claim_with_bad_signature() { fn cannot_claim_with_bad_signature() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_err!( assert_err!(Claims::claim(
Claims::claim(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
first_eth_public_key(), first_eth_public_key(),
wrong_signature() wrong_signature()),
), crate::Error::<Test>::InvalidEthereumAddress);
crate::Error::<Test>::InvalidEthereumAddress
);
assert_eq!(Balances::usable_balance(&alice_account_id()), 0); assert_eq!(Balances::usable_balance(&alice_account_id()), 0);
assert_eq!(Balances::usable_balance(&first_account_id()), 10); assert_eq!(Balances::usable_balance(&first_account_id()), 10);
@ -218,14 +212,11 @@ fn cannot_claim_with_bad_signature() {
#[test] #[test]
fn cannot_claim_with_wrong_address() { fn cannot_claim_with_wrong_address() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_err!( assert_err!(Claims::claim(
Claims::claim(
RuntimeOrigin::signed(bob_account_id()), RuntimeOrigin::signed(bob_account_id()),
first_eth_public_key(), first_eth_public_key(),
first_signature() first_signature()),
), crate::Error::<Test>::InvalidEthereumAddress);
crate::Error::<Test>::InvalidEthereumAddress
);
assert_eq!(Balances::usable_balance(&bob_account_id()), 0); assert_eq!(Balances::usable_balance(&bob_account_id()), 0);
assert_eq!(Balances::usable_balance(&alice_account_id()), 0); assert_eq!(Balances::usable_balance(&alice_account_id()), 0);
@ -246,14 +237,11 @@ fn cannot_claim_with_wrong_address() {
#[test] #[test]
fn cannot_claim_nothing() { fn cannot_claim_nothing() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
assert_err!( assert_err!(Claims::claim(
Claims::claim(
RuntimeOrigin::signed(bob_account_id()), RuntimeOrigin::signed(bob_account_id()),
fourth_eth_public_key(), fourth_eth_public_key(),
fourth_signature() fourth_signature()),
), crate::Error::<Test>::NoBalanceToClaim);
crate::Error::<Test>::NoBalanceToClaim
);
assert_eq!(Balances::usable_balance(&bob_account_id()), 0); assert_eq!(Balances::usable_balance(&bob_account_id()), 0);
assert_eq!(Balances::usable_balance(&fourth_account_id()), 0); assert_eq!(Balances::usable_balance(&fourth_account_id()), 0);
assert_eq!(Vesting::vesting_balance(&bob_account_id()), None); assert_eq!(Vesting::vesting_balance(&bob_account_id()), None);
@ -271,15 +259,16 @@ fn event_emitted_during_claim() {
System::reset_events(); System::reset_events();
assert_eq!(System::event_count(), 0); assert_eq!(System::event_count(), 0);
assert_ok!(Claims::claim( assert_ok!(Claims::claim(
RuntimeOrigin::signed(alice_account_id()), RuntimeOrigin::signed(alice_account_id()),
third_eth_public_key(), third_eth_public_key(),
third_signature(), third_signature(),
)); ));
System::assert_has_event(RuntimeEvent::Claims(crate::Event::Claimed { System::assert_has_event(RuntimeEvent::Claims(
receiver: alice_account_id(), crate::Event::Claimed {
donor: account, receiver: alice_account_id(),
amount, donor: account,
rank, amount,
})); rank,
}));
}) })
} }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-networks" name = "ghost-networks"
version = "0.1.12" version = "0.1.10"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true
edition.workspace = true edition.workspace = true

View File

@ -8,38 +8,26 @@ use sp_runtime::Saturating;
const MAX_NAME_LEN: u32 = 20; const MAX_NAME_LEN: u32 = 20;
const MAX_ENDPOINT_LEN: u32 = 150; const MAX_ENDPOINT_LEN: u32 = 150;
const MAX_ENDPOINT_NUMBER: u32 = 20;
fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) { fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
frame_system::Pallet::<T>::assert_last_event(generic_event.into()); frame_system::Pallet::<T>::assert_last_event(generic_event.into());
} }
fn prepare_network<T: Config>( fn prepare_network<T: Config>(
n: u32, n: u32, m: u32,
m: u32,
k: u32,
) -> (<T as module::Config>::NetworkId, NetworkData) { ) -> (<T as module::Config>::NetworkId, NetworkData) {
let chain_id: <T as module::Config>::NetworkId = Default::default(); let chain_id: <T as module::Config>::NetworkId = Default::default();
let chain_id = chain_id.saturating_add((n + m).into()); let chain_id = chain_id.saturating_add((n + m).into());
let mut gatekeeper = b"0x".to_vec(); let mut gatekeeper = b"0x".to_vec();
for i in 0..40 { for i in 0..40 { gatekeeper.push(i); }
gatekeeper.push(i);
}
let mut topic_name = b"0x".to_vec(); let mut topic_name = b"0x".to_vec();
for i in 0..64 { for i in 0..64 { topic_name.push(i); }
topic_name.push(i);
}
let mut default_endpoints = sp_std::vec![];
for _ in 0..(k as usize) {
default_endpoints.push(sp_std::vec![0x69; m as usize]);
}
let network = NetworkData { let network = NetworkData {
chain_name: sp_std::vec![0x69; n as usize], chain_name: sp_std::vec![0x69; n as usize],
default_endpoints, default_endpoint: sp_std::vec![0x69; m as usize],
gatekeeper, gatekeeper,
topic_name, topic_name,
network_type: NetworkType::Evm, network_type: NetworkType::Evm,
@ -63,11 +51,8 @@ fn create_network<T: Config>(
let authority = T::RegisterOrigin::try_successful_origin() let authority = T::RegisterOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
GhostNetworks::<T>::register_network( GhostNetworks::<T>::register_network(
authority.clone(), authority.clone(), chain_id.clone(), network.clone()
chain_id.clone(), ).map_err(|_| BenchmarkError::Weightless)?;
network.clone(),
)
.map_err(|_| BenchmarkError::Weightless)?;
network network
} }
}; };
@ -79,9 +64,8 @@ benchmarks! {
register_network { register_network {
let i in 1 .. MAX_NAME_LEN; let i in 1 .. MAX_NAME_LEN;
let j in 1 .. MAX_ENDPOINT_LEN; let j in 1 .. MAX_ENDPOINT_LEN;
let k in 1 .. MAX_ENDPOINT_NUMBER;
let (chain_id, network) = prepare_network::<T>(i, j, k); let (chain_id, network) = prepare_network::<T>(i, j);
let authority = T::RegisterOrigin::try_successful_origin() let authority = T::RegisterOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = GhostNetworks::<T>::networks(chain_id.clone()); let prev_network = GhostNetworks::<T>::networks(chain_id.clone());
@ -96,7 +80,7 @@ benchmarks! {
update_network_name { update_network_name {
let n in 1 .. MAX_NAME_LEN; let n in 1 .. MAX_NAME_LEN;
let name = sp_std::vec![0x42; n as usize]; let name = sp_std::vec![0x42; n as usize];
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 1);
let authority = T::UpdateOrigin::try_successful_origin() let authority = T::UpdateOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?; let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
@ -110,25 +94,22 @@ benchmarks! {
update_network_endpoint { update_network_endpoint {
let n in 1 .. MAX_ENDPOINT_LEN; let n in 1 .. MAX_ENDPOINT_LEN;
let index_to_update = 0u32;
let endpoint = sp_std::vec![0x42; n as usize]; let endpoint = sp_std::vec![0x42; n as usize];
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 1);
let authority = T::UpdateOrigin::try_successful_origin() let authority = T::UpdateOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?; let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
}: _<T::RuntimeOrigin>(authority, chain_id.clone(), Some(index_to_update), Some(endpoint.clone())) }: _<T::RuntimeOrigin>(authority, chain_id.clone(), endpoint.clone())
verify { verify {
assert_last_event::<T>(Event::NetworkEndpointUpdated { assert_last_event::<T>(Event::NetworkEndpointUpdated {
chain_id: chain_id.clone(), chain_id: chain_id.clone(), default_endpoint: endpoint,
index: index_to_update,
endpoint,
}.into()); }.into());
assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network); assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network);
} }
update_network_finality_delay { update_network_finality_delay {
let delay = 1337; let delay = 1337;
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 1);
let authority = T::UpdateOrigin::try_successful_origin() let authority = T::UpdateOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?; let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
@ -142,7 +123,7 @@ benchmarks! {
update_network_rate_limit_delay { update_network_rate_limit_delay {
let rate_limit = 1337; let rate_limit = 1337;
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 1);
let authority = T::UpdateOrigin::try_successful_origin() let authority = T::UpdateOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?; let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
@ -156,7 +137,7 @@ benchmarks! {
update_network_block_distance { update_network_block_distance {
let block_distance = 1337; let block_distance = 1337;
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 1);
let authority = T::UpdateOrigin::try_successful_origin() let authority = T::UpdateOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?; let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
@ -170,7 +151,7 @@ benchmarks! {
update_network_type { update_network_type {
let network_type = NetworkType::Utxo; let network_type = NetworkType::Utxo;
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 1);
let authority = T::UpdateOrigin::try_successful_origin() let authority = T::UpdateOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?; let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
@ -185,7 +166,7 @@ benchmarks! {
update_network_gatekeeper { update_network_gatekeeper {
let mut gatekeeper = b"0x".to_vec(); let mut gatekeeper = b"0x".to_vec();
for i in 0..40 { gatekeeper.push(i + 1); } for i in 0..40 { gatekeeper.push(i + 1); }
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 1);
let authority = T::UpdateOrigin::try_successful_origin() let authority = T::UpdateOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?; let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
@ -199,7 +180,7 @@ benchmarks! {
update_network_topic_name { update_network_topic_name {
let topic_name = b"0x9876543219876543219876543219876543219876543219876543219876543219".to_vec(); let topic_name = b"0x9876543219876543219876543219876543219876543219876543219876543219".to_vec();
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 1);
let authority = T::UpdateOrigin::try_successful_origin() let authority = T::UpdateOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?; let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
@ -213,7 +194,7 @@ benchmarks! {
update_incoming_network_fee { update_incoming_network_fee {
let incoming_fee = 1337; let incoming_fee = 1337;
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 1);
let authority = T::UpdateOrigin::try_successful_origin() let authority = T::UpdateOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?; let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
@ -227,7 +208,7 @@ benchmarks! {
update_outgoing_network_fee { update_outgoing_network_fee {
let outgoing_fee = 1337; let outgoing_fee = 1337;
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 1);
let authority = T::UpdateOrigin::try_successful_origin() let authority = T::UpdateOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?; let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
@ -240,7 +221,7 @@ benchmarks! {
} }
remove_network { remove_network {
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 1);
let authority = T::RemoveOrigin::try_successful_origin() let authority = T::RemoveOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?; .map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?; let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;

View File

@ -4,27 +4,27 @@
use frame_support::{ use frame_support::{
pallet_prelude::*, pallet_prelude::*,
storage::PrefixIterator, storage::PrefixIterator, traits::{tokens::fungible::Inspect, EnsureOrigin},
traits::{tokens::fungible::Inspect, EnsureOrigin},
}; };
use frame_system::pallet_prelude::*; use frame_system::pallet_prelude::*;
use scale_info::TypeInfo; use scale_info::TypeInfo;
use sp_runtime::{ use sp_runtime::{
traits::{CheckedSub, CheckedAdd, AtLeast32BitUnsigned, Member},
curve::PiecewiseLinear, curve::PiecewiseLinear,
traits::{AtLeast32BitUnsigned, CheckedAdd, CheckedSub, Member},
DispatchResult, DispatchResult,
}; };
use sp_std::{convert::TryInto, prelude::*}; use sp_std::{prelude::*, convert::TryInto};
pub use ghost_traits::networks::{ pub use ghost_traits::networks::{
NetworkDataBasicHandler, NetworkDataInspectHandler, NetworkDataMutateHandler, NetworkDataBasicHandler, NetworkDataInspectHandler,
NetworkDataMutateHandler,
}; };
mod weights; mod weights;
pub use crate::weights::WeightInfo;
pub use module::*; pub use module::*;
pub use crate::weights::WeightInfo;
#[cfg(any(feature = "runtime-benchmarks", test))] #[cfg(any(feature = "runtime-benchmarks", test))]
mod benchmarking; mod benchmarking;
@ -33,8 +33,9 @@ mod mock;
#[cfg(all(feature = "std", test))] #[cfg(all(feature = "std", test))]
mod tests; mod tests;
pub type BalanceOf<T> = pub type BalanceOf<T> = <<T as Config>::Currency as Inspect<
<<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance; <T as frame_system::Config>::AccountId,
>>::Balance;
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
pub enum NetworkType { pub enum NetworkType {
@ -44,15 +45,13 @@ pub enum NetworkType {
} }
impl Default for NetworkType { impl Default for NetworkType {
fn default() -> Self { fn default() -> Self { NetworkType::Evm }
NetworkType::Evm
}
} }
#[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] #[derive(Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
pub struct NetworkData { pub struct NetworkData {
pub chain_name: Vec<u8>, pub chain_name: Vec<u8>,
pub default_endpoints: Vec<Vec<u8>>, pub default_endpoint: Vec<u8>,
pub gatekeeper: Vec<u8>, pub gatekeeper: Vec<u8>,
pub topic_name: Vec<u8>, pub topic_name: Vec<u8>,
pub network_type: NetworkType, pub network_type: NetworkType,
@ -70,8 +69,7 @@ pub struct BridgeAdjustment<Balance> {
} }
pub struct BridgedInflationCurve<RewardCurve, T>(core::marker::PhantomData<(RewardCurve, T)>); pub struct BridgedInflationCurve<RewardCurve, T>(core::marker::PhantomData<(RewardCurve, T)>);
impl<Balance, RewardCurve, T> pallet_staking::EraPayout<Balance> impl<Balance, RewardCurve, T> pallet_staking::EraPayout<Balance> for BridgedInflationCurve<RewardCurve, T>
for BridgedInflationCurve<RewardCurve, T>
where where
Balance: Default + AtLeast32BitUnsigned + Clone + Copy + From<u128>, Balance: Default + AtLeast32BitUnsigned + Clone + Copy + From<u128>,
RewardCurve: Get<&'static PiecewiseLinear<'static>>, RewardCurve: Get<&'static PiecewiseLinear<'static>>,
@ -101,11 +99,10 @@ where
match piecewise_linear match piecewise_linear
.calculate_for_fraction_times_denominator(total_staked, adjusted_issuance) .calculate_for_fraction_times_denominator(total_staked, adjusted_issuance)
.checked_mul(&accumulated_balance) .checked_mul(&accumulated_balance)
.and_then(|product| product.checked_div(&adjusted_issuance)) .and_then(|product| product.checked_div(&adjusted_issuance)) {
{ Some(payout) => (payout, accumulated_balance.saturating_sub(payout)),
Some(payout) => (payout, accumulated_balance.saturating_sub(payout)), None => (Balance::default(), Balance::default()),
None => (Balance::default(), Balance::default()), }
}
} }
} }
@ -131,7 +128,7 @@ pub mod module {
+ TypeInfo + TypeInfo
+ MaybeSerializeDeserialize + MaybeSerializeDeserialize
+ MaxEncodedLen; + MaxEncodedLen;
/// The origin required to register new network. /// The origin required to register new network.
type RegisterOrigin: EnsureOrigin<Self::RuntimeOrigin>; type RegisterOrigin: EnsureOrigin<Self::RuntimeOrigin>;
/// The origin required to update network information. /// The origin required to update network information.
@ -158,62 +155,18 @@ pub mod module {
#[pallet::event] #[pallet::event]
#[pallet::generate_deposit(pub(crate) fn deposit_event)] #[pallet::generate_deposit(pub(crate) fn deposit_event)]
pub enum Event<T: Config> { pub enum Event<T: Config> {
NetworkRegistered { NetworkRegistered { chain_id: T::NetworkId, network: NetworkData },
chain_id: T::NetworkId, NetworkNameUpdated { chain_id: T::NetworkId, chain_name: Vec<u8> },
network: NetworkData, NetworkEndpointUpdated { chain_id: T::NetworkId, default_endpoint: Vec<u8> },
}, NetworkFinalityDelayUpdated { chain_id: T::NetworkId, finality_delay: u64 },
NetworkNameUpdated { NetworkRateLimitDelayUpdated { chain_id: T::NetworkId, rate_limit_delay: u64 },
chain_id: T::NetworkId, NetworkBlockDistanceUpdated { chain_id: T::NetworkId, block_distance: u64 },
chain_name: Vec<u8>, NetworkTypeUpdated { chain_id: T::NetworkId, network_type: NetworkType },
}, NetworkGatekeeperUpdated { chain_id: T::NetworkId, gatekeeper: Vec<u8> },
NetworkEndpointUpdated { NetworkTopicNameUpdated { chain_id: T::NetworkId, topic_name: Vec<u8> },
chain_id: T::NetworkId, NetworkIncomingFeeUpdated { chain_id: T::NetworkId, incoming_fee: u32 },
index: u32, NetworkOutgoingFeeUpdated { chain_id: T::NetworkId, outgoing_fee: u32 },
endpoint: Vec<u8>, NetworkRemoved { chain_id: T::NetworkId },
},
NetworkEndpointRemoved {
chain_id: T::NetworkId,
index: u32,
},
NetworkEndpointAdded {
chain_id: T::NetworkId,
endpoint: Vec<u8>,
},
NetworkFinalityDelayUpdated {
chain_id: T::NetworkId,
finality_delay: u64,
},
NetworkRateLimitDelayUpdated {
chain_id: T::NetworkId,
rate_limit_delay: u64,
},
NetworkBlockDistanceUpdated {
chain_id: T::NetworkId,
block_distance: u64,
},
NetworkTypeUpdated {
chain_id: T::NetworkId,
network_type: NetworkType,
},
NetworkGatekeeperUpdated {
chain_id: T::NetworkId,
gatekeeper: Vec<u8>,
},
NetworkTopicNameUpdated {
chain_id: T::NetworkId,
topic_name: Vec<u8>,
},
NetworkIncomingFeeUpdated {
chain_id: T::NetworkId,
incoming_fee: u32,
},
NetworkOutgoingFeeUpdated {
chain_id: T::NetworkId,
outgoing_fee: u32,
},
NetworkRemoved {
chain_id: T::NetworkId,
},
} }
#[pallet::storage] #[pallet::storage]
@ -227,7 +180,8 @@ pub mod module {
#[pallet::storage] #[pallet::storage]
#[pallet::getter(fn accumulated_commission)] #[pallet::getter(fn accumulated_commission)]
pub type AccumulatedCommission<T: Config> = StorageValue<_, BalanceOf<T>, ValueQuery>; pub type AccumulatedCommission<T: Config> =
StorageValue<_, BalanceOf<T>, ValueQuery>;
#[pallet::storage] #[pallet::storage]
#[pallet::getter(fn networks)] #[pallet::getter(fn networks)]
@ -236,8 +190,13 @@ pub mod module {
#[pallet::storage] #[pallet::storage]
#[pallet::getter(fn gatekeeper_amount)] #[pallet::getter(fn gatekeeper_amount)]
pub type GatekeeperAmount<T: Config> = pub type GatekeeperAmount<T: Config> = StorageMap<
StorageMap<_, Twox64Concat, T::NetworkId, BalanceOf<T>, ValueQuery>; _,
Twox64Concat,
T::NetworkId,
BalanceOf<T>,
ValueQuery,
>;
#[pallet::genesis_config] #[pallet::genesis_config]
pub struct GenesisConfig<T: Config> { pub struct GenesisConfig<T: Config> {
@ -246,7 +205,7 @@ pub mod module {
impl<T: Config> Default for GenesisConfig<T> { impl<T: Config> Default for GenesisConfig<T> {
fn default() -> Self { fn default() -> Self {
Self { networks: vec![] } Self { networks: vec![] }
} }
} }
@ -254,13 +213,12 @@ pub mod module {
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> { impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
fn build(&self) { fn build(&self) {
if !self.networks.is_empty() { if !self.networks.is_empty() {
self.networks self.networks.iter().for_each(|(chain_id, network_metadata)| {
.iter() let network =
.for_each(|(chain_id, network_metadata)| { NetworkData::decode(&mut &network_metadata[..])
let network = NetworkData::decode(&mut &network_metadata[..]) .expect("Error decoding NetworkData");
.expect("Error decoding NetworkData"); Pallet::<T>::do_register_network(chain_id.clone(), network)
Pallet::<T>::do_register_network(chain_id.clone(), network) .expect("Error registering network");
.expect("Error registering network");
}); });
} }
} }
@ -289,10 +247,7 @@ pub mod module {
#[pallet::call_index(0)] #[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::register_network( #[pallet::weight(T::WeightInfo::register_network(
network.chain_name.len() as u32, network.chain_name.len() as u32,
network.default_endpoints network.default_endpoint.len() as u32,
.iter()
.map(|endpoint| endpoint.len())
.sum::<usize>() as u32,
))] ))]
pub fn register_network( pub fn register_network(
origin: OriginFor<T>, origin: OriginFor<T>,
@ -313,24 +268,26 @@ pub mod module {
chain_name: Vec<u8>, chain_name: Vec<u8>,
) -> DispatchResult { ) -> DispatchResult {
T::UpdateOrigin::ensure_origin_or_root(origin)?; T::UpdateOrigin::ensure_origin_or_root(origin)?;
Self::do_update_network_name(chain_id, chain_name) Self::do_update_network_name(
chain_id,
chain_name,
)
} }
#[pallet::call_index(2)] #[pallet::call_index(2)]
#[pallet::weight(T::WeightInfo::update_network_endpoint( #[pallet::weight(T::WeightInfo::update_network_endpoint(
maybe_endpoint default_endpoint.len() as u32
.as_ref()
.map(|endpoint| endpoint.len())
.unwrap_or_default() as u32
))] ))]
pub fn update_network_endpoint( pub fn update_network_endpoint(
origin: OriginFor<T>, origin: OriginFor<T>,
chain_id: T::NetworkId, chain_id: T::NetworkId,
maybe_index: Option<u32>, default_endpoint: Vec<u8>,
maybe_endpoint: Option<Vec<u8>>,
) -> DispatchResult { ) -> DispatchResult {
T::UpdateOrigin::ensure_origin_or_root(origin)?; T::UpdateOrigin::ensure_origin_or_root(origin)?;
Self::do_update_network_endpoint(chain_id, maybe_index, maybe_endpoint) Self::do_update_network_endpoint(
chain_id,
default_endpoint,
)
} }
#[pallet::call_index(3)] #[pallet::call_index(3)]
@ -341,7 +298,10 @@ pub mod module {
finality_delay: u64, finality_delay: u64,
) -> DispatchResult { ) -> DispatchResult {
T::UpdateOrigin::ensure_origin_or_root(origin)?; T::UpdateOrigin::ensure_origin_or_root(origin)?;
Self::do_update_network_finality_delay(chain_id, finality_delay) Self::do_update_network_finality_delay(
chain_id,
finality_delay,
)
} }
#[pallet::call_index(4)] #[pallet::call_index(4)]
@ -352,7 +312,10 @@ pub mod module {
rate_limit_delay: u64, rate_limit_delay: u64,
) -> DispatchResult { ) -> DispatchResult {
T::UpdateOrigin::ensure_origin_or_root(origin)?; T::UpdateOrigin::ensure_origin_or_root(origin)?;
Self::do_update_network_rate_limit_delay(chain_id, rate_limit_delay) Self::do_update_network_rate_limit_delay(
chain_id,
rate_limit_delay,
)
} }
#[pallet::call_index(5)] #[pallet::call_index(5)]
@ -363,7 +326,10 @@ pub mod module {
block_distance: u64, block_distance: u64,
) -> DispatchResult { ) -> DispatchResult {
T::UpdateOrigin::ensure_origin_or_root(origin)?; T::UpdateOrigin::ensure_origin_or_root(origin)?;
Self::do_update_network_block_distance(chain_id, block_distance) Self::do_update_network_block_distance(
chain_id,
block_distance,
)
} }
#[pallet::call_index(6)] #[pallet::call_index(6)]
@ -374,7 +340,10 @@ pub mod module {
network_type: NetworkType, network_type: NetworkType,
) -> DispatchResult { ) -> DispatchResult {
T::UpdateOrigin::ensure_origin_or_root(origin)?; T::UpdateOrigin::ensure_origin_or_root(origin)?;
Self::do_update_network_type(chain_id, network_type) Self::do_update_network_type(
chain_id,
network_type,
)
} }
#[pallet::call_index(7)] #[pallet::call_index(7)]
@ -385,7 +354,10 @@ pub mod module {
gatekeeper: Vec<u8>, gatekeeper: Vec<u8>,
) -> DispatchResult { ) -> DispatchResult {
T::UpdateOrigin::ensure_origin_or_root(origin)?; T::UpdateOrigin::ensure_origin_or_root(origin)?;
Self::do_update_network_gatekeeper(chain_id, gatekeeper) Self::do_update_network_gatekeeper(
chain_id,
gatekeeper,
)
} }
#[pallet::call_index(8)] #[pallet::call_index(8)]
@ -396,7 +368,10 @@ pub mod module {
topic_name: Vec<u8>, topic_name: Vec<u8>,
) -> DispatchResult { ) -> DispatchResult {
T::UpdateOrigin::ensure_origin_or_root(origin)?; T::UpdateOrigin::ensure_origin_or_root(origin)?;
Self::do_update_network_topic_name(chain_id, topic_name) Self::do_update_network_topic_name(
chain_id,
topic_name,
)
} }
#[pallet::call_index(9)] #[pallet::call_index(9)]
@ -407,7 +382,10 @@ pub mod module {
incoming_fee: u32, incoming_fee: u32,
) -> DispatchResult { ) -> DispatchResult {
T::UpdateOrigin::ensure_origin_or_root(origin)?; T::UpdateOrigin::ensure_origin_or_root(origin)?;
Self::do_update_incoming_network_fee(chain_id, incoming_fee) Self::do_update_incoming_network_fee(
chain_id,
incoming_fee,
)
} }
#[pallet::call_index(10)] #[pallet::call_index(10)]
@ -418,12 +396,18 @@ pub mod module {
outgoing_fee: u32, outgoing_fee: u32,
) -> DispatchResult { ) -> DispatchResult {
T::UpdateOrigin::ensure_origin_or_root(origin)?; T::UpdateOrigin::ensure_origin_or_root(origin)?;
Self::do_update_outgoing_network_fee(chain_id, outgoing_fee) Self::do_update_outgoing_network_fee(
chain_id,
outgoing_fee,
)
} }
#[pallet::call_index(11)] #[pallet::call_index(11)]
#[pallet::weight(T::WeightInfo::remove_network())] #[pallet::weight(T::WeightInfo::remove_network())]
pub fn remove_network(origin: OriginFor<T>, chain_id: T::NetworkId) -> DispatchResult { pub fn remove_network(
origin: OriginFor<T>,
chain_id: T::NetworkId,
) -> DispatchResult {
T::RemoveOrigin::ensure_origin_or_root(origin)?; T::RemoveOrigin::ensure_origin_or_root(origin)?;
Self::do_remove_network(chain_id) Self::do_remove_network(chain_id)
} }
@ -432,12 +416,12 @@ pub mod module {
impl<T: Config> Pallet<T> { impl<T: Config> Pallet<T> {
/// Register a new network. /// Register a new network.
pub fn do_register_network(chain_id: T::NetworkId, network: NetworkData) -> DispatchResult { pub fn do_register_network(
chain_id: T::NetworkId,
network: NetworkData,
) -> DispatchResult {
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult { Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
ensure!( ensure!(maybe_network.is_none(), Error::<T>::NetworkAlreadyRegistered);
maybe_network.is_none(),
Error::<T>::NetworkAlreadyRegistered
);
*maybe_network = Some(network.clone()); *maybe_network = Some(network.clone());
Ok(()) Ok(())
})?; })?;
@ -459,7 +443,10 @@ impl<T: Config> Pallet<T> {
} }
/// Update existent network name. /// Update existent network name.
pub fn do_update_network_name(chain_id: T::NetworkId, chain_name: Vec<u8>) -> DispatchResult { pub fn do_update_network_name(
chain_id: T::NetworkId,
chain_name: Vec<u8>,
) -> DispatchResult {
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult { Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist); ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
let net = maybe_network.as_mut().unwrap(); let net = maybe_network.as_mut().unwrap();
@ -478,38 +465,19 @@ impl<T: Config> Pallet<T> {
/// Update existent network default endpoint. /// Update existent network default endpoint.
pub fn do_update_network_endpoint( pub fn do_update_network_endpoint(
chain_id: T::NetworkId, chain_id: T::NetworkId,
maybe_index: Option<u32>, default_endpoint: Vec<u8>,
maybe_endpoint: Option<Vec<u8>>,
) -> DispatchResult { ) -> DispatchResult {
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult { Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist); ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
let updated_network = maybe_network.as_mut().unwrap(); let net = maybe_network.as_mut().unwrap();
match (maybe_index, maybe_endpoint) { net.default_endpoint = default_endpoint.clone();
(Some(index), Some(endpoint)) => { *maybe_network = Some(net.clone());
if let Some(previous_endpoint) =
updated_network.default_endpoints.get_mut(index as usize)
{
*previous_endpoint = endpoint.clone();
Self::deposit_event(Event::<T>::NetworkEndpointUpdated {
chain_id,
index,
endpoint,
});
}
}
(None, Some(endpoint)) => {
updated_network.default_endpoints.push(endpoint.clone());
Self::deposit_event(Event::<T>::NetworkEndpointAdded { chain_id, endpoint });
}
(Some(index), None) => {
updated_network.default_endpoints.remove(index as usize);
Self::deposit_event(Event::<T>::NetworkEndpointRemoved { chain_id, index });
}
(None, None) => {}
}
*maybe_network = Some(updated_network.clone());
Ok(()) Ok(())
})?; })?;
Self::deposit_event(Event::<T>::NetworkEndpointUpdated {
chain_id,
default_endpoint,
});
Ok(()) Ok(())
} }
@ -594,10 +562,8 @@ impl<T: Config> Pallet<T> {
chain_id: T::NetworkId, chain_id: T::NetworkId,
gatekeeper: Vec<u8>, gatekeeper: Vec<u8>,
) -> DispatchResult { ) -> DispatchResult {
ensure!( ensure!(gatekeeper.len() == 42 && gatekeeper[0] == 48 && gatekeeper[1] == 120,
gatekeeper.len() == 42 && gatekeeper[0] == 48 && gatekeeper[1] == 120, Error::<T>::WrongGatekeeperAddress);
Error::<T>::WrongGatekeeperAddress
);
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult { Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist); ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
let net = maybe_network.as_mut().unwrap(); let net = maybe_network.as_mut().unwrap();
@ -617,10 +583,8 @@ impl<T: Config> Pallet<T> {
chain_id: T::NetworkId, chain_id: T::NetworkId,
topic_name: Vec<u8>, topic_name: Vec<u8>,
) -> DispatchResult { ) -> DispatchResult {
ensure!( ensure!(topic_name.len() == 66 && topic_name[0] == 48 && topic_name[1] == 120,
topic_name.len() == 66 && topic_name[0] == 48 && topic_name[1] == 120, Error::<T>::WrongTopicName);
Error::<T>::WrongTopicName
);
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult { Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist); ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
let net = maybe_network.as_mut().unwrap(); let net = maybe_network.as_mut().unwrap();
@ -703,16 +667,15 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
network_id: &T::NetworkId, network_id: &T::NetworkId,
amount: &BalanceOf<T>, amount: &BalanceOf<T>,
) -> Result<BalanceOf<T>, ()> { ) -> Result<BalanceOf<T>, ()> {
let new_gatekeeper_amount = let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| match gatekeeper_amount match gatekeeper_amount.checked_add(amount) {
.checked_add(amount)
{
Some(value) => { Some(value) => {
*gatekeeper_amount = value; *gatekeeper_amount = value;
Ok(value) Ok(value)
} },
None => Err(()), None => Err(())
})?; }
})?;
Ok(new_gatekeeper_amount) Ok(new_gatekeeper_amount)
} }
@ -721,29 +684,28 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
network_id: &T::NetworkId, network_id: &T::NetworkId,
amount: &BalanceOf<T>, amount: &BalanceOf<T>,
) -> Result<BalanceOf<T>, ()> { ) -> Result<BalanceOf<T>, ()> {
let new_gatekeeper_amount = let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| match gatekeeper_amount match gatekeeper_amount.checked_sub(amount) {
.checked_sub(amount)
{
Some(value) => { Some(value) => {
*gatekeeper_amount = value; *gatekeeper_amount = value;
Ok(value) Ok(value)
} },
None => Err(()), None => Err(())
})?; }
})?;
Ok(new_gatekeeper_amount) Ok(new_gatekeeper_amount)
} }
fn accumulate_outgoing_imbalance(amount: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> { fn accumulate_outgoing_imbalance(amount: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
let new_bridged_out_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| { let new_bridged_out_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
match bridged_imbalance.bridged_out.checked_add(amount) { match bridged_imbalance.bridged_out.checked_add(amount) {
Some(value) => { Some(value) => {
(*bridged_imbalance).bridged_out = value; (*bridged_imbalance).bridged_out = value;
Ok(value) Ok(value)
} },
None => Err(()), None => Err(())
} }
})?; })?;
Ok(new_bridged_out_amount) Ok(new_bridged_out_amount)
@ -755,8 +717,8 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
Some(value) => { Some(value) => {
(*bridged_imbalance).bridged_in = value; (*bridged_imbalance).bridged_in = value;
Ok(value) Ok(value)
} },
None => Err(()), None => Err(())
} }
})?; })?;
@ -769,7 +731,7 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
Some(value) => { Some(value) => {
*accumulated = value; *accumulated = value;
Ok(value) Ok(value)
} },
None => Err(()), None => Err(()),
} }
}) })

View File

@ -1,16 +1,17 @@
use crate::{self as ghost_networks}; use crate::{self as ghost_networks};
use frame_system::EnsureSignedBy;
use frame_support::{ use frame_support::{
construct_runtime, ord_parameter_types, parameter_types, construct_runtime, ord_parameter_types, parameter_types,
traits::{ConstU128, ConstU32, Everything}, traits::{ConstU128, ConstU32, Everything},
}; };
use frame_system::EnsureSignedBy;
pub use primitives::{ pub use primitives::{
AccountId, Balance, BlockNumber, FreezeIdentifier, Hash, Nonce, ReserveIdentifier, AccountId, Balance, Nonce, BlockNumber, Hash,
ReserveIdentifier, FreezeIdentifier,
}; };
use sp_runtime::{ use sp_runtime::{
curve::PiecewiseLinear, curve::PiecewiseLinear,
traits::{AccountIdLookup, BlakeTwo256}, traits::{AccountIdLookup, BlakeTwo256},
BuildStorage, BuildStorage
}; };
parameter_types! { parameter_types! {
@ -95,9 +96,9 @@ impl ghost_networks::Config for Test {
type RuntimeEvent = RuntimeEvent; type RuntimeEvent = RuntimeEvent;
type Currency = Balances; type Currency = Balances;
type NetworkId = u32; type NetworkId = u32;
type RegisterOrigin = EnsureSignedBy<RegistererAccount, AccountId>; type RegisterOrigin = EnsureSignedBy::<RegistererAccount, AccountId>;
type UpdateOrigin = EnsureSignedBy<UpdaterAccount, AccountId>; type UpdateOrigin = EnsureSignedBy::<UpdaterAccount, AccountId>;
type RemoveOrigin = EnsureSignedBy<RemoverAccount, AccountId>; type RemoveOrigin = EnsureSignedBy::<RemoverAccount, AccountId>;
type WeightInfo = crate::weights::SubstrateWeight<Test>; type WeightInfo = crate::weights::SubstrateWeight<Test>;
} }

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -3,8 +3,8 @@
use super::*; use super::*;
use frame_benchmarking::v1::*; use frame_benchmarking::v1::*;
use frame_support::traits::fungible::Inspect;
use frame_system::RawOrigin; use frame_system::RawOrigin;
use frame_support::traits::fungible::Inspect;
pub fn create_account<T: Config>() -> T::AccountId { pub fn create_account<T: Config>() -> T::AccountId {
let account_bytes = Vec::from([1u8; 32]); let account_bytes = Vec::from([1u8; 32]);

View File

@ -1,57 +0,0 @@
use crate::{Deserialize, Deserializer, Vec, H256};
pub fn de_string_to_bytes<'de, D>(de: D) -> Result<Option<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
Ok(Some(s.as_bytes().to_vec()))
}
pub fn de_string_to_u64<'de, D>(de: D) -> Result<Option<u64>, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
let s = if s.starts_with("0x") { &s[2..] } else { &s };
Ok(u64::from_str_radix(s, 16).ok())
}
pub fn de_string_to_u64_pure<'de, D>(de: D) -> Result<u64, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
let s = if s.starts_with("0x") { &s[2..] } else { &s };
Ok(u64::from_str_radix(s, 16).unwrap_or_default())
}
pub fn de_string_to_h256<'de, D>(de: D) -> Result<Option<H256>, D::Error>
where
D: Deserializer<'de>,
{
let s: &str = Deserialize::deserialize(de)?;
let start_index = if s.starts_with("0x") { 2 } else { 0 };
let h256: Vec<_> = (start_index..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("valid u8 symbol; qed"))
.collect();
Ok(Some(H256::from_slice(&h256)))
}
pub fn de_string_to_vec_of_bytes<'de, D>(de: D) -> Result<Vec<Vec<u8>>, D::Error>
where
D: Deserializer<'de>,
{
let strings: Vec<&str> = Deserialize::deserialize(de)?;
Ok(strings
.iter()
.map(|s| {
let start_index = if s.starts_with("0x") { 2 } else { 0 };
(start_index..s.len())
.step_by(2)
.map(|i| u8::from_str_radix(&s[i..i + 2], 16).expect("valid u8 symbol; qed"))
.collect::<Vec<u8>>()
})
.collect::<Vec<Vec<u8>>>())
}

View File

@ -1,49 +0,0 @@
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,
},
Decode, Deserialize, Encode, RuntimeDebug, Vec, H256,
};
const NUMBER_OF_TOPICS: usize = 3;
#[derive(RuntimeDebug, Clone, PartialEq, Deserialize, Encode, Decode)]
pub struct EvmResponse {
#[serde(default)]
id: Option<u32>,
#[serde(default, deserialize_with = "de_string_to_bytes")]
jsonrpc: Option<Vec<u8>>,
#[serde(default, deserialize_with = "de_string_to_bytes")]
pub error: Option<Vec<u8>>,
#[serde(default)]
pub result: Option<EvmResponseType>,
}
#[derive(RuntimeDebug, Clone, PartialEq, Deserialize, Encode, Decode)]
#[serde(untagged)]
pub enum EvmResponseType {
#[serde(deserialize_with = "de_string_to_u64_pure")]
BlockNumber(u64),
TransactionLogs(Vec<Log>),
}
#[derive(RuntimeDebug, Clone, Eq, PartialEq, Ord, PartialOrd, Deserialize, Encode, Decode)]
#[serde(rename_all = "camelCase")]
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_vec_of_bytes")]
pub topics: Vec<Vec<u8>>,
pub removed: bool,
}
impl Log {
pub fn is_sufficient(&self) -> bool {
self.transaction_hash.is_some()
&& self.block_number.is_some()
&& self.topics.len() == NUMBER_OF_TOPICS
}
}

File diff suppressed because it is too large Load Diff

View File

@ -2,15 +2,13 @@
use frame_support::{ use frame_support::{
derive_impl, parameter_types, derive_impl, parameter_types,
traits::{ConstU32, ConstU64}, traits::{ConstU32, ConstU64}, weights::Weight,
weights::Weight,
}; };
use frame_system::EnsureRoot; use frame_system::EnsureRoot;
use pallet_session::historical as pallet_session_historical; use pallet_session::historical as pallet_session_historical;
use sp_runtime::{ use sp_runtime::{
curve::PiecewiseLinear,
testing::{TestXt, UintAuthorityId}, testing::{TestXt, UintAuthorityId},
traits::ConvertInto, traits::ConvertInto, curve::PiecewiseLinear,
Permill, Permill,
}; };
use sp_staking::{ use sp_staking::{
@ -38,8 +36,8 @@ frame_support::construct_runtime!(
parameter_types! { parameter_types! {
pub static Validators: Option<Vec<u64>> = Some(vec![ pub static Validators: Option<Vec<u64>> = Some(vec![
1, 1,
2, 2,
3, 3,
]); ]);
} }
@ -55,10 +53,13 @@ impl pallet_session::SessionManager<u64> for TestSessionManager {
impl pallet_session::historical::SessionManager<u64, u64> for TestSessionManager { impl pallet_session::historical::SessionManager<u64, u64> for TestSessionManager {
fn new_session(_new_index: SessionIndex) -> Option<Vec<(u64, u64)>> { fn new_session(_new_index: SessionIndex) -> Option<Vec<(u64, u64)>> {
Validators::mutate(|l| { Validators::mutate(|l| l
l.take() .take()
.map(|validators| validators.iter().map(|v| (*v, *v)).collect()) .map(|validators| validators
}) .iter()
.map(|v| (*v, *v))
.collect())
)
} }
fn end_session(_: SessionIndex) {} fn end_session(_: SessionIndex) {}
fn start_session(_: SessionIndex) {} fn start_session(_: SessionIndex) {}
@ -93,10 +94,11 @@ pub fn new_test_ext() -> sp_io::TestExternalities {
result.execute_with(|| { result.execute_with(|| {
for i in 1..=3 { for i in 1..=3 {
System::inc_providers(&i); System::inc_providers(&i);
assert_eq!( assert_eq!(Session::set_keys(
Session::set_keys(RuntimeOrigin::signed(i), i.into(), vec![],), RuntimeOrigin::signed(i),
Ok(()) i.into(),
); vec![],
), Ok(()));
} }
}); });
@ -148,7 +150,7 @@ impl frame_support::traits::EstimateNextSessionRotation<u64> for TestNextSession
} }
fn estimate_current_session_progress(now: u64) -> (Option<Permill>, Weight) { fn estimate_current_session_progress(now: u64) -> (Option<Permill>, Weight) {
let (estimate, weight) = let (estimate, weight) =
pallet_session::PeriodicSessions::<Period, Offset>::estimate_current_session_progress( pallet_session::PeriodicSessions::<Period, Offset>::estimate_current_session_progress(
now, now,
); );
@ -255,7 +257,8 @@ pub fn advance_session_with_authority(authority: u64) {
UintAuthorityId::from(69), UintAuthorityId::from(69),
UintAuthorityId::from(420), UintAuthorityId::from(420),
UintAuthorityId::from(1337), UintAuthorityId::from(1337),
], ]
); );
assert_eq!(session_index, (now / Period::get()) as u32); assert_eq!(session_index, (now / Period::get()) as u32);
} }

View File

@ -7,9 +7,9 @@ use frame_support::{assert_err, assert_ok, dispatch};
use sp_core::offchain::{ use sp_core::offchain::{
testing, testing,
testing::{TestOffchainExt, TestTransactionPoolExt}, testing::{TestOffchainExt, TestTransactionPoolExt},
OffchainDbExt, OffchainWorkerExt, TransactionPoolExt, OffchainWorkerExt, OffchainDbExt, TransactionPoolExt,
}; };
use sp_runtime::{testing::UintAuthorityId, DispatchError}; use sp_runtime::{DispatchError, testing::UintAuthorityId};
use ghost_networks::BridgedInflationCurve; use ghost_networks::BridgedInflationCurve;
use pallet_staking::EraPayout; use pallet_staking::EraPayout;
@ -36,8 +36,7 @@ fn prepare_evm_network(
assert_ok!(Networks::register_network( assert_ok!(Networks::register_network(
RuntimeOrigin::root(), RuntimeOrigin::root(),
maybe_network_id.unwrap_or(1u32), maybe_network_id.unwrap_or(1u32),
network_data.clone() network_data.clone()));
));
network_data network_data
} }
@ -71,8 +70,8 @@ fn do_clap_from_first_authority(
} }
fn do_clap_from( fn do_clap_from(
session_index: u32, session_index: u32,
network_id: u32, network_id: u32,
authority_index: u32, authority_index: u32,
transaction_removed: bool, transaction_removed: bool,
) -> dispatch::DispatchResult { ) -> dispatch::DispatchResult {
@ -89,7 +88,7 @@ fn do_clap_from(
}; };
let authority = UintAuthorityId::from((authority_index + 1) as u64); let authority = UintAuthorityId::from((authority_index + 1) as u64);
let signature = authority.sign(&clap.encode()).unwrap(); let signature = authority.sign(&clap.encode()).unwrap();
SlowClap::pre_dispatch(&crate::Call::slow_clap { SlowClap::pre_dispatch(&crate::Call::slow_clap {
clap: clap.clone(), clap: clap.clone(),
signature: signature.clone(), signature: signature.clone(),
@ -109,14 +108,8 @@ fn test_throttling_slash_function() {
assert_eq!(dummy_offence.slash_fraction(1), Perbill::zero()); assert_eq!(dummy_offence.slash_fraction(1), Perbill::zero());
assert_eq!(dummy_offence.slash_fraction(5), Perbill::zero()); assert_eq!(dummy_offence.slash_fraction(5), Perbill::zero());
assert_eq!( assert_eq!(dummy_offence.slash_fraction(7), Perbill::from_parts(4200000));
dummy_offence.slash_fraction(7), assert_eq!(dummy_offence.slash_fraction(17), Perbill::from_parts(46200000));
Perbill::from_parts(4200000)
);
assert_eq!(
dummy_offence.slash_fraction(17),
Perbill::from_parts(46200000)
);
} }
#[test] #[test]
@ -128,10 +121,8 @@ fn request_body_is_correct_for_get_block_number() {
t.execute_with(|| { t.execute_with(|| {
let network_data = prepare_evm_network(Some(1), None); let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data); let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data);
assert_eq!( assert_eq!(core::str::from_utf8(&request_body).unwrap(),
core::str::from_utf8(&request_body).unwrap(), r#"{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber"}"#);
r#"{"id":0,"jsonrpc":"2.0","method":"eth_blockNumber"}"#
);
}); });
} }
@ -186,10 +177,7 @@ fn should_make_http_call_for_logs() {
let network_data = prepare_evm_network(Some(1), None); let network_data = prepare_evm_network(Some(1), None);
let request_body = SlowClap::prepare_request_body_for_latest_transfers( let request_body = SlowClap::prepare_request_body_for_latest_transfers(
from_block, from_block, to_block, &network_data);
to_block,
&network_data,
);
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?; let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
assert_eq!(raw_response.len(), 1805); // precalculated assert_eq!(raw_response.len(), 1805); // precalculated
Ok(()) Ok(())
@ -210,8 +198,7 @@ fn should_make_http_call_and_parse_block_number() {
let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data); let request_body = SlowClap::prepare_request_body_for_latest_block(&network_data);
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?; let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
let maybe_evm_block_number = let maybe_evm_block_number = SlowClap::apply_evm_response(&raw_response, 69, Default::default(), 420, 1)?;
SlowClap::apply_evm_response(&raw_response, 69, Default::default(), 420, 1)?;
assert_eq!(maybe_evm_block_number, Some(20335745)); assert_eq!(maybe_evm_block_number, Some(20335745));
Ok(()) Ok(())
@ -240,10 +227,7 @@ fn should_make_http_call_and_parse_logs() {
let network_data = prepare_evm_network(Some(network_id), None); let network_data = prepare_evm_network(Some(network_id), None);
let request_body = SlowClap::prepare_request_body_for_latest_transfers( let request_body = SlowClap::prepare_request_body_for_latest_transfers(
from_block, from_block, to_block, &network_data);
to_block,
&network_data,
);
let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?; let raw_response = SlowClap::fetch_from_remote(&rpc_endpoint, &request_body)?;
match SlowClap::parse_evm_response(&raw_response)? { match SlowClap::parse_evm_response(&raw_response)? {
@ -275,30 +259,21 @@ fn should_clear_sesions_based_on_history_depth() {
let storage_key = (session_index, transaction_hash, unique_transaction_hash); let storage_key = (session_index, transaction_hash, unique_transaction_hash);
assert_claps_info_correct(&storage_key, &session_index, 0); assert_claps_info_correct(&storage_key, &session_index, 0);
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), false);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
false
);
assert_ok!(do_clap_from(session_index, network_id, 0, false)); 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, 1, false));
assert_ok!(do_clap_from(session_index, network_id, 2, false)); assert_ok!(do_clap_from(session_index, network_id, 2, false));
assert_claps_info_correct(&storage_key, &session_index, 3); assert_claps_info_correct(&storage_key, &session_index, 3);
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), true);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
true
);
for _ in 0..history_depth { for _ in 0..history_depth {
advance_session(); advance_session();
} }
assert_claps_info_correct(&storage_key, &session_index, 0); assert_claps_info_correct(&storage_key, &session_index, 0);
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), false);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
false
);
}); });
} }
@ -337,10 +312,7 @@ fn should_increase_gatkeeper_amount_accordingly() {
assert_ok!(do_clap_from(session_index, network_id, 2, false)); assert_ok!(do_clap_from(session_index, network_id, 2, false));
assert_eq!(Networks::gatekeeper_amount(network_id), amount); assert_eq!(Networks::gatekeeper_amount(network_id), amount);
assert_eq!( assert_eq!(Networks::bridged_imbalance().bridged_in, amount.saturating_div(2));
Networks::bridged_imbalance().bridged_in,
amount.saturating_div(2)
);
assert_eq!(Networks::bridged_imbalance().bridged_out, 0); assert_eq!(Networks::bridged_imbalance().bridged_out, 0);
}); });
} }
@ -374,29 +346,18 @@ fn should_applause_and_take_next_claps() {
let session_index = advance_session_and_get_index(); let session_index = advance_session_and_get_index();
let storage_key = (session_index, transaction_hash, unique_transaction_hash); let storage_key = (session_index, transaction_hash, unique_transaction_hash);
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), false);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
false
);
assert_eq!(Balances::balance(&receiver), 0); assert_eq!(Balances::balance(&receiver), 0);
assert_ok!(do_clap_from(session_index, network_id, 0, false)); assert_ok!(do_clap_from(session_index, network_id, 0, false));
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), false);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
false
);
assert_eq!(Balances::balance(&receiver), 0); assert_eq!(Balances::balance(&receiver), 0);
assert_ok!(do_clap_from(session_index, network_id, 1, false)); assert_ok!(do_clap_from(session_index, network_id, 1, false));
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), true);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
true
);
assert_eq!(Balances::balance(&receiver), amount); assert_eq!(Balances::balance(&receiver), amount);
assert_ok!(do_clap_from(session_index, network_id, 2, false)); assert_ok!(do_clap_from(session_index, network_id, 2, false));
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), true);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
true
);
assert_eq!(Balances::balance(&receiver), amount); assert_eq!(Balances::balance(&receiver), amount);
}); });
} }
@ -412,10 +373,8 @@ fn should_throw_error_on_clap_duplication() {
assert_claps_info_correct(&storage_key, &session_index, 0); assert_claps_info_correct(&storage_key, &session_index, 0);
assert_ok!(do_clap_from(session_index, network_id, 0, false)); assert_ok!(do_clap_from(session_index, network_id, 0, false));
assert_claps_info_correct(&storage_key, &session_index, 1); assert_claps_info_correct(&storage_key, &session_index, 1);
assert_err!( assert_err!(do_clap_from(session_index, network_id, 0, false),
do_clap_from(session_index, network_id, 0, false), Error::<Runtime>::AlreadyClapped);
Error::<Runtime>::AlreadyClapped
);
assert_claps_info_correct(&storage_key, &session_index, 1); assert_claps_info_correct(&storage_key, &session_index, 1);
}); });
} }
@ -430,10 +389,8 @@ fn should_throw_error_on_removal_of_unregistered_clap() {
let storage_key = (session_index, transaction_hash, unique_transaction_hash); let storage_key = (session_index, transaction_hash, unique_transaction_hash);
assert_claps_info_correct(&storage_key, &session_index, 0); assert_claps_info_correct(&storage_key, &session_index, 0);
assert_err!( assert_err!(do_clap_from(session_index, network_id, 0, true),
do_clap_from(session_index, network_id, 0, true), Error::<Runtime>::UnregisteredClapRemove);
Error::<Runtime>::UnregisteredClapRemove
);
assert_claps_info_correct(&storage_key, &session_index, 0); assert_claps_info_correct(&storage_key, &session_index, 0);
}); });
} }
@ -463,21 +420,9 @@ fn should_throw_error_if_session_index_is_not_current() {
let session_index_prev = chunk[0].1; let session_index_prev = chunk[0].1;
let session_index_next = chunk[2].1; let session_index_next = chunk[2].1;
let storage_key_curr = ( let storage_key_curr = (session_index_curr, transaction_hash, unique_transaction_hash);
session_index_curr, let storage_key_prev = (session_index_prev, transaction_hash, unique_transaction_hash);
transaction_hash, let storage_key_next = (session_index_next, transaction_hash, unique_transaction_hash);
unique_transaction_hash,
);
let storage_key_prev = (
session_index_prev,
transaction_hash,
unique_transaction_hash,
);
let storage_key_next = (
session_index_next,
transaction_hash,
unique_transaction_hash,
);
assert_claps_info_correct(&storage_key_curr, &session_index_curr, 0); assert_claps_info_correct(&storage_key_curr, &session_index_curr, 0);
assert_claps_info_correct(&storage_key_prev, &session_index_prev, 0); assert_claps_info_correct(&storage_key_prev, &session_index_prev, 0);
@ -504,25 +449,14 @@ fn should_throw_error_if_session_index_is_not_current() {
assert_claps_info_correct(&storage_key_prev, &session_index_prev, 0); assert_claps_info_correct(&storage_key_prev, &session_index_prev, 0);
assert_claps_info_correct(&storage_key_next, &session_index_next, 0); assert_claps_info_correct(&storage_key_next, &session_index_next, 0);
assert_ok!(do_clap_from_first_authority( assert_ok!(do_clap_from_first_authority(session_index_curr, network_id, authority_curr));
session_index_curr, assert_ok!(do_clap_from_first_authority(session_index_prev, network_id, authority_prev));
network_id, assert_ok!(do_clap_from_first_authority(session_index_next, network_id, authority_next));
authority_curr
));
assert_ok!(do_clap_from_first_authority(
session_index_prev,
network_id,
authority_prev
));
assert_ok!(do_clap_from_first_authority(
session_index_next,
network_id,
authority_next
));
assert_claps_info_correct(&storage_key_curr, &session_index_curr, 1); assert_claps_info_correct(&storage_key_curr, &session_index_curr, 1);
assert_claps_info_correct(&storage_key_prev, &session_index_prev, 1); assert_claps_info_correct(&storage_key_prev, &session_index_prev, 1);
assert_claps_info_correct(&storage_key_next, &session_index_next, 1); assert_claps_info_correct(&storage_key_next, &session_index_next, 1);
} }
}); });
} }
@ -549,10 +483,8 @@ fn should_throw_error_if_signer_has_incorrect_index() {
}; };
let authority = UintAuthorityId::from((1) as u64); let authority = UintAuthorityId::from((1) as u64);
let signature = authority.sign(&clap.encode()).unwrap(); let signature = authority.sign(&clap.encode()).unwrap();
assert_err!( assert_err!(SlowClap::slow_clap(RuntimeOrigin::none(), clap, signature),
SlowClap::slow_clap(RuntimeOrigin::none(), clap, signature), Error::<Runtime>::NotAnAuthority);
Error::<Runtime>::NotAnAuthority
);
assert_claps_info_correct(&storage_key, &session_index, 0); assert_claps_info_correct(&storage_key, &session_index, 0);
}); });
} }
@ -568,41 +500,27 @@ fn should_throw_error_if_validator_disabled_and_ignore_later() {
assert_claps_info_correct(&storage_key, &session_index, 0); assert_claps_info_correct(&storage_key, &session_index, 0);
assert_eq!(Session::disable_index(0), true); assert_eq!(Session::disable_index(0), true);
assert_err!( assert_err!(do_clap_from(session_index, network_id, 0, false),
do_clap_from(session_index, network_id, 0, false), Error::<Runtime>::CurrentValidatorIsDisabled);
Error::<Runtime>::CurrentValidatorIsDisabled
);
assert_eq!(pallet::ReceivedClaps::<Runtime>::get(&storage_key).len(), 0); assert_eq!(pallet::ReceivedClaps::<Runtime>::get(&storage_key).len(), 0);
assert_eq!( assert_eq!(pallet::ClapsInSession::<Runtime>::get(&session_index).len(), 1);
pallet::ClapsInSession::<Runtime>::get(&session_index).len(), assert_eq!(pallet::ClapsInSession::<Runtime>::get(&session_index)
1 .into_iter()
); .filter(|(_, v)| !v.disabled)
assert_eq!( .collect::<Vec<_>>()
pallet::ClapsInSession::<Runtime>::get(&session_index) .len(), 0);
.into_iter()
.filter(|(_, v)| !v.disabled)
.collect::<Vec<_>>()
.len(),
0
);
assert_ok!(do_clap_from(session_index, network_id, 1, false)); assert_ok!(do_clap_from(session_index, network_id, 1, false));
assert_eq!(Session::disable_index(1), true); assert_eq!(Session::disable_index(1), true);
assert_eq!(pallet::ReceivedClaps::<Runtime>::get(&storage_key).len(), 1); assert_eq!(pallet::ReceivedClaps::<Runtime>::get(&storage_key).len(), 1);
assert_eq!( assert_eq!(pallet::ClapsInSession::<Runtime>::get(&session_index).len(), 2);
pallet::ClapsInSession::<Runtime>::get(&session_index).len(), assert_eq!(pallet::ClapsInSession::<Runtime>::get(&session_index)
2 .into_iter()
); .filter(|(_, v)| !v.disabled)
assert_eq!( .collect::<Vec<_>>()
pallet::ClapsInSession::<Runtime>::get(&session_index) .len(), 0);
.into_iter()
.filter(|(_, v)| !v.disabled)
.collect::<Vec<_>>()
.len(),
0
);
}); });
} }
@ -635,10 +553,7 @@ fn should_clap_without_applause_on_gatekeeper_amount_overflow() {
} }
assert_claps_info_correct(&storage_key_first, &session_index, 3); assert_claps_info_correct(&storage_key_first, &session_index, 3);
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key_first), true);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key_first),
true
);
assert_eq!(Balances::balance(&first_receiver), big_amount); assert_eq!(Balances::balance(&first_receiver), big_amount);
assert_eq!(Balances::balance(&second_receiver), 0); assert_eq!(Balances::balance(&second_receiver), 0);
@ -699,10 +614,7 @@ fn should_clap_without_applause_on_commission_overflow() {
} }
assert_claps_info_correct(&storage_key_first, &session_index, 3); assert_claps_info_correct(&storage_key_first, &session_index, 3);
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key_first), true);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key_first),
true
);
assert_eq!(Balances::balance(&first_receiver), big_amount); assert_eq!(Balances::balance(&first_receiver), big_amount);
assert_eq!(Balances::balance(&second_receiver), 0); assert_eq!(Balances::balance(&second_receiver), 0);
@ -750,14 +662,10 @@ fn should_nullify_commission_on_finalize() {
assert_eq!(Networks::accumulated_commission(), amount); assert_eq!(Networks::accumulated_commission(), amount);
assert_eq!(Networks::is_nullification_period(), false); assert_eq!(Networks::is_nullification_period(), false);
assert_eq!( assert_eq!(BridgedInflationCurve::<RewardCurve, Runtime>::era_payout(
BridgedInflationCurve::<RewardCurve, Runtime>::era_payout(
total_staked, total_staked,
total_issuance, total_issuance,
0 0), (420000000000000, 0)); // precomputed values
),
(420000000000000, 0)
); // precomputed values
assert_eq!(Networks::is_nullification_period(), true); assert_eq!(Networks::is_nullification_period(), true);
Networks::on_finalize(System::block_number()); Networks::on_finalize(System::block_number());
@ -781,14 +689,10 @@ fn should_avoid_applause_during_nullification_period() {
let session_index = advance_session_and_get_index(); let session_index = advance_session_and_get_index();
assert_eq!(Networks::is_nullification_period(), false); assert_eq!(Networks::is_nullification_period(), false);
assert_eq!( assert_eq!(BridgedInflationCurve::<RewardCurve, Runtime>::era_payout(
BridgedInflationCurve::<RewardCurve, Runtime>::era_payout(
total_staked, total_staked,
total_issuance, total_issuance,
0 0), (0, 0));
),
(0, 0)
);
assert_eq!(Networks::is_nullification_period(), true); 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, 0, false));
@ -814,66 +718,49 @@ fn should_self_applause_if_enough_received_claps() {
let session_index = advance_session_and_get_index(); let session_index = advance_session_and_get_index();
let storage_key = (session_index, transaction_hash, unique_transaction_hash); let storage_key = (session_index, transaction_hash, unique_transaction_hash);
assert_err!( assert_err!(SlowClap::self_applause(
SlowClap::self_applause(
RuntimeOrigin::signed(receiver), RuntimeOrigin::signed(receiver),
network_id, network_id,
session_index, session_index,
transaction_hash, transaction_hash,
receiver, receiver,
amount, amount,
), ), Error::<Runtime>::NotEnoughClaps);
Error::<Runtime>::NotEnoughClaps
);
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), false);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
false
);
assert_eq!(Balances::balance(&receiver), 0); assert_eq!(Balances::balance(&receiver), 0);
assert_eq!( assert_eq!(BridgedInflationCurve::<RewardCurve, Runtime>::era_payout(
BridgedInflationCurve::<RewardCurve, Runtime>::era_payout(0, 0, 0), 0, 0, 0), (0, 0));
(0, 0)
);
assert_ok!(do_clap_from(session_index, network_id, 0, false)); 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, 1, false));
assert_ok!(do_clap_from(session_index, network_id, 2, false)); assert_ok!(do_clap_from(session_index, network_id, 2, false));
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), false);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
false
);
assert_eq!(Balances::balance(&receiver), 0); assert_eq!(Balances::balance(&receiver), 0);
assert_ok!(SlowClap::self_applause( assert_ok!(SlowClap::self_applause(
RuntimeOrigin::signed(receiver), RuntimeOrigin::signed(receiver),
network_id, network_id,
session_index, session_index,
transaction_hash, transaction_hash,
receiver, receiver,
amount, amount,
)); ));
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), false);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
false
);
assert_eq!(Balances::balance(&receiver), 0); assert_eq!(Balances::balance(&receiver), 0);
Networks::on_finalize(System::block_number()); Networks::on_finalize(System::block_number());
assert_ok!(SlowClap::self_applause( assert_ok!(SlowClap::self_applause(
RuntimeOrigin::signed(receiver), RuntimeOrigin::signed(receiver),
network_id, network_id,
session_index, session_index,
transaction_hash, transaction_hash,
receiver, receiver,
amount, amount,
)); ));
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), true);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
true
);
assert_eq!(Balances::balance(&receiver), amount); assert_eq!(Balances::balance(&receiver), amount);
}); });
} }
@ -892,67 +779,60 @@ fn should_emit_event_on_each_clap_and_on_applause() {
let session_index = advance_session_and_get_index(); let session_index = advance_session_and_get_index();
let storage_key = (session_index, transaction_hash, unique_transaction_hash); let storage_key = (session_index, transaction_hash, unique_transaction_hash);
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), false);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
false
);
assert_claps_info_correct(&storage_key, &session_index, 0); assert_claps_info_correct(&storage_key, &session_index, 0);
assert_ok!(do_clap_from(session_index, network_id, 0, false)); assert_ok!(do_clap_from(session_index, network_id, 0, false));
System::assert_last_event(RuntimeEvent::SlowClap(crate::Event::Clapped { System::assert_last_event(RuntimeEvent::SlowClap(
receiver: receiver.clone(), crate::Event::Clapped {
authority_id: 0, receiver: receiver.clone(),
network_id, authority_id: 0,
transaction_hash, network_id,
amount, transaction_hash,
})); amount,
}));
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), false);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
false
);
assert_claps_info_correct(&storage_key, &session_index, 1); assert_claps_info_correct(&storage_key, &session_index, 1);
assert_ok!(do_clap_from(session_index, network_id, 1, false)); assert_ok!(do_clap_from(session_index, network_id, 1, false));
let binding = System::events(); let binding = System::events();
let last_two_events = binding.iter().rev().take(5).collect::<Vec<_>>(); let last_two_events = binding
assert_eq!( .iter()
last_two_events[0].event, .rev()
RuntimeEvent::SlowClap(crate::Event::Applaused { .take(5)
network_id, .collect::<Vec<_>>();
receiver: receiver.clone(), assert_eq!(last_two_events[0].event, RuntimeEvent::SlowClap(
received_amount: amount_after_commission, crate::Event::Applaused {
}) network_id,
); receiver: receiver.clone(),
assert_eq!( received_amount: amount_after_commission,
last_two_events[4].event, }));
RuntimeEvent::SlowClap(crate::Event::Clapped { assert_eq!(last_two_events[4].event, RuntimeEvent::SlowClap(
receiver: receiver.clone(), crate::Event::Clapped {
authority_id: 1, receiver: receiver.clone(),
network_id, authority_id: 1,
transaction_hash, network_id,
amount, transaction_hash,
}) amount,
); }));
assert_eq!( assert_eq!(pallet::ApplausesForTransaction::<Runtime>::get(&storage_key), true);
pallet::ApplausesForTransaction::<Runtime>::get(&storage_key),
true
);
assert_claps_info_correct(&storage_key, &session_index, 2); assert_claps_info_correct(&storage_key, &session_index, 2);
assert_ok!(do_clap_from(session_index, network_id, 2, false)); assert_ok!(do_clap_from(session_index, network_id, 2, false));
System::assert_last_event(RuntimeEvent::SlowClap(crate::Event::Clapped { System::assert_last_event(RuntimeEvent::SlowClap(
receiver: receiver.clone(), crate::Event::Clapped {
authority_id: 2, receiver: receiver.clone(),
network_id, authority_id: 2,
transaction_hash, network_id,
amount, transaction_hash,
})); amount,
}));
}); });
} }
#[test] #[test]
fn should_not_fail_on_sub_existential_balance() { fn should_not_fail_on_sub_existential_balance() {
let (network_id, transaction_hash, unique_transaction_hash) = let (network_id, transaction_hash, unique_transaction_hash)
generate_unique_hash(None, None, None, None); = generate_unique_hash(None, None, None, None);
let (_, receiver, amount) = get_mocked_metadata(); let (_, receiver, amount) = get_mocked_metadata();
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
@ -965,10 +845,7 @@ fn should_not_fail_on_sub_existential_balance() {
assert_eq!(Networks::bridged_imbalance().bridged_in, 0); assert_eq!(Networks::bridged_imbalance().bridged_in, 0);
assert_eq!(Networks::bridged_imbalance().bridged_out, 0); assert_eq!(Networks::bridged_imbalance().bridged_out, 0);
assert_eq!(Balances::balance(&receiver), 0); assert_eq!(Balances::balance(&receiver), 0);
assert_eq!( assert_eq!(SlowClap::applauses_for_transaction(&received_claps_key), false);
SlowClap::applauses_for_transaction(&received_claps_key),
false
);
assert_ok!(do_clap_from(session_index, network_id, 0, false)); 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, 1, false));
@ -979,10 +856,7 @@ fn should_not_fail_on_sub_existential_balance() {
assert_eq!(Networks::bridged_imbalance().bridged_in, 0); assert_eq!(Networks::bridged_imbalance().bridged_in, 0);
assert_eq!(Networks::bridged_imbalance().bridged_out, 0); assert_eq!(Networks::bridged_imbalance().bridged_out, 0);
assert_eq!(Balances::balance(&receiver), 0); assert_eq!(Balances::balance(&receiver), 0);
assert_eq!( assert_eq!(SlowClap::applauses_for_transaction(&received_claps_key), true);
SlowClap::applauses_for_transaction(&received_claps_key),
true
);
}); });
} }
@ -1007,34 +881,40 @@ fn generate_unique_hash(
let receiver = maybe_receiver.unwrap_or(receiver); let receiver = maybe_receiver.unwrap_or(receiver);
let amount = maybe_amount.unwrap_or(amount); let amount = maybe_amount.unwrap_or(amount);
let unique_transaction_hash = SlowClap::generate_unique_hash(&receiver, &amount, &network_id); let unique_transaction_hash = SlowClap::generate_unique_hash(
&receiver,
&amount,
&network_id,
);
(network_id, transaction_hash, unique_transaction_hash) (network_id, transaction_hash, unique_transaction_hash)
} }
fn assert_claps_info_correct(storage_key: &(u32, H256, H256), session_index: &u32, index: usize) { fn assert_claps_info_correct(
assert_eq!( storage_key: &(u32, H256, H256),
pallet::ReceivedClaps::<Runtime>::get(storage_key).len(), session_index: &u32,
index index: usize,
); ) {
assert_eq!( assert_eq!(pallet::ReceivedClaps::<Runtime>::get(storage_key).len(), index);
pallet::ClapsInSession::<Runtime>::get(session_index).len(), assert_eq!(pallet::ClapsInSession::<Runtime>::get(session_index).len(), index);
index
);
} }
fn assert_transaction_has_bad_signature(session_index: u32, network_id: u32, authority: u64) { fn assert_transaction_has_bad_signature(
assert_err!( session_index: u32,
do_clap_from_first_authority(session_index, network_id, authority), network_id: u32,
DispatchError::Other("Transaction has a bad signature") authority: u64,
); ) {
assert_err!(do_clap_from_first_authority(session_index, network_id, authority),
DispatchError::Other("Transaction has a bad signature"));
} }
fn assert_invalid_signing_address(session_index: u32, network_id: u32, authority_index: u32) { fn assert_invalid_signing_address(
assert_err!( session_index: u32,
do_clap_from(session_index, network_id, authority_index, false), network_id: u32,
DispatchError::Other("Invalid signing address") authority_index: u32,
); ) {
assert_err!(do_clap_from(session_index, network_id, authority_index, false),
DispatchError::Other("Invalid signing address"));
} }
fn get_rpc_endpoint() -> Vec<u8> { fn get_rpc_endpoint() -> Vec<u8> {

View File

@ -1,45 +0,0 @@
[package]
name = "ghost-sudo"
version = "0.0.1"
description = "Port of the sudo pallet because of dependencies issue"
license.workspace = true
authors.workspace = true
edition.workspace = true
homepage.workspace = true
repository.workspace = true
[dependencies]
docify = "0.2.8"
codec = { workspace = true, features = ["derive"] }
frame-benchmarking = { workspace = true, optional = true }
scale-info = { workspace = true, features = ["derive"] }
frame-support = { workspace = true }
frame-system = { workspace = true }
sp-io = { workspace = true }
sp-runtime = { workspace = true }
sp-std = { workspace = true }
[features]
default = ["std"]
std = [
"codec/std",
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"scale-info/std",
"sp-io/std",
"sp-runtime/std",
"sp-std/std",
]
runtime-benchmarks = [
"frame-benchmarking/runtime-benchmarks",
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-runtime/runtime-benchmarks",
]
try-runtime = [
"frame-support/try-runtime",
"frame-system/try-runtime",
"sp-runtime/try-runtime",
]

View File

@ -1,70 +0,0 @@
use super::*;
use crate::Pallet;
use frame_benchmarking::v2::*;
use frame_system::RawOrigin;
fn assert_last_event<T: Config>(generic_event: crate::Event<T>) {
let re: <T as Config>::RuntimeEvent = generic_event.into();
frame_system::Pallet::<T>::assert_last_event(re.into());
}
#[benchmarks(where <T as Config>::RuntimeCall: From<frame_system::Call<T>>)]
mod benchmarks {
use super::*;
#[benchmark]
fn set_key() {
let caller: T::AccountId = whitelisted_caller();
Key::<T>::put(&caller);
let new_sudoer: T::AccountId = account("sudoer", 0, 0);
let new_sudoer_lookup = T::Lookup::unlookup(new_sudoer.clone());
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()), new_sudoer_lookup);
assert_last_event::<T>(Event::KeyChanged { old: Some(caller), new: new_sudoer });
}
#[benchmark]
fn sudo() {
let caller: T::AccountId = whitelisted_caller();
Key::<T>::put(&caller);
let call = frame_system::Call::remark { remark: vec![] }.into();
#[extrinsic_call]
_(RawOrigin::Signed(caller), Box::new(call));
assert_last_event::<T>(Event::Sudid { sudo_result: Ok(()) })
}
#[benchmark]
fn sudo_as() {
let caller: T::AccountId = whitelisted_caller();
Key::<T>::put(caller.clone());
let call = frame_system::Call::remark { remark: vec![] }.into();
let who: T::AccountId = account("as", 0, 0);
let who_lookup = T::Lookup::unlookup(who);
#[extrinsic_call]
_(RawOrigin::Signed(caller), who_lookup, Box::new(call));
assert_last_event::<T>(Event::SudoAsDone { sudo_result: Ok(()) })
}
#[benchmark]
fn remove_key() {
let caller: T::AccountId = whitelisted_caller();
Key::<T>::put(&caller);
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()));
assert_last_event::<T>(Event::KeyRemoved {});
}
impl_benchmark_test_suite!(Pallet, crate::mock::new_bench_ext(), crate::mock::Test);
}

View File

@ -1,82 +0,0 @@
use crate::{Config, Key};
use codec::{Decode, Encode};
use frame_support::{dispatch::DispatchInfo, ensure};
use scale_info::TypeInfo;
use sp_runtime::{
traits::{DispatchInfoOf, Dispatchable, SignedExtension},
transaction_validity::{
InvalidTransaction, TransactionPriority, TransactionValidity, TransactionValidityError,
UnknownTransaction, ValidTransaction,
},
};
use sp_std::{fmt, marker::PhantomData};
#[derive(Clone, Eq, PartialEq, Encode, Decode, TypeInfo)]
#[scale_info(skip_type_params(T))]
pub struct CheckOnlySudoAccount<T: Config + Send + Sync>(PhantomData<T>);
impl<T: Config + Send + Sync> Default for CheckOnlySudoAccount<T> {
fn default() -> Self {
Self(Default::default())
}
}
impl<T: Config + Send + Sync> fmt::Debug for CheckOnlySudoAccount<T> {
#[cfg(feature = "std")]
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "CheckOnlySudoAccount")
}
#[cfg(not(feature = "std"))]
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
Ok(())
}
}
impl<T: Config + Send + Sync> CheckOnlySudoAccount<T> {
/// Creates new `SignedExtension` to check sudo key.
pub fn new() -> Self {
Self::default()
}
}
impl<T: Config + Send + Sync> SignedExtension for CheckOnlySudoAccount<T>
where
<T as Config>::RuntimeCall: Dispatchable<Info = DispatchInfo>,
{
const IDENTIFIER: &'static str = "CheckOnlySudoAccount";
type AccountId = T::AccountId;
type Call = <T as Config>::RuntimeCall;
type AdditionalSigned = ();
type Pre = ();
fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
Ok(())
}
fn validate(
&self,
who: &Self::AccountId,
_call: &Self::Call,
info: &DispatchInfoOf<Self::Call>,
_len: usize,
) -> TransactionValidity {
let sudo_key: T::AccountId = Key::<T>::get().ok_or(UnknownTransaction::CannotLookup)?;
ensure!(*who == sudo_key, InvalidTransaction::BadSigner);
Ok(ValidTransaction {
priority: info.weight.ref_time() as TransactionPriority,
..Default::default()
})
}
fn pre_dispatch(
self,
who: &Self::AccountId,
call: &Self::Call,
info: &DispatchInfoOf<Self::Call>,
len: usize,
) -> Result<Self::Pre, TransactionValidityError> {
self.validate(who, call, info, len).map(|_| ())
}
}

View File

@ -1,203 +0,0 @@
#![cfg_attr(not(feature = "std"), no_std)]
use sp_runtime::{traits::StaticLookup, DispatchResult};
use sp_std::prelude::*;
use frame_support::{dispatch::GetDispatchInfo, traits::UnfilteredDispatchable};
mod extension;
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
pub mod weights;
pub use weights::WeightInfo;
pub use extension::CheckOnlySudoAccount;
pub use pallet::*;
type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup>::Source;
#[frame_support::pallet]
pub mod pallet {
use super::{DispatchResult, *};
use frame_support::pallet_prelude::*;
use frame_system::{pallet_prelude::*, RawOrigin};
pub mod config_preludes {
use super::*;
use frame_support::derive_impl;
pub struct TestDefaultConfig;
#[derive_impl(frame_system::config_preludes::TestDefaultConfig, no_aggregated_types)]
impl frame_system::DefaultConfig for TestDefaultConfig {}
#[frame_support::register_default_impl(TestDefaultConfig)]
impl DefaultConfig for TestDefaultConfig {
type WeightInfo = ();
#[inject_runtime_type]
type RuntimeEvent = ();
#[inject_runtime_type]
type RuntimeCall = ();
}
}
#[pallet::config(with_default)]
pub trait Config: frame_system::Config {
#[pallet::no_default_bounds]
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
#[pallet::no_default_bounds]
type RuntimeCall: Parameter
+ UnfilteredDispatchable<RuntimeOrigin = Self::RuntimeOrigin>
+ GetDispatchInfo;
type WeightInfo: WeightInfo;
}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight({
let dispatch_info = call.get_dispatch_info();
(
T::WeightInfo::sudo().saturating_add(dispatch_info.weight),
dispatch_info.class
)
})]
pub fn sudo(
origin: OriginFor<T>,
call: Box<<T as Config>::RuntimeCall>,
) -> DispatchResultWithPostInfo {
Self::ensure_sudo(origin)?;
let res = call.dispatch_bypass_filter(RawOrigin::Root.into());
Self::deposit_event(Event::Sudid { sudo_result: res.map(|_| ()).map_err(|e| e.error) });
Ok(Pays::No.into())
}
#[pallet::call_index(1)]
#[pallet::weight((*weight, call.get_dispatch_info().class))]
pub fn sudo_unchecked_weight(
origin: OriginFor<T>,
call: Box<<T as Config>::RuntimeCall>,
weight: Weight,
) -> DispatchResultWithPostInfo {
Self::ensure_sudo(origin)?;
let _ = weight;
let res = call.dispatch_bypass_filter(RawOrigin::Root.into());
Self::deposit_event(Event::Sudid { sudo_result: res.map(|_| ()).map_err(|e| e.error) });
Ok(Pays::No.into())
}
#[pallet::call_index(2)]
#[pallet::weight(T::WeightInfo::set_key())]
pub fn set_key(
origin: OriginFor<T>,
new: AccountIdLookupOf<T>,
) -> DispatchResultWithPostInfo {
Self::ensure_sudo(origin)?;
let new = T::Lookup::lookup(new)?;
Self::deposit_event(Event::KeyChanged { old: Key::<T>::get(), new: new.clone() });
Key::<T>::put(new);
Ok(Pays::No.into())
}
#[pallet::call_index(3)]
#[pallet::weight({
let dispatch_info = call.get_dispatch_info();
(
T::WeightInfo::sudo_as().saturating_add(dispatch_info.weight),
dispatch_info.class,
)
})]
pub fn sudo_as(
origin: OriginFor<T>,
who: AccountIdLookupOf<T>,
call: Box<<T as Config>::RuntimeCall>,
) -> DispatchResultWithPostInfo {
Self::ensure_sudo(origin)?;
let who = T::Lookup::lookup(who)?;
let res = call.dispatch_bypass_filter(RawOrigin::Signed(who).into());
Self::deposit_event(Event::SudoAsDone {
sudo_result: res.map(|_| ()).map_err(|e| e.error),
});
Ok(Pays::No.into())
}
#[pallet::call_index(4)]
#[pallet::weight(T::WeightInfo::remove_key())]
pub fn remove_key(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
Self::ensure_sudo(origin)?;
Self::deposit_event(Event::KeyRemoved {});
Key::<T>::kill();
Ok(Pays::No.into())
}
}
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
Sudid {
sudo_result: DispatchResult,
},
KeyChanged {
old: Option<T::AccountId>,
new: T::AccountId,
},
KeyRemoved,
SudoAsDone { sudo_result: DispatchResult },
}
#[pallet::error]
pub enum Error<T> {
RequireSudo,
}
#[pallet::storage]
pub(super) type Key<T: Config> = StorageValue<_, T::AccountId, OptionQuery>;
#[pallet::genesis_config]
#[derive(frame_support::DefaultNoBound)]
pub struct GenesisConfig<T: Config> {
pub key: Option<T::AccountId>,
}
#[pallet::genesis_build]
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
fn build(&self) {
Key::<T>::set(self.key.clone());
}
}
impl<T: Config> Pallet<T> {
pub(crate) fn ensure_sudo(origin: OriginFor<T>) -> DispatchResult {
let sender = ensure_signed_or_root(origin)?;
if let Some(sender) = sender {
if Key::<T>::get().map_or(false, |k| k == sender) {
Ok(())
} else {
Err(Error::<T>::RequireSudo.into())
}
} else {
Ok(())
}
}
}
}

View File

@ -1,109 +0,0 @@
use super::*;
use crate as sudo;
use frame_support::derive_impl;
use sp_io;
use sp_runtime::BuildStorage;
#[frame_support::pallet]
pub mod logger {
use frame_support::pallet_prelude::*;
use frame_system::pallet_prelude::*;
#[pallet::config]
pub trait Config: frame_system::Config {
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pallet::call]
impl<T: Config> Pallet<T> {
#[pallet::call_index(0)]
#[pallet::weight(*weight)]
pub fn privileged_i32_log(
origin: OriginFor<T>,
i: i32,
weight: Weight,
) -> DispatchResultWithPostInfo {
ensure_root(origin)?;
<I32Log<T>>::try_append(i).map_err(|_| "could not append")?;
Self::deposit_event(Event::AppendI32 { value: i, weight });
Ok(().into())
}
#[pallet::call_index(1)]
#[pallet::weight(*weight)]
pub fn non_privileged_log(
origin: OriginFor<T>,
i: i32,
weight: Weight,
) -> DispatchResultWithPostInfo {
let sender = ensure_signed(origin)?;
<I32Log<T>>::try_append(i).map_err(|_| "could not append")?;
<AccountLog<T>>::try_append(sender.clone()).map_err(|_| "could not append")?;
Self::deposit_event(Event::AppendI32AndAccount { sender, value: i, weight });
Ok(().into())
}
}
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
AppendI32 { value: i32, weight: Weight },
AppendI32AndAccount { sender: T::AccountId, value: i32, weight: Weight },
}
#[pallet::storage]
#[pallet::getter(fn account_log)]
pub(super) type AccountLog<T: Config> =
StorageValue<_, BoundedVec<T::AccountId, ConstU32<1_000>>, ValueQuery>;
#[pallet::storage]
#[pallet::getter(fn i32_log)]
pub(super) type I32Log<T> = StorageValue<_, BoundedVec<i32, ConstU32<1_000>>, ValueQuery>;
}
type Block = frame_system::mocking::MockBlock<Test>;
frame_support::construct_runtime!(
pub enum Test
{
System: frame_system,
Sudo: sudo,
Logger: logger,
}
);
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Test {
type Block = Block;
}
impl logger::Config for Test {
type RuntimeEvent = RuntimeEvent;
}
impl Config for Test {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type WeightInfo = ();
}
pub type SudoCall = sudo::Call<Test>;
pub type LoggerCall = logger::Call<Test>;
pub fn new_test_ext(root_key: u64) -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::<Test>::default().build_storage().unwrap();
sudo::GenesisConfig::<Test> { key: Some(root_key) }
.assimilate_storage(&mut t)
.unwrap();
let mut ext: sp_io::TestExternalities = t.into();
ext.execute_with(|| System::set_block_number(1));
ext
}
#[cfg(feature = "runtime-benchmarks")]
pub fn new_bench_ext() -> sp_io::TestExternalities {
frame_system::GenesisConfig::<Test>::default().build_storage().unwrap().into()
}

View File

@ -1,188 +0,0 @@
use super::*;
use frame_support::{assert_noop, assert_ok, weights::Weight};
use mock::{
new_test_ext, Logger, LoggerCall, RuntimeCall, RuntimeEvent as TestEvent, RuntimeOrigin, Sudo,
SudoCall, System, Test,
};
#[test]
fn test_setup_works() {
new_test_ext(1).execute_with(|| {
assert_eq!(Key::<Test>::get(), Some(1u64));
assert!(Logger::i32_log().is_empty());
assert!(Logger::account_log().is_empty());
});
}
#[docify::export]
#[test]
fn sudo_basics() {
new_test_ext(1).execute_with(|| {
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
i: 42,
weight: Weight::from_parts(1_000, 0),
}));
assert_ok!(Sudo::sudo(RuntimeOrigin::signed(1), call));
assert_eq!(Logger::i32_log(), vec![42i32]);
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
i: 42,
weight: Weight::from_parts(1_000, 0),
}));
assert_noop!(Sudo::sudo(RuntimeOrigin::signed(2), call), Error::<Test>::RequireSudo);
});
}
#[test]
fn sudo_emits_events_correctly() {
new_test_ext(1).execute_with(|| {
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
i: 42,
weight: Weight::from_parts(1, 0),
}));
assert_ok!(Sudo::sudo(RuntimeOrigin::signed(1), call));
System::assert_has_event(TestEvent::Sudo(Event::Sudid { sudo_result: Ok(()) }));
})
}
#[test]
fn sudo_unchecked_weight_basics() {
new_test_ext(1).execute_with(|| {
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
i: 42,
weight: Weight::from_parts(1_000, 0),
}));
assert_ok!(Sudo::sudo_unchecked_weight(
RuntimeOrigin::signed(1),
call,
Weight::from_parts(1_000, 0)
));
assert_eq!(Logger::i32_log(), vec![42i32]);
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
i: 42,
weight: Weight::from_parts(1_000, 0),
}));
assert_noop!(
Sudo::sudo_unchecked_weight(
RuntimeOrigin::signed(2),
call,
Weight::from_parts(1_000, 0)
),
Error::<Test>::RequireSudo,
);
assert_eq!(Logger::i32_log(), vec![42i32]);
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
i: 42,
weight: Weight::from_parts(1, 0),
}));
let sudo_unchecked_weight_call =
SudoCall::sudo_unchecked_weight { call, weight: Weight::from_parts(1_000, 0) };
let info = sudo_unchecked_weight_call.get_dispatch_info();
assert_eq!(info.weight, Weight::from_parts(1_000, 0));
});
}
#[test]
fn sudo_unchecked_weight_emits_events_correctly() {
new_test_ext(1).execute_with(|| {
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
i: 42,
weight: Weight::from_parts(1, 0),
}));
assert_ok!(Sudo::sudo_unchecked_weight(
RuntimeOrigin::signed(1),
call,
Weight::from_parts(1_000, 0)
));
System::assert_has_event(TestEvent::Sudo(Event::Sudid { sudo_result: Ok(()) }));
})
}
#[docify::export]
#[test]
fn set_key_basics() {
new_test_ext(1).execute_with(|| {
assert_ok!(Sudo::set_key(RuntimeOrigin::signed(1), 2));
assert_eq!(Key::<Test>::get(), Some(2u64));
});
new_test_ext(1).execute_with(|| {
assert_noop!(Sudo::set_key(RuntimeOrigin::signed(2), 3), Error::<Test>::RequireSudo);
});
}
#[test]
fn set_key_emits_events_correctly() {
new_test_ext(1).execute_with(|| {
assert_ok!(Sudo::set_key(RuntimeOrigin::signed(1), 2));
System::assert_has_event(TestEvent::Sudo(Event::KeyChanged { old: Some(1), new: 2 }));
assert_ok!(Sudo::set_key(RuntimeOrigin::signed(2), 4));
System::assert_has_event(TestEvent::Sudo(Event::KeyChanged { old: Some(2), new: 4 }));
});
}
#[test]
fn remove_key_works() {
new_test_ext(1).execute_with(|| {
assert_ok!(Sudo::remove_key(RuntimeOrigin::signed(1)));
assert!(Key::<Test>::get().is_none());
System::assert_has_event(TestEvent::Sudo(Event::KeyRemoved {}));
assert_noop!(Sudo::remove_key(RuntimeOrigin::signed(1)), Error::<Test>::RequireSudo);
assert_noop!(Sudo::set_key(RuntimeOrigin::signed(1), 1), Error::<Test>::RequireSudo);
});
}
#[test]
fn using_root_origin_works() {
new_test_ext(1).execute_with(|| {
assert_ok!(Sudo::remove_key(RuntimeOrigin::root()));
assert!(Key::<Test>::get().is_none());
System::assert_has_event(TestEvent::Sudo(Event::KeyRemoved {}));
assert_ok!(Sudo::set_key(RuntimeOrigin::root(), 1));
assert_eq!(Some(1), Key::<Test>::get());
});
}
#[test]
fn sudo_as_basics() {
new_test_ext(1).execute_with(|| {
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
i: 42,
weight: Weight::from_parts(1_000, 0),
}));
assert_ok!(Sudo::sudo_as(RuntimeOrigin::signed(1), 2, call));
assert!(Logger::i32_log().is_empty());
assert!(Logger::account_log().is_empty());
let call = Box::new(RuntimeCall::Logger(LoggerCall::non_privileged_log {
i: 42,
weight: Weight::from_parts(1, 0),
}));
assert_noop!(Sudo::sudo_as(RuntimeOrigin::signed(3), 2, call), Error::<Test>::RequireSudo);
let call = Box::new(RuntimeCall::Logger(LoggerCall::non_privileged_log {
i: 42,
weight: Weight::from_parts(1, 0),
}));
assert_ok!(Sudo::sudo_as(RuntimeOrigin::signed(1), 2, call));
assert_eq!(Logger::i32_log(), vec![42i32]);
assert_eq!(Logger::account_log(), vec![2]);
});
}
#[docify::export]
#[test]
fn sudo_as_emits_events_correctly() {
new_test_ext(1).execute_with(|| {
let call = Box::new(RuntimeCall::Logger(LoggerCall::non_privileged_log {
i: 42,
weight: Weight::from_parts(1, 0),
}));
assert_ok!(Sudo::sudo_as(RuntimeOrigin::signed(1), 2, call));
System::assert_has_event(TestEvent::Sudo(Event::SudoAsDone { sudo_result: Ok(()) }));
});
}

View File

@ -1,156 +0,0 @@
// 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_sudo`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-07-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=ghost-sudo
// --extrinsic=*
// --wasm-execution=compiled
// --heap-pages=4096
// --header=./file_header.txt
// --output=./runtime/casper/src/weights/ghost_sudo.rs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(missing_docs)]
use frame_support::{
traits::Get,
weights::{Weight, constants::RocksDbWeight},
};
use core::marker::PhantomData;
/// Weight functions needed for `pallet_sudo`.
pub trait WeightInfo {
fn set_key() -> Weight;
fn sudo() -> Weight;
fn sudo_as() -> Weight;
fn remove_key() -> Weight;
}
/// Weight functions for `ghost_sudo`.
pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
/// Storage: `GhostSudo::Key` (r:1 w:1)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn set_key() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 40_014_000 picoseconds.
Weight::from_parts(40_856_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `GhostSudo::Key` (r:1 w:0)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn sudo() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 44_086_000 picoseconds.
Weight::from_parts(45_920_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(T::DbWeight::get().reads(1))
}
/// Storage: `GhostSudo::Key` (r:1 w:0)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn sudo_as() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 44_106_000 picoseconds.
Weight::from_parts(44_650_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(T::DbWeight::get().reads(1))
}
/// Storage: `GhostSudo::Key` (r:1 w:1)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn remove_key() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 36_416_000 picoseconds.
Weight::from_parts(37_373_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
}
// For backwards compatibility and tests.
impl WeightInfo for () {
/// Storage: `GhostSudo::Key` (r:1 w:1)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn set_key() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 40_014_000 picoseconds.
Weight::from_parts(40_856_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
/// Storage: `GhostSudo::Key` (r:1 w:0)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn sudo() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 44_086_000 picoseconds.
Weight::from_parts(45_920_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(RocksDbWeight::get().reads(1))
}
/// Storage: `GhostSudo::Key` (r:1 w:0)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn sudo_as() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 44_106_000 picoseconds.
Weight::from_parts(44_650_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(RocksDbWeight::get().reads(1))
}
/// Storage: `GhostSudo::Key` (r:1 w:1)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn remove_key() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 36_416_000 picoseconds.
Weight::from_parts(37_373_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
}

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-traits" name = "ghost-traits"
version = "0.3.23" version = "0.3.22"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true
edition.workspace = true edition.workspace = true

View File

@ -1,7 +1,10 @@
use frame_support::{pallet_prelude::*, storage::PrefixIterator}; use frame_support::{
pallet_prelude::*,
storage::PrefixIterator,
};
use sp_runtime::{ use sp_runtime::{
traits::{AtLeast32BitUnsigned, Member},
DispatchResult, DispatchResult,
traits::{AtLeast32BitUnsigned, Member},
}; };
pub trait NetworkDataBasicHandler { pub trait NetworkDataBasicHandler {
@ -25,14 +28,8 @@ pub trait NetworkDataMutateHandler<Network, Balance>: NetworkDataInspectHandler<
fn register(chain_id: Self::NetworkId, network: Network) -> DispatchResult; fn register(chain_id: Self::NetworkId, network: Network) -> DispatchResult;
fn remove(chain_id: Self::NetworkId) -> DispatchResult; fn remove(chain_id: Self::NetworkId) -> DispatchResult;
fn increase_gatekeeper_amount( fn increase_gatekeeper_amount(chain_id: &Self::NetworkId, amount: &Balance) -> Result<Balance, ()>;
chain_id: &Self::NetworkId, fn decrease_gatekeeper_amount(chain_id: &Self::NetworkId, amount: &Balance) -> Result<Balance, ()>;
amount: &Balance,
) -> Result<Balance, ()>;
fn decrease_gatekeeper_amount(
chain_id: &Self::NetworkId,
amount: &Balance,
) -> Result<Balance, ()>;
fn accumulate_outgoing_imbalance(amount: &Balance) -> Result<Balance, ()>; fn accumulate_outgoing_imbalance(amount: &Balance) -> Result<Balance, ()>;
fn accumulate_incoming_imbalance(amount: &Balance) -> Result<Balance, ()>; fn accumulate_incoming_imbalance(amount: &Balance) -> Result<Balance, ()>;

View File

@ -1,6 +1,6 @@
[package] [package]
name = "casper-runtime" name = "casper-runtime"
version = "3.5.27" version = "3.5.25"
build = "build.rs" build = "build.rs"
description = "Runtime of the Casper Network" description = "Runtime of the Casper Network"
edition.workspace = true edition.workspace = true
@ -87,7 +87,6 @@ pallet-whitelist = { workspace = true }
ghost-networks = { workspace = true } ghost-networks = { workspace = true }
ghost-claims = { workspace = true } ghost-claims = { workspace = true }
ghost-slow-clap = { workspace = true } ghost-slow-clap = { workspace = true }
ghost-sudo = { workspace = true }
casper-runtime-constants = { workspace = true } casper-runtime-constants = { workspace = true }
runtime-common = { workspace = true } runtime-common = { workspace = true }
primitives = { workspace = true } primitives = { workspace = true }
@ -206,7 +205,6 @@ std = [
"ghost-networks/std", "ghost-networks/std",
"ghost-claims/std", "ghost-claims/std",
"ghost-slow-clap/std", "ghost-slow-clap/std",
"ghost-sudo/std",
"casper-runtime-constants/std", "casper-runtime-constants/std",
"runtime-common/std", "runtime-common/std",
"primitives/std", "primitives/std",
@ -254,7 +252,6 @@ runtime-benchmarks = [
"ghost-networks/runtime-benchmarks", "ghost-networks/runtime-benchmarks",
"ghost-claims/runtime-benchmarks", "ghost-claims/runtime-benchmarks",
"ghost-slow-clap/runtime-benchmarks", "ghost-slow-clap/runtime-benchmarks",
"ghost-sudo/runtime-benchmarks",
"runtime-common/runtime-benchmarks", "runtime-common/runtime-benchmarks",
] ]
try-runtime = [ try-runtime = [
@ -300,6 +297,5 @@ try-runtime = [
"ghost-networks/try-runtime", "ghost-networks/try-runtime",
"ghost-claims/try-runtime", "ghost-claims/try-runtime",
"ghost-slow-clap/try-runtime", "ghost-slow-clap/try-runtime",
"ghost-sudo/try-runtime",
"runtime-common/try-runtime", "runtime-common/try-runtime",
] ]

View File

@ -28,6 +28,3 @@ std = [
"sp-runtime/std", "sp-runtime/std",
"sp-weights/std", "sp-weights/std",
] ]
# Set timing constants (e.g session period) to faster versions to speed up testing.
fast-runtime = []

View File

@ -1105,12 +1105,6 @@ impl ghost_slow_clap::Config for Runtime {
type WeightInfo = weights::ghost_slow_clap::WeightInfo<Runtime>; type WeightInfo = weights::ghost_slow_clap::WeightInfo<Runtime>;
} }
impl ghost_sudo::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type WeightInfo = weights::ghost_sudo::WeightInfo<Runtime>;
}
construct_runtime! { construct_runtime! {
pub enum Runtime pub enum Runtime
{ {
@ -1138,7 +1132,6 @@ construct_runtime! {
Session: pallet_session = 9, Session: pallet_session = 9,
Grandpa: pallet_grandpa = 11, Grandpa: pallet_grandpa = 11,
AuthorityDiscovery: pallet_authority_discovery = 12, AuthorityDiscovery: pallet_authority_discovery = 12,
GhostSudo: ghost_sudo = 13,
// Governance stuff. // Governance stuff.
Treasury: pallet_treasury = 19, Treasury: pallet_treasury = 19,
@ -1267,7 +1260,6 @@ mod benches {
[ghost_networks, GhostNetworks] [ghost_networks, GhostNetworks]
[ghost_claims, GhostClaims] [ghost_claims, GhostClaims]
[ghost_slow_clap, GhostSlowClaps] [ghost_slow_clap, GhostSlowClaps]
[ghost_sudo, GhostSudo]
); );
} }
@ -1574,7 +1566,6 @@ sp_api::impl_runtime_apis! {
(list, storage_info) (list, storage_info)
} }
#[allow(non_local_definitions)]
fn dispatch_benchmark( fn dispatch_benchmark(
config: frame_benchmarking::BenchmarkConfig, config: frame_benchmarking::BenchmarkConfig,
) -> Result< ) -> Result<

View File

@ -1,95 +0,0 @@
// 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_sudo`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-07-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=ghost-sudo
// --extrinsic=*
// --wasm-execution=compiled
// --heap-pages=4096
// --header=./file_header.txt
// --output=./runtime/casper/src/weights/ghost_sudo.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 `ghost_sudo`.
pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> ghost_sudo::WeightInfo for WeightInfo<T> {
/// Storage: `GhostSudo::Key` (r:1 w:1)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn set_key() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 40_014_000 picoseconds.
Weight::from_parts(40_856_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `GhostSudo::Key` (r:1 w:0)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn sudo() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 44_086_000 picoseconds.
Weight::from_parts(45_920_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(T::DbWeight::get().reads(1))
}
/// Storage: `GhostSudo::Key` (r:1 w:0)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn sudo_as() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 44_106_000 picoseconds.
Weight::from_parts(44_650_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(T::DbWeight::get().reads(1))
}
/// Storage: `GhostSudo::Key` (r:1 w:1)
/// Proof: `GhostSudo::Key` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
fn remove_key() -> Weight {
// Proof Size summary in bytes:
// Measured: `165`
// Estimated: `1517`
// Minimum execution time: 36_416_000 picoseconds.
Weight::from_parts(37_373_000, 0)
.saturating_add(Weight::from_parts(0, 1517))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
}

View File

@ -3,7 +3,6 @@ pub mod frame_system;
pub mod ghost_claims; pub mod ghost_claims;
pub mod ghost_networks; pub mod ghost_networks;
pub mod ghost_slow_clap; pub mod ghost_slow_clap;
pub mod ghost_sudo;
pub mod pallet_alliance; pub mod pallet_alliance;
pub mod pallet_bags_list; pub mod pallet_bags_list;
pub mod pallet_balances; pub mod pallet_balances;

View File

@ -2,7 +2,6 @@
set -Ee set -Ee
HARD_RESET=false
CHECK_KEYS=false CHECK_KEYS=false
INSERT_KEYS=false INSERT_KEYS=false
UNIT_FILE=false UNIT_FILE=false
@ -97,7 +96,6 @@ help() {
echo -e "-s, --base-path\n\tPath to the folder with chain database ('/var/lib/ghost' is default)." echo -e "-s, --base-path\n\tPath to the folder with chain database ('/var/lib/ghost' is default)."
echo -e "-c, --specification-path\n\tPath to specification ('/etc/ghost' is default)." echo -e "-c, --specification-path\n\tPath to specification ('/etc/ghost' is default)."
echo -e "-n, --specification-name\n\tSpecification name to be used ('casper' is default)." echo -e "-n, --specification-name\n\tSpecification name to be used ('casper' is default)."
echo -e "--hard-reset-i-know-what-im-doing\n\tWill completely remove ledger along with associated session keys."
echo -e "-h, --help\n\tPrints help information." echo -e "-h, --help\n\tPrints help information."
} }
@ -165,9 +163,6 @@ while [ $# -gt 0 ]; do
if [[ "$1" != *=* ]]; then shift; fi if [[ "$1" != *=* ]]; then shift; fi
SPECIFICATION_NAME="${1#*=}" SPECIFICATION_NAME="${1#*=}"
;; ;;
--hard-reset-i-know-what-im-doing)
HARD_RESET=true
;;
--help|-h) --help|-h)
help help
exit 0 exit 0
@ -180,60 +175,6 @@ while [ $# -gt 0 ]; do
shift shift
done done
if [[ $HARD_RESET = true ]]; then
echo -e "\n"
echo "WARNING!!! THIS ACTION WILL COMPLETELY PURGE THE LEDGER AND REBUILD THE NODE USING THE LATEST"
echo "REPOSITORY VERSION. NOTE THAT THE VALIDATION PROCESS WILL BE LOST BECAUSE SESSION OF KEYS."
echo "THERE ARE TWO SCENARIOS IN WHICH YOU MIGHT NEED TO PROCEED:"
echo -e "\t- A new version of the network hsa been released, and a restart is neccessary"
echo -e "\t- There is a critical issue, and you require a hard reset of the node in a single command"
echo -e "\n"
if prompt "[?] do you understand all risks?"; then
echo "[+] you were warned, I hope you know what you're doing"
else
echo "[-] aborting hard reset"
exit 1
fi
cd $PROJECT_FOLDER
# TODO: uncomment later
# echo "[+] fetching the latest ghost-node source code"
# git switch main
# git pull origin main
# rustc version control, this works fine
# cargo --version | cut -d'.' -f2, if higher then do
# rustup default 1.83.0
# rustup target add wasm32-unknown-unknown --toolchain 1.83.0-x86_64-unknown-linux-gnu
# rustup component add rust-src --toolchain 1.83.0-x86_64-unknown-linux-gnu
#
# I think we need to do clean before recompilation
# cargo clean
cd $PROJECT_FOLDER
echo "[+] starting build in 3 seconds..."
sleep 3
cargo build $RELEASE $FEATURES
echo "[+] trying to stop current ghost-node"
sudo systemctl stop ghost-node
echo "[+] trying to remove locally stored ledger"
sudo rm -rf "$BASE_PATH/chains/*"
cd $PROJECT_FOLDER
echo "[+] trying to copy executable to '$EXECUTABLE_PATH'"
sudo cp target/$TARGET/ghost $EXECUTABLE_PATH
cp service/chain-specs/$SPECIFICATION_NAME.json $SPECIFICATION_PATH
echo "[+] ghost executable copied in '$EXECUTABLE_PATH' from '$TARGET'"
echo "[+] specification '$SPECIFICATION_NAME.json' copied to '$SPECIFICATION_PATH'"
echo "[+] starting ghost-node"
sudo systemctl start ghost-node
exit 0
fi
if [[ $SET_ENVIRONMENT = true ]]; then if [[ $SET_ENVIRONMENT = true ]]; then
echo -e "\n" echo -e "\n"
echo "WARNING!!! THIS IS HIGHLY EXPERIMENTAL FLAG, USE IT ONLY ON YOUR" echo "WARNING!!! THIS IS HIGHLY EXPERIMENTAL FLAG, USE IT ONLY ON YOUR"
@ -321,7 +262,7 @@ fi
if [[ ! -z $RELEASE ]]; then if [[ ! -z $RELEASE ]]; then
if prompt "[?] 'cargo build $RELEASE $FEATURES' is what you want?"; then if prompt "[?] 'cargo build $RELEASE $FEATURES' is what you want?"; then
cd $PROJECT_FOLDER cd $PROJECT_FOLDER
echo "[+] starting build in 3 seconds..." echo "[+] Starting build in 3 seconds..."
sleep 3 sleep 3
cargo build $RELEASE $FEATURES cargo build $RELEASE $FEATURES
fi fi
@ -406,6 +347,7 @@ if [[ $ARGUMENTS = true ]]; then
CLI_ARGS+=("--public-addr=$public_addr") CLI_ARGS+=("--public-addr=$public_addr")
fi fi
# default for now # default for now
CLI_ARGS+=("--telemetry-url='wss://telemetry.ghostchain.io/submit/ 9'") CLI_ARGS+=("--telemetry-url='wss://telemetry.ghostchain.io/submit/ 9'")
CLI_ARGS+=("--base-path=$BASE_PATH") CLI_ARGS+=("--base-path=$BASE_PATH")

View File

@ -176,11 +176,9 @@ fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>)> {
vec![ vec![
(1, ghost_networks::NetworkData { (1, ghost_networks::NetworkData {
chain_name: "ethereum-mainnet".into(), chain_name: "ethereum-mainnet".into(),
default_endpoint: vec![ default_endpoint: "https://nd-422-757-666.p2pify.com/0a9d79d93fb2f4a4b1e04695da2b77a7/".into(),
"https://nd-422-757-666.p2pify.com/0a9d79d93fb2f4a4b1e04695da2b77a7/".into(),
],
finality_delay: 40u64, finality_delay: 40u64,
rate_limit_delay: 1_000u64, rate_limit_delay: 1u64,
block_distance: 50u64, block_distance: 50u64,
network_type: ghost_networks::NetworkType::Evm, network_type: ghost_networks::NetworkType::Evm,
gatekeeper: "0x4d224452801aced8b2f0aebe155379bb5d594381".into(), gatekeeper: "0x4d224452801aced8b2f0aebe155379bb5d594381".into(),
@ -190,11 +188,9 @@ fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>)> {
}.encode()), }.encode()),
(56, ghost_networks::NetworkData { (56, ghost_networks::NetworkData {
chain_name: "bnb-mainnet".into(), chain_name: "bnb-mainnet".into(),
default_endpoint: vec![ default_endpoint: "https://bsc-mainnet.core.chainstack.com/35848e183f3e3303c8cfeacbea831cab/".into(),
"https://bsc-mainnet.core.chainstack.com/35848e183f3e3303c8cfeacbea831cab/".into(),
],
finality_delay: 20u64, finality_delay: 20u64,
rate_limit_delay: 1_000u64, rate_limit_delay: 1u64,
block_distance: 50u64, block_distance: 50u64,
network_type: ghost_networks::NetworkType::Evm, network_type: ghost_networks::NetworkType::Evm,
gatekeeper: "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82".into(), gatekeeper: "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82".into(),
@ -276,11 +272,6 @@ pub fn testnet_config_genesis(
"babe": { "babe": {
"epochConfig": Some(casper::BABE_GENESIS_EPOCH_CONFIG), "epochConfig": Some(casper::BABE_GENESIS_EPOCH_CONFIG),
}, },
"ghostSudo": {
"key": endowed_accounts
.first()
.cloned(),
},
"ghostNetworks": { "ghostNetworks": {
"networks": evm_networks, "networks": evm_networks,
}, },
@ -718,11 +709,6 @@ fn casper_staging_config_genesis() -> serde_json::Value {
"babe": { "babe": {
"epochConfig": Some(casper::BABE_GENESIS_EPOCH_CONFIG), "epochConfig": Some(casper::BABE_GENESIS_EPOCH_CONFIG),
}, },
"ghostSudo": {
"key": endowed_accounts
.first()
.cloned(),
},
"ghostNetworks": { "ghostNetworks": {
"networks": evm_networks, "networks": evm_networks,
}, },