Compare commits

..

No commits in common. "main" and "pallet-claims" have entirely different histories.

115 changed files with 6492 additions and 9868 deletions

57
Cargo.lock generated
View File

@ -1,6 +1,6 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 4 version = 3
[[package]] [[package]]
name = "Inflector" name = "Inflector"
@ -1186,7 +1186,7 @@ dependencies = [
[[package]] [[package]]
name = "casper-runtime" name = "casper-runtime"
version = "3.5.31" version = "3.5.20"
dependencies = [ dependencies = [
"casper-runtime-constants", "casper-runtime-constants",
"frame-benchmarking", "frame-benchmarking",
@ -1203,7 +1203,6 @@ dependencies = [
"ghost-networks", "ghost-networks",
"ghost-runtime-common", "ghost-runtime-common",
"ghost-slow-clap", "ghost-slow-clap",
"ghost-sudo",
"log", "log",
"pallet-alliance", "pallet-alliance",
"pallet-authority-discovery", "pallet-authority-discovery",
@ -3505,7 +3504,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-claims" name = "ghost-claims"
version = "0.2.4" version = "0.2.2"
dependencies = [ dependencies = [
"frame-benchmarking", "frame-benchmarking",
"frame-support", "frame-support",
@ -3529,7 +3528,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-cli" name = "ghost-cli"
version = "0.8.2" version = "0.7.197"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"clap 4.5.4", "clap 4.5.4",
@ -3561,7 +3560,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-client-cli" name = "ghost-client-cli"
version = "0.1.4" version = "0.1.3"
dependencies = [ dependencies = [
"array-bytes", "array-bytes",
"clap 4.5.4", "clap 4.5.4",
@ -3585,7 +3584,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-machine-primitives" name = "ghost-machine-primitives"
version = "0.8.2" version = "0.7.197"
dependencies = [ dependencies = [
"lazy_static", "lazy_static",
"sc-sysinfo", "sc-sysinfo",
@ -3594,7 +3593,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-metrics" name = "ghost-metrics"
version = "0.8.2" version = "0.7.197"
dependencies = [ dependencies = [
"assert_cmd", "assert_cmd",
"bs58 0.5.1", "bs58 0.5.1",
@ -3617,7 +3616,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-miner" name = "ghost-miner"
version = "1.5.1" version = "1.5.0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"assert_cmd", "assert_cmd",
@ -3649,14 +3648,13 @@ dependencies = [
[[package]] [[package]]
name = "ghost-networks" name = "ghost-networks"
version = "0.1.16" version = "0.1.2"
dependencies = [ dependencies = [
"frame-benchmarking", "frame-benchmarking",
"frame-support", "frame-support",
"frame-system", "frame-system",
"ghost-core-primitives", "ghost-core-primitives",
"ghost-traits", "ghost-traits",
"num-traits",
"pallet-balances", "pallet-balances",
"pallet-staking", "pallet-staking",
"pallet-staking-reward-curve", "pallet-staking-reward-curve",
@ -3669,7 +3667,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-node" name = "ghost-node"
version = "0.8.2" version = "0.7.197"
dependencies = [ dependencies = [
"assert_cmd", "assert_cmd",
"color-eyre", "color-eyre",
@ -3685,7 +3683,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-remote-ext-tests-bags-list" name = "ghost-remote-ext-tests-bags-list"
version = "1.0.1" version = "1.0.0"
dependencies = [ dependencies = [
"casper-runtime", "casper-runtime",
"casper-runtime-constants", "casper-runtime-constants",
@ -3700,7 +3698,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-rpc" name = "ghost-rpc"
version = "0.8.2" version = "0.7.197"
dependencies = [ dependencies = [
"ghost-core-primitives", "ghost-core-primitives",
"jsonrpsee", "jsonrpsee",
@ -3729,7 +3727,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-runtime-common" name = "ghost-runtime-common"
version = "0.4.3" version = "0.4.2"
dependencies = [ dependencies = [
"frame-support", "frame-support",
"frame-system", "frame-system",
@ -3752,7 +3750,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-service" name = "ghost-service"
version = "0.8.2" version = "0.7.197"
dependencies = [ dependencies = [
"assert_matches", "assert_matches",
"async-trait", "async-trait",
@ -3836,7 +3834,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-slow-clap" name = "ghost-slow-clap"
version = "0.3.40" version = "0.3.15"
dependencies = [ dependencies = [
"frame-benchmarking", "frame-benchmarking",
"frame-support", "frame-support",
@ -3845,8 +3843,6 @@ dependencies = [
"log", "log",
"pallet-balances", "pallet-balances",
"pallet-session", "pallet-session",
"pallet-staking",
"pallet-staking-reward-curve",
"parity-scale-codec", "parity-scale-codec",
"scale-info", "scale-info",
"serde", "serde",
@ -3861,7 +3857,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-staging-chain-spec-builder" name = "ghost-staging-chain-spec-builder"
version = "1.6.2" version = "1.6.1"
dependencies = [ dependencies = [
"clap 4.5.4", "clap 4.5.4",
"log", "log",
@ -3870,24 +3866,9 @@ dependencies = [
"sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.12.0)", "sp-tracing 16.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.12.0)",
] ]
[[package]]
name = "ghost-sudo"
version = "0.0.2"
dependencies = [
"docify",
"frame-benchmarking",
"frame-support",
"frame-system",
"parity-scale-codec",
"scale-info",
"sp-io 30.0.0",
"sp-runtime 31.0.1",
"sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.12.0)",
]
[[package]] [[package]]
name = "ghost-traits" name = "ghost-traits"
version = "0.3.23" version = "0.3.19"
dependencies = [ dependencies = [
"frame-support", "frame-support",
"sp-runtime 31.0.1", "sp-runtime 31.0.1",
@ -3895,7 +3876,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-voter-bags" name = "ghost-voter-bags"
version = "0.3.7" version = "0.3.6"
dependencies = [ dependencies = [
"casper-runtime", "casper-runtime",
"clap 4.5.4", "clap 4.5.4",
@ -3905,7 +3886,7 @@ dependencies = [
[[package]] [[package]]
name = "ghostkey" name = "ghostkey"
version = "0.3.16" version = "0.3.15"
dependencies = [ dependencies = [
"clap 4.5.4", "clap 4.5.4",
"ghost-client-cli", "ghost-client-cli",

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.8.2" version = "0.7.197"
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"
@ -69,7 +69,6 @@ bs58 = { version = "0.5.0" }
prometheus-parse = { version = "0.2.2" } prometheus-parse = { version = "0.2.2" }
rustc-hex = { version = "2.1.0", default-features = false } rustc-hex = { version = "2.1.0", default-features = false }
log = { version = "0.4", default-features = false } log = { version = "0.4", default-features = false }
num-traits = { version = "0.2.17", default-features = false }
libsecp256k1 = { version = "0.7", default-features = false } libsecp256k1 = { version = "0.7", default-features = false }
bip39 = { package = "parity-bip39", version = "2.0.1" } bip39 = { package = "parity-bip39", version = "2.0.1" }
sha3 = { version = "0.10", default-features = false } sha3 = { version = "0.10", default-features = false }
@ -230,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 }
@ -273,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",

126
README.md
View File

@ -150,8 +150,28 @@ rustup default stable
rustup update rustup update
``` ```
Add the nightly release and the nightly WebAssembly (wasm) targets
to your development environment by running the following commands:
```bash ```bash
rustup target add wasm32-unknown-unknown --toolchain stable rustup update nightly
```
```bash
rustup target add wasm32-unknown-unknown --toolchain nightly
```
```bash
rustup target add wasm32-unknown-unknown --toolchain stable-x86_64-unknown-linux-gnu
```
If you are trying to install WebAssembly (wasm) on an ARM-based processor like the ones in Raspberry Pi try this instead:
```bash
rustup target add wasm32-unknown-unknown --toolchain stable-aarch64-unknown-linux-gnu
```
**_IF error try_**
```bash
rustup target add wasm32-unknown-unknown --toolchain default
``` ```
Verify the configuration of your development environment by running Verify the configuration of your development environment by running
@ -160,6 +180,10 @@ the following command:
rustup show rustup show
``` ```
```bash
rustup +nightly show
```
You should see something like this: You should see something like this:
![images/img_9.png](images/img_9.png) ![images/img_9.png](images/img_9.png)
@ -170,6 +194,13 @@ Now run:
rustup component add rust-src --toolchain stable rustup component add rust-src --toolchain stable
``` ```
**_IF error try_**
```bash
rustup component add rust-src --toolchain default
```
## Install GHOST ## Install GHOST
Check if Git is already installed: Check if Git is already installed:
@ -180,7 +211,7 @@ git --version
Make a GHOST Directory and go to it: Make a GHOST Directory and go to it:
```bash ```bash
mkdir ~/ghost && cd ~/ghost mkdir ghost && cd ghost
``` ```
Clone GHOST Node Git: Clone GHOST Node Git:
@ -195,7 +226,7 @@ cd ghost-node
Compile the node template by running the following command: Compile the node template by running the following command:
```bash ```bash
./scripts/starter.sh --release cargo build --release
``` ```
The build can take up to 20 minutes depending on the specifications of your machine. The build can take up to 20 minutes depending on the specifications of your machine.
@ -203,6 +234,7 @@ The build can take up to 20 minutes depending on the specifications of your mach
![images/img_12.png](images/img_12.png) ![images/img_12.png](images/img_12.png)
# Boot Node Qualification # Boot Node Qualification
## Boot Node Qualification Test ## Boot Node Qualification Test
@ -288,7 +320,7 @@ Only `port 30333` should be opened.
Press _CTRL+C_ to stop the node. Press _CTRL+C_ to stop the node.
# Launching GHOST TestNet # Launching GHOST TestNet 3.1
Switch to main GIT branch: Switch to main GIT branch:
```bash ```bash
@ -316,7 +348,66 @@ To generate the node key use the following command:
./target/release/ghost key generate-node-key --bin --file=/etc/ghost/node-key ./target/release/ghost key generate-node-key --bin --file=/etc/ghost/node-key
``` ```
Feel free to backup the file on a separate storage device. Generate Wallet Key file with the following command:
```bash
./target/release/ghost key generate | grep "Secret seed" | awk '{$1=$2=""; sub(/^[ \t]+/, ""); print}' > /etc/ghost/wallet-key
```
Display the wallet-key on the screen by using cat command:
```bash
./target/release/ghost key inspect $(cat /etc/ghost/wallet-key)
```
![images/img_22.png](images/img_22.png)
Feel free to back the file on a separate storage device.
Generate Stash Key file with the following command:
```bash
./target/release/ghost key generate | grep "Secret seed" | awk '{$1=$2=""; sub(/^[ \t]+/, ""); print}' > /etc/ghost/stash-key
```
Display the stash-key on the screen by using cat command:
```bash
./target/release/ghost key inspect $(cat /etc/ghost/stash-key)
```
![images/img_23.png](images/img_23.png)
Generate Session Key file with the following command:
```bash
./target/release/ghost key generate | grep "Secret seed" | awk '{$1=$2=""; sub(/^[ \t]+/, ""); print}' > /etc/ghost/session-key
```
You have generates 4 types of Session Keys:
1. Session Key AUDI
2. Session Key BABE
3. Session Key SLOW
4. Session Key GRAN
Now let's display them!
Display the session-key//audi on the screen by using cat command:
```bash
./target/release/ghost key inspect "$(cat /etc/ghost/session-key)//audi"
```
![images/img_24.png](images/img_24.png)
Display the session-key//babe on the screen by using cat command:
```bash
./target/release/ghost key inspect "$(cat /etc/ghost/session-key)//babe"
```
![images/img_25.png](images/img_25.png)
Display the session-key//slow on the screen by using cat command:
```bash
./target/release/ghost key inspect "$(cat /etc/ghost/session-key)//slow"
```
![images/img_26.png](images/img_26.png)
Display the session-key//gran on the screen by using cat command:
```bash
./target/release/ghost key inspect "$(cat /etc/ghost/session-key)//gran" --scheme=ed25519
```
![images/img_27.png](images/img_27.png)
## Build and start the ghost-node ## Build and start the ghost-node
@ -346,7 +437,7 @@ sha256sum /etc/ghost/casper.json
You should see: You should see:
``` ```
9da6045ed6d4fd844e3939573b31c013d0e564e542029330faa6d978cb4a915a ad653233c978bfd00c5e4525b17628632bc4319c5f5f4b4dcc2f050ef3c3d145
``` ```
Create running `ghost-node` service that starts on system boot using `--unit-file` flag. Create running `ghost-node` service that starts on system boot using `--unit-file` flag.
@ -372,7 +463,10 @@ To choose default options press Enter here:
![images/img_30.png](images/img_30.png) ![images/img_30.png](images/img_30.png)
If you want to validate from this node press Enter: Currently, you have to qualify to become a validator node through [GHOST Whales](https://ghostchain.io/whales-apply).
If you were NOT included in the [ghosties file](https://git.ghostchain.io/ghostchain/ghost-node/src/branch/main/service/ghosties) then you cannot be a validator node,
and you can only be a full node so for `disable validator mode? [y/N]` type `y`.
If you were included in the ghosties file you can press Enter:
``` ```
disable validator mode? [y/N]: y disable validator mode? [y/N]: y
``` ```
@ -417,6 +511,17 @@ Type `y` and press _Enter_ for create dedicated user for running `ghost-node`:
![images/img_37.png](images/img_37.png) ![images/img_37.png](images/img_37.png)
Now you can check whether or not the keys on your GHOST Node match those
in the [ghosties file](https://git.ghostchain.io/ghostchain/ghost-node/src/branch/main/service/ghosties) on GHOST Git.
If you are running a **Validator Node** and if you have followed
the Generating Keys Part you will see all `[+]`.
If you are a running a **Full Node** you will see errors:
(Press _Enter_ for prompts)
```bash
./scripts/starter.sh --check-keys
```
Full Node: Full Node:
![images/img_38.png](images/img_38.png) ![images/img_38.png](images/img_38.png)
@ -430,7 +535,7 @@ Start `ghost-node`:
sudo systemctl start ghost-node sudo systemctl start ghost-node
``` ```
Wait ~60 seconds! Wait 60 seconds!
Check node is started: Check node is started:
```bash ```bash
@ -440,6 +545,11 @@ sudo systemctl status ghost-node
For exit press _CTRL+C_ For exit press _CTRL+C_
In order to insert keys run the following flags `--check-keys` `--insert-keys`:
```bash
./scripts/starter.sh --check-keys --insert-keys
```
Restart `ghost-node`: Restart `ghost-node`:
```bash ```bash
sudo systemctl restart ghost-node sudo systemctl restart ghost-node

View File

@ -1,13 +1,14 @@
use crate::cli::{Cli, Subcommand}; use crate::cli::{Cli, Subcommand};
use frame_benchmarking_cli::{BenchmarkCmd, ExtrinsicFactory}; use frame_benchmarking_cli::{BenchmarkCmd, ExtrinsicFactory};
use futures::future::TryFutureExt; use futures::future::TryFutureExt;
use keyring::Sr25519Keyring;
use sc_cli::SubstrateCli; use sc_cli::SubstrateCli;
use service::{ use service::{
self, self, IdentifyVariant,
benchmarking::{benchmark_inherent_data, RemarkBuilder, TransferKeepAliveBuilder}, benchmarking::{
IdentifyVariant, benchmark_inherent_data, RemarkBuilder, TransferKeepAliveBuilder
},
}; };
use keyring::Sr25519Keyring;
pub use crate::{error::Error, service::BlockId}; pub use crate::{error::Error, service::BlockId};
#[cfg(feature = "pyroscope")] #[cfg(feature = "pyroscope")]
@ -67,35 +68,28 @@ impl SubstrateCli for Cli {
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
"casper" => Box::new(service::chain_spec::casper_config()?), "casper" => Box::new(service::chain_spec::casper_config()?),
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
"casper-dev" | "dev" | "development" => { "casper-dev" | "dev" | "development" => Box::new(service::chain_spec::casper_development_config()?),
Box::new(service::chain_spec::casper_development_config()?)
}
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
"casper-local" | "local" => { "casper-local" | "local" => Box::new(service::chain_spec::casper_local_testnet_config()?),
Box::new(service::chain_spec::casper_local_testnet_config()?)
}
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
"casper-staging" | "staging" => { "casper-staging" | "staging" => Box::new(service::chain_spec::casper_staging_testnet_config()?),
Box::new(service::chain_spec::casper_staging_testnet_config()?)
}
#[cfg(not(feature = "casper-native"))] #[cfg(not(feature = "casper-native"))]
name if name.starts_with("casper-") && !name.ends_with(".json") => Err(format!( name if name.starts_with("casper-") && !name.ends_with(".json") =>
"`{}` only supported with `casper-native` feature enabled.", Err(format!("`{}` only supported with `casper-native` feature enabled.", name))?,
name
))?,
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
path => { path => {
let path = std::path::PathBuf::from(path); let path = std::path::PathBuf::from(path);
let chain_spec = Box::new(service::GenericChainSpec::from_json_file(path.clone())?) let chain_spec = Box::new(
as Box<dyn service::ChainSpec>; service::GenericChainSpec::from_json_file(path.clone())?
) as Box<dyn service::ChainSpec>;
if chain_spec.is_casper() { if chain_spec.is_casper() {
Box::new(service::CasperChainSpec::from_json_file(path)?) Box::new(service::CasperChainSpec::from_json_file(path)?)
} else { } else {
chain_spec chain_spec
} }
} },
}) })
} }
} }
@ -115,7 +109,10 @@ fn set_ss58_version(spec: &Box<dyn service::ChainSpec>) {
sp_core::crypto::set_default_ss58_version(ss58_version); sp_core::crypto::set_default_ss58_version(ss58_version);
} }
fn run_node_inner<F>(cli: Cli, logger_hook: F) -> Result<()> fn run_node_inner<F>(
cli: Cli,
logger_hook: F,
) -> Result<()>
where where
F: FnOnce(&mut sc_cli::LoggerBuilder, &sc_service::Configuration), F: FnOnce(&mut sc_cli::LoggerBuilder, &sc_service::Configuration),
{ {
@ -131,8 +128,7 @@ where
.then_some(config.database.path().map(|database_path| { .then_some(config.database.path().map(|database_path| {
let _ = std::fs::create_dir_all(&database_path); let _ = std::fs::create_dir_all(&database_path);
sc_sysinfo::gather_hwbench(Some(database_path)) sc_sysinfo::gather_hwbench(Some(database_path))
})) })).flatten();
.flatten();
let database_source = config.database.clone(); let database_source = config.database.clone();
let task_manager = service::build_full( let task_manager = service::build_full(
@ -142,8 +138,7 @@ where
telemetry_worker_handle: None, telemetry_worker_handle: None,
hwbench, hwbench,
}, },
) ).map(|full| full.task_manager)?;
.map(|full| full.task_manager)?;
if let Some(path) = database_source.path() { if let Some(path) = database_source.path() {
sc_storage_monitor::StorageMonitorService::try_spawn( sc_storage_monitor::StorageMonitorService::try_spawn(
@ -172,9 +167,7 @@ pub fn run() -> Result<()> {
let agent = pyro::Pyroscope::builder( let agent = pyro::Pyroscope::builder(
"http://".to_owned() + address.to_string().as_str(), "http://".to_owned() + address.to_string().as_str(),
"ghost".to_owned(), "ghost".to_owned(),
) ).backend(pprof_backend(PprofConfig::new().sample_rate(113))).build()?;
.backend(pprof_backend(PprofConfig::new().sample_rate(113)))
.build()?;
Some(agent.start()?) Some(agent.start()?)
} else { } else {
@ -183,7 +176,7 @@ pub fn run() -> Result<()> {
#[cfg(not(feature = "pyroscope"))] #[cfg(not(feature = "pyroscope"))]
if cli.run.pyroscope_server.is_some() { if cli.run.pyroscope_server.is_some() {
return Err(Error::PyroscopeNotCompiledIn); return Err(Error::PyroscopeNotCompiledIn)
} }
match &cli.subcommand { match &cli.subcommand {
@ -191,7 +184,7 @@ pub fn run() -> Result<()> {
Some(Subcommand::BuildSpec(cmd)) => { Some(Subcommand::BuildSpec(cmd)) => {
let runner = cli.create_runner(cmd).map_err(Error::SubstrateCli)?; let runner = cli.create_runner(cmd).map_err(Error::SubstrateCli)?;
Ok(runner.sync_run(|config| cmd.run(config.chain_spec, config.network))?) Ok(runner.sync_run(|config| cmd.run(config.chain_spec, config.network))?)
} },
Some(Subcommand::CheckBlock(cmd)) => { Some(Subcommand::CheckBlock(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;
@ -199,13 +192,11 @@ pub fn run() -> Result<()> {
set_ss58_version(chain_spec); set_ss58_version(chain_spec);
runner.async_run(|mut config| { runner.async_run(|mut config| {
let (client, _, import_queue, task_manager) = service::new_chain_ops(&mut config)?; let (client, _, import_queue, task_manager) =
Ok(( service::new_chain_ops(&mut config)?;
cmd.run(client, import_queue).map_err(Error::SubstrateCli), Ok((cmd.run(client, import_queue).map_err(Error::SubstrateCli), task_manager))
task_manager,
))
}) })
} },
Some(Subcommand::ExportBlocks(cmd)) => { Some(Subcommand::ExportBlocks(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;
@ -213,14 +204,11 @@ pub fn run() -> Result<()> {
set_ss58_version(chain_spec); set_ss58_version(chain_spec);
Ok(runner.async_run(|mut config| { Ok(runner.async_run(|mut config| {
let (client, _, _, task_manager) = service::new_chain_ops(&mut config)?; let ( client, _, _, task_manager ) =
Ok(( service::new_chain_ops(&mut config)?;
cmd.run(client, config.database) Ok((cmd.run(client, config.database).map_err(Error::SubstrateCli), task_manager))
.map_err(Error::SubstrateCli),
task_manager,
))
})?) })?)
} },
Some(Subcommand::ExportState(cmd)) => { Some(Subcommand::ExportState(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;
@ -228,14 +216,11 @@ pub fn run() -> Result<()> {
set_ss58_version(chain_spec); set_ss58_version(chain_spec);
Ok(runner.async_run(|mut config| { Ok(runner.async_run(|mut config| {
let (client, _, _, task_manager) = service::new_chain_ops(&mut config)?; let ( client, _, _, task_manager ) =
Ok(( service::new_chain_ops(&mut config)?;
cmd.run(client, config.chain_spec) Ok((cmd.run(client, config.chain_spec).map_err(Error::SubstrateCli), task_manager))
.map_err(Error::SubstrateCli),
task_manager,
))
})?) })?)
} },
Some(Subcommand::ImportBlocks(cmd)) => { Some(Subcommand::ImportBlocks(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;
@ -243,17 +228,15 @@ pub fn run() -> Result<()> {
set_ss58_version(chain_spec); set_ss58_version(chain_spec);
Ok(runner.async_run(|mut config| { Ok(runner.async_run(|mut config| {
let (client, _, import_queue, task_manager) = service::new_chain_ops(&mut config)?; let ( client, _, import_queue, task_manager ) =
Ok(( service::new_chain_ops(&mut config)?;
cmd.run(client, import_queue).map_err(Error::SubstrateCli), Ok((cmd.run(client, import_queue).map_err(Error::SubstrateCli), task_manager))
task_manager,
))
})?) })?)
} },
Some(Subcommand::PurgeChain(cmd)) => { Some(Subcommand::PurgeChain(cmd)) => {
let runner = cli.create_runner(cmd).map_err(Error::SubstrateCli)?; let runner = cli.create_runner(cmd).map_err(Error::SubstrateCli)?;
Ok(runner.sync_run(|config| cmd.run(config.database))?) Ok(runner.sync_run(|config| cmd.run(config.database))?)
} },
Some(Subcommand::Revert(cmd)) => { Some(Subcommand::Revert(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;
@ -261,59 +244,62 @@ pub fn run() -> Result<()> {
set_ss58_version(chain_spec); set_ss58_version(chain_spec);
Ok(runner.async_run(|mut config| { Ok(runner.async_run(|mut config| {
let (client, backend, _, task_manager) = service::new_chain_ops(&mut config)?; let (client, backend, _, task_manager) =
service::new_chain_ops(&mut config)?;
let aux_revert = Box::new(|client, backend, blocks| { let aux_revert = Box::new(|client, backend, blocks| {
service::revert_backend(client, backend, blocks).map_err(|err| match err { service::revert_backend(client, backend, blocks).map_err(|err| {
match err {
service::Error::Blockchain(err) => err.into(), service::Error::Blockchain(err) => err.into(),
err => sc_cli::Error::Application(err.into()), err => sc_cli::Error::Application(err.into()),
}
}) })
}); });
Ok(( Ok((
cmd.run(client, backend, Some(aux_revert)) cmd.run(client, backend, Some(aux_revert)).map_err(Error::SubstrateCli),
.map_err(Error::SubstrateCli), task_manager
task_manager,
)) ))
})?) })?)
} },
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"))] #[cfg(not(feature = "runtime-benchmarks"))]
BenchmarkCmd::Storage(_) => { BenchmarkCmd::Storage(_) =>
return Err(sc_cli::Error::Input( return Err(sc_cli::Error::Input(
"Compile with `--feature=runtime-benchmarks \ "Compile with `--feature=runtime-benchmarks \
to enable storage benchmarks." to enable storage benchmarks.".into()
.into(), ).into()),
)
.into())
}
#[cfg(feature = "runtime-benchmarks")] #[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();
let storage = backend.expose_storage(); let storage = backend.expose_storage();
cmd.run(config, client.clone(), db, storage) cmd.run(config, client.clone(), db, storage).map_err(Error::SubstrateCli)
.map_err(Error::SubstrateCli)
}), }),
BenchmarkCmd::Block(cmd) => runner.sync_run(|mut config| { BenchmarkCmd::Block(cmd) => runner.sync_run(|mut config| {
let (client, _, _, _) = service::new_chain_ops(&mut config)?; let (client, _, _, _,) =
service::new_chain_ops(&mut config)?;
cmd.run(client.clone()).map_err(Error::SubstrateCli) cmd.run(client.clone()).map_err(Error::SubstrateCli)
}), }),
// These commands are very similar and can be handled in nearly the same way // These commands are very similar and can be handled in nearly the same way
BenchmarkCmd::Extrinsic(_) | BenchmarkCmd::Overhead(_) => { BenchmarkCmd::Extrinsic(_) | BenchmarkCmd::Overhead(_) =>
runner.sync_run(|mut config| { runner.sync_run(|mut config| {
let (client, _, _, _) = service::new_chain_ops(&mut config)?; let (client, _, _, _) =
service::new_chain_ops(&mut config)?;
let inherent_data = benchmark_inherent_data() let inherent_data = benchmark_inherent_data()
.map_err(|e| format!("generating inherent data: {:?}", e))?; .map_err(|e| format!("generating inherent data: {:?}", e))?;
let remark_builder = let remark_builder = RemarkBuilder::new(
RemarkBuilder::new(client.clone(), config.chain_spec.identify_chain()); client.clone(),
config.chain_spec.identify_chain(),
);
match cmd { match cmd {
BenchmarkCmd::Extrinsic(cmd) => { BenchmarkCmd::Extrinsic(cmd) => {
@ -330,20 +316,17 @@ pub fn run() -> Result<()> {
cmd.run(client.clone(), inherent_data, Vec::new(), &ext_factory) cmd.run(client.clone(), inherent_data, Vec::new(), &ext_factory)
.map_err(Error::SubstrateCli) .map_err(Error::SubstrateCli)
} },
BenchmarkCmd::Overhead(cmd) => cmd BenchmarkCmd::Overhead(cmd) => cmd.run(
.run(
config, config,
client.clone(), client.clone(),
inherent_data, inherent_data,
Vec::new(), Vec::new(),
&remark_builder, &remark_builder,
) ).map_err(Error::SubstrateCli),
.map_err(Error::SubstrateCli),
_ => unreachable!("Ensured by the outside match; qed"), _ => unreachable!("Ensured by the outside match; qed"),
} }
}) }),
}
BenchmarkCmd::Pallet(cmd) => { BenchmarkCmd::Pallet(cmd) => {
set_ss58_version(chain_spec); set_ss58_version(chain_spec);
@ -351,23 +334,17 @@ pub fn run() -> Result<()> {
runner.sync_run(|config| { runner.sync_run(|config| {
cmd.run_with_spec::<sp_runtime::traits::HashingFor<service::Block>, ()>( cmd.run_with_spec::<sp_runtime::traits::HashingFor<service::Block>, ()>(
Some(config.chain_spec), Some(config.chain_spec),
) ).map_err(|e| Error::SubstrateCli(e))
.map_err(|e| Error::SubstrateCli(e))
}) })
} else { } else {
Err(sc_cli::Error::Input( Err(sc_cli::Error::Input(
"Benchmarking wasn't enabled when building the node. \ "Benchmarking wasn't enabled when building the node. \
You can enable it with `--features=runtime-benchmarks`." You can enable it with `--features=runtime-benchmarks`.".into()
.into(), ).into())
)
.into())
}
} }
},
BenchmarkCmd::Machine(cmd) => runner.sync_run(|config| { BenchmarkCmd::Machine(cmd) => runner.sync_run(|config| {
cmd.run( cmd.run(&config, ghost_machine_primitives::GHOST_NODE_REFERENCE_HARDWARE.clone())
&config,
ghost_machine_primitives::GHOST_NODE_REFERENCE_HARDWARE.clone(),
)
.map_err(Error::SubstrateCli) .map_err(Error::SubstrateCli)
}), }),
// Note: this allows to implement additional new benchmark // Note: this allows to implement additional new benchmark
@ -375,12 +352,12 @@ pub fn run() -> Result<()> {
#[allow(unreachable_patterns)] #[allow(unreachable_patterns)]
_ => Err(Error::CommandNotImplemented), _ => Err(Error::CommandNotImplemented),
} }
} },
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)?;
Ok(runner.sync_run(|config| cmd.run::<service::Block>(&config))?) Ok(runner.sync_run(|config| cmd.run::<service::Block>(&config))?)
} },
}?; }?;
#[cfg(feature = "pyroscope")] #[cfg(feature = "pyroscope")]

View File

@ -6,7 +6,9 @@ mod command;
mod error; mod error;
#[cfg(feature = "service")] #[cfg(feature = "service")]
pub use service::{self, Block, CoreApi, IdentifyVariant, ProvideRuntimeApi, TFullClient}; pub use service::{
self, Block, CoreApi, IdentifyVariant, ProvideRuntimeApi, TFullClient,
};
#[cfg(feature = "cli")] #[cfg(feature = "cli")]
pub use cli::*; pub use cli::*;

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-client-cli" name = "ghost-client-cli"
version = "0.1.4" version = "0.1.3"
description = "Ghost CLI interface" description = "Ghost CLI interface"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -3,10 +3,13 @@
use bip39::Mnemonic; use bip39::Mnemonic;
use clap::Parser; use clap::Parser;
use itertools::Itertools; use itertools::Itertools;
use sc_cli::{with_crypto_scheme, CryptoSchemeFlag, Error, KeystoreParams, OutputTypeFlag}; use sc_cli::{
with_crypto_scheme, KeystoreParams, OutputTypeFlag,
CryptoSchemeFlag, Error,
};
use crate::commands::utils::print_from_uri;
use crate::params::NetworkSchemeFlag; use crate::params::NetworkSchemeFlag;
use crate::commands::utils::print_from_uri;
/// The `generate` command /// The `generate` command
#[derive(Debug, Clone, Parser)] #[derive(Debug, Clone, Parser)]

View File

@ -1,13 +1,14 @@
//! Implementation of the `inspect` subcommand //! Implementation of the `inspect` subcommand
use crate::commands::utils::{print_from_public, print_from_uri};
use crate::params::NetworkSchemeFlag;
use clap::Parser; use clap::Parser;
use sc_cli::{
utils::read_uri, with_crypto_scheme, CryptoSchemeFlag, Error, KeystoreParams, OutputTypeFlag,
};
use sp_core::crypto::{ExposeSecret, SecretString, SecretUri, Ss58Codec}; use sp_core::crypto::{ExposeSecret, SecretString, SecretUri, Ss58Codec};
use std::str::FromStr; use std::str::FromStr;
use sc_cli::{
with_crypto_scheme, KeystoreParams, OutputTypeFlag, CryptoSchemeFlag, Error,
utils::read_uri,
};
use crate::params::NetworkSchemeFlag;
use crate::commands::utils::{print_from_public, print_from_uri};
/// The `inspect` command /// The `inspect` command
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
@ -235,16 +236,8 @@ mod tests {
array_bytes::bytes2hex("0x", valid_public_with_password_and_derivation.as_slice()); array_bytes::bytes2hex("0x", valid_public_with_password_and_derivation.as_slice());
// They should still be valid, because we check the base secret key. // They should still be valid, because we check the base secret key.
check_cmd( check_cmd(&seed_with_password_and_derivation, &valid_public_hex_with_password, true);
&seed_with_password_and_derivation, check_cmd(&seed_with_password_and_derivation, &valid_accountid_with_password, true);
&valid_public_hex_with_password,
true,
);
check_cmd(
&seed_with_password_and_derivation,
&valid_accountid_with_password,
true,
);
// And these should be invalid. // And these should be invalid.
check_cmd(&seed_with_password_and_derivation, &valid_public_hex, false); check_cmd(&seed_with_password_and_derivation, &valid_public_hex, false);

View File

@ -1,7 +1,10 @@
//! Key related CLI utilities //! Key related CLI utilities
use super::{generate::GenerateCmd, inspect_key::InspectKeyCmd}; use super::{generate::GenerateCmd, inspect_key::InspectKeyCmd};
use sc_cli::{Error, GenerateKeyCmdCommon, InsertKeyCmd, InspectNodeKeyCmd, SubstrateCli}; use sc_cli::{
GenerateKeyCmdCommon, InsertKeyCmd, InspectNodeKeyCmd, Error,
SubstrateCli,
};
/// Key utilities for the cli. /// Key utilities for the cli.
#[derive(Debug, clap::Subcommand)] #[derive(Debug, clap::Subcommand)]

View File

@ -1,13 +1,11 @@
mod generate;
mod inspect_key;
mod key; mod key;
mod utils; mod generate;
mod vanity; mod vanity;
mod inspect_key;
mod utils;
pub use self::{ pub use self::{
key::KeySubcommand, vanity::VanityCmd, inspect_key::InspectKeyCmd,
generate::GenerateCmd, generate::GenerateCmd,
inspect_key::InspectKeyCmd, utils::{unwrap_or_default_ss58_name, print_from_uri, print_from_public},
key::KeySubcommand,
utils::{print_from_public, print_from_uri, unwrap_or_default_ss58_name},
vanity::VanityCmd,
}; };

View File

@ -1,15 +1,16 @@
use sc_cli::{
utils::{PublicFor, SeedFor},
OutputType,
};
use serde_json::json; use serde_json::json;
use sc_cli::{
OutputType,
utils::{PublicFor, SeedFor},
};
use sp_runtime::{traits::IdentifyAccount, MultiSigner};
use sp_core::{ use sp_core::{
crypto::{ crypto::{
unwrap_or_default_ss58_version, ExposeSecret, SecretString, Ss58AddressFormat, Ss58Codec, unwrap_or_default_ss58_version,
Ss58Codec, ExposeSecret, Ss58AddressFormat, SecretString,
}, },
hexdisplay::HexDisplay, hexdisplay::HexDisplay,
}; };
use sp_runtime::{traits::IdentifyAccount, MultiSigner};
pub fn print_from_uri<Pair>( pub fn print_from_uri<Pair>(
uri: &str, uri: &str,
@ -42,7 +43,7 @@ pub fn print_from_uri<Pair>(
"{}", "{}",
serde_json::to_string_pretty(&json).expect("Json pretty print failed") serde_json::to_string_pretty(&json).expect("Json pretty print failed")
); );
} },
OutputType::Text => { OutputType::Text => {
println!( println!(
"Secret phrase: {}\n \ "Secret phrase: {}\n \
@ -58,12 +59,9 @@ pub fn print_from_uri<Pair>(
format_public_key::<Pair>(public_key.clone()), format_public_key::<Pair>(public_key.clone()),
format_account_id::<Pair>(public_key.clone()), format_account_id::<Pair>(public_key.clone()),
public_key.to_ss58check_with_version(network_override), public_key.to_ss58check_with_version(network_override),
pair.public() pair.public().into().into_account().to_ss58check_with_version(network_override),
.into()
.into_account()
.to_ss58check_with_version(network_override),
); );
} },
} }
} else if let Ok((pair, seed)) = Pair::from_string_with_seed(uri, password) { } else if let Ok((pair, seed)) = Pair::from_string_with_seed(uri, password) {
let public_key = pair.public(); let public_key = pair.public();
@ -84,7 +82,7 @@ pub fn print_from_uri<Pair>(
"{}", "{}",
serde_json::to_string_pretty(&json).expect("Json pretty print failed") serde_json::to_string_pretty(&json).expect("Json pretty print failed")
); );
} },
OutputType::Text => { OutputType::Text => {
println!( println!(
"Secret Key URI `{}` is account:\n \ "Secret Key URI `{}` is account:\n \
@ -96,20 +94,13 @@ pub fn print_from_uri<Pair>(
SS58 Address: {}", SS58 Address: {}",
uri, uri,
network_id, network_id,
if let Some(seed) = seed { if let Some(seed) = seed { format_seed::<Pair>(seed) } else { "n/a".into() },
format_seed::<Pair>(seed)
} else {
"n/a".into()
},
format_public_key::<Pair>(public_key.clone()), format_public_key::<Pair>(public_key.clone()),
format_account_id::<Pair>(public_key.clone()), format_account_id::<Pair>(public_key.clone()),
public_key.to_ss58check_with_version(network_override), public_key.to_ss58check_with_version(network_override),
pair.public() pair.public().into().into_account().to_ss58check_with_version(network_override),
.into()
.into_account()
.to_ss58check_with_version(network_override),
); );
} },
} }
} else if let Ok((public_key, network)) = Pair::Public::from_string_with_version(uri) { } else if let Ok((public_key, network)) = Pair::Public::from_string_with_version(uri) {
let network_override = network_override.unwrap_or(network); let network_override = network_override.unwrap_or(network);
@ -129,7 +120,7 @@ pub fn print_from_uri<Pair>(
"{}", "{}",
serde_json::to_string_pretty(&json).expect("Json pretty print failed") serde_json::to_string_pretty(&json).expect("Json pretty print failed")
); );
} },
OutputType::Text => { OutputType::Text => {
println!( println!(
"Public Key URI `{}` is account:\n \ "Public Key URI `{}` is account:\n \
@ -145,7 +136,7 @@ pub fn print_from_uri<Pair>(
public_key.to_ss58check_with_version(network_override), public_key.to_ss58check_with_version(network_override),
public_key.to_ss58check_with_version(network_override), public_key.to_ss58check_with_version(network_override),
); );
} },
} }
} else { } else {
println!("Invalid phrase/URI given"); println!("Invalid phrase/URI given");
@ -179,11 +170,8 @@ where
"ss58Address": public_key.to_ss58check_with_version(network_override), "ss58Address": public_key.to_ss58check_with_version(network_override),
}); });
println!( println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed"));
"{}", },
serde_json::to_string_pretty(&json).expect("Json pretty print failed")
);
}
OutputType::Text => { OutputType::Text => {
println!( println!(
"Network ID/Version: {}\n \ "Network ID/Version: {}\n \
@ -197,7 +185,7 @@ where
public_key.to_ss58check_with_version(network_override), public_key.to_ss58check_with_version(network_override),
public_key.to_ss58check_with_version(network_override), public_key.to_ss58check_with_version(network_override),
); );
} },
} }
Ok(()) Ok(())
@ -228,8 +216,5 @@ fn format_account_id<P: sp_core::Pair>(public_key: PublicFor<P>) -> String
where where
PublicFor<P>: Into<MultiSigner>, PublicFor<P>: Into<MultiSigner>,
{ {
format!( format!("0x{}", HexDisplay::from(&public_key.into().into_account().as_ref()))
"0x{}",
HexDisplay::from(&public_key.into().into_account().as_ref())
)
} }

View File

@ -2,19 +2,21 @@
use clap::Parser; use clap::Parser;
use rand::{rngs::OsRng, RngCore}; use rand::{rngs::OsRng, RngCore};
use sc_cli::{utils::format_seed, with_crypto_scheme, CryptoSchemeFlag, Error, OutputTypeFlag}; use sp_core::crypto::{
use sp_core::crypto::{unwrap_or_default_ss58_version, Ss58AddressFormat, Ss58Codec}; unwrap_or_default_ss58_version, Ss58AddressFormat, Ss58Codec,
};
use sp_runtime::traits::IdentifyAccount; use sp_runtime::traits::IdentifyAccount;
use sc_cli::{
with_crypto_scheme, Error, OutputTypeFlag, CryptoSchemeFlag,
utils::format_seed,
};
use crate::commands::utils::print_from_uri; use crate::commands::utils::print_from_uri;
use crate::params::NetworkSchemeFlag; use crate::params::NetworkSchemeFlag;
/// The `vanity` command /// The `vanity` command
#[derive(Debug, Clone, Parser)] #[derive(Debug, Clone, Parser)]
#[command( #[command(name = "vanity", about = "Generate a seed that provides a vanity address")]
name = "vanity",
about = "Generate a seed that provides a vanity address"
)]
pub struct VanityCmd { pub struct VanityCmd {
/// Desired pattern /// Desired pattern
#[arg(long, value_parser = assert_non_empty_string)] #[arg(long, value_parser = assert_non_empty_string)]
@ -82,17 +84,14 @@ where
} }
let p = Pair::from_seed(&seed); let p = Pair::from_seed(&seed);
let ss58 = p let ss58 = p.public().into_account().to_ss58check_with_version(network_override);
.public()
.into_account()
.to_ss58check_with_version(network_override);
println!("{:?}", ss58); println!("{:?}", ss58);
let score = calculate_score(desired, &ss58); let score = calculate_score(desired, &ss58);
if score > best || desired.len() < 2 { if score > best || desired.len() < 2 {
best = score; best = score;
if best >= top { if best >= top {
println!("best: {} == top: {}", best, top); println!("best: {} == top: {}", best, top);
return Ok(format_seed::<Pair>(seed.clone())); return Ok(format_seed::<Pair>(seed.clone()))
} }
} }
done += 1; done += 1;
@ -117,11 +116,11 @@ fn next_seed(seed: &mut [u8]) {
match s { match s {
255 => { 255 => {
*s = 0; *s = 0;
} },
_ => { _ => {
*s += 1; *s += 1;
break; break
} },
} }
} }
} }
@ -133,7 +132,7 @@ fn calculate_score(_desired: &str, key: &str) -> usize {
let snip_size = _desired.len() - truncate; let snip_size = _desired.len() - truncate;
let truncated = &_desired[0..snip_size]; let truncated = &_desired[0..snip_size];
if let Some(pos) = key.find(truncated) { if let Some(pos) = key.find(truncated) {
return (47 - pos) + (snip_size * 48); return (47 - pos) + (snip_size * 48)
} }
} }
0 0
@ -165,13 +164,11 @@ mod tests {
#[test] #[test]
fn test_generation_with_single_char() { fn test_generation_with_single_char() {
let seed = generate_key::<sr25519::Pair>("ab", default_ss58_version()).unwrap(); let seed = generate_key::<sr25519::Pair>("ab", default_ss58_version()).unwrap();
assert!( assert!(sr25519::Pair::from_seed_slice(&array_bytes::hex2bytes_unchecked(&seed))
sr25519::Pair::from_seed_slice(&array_bytes::hex2bytes_unchecked(&seed))
.unwrap() .unwrap()
.public() .public()
.to_ss58check() .to_ss58check()
.contains("ab") .contains("ab"));
);
} }
#[test] #[test]
@ -179,13 +176,11 @@ mod tests {
let seed = let seed =
generate_key::<sr25519::Pair>("ab", Ss58AddressFormatRegistry::PolkadotAccount.into()) generate_key::<sr25519::Pair>("ab", Ss58AddressFormatRegistry::PolkadotAccount.into())
.unwrap(); .unwrap();
assert!( assert!(sr25519::Pair::from_seed_slice(&array_bytes::hex2bytes_unchecked(&seed))
sr25519::Pair::from_seed_slice(&array_bytes::hex2bytes_unchecked(&seed))
.unwrap() .unwrap()
.public() .public()
.to_ss58check_with_version(Ss58AddressFormatRegistry::PolkadotAccount.into()) .to_ss58check_with_version(Ss58AddressFormatRegistry::PolkadotAccount.into())
.contains("ab") .contains("ab"));
);
} }
#[test] #[test]

View File

@ -1,5 +1,5 @@
pub mod commands;
pub mod params; pub mod params;
pub mod commands;
pub use commands::KeySubcommand; pub use commands::KeySubcommand;
pub use commands::VanityCmd; pub use commands::VanityCmd;

View File

@ -21,21 +21,15 @@ pub struct InnerSs58AddressFormat(Ss58AddressFormat);
impl InnerSs58AddressFormat { impl InnerSs58AddressFormat {
#[inline] #[inline]
pub fn custom(prefix: u16) -> Self { pub fn custom(prefix: u16) -> Self {
Self { Self { 0: Ss58AddressFormat::custom(prefix) }
0: Ss58AddressFormat::custom(prefix),
}
} }
} }
impl std::fmt::Display for InnerSs58AddressFormat { impl std::fmt::Display for InnerSs58AddressFormat {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!( write!(f, "{} network", ALL_POSSIBLE_IDS
f,
"{} network",
ALL_POSSIBLE_IDS
.binary_search(&u16::from(self.0)) .binary_search(&u16::from(self.0))
.expect("always be found") .expect("always be found"))
)
} }
} }
@ -50,13 +44,13 @@ impl<'a> TryFrom<&'a str> for InnerSs58AddressFormat {
} }
} }
pub fn parse_s58_prefix_address_format(x: &str) -> Result<Ss58AddressFormat, String> { pub fn parse_s58_prefix_address_format(x: &str,) -> Result<Ss58AddressFormat, String> {
match InnerSs58AddressFormat::try_from(x) { match InnerSs58AddressFormat::try_from(x) {
Ok(format_registry) => Ok(format_registry.0.into()), Ok(format_registry) => Ok(format_registry.0.into()),
Err(_) => Err(format!( Err(_) => Err(format!(
"Unable to parse variant. Known variants: {:?}", "Unable to parse variant. Known variants: {:?}",
&ALL_POSSIBLE_NAMES &ALL_POSSIBLE_NAMES
)), ))
} }
} }

View File

@ -22,11 +22,7 @@ impl Metronome {
/// Create a new metronome source with a defined cycle duration. /// Create a new metronome source with a defined cycle duration.
pub fn new(cycle: Duration) -> Self { pub fn new(cycle: Duration) -> Self {
let period = cycle.into(); let period = cycle.into();
Self { Self { period, delay: Delay::new(period), state: MetronomeState::Snooze }
period,
delay: Delay::new(period),
state: MetronomeState::Snooze,
}
} }
} }
@ -40,14 +36,14 @@ impl futures::Stream for Metronome {
let val = self.period; let val = self.period;
self.delay.reset(val); self.delay.reset(val);
self.state = MetronomeState::Snooze; self.state = MetronomeState::Snooze;
} },
MetronomeState::Snooze => { MetronomeState::Snooze => {
if !Pin::new(&mut self.delay).poll(cx).is_ready() { if !Pin::new(&mut self.delay).poll(cx).is_ready() {
break; break
} }
self.state = MetronomeState::SetAlarm; self.state = MetronomeState::SetAlarm;
return Poll::Ready(Some(())); return Poll::Ready(Some(()))
} },
} }
} }
Poll::Pending Poll::Pending

View File

@ -2,16 +2,19 @@
use codec::Decode; use codec::Decode;
use core_primitives::{ use core_primitives::{
metrics_definitions::{CounterDefinition, CounterVecDefinition, HistogramDefinition}, metrics_definitions::{
CounterDefinition, CounterVecDefinition, HistogramDefinition,
},
RuntimeMetricLabelValues, RuntimeMetricOp, RuntimeMetricUpdate, RuntimeMetricLabelValues, RuntimeMetricOp, RuntimeMetricUpdate,
}; };
use prometheus_endpoint::{ use prometheus_endpoint::{
register, Counter, CounterVec, Histogram, HistogramOpts, Opts, PrometheusError, Registry, U64, register, Counter, CounterVec, Histogram, HistogramOpts, Opts, Registry,
PrometheusError, U64,
}; };
use std::{ use std::{
collections::hash_map::HashMap, collections::hash_map::HashMap,
sync::{Arc, Mutex, MutexGuard}, sync::{Arc, Mutex, MutexGuard},
}; }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Metrics { pub struct Metrics {
@ -29,9 +32,7 @@ impl RuntimeMetricsProvider {
pub fn register_countervec(&self, countervec: CounterVecDefinition) { pub fn register_countervec(&self, countervec: CounterVecDefinition) {
self.with_counter_vecs_lock_held(|mut hashmap| { self.with_counter_vecs_lock_held(|mut hashmap| {
hashmap hashmap.entry(countervec.name.to_owned()).or_insert(register(
.entry(countervec.name.to_owned())
.or_insert(register(
CounterVec::new( CounterVec::new(
Opts::new(countervec.name, countervec.description), Opts::new(countervec.name, countervec.description),
countervec.labels, countervec.labels,
@ -45,7 +46,10 @@ impl RuntimeMetricsProvider {
pub fn register_counter(&self, counter: CounterDefinition) { pub fn register_counter(&self, counter: CounterDefinition) {
self.with_counters_lock_held(|mut hashmap| { self.with_counters_lock_held(|mut hashmap| {
hashmap.entry(counter.name.to_owned()).or_insert(register( hashmap.entry(counter.name.to_owned()).or_insert(register(
Counter::new(counter.name, counter.description)?, Counter::new(
counter.name,
counter.description,
)?,
&self.0, &self.0,
)?); )?);
Ok(()) Ok(())
@ -56,7 +60,8 @@ impl RuntimeMetricsProvider {
self.with_histograms_lock_held(|mut hashmap| { self.with_histograms_lock_held(|mut hashmap| {
hashmap.entry(hist.name.to_owned()).or_insert(register( hashmap.entry(hist.name.to_owned()).or_insert(register(
Histogram::with_opts( Histogram::with_opts(
HistogramOpts::new(hist.name, hist.description).buckets(hist.buckets.to_vec()), HistogramOpts::new(hist.name, hist.description)
.buckets(hist.buckets.to_vec()),
)?, )?,
&self.0, &self.0,
)?); )?);
@ -64,12 +69,15 @@ impl RuntimeMetricsProvider {
}) })
} }
pub fn inc_counter_vec_by(&self, name: &str, value: u64, labels: &RuntimeMetricsProvider) { pub fn inc_counter_vec_by(
&self,
name: &str,
value: u64,
labels: &RuntimeMetricsProvider,
) {
self.with_counter_vecs_lock_held(|mut hashmap| { self.with_counter_vecs_lock_held(|mut hashmap| {
hashmap.entry(name.to_owned()).and_modify(|counter_vec| { hashmap.entry(name.to_owned()).and_modify(|counter_vec| {
counter_vec counter_vec.with_label_values(&labels.as_str_vec()).inc_by(value)
.with_label_values(&labels.as_str_vec())
.inc_by(value)
}); });
Ok(()) Ok(())
}) })
@ -77,8 +85,7 @@ impl RuntimeMetricsProvider {
pub fn inc_counter_by(&self, name: &str, value: u64) { pub fn inc_counter_by(&self, name: &str, value: u64) {
self.with_counters_lock_held(|mut hashmap| { self.with_counters_lock_held(|mut hashmap| {
hashmap hashmap.entry(name.to_owned())
.entry(name.to_owned())
.and_modify(|counter_vec| counter_vec.inc_by(value)); .and_modify(|counter_vec| counter_vec.inc_by(value));
Ok(()) Ok(())
}) })
@ -86,9 +93,8 @@ impl RuntimeMetricsProvider {
pub fn observe_histogram(&self, name: &str, value: u128) { pub fn observe_histogram(&self, name: &str, value: u128) {
self.with_histograms_lock_held(|mut hashmap| { self.with_histograms_lock_held(|mut hashmap| {
hashmap hashmap.entry(name.to_owned())
.entry(name.to_owned()) and_modify(|histogram| histogram.observe(value as f64 / 1_000_000_000.0));
.and_modify(|histogram| histogram.observe(value as f64 / 1_000_000_000.0));
Ok(()) Ok(())
}) })
} }
@ -97,36 +103,21 @@ impl RuntimeMetricsProvider {
where where
F: FnOnce(MutexGuard<'_, HashMap<String, Counter<U64>>>) -> Result<(), PrometheusError>, F: FnOnce(MutexGuard<'_, HashMap<String, Counter<U64>>>) -> Result<(), PrometheusError>,
{ {
let _ = self let _ = self.1.counters.lock().map(do_something).or_else(|error| Err(error));
.1
.counters
.lock()
.map(do_something)
.or_else(|error| Err(error));
} }
fn with_counter_vecs_lock_held<F>(&self, do_something: F) fn with_counter_vecs_lock_held<F>(&self, do_something: F)
where where
F: FnOnce(MutexGuard<'_, HashMap<String, CounterVec<U64>>>) -> Result<(), PrometheusError>, F: FnOnce(MutexGuard<'_, HashMap<String, CounterVec<U64>>>) -> Result<(), PrometheusError>,
{ {
let _ = self let _ = self.1.counter_vecs.lock().map(do_something).or_else(|error| Err(error));
.1
.counter_vecs
.lock()
.map(do_something)
.or_else(|error| Err(error));
} }
fn with_histograms_lock_held<F>(&self, do_something: F) fn with_histograms_lock_held<F>(&self, do_something: F)
where where
F: FnOnce(MutexGuard<'_, HashMap<String, Histogram>>) -> Result<(), PrometheusError>, F: FnOnce(MutexGuard<'_, HashMap<String, Histogram>>) -> Result<(), PrometheusError>,
{ {
let _ = self let _ = self.1.histograms.lock().map(do_something).or_else(|error| Err(error));
.1
.histograms
.lock()
.map(do_something)
.or_else(|error| Err(error));
} }
} }
@ -140,7 +131,7 @@ impl sc_tracing::TraceHandler for RuntimeMetricsProvider {
.unwrap_or(&String::default()) .unwrap_or(&String::default())
.ne("metrics") .ne("metrics")
{ {
return; return
} }
if let Some(update_op_bs58) = event.values.string_values.get("params") { if let Some(update_op_bs58) = event.values.string_values.get("params") {
@ -150,7 +141,7 @@ impl sc_tracing::TraceHandler for RuntimeMetricsProvider {
.as_slice(), .as_slice(),
) { ) {
Ok(update_op) => self.parse_metric_update(update_op), Ok(update_op) => self.parse_metric_update(update_op),
Err(_) => {} Err(_) => {},
} }
} }
} }
@ -159,15 +150,12 @@ impl sc_tracing::TraceHandler for RuntimeMetricsProvider {
impl RuntimeMetricsProvider { impl RuntimeMetricsProvider {
fn parse_metric_update(&self, update: RuntimeMetricUpdate) { fn parse_metric_update(&self, update: RuntimeMetricUpdate) {
match update.op { match update.op {
RuntimeMetricOp::IncrementCounterVec(value, ref labels) => { RuntimeMetricOp::IncrementCounterVec(value, ref labels) =>
self.inc_counter_vec_by(update.metric_name(), value, labels) self.inc_counter_vec_by(update.metric_name(), value, labels),
} RuntimeMetricOp::IncrementCounter(value) =>
RuntimeMetricOp::IncrementCounter(value) => { self.inc_counter_by(update.metric_name(), value),
self.inc_counter_by(update.metric_name(), value) RuntimeMetricOp::ObserveHistogram(value) =>
} self.observe_histogram(update.metric_name(), value),
RuntimeMetricOp::ObserveHistogram(value) => {
self.observe_histogram(update.metric_name(), value)
}
} }
} }
@ -190,7 +178,7 @@ impl RuntimeMetricsProvider {
pub fn logger_hook() -> impl FnOnce(&mut sc_cli::LoggerBuilder, &sc_service::Configuration) -> () { pub fn logger_hook() -> impl FnOnce(&mut sc_cli::LoggerBuilder, &sc_service::Configuration) -> () {
|logger_builder, config| { |logger_builder, config| {
if config.prometheus_registry().is_none() { if config.prometheus_registry().is_none() {
return; return
} }
let registry = config.prometheus_registry().cloned().unwrap(); let registry = config.prometheus_registry().cloned().unwrap();

View File

@ -1,5 +1,5 @@
use ghost_test_service::{node_config, run_validator_node, test_prometheus_config};
use hyper::{Client, Uri}; use hyper::{Client, Uri};
use ghost_test_service::{node_config, run_validator_node, test_prometheus_config};
use keyring::AccountKeyring::*; use keyring::AccountKeyring::*;
use std::collections::HashMap; use std::collections::HashMap;
@ -7,13 +7,8 @@ const DEFAULT_PROMETHEUS_PORT: u16 = 9616;
#[tokio::test(flavor = "multi_thread")] #[tokio::test(flavor = "multi_thread")]
async fn runtime_can_publish_metrics() { async fn runtime_can_publish_metrics() {
let mut alice_config = node_config( let mut alice_config =
|| {}, node_config(|| {}, tokio::runtime::Handle::current(), Alice, Vec::new(), true);
tokio::runtime::Handle::current(),
Alice,
Vec::new(),
true,
);
// Enable prometheus metrics for Alice. // Enable prometheus metrics for Alice.
alice_config.prometheus_config = Some(test_prometheus_config(DEFAULT_PROMETHEUS_PORT)); alice_config.prometheus_config = Some(test_prometheus_config(DEFAULT_PROMETHEUS_PORT));
@ -31,13 +26,8 @@ async fn runtime_can_publish_metrics() {
// Start validator Alice // Start validator Alice
let alice = run_validator_node(alice_config, None); let alice = run_validator_node(alice_config, None);
let bob_config = node_config( let bob_config =
|| {}, node_config(|| {}, tokio::runtime::Handle::current(), Bob, vec![alice.addr.clone()], true);
tokio::runtime::Handle::current(),
Bob,
vec![alice.addr.clone()],
true,
);
// Start validator Bob // Start validator Bob
let _bob = run_validator_node(bob_config, None); let _bob = run_validator_node(bob_config, None);
@ -58,25 +48,19 @@ async fn scrape_prometheus_metrics(metrics_uri: &str) -> HashMap<String, u64> {
.expect("GET request failed"); .expect("GET request failed");
let body = String::from_utf8( let body = String::from_utf8(
hyper::body::to_bytes(res) hyper::body::to_bytes(res).await.expect("can't get body as bytes").to_vec(),
.await ).expect("body is not an UTF8 string");
.expect("can't get body as bytes")
.to_vec(),
)
.expect("body is not an UTF8 string");
let lines: Vec<_> = body.lines().map(|s| Ok(s.to_owned())).collect(); let lines: Vec<_> = body.lines().map(|s| Ok(s.to_owned())).collect();
prometheus_parse::Scrape::parse(lines.into_iter()) prometheus_parse::Scrape::parse(lines.into_iter())
.expect("Scraper failed to parse Prometheus metrics") .expect("Scraper failed to parse Prometheus metrics")
.samples .samples
.into_iter() .into_iter()
.filter_map( .filter_map(|prometheus_parse::Sample { metric, value, .. }| match value {
|prometheus_parse::Sample { metric, value, .. }| match value {
prometheus_parse::Value::Counter(value) => Some((metric, value as u64)), prometheus_parse::Value::Counter(value) => Some((metric, value as u64)),
prometheus_parse::Value::Gauge(value) => Some((metric, value as u64)), prometheus_parse::Value::Gauge(value) => Some((metric, value as u64)),
prometheus_parse::Value::Untyped(value) => Some((metric, value as u64)), prometheus_parse::Value::Untyped(value) => Some((metric, value as u64)),
_ => None, _ => None,
}, })
)
.collect() .collect()
} }

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).
/// ///
@ -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>>;
@ -162,11 +159,7 @@ 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,
false
)
.is_ok(),
"error during adding and promotion" "error during adding and promotion"
); );
account_id account_id
@ -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)
} }
@ -250,15 +243,12 @@ 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)
@ -290,32 +280,20 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
)?; )?;
} }
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 => current_rank,
Some(current_rank) if current_rank < rank => { Some(current_rank) if current_rank < rank => {
for _ in 0..rank - current_rank { for _ in 0..rank - current_rank {
pallet_ranked_collective::Pallet::<T, I>::do_promote_member( pallet_ranked_collective::Pallet::<T, I>::do_promote_member(receiver.clone(), None, false)?;
receiver.clone(),
None,
false,
)?;
} }
rank rank
} },
_ => { _ => {
pallet_ranked_collective::Pallet::<T, I>::do_add_member_to_rank( pallet_ranked_collective::Pallet::<T, I>::do_add_member_to_rank(receiver.clone(), rank, false)?;
receiver.clone(),
rank,
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)

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,6 +66,7 @@ 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 =
@ -140,7 +79,8 @@ 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;

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
} }
@ -26,7 +25,10 @@ pub fn sig<T: Config<I>, I: 'static>(
&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() {
@ -56,8 +58,7 @@ fn small_claiming_works() {
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);
@ -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));
));
}) })
} }
@ -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);
@ -275,7 +263,8 @@ fn event_emitted_during_claim() {
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(
crate::Event::Claimed {
receiver: alice_account_id(), receiver: alice_account_id(),
donor: account, donor: account,
amount, amount,

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-networks" name = "ghost-networks"
version = "0.1.16" version = "0.1.2"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true
edition.workspace = true edition.workspace = true
@ -10,7 +10,6 @@ repository.workspace = true
[dependencies] [dependencies]
scale-info = { workspace = true, features = ["derive"] } scale-info = { workspace = true, features = ["derive"] }
codec = { workspace = true, features = ["max-encoded-len"] } codec = { workspace = true, features = ["max-encoded-len"] }
num-traits = { workspace = true }
frame-benchmarking = { workspace = true, optional = true } frame-benchmarking = { workspace = true, optional = true }
frame-support = { workspace = true } frame-support = { workspace = true }
@ -31,7 +30,6 @@ default = ["std"]
std = [ std = [
"scale-info/std", "scale-info/std",
"codec/std", "codec/std",
"num-traits/std",
"frame-support/std", "frame-support/std",
"frame-system/std", "frame-system/std",
"frame-benchmarking?/std", "frame-benchmarking?/std",
@ -52,6 +50,4 @@ runtime-benchmarks = [
try-runtime = [ try-runtime = [
"frame-support/try-runtime", "frame-support/try-runtime",
"frame-system/try-runtime", "frame-system/try-runtime",
"pallet-staking/try-runtime",
"pallet-balances/try-runtime",
] ]

View File

@ -8,44 +8,31 @@ 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,
finality_delay: Some(69),
release_delay: Some(69),
network_type: NetworkType::Evm, network_type: NetworkType::Evm,
finality_delay: 69,
rate_limit_delay: 69,
block_distance: 69,
incoming_fee: 0, incoming_fee: 0,
outgoing_fee: 0, outgoing_fee: 0,
}; };
@ -63,11 +50,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 +63,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 +79,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 +93,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 = Some(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())?;
@ -140,37 +120,23 @@ benchmarks! {
assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network); assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network);
} }
update_network_rate_limit_delay { update_network_release_delay {
let rate_limit = 1337; let delay = Some(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())?;
}: _<T::RuntimeOrigin>(authority, chain_id.clone(), rate_limit) }: _<T::RuntimeOrigin>(authority, chain_id.clone(), delay)
verify { verify {
assert_last_event::<T>(Event::NetworkRateLimitDelayUpdated { assert_last_event::<T>(Event::NetworkReleaseDelayUpdated {
chain_id: chain_id.clone(), rate_limit_delay: rate_limit, chain_id: chain_id.clone(), release_delay: delay,
}.into());
assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network);
}
update_network_block_distance {
let block_distance = 1337;
let (chain_id, network) = prepare_network::<T>(1, 1, 1);
let authority = T::UpdateOrigin::try_successful_origin()
.map_err(|_| BenchmarkError::Weightless)?;
let prev_network = create_network::<T>(chain_id.clone(), network.clone())?;
}: _<T::RuntimeOrigin>(authority, chain_id.clone(), block_distance)
verify {
assert_last_event::<T>(Event::NetworkBlockDistanceUpdated {
chain_id: chain_id.clone(), block_distance,
}.into()); }.into());
assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network); assert_ne!(GhostNetworks::<T>::networks(chain_id.clone()), prev_network);
} }
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 +151,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 +165,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 +179,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 +193,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 +206,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,29 +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::*;
use sp_std::convert::TryInto;
pub use ghost_traits::networks::{ pub use ghost_traits::networks::{
NetworkDataBasicHandler, NetworkDataInspectHandler, NetworkDataMutateHandler, NetworkDataBasicHandler, NetworkDataInspectHandler,
NetworkDataMutateHandler,
}; };
mod math;
mod weights; mod weights;
pub use crate::weights::WeightInfo;
use math::MulDiv;
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;
@ -35,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 {
@ -46,46 +45,32 @@ 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 finality_delay: Option<u64>,
pub release_delay: Option<u64>,
pub network_type: NetworkType, pub network_type: NetworkType,
pub finality_delay: u64,
pub rate_limit_delay: u64,
pub block_distance: u64,
pub incoming_fee: u32, pub incoming_fee: u32,
pub outgoing_fee: u32, pub outgoing_fee: u32,
} }
#[derive(Default, Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)] #[derive(Default, Encode, Decode, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo)]
pub struct BridgeAdjustment<Balance> { pub struct BridgeAdjustment<Balance> {
pub bridged_out: Balance, bridged_out: Balance,
pub bridged_in: Balance, bridged_in: 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 Balance: Default + AtLeast32BitUnsigned + Clone + Copy + From<u128>,
+ Copy
+ From<BalanceOf<T>>
+ AtLeast32BitUnsigned
+ num_traits::ops::wrapping::WrappingAdd
+ num_traits::ops::overflowing::OverflowingAdd
+ sp_std::ops::AddAssign
+ sp_std::ops::Not<Output = Balance>
+ sp_std::ops::Shl<Output = Balance>
+ sp_std::ops::Shr<Output = Balance>
+ sp_std::ops::BitAnd<Balance, Output = Balance>,
RewardCurve: Get<&'static PiecewiseLinear<'static>>, RewardCurve: Get<&'static PiecewiseLinear<'static>>,
T: Config, T: Config,
{ {
@ -94,27 +79,27 @@ where
total_issuance: Balance, total_issuance: Balance,
_era_duration_in_millis: u64, _era_duration_in_millis: u64,
) -> (Balance, Balance) { ) -> (Balance, Balance) {
let reward_curve = RewardCurve::get(); let piecewise_linear = RewardCurve::get();
let bridged_imbalance = BridgedImbalance::<T>::get(); let bridge_adjustment = BridgedImbalance::<T>::get();
let accumulated_commission = AccumulatedCommission::<T>::get(); let accumulated_commission = AccumulatedCommission::<T>::get();
let accumulated_commission: Balance = accumulated_commission.into(); let bridged_out: u128 = bridge_adjustment.bridged_out.try_into().unwrap_or_default();
let adjusted_issuance: Balance = total_issuance let bridged_in: u128 = bridge_adjustment.bridged_in.try_into().unwrap_or_default();
.saturating_add(bridged_imbalance.bridged_out.into()) let accumulated_commission: u128 = accumulated_commission.try_into().unwrap_or_default();
.saturating_sub(bridged_imbalance.bridged_in.into());
NullifyNeeded::<T>::set(true); let accumulated_balance = Balance::from(accumulated_commission);
let adjusted_issuance = match bridged_out > bridged_in {
true => total_issuance.saturating_add(Balance::from(bridged_out - bridged_in)),
false => total_issuance.saturating_sub(Balance::from(bridged_in - bridged_out)),
};
let estimated_reward = match piecewise_linear
reward_curve.calculate_for_fraction_times_denominator(total_staked, adjusted_issuance); .calculate_for_fraction_times_denominator(total_staked, adjusted_issuance)
let payout = MulDiv::<Balance>::calculate( .checked_mul(&accumulated_balance)
estimated_reward, .and_then(|product| product.checked_div(&adjusted_issuance)) {
accumulated_commission, Some(payout) => (payout, accumulated_balance.saturating_sub(payout)),
adjusted_issuance, None => (Balance::default(), Balance::default()),
); }
let rest_payout = accumulated_commission.saturating_sub(payout);
(payout, rest_payout)
} }
} }
@ -167,68 +152,19 @@ 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: Option<u64> },
NetworkNameUpdated { NetworkReleaseDelayUpdated { chain_id: T::NetworkId, release_delay: Option<u64> },
chain_id: T::NetworkId, NetworkTypeUpdated { chain_id: T::NetworkId, network_type: NetworkType },
chain_name: Vec<u8>, NetworkGatekeeperUpdated { chain_id: T::NetworkId, gatekeeper: Vec<u8> },
}, NetworkTopicNameUpdated { chain_id: T::NetworkId, topic_name: Vec<u8> },
NetworkEndpointUpdated { NetworkIncomingFeeUpdated { chain_id: T::NetworkId, incoming_fee: u32 },
chain_id: T::NetworkId, NetworkOutgoingFeeUpdated { chain_id: T::NetworkId, outgoing_fee: u32 },
index: u32, NetworkRemoved { chain_id: T::NetworkId },
endpoint: Vec<u8>,
},
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::getter(fn nullify_needed)]
pub type NullifyNeeded<T: Config> = StorageValue<_, bool, ValueQuery>;
#[pallet::storage] #[pallet::storage]
#[pallet::getter(fn bridged_imbalance)] #[pallet::getter(fn bridged_imbalance)]
pub type BridgedImbalance<T: Config> = pub type BridgedImbalance<T: Config> =
@ -236,7 +172,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)]
@ -245,8 +182,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> {
@ -263,10 +205,9 @@ 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");
@ -280,30 +221,14 @@ pub mod module {
pub struct Pallet<T>(PhantomData<T>); pub struct Pallet<T>(PhantomData<T>);
#[pallet::hooks] #[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> { impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {}
fn on_initialize(_: BlockNumberFor<T>) -> Weight {
T::DbWeight::get().reads_writes(1, 1)
}
fn on_finalize(_: BlockNumberFor<T>) {
if Self::nullify_needed() {
Self::nullify_commission();
NullifyNeeded::<T>::put(false);
}
}
}
#[pallet::call] #[pallet::call]
impl<T: Config> Pallet<T> { impl<T: Config> Pallet<T> {
#[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())
.max()
.unwrap_or_default() as u32,
network.default_endpoints.len() as u32,
))] ))]
pub fn register_network( pub fn register_network(
origin: OriginFor<T>, origin: OriginFor<T>,
@ -324,24 +249,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)]
@ -349,35 +276,30 @@ pub mod module {
pub fn update_network_finality_delay( pub fn update_network_finality_delay(
origin: OriginFor<T>, origin: OriginFor<T>,
chain_id: T::NetworkId, chain_id: T::NetworkId,
finality_delay: u64, finality_delay: Option<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)]
#[pallet::weight(T::WeightInfo::update_network_rate_limit_delay())] #[pallet::weight(T::WeightInfo::update_network_release_delay())]
pub fn update_network_rate_limit_delay( pub fn update_network_release_delay(
origin: OriginFor<T>, origin: OriginFor<T>,
chain_id: T::NetworkId, chain_id: T::NetworkId,
rate_limit_delay: u64, release_delay: Option<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_release_delay(
chain_id,
release_delay,
)
} }
#[pallet::call_index(5)] #[pallet::call_index(5)]
#[pallet::weight(T::WeightInfo::update_network_block_distance())]
pub fn update_network_block_distance(
origin: OriginFor<T>,
chain_id: T::NetworkId,
block_distance: u64,
) -> DispatchResult {
T::UpdateOrigin::ensure_origin_or_root(origin)?;
Self::do_update_network_block_distance(chain_id, block_distance)
}
#[pallet::call_index(6)]
#[pallet::weight(T::WeightInfo::update_network_type())] #[pallet::weight(T::WeightInfo::update_network_type())]
pub fn update_network_type( pub fn update_network_type(
origin: OriginFor<T>, origin: OriginFor<T>,
@ -385,10 +307,13 @@ 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(6)]
#[pallet::weight(T::WeightInfo::update_network_gatekeeper())] #[pallet::weight(T::WeightInfo::update_network_gatekeeper())]
pub fn update_network_gatekeeper( pub fn update_network_gatekeeper(
origin: OriginFor<T>, origin: OriginFor<T>,
@ -396,10 +321,13 @@ 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(7)]
#[pallet::weight(T::WeightInfo::update_network_topic_name())] #[pallet::weight(T::WeightInfo::update_network_topic_name())]
pub fn update_network_topic_name( pub fn update_network_topic_name(
origin: OriginFor<T>, origin: OriginFor<T>,
@ -407,10 +335,13 @@ 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(8)]
#[pallet::weight(T::WeightInfo::update_incoming_network_fee())] #[pallet::weight(T::WeightInfo::update_incoming_network_fee())]
pub fn update_incoming_network_fee( pub fn update_incoming_network_fee(
origin: OriginFor<T>, origin: OriginFor<T>,
@ -418,10 +349,13 @@ 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(9)]
#[pallet::weight(T::WeightInfo::update_outgoing_network_fee())] #[pallet::weight(T::WeightInfo::update_outgoing_network_fee())]
pub fn update_outgoing_network_fee( pub fn update_outgoing_network_fee(
origin: OriginFor<T>, origin: OriginFor<T>,
@ -429,12 +363,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(10)]
#[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)
} }
@ -443,12 +383,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(())
})?; })?;
@ -470,7 +410,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();
@ -489,45 +432,26 @@ 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(())
} }
/// Update existent network default finality delay. /// Update existent network default endpoint.
pub fn do_update_network_finality_delay( pub fn do_update_network_finality_delay(
chain_id: T::NetworkId, chain_id: T::NetworkId,
finality_delay: u64, finality_delay: Option<u64>,
) -> 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);
@ -543,40 +467,21 @@ impl<T: Config> Pallet<T> {
Ok(()) Ok(())
} }
/// Update existent network default rate limit delay. /// Update existent network default endpoint.
pub fn do_update_network_rate_limit_delay( pub fn do_update_network_release_delay(
chain_id: T::NetworkId, chain_id: T::NetworkId,
rate_limit_delay: u64, release_delay: Option<u64>,
) -> 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.rate_limit_delay = rate_limit_delay; net.release_delay = release_delay;
*maybe_network = Some(net.clone()); *maybe_network = Some(net.clone());
Ok(()) Ok(())
})?; })?;
Self::deposit_event(Event::<T>::NetworkRateLimitDelayUpdated { Self::deposit_event(Event::<T>::NetworkReleaseDelayUpdated {
chain_id, chain_id,
rate_limit_delay, release_delay,
});
Ok(())
}
/// Update existent network default max distance between blocks.
pub fn do_update_network_block_distance(
chain_id: T::NetworkId,
block_distance: u64,
) -> DispatchResult {
Networks::<T>::try_mutate(&chain_id, |maybe_network| -> DispatchResult {
ensure!(maybe_network.is_some(), Error::<T>::NetworkDoesNotExist);
let net = maybe_network.as_mut().unwrap();
net.block_distance = block_distance;
*maybe_network = Some(net.clone());
Ok(())
})?;
Self::deposit_event(Event::<T>::NetworkBlockDistanceUpdated {
chain_id,
block_distance,
}); });
Ok(()) Ok(())
} }
@ -605,10 +510,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();
@ -628,10 +531,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();
@ -695,10 +596,6 @@ impl<T: Config> NetworkDataInspectHandler<NetworkData> for Pallet<T> {
fn iter() -> PrefixIterator<(Self::NetworkId, NetworkData)> { fn iter() -> PrefixIterator<(Self::NetworkId, NetworkData)> {
Networks::<T>::iter() Networks::<T>::iter()
} }
fn is_nullification_period() -> bool {
NullifyNeeded::<T>::get()
}
} }
impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T> { impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T> {
@ -713,65 +610,55 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
fn increase_gatekeeper_amount( fn increase_gatekeeper_amount(
network_id: &T::NetworkId, network_id: &T::NetworkId,
amount: &BalanceOf<T>, amount: &BalanceOf<T>,
) -> Result<BalanceOf<T>, ()> { ) -> Result<(BalanceOf<T>, BalanceOf<T>), ()> {
let new_gatekeeper_amount =
GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| match gatekeeper_amount
.checked_add(amount)
{
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
}
None => Err(()),
})?;
Ok(new_gatekeeper_amount)
}
fn decrease_gatekeeper_amount(
network_id: &T::NetworkId,
amount: &BalanceOf<T>,
) -> Result<BalanceOf<T>, ()> {
let new_gatekeeper_amount =
GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| match gatekeeper_amount
.checked_sub(amount)
{
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
}
None => Err(()),
})?;
Ok(new_gatekeeper_amount)
}
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(()),
}
})?;
Ok(new_bridged_out_amount)
}
fn accumulate_incoming_imbalance(amount: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
let new_bridged_in_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| { let new_bridged_in_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
match bridged_imbalance.bridged_in.checked_add(amount) { match bridged_imbalance.bridged_in.checked_add(amount) {
Some(value) => { Some(value) => {
(*bridged_imbalance).bridged_in = value; (*bridged_imbalance).bridged_in = value;
Ok(value) Ok(value)
} },
None => Err(()), None => Err(())
} }
})?; })?;
Ok(new_bridged_in_amount) let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
match gatekeeper_amount.checked_add(amount) {
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
},
None => Err(())
}
})?;
Ok((new_gatekeeper_amount, new_bridged_in_amount))
}
fn decrease_gatekeeper_amount(
network_id: &T::NetworkId,
amount: &BalanceOf<T>,
) -> Result<(BalanceOf<T>, BalanceOf<T>), ()> {
let new_gatekeeper_amount = GatekeeperAmount::<T>::mutate(network_id, |gatekeeper_amount| {
match gatekeeper_amount.checked_sub(amount) {
Some(value) => {
*gatekeeper_amount = value;
Ok(value)
},
None => Err(())
}
})?;
let new_bridged_out_amount = BridgedImbalance::<T>::mutate(|bridged_imbalance| {
match bridged_imbalance.bridged_out.checked_add(amount) {
Some(value) => {
(*bridged_imbalance).bridged_out = value;
Ok(value)
},
None => Err(())
}
})?;
Ok((new_gatekeeper_amount, new_bridged_out_amount))
} }
fn accumulate_commission(commission: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> { fn accumulate_commission(commission: &BalanceOf<T>) -> Result<BalanceOf<T>, ()> {
@ -780,7 +667,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(()),
} }
}) })
@ -788,15 +675,5 @@ impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T
fn nullify_commission() { fn nullify_commission() {
AccumulatedCommission::<T>::set(Default::default()); AccumulatedCommission::<T>::set(Default::default());
BridgedImbalance::<T>::set(Default::default());
}
fn trigger_nullification() {
if NullifyNeeded::<T>::get() {
Self::nullify_commission();
NullifyNeeded::<T>::put(false);
} else {
NullifyNeeded::<T>::put(true);
}
} }
} }

View File

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

View File

@ -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

@ -15,14 +15,14 @@
//! Autogenerated weights for `ghost_networks` //! Autogenerated weights for `ghost_networks`
//! //!
//! 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 4.0.0-dev
//! DATE: 2025-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! DATE: 2023-11-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000` //! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz` //! HOSTNAME: `ghost`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024 //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("casper-dev"), DB CACHE: 1024
// Executed Command: // Executed Command:
// ./target/release/ghost // ./target/production/ghost
// benchmark // benchmark
// pallet // pallet
// --chain=casper-dev // --chain=casper-dev
@ -30,8 +30,8 @@
// --repeat=20 // --repeat=20
// --pallet=ghost_networks // --pallet=ghost_networks
// --extrinsic=* // --extrinsic=*
// --execution=wasm
// --wasm-execution=compiled // --wasm-execution=compiled
// --heap-pages=4096
// --header=./file_header.txt // --header=./file_header.txt
// --output=./runtime/casper/src/weights/ghost_networks.rs // --output=./runtime/casper/src/weights/ghost_networks.rs
@ -49,12 +49,11 @@ use sp_std::marker::PhantomData;
/// Weight functions needed for ghost_networks /// Weight functions needed for ghost_networks
pub trait WeightInfo { pub trait WeightInfo {
fn register_network(i: u32, j: u32, k: u32, ) -> Weight; fn register_network(n: u32, m: u32, ) -> Weight;
fn update_network_name(n: u32, ) -> Weight; fn update_network_name(n: u32, ) -> Weight;
fn update_network_endpoint(n: u32, ) -> Weight; fn update_network_endpoint(n: u32, ) -> Weight;
fn update_network_finality_delay() -> Weight; fn update_network_finality_delay() -> Weight;
fn update_network_rate_limit_delay() -> Weight; fn update_network_release_delay() -> Weight;
fn update_network_block_distance() -> Weight;
fn update_network_type() -> Weight; fn update_network_type() -> Weight;
fn update_network_gatekeeper() -> Weight; fn update_network_gatekeeper() -> Weight;
fn update_network_topic_name() -> Weight; fn update_network_topic_name() -> Weight;
@ -66,316 +65,260 @@ pub trait WeightInfo {
/// Weight for ghost_networks using the Substrate node and recommended hardware. /// Weight for ghost_networks using the Substrate node and recommended hardware.
pub struct SubstrateWeight<T>(PhantomData<T>); pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> { impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
/// The range of component `i` is `[1, 20]`.
/// The range of component `j` is `[1, 150]`.
/// The range of component `k` is `[1, 20]`.
fn register_network(_i: u32, _j: u32, k: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `109`
// Estimated: `3574`
// Minimum execution time: 46_023_000 picoseconds.
Weight::from_parts(97_871_287, 0)
.saturating_add(Weight::from_parts(0, 3574))
// Standard Error: 94_524
.saturating_add(Weight::from_parts(940_486, 0).saturating_mul(k.into()))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// The range of component `n` is `[1, 20]`. /// The range of component `n` is `[1, 20]`.
fn update_network_name(n: u32, ) -> Weight { /// The range of component `m` is `[1, 150]`.
fn register_network(_n: u32, _m: u32, ) -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `76`
// Estimated: `3767` // Estimated: `2551`
// Minimum execution time: 49_906_000 picoseconds. // Minimum execution time: 32_086 nanoseconds.
Weight::from_parts(55_537_587, 0) Weight::from_parts(33_092_855, 2551)
.saturating_add(Weight::from_parts(0, 3767))
// Standard Error: 87_704
.saturating_add(Weight::from_parts(92_366, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
/// The range of component `n` is `[1, 20]`.
fn update_network_name(_n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `141`
// Estimated: `2616`
// Minimum execution time: 34_496 nanoseconds.
Weight::from_parts(35_728_230, 2616)
// Standard Error: 2_591
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: GhostNetworks Networks (r:1 w:1)
/// Proof Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
/// The range of component `n` is `[1, 150]`. /// The range of component `n` is `[1, 150]`.
fn update_network_endpoint(n: u32, ) -> Weight { fn update_network_endpoint(_n: u32, ) -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 50_556_000 picoseconds. // Minimum execution time: 34_666 nanoseconds.
Weight::from_parts(57_726_674, 0) Weight::from_parts(35_959_961, 2616)
.saturating_add(Weight::from_parts(0, 3767)) // Standard Error: 381
// Standard Error: 12_261
.saturating_add(Weight::from_parts(274, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_network_finality_delay() -> Weight { fn update_network_finality_delay() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 49_406_000 picoseconds. // Minimum execution time: 33_860 nanoseconds.
Weight::from_parts(51_256_000, 0) Weight::from_parts(34_995_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_network_rate_limit_delay() -> Weight { fn update_network_release_delay() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 49_572_000 picoseconds. // Minimum execution time: 33_860 nanoseconds.
Weight::from_parts(52_584_000, 0) Weight::from_parts(34_995_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_network_block_distance() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 48_880_000 picoseconds.
Weight::from_parts(50_596_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_type() -> Weight { fn update_network_type() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 48_282_000 picoseconds. // Minimum execution time: 34_976 nanoseconds.
Weight::from_parts(49_137_000, 0) Weight::from_parts(36_182_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_network_gatekeeper() -> Weight { fn update_network_gatekeeper() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 50_853_000 picoseconds. // Minimum execution time: 34_768 nanoseconds.
Weight::from_parts(51_982_000, 0) Weight::from_parts(35_580_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_network_topic_name() -> Weight { fn update_network_topic_name() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 50_343_000 picoseconds. // Minimum execution time: 34_768 nanoseconds.
Weight::from_parts(52_380_000, 0) Weight::from_parts(35_580_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_incoming_network_fee() -> Weight { fn update_incoming_network_fee() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 49_393_000 picoseconds. // Minimum execution time: 34_768 nanoseconds.
Weight::from_parts(80_966_000, 0) Weight::from_parts(35_580_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_outgoing_network_fee() -> Weight { fn update_outgoing_network_fee() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 49_579_000 picoseconds. // Minimum execution time: 34_768 nanoseconds.
Weight::from_parts(51_126_000, 0) Weight::from_parts(35_580_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn remove_network() -> Weight { fn remove_network() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 44_634_000 picoseconds. // Minimum execution time: 33_336 nanoseconds.
Weight::from_parts(45_815_000, 0) Weight::from_parts(34_609_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
} }
impl WeightInfo for () { 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
/// The range of component `i` is `[1, 20]`.
/// The range of component `j` is `[1, 150]`.
/// The range of component `k` is `[1, 20]`.
fn register_network(_i: u32, _j: u32, k: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `109`
// Estimated: `3574`
// Minimum execution time: 46_023_000 picoseconds.
Weight::from_parts(97_871_287, 0)
.saturating_add(Weight::from_parts(0, 3574))
// Standard Error: 94_524
.saturating_add(Weight::from_parts(940_486, 0).saturating_mul(k.into()))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
/// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// The range of component `n` is `[1, 20]`. /// The range of component `n` is `[1, 20]`.
fn update_network_name(n: u32, ) -> Weight { /// The range of component `m` is `[1, 150]`.
fn register_network(_n: u32, _m: u32, ) -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `76`
// Estimated: `3767` // Estimated: `2551`
// Minimum execution time: 49_906_000 picoseconds. // Minimum execution time: 32_086 nanoseconds.
Weight::from_parts(55_537_587, 0) Weight::from_parts(33_092_855, 2551)
.saturating_add(Weight::from_parts(0, 3767))
// Standard Error: 87_704
.saturating_add(Weight::from_parts(92_366, 0).saturating_mul(n.into()))
.saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1)) .saturating_add(RocksDbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
/// The range of component `n` is `[1, 20]`.
fn update_network_name(_n: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `141`
// Estimated: `2616`
// Minimum execution time: 34_496 nanoseconds.
Weight::from_parts(35_728_230, 2616)
// Standard Error: 2_591
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
/// Storage: GhostNetworks Networks (r:1 w:1)
/// Proof Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
/// The range of component `n` is `[1, 150]`. /// The range of component `n` is `[1, 150]`.
fn update_network_endpoint(n: u32, ) -> Weight { fn update_network_endpoint(_n: u32, ) -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 50_556_000 picoseconds. // Minimum execution time: 34_666 nanoseconds.
Weight::from_parts(57_726_674, 0) Weight::from_parts(35_959_961, 2616)
.saturating_add(Weight::from_parts(0, 3767)) // Standard Error: 381
// Standard Error: 12_261
.saturating_add(Weight::from_parts(274, 0).saturating_mul(n.into()))
.saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1)) .saturating_add(RocksDbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_network_finality_delay() -> Weight { fn update_network_finality_delay() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 49_406_000 picoseconds. // Minimum execution time: 33_860 nanoseconds.
Weight::from_parts(51_256_000, 0) Weight::from_parts(34_995_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1)) .saturating_add(RocksDbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_network_rate_limit_delay() -> Weight { fn update_network_release_delay() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 49_572_000 picoseconds. // Minimum execution time: 33_860 nanoseconds.
Weight::from_parts(52_584_000, 0) Weight::from_parts(34_995_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1)) .saturating_add(RocksDbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_network_block_distance() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 48_880_000 picoseconds.
Weight::from_parts(50_596_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1))
}
/// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_type() -> Weight { fn update_network_type() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 48_282_000 picoseconds. // Minimum execution time: 34_976 nanoseconds.
Weight::from_parts(49_137_000, 0) Weight::from_parts(36_182_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1)) .saturating_add(RocksDbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_network_gatekeeper() -> Weight { fn update_network_gatekeeper() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 50_853_000 picoseconds. // Minimum execution time: 34_768 nanoseconds.
Weight::from_parts(51_982_000, 0) Weight::from_parts(35_580_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1)) .saturating_add(RocksDbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_network_topic_name() -> Weight { fn update_network_topic_name() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 50_343_000 picoseconds. // Minimum execution time: 34_768 nanoseconds.
Weight::from_parts(52_380_000, 0) Weight::from_parts(35_580_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1)) .saturating_add(RocksDbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_incoming_network_fee() -> Weight { fn update_incoming_network_fee() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 49_393_000 picoseconds. // Minimum execution time: 34_768 nanoseconds.
Weight::from_parts(80_966_000, 0) Weight::from_parts(35_580_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1)) .saturating_add(RocksDbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn update_outgoing_network_fee() -> Weight { fn update_outgoing_network_fee() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 49_579_000 picoseconds. // Minimum execution time: 34_768 nanoseconds.
Weight::from_parts(51_126_000, 0) Weight::from_parts(35_580_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1)) .saturating_add(RocksDbWeight::get().writes(1))
} }
/// 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 Skipped: GhostNetworks Networks (max_values: None, max_size: None, mode: Measured)
fn remove_network() -> Weight { fn remove_network() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `141`
// Estimated: `3767` // Estimated: `2616`
// Minimum execution time: 44_634_000 picoseconds. // Minimum execution time: 33_336 nanoseconds.
Weight::from_parts(45_815_000, 0) Weight::from_parts(34_609_000, 2616)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().reads(1))
.saturating_add(RocksDbWeight::get().writes(1)) .saturating_add(RocksDbWeight::get().writes(1))
} }

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

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-slow-clap" name = "ghost-slow-clap"
version = "0.3.40" version = "0.3.15"
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
@ -27,13 +27,11 @@ sp-staking = { workspace = true }
sp-io = { workspace = true } sp-io = { workspace = true }
sp-std = { workspace = true } sp-std = { workspace = true }
pallet-balances = { workspace = true }
ghost-networks = { workspace = true } ghost-networks = { workspace = true }
[dev-dependencies] [dev-dependencies]
pallet-balances = { workspace = true } pallet-session = { workspace = true, default-features = true }
pallet-session = { workspace = true }
pallet-staking = { workspace = true }
pallet-staking-reward-curve = { workspace = true }
[features] [features]
default = ["std"] default = ["std"]
@ -51,7 +49,6 @@ std = [
"sp-io/std", "sp-io/std",
"sp-std/std", "sp-std/std",
"pallet-session/std", "pallet-session/std",
"pallet-staking/std",
"pallet-balances/std", "pallet-balances/std",
"ghost-networks/std", "ghost-networks/std",
] ]

View File

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

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
}
}

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,176 +1,18 @@
// This file is part of Ghost Network. use frame_support::weights::Weight;
// 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_slow_clap`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 32.0.0
//! DATE: 2025-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! 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_slow_clap
// --extrinsic=*
// --wasm-execution=compiled
// --heap-pages=4096
// --header=./file_header.txt
// --output=./runtime/casper/src/weights/ghost_slow_clap.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;
pub trait WeightInfo { pub trait WeightInfo {
fn slow_clap() -> Weight; fn slow_clap(claps_len: u32, companions_len: u32) -> Weight;
fn self_applause()-> Weight; fn propose_companion() -> Weight;
} fn release_companion() -> Weight;
fn kill_companion() -> Weight;
/// Weight functions for `ghost_slow_clap`.
pub struct SubstrateWeight<T>(PhantomData<T>);
impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
/// Storage: `GhostSlowClaps::Authorities` (r:1 w:0)
/// Proof: `GhostSlowClaps::Authorities` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ReceivedClaps` (r:1 w:1)
/// Proof: `GhostSlowClaps::ReceivedClaps` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ClapsInSession` (r:1 w:1)
/// Proof: `GhostSlowClaps::ClapsInSession` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ApplausesForTransaction` (r:1 w:1)
/// Proof: `GhostSlowClaps::ApplausesForTransaction` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::NullifyNeeded` (r:1 w:0)
/// Proof: `GhostNetworks::NullifyNeeded` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::GatekeeperAmount` (r:1 w:1)
/// Proof: `GhostNetworks::GatekeeperAmount` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::BridgedImbalance` (r:1 w:1)
/// Proof: `GhostNetworks::BridgedImbalance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::AccumulatedCommission` (r:1 w:1)
/// Proof: `GhostNetworks::AccumulatedCommission` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn slow_clap() -> Weight {
// Proof Size summary in bytes:
// Measured: `355`
// Estimated: `3820`
// Minimum execution time: 213_817_000 picoseconds.
Weight::from_parts(216_977_000, 0)
.saturating_add(Weight::from_parts(0, 3820))
.saturating_add(T::DbWeight::get().reads(10))
.saturating_add(T::DbWeight::get().writes(7))
}
/// Storage: `GhostSlowClaps::ReceivedClaps` (r:1 w:0)
/// Proof: `GhostSlowClaps::ReceivedClaps` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::Authorities` (r:1 w:0)
/// Proof: `GhostSlowClaps::Authorities` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ApplausesForTransaction` (r:1 w:1)
/// Proof: `GhostSlowClaps::ApplausesForTransaction` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::NullifyNeeded` (r:1 w:0)
/// Proof: `GhostNetworks::NullifyNeeded` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::GatekeeperAmount` (r:1 w:1)
/// Proof: `GhostNetworks::GatekeeperAmount` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::BridgedImbalance` (r:1 w:1)
/// Proof: `GhostNetworks::BridgedImbalance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::AccumulatedCommission` (r:1 w:1)
/// Proof: `GhostNetworks::AccumulatedCommission` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn self_applause() -> Weight {
// Proof Size summary in bytes:
// Measured: `655`
// Estimated: `4120`
// Minimum execution time: 210_676_000 picoseconds.
Weight::from_parts(212_905_000, 0)
.saturating_add(Weight::from_parts(0, 4120))
.saturating_add(T::DbWeight::get().reads(9))
.saturating_add(T::DbWeight::get().writes(5))
}
} }
impl WeightInfo for () { impl WeightInfo for () {
/// Storage: `GhostSlowClaps::Authorities` (r:1 w:0) fn slow_clap(
/// Proof: `GhostSlowClaps::Authorities` (`max_values`: None, `max_size`: None, mode: `Measured`) _claps_len: u32,
/// Storage: `GhostSlowClaps::ReceivedClaps` (r:1 w:1) _companions_len: u32,
/// Proof: `GhostSlowClaps::ReceivedClaps` (`max_values`: None, `max_size`: None, mode: `Measured`) ) -> Weight { Weight::zero() }
/// Storage: `GhostSlowClaps::ClapsInSession` (r:1 w:1) fn propose_companion() -> Weight { Weight::zero() }
/// Proof: `GhostSlowClaps::ClapsInSession` (`max_values`: None, `max_size`: None, mode: `Measured`) fn release_companion() -> Weight { Weight::zero() }
/// Storage: `GhostSlowClaps::ApplausesForTransaction` (r:1 w:1) fn kill_companion() -> Weight { Weight::zero() }
/// Proof: `GhostSlowClaps::ApplausesForTransaction` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::NullifyNeeded` (r:1 w:0)
/// Proof: `GhostNetworks::NullifyNeeded` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::GatekeeperAmount` (r:1 w:1)
/// Proof: `GhostNetworks::GatekeeperAmount` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::BridgedImbalance` (r:1 w:1)
/// Proof: `GhostNetworks::BridgedImbalance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::AccumulatedCommission` (r:1 w:1)
/// Proof: `GhostNetworks::AccumulatedCommission` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn slow_clap() -> Weight {
// Proof Size summary in bytes:
// Measured: `355`
// Estimated: `3820`
// Minimum execution time: 213_817_000 picoseconds.
Weight::from_parts(216_977_000, 0)
.saturating_add(Weight::from_parts(0, 3820))
.saturating_add(RocksDbWeight::get().reads(10))
.saturating_add(RocksDbWeight::get().writes(7))
}
/// Storage: `GhostSlowClaps::ReceivedClaps` (r:1 w:0)
/// Proof: `GhostSlowClaps::ReceivedClaps` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::Authorities` (r:1 w:0)
/// Proof: `GhostSlowClaps::Authorities` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ApplausesForTransaction` (r:1 w:1)
/// Proof: `GhostSlowClaps::ApplausesForTransaction` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::NullifyNeeded` (r:1 w:0)
/// Proof: `GhostNetworks::NullifyNeeded` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::GatekeeperAmount` (r:1 w:1)
/// Proof: `GhostNetworks::GatekeeperAmount` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::BridgedImbalance` (r:1 w:1)
/// Proof: `GhostNetworks::BridgedImbalance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::AccumulatedCommission` (r:1 w:1)
/// Proof: `GhostNetworks::AccumulatedCommission` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn self_applause() -> Weight {
// Proof Size summary in bytes:
// Measured: `655`
// Estimated: `4120`
// Minimum execution time: 210_676_000 picoseconds.
Weight::from_parts(212_905_000, 0)
.saturating_add(Weight::from_parts(0, 4120))
.saturating_add(RocksDbWeight::get().reads(9))
.saturating_add(RocksDbWeight::get().writes(5))
}
} }

View File

@ -1,45 +0,0 @@
[package]
name = "ghost-sudo"
version = "0.0.2"
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,77 +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,212 +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,127 +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,217 +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.19"
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 {
@ -18,7 +21,6 @@ pub trait NetworkDataBasicHandler {
pub trait NetworkDataInspectHandler<Network>: NetworkDataBasicHandler { pub trait NetworkDataInspectHandler<Network>: NetworkDataBasicHandler {
fn get(n: &Self::NetworkId) -> Option<Network>; fn get(n: &Self::NetworkId) -> Option<Network>;
fn iter() -> PrefixIterator<(Self::NetworkId, Network)>; fn iter() -> PrefixIterator<(Self::NetworkId, Network)>;
fn is_nullification_period() -> bool;
} }
pub trait NetworkDataMutateHandler<Network, Balance>: NetworkDataInspectHandler<Network> { pub trait NetworkDataMutateHandler<Network, Balance>: NetworkDataInspectHandler<Network> {
@ -28,16 +30,11 @@ pub trait NetworkDataMutateHandler<Network, Balance>: NetworkDataInspectHandler<
fn increase_gatekeeper_amount( fn increase_gatekeeper_amount(
chain_id: &Self::NetworkId, chain_id: &Self::NetworkId,
amount: &Balance, amount: &Balance,
) -> Result<Balance, ()>; ) -> Result<(Balance, Balance), ()>;
fn decrease_gatekeeper_amount( fn decrease_gatekeeper_amount(
chain_id: &Self::NetworkId, chain_id: &Self::NetworkId,
amount: &Balance, amount: &Balance,
) -> Result<Balance, ()>; ) -> Result<(Balance, Balance), ()>;
fn accumulate_outgoing_imbalance(amount: &Balance) -> Result<Balance, ()>;
fn accumulate_incoming_imbalance(amount: &Balance) -> Result<Balance, ()>;
fn accumulate_commission(commission: &Balance) -> Result<Balance, ()>; fn accumulate_commission(commission: &Balance) -> Result<Balance, ()>;
fn nullify_commission(); fn nullify_commission();
fn trigger_nullification();
} }

View File

@ -1,15 +1,17 @@
use std::sync::Arc; use std::sync::Arc;
use babe_primitives::BabeApi;
use block_builder_api::BlockBuilder;
use consensus_common::SelectChain;
use grandpa::FinalityProofProvider;
use jsonrpsee::RpcModule; use jsonrpsee::RpcModule;
use primitives::{AccountId, Balance, Block, BlockNumber, Hash, Nonce}; use primitives::{
AccountId, Balance, Block, BlockNumber, Hash, Nonce,
};
use sc_client_api::AuxStore; use sc_client_api::AuxStore;
use grandpa::FinalityProofProvider;
pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor}; pub use sc_rpc::{DenyUnsafe, SubscriptionTaskExecutor};
use sp_api::ProvideRuntimeApi; use sp_api::ProvideRuntimeApi;
use block_builder_api::BlockBuilder;
use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata}; use sp_blockchain::{Error as BlockChainError, HeaderBackend, HeaderMetadata};
use consensus_common::SelectChain;
use babe_primitives::BabeApi;
use sp_keystore::KeystorePtr; use sp_keystore::KeystorePtr;
use tx_pool_api::TransactionPool; use tx_pool_api::TransactionPool;
@ -59,16 +61,7 @@ pub struct FullDeps<C, P, SC, B> {
} }
pub fn create_full_rpc<C, P, SC, B>( pub fn create_full_rpc<C, P, SC, B>(
FullDeps { FullDeps { client, pool, select_chain, chain_spec, deny_unsafe, babe, grandpa, backend } : FullDeps<C, P, SC, B>,
client,
pool,
select_chain,
chain_spec,
deny_unsafe,
babe,
grandpa,
backend,
}: FullDeps<C, P, SC, B>,
) -> Result<RpcExtension, Box<dyn std::error::Error + Send + Sync>> ) -> Result<RpcExtension, Box<dyn std::error::Error + Send + Sync>>
where where
C: ProvideRuntimeApi<Block> C: ProvideRuntimeApi<Block>
@ -87,19 +80,20 @@ where
B: sc_client_api::Backend<Block> + Send + Sync + 'static, B: sc_client_api::Backend<Block> + Send + Sync + 'static,
B::State: sc_client_api::StateBackend<sp_runtime::traits::HashingFor<Block>>, B::State: sc_client_api::StateBackend<sp_runtime::traits::HashingFor<Block>>,
{ {
use babe_rpc::{Babe, BabeApiServer};
use frame_rpc_system::{System, SystemApiServer}; use frame_rpc_system::{System, SystemApiServer};
use pallet_transaction_payment_rpc::{
TransactionPayment, TransactionPaymentApiServer,
};
use babe_rpc::{Babe, BabeApiServer};
use grandpa_rpc::{Grandpa, GrandpaApiServer}; use grandpa_rpc::{Grandpa, GrandpaApiServer};
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
use sc_rpc_spec_v2::chain_spec::{ChainSpec, ChainSpecApiServer}; use sc_rpc_spec_v2::chain_spec::{ChainSpec, ChainSpecApiServer};
use sc_sync_state_rpc::{SyncState, SyncStateApiServer}; use sc_sync_state_rpc::{SyncState, SyncStateApiServer};
use substrate_state_trie_migration_rpc::{StateMigration, StateMigrationApiServer}; use substrate_state_trie_migration_rpc::{
StateMigration, StateMigrationApiServer,
};
let mut io = RpcModule::new(()); let mut io = RpcModule::new(());
let BabeDeps { let BabeDeps { babe_worker_handle, keystore } = babe;
babe_worker_handle,
keystore,
} = babe;
let GrandpaDeps { let GrandpaDeps {
shared_voter_state, shared_voter_state,
shared_authority_set, shared_authority_set,
@ -109,13 +103,10 @@ where
} = grandpa; } = grandpa;
let chain_name = chain_spec.name().to_string(); let chain_name = chain_spec.name().to_string();
let genesis_hash = client let genesis_hash = client.hash(0).ok().flatten().expect("Genesis block exists; qed;");
.hash(0)
.ok()
.flatten()
.expect("Genesis block exists; qed;");
let properties = chain_spec.properties(); let properties = chain_spec.properties();
io.merge(ChainSpec::new(chain_name, genesis_hash, properties).into_rpc())?; io.merge(ChainSpec::new(chain_name, genesis_hash, properties).into_rpc())?;
io.merge(StateMigration::new(client.clone(), backend.clone(), deny_unsafe).into_rpc())?; io.merge(StateMigration::new(client.clone(), backend.clone(), deny_unsafe).into_rpc())?;
io.merge(System::new(client.clone(), pool.clone(), deny_unsafe).into_rpc())?; io.merge(System::new(client.clone(), pool.clone(), deny_unsafe).into_rpc())?;
@ -128,8 +119,7 @@ where
keystore, keystore,
select_chain, select_chain,
deny_unsafe, deny_unsafe,
) ).into_rpc()
.into_rpc(),
)?; )?;
io.merge( io.merge(
@ -139,8 +129,7 @@ where
shared_voter_state, shared_voter_state,
justification_stream, justification_stream,
finality_provider, finality_provider,
) ).into_rpc(),
.into_rpc(),
)?; )?;
io.merge( io.merge(
@ -148,9 +137,8 @@ where
chain_spec, chain_spec,
client.clone(), client.clone(),
shared_authority_set, shared_authority_set,
babe_worker_handle, babe_worker_handle
)? )?.into_rpc(),
.into_rpc(),
)?; )?;
Ok(io) Ok(io)

View File

@ -1,6 +1,6 @@
[package] [package]
name = "casper-runtime" name = "casper-runtime"
version = "3.5.31" version = "3.5.20"
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

@ -86,7 +86,7 @@ pub mod fee {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{ use super::{
currency::{CSPR, STNK, STRH}, currency::{STNK, STRH, CSPR},
fee::WeightToFee, fee::WeightToFee,
}; };
use crate::weights::ExtrinsicBaseWeight; use crate::weights::ExtrinsicBaseWeight;

View File

@ -1,9 +1,9 @@
pub mod block_weights; pub mod block_weights;
pub mod extrinsic_weights; pub mod extrinsic_weights;
pub mod paritydb_weights;
pub mod rocksdb_weights; pub mod rocksdb_weights;
pub mod paritydb_weights;
pub use block_weights::BlockExecutionWeight; pub use block_weights::BlockExecutionWeight;
pub use extrinsic_weights::ExtrinsicBaseWeight; pub use extrinsic_weights::ExtrinsicBaseWeight;
pub use paritydb_weights::constants::ParityDbWeight;
pub use rocksdb_weights::constants::RocksDbWeight; pub use rocksdb_weights::constants::RocksDbWeight;
pub use paritydb_weights::constants::ParityDbWeight;

View File

@ -1,3 +1,4 @@
//! Autogenerated bag thresholds. //! Autogenerated bag thresholds.
//! //!
//! Generated on 2024-06-30T17:36:29.986756974+00:00 //! Generated on 2024-06-30T17:36:29.986756974+00:00

View File

@ -2,34 +2,25 @@ use super::*;
use frame_support::{ use frame_support::{
parameter_types, parameter_types,
traits::{ traits::{
tokens::pay::PayFromAccount, EitherOf, EitherOfDiverse, MapSuccess, OriginTrait, EitherOf, EitherOfDiverse, MapSuccess, OriginTrait, TryWithMorphedArg,
TryWithMorphedArg, tokens::pay::PayFromAccount,
}, },
}; };
use frame_system::EnsureRootWithSuccess; use frame_system::EnsureRootWithSuccess;
use pallet_ranked_collective::EnsureOfRank;
use sp_core::{ConstU128, ConstU32}; use sp_core::{ConstU128, ConstU32};
use sp_runtime::traits::{ConstU16, TakeFirst}; use sp_runtime::traits::{ConstU16, TakeFirst};
use pallet_ranked_collective::EnsureOfRank;
use crate::{ use crate::{
AccountId,
Balance,
Balances,
Preimage,
Runtime,
// weights, // weights,
RuntimeCall, RuntimeCall, RuntimeEvent, Scheduler, DAYS, CSPR, AccountId, Balance,
RuntimeEvent, TreasuryAccount, Balances, Preimage, Runtime,
Scheduler,
TreasuryAccount,
CSPR,
DAYS,
}; };
mod origins; mod origins;
pub use origins::{ pub use origins::{
pallet_cult_origins, CultTreasurySpender, Degens, EnsureCanPromoteTo, EnsureCanRetainAt, pallet_cult_origins, Geniuses, Degens, Zombies, Skeletons, Ghosts,
EnsureCult, Geniuses, Ghosts, Skeletons, ToVoice, Zombies, EnsureCanRetainAt, EnsureCanPromoteTo, EnsureCult, ToVoice, CultTreasurySpender,
}; };
mod tracks; mod tracks;
@ -54,10 +45,14 @@ parameter_types! {
impl pallet_whitelist::Config for Runtime { impl pallet_whitelist::Config for Runtime {
type RuntimeCall = RuntimeCall; type RuntimeCall = RuntimeCall;
type RuntimeEvent = RuntimeEvent; type RuntimeEvent = RuntimeEvent;
type WhitelistOrigin = type WhitelistOrigin = EitherOfDiverse<
EitherOfDiverse<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Skeletons>; EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
type DispatchWhitelistedOrigin = Skeletons,
EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Geniuses>; >;
type DispatchWhitelistedOrigin = EitherOf<
EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
Geniuses,
>;
type Preimages = Preimage; type Preimages = Preimage;
type WeightInfo = weights::pallet_whitelist::WeightInfo<Runtime>; type WeightInfo = weights::pallet_whitelist::WeightInfo<Runtime>;
} }
@ -70,7 +65,7 @@ parameter_types! {
pub type CultReferendaInstance = pallet_referenda::Instance1; pub type CultReferendaInstance = pallet_referenda::Instance1;
impl pallet_referenda::Config<CultReferendaInstance> for Runtime { impl pallet_referenda::Config<CultReferendaInstance> for Runtime {
type WeightInfo = weights::pallet_referenda::WeightInfo<Runtime>; type WeightInfo = ();
type RuntimeCall = RuntimeCall; type RuntimeCall = RuntimeCall;
type RuntimeEvent = RuntimeEvent; type RuntimeEvent = RuntimeEvent;
type Scheduler = Scheduler; type Scheduler = Scheduler;
@ -86,7 +81,7 @@ impl pallet_referenda::Config<CultReferendaInstance> for Runtime {
(AccountId, u16), (AccountId, u16),
>, >,
TakeFirst, TakeFirst,
>, >
>; >;
type CancelOrigin = Skeletons; type CancelOrigin = Skeletons;
type KillOrigin = Ghosts; type KillOrigin = Ghosts;
@ -140,13 +135,10 @@ impl pallet_core_fellowship::Config<CultCoreInstance> for Runtime {
type Members = pallet_ranked_collective::Pallet<Runtime, CultCollectiveInstance>; type Members = pallet_ranked_collective::Pallet<Runtime, CultCollectiveInstance>;
type Balance = Balance; type Balance = Balance;
type ParamsOrigin = type ParamsOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Skeletons>;
EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Skeletons>;
type InductOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Zombies>; type InductOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Zombies>;
type ApproveOrigin = type ApproveOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, EnsureCanRetainAt>;
EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, EnsureCanRetainAt>; type PromoteOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, EnsureCanPromoteTo>;
type PromoteOrigin =
EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, EnsureCanPromoteTo>;
type EvidenceSize = ConstU32<65536>; type EvidenceSize = ConstU32<65536>;
} }

View File

@ -5,8 +5,8 @@ pub use pallet_cult_origins::*;
#[frame_support::pallet] #[frame_support::pallet]
pub mod pallet_cult_origins { pub mod pallet_cult_origins {
use super::ranks;
use crate::{Balance, CSPR}; use crate::{Balance, CSPR};
use super::ranks;
use frame_support::pallet_prelude::*; use frame_support::pallet_prelude::*;
use pallet_ranked_collective::Rank; use pallet_ranked_collective::Rank;

View File

@ -1,4 +1,4 @@
use crate::{Balance, BlockNumber, RuntimeOrigin, CSPR, DAYS, HOURS, MINUTES}; use crate::{Balance, BlockNumber, RuntimeOrigin, DAYS, CSPR, HOURS, MINUTES};
use pallet_ranked_collective::Rank; use pallet_ranked_collective::Rank;
use sp_runtime::{traits::Convert, Perbill}; use sp_runtime::{traits::Convert, Perbill};
@ -255,6 +255,7 @@ const TRACKS_DATA: [(u16, pallet_referenda::TrackInfo<Balance, BlockNumber>); 15
min_support: RETAIN_MIN_SUPPORT, min_support: RETAIN_MIN_SUPPORT,
}, },
), ),
( (
constants::PROMOTE_TO_GENIUSES, constants::PROMOTE_TO_GENIUSES,
pallet_referenda::TrackInfo { pallet_referenda::TrackInfo {
@ -346,7 +347,7 @@ impl pallet_referenda::TracksInfo<Balance, BlockNumber> for TracksInfo {
// It is important that this is NOT availiable in production! // It is important that this is NOT availiable in production!
let root: Self::RuntimeOrigin = frame_system::RawOrigin::Root.into(); let root: Self::RuntimeOrigin = frame_system::RawOrigin::Root.into();
if &root == id { if &root == id {
return Ok(tracks::GHOSTS); return Ok(tracks::GHOSTS)
} }
} }

View File

@ -3,20 +3,20 @@ use pallet_staking::Forcing;
use sp_staking::StakerStatus; use sp_staking::StakerStatus;
use crate::{opaque::SessionKeys, BABE_GENESIS_EPOCH_CONFIG}; use crate::{opaque::SessionKeys, BABE_GENESIS_EPOCH_CONFIG};
use casper_runtime_constants::currency::CSPR;
use primitives::{AccountId, AccountPublic}; use primitives::{AccountId, AccountPublic};
use casper_runtime_constants::currency::CSPR;
use ghost_slow_clap::sr25519::AuthorityId as SlowClapId;
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId; use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
use babe_primitives::AuthorityId as BabeId; use babe_primitives::AuthorityId as BabeId;
use ghost_slow_clap::sr25519::AuthorityId as SlowClapId;
use grandpa_primitives::AuthorityId as GrandpaId; use grandpa_primitives::AuthorityId as GrandpaId;
use sp_core::{sr25519, Pair, Public};
use sp_runtime::{traits::IdentifyAccount, Perbill};
#[cfg(not(feature = "std"))] #[cfg(not(feature = "std"))]
use sp_std::alloc::format; use sp_std::alloc::format;
use sp_std::prelude::*;
use sp_std::vec::Vec; use sp_std::vec::Vec;
use sp_std::prelude::*;
use sp_core::{sr25519, Pair, Public};
use sp_runtime::{Perbill, traits::IdentifyAccount};
#[derive(Encode, Clone)] #[derive(Encode, Clone)]
struct PreparedNetworkData { struct PreparedNetworkData {
@ -84,69 +84,40 @@ fn casper_testnet_accounts() -> Vec<AccountId> {
fn casper_testnet_evm_accounts() -> Vec<(AccountId, u128, u8)> { fn casper_testnet_evm_accounts() -> Vec<(AccountId, u128, u8)> {
vec![ vec![
// 01c928771aea942a1e7ac06adf2b73dfbc9a25d9eaa516e3673116af7f345198 // 01c928771aea942a1e7ac06adf2b73dfbc9a25d9eaa516e3673116af7f345198
( (get_account_id_from_seed::<sr25519::Public>("1A69d2D5568D1878023EeB121a73d33B9116A760"), 1337 * CSPR, 1),
get_account_id_from_seed::<sr25519::Public>("1A69d2D5568D1878023EeB121a73d33B9116A760"),
1337 * CSPR,
1,
),
// b19a435901872f817185f7234a1484eae837613f9d10cf21927a23c2d8cb9139 // b19a435901872f817185f7234a1484eae837613f9d10cf21927a23c2d8cb9139
( (get_account_id_from_seed::<sr25519::Public>("2f86cfBED3fbc1eCf2989B9aE5fc019a837A9C12"), 1337 * CSPR, 2),
get_account_id_from_seed::<sr25519::Public>("2f86cfBED3fbc1eCf2989B9aE5fc019a837A9C12"),
1337 * CSPR,
2,
),
// d3baf57b74d65719b2dc33f5a464176022d0cc5edbca002234229f3e733875fc // d3baf57b74d65719b2dc33f5a464176022d0cc5edbca002234229f3e733875fc
( (get_account_id_from_seed::<sr25519::Public>("e83f67361Ac74D42A48E2DAfb6706eb047D8218D"), 69 * CSPR, 3),
get_account_id_from_seed::<sr25519::Public>("e83f67361Ac74D42A48E2DAfb6706eb047D8218D"),
69 * CSPR,
3,
),
// c4683d566436af6b58b4a59c8f501319226e85b21869bf93d5eeb4596d4791d4 // c4683d566436af6b58b4a59c8f501319226e85b21869bf93d5eeb4596d4791d4
( (get_account_id_from_seed::<sr25519::Public>("827ee4ad9b259b6fa1390ed60921508c78befd63"), 69 * CSPR, 4),
get_account_id_from_seed::<sr25519::Public>("827ee4ad9b259b6fa1390ed60921508c78befd63"),
69 * CSPR,
4,
),
] ]
} }
fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>)> { fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>)> {
vec![ vec![
( (1, PreparedNetworkData {
1,
PreparedNetworkData {
chain_name: "ethereum-mainnet".into(), chain_name: "ethereum-mainnet".into(),
default_endpoint: default_endpoint: "https://nd-422-757-666.p2pify.com/0a9d79d93fb2f4a4b1e04695da2b77a7/".into(),
"https://nd-422-757-666.p2pify.com/0a9d79d93fb2f4a4b1e04695da2b77a7/".into(),
finality_delay: Some(40), finality_delay: Some(40),
release_delay: Some(80), release_delay: Some(80),
network_type: Default::default(), network_type: Default::default(),
gatekeeper: "0x4d224452801aced8b2f0aebe155379bb5d594381".into(), gatekeeper: "0x4d224452801aced8b2f0aebe155379bb5d594381".into(),
topic_name: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" topic_name: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef".into(),
.into(),
incoming_fee: 0, incoming_fee: 0,
outgoing_fee: 0, outgoing_fee: 0,
} }.encode()),
.encode(), (56, PreparedNetworkData {
),
(
56,
PreparedNetworkData {
chain_name: "bnb-mainnet".into(), chain_name: "bnb-mainnet".into(),
default_endpoint: default_endpoint: "https://bsc-mainnet.core.chainstack.com/35848e183f3e3303c8cfeacbea831cab/".into(),
"https://bsc-mainnet.core.chainstack.com/35848e183f3e3303c8cfeacbea831cab/"
.into(),
finality_delay: Some(20), finality_delay: Some(20),
release_delay: Some(40), release_delay: Some(40),
network_type: Default::default(), network_type: Default::default(),
gatekeeper: "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82".into(), gatekeeper: "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82".into(),
topic_name: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" topic_name: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef".into(),
.into(),
incoming_fee: 0, incoming_fee: 0,
outgoing_fee: 0, outgoing_fee: 0,
} }.encode())
.encode(),
),
] ]
} }
@ -156,12 +127,7 @@ fn casper_session_keys(
authority_discovery: AuthorityDiscoveryId, authority_discovery: AuthorityDiscoveryId,
slow_clap: SlowClapId, slow_clap: SlowClapId,
) -> SessionKeys { ) -> SessionKeys {
SessionKeys { SessionKeys { babe, grandpa, authority_discovery, slow_clap }
babe,
grandpa,
authority_discovery,
slow_clap,
}
} }
fn testnet_config_genesis( fn testnet_config_genesis(
@ -177,7 +143,8 @@ fn testnet_config_genesis(
ghost_accounts: Option<Vec<(AccountId, u128, u8)>>, ghost_accounts: Option<Vec<(AccountId, u128, u8)>>,
evm_networks: Option<Vec<(u32, Vec<u8>)>>, evm_networks: Option<Vec<(u32, Vec<u8>)>>,
) -> serde_json::Value { ) -> serde_json::Value {
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(casper_testnet_accounts); let endowed_accounts: Vec<AccountId> =
endowed_accounts.unwrap_or_else(casper_testnet_accounts);
let ghost_accounts: Vec<(AccountId, u128, u8)> = let ghost_accounts: Vec<(AccountId, u128, u8)> =
ghost_accounts.unwrap_or_else(casper_testnet_evm_accounts); ghost_accounts.unwrap_or_else(casper_testnet_evm_accounts);
@ -251,9 +218,7 @@ fn testnet_config_genesis(
fn casper_development_config_genesis() -> serde_json::Value { fn casper_development_config_genesis() -> serde_json::Value {
testnet_config_genesis( testnet_config_genesis(
vec![get_authority_keys_from_seed("Alice")], vec![get_authority_keys_from_seed("Alice")],
None, None, None, None,
None,
None,
) )
} }
@ -264,9 +229,7 @@ fn casper_local_config_genesis() -> serde_json::Value {
get_authority_keys_from_seed("Alice"), get_authority_keys_from_seed("Alice"),
get_authority_keys_from_seed("Bob"), get_authority_keys_from_seed("Bob"),
], ],
None, None, None, None,
None,
None,
) )
} }
@ -277,11 +240,9 @@ pub fn get_preset(id: &sp_genesis_builder::PresetId) -> Option<sp_std::vec::Vec<
Ok("local_testnet") => casper_local_config_genesis(), Ok("local_testnet") => casper_local_config_genesis(),
_ => return None, _ => return None,
}; };
Some( Some(serde_json::to_string(&patch)
serde_json::to_string(&patch)
.expect("serialization to json is expected to work; qed") .expect("serialization to json is expected to work; qed")
.into_bytes(), .into_bytes())
)
} }
/// Returns a list of identifiers for available builtin `RuntimeGenesisConfig` presets. /// Returns a list of identifiers for available builtin `RuntimeGenesisConfig` presets.

View File

@ -1,5 +1,8 @@
use super::*; use super::*;
use frame_support::{dispatch::DispatchResultWithPostInfo, traits::PrivilegeCmp}; use frame_support::{
dispatch::DispatchResultWithPostInfo,
traits::PrivilegeCmp,
};
use pallet_alliance::{ProposalIndex, ProposalProvider}; use pallet_alliance::{ProposalIndex, ProposalProvider};
use sp_runtime::DispatchError; use sp_runtime::DispatchError;
use sp_std::{cmp::Ordering, marker::PhantomData}; use sp_std::{cmp::Ordering, marker::PhantomData};
@ -11,8 +14,7 @@ type HashOf<T> = <T as frame_system::Config>::Hash;
/// Proposal provider for alliance pallet. /// Proposal provider for alliance pallet.
/// Adapter from collective pallet to alliance proposal provider trait. /// Adapter from collective pallet to alliance proposal provider trait.
pub struct AllianceProposalProvider<T, I = ()>(PhantomData<(T, I)>); pub struct AllianceProposalProvider<T, I = ()>(PhantomData<(T, I)>);
impl<T, I> ProposalProvider<AccountIdOf<T>, HashOf<T>, ProposalOf<T, I>> impl <T, I> ProposalProvider<AccountIdOf<T>, HashOf<T>, ProposalOf<T, I>> for AllianceProposalProvider<T, I>
for AllianceProposalProvider<T, I>
where where
T: pallet_collective::Config<I> + frame_system::Config, T: pallet_collective::Config<I> + frame_system::Config,
I: 'static, I: 'static,
@ -23,12 +25,7 @@ where
proposal: Box<ProposalOf<T, I>>, proposal: Box<ProposalOf<T, I>>,
length_bound: u32, length_bound: u32,
) -> Result<(u32, u32), DispatchError> { ) -> Result<(u32, u32), DispatchError> {
pallet_collective::Pallet::<T, I>::do_propose_proposed( pallet_collective::Pallet::<T, I>::do_propose_proposed(who, threshold, proposal, length_bound)
who,
threshold,
proposal,
length_bound,
)
} }
fn vote_proposal( fn vote_proposal(
@ -64,7 +61,7 @@ pub struct EqualOrGreatestRootCmp;
impl PrivilegeCmp<OriginCaller> for EqualOrGreatestRootCmp { impl PrivilegeCmp<OriginCaller> for EqualOrGreatestRootCmp {
fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option<Ordering> { fn cmp_privilege(left: &OriginCaller, right: &OriginCaller) -> Option<Ordering> {
if left == right { if left == right {
return Some(Ordering::Equal); return Some(Ordering::Equal)
} }
match (left, right) { match (left, right) {

View File

@ -1,59 +1,63 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// `construct_runtime!` does a lot of recursion and requires us to increase // `construct_runtime!` does a lot of recursion and requires us to increase
// the limit to 256 // the limit to 256
#![recursion_limit = "256"] #![recursion_limit = "256"]
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
use frame_election_provider_support::{
bounds::ElectionBoundsBuilder, generate_solution_type, onchain, SequentialPhragmen,
};
use frame_support::{
construct_runtime,
genesis_builder_helper::{build_state, get_preset},
parameter_types,
traits::{
fungible::HoldConsideration, tokens::UnityAssetBalanceConversion, ConstU128, ConstU32,
EitherOf, EitherOfDiverse, InstanceFilter, KeyOwnerProofSystem, LinearStoragePrice,
WithdrawReasons,
},
weights::ConstantMultiplier,
PalletId,
};
use frame_system::{EnsureRoot, EnsureRootWithSuccess}; use frame_system::{EnsureRoot, EnsureRootWithSuccess};
use runtime_common::{ use runtime_common::{
impl_runtime_weights, impls::DealWithFees, prod_or_fast, BlockHashCount, BlockLength, impls::DealWithFees, BlockHashCount, BlockLength, CurrencyToVote,
CurrencyToVote, SlowAdjustingFeeUpdate, SlowAdjustingFeeUpdate, impl_runtime_weights, prod_or_fast,
};
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
use frame_election_provider_support::{
generate_solution_type, onchain, SequentialPhragmen,
bounds::ElectionBoundsBuilder,
};
use frame_support::{
construct_runtime, parameter_types,
genesis_builder_helper::{build_state, get_preset},
traits::{
fungible::HoldConsideration,
tokens::UnityAssetBalanceConversion,
ConstU128, ConstU32, EitherOf, EitherOfDiverse, InstanceFilter,
KeyOwnerProofSystem, LinearStoragePrice, WithdrawReasons,
},
weights::ConstantMultiplier, PalletId
}; };
use frame_support::traits::tokens::pay::PayFromAccount;
#[cfg(feature = "runtime-benchmarks")] #[cfg(feature = "runtime-benchmarks")]
use runtime_common::benchmarking::BenchmarkTreasuryHelper; use runtime_common::benchmarking::BenchmarkTreasuryHelper;
use frame_support::traits::tokens::pay::PayFromAccount;
use codec::{Decode, Encode, MaxEncodedLen}; use pallet_transaction_payment::FungibleAdapter;
use ghost_slow_clap::sr25519::AuthorityId as SlowClapId;
use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId}; use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId};
use pallet_identity::legacy::IdentityInfo; use pallet_identity::legacy::IdentityInfo;
use ghost_slow_clap::sr25519::AuthorityId as SlowClapId;
use pallet_session::historical as session_historical; use pallet_session::historical as session_historical;
use pallet_transaction_payment::FungibleAdapter;
use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo}; use pallet_transaction_payment::{FeeDetails, RuntimeDispatchInfo};
use codec::{Decode, Encode, MaxEncodedLen};
use primitives::{ use primitives::{
AccountId, AccountIndex, Balance, BlockNumber, Hash, Moment, Nonce, ReserveIdentifier, AccountId, AccountIndex, Balance, BlockNumber, Hash, Moment, Nonce,
Signature, Signature, ReserveIdentifier,
}; };
use sp_core::OpaqueMetadata; use sp_core::OpaqueMetadata;
use sp_genesis_builder::PresetId;
use sp_runtime::{ use sp_runtime::{
create_runtime_str, create_runtime_str, generic, impl_opaque_keys, FixedU128,
curve::PiecewiseLinear, curve::PiecewiseLinear,
generic, impl_opaque_keys,
traits::{ traits::{
AccountIdLookup, BlakeTwo256, Block as BlockT, ConstU16, ConvertInto, AccountIdLookup, BlakeTwo256, Block as BlockT, Extrinsic as ExtrinsicT,
Extrinsic as ExtrinsicT, IdentityLookup, OpaqueKeys, SaturatedConversion, Verify, OpaqueKeys, SaturatedConversion, Verify, IdentityLookup, ConvertInto,
ConstU16,
}, },
transaction_validity::{TransactionPriority, TransactionSource, TransactionValidity}, transaction_validity::{
ApplyExtrinsicResult, FixedU128, KeyTypeId, Perbill, Percent, Permill, RuntimeDebug, TransactionPriority, TransactionSource, TransactionValidity,
},
ApplyExtrinsicResult, KeyTypeId, Perbill, Percent, Permill,
RuntimeDebug,
}; };
use sp_genesis_builder::PresetId;
use sp_std::prelude::*; use sp_std::prelude::*;
#[cfg(any(feature = "std", test))] #[cfg(any(feature = "std", test))]
use sp_version::NativeVersion; use sp_version::NativeVersion;
@ -71,20 +75,20 @@ pub use pallet_timestamp::Call as TimestampCall;
pub use sp_runtime::BuildStorage; pub use sp_runtime::BuildStorage;
/// Constant values used within the runtime. /// Constant values used within the runtime.
use casper_runtime_constants::{currency::*, fee::*, time::*}; use casper_runtime_constants::{currency::*, time::*, fee::*};
mod bag_thresholds;
mod genesis_config_presets;
mod impls;
mod weights; mod weights;
mod bag_thresholds;
mod impls;
mod genesis_config_presets;
pub use impls::{AllianceProposalProvider, EqualOrGreatestRootCmp}; pub use impls::{AllianceProposalProvider, EqualOrGreatestRootCmp};
// Governance configuration. // Governance configuration.
pub mod cult; pub mod cult;
use cult::{ use cult::{
pallet_cult_origins, CultCollectiveInstance, CultTreasurySpender, Degens, Geniuses, Ghosts, pallet_cult_origins, CultCollectiveInstance, CultTreasurySpender,
Skeletons, Zombies, Geniuses, Degens, Zombies, Skeletons, Ghosts,
}; };
pub const LOG_TARGET: &str = "runtime::casper"; pub const LOG_TARGET: &str = "runtime::casper";
@ -117,7 +121,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
spec_name: create_runtime_str!("casper"), spec_name: create_runtime_str!("casper"),
impl_name: create_runtime_str!("casper-svengali"), impl_name: create_runtime_str!("casper-svengali"),
authoring_version: 0, authoring_version: 0,
spec_version: 2, spec_version: 1,
impl_version : 0, impl_version : 0,
apis: RUNTIME_API_VERSIONS, apis: RUNTIME_API_VERSIONS,
transaction_version: 1, transaction_version: 1,
@ -418,12 +422,10 @@ impl pallet_election_provider_multi_phase::Config for Runtime {
type SignedMaxSubmissions = SignedMaxSubmissions; type SignedMaxSubmissions = SignedMaxSubmissions;
type SignedMaxRefunds = SignedMaxRefunds; type SignedMaxRefunds = SignedMaxRefunds;
type SignedRewardBase = SignedRewardBase; type SignedRewardBase = SignedRewardBase;
type SignedDepositBase = type SignedDepositBase = GeometricDepositBase<Balance, SignedFixedDeposit, SignedDepositIncreaseFactor>;
GeometricDepositBase<Balance, SignedFixedDeposit, SignedDepositIncreaseFactor>;
type SignedDepositByte = SignedDepositByte; type SignedDepositByte = SignedDepositByte;
type SignedDepositWeight = (); type SignedDepositWeight = ();
type SignedMaxWeight = type SignedMaxWeight = <Self::MinerConfig as pallet_election_provider_multi_phase::MinerConfig>::MaxWeight;
<Self::MinerConfig as pallet_election_provider_multi_phase::MinerConfig>::MaxWeight;
type MinerConfig = Self; type MinerConfig = Self;
type SlashHandler = (); type SlashHandler = ();
type RewardHandler= (); type RewardHandler= ();
@ -447,7 +449,10 @@ impl pallet_election_provider_multi_phase::Config for Runtime {
(), (),
>; >;
type BenchmarkingConfig = runtime_common::elections::BenchmarkConfig; type BenchmarkingConfig = runtime_common::elections::BenchmarkConfig;
type ForceOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Zombies>; type ForceOrigin = EitherOf<
EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
Zombies,
>;
type MaxWinners = MaxActiveValidators; type MaxWinners = MaxActiveValidators;
type ElectionBounds = ElectionBounds; type ElectionBounds = ElectionBounds;
type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>; type WeightInfo = weights::pallet_election_provider_multi_phase::WeightInfo<Runtime>;
@ -487,8 +492,6 @@ parameter_types! {
pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17); pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17);
pub const MaxNominations: u32 = pub const MaxNominations: u32 =
<NposCompactSolution16 as frame_election_provider_support::NposSolution>::LIMIT as u32; <NposCompactSolution16 as frame_election_provider_support::NposSolution>::LIMIT as u32;
pub const StakingHistoryDepth: u32 = 84;
pub const MaxUnlockingChunks: u32 = 32;
} }
impl pallet_staking::Config for Runtime { impl pallet_staking::Config for Runtime {
@ -503,9 +506,12 @@ impl pallet_staking::Config for Runtime {
type SessionsPerEra = SessionsPerEra; type SessionsPerEra = SessionsPerEra;
type BondingDuration = BondingDuration; type BondingDuration = BondingDuration;
type SlashDeferDuration = SlashDeferDuration; type SlashDeferDuration = SlashDeferDuration;
type AdminOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Skeletons>; type AdminOrigin = EitherOf<
EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
Skeletons,
>;
type SessionInterface = Self; type SessionInterface = Self;
type EraPayout = ghost_networks::BridgedInflationCurve<RewardCurve, Self>; type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
type MaxExposurePageSize = MaxExposurePageSize; type MaxExposurePageSize = MaxExposurePageSize;
type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy; type DisablingStrategy = pallet_staking::UpToLimitDisablingStrategy;
type NextNewSession = Session; type NextNewSession = Session;
@ -514,8 +520,8 @@ impl pallet_staking::Config for Runtime {
type VoterList = VoterList; type VoterList = VoterList;
type TargetList = UseValidatorsMap<Self>; type TargetList = UseValidatorsMap<Self>;
type NominationsQuota = pallet_staking::FixedNominationsQuota<{ MaxNominations::get() }>; type NominationsQuota = pallet_staking::FixedNominationsQuota<{ MaxNominations::get() }>;
type MaxUnlockingChunks = MaxUnlockingChunks; type MaxUnlockingChunks = frame_support::traits::ConstU32<32>;
type HistoryDepth = StakingHistoryDepth; type HistoryDepth = frame_support::traits::ConstU32<84>;
type MaxControllersInDeprecationBatch = ConstU32<5314>; type MaxControllersInDeprecationBatch = ConstU32<5314>;
type BenchmarkingConfig = runtime_common::StakingBenchmarkingConfig; type BenchmarkingConfig = runtime_common::StakingBenchmarkingConfig;
type EventListeners = NominationPools; type EventListeners = NominationPools;
@ -527,7 +533,10 @@ impl pallet_fast_unstake::Config for Runtime {
type Currency = Balances; type Currency = Balances;
type BatchSize = frame_support::traits::ConstU32<16>; type BatchSize = frame_support::traits::ConstU32<16>;
type Deposit = ConstU128<{ STRH }>; type Deposit = ConstU128<{ STRH }>;
type ControlOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Zombies>; type ControlOrigin = EitherOf<
EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
Zombies,
>;
type Staking = Staking; type Staking = Staking;
type MaxErasToCheckPerBlock = ConstU32<1>; type MaxErasToCheckPerBlock = ConstU32<1>;
type WeightInfo = weights::pallet_fast_unstake::WeightInfo<Runtime>; type WeightInfo = weights::pallet_fast_unstake::WeightInfo<Runtime>;
@ -588,7 +597,10 @@ impl pallet_treasury::Config for Runtime {
type ApproveOrigin = frame_support::traits::NeverEnsureOrigin<Balance>; type ApproveOrigin = frame_support::traits::NeverEnsureOrigin<Balance>;
#[cfg(feature = "runtime-benchmarks")] #[cfg(feature = "runtime-benchmarks")]
type ApproveOrigin = EnsureRoot<Self::AccountId>; type ApproveOrigin = EnsureRoot<Self::AccountId>;
type RejectOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Degens>; type RejectOrigin = EitherOf<
EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
Degens,
>;
type RuntimeEvent = RuntimeEvent; type RuntimeEvent = RuntimeEvent;
type OnSlash = Treasury; type OnSlash = Treasury;
@ -611,7 +623,10 @@ impl pallet_treasury::Config for Runtime {
type MaxApprovals = MaxApprovals; type MaxApprovals = MaxApprovals;
type WeightInfo = (); type WeightInfo = ();
type SpendOrigin = EitherOf<EnsureRootWithSuccess<AccountId, MaxBalance>, CultTreasurySpender>; type SpendOrigin = EitherOf<
EnsureRootWithSuccess<AccountId, MaxBalance>,
CultTreasurySpender
>;
type AssetKind = (); type AssetKind = ();
type Beneficiary = AccountId; type Beneficiary = AccountId;
@ -691,7 +706,8 @@ impl pallet_grandpa::Config for Runtime {
type MaxNominators = MaxNominators; 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;
type EquivocationReportSystem = type EquivocationReportSystem =
pallet_grandpa::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>; pallet_grandpa::EquivocationReportSystem<Self, Offences, Historical, ReportLongevity>;
@ -708,17 +724,13 @@ where
public: <Signature as Verify>::Signer, public: <Signature as Verify>::Signer,
account: AccountId, account: AccountId,
nonce: <Runtime as frame_system::Config>::Nonce, nonce: <Runtime as frame_system::Config>::Nonce,
) -> Option<( ) -> Option<(RuntimeCall, <UncheckedExtrinsic as ExtrinsicT>::SignaturePayload)> {
RuntimeCall,
<UncheckedExtrinsic as ExtrinsicT>::SignaturePayload,
)> {
use sp_runtime::traits::StaticLookup; use sp_runtime::traits::StaticLookup;
// take the biggest period possible // take the biggest period possible
let period = BlockHashCount::get() let period = BlockHashCount::get()
.checked_next_power_of_two() .checked_next_power_of_two()
.map(|c| c / 2) .map(|c| c / 2).unwrap_or(2) as u64;
.unwrap_or(2) as u64;
let current_block = System::block_number() let current_block = System::block_number()
.saturated_into::<u64>() .saturated_into::<u64>()
@ -732,10 +744,9 @@ where
frame_system::CheckSpecVersion::<Runtime>::new(), frame_system::CheckSpecVersion::<Runtime>::new(),
frame_system::CheckTxVersion::<Runtime>::new(), frame_system::CheckTxVersion::<Runtime>::new(),
frame_system::CheckGenesis::<Runtime>::new(), frame_system::CheckGenesis::<Runtime>::new(),
frame_system::CheckMortality::<Runtime>::from(generic::Era::mortal( frame_system::CheckMortality::<Runtime>::from(
period, generic::Era::mortal(period, current_block),
current_block, ),
)),
frame_system::CheckNonce::<Runtime>::from(nonce), frame_system::CheckNonce::<Runtime>::from(nonce),
frame_system::CheckWeight::<Runtime>::new(), frame_system::CheckWeight::<Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip), pallet_transaction_payment::ChargeTransactionPayment::<Runtime>::from(tip),
@ -817,17 +828,8 @@ parameter_types! {
/// The type used to represent the kinds of proxying allowed. /// The type used to represent the kinds of proxying allowed.
#[derive( #[derive(
Copy, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Encode,
Clone, Decode, RuntimeDebug, MaxEncodedLen, scale_info::TypeInfo,
Eq,
PartialEq,
Ord,
PartialOrd,
Encode,
Decode,
RuntimeDebug,
MaxEncodedLen,
scale_info::TypeInfo,
)] )]
pub enum ProxyType { pub enum ProxyType {
Any = 0, Any = 0,
@ -852,40 +854,42 @@ impl InstanceFilter<RuntimeCall> for ProxyType {
ProxyType::NonTransfer => matches!(c, RuntimeCall::Balances { .. }), ProxyType::NonTransfer => matches!(c, RuntimeCall::Balances { .. }),
ProxyType::Governance => matches!( ProxyType::Governance => matches!(
c, c,
RuntimeCall::Bounties { .. } RuntimeCall::Bounties { .. } |
| RuntimeCall::Utility { .. } RuntimeCall::Utility { .. } |
| RuntimeCall::ChildBounties { .. } RuntimeCall::ChildBounties { .. } |
| RuntimeCall::CultReferenda { .. } RuntimeCall::CultReferenda { .. } |
| RuntimeCall::CultCollective { .. } RuntimeCall::CultCollective { .. } |
| RuntimeCall::Whitelist { .. } RuntimeCall::Whitelist { .. } |
| RuntimeCall::AllianceMotion { .. } RuntimeCall::AllianceMotion { .. } |
| RuntimeCall::Alliance { .. } RuntimeCall::Alliance { .. } |
| RuntimeCall::Multisig { .. } RuntimeCall::Multisig { .. }
), ),
ProxyType::Staking => matches!( ProxyType::Staking => matches!(
c, c,
RuntimeCall::Staking { .. } RuntimeCall::Staking { .. } |
| RuntimeCall::Session { .. } RuntimeCall::Session { .. } |
| RuntimeCall::Utility { .. } RuntimeCall::Utility { .. } |
| RuntimeCall::FastUnstake { .. } RuntimeCall::FastUnstake { .. } |
| RuntimeCall::VoterList { .. } RuntimeCall::VoterList { .. } |
| RuntimeCall::NominationPools { .. } RuntimeCall::NominationPools { .. }
), ),
ProxyType::IdentityJudgement => matches!( ProxyType::IdentityJudgement => matches!(
c, c,
RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. }) RuntimeCall::Identity(pallet_identity::Call::provide_judgement { .. }) |
| RuntimeCall::Utility { .. } RuntimeCall::Utility { .. }
), ),
ProxyType::CancelProxy => matches!( ProxyType::CancelProxy => matches!(
c, c,
RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { .. }) |
| RuntimeCall::Utility { .. } RuntimeCall::Utility { .. } |
| RuntimeCall::Multisig { .. } RuntimeCall::Multisig { .. }
), ),
ProxyType::NominationPools => matches!( ProxyType::NominationPools => matches!(
c, c,
RuntimeCall::NominationPools { .. } | RuntimeCall::Utility { .. } RuntimeCall::NominationPools { .. } |
RuntimeCall::Utility { .. }
), ),
} }
} }
@ -934,7 +938,10 @@ impl pallet_nomination_pools::Config for Runtime {
type MaxUnbonding = <Self as pallet_staking::Config>::MaxUnlockingChunks; type MaxUnbonding = <Self as pallet_staking::Config>::MaxUnlockingChunks;
type PalletId = PoolsPalletId; type PalletId = PoolsPalletId;
type MaxPointsToBalance = MaxPointsToBalance; type MaxPointsToBalance = MaxPointsToBalance;
type AdminOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Zombies>; type AdminOrigin = EitherOf<
EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
Zombies,
>;
type WeightInfo = weights::pallet_nomination_pools::WeightInfo<Runtime>; type WeightInfo = weights::pallet_nomination_pools::WeightInfo<Runtime>;
} }
@ -1028,12 +1035,19 @@ impl pallet_alliance::Config for Runtime {
impl ghost_networks::Config for Runtime { impl ghost_networks::Config for Runtime {
type RuntimeEvent = RuntimeEvent; type RuntimeEvent = RuntimeEvent;
type NetworkId = u64; type NetworkId = u64;
type Currency = Balances;
type RegisterOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Ghosts>; type RegisterOrigin = EitherOf<
type UpdateOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Zombies>; EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
type RemoveOrigin = Ghosts,
EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Skeletons>; >;
type UpdateOrigin = EitherOf<
EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
Zombies,
>;
type RemoveOrigin = EitherOf<
EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
Skeletons,
>;
type WeightInfo = weights::ghost_networks::WeightInfo<Runtime>; type WeightInfo = weights::ghost_networks::WeightInfo<Runtime>;
} }
@ -1044,6 +1058,7 @@ parameter_types! {
pub VestingBlocks: u32 = 10 * WEEKS; pub VestingBlocks: u32 = 10 * WEEKS;
} }
impl ghost_claims::Config<CultCollectiveInstance> for Runtime { impl ghost_claims::Config<CultCollectiveInstance> for Runtime {
type RuntimeEvent = RuntimeEvent; type RuntimeEvent = RuntimeEvent;
type VestingSchedule = Vesting; type VestingSchedule = Vesting;
@ -1058,13 +1073,14 @@ impl ghost_claims::Config<CultCollectiveInstance> for Runtime {
} }
parameter_types! { parameter_types! {
// maximum number of claps in one tx
pub MaxNumberOfClaps: u32 = 5;
// will be used in `Perbill::from_percent()` // will be used in `Perbill::from_percent()`
pub const ApplauseThreshold: u32 = 70; pub ApplauseThreshold: u32 = 70;
// will be used in `Perbill::from_percent()` // will be used in `Perbill::from_percent()`
pub const OffenceThreshold: u32 = 40; pub OffenceThreshold: u32 = 40;
pub const SlowClapUnsignedPriority: TransactionPriority = TransactionPriority::MAX; pub const SlowClapUnsignedPriority: TransactionPriority =
pub const SlowClapHistoryDepth: sp_staking::SessionIndex = TransactionPriority::max_value();
StakingHistoryDepth::get() * SessionsPerEra::get();
} }
impl ghost_slow_clap::Config for Runtime { impl ghost_slow_clap::Config for Runtime {
@ -1079,20 +1095,17 @@ impl ghost_slow_clap::Config for Runtime {
type ReportUnresponsiveness = Offences; type ReportUnresponsiveness = Offences;
type MaxAuthorities = MaxAuthorities; type MaxAuthorities = MaxAuthorities;
type MaxNumberOfClaps = MaxNumberOfClaps;
type ApplauseThreshold = ApplauseThreshold; type ApplauseThreshold = ApplauseThreshold;
type MaxAuthorityInfoInSession = MaxAuthorities;
type OffenceThreshold = OffenceThreshold; type OffenceThreshold = OffenceThreshold;
type UnsignedPriority = SlowClapUnsignedPriority; type UnsignedPriority = SlowClapUnsignedPriority;
type HistoryDepth = SlowClapHistoryDepth; type TreasuryPalletId = TreasuryPalletId;
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
{ {
@ -1120,7 +1133,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,
@ -1249,7 +1261,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]
); );
} }
@ -1556,7 +1567,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<
@ -1696,10 +1706,7 @@ mod test_fees {
test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_00u128)); test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_00u128));
test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_000u128)); test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_000u128));
test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_000_000u128)); test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_000_000u128));
test_with_multiplier(Multiplier::saturating_from_rational( test_with_multiplier(Multiplier::saturating_from_rational(1u128, 1_000_000_000u128));
1u128,
1_000_000_000u128,
));
} }
#[test] #[test]
@ -1721,21 +1728,14 @@ mod test_fees {
}; };
let mut active = target_voters; let mut active = target_voters;
while weight_with(active).all_lte(OffchainSolutionWeightLimit::get()) while weight_with(active).all_lte(OffchainSolutionWeightLimit::get()) ||
|| active == target_voters active == target_voters
{ {
active += 1; active += 1;
} }
println!( println!("can support {} nominators to yield a weight of {}", active, weight_with(active));
"can support {} nominators to yield a weight of {}", assert!(active > target_voters, "we need to reevaluate the weight of the election system");
active,
weight_with(active)
);
assert!(
active > target_voters,
"we need to reevaluate the weight of the election system"
);
} }
#[test] #[test]
@ -1764,25 +1764,15 @@ mod test {
.collect(); .collect();
// Block number // Block number
assert!( assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac"));
whitelist.contains("26aa394eea5630e07c48ae0c9558cef702a5c1b19ab7a04f536c519aca4983ac")
);
// Total issuance // Total issuance
assert!( assert!(whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80"));
whitelist.contains("c2261276cc9d1f8598ea4b6a74b15c2f57c875e4cff74148e4628f264b974c80")
);
// Execution phase // Execution phase
assert!( assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a"));
whitelist.contains("26aa394eea5630e07c48ae0c9558cef7ff553b5a9862a516939d82b3d3d8661a")
);
// Event count // Event count
assert!( assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850"));
whitelist.contains("26aa394eea5630e07c48ae0c9558cef70a98fdbe9ce6c55837576c60c7af3850")
);
// System events // System events
assert!( assert!(whitelist.contains("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7"));
whitelist.contains("26aa394eea5630e07c48ae0c9558cef780d41e5e16056765bc8461851072c9d7")
);
} }
#[test] #[test]
@ -1819,21 +1809,13 @@ mod multiplier_tests {
#[test] #[test]
fn multiplier_can_grow_from_zero() { fn multiplier_can_grow_from_zero() {
let minimum_multiplier = MinimumMultiplier::get(); let minimum_multiplier = MinimumMultiplier::get();
let target = TargetBlockFullness::get() let target = TargetBlockFullness::get() *
* BlockWeights::get() BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap();
.get(DispatchClass::Normal)
.max_total
.unwrap();
// if the min is too small, then this will not change, and we are doomed forever. // if the min is too small, then this will not change, and we are doomed forever.
// the weight is 1/100th bigger than target. // the weight is 1/100th bigger than target.
run_with_system_weight(target.saturating_mul(101) / 100, || { run_with_system_weight(target.saturating_mul(101) / 100, || {
let next = SlowAdjustingFeeUpdate::<Runtime>::convert(minimum_multiplier); let next = SlowAdjustingFeeUpdate::<Runtime>::convert(minimum_multiplier);
assert!( assert!(next > minimum_multiplier, "{:?} !>= {:?}", next, minimum_multiplier);
next > minimum_multiplier,
"{:?} !>= {:?}",
next,
minimum_multiplier
);
}) })
} }
@ -1846,10 +1828,7 @@ mod multiplier_tests {
<Runtime as pallet_fast_unstake::Config>::BatchSize::get(), <Runtime as pallet_fast_unstake::Config>::BatchSize::get(),
) )
.ref_time() as f32; .ref_time() as f32;
println!( println!("ratio of block weight for full batch fast-unstake {}", on_idle / block_time);
"ratio of block weight for full batch fast-unstake {}",
on_idle / block_time
);
assert!(on_idle / block_time <= 0.5f32) assert!(on_idle / block_time <= 0.5f32)
} }
@ -1859,18 +1838,12 @@ mod multiplier_tests {
// assume the multiplier is initially set to its minimum. We update it with values twice the // assume the multiplier is initially set to its minimum. We update it with values twice the
//target (target is 25%, thus 50%) and we see at which point it reaches 1. //target (target is 25%, thus 50%) and we see at which point it reaches 1.
let mut multiplier = MinimumMultiplier::get(); let mut multiplier = MinimumMultiplier::get();
let block_weight = BlockWeights::get() let block_weight = BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap();
.get(DispatchClass::Normal)
.max_total
.unwrap();
let mut blocks = 0; let mut blocks = 0;
let mut fees_paid = 0; let mut fees_paid = 0;
frame_system::Pallet::<Runtime>::set_block_consumed_resources(Weight::MAX, 0); frame_system::Pallet::<Runtime>::set_block_consumed_resources(Weight::MAX, 0);
let info = DispatchInfo { let info = DispatchInfo { weight: Weight::MAX, ..Default::default() };
weight: Weight::MAX,
..Default::default()
};
let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::default() let mut t: sp_io::TestExternalities = frame_system::GenesisConfig::default()
.build_storage::<Runtime>() .build_storage::<Runtime>()

View File

@ -16,7 +16,7 @@
//! Autogenerated weights for `ghost_networks` //! Autogenerated weights for `ghost_networks`
//! //!
//! 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: 2025-07-29, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! DATE: 2024-08-01, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000` //! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz` //! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
@ -28,7 +28,7 @@
// --chain=casper-dev // --chain=casper-dev
// --steps=50 // --steps=50
// --repeat=20 // --repeat=20
// --pallet=ghost-networks // --pallet=ghost_networks
// --extrinsic=* // --extrinsic=*
// --wasm-execution=compiled // --wasm-execution=compiled
// --heap-pages=4096 // --heap-pages=4096
@ -50,31 +50,30 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// The range of component `i` is `[1, 20]`. /// The range of component `i` is `[1, 20]`.
/// The range of component `j` is `[1, 150]`. /// The range of component `j` is `[1, 150]`.
/// The range of component `k` is `[1, 20]`. fn register_network(i: u32, j: u32, ) -> Weight {
fn register_network(_i: u32, _j: u32, k: u32, ) -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `109` // Measured: `109`
// Estimated: `3574` // Estimated: `3574`
// Minimum execution time: 46_023_000 picoseconds. // Minimum execution time: 44_464_000 picoseconds.
Weight::from_parts(97_871_287, 0) Weight::from_parts(44_802_179, 0)
.saturating_add(Weight::from_parts(0, 3574)) .saturating_add(Weight::from_parts(0, 3574))
// Standard Error: 94_524 // Standard Error: 11_381
.saturating_add(Weight::from_parts(940_486, 0).saturating_mul(k.into())) .saturating_add(Weight::from_parts(42_872, 0).saturating_mul(i.into()))
// Standard Error: 1_492
.saturating_add(Weight::from_parts(8_794, 0).saturating_mul(j.into()))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
/// 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`)
/// The range of component `n` is `[1, 20]`. /// The range of component `n` is `[1, 20]`.
fn update_network_name(n: u32, ) -> Weight { fn update_network_name(_n: u32, ) -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `295`
// Estimated: `3767` // Estimated: `3760`
// Minimum execution time: 49_906_000 picoseconds. // Minimum execution time: 50_224_000 picoseconds.
Weight::from_parts(55_537_587, 0) Weight::from_parts(54_405_362, 0)
.saturating_add(Weight::from_parts(0, 3767)) .saturating_add(Weight::from_parts(0, 3760))
// Standard Error: 87_704
.saturating_add(Weight::from_parts(92_366, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@ -83,13 +82,13 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// The range of component `n` is `[1, 150]`. /// The range of component `n` is `[1, 150]`.
fn update_network_endpoint(n: u32, ) -> Weight { fn update_network_endpoint(n: u32, ) -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `295`
// Estimated: `3767` // Estimated: `3760`
// Minimum execution time: 50_556_000 picoseconds. // Minimum execution time: 50_598_000 picoseconds.
Weight::from_parts(57_726_674, 0) Weight::from_parts(54_951_352, 0)
.saturating_add(Weight::from_parts(0, 3767)) .saturating_add(Weight::from_parts(0, 3760))
// Standard Error: 12_261 // Standard Error: 10_596
.saturating_add(Weight::from_parts(274, 0).saturating_mul(n.into())) .saturating_add(Weight::from_parts(11_691, 0).saturating_mul(n.into()))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@ -97,35 +96,23 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_finality_delay() -> Weight { fn update_network_finality_delay() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `295`
// Estimated: `3767` // Estimated: `3760`
// Minimum execution time: 49_406_000 picoseconds. // Minimum execution time: 49_089_000 picoseconds.
Weight::from_parts(51_256_000, 0) Weight::from_parts(50_797_000, 0)
.saturating_add(Weight::from_parts(0, 3767)) .saturating_add(Weight::from_parts(0, 3760))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
/// 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_network_rate_limit_delay() -> Weight { fn update_network_release_delay() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `295`
// Estimated: `3767` // Estimated: `3760`
// Minimum execution time: 49_572_000 picoseconds. // Minimum execution time: 49_606_000 picoseconds.
Weight::from_parts(52_584_000, 0) Weight::from_parts(50_371_000, 0)
.saturating_add(Weight::from_parts(0, 3767)) .saturating_add(Weight::from_parts(0, 3760))
.saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `GhostNetworks::Networks` (r:1 w:1)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_block_distance() -> Weight {
// Proof Size summary in bytes:
// Measured: `302`
// Estimated: `3767`
// Minimum execution time: 48_880_000 picoseconds.
Weight::from_parts(50_596_000, 0)
.saturating_add(Weight::from_parts(0, 3767))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@ -133,11 +120,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_type() -> Weight { fn update_network_type() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `295`
// Estimated: `3767` // Estimated: `3760`
// Minimum execution time: 48_282_000 picoseconds. // Minimum execution time: 48_135_000 picoseconds.
Weight::from_parts(49_137_000, 0) Weight::from_parts(48_619_000, 0)
.saturating_add(Weight::from_parts(0, 3767)) .saturating_add(Weight::from_parts(0, 3760))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@ -145,11 +132,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_gatekeeper() -> Weight { fn update_network_gatekeeper() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `295`
// Estimated: `3767` // Estimated: `3760`
// Minimum execution time: 50_853_000 picoseconds. // Minimum execution time: 50_027_000 picoseconds.
Weight::from_parts(51_982_000, 0) Weight::from_parts(51_212_000, 0)
.saturating_add(Weight::from_parts(0, 3767)) .saturating_add(Weight::from_parts(0, 3760))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@ -157,11 +144,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn update_network_topic_name() -> Weight { fn update_network_topic_name() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `295`
// Estimated: `3767` // Estimated: `3760`
// Minimum execution time: 50_343_000 picoseconds. // Minimum execution time: 50_686_000 picoseconds.
Weight::from_parts(52_380_000, 0) Weight::from_parts(52_276_000, 0)
.saturating_add(Weight::from_parts(0, 3767)) .saturating_add(Weight::from_parts(0, 3760))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@ -169,11 +156,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// 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_fee() -> Weight { fn update_incoming_network_fee() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `295`
// Estimated: `3767` // Estimated: `3760`
// Minimum execution time: 49_393_000 picoseconds. // Minimum execution time: 48_485_000 picoseconds.
Weight::from_parts(80_966_000, 0) Weight::from_parts(49_672_000, 0)
.saturating_add(Weight::from_parts(0, 3767)) .saturating_add(Weight::from_parts(0, 3760))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@ -181,11 +168,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// 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_fee() -> Weight { fn update_outgoing_network_fee() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `295`
// Estimated: `3767` // Estimated: `3760`
// Minimum execution time: 49_579_000 picoseconds. // Minimum execution time: 48_926_000 picoseconds.
Weight::from_parts(51_126_000, 0) Weight::from_parts(49_482_000, 0)
.saturating_add(Weight::from_parts(0, 3767)) .saturating_add(Weight::from_parts(0, 3760))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }
@ -193,11 +180,11 @@ impl<T: frame_system::Config> ghost_networks::WeightInfo for WeightInfo<T> {
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn remove_network() -> Weight { fn remove_network() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `302` // Measured: `295`
// Estimated: `3767` // Estimated: `3760`
// Minimum execution time: 44_634_000 picoseconds. // Minimum execution time: 45_163_000 picoseconds.
Weight::from_parts(45_815_000, 0) Weight::from_parts(45_822_000, 0)
.saturating_add(Weight::from_parts(0, 3767)) .saturating_add(Weight::from_parts(0, 3760))
.saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().reads(1))
.saturating_add(T::DbWeight::get().writes(1)) .saturating_add(T::DbWeight::get().writes(1))
} }

View File

@ -16,7 +16,7 @@
//! Autogenerated weights for `ghost_slow_clap` //! Autogenerated weights for `ghost_slow_clap`
//! //!
//! 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: 2025-06-19, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` //! DATE: 2024-08-02, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000` //! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz` //! HOSTNAME: `ghostown`, CPU: `Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024 //! WASM-EXECUTION: `Compiled`, CHAIN: `Some("casper-dev")`, DB CACHE: 1024
@ -47,61 +47,79 @@ use core::marker::PhantomData;
pub struct WeightInfo<T>(PhantomData<T>); pub struct WeightInfo<T>(PhantomData<T>);
impl<T: frame_system::Config> ghost_slow_clap::WeightInfo for WeightInfo<T> { impl<T: frame_system::Config> ghost_slow_clap::WeightInfo for WeightInfo<T> {
/// Storage: `GhostSlowClaps::Authorities` (r:1 w:0) /// Storage: `GhostSlowClaps::Authorities` (r:1 w:0)
/// Proof: `GhostSlowClaps::Authorities` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostSlowClaps::Authorities` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ReceivedClaps` (r:1 w:1) /// Storage: `GhostSlowClaps::AuthorityInfoInSession` (r:1 w:0)
/// Proof: `GhostSlowClaps::ReceivedClaps` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostSlowClaps::AuthorityInfoInSession` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ClapsInSession` (r:1 w:1) /// Storage: `GhostSlowClaps::ApplausesForTransaction` (r:1 w:0)
/// Proof: `GhostSlowClaps::ClapsInSession` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ApplausesForTransaction` (r:1 w:1)
/// Proof: `GhostSlowClaps::ApplausesForTransaction` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostSlowClaps::ApplausesForTransaction` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::NullifyNeeded` (r:1 w:0)
/// Proof: `GhostNetworks::NullifyNeeded` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::GatekeeperAmount` (r:1 w:1)
/// Proof: `GhostNetworks::GatekeeperAmount` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::BridgedImbalance` (r:1 w:1)
/// Proof: `GhostNetworks::BridgedImbalance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::AccumulatedCommission` (r:1 w:1)
/// Proof: `GhostNetworks::AccumulatedCommission` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn slow_clap() -> Weight {
// Proof Size summary in bytes:
// Measured: `355`
// Estimated: `3820`
// Minimum execution time: 213_817_000 picoseconds.
Weight::from_parts(216_977_000, 0)
.saturating_add(Weight::from_parts(0, 3820))
.saturating_add(T::DbWeight::get().reads(10))
.saturating_add(T::DbWeight::get().writes(7))
}
/// Storage: `GhostSlowClaps::ReceivedClaps` (r:1 w:0) /// Storage: `GhostSlowClaps::ReceivedClaps` (r:1 w:0)
/// Proof: `GhostSlowClaps::ReceivedClaps` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostSlowClaps::ReceivedClaps` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::Authorities` (r:1 w:0) /// The range of component `k` is `[1, 100]`.
/// Proof: `GhostSlowClaps::Authorities` (`max_values`: None, `max_size`: None, mode: `Measured`) /// The range of component `j` is `[1, 20]`.
/// Storage: `GhostSlowClaps::ApplausesForTransaction` (r:1 w:1) fn slow_clap(k: u32, j: u32, ) -> Weight {
/// Proof: `GhostSlowClaps::ApplausesForTransaction` (`max_values`: None, `max_size`: None, mode: `Measured`) // Proof Size summary in bytes:
/// Storage: `GhostNetworks::NullifyNeeded` (r:1 w:0) // Measured: `372 + j * (19 ±0)`
/// Proof: `GhostNetworks::NullifyNeeded` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) // Estimated: `3853 + j * (19 ±0)`
// Minimum execution time: 95_459_000 picoseconds.
Weight::from_parts(96_224_000, 0)
.saturating_add(Weight::from_parts(0, 3853))
// Standard Error: 152_014
.saturating_add(Weight::from_parts(32_092_278, 0).saturating_mul(k.into()))
// Standard Error: 761_228
.saturating_add(Weight::from_parts(22_412_712, 0).saturating_mul(j.into()))
.saturating_add(T::DbWeight::get().reads(4))
.saturating_add(Weight::from_parts(0, 19).saturating_mul(j.into()))
}
/// Storage: `GhostSlowClaps::CurrentCompanionId` (r:1 w:1)
/// Proof: `GhostSlowClaps::CurrentCompanionId` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:0) /// Storage: `GhostNetworks::Networks` (r:1 w:0)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::GatekeeperAmount` (r:1 w:1) /// Storage: `GhostSlowClaps::Companions` (r:0 w:1)
/// Proof: `GhostNetworks::GatekeeperAmount` (`max_values`: None, `max_size`: None, mode: `Measured`) /// Proof: `GhostSlowClaps::Companions` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::BridgedImbalance` (r:1 w:1) /// Storage: `GhostSlowClaps::CompanionDetails` (r:0 w:1)
/// Proof: `GhostNetworks::BridgedImbalance` (`max_values`: Some(1), `max_size`: None, mode: `Measured`) /// Proof: `GhostSlowClaps::CompanionDetails` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::AccumulatedCommission` (r:1 w:1) fn propose_companion() -> Weight {
/// Proof: `GhostNetworks::AccumulatedCommission` (`max_values`: Some(1), `max_size`: None, mode: `Measured`)
/// Storage: `System::Account` (r:1 w:1)
/// Proof: `System::Account` (`max_values`: None, `max_size`: Some(128), added: 2603, mode: `MaxEncodedLen`)
fn self_applause() -> Weight {
// Proof Size summary in bytes: // Proof Size summary in bytes:
// Measured: `655` // Measured: `634`
// Estimated: `4120` // Estimated: `4099`
// Minimum execution time: 210_676_000 picoseconds. // Minimum execution time: 167_770_000 picoseconds.
Weight::from_parts(212_905_000, 0) Weight::from_parts(168_826_000, 0)
.saturating_add(Weight::from_parts(0, 4120)) .saturating_add(Weight::from_parts(0, 4099))
.saturating_add(T::DbWeight::get().reads(9)) .saturating_add(T::DbWeight::get().reads(2))
.saturating_add(T::DbWeight::get().writes(5)) .saturating_add(T::DbWeight::get().writes(3))
}
/// Storage: `GhostSlowClaps::Companions` (r:1 w:0)
/// Proof: `GhostSlowClaps::Companions` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostNetworks::Networks` (r:1 w:0)
/// Proof: `GhostNetworks::Networks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::CompanionDetails` (r:1 w:0)
/// Proof: `GhostSlowClaps::CompanionDetails` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::ReleaseBlocks` (r:0 w:1)
/// Proof: `GhostSlowClaps::ReleaseBlocks` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn release_companion() -> Weight {
// Proof Size summary in bytes:
// Measured: `839`
// Estimated: `4304`
// Minimum execution time: 82_884_000 picoseconds.
Weight::from_parts(84_135_000, 0)
.saturating_add(Weight::from_parts(0, 4304))
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(1))
}
/// Storage: `GhostSlowClaps::ReleaseBlocks` (r:1 w:0)
/// Proof: `GhostSlowClaps::ReleaseBlocks` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::Companions` (r:1 w:1)
/// Proof: `GhostSlowClaps::Companions` (`max_values`: None, `max_size`: None, mode: `Measured`)
/// Storage: `GhostSlowClaps::CompanionDetails` (r:1 w:1)
/// Proof: `GhostSlowClaps::CompanionDetails` (`max_values`: None, `max_size`: None, mode: `Measured`)
fn kill_companion() -> Weight {
// Proof Size summary in bytes:
// Measured: `514`
// Estimated: `3979`
// Minimum execution time: 152_418_000 picoseconds.
Weight::from_parts(153_436_000, 0)
.saturating_add(Weight::from_parts(0, 3979))
.saturating_add(T::DbWeight::get().reads(3))
.saturating_add(T::DbWeight::get().writes(2))
} }
} }

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;
@ -18,7 +17,7 @@ pub mod pallet_nomination_pools;
pub mod pallet_preimage; pub mod pallet_preimage;
pub mod pallet_proxy; pub mod pallet_proxy;
pub mod pallet_ranked_collective; pub mod pallet_ranked_collective;
pub mod pallet_referenda; // pub mod pallet_referenda;
pub mod pallet_salary; pub mod pallet_salary;
pub mod pallet_scheduler; pub mod pallet_scheduler;
pub mod pallet_session; pub mod pallet_session;

View File

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

View File

@ -1,13 +1,11 @@
use frame_support::traits::tokens::{Pay, PaymentStatus};
use pallet_treasury::ArgumentsFactory;
use primitives::{AccountId, Balance}; use primitives::{AccountId, Balance};
use pallet_treasury::ArgumentsFactory;
use sp_core::crypto::FromEntropy; use sp_core::crypto::FromEntropy;
use frame_support::traits::tokens::{Pay, PaymentStatus};
pub struct BenchmarkTreasuryHelper; pub struct BenchmarkTreasuryHelper;
impl ArgumentsFactory<(), AccountId> for BenchmarkTreasuryHelper { 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(seed: [u8; 32]) -> AccountId {
AccountId::from_entropy(&mut seed.as_slice()).unwrap() AccountId::from_entropy(&mut seed.as_slice()).unwrap()
} }
@ -21,16 +19,8 @@ impl Pay for BenchmarkTreasuryPaymaster {
type AssetKind = (); type AssetKind = ();
type Error = (); type Error = ();
fn pay( fn pay(_: &Self::Beneficiary, _: Self::AssetKind, _: Self::Balance) -> Result<Self::Id, Self::Error> { Ok(()) }
_: &Self::Beneficiary, fn check_payment(_: Self::Id) -> PaymentStatus { PaymentStatus::Success }
_: Self::AssetKind,
_: Self::Balance,
) -> Result<Self::Id, Self::Error> {
Ok(())
}
fn check_payment(_: Self::Id) -> PaymentStatus {
PaymentStatus::Success
}
fn ensure_successful(_: &Self::Beneficiary, _: Self::AssetKind, _: Self::Balance) {} fn ensure_successful(_: &Self::Beneficiary, _: Self::AssetKind, _: Self::Balance) {}
fn ensure_concluded(_: Self::Id) {} fn ensure_concluded(_: Self::Id) {}
} }

View File

@ -55,7 +55,7 @@ mod tests {
parameter_types, parameter_types,
traits::{ traits::{
tokens::{PayFromAccount, UnityAssetBalanceConversion}, tokens::{PayFromAccount, UnityAssetBalanceConversion},
ConstU32, FindAuthor, ConstU32, FindAuthor
}, },
weights::Weight, weights::Weight,
PalletId, PalletId,
@ -65,7 +65,7 @@ mod tests {
use sp_core::{ConstU64, H256}; use sp_core::{ConstU64, H256};
use sp_runtime::{ use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup}, traits::{BlakeTwo256, IdentityLookup},
BuildStorage, Perbill, Perbill, BuildStorage,
}; };
type Block = frame_system::mocking::MockingBlock<Test>; type Block = frame_system::mocking::MockingBlock<Test>;
@ -172,10 +172,7 @@ mod tests {
pub struct OneAuthor; pub struct OneAuthor;
impl FindAuthor<AccountId> for OneAuthor { impl FindAuthor<AccountId> for OneAuthor {
fn find_author<'a, I>(_: I) -> Option<AccountId> fn find_author<'a, I>(_: I) -> Option<AccountId> where I: 'a {
where
I: 'a,
{
Some(TEST_ACCOUNT) Some(TEST_ACCOUNT)
} }
} }
@ -188,9 +185,7 @@ mod tests {
} }
pub fn new_test_ext() -> sp_io::TestExternalities { pub fn new_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::default() let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
.build_storage::<Test>()
.unwrap();
// We use default for brevity, but you can configure as desired if needed. // We use default for brevity, but you can configure as desired if needed.
pallet_balances::GenesisConfig::<Test>::default() pallet_balances::GenesisConfig::<Test>::default()
.assimilate_storage(&mut t) .assimilate_storage(&mut t)
@ -201,14 +196,8 @@ mod tests {
#[test] #[test]
fn test_fees_and_tips_split() { fn test_fees_and_tips_split() {
new_test_ext().execute_with(|| { new_test_ext().execute_with(|| {
let fee = let fee = <paller_balances::Pallet<Test> as frame_support::traits::fungible::Balanced<AccountId>>::issue(10);
<paller_balances::Pallet<Test> as frame_support::traits::fungible::Balanced< let tip = <paller_balances::Pallet<Test> as frame_support::traits::fungible::Balanced<AccountId>>::issue(20);
AccountId,
>>::issue(10);
let tip =
<paller_balances::Pallet<Test> as frame_support::traits::fungible::Balanced<
AccountId,
>>::issue(20);
assert_eq!(Balances::free_balance(Treasury::account_id()), 0); assert_eq!(Balances::free_balance(Treasury::account_id()), 0);
assert_eq!(Balances::free_balance(TEST_ACCOUNT), 0); assert_eq!(Balances::free_balance(TEST_ACCOUNT), 0);
@ -253,23 +242,11 @@ mod tests {
#[test] #[test]
fn era_payout_should_give_sensible_results() { fn era_payout_should_give_sensible_results() {
assert_eq!( assert_eq!(
era_payout( era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0, ),
75,
100,
Perquintill::from_percent(10),
Perquintill::one(),
0,
),
(10, 0) (10, 0)
); );
assert_eq!( assert_eq!(
era_payout( era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0, ),
80,
100,
Perquintill::from_percent(10),
Perquintill::one(),
0,
),
(6, 4) (6, 4)
); );
} }

View File

@ -1,7 +1,7 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
pub mod elections;
pub mod impls; pub mod impls;
pub mod elections;
#[cfg(feature = "try-runtime")] #[cfg(feature = "try-runtime")]
pub mod elections; pub mod elections;
@ -10,8 +10,7 @@ pub mod elections;
pub mod benchmarking; pub mod benchmarking;
use frame_support::{ use frame_support::{
parameter_types, parameter_types, traits::ConstU32,
traits::ConstU32,
weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight}, weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight},
}; };
use frame_system::limits; use frame_system::limits;
@ -93,8 +92,8 @@ macro_rules! impl_runtime_weights {
use frame_system::limits; use frame_system::limits;
use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment}; use pallet_transaction_payment::{Multiplier, TargetedFeeAdjustment};
pub use runtime_common::{ pub use runtime_common::{
impl_elections_weights, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT, impl_elections_weights, AVERAGE_ON_INITIALIZE_RATIO,
NORMAL_DISPATCH_RATIO, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO,
}; };
use sp_runtime::{FixedPointNumber, Perquintill}; use sp_runtime::{FixedPointNumber, Perquintill};
@ -102,7 +101,8 @@ macro_rules! impl_runtime_weights {
// Expose the weight from the runtime constants module. // Expose the weight from the runtime constants module.
pub use $runtime::weights::{ pub use $runtime::weights::{
BlockExecutionWeight, ExtrinsicBaseWeight, ParityDbWeight, RocksDbWeight, BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight,
ParityDbWeight,
}; };
parameter_types! { parameter_types! {
@ -129,6 +129,7 @@ macro_rules! impl_runtime_weights {
}; };
} }
/// The type used for currency conversion. /// The type used for currency conversion.
/// ///
/// This must be only be used as long as the balance type is `u128`. /// This must be only be used as long as the balance type is `u128`.

View File

@ -4,7 +4,7 @@ use frame_support::{
}; };
use pallet_fast_unstake::{Pallet as FastUnstake, *}; use pallet_fast_unstake::{Pallet as FastUnstake, *};
use pallet_staking::*; use pallet_staking::*;
use sp_std::{collections::btree_set::BTreeSet, prelude::*}; use sp_std::{collections::btree_set::BTreeSet, prelude:*};
/// Register all inactive nominators for fast unstake, and progress until they /// Register all inactive nominators for fast unstake, and progress until they
/// have all benn processed. /// have all benn processed.
@ -16,9 +16,7 @@ where
let mut unstaked_err = 0; let mut unstaked_err = 0;
let mut unstaked_slashed = 0; let mut unstaked_slashed = 0;
let all_stakers = Ledger::<T>::iter() let all_stakers = Ledger::<T>::iter().map(|(ctrl, l)| (ctrl, l.stash)).collect::<BTreeSet<_>>();
.map(|(ctrl, l)| (ctrl, l.stash))
.collect::<BTreeSet<_>>();
let mut all_exposed = BTreeSet::new(); let mut all_exposed = BTreeSet::new();
ErasStakers::<T>::iter().for_each(|(_, val, expo)| { ErasStakers::<T>::iter().for_each(|(_, val, expo)| {
all_exposed.insert(val); all_exposed.insert(val);
@ -72,16 +70,15 @@ where
maybe_fast_unstake_event maybe_fast_unstake_event
}) })
.for_each(|e: pallet_fast_unstake::Event<T>| match e { .for_each(|e: pallet_fast_unstake::Event<T>| match e {
pallet_fast_unstake::Event::<T>::Unstaked { result, .. } => { pallet_fast_unstake::Event<T>::Unstaked { result, .. } =>
if result.is_ok() { if result.is_ok() {
unstaked_ok += 1; unstaked_ok += 1;
} else { } else {
unstaked_err += 1; unstaked_err += 1;
} },
}
pallet_fast_unstake::Event::<T>::Slashed { .. } => unstaked_slashed += 1, pallet_fast_unstake::Event::<T>::Slashed { .. } => unstaked_slashed += 1,
pallet_fast_unstake::Event::<T>::InternalError { .. } => unreachable!(), pallet_fast_unstake::Event::<T>::InternalError { .. } => unreachable!(),
_ => {} _ => {},
}); });
if now % 100u32.into() == sp_runtime::traits::Zero::zero() { if now % 100u32.into() == sp_runtime::traits::Zero::zero() {

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
@ -80,30 +79,6 @@ extract_seed() {
echo $seed echo $seed
} }
downgrade_compiler_if_needed() {
echo "[+] fetching the latest ghost-node source code"
git switch main
git pull origin main
# 1.86.0 works fine, tested with:
# 1.87.0 throws errors during compilation
# 1.88.0 throws errors during compilation
LATEST_TESTED_VERSION=86
cargo_version=$(cargo --version | cut -d'.' -f2)
if [ "$cargo_version" -gt "$LATEST_TESTED_VERSION" ]; then
echo "[+] downgrading rustc compiler version to 1.86.0"
rustup default 1.86.0
toolchain_name=$(rustup show | grep default | head -n 1 | cut -d' ' -f1)
rustup target add wasm32-unknown-unknown --toolchain $toolchain_name
rustup component add rust-src --toolchain $toolchain_name
cd $PROJECT_FOLDER
echo "[+] clean build cache..."
cargo clean
else
echo "[+] rustc compiler version is compatible"
fi
}
help() { help() {
echo -e "Ghost Node Build automation tool. Helper for Ghost Node environment preparation.\n" echo -e "Ghost Node Build automation tool. Helper for Ghost Node environment preparation.\n"
echo -e "With no OPTION nothing will happen, possible OPTION:\n" echo -e "With no OPTION nothing will happen, possible OPTION:\n"
@ -121,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."
} }
@ -189,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
@ -204,51 +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
downgrade_compiler_if_needed
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/casper_staging_testnet"
cd $PROJECT_FOLDER
git pull origin main
echo "[+] starting build in 3 seconds..."
sleep 3
cargo build --release
printf "[?] are you ready to continue?"
read anything
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"
@ -327,15 +253,16 @@ if [[ $SET_ENVIRONMENT = true ]]; then
if prompt "[?] setup the rust environment (e.g. WASM support)?"; then if prompt "[?] setup the rust environment (e.g. WASM support)?"; then
rustup default stable rustup default stable
downgrade_compiler_if_needed rustup update
rustup target add wasm32-unknown-unknown
rustup component add rust-src
fi fi
fi fi
if [[ ! -z $RELEASE ]]; then if [[ ! -z $RELEASE ]]; then
downgrade_compiler_if_needed
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
@ -420,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")

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,7 +1,7 @@
use keyring::Sr25519Keyring;
use primitives::AccountId; use primitives::AccountId;
use sc_client_api::UsageProvider; use sc_client_api::UsageProvider;
use sp_runtime::OpaqueExtrinsic; use sp_runtime::OpaqueExtrinsic;
use keyring::Sr25519Keyring;
use crate::*; use crate::*;
@ -21,41 +21,27 @@ macro_rules! identify_chain {
{ {
use ghost_runtime as runtime; use ghost_runtime as runtime;
let call = $generic_code; let call = $generic_code;
Ok(ghost_sign_call( Ok(ghost_sign_call(call, $nonce, $current_block, $period, $genesis, $signer))
call,
$nonce,
$current_block,
$period,
$genesis,
$signer,
))
} }
#[cfg(not(feature = "ghost-native"))] #[cfg(not(feature = "ghost-native"))]
{ {
Err("`ghost-native` feature not enabled") Err("`ghost-native` feature not enabled")
} }
} },
Chain::Casper => { Chain::Casper => {
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
{ {
use casper_runtime as runtime; use casper_runtime as runtime;
let call = $generic_code; let call = $generic_code;
Ok(casper_sign_call( Ok(casper_sign_call(call, $nonce, $current_block, $period, $genesis, $signer))
call,
$nonce,
$current_block,
$period,
$genesis,
$signer,
))
} }
#[cfg(not(feature = "casper-native"))] #[cfg(not(feature = "casper-native"))]
{ {
Err("`casper-native` feature not enabled") Err("`casper-native` feature not enabled")
} }
} },
Chain::Unknown => { Chain::Unknown => {
let _ = $nonce; let _ = $nonce;
let _ = $current_block; let _ = $current_block;
@ -64,7 +50,7 @@ macro_rules! identify_chain {
let _ = $signer; let _ = $signer;
Err("Unknown chain") Err("Unknown chain")
} },
} }
}; };
} }
@ -119,11 +105,7 @@ pub struct TransferKeepAliveBuilder {
impl TransferKeepAliveBuilder { impl TransferKeepAliveBuilder {
pub fn new(client: Arc<FullClient>, dest: AccountId, chain: Chain) -> Self { pub fn new(client: Arc<FullClient>, dest: AccountId, chain: Chain) -> Self {
Self { Self { client, dest, chain }
client,
dest,
chain,
}
} }
} }
@ -177,9 +159,10 @@ fn casper_sign_call(
frame_system::CheckSpecVersion::<casper_runtime::Runtime>::new(), frame_system::CheckSpecVersion::<casper_runtime::Runtime>::new(),
frame_system::CheckTxVersion::<casper_runtime::Runtime>::new(), frame_system::CheckTxVersion::<casper_runtime::Runtime>::new(),
frame_system::CheckGenesis::<casper_runtime::Runtime>::new(), frame_system::CheckGenesis::<casper_runtime::Runtime>::new(),
frame_system::CheckMortality::<casper_runtime::Runtime>::from( frame_system::CheckMortality::<casper_runtime::Runtime>::from(sp_runtime::generic::Era::mortal(
sp_runtime::generic::Era::mortal(period, current_block), period,
), current_block,
)),
frame_system::CheckNonce::<casper_runtime::Runtime>::from(nonce), frame_system::CheckNonce::<casper_runtime::Runtime>::from(nonce),
frame_system::CheckWeight::<casper_runtime::Runtime>::new(), frame_system::CheckWeight::<casper_runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<casper_runtime::Runtime>::from(0), pallet_transaction_payment::ChargeTransactionPayment::<casper_runtime::Runtime>::from(0),
@ -206,8 +189,7 @@ fn casper_sign_call(
sp_runtime::AccountId32::from(acc.public()).into(), sp_runtime::AccountId32::from(acc.public()).into(),
primitives::Signature::Sr25519(signature), primitives::Signature::Sr25519(signature),
extra, extra,
) ).into()
.into()
} }
pub fn benchmark_inherent_data() -> std::result::Result<inherents::InherentData, inherents::Error> { pub fn benchmark_inherent_data() -> std::result::Result<inherents::InherentData, inherents::Error> {

View File

@ -2,13 +2,13 @@
use codec::Encode; use codec::Encode;
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
use babe_primitives::AuthorityId as BabeId;
use ghost_slow_clap::sr25519::AuthorityId as SlowClapId; use ghost_slow_clap::sr25519::AuthorityId as SlowClapId;
use primitives::{AccountId, AccountPublic};
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
use grandpa_primitives::AuthorityId as GrandpaId; use grandpa_primitives::AuthorityId as GrandpaId;
use babe_primitives::AuthorityId as BabeId;
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
use pallet_staking::Forcing; use pallet_staking::Forcing;
use primitives::{AccountId, AccountPublic};
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
use casper_runtime as casper; use casper_runtime as casper;
@ -76,6 +76,7 @@ fn casper_session_keys(
} }
} }
pub fn casper_chain_spec_properties() -> serde_json::map::Map<String, serde_json::Value> { pub fn casper_chain_spec_properties() -> serde_json::map::Map<String, serde_json::Value> {
serde_json::json!({ serde_json::json!({
"ss58Format": 1996, "ss58Format": 1996,
@ -160,59 +161,42 @@ fn casper_testnet_accounts() -> Vec<AccountId> {
fn casper_testnet_evm_accounts() -> Vec<(AccountId, u128, u8)> { fn casper_testnet_evm_accounts() -> Vec<(AccountId, u128, u8)> {
vec![ vec![
// 01c928771aea942a1e7ac06adf2b73dfbc9a25d9eaa516e3673116af7f345198 // 01c928771aea942a1e7ac06adf2b73dfbc9a25d9eaa516e3673116af7f345198
( (get_account_id_from_seed::<sr25519::Public>("1A69d2D5568D1878023EeB121a73d33B9116A760"), 1337 * CSPR, 1),
get_account_id_from_seed::<sr25519::Public>("1A69d2D5568D1878023EeB121a73d33B9116A760"),
1337 * CSPR,
1,
),
// b19a435901872f817185f7234a1484eae837613f9d10cf21927a23c2d8cb9139 // b19a435901872f817185f7234a1484eae837613f9d10cf21927a23c2d8cb9139
( (get_account_id_from_seed::<sr25519::Public>("2f86cfBED3fbc1eCf2989B9aE5fc019a837A9C12"), 1337 * CSPR, 2),
get_account_id_from_seed::<sr25519::Public>("2f86cfBED3fbc1eCf2989B9aE5fc019a837A9C12"),
1337 * CSPR,
2,
),
// d3baf57b74d65719b2dc33f5a464176022d0cc5edbca002234229f3e733875fc // d3baf57b74d65719b2dc33f5a464176022d0cc5edbca002234229f3e733875fc
( (get_account_id_from_seed::<sr25519::Public>("e83f67361Ac74D42A48E2DAfb6706eb047D8218D"), 69 * CSPR, 3),
get_account_id_from_seed::<sr25519::Public>("e83f67361Ac74D42A48E2DAfb6706eb047D8218D"),
69 * CSPR,
3,
),
// c4683d566436af6b58b4a59c8f501319226e85b21869bf93d5eeb4596d4791d4 // c4683d566436af6b58b4a59c8f501319226e85b21869bf93d5eeb4596d4791d4
( (get_account_id_from_seed::<sr25519::Public>("827ee4ad9b259b6fa1390ed60921508c78befd63"), 69 * CSPR, 4),
get_account_id_from_seed::<sr25519::Public>("827ee4ad9b259b6fa1390ed60921508c78befd63"),
69 * CSPR,
4,
),
] ]
} }
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>)> { fn casper_testnet_evm_networks() -> Vec<(u32, Vec<u8>)> {
vec![( vec![
11155111, (1, ghost_networks::NetworkData {
ghost_networks::NetworkData { chain_name: "ethereum-mainnet".into(),
chain_name: "sepolia-ethereum-testnet".into(), default_endpoint: "https://nd-422-757-666.p2pify.com/0a9d79d93fb2f4a4b1e04695da2b77a7/".into(),
default_endpoints: vec![ finality_delay: Some(40u64),
"https://sepolia.drpc.org".into(), release_delay: Some(80u64),
"https://sepolia.gateway.tenderly.co".into(),
"https://api.zan.top/eth-sepolia".into(),
"https://rpc.sepolia.ethpandaops.io".into(),
"https://ethereum-sepolia-rpc.publicnode.com".into(),
"https://1rpc.io/sepolia".into(),
"https://0xrpc.io/sep".into(),
"https://eth-sepolia.api.onfinality.io/public".into(),
],
finality_delay: 69u64,
rate_limit_delay: 5_000u64,
block_distance: 20u64,
network_type: ghost_networks::NetworkType::Evm, network_type: ghost_networks::NetworkType::Evm,
gatekeeper: "0xc85129A097773B7F8970a7364c928C05f265E6A1".into(), gatekeeper: "0x4d224452801aced8b2f0aebe155379bb5d594381".into(),
topic_name: "0x7ab52ec05c331e6257a3d705d6bea6e4c27277351764ad139209e06b203811a6".into(), topic_name: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef".into(),
incoming_fee: 69_000_000u32, incoming_fee: 0u32,
outgoing_fee: 0u32, outgoing_fee: 0u32,
} }.encode()),
.encode(), (56, ghost_networks::NetworkData {
)] chain_name: "bnb-mainnet".into(),
default_endpoint: "https://bsc-mainnet.core.chainstack.com/35848e183f3e3303c8cfeacbea831cab/".into(),
finality_delay: Some(20u64),
release_delay: Some(40u64),
network_type: ghost_networks::NetworkType::Evm,
gatekeeper: "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82".into(),
topic_name: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef".into(),
incoming_fee: 0u32,
outgoing_fee: 0u32,
}.encode())
]
} }
/// Helper function to create casper `GenesisConfig` for testing /// Helper function to create casper `GenesisConfig` for testing
@ -230,11 +214,14 @@ pub fn testnet_config_genesis(
ghost_accounts: Option<Vec<(AccountId, u128, u8)>>, ghost_accounts: Option<Vec<(AccountId, u128, u8)>>,
evm_networks: Option<Vec<(u32, Vec<u8>)>>, evm_networks: Option<Vec<(u32, Vec<u8>)>>,
) -> serde_json::Value { ) -> serde_json::Value {
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(casper_testnet_accounts); let endowed_accounts: Vec<AccountId> = endowed_accounts
.unwrap_or_else(casper_testnet_accounts);
let ghost_accounts: Vec<(AccountId, u128, u8)> = ghost_accounts.unwrap_or_default(); let ghost_accounts: Vec<(AccountId, u128, u8)> = ghost_accounts
.unwrap_or_default();
let evm_networks: Vec<(u32, Vec<u8>)> = evm_networks.unwrap_or_default(); let evm_networks: Vec<(u32, Vec<u8>)> = evm_networks
.unwrap_or_default();
const ENDOWMENT: u128 = 1_000 * CSPR; const ENDOWMENT: u128 = 1_000 * CSPR;
const STASH: u128 = 500 * CSPR; const STASH: u128 = 500 * CSPR;
@ -283,11 +270,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,
}, },
@ -306,6 +288,148 @@ fn casper_staging_config_genesis() -> serde_json::Value {
use hex_literal::hex; use hex_literal::hex;
use sp_core::crypto::UncheckedInto; use sp_core::crypto::UncheckedInto;
// Endowments for the whales from previous testnet.
let whales_endowments = [
// sfHXFVNvLVp8uSZauMyMijqXfoods8kkkik2MKnmr5MTdsweh
(hex!["a8ab31b36aae0dc29d2b92714cee75ee2784037c6f150d759d9aa757ab5a4666"].into(), 25 * CSPR),
// sfEtW9ijdwbU17oderTmwseMV84c7c9Xi1JW7T94rBbYKMMZq
(hex!["342c0035531136ff50d8488eb4d4772dfd10e565f6a5d28c7298b354d33f2dfe"].into(), 14 * CSPR),
// sfJtE2J5yVQBHdzwmXhzTwQZLtS853MFkUVYv5AfnB7TEVp2E
(hex!["e4e6a493d23633bf72b16ead89ab1451611b08311a9a49cc874a92e6ac4f5b1d"].into(), 31 * CSPR),
// sfFf48EnVLjD4wMecZh7meP5RWwYXZr54QiW2xQyPKPjxsxNo
(hex!["56266f27a02869f9498a113cbd4d1507ae5f4b8c91a6b8ccecda3331c21fd67f"].into(), 6 * CSPR),
// sfHxHVmMKZfUUzXRzKrV3oXSSynG1uAJ7c6dhFSq4CwE8qLn3
(hex!["bbc31594a2338e91c248aba474d892f41811a072c7e7c692fcae07fdb398b89f"].into(), 3 * CSPR),
// sfGvSkgfv99AndiEuhmL6t49ekbb2og2aYVRisAeNMPHueACW
(hex!["8e1f85cc6bb89182bc473859287b82fc2b9c89f461431090c2246a1a8d92d911"].into(), 14 * CSPR),
// sfHfByscdWfjzQNXc5g2q2ScMhop5pr5TiqiZosKxtMit1bRy
(hex!["aeb95893ab118bf02f5cd80ebab71ba58490c645e4302773fdc90b659f5c5e22"].into(), 11 * CSPR),
// sfGh1jtdTwWEco2N6cymxKgaoAJwYFMj2K2tdEbuML5LjUprc
(hex!["83e120fa3994efedc51092a8d90882803997f39f552a37699e3acb06c1f8158d"].into(), 28 * CSPR),
// sfJHvJDgdKdo1ZFXB146jhKVgngDrDeKTKF3GV5Eyvg1tJqTq
(hex!["cabca1450cbdc5769fa8f7b80d5bfd00df35b65613d8694e02517c9415fc5462"].into(), 12 * CSPR),
// sfE4SvLvh66FSThDnrTx5Qf5vHNCmBkrAJy8Zt8pMPN8h6dzw
(hex!["0f85589e37f3c0859ba7c055dec527a63796d6285b73cf8bd4657da052ff893c"].into(), 2 * CSPR),
// sfHJF1dYfzCpjJ8QHRBexNMfvSfsJvE75eCzgosrB6PwFXmpz
(hex!["9ebf64b6bc73baf1428da1cfcf36fde9695be0a56a855ddabb5612a70b10e447"].into(), 6 * CSPR),
// sfEEixqLWYct7au1PWkQAKbyso5VQhrgXQ2RXVW5TjcBm3vZ6
(hex!["175bce3674e24ec942112d91df594ba551b329ae7183b0faaef79fa051a85948"].into(), 21 * CSPR),
// sfH5nCFu2wNXnfD1Fic1weyLHncxHb7qpa8yXXQuNbQRUm9HH
(hex!["953e2cdbf7a66e34c50c51d199ad8970b1b2233da5604eb79a1de8d277c03061"].into(), 10 * CSPR),
// sfJnVLd4PMfoABtQiPmifeqkpQQKoV4wbXyAzhXKdSDHfi1bY
(hex!["e086ba892126243d6ef1c2b9132790e4455a3b1271baac8033306d55c8473af4"].into(), 30 * CSPR),
// sfECamJamifU5XyHH27ekuWY3MHAwj1z3rDcV2rpWdeGdAe2Y
(hex!["15b9b710a589968804e6e00f2ccb576ded431627a733b7f9fa0845f59e73f5cc"].into(), 31 * CSPR),
// sfEAhZrKxxChBR5SHQML6gNDJCK2FTMnRZZ2s2KVCFRxqFFTG
(hex!["144a1fa97fdba679efd2a36696a0d40f585b649143bb7da5cbd7458ea4a0f674"].into(), 2 * CSPR),
// sfDrDchmoxEfzyyPFWGX2fekP4mic99D6inhPnRvwokRZCbv5
(hex!["06319d9539108995233c48032bda04d50115fe829a2c4b5b23e54a4d17188606"].into(), 14 * CSPR),
// sfEb6NRc4ZbcuWUGJAnBkvEoacoXLbHZSM1asLpHiXqeY6YkE
(hex!["26e4c66dab5d9df3cb196ce320314e2565489f7d56b9868299a68cc4a1b4c917"].into(), 24 * CSPR),
// sfHfQMwpzNaA3D1uRGrzNPwZDeFbdXQDBJMay1oFDmD7C2RLn
(hex!["aee305cf2e015ef860c96815bb34ff9ac7df36db95f0587b6ded75218ae0d526"].into(), 22 * CSPR),
// sfKPnkuxV9u7AEk6bqU4i83NpAeG5w6VjcXYER5yfoojkkcN4
(hex!["fb72f46bd61ce821d12f5bdd6dc587afe5ae5821632b7e4b09464ea9e04111e3"].into(), 4 * CSPR),
// sfJGyU6k2gPVhmQJvgtY3iaVsakKQuD56jdgKZTGRLwjkHcbQ
(hex!["ca040e9167e0e7675ea2163506706cb7883a601a9ece1ba702fd253446f69e5d"].into(), 19 * CSPR),
// sfF8tAs7Z9R3GU8AnWgHEubxbwGt4zk7V6gSBeJJSqvt1xs8e
(hex!["3f238fbe70fdf9df12ed42416be91fa556802e7be7ea43c4de33314f5fb2da53"].into(), 22 * CSPR),
// sfHtQ3XxjAc3fbr4rxnx5P5ejV7LPXnN8nXwxevJ5MZwPJFCa
(hex!["b8cc24f449bd14c9903431b710842e1398a83d2ced33c5ea8fa4b75461db2f1f"].into(), 28 * CSPR),
// sfG5KDhmeKs6jXC2Jt1otffwHQyLR58dMGHwJCizUJHr4a7pU
(hex!["68a722b719350846a1f5a83143e01fdf18422d0d3d489877510062498ba74e5b"].into(), 17 * CSPR),
// sfH28MB4HFrE8YmtAcj95oTyMsQ9GgYWqxVtisWPqV5SwSMVS
(hex!["9275098141352f7e4fb3a4be9b2e50269947b7f54ecf2a493454955dd327274a"].into(), 28 * CSPR),
// sfEBNrjumQ8GLJTxeu3HvUDqHki3UxHCoSzg1x8SDJkfWfhWc
(hex!["14ce63bf285ad88594a93af2f1b8fd822c4db73030ae0783836083201876cb71"].into(), 14 * CSPR),
// sfFMYowKRoik3N9tYoSaPZ4vGPaPrDaezXiTVGZUBGWEwSKWQ
(hex!["48cc93d26f56df01cbd642e2d6eca745a9e2b84616e7f3b405411963c9aefa2f"].into(), 11 * CSPR),
// sfHPg4uVcq3s3TnfqHcsT6nEmeKJuNiJCW2eHk8Uk5aRfS7jr
(hex!["a2e3f7cfc7d8b7992a17b7aa8a85b47f1e0d254f3f0b760764f79af5a8349b33"].into(), 22 * CSPR),
// sfFo97CYcVqhjeiQiu6umcDggkNRWNjNu3XA6pU67F2C4Zs7g
(hex!["5c512b2cdb7da57ac056d6573ae3d1ae027bcec1b3b3d4dd79dc50160b24101b"].into(), 3 * CSPR),
// sfGxyWHjTMDVfmScYXjRFwXuVLyPj6XB8nzVjeZTLZ8RQkXQU
(hex!["900d88832e0748670c2358f2238bd34aaf49e070aa41aba84d931a0d1fef0978"].into(), 15 * CSPR),
// sfJHHLnAf9kbZz1PL4ESDpEMuAw7GXfFigC9wJD7ZArqRPwVG
(hex!["ca4039b68f9924c12399808da77247f2f45b0a9e397de94a33104c610cd8287f"].into(), 1 * CSPR),
// sfHqoR2AnJgWckgFY4HE2p5SK5gf6mUZGCXV5S3Ck7mnpTWps
(hex!["b6d11481813a6968a1d056794e6f0b85408480c5e8a6056769fbec9b5424314d"].into(), 18 * CSPR),
// sfJCVDhbVQzg7Y9JTm9mYiowUg2SuGQLLKGPwtstLVgtrcnmu
(hex!["c697fbb0ecf8069a0f88292d0a2097ba24b8c6998d04d21a02d92f6a23a65b43"].into(), 11 * CSPR),
// sfFFc7sBndJG1sZpxXfzti9K4Z7cNNfW8EQtEzsX9B1BWXoBv
(hex!["44443e9670b7f6decd4da7b042b6c9f740bd6b82e564fd51c1453fa442f0192f"].into(), 15 * CSPR),
// sfJbxCLF7tdMQRqzVgTiGyJQ2V2tEJXeC9pmeZqRaH3kNqYFA
(hex!["d87d702b99b8b3d58d8a48e5d750f40338b3a3d43fab09c23c50036226ba5325"].into(), 28 * CSPR),
// sfDrr9Vh9k3hC8JnpN4BG15z5yJPfMhHuPwFsZrd3S62b5U2Y
(hex!["06ac96e99519ae0a38f2475edfda3e432d3ae8d1f889a82e9ded1f1ccc850505"].into(), 15 * CSPR),
// sfJq7W4AboVKNgeG33y2oCE5o6h3eJaG6cyoKwtqjTkjSZXs4
(hex!["e286f428cd368ae7249d4ea76ad17df9350b0dcb437eadbf60053177769fbc5a"].into(), 14 * CSPR),
// sfG8ERVrJaoaJZdxT8tt9ZBRH4y1q9RHkyW1juiQBFjfqNm5s
(hex!["6ae0b990e482c499d93382e6183c0d2f3e8228e603de7c154ffb93e2299f152a"].into(), 14 * CSPR),
// sfG7q2arcyPyzNWrEZRoFvrf6go5PuhwofYVcthR3Mpu8dHgz
(hex!["6a91f855ff00e83c9b03cc222291cd6d098be0318eb60b88e6c167ce9e513a50"].into(), 11 * CSPR),
// sfFoee91wxv2u9LRFxCv9pzpM9L9YWGX2CPZveLFWbntrq6zd
(hex!["5cb4964925c2061492b88ff8daea2804b5770c044946c4ff0ac5a170eab1422c"].into(), 26 * CSPR),
// sfGkHJcQDaqeagPGrpaNFKR1kdRShUZH4Ec8iYMj6kyH8M2Tg
(hex!["865f4233b54d0903f5fdad05b0ec715b0ad9613fc69df18df4a013d3c7d3ab73"].into(), 2 * CSPR),
// sfFXJNrot6ou3UAmcynzSrD1RZnZzyhKM4gdMPfuDLUhCPyDs
(hex!["503c72a0f2c549a62d876dea81aa2e597b88503fa639ab0e9b65db599785f61d"].into(), 26 * CSPR),
// sfJyW71FYeFRb3YSQSVJAEp3CjPpNcUmzkw7riKMSkCiBEAs6
(hex!["e8ed0109c607d78aec9d8aa3575a565e34d65b399a5bd0e0102032d807ea0975"].into(), 5 * CSPR),
// sfKCXSvdcMTWyJDXDdZ2QP88ZsHDiwnGPfDVRPetf6KQfDAKY
(hex!["f2dbb77f0f922e5e92d98de7d43612d2f0b0d503aff20607d6c771fe8ee4a623"].into(), 31 * CSPR),
// sfJjXxYZNuXNirgQFE4MxuJ1w2ekxXHvXtowqUqEN52BNRryW
(hex!["de45cf59f588af5ee252c0ee0c805be8fa1ce172f8a6187d3b63dce1dc9c0b60"].into(), 8 * CSPR),
// sfGZf5wgfaLUq3h3JwHgZ52Fg2P27JYn2tSCgjosp4gL2Mdpx
(hex!["7e44e1ede822621cc9f618480433fe002bb8edde02d2fcd4fcf406409e154e68"].into(), 28 * CSPR),
// sfETREDdpH8vyT6zHEfcF5qdJhNw8iJVFeSfspKHv2BeUGQg5
(hex!["210a4b979e39c3136be105df1974fc036f4fe9b035936c149bdb94a3f4820487"].into(), 6 * CSPR),
// sfHA9NkB5Bb5hgt1f58jf1UminCdrmyu94VGoKB3jo9YRoPjW
(hex!["98927535310e1b910ca19860e1539a15c5dc02df780a66a22f5796cec3768812"].into(), 12 * CSPR),
// sfJeYC8LPe41yBP8WptgSzkYgfM39y3derRV4YeYXkpEysT7b
(hex!["da765f0ad9bedffdc9aa88da6fdacf4afa4463395785b6e03acb0811395a8f5d"].into(), 20 * CSPR),
// sfEu7ZzgjwEuhS1EkebXfkvH3wMyxpSgcvH8btDi6EMqG4goQ
(hex!["34a33af049f4f1b65d518e51f38c7afb0cd973c649588808b2ba0211f4ada535"].into(), 5 * CSPR),
// sfHZx1bZK6aoJKfQ1XQfpRD5VZBXZM1uREGcBsnKJdTZDnDod
(hex!["aaba173e1cd257c1ba67afbed0fbf2c4aadbfac329f129f12c4941b8b6bc5865"].into(), 5 * CSPR),
// sfJHhyq2r19nHEbKbVn3NEWqkDWnK53rU9mpRVPEYh7dqkCwU
(hex!["ca932abf1648393d722ad23c2cd97515a436840d905d3dd2b4d1913989abbc12"].into(), 2 * CSPR),
// sfE8Hv37BNfZfdj6aKC8XuBPQRG6eLRJPuRqEmrCfPGF4F7Ag
(hex!["1274036453f19a410d99cd7a13235422062ff5b0d2dbd608d87ad33b9b7b544c"].into(), 17 * CSPR),
// sfJHHALMCEmBTJHEdHkgMbUt2XMFP4K2AcYPiwgtz429YUqWv
(hex!["ca3f9e8480f200b6afe9661cb96a30259fc88b947c3ab466bd2b8e902a859719"].into(), 2 * CSPR),
// sfKTaDy3Yw6eXz4GFfXLRx9LnDf8qEt4JpqnPJc8bQVAu6kET
(hex!["fe55bea13108c5f9e070689c96d63c40ca79db709bebe921289003e56a1fdf27"].into(), 3 * CSPR),
// sfJ4NLMc92S6gSvQLsxUvhh4zXwde1yHYJCBu2WFjwL1Hxgfh
(hex!["c066d79465a7bd3138c770f52c1ad160272705e98f9b3dacc22bc70f010a1564"].into(), 12 * CSPR),
// sfJcMpW8ESzTzpmftos8MoJ7pUyRbxPabxPHSuigfxQxy8GBR
(hex!["d8ccf65eb5e93fdf7af47e9c6962a6822c7f0e8ed14d84f2bebdae0c5623e62b"].into(), 16 * CSPR),
// sfESZE2fNkkRCR2bSmmKZ5VzmMGHFh8eUdE2isdjne7JGW9AU
(hex!["2061f823e814d8c6b524da2f26ba2bfa048bbce57a1186e560b84c47a162b927"].into(), 1 * CSPR),
// sfFSxdDQWSnuF2zJ3tRv3B9Xxzu8boEkByCSXkq1T1F6vRky5
(hex!["4cecf92b37e6954f086002cf7b6a61ac7d9ba40c83ef963005e3cacfb5c1e13f"].into(), 21 * CSPR),
// sfEivpTTfp6Xh7nHaco1sxXQiy163pT474cS2dj8d8MREaJ2x
(hex!["2cde961358bf934533495f186755eb538a925aaa19ab4bad097f9d23665a9553"].into(), 24 * CSPR),
// sfJHPU8JPeCg35QvgTwZ2iFAwiavxem4McAYtgvTKpePSnUrw
(hex!["ca54d983c77c48c948fa9a6f9261ce2d9c4f20abf6632e28da3ec41d4752d519"].into(), 8 * CSPR),
// sfDyruPst6vv93A1pUYtmNQa95iypWhMw1n4PWDfpP9g1WHTQ
(hex!["0c05daf23268fdae4efd5bc1211f662c63399be10666ad3bdc75f3470a5b3378"].into(), 11 * CSPR),
// sfG5dZrh8trJRWewe1THxhvCTdR1Qq6NDUkoGuQg4VA6iAm2z
(hex!["68e4e6131e6a7aaf5ab2629d2ee721031df2e2a6573701862508fa3dc5765f5c"].into(), 4 * CSPR),
// sfHNVjWNHs6fwPpHmmPj4nJQ7evN35qr9KkJVeiJjmyf3fGxj
(hex!["a1fdef07d92813b10b15914afe763aa16bbf3feca8db73fabf1422cd48e05db0"].into(), 16 * CSPR),
// sfEYCLQnQzp8EYfqqhWmB1mtWNPX9AmVLGiwhVpFVQ5JuuGmu
(hex!["24af1eab02801a2d1afe16c75baa55f930138d58229f02f2840f387241529424"].into(), 18 * CSPR),
// sfDwQQ2Zy16Hx5qnHQbsXw8reMewJ684yUydmTXT7E3Y489se
(hex!["0a2622dc4be5606375d3a47e56e2580636b0057c46ec85bd44e149bff55fb943"].into(), 27 * CSPR),
// sfFMhheEBKGwDcJ9aqpYvVsAAq3tu2tEcVaRd66zfxY8qaShs
(hex!["48ea8240144388abb847a7b2c52f6290aeb77f1b6d8e10cda7d14a2f48b05035"].into(), 3 * CSPR),
// sfE66BLe2b6wM9dWctMnizM7yzadJrzGtTDC64cMTmJxZqGG1
(hex!["10c603d5a51516d1ee97212cf0b79f106332439750673b8605a527ffe1d45c50"].into(), 3 * CSPR),
// sfEiXa1R4CGPDZcdJ7oEnTuwiicA5Dhtny8z7aYhSrbDQNygK
(hex!["2c90529d502a1f3c51fcf487782b4defa09bd0e7470d1d080e44da713058241c"].into(), 24 * CSPR),
];
// Following keys are used in genesis config for testing (casper) chains. // Following keys are used in genesis config for testing (casper) chains.
// DO NOT use them in production chains such as ghost. // DO NOT use them in production chains such as ghost.
let endowed_accounts = vec![ let endowed_accounts = vec![
@ -313,10 +437,28 @@ fn casper_staging_config_genesis() -> serde_json::Value {
hex!["328d3b7c3046ef7700937d99fb2e98ce2591682c2b5dcf3f562e4da157650237"].into(), hex!["328d3b7c3046ef7700937d99fb2e98ce2591682c2b5dcf3f562e4da157650237"].into(),
// sfEwRjyvEQcpRQ1qbCZum27nEkTggKEt7DtqxwyYQULt9UuUN // sfEwRjyvEQcpRQ1qbCZum27nEkTggKEt7DtqxwyYQULt9UuUN
hex!["3666e4e19f87bb8680495f31864ce1f1c69d4178002cc01911aef2cc7313f203"].into(), hex!["3666e4e19f87bb8680495f31864ce1f1c69d4178002cc01911aef2cc7313f203"].into(),
// sfHcJxw5cgkvukZZyxcNUMCdbm9e7773orByLrGgAREka81TK
hex!["ac871e8bab00dd56ba3a1c0bd289357203dcaf10010b0b04ad7472870cd22a3c"].into(),
// sfFD7KSRi2aSREJWc9X75sVTN4a5pbPM5VSSJefmPvMuiVbPr // sfFD7KSRi2aSREJWc9X75sVTN4a5pbPM5VSSJefmPvMuiVbPr
hex!["425ccd7bda4f5c76788ba23bc0381d7a2e496179c93301208c57501c80a4232a"].into(), hex!["425ccd7bda4f5c76788ba23bc0381d7a2e496179c93301208c57501c80a4232a"].into(),
// sfH29zyFYtoFj6fSXskAEXG5XyyMCa5YycahJkYMwSUz8CcEU // sfH29zyFYtoFj6fSXskAEXG5XyyMCa5YycahJkYMwSUz8CcEU
hex!["927a98dcf8f721103005f168476c24b91d7d10d580f457006a908e10e62c7729"].into(), hex!["927a98dcf8f721103005f168476c24b91d7d10d580f457006a908e10e62c7729"].into(),
// sfHcRoUmrL8GDmWxUcPcZEWVfJbnaXyjWuaBxu5pNtdW5nERK
hex!["ac9e227e30a63ce6eeb55cfbb1fb832aa7e1d3fad2bcb3f663de4a91d744fd50"].into(),
// sfFJuDxqSc3skWaNUQgqmtCDYvcRj9c56urEky7ByD26aXQEW
hex!["46c78fcacffd80abc9cca4917ef8369a37e21a1691ca11e7a3b53f80be745313"].into(),
// sfKNNbANdBuBpA4n1sXwPBhV57HBgV2y3R3YjHz1S1uWKfKAy
hex!["fa5e5a295ec74c3dda81118d9240db1552b28f831838465ae0712e97e78a6728"].into(),
// sfFAdZQQVdbCTA7eWomTrJXe5L8ZcwZRfkyyRkMQZftDqbcMg
hex!["4078ddb1ba1388f768fe6aa40ba9124a72692ecbcc83dc088fa86c735e4dc128"].into(),
// sfFqT8fmF15Ddshio5rnucmqzMxtUoHZVh7qSALSdAaM7Y6zb
hex!["5e1456904c40192cd3a18183df7dffea90d97739830a902cabb702ecdae4f649"].into(),
// sfFzUcPxuourb6JtdiudRkrsbnkxne1KEcpksVMJYGau5BVTG
hex!["64f685baa838323c0ef8c45259a3036b3e2bc54edf6553ce323e25b5e37a3721"].into(),
// sfHLkJNKVyAsVMC4bQQwsm1EMyWgKLQH8FFnZzLC78dYJDqSp
hex!["a0a87a75dba18037aa2e7b8036ce951e8d8356104758e15c9f44e2fd7d1bbc41"].into(),
// sfGCg772bqKp3wH23EQbgSbCQ5Q8BCwmCJ39XjR3xLwq6foYD
hex!["6e4429a8fa85cfe2a60488af446d57e719207831b2579b937325645e110bb666"].into(),
]; ];
let initial_authorities: Vec<( let initial_authorities: Vec<(
@ -333,17 +475,13 @@ fn casper_staging_config_genesis() -> serde_json::Value {
// sfFXZmnDVnkQ781J2gbqUpi7K5KgMWMdM4eeii74xxGgKYnNN // sfFXZmnDVnkQ781J2gbqUpi7K5KgMWMdM4eeii74xxGgKYnNN
hex!["507045c82be367f95408466cd054ca39bfa52697a3ef22809af14cf9de304f02"].into(), hex!["507045c82be367f95408466cd054ca39bfa52697a3ef22809af14cf9de304f02"].into(),
// sfJeojACBa7WiH6tBwikBKAMU2oKmseEBD1GYUYATvfWuLcPa // sfJeojACBa7WiH6tBwikBKAMU2oKmseEBD1GYUYATvfWuLcPa
hex!["daaaaab6a6e574099e24ae9bb75b543610edef9d374fa85a378edb573b47615f"] hex!["daaaaab6a6e574099e24ae9bb75b543610edef9d374fa85a378edb573b47615f"].unchecked_into(),
.unchecked_into(),
// sfFdtzNxJdeEkgHxvk144rJKxf7wcYvgX5tqfgZRutW9YvAKE // sfFdtzNxJdeEkgHxvk144rJKxf7wcYvgX5tqfgZRutW9YvAKE
hex!["55446f9a7aa99ced06b317c80ce90d56b84e56526775683af2525969e8da0b64"] hex!["55446f9a7aa99ced06b317c80ce90d56b84e56526775683af2525969e8da0b64"].unchecked_into(),
.unchecked_into(),
// sfE8gsMYAjAJHk5gyYZN7AW6pfmJ7V9H7xxWto24nmhzCUXaQ // sfE8gsMYAjAJHk5gyYZN7AW6pfmJ7V9H7xxWto24nmhzCUXaQ
hex!["12c14850562021eb99f58f90ab624fb6cfaf3ac9228a92f8b60115fe6a6af15a"] hex!["12c14850562021eb99f58f90ab624fb6cfaf3ac9228a92f8b60115fe6a6af15a"].unchecked_into(),
.unchecked_into(),
// sfE3GKSrKZzrZpdapJ2VGRpPor45T4D4i8QBZNumSNGqGv7PX // sfE3GKSrKZzrZpdapJ2VGRpPor45T4D4i8QBZNumSNGqGv7PX
hex!["0e9e698c7b2bf5ce3861cb4bc4ddf9e200237c282025b093ada850d764d12a35"] hex!["0e9e698c7b2bf5ce3861cb4bc4ddf9e200237c282025b093ada850d764d12a35"].unchecked_into(),
.unchecked_into(),
), ),
( (
// sfHLqWNC4hMKHhwvPWmWcxZsDPhCTQKgh1Ap7pm3qML5GBTBa // sfHLqWNC4hMKHhwvPWmWcxZsDPhCTQKgh1Ap7pm3qML5GBTBa
@ -351,17 +489,27 @@ fn casper_staging_config_genesis() -> serde_json::Value {
// sfHLqWNC4hMKHhwvPWmWcxZsDPhCTQKgh1Ap7pm3qML5GBTBa // sfHLqWNC4hMKHhwvPWmWcxZsDPhCTQKgh1Ap7pm3qML5GBTBa
hex!["a0ba0196e6ee7e6b5b0553035c5cb5c04e9725001b5732839d0529cbc00c9600"].into(), hex!["a0ba0196e6ee7e6b5b0553035c5cb5c04e9725001b5732839d0529cbc00c9600"].into(),
// sfGA6tPPF8dAc8QpMCMjxitG3j8sXPhkdpm5bwz4UsXAApUiw // sfGA6tPPF8dAc8QpMCMjxitG3j8sXPhkdpm5bwz4UsXAApUiw
hex!["6c4dd88b43e2011cf9a6a73d53446336ac9e04cdd4ca23587df63187ac455e49"] hex!["6c4dd88b43e2011cf9a6a73d53446336ac9e04cdd4ca23587df63187ac455e49"].unchecked_into(),
.unchecked_into(),
// sfGxQZXFUQH1AXv82rpjiJHFs7YsdEuVGdyvKiS2Tajpvw6Se // sfGxQZXFUQH1AXv82rpjiJHFs7YsdEuVGdyvKiS2Tajpvw6Se
hex!["8f9ea20bf4a807a8e710f7559dece86e94672b5b361de157bdaa5c1f37849f8d"] hex!["8f9ea20bf4a807a8e710f7559dece86e94672b5b361de157bdaa5c1f37849f8d"].unchecked_into(),
.unchecked_into(),
// sfGz2enFUR22cQ5ey61MdtPqbCeEWZA1wsCFFSLGaK7vKnv8C // sfGz2enFUR22cQ5ey61MdtPqbCeEWZA1wsCFFSLGaK7vKnv8C
hex!["90db5ed339a559ed157995a48d781f44c7df972dfba4bc855e4b59fa46438e17"] hex!["90db5ed339a559ed157995a48d781f44c7df972dfba4bc855e4b59fa46438e17"].unchecked_into(),
.unchecked_into(),
// sfEtwe5BoroNjkdLsvnjnMemUKiw8MS1X4YW8bepbbGvhS4LZ // sfEtwe5BoroNjkdLsvnjnMemUKiw8MS1X4YW8bepbbGvhS4LZ
hex!["3481cdcbcf37a4669c29a78cf9ceb39383a10ef0a18b36b92d149fdd0c24ae00"] hex!["3481cdcbcf37a4669c29a78cf9ceb39383a10ef0a18b36b92d149fdd0c24ae00"].unchecked_into(),
.unchecked_into(), ),
(
// sfGq75CrCrkcfqNzyyidu3D4jW3AoJSzL5tKKuv1UbS16ezzy
hex!["8a0d0b66e827bf20e79f9a499317e73925ce4f422371067edfab690e43857f13"].into(),
// sfGq75CrCrkcfqNzyyidu3D4jW3AoJSzL5tKKuv1UbS16ezzy
hex!["8a0d0b66e827bf20e79f9a499317e73925ce4f422371067edfab690e43857f13"].into(),
// sfJo2ogBpssRAU9ZPTvuXFZEdmJw9pKsPydLjXe8DypRScjzT
hex!["e0f0a776ecc9fa5e1f22e2fa001fe3fba5aea52b9444bc894b45589d42132475"].unchecked_into(),
// sfHq3EVT1sqY7o5ki3zA6LEdRDfdFc29YaZN3w2Thhz6JD5ZF
hex!["b63c5a0cf342b9b04931bc8ed74d7d0165ab99ab5f8a4514797d4b299a4501fe"].unchecked_into(),
// sfEj3wrDy9EDLCAodyEdQEYxJpNnM8Etaj3RJ5bCBRzdaDced
hex!["2cf69452e9f2a8457119139408884941ed50f590c0fc0f2b044c4d82c69e4245"].unchecked_into(),
// sfE32RmBp1xX4KRTphVGLUJBxLGPN3Dzg9BwCJktxMf3iEwck
hex!["0e6fa6934f9e99fa84874f2ed9318825a0d5443a0ced984acfbd24ece72ba55e"].unchecked_into(),
), ),
( (
// sfG9iWUS7AKBzvqdz3uDZv7f1t79vvSTYL1VxzYPHjhmLnQVn // sfG9iWUS7AKBzvqdz3uDZv7f1t79vvSTYL1VxzYPHjhmLnQVn
@ -369,17 +517,13 @@ fn casper_staging_config_genesis() -> serde_json::Value {
// sfG9iWUS7AKBzvqdz3uDZv7f1t79vvSTYL1VxzYPHjhmLnQVn // sfG9iWUS7AKBzvqdz3uDZv7f1t79vvSTYL1VxzYPHjhmLnQVn
hex!["6c0283f4c688f0e75ad546c790bbd5961c1a6931543aa589f368f8272c44b758"].into(), hex!["6c0283f4c688f0e75ad546c790bbd5961c1a6931543aa589f368f8272c44b758"].into(),
// sfGMUYXSjHgwGBpbGiHFoqT1DdJwZdHk49H5ViaQM7HUnayvZ // sfGMUYXSjHgwGBpbGiHFoqT1DdJwZdHk49H5ViaQM7HUnayvZ
hex!["74fa7381a7a74b316afb6793a00387eed9d95d46a69866cbb316b5d9c918af0e"] hex!["74fa7381a7a74b316afb6793a00387eed9d95d46a69866cbb316b5d9c918af0e"].unchecked_into(),
.unchecked_into(),
// sfEWYhczV6PbmeNXZTcA4LvhpzvCfNMatYoSNKvDphmNaQzqB // sfEWYhczV6PbmeNXZTcA4LvhpzvCfNMatYoSNKvDphmNaQzqB
hex!["236d2fa03f4ed8cb65de7e514d7540159b328f1c170dd402b094ad7fbf547218"] hex!["236d2fa03f4ed8cb65de7e514d7540159b328f1c170dd402b094ad7fbf547218"].unchecked_into(),
.unchecked_into(),
// sfDirg32ityDvrjxh4822unhP4qm4S9yTqN99gesN322swn7h // sfDirg32ityDvrjxh4822unhP4qm4S9yTqN99gesN322swn7h
hex!["00946618c353e4c6546b87f9ca1089b846b0ea4658ee8e6d9d1200c24cb5ee27"] hex!["00946618c353e4c6546b87f9ca1089b846b0ea4658ee8e6d9d1200c24cb5ee27"].unchecked_into(),
.unchecked_into(),
// sfFZgp1Z5diFAZ16swuQD5GojGCsMMFVR19uWnCrppMLuYjRv // sfFZgp1Z5diFAZ16swuQD5GojGCsMMFVR19uWnCrppMLuYjRv
hex!["520e74f8c5853ec8577932327ad3247656db25b74c79ad09adb431b271002401"] hex!["520e74f8c5853ec8577932327ad3247656db25b74c79ad09adb431b271002401"].unchecked_into(),
.unchecked_into(),
), ),
( (
// sfHjtrXFzRmxwjE4rjVxFJXpvVv7furjdymZS7PQRFiANpodz // sfHjtrXFzRmxwjE4rjVxFJXpvVv7furjdymZS7PQRFiANpodz
@ -387,17 +531,125 @@ fn casper_staging_config_genesis() -> serde_json::Value {
// sfHjtrXFzRmxwjE4rjVxFJXpvVv7furjdymZS7PQRFiANpodz // sfHjtrXFzRmxwjE4rjVxFJXpvVv7furjdymZS7PQRFiANpodz
hex!["b24feb55b2cac4b365a9245c2a97525b01bd1a594d2d42b91f6bc38c9c2e6517"].into(), hex!["b24feb55b2cac4b365a9245c2a97525b01bd1a594d2d42b91f6bc38c9c2e6517"].into(),
// sfF5XWwvNPjZEsBz1HWs5Ys5zcE85UHnN1BV8TBBectqFQZRm // sfF5XWwvNPjZEsBz1HWs5Ys5zcE85UHnN1BV8TBBectqFQZRm
hex!["3c944c704cae203619b9e7a5a4b6742736da6a8e76c762291bebdc7652cfec2f"] hex!["3c944c704cae203619b9e7a5a4b6742736da6a8e76c762291bebdc7652cfec2f"].unchecked_into(),
.unchecked_into(),
// sfDx3gj4wFHg3cK6bopnypHQ6TxW1VgyPsYVbXKhRHtLDLxQb // sfDx3gj4wFHg3cK6bopnypHQ6TxW1VgyPsYVbXKhRHtLDLxQb
hex!["0aa3a88f6b777c95c3dfe7e997b76798413f16aa325f34824cae0c9102b281d5"] hex!["0aa3a88f6b777c95c3dfe7e997b76798413f16aa325f34824cae0c9102b281d5"].unchecked_into(),
.unchecked_into(),
// sfHXZbnZV3YWwnH28q2xumm7stvuC8LweYYxPNuHGonnX7QHL // sfHXZbnZV3YWwnH28q2xumm7stvuC8LweYYxPNuHGonnX7QHL
hex!["a8e828d10cf7b74481b6e746e5532d4740ea8014a0d3d856540a59847f8a6b76"] hex!["a8e828d10cf7b74481b6e746e5532d4740ea8014a0d3d856540a59847f8a6b76"].unchecked_into(),
.unchecked_into(),
// sfEaHBrBgeMhRTA3WHE9Nbyvn3h7xkhYKi7go4yo81L88o9zJ // sfEaHBrBgeMhRTA3WHE9Nbyvn3h7xkhYKi7go4yo81L88o9zJ
hex!["2645f1f6820dd3a917eebbdab033088d8862477c1c14759b218685f9a0893377"] hex!["2645f1f6820dd3a917eebbdab033088d8862477c1c14759b218685f9a0893377"].unchecked_into(),
.unchecked_into(), ),
(
// sfFFYKBEwmJAQEJR73Q4Gfs1sH1c8wyuBGnHc1UdzWucAYrKC
hex!["44376f8fa786be1f16fcb45232cfb07300cea845b2fc6e30dde61952de3e5e33"].into(),
// sfFFYKBEwmJAQEJR73Q4Gfs1sH1c8wyuBGnHc1UdzWucAYrKC
hex!["44376f8fa786be1f16fcb45232cfb07300cea845b2fc6e30dde61952de3e5e33"].into(),
// sfK4K5bS7M6bHeKHoGec9bw1PMngNyzhTx9YZq6hkqibos4LJ
hex!["ec981eb1ef1ddbc8ded2db16198cb03667b4b39a8ea58f28ad469ddfaf256161"].unchecked_into(),
// sfECakKMW2xf5dK8Ut55tnwadoKTNGKdRLh5E7dYRmV6sW812
hex!["15b9a867891cf449584b108e512d60b945b1a065bec1703c4c5709ee5093c03d"].unchecked_into(),
// sfErEin4Ljy11VGnYtTYJZ9LLcDP4fvsKV6f9LXYRwRXtrNqa
hex!["3271915dc67eba8ad2759a30c2537702f4fbf45647cba565e3a464ab75b91f05"].unchecked_into(),
// sfGD5sHSa1h8NGpUD29ZogBJW6fatg8Sg6Pzg9Q7RPUm24Mkr
hex!["6e9426dc78fba9eeb264dcab98be86daf3d8cf510ecfb2acddec370295ff8176"].unchecked_into(),
),
(
// sfFPZZNrhDuY9MKJCBHyBCkgJecgDqPJBPSjA37be4czdX6t3
hex!["4a5596e97c602e7846d54fae81dcdc5a553b7422231e32f9567ac30a6b7c743a"].into(),
// sfFPZZNrhDuY9MKJCBHyBCkgJecgDqPJBPSjA37be4czdX6t3
hex!["4a5596e97c602e7846d54fae81dcdc5a553b7422231e32f9567ac30a6b7c743a"].into(),
// sfJP8aW6eSUs14AfUG6ZDFFjtyJxDed5Ubk1CFh7dNmL69rbx
hex!["ceb63298b1b7a1277fddf6eee735dbbf9921fd5ebaac0132eee1963e22cf5935"].unchecked_into(),
// sfH6jAeHqDpwtYGv9KJWNJ8aom8ivSvVztRSwAHw4bXd1isoP
hex!["95f73a6271b517f2016fa91411bdeeb990158066c95f106a79697446ba9f78b4"].unchecked_into(),
// sfEXSdKyx6uQBzgR3a7oH53XSCLrjUM2B7fbcvUvm21b5J6Uf
hex!["241bfc05caa2d3e53e671df7261599c13f069a37f6cc4be10b5d49502c3a1e1c"].unchecked_into(),
// sfGXqJTwJTkh3bwhECju7XCdgvJXYJZUtYSEJ2PbfpXGak42s
hex!["7ce0c80ee65fb00e229d8c8fa5484144eca3d45d733165fbffcdb4de24c14951"].unchecked_into(),
),
(
// sfESE7VifnknxVe71z3zsqC3xiirXyzHurKjdQoD537WpwJjW
hex!["2021a16182e3af39a79d20021a1b8755d589c04292d361d6b387411f7e975602"].into(),
// sfESE7VifnknxVe71z3zsqC3xiirXyzHurKjdQoD537WpwJjW
hex!["2021a16182e3af39a79d20021a1b8755d589c04292d361d6b387411f7e975602"].into(),
// sfFzQmYYckD8XLV7XGU1pJAyt1K3foCpPumpKBqdb5sJGHXrc
hex!["64e9968f3af2e1a86ee8d4be9ad77a1d66f50138527988bf93ede25baaf2e671"].unchecked_into(),
// sfFHjCLzWetvQJQzNwxeWcrkHmnPS1mVz7gT63yiRdvxFZ9T8
hex!["45e28f333bf0d4a9956ae20341cd07db8d471c4b482ed15d5cf7edd70201670d"].unchecked_into(),
// sfHJAk4HiVuMjXqaXoFEKTCF6938Lta7qd9w3zbyyuWCs1T5L
hex!["9eb1063afcaf568e7a62458ef33237a41ca500c89e084f7a5dd75bf5d89b105a"].unchecked_into(),
// sfEm2SME5H6GiezhYokZWmrZLMTUNFbLV7xwgKrMXz3NwppKb
hex!["2e77fde21162d1f21ca371846d70c3b75931329074101ee668e614336d25c120"].unchecked_into(),
),
(
// sfHpvEbP79MrDMVw4GhTvgLSU987ZSJ21VAsDWiJdgjG3ijse
hex!["b624cb291f7464773f3b449ee2252165f3934ace08b1e10611a53e174766fc73"].into(),
// sfHpvEbP79MrDMVw4GhTvgLSU987ZSJ21VAsDWiJdgjG3ijse
hex!["b624cb291f7464773f3b449ee2252165f3934ace08b1e10611a53e174766fc73"].into(),
// sfJHYLgjoHotvKi46URmtaVoG4p54SPE2ASTrauym99WxFcAn
hex!["ca72b6ea2c83f9e429479bf51c324ea90cbf01e08d2850ced2590c8796cfe222"].unchecked_into(),
// sfFVPqgCsDQe3k4qhGmUH4UoZaxsGb9majPgoH3WaYCZjFhTf
hex!["4ec8584ca9da16d8c60e1770e98fbca8bec648e13c69601e3dfdc1330bf1f999"].unchecked_into(),
// sfJ6nxM1SvcdbV2Gmf8WKkPKeX6rRYaEmSj7V9r64799acqHV
hex!["c2403683be24a92ae8489e28fb502e2bab16d815c4f6c865c50ffb34430a8d7c"].unchecked_into(),
// sfK1sQY3GL8waX2htW9EaBo9MjWGuy4VGeiUfP4NCq5tCjt37
hex!["eabb3463e300f357b9886683d5a240a395f6bd41182057f03b0e9697a8b3465e"].unchecked_into(),
),
(
// sfJeU4TBQyuGxfsCqNDPax1TcfAseEmBDPqx5YEm7kXUvnnPa
hex!["da6875e9df9a7894e065ef5befcde567dec4dc2c0b73a6ad5514dcca26a90702"].into(),
// sfJeU4TBQyuGxfsCqNDPax1TcfAseEmBDPqx5YEm7kXUvnnPa
hex!["da6875e9df9a7894e065ef5befcde567dec4dc2c0b73a6ad5514dcca26a90702"].into(),
// sfGbxmQAD2jbktjRkq6NsJxHKHWnkdtvoR14fFPAX85t148ej
hex!["8006e3f6e3d92c4c5f2e2f001452e4993e6d5c2b1136f2ae6060c6e9c9523b4a"].unchecked_into(),
// sfGm1jJagueW5dCng6xKCDx3FX2JohtsYMuNjf2tJGXN5ePUL
hex!["86ee138c9e7e67c1c2e157c0ba888761a122d8b9aa6a8653e886ac329e34255d"].unchecked_into(),
// sfEB68auUQmSCK8M3Zr7WuzRSipj9sQ5ykfDmvLmT8FDY5bg6
hex!["1496150847d512e0491899eba72ee36f76b882ae29fccf18201fd9fbd5bfd300"].unchecked_into(),
// sfHZqUptNXpRNGPHKn2Tfv8K1RjFGJ9XCdSw41nPAw9ZXM37T
hex!["aaa41b6ade4c30b5792aa6e5604c444e424900ddf649b23eed4bd0d7f5d3a34f"].unchecked_into(),
),
(
// sfFBEdrB1J7jLJKQp3fABEiHkwec1gCgGeTxMVyVm4UjWwvRs
hex!["40eef1c6c8d8242ccbd3f03144bd4ea1a7374cbd8219e2849d3a3ee78f1da045"].into(),
// sfFBEdrB1J7jLJKQp3fABEiHkwec1gCgGeTxMVyVm4UjWwvRs
hex!["40eef1c6c8d8242ccbd3f03144bd4ea1a7374cbd8219e2849d3a3ee78f1da045"].into(),
// sfF2FRJSuQSCidfbpu8DwpsHwezCcBJcZfh7Pds5vqtEF3Rbw
hex!["3a145fb664353e473f1937058c881b14ed150285f3cec1aff348c5209d56d96d"].unchecked_into(),
// sfDysi9h3PJoA5BGeJ2vfAkx3wXS9oK7yTDUyuJG2CRMJvXnh
hex!["0c0891a518270014530061bd217606269686abdf3c1d237a3c6a3db308fc2d0d"].unchecked_into(),
// sfGsyqzBAT7a9oBGdDBykyRwF95wRBL4yaGs4QFWznXHw5xsF
hex!["8c3e730f6e6ecfb96581091e71556175384f077bee31b0199f13321df018427d"].unchecked_into(),
// sfJP7W9aZe2F6G5w7xZtHhzSUCg86SvUcur4GPm2LMs7N2f5w
hex!["ceb294227950d177b63e6c1d10a66131f5da3792428b03f5b83be84a33db215f"].unchecked_into(),
),
(
// sfFCsSaJrPqkCZMdkm7WoyHP7w3UbNaC3aCHQfWbUaLbDqfdR
hex!["422e16b0c58f03af378d1638fe56127f337abf1d1a4a740c3371714616abd43d"].into(),
// sfFCsSaJrPqkCZMdkm7WoyHP7w3UbNaC3aCHQfWbUaLbDqfdR
hex!["422e16b0c58f03af378d1638fe56127f337abf1d1a4a740c3371714616abd43d"].into(),
// sfGShS9zKf8nzDr71qPv9LZJtK1LCMxPV4QUMYG8jvZhVe9pS
hex!["78f612068566eb6cc5cb5d9f1fda92c5dc3e3888eb61eb1af27af6855365ba3c"].unchecked_into(),
// sfJg5cPBkyrcu7zZaKaUkjp2vDVGfpGNjjT1sn8fS6qjv9mDU
hex!["dba3613933d60ca248ee024deac42bc9c8c2d9fe8734b6052cd9a148978cbedb"].unchecked_into(),
// sfFav2ALRGkJtmEHEpz2LiRmshGPzn4aWdAZeFUyKA56LqDDF
hex!["52fe2b63b03a0d439923967278442418a2d1f0d250bcab26f85f12ea212cbd3e"].unchecked_into(),
// sfDmN4zoicQ54R5MmSpCf9ojg8zE2eD3x39pnba412oDivkBc
hex!["027dd852bf20bef53545afd1e08bf8760abb6b1af1df6c17e73f4cf88210ee46"].unchecked_into(),
),
(
// sfF2fiFe2PteoYe286cZNJpxaT1omCPuTgwHjB1Z8tqjsLxRn
hex!["3a6626211a2dd35683fd7cb5f2f343d75f2b698d6c48c2d6eb1cdbe116e32315"].into(),
// sfF2fiFe2PteoYe286cZNJpxaT1omCPuTgwHjB1Z8tqjsLxRn
hex!["3a6626211a2dd35683fd7cb5f2f343d75f2b698d6c48c2d6eb1cdbe116e32315"].into(),
// sfG9m1LEV1sjUwyLwp1UQPUGnuMGF1oaCjSC4PVx9q4zgJRMr
hex!["6c0aec49974aaff08ff962a2d8d7857227d027ed27a272cbc4acaa1ee937db0f"].unchecked_into(),
// sfH3JwHTbimvG3SZLd5d8Ad8Ztvgb8NVSwxxzxYfArpXVYqFD
hex!["935becdfb2e0d4fcd46ba82e680cfc447180de6b85ec42d17f1396a520b0c04f"].unchecked_into(),
// sfGkKjBX5UdujuTrbxyepUzdU4Jew7DvgNs1UUM2HBLj4xNM5
hex!["86676ad3cd2d970b86dee2f25d4318f9bba40455111f16300e114e7f00c58706"].unchecked_into(),
// sfDisU5wryao4kcd4WuHyZZB6LfJrDuoQoU14cTiiJqD7Whoc
hex!["009712519ba7dad1c682c871b94573ccaba8b7d530f7194fb16bf553fd7ae67d"].unchecked_into(),
), ),
]; ];
@ -413,6 +665,7 @@ fn casper_staging_config_genesis() -> serde_json::Value {
.iter() .iter()
.map(|k: &AccountId| (k.clone(), ENDOWMENT)) .map(|k: &AccountId| (k.clone(), ENDOWMENT))
.chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH))) .chain(initial_authorities.iter().map(|x| (x.0.clone(), STASH)))
.chain(whales_endowments)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
}, },
"session": { "session": {
@ -454,11 +707,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,
}, },
@ -478,9 +726,7 @@ fn casper_staging_config_genesis() -> serde_json::Value {
fn casper_development_config_genesis() -> serde_json::Value { fn casper_development_config_genesis() -> serde_json::Value {
testnet_config_genesis( testnet_config_genesis(
vec![get_authority_keys_from_seed("Alice")], vec![get_authority_keys_from_seed("Alice")],
None, None, None, None,
None,
None,
) )
} }

View File

@ -7,15 +7,15 @@ pub mod chain_spec;
use { use {
grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider}, grandpa::{self, FinalityProofProvider as GrandpaFinalityProofProvider},
sc_client_api::BlockBackend, sc_client_api::BlockBackend,
sc_service::{KeystoreContainer, RpcHandlers},
sp_blockchain::HeaderBackend,
telemetry::{Telemetry, TelemetryWorkerHandle},
tx_pool_api::OffchainTransactionPoolFactory, tx_pool_api::OffchainTransactionPoolFactory,
sp_blockchain::HeaderBackend,
sc_service::{KeystoreContainer, RpcHandlers},
telemetry::{Telemetry, TelemetryWorkerHandle},
}; };
use sc_executor::{HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY};
use std::{sync::Arc, time::Duration}; use std::{sync::Arc, time::Duration};
use telemetry::TelemetryWorker; use telemetry::TelemetryWorker;
use sc_executor::{HeapAllocStrategy, WasmExecutor, DEFAULT_HEAP_ALLOC_STRATEGY};
pub use chain_spec::GenericChainSpec; pub use chain_spec::GenericChainSpec;
pub use consensus_common::{Proposal, SelectChain}; pub use consensus_common::{Proposal, SelectChain};
@ -23,23 +23,27 @@ pub use primitives::{Block, BlockId, BlockNumber, Hash};
pub use sc_client_api::{Backend, CallExecutor}; pub use sc_client_api::{Backend, CallExecutor};
pub use sc_consensus::BlockImport; pub use sc_consensus::BlockImport;
pub use sc_executor::NativeExecutionDispatch; pub use sc_executor::NativeExecutionDispatch;
pub use sp_api::{ApiRef, ConstructRuntimeApi, Core as CoreApi, ProvideRuntimeApi};
pub use sc_service::{ pub use sc_service::{
config::{DatabaseSource, PrometheusConfig}, config::{DatabaseSource, PrometheusConfig},
ChainSpec, Configuration, Error as SubstrateServiceError, PruningMode, Role, RuntimeGenesis, ChainSpec, Configuration, Error as SubstrateServiceError, PruningMode, Role,
TFullBackend, TFullCallExecutor, TFullClient, TaskManager, TransactionPoolOptions, RuntimeGenesis, TFullBackend, TFullCallExecutor, TFullClient, TaskManager,
TransactionPoolOptions,
}; };
pub use sp_api::{ApiRef, ConstructRuntimeApi, Core as CoreApi, ProvideRuntimeApi};
pub use sp_runtime::{ pub use sp_runtime::{
generic, generic,
traits::{self as runtime_traits, BlakeTwo256, Block as BlockT, Header as HeaderT, NumberFor}, traits::{
self as runtime_traits, BlakeTwo256, Block as BlockT, Header as HeaderT,
NumberFor,
},
}; };
#[cfg(feature = "casper-native")]
use casper_runtime::RuntimeApi;
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
pub use chain_spec::CasperChainSpec; pub use chain_spec::CasperChainSpec;
#[cfg(feature = "casper-native")] #[cfg(feature = "casper-native")]
pub use {casper_runtime, casper_runtime_constants}; pub use {casper_runtime, casper_runtime_constants};
#[cfg(feature = "casper-native")]
use casper_runtime::RuntimeApi;
#[cfg(feature = "full-node")] #[cfg(feature = "full-node")]
pub type FullBackend = sc_service::TFullBackend<Block>; pub type FullBackend = sc_service::TFullBackend<Block>;
@ -173,13 +177,9 @@ impl IdentifyVariant for Box<dyn ChainSpec> {
} }
fn identify_chain(&self) -> Chain { fn identify_chain(&self) -> Chain {
if self.is_ghost() { if self.is_ghost() { Chain::Ghost }
Chain::Ghost else if self.is_casper() { Chain::Casper }
} else if self.is_casper() { else { Chain::Unknown }
Chain::Casper
} else {
Chain::Unknown
}
} }
} }
@ -222,9 +222,7 @@ fn new_partial_basics(
let heap_pages = config let heap_pages = config
.default_heap_pages .default_heap_pages
.map_or(DEFAULT_HEAP_ALLOC_STRATEGY, |h| HeapAllocStrategy::Static { .map_or(DEFAULT_HEAP_ALLOC_STRATEGY, |h| HeapAllocStrategy::Static { extra_pages: h as _ });
extra_pages: h as _,
});
let executor = WasmExecutor::builder() let executor = WasmExecutor::builder()
.with_execution_method(config.wasm_method) .with_execution_method(config.wasm_method)
@ -253,25 +251,13 @@ fn new_partial_basics(
telemetry telemetry
}); });
Ok(Basics { Ok(Basics { task_manager, client, backend, keystore_container, telemetry })
task_manager,
client,
backend,
keystore_container,
telemetry,
})
} }
#[cfg(feature = "full-node")] #[cfg(feature = "full-node")]
fn new_partial<ChainSelection>( fn new_partial<ChainSelection>(
config: &mut Configuration, config: &mut Configuration,
Basics { Basics { task_manager, backend, client, keystore_container, telemetry }: Basics,
task_manager,
backend,
client,
keystore_container,
telemetry,
}: Basics,
select_chain: ChainSelection, select_chain: ChainSelection,
) -> Result< ) -> Result<
sc_service::PartialComponents< sc_service::PartialComponents<
@ -286,7 +272,11 @@ fn new_partial<ChainSelection>(
ghost_rpc::SubscriptionTaskExecutor, ghost_rpc::SubscriptionTaskExecutor,
) -> Result<ghost_rpc::RpcExtension, SubstrateServiceError>, ) -> Result<ghost_rpc::RpcExtension, SubstrateServiceError>,
( (
babe::BabeBlockImport<Block, FullClient, FullGrandpaBlockImport<ChainSelection>>, babe::BabeBlockImport<
Block,
FullClient,
FullGrandpaBlockImport<ChainSelection>,
>,
grandpa::LinkHalf<Block, FullClient, ChainSelection>, grandpa::LinkHalf<Block, FullClient, ChainSelection>,
babe::BabeLink<Block>, babe::BabeLink<Block>,
), ),
@ -307,7 +297,8 @@ where
client.clone(), client.clone(),
); );
let (grandpa_block_import, grandpa_link) = grandpa::block_import( let (grandpa_block_import, grandpa_link) =
grandpa::block_import(
client.clone(), client.clone(),
GRANDPA_JUSTIFICATION_PERIOD, GRANDPA_JUSTIFICATION_PERIOD,
&(client.clone() as Arc<_>), &(client.clone() as Arc<_>),
@ -321,7 +312,8 @@ where
babe::block_import(babe_config.clone(), grandpa_block_import, client.clone())?; babe::block_import(babe_config.clone(), grandpa_block_import, client.clone())?;
let slot_duration = babe_link.config().slot_duration(); let slot_duration = babe_link.config().slot_duration();
let (import_queue, babe_worker_handle) = babe::import_queue(babe::ImportQueueParams { let (import_queue, babe_worker_handle) =
babe::import_queue(babe::ImportQueueParams {
link: babe_link.clone(), link: babe_link.clone(),
block_import: block_import.clone(), block_import: block_import.clone(),
justification_import: Some(Box::new(justification_import)), justification_import: Some(Box::new(justification_import)),
@ -361,9 +353,10 @@ where
let chain_spec = config.chain_spec.cloned_box(); let chain_spec = config.chain_spec.cloned_box();
let backend = backend.clone(); let backend = backend.clone();
move |deny_unsafe, move |
subscription_executor: ghost_rpc::SubscriptionTaskExecutor| deny_unsafe,
-> Result<ghost_rpc::RpcExtension, sc_service::Error> { subscription_executor: ghost_rpc::SubscriptionTaskExecutor,
| -> Result<ghost_rpc::RpcExtension, sc_service::Error> {
let deps = ghost_rpc::FullDeps { let deps = ghost_rpc::FullDeps {
client: client.clone(), client: client.clone(),
pool: transaction_pool.clone(), pool: transaction_pool.clone(),
@ -435,7 +428,8 @@ pub fn new_full<Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Ha
let backoff_authoring_blocks = if !force_authoring_backoff { let backoff_authoring_blocks = if !force_authoring_backoff {
None None
} else { } else {
let mut backoff = sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default(); let mut backoff =
sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default();
if config.chain_spec.is_dev() { if config.chain_spec.is_dev() {
backoff.max_interval = 10; backoff.max_interval = 10;
@ -452,14 +446,7 @@ pub fn new_full<Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Ha
let prometheus_registry = config.prometheus_registry().cloned(); let prometheus_registry = config.prometheus_registry().cloned();
let select_chain = sc_consensus::LongestChain::new(basics.backend.clone()); let select_chain = sc_consensus::LongestChain::new(basics.backend.clone());
let sc_service::PartialComponents::< let sc_service::PartialComponents::<_, _, sc_consensus::LongestChain<FullBackend, Block>, _, _, _,> {
_,
_,
sc_consensus::LongestChain<FullBackend, Block>,
_,
_,
_,
> {
client, client,
backend, backend,
mut task_manager, mut task_manager,
@ -467,7 +454,12 @@ pub fn new_full<Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Ha
select_chain, select_chain,
import_queue, import_queue,
transaction_pool, transaction_pool,
other: (rpc_extensions_builder, import_setup, rpc_setup, mut telemetry), other: (
rpc_extensions_builder,
import_setup,
rpc_setup,
mut telemetry,
),
} = new_partial::<sc_consensus::LongestChain<FullBackend, Block>>( } = new_partial::<sc_consensus::LongestChain<FullBackend, Block>>(
&mut config, &mut config,
basics, basics,
@ -484,11 +476,7 @@ pub fn new_full<Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Ha
let mut net_config = let mut net_config =
sc_network::config::FullNetworkConfiguration::<_, _, Network>::new(&config.network); sc_network::config::FullNetworkConfiguration::<_, _, Network>::new(&config.network);
let genesis_hash = client let genesis_hash = client.block_hash(0).ok().flatten().expect("Genesis block exists; qed");
.block_hash(0)
.ok()
.flatten()
.expect("Genesis block exists; qed");
let peer_store_handle = net_config.peer_store_handle(); let peer_store_handle = net_config.peer_store_handle();
let grandpa_protocol_name = grandpa::protocol_standard_name(&genesis_hash, &config.chain_spec); let grandpa_protocol_name = grandpa::protocol_standard_name(&genesis_hash, &config.chain_spec);
@ -566,8 +554,8 @@ pub fn new_full<Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Ha
"⚠️ The hardware does not meet the minimal requirements {} for role 'Authority'", "⚠️ The hardware does not meet the minimal requirements {} for role 'Authority'",
err err
); );
} },
_ => {} _ => {},
} }
if let Some(ref mut telemetry) = telemetry { if let Some(ref mut telemetry) = telemetry {
@ -575,7 +563,10 @@ pub fn new_full<Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Ha
task_manager.spawn_handle().spawn( task_manager.spawn_handle().spawn(
"telemetry_hwbench", "telemetry_hwbench",
None, None,
sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench), sc_sysinfo::initialize_hwbench_telemetry(
telemetry_handle,
hwbench,
),
); );
} }
} }
@ -589,9 +580,7 @@ pub fn new_full<Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Ha
let authority_discovery_role = let authority_discovery_role =
sc_authority_discovery::Role::PublishAndDiscover(keystore_container.keystore()); sc_authority_discovery::Role::PublishAndDiscover(keystore_container.keystore());
let dht_event_stream = let dht_event_stream =
network network.event_stream("authority-discovery").filter_map(|e| async move {
.event_stream("authority-discovery")
.filter_map(|e| async move {
match e { match e {
Event::Dht(e) => Some(e), Event::Dht(e) => Some(e),
_ => None, _ => None,
@ -608,7 +597,7 @@ pub fn new_full<Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Ha
Arc::new(network.clone()), Arc::new(network.clone()),
Box::pin(dht_event_stream), Box::pin(dht_event_stream),
authority_discovery_role, authority_discovery_role,
prometheus_registry.clone(), prometheus_registry.clone()
); );
task_manager.spawn_handle().spawn( task_manager.spawn_handle().spawn(
@ -636,7 +625,8 @@ pub fn new_full<Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Ha
env: proposer, env: proposer,
sync_oracle: sync_service.clone(), sync_oracle: sync_service.clone(),
justification_sync_link: sync_service.clone(), justification_sync_link: sync_service.clone(),
create_inherent_data_providers: move |_, ()| async move { create_inherent_data_providers: move |_, ()| {
async move {
let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
let slot = let slot =
babe_primitives::inherents::InherentDataProvider::from_timestamp_and_slot_duration( babe_primitives::inherents::InherentDataProvider::from_timestamp_and_slot_duration(
@ -644,6 +634,7 @@ pub fn new_full<Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Ha
slot_duration, slot_duration,
); );
Ok((slot, timestamp)) Ok((slot, timestamp))
}
}, },
force_authoring, force_authoring,
backoff_authoring_blocks, backoff_authoring_blocks,
@ -655,9 +646,7 @@ pub fn new_full<Network: sc_network::NetworkBackend<Block, <Block as BlockT>::Ha
let babe = babe::start_babe(babe_config)?; let babe = babe::start_babe(babe_config)?;
task_manager task_manager.spawn_essential_handle().spawn_blocking("babe", None, babe);
.spawn_essential_handle()
.spawn_blocking("babe", None, babe);
} }
let keystore_opt = if role.is_authority() { let keystore_opt = if role.is_authority() {
@ -722,17 +711,8 @@ macro_rules! chain_ops {
let chain_selection = sc_consensus::LongestChain::new(basics.backend.clone()); let chain_selection = sc_consensus::LongestChain::new(basics.backend.clone());
let sc_service::PartialComponents { let sc_service::PartialComponents { client, backend, import_queue, task_manager, .. } =
client, new_partial::<sc_consensus::LongestChain<FullBackend, Block>>(&mut config, basics, chain_selection)?;
backend,
import_queue,
task_manager,
..
} = new_partial::<sc_consensus::LongestChain<FullBackend, Block>>(
&mut config,
basics,
chain_selection,
)?;
Ok((client, backend, import_queue, task_manager)) Ok((client, backend, import_queue, task_manager))
}}; }};
} }
@ -740,28 +720,22 @@ macro_rules! chain_ops {
#[cfg(feature = "full-node")] #[cfg(feature = "full-node")]
pub fn new_chain_ops( pub fn new_chain_ops(
config: &mut Configuration, config: &mut Configuration,
) -> Result< ) -> Result<(Arc<FullClient>, Arc<FullBackend>, sc_consensus::BasicQueue<Block>, TaskManager), Error>
( {
Arc<FullClient>,
Arc<FullBackend>,
sc_consensus::BasicQueue<Block>,
TaskManager,
),
Error,
> {
config.keystore = sc_service::config::KeystoreConfig::InMemory; config.keystore = sc_service::config::KeystoreConfig::InMemory;
chain_ops!(config, None) chain_ops!(config, None)
} }
#[cfg(feature = "full-node")] #[cfg(feature = "full-node")]
pub fn build_full(config: Configuration, params: NewFullParams) -> Result<NewFull, Error> { pub fn build_full(
config: Configuration,
params: NewFullParams,
) -> Result<NewFull, Error> {
match config.network.network_backend { match config.network.network_backend {
sc_network::config::NetworkBackendType::Libp2p => { sc_network::config::NetworkBackendType::Libp2p =>
new_full::<sc_network::NetworkWorker<Block, Hash>>(config, params) new_full::<sc_network::NetworkWorker<Block, Hash>>(config, params),
} sc_network::config::NetworkBackendType::Litep2p =>
sc_network::config::NetworkBackendType::Litep2p => { new_full::<sc_network::Litep2pNetworkBackend>(config, params),
new_full::<sc_network::Litep2pNetworkBackend>(config, params)
}
} }
} }
@ -776,7 +750,7 @@ pub fn revert_backend(
let revertible = blocks.min(best_number - finalized); let revertible = blocks.min(best_number - finalized);
if revertible == 0 { if revertible == 0 {
return Ok(()); return Ok(())
} }
babe::revert(client.clone(), backend, blocks)?; babe::revert(client.clone(), backend, blocks)?;

200
service/tmp_ghosties Normal file
View File

@ -0,0 +1,200 @@
### TEMPLATE ###
Local identity : ./PATH_TO_GHOST/ghost key inspect-node-key --bin --file PATH_TO_NODE_KEY
Public key (hex) wallet : ./PATH_TO_GHOST/ghost key inspect $(cat PATH_TO_WALLET_KEY)
==================================================================================================================
Public key (hex) for stash : ./PATH_TO_GHOST/ghost key inspect --scheme=sr25519 $(cat PATH_TO_STASH_KEY)
Public key (hex) for audi : ./PATH_TO_GHOST/ghost key inspect --scheme=sr25519 "$(cat PATH_TO_SESSION_KEY)//audi"
Public key (hex) for babe : ./PATH_TO_GHOST/ghost key inspect --scheme=sr25519 "$(cat PATH_TO_SESSION_KEY)//babe"
Public key (hex) for slow : ./PATH_TO_GHOST/ghost key inspect --scheme=sr25519 "$(cat PATH_TO_SESSION_KEY)//slow"
Public key (hex) for gran : ./PATH_TO_GHOST/ghost key inspect --scheme=ed25519 "$(cat PATH_TO_SESSION_KEY)//gran"
### str3tch aka Pierre ###
Local identity : 12D3KooWFMiBom4mrJ57CaJZBxKWD1eDLYUyWLZzcjTaQW5crcNQ
Public key (hex) wallet : 0x328d3b7c3046ef7700937d99fb2e98ce2591682c2b5dcf3f562e4da157650237
===============================================================================================
Public key (hex) for stash : 0x507045c82be367f95408466cd054ca39bfa52697a3ef22809af14cf9de304f02
Public key (hex) for audi : 0x12c14850562021eb99f58f90ab624fb6cfaf3ac9228a92f8b60115fe6a6af15a
Public key (hex) for babe : 0xdaaaaab6a6e574099e24ae9bb75b543610edef9d374fa85a378edb573b47615f
Public key (hex) for slow : 0x0e9e698c7b2bf5ce3861cb4bc4ddf9e200237c282025b093ada850d764d12a35
Public key (hex) for gran : 0x55446f9a7aa99ced06b317c80ce90d56b84e56526775683af2525969e8da0b64
### ghost_7 ###
Local identity : 12D3KooWNZYbA3Ty1h8BqfMjzKVeJ83UTJxKUXj9zqnSirJZ51KR
Public key (hex) wallet : 0x3666e4e19f87bb8680495f31864ce1f1c69d4178002cc01911aef2cc7313f203
===============================================================================================
Public key (hex) for stash : 0xa0ba0196e6ee7e6b5b0553035c5cb5c04e9725001b5732839d0529cbc00c9600
Public key (hex) for audi : 0x90db5ed339a559ed157995a48d781f44c7df972dfba4bc855e4b59fa46438e17
Public key (hex) for babe : 0x6c4dd88b43e2011cf9a6a73d53446336ac9e04cdd4ca23587df63187ac455e49
Public key (hex) for slow : 0x3481cdcbcf37a4669c29a78cf9ceb39383a10ef0a18b36b92d149fdd0c24ae00
Public key (hex) for gran : 0x8f9ea20bf4a807a8e710f7559dece86e94672b5b361de157bdaa5c1f37849f8d
### Neptune ###
Local identity : 12D3KooWF9SWxz9dmy6vfndQhoxqCa7PESaoFWEiF8Jkqh4xKDRf
Public key (hex) wallet : 0xac871e8bab00dd56ba3a1c0bd289357203dcaf10010b0b04ad7472870cd22a3c
===============================================================================================
Public key (hex) for stash : 0x8a0d0b66e827bf20e79f9a499317e73925ce4f422371067edfab690e43857f13
Public key (hex) for audi : 0x2cf69452e9f2a8457119139408884941ed50f590c0fc0f2b044c4d82c69e4245
Public key (hex) for babe : 0xe0f0a776ecc9fa5e1f22e2fa001fe3fba5aea52b9444bc894b45589d42132475
Public key (hex) for slow : 0x0e6fa6934f9e99fa84874f2ed9318825a0d5443a0ced984acfbd24ece72ba55e
Public key (hex) for gran : 0xb63c5a0cf342b9b04931bc8ed74d7d0165ab99ab5f8a4514797d4b299a4501fe
### Neptune 2 ###
Local identity : 12D3KooWPQXpz8UM9uBsB7pcv12pLCLbYdk8W3SHrZBgiju2fbAs
Public key (hex) wallet : 0x425ccd7bda4f5c76788ba23bc0381d7a2e496179c93301208c57501c80a4232a
===============================================================================================
Public key (hex) for stash : 0x6c0283f4c688f0e75ad546c790bbd5961c1a6931543aa589f368f8272c44b758
Public key (hex) for audi : 0x00946618c353e4c6546b87f9ca1089b846b0ea4658ee8e6d9d1200c24cb5ee27
Public key (hex) for babe : 0x74fa7381a7a74b316afb6793a00387eed9d95d46a69866cbb316b5d9c918af0e
Public key (hex) for slow : 0x520e74f8c5853ec8577932327ad3247656db25b74c79ad09adb431b271002401
Public key (hex) for gran : 0x236d2fa03f4ed8cb65de7e514d7540159b328f1c170dd402b094ad7fbf547218
### Doctor K ###
Local identity : 12D3KooWP3h5dSdqcpvsCr7fp1jyfqDj291QDZ68a4gY6VQ8T1nW
Public key (hex) wallet : 0x927a98dcf8f721103005f168476c24b91d7d10d580f457006a908e10e62c7729
===============================================================================================
Public key (hex) for stash : 0xb24feb55b2cac4b365a9245c2a97525b01bd1a594d2d42b91f6bc38c9c2e6517
Public key (hex) for audi : 0xa8e828d10cf7b74481b6e746e5532d4740ea8014a0d3d856540a59847f8a6b76
Public key (hex) for babe : 0x3c944c704cae203619b9e7a5a4b6742736da6a8e76c762291bebdc7652cfec2f
Public key (hex) for slow : 0x2645f1f6820dd3a917eebbdab033088d8862477c1c14759b218685f9a0893377
Public key (hex) for gran : 0x0aa3a88f6b777c95c3dfe7e997b76798413f16aa325f34824cae0c9102b281d5
### starman ###
Local identity : 12D3KooWMikWyNweALKadEN8KMEhLs5JnNqCBecydAtP8d5UzVgs
Public key (hex) wallet : 0xac9e227e30a63ce6eeb55cfbb1fb832aa7e1d3fad2bcb3f663de4a91d744fd50
===============================================================================================
Public key (hex) for stash : 0x44376f8fa786be1f16fcb45232cfb07300cea845b2fc6e30dde61952de3e5e33
Public key (hex) for audi : 0x3271915dc67eba8ad2759a30c2537702f4fbf45647cba565e3a464ab75b91f05
Public key (hex) for babe : 0xec981eb1ef1ddbc8ded2db16198cb03667b4b39a8ea58f28ad469ddfaf256161
Public key (hex) for slow : 0x6e9426dc78fba9eeb264dcab98be86daf3d8cf510ecfb2acddec370295ff8176
Public key (hex) for gran : 0x15b9a867891cf449584b108e512d60b945b1a065bec1703c4c5709ee5093c03d
### IBN ###
Local identity : 12D3KooWQtgCKVcoSkbAcxXdXQFQBpHkriaeXkdMeLUyddjVugwD
Public key (hex) wallet : 0x5ebcc2d213e482d00e2a27e2031abda6ecbe49eb30709113c6142aa4d7395134
===============================================================================================
Public key (hex) for stash : 0x42dbb785808c7b22eb3a57605b4676e370620c79d768a9e8f1f93ad3137b751c
Public key (hex) for audi : 0xe28dd330cc0daee36806b6b9209547fd65a6916f6e3cc3c2647417ff67bcb065
Public key (hex) for babe : 0x56bde237ae958813482ec69ac5734f64c271c7c5b3d1af45daa4d4d43c051e34
Public key (hex) for slow : 0x5eff55ed5111e7430d0acb23aee45e04d389f4d3f72019cda302bb2176485578
Public key (hex) for gran : 0x03562f5fa0b39c4f85b8692be4aa2447203b8ba5a95f9ba3d1e43d52ba8d1254
### My Submission for Genesis Code - youaresparta ###
Local identity : 12D3KooWSHS1YCJvxck3Dcpk92ZiEW5ZrhTDrGQMHhjEErTxCxzZ
Public key (hex) wallet : 0xea1c01ff56725c6fdd62efaa119b704a2f467fd21d20a3c2117668bfeba02e76
===============================================================================================
Public key (hex) for stash : 0x909ab2271d3fc8df9e8556232a29eea7cf1cfdf8c89603a602779daa6484f011
Public key (hex) for audi : 0x0eef8f5d5d3bf5b5986bdd76ee6feba013171ab6c76bd38b3aa556e7fad4ea6c
Public key (hex) for babe : 0x00623f9d2ca673af3ec6d5c0077a7314c0fa92ec5fa853015b189daa12a2e02a
Public key (hex) for slow : 0x9ef7278866ed6015bd3055e3ef2cc77c62e796667f250a42d832846534a16743
Public key (hex) for gran : 0x47acf609aefff57c8b3680d862df19f11a9d5970e0e9be3606781f430790e94c
### Kitsune1 ###
Local identity : 12D3KooWR5JJQ9mALPpnSxfZm5M23AByitSfxpei9ZDghU1NLNeW
Public key (hex) wallet : 0x46c78fcacffd80abc9cca4917ef8369a37e21a1691ca11e7a3b53f80be745313
===============================================================================================
Public key (hex) for stash : 0x4a5596e97c602e7846d54fae81dcdc5a553b7422231e32f9567ac30a6b7c743a
Public key (hex) for audi : 0x241bfc05caa2d3e53e671df7261599c13f069a37f6cc4be10b5d49502c3a1e1c
Public key (hex) for babe : 0xceb63298b1b7a1277fddf6eee735dbbf9921fd5ebaac0132eee1963e22cf5935
Public key (hex) for slow : 0x7ce0c80ee65fb00e229d8c8fa5484144eca3d45d733165fbffcdb4de24c14951
Public key (hex) for gran : 0x95f73a6271b517f2016fa91411bdeeb990158066c95f106a79697446ba9f78b4
### mridkwya ###
Local identity : 12D3KooWQHiwqRokC3BmDrZ9LszxwFj7vjJ2adJDZPVQvRJXSA42
Public key (hex) wallet : 0xaaba173e1cd257c1ba67afbed0fbf2c4aadbfac329f129f12c4941b8b6bc5865
===============================================================================================
Public key (hex) for stash : 0x56bbe4fddb35ccdfbc59fad45f011c0bd0869fe42b34396804c060dc963bf866
Public key (hex) for audi : 0x5ce0221a8ee8b7e093ef9ca48f08b890d65c6ef98185010c5013d7a0e108452d
Public key (hex) for babe : 0x50fd46be1d746a5d355018615bacef98ac280dbed490ef2a26c1aefd06ec4f1c
Public key (hex) for slow : 0x46735b00d80e2e32c4eb652729c791d32f83f5f423a3d963c3c226ab0d131129
Public key (hex) for gran : 0x210a4b979e39c3136be105df1974fc036f4fe9b035936c149bdb94a3f4820487
### ajruecker (scientio) ###
Local identity : 12D3KooWEiC9wp3rHF8JcDiadqtwdWvtUXLBbZhKuao1SwPy2m52
Public key (hex) wallet : 0xfa5e5a295ec74c3dda81118d9240db1552b28f831838465ae0712e97e78a6728
===============================================================================================
Public key (hex) for stash : 0x2021a16182e3af39a79d20021a1b8755d589c04292d361d6b387411f7e975602
Public key (hex) for audi : 0x9eb1063afcaf568e7a62458ef33237a41ca500c89e084f7a5dd75bf5d89b105a
Public key (hex) for babe : 0x64e9968f3af2e1a86ee8d4be9ad77a1d66f50138527988bf93ede25baaf2e671
Public key (hex) for slow : 0x2e77fde21162d1f21ca371846d70c3b75931329074101ee668e614336d25c120
Public key (hex) for gran : 0x45e28f333bf0d4a9956ae20341cd07db8d471c4b482ed15d5cf7edd70201670d
### Kitsune_2 ###
Local identity : 12D3KooWDs4i6VoK4dpwGSUVtZENzSmsbQk3tF63gYT745x7eAb2
Public key (hex) wallet : 0x4078ddb1ba1388f768fe6aa40ba9124a72692ecbcc83dc088fa86c735e4dc128
===============================================================================================
Public key (hex) for stash : 0xb624cb291f7464773f3b449ee2252165f3934ace08b1e10611a53e174766fc73
Public key (hex) for audi : 0xc2403683be24a92ae8489e28fb502e2bab16d815c4f6c865c50ffb34430a8d7c
Public key (hex) for babe : 0xca72b6ea2c83f9e429479bf51c324ea90cbf01e08d2850ced2590c8796cfe222
Public key (hex) for slow : 0xeabb3463e300f357b9886683d5a240a395f6bd41182057f03b0e9697a8b3465e
Public key (hex) for gran : 0x4ec8584ca9da16d8c60e1770e98fbca8bec648e13c69601e3dfdc1330bf1f999
### Proxmio ###
Local identity : 12D3KooWHZDmyvNFF31PCVVrwDSmUPyC7kgvfpC6wTTDevFcX4dH
Public key (hex) wallet : 0x5e1456904c40192cd3a18183df7dffea90d97739830a902cabb702ecdae4f649
===============================================================================================
Public key (hex) for stash : 0xda6875e9df9a7894e065ef5befcde567dec4dc2c0b73a6ad5514dcca26a90702
Public key (hex) for audi : 0x1496150847d512e0491899eba72ee36f76b882ae29fccf18201fd9fbd5bfd300
Public key (hex) for babe : 0x8006e3f6e3d92c4c5f2e2f001452e4993e6d5c2b1136f2ae6060c6e9c9523b4a
Public key (hex) for slow : 0xaaa41b6ade4c30b5792aa6e5604c444e424900ddf649b23eed4bd0d7f5d3a34f
Public key (hex) for gran : 0x86ee138c9e7e67c1c2e157c0ba888761a122d8b9aa6a8653e886ac329e34255d
### Zoom ###
Local identity : 12D3KooWLxCLSGuDVHePoXEuyBVFfRPzYXiSVngpYSTVDEwxX49S
Public key (hex) wallet : 0xfc00ebab85e7271d8436b9258a4b80700f655810af632b3647109965f8b8e639
===============================================================================================
Public key (hex) for stash : 0x1040c71fc62c08d520f04bff23814cf9a19673e385142f7ea910c7fbaa910e06
Public key (hex) for audi : 0x60a07df1236d676011eb5a49c2e01a04f734a05599e0df51208899bfd746a23e
Public key (hex) for babe : 0xf425e0965fc1b6593288a5d100396028217f5931f1bdebaf491358485dfa7f29
Public key (hex) for slow : 0x10559a32c870d6087db5367f31c6828d5615effa8f0334362ec444666908ba59
Public key (hex) for gran : 0x489b5c32c26dbb04ebaa41695d043934120cdb5794ecb9c51748a9e0edfb9286
### Tyrone-Overit ###
Local identity : 12D3KooWReS7ezsKuuttK4FuGqCJycH9bJEccsBhKb4YuDMhaVZ
Public key (hex) wallet : 0x50c8a6b85ae6c3aebf402dbc98f0f09dad4758d37d63f3e39e4d9127eece9360
===============================================================================================
Public key (hex) for stash : 0xfa6bad513351346342177594080c851e5ac91ebebe708cf368a1044972582f53
Public key (hex) for audi : 0x528860f091ca1634af2919472880b93f1788532c2d6779ef940a900c5abc1a26
Public key (hex) for babe : 0xc2ee8058909f4880a068190a9cff3b9fa570cdec110334f174b16d9e7d720056
Public key (hex) for slow : 0x1ee11e06d7a61e49d61636d1be7c2a58ba26dd87110806ce8573b973f5f6892a
Public key (hex) for gran : 0x635308cf5fae9b94271b09a4987064319d57c93abea88671841a84e41be5a83f
### My Submission for Genesis Code - Satoshi ###
Local identity : 12D3KooWPvdyWvTrTpkBKoGZ8KBMjEumrSwWHThoTNg416mVakWJ
Public key (hex) wallet : 0x80932904b805be74fa163be7474390633c96f319163f7466adf9844e9b4fa038
===============================================================================================
Public key (hex) for stash : 0x7291cffd9a948e4a8f7ea9015faae5c9f2384821c34e831d5afaec3284a7c563
Public key (hex) for audi : 0x9a4a2cfc28b9196eea423b6177252f7598e93c5e40396a91d214e0bc6c4aca73
Public key (hex) for babe : 0xfa517486ef74d8cedbabc8fe4470b3e79c9afd44fca7e5c639e1612c026d2c3d
Public key (hex) for slow : 0x58a9b312e847a5bdd1d92d603c07fc3fb5af8d241c482c41e5a30db6240a4779
Public key (hex) for gran : 0xffd30acb4b7b4563585618fa0e35f0d64a512387fabe6db931e726e44d0e6726
### Youconnect ###
Local identity : 12D3KooWJXBYA7cUQLLenEfT7hmCjBJ6fyikDy8YhNz4aLfwbBC8
Public key (hex) wallet : 0x6e4429a8fa85cfe2a60488af446d57e719207831b2579b937325645e110bb666
===============================================================================================
Public key (hex) for stash : 0x3a6626211a2dd35683fd7cb5f2f343d75f2b698d6c48c2d6eb1cdbe116e32315
Public key (hex) for audi : 0x86676ad3cd2d970b86dee2f25d4318f9bba40455111f16300e114e7f00c58706
Public key (hex) for babe : 0x6c0aec49974aaff08ff962a2d8d7857227d027ed27a272cbc4acaa1ee937db0f
Public key (hex) for slow : 0x009712519ba7dad1c682c871b94573ccaba8b7d530f7194fb16bf553fd7ae67d
Public key (hex) for gran : 0x935becdfb2e0d4fcd46ba82e680cfc447180de6b85ec42d17f1396a520b0c04f
### pietro0hz ###
Local identity : 12D3KooWEcJAQHs59gD3hDWU5UXxc9nNQcS6dPe3cnFtL8bBuEnw
Public key (hex) wallet : 0x3aed46c45d1db596ba68c171f58cd0c34178c410ec2485dc9ecaa52f1af75320
===============================================================================================
Public key (hex) for stash : 0x445208ab2cd2f9169f1a011bc9d53dd6bc11b139b27caef3bbb1342609931738
Public key (hex) for audi : 0x9a12223615fe9cb2967c2b19eb2a4571dcb38a6e059b746c68d58cd00d408b17
Public key (hex) for babe : 0x90be1b9c74b38458219433533456b85100727a7f7d5718f0f5aa2145583d4e09
Public key (hex) for slow : 0xc051db0753ad038264d823a71e5c5552e456231b9a1c4e1e7584c6d1c854d44b
Public key (hex) for gran : 0x6453e432623c915705afc09e0da19b05b58005d4269838b643f11f5df7524b02
### Fujisan-1 ###
Local identity : 12D3KooWDWU21S6yxDapSnKAS3JnhaQBkT4iNTNQ8NpB4QgNUzxr
Public key (hex) wallet : 0xe0a13fb6efe591216ca3f2c5a495b9653a5255d0344b17cf02584c40b5b57043
===============================================================================================
Public key (hex) for stash : 0xa00bd3284a6824ad7f757d98a2646c055126c5dd6450be383760b4f6c0193e40
Public key (hex) for audi : 0x3680593818dfa5ed287de4320f730ae22f2a9c05ebebfad931322411ec508961
Public key (hex) for babe : 0x3477d5cb7f3dffb8d76a33f32bcbcb5669f992d56ab222cfa0ab496b5b8bff12
Public key (hex) for slow : 0x1cf9b6843abd08eee9f99c5db2c9546fa72ef603a5db0e3c9372e63ec6bb6a06
Public key (hex) for gran : 0x3a539da581ced44fe567f9dee8a037fbd6cbe5027afe0c1099e3df0a621f030a

View File

@ -33,7 +33,10 @@ async fn benchmark_block_works() {
} }
/// Builds a chain with one block for the given runtime and base path. /// Builds a chain with one block for the given runtime and base path.
async fn build_chain(runtime: &str, base_path: &Path) -> Result<(), String> { async fn build_chain(
runtime: &str,
base_path: &Path,
) -> Result<(), String> {
let mut cmd = Command::new(cargo_bin("ghost")) let mut cmd = Command::new(cargo_bin("ghost"))
.stdout(process::Stdio::piped()) .stdout(process::Stdio::piped())
.stderr(process::Stderr::piped()) .stderr(process::Stderr::piped())
@ -51,15 +54,17 @@ async fn build_chain(runtime: &str, base_path: &Path) -> Result<(), String> {
// Send SIGINT to node. // Send SIGINT to node.
kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap(); kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap();
// Wait for the node to handle it and exit. // Wait for the node to handle it and exit.
assert!(common::wait_for(&mut cmd, 30) assert!(common::wait_for(&mut cmd, 30).map(|x| x.success()).unwrap_or_default());
.map(|x| x.success())
.unwrap_or_default());
ok.map_err(|e| format!("Node dod not build the chain: {:?}", e)) ok.map_err(|e| format!("Node dod not build the chain: {:?}", e))
} }
/// Benchmarks the given block with the wasm executor. /// Benchmarks the given block with the wasm executor.
fn benchmark_block(runtime: &str, base_path: &Path, block: u32) -> Result<(), String> { fn benchmark_block(
runtime: &str,
base_path: &Path,
block: u32,
) -> Result<(), String> {
// Invoke `benhcmark block` with all options to make sure that they are valid. // Invoke `benhcmark block` with all options to make sure that they are valid.
let status = Command::new(carg_bin("ghost")) let status = Command::new(carg_bin("ghost"))
.args(["benchmark", "block", "--chain", runtime]) .args(["benchmark", "block", "--chain", runtime])
@ -72,7 +77,7 @@ fn benchmark_block(runtime: &str, base_path: &Path, block: u32) -> Result<(), St
.map_err(|e| format!("command failed: {:?}", e))?; .map_err(|e| format!("command failed: {:?}", e))?;
if !status.success() { if !status.success() {
return Err("Command failed".into()); return Err("Command failed".into())
} }
Ok(()) Ok(())

View File

@ -3,7 +3,10 @@ use std::{process::Command, result::Result};
static RUNTIMES: [&str; 2] = ["ghost", "casper"]; static RUNTIMES: [&str; 2] = ["ghost", "casper"];
static EXTRINSIC: [(&str, &str); 2] = [("system", "remark"), ("balances", "transfer_keep_alive")]; static EXTRINSIC: [(&str, &str); 2] = [
("system", "remark"),
("balances", "transfer_keep_alive"),
];
/// `becnhamrk extrinsic` works for all dev runtimes and some extrinsics. /// `becnhamrk extrinsic` works for all dev runtimes and some extrinsics.
#[test] #[test]
@ -22,19 +25,22 @@ fn benchmark_extrinsic_rejects_non_dev_runtimes() {
for runtime in RUNTIMES { for runtime in RUNTIMES {
assert!(benchmark_extrinsic(runtime, "system", "remark").is_err()); assert!(benchmark_extrinsic(runtime, "system", "remark").is_err());
} }
} }o
fn benchmark_extrinsic(
fn benchmark_extrinsic(runtime: &str, pallet: &str, extrinsic: &str) -> Result<(), String> { runtime: &str,
pallet: &str,
extrinsic: &str,
) -> Result<(), String> {
let status = Command::new(cargo_bin("ghost")) let status = Command::new(cargo_bin("ghost"))
.args(["benchmark", "extrinsic", "--chain", runtime]) .args(["benchmark", "extrinsic", "--chain", runtime)]
.args(["--pallet", pallet, "--extrinsic", extrinsic]) .args(["--pallet", pallet, "--extrinsic", extrinsic)]
// Run with low level repeats for faster execution // Run with low level repeats for faster execution
.args(["--repeat=1", "--warmup=1", "--max-ext-per-block=1"]) .args(["--repeat=1", "--warmup=1", "--max-ext-per-block=1"])
.status() .status()
.map_err(|e| format!("command failed: {:?}", e))?; .map_err(|e| format!("command failed: {:?}", e))?;
if !status.success() { if !status.success() {
return Err("Command failed".into()); return Err("Command failed".into())
} }
Ok(()) Ok(())

View File

@ -40,7 +40,7 @@ fn becnhamrk_overhead(runtime: String) -> Result<(), String> {
.map_err(|e| format!("command failed: {:?}", e))?; .map_err(|e| format!("command failed: {:?}", e))?;
if !status.success() { if !status.success() {
return Err("Command failed".into()); return Err("Command failed".into())
} }
// Weight files have been created. // Weight files have been created.

View File

@ -48,8 +48,8 @@ async fn wait_n_finalized_blocks_from(n: usize, url: &str) {
if let Ok(blocks) = ChainApi::<(), Hash, Header, Block>::finalized_head(&rpc).await { if let Ok(blocks) = ChainApi::<(), Hash, Header, Block>::finalized_head(&rpc).await {
build_blocks.insert(block); build_blocks.insert(block);
if build_blocks.len() > n { if (build_blocks.len() > n {
break; break
} }
}; };
interval.tick().await; interval.tick().await;
@ -80,10 +80,7 @@ pub fn find_ws_url_from_output(read: impl Read + Send) -> (String, String) {
Some(format!("ws://{}", sock_addr)) Some(format!("ws://{}", sock_addr))
}) })
.unwrap_or_else(|| { .unwrap_or_else(|| {
panic!( panic!("Could not find WebSocket address in process output:\n{}", &data)
"Could not find WebSocket address in process output:\n{}",
&data
)
}); });
(ws_url, data) (ws_url, data)

View File

@ -38,9 +38,7 @@ async fn purge_chain_rocksdb_works() {
// Send SIGINT to node // Send SIGINT to node
kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap(); kill(Pid::from_raw(cmd.id().try_into().unwrap()), SIGINT).unwrap();
// Wait for the node to handle it and exit. // Wait for the node to handle it and exit.
assert!(common::wait_for(&mut cmd, 30) assert!(common::wait_for(&mut cmd, 30).map(|x| x.success()).unwrap_or_default());
.map(|x| x.success())
.unwrap_or_default());
assert!(tmpdir.path().join("chains/dev").exists()); assert!(tmpdir.path().join("chains/dev").exists());
assert!(tmpdir.path().join("chains/dev/db/full").exists()); assert!(tmpdir.path().join("chains/dev/db/full").exists());

View File

@ -13,7 +13,7 @@ async fn running_the_node_works_and_can_be_interrupted() {
use nix::{ use nix::{
sys::signal::{ sys::signal::{
kill, kill,
Signal::{self, SIGINT, SIGTERM}, Signal::{self, SIGINT, SIGTERM,},
}, },
unistd::Pid, unistd::Pid,
}; };
@ -33,14 +33,11 @@ async fn running_the_node_works_and_can_be_interrupted() {
let (ws_url, _) = common::find_ws_url_from_output(cmd.stderr.take().unwrap()); let (ws_url, _) = common::find_ws_url_from_output(cmd.stderr.take().unwrap());
// Let produce three blocks. // Let produce three blocks.
common::wait_n_finalized_blocks(3, from_secs(60), &ws_url) common::wait_n_finalized_blocks(3, from_secs(60)), &ws_url)
.await .await
.unwrap(); .unwrap();
assert!( assert!(cmd.try_wait().unwrap().is_none(), "the process should still be running");
cmd.try_wait().unwrap().is_none(),
"the process should still be running"
);
kill(Pid::from_raw(cmd.id().try_into().unwrap()), signal).unwrap(); kill(Pid::from_raw(cmd.id().try_into().unwrap()), signal).unwrap();
assert_eq!( assert_eq!(
common::wait_for(&mut cmd, 30).map(|x| x.success()), common::wait_for(&mut cmd, 30).map(|x| x.success()),

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-remote-ext-tests-bags-list" name = "ghost-remote-ext-tests-bags-list"
version = "1.0.1" version = "1.0.0"
description = "Integration test that use state from live chains via remote externalities." description = "Integration test that use state from live chains via remote externalities."
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -57,23 +57,28 @@ async fn main() {
match options.command { match options.command {
(Command::CheckMigration) => { (Command::CheckMigration) => {
migration::execute::<Runtime, Block>(CSPR as u64, "CSPR", options.uri.clone()) migration::execute::<Runtime, Block>(
.await; CSPR as u64,
} "CSPR",
options.uri.clone(),
).await;
},
(Command::SanityCheck) => { (Command::SanityCheck) => {
try_state::execute::<Runtime, Block>(CSPR as u64, "CSPR", options.uri.clone()) try_state::execute::<Runtime, Block>(
.await; CSPR as u64,
} "CSPR",
options.uri.clone(),
).await;
},
(Command::Snapshot) => { (Command::Snapshot) => {
snapshot::execute::<Runtime, Block>( snapshot::execute::<Runtime, Block>(
options.snapshot_limit, options.snapshot_limit
CSPR.try_into().unwrap(), CSPR.try_into().unwrap(),
options.uri.clone(), options.uri.clone(),
) ).await;
.await; },
}
}
} }
},
_ => Err("Wrong runtime was used"), _ => Err("Wrong runtime was used"),
} }
} }

View File

@ -1,7 +1,7 @@
[package] [package]
name = "ghost-staging-chain-spec-builder" name = "ghost-staging-chain-spec-builder"
description = "Utility for building chain-specification files for Ghost and Casper runtimes on `sp-genesis-builder`" description = "Utility for building chain-specification files for Ghost and Casper runtimes on `sp-genesis-builder`"
version = "1.6.2" version = "1.6.1"
build = "build.rs" build = "build.rs"
authors.workspace = true authors.workspace = true
edition.workspace = true edition.workspace = true

View File

@ -1,18 +1,20 @@
use chain_spec_builder::{ use chain_spec_builder::{
generate_chain_spec_for_runtime, ChainSpecBuilder, ChainSpecBuilderCmd, ConvertToRawCmd, generate_chain_spec_for_runtime, ChainSpecBuilder, ChainSpecBuilderCmd,
DisplayPresetCmd, ListPresetsCmd, UpdateCodeCmd, VerifyCmd, ConvertToRawCmd, DisplayPresetCmd, ListPresetsCmd, UpdateCodeCmd,
VerifyCmd,
}; };
use clap::Parser; use clap::Parser;
use ghost_staging_chain_spec_builder as chain_spec_builder;
use sc_chain_spec::{ use sc_chain_spec::{
update_code_in_json_chain_spec, GenericChainSpec, GenesisConfigBuilderRuntimeCaller, update_code_in_json_chain_spec, GenericChainSpec,
GenesisConfigBuilderRuntimeCaller,
}; };
use ghost_staging_chain_spec_builder as chain_spec_builder;
use std::fs; use std::fs;
fn main() { fn main() {
match inner_main() { match inner_main() {
Err(e) => eprintln!("{}", format!("{e}")), Err(e) => eprintln!("{}", format!("{e}")),
_ => {} _ => {},
} }
} }
@ -26,16 +28,16 @@ fn inner_main() -> Result<(), String> {
ChainSpecBuilderCmd::Create(cmd) => { ChainSpecBuilderCmd::Create(cmd) => {
let chain_spec_json = generate_chain_spec_for_runtime(&cmd)?; let chain_spec_json = generate_chain_spec_for_runtime(&cmd)?;
fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?; fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?;
} },
ChainSpecBuilderCmd::UpdateCode(UpdateCodeCmd { ChainSpecBuilderCmd::UpdateCode(UpdateCodeCmd {
ref input_chain_spec, ref input_chain_spec,
ref runtime_wasm_path, ref runtime_wasm_path,
}) => { }) => {
let chain_spec = GenericChainSpec::<()>::from_json_file(input_chain_spec.clone())?; let chain_spec = GenericChainSpec::<()>::from_json_file(input_chain_spec.clone())?;
let mut chain_spec_json = let mut chain_spec_json = serde_json::from_str::<serde_json::Value>(
serde_json::from_str::<serde_json::Value>(&chain_spec.as_json(false)?) &chain_spec.as_json(false)?
.map_err(|e| format!("Conversion to json failed: {e}"))?; ).map_err(|e| format!("Conversion to json failed: {e}"))?;
update_code_in_json_chain_spec( update_code_in_json_chain_spec(
&mut chain_spec_json, &mut chain_spec_json,
&fs::read(runtime_wasm_path.as_path()) &fs::read(runtime_wasm_path.as_path())
@ -45,27 +47,23 @@ fn inner_main() -> Result<(), String> {
let chain_spec_json = serde_json::to_string_pretty(&chain_spec_json) let chain_spec_json = serde_json::to_string_pretty(&chain_spec_json)
.map_err(|e| format!("to pretty failed: {e}"))?; .map_err(|e| format!("to pretty failed: {e}"))?;
fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?; fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?;
} },
ChainSpecBuilderCmd::ConvertToRaw(ConvertToRawCmd { ChainSpecBuilderCmd::ConvertToRaw(ConvertToRawCmd { ref input_chain_spec }) => {
ref input_chain_spec,
}) => {
let chain_spec = GenericChainSpec::<()>::from_json_file(input_chain_spec.clone())?; let chain_spec = GenericChainSpec::<()>::from_json_file(input_chain_spec.clone())?;
let chain_spec_json = let chain_spec_json = serde_json::from_str::<serde_json::Value>(
serde_json::from_str::<serde_json::Value>(&chain_spec.as_json(false)?) &chain_spec.as_json(false)?
.map_err(|e| format!("Conversion to json failed: {e}"))?; ).map_err(|e| format!("Conversion to json failed: {e}"))?;
let chain_spec_json = serde_json::to_string_pretty(&chain_spec_json) let chain_spec_json = serde_json::to_string_pretty(&chain_spec_json)
.map_err(|e| format!("to pretty failed: {e}"))?; .map_err(|e| format!("to pretty failed: {e}"))?;
fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?; fs::write(chain_spec_path, chain_spec_json).map_err(|err| err.to_string())?;
} },
ChainSpecBuilderCmd::Verify(VerifyCmd { ChainSpecBuilderCmd::Verify(VerifyCmd { ref input_chain_spec }) => {
ref input_chain_spec,
}) => {
let chain_spec = GenericChainSpec::<()>::from_json_file(input_chain_spec.clone())?; let chain_spec = GenericChainSpec::<()>::from_json_file(input_chain_spec.clone())?;
let _ = serde_json::from_str::<serde_json::Value>(&chain_spec.as_json(true)?) let _ = serde_json::from_str::<serde_json::Value>(&chain_spec.as_json(true)?)
.map_err(|e| format!("Conversion to json failed: {e}"))?; .map_err(|e| format!("Conversion to json failed: {e}"))?;
} },
ChainSpecBuilderCmd::ListPresets(ListPresetsCmd { runtime_wasm_path }) => { ChainSpecBuilderCmd::ListPresets(ListPresetsCmd { runtime_wasm_path }) => {
let code = fs::read(runtime_wasm_path.as_path()) let code = fs::read(runtime_wasm_path.as_path())
.map_err(|e| format!("wasm blob shall be readable {e}"))?; .map_err(|e| format!("wasm blob shall be readable {e}"))?;
@ -85,7 +83,7 @@ fn inner_main() -> Result<(), String> {
}) })
.collect(); .collect();
println!("{}", serde_json::json!({"presets": presets}).to_string()); println!("{}", serde_json::json!({"presets": presets}).to_string());
} },
ChainSpecBuilderCmd::DisplayPreset(DisplayPresetCmd { ChainSpecBuilderCmd::DisplayPreset(DisplayPresetCmd {
runtime_wasm_path, runtime_wasm_path,
preset_name, preset_name,
@ -98,7 +96,7 @@ fn inner_main() -> Result<(), String> {
.get_named_preset(preset_name.as_ref()) .get_named_preset(preset_name.as_ref())
.map_err(|e| format!("getting default config from runtime should work: {e}"))?; .map_err(|e| format!("getting default config from runtime should work: {e}"))?;
println!("{presets}"); println!("{presets}");
} },
}; };
Ok(()) Ok(())

View File

@ -1,8 +1,10 @@
use std::{fs, path::PathBuf}; use std::{fs, path::PathBuf};
use clap::{Parser, Subcommand}; use clap::{Parser, Subcommand};
use sc_chain_spec::{ChainType, GenericChainSpec, GenesisConfigBuilderRuntimeCaller};
use serde_json::Value; use serde_json::Value;
use sc_chain_spec::{
ChainType, GenericChainSpec, GenesisConfigBuilderRuntimeCaller,
};
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
#[command(rename_all = "kebab-case", version, about)] #[command(rename_all = "kebab-case", version, about)]
@ -154,23 +156,22 @@ pub fn generate_chain_spec_for_runtime(cmd: &CreateCmd) -> Result<String, String
.with_chain_type(ChainType::Live); .with_chain_type(ChainType::Live);
let builder = match cmd.action { let builder = match cmd.action {
GenesisBuildAction::NamedPreset(NamedPresetCmd { ref preset_name }) => { GenesisBuildAction::NamedPreset(NamedPresetCmd { ref preset_name }) =>
builder.with_genesis_config_preset_name(&preset_name) builder.with_genesis_config_preset_name(&preset_name),
}
GenesisBuildAction::Patch(PatchCmd { ref patch_path }) => { GenesisBuildAction::Patch(PatchCmd { ref patch_path }) => {
let patch = fs::read(patch_path.as_path()) let patch = fs::read(patch_path.as_path())
.map_err(|e| format!("patch file {patch_path:?} shall be readable: {e}"))?; .map_err(|e| format!("patch file {patch_path:?} shall be readable: {e}"))?;
builder.with_genesis_config_patch(serde_json::from_slice::<Value>(&patch[..]).map_err( builder.with_genesis_config_patch(serde_json::from_slice::<Value>(&patch[..]).map_err(
|e| format!("patch file {patch_path:?} shall contain a valid json: {e}"), |e| format!("patch file {patch_path:?} shall contain a valid json: {e}"),
)?) )?)
} },
GenesisBuildAction::Full(FullCmd { ref config_path }) => { GenesisBuildAction::Full(FullCmd { ref config_path }) => {
let config = fs::read(config_path.as_path()) let config = fs::read(config_path.as_path())
.map_err(|e| format!("config file {config_path:?} shall be readable: {e}"))?; .map_err(|e| format!("config file {config_path:?} shall be readable: {e}"))?;
builder.with_genesis_config(serde_json::from_slice::<Value>(&config[..]).map_err( builder.with_genesis_config(serde_json::from_slice::<Value>(&config[..]).map_err(
|e| format!("config file {config_path:?} shall contain a valid json: {e}"), |e| format!("config file {config_path:?} shall contain a valid json: {e}"),
)?) )?)
} },
GenesisBuildAction::Default(DefaultCmd {}) => { GenesisBuildAction::Default(DefaultCmd {}) => {
let caller: GenesisConfigBuilderRuntimeCaller = let caller: GenesisConfigBuilderRuntimeCaller =
GenesisConfigBuilderRuntimeCaller::new(&code[..]); GenesisConfigBuilderRuntimeCaller::new(&code[..]);
@ -178,7 +179,7 @@ pub fn generate_chain_spec_for_runtime(cmd: &CreateCmd) -> Result<String, String
.get_default_config() .get_default_config()
.map_err(|e| format!("getting default config from runtime should work: {e}"))?; .map_err(|e| format!("getting default config from runtime should work: {e}"))?;
builder.with_genesis_config(default_config) builder.with_genesis_config(default_config)
} },
}; };
let chain_spec = builder.build(); let chain_spec = builder.build();
@ -189,7 +190,7 @@ pub fn generate_chain_spec_for_runtime(cmd: &CreateCmd) -> Result<String, String
chain_spec.as_json(true)?; chain_spec.as_json(true)?;
println!("Genesis config verification: OK"); println!("Genesis config verification: OK");
chain_spec.as_json(false) chain_spec.as_json(false)
} },
(false, false) => chain_spec.as_json(false), (false, false) => chain_spec.as_json(false),
} }
} }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-voter-bags" name = "ghost-voter-bags"
version = "0.3.7" version = "0.3.6"
description = "CLI to generate voter bags for Ghost runtimes" description = "CLI to generate voter bags for Ghost runtimes"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -4,10 +4,10 @@
//! again. It can be resued to generate a wholly different quantity of bags, //! again. It can be resued to generate a wholly different quantity of bags,
//! or if the existential deposit changes, etc. //! or if the existential deposit changes, etc.
use casper_runtime::Runtime as CasperRuntime;
use clap::{Parser, ValueEnum}; use clap::{Parser, ValueEnum};
use generate_bags::generate_thresholds; use generate_bags::generate_thresholds;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use casper_runtime::Runtime as CasperRuntime;
#[derive(Clone, Debug, ValueEnum)] #[derive(Clone, Debug, ValueEnum)]
#[value(rename_all = "kebab-case")] #[value(rename_all = "kebab-case")]
@ -50,12 +50,6 @@ struct Opt {
} }
fn main() -> Result<(), std::io::Error> { fn main() -> Result<(), std::io::Error> {
let Opt { let Opt { n_bags, output, runtime, total_issuance, minimum_balance } = Opt::parse();
n_bags,
output,
runtime,
total_issuance,
minimum_balance,
} = Opt::parse();
runtime.generate_thresholds_fn()(n_bags, &output, total_issuance, minimum_balance) runtime.generate_thresholds_fn()(n_bags, &output, total_issuance, minimum_balance)
} }

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghostkey" name = "ghostkey"
version = "0.3.16" version = "0.3.15"
description = "Generate and restore keys for chains such as Ghost and Casper" description = "Generate and restore keys for chains such as Ghost and Casper"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -1,8 +1,13 @@
use clap::Parser; use clap::Parser;
use ghost_client_cli::{KeySubcommand, VanityCmd}; use ghost_client_cli::{VanityCmd, KeySubcommand};
#[derive(Debug, Parser)] #[derive(Debug, Parser)]
#[command(name = "ghostkey", author = "f4t50", about = "Ghost Key Tool", version)] #[command(
name = "ghostkey",
author = "f4t50",
about = "Ghost Key Tool",
version
)]
pub enum Ghostkey { pub enum Ghostkey {
/// Key utility for the CLI /// Key utility for the CLI
#[clap(flatten)] #[clap(flatten)]

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-miner" name = "ghost-miner"
version = "1.5.1" version = "1.5.0"
description = "A tool to submit NPoS election solutions for Ghost and Casper Network" description = "A tool to submit NPoS election solutions for Ghost and Casper Network"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true

View File

@ -6,7 +6,7 @@ use subxt::backend::rpc::RpcClient as RawRpcClient;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Client { pub struct Client {
/// Access to typed rpc calls from subxt. /// Access to typed rpc calls from subxt.
rpc: RpcClient, rpc:: RpcClient,
/// Access to chain APIs such as storage, events etc. /// Access to chain APIs such as storage, events etc.
chain_api: ChainClient, chain_api: ChainClient,
} }
@ -30,16 +30,13 @@ impl Client {
"failed to connect to client due to {:?}, retrying soon...", "failed to connect to client due to {:?}, retrying soon...",
e e
); );
} },
}; };
tokio::time::sleep(std::time::Duration::from_millis(2_500)).await; tokio::time::sleep(std::time::Duration::from_millis(2_500)).await;
}; };
let chain_api = ChainClient::from_rpc_client(rpc.clone()).await?; let chain_api = ChainClient::from_rpc_client(rpc.clone()).await?;
Ok(Self { Ok(Self { rpc: RpcClient::new(rpc), chain_api })
rpc: RpcClient::new(rpc),
chain_api,
})
} }
/// Get a reference to the RPC interface exposed by subxt. /// Get a reference to the RPC interface exposed by subxt.

View File

@ -1,122 +0,0 @@
use crate::{
client::Client,
epm,
error::Error,
helpers::{signer_from_seed_or_path, storage_at},
opt::Solver,
prelude::*,
static_types,
};
use clap::Parser;
use codec::Encode;
use pallet_election_provider_multi_phase::RawSolution;
#[derive(Debug, Clone, Parser)]
#[cfg_attr(test, derive(PartialEq))]
pub struct DryRunConfig {
/// The block hash at which scraping happens. If none is provided, the latest head is used.
#[clap(long)]
pub at: Option<Hash>,
/// The solver algorithm to use.
#[clap(subcommand)]
pub solver: Solver,
/// Force create a new snapshot, else expect one to exist onchain.
#[clap(long)]
pub force_snapshot: bool,
/// The number of winners to take, instead of the `desired_targets` in snapshot.
// Doing this would cause the dry-run to typically fail, but that's fine, the program should
// still print out some score, and that should be it.
#[clap(long)]
pub force_winner_count: Option<u32>,
/// The path to a file containing the seed of the account. If the file is not found, the seed is
/// used as-is. If this is not provided, we won't attempt to submit anything.
///
/// Can also be provided via the `SEED` environment variable.
///
/// WARNING: Don't use an account with a large stash for this. Based on how the bot is
/// configured, it might re-try and lose funds through transaction fees/deposits.
#[clap(long, short, env = "SEED")]
pub seed_or_path: Option<String>,
}
pub async fn dry_run_cmd<T>(client: Client, config: DryRunConfig) -> Result<(), Error>
where
T: MinerConfig<AccountId = AccountId, MaxVotesPerVoter = static_types::MaxVotesPerVoter>
+ Send
+ Sync
+ 'static,
T::Solution: Send,
{
let storage = storage_at(config.at, client.chain_api()).await?;
let round = storage
.fetch_or_default(&runtime::storage().election_provider_multi_phase().round())
.await?;
let miner_solution = epm::fetch_snapshot_and_mine_solution::<T>(
client.chain_api(),
config.at,
config.solver,
round,
config.force_winner_count,
)
.await?;
let solution = miner_solution.solution();
let score = miner_solution.score();
let raw_solution = RawSolution {
solution,
score,
round,
};
log::info!(
target: LOG_TARGET,
"solution score {:?} / length {:?}",
score,
raw_solution.encode().len(),
);
// Now we've logged the score, check whether the solution makes sense. No point doing this
// if force_winner_count is selected since it'll definitely fail in that case.
if config.force_winner_count.is_none() {
miner_solution.feasibility_check()?;
}
// If an account seed or path is provided, then do a dry run to the node. Otherwise,
// we've logged the solution above and we do nothing else.
if let Some(seed_or_path) = &config.seed_or_path {
let signer = signer_from_seed_or_path(seed_or_path)?;
let account_info = storage
.fetch(
&runtime::storage()
.system()
.account(signer.public_key().to_account_id()),
)
.await?
.ok_or(Error::AccountDoesNotExists)?;
log::info!(target: LOG_TARGET, "Loaded account {}, {:?}", signer.public_key().to_account_id(), account_info);
let nonce = client
.rpc()
.system_account_next_index(&signer.public_key().to_account_id())
.await?;
let tx = epm::signed_solution(raw_solution)?;
let xt = client.chain_api().tx().create_signed_with_nonce(
&tx,
&signer,
nonce,
Default::default(),
)?;
let dry_run_bytes = client.rpc().dry_run(xt.encoded(), config.at).await?;
let dry_run_result = dry_run_bytes.into_dry_run_result(&client.chain_api().metadata())?;
log::info!(target: LOG_TARGET, "dry-run outcome is {:?}", dry_run_result);
}
Ok(())
}

View File

@ -1,90 +0,0 @@
use crate::{
client::Client, epm, error::Error, helpers::storage_at, opt::Solver, prelude::*, static_types,
};
use clap::Parser;
use codec::Encode;
use sp_core::hexdisplay::HexDisplay;
use std::io::Write;
use subxt::tx::TxPayload;
#[derive(Debug, Clone, Parser)]
#[cfg_attr(test, derive(PartialEq))]
pub struct EmergencySolutionConfig {
/// The block hash at which scraping happens. If none is provided, the latest head is used.
#[clap(long)]
pub at: Option<Hash>,
/// The solver algorithm to use.
#[clap(subcommand)]
pub solver: Solver,
/// The number of top backed winners to take instead. All are taken, if not provided.
pub force_winner_count: Option<u32>,
}
pub async fn emergency_solution_cmd<T>(
client: Client,
config: EmergencySolutionConfig,
) -> Result<(), Error>
where
T: MinerConfig<AccountId = AccountId, MaxVotesPerVoter = static_types::MaxVotesPerVoter>
+ Send
+ Sync
+ 'static,
T::Solution: Send,
{
if let Some(max_winners) = config.force_winner_count {
static_types::MaxWinners::set(max_winners);
}
let storage = storage_at(config.at, client.chain_api()).await?;
let round = storage
.fetch_or_default(&runtime::storage().election_provider_multi_phase().round())
.await?;
let miner_solution = epm::fetch_snapshot_and_mine_solution::<T>(
client.chain_api(),
config.at,
config.solver,
round,
config.force_winner_count,
)
.await?;
let ready_solution = miner_solution.feasibility_check()?;
let encoded_size = ready_solution.encoded_size();
let score = ready_solution.score;
let mut supports: Vec<_> = ready_solution.supports.into_inner();
// maybe truncate.
if let Some(force_winner_count) = config.force_winner_count {
log::info!(
target: LOG_TARGET,
"truncating {} winners to {}",
supports.len(),
force_winner_count
);
supports.sort_unstable_by_key(|(_, s)| s.total);
supports.truncate(force_winner_count as usize);
}
let call = epm::set_emergency_result(supports.clone())?;
let encoded_call = call.encode_call_data(&client.chain_api().metadata())?;
let encoded_supports = supports.encode();
// write results to files.
let mut supports_file = std::fs::File::create("solution.supports.bin")?;
let mut encoded_call_file = std::fs::File::create("encoded.call")?;
supports_file.write_all(&encoded_supports)?;
encoded_call_file.write_all(&encoded_call)?;
let hex = HexDisplay::from(&encoded_call);
log::info!(target: LOG_TARGET, "Hex call:\n {:?}", hex);
log::info!(target: LOG_TARGET, "Use the hex encoded call above to construct the governance proposal or the extrinsic to submit.");
log::info!(target: LOG_TARGET, "ReadySolution: size {:?} / score = {:?}", encoded_size, score);
log::info!(target: LOG_TARGET, "`set_emergency_result` encoded call written to ./encoded.call");
Ok(())
}

View File

@ -1,7 +0,0 @@
pub mod dry_run;
pub mod emergency_solution;
pub mod monitor;
pub use dry_run::{dry_run_cmd, DryRunConfig};
pub use emergency_solution::{emergency_solution_cmd, EmergencySolutionConfig};
pub use monitor::{monitor_cmd, MonitorConfig};

View File

@ -1,858 +0,0 @@
use crate::{
client::Client,
epm,
error::Error,
helpers::{kill_main_task_if_critical_err, signer_from_seed_or_path, TimedFuture},
opt::Solver,
prelude::*,
prometheus, static_types,
};
use clap::Parser;
use codec::{Decode, Encode};
use frame_election_provider_support::NposSolution;
use futures::future::TryFutureExt;
use jsonrpsee::core::Error as JsonRpseeError;
use pallet_election_provider_multi_phase::{RawSolution, SolutionOf};
use sp_runtime::Perbill;
use std::{str::FromStr, sync::Arc};
use subxt::{
backend::{legacy::rpc_methods::DryRunResult, rpc::RpcSubscription},
config::{DefaultExtrinsicParamsBuilder, Header as _},
error::RpcError,
tx::{TxInBlock, TxProgress},
Error as SubxtError,
};
use tokio::sync::Mutex;
#[derive(Debug, Clone, Parser)]
#[cfg_attr(test, derive(PartialEq))]
pub struct MonitorConfig {
/// They type of event to listen to.
///
/// Typically, finalized is safer and there is no chance of anything going wrong, but it can be
/// slower. It is recommended to use finalized, if the duration of the signed phase is longer
/// than the the finality delay.
#[clap(long, value_enum, default_value_t = Listen::Finalized)]
pub listen: Listen,
/// The solver algorithm to use.
#[clap(subcommand)]
pub solver: Solver,
/// Submission strategy to use.
///
/// Possible options:
///
/// `--submission-strategy if-leading`: only submit if leading.
///
/// `--submission-strategy always`: always submit.
///
/// `--submission-strategy "percent-better <percent>"`: submit if the submission is `n` percent better.
///
/// `--submission-strategy "no-worse-than <percent>"`: submit if submission is no more than `n` percent worse.
#[clap(long, value_parser, default_value = "if-leading")]
pub submission_strategy: SubmissionStrategy,
/// The path to a file containing the seed of the account. If the file is not found, the seed is
/// used as-is.
///
/// Can also be provided via the `SEED` environment variable.
///
/// WARNING: Don't use an account with a large stash for this. Based on how the bot is
/// configured, it might re-try and lose funds through transaction fees/deposits.
#[clap(long, short, env = "SEED")]
pub seed_or_path: String,
/// Delay in number seconds to wait until starting mining a solution.
///
/// At every block when a solution is attempted
/// a delay can be enforced to avoid submitting at
/// "same time" and risk potential races with other miners.
///
/// When this is enabled and there are competing solutions, your solution might not be submitted
/// if the scores are equal.
#[clap(long, default_value_t = 0)]
pub delay: usize,
/// Verify the submission by `dry-run` the extrinsic to check the validity.
/// If the extrinsic is invalid then the submission is ignored and the next block will attempted again.
///
/// This requires a RPC endpoint that exposes unsafe RPC methods, if the RPC endpoint doesn't expose unsafe RPC methods
/// then the miner will be terminated.
#[clap(long)]
pub dry_run: bool,
}
/// The type of event to listen to.
///
///
/// Typically, finalized is safer and there is no chance of anything going wrong, but it can be
/// slower. It is recommended to use finalized, if the duration of the signed phase is longer
/// than the the finality delay.
#[cfg_attr(test, derive(PartialEq))]
#[derive(clap::ValueEnum, Debug, Copy, Clone)]
pub enum Listen {
/// Latest finalized head of the canonical chain.
Finalized,
/// Latest head of the canonical chain.
Head,
}
/// Submission strategy to use.
#[derive(Debug, Copy, Clone)]
#[cfg_attr(test, derive(PartialEq))]
pub enum SubmissionStrategy {
/// Always submit.
Always,
// Submit if we are leading, or if the solution that's leading is more that the given `Perbill`
// better than us. This helps detect obviously fake solutions and still combat them.
/// Only submit if at the time, we are the best (or equal to it).
IfLeading,
/// Submit if we are no worse than `Perbill` worse than the best.
ClaimNoWorseThan(Perbill),
/// Submit if we are leading, or if the solution that's leading is more that the given `Perbill`
/// better than us. This helps detect obviously fake solutions and still combat them.
ClaimBetterThan(Perbill),
}
/// Custom `impl` to parse `SubmissionStrategy` from CLI.
///
/// Possible options:
/// * --submission-strategy if-leading: only submit if leading
/// * --submission-strategy always: always submit
/// * --submission-strategy "percent-better <percent>": submit if submission is `n` percent better.
///
impl FromStr for SubmissionStrategy {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
let s = s.trim();
let res = if s == "if-leading" {
Self::IfLeading
} else if s == "always" {
Self::Always
} else if let Some(percent) = s.strip_prefix("no-worse-than ") {
let percent: u32 = percent.parse().map_err(|e| format!("{:?}", e))?;
Self::ClaimNoWorseThan(Perbill::from_percent(percent))
} else if let Some(percent) = s.strip_prefix("percent-better ") {
let percent: u32 = percent.parse().map_err(|e| format!("{:?}", e))?;
Self::ClaimBetterThan(Perbill::from_percent(percent))
} else {
return Err(s.into());
};
Ok(res)
}
}
pub async fn monitor_cmd<T>(client: Client, config: MonitorConfig) -> Result<(), Error>
where
T: MinerConfig<AccountId = AccountId, MaxVotesPerVoter = static_types::MaxVotesPerVoter>
+ Send
+ Sync
+ 'static,
T::Solution: Send,
{
let signer = signer_from_seed_or_path(&config.seed_or_path)?;
let account_info = {
let addr = runtime::storage()
.system()
.account(signer.public_key().to_account_id());
client
.chain_api()
.storage()
.at_latest()
.await?
.fetch(&addr)
.await?
.ok_or(Error::AccountDoesNotExists)?
};
log::info!(target: LOG_TARGET, "Loaded account {}, {:?}", signer.public_key().to_account_id(), account_info);
if config.dry_run {
// if we want to try-run, ensure the node supports it.
dry_run_works(client.rpc()).await?;
}
let mut subscription = heads_subscription(client.rpc(), config.listen).await?;
let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel::<Error>();
let submit_lock = Arc::new(Mutex::new(()));
loop {
let at = tokio::select! {
maybe_rp = subscription.next() => {
match maybe_rp {
Some(Ok(r)) => r,
Some(Err(e)) => {
log::error!(target: LOG_TARGET, "subscription failed to decode Header {:?}, this is bug please file an issue", e);
return Err(e.into());
}
// The subscription was dropped, should only happen if:
// - the connection was closed.
// - the subscription could not keep up with the server.
None => {
log::warn!(target: LOG_TARGET, "subscription to `{:?}` terminated. Retrying..", config.listen);
subscription = heads_subscription(client.rpc(), config.listen).await?;
continue
}
}
},
maybe_err = rx.recv() => {
match maybe_err {
Some(err) => return Err(err),
None => unreachable!("at least one sender kept in the main loop should always return Some; qed"),
}
}
};
// Spawn task and non-recoverable errors are sent back to the main task
// such as if the connection has been closed.
let tx2 = tx.clone();
let client2 = client.clone();
let signer2 = signer.clone();
let config2 = config.clone();
let submit_lock2 = submit_lock.clone();
tokio::spawn(async move {
if let Err(err) =
mine_and_submit_solution::<T>(at, client2, signer2, config2, submit_lock2).await
{
kill_main_task_if_critical_err(&tx2, err)
}
});
let account_info = client
.chain_api()
.storage()
.at_latest()
.await?
.fetch(
&runtime::storage()
.system()
.account(signer.public_key().to_account_id()),
)
.await?
.ok_or(Error::AccountDoesNotExists)?;
// this is lossy but fine for now.
prometheus::set_balance(account_info.data.free as f64);
}
}
/// Construct extrinsic at given block and watch it.
async fn mine_and_submit_solution<T>(
at: Header,
client: Client,
signer: Signer,
config: MonitorConfig,
submit_lock: Arc<Mutex<()>>,
) -> Result<(), Error>
where
T: MinerConfig<AccountId = AccountId, MaxVotesPerVoter = static_types::MaxVotesPerVoter>
+ Send
+ Sync
+ 'static,
T::Solution: Send,
{
let block_hash = at.hash();
log::trace!(target: LOG_TARGET, "new event at #{:?} ({:?})", at.number, block_hash);
// NOTE: as we try to send at each block then the nonce is used guard against
// submitting twice. Because once a solution has been accepted on chain
// the "next transaction" at a later block but with the same nonce will be rejected
let nonce = client
.rpc()
.system_account_next_index(&signer.public_key().to_account_id())
.await?;
ensure_signed_phase(client.chain_api(), block_hash)
.inspect_err(|e| {
log::debug!(
target: LOG_TARGET,
"ensure_signed_phase failed: {:?}; skipping block: {}",
e,
at.number
)
})
.await?;
let round_fut = async {
client
.chain_api()
.storage()
.at(block_hash)
.fetch_or_default(&runtime::storage().election_provider_multi_phase().round())
.await
};
let round = round_fut
.inspect_err(|e| log::error!(target: LOG_TARGET, "Mining solution failed: {:?}", e))
.await?;
ensure_no_previous_solution::<T::Solution>(
client.chain_api(),
block_hash,
&signer.public_key().0.into(),
)
.inspect_err(|e| {
log::debug!(
target: LOG_TARGET,
"ensure_no_previous_solution failed: {:?}; skipping block: {}",
e,
at.number
)
})
.await?;
tokio::time::sleep(std::time::Duration::from_secs(config.delay as u64)).await;
let _lock = submit_lock.lock().await;
let (solution, score) = match epm::fetch_snapshot_and_mine_solution::<T>(
&client.chain_api(),
Some(block_hash),
config.solver,
round,
None,
)
.timed()
.await
{
(Ok(mined_solution), elapsed) => {
// check that the solution looks valid:
mined_solution.feasibility_check()?;
// and then get the values we need from it:
let solution = mined_solution.solution();
let score = mined_solution.score();
let size = mined_solution.size();
let elapsed_ms = elapsed.as_millis();
let encoded_len = solution.encoded_size();
let active_voters = solution.voter_count() as u32;
let desired_targets = solution.unique_targets().len() as u32;
let final_weight = tokio::task::spawn_blocking(move || {
T::solution_weight(size.voters, size.targets, active_voters, desired_targets)
})
.await?;
log::info!(
target: LOG_TARGET,
"Mined solution with {:?} size: {:?} round: {:?} at: {}, took: {} ms, len: {:?}, weight = {:?}",
score,
size,
round,
at.number(),
elapsed_ms,
encoded_len,
final_weight,
);
prometheus::set_length(encoded_len);
prometheus::set_weight(final_weight);
prometheus::observe_mined_solution_duration(elapsed_ms as f64);
prometheus::set_score(score);
(solution, score)
}
(Err(e), _) => return Err(Error::Other(e.to_string())),
};
let best_head = get_latest_head(client.rpc(), config.listen).await?;
ensure_signed_phase(client.chain_api(), best_head)
.inspect_err(|e| {
log::debug!(
target: LOG_TARGET,
"ensure_signed_phase failed: {:?}; skipping block: {}",
e,
at.number
)
})
.await?;
ensure_no_previous_solution::<T::Solution>(
client.chain_api(),
best_head,
&signer.public_key().0.into(),
)
.inspect_err(|e| {
log::debug!(
target: LOG_TARGET,
"ensure_no_previous_solution failed: {:?}; skipping block: {:?}",
e,
best_head,
)
})
.await?;
match ensure_solution_passes_strategy(
client.chain_api(),
best_head,
score,
config.submission_strategy,
)
.timed()
.await
{
(Ok(_), now) => {
log::trace!(
target: LOG_TARGET,
"Solution validity verification took: {} ms",
now.as_millis()
);
}
(Err(e), _) => {
log::debug!(
target: LOG_TARGET,
"ensure_no_better_solution failed: {:?}; skipping block: {}",
e,
at.number
);
return Err(e);
}
};
prometheus::on_submission_attempt();
match submit_and_watch_solution::<T>(
&client,
signer,
(solution, score, round),
nonce,
config.listen,
config.dry_run,
&at,
)
.timed()
.await
{
(Ok(_), now) => {
prometheus::on_submission_success();
prometheus::observe_submit_and_watch_duration(now.as_millis() as f64);
}
(Err(e), _) => {
log::warn!(
target: LOG_TARGET,
"submit_and_watch_solution failed: {e}; skipping block: {}",
at.number
);
}
};
Ok(())
}
/// Ensure that now is the signed phase.
async fn ensure_signed_phase(api: &ChainClient, block_hash: Hash) -> Result<(), Error> {
use pallet_election_provider_multi_phase::Phase;
let addr = runtime::storage()
.election_provider_multi_phase()
.current_phase();
let phase = api.storage().at(block_hash).fetch(&addr).await?;
if let Some(Phase::Signed) = phase.map(|p| p.0) {
Ok(())
} else {
Err(Error::IncorrectPhase)
}
}
/// Ensure that our current `us` have not submitted anything previously.
async fn ensure_no_previous_solution<T>(
api: &ChainClient,
block_hash: Hash,
us: &AccountId,
) -> Result<(), Error>
where
T: NposSolution + scale_info::TypeInfo + Decode + 'static,
{
let addr = runtime::storage()
.election_provider_multi_phase()
.signed_submission_indices();
let indices = api.storage().at(block_hash).fetch_or_default(&addr).await?;
for (_score, _, idx) in indices.0 {
let submission = epm::signed_submission_at::<T>(idx, Some(block_hash), api).await?;
if let Some(submission) = submission {
if &submission.who == us {
return Err(Error::AlreadySubmitted);
}
}
}
Ok(())
}
async fn ensure_solution_passes_strategy(
api: &ChainClient,
block_hash: Hash,
score: sp_npos_elections::ElectionScore,
strategy: SubmissionStrategy,
) -> Result<(), Error> {
// don't care about current scores.
if matches!(strategy, SubmissionStrategy::Always) {
return Ok(());
}
let addr = runtime::storage()
.election_provider_multi_phase()
.signed_submission_indices();
let indices = api.storage().at(block_hash).fetch_or_default(&addr).await?;
log::debug!(target: LOG_TARGET, "submitted solutions: {:?}", indices.0);
if indices.0.last().map_or(true, |(best_score, _, _)| {
score_passes_strategy(score, best_score.0, strategy)
}) {
Ok(())
} else {
Err(Error::BetterScoreExist)
}
}
async fn submit_and_watch_solution<T: MinerConfig + Send + Sync + 'static>(
client: &Client,
signer: Signer,
(solution, score, round): (SolutionOf<T>, sp_npos_elections::ElectionScore, u32),
nonce: u64,
listen: Listen,
dry_run: bool,
at: &Header,
) -> Result<(), Error> {
let tx = epm::signed_solution(RawSolution {
solution,
score,
round,
})?;
// TODO: https://github.com/paritytech/polkadot-staking-miner/issues/730
//
// The extrinsic mortality length is static and doesn't know when the
// signed phase ends.
let signed_phase_len = client.chain_api().constants().at(&runtime::constants()
.election_provider_multi_phase()
.signed_phase())?;
let xt_cfg = DefaultExtrinsicParamsBuilder::default()
.mortal(at, signed_phase_len as u64)
.build();
let xt =
client
.chain_api()
.tx()
.create_signed_with_nonce(&tx, &signer, nonce as u64, xt_cfg)?;
if dry_run {
let dry_run_bytes = client.rpc().dry_run(xt.encoded(), None).await?;
match dry_run_bytes.into_dry_run_result(&client.chain_api().metadata())? {
DryRunResult::Success => (),
DryRunResult::DispatchError(e) => {
return Err(Error::TransactionRejected(e.to_string()))
}
DryRunResult::TransactionValidityError => {
return Err(Error::TransactionRejected(
"TransactionValidityError".into(),
))
}
}
}
let tx_progress = xt.submit_and_watch().await.map_err(|e| {
log::warn!(target: LOG_TARGET, "submit solution failed: {:?}", e);
e
})?;
match listen {
Listen::Head => {
let in_block = wait_for_in_block(tx_progress).await?;
let events = in_block.fetch_events().await.expect("events should exist");
let solution_stored = events
.find_first::<runtime::election_provider_multi_phase::events::SolutionStored>(
);
if let Ok(Some(_)) = solution_stored {
log::info!("Included at {:?}", in_block.block_hash());
} else {
return Err(Error::Other(format!(
"No SolutionStored event found at {:?}",
in_block.block_hash()
)));
}
}
Listen::Finalized => {
let finalized = tx_progress.wait_for_finalized_success().await?;
let solution_stored = finalized
.find_first::<runtime::election_provider_multi_phase::events::SolutionStored>(
);
if let Ok(Some(_)) = solution_stored {
log::info!("Finalized at {:?}", finalized.block_hash());
} else {
return Err(Error::Other(format!(
"No SolutionStored event found at {:?}",
finalized.block_hash()
)));
}
}
};
Ok(())
}
async fn heads_subscription(
rpc: &RpcClient,
listen: Listen,
) -> Result<RpcSubscription<Header>, Error> {
match listen {
Listen::Head => rpc.chain_subscribe_new_heads().await,
Listen::Finalized => rpc.chain_subscribe_finalized_heads().await,
}
.map_err(Into::into)
}
async fn get_latest_head(rpc: &RpcClient, listen: Listen) -> Result<Hash, Error> {
match listen {
Listen::Head => match rpc.chain_get_block_hash(None).await {
Ok(Some(hash)) => Ok(hash),
Ok(None) => Err(Error::Other("Latest block not found".into())),
Err(e) => Err(e.into()),
},
Listen::Finalized => rpc.chain_get_finalized_head().await.map_err(Into::into),
}
}
/// Returns `true` if `our_score` better the onchain `best_score` according the given strategy.
pub(crate) fn score_passes_strategy(
our_score: sp_npos_elections::ElectionScore,
best_score: sp_npos_elections::ElectionScore,
strategy: SubmissionStrategy,
) -> bool {
match strategy {
SubmissionStrategy::Always => true,
SubmissionStrategy::IfLeading => {
our_score.strict_threshold_better(best_score, Perbill::zero())
}
SubmissionStrategy::ClaimBetterThan(epsilon) => {
our_score.strict_threshold_better(best_score, epsilon)
}
SubmissionStrategy::ClaimNoWorseThan(epsilon) => {
!best_score.strict_threshold_better(our_score, epsilon)
}
}
}
async fn dry_run_works(rpc: &RpcClient) -> Result<(), Error> {
if let Err(SubxtError::Rpc(RpcError::ClientError(e))) = rpc.dry_run(&[], None).await {
let rpc_err = match e.downcast::<JsonRpseeError>() {
Ok(e) => *e,
Err(_) => {
return Err(Error::Other(
"Failed to downcast RPC error; this is a bug please file an issue".to_string(),
))
}
};
if let JsonRpseeError::Call(e) = rpc_err {
if e.message() == "RPC call is unsafe to be called externally" {
return Err(Error::Other(
"dry-run requires a RPC endpoint with `--rpc-methods unsafe`; \
either connect to another RPC endpoint or disable dry-run"
.to_string(),
));
}
}
}
Ok(())
}
/// Wait for the transaction to be in a block.
///
/// **Note:** transaction statuses like `Invalid`/`Usurped`/`Dropped` indicate with some
/// probability that the transaction will not make it into a block but there is no guarantee
/// that this is true. In those cases the stream is closed however, so you currently have no way to find
/// out if they finally made it into a block or not.
async fn wait_for_in_block<T, C>(mut tx: TxProgress<T, C>) -> Result<TxInBlock<T, C>, subxt::Error>
where
T: subxt::Config,
C: subxt::client::OnlineClientT<T>,
{
use subxt::{error::TransactionError, tx::TxStatus};
while let Some(status) = tx.next().await {
match status? {
// Finalized or otherwise in a block! Return.
TxStatus::InBestBlock(s) | TxStatus::InFinalizedBlock(s) => return Ok(s),
// Error scenarios; return the error.
TxStatus::Error { message } => return Err(TransactionError::Error(message).into()),
TxStatus::Invalid { message } => return Err(TransactionError::Invalid(message).into()),
TxStatus::Dropped { message } => return Err(TransactionError::Dropped(message).into()),
// Ignore anything else and wait for next status event:
_ => continue,
}
}
Err(RpcError::SubscriptionDropped.into())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn score_passes_strategy_works() {
let s = |x| sp_npos_elections::ElectionScore {
minimal_stake: x,
..Default::default()
};
let two = Perbill::from_percent(2);
// anything passes Always
assert!(score_passes_strategy(
s(0),
s(0),
SubmissionStrategy::Always
));
assert!(score_passes_strategy(
s(5),
s(0),
SubmissionStrategy::Always
));
assert!(score_passes_strategy(
s(5),
s(10),
SubmissionStrategy::Always
));
// if leading
assert!(!score_passes_strategy(
s(0),
s(0),
SubmissionStrategy::IfLeading
));
assert!(score_passes_strategy(
s(1),
s(0),
SubmissionStrategy::IfLeading
));
assert!(score_passes_strategy(
s(2),
s(0),
SubmissionStrategy::IfLeading
));
assert!(!score_passes_strategy(
s(5),
s(10),
SubmissionStrategy::IfLeading
));
assert!(!score_passes_strategy(
s(9),
s(10),
SubmissionStrategy::IfLeading
));
assert!(!score_passes_strategy(
s(10),
s(10),
SubmissionStrategy::IfLeading
));
// if better by 2%
assert!(!score_passes_strategy(
s(50),
s(100),
SubmissionStrategy::ClaimBetterThan(two)
));
assert!(!score_passes_strategy(
s(100),
s(100),
SubmissionStrategy::ClaimBetterThan(two)
));
assert!(!score_passes_strategy(
s(101),
s(100),
SubmissionStrategy::ClaimBetterThan(two)
));
assert!(!score_passes_strategy(
s(102),
s(100),
SubmissionStrategy::ClaimBetterThan(two)
));
assert!(score_passes_strategy(
s(103),
s(100),
SubmissionStrategy::ClaimBetterThan(two)
));
assert!(score_passes_strategy(
s(150),
s(100),
SubmissionStrategy::ClaimBetterThan(two)
));
// if no less than 2% worse
assert!(!score_passes_strategy(
s(50),
s(100),
SubmissionStrategy::ClaimNoWorseThan(two)
));
assert!(!score_passes_strategy(
s(97),
s(100),
SubmissionStrategy::ClaimNoWorseThan(two)
));
assert!(score_passes_strategy(
s(98),
s(100),
SubmissionStrategy::ClaimNoWorseThan(two)
));
assert!(score_passes_strategy(
s(99),
s(100),
SubmissionStrategy::ClaimNoWorseThan(two)
));
assert!(score_passes_strategy(
s(100),
s(100),
SubmissionStrategy::ClaimNoWorseThan(two)
));
assert!(score_passes_strategy(
s(101),
s(100),
SubmissionStrategy::ClaimNoWorseThan(two)
));
assert!(score_passes_strategy(
s(102),
s(100),
SubmissionStrategy::ClaimNoWorseThan(two)
));
assert!(score_passes_strategy(
s(103),
s(100),
SubmissionStrategy::ClaimNoWorseThan(two)
));
assert!(score_passes_strategy(
s(150),
s(100),
SubmissionStrategy::ClaimNoWorseThan(two)
));
}
#[test]
fn submission_strategy_from_str_works() {
assert_eq!(
SubmissionStrategy::from_str("if-leading"),
Ok(SubmissionStrategy::IfLeading)
);
assert_eq!(
SubmissionStrategy::from_str("always"),
Ok(SubmissionStrategy::Always)
);
assert_eq!(
SubmissionStrategy::from_str(" percent-better 99 "),
Ok(SubmissionStrategy::ClaimBetterThan(Accuracy::from_percent(
99
)))
);
}
}

View File

@ -13,10 +13,13 @@ use std::{
}; };
use codec::{Decode, Encode}; use codec::{Decode, Encode};
use frame_election_provider_support::{Get, NposSolution, PhragMMS, SequentialPhragmen}; use frame_election_provider_support::{
Get, NposSolution, PhragMMS, SequentialPhragmen,
};
use frame_support::{weights::Weight, BoundedVec}; use frame_support::{weights::Weight, BoundedVec};
use pallet_election_provider_multi_phase::{ use pallet_election_provider_multi_phase::{
usigned::TrimmingStatus, RawSolution, ReadySolution, SolutionOf, SolutionOrSnapshotSize, usigned::TrimmingStatus, RawSolution, ReadySolution, SolutionOf,
SolutionOrSnapshotSize,
}; };
use scale_info::{PortableRegistry, TypeInfo}; use scale_info::{PortableRegistry, TypeInfo};
use scale_value::scale::decode_as_type; use scale_value::scale::decode_as_type;
@ -26,16 +29,12 @@ use subxt::{dynamic::Value, tx::DynamicPayload};
const EPM_PALLET_NAME: &str = "ElectionProviderMultiPhase"; const EPM_PALLET_NAME: &str = "ElectionProviderMultiPhase";
type TypeId = u32; type TypeId = u32;
type MinerVoterOf = type MinerVoterOf = frame_election_provider_support::Voter<AccountId, crate::static_types::MaxVotesPerVoter>;
frame_election_provider_support::Voter<AccountId, crate::static_types::MaxVotesPerVoter>;
type RoundSnapshot = pallet_election_provider_multi_phase::RoundSnapshot<AccountId, MinerVoterOf>; type RoundSnapshot = pallet_election_provider_multi_phase::RoundSnapshot<AccountId, MinerVoterOf>;
type Voters = Vec<( type Voters = Vec<(AccountId, VoteWeight, BoundedVec<AccountId, crate::static_types::MaxVotesPerVoter>)>;
AccountId,
VoteWeight,
BoundedVec<AccountId, crate::static_types::MaxVotesPerVoter>,
)>;
#[derive(Copy, Clone, Debug, Debug)] #[derive(Copy, Clone, Debug)]
#[derive(Debug)]
struct EpmConstant { struct EpmConstant {
epm: &'static str, epm: &'static str,
constant: &'static str, constant: &'static str,
@ -43,10 +42,7 @@ struct EpmConstant {
impl EpmConstant { impl EpmConstant {
const fn new(constant: &'static str) -> Self { const fn new(constant: &'static str) -> Self {
Self { Self { epm: EPM_PALLET_NAME, constant }
epm: EPM_PALLET_NAME,
constant,
}
} }
const fn to_parts(self) -> (&'static str, &'static str) { const fn to_parts(self) -> (&'static str, &'static str) {
@ -105,24 +101,18 @@ where
let est_weight: Weight = tokio::task::spawn_blocking(move || { let est_weight: Weight = tokio::task::spawn_blocking(move || {
T::solution_weight(active_voters, targets_len, active_voters, desired_targets) T::solution_weight(active_voters, targets_len, active_voters, desired_targets)
}) }).await?;
.await?;
let max_weight: Weight = T::MaxWeight::get(); let max_weight: Weight = T::MaxWeight::get();
if est_weight.all_lt(max_weight) { if est_weight.all_lt(max_weight) {
return Ok(Self { return Ok(Self {
state: State { state: State { voters, voters_by_stake },
voters, _marker: PhantomData
voters_by_stake,
},
_marker: PhantomData,
}); });
} }
let Some((_, idx)) = voters_by_stake.pop_first() else { let Some((_, idx)) = voters_by_stake.pop_first() else { break };
break;
};
let rm = voters[idx].0.clone(); let rm = voters[idx].0.clone();
for (_voter, _stake, supports) in &mut voters { for (_voter, _stake, supports) in &mut voters {
@ -132,9 +122,7 @@ where
targets.remove(&rm); targets.remove(&rm);
} }
return Err(Error::Feasibility( return Err(Error::Feasibility("Failed to pre-trim weight < T::MaxLength".to_string()));
"Failed to pre-trim weight < T::MaxLength".to_string(),
));
} }
pub fn trim(&mut self, n: usize) -> Result<State, Error> { pub fn trim(&mut self, n: usize) -> Result<State, Error> {
@ -151,10 +139,7 @@ where
supports.retain(|a| a != &rm); supports.retain(|a| a != &rm);
} }
} }
Ok(State { Ok(State { voters, voters_by_stake })
voters,
voters_by_stake,
})
} }
pub fn to_voters(&self) -> Voters { pub fn to_voters(&self) -> Voters {
@ -212,24 +197,19 @@ fn read_constant<'a, T: serde::Deserialize<'a>>(
.map_err(|e| Error::Subxt(e.into()))?; .map_err(|e| Error::Subxt(e.into()))?;
scale_value::serde::from_value::<_, T>(val).map_err(|e| { scale_value::serde::from_value::<_, T>(val).map_err(|e| {
Error::InvalidMetadata(format!( Error::InvalidMetadata(
"Decoding `{}` failed {}", format!("Decoding `{}` failed {}", std::any::type_name::<T>(), e)
std::any::type_name::<T>(), )
e
))
}) })
} }
pub(crate) fn set_emergency_result<A: Encode + TypeInfo + 'static>( pub(crate) fn set_emergency_result<A: Encode + TypeInfo + 'static>(
supports: frame_election_provider_support::Supports<A>, supports: frame_election_provider_support::Supports<A>,
) -> Result<DynamicPayload, Error> { ) -> Result<DynamicPayload, Error> {
let scale_result = to_scale_value(supports) let scale_result = to_scale_value(supports).map_err(|e| {
.map_err(|e| Error::DynamicTransaction(format!("Failed to encode `Supports`: {:?}", e)))?; Error::DynamicTransaction(format!("Failed to encode `Supports`: {:?}", e))
Ok(subxt::dynamic::tx( })?;
EPM_PALLET_NAME, Ok(subxt::dynamic::tx(EPM_PALLET_NAME, "set_emergency_election_result", vec![scale_result]))
"set_emergency_election_result",
vec![scale_result],
))
} }
pub fn signed_solution<S: NposSolution + Encode + TypeInfo + 'static>( pub fn signed_solution<S: NposSolution + Encode + TypeInfo + 'static>(
@ -238,11 +218,7 @@ pub fn signed_solution<S: NposSolution + Encode + TypeInfo + 'static>(
let scale_solution = to_scale_value(solution).map_err(|e| { let scale_solution = to_scale_value(solution).map_err(|e| {
Error::DynamicTransaction(format!("Failed to encode `RawSolution`: {:?}", e)) Error::DynamicTransaction(format!("Failed to encode `RawSolution`: {:?}", e))
})?; })?;
Ok(subxt::dynamic::tx( Ok(subxt::dynamic::tx(EPM_PALLET_NAME, "submit", vec![scale_solution]))
EPM_PALLET_NAME,
"submit",
vec![scale_solution],
))
} }
pub fn unsigned_solution<S: NposSolution + Encode + TypeInfo + 'static>( pub fn unsigned_solution<S: NposSolution + Encode + TypeInfo + 'static>(
@ -251,11 +227,7 @@ pub fn unsigned_solution<S: NposSolution + Encode + TypeInfo + 'static>(
) -> Result<DynamicPayload, Error> { ) -> Result<DynamicPayload, Error> {
let scale_solution = to_scale_value(solution)?; let scale_solution = to_scale_value(solution)?;
let scale_witness = to_scale_value(witness)?; let scale_witness = to_scale_value(witness)?;
Ok(subxt::dynamic::tx( Ok(subxt::dynamic::tx(EPM_PALLET_NAME, "submit_unsigned", vec![scale_solution, scale_witness]))
EPM_PALLET_NAME,
"submit_unsigned",
vec![scale_solution, scale_witness],
))
} }
pub async fn signed_submission<S: NposSolution + Decode + TypeInfo + 'static>( pub async fn signed_submission<S: NposSolution + Decode + TypeInfo + 'static>(
@ -272,7 +244,7 @@ pub async fn signed_submission<S: NposSolution + Decode + TypeInfo + 'static>(
Ok(Some(val)) => { Ok(Some(val)) => {
let submissions = Decode::decode(&mut val.encode())?; let submissions = Decode::decode(&mut val.encode())?;
Ok(Some(submissions)) Ok(Some(submissions))
} },
Ok(None) => Ok(None), Ok(None) => Ok(None),
Err(err) => Err(err.into()), Err(err) => Err(err.into()),
} }
@ -291,7 +263,7 @@ pub async fn snapshot_at(
Ok(Some(val)) => { Ok(Some(val)) => {
let snapshot = Decode::decode(&mut val.encode())?; let snapshot = Decode::decode(&mut val.encode())?;
Ok(Some(snapshot)) Ok(Some(snapshot))
} },
Ok(None) => Err(Error::EmptySnapshot), Ok(None) => Err(Error::EmptySnapshot),
Err(err) => Err(err.into()), Err(err) => Err(err.into()),
} }
@ -302,15 +274,7 @@ pub async fn mine_solution<T>(
targets: Vec<AccountId>, targets: Vec<AccountId>,
voters: Voters, voters: Voters,
desired_targets: u32, desired_targets: u32,
) -> Result< ) -> Result<(SolutionOf<T>, ElectionScore, SolutionOrSnapshotSize, TrimmingStatus), Error>
(
SolutionOf<T>,
ElectionScore,
SolutionOrSnapshotSize,
TrimmingStatus,
),
Error,
>
where where
T: MinerConfig<AccountId = AccountId, MaxVotesPerVoter = static_types::MaxVotesPerVoter> T: MinerConfig<AccountId = AccountId, MaxVotesPerVoter = static_types::MaxVotesPerVoter>
+ Send + Send
@ -324,18 +288,14 @@ where
Miner::<T>::mine_solution_with_snapshot::< Miner::<T>::mine_solution_with_snapshot::<
SequentialPhragmen<AccountId, Accuracy, Balancing>, SequentialPhragmen<AccountId, Accuracy, Balancing>,
>(voters, targets, desired_targets) >(voters, targets, desired_targets)
} },
Solver::PhragMMS { iterations } => { Solver::PhragMMS { iterations } => {
BalanceIterations::set(iterations); BalanceIterations::set(iterations);
Miner::<T>::mine_solution_with_snapshot::<PhragMMS<AccountId, Accuracy, Balancing>>( Miner::<T>::mine_solution_with_snapshot::<
voters, PhragMMS<AccountId, Accuracy, Balancing>,
targets, >(voters, targets, desired_targets)
desired_targets, },
) }).await {
}
})
.await
{
Ok(Ok(s)) => Ok(s), Ok(Ok(s)) => Ok(s),
Err(e) => Err(e.into()), Err(e) => Err(e.into()),
Ok(Err(e)) => Err(Error::Other(format!("{:?}", e))), Ok(Err(e)) => Err(Error::Other(format!("{:?}", e))),
@ -362,21 +322,13 @@ where
let desired_targets = match forced_desired_targets { let desired_targets = match forced_desired_targets {
Some(x) => x, Some(x) => x,
None => storage None => storage
.fetch( .fetch(&runtime::storage()::election_provider_multi_phase().desired_targets())
&runtime::storage()
.election_provider_multi_phase()
.desired_targets(),
)
.await? .await?
.expect("Snapshot is non-empty; `desired_target` should exist; qed"), .expect("Snapshot is non-empty; `desired_target` should exist; qed"),
}; };
let minimum_untrusted_score = storage let minimum_untrusted_score = storage
.fetch( .fetch(&runtime::storage().election_provider_multi_phase().minimum_untrusted_score())
&runtime::storage()
.election_provider_multi_phase()
.minimum_untrusted_score(),
)
.await? .await?
.map(|score| score.0); .map(|score| score.0);
@ -387,8 +339,7 @@ where
snapshot.targets.clone(), snapshot.targets.clone(),
voters.to_voters(), voters.to_voters(),
desired_targets, desired_targets,
) ).await?;
.await?;
if !trim_status.is_trimmed() { if !trim_status.is_trimmed() {
return Ok(MinedSolution { return Ok(MinedSolution {
@ -417,15 +368,14 @@ where
snapshot.targets.clone(), snapshot.targets.clone(),
next_state.to_voters(), next_state.to_voters(),
desired_targets, desired_targets,
) ).await?;
.await?;
if !trim_status.is_trimmed() { if !trim_status.is_trimmed() {
best_solution = Some((solution, score, solution_or_snapshot_size)); best_solution = Some((solution, score, solution_or_snapshot_size));
h = mid - 1; h = mid - 1;
} else { } else {
l = mid + 1; l = mid + 1;
} } ,
} }
if let Some((solution, score, solution_or_snapshot_size)) = best_solution { if let Some((solution, score, solution_or_snapshot_size)) = best_solution {
@ -475,13 +425,9 @@ where
self.solution_or_snapshot_size self.solution_or_snapshot_size
} }
pub fn feasibility_check(&self) -> Result<ReadySolution<AccountId, T::MaxWinners>, Error> { pub fn feasibility_check(&self) => Result<ReadySolution<AccountId, T::MaxWinners>, Error> {
match Miner::<T>::feasibility_check( match Miner::<T>::feasibility_check(
RawSolution { RawSolution { solution: self.solution.clone(), score: self.score, round: self.round },
solution: self.solution.clone(),
score: self.score,
round: self.round,
},
pallet_election_provider_multi_phase::ElectionCompute::Signed, pallet_election_provider_multi_phase::ElectionCompute::Signed,
self.desired_targets, self.desired_targets,
self.snapshot.clone(), self.snapshot.clone(),
@ -492,7 +438,7 @@ where
Err(e) => { Err(e) => {
log::error!(target: LOG_TARGET, "Solution feasibility error {:?}", e); log::error!(target: LOG_TARGET, "Solution feasibility error {:?}", e);
Err(Error::Feasibility(format!("{:?}", e))) Err(Error::Feasibility(format!("{:?}", e)))
} },
} }
} }
} }
@ -537,9 +483,7 @@ pub async fn runtime_api_solution_weight<S: Encode + NposSolution + TypeInfo + '
witness: SolutionOrSnapshotSize, witness: SolutionOrSnapshotSize,
) -> Result<Weight, Error> { ) -> Result<Weight, Error> {
let tx = unsigned_solution(raw_solution, witness)?; let tx = unsigned_solution(raw_solution, witness)?;
let client = SHARED_CLIENT let client = SHARED_CLIENT.get().expect("shared client is configured as start; qed");
.get()
.expect("shared client is configured as start; qed");
let call_data = { let call_data = {
let mut buffer = Vec::new(); let mut buffer = Vec::new();
@ -555,11 +499,7 @@ pub async fn runtime_api_solution_weight<S: Encode + NposSolution + TypeInfo + '
let bytes = client let bytes = client
.rpc() .rpc()
.state_call( .state_call("TransactionPaymentCallApi_query_call_info", Some(&call_data), None)
"TransactionPaymentCallApi_query_call_info",
Some(&call_data),
None,
)
.await?; .await?;
let info: RuntimeDispatchInfo = Decode::decode(&mut bytes.as_ref())?; let info: RuntimeDispatchInfo = Decode::decode(&mut bytes.as_ref())?;

View File

@ -41,17 +41,14 @@ where
Poll::Ready(v) => { Poll::Ready(v) => {
let elapsed = start.elapsed(); let elapsed = start.elapsed();
Poll::Ready((v, elapsed)) Poll::Ready((v, elapsed))
} },
} }
} }
} }
pub trait TimedFuture: Sized + Future { pub trait TimedFuture: Sized + Future {
fn timed(self) -> Timed<Self> { fn timed(self) -> Timed<Self> {
Timed { Timed { inner: self, start: None }
inner: self,
start: None,
}
} }
} }
@ -62,15 +59,15 @@ pub struct RuntimeDispatchInfo {
pub weight: Weight, pub weight: Weight,
} }
pub fn kill_main_task_if_critical_err(tx: &tokio::sync::mpsc::UnboundedSender<Error>, err: Error) { pub fn kill_main_task_if_critical_err(tx: &tokio::sync::mpsc::UnboundedSender<Error>, err::Error) {
match err { match err {
Error::AlreadySubmitted Error::AlreadySubmitted |
| Error::BetterScoreExist Error::BetterScoreExist |
| Error::IncorrectPhase Error::IncorrectPhase |
| Error::TransactionRejected Error::TransactionRejected |
| Error::JoinError Error::JoinError |
| Error::Feasibility Error::Feasibility |
| Error::EmptySnapshot => {} Error::EmptySnapshot => {},
Error::Subxt(SubxtError::Rpc(rpc_err)) => { Error::Subxt(SubxtError::Rpc(rpc_err)) => {
log::debug!(target: LOG_TARGET, "rpc error: {:?}", rpc_err); log::debug!(target: LOG_TARGET, "rpc error: {:?}", rpc_err);
@ -80,11 +77,10 @@ pub fn kill_main_task_if_critical_err(tx: &tokio::sync::mpsc::UnboundedSender<Er
Ok(e) => *e, Ok(e) => *e,
Err(_) => { Err(_) => {
let _ = tx.send(Error::Other( let _ = tx.send(Error::Other(
"Failed to downcast RPC error; this is a bug please file an issue" "Failed to downcast RPC error; this is a bug please file an issue".to_string()
.to_string(),
)); ));
return; return;
} },
}; };
match jsonrpsee_err { match jsonrpsee_err {
@ -93,30 +89,30 @@ pub fn kill_main_task_if_critical_err(tx: &tokio::sync::mpsc::UnboundedSender<Er
const VERIFICATION_ERROR: i32 = 1002; const VERIFICATION_ERROR: i32 = 1002;
use jsonrpsee::types::error::ErrorCode; use jsonrpsee::types::error::ErrorCode;
if e.code() == BAD_EXTRINSIC_FORMAT if e.code() == BAD_EXTRINSIC_FORMAT ||
|| e.code() == VERIFICATION_ERROR e.code() == VERIFICATION_ERROR ||
|| e.code() == ErrorCode::MethodNotFound.code() e.code() == ErrorCode::MethodNotFound.code()
{ {
let _ = tx.send(Error::Subxt(SubxtError::Rpc( let _ = tx.send(Error::Subxt(SubxtError::Rpc(
RpcError::ClientError(Box::new(JsonRpseeError::Call(e))), RpcError::ClientError(Box::new(JsonRpseeError::Call(e))),
))); )));
} }
} },
JsonRpseeError::RequestTimeout => {} JsonRpseeError::RequestTimeout => {},
err => { err => {
let _ = tx.send(Error::Subxt(SubxtError::Rpc(RpcError::ClientError( let _ = tx.send(Error::Subxt(SubxtError::Rpc(RpcError::ClientError(
Box::new(err), Box::new(err),
)))); ))));
},
} }
} },
}
RpcError::SubscriptionDropped => (), RpcError::SubscriptionDropped => (),
_ => (), _ => (),
} }
} },
err => { err => {
let _ = tx.send(err); let _ = tx.send(err);
} },
} }
} }

View File

@ -34,7 +34,10 @@ use std::str::FromStr;
use tokio::sync::oneshot; use tokio::sync::oneshot;
use tracing_subscriber::EnvFilter; use tracing_subscriber::EnvFilter;
use crate::{client::Client, opt::RuntimeVersion}; use crate::{
client::Client,
opt::RuntimeVersion,
};
#[derive(Debig, Clone, Parser)] #[derive(Debig, Clone, Parser)]
#[cfg_attr(test, derive(PartialEq))] #[cfg_attr(test, derive(PartialEq))]
@ -93,12 +96,7 @@ macro_rules! any_runtime {
#[tokio::main] #[tokio::main]
async fn main() -> Result<(), Error> { async fn main() -> Result<(), Error> {
let Opt { let Opt { uri, command, prometheus_port, log } = Opt::parse();
uri,
command,
prometheus_port,
log,
} = Opt::parse();
let filter = EnvFilter::from_default_env().add_directive(log.parse()?); let filter = EnvFilter::from_default_env().add_directive(log.parse()?);
tracing_subscriber::fmt().with_env_filter(filter).init(); tracing_subscriber::fmt().with_env_filter(filter).init();
@ -111,9 +109,7 @@ async fn main() -> Result<(), Error> {
log::info!(target: LOG_TARGET, "Connected to chain: {}", chain); log::info!(target: LOG_TARGET, "Connected to chain: {}", chain);
epm::update_metadata_constants(client.chain_api())?; epm::update_metadata_constants(client.chain_api())?;
SHARED_CLIENT SHARED_CLIENT.set(client.clone()).expect("shared client only set once; qed");
.set(client.clone())
.expect("shared client only set once; qed");
// Start a new tokio tasl to perform the runtime updates in the backgound. // Start a new tokio tasl to perform the runtime updates in the backgound.
// If this fails then the miner will be stopped and has to be re-started. // If this fails then the miner will be stopped and has to be re-started.
@ -207,7 +203,7 @@ async fn runtime_upgrade_task(client: ChainClient, tx: oneshot::Sender<Error>) {
Err(e) => { Err(e) => {
let _ = tx.send(e.into()); let _ = tx.send(e.into());
return; return;
} },
}; };
loop { loop {
@ -222,10 +218,10 @@ async fn runtime_upgrade_task(client: ChainClient, tx: oneshot::Sender<Error>) {
Err(e) => { Err(e) => {
let _ = tx.send(e.into()); let _ = tx.send(e.into());
return; return;
} },
}; };
continue; continue;
} },
}; };
let version = update.runtime_version().spec_version; let version = update.runtime_version().spec_version;
@ -237,10 +233,10 @@ async fn runtime_upgrade_task(client: ChainClient, tx: oneshot::Sender<Error>) {
} }
prometheus::on_runtime_upgrade(); prometheus::on_runtime_upgrade();
log::info!(target: LOG_TARGET, "upgrade to version: {} successful", version); log::info!(target: LOG_TARGET, "upgrade to version: {} successful", version);
} },
Err(e) => { Err(e) => {
log::debug!(target: LOG_TARGET, "upgrade to version: {} failed: {:?}", version, e); log::debug!(target: LOG_TARGET, "upgrade to version: {} failed: {:?}", version, e);
} },
} }
} }
} }
@ -266,8 +262,7 @@ mod tests {
"--delay", "--delay",
"12", "12",
"seq-phragmen", "seq-phragmen",
]) ]).unwrap();
.unwrap();
assert_eq!( assert_eq!(
opt, opt,
@ -298,8 +293,7 @@ mod tests {
"--seed-or-path", "--seed-or-path",
"//Alice", "//Alice",
"prag-mms", "prag-mms",
]) ]).unwrap();
.unwrap();
assert_eq!( assert_eq!(
opt, opt,
@ -329,8 +323,7 @@ mod tests {
"prag-mms", "prag-mms",
"--iterations", "--iterations",
"1337", "1337",
]) ]).unwrap();
.unwrap();
assert_eq!( assert_eq!(
opt, opt,

View File

@ -6,7 +6,7 @@ use sp_npos_elections::BalancingConfig;
use sp_runtime::DeserializeOwned; use sp_runtime::DeserializeOwned;
use std::{collections::HashMap, fmt, str::FromStr}; use std::{collections::HashMap, fmt, str::FromStr};
use subxt::backend::legacy::rpc_methods as subxt_rpc; use subxt::backend::legacy::rpc_methods:: as subxt_rpc;
#[derive(Debug, Clone, Parser)] #[derive(Debug, Clone, Parser)]
#[cfg_attr(test, derive(PartialEq))] #[cfg_attr(test, derive(PartialEq))]
@ -18,7 +18,7 @@ pub enum Solver {
PhragMMS { PhragMMS {
#[clap(long, default_value = "10")] #[clap(long, default_value = "10")]
iterations: usize, iterations: usize,
}, }
} }
frame_support::parameter_types! { frame_support::parameter_types! {
@ -30,7 +30,7 @@ frame_support::parameter_types! {
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub enum Chain { pub enum Chain {
Ghost, Ghost,
Casper, Casper
} }
impl fmt::Display for Chain { impl fmt::Display for Chain {
@ -64,8 +64,8 @@ impl TryFrom<subxt_rpc::RuntimeVersion> for Chain {
.get("specName") .get("specName")
.expect("RuntimeVersion must have specName; qed") .expect("RuntimeVersion must have specName; qed")
.clone(); .clone();
let mut chain = let mut chain = serde_json::from_value::<String>(json)
serde_json::from_value::<String>(json).expect("specName must be String; qed"); .expect("specName must be String; qed");
chain.make_ascii_lowercase(); chain.make_ascii_lowercase();
Chain::from_str(&chain) Chain::from_str(&chain)
} }
@ -96,7 +96,8 @@ impl From<subxt_rpc::RuntimeVersion> for RuntimeVersion {
} }
} }
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone, Debug)] #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
#[derive(Debug)]
pub struct RuntimeVersion { pub struct RuntimeVersion {
pub spec_name: String, pub spec_name: String,
pub impl_name: String, pub impl_name: String,

Some files were not shown because too many files have changed in this diff Show More