Compare commits

..

No commits in common. "613b09ac6aec01cbdd2b97a08023cf5e5477341f" and "d83ee595086bafb7c92fc911a384fbe4f9bbea41" have entirely different histories.

40 changed files with 1141 additions and 718 deletions

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.9.1" version = "0.9.0"
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"

View File

@ -55,7 +55,6 @@ pub enum Subcommand {
/// Revert the chain to a previous state. /// Revert the chain to a previous state.
Revert(sc_cli::RevertCmd), Revert(sc_cli::RevertCmd),
#[cfg(feature = "runtime-benchmarks")]
/// The custom benchmark subcommmand benchmarking runtime pallets. /// The custom benchmark subcommmand benchmarking runtime pallets.
#[clap(subcommand)] #[clap(subcommand)]
Benchmark(frame_benchmarking_cli::BenchmarkCmd), Benchmark(frame_benchmarking_cli::BenchmarkCmd),

View File

@ -279,13 +279,22 @@ pub fn run() -> Result<()> {
task_manager, task_manager,
)) ))
})?) })?)
}, }
#[cfg(feature = "runtime-benchmarks")]
Some(Subcommand::Benchmark(cmd)) => { Some(Subcommand::Benchmark(cmd)) => {
let runner = cli.create_runner(cmd).map_err(Error::SubstrateCli)?; let runner = cli.create_runner(cmd).map_err(Error::SubstrateCli)?;
let chain_spec = &runner.config().chain_spec; let chain_spec = &runner.config().chain_spec;
match cmd { match cmd {
#[cfg(not(feature = "runtime-benchmarks"))]
BenchmarkCmd::Storage(_) => {
return Err(sc_cli::Error::Input(
"Compile with `--feature=runtime-benchmarks \
to enable storage benchmarks."
.into(),
)
.into())
}
#[cfg(feature = "runtime-benchmarks")]
BenchmarkCmd::Storage(cmd) => runner.sync_run(|mut config| { BenchmarkCmd::Storage(cmd) => runner.sync_run(|mut config| {
let (client, backend, _, _) = service::new_chain_ops(&mut config)?; let (client, backend, _, _) = service::new_chain_ops(&mut config)?;
let db = backend.expose_db(); let db = backend.expose_db();
@ -341,11 +350,21 @@ pub fn run() -> Result<()> {
BenchmarkCmd::Pallet(cmd) => { BenchmarkCmd::Pallet(cmd) => {
set_ss58_version(chain_spec); set_ss58_version(chain_spec);
runner.sync_run(|config| { if cfg!(feature = "runtime-benchmarks") {
cmd.run_with_spec::<sp_runtime::traits::HashingFor<service::Block>, ()>( runner.sync_run(|config| {
Some(config.chain_spec), cmd.run_with_spec::<sp_runtime::traits::HashingFor<service::Block>, ()>(
).map_err(|e| Error::SubstrateCli(e)) Some(config.chain_spec),
}) )
.map_err(|e| Error::SubstrateCli(e))
})
} else {
Err(sc_cli::Error::Input(
"Benchmarking wasn't enabled when building the node. \
You can enable it with `--features=runtime-benchmarks`."
.into(),
)
.into())
}
} }
BenchmarkCmd::Machine(cmd) => runner.sync_run(|config| { BenchmarkCmd::Machine(cmd) => runner.sync_run(|config| {
cmd.run( cmd.run(
@ -360,13 +379,6 @@ pub fn run() -> Result<()> {
_ => Err(Error::CommandNotImplemented), _ => Err(Error::CommandNotImplemented),
} }
} }
#[cfg(not(feature = "runtime-benchmarks"))]
Some(Subcommand::Benchmark(_)) => {
return Err(sc_cli::Error::Input(
"Benchmarking wasn't enabled when building the node. \
You can enable it with `--features=runtime-benchmarks`.".into(),
).into())
},
Some(Subcommand::Key(cmd)) => Ok(cmd.run(&cli)?), Some(Subcommand::Key(cmd)) => Ok(cmd.run(&cli)?),
Some(Subcommand::ChainInfo(cmd)) => { Some(Subcommand::ChainInfo(cmd)) => {
let runner = cli.create_runner(cmd)?; let runner = cli.create_runner(cmd)?;

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-exodus" name = "ghost-exodus"
version = "0.0.2" version = "0.0.0"
description = "Threshold signature generation with DKG included" description = "Threshold signature generation with DKG included"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -59,7 +59,7 @@ use rand_chacha::{ChaCha20Rng, rand_core::SeedableRng};
#[cfg(feature = "runtime-benchmarks")] #[cfg(feature = "runtime-benchmarks")]
mod benchmarking; mod benchmarking;
#[cfg(any(test))] #[cfg(any(test, feature = "runtime-benchmarks"))]
mod mock; mod mock;
#[cfg(test)] #[cfg(test)]
@ -497,7 +497,7 @@ pub mod pallet {
who: T::AccountId, who: T::AccountId,
network_id: NetworkIdOf<T>, network_id: NetworkIdOf<T>,
amount: BalanceOf<T>, amount: BalanceOf<T>,
bounty: Perbill, commission: Perbill,
receiver: EvmAddress, receiver: EvmAddress,
} }
} }
@ -1843,7 +1843,7 @@ pub mod pallet {
origin: OriginFor<T>, origin: OriginFor<T>,
network_id: NetworkIdOf<T>, network_id: NetworkIdOf<T>,
amount: BalanceOf<T>, amount: BalanceOf<T>,
bounty: Perbill, commission: Perbill,
receiver: EvmAddress, receiver: EvmAddress,
) -> DispatchResult { ) -> DispatchResult {
let who = ensure_signed(origin)?; let who = ensure_signed(origin)?;
@ -1858,7 +1858,7 @@ pub mod pallet {
Self::do_register_evm_bridge_out_exodus( Self::do_register_evm_bridge_out_exodus(
network_id, network_id,
amount, amount,
bounty, commission,
receiver, receiver,
)?; )?;
@ -1866,7 +1866,7 @@ pub mod pallet {
who, who,
network_id, network_id,
amount, amount,
bounty, commission,
receiver, receiver,
}); });
@ -2138,7 +2138,7 @@ impl<T: Config> Pallet<T> {
fn do_register_evm_bridge_out_exodus( fn do_register_evm_bridge_out_exodus(
network_id: NetworkIdOf<T>, network_id: NetworkIdOf<T>,
amount: BalanceOf<T>, amount: BalanceOf<T>,
bounty: Perbill, commission: Perbill,
receiver: EvmAddress, receiver: EvmAddress,
) -> DispatchResult { ) -> DispatchResult {
let network = T::NetworkDataHandler::get(&network_id) let network = T::NetworkDataHandler::get(&network_id)
@ -2156,7 +2156,7 @@ impl<T: Config> Pallet<T> {
exodus_session, exodus_session,
network_id, network_id,
amount, amount,
bounty, commission,
receiver receiver
); );
@ -3921,6 +3921,7 @@ impl<T: Config> Pallet<T> {
network_curve, network_curve,
); );
// TODO: log here
let round1_secret_package = round1_metadata.try_update_max_signers( let round1_secret_package = round1_metadata.try_update_max_signers(
|round1_secret_package| -> ExodusResult<Vec<u8>> { |round1_secret_package| -> ExodusResult<Vec<u8>> {
network_curve.dkg_narrow_round_max_signers( network_curve.dkg_narrow_round_max_signers(

View File

@ -1,6 +1,5 @@
use crate::*; use crate::*;
use crate::mock::*; use crate::mock::*;
use strum::IntoEnumIterator;
use sp_std::{ use sp_std::{
prelude::Vec, prelude::Vec,
@ -586,7 +585,7 @@ fn run_succesfull_dkg_session_partially(
) -> (u64, u64) { ) -> (u64, u64) {
let authorities: Vec<UintAuthorityId> = raw_authorities.iter().map(|&id| id.into()).collect(); let authorities: Vec<UintAuthorityId> = raw_authorities.iter().map(|&id| id.into()).collect();
let prev_dkg_index = ext.execute_with(|| QualificationDkgState::<Runtime>::get(curve).get_dkg_index()); let prev_dkg_index = ext.execute_with(|| QualificationDkgState::<Runtime>::get(curve).get_dkg_index());
ext.execute_with(|| Exodus::start_dkg_qualification(authorities, NetworkCurve::iter())); ext.execute_with(|| Exodus::start_dkg_qualification(authorities));
let dkg_index = ext.execute_with(|| QualificationDkgState::<Runtime>::get(curve).get_dkg_index()); let dkg_index = ext.execute_with(|| QualificationDkgState::<Runtime>::get(curve).get_dkg_index());
let (start_block, round_delay) = ext.execute_with(|| { let (start_block, round_delay) = ext.execute_with(|| {
@ -1103,7 +1102,7 @@ fn test_exodus_dkg_robustness() {
]; ];
let mut dkg_index = ext.execute_with(|| { let mut dkg_index = ext.execute_with(|| {
Exodus::start_dkg_qualification(authorities, NetworkCurve::iter()); Exodus::start_dkg_qualification(authorities);
QualificationDkgState::<Runtime>::get(curve).get_dkg_index() QualificationDkgState::<Runtime>::get(curve).get_dkg_index()
}); });
@ -1224,7 +1223,7 @@ fn test_prepare_round4_abort_on_byzantine_attack() {
let authorities: Vec<UintAuthorityId> = raw_authorities.iter().map(|&id| id.into()).collect(); let authorities: Vec<UintAuthorityId> = raw_authorities.iter().map(|&id| id.into()).collect();
let authorities_len = authorities.len(); let authorities_len = authorities.len();
ext.execute_with(|| Exodus::start_dkg_qualification(authorities, NetworkCurve::iter())); ext.execute_with(|| Exodus::start_dkg_qualification(authorities));
let dkg_rounds = [ let dkg_rounds = [
execute_round0_happy_path, execute_round0_happy_path,
@ -1268,7 +1267,7 @@ fn test_prepare_round5_abort_on_byzantine_attack() {
let authorities: Vec<UintAuthorityId> = raw_authorities.iter().map(|&id| id.into()).collect(); let authorities: Vec<UintAuthorityId> = raw_authorities.iter().map(|&id| id.into()).collect();
let authorities_len = authorities.len(); let authorities_len = authorities.len();
ext.execute_with(|| Exodus::start_dkg_qualification(authorities, NetworkCurve::iter())); ext.execute_with(|| Exodus::start_dkg_qualification(authorities));
let dkg_rounds = [ let dkg_rounds = [
execute_round0_happy_path, execute_round0_happy_path,
@ -1316,7 +1315,7 @@ fn test_prepare_round5_kick_on_empty_justifications() {
let authorities: Vec<UintAuthorityId> = raw_authorities.iter().map(|&id| id.into()).collect(); let authorities: Vec<UintAuthorityId> = raw_authorities.iter().map(|&id| id.into()).collect();
let authorities_len = authorities.len(); let authorities_len = authorities.len();
ext.execute_with(|| Exodus::start_dkg_qualification(authorities, NetworkCurve::iter())); ext.execute_with(|| Exodus::start_dkg_qualification(authorities));
let dkg_rounds = [ let dkg_rounds = [
execute_round0_happy_path, execute_round0_happy_path,

View File

@ -120,7 +120,7 @@ pub enum ExodusRequestType<NetworkId, Balance> {
exodus_session: ExodusSession, exodus_session: ExodusSession,
network_id: NetworkId, network_id: NetworkId,
amount: Balance, amount: Balance,
bounty: Perbill, commission: Perbill,
receiver: EvmAddress, receiver: EvmAddress,
}, },
EvmGovernance { network_id: NetworkId }, EvmGovernance { network_id: NetworkId },
@ -144,22 +144,22 @@ where
[exodus_session, public_key, parity] [exodus_session, public_key, parity]
) )
}, },
ExodusRequestType::EvmBridgeOut { exodus_session, network_id, amount, bounty, receiver } => { ExodusRequestType::EvmBridgeOut { exodus_session, network_id, amount, commission, receiver } => {
let mut buffer = [0u8; 32]; let mut buffer = [0u8; 32];
buffer[0..20].copy_from_slice(receiver.as_ref()); buffer[0..20].copy_from_slice(receiver.as_ref());
let chain_id_u64: u64 = (*network_id).unique_saturated_into(); let chain_id_u64: u64 = (*network_id).unique_saturated_into();
buffer[20..28].copy_from_slice(&chain_id_u64.to_be_bytes()); buffer[20..28].copy_from_slice(&chain_id_u64.to_be_bytes());
let scaled_bounty = multiply_by_rational_with_rounding( let scaled_commission = multiply_by_rational_with_rounding(
bounty.deconstruct() as u128, commission.deconstruct() as u128,
1u128 << 32, 1u128 << 32,
1_000_000_000, 1_000_000_000,
sp_runtime::Rounding::Down sp_runtime::Rounding::Down
)?; )?;
let bounty_uint32 = scaled_bounty as u32; let commission_uint32 = scaled_commission as u32;
buffer[28..32].copy_from_slice(&bounty_uint32.to_be_bytes()); buffer[28..32].copy_from_slice(&commission_uint32.to_be_bytes());
let mut amount_buffer = [0u8; 32]; let mut amount_buffer = [0u8; 32];
let amount_u128: u128 = (*amount).unique_saturated_into(); let amount_u128: u128 = (*amount).unique_saturated_into();
@ -208,14 +208,14 @@ where
exodus_session: ExodusSession, exodus_session: ExodusSession,
network_id: NetworkId, network_id: NetworkId,
amount: Balance, amount: Balance,
bounty: Perbill, commission: Perbill,
receiver: EvmAddress, receiver: EvmAddress,
) -> Self { ) -> Self {
let evm_bridge_out = ExodusRequestType::EvmBridgeOut { let evm_bridge_out = ExodusRequestType::EvmBridgeOut {
exodus_session, exodus_session,
network_id, network_id,
amount, amount,
bounty, commission,
receiver, receiver,
}; };
Self::default_request_for(evm_bridge_out) Self::default_request_for(evm_bridge_out)

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-governance" name = "ghost-governance"
version = "0.3.2" version = "0.3.0"
description = "Full-chain and cross-chain governance pallet with early adopter share claims" description = "Full-chain and cross-chain governance pallet with early adopter share claims"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true
@ -33,7 +33,9 @@ ghost-networks = { workspace = true }
[dev-dependencies] [dev-dependencies]
libsecp256k1 = { workspace = true, default-features = true } libsecp256k1 = { workspace = true, default-features = true }
hex-literal = { workspace = true, default-features = true } hex = { workspace = true }
# hex-literal = { workspace = true, default-features = true }
# serde_json = { workspace = true, default-features = true }
[features] [features]
default = ["std"] default = ["std"]
@ -41,6 +43,7 @@ std = [
"frame-benchmarking?/std", "frame-benchmarking?/std",
"serde/std", "serde/std",
"codec/std", "codec/std",
"hex/std",
"scale-info/std", "scale-info/std",
"libsecp256k1/std", "libsecp256k1/std",
"frame-support/std", "frame-support/std",

View File

@ -2,25 +2,25 @@
use super::*; use super::*;
use frame_benchmarking::v2::*; use frame_benchmarking::v2::*;
use frame_support::dispatch::RawOrigin; use frame_support::dispatch::RawOrigin;
use ghost_helpers::merkle_tree::{generate_tree, generate_proof};
#[benchmarks(where T: Config)] #[benchmarks(where T: Config)]
mod benchmarks { mod benchmarks {
use super::*; use super::*;
#[benchmark] #[benchmark]
fn claim( fn claim() {
p: Linear<1, { T::MaxProofDepth::get() }>
) -> Result<(), BenchmarkError> {
let network_id = Default::default(); let network_id = Default::default();
let current_account: T::AccountId = frame_benchmarking::whitelisted_caller(); let current_account: T::AccountId = frame_benchmarking::whitelisted_caller();
let max_proof_depth = p;
let max_proof_depth = <<T as Config>::MaxProofDepth as Get<u32>>::get();
let minimum_donation_u128 = <<T as Config>::MinimumDonation as Get<u128>>::get(); let minimum_donation_u128 = <<T as Config>::MinimumDonation as Get<u128>>::get();
let minimum_donation: BalanceOf<T> = minimum_donation_u128.unique_saturated_into(); let minimum_donation: BalanceOf<T> = minimum_donation_u128.unique_saturated_into();
let dummy_shares_u128 = 420u128; let dummy_balance_u128 = 420u128;
let dummy_shares: BalanceOf<T> = dummy_shares_u128.unique_saturated_into(); let dummy_balance: BalanceOf<T> = dummy_balance_u128.unique_saturated_into();
let secret_key = libsecp256k1::SecretKey::parse(&[69u8; 32]).unwrap(); let secret_key = libsecp256k1::SecretKey::parse(&[69u8; 32]).unwrap();
let public_key = libsecp256k1::PublicKey::from_secret_key(&secret_key); let public_key = libsecp256k1::PublicKey::from_secret_key(&secret_key);
@ -31,45 +31,28 @@ mod benchmarks {
evm_addr_bytes.copy_from_slice(&pubkey_hash.as_ref()[12..32]); evm_addr_bytes.copy_from_slice(&pubkey_hash.as_ref()[12..32]);
let dummy_evm_address = EvmAddress::from(evm_addr_bytes); let dummy_evm_address = EvmAddress::from(evm_addr_bytes);
let target_index = 0u32; let total_entries = 1u64 << max_proof_depth;
let claim_package_init = ClaimPackage { let max_index = total_entries - 1;
shares: dummy_shares, let raw_values = (0..total_entries)
merkle_proof: Default::default(), .map(|i| i as TokenId)
token_id: 0, .collect::<Vec<TokenId>>();
index: target_index,
};
let preimage_init = claim_package_init.get_preimage(&dummy_evm_address, network_id); let merkle_tree = generate_tree::<SubstrateKeccakHasher, _, _, _, _>(
let mut current_hash = SubstrateKeccakHasher::hash(&preimage_init); max_index,
raw_values,
|index: TokenId| -> Result<(usize, Vec<u8>), ()> {
let claim_package = ClaimPackage {
balance: dummy_balance,
merkle_proof: Default::default(),
token_id: index,
};
let mut proof_hashes = Vec::with_capacity(max_proof_depth as usize); let claim_preimage = claim_package.get_preimage(&dummy_evm_address);
let mut current_index = target_index as usize; Ok((index as usize, claim_preimage.to_vec()))
let hash_len = SubstrateKeccakHasher::hash_len();
let mut combined = sp_std::vec![0u8; hash_len * 2];
for i in 0..max_proof_depth {
let mut sibling_bytes = [0u8; 32];
sibling_bytes[24..32].copy_from_slice(&(i as u64).to_be_bytes());
let sibling_hash = EvmHash::from_slice(&sibling_bytes);
proof_hashes.push(sibling_hash);
let sibling_bytes_ref = sibling_hash.as_ref();
let hash_bytes = current_hash.as_ref();
if current_index % 2 == 0 {
combined[..hash_len].copy_from_slice(hash_bytes);
combined[hash_len..].copy_from_slice(sibling_bytes_ref);
} else {
combined[..hash_len].copy_from_slice(sibling_bytes_ref);
combined[hash_len..].copy_from_slice(hash_bytes);
} }
).unwrap();
current_hash = SubstrateKeccakHasher::hash(&combined); let merkle_root = *merkle_tree.last().unwrap();
current_index >>= 1;
}
let merkle_root = current_hash;
let member_share = MemberShare { let member_share = MemberShare {
initiated_network: None, initiated_network: None,
@ -79,23 +62,28 @@ mod benchmarks {
MemberShares::<T>::insert(&current_account, member_share); MemberShares::<T>::insert(&current_account, member_share);
let network_state = NetworkShare::new( let network_state = NetworkShare::new(
dummy_shares, dummy_balance,
merkle_root, merkle_root,
max_proof_depth, max_proof_depth,
); );
NetworkShares::<T>::insert(&network_id, network_state); NetworkShares::<T>::insert(&network_id, network_state);
let global_state = ShareState::new(dummy_shares); let global_state = ShareState::new(dummy_balance);
GlobalShares::<T>::put(global_state); GlobalShares::<T>::put(global_state);
let merkle_proof = generate_proof::<SubstrateKeccakHasher, _>(
&merkle_tree,
total_entries - 1,
0,
);
let claim_package = ClaimPackage { let claim_package = ClaimPackage {
index: 0, merkle_proof: BoundedVec::try_from(merkle_proof).unwrap(),
merkle_proof: BoundedVec::try_from(proof_hashes).unwrap(), balance: dummy_balance,
shares: dummy_shares,
token_id: 0 token_id: 0
}; };
let preimage = claim_package.get_preimage(&dummy_evm_address, network_id); let preimage = claim_package.get_preimage(&dummy_evm_address);
let preimage_hash = SubstrateKeccakHasher::hash(&preimage); let preimage_hash = SubstrateKeccakHasher::hash(&preimage);
let message_string_bytes = Pallet::<T>::ethereum_signable_message( let message_string_bytes = Pallet::<T>::ethereum_signable_message(
@ -128,17 +116,15 @@ mod benchmarks {
evm_signature, evm_signature,
); );
assert_eq!(dummy_shares, GlobalShares::<T>::get().claimed_shares); assert_eq!(dummy_balance, GlobalShares::<T>::get().claimed_shares);
assert_eq!( assert_eq!(
dummy_shares, dummy_balance,
MemberShares::<T>::get(&current_account).activated_shares MemberShares::<T>::get(&current_account).activated_shares
); );
assert_eq!( assert_eq!(
dummy_shares, dummy_balance,
NetworkShares::<T>::get(&network_id).claimed_shares(), NetworkShares::<T>::get(&network_id).claimed_shares(),
); );
Ok(())
} }
impl_benchmark_test_suite!( impl_benchmark_test_suite!(

View File

@ -143,9 +143,8 @@ pub struct ClaimPackage<Balance>
where where
Balance: Default + Copy + Clone, Balance: Default + Copy + Clone,
{ {
pub index: u32,
pub token_id: TokenId, pub token_id: TokenId,
pub shares: Balance, pub balance: Balance,
pub merkle_proof: BoundedVec<EvmHash, ConstU32<MAX_POSSIBLE_PROOF_DEPTH>>, pub merkle_proof: BoundedVec<EvmHash, ConstU32<MAX_POSSIBLE_PROOF_DEPTH>>,
} }
@ -153,33 +152,21 @@ impl<Balance> ClaimPackage<Balance>
where where
Balance: Default + Copy + Clone + UniqueSaturatedInto<u128>, Balance: Default + Copy + Clone + UniqueSaturatedInto<u128>,
{ {
pub fn get_preimage<NetworkId>( pub fn get_preimage(&self, evm_address: &EvmAddress) -> [u8; 96] {
&self,
evm_address: &EvmAddress,
network_id: NetworkId
) -> [u8; 128]
where
NetworkId: Default + Copy + Clone + UniqueSaturatedInto<u128>,
{
let mut token_id_bytes = [0u8; 32]; let mut token_id_bytes = [0u8; 32];
U256::from(self.token_id as u128).to_big_endian(&mut token_id_bytes); U256::from(self.token_id as u128).to_big_endian(&mut token_id_bytes);
let mut shares_bytes = [0u8; 32]; let balance_u128: u128 = self.balance.unique_saturated_into();
let shares_u128: u128 = self.shares.unique_saturated_into(); let mut balance_bytes = [0u8; 32];
U256::from(shares_u128).to_big_endian(&mut shares_bytes); U256::from(balance_u128).to_big_endian(&mut balance_bytes);
let mut address_bytes = [0u8; 32]; let mut address_bytes = [0u8; 32];
address_bytes[12..32].copy_from_slice(evm_address.as_bytes()); address_bytes[12..32].copy_from_slice(evm_address.as_bytes());
let mut network_id_bytes = [0u8; 32]; let mut preimage = [0u8; 96];
let network_id_u128: u128 = network_id.unique_saturated_into();
U256::from(network_id_u128).to_big_endian(&mut network_id_bytes);
let mut preimage = [0u8; 128];
preimage[0..32].copy_from_slice(&token_id_bytes); preimage[0..32].copy_from_slice(&token_id_bytes);
preimage[32..64].copy_from_slice(&shares_bytes); preimage[32..64].copy_from_slice(&balance_bytes);
preimage[64..96].copy_from_slice(&address_bytes); preimage[64..96].copy_from_slice(&address_bytes);
preimage[96..128].copy_from_slice(&network_id_bytes);
preimage preimage
} }
@ -222,7 +209,7 @@ pub mod pallet {
pub enum Event<T: Config> { pub enum Event<T: Config> {
SharesClaimed { SharesClaimed {
who: T::AccountId, who: T::AccountId,
shares: BalanceOf<T>, balance: BalanceOf<T>,
network_id: NetworkIdOf<T>, network_id: NetworkIdOf<T>,
} }
} }
@ -308,9 +295,7 @@ pub mod pallet {
#[pallet::call] #[pallet::call]
impl<T: Config> Pallet<T> { impl<T: Config> Pallet<T> {
#[pallet::call_index(0)] #[pallet::call_index(0)]
#[pallet::weight(<T as Config>::WeightInfo::claim( #[pallet::weight(<T as Config>::WeightInfo::claim())]
claim_package.merkle_proof.len() as u32,
))]
pub fn claim( pub fn claim(
origin: OriginFor<T>, origin: OriginFor<T>,
network_id: NetworkIdOf<T>, network_id: NetworkIdOf<T>,
@ -335,7 +320,7 @@ pub mod pallet {
ensure!(correct_network_bound, Error::<T>::BoundedToOtherNetwork); ensure!(correct_network_bound, Error::<T>::BoundedToOtherNetwork);
let preimage = claim_package.get_preimage(&evm_address, network_id); let preimage = claim_package.get_preimage(&evm_address);
let preimage_hash = SubstrateKeccakHasher::hash(&preimage); let preimage_hash = SubstrateKeccakHasher::hash(&preimage);
ensure!( ensure!(
@ -351,25 +336,25 @@ pub mod pallet {
let proof_size_match = package_proof_size == state.proofs_size; let proof_size_match = package_proof_size == state.proofs_size;
ensure!(proof_size_match, Error::<T>::SharesOverflowed); ensure!(proof_size_match, Error::<T>::SharesOverflowed);
let increased = state.try_increase_claimed(claim_package.shares); let increased = state.try_increase_claimed(claim_package.balance);
ensure!(increased.is_some(), Error::<T>::SharesOverflowed); ensure!(increased.is_some(), Error::<T>::SharesOverflowed);
Ok(()) Ok(())
})?; })?;
GlobalShares::<T>::try_mutate(|state| -> DispatchResult { GlobalShares::<T>::try_mutate(|state| -> DispatchResult {
let increased = state.try_increase_claimed(claim_package.shares); let increased = state.try_increase_claimed(claim_package.balance);
ensure!(increased.is_some(), Error::<T>::SharesOverflowed); ensure!(increased.is_some(), Error::<T>::SharesOverflowed);
Ok(()) Ok(())
})?; })?;
member_share.increase_activated_shares(claim_package.shares); member_share.increase_activated_shares(claim_package.balance);
member_share.initiate_on_network(network_id); member_share.initiate_on_network(network_id);
MemberShares::<T>::insert(&who, member_share); MemberShares::<T>::insert(&who, member_share);
ClaimedHashes::<T>::insert(&preimage_hash, true); ClaimedHashes::<T>::insert(&preimage_hash, true);
Self::deposit_event(Event::<T>::SharesClaimed { Self::deposit_event(Event::<T>::SharesClaimed {
shares: claim_package.shares, balance: claim_package.balance,
network_id, network_id,
who, who,
}); });
@ -462,11 +447,11 @@ impl<T: Config> Pallet<T> {
let network_state = NetworkShares::<T>::get(network_id); let network_state = NetworkShares::<T>::get(network_id);
let is_merkle_proof_valid = let is_merkle_proof_valid =
verify_tree_proof::<SubstrateKeccakHasher, _>( verify_tree_proof::<SubstrateKeccakHasher, TokenId>(
preimage, preimage,
&claim_package.merkle_proof, &claim_package.merkle_proof,
network_state.merkle_root, network_state.merkle_root,
claim_package.index, claim_package.token_id,
); );
ensure!(is_merkle_proof_valid, Error::<T>::InvalidMerkleProof); ensure!(is_merkle_proof_valid, Error::<T>::InvalidMerkleProof);

View File

@ -16,7 +16,7 @@ impl frame_system::Config for Test {
type RuntimeCall = RuntimeCall; type RuntimeCall = RuntimeCall;
type Block = Block; type Block = Block;
type RuntimeEvent = RuntimeEvent; type RuntimeEvent = RuntimeEvent;
type AccountData = pallet_balances::AccountData<u128>; type AccountData = pallet_balances::AccountData<u64>;
type MaxConsumers = frame_support::traits::ConstU32<16>; type MaxConsumers = frame_support::traits::ConstU32<16>;
type AccountId = sp_runtime::AccountId32; type AccountId = sp_runtime::AccountId32;
@ -25,9 +25,7 @@ impl frame_system::Config for Test {
#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)] #[derive_impl(pallet_balances::config_preludes::TestDefaultConfig)]
impl pallet_balances::Config for Test { impl pallet_balances::Config for Test {
type ExistentialDeposit = frame_support::traits::ConstU128<1>;
type AccountStore = System; type AccountStore = System;
type Balance = u128;
} }
parameter_types! { parameter_types! {

View File

@ -2,7 +2,6 @@
use mock::*; use mock::*;
use super::*; use super::*;
use hex_literal::hex;
use sp_runtime::AccountId32; use sp_runtime::AccountId32;
use frame_support::traits::Get; use frame_support::traits::Get;
@ -16,7 +15,7 @@ pub struct NewTestUser {
pub substrate_account: AccountId32, pub substrate_account: AccountId32,
pub evm_secret: SecretKey, pub evm_secret: SecretKey,
pub evm_address: EvmAddress, pub evm_address: EvmAddress,
pub allowed_shares: u128, pub allowed_balance: u64,
pub token_id: u128, pub token_id: u128,
} }
@ -40,7 +39,7 @@ fn claim_happy_path() {
substrate_account: AccountId32::new([11u8; 32]), substrate_account: AccountId32::new([11u8; 32]),
evm_secret: secret_key_1, evm_secret: secret_key_1,
evm_address: EvmAddress::from(evm_addr_bytes_1), evm_address: EvmAddress::from(evm_addr_bytes_1),
allowed_shares: 420u128, allowed_balance: 420u64,
token_id: 0, token_id: 0,
}; };
@ -56,7 +55,7 @@ fn claim_happy_path() {
substrate_account: AccountId32::new([22u8; 32]), substrate_account: AccountId32::new([22u8; 32]),
evm_secret: secret_key_2, evm_secret: secret_key_2,
evm_address: EvmAddress::from(evm_addr_bytes_2), evm_address: EvmAddress::from(evm_addr_bytes_2),
allowed_shares: 1337u128, allowed_balance: 1337u64,
token_id: 1, token_id: 1,
}; };
@ -72,7 +71,7 @@ fn claim_happy_path() {
substrate_account: AccountId32::new([69u8; 32]), substrate_account: AccountId32::new([69u8; 32]),
evm_secret: secret_key_3, evm_secret: secret_key_3,
evm_address: EvmAddress::from(evm_addr_bytes_3), evm_address: EvmAddress::from(evm_addr_bytes_3),
allowed_shares: 69u128, allowed_balance: 69u64,
token_id: 2, token_id: 2,
}; };
@ -88,13 +87,12 @@ fn claim_happy_path() {
let (index, u) = item; let (index, u) = item;
let tmp_package = ClaimPackage { let tmp_package = ClaimPackage {
shares: u.allowed_shares, balance: u.allowed_balance,
merkle_proof: Default::default(), merkle_proof: Default::default(),
token_id: u.token_id, token_id: u.token_id,
index: index as u32
}; };
Ok((index as usize, tmp_package.get_preimage(&u.evm_address, network_id).to_vec())) Ok((index as usize, tmp_package.get_preimage(&u.evm_address).to_vec()))
} }
).unwrap(); ).unwrap();
@ -119,13 +117,12 @@ fn claim_happy_path() {
let proof = generate_proof::<SubstrateKeccakHasher, u8>(&merkle_tree, max_index, slot_index as u8); let proof = generate_proof::<SubstrateKeccakHasher, u8>(&merkle_tree, max_index, slot_index as u8);
let claim_package = ClaimPackage { let claim_package = ClaimPackage {
shares: current_user.allowed_shares, balance: current_user.allowed_balance,
merkle_proof: BoundedVec::try_from(proof).unwrap(), merkle_proof: BoundedVec::try_from(proof).unwrap(),
token_id: current_user.token_id, token_id: current_user.token_id,
index: slot_index as u32,
}; };
let preimage = claim_package.get_preimage(&current_user.evm_address, network_id); let preimage = claim_package.get_preimage(&current_user.evm_address);
let preimage_hash = SubstrateKeccakHasher::hash(&preimage); let preimage_hash = SubstrateKeccakHasher::hash(&preimage);
let message_string_bytes = Governance::ethereum_signable_message( let message_string_bytes = Governance::ethereum_signable_message(
@ -158,10 +155,10 @@ fn claim_happy_path() {
)); ));
let updated_share = MemberShares::<Test>::get(&current_user.substrate_account); let updated_share = MemberShares::<Test>::get(&current_user.substrate_account);
assert_eq!(updated_share.activated_shares, current_user.allowed_shares); assert_eq!(updated_share.activated_shares, current_user.allowed_balance);
global_activated += current_user.allowed_shares; global_activated += current_user.allowed_balance;
network_activated += current_user.allowed_shares; network_activated += current_user.allowed_balance;
} }
assert_eq!(global_activated, GlobalShares::<Test>::get().claimed_shares); assert_eq!(global_activated, GlobalShares::<Test>::get().claimed_shares);
@ -171,139 +168,3 @@ fn claim_happy_path() {
); );
}); });
} }
#[test]
fn verify_proof_from_python_preclaims_for_sepolia() {
new_test_ext().execute_with(|| {
// ===========================================================================================================
// === FINAL MERKLE ROOT FOR [SEPOLIA]: 0xd7f7f0061338c2c59a96caa8a2572491315755cdcce534954d4ce30150c3bb7c ===
// ===========================================================================================================
// [+] Total padded leaves: 128
// [+] Merkle tree size: 255
// [+] Network ID: 11155111
// [+] Proof size: 7
// [+] Total shares: 694000000000000000000
let network_id = 11155111u64;
let merkle_root = EvmHash::from(hex!("d7f7f0061338c2c59a96caa8a2572491315755cdcce534954d4ce30150c3bb7c"));
let proof_size = 7;
let total_shares = 694000000000000000000;
let network_state = NetworkShare::new(total_shares, merkle_root, proof_size);
let global_state = ShareState::new(total_shares);
NetworkShares::<Test>::insert(&network_id, network_state);
GlobalShares::<Test>::put(global_state);
let evm_holder_1 = EvmAddress::from(hex!("D500EFDef75E89Bf6caF5C98F7633575d0049a72"));
let claim_package_1 = ClaimPackage {
index: 0,
token_id: 1,
shares: 670000000000000000000,
merkle_proof: BoundedVec::try_from(
vec![
EvmHash::from(hex!("4dba08ba4fae6cbb0a6be6bdce81e91baf913d1857f470e97388157edd4d8d5c")),
EvmHash::from(hex!("7c1a4d2ebe6a500171b0c0f6c624898261da62d09c132106c4acec277660bd01")),
EvmHash::from(hex!("00c5bca05597b46f72d9ee739bd3c6ff80ebd1d20944879fe0c8d1dc9fda1643")),
EvmHash::from(hex!("5cf752cd738db6581182f07395e89cc61cd2ca630d6e85235d506f7395217d5f")),
EvmHash::from(hex!("4df068cecd63b6ccfd326df735afbfbe254df62613f7d9b52769f0e99f156957")),
EvmHash::from(hex!("d7f20777e3a1fed303fe1a459ce115e2561a92d66b34fd16dd793b8b69295082")),
EvmHash::from(hex!("4524fdc1aa98beafabe1341f53ee2373e541ad2efd152963fd9ce94571d283e4")),
]
).unwrap(),
};
let preimage_1 = claim_package_1.get_preimage(&evm_holder_1, network_id);
assert_ok!(
Governance::verify_merkle_proof(
&network_id,
&preimage_1,
&claim_package_1,
)
);
let evm_holder_2 = EvmAddress::from(hex!("Ee71538ae7677829676BD8dD18259Ed93E6B44e9"));
let claim_package_2 = ClaimPackage {
index: 2,
token_id: 3,
shares: 8000000000000000000,
merkle_proof: BoundedVec::try_from(
vec![
EvmHash::from(hex!("a8bbe4e0578964e3e6c40b93380967d69b7a1fd0358bffe789473892ec82872d")),
EvmHash::from(hex!("9b771d13977930979a26632d74e350885d5750b00646a5b03114b5815afb9f2f")),
EvmHash::from(hex!("00c5bca05597b46f72d9ee739bd3c6ff80ebd1d20944879fe0c8d1dc9fda1643")),
EvmHash::from(hex!("5cf752cd738db6581182f07395e89cc61cd2ca630d6e85235d506f7395217d5f")),
EvmHash::from(hex!("4df068cecd63b6ccfd326df735afbfbe254df62613f7d9b52769f0e99f156957")),
EvmHash::from(hex!("d7f20777e3a1fed303fe1a459ce115e2561a92d66b34fd16dd793b8b69295082")),
EvmHash::from(hex!("4524fdc1aa98beafabe1341f53ee2373e541ad2efd152963fd9ce94571d283e4")),
]
).unwrap(),
};
let preimage_2 = claim_package_2.get_preimage(&evm_holder_2, network_id);
assert_ok!(
Governance::verify_merkle_proof(
&network_id,
&preimage_2,
&claim_package_2,
)
);
let evm_holder_3 = EvmAddress::from(hex!("29c6D9e3c3981e4FcF2AC6B486e4E4210daeA1Ee"));
let claim_package_3 = ClaimPackage {
index: 6,
token_id: 7,
shares: 4000000000000000000,
merkle_proof: BoundedVec::try_from(
vec![
EvmHash::from(hex!("d28eec1544597d9e050c88a7a84535be82caf9b9e0b0c9b59b39283e7885a0d1")),
EvmHash::from(hex!("6e939188f98c3ed00931e66fdfc220c036b98edc54a212f5b18e2d3776c7c22f")),
EvmHash::from(hex!("4141baa2d892b0111bbb102078bd3ad5331c74f176b228c588741c1c306cb67d")),
EvmHash::from(hex!("5cf752cd738db6581182f07395e89cc61cd2ca630d6e85235d506f7395217d5f")),
EvmHash::from(hex!("4df068cecd63b6ccfd326df735afbfbe254df62613f7d9b52769f0e99f156957")),
EvmHash::from(hex!("d7f20777e3a1fed303fe1a459ce115e2561a92d66b34fd16dd793b8b69295082")),
EvmHash::from(hex!("4524fdc1aa98beafabe1341f53ee2373e541ad2efd152963fd9ce94571d283e4"))
]
).unwrap(),
};
let preimage_3 = claim_package_3.get_preimage(&evm_holder_3, network_id);
assert_ok!(
Governance::verify_merkle_proof(
&network_id,
&preimage_3,
&claim_package_3,
)
);
let evm_holder_4 = EvmAddress::from(hex!("Fe962E8BB2a6877d14b53E0a07932C040eC885ea"));
let claim_package_4 = ClaimPackage {
index: 35,
token_id: 36,
shares: 4000000000000000000,
merkle_proof: BoundedVec::try_from(
vec![
EvmHash::from(hex!("6b405422bcab22b7c28a9b429096e31d664522154856efb0d7b16485080b2e2a")),
EvmHash::from(hex!("620bb1858eaf6c6bb543fcf5f4b0d0b5adfbb95506403038eb153f075a00f522")),
EvmHash::from(hex!("e0b7058849ff216808963201ad2336f5587ff02eff08aceddb4764cc785413fd")),
EvmHash::from(hex!("e23325a502fe4248c8e049400a92a1c655689499c129b0ce6be3fad5d4a12dc1")),
EvmHash::from(hex!("0cde8f646452003d6c8ff1fd265ea41cd3af2e733e63ec25a9dfc82ddf41e968")),
EvmHash::from(hex!("c012942dae89ee6d1e1e44e876ae29b9421aaf0597dd2345f07a1439a98e0cbd")),
EvmHash::from(hex!("4524fdc1aa98beafabe1341f53ee2373e541ad2efd152963fd9ce94571d283e4"))
]
).unwrap(),
};
let preimage_4 = claim_package_4.get_preimage(&evm_holder_4, network_id);
assert_ok!(
Governance::verify_merkle_proof(
&network_id,
&preimage_4,
&claim_package_4,
)
);
})
}

View File

@ -48,7 +48,7 @@ use core::marker::PhantomData;
/// Weight functions needed for `ghost_claims`. /// Weight functions needed for `ghost_claims`.
pub trait WeightInfo { pub trait WeightInfo {
fn claim(p: u32) -> Weight; fn claim() -> Weight;
} }
impl WeightInfo for () { impl WeightInfo for () {
@ -64,7 +64,7 @@ impl WeightInfo for () {
/// Proof: `CultCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// Proof: `CultCollective::IdToIndex` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`)
/// Storage: `CultCollective::IndexToId` (r:0 w:6) /// Storage: `CultCollective::IndexToId` (r:0 w:6)
/// Proof: `CultCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`) /// Proof: `CultCollective::IndexToId` (`max_values`: None, `max_size`: Some(54), added: 2529, mode: `MaxEncodedLen`)
fn claim(_p: u32) -> Weight { fn claim() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `896` // Measured: `896`
// Estimated: `16164` // Estimated: `16164`

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-helpers" name = "ghost-helpers"
version = "0.0.6" version = "0.0.5"
description = "Cryptographic utility suite for custom runtimes: optimized Bitmaps, UTXO parsing, Merkle Tree proofs, and Hash Chain components." description = "Cryptographic utility suite for custom runtimes: optimized Bitmaps, UTXO parsing, Merkle Tree proofs, and Hash Chain components."
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -223,8 +223,8 @@ pub struct NetworkData {
pub rate_limit_delay: u64, pub rate_limit_delay: u64,
pub block_deviation: u64, pub block_deviation: u64,
pub incoming_share: u32, pub incoming_fee: u32,
pub outgoing_share: u32, pub outgoing_fee: u32,
} }
#[derive(Default)] #[derive(Default)]
@ -240,8 +240,8 @@ pub struct NetworkDataBuilder {
pub rate_limit_delay: u64, pub rate_limit_delay: u64,
pub block_deviation: u64, pub block_deviation: u64,
pub incoming_share: u32, pub incoming_fee: u32,
pub outgoing_share: u32, pub outgoing_fee: u32,
} }
impl NetworkDataBuilder { impl NetworkDataBuilder {
@ -280,13 +280,13 @@ impl NetworkDataBuilder {
self self
} }
pub fn with_incoming_share(mut self, incoming_share: u32) -> Self { pub fn with_incoming_fee(mut self, incoming_fee: u32) -> Self {
self.incoming_share = incoming_share; self.incoming_fee = incoming_fee;
self self
} }
pub fn with_outgoing_share(mut self, outgoing_share: u32) -> Self { pub fn with_outgoing_fee(mut self, outgoing_fee: u32) -> Self {
self.outgoing_share = outgoing_share; self.outgoing_fee = outgoing_fee;
self self
} }
@ -328,8 +328,8 @@ impl NetworkDataBuilder {
rate_limit_delay: self.rate_limit_delay, rate_limit_delay: self.rate_limit_delay,
block_deviation: self.block_deviation, block_deviation: self.block_deviation,
incoming_share: self.incoming_share, incoming_fee: self.incoming_fee,
outgoing_share: self.outgoing_share, outgoing_fee: self.outgoing_fee,
} }
} }
} }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-networks" name = "ghost-networks"
version = "0.2.8" version = "0.2.7"
description = "Registry and lifecycle management for external network metadata and cryptographic profiles." description = "Registry and lifecycle management for external network metadata and cryptographic profiles."
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -42,8 +42,8 @@ fn prepare_network<T: Config>(
.with_rate_limit_delay(6) .with_rate_limit_delay(6)
.with_finality_delay(69) .with_finality_delay(69)
.with_block_deviation(420) .with_block_deviation(420)
.with_incoming_share(0) .with_incoming_fee(0)
.with_outgoing_share(0) .with_outgoing_fee(0)
.build(); .build();
(chain_id, network) (chain_id, network)
@ -204,27 +204,27 @@ benchmarks! {
assert_ne!(GhostNetworks::<T>::networks(chain_id), prev_network); assert_ne!(GhostNetworks::<T>::networks(chain_id), prev_network);
} }
update_incoming_network_share { update_incoming_network_fee {
let incoming_share = 1337; let incoming_fee = 1337;
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 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, network)?; let prev_network = create_network::<T>(chain_id, network)?;
}: _<T::RuntimeOrigin>(authority, chain_id, incoming_share) }: _<T::RuntimeOrigin>(authority, chain_id, incoming_fee)
verify { verify {
assert_last_event::<T>(Event::NetworkIncomingShareUpdated { chain_id, incoming_share }.into()); assert_last_event::<T>(Event::NetworkIncomingFeeUpdated { chain_id, incoming_fee }.into());
assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network); assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network);
} }
update_outgoing_network_share { update_outgoing_network_fee {
let outgoing_share = 1337; let outgoing_fee = 1337;
let (chain_id, network) = prepare_network::<T>(1, 1, 1); let (chain_id, network) = prepare_network::<T>(1, 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, network)?; let prev_network = create_network::<T>(chain_id, network)?;
}: _<T::RuntimeOrigin>(authority, chain_id, outgoing_share) }: _<T::RuntimeOrigin>(authority, chain_id, outgoing_fee)
verify { verify {
assert_last_event::<T>(Event::NetworkOutgoingShareUpdated { chain_id, outgoing_share }.into()); assert_last_event::<T>(Event::NetworkOutgoingFeeUpdated { chain_id, outgoing_fee }.into());
assert_ne!(GhostNetworks::<T>::networks(chain_id), prev_network); assert_ne!(GhostNetworks::<T>::networks(chain_id), prev_network);
} }

View File

@ -1,4 +1,6 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
#![allow(clippy::large_enum_variant)]
#![allow(clippy::too_many_arguments)]
use frame_support::{ use frame_support::{
pallet_prelude::*, pallet_prelude::*,
@ -10,11 +12,8 @@ use scale_info::TypeInfo;
use sp_runtime::{ use sp_runtime::{
curve::PiecewiseLinear, curve::PiecewiseLinear,
traits::{ traits::{AtLeast32BitUnsigned, CheckedAdd, CheckedSub, Member, UniqueSaturatedInto},
AtLeast32BitUnsigned, CheckedAdd, CheckedSub, Member, DispatchResult,
Saturating, UniqueSaturatedInto,
},
DispatchResult, Perbill,
}; };
use sp_std::{convert::TryInto, prelude::*}; use sp_std::{convert::TryInto, prelude::*};
@ -43,10 +42,9 @@ pub type BalanceOf<T> =
<<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance; <<T as Config>::Currency as Inspect<<T as frame_system::Config>::AccountId>>::Balance;
#[derive(Default, Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] #[derive(Default, Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
pub struct NetworkImbalanceState<Balance> { pub struct BridgeAdjustment<Balance> {
pub outgoing: Balance, pub bridged_out: Balance,
pub incoming: Balance, pub bridged_in: Balance,
pub curve_share: Balance,
} }
pub struct BridgedInflationCurve<RewardCurve, T>(core::marker::PhantomData<(RewardCurve, T)>); pub struct BridgedInflationCurve<RewardCurve, T>(core::marker::PhantomData<(RewardCurve, T)>);
@ -73,18 +71,16 @@ where
_era_duration_in_millis: u64, _era_duration_in_millis: u64,
) -> (Balance, Balance) { ) -> (Balance, Balance) {
let reward_curve = RewardCurve::get(); let reward_curve = RewardCurve::get();
let state = NetworkImbalance::<T>::take(); let bridged_imbalance = BridgedImbalance::<T>::take();
let accumulated_commission = AccumulatedCommission::<T>::take();
let accumulated_commission: Balance = state.curve_share.into(); let accumulated_commission: Balance = accumulated_commission.into();
let adjusted_issuance: Balance = total_issuance let adjusted_issuance: Balance = total_issuance
.saturating_add(state.outgoing.into()) .saturating_add(bridged_imbalance.bridged_out.into())
.saturating_sub(state.incoming.into()); .saturating_sub(bridged_imbalance.bridged_in.into());
let estimated_reward = let estimated_reward =
reward_curve.calculate_for_fraction_times_denominator( reward_curve.calculate_for_fraction_times_denominator(total_staked, adjusted_issuance);
total_staked,
adjusted_issuance,
);
let payout: Balance = sp_runtime::helpers_128bit::multiply_by_rational_with_rounding( let payout: Balance = sp_runtime::helpers_128bit::multiply_by_rational_with_rounding(
estimated_reward.unique_saturated_into(), estimated_reward.unique_saturated_into(),
@ -176,19 +172,20 @@ pub mod module {
NetworkTypeUpdated { chain_id: T::NetworkId, network_type: NetworkType }, NetworkTypeUpdated { chain_id: T::NetworkId, network_type: NetworkType },
NetworkCurveUpdated { chain_id: T::NetworkId, network_curve: NetworkCurve }, NetworkCurveUpdated { chain_id: T::NetworkId, network_curve: NetworkCurve },
NetworkGatekeeperUpdated { chain_id: T::NetworkId }, NetworkGatekeeperUpdated { chain_id: T::NetworkId },
NetworkIncomingShareUpdated { chain_id: T::NetworkId, incoming_share: u32 }, NetworkIncomingFeeUpdated { chain_id: T::NetworkId, incoming_fee: u32 },
NetworkOutgoingShareUpdated { chain_id: T::NetworkId, outgoing_share: u32 }, NetworkOutgoingFeeUpdated { chain_id: T::NetworkId, outgoing_fee: u32 },
NetworkAvgBlockSpeedUpdated { chain_id: T::NetworkId, avg_block_speed: u64 }, NetworkAvgBlockSpeedUpdated { chain_id: T::NetworkId, avg_block_speed: u64 },
NetworkRemoved { chain_id: T::NetworkId }, NetworkRemoved { chain_id: T::NetworkId },
} }
#[pallet::storage] #[pallet::storage]
#[pallet::getter(fn network_imbalance)] #[pallet::getter(fn bridged_imbalance)]
pub type NetworkImbalance<T: Config> = StorageValue< pub type BridgedImbalance<T: Config> =
_, StorageValue<_, BridgeAdjustment<BalanceOf<T>>, ValueQuery>;
NetworkImbalanceState<BalanceOf<T>>,
ValueQuery, #[pallet::storage]
>; #[pallet::getter(fn accumulated_commission)]
pub type AccumulatedCommission<T: Config> = StorageValue<_, BalanceOf<T>, ValueQuery>;
#[pallet::storage] #[pallet::storage]
#[pallet::getter(fn network_indexes)] #[pallet::getter(fn network_indexes)]
@ -219,8 +216,8 @@ pub mod module {
>; >;
#[pallet::storage] #[pallet::storage]
#[pallet::getter(fn gatekeeper_amounts)] #[pallet::getter(fn gatekeeper_amount)]
pub type GatekeeperAmounts<T: Config> = pub type GatekeeperAmount<T: Config> =
StorageMap<_, Twox64Concat, T::NetworkId, BalanceOf<T>, ValueQuery>; StorageMap<_, Twox64Concat, T::NetworkId, BalanceOf<T>, ValueQuery>;
#[pallet::genesis_config] #[pallet::genesis_config]
@ -242,7 +239,7 @@ pub mod module {
.for_each(|network| { .for_each(|network| {
Pallet::<T>::do_register_network(network.id, network.data.clone()) Pallet::<T>::do_register_network(network.id, network.data.clone())
.expect("Error registering network"); .expect("Error registering network");
GatekeeperAmounts::<T>::insert(network.id, network.amount); GatekeeperAmount::<T>::insert(network.id, network.amount);
}); });
} }
@ -369,25 +366,25 @@ pub mod module {
} }
#[pallet::call_index(9)] #[pallet::call_index(9)]
#[pallet::weight(T::WeightInfo::update_incoming_network_share())] #[pallet::weight(T::WeightInfo::update_incoming_network_fee())]
pub fn update_incoming_network_share( pub fn update_incoming_network_fee(
origin: OriginFor<T>, origin: OriginFor<T>,
chain_id: T::NetworkId, chain_id: T::NetworkId,
incoming_share: 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_share(chain_id, incoming_share) Self::do_update_incoming_network_fee(chain_id, incoming_fee)
} }
#[pallet::call_index(10)] #[pallet::call_index(10)]
#[pallet::weight(T::WeightInfo::update_outgoing_network_share())] #[pallet::weight(T::WeightInfo::update_outgoing_network_fee())]
pub fn update_outgoing_network_share( pub fn update_outgoing_network_fee(
origin: OriginFor<T>, origin: OriginFor<T>,
chain_id: T::NetworkId, chain_id: T::NetworkId,
outgoing_share: 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_share(chain_id, outgoing_share) Self::do_update_outgoing_network_fee(chain_id, outgoing_fee)
} }
#[pallet::call_index(11)] #[pallet::call_index(11)]
@ -691,38 +688,38 @@ impl<T: Config> Pallet<T> {
Ok(()) Ok(())
} }
pub fn do_update_incoming_network_share( pub fn do_update_incoming_network_fee(
chain_id: T::NetworkId, chain_id: T::NetworkId,
incoming_share: u32, incoming_fee: u32,
) -> 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 net = maybe_network.as_mut().unwrap(); let net = maybe_network.as_mut().unwrap();
net.incoming_share = incoming_share; net.incoming_fee = incoming_fee;
*maybe_network = Some(net.clone()); *maybe_network = Some(net.clone());
Ok(()) Ok(())
})?; })?;
Self::deposit_event(Event::<T>::NetworkIncomingShareUpdated { Self::deposit_event(Event::<T>::NetworkIncomingFeeUpdated {
chain_id, chain_id,
incoming_share, incoming_fee,
}); });
Ok(()) Ok(())
} }
pub fn do_update_outgoing_network_share( pub fn do_update_outgoing_network_fee(
chain_id: T::NetworkId, chain_id: T::NetworkId,
outgoing_share: u32, outgoing_fee: u32,
) -> 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 net = maybe_network.as_mut().unwrap(); let net = maybe_network.as_mut().unwrap();
net.outgoing_share = outgoing_share; net.outgoing_fee = outgoing_fee;
*maybe_network = Some(net.clone()); *maybe_network = Some(net.clone());
Ok(()) Ok(())
})?; })?;
Self::deposit_event(Event::<T>::NetworkOutgoingShareUpdated { Self::deposit_event(Event::<T>::NetworkOutgoingFeeUpdated {
chain_id, chain_id,
outgoing_share, outgoing_fee,
}); });
Ok(()) Ok(())
} }
@ -796,61 +793,79 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
Self::do_remove_network(chain_id) Self::do_remove_network(chain_id)
} }
fn register_incoming( fn increase_gatekeeper_amount(
network_id: &T::NetworkId, network_id: &T::NetworkId,
amount: BalanceOf<T>, amount: &BalanceOf<T>,
) -> Result<BalanceOf<T>, ()> { ) -> Result<BalanceOf<T>, ()> {
let incoming_share = Networks::<T>::get(&network_id) let new_gatekeeper_amount =
.map(|network| network.incoming_share) GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| match gatekeeper_amount
.ok_or(())?; .checked_add(amount)
{
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
}
None => Err(()),
})?;
GatekeeperAmounts::<T>::try_mutate(network_id, |gatekeeper_amount| -> Result<(), ()> { Ok(new_gatekeeper_amount)
*gatekeeper_amount = gatekeeper_amount.checked_add(&amount).ok_or(())?;
Ok(())
})?;
let curve_share = Perbill::from_parts(incoming_share).mul_ceil(amount);
let final_amount = amount.saturating_sub(curve_share);
NetworkImbalance::<T>::try_mutate(|imbalance_state| -> Result<(), ()> {
imbalance_state.incoming = imbalance_state.incoming
.checked_add(&final_amount)
.ok_or(())?;
imbalance_state.curve_share = imbalance_state.curve_share
.checked_add(&curve_share)
.ok_or(())?;
Ok(())
})?;
Ok(final_amount)
} }
fn register_outgoing( fn decrease_gatekeeper_amount(
network_id: &T::NetworkId, network_id: &T::NetworkId,
amount: BalanceOf<T> amount: &BalanceOf<T>,
) -> Result<BalanceOf<T>, ()> { ) -> Result<BalanceOf<T>, ()> {
let outgoing_share = Networks::<T>::get(&network_id) let new_gatekeeper_amount =
.map(|network| network.outgoing_share) GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| match gatekeeper_amount
.ok_or(())?; .checked_sub(amount)
{
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
}
None => Err(()),
})?;
GatekeeperAmounts::<T>::try_mutate(network_id, |gatekeeper_amount| -> Result<(), ()> { Ok(new_gatekeeper_amount)
*gatekeeper_amount = gatekeeper_amount.checked_sub(&amount).ok_or(())?; }
Ok(())
fn accumulate_outgoing_imbalance(amount: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
let new_bridged_out_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
match bridged_imbalance.bridged_out.checked_add(amount) {
Some(value) => {
(*bridged_imbalance).bridged_out = value;
Ok(value)
}
None => Err(()),
}
})?; })?;
let curve_share = Perbill::from_parts(outgoing_share).mul_ceil(amount); Ok(new_bridged_out_amount)
let final_amount = amount.saturating_sub(curve_share); }
NetworkImbalance::<T>::try_mutate(|imbalance_state| -> Result<(), ()> { fn accumulate_incoming_imbalance(amount: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
imbalance_state.outgoing = imbalance_state.outgoing let new_bridged_in_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
.checked_add(&final_amount) match bridged_imbalance.bridged_in.checked_add(amount) {
.ok_or(())?; Some(value) => {
imbalance_state.curve_share = imbalance_state.curve_share (*bridged_imbalance).bridged_in = value;
.checked_add(&curve_share) Ok(value)
.ok_or(())?; }
Ok(()) None => Err(()),
}
})?; })?;
Ok(final_amount) Ok(new_bridged_in_amount)
}
fn accumulate_commission(commission: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
AccumulatedCommission::<T>::mutate(|accumulated| {
match accumulated.checked_add(commission) {
Some(value) => {
*accumulated = value;
Ok(value)
}
None => Err(()),
}
})
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -58,8 +58,8 @@ pub trait WeightInfo {
fn update_network_curve() -> Weight; fn update_network_curve() -> Weight;
fn update_network_gatekeeper() -> Weight; fn update_network_gatekeeper() -> Weight;
fn update_network_topic_name() -> Weight; fn update_network_topic_name() -> Weight;
fn update_incoming_network_share() -> Weight; fn update_incoming_network_fee() -> Weight;
fn update_outgoing_network_share() -> Weight; fn update_outgoing_network_fee() -> Weight;
fn update_avg_block_speed() -> Weight; fn update_avg_block_speed() -> Weight;
fn remove_network() -> Weight; fn remove_network() -> Weight;
} }
@ -191,7 +191,7 @@ impl WeightInfo for () {
} }
/// Storage: `GhostNetworks::Networks` (r:1 w:1) /// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_incoming_network_share() -> Weight { fn update_incoming_network_fee() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `339` // Measured: `339`
// Estimated: `3804` // Estimated: `3804`
@ -203,7 +203,7 @@ impl WeightInfo for () {
} }
/// Storage: `GhostNetworks::Networks` (r:1 w:1) /// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_outgoing_network_share() -> Weight { fn update_outgoing_network_fee() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `339` // Measured: `339`
// Estimated: `3804` // Estimated: `3804`

View File

@ -16,6 +16,7 @@
// limitations under the License. // limitations under the License.
use super::*; use super::*;
use crate::log;
use frame_support::traits::{OnRuntimeUpgrade, UncheckedOnRuntimeUpgrade}; use frame_support::traits::{OnRuntimeUpgrade, UncheckedOnRuntimeUpgrade};
use sp_std::{collections::btree_map::BTreeMap, vec::Vec}; use sp_std::{collections::btree_map::BTreeMap, vec::Vec};

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-traits" name = "ghost-traits"
version = "0.4.3" version = "0.4.2"
description = "Shared traits including `GhostHasher`, `NetworkDataBasicHandler`, `BoundedBTreeMap`, `MerkleTree` and more." description = "Shared traits including `GhostHasher`, `NetworkDataBasicHandler`, `BoundedBTreeMap`, `MerkleTree` and more."
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -47,8 +47,18 @@ 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 register_incoming(chain_id: &Self::NetworkId, amount: Balance) -> Result<Balance, ()>; fn increase_gatekeeper_amount(
fn register_outgoing(chain_id: &Self::NetworkId, amount: Balance) -> Result<Balance, ()>; chain_id: &Self::NetworkId,
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_incoming_imbalance(amount: &Balance) -> Result<Balance, ()>;
fn accumulate_commission(commission: &Balance) -> Result<Balance, ()>;
} }
pub trait NetworkRpcResolver<W, B, H, I, S> { pub trait NetworkRpcResolver<W, B, H, I, S> {

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-weaver" name = "ghost-weaver"
version = "0.0.2" version = "0.0.0"
description = "Weaving a secure cryptographic tapestry across different external chains." description = "Weaving a secure cryptographic tapestry across different external chains."
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -19,8 +19,8 @@ use sp_runtime::{
storage::StorageValueRef, storage::StorageValueRef,
storage_lock::{StorageLock, Time}, storage_lock::{StorageLock, Time},
}, },
traits::{BlockNumberProvider, UniqueSaturatedInto}, traits::{BlockNumberProvider, Saturating, UniqueSaturatedInto},
RuntimeAppPublic, Perbill, RuntimeAppPublic,
}; };
use ghost_helpers::{ use ghost_helpers::{
@ -47,7 +47,7 @@ mod tests;
#[cfg(feature = "runtime-benchmarks")] #[cfg(feature = "runtime-benchmarks")]
mod benchmarking; mod benchmarking;
#[cfg(any(test))] #[cfg(any(test, feature = "runtime-benchmarks"))]
mod mock; mod mock;
use crate::errors::*; use crate::errors::*;
@ -179,7 +179,9 @@ pub mod pallet {
ThreadAlreadyPulled, ThreadAlreadyPulled,
InvalidMerkleProof, InvalidMerkleProof,
InvalidReceiverAddress, InvalidReceiverAddress,
CouldNotRegisterIncoming, CouldNotAccumulateIncomingImbalance,
CouldNotIncreaseGatekeeperAmount,
CouldNotAccumulateCommission,
} }
#[pallet::storage] #[pallet::storage]
@ -444,14 +446,24 @@ pub mod pallet {
.verify_proof(root_hash, &network_data.gatekeeper) .verify_proof(root_hash, &network_data.gatekeeper)
.ok_or(Error::<T>::InvalidMerkleProof)?; .ok_or(Error::<T>::InvalidMerkleProof)?;
let amount = thread_proof.amount().clone();
let receiver_bytes: &[u8; 32] = receiver_account.as_ref(); let receiver_bytes: &[u8; 32] = receiver_account.as_ref();
let receiver = T::AccountId::decode(&mut &receiver_bytes[..]) let receiver = T::AccountId::decode(&mut &receiver_bytes[..])
.map_err(|_| Error::<T>::InvalidReceiverAddress)?; .map_err(|_| Error::<T>::InvalidReceiverAddress)?;
let amount = thread_proof.amount(); let commission = Perbill::from_parts(network_data.incoming_fee).mul_ceil(amount);
let pure_amount = let pure_amount = amount.saturating_sub(commission);
T::NetworkDataHandler::register_incoming(&network_id, amount)
.map_err(|_| Error::<T>::CouldNotRegisterIncoming)?; let _ = T::NetworkDataHandler::accumulate_incoming_imbalance(&pure_amount)
.map_err(|_| Error::<T>::CouldNotAccumulateIncomingImbalance)
.and_then(|_| {
T::NetworkDataHandler::increase_gatekeeper_amount(&network_id, &amount)
.map_err(|_| Error::<T>::CouldNotIncreaseGatekeeperAmount)
})
.and_then(|_| {
T::NetworkDataHandler::accumulate_commission(&commission)
.map_err(|_| Error::<T>::CouldNotAccumulateCommission)
})?;
let _ = T::Currency::deposit_creating(&receiver, pure_amount); let _ = T::Currency::deposit_creating(&receiver, pure_amount);
PulledThreads::<T>::insert(pulled_thread_key, ()); PulledThreads::<T>::insert(pulled_thread_key, ());

View File

@ -220,6 +220,16 @@ impl<Block, NetworkId, AuthIndex> AttestationMetadata<Block, NetworkId, AuthInde
} }
} }
#[derive(Default, Clone, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub struct NetworkAttestation<Block, BoundedMap>
where
Block: AtLeast32BitUnsigned + Encode + Decode + TypeInfo + MaxEncodedLen + Default,
BoundedMap: Encode + Decode + TypeInfo + MaxEncodedLen + Default + Clone,
{
pub until: Block,
pub map: BoundedMap,
}
#[derive(Default, Copy, Clone, Encode, Decode, TypeInfo, MaxEncodedLen)] #[derive(Default, Copy, Clone, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub struct TapestryDraft<Block: AtLeast32BitUnsigned> { pub struct TapestryDraft<Block: AtLeast32BitUnsigned> {
pub until: Block, pub until: Block,
@ -267,6 +277,12 @@ where
} }
} }
#[derive(Default, Copy, Clone, Encode, Decode, TypeInfo, MaxEncodedLen)]
pub struct LoomState {
pub hash: H256,
pub pulled_threads: ThreadId,
}
#[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] #[derive(Clone, Encode, Decode, Eq, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)]
pub struct ThreadPayload<Balance: UniqueSaturatedInto<u128>> { pub struct ThreadPayload<Balance: UniqueSaturatedInto<u128>> {
proof_index: ThreadId, proof_index: ThreadId,

View File

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

View File

@ -1,6 +1,6 @@
[package] [package]
name = "casper-runtime-constants" name = "casper-runtime-constants"
version = "0.4.2" version = "0.4.0"
authors.workspace = true authors.workspace = true
edition.workspace = true edition.workspace = true
homepage.workspace = true homepage.workspace = true

View File

@ -15,10 +15,10 @@ pub mod currency {
pub const CSPR: Balance = 1_000 * STRH; // 10^18 pub const CSPR: Balance = 1_000 * STRH; // 10^18
/// The existential deposit. /// The existential deposit.
pub const EXISTENTIAL_DEPOSIT: Balance = 500 * STNK; pub const EXISTENTIAL_DEPOSIT: Balance = STNK;
pub const fn deposit(items: u32, bytes: u32) -> Balance { pub const fn deposit(items: u32, bytes: u32) -> Balance {
(items as Balance) * 2 * STRH + (bytes as Balance) * 200 * STNK (items as Balance) * 20 * STRH + (bytes as Balance) * 200 * STNK
} }
} }
@ -39,7 +39,7 @@ pub mod time {
// 1 in 4 blocks (on average, not counting collisions) woll be primary babe // 1 in 4 blocks (on average, not counting collisions) woll be primary babe
// blocks.The choice of is done on accordance to the slot duration and expected // blocks.The choice of is done on accordance to the slot duration and expected
// target block time, for safely resisting network delays of maximum two // target block tim, for safely resisting network delays of maximum two
// seconds. // seconds.
pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4); pub const PRIMARY_PROBABILITY: (u64, u64) = (1, 4);
} }
@ -69,7 +69,7 @@ pub mod fee {
type Balance = Balance; type Balance = Balance;
fn polynomial() -> WeightToFeeCoefficients<Self::Balance> { fn polynomial() -> WeightToFeeCoefficients<Self::Balance> {
let fee_per_nanosecond: Balance = (424 * super::currency::FTSO) / 1_200_000; let fee_per_nanosecond: Balance = 10 * super::currency::FTSO;
smallvec![WeightToFeeCoefficient { smallvec![WeightToFeeCoefficient {
degree: 1, degree: 1,
@ -84,7 +84,7 @@ pub mod fee {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{ use super::{
currency::{CSPR, STNK}, currency::{CSPR, STNK, STRH},
fee::WeightToFee, fee::WeightToFee,
}; };
use crate::weights::ExtrinsicBaseWeight; use crate::weights::ExtrinsicBaseWeight;
@ -94,22 +94,18 @@ mod tests {
#[test] #[test]
fn full_block_fee_is_correct() { fn full_block_fee_is_correct() {
let full_block = WeightToFee::weight_to_fee(&MAXIMUM_BLOCK_WEIGHT); let full_block = WeightToFee::weight_to_fee(&MAXIMUM_BLOCK_WEIGHT);
assert!(full_block >= 50 * CSPR);
let lower_bound = 1 * CSPR; assert!(full_block <= 70 * CSPR);
let upper_bound = 2 * CSPR;
assert!(full_block >= lower_bound);
assert!(full_block <= upper_bound);
} }
#[test] #[test]
fn extrinsic_base_fee_is_correct() { fn extrinsic_base_fee_is_correct() {
let ext_weight = WeightToFee::weight_to_fee(&ExtrinsicBaseWeight::get()); let x = WeightToFee::weight_to_fee(&ExtrinsicBaseWeight::get());
let lower_bound = 100 * STNK; let lower_bound = STRH / 2;
let upper_bound = 300 * STNK; let upper_bound = (3 * STRH) / 2;
assert!(ext_weight >= lower_bound); assert!(x >= lower_bound);
assert!(ext_weight <= upper_bound); assert!(x <= upper_bound);
} }
} }

View File

@ -7,15 +7,15 @@
// Ghost Network is distributed in the hope that it will be useful, // Ghost Network is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with Ghost Network. If not, see <http://www.gnu.org/licenses/>. // along with Ghost Network. If not, see <http://www.gnu.org/licenses/>.
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0 //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2026-08-31 (Y/M/D) //! DATE: 2024-07-30 (Y/M/D)
//! HOSTNAME: `LAPTOP-IOUQRLAP`, CPU: `AMD Ryzen 7 2700U with Radeon Vega Mobile Gfx` //! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! //!
//! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Development` //! SHORT-NAME: `block`, LONG-NAME: `BlockExecution`, RUNTIME: `Development`
//! WARMUPS: `10`, REPEAT: `100` //! WARMUPS: `10`, REPEAT: `100`
@ -37,43 +37,43 @@ use sp_core::parameter_types;
use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight}; use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight};
parameter_types! { parameter_types! {
/// Time to execute an empty block. /// Time to execute an empty block.
/// Calculated by multiplying the *Average* with `1.0` and adding `0`. /// Calculated by multiplying the *Average* with `1.0` and adding `0`.
/// ///
/// Stats nanoseconds: /// Stats nanoseconds:
/// Min, Max: 553_400, 1_996_400 /// Min, Max: 64_363_191, 66_078_314
/// Average: 771_526 /// Average: 64_551_214
/// Median: 680_500 /// Median: 64_500_078
/// Std-Dev: 248209.17 /// Std-Dev: 229678.99
/// ///
/// Percentiles nanoseconds: /// Percentiles nanoseconds:
/// 99th: 1_652_700 /// 99th: 65_668_012
/// 95th: 1_212_900 /// 95th: 64_888_421
/// 75th: 849_300 /// 75th: 64_563_448
pub const BlockExecutionWeight: Weight = pub const BlockExecutionWeight: Weight =
Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(771_526), 0); Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(64_551_214), 0);
} }
#[cfg(test)] #[cfg(test)]
mod test_weights { mod test_weights {
use sp_weights::constants; use sp_weights::constants;
/// Checks that the weight exists and is sane. /// Checks that the weight exists and is sane.
// NOTE: If this test fails but you are sure that the generated values are fine, // NOTE: If this test fails but you are sure that the generated values are fine,
// you can delete it. // you can delete it.
#[test] #[test]
fn sane() { fn sane() {
let w = super::BlockExecutionWeight::get(); let w = super::BlockExecutionWeight::get();
// At least 100 µs. // At least 100 µs.
assert!( assert!(
w.ref_time() >= 100u64 * constants::WEIGHT_REF_TIME_PER_MICROS, w.ref_time() >= 100u64 * constants::WEIGHT_REF_TIME_PER_MICROS,
"Weight should be at least 100 µs." "Weight should be at least 100 µs."
); );
// At most 50 ms. // At most 50 ms.
assert!( assert!(
w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS, w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS,
"Weight should be at most 50 ms." "Weight should be at most 50 ms."
); );
} }
} }

View File

@ -221,8 +221,8 @@ fn casper_testnet_networks() -> Vec<NetworkInitiation<NetworkId, Balance>> {
.with_finality_delay(69) .with_finality_delay(69)
.with_rate_limit_delay(5_000) .with_rate_limit_delay(5_000)
.with_block_deviation(420) .with_block_deviation(420)
.with_incoming_share(69_000_000u32) .with_incoming_fee(69_000_000u32)
.with_outgoing_share(69_000_000u32) .with_outgoing_fee(69_000_000u32)
.build() .build()
) )
.build() .build()
@ -235,9 +235,8 @@ pub fn testnet_config_genesis(
initial_networks: Vec<NetworkInitiation<NetworkId, Balance>>, initial_networks: Vec<NetworkInitiation<NetworkId, Balance>>,
initial_claims: Vec<NetworkClaim<NetworkId, Balance>>, initial_claims: Vec<NetworkClaim<NetworkId, Balance>>,
) -> serde_json::Value { ) -> serde_json::Value {
const ENDOWMENT: u128 = 31 * CSPR; const ENDOWMENT: u128 = 31 * CSPR;
const STASH_BOND: u128 = 68 * CSPR; const STASH: u128 = 69 * CSPR;
const STASH_FEES: u128 = 1 * CSPR;
let sudo = initial_authorities.first().map(|x| x.account.clone()).unwrap(); let sudo = initial_authorities.first().map(|x| x.account.clone()).unwrap();
@ -247,7 +246,7 @@ pub fn testnet_config_genesis(
.iter() .iter()
.map(|x| (x.account.clone(), x.balance)) .map(|x| (x.account.clone(), x.balance))
.chain(initial_authorities.iter().map(|x| (x.account.clone(), ENDOWMENT))) .chain(initial_authorities.iter().map(|x| (x.account.clone(), ENDOWMENT)))
.chain(initial_authorities.iter().map(|x| (x.stash.clone(), STASH_BOND + STASH_FEES))) .chain(initial_authorities.iter().map(|x| (x.stash.clone(), STASH)))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
}, },
"session": { "session": {
@ -259,39 +258,25 @@ pub fn testnet_config_genesis(
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
}, },
"staking": { "staking": {
// "minNominatorBond": 42 * CSPR, "validatorCount": initial_authorities.len() as u32,
// "minValidatorBond": 6900 * STRH, "minimumValidatorCount": 4,
// "maxNominatorsCount": 3000u32, "invulnerables": initial_authorities
// "maxValidatorsCount": 500u32, .iter()
.map(|x| x.stash.clone())
"minimumValidatorCount": if cfg!(feature = "runtime-benchmarks") { .collect::<Vec<_>>(),
1u32
} else {
4u32
},
// "validatorCount": 50u32,
"forceEra": Forcing::NotForcing, "forceEra": Forcing::NotForcing,
// "slashRewardFraction": Perbill::from_percent(10), "slashRewardFraction": Perbill::from_percent(10),
"stakers": initial_authorities "stakers": initial_authorities
.iter() .iter()
.map(|x| ( .map(|x| (
x.stash.clone(), x.stash.clone(),
x.stash.clone(), x.stash.clone(),
STASH_BOND, STASH,
StakerStatus::<AccountId>::Validator, StakerStatus::<AccountId>::Validator,
)) ))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
}, },
"babe": { "epochConfig": Some(crate::BABE_GENESIS_EPOCH_CONFIG) }, "babe": { "epochConfig": Some(crate::BABE_GENESIS_EPOCH_CONFIG) },
// "ghostNominationPools": {
// "minJoinBond": 10 * STNK,
// "minCreateBond": 20 * CSPR,
// "maxPools": 256u32,
// "maxMembersPerPool": 1024u32,
// "maxMembers": 20000u32,
// "globalMaxCommission": Perbill::from_percent(15),
// },
"ghostSudo": { "key": sudo }, "ghostSudo": { "key": sudo },
"ghostNetworks": { "networks": initial_networks }, "ghostNetworks": { "networks": initial_networks },
"ghostGovernance": { "networkClaims": initial_claims }, "ghostGovernance": { "networkClaims": initial_claims },

View File

@ -14,15 +14,11 @@ use frame_support::{
genesis_builder_helper::{build_state, get_preset}, genesis_builder_helper::{build_state, get_preset},
traits::{ traits::{
fungible::HoldConsideration, fungible::HoldConsideration,
tokens::{imbalance::ResolveTo, UnityAssetBalanceConversion}, tokens::{imbalance::ResolveTo, PayFromAccount, UnityAssetBalanceConversion},
ConstU128, ConstU32, InstanceFilter, KeyOwnerProofSystem, ConstU128, ConstU32, InstanceFilter, KeyOwnerProofSystem,
LinearStoragePrice, LinearStoragePrice,
}, },
}; };
#[cfg(not(feature = "runtime-benchmarks"))]
use frame_support::traits::tokens::PayFromAccount;
use frame_system::EnsureRoot; use frame_system::EnsureRoot;
use runtime_common::{ use runtime_common::{
impl_runtime_weights, impls::DealWithFees, prod_or_fast, BlockHashCount, BlockLength, impl_runtime_weights, impls::DealWithFees, prod_or_fast, BlockHashCount, BlockLength,
@ -242,8 +238,8 @@ impl pallet_babe::Config for Runtime {
type DisabledValidators = Session; type DisabledValidators = Session;
type WeightInfo = weights::pallet_babe::WeightInfo<Runtime>; type WeightInfo = weights::pallet_babe::WeightInfo<Runtime>;
type MaxAuthorities = MaxActiveValidators; type MaxAuthorities = MaxAuthorities;
type MaxNominators = MaxElectingVoters; type MaxNominators = MaxNominators;
type KeyOwnerProof = type KeyOwnerProof =
<Historical as KeyOwnerProofSystem<(KeyTypeId, pallet_babe::AuthorityId)>>::Proof; <Historical as KeyOwnerProofSystem<(KeyTypeId, pallet_babe::AuthorityId)>>::Proof;
@ -343,9 +339,9 @@ parameter_types! {
// 4 hour session, 1 hour unsigned phase, 32 ofchain executions. // 4 hour session, 1 hour unsigned phase, 32 ofchain executions.
pub OffchainRepeat: BlockNumber = UnsignedPhase::get() / 32; pub OffchainRepeat: BlockNumber = UnsignedPhase::get() / 32;
pub const MaxElectingVoters: u32 = 3_000; pub const MaxElectingVoters: u32 = 5_000;
pub const MaxElectableTargets: u32 = 400; pub const MaxElectableTargets: u32 = 1500;
pub const MaxActiveValidators: u32 = 300; pub const MaxActiveValidators: u32 = 1_000;
// ... and all of the validators as electable targets. Whilist this is the // ... and all of the validators as electable targets. Whilist this is the
// case, we cannot and shall increase the size of the validator intentions. // case, we cannot and shall increase the size of the validator intentions.
@ -553,6 +549,8 @@ parameter_types! {
pub const DataDepositPerByte: Balance = 1 * STRH; pub const DataDepositPerByte: Balance = 1 * STRH;
pub const MaxApprovals: u32 = 10; pub const MaxApprovals: u32 = 10;
pub const MaxAuthorities: u32 = 1_500;
pub const MaxNominators: u32 = 10_000;
} }
#[cfg(not(feature = "runtime-benchmarks"))] #[cfg(not(feature = "runtime-benchmarks"))]
@ -579,8 +577,8 @@ impl EnsureOrigin<RuntimeOrigin> for RootSpendOrigin {
} }
#[cfg(feature = "runtime-benchmarks")] #[cfg(feature = "runtime-benchmarks")]
fn try_successful_origin() -> Result<RuntimeOrigin, ()> { fn successful_origin() -> RuntimeOrigin {
EnsureRoot::<AccountId>::try_successful_origin() EnsureRoot::<AccountId>::successful_origin()
} }
} }
@ -646,7 +644,7 @@ impl pallet_offences::Config for Runtime {
} }
impl pallet_authority_discovery::Config for Runtime { impl pallet_authority_discovery::Config for Runtime {
type MaxAuthorities = MaxActiveValidators; type MaxAuthorities = MaxAuthorities;
} }
parameter_types! { parameter_types! {
@ -663,8 +661,8 @@ impl pallet_grandpa::Config for Runtime {
type RuntimeEvent = RuntimeEvent; type RuntimeEvent = RuntimeEvent;
type WeightInfo = weights::pallet_grandpa::WeightInfo<Runtime>; type WeightInfo = weights::pallet_grandpa::WeightInfo<Runtime>;
type MaxAuthorities = MaxActiveValidators; type MaxAuthorities = MaxAuthorities;
type MaxNominators = MaxElectingVoters; type MaxNominators = MaxNominators;
type MaxSetIdSessionEntries = MaxSetIdSessionEntries; type MaxSetIdSessionEntries = MaxSetIdSessionEntries;
type KeyOwnerProof = <Historical as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof; type KeyOwnerProof = <Historical as KeyOwnerProofSystem<(KeyTypeId, GrandpaId)>>::Proof;
@ -1056,6 +1054,7 @@ mod benches {
// that path resolves correctly in the generated file. // that path resolves correctly in the generated file.
// Substrate // Substrate
[pallet_alliance, Alliance]
[pallet_babe, Babe] [pallet_babe, Babe]
[pallet_bags_list, VoterList] [pallet_bags_list, VoterList]
[pallet_balances, Balances] [pallet_balances, Balances]
@ -1078,7 +1077,7 @@ mod benches {
// Ghosts // Ghosts
[ghost_nomination_pools, NominationPoolsBench::<Runtime>] [ghost_nomination_pools, NominationPoolsBench::<Runtime>]
[ghost_networks, GhostNetworks] [ghost_networks, GhostNetworks]
[ghost_governance, GhostGovernance] [ghost_claims, GhostClaims]
[ghost_weaver, GhostWeaver] [ghost_weaver, GhostWeaver]
[ghost_exodus, GhostExodus] [ghost_exodus, GhostExodus]
[ghost_sudo, GhostSudo] [ghost_sudo, GhostSudo]
@ -1538,11 +1537,11 @@ mod test_fees {
fn nominator_limit() { fn nominator_limit() {
use pallet_election_provider_multi_phase::WeightInfo; use pallet_election_provider_multi_phase::WeightInfo;
// starting point of the nominators. // starting point of the nominators.
let target_voters: u32 = 3_000; let target_voters: u32 = 50_000;
// assuming we want around 3k candidates and 300 active validators. // assuming we want around 5k candidates and 1k active validators. (March 31, 2021)
let all_targets: u32 = 400; let all_targets: u32 = 5_000;
let desired: u32 = 300; let desired: u32 = 1_000;
let weight_with = |active| { let weight_with = |active| {
<Runtime as pallet_election_provider_multi_phase::Config>::WeightInfo::submit_unsigned( <Runtime as pallet_election_provider_multi_phase::Config>::WeightInfo::submit_unsigned(
active, active,

View File

@ -1,6 +1,6 @@
[package] [package]
name = "runtime-common" name = "runtime-common"
version = "0.4.7" version = "0.4.5"
authors.workspace = true authors.workspace = true
edition.workspace = true edition.workspace = true
homepage.workspace = true homepage.workspace = true

View File

@ -8,7 +8,7 @@ impl ArgumentsFactory<(), AccountId> for BenchmarkTreasuryHelper {
fn create_asset_kind(_seed: u32) -> () { fn create_asset_kind(_seed: u32) -> () {
() ()
} }
fn create_beneficiary(seed: [u8; 32]) -> AccountId { fn create_beneficiary(mut seed: [u8; 32]) -> AccountId {
AccountId::from_entropy(&mut seed.as_slice()).unwrap() AccountId::from_entropy(&mut seed.as_slice()).unwrap()
} }
} }

View File

@ -30,19 +30,19 @@ pub use sp_runtime::BuildStorage;
pub use impls::ToAuthor; pub use impls::ToAuthor;
/// We assume that an on-initialize consumes 10% of the weight on average, hence /// We assume that an on-initialize consumes 30% of the weight on average, hence
/// a single extrinsic will not be allowed to consume more than /// a single extrinsic will not be allowed to consume more than
/// `AvailableBlockRatio - 10%`. /// `AvailableBlockRatio - 30%`.
pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(10); pub const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(30);
/// We allow `Normal` extrinsics to fill up the block up to 75%, the rest can /// We allow `Normal` extrinsics to fill up the block up to 60%, the rest can
/// be used by `Operational` extrinsics. /// be used by `Operational` extrinsics.
pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(75); pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(60);
/// We allow for 4 seconds of compute with a 12 seconds average block time. /// We allow for 6 seconds of compute with a 12 seconds average block time.
/// The storage proof size is not limited so far. /// The storage proof size is not limited so far.
pub const MAXIMUM_BLOCK_WEIGHT: Weight = pub const MAXIMUM_BLOCK_WEIGHT: Weight =
Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(4), u64::MAX); Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(6), u64::MAX);
const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct()); const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct());
@ -112,19 +112,19 @@ macro_rules! impl_runtime_weights {
.for_class(DispatchClass::all(), |weights| { .for_class(DispatchClass::all(), |weights| {
weights.base_extrinsic = $runtime::weights::ExtrinsicBaseWeight::get(); weights.base_extrinsic = $runtime::weights::ExtrinsicBaseWeight::get();
}) })
.for_class(DispatchClass::Normal, |weights| { .for_class(DispatchClass::Normal, |weights| {
weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT); weights.max_total = Some(NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT);
}) })
.for_class(DispatchClass::Operational, |weights| { .for_class(DispatchClass::Operational, |weights| {
weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT); weights.max_total = Some(MAXIMUM_BLOCK_WEIGHT);
// Operational transactions have an extra reserved space, so that they // Operational transactions have an extra reserved space, so that they
// are included even if block reached `MAXIMUM_BLOCK_WEIGHT`. // are included even if block reached `MAXIMUM_BLOCK_WEIGHT`.
weights.reserved = Some( weights.reserved = Some(
MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT, MAXIMUM_BLOCK_WEIGHT - NORMAL_DISPATCH_RATIO * MAXIMUM_BLOCK_WEIGHT,
); );
}) })
.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO) .avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
.build_or_panic(); .build_or_panic();
} }
}; };
} }
@ -138,8 +138,8 @@ static_assertions::assert_eq_size!(primitives::Balance, u128);
/// A reasonable benchmarking config for staking pallet. /// A reasonable benchmarking config for staking pallet.
pub struct StakingBenchmarkingConfig; pub struct StakingBenchmarkingConfig;
impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig { impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig {
type MaxValidators = ConstU32<299>; // MaxActiveValidators: u32 = 300 type MaxValidators = ConstU32<500>;
type MaxNominators = ConstU32<3_000>; type MaxNominators = ConstU32<10_000>;
} }
/// Convert a balance to an unsigned 256-bit number, use in nomination pools. /// Convert a balance to an unsigned 256-bit number, use in nomination pools.
@ -173,7 +173,7 @@ macro_rules! prod_or_fast {
} }
}; };
($prod:expr, $test:expr, $env:expr) => { ($prod:expr, $test:expr, $env:expr) => {
if cfg!(feature = "fast-runtime") { if cfg!(feature == "fast-runtime") {
core::option_env!($env) core::option_env!($env)
.map(|s| s.parse().ok()) .map(|s| s.parse().ok())
.flatten() .flatten()

View File

@ -0,0 +1,27 @@
use sp_core::parameter_types;
use sp_weights::{constants::WEIGHT_PER_TIME_PER_NANOS, Weight};
parameter_types! {
pub const BlockExecutionWeight: Weight =
Weight::from_ref_time(WEIGHT_PER_TIME_PER_NANOS.saturating_mul(7_955_558));
}
#[cfg(test)]
mod test_weights {
use sp_weights::constants;
#[test]
fn sane() {
let w = super::BlockExecutionWeight::get();
assert!(
w.ref_time() >= 100u64 * constants::WEIGHT_PER_TIME_PER_MICROS,
"Weight should be at least 100 µs."
);
assert!(
w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS,
"Weight should be at most 50 ms."
);
}
}

View File

@ -0,0 +1,28 @@
use sp_core::parameter_types;
use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight};
parameter_types! {
pub const ExtrinsicBaseWeight: Weight =
Weight::from_ref_time(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(94_914));
}
#[cfg(test)]
mod test_weights {
use frame_support::traits::Get;
use sp_weights::constants;
#[test]
fn sane() {
let w = super::ExtrinsicBaseWeight::get();
assert!(
w.ref_time() >= 10u64 * constants::WEIGHT_REF_TIME_PER_MICROS,
"Weight should be at least 10 µs."
);
assert!(
w.ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
"Weight should be at most 1 ms."
);
}
}

View File

@ -0,0 +1,5 @@
pub mod block_weights;
pub mod extrinsic_weight;
pub use block_weights::BlockExecutionWeight;
pub use extrinsic_weights::ExtrinsicBaseWeight;

View File

@ -40,23 +40,23 @@ while getopts 'bfp:v' flag; do
esac esac
done done
if [ "$skip_build" != true ]
then
echo "[+] Compiling Node with 'runtime-benchmarks' features"
cargo build --release --locked --features=runtime-benchmarks
fi
ERR_FILE="benchmarking_errors.txt" ERR_FILE="benchmarking_errors.txt"
EXECUTABLE=./target/release/ghost EXECUTABLE=./target/release/ghost
RUNTIME="casper" RUNTIME="casper"
rm -f $ERR_FILE rm -f $ERR_FILE
if [ "$skip_build" != true ]
then
echo "[+] Compiling Node with 'runtime-benchmarks' features"
cargo build --release --locked --features=runtime-benchmarks,$RUNTIME-native
fi
# Update the block and extrinsic overhead weights # Update the block and extrinsic overhead weights
echo "[+] Benchmarking block and extrinsic overheads..." echo "[+] Benchmarking block and extrinsic overheads..."
OUTPUT=$( OUTPUT=$(
$EXECUTABLE benchmark overhead \ $EXECUTABLE benchmark overhead \
--chain="${RUNTIME}-local" \ --chain="${RUNTIME}-dev" \
--wasm-execution=compiled \ --wasm-execution=compiled \
--weight-path="./runtime/${RUNTIME}/constants/src/weights/" \ --weight-path="./runtime/${RUNTIME}/constants/src/weights/" \
--header=./file_header.txt \ --header=./file_header.txt \
@ -70,7 +70,7 @@ fi
echo "[+] Benchmarking the machine..." echo "[+] Benchmarking the machine..."
OUTPUT=$( OUTPUT=$(
$EXECUTABLE benchmark machine --allow-fail --chain=${RUNTIME}-dev 2>&1 $EXECUTABLE benchmark machine --chain=${RUNTIME}-dev 2>&1
) )
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
# Do not write the error file since it is not a benchmarking error # Do not write the error file since it is not a benchmarking error
@ -108,18 +108,23 @@ fi
EXCLUDED_PALLETS=( EXCLUDED_PALLETS=(
# helper pallets # helper pallets
"frame_benchmarking" "pallet_election_provider_support_benchmarking"
# pallets without automatic benchmarking
"pallet_babe"
"pallet_grandpa"
"pallet_bags_list"
"frame_system"
"pallet_staking"
"pallet_offences"
) )
# Load all pallet names in an array # Load all pallet names in an array
ALL_PALLETS=($( ALL_PALLETS=($(
$EXECUTABLE benchmark pallet --list=pallets --no-csv-header --chain=${RUNTIME}-dev 2>/dev/null | grep -v ':' | grep -v 'baseline' $EXECUTABLE benchmark pallet --list=pallets --no-csv-header --chain=${RUNTIME}-dev
)) ))
# Filter out the excluded pallets by concatenating the arrays and discarding duplicates # Filter out the excluded pallets by concatenating the arrays and discarding duplicates
PALLETS=($( PALLETS=($({ printf '%s\n' "${ALL_PALLETS[@]}" "${EXCLUDED_PALLETS[@]}"; } | sort | uniq -u))
printf '%s\n' "${ALL_PALLETS[@]}" | grep -Fvxf <(printf '%s\n' "${EXCLUDED_PALLETS[@]}")
))
TOTAL_PALLETS=${#PALLETS[@]} TOTAL_PALLETS=${#PALLETS[@]}
CURRENT=0 CURRENT=0
@ -137,11 +142,6 @@ for PALLET in "${PALLETS[@]}"; do
unset start_pallet unset start_pallet
fi fi
if [[ -z "$PALLET" || "$PALLET" == "::" || "$PALLET" == "baseline" || "$PALLET" == "pallet" ]]; then
echo "[+] ($CURRENT/$TOTAL_PALLETS) Skipping garbage names: '${PALLET}'"
continue
fi
FOLDER="$(echo "${PALLET#*_}" | tr '_' '-')"; FOLDER="$(echo "${PALLET#*_}" | tr '_' '-')";
WEIGHT_FILE="./runtime/${RUNTIME}/src/weights/${PALLET}.rs" WEIGHT_FILE="./runtime/${RUNTIME}/src/weights/${PALLET}.rs"
echo "[+] Benchmarking $PALLET for $RUNTIME with weight file $WEIGHT_FILE ($CURRENT/$TOTAL_PALLETS)"; echo "[+] Benchmarking $PALLET for $RUNTIME with weight file $WEIGHT_FILE ($CURRENT/$TOTAL_PALLETS)";

View File

@ -106,7 +106,7 @@ tempfile = { workspace = true }
[features] [features]
default = ["db", "full-node"] default = ["db", "full-node"]
db = ["sc-service/rocksdb"] db = ["sc-service/rocksdb"]
full-node = ["kvdb-rocksdb", "parity-db", "casper-native"] full-node = ["kvdb-rocksdb", "parity-db"]
runtime-benchmarks = [ runtime-benchmarks = [
"frame-benchmarking-cli/runtime-benchmarks", "frame-benchmarking-cli/runtime-benchmarks",
"frame-benchmarking/runtime-benchmarks", "frame-benchmarking/runtime-benchmarks",