Compare commits
18 Commits
2bb66c4e19
...
df85600159
Author | SHA1 | Date | |
---|---|---|---|
df85600159 | |||
141f05ddab | |||
6ae3fd6291 | |||
767161ac9c | |||
a74e42369b | |||
7216f1d82b | |||
792e70c988 | |||
eb3b4f2651 | |||
24a6f803c5 | |||
8d69e5c87e | |||
48ff511685 | |||
8f20b7ef5c | |||
ce26787a11 | |||
e21ac88235 | |||
c933ed3809 | |||
2ad43a56ba | |||
6d06fcf9a0 | |||
c2f9958c1a |
50
Cargo.lock
generated
50
Cargo.lock
generated
@ -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 = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "Inflector"
|
name = "Inflector"
|
||||||
@ -1186,7 +1186,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "casper-runtime"
|
name = "casper-runtime"
|
||||||
version = "3.5.25"
|
version = "3.5.29"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"casper-runtime-constants",
|
"casper-runtime-constants",
|
||||||
"frame-benchmarking",
|
"frame-benchmarking",
|
||||||
@ -1203,6 +1203,7 @@ 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",
|
||||||
@ -3528,7 +3529,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-cli"
|
name = "ghost-cli"
|
||||||
version = "0.7.201"
|
version = "0.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"clap 4.5.4",
|
"clap 4.5.4",
|
||||||
@ -3560,7 +3561,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-client-cli"
|
name = "ghost-client-cli"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"array-bytes",
|
"array-bytes",
|
||||||
"clap 4.5.4",
|
"clap 4.5.4",
|
||||||
@ -3584,7 +3585,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-machine-primitives"
|
name = "ghost-machine-primitives"
|
||||||
version = "0.7.201"
|
version = "0.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"sc-sysinfo",
|
"sc-sysinfo",
|
||||||
@ -3593,7 +3594,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-metrics"
|
name = "ghost-metrics"
|
||||||
version = "0.7.201"
|
version = "0.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_cmd",
|
"assert_cmd",
|
||||||
"bs58 0.5.1",
|
"bs58 0.5.1",
|
||||||
@ -3616,7 +3617,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-miner"
|
name = "ghost-miner"
|
||||||
version = "1.5.0"
|
version = "1.5.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"assert_cmd",
|
"assert_cmd",
|
||||||
@ -3648,7 +3649,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-networks"
|
name = "ghost-networks"
|
||||||
version = "0.1.11"
|
version = "0.1.13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"frame-benchmarking",
|
"frame-benchmarking",
|
||||||
"frame-support",
|
"frame-support",
|
||||||
@ -3667,7 +3668,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-node"
|
name = "ghost-node"
|
||||||
version = "0.7.201"
|
version = "0.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_cmd",
|
"assert_cmd",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
@ -3683,7 +3684,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-remote-ext-tests-bags-list"
|
name = "ghost-remote-ext-tests-bags-list"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"casper-runtime",
|
"casper-runtime",
|
||||||
"casper-runtime-constants",
|
"casper-runtime-constants",
|
||||||
@ -3698,7 +3699,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-rpc"
|
name = "ghost-rpc"
|
||||||
version = "0.7.201"
|
version = "0.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ghost-core-primitives",
|
"ghost-core-primitives",
|
||||||
"jsonrpsee",
|
"jsonrpsee",
|
||||||
@ -3727,7 +3728,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-runtime-common"
|
name = "ghost-runtime-common"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"frame-support",
|
"frame-support",
|
||||||
"frame-system",
|
"frame-system",
|
||||||
@ -3750,7 +3751,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-service"
|
name = "ghost-service"
|
||||||
version = "0.7.201"
|
version = "0.8.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_matches",
|
"assert_matches",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
@ -3834,7 +3835,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-slow-clap"
|
name = "ghost-slow-clap"
|
||||||
version = "0.3.33"
|
version = "0.3.35"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"frame-benchmarking",
|
"frame-benchmarking",
|
||||||
"frame-support",
|
"frame-support",
|
||||||
@ -3859,7 +3860,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-staging-chain-spec-builder"
|
name = "ghost-staging-chain-spec-builder"
|
||||||
version = "1.6.1"
|
version = "1.6.2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 4.5.4",
|
"clap 4.5.4",
|
||||||
"log",
|
"log",
|
||||||
@ -3868,6 +3869,21 @@ 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.23"
|
||||||
@ -3878,7 +3894,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghost-voter-bags"
|
name = "ghost-voter-bags"
|
||||||
version = "0.3.6"
|
version = "0.3.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"casper-runtime",
|
"casper-runtime",
|
||||||
"clap 4.5.4",
|
"clap 4.5.4",
|
||||||
@ -3888,7 +3904,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ghostkey"
|
name = "ghostkey"
|
||||||
version = "0.3.15"
|
version = "0.3.16"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap 4.5.4",
|
"clap 4.5.4",
|
||||||
"ghost-client-cli",
|
"ghost-client-cli",
|
||||||
|
@ -17,7 +17,7 @@ homepage.workspace = true
|
|||||||
[workspace.package]
|
[workspace.package]
|
||||||
license = "GPL-3.0-only"
|
license = "GPL-3.0-only"
|
||||||
authors = ["571nky", "57r37ch", "f4750"]
|
authors = ["571nky", "57r37ch", "f4750"]
|
||||||
version = "0.7.204"
|
version = "0.8.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
homepage = "https://ghostchain.io"
|
homepage = "https://ghostchain.io"
|
||||||
repository = "https://git.ghostchain.io/ghostchain/ghost-node"
|
repository = "https://git.ghostchain.io/ghostchain/ghost-node"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
fn main () {
|
fn main() {
|
||||||
if let Ok(profile) = std::env::var("PROFILE") {
|
if let Ok(profile) = std::env::var("PROFILE") {
|
||||||
println!("cargo:rustc-cfg=build_type=\"{}\"", profile);
|
println!("cargo:rustc-cfg=build_type=\"{}\"", profile);
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,13 @@
|
|||||||
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, IdentifyVariant,
|
self,
|
||||||
benchmarking::{
|
benchmarking::{benchmark_inherent_data, RemarkBuilder, TransferKeepAliveBuilder},
|
||||||
benchmark_inherent_data, RemarkBuilder, TransferKeepAliveBuilder
|
IdentifyVariant,
|
||||||
},
|
|
||||||
};
|
};
|
||||||
use keyring::Sr25519Keyring;
|
|
||||||
|
|
||||||
pub use crate::{error::Error, service::BlockId};
|
pub use crate::{error::Error, service::BlockId};
|
||||||
#[cfg(feature = "pyroscope")]
|
#[cfg(feature = "pyroscope")]
|
||||||
@ -68,28 +67,35 @@ 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" => Box::new(service::chain_spec::casper_development_config()?),
|
"casper-dev" | "dev" | "development" => {
|
||||||
|
Box::new(service::chain_spec::casper_development_config()?)
|
||||||
|
}
|
||||||
#[cfg(feature = "casper-native")]
|
#[cfg(feature = "casper-native")]
|
||||||
"casper-local" | "local" => Box::new(service::chain_spec::casper_local_testnet_config()?),
|
"casper-local" | "local" => {
|
||||||
|
Box::new(service::chain_spec::casper_local_testnet_config()?)
|
||||||
|
}
|
||||||
#[cfg(feature = "casper-native")]
|
#[cfg(feature = "casper-native")]
|
||||||
"casper-staging" | "staging" => Box::new(service::chain_spec::casper_staging_testnet_config()?),
|
"casper-staging" | "staging" => {
|
||||||
|
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") =>
|
name if name.starts_with("casper-") && !name.ends_with(".json") => Err(format!(
|
||||||
Err(format!("`{}` only supported with `casper-native` feature enabled.", name))?,
|
"`{}` only supported with `casper-native` feature enabled.",
|
||||||
|
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(
|
let chain_spec = Box::new(service::GenericChainSpec::from_json_file(path.clone())?)
|
||||||
service::GenericChainSpec::from_json_file(path.clone())?
|
as Box<dyn service::ChainSpec>;
|
||||||
) 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
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,10 +115,7 @@ 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>(
|
fn run_node_inner<F>(cli: Cli, logger_hook: F) -> Result<()>
|
||||||
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),
|
||||||
{
|
{
|
||||||
@ -128,7 +131,8 @@ 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(
|
||||||
@ -138,7 +142,8 @@ 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(
|
||||||
@ -167,7 +172,9 @@ 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 {
|
||||||
@ -176,7 +183,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 {
|
||||||
@ -184,7 +191,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;
|
||||||
@ -192,11 +199,13 @@ 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) =
|
let (client, _, import_queue, task_manager) = service::new_chain_ops(&mut config)?;
|
||||||
service::new_chain_ops(&mut config)?;
|
Ok((
|
||||||
Ok((cmd.run(client, import_queue).map_err(Error::SubstrateCli), task_manager))
|
cmd.run(client, import_queue).map_err(Error::SubstrateCli),
|
||||||
|
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;
|
||||||
@ -204,11 +213,14 @@ 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 ) =
|
let (client, _, _, task_manager) = service::new_chain_ops(&mut config)?;
|
||||||
service::new_chain_ops(&mut config)?;
|
Ok((
|
||||||
Ok((cmd.run(client, config.database).map_err(Error::SubstrateCli), task_manager))
|
cmd.run(client, config.database)
|
||||||
|
.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;
|
||||||
@ -216,11 +228,14 @@ 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 ) =
|
let (client, _, _, task_manager) = service::new_chain_ops(&mut config)?;
|
||||||
service::new_chain_ops(&mut config)?;
|
Ok((
|
||||||
Ok((cmd.run(client, config.chain_spec).map_err(Error::SubstrateCli), task_manager))
|
cmd.run(client, config.chain_spec)
|
||||||
|
.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;
|
||||||
@ -228,15 +243,17 @@ 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 ) =
|
let (client, _, import_queue, task_manager) = service::new_chain_ops(&mut config)?;
|
||||||
service::new_chain_ops(&mut config)?;
|
Ok((
|
||||||
Ok((cmd.run(client, import_queue).map_err(Error::SubstrateCli), task_manager))
|
cmd.run(client, import_queue).map_err(Error::SubstrateCli),
|
||||||
|
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;
|
||||||
@ -244,62 +261,59 @@ 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) =
|
let (client, backend, _, task_manager) = service::new_chain_ops(&mut config)?;
|
||||||
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| {
|
service::revert_backend(client, backend, blocks).map_err(|err| match 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)).map_err(Error::SubstrateCli),
|
cmd.run(client, backend, Some(aux_revert))
|
||||||
task_manager
|
.map_err(Error::SubstrateCli),
|
||||||
|
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.".into()
|
to enable storage benchmarks."
|
||||||
).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, _, _,) =
|
let (client, backend, _, _) = service::new_chain_ops(&mut config)?;
|
||||||
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).map_err(Error::SubstrateCli)
|
cmd.run(config, client.clone(), db, storage)
|
||||||
|
.map_err(Error::SubstrateCli)
|
||||||
}),
|
}),
|
||||||
BenchmarkCmd::Block(cmd) => runner.sync_run(|mut config| {
|
BenchmarkCmd::Block(cmd) => runner.sync_run(|mut config| {
|
||||||
let (client, _, _, _,) =
|
let (client, _, _, _) = service::new_chain_ops(&mut config)?;
|
||||||
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, _, _, _) =
|
let (client, _, _, _) = service::new_chain_ops(&mut config)?;
|
||||||
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 = RemarkBuilder::new(
|
let remark_builder =
|
||||||
client.clone(),
|
RemarkBuilder::new(client.clone(), config.chain_spec.identify_chain());
|
||||||
config.chain_spec.identify_chain(),
|
|
||||||
);
|
|
||||||
|
|
||||||
match cmd {
|
match cmd {
|
||||||
BenchmarkCmd::Extrinsic(cmd) => {
|
BenchmarkCmd::Extrinsic(cmd) => {
|
||||||
@ -316,17 +330,20 @@ 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.run(
|
BenchmarkCmd::Overhead(cmd) => cmd
|
||||||
config,
|
.run(
|
||||||
client.clone(),
|
config,
|
||||||
inherent_data,
|
client.clone(),
|
||||||
Vec::new(),
|
inherent_data,
|
||||||
&remark_builder,
|
Vec::new(),
|
||||||
).map_err(Error::SubstrateCli),
|
&remark_builder,
|
||||||
|
)
|
||||||
|
.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);
|
||||||
|
|
||||||
@ -334,30 +351,36 @@ 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`.".into()
|
You can enable it with `--features=runtime-benchmarks`."
|
||||||
).into())
|
.into(),
|
||||||
|
)
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
BenchmarkCmd::Machine(cmd) => runner.sync_run(|config| {
|
BenchmarkCmd::Machine(cmd) => runner.sync_run(|config| {
|
||||||
cmd.run(&config, ghost_machine_primitives::GHOST_NODE_REFERENCE_HARDWARE.clone())
|
cmd.run(
|
||||||
.map_err(Error::SubstrateCli)
|
&config,
|
||||||
|
ghost_machine_primitives::GHOST_NODE_REFERENCE_HARDWARE.clone(),
|
||||||
|
)
|
||||||
|
.map_err(Error::SubstrateCli)
|
||||||
}),
|
}),
|
||||||
// Note: this allows to implement additional new benchmark
|
// Note: this allows to implement additional new benchmark
|
||||||
// commands.
|
// commands.
|
||||||
#[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")]
|
||||||
|
@ -6,9 +6,7 @@ mod command;
|
|||||||
mod error;
|
mod error;
|
||||||
|
|
||||||
#[cfg(feature = "service")]
|
#[cfg(feature = "service")]
|
||||||
pub use service::{
|
pub use service::{self, Block, CoreApi, IdentifyVariant, ProvideRuntimeApi, TFullClient};
|
||||||
self, Block, CoreApi, IdentifyVariant, ProvideRuntimeApi, TFullClient,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[cfg(feature = "cli")]
|
#[cfg(feature = "cli")]
|
||||||
pub use cli::*;
|
pub use cli::*;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghost-client-cli"
|
name = "ghost-client-cli"
|
||||||
version = "0.1.3"
|
version = "0.1.4"
|
||||||
description = "Ghost CLI interface"
|
description = "Ghost CLI interface"
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
|
@ -3,13 +3,10 @@
|
|||||||
use bip39::Mnemonic;
|
use bip39::Mnemonic;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use sc_cli::{
|
use sc_cli::{with_crypto_scheme, CryptoSchemeFlag, Error, KeystoreParams, OutputTypeFlag};
|
||||||
with_crypto_scheme, KeystoreParams, OutputTypeFlag,
|
|
||||||
CryptoSchemeFlag, Error,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::params::NetworkSchemeFlag;
|
|
||||||
use crate::commands::utils::print_from_uri;
|
use crate::commands::utils::print_from_uri;
|
||||||
|
use crate::params::NetworkSchemeFlag;
|
||||||
|
|
||||||
/// The `generate` command
|
/// The `generate` command
|
||||||
#[derive(Debug, Clone, Parser)]
|
#[derive(Debug, Clone, Parser)]
|
||||||
@ -17,58 +14,58 @@ use crate::commands::utils::print_from_uri;
|
|||||||
pub struct GenerateCmd {
|
pub struct GenerateCmd {
|
||||||
/// The number of words in the phrase to generate. One of 12 (default),
|
/// The number of words in the phrase to generate. One of 12 (default),
|
||||||
/// 15, 18, 21 and 24.
|
/// 15, 18, 21 and 24.
|
||||||
#[arg(short = 'w', long, value_name = "WORDS")]
|
#[arg(short = 'w', long, value_name = "WORDS")]
|
||||||
words: Option<usize>,
|
words: Option<usize>,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
pub keystore_params: KeystoreParams,
|
pub keystore_params: KeystoreParams,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
pub network_scheme: NetworkSchemeFlag,
|
pub network_scheme: NetworkSchemeFlag,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
pub output_scheme: OutputTypeFlag,
|
pub output_scheme: OutputTypeFlag,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
pub crypto_scheme: CryptoSchemeFlag,
|
pub crypto_scheme: CryptoSchemeFlag,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GenerateCmd {
|
impl GenerateCmd {
|
||||||
/// Run the command
|
/// Run the command
|
||||||
pub fn run(&self) -> Result<(), Error> {
|
pub fn run(&self) -> Result<(), Error> {
|
||||||
let words = match self.words {
|
let words = match self.words {
|
||||||
Some(words_count) if [12, 15, 18, 21, 24].contains(&words_count) => Ok(words_count),
|
Some(words_count) if [12, 15, 18, 21, 24].contains(&words_count) => Ok(words_count),
|
||||||
Some(_) => Err(Error::Input(
|
Some(_) => Err(Error::Input(
|
||||||
"Invalid number of words given for phrase: must be 12/15/18/21/24".into(),
|
"Invalid number of words given for phrase: must be 12/15/18/21/24".into(),
|
||||||
)),
|
)),
|
||||||
None => Ok(12),
|
None => Ok(12),
|
||||||
}?;
|
}?;
|
||||||
let mnemonic = Mnemonic::generate(words)
|
let mnemonic = Mnemonic::generate(words)
|
||||||
.map_err(|e| Error::Input(format!("Mnemonic generation failed: {e}").into()))?;
|
.map_err(|e| Error::Input(format!("Mnemonic generation failed: {e}").into()))?;
|
||||||
let password = self.keystore_params.read_password()?;
|
let password = self.keystore_params.read_password()?;
|
||||||
let output = self.output_scheme.output_type;
|
let output = self.output_scheme.output_type;
|
||||||
|
|
||||||
let phrase = mnemonic.words().join(" ");
|
let phrase = mnemonic.words().join(" ");
|
||||||
|
|
||||||
with_crypto_scheme!(
|
with_crypto_scheme!(
|
||||||
self.crypto_scheme.scheme,
|
self.crypto_scheme.scheme,
|
||||||
print_from_uri(&phrase, password, self.network_scheme.network, output)
|
print_from_uri(&phrase, password, self.network_scheme.network, output)
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generate() {
|
fn generate() {
|
||||||
let generate = GenerateCmd::parse_from(&["generate", "--password", "12345"]);
|
let generate = GenerateCmd::parse_from(&["generate", "--password", "12345"]);
|
||||||
assert!(generate.run().is_ok())
|
assert!(generate.run().is_ok())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,102 +1,101 @@
|
|||||||
//! 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)]
|
||||||
#[command(
|
#[command(
|
||||||
name = "inspect",
|
name = "inspect",
|
||||||
about = "Gets a public key and a SS58 address from the provided Secret URI"
|
about = "Gets a public key and a SS58 address from the provided Secret URI"
|
||||||
)]
|
)]
|
||||||
pub struct InspectKeyCmd {
|
pub struct InspectKeyCmd {
|
||||||
/// A Key URI to be inspected. May be a secret seed, secret URI
|
/// A Key URI to be inspected. May be a secret seed, secret URI
|
||||||
/// (with derivation paths and password), SS58, public URI or a hex encoded public key.
|
/// (with derivation paths and password), SS58, public URI or a hex encoded public key.
|
||||||
///
|
///
|
||||||
/// If it is a hex encoded public key, `--public` needs to be given as argument.
|
/// If it is a hex encoded public key, `--public` needs to be given as argument.
|
||||||
///
|
///
|
||||||
/// If the given value is a file, the file content will be used
|
/// If the given value is a file, the file content will be used
|
||||||
/// as URI.
|
/// as URI.
|
||||||
///
|
///
|
||||||
/// If omitted, you will be prompted for the URI.
|
/// If omitted, you will be prompted for the URI.
|
||||||
uri: Option<String>,
|
uri: Option<String>,
|
||||||
|
|
||||||
/// Is the given `uri` a hex encoded public key?
|
/// Is the given `uri` a hex encoded public key?
|
||||||
#[arg(long)]
|
#[arg(long)]
|
||||||
public: bool,
|
public: bool,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
pub keystore_params: KeystoreParams,
|
pub keystore_params: KeystoreParams,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
pub network_scheme: NetworkSchemeFlag,
|
pub network_scheme: NetworkSchemeFlag,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
pub output_scheme: OutputTypeFlag,
|
pub output_scheme: OutputTypeFlag,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
pub crypto_scheme: CryptoSchemeFlag,
|
pub crypto_scheme: CryptoSchemeFlag,
|
||||||
|
|
||||||
/// Expect that `--uri` has the given public key/account-id.
|
/// Expect that `--uri` has the given public key/account-id.
|
||||||
///
|
///
|
||||||
/// If `--uri` has any derivations, the public key is checked against the base `uri`, i.e. the
|
/// If `--uri` has any derivations, the public key is checked against the base `uri`, i.e. the
|
||||||
/// `uri` without any derivation applied. However, if `uri` has a password or there is one
|
/// `uri` without any derivation applied. However, if `uri` has a password or there is one
|
||||||
/// given by `--password`, it will be used to decrypt `uri` before comparing the public
|
/// given by `--password`, it will be used to decrypt `uri` before comparing the public
|
||||||
/// key/account-id.
|
/// key/account-id.
|
||||||
///
|
///
|
||||||
/// If there is no derivation in `--uri`, the public key will be checked against the public key
|
/// If there is no derivation in `--uri`, the public key will be checked against the public key
|
||||||
/// of `--uri` directly.
|
/// of `--uri` directly.
|
||||||
#[arg(long, conflicts_with = "public")]
|
#[arg(long, conflicts_with = "public")]
|
||||||
pub expect_public: Option<String>,
|
pub expect_public: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InspectKeyCmd {
|
impl InspectKeyCmd {
|
||||||
/// Run the command
|
/// Run the command
|
||||||
pub fn run(&self) -> Result<(), Error> {
|
pub fn run(&self) -> Result<(), Error> {
|
||||||
let uri = read_uri(self.uri.as_ref())?;
|
let uri = read_uri(self.uri.as_ref())?;
|
||||||
let password = self.keystore_params.read_password()?;
|
let password = self.keystore_params.read_password()?;
|
||||||
|
|
||||||
if self.public {
|
if self.public {
|
||||||
with_crypto_scheme!(
|
with_crypto_scheme!(
|
||||||
self.crypto_scheme.scheme,
|
self.crypto_scheme.scheme,
|
||||||
print_from_public(
|
print_from_public(
|
||||||
&uri,
|
&uri,
|
||||||
self.network_scheme.network,
|
self.network_scheme.network,
|
||||||
self.output_scheme.output_type,
|
self.output_scheme.output_type,
|
||||||
)
|
)
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
if let Some(ref expect_public) = self.expect_public {
|
if let Some(ref expect_public) = self.expect_public {
|
||||||
with_crypto_scheme!(
|
with_crypto_scheme!(
|
||||||
self.crypto_scheme.scheme,
|
self.crypto_scheme.scheme,
|
||||||
expect_public_from_phrase(expect_public, &uri, password.as_ref())
|
expect_public_from_phrase(expect_public, &uri, password.as_ref())
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
with_crypto_scheme!(
|
with_crypto_scheme!(
|
||||||
self.crypto_scheme.scheme,
|
self.crypto_scheme.scheme,
|
||||||
print_from_uri(
|
print_from_uri(
|
||||||
&uri,
|
&uri,
|
||||||
password,
|
password,
|
||||||
self.network_scheme.network,
|
self.network_scheme.network,
|
||||||
self.output_scheme.output_type,
|
self.output_scheme.output_type,
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks that `expect_public` is the public key of `suri`.
|
/// Checks that `expect_public` is the public key of `suri`.
|
||||||
@ -106,148 +105,156 @@ impl InspectKeyCmd {
|
|||||||
///
|
///
|
||||||
/// Returns an error if the public key does not match.
|
/// Returns an error if the public key does not match.
|
||||||
fn expect_public_from_phrase<Pair: sp_core::Pair>(
|
fn expect_public_from_phrase<Pair: sp_core::Pair>(
|
||||||
expect_public: &str,
|
expect_public: &str,
|
||||||
suri: &str,
|
suri: &str,
|
||||||
password: Option<&SecretString>,
|
password: Option<&SecretString>,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let secret_uri = SecretUri::from_str(suri).map_err(|e| format!("{:?}", e))?;
|
let secret_uri = SecretUri::from_str(suri).map_err(|e| format!("{:?}", e))?;
|
||||||
let expected_public = if let Some(public) = expect_public.strip_prefix("0x") {
|
let expected_public = if let Some(public) = expect_public.strip_prefix("0x") {
|
||||||
let hex_public = array_bytes::hex2bytes(public)
|
let hex_public = array_bytes::hex2bytes(public)
|
||||||
.map_err(|_| format!("Invalid expected public key hex: `{}`", expect_public))?;
|
.map_err(|_| format!("Invalid expected public key hex: `{}`", expect_public))?;
|
||||||
Pair::Public::try_from(&hex_public)
|
Pair::Public::try_from(&hex_public)
|
||||||
.map_err(|_| format!("Invalid expected public key: `{}`", expect_public))?
|
.map_err(|_| format!("Invalid expected public key: `{}`", expect_public))?
|
||||||
} else {
|
} else {
|
||||||
Pair::Public::from_string_with_version(expect_public)
|
Pair::Public::from_string_with_version(expect_public)
|
||||||
.map_err(|_| format!("Invalid expected account id: `{}`", expect_public))?
|
.map_err(|_| format!("Invalid expected account id: `{}`", expect_public))?
|
||||||
.0
|
.0
|
||||||
};
|
};
|
||||||
|
|
||||||
let pair = Pair::from_string_with_seed(
|
let pair = Pair::from_string_with_seed(
|
||||||
secret_uri.phrase.expose_secret().as_str(),
|
secret_uri.phrase.expose_secret().as_str(),
|
||||||
password
|
password
|
||||||
.or_else(|| secret_uri.password.as_ref())
|
.or_else(|| secret_uri.password.as_ref())
|
||||||
.map(|p| p.expose_secret().as_str()),
|
.map(|p| p.expose_secret().as_str()),
|
||||||
)
|
)
|
||||||
.map_err(|_| format!("Invalid secret uri: {}", suri))?
|
.map_err(|_| format!("Invalid secret uri: {}", suri))?
|
||||||
.0;
|
.0;
|
||||||
|
|
||||||
if pair.public() == expected_public {
|
if pair.public() == expected_public {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(format!("Expected public ({}) key does not match.", expect_public).into())
|
Err(format!("Expected public ({}) key does not match.", expect_public).into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use sp_core::crypto::{ByteArray, Pair};
|
use sp_core::crypto::{ByteArray, Pair};
|
||||||
use sp_runtime::traits::IdentifyAccount;
|
use sp_runtime::traits::IdentifyAccount;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn inspect() {
|
fn inspect() {
|
||||||
let words =
|
let words =
|
||||||
"remember fiber forum demise paper uniform squirrel feel access exclude casual effort";
|
"remember fiber forum demise paper uniform squirrel feel access exclude casual effort";
|
||||||
let seed = "0xad1fb77243b536b90cfe5f0d351ab1b1ac40e3890b41dc64f766ee56340cfca5";
|
let seed = "0xad1fb77243b536b90cfe5f0d351ab1b1ac40e3890b41dc64f766ee56340cfca5";
|
||||||
|
|
||||||
let inspect = InspectKeyCmd::parse_from(&["inspect-key", words, "--password", "12345"]);
|
let inspect = InspectKeyCmd::parse_from(&["inspect-key", words, "--password", "12345"]);
|
||||||
assert!(inspect.run().is_ok());
|
assert!(inspect.run().is_ok());
|
||||||
|
|
||||||
let inspect = InspectKeyCmd::parse_from(&["inspect-key", seed]);
|
let inspect = InspectKeyCmd::parse_from(&["inspect-key", seed]);
|
||||||
assert!(inspect.run().is_ok());
|
assert!(inspect.run().is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn inspect_public_key() {
|
fn inspect_public_key() {
|
||||||
let public = "0x12e76e0ae8ce41b6516cce52b3f23a08dcb4cfeed53c6ee8f5eb9f7367341069";
|
let public = "0x12e76e0ae8ce41b6516cce52b3f23a08dcb4cfeed53c6ee8f5eb9f7367341069";
|
||||||
|
|
||||||
let inspect = InspectKeyCmd::parse_from(&["inspect-key", "--public", public]);
|
let inspect = InspectKeyCmd::parse_from(&["inspect-key", "--public", public]);
|
||||||
assert!(inspect.run().is_ok());
|
assert!(inspect.run().is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn inspect_with_expected_public_key() {
|
fn inspect_with_expected_public_key() {
|
||||||
let check_cmd = |seed, expected_public, success| {
|
let check_cmd = |seed, expected_public, success| {
|
||||||
let inspect = InspectKeyCmd::parse_from(&[
|
let inspect = InspectKeyCmd::parse_from(&[
|
||||||
"inspect-key",
|
"inspect-key",
|
||||||
"--expect-public",
|
"--expect-public",
|
||||||
expected_public,
|
expected_public,
|
||||||
seed,
|
seed,
|
||||||
]);
|
]);
|
||||||
let res = inspect.run();
|
let res = inspect.run();
|
||||||
|
|
||||||
if success {
|
if success {
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
} else {
|
} else {
|
||||||
assert!(res.unwrap_err().to_string().contains(&format!(
|
assert!(res.unwrap_err().to_string().contains(&format!(
|
||||||
"Expected public ({}) key does not match.",
|
"Expected public ({}) key does not match.",
|
||||||
expected_public
|
expected_public
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let seed =
|
let seed =
|
||||||
"remember fiber forum demise paper uniform squirrel feel access exclude casual effort";
|
"remember fiber forum demise paper uniform squirrel feel access exclude casual effort";
|
||||||
let invalid_public = "0x12e76e0ae8ce41b6516cce52b3f23a08dcb4cfeed53c6ee8f5eb9f7367341069";
|
let invalid_public = "0x12e76e0ae8ce41b6516cce52b3f23a08dcb4cfeed53c6ee8f5eb9f7367341069";
|
||||||
let valid_public = sp_core::sr25519::Pair::from_string_with_seed(seed, None)
|
let valid_public = sp_core::sr25519::Pair::from_string_with_seed(seed, None)
|
||||||
.expect("Valid")
|
.expect("Valid")
|
||||||
.0
|
.0
|
||||||
.public();
|
.public();
|
||||||
let valid_public_hex = array_bytes::bytes2hex("0x", valid_public.as_slice());
|
let valid_public_hex = array_bytes::bytes2hex("0x", valid_public.as_slice());
|
||||||
let valid_accountid = format!("{}", valid_public.into_account());
|
let valid_accountid = format!("{}", valid_public.into_account());
|
||||||
|
|
||||||
// It should fail with the invalid public key
|
// It should fail with the invalid public key
|
||||||
check_cmd(seed, invalid_public, false);
|
check_cmd(seed, invalid_public, false);
|
||||||
|
|
||||||
// It should work with the valid public key & account id
|
// It should work with the valid public key & account id
|
||||||
check_cmd(seed, &valid_public_hex, true);
|
check_cmd(seed, &valid_public_hex, true);
|
||||||
check_cmd(seed, &valid_accountid, true);
|
check_cmd(seed, &valid_accountid, true);
|
||||||
|
|
||||||
let password = "test12245";
|
let password = "test12245";
|
||||||
let seed_with_password = format!("{}///{}", seed, password);
|
let seed_with_password = format!("{}///{}", seed, password);
|
||||||
let valid_public_with_password =
|
let valid_public_with_password =
|
||||||
sp_core::sr25519::Pair::from_string_with_seed(&seed_with_password, Some(password))
|
sp_core::sr25519::Pair::from_string_with_seed(&seed_with_password, Some(password))
|
||||||
.expect("Valid")
|
.expect("Valid")
|
||||||
.0
|
.0
|
||||||
.public();
|
.public();
|
||||||
let valid_public_hex_with_password =
|
let valid_public_hex_with_password =
|
||||||
array_bytes::bytes2hex("0x", valid_public_with_password.as_slice());
|
array_bytes::bytes2hex("0x", valid_public_with_password.as_slice());
|
||||||
let valid_accountid_with_password =
|
let valid_accountid_with_password =
|
||||||
format!("{}", &valid_public_with_password.into_account());
|
format!("{}", &valid_public_with_password.into_account());
|
||||||
|
|
||||||
// Only the public key that corresponds to the seed with password should be accepted.
|
// Only the public key that corresponds to the seed with password should be accepted.
|
||||||
check_cmd(&seed_with_password, &valid_public_hex, false);
|
check_cmd(&seed_with_password, &valid_public_hex, false);
|
||||||
check_cmd(&seed_with_password, &valid_accountid, false);
|
check_cmd(&seed_with_password, &valid_accountid, false);
|
||||||
|
|
||||||
check_cmd(&seed_with_password, &valid_public_hex_with_password, true);
|
check_cmd(&seed_with_password, &valid_public_hex_with_password, true);
|
||||||
check_cmd(&seed_with_password, &valid_accountid_with_password, true);
|
check_cmd(&seed_with_password, &valid_accountid_with_password, true);
|
||||||
|
|
||||||
let seed_with_password_and_derivation = format!("{}//test//account///{}", seed, password);
|
let seed_with_password_and_derivation = format!("{}//test//account///{}", seed, password);
|
||||||
|
|
||||||
let valid_public_with_password_and_derivation =
|
let valid_public_with_password_and_derivation =
|
||||||
sp_core::sr25519::Pair::from_string_with_seed(
|
sp_core::sr25519::Pair::from_string_with_seed(
|
||||||
&seed_with_password_and_derivation,
|
&seed_with_password_and_derivation,
|
||||||
Some(password),
|
Some(password),
|
||||||
)
|
)
|
||||||
.expect("Valid")
|
.expect("Valid")
|
||||||
.0
|
.0
|
||||||
.public();
|
.public();
|
||||||
let valid_public_hex_with_password_and_derivation =
|
let valid_public_hex_with_password_and_derivation =
|
||||||
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(&seed_with_password_and_derivation, &valid_public_hex_with_password, true);
|
check_cmd(
|
||||||
check_cmd(&seed_with_password_and_derivation, &valid_accountid_with_password, true);
|
&seed_with_password_and_derivation,
|
||||||
|
&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);
|
||||||
check_cmd(&seed_with_password_and_derivation, &valid_accountid, false);
|
check_cmd(&seed_with_password_and_derivation, &valid_accountid, false);
|
||||||
|
|
||||||
// The public of the derived account should fail.
|
// The public of the derived account should fail.
|
||||||
check_cmd(
|
check_cmd(
|
||||||
&seed_with_password_and_derivation,
|
&seed_with_password_and_derivation,
|
||||||
&valid_public_hex_with_password_and_derivation,
|
&valid_public_hex_with_password_and_derivation,
|
||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,37 @@
|
|||||||
//! 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::{
|
use sc_cli::{Error, GenerateKeyCmdCommon, InsertKeyCmd, InspectNodeKeyCmd, SubstrateCli};
|
||||||
GenerateKeyCmdCommon, InsertKeyCmd, InspectNodeKeyCmd, Error,
|
|
||||||
SubstrateCli,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// Key utilities for the cli.
|
/// Key utilities for the cli.
|
||||||
#[derive(Debug, clap::Subcommand)]
|
#[derive(Debug, clap::Subcommand)]
|
||||||
pub enum KeySubcommand {
|
pub enum KeySubcommand {
|
||||||
/// Generate a random node key, write it to a file or stdout and write the
|
/// Generate a random node key, write it to a file or stdout and write the
|
||||||
/// corresponding peer-id to stderr
|
/// corresponding peer-id to stderr
|
||||||
GenerateNodeKey(GenerateKeyCmdCommon),
|
GenerateNodeKey(GenerateKeyCmdCommon),
|
||||||
|
|
||||||
/// Generate a Substrate-based random account
|
/// Generate a Substrate-based random account
|
||||||
Generate(GenerateCmd),
|
Generate(GenerateCmd),
|
||||||
|
|
||||||
/// Gets a public key and a SS58 address from the provided Secret URI
|
/// Gets a public key and a SS58 address from the provided Secret URI
|
||||||
Inspect(InspectKeyCmd),
|
Inspect(InspectKeyCmd),
|
||||||
|
|
||||||
/// Load a node key from a file or stdin and print the corresponding peer-id
|
/// Load a node key from a file or stdin and print the corresponding peer-id
|
||||||
InspectNodeKey(InspectNodeKeyCmd),
|
InspectNodeKey(InspectNodeKeyCmd),
|
||||||
|
|
||||||
/// Insert a key to the keystore of a node.
|
/// Insert a key to the keystore of a node.
|
||||||
Insert(InsertKeyCmd),
|
Insert(InsertKeyCmd),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl KeySubcommand {
|
impl KeySubcommand {
|
||||||
/// run the key subcommands
|
/// run the key subcommands
|
||||||
pub fn run<C: SubstrateCli>(&self, cli: &C) -> Result<(), Error> {
|
pub fn run<C: SubstrateCli>(&self, cli: &C) -> Result<(), Error> {
|
||||||
match self {
|
match self {
|
||||||
KeySubcommand::GenerateNodeKey(cmd) => cmd.run(),
|
KeySubcommand::GenerateNodeKey(cmd) => cmd.run(),
|
||||||
KeySubcommand::Generate(cmd) => cmd.run(),
|
KeySubcommand::Generate(cmd) => cmd.run(),
|
||||||
KeySubcommand::Inspect(cmd) => cmd.run(),
|
KeySubcommand::Inspect(cmd) => cmd.run(),
|
||||||
KeySubcommand::Insert(cmd) => cmd.run(cli),
|
KeySubcommand::Insert(cmd) => cmd.run(cli),
|
||||||
KeySubcommand::InspectNodeKey(cmd) => cmd.run(),
|
KeySubcommand::InspectNodeKey(cmd) => cmd.run(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
mod key;
|
|
||||||
mod generate;
|
mod generate;
|
||||||
mod vanity;
|
|
||||||
mod inspect_key;
|
mod inspect_key;
|
||||||
|
mod key;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
mod vanity;
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
key::KeySubcommand, vanity::VanityCmd, inspect_key::InspectKeyCmd,
|
|
||||||
generate::GenerateCmd,
|
generate::GenerateCmd,
|
||||||
utils::{unwrap_or_default_ss58_name, print_from_uri, print_from_public},
|
inspect_key::InspectKeyCmd,
|
||||||
|
key::KeySubcommand,
|
||||||
|
utils::{print_from_public, print_from_uri, unwrap_or_default_ss58_name},
|
||||||
|
vanity::VanityCmd,
|
||||||
};
|
};
|
||||||
|
@ -1,194 +1,206 @@
|
|||||||
use serde_json::json;
|
|
||||||
use sc_cli::{
|
use sc_cli::{
|
||||||
OutputType,
|
|
||||||
utils::{PublicFor, SeedFor},
|
utils::{PublicFor, SeedFor},
|
||||||
|
OutputType,
|
||||||
};
|
};
|
||||||
use sp_runtime::{traits::IdentifyAccount, MultiSigner};
|
use serde_json::json;
|
||||||
use sp_core::{
|
use sp_core::{
|
||||||
crypto::{
|
crypto::{
|
||||||
unwrap_or_default_ss58_version,
|
unwrap_or_default_ss58_version, ExposeSecret, SecretString, Ss58AddressFormat, Ss58Codec,
|
||||||
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,
|
||||||
password: Option<SecretString>,
|
password: Option<SecretString>,
|
||||||
network_override: Option<Ss58AddressFormat>,
|
network_override: Option<Ss58AddressFormat>,
|
||||||
output: OutputType,
|
output: OutputType,
|
||||||
) where
|
) where
|
||||||
Pair: sp_core::Pair,
|
Pair: sp_core::Pair,
|
||||||
Pair::Public: Into<MultiSigner>,
|
Pair::Public: Into<MultiSigner>,
|
||||||
{
|
{
|
||||||
let password = password.as_ref().map(|s| s.expose_secret().as_str());
|
let password = password.as_ref().map(|s| s.expose_secret().as_str());
|
||||||
let network_id = unwrap_or_default_ss58_name(network_override);
|
let network_id = unwrap_or_default_ss58_name(network_override);
|
||||||
|
|
||||||
if let Ok((pair, seed)) = Pair::from_phrase(uri, password) {
|
if let Ok((pair, seed)) = Pair::from_phrase(uri, password) {
|
||||||
let public_key = pair.public();
|
let public_key = pair.public();
|
||||||
let network_override = unwrap_or_default_ss58_version(network_override);
|
let network_override = unwrap_or_default_ss58_version(network_override);
|
||||||
|
|
||||||
match output {
|
match output {
|
||||||
OutputType::Json => {
|
OutputType::Json => {
|
||||||
let json = json!({
|
let json = json!({
|
||||||
"secretPhrase": uri,
|
"secretPhrase": uri,
|
||||||
"networkId": network_id,
|
"networkId": network_id,
|
||||||
"secretSeed": format_seed::<Pair>(seed),
|
"secretSeed": format_seed::<Pair>(seed),
|
||||||
"publicKey": format_public_key::<Pair>(public_key.clone()),
|
"publicKey": format_public_key::<Pair>(public_key.clone()),
|
||||||
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
|
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
|
||||||
"accountId": format_account_id::<Pair>(public_key),
|
"accountId": format_account_id::<Pair>(public_key),
|
||||||
"ss58Address": pair.public().into().into_account().to_ss58check_with_version(network_override),
|
"ss58Address": pair.public().into().into_account().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!(
|
||||||
"Secret phrase: {}\n \
|
"Secret phrase: {}\n \
|
||||||
Network ID: {}\n \
|
Network ID: {}\n \
|
||||||
Secret seed: {}\n \
|
Secret seed: {}\n \
|
||||||
Public key (hex): {}\n \
|
Public key (hex): {}\n \
|
||||||
Account ID: {}\n \
|
Account ID: {}\n \
|
||||||
Public key (SS58): {}\n \
|
Public key (SS58): {}\n \
|
||||||
SS58 Address: {}",
|
SS58 Address: {}",
|
||||||
uri,
|
uri,
|
||||||
network_id,
|
network_id,
|
||||||
format_seed::<Pair>(seed),
|
format_seed::<Pair>(seed),
|
||||||
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().into().into_account().to_ss58check_with_version(network_override),
|
pair.public()
|
||||||
);
|
.into()
|
||||||
},
|
.into_account()
|
||||||
}
|
.to_ss58check_with_version(network_override),
|
||||||
} else if let Ok((pair, seed)) = Pair::from_string_with_seed(uri, password) {
|
);
|
||||||
let public_key = pair.public();
|
}
|
||||||
let network_override = unwrap_or_default_ss58_version(network_override);
|
}
|
||||||
|
} else if let Ok((pair, seed)) = Pair::from_string_with_seed(uri, password) {
|
||||||
|
let public_key = pair.public();
|
||||||
|
let network_override = unwrap_or_default_ss58_version(network_override);
|
||||||
|
|
||||||
match output {
|
match output {
|
||||||
OutputType::Json => {
|
OutputType::Json => {
|
||||||
let json = json!({
|
let json = json!({
|
||||||
"secretKeyUri": uri,
|
"secretKeyUri": uri,
|
||||||
"networkId": network_id,
|
"networkId": network_id,
|
||||||
"secretSeed": if let Some(seed) = seed { format_seed::<Pair>(seed) } else { "n/a".into() },
|
"secretSeed": if let Some(seed) = seed { format_seed::<Pair>(seed) } else { "n/a".into() },
|
||||||
"publicKey": format_public_key::<Pair>(public_key.clone()),
|
"publicKey": format_public_key::<Pair>(public_key.clone()),
|
||||||
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
|
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
|
||||||
"accountId": format_account_id::<Pair>(public_key),
|
"accountId": format_account_id::<Pair>(public_key),
|
||||||
"ss58Address": pair.public().into().into_account().to_ss58check_with_version(network_override),
|
"ss58Address": pair.public().into().into_account().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!(
|
||||||
"Secret Key URI `{}` is account:\n \
|
"Secret Key URI `{}` is account:\n \
|
||||||
Network ID: {}\n \
|
Network ID: {}\n \
|
||||||
Secret seed: {}\n \
|
Secret seed: {}\n \
|
||||||
Public key (hex): {}\n \
|
Public key (hex): {}\n \
|
||||||
Account ID: {}\n \
|
Account ID: {}\n \
|
||||||
Public key (SS58): {}\n \
|
Public key (SS58): {}\n \
|
||||||
SS58 Address: {}",
|
SS58 Address: {}",
|
||||||
uri,
|
uri,
|
||||||
network_id,
|
network_id,
|
||||||
if let Some(seed) = seed { format_seed::<Pair>(seed) } else { "n/a".into() },
|
if let Some(seed) = seed {
|
||||||
format_public_key::<Pair>(public_key.clone()),
|
format_seed::<Pair>(seed)
|
||||||
format_account_id::<Pair>(public_key.clone()),
|
} else {
|
||||||
public_key.to_ss58check_with_version(network_override),
|
"n/a".into()
|
||||||
pair.public().into().into_account().to_ss58check_with_version(network_override),
|
},
|
||||||
);
|
format_public_key::<Pair>(public_key.clone()),
|
||||||
},
|
format_account_id::<Pair>(public_key.clone()),
|
||||||
}
|
public_key.to_ss58check_with_version(network_override),
|
||||||
} else if let Ok((public_key, network)) = Pair::Public::from_string_with_version(uri) {
|
pair.public()
|
||||||
let network_override = network_override.unwrap_or(network);
|
.into()
|
||||||
|
.into_account()
|
||||||
|
.to_ss58check_with_version(network_override),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let Ok((public_key, network)) = Pair::Public::from_string_with_version(uri) {
|
||||||
|
let network_override = network_override.unwrap_or(network);
|
||||||
|
|
||||||
match output {
|
match output {
|
||||||
OutputType::Json => {
|
OutputType::Json => {
|
||||||
let json = json!({
|
let json = json!({
|
||||||
"publicKeyUri": uri,
|
"publicKeyUri": uri,
|
||||||
"networkId": String::from(network_override),
|
"networkId": String::from(network_override),
|
||||||
"publicKey": format_public_key::<Pair>(public_key.clone()),
|
"publicKey": format_public_key::<Pair>(public_key.clone()),
|
||||||
"accountId": format_account_id::<Pair>(public_key.clone()),
|
"accountId": format_account_id::<Pair>(public_key.clone()),
|
||||||
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
|
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
|
||||||
"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!(
|
||||||
"Public Key URI `{}` is account:\n \
|
"Public Key URI `{}` is account:\n \
|
||||||
Network ID/Version: {}\n \
|
Network ID/Version: {}\n \
|
||||||
Public key (hex): {}\n \
|
Public key (hex): {}\n \
|
||||||
Account ID: {}\n \
|
Account ID: {}\n \
|
||||||
Public key (SS58): {}\n \
|
Public key (SS58): {}\n \
|
||||||
SS58 Address: {}",
|
SS58 Address: {}",
|
||||||
uri,
|
uri,
|
||||||
String::from(network_override),
|
String::from(network_override),
|
||||||
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),
|
||||||
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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Try to parse given `public` as hex encoded public key and print relevant information.
|
/// Try to parse given `public` as hex encoded public key and print relevant information.
|
||||||
pub fn print_from_public<Pair>(
|
pub fn print_from_public<Pair>(
|
||||||
public_str: &str,
|
public_str: &str,
|
||||||
network_override: Option<Ss58AddressFormat>,
|
network_override: Option<Ss58AddressFormat>,
|
||||||
output: OutputType,
|
output: OutputType,
|
||||||
) -> Result<(), sc_cli::Error>
|
) -> Result<(), sc_cli::Error>
|
||||||
where
|
where
|
||||||
Pair: sp_core::Pair,
|
Pair: sp_core::Pair,
|
||||||
Pair::Public: Into<MultiSigner>,
|
Pair::Public: Into<MultiSigner>,
|
||||||
{
|
{
|
||||||
let public = array_bytes::hex2bytes(public_str)?;
|
let public = array_bytes::hex2bytes(public_str)?;
|
||||||
|
|
||||||
let public_key = Pair::Public::try_from(&public)
|
let public_key = Pair::Public::try_from(&public)
|
||||||
.map_err(|_| "Failed to construct public key from given hex")?;
|
.map_err(|_| "Failed to construct public key from given hex")?;
|
||||||
|
|
||||||
let network_override = unwrap_or_default_ss58_version(network_override);
|
let network_override = unwrap_or_default_ss58_version(network_override);
|
||||||
|
|
||||||
match output {
|
match output {
|
||||||
OutputType::Json => {
|
OutputType::Json => {
|
||||||
let json = json!({
|
let json = json!({
|
||||||
"networkId": String::from(network_override),
|
"networkId": String::from(network_override),
|
||||||
"publicKey": format_public_key::<Pair>(public_key.clone()),
|
"publicKey": format_public_key::<Pair>(public_key.clone()),
|
||||||
"accountId": format_account_id::<Pair>(public_key.clone()),
|
"accountId": format_account_id::<Pair>(public_key.clone()),
|
||||||
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
|
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
|
||||||
"ss58Address": public_key.to_ss58check_with_version(network_override),
|
"ss58Address": public_key.to_ss58check_with_version(network_override),
|
||||||
});
|
});
|
||||||
|
|
||||||
println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed"));
|
println!(
|
||||||
},
|
"{}",
|
||||||
OutputType::Text => {
|
serde_json::to_string_pretty(&json).expect("Json pretty print failed")
|
||||||
println!(
|
);
|
||||||
"Network ID/Version: {}\n \
|
}
|
||||||
|
OutputType::Text => {
|
||||||
|
println!(
|
||||||
|
"Network ID/Version: {}\n \
|
||||||
Public key (hex): {}\n \
|
Public key (hex): {}\n \
|
||||||
Account ID: {}\n \
|
Account ID: {}\n \
|
||||||
Public key (SS58): {}\n \
|
Public key (SS58): {}\n \
|
||||||
SS58 Address: {}",
|
SS58 Address: {}",
|
||||||
String::from(network_override),
|
String::from(network_override),
|
||||||
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),
|
||||||
public_key.to_ss58check_with_version(network_override),
|
public_key.to_ss58check_with_version(network_override),
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unwrap_or_default_ss58_name(x: Option<Ss58AddressFormat>) -> String {
|
pub fn unwrap_or_default_ss58_name(x: Option<Ss58AddressFormat>) -> String {
|
||||||
@ -216,5 +228,8 @@ fn format_account_id<P: sp_core::Pair>(public_key: PublicFor<P>) -> String
|
|||||||
where
|
where
|
||||||
PublicFor<P>: Into<MultiSigner>,
|
PublicFor<P>: Into<MultiSigner>,
|
||||||
{
|
{
|
||||||
format!("0x{}", HexDisplay::from(&public_key.into().into_account().as_ref()))
|
format!(
|
||||||
|
"0x{}",
|
||||||
|
HexDisplay::from(&public_key.into().into_account().as_ref())
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,213 +2,218 @@
|
|||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use rand::{rngs::OsRng, RngCore};
|
use rand::{rngs::OsRng, RngCore};
|
||||||
use sp_core::crypto::{
|
use sc_cli::{utils::format_seed, with_crypto_scheme, CryptoSchemeFlag, Error, OutputTypeFlag};
|
||||||
unwrap_or_default_ss58_version, Ss58AddressFormat, Ss58Codec,
|
use sp_core::crypto::{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(name = "vanity", about = "Generate a seed that provides a vanity address")]
|
#[command(
|
||||||
|
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)]
|
||||||
pattern: String,
|
pattern: String,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
network_scheme: NetworkSchemeFlag,
|
network_scheme: NetworkSchemeFlag,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
output_scheme: OutputTypeFlag,
|
output_scheme: OutputTypeFlag,
|
||||||
|
|
||||||
#[allow(missing_docs)]
|
#[allow(missing_docs)]
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
crypto_scheme: CryptoSchemeFlag,
|
crypto_scheme: CryptoSchemeFlag,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VanityCmd {
|
impl VanityCmd {
|
||||||
/// Run the command
|
/// Run the command
|
||||||
pub fn run(&self) -> Result<(), Error> {
|
pub fn run(&self) -> Result<(), Error> {
|
||||||
let formated_seed = with_crypto_scheme!(
|
let formated_seed = with_crypto_scheme!(
|
||||||
self.crypto_scheme.scheme,
|
self.crypto_scheme.scheme,
|
||||||
generate_key(
|
generate_key(
|
||||||
&self.pattern,
|
&self.pattern,
|
||||||
unwrap_or_default_ss58_version(self.network_scheme.network)
|
unwrap_or_default_ss58_version(self.network_scheme.network)
|
||||||
),
|
),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
with_crypto_scheme!(
|
with_crypto_scheme!(
|
||||||
self.crypto_scheme.scheme,
|
self.crypto_scheme.scheme,
|
||||||
print_from_uri(
|
print_from_uri(
|
||||||
&formated_seed,
|
&formated_seed,
|
||||||
None,
|
None,
|
||||||
self.network_scheme.network,
|
self.network_scheme.network,
|
||||||
self.output_scheme.output_type,
|
self.output_scheme.output_type,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// genertae a key based on given pattern
|
/// genertae a key based on given pattern
|
||||||
fn generate_key<Pair>(
|
fn generate_key<Pair>(
|
||||||
desired: &str,
|
desired: &str,
|
||||||
network_override: Ss58AddressFormat,
|
network_override: Ss58AddressFormat,
|
||||||
) -> Result<String, &'static str>
|
) -> Result<String, &'static str>
|
||||||
where
|
where
|
||||||
Pair: sp_core::Pair,
|
Pair: sp_core::Pair,
|
||||||
Pair::Public: IdentifyAccount,
|
Pair::Public: IdentifyAccount,
|
||||||
<Pair::Public as IdentifyAccount>::AccountId: Ss58Codec,
|
<Pair::Public as IdentifyAccount>::AccountId: Ss58Codec,
|
||||||
{
|
{
|
||||||
println!("Generating key containing pattern '{}'", desired);
|
println!("Generating key containing pattern '{}'", desired);
|
||||||
|
|
||||||
let top = 45 + (desired.len() * 48);
|
let top = 45 + (desired.len() * 48);
|
||||||
let mut best = 0;
|
let mut best = 0;
|
||||||
let mut seed = Pair::Seed::default();
|
let mut seed = Pair::Seed::default();
|
||||||
let mut done = 0;
|
let mut done = 0;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if done % 100000 == 0 {
|
if done % 100000 == 0 {
|
||||||
OsRng.fill_bytes(seed.as_mut());
|
OsRng.fill_bytes(seed.as_mut());
|
||||||
} else {
|
} else {
|
||||||
next_seed(seed.as_mut());
|
next_seed(seed.as_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
let p = Pair::from_seed(&seed);
|
let p = Pair::from_seed(&seed);
|
||||||
let ss58 = p.public().into_account().to_ss58check_with_version(network_override);
|
let ss58 = p
|
||||||
|
.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;
|
||||||
|
|
||||||
if done % good_waypoint(done) == 0 {
|
if done % good_waypoint(done) == 0 {
|
||||||
println!("{} keys searched; best is {}/{} complete", done, best, top);
|
println!("{} keys searched; best is {}/{} complete", done, best, top);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn good_waypoint(done: u64) -> u64 {
|
fn good_waypoint(done: u64) -> u64 {
|
||||||
match done {
|
match done {
|
||||||
0..=1_000_000 => 100_000,
|
0..=1_000_000 => 100_000,
|
||||||
1_000_001..=10_000_000 => 1_000_000,
|
1_000_001..=10_000_000 => 1_000_000,
|
||||||
10_000_001..=100_000_000 => 10_000_000,
|
10_000_001..=100_000_000 => 10_000_000,
|
||||||
100_000_001.. => 100_000_000,
|
100_000_001.. => 100_000_000,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_seed(seed: &mut [u8]) {
|
fn next_seed(seed: &mut [u8]) {
|
||||||
for s in seed {
|
for s in seed {
|
||||||
match s {
|
match s {
|
||||||
255 => {
|
255 => {
|
||||||
*s = 0;
|
*s = 0;
|
||||||
},
|
}
|
||||||
_ => {
|
_ => {
|
||||||
*s += 1;
|
*s += 1;
|
||||||
break
|
break;
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculate the score of a key based on the desired
|
/// Calculate the score of a key based on the desired
|
||||||
/// input.
|
/// input.
|
||||||
fn calculate_score(_desired: &str, key: &str) -> usize {
|
fn calculate_score(_desired: &str, key: &str) -> usize {
|
||||||
for truncate in 0.._desired.len() {
|
for truncate in 0.._desired.len() {
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
/// checks that `pattern` is non-empty
|
/// checks that `pattern` is non-empty
|
||||||
fn assert_non_empty_string(pattern: &str) -> Result<String, &'static str> {
|
fn assert_non_empty_string(pattern: &str) -> Result<String, &'static str> {
|
||||||
if pattern.is_empty() {
|
if pattern.is_empty() {
|
||||||
Err("Pattern must not be empty")
|
Err("Pattern must not be empty")
|
||||||
} else {
|
} else {
|
||||||
Ok(pattern.to_string())
|
Ok(pattern.to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use sp_core::{
|
use sp_core::{
|
||||||
crypto::{default_ss58_version, Ss58AddressFormatRegistry, Ss58Codec},
|
crypto::{default_ss58_version, Ss58AddressFormatRegistry, Ss58Codec},
|
||||||
sr25519, Pair,
|
sr25519, Pair,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn vanity() {
|
fn vanity() {
|
||||||
let vanity = VanityCmd::parse_from(&["vanity", "--pattern", "j"]);
|
let vanity = VanityCmd::parse_from(&["vanity", "--pattern", "j"]);
|
||||||
assert!(vanity.run().is_ok());
|
assert!(vanity.run().is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[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!(sr25519::Pair::from_seed_slice(&array_bytes::hex2bytes_unchecked(&seed))
|
assert!(
|
||||||
.unwrap()
|
sr25519::Pair::from_seed_slice(&array_bytes::hex2bytes_unchecked(&seed))
|
||||||
.public()
|
.unwrap()
|
||||||
.to_ss58check()
|
.public()
|
||||||
.contains("ab"));
|
.to_ss58check()
|
||||||
}
|
.contains("ab")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn generate_key_respects_network_override() {
|
fn generate_key_respects_network_override() {
|
||||||
let seed =
|
let seed =
|
||||||
generate_key::<sr25519::Pair>("ab", Ss58AddressFormatRegistry::PolkadotAccount.into())
|
generate_key::<sr25519::Pair>("ab", Ss58AddressFormatRegistry::PolkadotAccount.into())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(sr25519::Pair::from_seed_slice(&array_bytes::hex2bytes_unchecked(&seed))
|
assert!(
|
||||||
.unwrap()
|
sr25519::Pair::from_seed_slice(&array_bytes::hex2bytes_unchecked(&seed))
|
||||||
.public()
|
.unwrap()
|
||||||
.to_ss58check_with_version(Ss58AddressFormatRegistry::PolkadotAccount.into())
|
.public()
|
||||||
.contains("ab"));
|
.to_ss58check_with_version(Ss58AddressFormatRegistry::PolkadotAccount.into())
|
||||||
}
|
.contains("ab")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_score_1_char_100() {
|
fn test_score_1_char_100() {
|
||||||
let score = calculate_score("j", "sYrjWiZkEP1PQe2kKEZiC1Bi9L8yFSsB5RPEkzEPd5NThsB5H");
|
let score = calculate_score("j", "sYrjWiZkEP1PQe2kKEZiC1Bi9L8yFSsB5RPEkzEPd5NThsB5H");
|
||||||
assert_eq!(score, 96);
|
assert_eq!(score, 96);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_score_100() {
|
fn test_score_100() {
|
||||||
let score = calculate_score("ghst", "sYsghstuhYd9p6unUC3kPxjD2gv2zRCztYQaEDCMJpYrPTqTG");
|
let score = calculate_score("ghst", "sYsghstuhYd9p6unUC3kPxjD2gv2zRCztYQaEDCMJpYrPTqTG");
|
||||||
assert_eq!(score, 246);
|
assert_eq!(score, 246);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_score_50_2() {
|
fn test_score_50_2() {
|
||||||
// 50% for the position + 50% for the size
|
// 50% for the position + 50% for the size
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
calculate_score("ghst", "sYsghXXuhYd9p6unUC3kPxjD2gv2zRCztYQaEDCMJpYrPTqTG"),
|
calculate_score("ghst", "sYsghXXuhYd9p6unUC3kPxjD2gv2zRCztYQaEDCMJpYrPTqTG"),
|
||||||
146
|
146
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_score_0() {
|
fn test_score_0() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
calculate_score("ghst", "sYrjWiZkEP1PQe2kKEZiC1Bi9L8yFSsB5RPEkzEPd5NThsB5H"),
|
calculate_score("ghst", "sYrjWiZkEP1PQe2kKEZiC1Bi9L8yFSsB5RPEkzEPd5NThsB5H"),
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
pub mod params;
|
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
|
pub mod params;
|
||||||
|
|
||||||
pub use commands::KeySubcommand;
|
pub use commands::KeySubcommand;
|
||||||
pub use commands::VanityCmd;
|
pub use commands::VanityCmd;
|
||||||
|
@ -21,19 +21,25 @@ pub struct InnerSs58AddressFormat(Ss58AddressFormat);
|
|||||||
impl InnerSs58AddressFormat {
|
impl InnerSs58AddressFormat {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn custom(prefix: u16) -> Self {
|
pub fn custom(prefix: u16) -> Self {
|
||||||
Self { 0: Ss58AddressFormat::custom(prefix) }
|
Self {
|
||||||
|
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!(f, "{} network", ALL_POSSIBLE_IDS
|
write!(
|
||||||
.binary_search(&u16::from(self.0))
|
f,
|
||||||
.expect("always be found"))
|
"{} network",
|
||||||
|
ALL_POSSIBLE_IDS
|
||||||
|
.binary_search(&u16::from(self.0))
|
||||||
|
.expect("always be found")
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a>TryFrom<&'a str> for InnerSs58AddressFormat {
|
impl<'a> TryFrom<&'a str> for InnerSs58AddressFormat {
|
||||||
type Error = ParseError;
|
type Error = ParseError;
|
||||||
|
|
||||||
fn try_from(x: &'a str) -> Result<Self, Self::Error> {
|
fn try_from(x: &'a str) -> Result<Self, Self::Error> {
|
||||||
@ -44,13 +50,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
|
||||||
))
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,11 @@ 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 { period, delay: Delay::new(period), state: MetronomeState::Snooze }
|
Self {
|
||||||
|
period,
|
||||||
|
delay: Delay::new(period),
|
||||||
|
state: MetronomeState::Snooze,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,14 +40,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
|
||||||
|
@ -2,19 +2,16 @@
|
|||||||
|
|
||||||
use codec::Decode;
|
use codec::Decode;
|
||||||
use core_primitives::{
|
use core_primitives::{
|
||||||
metrics_definitions::{
|
metrics_definitions::{CounterDefinition, CounterVecDefinition, HistogramDefinition},
|
||||||
CounterDefinition, CounterVecDefinition, HistogramDefinition,
|
|
||||||
},
|
|
||||||
RuntimeMetricLabelValues, RuntimeMetricOp, RuntimeMetricUpdate,
|
RuntimeMetricLabelValues, RuntimeMetricOp, RuntimeMetricUpdate,
|
||||||
};
|
};
|
||||||
use prometheus_endpoint::{
|
use prometheus_endpoint::{
|
||||||
register, Counter, CounterVec, Histogram, HistogramOpts, Opts, Registry,
|
register, Counter, CounterVec, Histogram, HistogramOpts, Opts, PrometheusError, Registry, U64,
|
||||||
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 {
|
||||||
@ -32,13 +29,15 @@ 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.entry(countervec.name.to_owned()).or_insert(register(
|
hashmap
|
||||||
CounterVec::new(
|
.entry(countervec.name.to_owned())
|
||||||
Opts::new(countervec.name, countervec.description),
|
.or_insert(register(
|
||||||
countervec.labels,
|
CounterVec::new(
|
||||||
)?,
|
Opts::new(countervec.name, countervec.description),
|
||||||
&self.0,
|
countervec.labels,
|
||||||
)?);
|
)?,
|
||||||
|
&self.0,
|
||||||
|
)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -46,10 +45,7 @@ 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::new(counter.name, counter.description)?,
|
||||||
counter.name,
|
|
||||||
counter.description,
|
|
||||||
)?,
|
|
||||||
&self.0,
|
&self.0,
|
||||||
)?);
|
)?);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -60,8 +56,7 @@ 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)
|
HistogramOpts::new(hist.name, hist.description).buckets(hist.buckets.to_vec()),
|
||||||
.buckets(hist.buckets.to_vec()),
|
|
||||||
)?,
|
)?,
|
||||||
&self.0,
|
&self.0,
|
||||||
)?);
|
)?);
|
||||||
@ -69,15 +64,12 @@ impl RuntimeMetricsProvider {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inc_counter_vec_by(
|
pub fn inc_counter_vec_by(&self, name: &str, value: u64, labels: &RuntimeMetricsProvider) {
|
||||||
&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.with_label_values(&labels.as_str_vec()).inc_by(value)
|
counter_vec
|
||||||
|
.with_label_values(&labels.as_str_vec())
|
||||||
|
.inc_by(value)
|
||||||
});
|
});
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
@ -85,7 +77,8 @@ 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.entry(name.to_owned())
|
hashmap
|
||||||
|
.entry(name.to_owned())
|
||||||
.and_modify(|counter_vec| counter_vec.inc_by(value));
|
.and_modify(|counter_vec| counter_vec.inc_by(value));
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
@ -93,8 +86,9 @@ 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.entry(name.to_owned())
|
hashmap
|
||||||
and_modify(|histogram| histogram.observe(value as f64 / 1_000_000_000.0));
|
.entry(name.to_owned())
|
||||||
|
.and_modify(|histogram| histogram.observe(value as f64 / 1_000_000_000.0));
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -103,21 +97,36 @@ impl RuntimeMetricsProvider {
|
|||||||
where
|
where
|
||||||
F: FnOnce(MutexGuard<'_, HashMap<String, Counter<U64>>>) -> Result<(), PrometheusError>,
|
F: FnOnce(MutexGuard<'_, HashMap<String, Counter<U64>>>) -> Result<(), PrometheusError>,
|
||||||
{
|
{
|
||||||
let _ = self.1.counters.lock().map(do_something).or_else(|error| Err(error));
|
let _ = self
|
||||||
|
.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.1.counter_vecs.lock().map(do_something).or_else(|error| Err(error));
|
let _ = self
|
||||||
|
.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.1.histograms.lock().map(do_something).or_else(|error| Err(error));
|
let _ = self
|
||||||
|
.1
|
||||||
|
.histograms
|
||||||
|
.lock()
|
||||||
|
.map(do_something)
|
||||||
|
.or_else(|error| Err(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +140,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") {
|
||||||
@ -141,7 +150,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(_) => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -150,12 +159,15 @@ 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) =>
|
}
|
||||||
self.inc_counter_by(update.metric_name(), value),
|
RuntimeMetricOp::IncrementCounter(value) => {
|
||||||
RuntimeMetricOp::ObserveHistogram(value) =>
|
self.inc_counter_by(update.metric_name(), value)
|
||||||
self.observe_histogram(update.metric_name(), value),
|
}
|
||||||
|
RuntimeMetricOp::ObserveHistogram(value) => {
|
||||||
|
self.observe_histogram(update.metric_name(), value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -178,7 +190,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();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use hyper::{Client, Uri};
|
|
||||||
use ghost_test_service::{node_config, run_validator_node, test_prometheus_config};
|
use ghost_test_service::{node_config, run_validator_node, test_prometheus_config};
|
||||||
|
use hyper::{Client, Uri};
|
||||||
use keyring::AccountKeyring::*;
|
use keyring::AccountKeyring::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@ -7,8 +7,13 @@ 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 =
|
let mut alice_config = node_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));
|
||||||
@ -26,8 +31,13 @@ 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 =
|
let bob_config = node_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);
|
||||||
@ -48,19 +58,25 @@ 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).await.expect("can't get body as bytes").to_vec(),
|
hyper::body::to_bytes(res)
|
||||||
).expect("body is not an UTF8 string");
|
.await
|
||||||
|
.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(|prometheus_parse::Sample { metric, value, .. }| match value {
|
.filter_map(
|
||||||
prometheus_parse::Value::Counter(value) => Some((metric, value as u64)),
|
|prometheus_parse::Sample { metric, value, .. }| match value {
|
||||||
prometheus_parse::Value::Gauge(value) => Some((metric, value as u64)),
|
prometheus_parse::Value::Counter(value) => Some((metric, value as u64)),
|
||||||
prometheus_parse::Value::Untyped(value) => Some((metric, value as u64)),
|
prometheus_parse::Value::Gauge(value) => Some((metric, value as u64)),
|
||||||
_ => None,
|
prometheus_parse::Value::Untyped(value) => Some((metric, value as u64)),
|
||||||
})
|
_ => None,
|
||||||
|
},
|
||||||
|
)
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghost-slow-clap"
|
name = "ghost-slow-clap"
|
||||||
version = "0.3.34"
|
version = "0.3.35"
|
||||||
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
|
||||||
|
@ -702,23 +702,27 @@ impl<T: Config> Pallet<T> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let random_seed = sp_io::offchain::random_seed();
|
let random_seed = sp_io::offchain::random_seed();
|
||||||
let random_number = <u32>::decode(
|
let random_number = <u32>::decode(&mut TrailingZeroInput::new(random_seed.as_ref()))
|
||||||
&mut TrailingZeroInput::new(random_seed.as_ref())
|
.expect("input is padded with zeroes; qed");
|
||||||
).expect("input is padded with zeroes; qed");
|
|
||||||
|
|
||||||
let rpc_endpoint = if stored_endpoints.len() > 0 {
|
let rpc_endpoint = if stored_endpoints.len() > 0 {
|
||||||
stored_endpoints
|
stored_endpoints
|
||||||
.iter()
|
.iter()
|
||||||
.nth((random_number as usize)
|
.nth(
|
||||||
.checked_rem(stored_endpoints.len())
|
(random_number as usize)
|
||||||
.unwrap_or_default())
|
.checked_rem(stored_endpoints.len())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
.expect("stored endpoint should be non empty; qed")
|
.expect("stored endpoint should be non empty; qed")
|
||||||
} else {
|
} else {
|
||||||
network_data.default_endpoints
|
network_data
|
||||||
|
.default_endpoints
|
||||||
.iter()
|
.iter()
|
||||||
.nth((random_number as usize)
|
.nth(
|
||||||
.checked_rem(network_data.default_endpoints.len())
|
(random_number as usize)
|
||||||
.unwrap_or_default())
|
.checked_rem(network_data.default_endpoints.len())
|
||||||
|
.unwrap_or_default(),
|
||||||
|
)
|
||||||
.expect("default endpoint should be non empty; qed")
|
.expect("default endpoint should be non empty; qed")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghost-sudo"
|
name = "ghost-sudo"
|
||||||
version = "0.0.1"
|
version = "0.0.2"
|
||||||
description = "Port of the sudo pallet because of dependencies issue"
|
description = "Port of the sudo pallet because of dependencies issue"
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
|
@ -4,67 +4,74 @@ use frame_benchmarking::v2::*;
|
|||||||
use frame_system::RawOrigin;
|
use frame_system::RawOrigin;
|
||||||
|
|
||||||
fn assert_last_event<T: Config>(generic_event: crate::Event<T>) {
|
fn assert_last_event<T: Config>(generic_event: crate::Event<T>) {
|
||||||
let re: <T as Config>::RuntimeEvent = generic_event.into();
|
let re: <T as Config>::RuntimeEvent = generic_event.into();
|
||||||
frame_system::Pallet::<T>::assert_last_event(re.into());
|
frame_system::Pallet::<T>::assert_last_event(re.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[benchmarks(where <T as Config>::RuntimeCall: From<frame_system::Call<T>>)]
|
#[benchmarks(where <T as Config>::RuntimeCall: From<frame_system::Call<T>>)]
|
||||||
mod benchmarks {
|
mod benchmarks {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[benchmark]
|
#[benchmark]
|
||||||
fn set_key() {
|
fn set_key() {
|
||||||
let caller: T::AccountId = whitelisted_caller();
|
let caller: T::AccountId = whitelisted_caller();
|
||||||
Key::<T>::put(&caller);
|
Key::<T>::put(&caller);
|
||||||
|
|
||||||
let new_sudoer: T::AccountId = account("sudoer", 0, 0);
|
let new_sudoer: T::AccountId = account("sudoer", 0, 0);
|
||||||
let new_sudoer_lookup = T::Lookup::unlookup(new_sudoer.clone());
|
let new_sudoer_lookup = T::Lookup::unlookup(new_sudoer.clone());
|
||||||
|
|
||||||
#[extrinsic_call]
|
#[extrinsic_call]
|
||||||
_(RawOrigin::Signed(caller.clone()), new_sudoer_lookup);
|
_(RawOrigin::Signed(caller.clone()), new_sudoer_lookup);
|
||||||
|
|
||||||
assert_last_event::<T>(Event::KeyChanged { old: Some(caller), new: new_sudoer });
|
assert_last_event::<T>(Event::KeyChanged {
|
||||||
}
|
old: Some(caller),
|
||||||
|
new: new_sudoer,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[benchmark]
|
#[benchmark]
|
||||||
fn sudo() {
|
fn sudo() {
|
||||||
let caller: T::AccountId = whitelisted_caller();
|
let caller: T::AccountId = whitelisted_caller();
|
||||||
Key::<T>::put(&caller);
|
Key::<T>::put(&caller);
|
||||||
|
|
||||||
let call = frame_system::Call::remark { remark: vec![] }.into();
|
let call = frame_system::Call::remark { remark: vec![] }.into();
|
||||||
|
|
||||||
#[extrinsic_call]
|
#[extrinsic_call]
|
||||||
_(RawOrigin::Signed(caller), Box::new(call));
|
_(RawOrigin::Signed(caller), Box::new(call));
|
||||||
|
|
||||||
assert_last_event::<T>(Event::Sudid { sudo_result: Ok(()) })
|
assert_last_event::<T>(Event::Sudid {
|
||||||
}
|
sudo_result: Ok(()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[benchmark]
|
#[benchmark]
|
||||||
fn sudo_as() {
|
fn sudo_as() {
|
||||||
let caller: T::AccountId = whitelisted_caller();
|
let caller: T::AccountId = whitelisted_caller();
|
||||||
Key::<T>::put(caller.clone());
|
Key::<T>::put(caller.clone());
|
||||||
|
|
||||||
let call = frame_system::Call::remark { remark: vec![] }.into();
|
let call = frame_system::Call::remark { remark: vec![] }.into();
|
||||||
|
|
||||||
let who: T::AccountId = account("as", 0, 0);
|
let who: T::AccountId = account("as", 0, 0);
|
||||||
let who_lookup = T::Lookup::unlookup(who);
|
let who_lookup = T::Lookup::unlookup(who);
|
||||||
|
|
||||||
#[extrinsic_call]
|
#[extrinsic_call]
|
||||||
_(RawOrigin::Signed(caller), who_lookup, Box::new(call));
|
_(RawOrigin::Signed(caller), who_lookup, Box::new(call));
|
||||||
|
|
||||||
assert_last_event::<T>(Event::SudoAsDone { sudo_result: Ok(()) })
|
assert_last_event::<T>(Event::SudoAsDone {
|
||||||
}
|
sudo_result: Ok(()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
#[benchmark]
|
#[benchmark]
|
||||||
fn remove_key() {
|
fn remove_key() {
|
||||||
let caller: T::AccountId = whitelisted_caller();
|
let caller: T::AccountId = whitelisted_caller();
|
||||||
Key::<T>::put(&caller);
|
Key::<T>::put(&caller);
|
||||||
|
|
||||||
#[extrinsic_call]
|
#[extrinsic_call]
|
||||||
_(RawOrigin::Signed(caller.clone()));
|
_(RawOrigin::Signed(caller.clone()));
|
||||||
|
|
||||||
assert_last_event::<T>(Event::KeyRemoved {});
|
assert_last_event::<T>(Event::KeyRemoved {});
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_benchmark_test_suite!(Pallet, crate::mock::new_bench_ext(), crate::mock::Test);
|
impl_benchmark_test_suite!(Pallet, crate::mock::new_bench_ext(), crate::mock::Test);
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,11 @@ use codec::{Decode, Encode};
|
|||||||
use frame_support::{dispatch::DispatchInfo, ensure};
|
use frame_support::{dispatch::DispatchInfo, ensure};
|
||||||
use scale_info::TypeInfo;
|
use scale_info::TypeInfo;
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
traits::{DispatchInfoOf, Dispatchable, SignedExtension},
|
traits::{DispatchInfoOf, Dispatchable, SignedExtension},
|
||||||
transaction_validity::{
|
transaction_validity::{
|
||||||
InvalidTransaction, TransactionPriority, TransactionValidity, TransactionValidityError,
|
InvalidTransaction, TransactionPriority, TransactionValidity, TransactionValidityError,
|
||||||
UnknownTransaction, ValidTransaction,
|
UnknownTransaction, ValidTransaction,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use sp_std::{fmt, marker::PhantomData};
|
use sp_std::{fmt, marker::PhantomData};
|
||||||
|
|
||||||
@ -16,67 +16,67 @@ use sp_std::{fmt, marker::PhantomData};
|
|||||||
pub struct CheckOnlySudoAccount<T: Config + Send + Sync>(PhantomData<T>);
|
pub struct CheckOnlySudoAccount<T: Config + Send + Sync>(PhantomData<T>);
|
||||||
|
|
||||||
impl<T: Config + Send + Sync> Default for CheckOnlySudoAccount<T> {
|
impl<T: Config + Send + Sync> Default for CheckOnlySudoAccount<T> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self(Default::default())
|
Self(Default::default())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config + Send + Sync> fmt::Debug for CheckOnlySudoAccount<T> {
|
impl<T: Config + Send + Sync> fmt::Debug for CheckOnlySudoAccount<T> {
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "CheckOnlySudoAccount")
|
write!(f, "CheckOnlySudoAccount")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
#[cfg(not(feature = "std"))]
|
||||||
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config + Send + Sync> CheckOnlySudoAccount<T> {
|
impl<T: Config + Send + Sync> CheckOnlySudoAccount<T> {
|
||||||
/// Creates new `SignedExtension` to check sudo key.
|
/// Creates new `SignedExtension` to check sudo key.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config + Send + Sync> SignedExtension for CheckOnlySudoAccount<T>
|
impl<T: Config + Send + Sync> SignedExtension for CheckOnlySudoAccount<T>
|
||||||
where
|
where
|
||||||
<T as Config>::RuntimeCall: Dispatchable<Info = DispatchInfo>,
|
<T as Config>::RuntimeCall: Dispatchable<Info = DispatchInfo>,
|
||||||
{
|
{
|
||||||
const IDENTIFIER: &'static str = "CheckOnlySudoAccount";
|
const IDENTIFIER: &'static str = "CheckOnlySudoAccount";
|
||||||
type AccountId = T::AccountId;
|
type AccountId = T::AccountId;
|
||||||
type Call = <T as Config>::RuntimeCall;
|
type Call = <T as Config>::RuntimeCall;
|
||||||
type AdditionalSigned = ();
|
type AdditionalSigned = ();
|
||||||
type Pre = ();
|
type Pre = ();
|
||||||
|
|
||||||
fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
|
fn additional_signed(&self) -> Result<Self::AdditionalSigned, TransactionValidityError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn validate(
|
fn validate(
|
||||||
&self,
|
&self,
|
||||||
who: &Self::AccountId,
|
who: &Self::AccountId,
|
||||||
_call: &Self::Call,
|
_call: &Self::Call,
|
||||||
info: &DispatchInfoOf<Self::Call>,
|
info: &DispatchInfoOf<Self::Call>,
|
||||||
_len: usize,
|
_len: usize,
|
||||||
) -> TransactionValidity {
|
) -> TransactionValidity {
|
||||||
let sudo_key: T::AccountId = Key::<T>::get().ok_or(UnknownTransaction::CannotLookup)?;
|
let sudo_key: T::AccountId = Key::<T>::get().ok_or(UnknownTransaction::CannotLookup)?;
|
||||||
ensure!(*who == sudo_key, InvalidTransaction::BadSigner);
|
ensure!(*who == sudo_key, InvalidTransaction::BadSigner);
|
||||||
|
|
||||||
Ok(ValidTransaction {
|
Ok(ValidTransaction {
|
||||||
priority: info.weight.ref_time() as TransactionPriority,
|
priority: info.weight.ref_time() as TransactionPriority,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pre_dispatch(
|
fn pre_dispatch(
|
||||||
self,
|
self,
|
||||||
who: &Self::AccountId,
|
who: &Self::AccountId,
|
||||||
call: &Self::Call,
|
call: &Self::Call,
|
||||||
info: &DispatchInfoOf<Self::Call>,
|
info: &DispatchInfoOf<Self::Call>,
|
||||||
len: usize,
|
len: usize,
|
||||||
) -> Result<Self::Pre, TransactionValidityError> {
|
) -> Result<Self::Pre, TransactionValidityError> {
|
||||||
self.validate(who, call, info, len).map(|_| ())
|
self.validate(who, call, info, len).map(|_| ())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,181 +23,190 @@ type AccountIdLookupOf<T> = <<T as frame_system::Config>::Lookup as StaticLookup
|
|||||||
|
|
||||||
#[frame_support::pallet]
|
#[frame_support::pallet]
|
||||||
pub mod pallet {
|
pub mod pallet {
|
||||||
use super::{DispatchResult, *};
|
use super::{DispatchResult, *};
|
||||||
use frame_support::pallet_prelude::*;
|
use frame_support::pallet_prelude::*;
|
||||||
use frame_system::{pallet_prelude::*, RawOrigin};
|
use frame_system::{pallet_prelude::*, RawOrigin};
|
||||||
|
|
||||||
pub mod config_preludes {
|
pub mod config_preludes {
|
||||||
use super::*;
|
use super::*;
|
||||||
use frame_support::derive_impl;
|
use frame_support::derive_impl;
|
||||||
|
|
||||||
pub struct TestDefaultConfig;
|
pub struct TestDefaultConfig;
|
||||||
|
|
||||||
#[derive_impl(frame_system::config_preludes::TestDefaultConfig, no_aggregated_types)]
|
#[derive_impl(frame_system::config_preludes::TestDefaultConfig, no_aggregated_types)]
|
||||||
impl frame_system::DefaultConfig for TestDefaultConfig {}
|
impl frame_system::DefaultConfig for TestDefaultConfig {}
|
||||||
|
|
||||||
#[frame_support::register_default_impl(TestDefaultConfig)]
|
#[frame_support::register_default_impl(TestDefaultConfig)]
|
||||||
impl DefaultConfig for TestDefaultConfig {
|
impl DefaultConfig for TestDefaultConfig {
|
||||||
type WeightInfo = ();
|
type WeightInfo = ();
|
||||||
#[inject_runtime_type]
|
#[inject_runtime_type]
|
||||||
type RuntimeEvent = ();
|
type RuntimeEvent = ();
|
||||||
#[inject_runtime_type]
|
#[inject_runtime_type]
|
||||||
type RuntimeCall = ();
|
type RuntimeCall = ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[pallet::config(with_default)]
|
#[pallet::config(with_default)]
|
||||||
pub trait Config: frame_system::Config {
|
pub trait Config: frame_system::Config {
|
||||||
#[pallet::no_default_bounds]
|
#[pallet::no_default_bounds]
|
||||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
||||||
|
|
||||||
#[pallet::no_default_bounds]
|
#[pallet::no_default_bounds]
|
||||||
type RuntimeCall: Parameter
|
type RuntimeCall: Parameter
|
||||||
+ UnfilteredDispatchable<RuntimeOrigin = Self::RuntimeOrigin>
|
+ UnfilteredDispatchable<RuntimeOrigin = Self::RuntimeOrigin>
|
||||||
+ GetDispatchInfo;
|
+ GetDispatchInfo;
|
||||||
|
|
||||||
type WeightInfo: WeightInfo;
|
type WeightInfo: WeightInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pallet::pallet]
|
#[pallet::pallet]
|
||||||
pub struct Pallet<T>(_);
|
pub struct Pallet<T>(_);
|
||||||
|
|
||||||
#[pallet::call]
|
#[pallet::call]
|
||||||
impl<T: Config> Pallet<T> {
|
impl<T: Config> Pallet<T> {
|
||||||
#[pallet::call_index(0)]
|
#[pallet::call_index(0)]
|
||||||
#[pallet::weight({
|
#[pallet::weight({
|
||||||
let dispatch_info = call.get_dispatch_info();
|
let dispatch_info = call.get_dispatch_info();
|
||||||
(
|
(
|
||||||
T::WeightInfo::sudo().saturating_add(dispatch_info.weight),
|
T::WeightInfo::sudo().saturating_add(dispatch_info.weight),
|
||||||
dispatch_info.class
|
dispatch_info.class
|
||||||
)
|
)
|
||||||
})]
|
})]
|
||||||
pub fn sudo(
|
pub fn sudo(
|
||||||
origin: OriginFor<T>,
|
origin: OriginFor<T>,
|
||||||
call: Box<<T as Config>::RuntimeCall>,
|
call: Box<<T as Config>::RuntimeCall>,
|
||||||
) -> DispatchResultWithPostInfo {
|
) -> DispatchResultWithPostInfo {
|
||||||
Self::ensure_sudo(origin)?;
|
Self::ensure_sudo(origin)?;
|
||||||
|
|
||||||
let res = call.dispatch_bypass_filter(RawOrigin::Root.into());
|
let res = call.dispatch_bypass_filter(RawOrigin::Root.into());
|
||||||
Self::deposit_event(Event::Sudid { sudo_result: res.map(|_| ()).map_err(|e| e.error) });
|
Self::deposit_event(Event::Sudid {
|
||||||
|
sudo_result: res.map(|_| ()).map_err(|e| e.error),
|
||||||
|
});
|
||||||
|
|
||||||
Ok(Pays::No.into())
|
Ok(Pays::No.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pallet::call_index(1)]
|
#[pallet::call_index(1)]
|
||||||
#[pallet::weight((*weight, call.get_dispatch_info().class))]
|
#[pallet::weight((*weight, call.get_dispatch_info().class))]
|
||||||
pub fn sudo_unchecked_weight(
|
pub fn sudo_unchecked_weight(
|
||||||
origin: OriginFor<T>,
|
origin: OriginFor<T>,
|
||||||
call: Box<<T as Config>::RuntimeCall>,
|
call: Box<<T as Config>::RuntimeCall>,
|
||||||
weight: Weight,
|
weight: Weight,
|
||||||
) -> DispatchResultWithPostInfo {
|
) -> DispatchResultWithPostInfo {
|
||||||
Self::ensure_sudo(origin)?;
|
Self::ensure_sudo(origin)?;
|
||||||
let _ = weight;
|
let _ = weight;
|
||||||
|
|
||||||
let res = call.dispatch_bypass_filter(RawOrigin::Root.into());
|
let res = call.dispatch_bypass_filter(RawOrigin::Root.into());
|
||||||
Self::deposit_event(Event::Sudid { sudo_result: res.map(|_| ()).map_err(|e| e.error) });
|
Self::deposit_event(Event::Sudid {
|
||||||
|
sudo_result: res.map(|_| ()).map_err(|e| e.error),
|
||||||
|
});
|
||||||
|
|
||||||
Ok(Pays::No.into())
|
Ok(Pays::No.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pallet::call_index(2)]
|
#[pallet::call_index(2)]
|
||||||
#[pallet::weight(T::WeightInfo::set_key())]
|
#[pallet::weight(T::WeightInfo::set_key())]
|
||||||
pub fn set_key(
|
pub fn set_key(
|
||||||
origin: OriginFor<T>,
|
origin: OriginFor<T>,
|
||||||
new: AccountIdLookupOf<T>,
|
new: AccountIdLookupOf<T>,
|
||||||
) -> DispatchResultWithPostInfo {
|
) -> DispatchResultWithPostInfo {
|
||||||
Self::ensure_sudo(origin)?;
|
Self::ensure_sudo(origin)?;
|
||||||
|
|
||||||
let new = T::Lookup::lookup(new)?;
|
let new = T::Lookup::lookup(new)?;
|
||||||
Self::deposit_event(Event::KeyChanged { old: Key::<T>::get(), new: new.clone() });
|
Self::deposit_event(Event::KeyChanged {
|
||||||
Key::<T>::put(new);
|
old: Key::<T>::get(),
|
||||||
|
new: new.clone(),
|
||||||
|
});
|
||||||
|
Key::<T>::put(new);
|
||||||
|
|
||||||
Ok(Pays::No.into())
|
Ok(Pays::No.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pallet::call_index(3)]
|
#[pallet::call_index(3)]
|
||||||
#[pallet::weight({
|
#[pallet::weight({
|
||||||
let dispatch_info = call.get_dispatch_info();
|
let dispatch_info = call.get_dispatch_info();
|
||||||
(
|
(
|
||||||
T::WeightInfo::sudo_as().saturating_add(dispatch_info.weight),
|
T::WeightInfo::sudo_as().saturating_add(dispatch_info.weight),
|
||||||
dispatch_info.class,
|
dispatch_info.class,
|
||||||
)
|
)
|
||||||
})]
|
})]
|
||||||
pub fn sudo_as(
|
pub fn sudo_as(
|
||||||
origin: OriginFor<T>,
|
origin: OriginFor<T>,
|
||||||
who: AccountIdLookupOf<T>,
|
who: AccountIdLookupOf<T>,
|
||||||
call: Box<<T as Config>::RuntimeCall>,
|
call: Box<<T as Config>::RuntimeCall>,
|
||||||
) -> DispatchResultWithPostInfo {
|
) -> DispatchResultWithPostInfo {
|
||||||
Self::ensure_sudo(origin)?;
|
Self::ensure_sudo(origin)?;
|
||||||
|
|
||||||
let who = T::Lookup::lookup(who)?;
|
let who = T::Lookup::lookup(who)?;
|
||||||
let res = call.dispatch_bypass_filter(RawOrigin::Signed(who).into());
|
let res = call.dispatch_bypass_filter(RawOrigin::Signed(who).into());
|
||||||
Self::deposit_event(Event::SudoAsDone {
|
Self::deposit_event(Event::SudoAsDone {
|
||||||
sudo_result: res.map(|_| ()).map_err(|e| e.error),
|
sudo_result: res.map(|_| ()).map_err(|e| e.error),
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(Pays::No.into())
|
Ok(Pays::No.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pallet::call_index(4)]
|
#[pallet::call_index(4)]
|
||||||
#[pallet::weight(T::WeightInfo::remove_key())]
|
#[pallet::weight(T::WeightInfo::remove_key())]
|
||||||
pub fn remove_key(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
|
pub fn remove_key(origin: OriginFor<T>) -> DispatchResultWithPostInfo {
|
||||||
Self::ensure_sudo(origin)?;
|
Self::ensure_sudo(origin)?;
|
||||||
|
|
||||||
Self::deposit_event(Event::KeyRemoved {});
|
Self::deposit_event(Event::KeyRemoved {});
|
||||||
Key::<T>::kill();
|
Key::<T>::kill();
|
||||||
|
|
||||||
Ok(Pays::No.into())
|
Ok(Pays::No.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pallet::event]
|
#[pallet::event]
|
||||||
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
||||||
pub enum Event<T: Config> {
|
pub enum Event<T: Config> {
|
||||||
Sudid {
|
Sudid {
|
||||||
sudo_result: DispatchResult,
|
sudo_result: DispatchResult,
|
||||||
},
|
},
|
||||||
KeyChanged {
|
KeyChanged {
|
||||||
old: Option<T::AccountId>,
|
old: Option<T::AccountId>,
|
||||||
new: T::AccountId,
|
new: T::AccountId,
|
||||||
},
|
},
|
||||||
KeyRemoved,
|
KeyRemoved,
|
||||||
SudoAsDone { sudo_result: DispatchResult },
|
SudoAsDone {
|
||||||
}
|
sudo_result: DispatchResult,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
#[pallet::error]
|
#[pallet::error]
|
||||||
pub enum Error<T> {
|
pub enum Error<T> {
|
||||||
RequireSudo,
|
RequireSudo,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
pub(super) type Key<T: Config> = StorageValue<_, T::AccountId, OptionQuery>;
|
pub(super) type Key<T: Config> = StorageValue<_, T::AccountId, OptionQuery>;
|
||||||
|
|
||||||
#[pallet::genesis_config]
|
#[pallet::genesis_config]
|
||||||
#[derive(frame_support::DefaultNoBound)]
|
#[derive(frame_support::DefaultNoBound)]
|
||||||
pub struct GenesisConfig<T: Config> {
|
pub struct GenesisConfig<T: Config> {
|
||||||
pub key: Option<T::AccountId>,
|
pub key: Option<T::AccountId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pallet::genesis_build]
|
#[pallet::genesis_build]
|
||||||
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
|
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
|
||||||
fn build(&self) {
|
fn build(&self) {
|
||||||
Key::<T>::set(self.key.clone());
|
Key::<T>::set(self.key.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Config> Pallet<T> {
|
impl<T: Config> Pallet<T> {
|
||||||
pub(crate) fn ensure_sudo(origin: OriginFor<T>) -> DispatchResult {
|
pub(crate) fn ensure_sudo(origin: OriginFor<T>) -> DispatchResult {
|
||||||
let sender = ensure_signed_or_root(origin)?;
|
let sender = ensure_signed_or_root(origin)?;
|
||||||
|
|
||||||
if let Some(sender) = sender {
|
if let Some(sender) = sender {
|
||||||
if Key::<T>::get().map_or(false, |k| k == sender) {
|
if Key::<T>::get().map_or(false, |k| k == sender) {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::<T>::RequireSudo.into())
|
Err(Error::<T>::RequireSudo.into())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,104 +6,122 @@ use sp_runtime::BuildStorage;
|
|||||||
|
|
||||||
#[frame_support::pallet]
|
#[frame_support::pallet]
|
||||||
pub mod logger {
|
pub mod logger {
|
||||||
use frame_support::pallet_prelude::*;
|
use frame_support::pallet_prelude::*;
|
||||||
use frame_system::pallet_prelude::*;
|
use frame_system::pallet_prelude::*;
|
||||||
|
|
||||||
#[pallet::config]
|
#[pallet::config]
|
||||||
pub trait Config: frame_system::Config {
|
pub trait Config: frame_system::Config {
|
||||||
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pallet::pallet]
|
#[pallet::pallet]
|
||||||
pub struct Pallet<T>(_);
|
pub struct Pallet<T>(_);
|
||||||
|
|
||||||
#[pallet::call]
|
#[pallet::call]
|
||||||
impl<T: Config> Pallet<T> {
|
impl<T: Config> Pallet<T> {
|
||||||
#[pallet::call_index(0)]
|
#[pallet::call_index(0)]
|
||||||
#[pallet::weight(*weight)]
|
#[pallet::weight(*weight)]
|
||||||
pub fn privileged_i32_log(
|
pub fn privileged_i32_log(
|
||||||
origin: OriginFor<T>,
|
origin: OriginFor<T>,
|
||||||
i: i32,
|
i: i32,
|
||||||
weight: Weight,
|
weight: Weight,
|
||||||
) -> DispatchResultWithPostInfo {
|
) -> DispatchResultWithPostInfo {
|
||||||
ensure_root(origin)?;
|
ensure_root(origin)?;
|
||||||
<I32Log<T>>::try_append(i).map_err(|_| "could not append")?;
|
<I32Log<T>>::try_append(i).map_err(|_| "could not append")?;
|
||||||
Self::deposit_event(Event::AppendI32 { value: i, weight });
|
Self::deposit_event(Event::AppendI32 { value: i, weight });
|
||||||
Ok(().into())
|
Ok(().into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pallet::call_index(1)]
|
#[pallet::call_index(1)]
|
||||||
#[pallet::weight(*weight)]
|
#[pallet::weight(*weight)]
|
||||||
pub fn non_privileged_log(
|
pub fn non_privileged_log(
|
||||||
origin: OriginFor<T>,
|
origin: OriginFor<T>,
|
||||||
i: i32,
|
i: i32,
|
||||||
weight: Weight,
|
weight: Weight,
|
||||||
) -> DispatchResultWithPostInfo {
|
) -> DispatchResultWithPostInfo {
|
||||||
let sender = ensure_signed(origin)?;
|
let sender = ensure_signed(origin)?;
|
||||||
<I32Log<T>>::try_append(i).map_err(|_| "could not append")?;
|
<I32Log<T>>::try_append(i).map_err(|_| "could not append")?;
|
||||||
<AccountLog<T>>::try_append(sender.clone()).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 });
|
Self::deposit_event(Event::AppendI32AndAccount {
|
||||||
Ok(().into())
|
sender,
|
||||||
}
|
value: i,
|
||||||
}
|
weight,
|
||||||
|
});
|
||||||
|
Ok(().into())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[pallet::event]
|
#[pallet::event]
|
||||||
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
#[pallet::generate_deposit(pub(super) fn deposit_event)]
|
||||||
pub enum Event<T: Config> {
|
pub enum Event<T: Config> {
|
||||||
AppendI32 { value: i32, weight: Weight },
|
AppendI32 {
|
||||||
AppendI32AndAccount { sender: T::AccountId, value: i32, weight: Weight },
|
value: i32,
|
||||||
}
|
weight: Weight,
|
||||||
|
},
|
||||||
|
AppendI32AndAccount {
|
||||||
|
sender: T::AccountId,
|
||||||
|
value: i32,
|
||||||
|
weight: Weight,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
#[pallet::getter(fn account_log)]
|
#[pallet::getter(fn account_log)]
|
||||||
pub(super) type AccountLog<T: Config> =
|
pub(super) type AccountLog<T: Config> =
|
||||||
StorageValue<_, BoundedVec<T::AccountId, ConstU32<1_000>>, ValueQuery>;
|
StorageValue<_, BoundedVec<T::AccountId, ConstU32<1_000>>, ValueQuery>;
|
||||||
|
|
||||||
#[pallet::storage]
|
#[pallet::storage]
|
||||||
#[pallet::getter(fn i32_log)]
|
#[pallet::getter(fn i32_log)]
|
||||||
pub(super) type I32Log<T> = StorageValue<_, BoundedVec<i32, ConstU32<1_000>>, ValueQuery>;
|
pub(super) type I32Log<T> = StorageValue<_, BoundedVec<i32, ConstU32<1_000>>, ValueQuery>;
|
||||||
}
|
}
|
||||||
|
|
||||||
type Block = frame_system::mocking::MockBlock<Test>;
|
type Block = frame_system::mocking::MockBlock<Test>;
|
||||||
|
|
||||||
frame_support::construct_runtime!(
|
frame_support::construct_runtime!(
|
||||||
pub enum Test
|
pub enum Test
|
||||||
{
|
{
|
||||||
System: frame_system,
|
System: frame_system,
|
||||||
Sudo: sudo,
|
Sudo: sudo,
|
||||||
Logger: logger,
|
Logger: logger,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
|
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
|
||||||
impl frame_system::Config for Test {
|
impl frame_system::Config for Test {
|
||||||
type Block = Block;
|
type Block = Block;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl logger::Config for Test {
|
impl logger::Config for Test {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config for Test {
|
impl Config for Test {
|
||||||
type RuntimeEvent = RuntimeEvent;
|
type RuntimeEvent = RuntimeEvent;
|
||||||
type RuntimeCall = RuntimeCall;
|
type RuntimeCall = RuntimeCall;
|
||||||
type WeightInfo = ();
|
type WeightInfo = ();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type SudoCall = sudo::Call<Test>;
|
pub type SudoCall = sudo::Call<Test>;
|
||||||
pub type LoggerCall = logger::Call<Test>;
|
pub type LoggerCall = logger::Call<Test>;
|
||||||
|
|
||||||
pub fn new_test_ext(root_key: u64) -> sp_io::TestExternalities {
|
pub fn new_test_ext(root_key: u64) -> sp_io::TestExternalities {
|
||||||
let mut t = frame_system::GenesisConfig::<Test>::default().build_storage().unwrap();
|
let mut t = frame_system::GenesisConfig::<Test>::default()
|
||||||
sudo::GenesisConfig::<Test> { key: Some(root_key) }
|
.build_storage()
|
||||||
.assimilate_storage(&mut t)
|
.unwrap();
|
||||||
.unwrap();
|
sudo::GenesisConfig::<Test> {
|
||||||
let mut ext: sp_io::TestExternalities = t.into();
|
key: Some(root_key),
|
||||||
ext.execute_with(|| System::set_block_number(1));
|
}
|
||||||
ext
|
.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")]
|
#[cfg(feature = "runtime-benchmarks")]
|
||||||
pub fn new_bench_ext() -> sp_io::TestExternalities {
|
pub fn new_bench_ext() -> sp_io::TestExternalities {
|
||||||
frame_system::GenesisConfig::<Test>::default().build_storage().unwrap().into()
|
frame_system::GenesisConfig::<Test>::default()
|
||||||
|
.build_storage()
|
||||||
|
.unwrap()
|
||||||
|
.into()
|
||||||
}
|
}
|
||||||
|
@ -1,188 +1,217 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use frame_support::{assert_noop, assert_ok, weights::Weight};
|
use frame_support::{assert_noop, assert_ok, weights::Weight};
|
||||||
use mock::{
|
use mock::{
|
||||||
new_test_ext, Logger, LoggerCall, RuntimeCall, RuntimeEvent as TestEvent, RuntimeOrigin, Sudo,
|
new_test_ext, Logger, LoggerCall, RuntimeCall, RuntimeEvent as TestEvent, RuntimeOrigin, Sudo,
|
||||||
SudoCall, System, Test,
|
SudoCall, System, Test,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_setup_works() {
|
fn test_setup_works() {
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
assert_eq!(Key::<Test>::get(), Some(1u64));
|
assert_eq!(Key::<Test>::get(), Some(1u64));
|
||||||
assert!(Logger::i32_log().is_empty());
|
assert!(Logger::i32_log().is_empty());
|
||||||
assert!(Logger::account_log().is_empty());
|
assert!(Logger::account_log().is_empty());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[docify::export]
|
#[docify::export]
|
||||||
#[test]
|
#[test]
|
||||||
fn sudo_basics() {
|
fn sudo_basics() {
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
||||||
i: 42,
|
i: 42,
|
||||||
weight: Weight::from_parts(1_000, 0),
|
weight: Weight::from_parts(1_000, 0),
|
||||||
}));
|
}));
|
||||||
assert_ok!(Sudo::sudo(RuntimeOrigin::signed(1), call));
|
assert_ok!(Sudo::sudo(RuntimeOrigin::signed(1), call));
|
||||||
assert_eq!(Logger::i32_log(), vec![42i32]);
|
assert_eq!(Logger::i32_log(), vec![42i32]);
|
||||||
|
|
||||||
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
||||||
i: 42,
|
i: 42,
|
||||||
weight: Weight::from_parts(1_000, 0),
|
weight: Weight::from_parts(1_000, 0),
|
||||||
}));
|
}));
|
||||||
assert_noop!(Sudo::sudo(RuntimeOrigin::signed(2), call), Error::<Test>::RequireSudo);
|
assert_noop!(
|
||||||
});
|
Sudo::sudo(RuntimeOrigin::signed(2), call),
|
||||||
|
Error::<Test>::RequireSudo
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sudo_emits_events_correctly() {
|
fn sudo_emits_events_correctly() {
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
||||||
i: 42,
|
i: 42,
|
||||||
weight: Weight::from_parts(1, 0),
|
weight: Weight::from_parts(1, 0),
|
||||||
}));
|
}));
|
||||||
assert_ok!(Sudo::sudo(RuntimeOrigin::signed(1), call));
|
assert_ok!(Sudo::sudo(RuntimeOrigin::signed(1), call));
|
||||||
System::assert_has_event(TestEvent::Sudo(Event::Sudid { sudo_result: Ok(()) }));
|
System::assert_has_event(TestEvent::Sudo(Event::Sudid {
|
||||||
})
|
sudo_result: Ok(()),
|
||||||
|
}));
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sudo_unchecked_weight_basics() {
|
fn sudo_unchecked_weight_basics() {
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
||||||
i: 42,
|
i: 42,
|
||||||
weight: Weight::from_parts(1_000, 0),
|
weight: Weight::from_parts(1_000, 0),
|
||||||
}));
|
}));
|
||||||
assert_ok!(Sudo::sudo_unchecked_weight(
|
assert_ok!(Sudo::sudo_unchecked_weight(
|
||||||
RuntimeOrigin::signed(1),
|
RuntimeOrigin::signed(1),
|
||||||
call,
|
call,
|
||||||
Weight::from_parts(1_000, 0)
|
Weight::from_parts(1_000, 0)
|
||||||
));
|
));
|
||||||
assert_eq!(Logger::i32_log(), vec![42i32]);
|
assert_eq!(Logger::i32_log(), vec![42i32]);
|
||||||
|
|
||||||
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
||||||
i: 42,
|
i: 42,
|
||||||
weight: Weight::from_parts(1_000, 0),
|
weight: Weight::from_parts(1_000, 0),
|
||||||
}));
|
}));
|
||||||
assert_noop!(
|
assert_noop!(
|
||||||
Sudo::sudo_unchecked_weight(
|
Sudo::sudo_unchecked_weight(
|
||||||
RuntimeOrigin::signed(2),
|
RuntimeOrigin::signed(2),
|
||||||
call,
|
call,
|
||||||
Weight::from_parts(1_000, 0)
|
Weight::from_parts(1_000, 0)
|
||||||
),
|
),
|
||||||
Error::<Test>::RequireSudo,
|
Error::<Test>::RequireSudo,
|
||||||
);
|
);
|
||||||
assert_eq!(Logger::i32_log(), vec![42i32]);
|
assert_eq!(Logger::i32_log(), vec![42i32]);
|
||||||
|
|
||||||
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
||||||
i: 42,
|
i: 42,
|
||||||
weight: Weight::from_parts(1, 0),
|
weight: Weight::from_parts(1, 0),
|
||||||
}));
|
}));
|
||||||
let sudo_unchecked_weight_call =
|
let sudo_unchecked_weight_call = SudoCall::sudo_unchecked_weight {
|
||||||
SudoCall::sudo_unchecked_weight { call, weight: Weight::from_parts(1_000, 0) };
|
call,
|
||||||
let info = sudo_unchecked_weight_call.get_dispatch_info();
|
weight: Weight::from_parts(1_000, 0),
|
||||||
assert_eq!(info.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]
|
#[test]
|
||||||
fn sudo_unchecked_weight_emits_events_correctly() {
|
fn sudo_unchecked_weight_emits_events_correctly() {
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
||||||
i: 42,
|
i: 42,
|
||||||
weight: Weight::from_parts(1, 0),
|
weight: Weight::from_parts(1, 0),
|
||||||
}));
|
}));
|
||||||
assert_ok!(Sudo::sudo_unchecked_weight(
|
assert_ok!(Sudo::sudo_unchecked_weight(
|
||||||
RuntimeOrigin::signed(1),
|
RuntimeOrigin::signed(1),
|
||||||
call,
|
call,
|
||||||
Weight::from_parts(1_000, 0)
|
Weight::from_parts(1_000, 0)
|
||||||
));
|
));
|
||||||
System::assert_has_event(TestEvent::Sudo(Event::Sudid { sudo_result: Ok(()) }));
|
System::assert_has_event(TestEvent::Sudo(Event::Sudid {
|
||||||
})
|
sudo_result: Ok(()),
|
||||||
|
}));
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[docify::export]
|
#[docify::export]
|
||||||
#[test]
|
#[test]
|
||||||
fn set_key_basics() {
|
fn set_key_basics() {
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
assert_ok!(Sudo::set_key(RuntimeOrigin::signed(1), 2));
|
assert_ok!(Sudo::set_key(RuntimeOrigin::signed(1), 2));
|
||||||
assert_eq!(Key::<Test>::get(), Some(2u64));
|
assert_eq!(Key::<Test>::get(), Some(2u64));
|
||||||
});
|
});
|
||||||
|
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
assert_noop!(Sudo::set_key(RuntimeOrigin::signed(2), 3), Error::<Test>::RequireSudo);
|
assert_noop!(
|
||||||
});
|
Sudo::set_key(RuntimeOrigin::signed(2), 3),
|
||||||
|
Error::<Test>::RequireSudo
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_key_emits_events_correctly() {
|
fn set_key_emits_events_correctly() {
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
assert_ok!(Sudo::set_key(RuntimeOrigin::signed(1), 2));
|
assert_ok!(Sudo::set_key(RuntimeOrigin::signed(1), 2));
|
||||||
System::assert_has_event(TestEvent::Sudo(Event::KeyChanged { old: Some(1), new: 2 }));
|
System::assert_has_event(TestEvent::Sudo(Event::KeyChanged {
|
||||||
assert_ok!(Sudo::set_key(RuntimeOrigin::signed(2), 4));
|
old: Some(1),
|
||||||
System::assert_has_event(TestEvent::Sudo(Event::KeyChanged { old: Some(2), new: 4 }));
|
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]
|
#[test]
|
||||||
fn remove_key_works() {
|
fn remove_key_works() {
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
assert_ok!(Sudo::remove_key(RuntimeOrigin::signed(1)));
|
assert_ok!(Sudo::remove_key(RuntimeOrigin::signed(1)));
|
||||||
assert!(Key::<Test>::get().is_none());
|
assert!(Key::<Test>::get().is_none());
|
||||||
System::assert_has_event(TestEvent::Sudo(Event::KeyRemoved {}));
|
System::assert_has_event(TestEvent::Sudo(Event::KeyRemoved {}));
|
||||||
|
|
||||||
assert_noop!(Sudo::remove_key(RuntimeOrigin::signed(1)), Error::<Test>::RequireSudo);
|
assert_noop!(
|
||||||
assert_noop!(Sudo::set_key(RuntimeOrigin::signed(1), 1), Error::<Test>::RequireSudo);
|
Sudo::remove_key(RuntimeOrigin::signed(1)),
|
||||||
});
|
Error::<Test>::RequireSudo
|
||||||
|
);
|
||||||
|
assert_noop!(
|
||||||
|
Sudo::set_key(RuntimeOrigin::signed(1), 1),
|
||||||
|
Error::<Test>::RequireSudo
|
||||||
|
);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn using_root_origin_works() {
|
fn using_root_origin_works() {
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
assert_ok!(Sudo::remove_key(RuntimeOrigin::root()));
|
assert_ok!(Sudo::remove_key(RuntimeOrigin::root()));
|
||||||
assert!(Key::<Test>::get().is_none());
|
assert!(Key::<Test>::get().is_none());
|
||||||
System::assert_has_event(TestEvent::Sudo(Event::KeyRemoved {}));
|
System::assert_has_event(TestEvent::Sudo(Event::KeyRemoved {}));
|
||||||
|
|
||||||
assert_ok!(Sudo::set_key(RuntimeOrigin::root(), 1));
|
assert_ok!(Sudo::set_key(RuntimeOrigin::root(), 1));
|
||||||
assert_eq!(Some(1), Key::<Test>::get());
|
assert_eq!(Some(1), Key::<Test>::get());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn sudo_as_basics() {
|
fn sudo_as_basics() {
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
let call = Box::new(RuntimeCall::Logger(LoggerCall::privileged_i32_log {
|
||||||
i: 42,
|
i: 42,
|
||||||
weight: Weight::from_parts(1_000, 0),
|
weight: Weight::from_parts(1_000, 0),
|
||||||
}));
|
}));
|
||||||
assert_ok!(Sudo::sudo_as(RuntimeOrigin::signed(1), 2, call));
|
assert_ok!(Sudo::sudo_as(RuntimeOrigin::signed(1), 2, call));
|
||||||
assert!(Logger::i32_log().is_empty());
|
assert!(Logger::i32_log().is_empty());
|
||||||
assert!(Logger::account_log().is_empty());
|
assert!(Logger::account_log().is_empty());
|
||||||
|
|
||||||
let call = Box::new(RuntimeCall::Logger(LoggerCall::non_privileged_log {
|
let call = Box::new(RuntimeCall::Logger(LoggerCall::non_privileged_log {
|
||||||
i: 42,
|
i: 42,
|
||||||
weight: Weight::from_parts(1, 0),
|
weight: Weight::from_parts(1, 0),
|
||||||
}));
|
}));
|
||||||
assert_noop!(Sudo::sudo_as(RuntimeOrigin::signed(3), 2, call), Error::<Test>::RequireSudo);
|
assert_noop!(
|
||||||
|
Sudo::sudo_as(RuntimeOrigin::signed(3), 2, call),
|
||||||
|
Error::<Test>::RequireSudo
|
||||||
|
);
|
||||||
|
|
||||||
let call = Box::new(RuntimeCall::Logger(LoggerCall::non_privileged_log {
|
let call = Box::new(RuntimeCall::Logger(LoggerCall::non_privileged_log {
|
||||||
i: 42,
|
i: 42,
|
||||||
weight: Weight::from_parts(1, 0),
|
weight: Weight::from_parts(1, 0),
|
||||||
}));
|
}));
|
||||||
assert_ok!(Sudo::sudo_as(RuntimeOrigin::signed(1), 2, call));
|
assert_ok!(Sudo::sudo_as(RuntimeOrigin::signed(1), 2, call));
|
||||||
assert_eq!(Logger::i32_log(), vec![42i32]);
|
assert_eq!(Logger::i32_log(), vec![42i32]);
|
||||||
assert_eq!(Logger::account_log(), vec![2]);
|
assert_eq!(Logger::account_log(), vec![2]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[docify::export]
|
#[docify::export]
|
||||||
#[test]
|
#[test]
|
||||||
fn sudo_as_emits_events_correctly() {
|
fn sudo_as_emits_events_correctly() {
|
||||||
new_test_ext(1).execute_with(|| {
|
new_test_ext(1).execute_with(|| {
|
||||||
let call = Box::new(RuntimeCall::Logger(LoggerCall::non_privileged_log {
|
let call = Box::new(RuntimeCall::Logger(LoggerCall::non_privileged_log {
|
||||||
i: 42,
|
i: 42,
|
||||||
weight: Weight::from_parts(1, 0),
|
weight: Weight::from_parts(1, 0),
|
||||||
}));
|
}));
|
||||||
assert_ok!(Sudo::sudo_as(RuntimeOrigin::signed(1), 2, call));
|
assert_ok!(Sudo::sudo_as(RuntimeOrigin::signed(1), 2, call));
|
||||||
System::assert_has_event(TestEvent::Sudo(Event::SudoAsDone { sudo_result: Ok(()) }));
|
System::assert_has_event(TestEvent::Sudo(Event::SudoAsDone {
|
||||||
});
|
sudo_result: Ok(()),
|
||||||
|
}));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,15 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use jsonrpsee::RpcModule;
|
use babe_primitives::BabeApi;
|
||||||
use primitives::{
|
use block_builder_api::BlockBuilder;
|
||||||
AccountId, Balance, Block, BlockNumber, Hash, Nonce,
|
use consensus_common::SelectChain;
|
||||||
};
|
|
||||||
use sc_client_api::AuxStore;
|
|
||||||
use grandpa::FinalityProofProvider;
|
use grandpa::FinalityProofProvider;
|
||||||
|
use jsonrpsee::RpcModule;
|
||||||
|
use primitives::{AccountId, Balance, Block, BlockNumber, Hash, Nonce};
|
||||||
|
use sc_client_api::AuxStore;
|
||||||
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;
|
||||||
|
|
||||||
@ -61,7 +59,16 @@ 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 { client, pool, select_chain, chain_spec, deny_unsafe, babe, grandpa, backend } : FullDeps<C, P, SC, B>,
|
FullDeps {
|
||||||
|
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>
|
||||||
@ -80,20 +87,19 @@ 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 frame_rpc_system::{System, SystemApiServer};
|
|
||||||
use pallet_transaction_payment_rpc::{
|
|
||||||
TransactionPayment, TransactionPaymentApiServer,
|
|
||||||
};
|
|
||||||
use babe_rpc::{Babe, BabeApiServer};
|
use babe_rpc::{Babe, BabeApiServer};
|
||||||
|
use frame_rpc_system::{System, SystemApiServer};
|
||||||
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::{
|
use substrate_state_trie_migration_rpc::{StateMigration, StateMigrationApiServer};
|
||||||
StateMigration, StateMigrationApiServer,
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut io = RpcModule::new(());
|
let mut io = RpcModule::new(());
|
||||||
let BabeDeps { babe_worker_handle, keystore } = babe;
|
let BabeDeps {
|
||||||
|
babe_worker_handle,
|
||||||
|
keystore,
|
||||||
|
} = babe;
|
||||||
let GrandpaDeps {
|
let GrandpaDeps {
|
||||||
shared_voter_state,
|
shared_voter_state,
|
||||||
shared_authority_set,
|
shared_authority_set,
|
||||||
@ -103,10 +109,13 @@ where
|
|||||||
} = grandpa;
|
} = grandpa;
|
||||||
|
|
||||||
let chain_name = chain_spec.name().to_string();
|
let chain_name = chain_spec.name().to_string();
|
||||||
let genesis_hash = client.hash(0).ok().flatten().expect("Genesis block exists; qed;");
|
let genesis_hash = client
|
||||||
|
.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())?;
|
||||||
@ -119,7 +128,8 @@ where
|
|||||||
keystore,
|
keystore,
|
||||||
select_chain,
|
select_chain,
|
||||||
deny_unsafe,
|
deny_unsafe,
|
||||||
).into_rpc()
|
)
|
||||||
|
.into_rpc(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
io.merge(
|
io.merge(
|
||||||
@ -129,7 +139,8 @@ where
|
|||||||
shared_voter_state,
|
shared_voter_state,
|
||||||
justification_stream,
|
justification_stream,
|
||||||
finality_provider,
|
finality_provider,
|
||||||
).into_rpc(),
|
)
|
||||||
|
.into_rpc(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
io.merge(
|
io.merge(
|
||||||
@ -137,8 +148,9 @@ 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)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "casper-runtime"
|
name = "casper-runtime"
|
||||||
version = "3.5.28"
|
version = "3.5.29"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
description = "Runtime of the Casper Network"
|
description = "Runtime of the Casper Network"
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
@ -10,15 +10,15 @@ pub mod currency {
|
|||||||
|
|
||||||
/// Constant values used within runtime.
|
/// Constant values used within runtime.
|
||||||
pub const FTSO: Balance = 1_000_000_000; // 10^9
|
pub const FTSO: Balance = 1_000_000_000; // 10^9
|
||||||
pub const STNK: Balance = 1_000 * FTSO; // 10^12
|
pub const STNK: Balance = 1_000 * FTSO; // 10^12
|
||||||
pub const STRH: Balance = 1_000 * STNK; // 10^15
|
pub const STRH: Balance = 1_000 * STNK; // 10^15
|
||||||
pub const CSPR: Balance = 1_000 * STRH; // 10^18
|
pub const CSPR: Balance = 1_000 * STRH; // 10^18
|
||||||
|
|
||||||
/// The existential deposit.
|
/// The existential deposit.
|
||||||
pub const EXISTENTIAL_DEPOSIT: Balance = STNK;
|
pub const EXISTENTIAL_DEPOSIT: Balance = STNK;
|
||||||
|
|
||||||
pub const fn deposit(items: u32, bytes: u32) -> Balance {
|
pub const fn deposit(items: u32, bytes: u32) -> Balance {
|
||||||
(items as Balance) * 200 * STRH + (bytes as Balance) * 1000 * STNK
|
(items as Balance) * 200 * STRH + (bytes as Balance) * 1000 * STNK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ pub mod fee {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{
|
use super::{
|
||||||
currency::{STNK, STRH, CSPR},
|
currency::{CSPR, STNK, STRH},
|
||||||
fee::WeightToFee,
|
fee::WeightToFee,
|
||||||
};
|
};
|
||||||
use crate::weights::ExtrinsicBaseWeight;
|
use crate::weights::ExtrinsicBaseWeight;
|
||||||
|
@ -37,43 +37,43 @@ use sp_core::parameter_types;
|
|||||||
use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight};
|
use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight};
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
/// Time to execute an empty block.
|
/// Time to execute an empty block.
|
||||||
/// Calculated by multiplying the *Average* with `1.0` and adding `0`.
|
/// Calculated by multiplying the *Average* with `1.0` and adding `0`.
|
||||||
///
|
///
|
||||||
/// Stats nanoseconds:
|
/// Stats nanoseconds:
|
||||||
/// Min, Max: 64_363_191, 66_078_314
|
/// Min, Max: 64_363_191, 66_078_314
|
||||||
/// Average: 64_551_214
|
/// Average: 64_551_214
|
||||||
/// Median: 64_500_078
|
/// Median: 64_500_078
|
||||||
/// Std-Dev: 229678.99
|
/// Std-Dev: 229678.99
|
||||||
///
|
///
|
||||||
/// Percentiles nanoseconds:
|
/// Percentiles nanoseconds:
|
||||||
/// 99th: 65_668_012
|
/// 99th: 65_668_012
|
||||||
/// 95th: 64_888_421
|
/// 95th: 64_888_421
|
||||||
/// 75th: 64_563_448
|
/// 75th: 64_563_448
|
||||||
pub const BlockExecutionWeight: Weight =
|
pub const BlockExecutionWeight: Weight =
|
||||||
Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(64_551_214), 0);
|
Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(64_551_214), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_weights {
|
mod test_weights {
|
||||||
use sp_weights::constants;
|
use sp_weights::constants;
|
||||||
|
|
||||||
/// Checks that the weight exists and is sane.
|
/// Checks that the weight exists and is sane.
|
||||||
// NOTE: If this test fails but you are sure that the generated values are fine,
|
// NOTE: If this test fails but you are sure that the generated values are fine,
|
||||||
// you can delete it.
|
// you can delete it.
|
||||||
#[test]
|
#[test]
|
||||||
fn sane() {
|
fn sane() {
|
||||||
let w = super::BlockExecutionWeight::get();
|
let w = super::BlockExecutionWeight::get();
|
||||||
|
|
||||||
// At least 100 µs.
|
// At least 100 µs.
|
||||||
assert!(
|
assert!(
|
||||||
w.ref_time() >= 100u64 * constants::WEIGHT_REF_TIME_PER_MICROS,
|
w.ref_time() >= 100u64 * constants::WEIGHT_REF_TIME_PER_MICROS,
|
||||||
"Weight should be at least 100 µs."
|
"Weight should be at least 100 µs."
|
||||||
);
|
);
|
||||||
// At most 50 ms.
|
// At most 50 ms.
|
||||||
assert!(
|
assert!(
|
||||||
w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS,
|
w.ref_time() <= 50u64 * constants::WEIGHT_REF_TIME_PER_MILLIS,
|
||||||
"Weight should be at most 50 ms."
|
"Weight should be at most 50 ms."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,43 +37,43 @@ use sp_core::parameter_types;
|
|||||||
use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight};
|
use sp_weights::{constants::WEIGHT_REF_TIME_PER_NANOS, Weight};
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
/// Time to execute a NO-OP extrinsic, for example `System::remark`.
|
/// Time to execute a NO-OP extrinsic, for example `System::remark`.
|
||||||
/// Calculated by multiplying the *Average* with `1.0` and adding `0`.
|
/// Calculated by multiplying the *Average* with `1.0` and adding `0`.
|
||||||
///
|
///
|
||||||
/// Stats nanoseconds:
|
/// Stats nanoseconds:
|
||||||
/// Min, Max: 402_868, 1_292_427
|
/// Min, Max: 402_868, 1_292_427
|
||||||
/// Average: 565_926
|
/// Average: 565_926
|
||||||
/// Median: 414_626
|
/// Median: 414_626
|
||||||
/// Std-Dev: 283192.19
|
/// Std-Dev: 283192.19
|
||||||
///
|
///
|
||||||
/// Percentiles nanoseconds:
|
/// Percentiles nanoseconds:
|
||||||
/// 99th: 1_251_123
|
/// 99th: 1_251_123
|
||||||
/// 95th: 1_196_903
|
/// 95th: 1_196_903
|
||||||
/// 75th: 491_329
|
/// 75th: 491_329
|
||||||
pub const ExtrinsicBaseWeight: Weight =
|
pub const ExtrinsicBaseWeight: Weight =
|
||||||
Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(565_926), 0);
|
Weight::from_parts(WEIGHT_REF_TIME_PER_NANOS.saturating_mul(565_926), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_weights {
|
mod test_weights {
|
||||||
use sp_weights::constants;
|
use sp_weights::constants;
|
||||||
|
|
||||||
/// Checks that the weight exists and is sane.
|
/// Checks that the weight exists and is sane.
|
||||||
// NOTE: If this test fails but you are sure that the generated values are fine,
|
// NOTE: If this test fails but you are sure that the generated values are fine,
|
||||||
// you can delete it.
|
// you can delete it.
|
||||||
#[test]
|
#[test]
|
||||||
fn sane() {
|
fn sane() {
|
||||||
let w = super::ExtrinsicBaseWeight::get();
|
let w = super::ExtrinsicBaseWeight::get();
|
||||||
|
|
||||||
// At least 10 µs.
|
// At least 10 µs.
|
||||||
assert!(
|
assert!(
|
||||||
w.ref_time() >= 10u64 * constants::WEIGHT_REF_TIME_PER_MICROS,
|
w.ref_time() >= 10u64 * constants::WEIGHT_REF_TIME_PER_MICROS,
|
||||||
"Weight should be at least 10 µs."
|
"Weight should be at least 10 µs."
|
||||||
);
|
);
|
||||||
// At most 1 ms.
|
// At most 1 ms.
|
||||||
assert!(
|
assert!(
|
||||||
w.ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
|
w.ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
|
||||||
"Weight should be at most 1 ms."
|
"Weight should be at most 1 ms."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
pub mod block_weights;
|
pub mod block_weights;
|
||||||
pub mod extrinsic_weights;
|
pub mod extrinsic_weights;
|
||||||
pub mod rocksdb_weights;
|
|
||||||
pub mod paritydb_weights;
|
pub mod paritydb_weights;
|
||||||
|
pub mod rocksdb_weights;
|
||||||
|
|
||||||
pub use block_weights::BlockExecutionWeight;
|
pub use block_weights::BlockExecutionWeight;
|
||||||
pub use extrinsic_weights::ExtrinsicBaseWeight;
|
pub use extrinsic_weights::ExtrinsicBaseWeight;
|
||||||
pub use rocksdb_weights::constants::RocksDbWeight;
|
|
||||||
pub use paritydb_weights::constants::ParityDbWeight;
|
pub use paritydb_weights::constants::ParityDbWeight;
|
||||||
|
pub use rocksdb_weights::constants::RocksDbWeight;
|
||||||
|
@ -37,47 +37,47 @@
|
|||||||
|
|
||||||
/// Storage DB weights for the `Development` runtime and `ParityDb`.
|
/// Storage DB weights for the `Development` runtime and `ParityDb`.
|
||||||
pub mod constants {
|
pub mod constants {
|
||||||
use frame_support::weights::constants;
|
use frame_support::weights::constants;
|
||||||
use sp_core::parameter_types;
|
use sp_core::parameter_types;
|
||||||
use sp_weights::RuntimeDbWeight;
|
use sp_weights::RuntimeDbWeight;
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
/// `ParityDB` can be enabled with a feature flag, but is still experimental. These weights
|
/// `ParityDB` can be enabled with a feature flag, but is still experimental. These weights
|
||||||
/// are available for brave runtime engineers who may want to try this out as default.
|
/// are available for brave runtime engineers who may want to try this out as default.
|
||||||
pub const ParityDbWeight: RuntimeDbWeight = RuntimeDbWeight {
|
pub const ParityDbWeight: RuntimeDbWeight = RuntimeDbWeight {
|
||||||
read: 40_820 * constants::WEIGHT_REF_TIME_PER_NANOS,
|
read: 40_820 * constants::WEIGHT_REF_TIME_PER_NANOS,
|
||||||
write: 293_659 * constants::WEIGHT_REF_TIME_PER_NANOS,
|
write: 293_659 * constants::WEIGHT_REF_TIME_PER_NANOS,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_db_weights {
|
mod test_db_weights {
|
||||||
use super::constants::ParityDbWeight as W;
|
use super::constants::ParityDbWeight as W;
|
||||||
use sp_weights::constants;
|
use sp_weights::constants;
|
||||||
|
|
||||||
/// Checks that all weights exist and have sane values.
|
/// Checks that all weights exist and have sane values.
|
||||||
// NOTE: If this test fails but you are sure that the generated values are fine,
|
// NOTE: If this test fails but you are sure that the generated values are fine,
|
||||||
// you can delete it.
|
// you can delete it.
|
||||||
#[test]
|
#[test]
|
||||||
fn bound() {
|
fn bound() {
|
||||||
// At least 1 µs.
|
// At least 1 µs.
|
||||||
assert!(
|
assert!(
|
||||||
W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS,
|
W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS,
|
||||||
"Read weight should be at least 1 µs."
|
"Read weight should be at least 1 µs."
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS,
|
W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS,
|
||||||
"Write weight should be at least 1 µs."
|
"Write weight should be at least 1 µs."
|
||||||
);
|
);
|
||||||
// At most 1 ms.
|
// At most 1 ms.
|
||||||
assert!(
|
assert!(
|
||||||
W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
|
W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
|
||||||
"Read weight should be at most 1 ms."
|
"Read weight should be at most 1 ms."
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
|
W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
|
||||||
"Write weight should be at most 1 ms."
|
"Write weight should be at most 1 ms."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,47 +36,47 @@
|
|||||||
|
|
||||||
/// Storage DB weights for the `Development` runtime and `RocksDb`.
|
/// Storage DB weights for the `Development` runtime and `RocksDb`.
|
||||||
pub mod constants {
|
pub mod constants {
|
||||||
use frame_support::weights::constants;
|
use frame_support::weights::constants;
|
||||||
use sp_core::parameter_types;
|
use sp_core::parameter_types;
|
||||||
use sp_weights::RuntimeDbWeight;
|
use sp_weights::RuntimeDbWeight;
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
/// By default, Substrate uses `RocksDB`, so this will be the weight used throughout
|
/// By default, Substrate uses `RocksDB`, so this will be the weight used throughout
|
||||||
/// the runtime.
|
/// the runtime.
|
||||||
pub const RocksDbWeight: RuntimeDbWeight = RuntimeDbWeight {
|
pub const RocksDbWeight: RuntimeDbWeight = RuntimeDbWeight {
|
||||||
read: 31_627 * constants::WEIGHT_REF_TIME_PER_NANOS,
|
read: 31_627 * constants::WEIGHT_REF_TIME_PER_NANOS,
|
||||||
write: 412_279 * constants::WEIGHT_REF_TIME_PER_NANOS,
|
write: 412_279 * constants::WEIGHT_REF_TIME_PER_NANOS,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test_db_weights {
|
mod test_db_weights {
|
||||||
use super::constants::RocksDbWeight as W;
|
use super::constants::RocksDbWeight as W;
|
||||||
use sp_weights::constants;
|
use sp_weights::constants;
|
||||||
|
|
||||||
/// Checks that all weights exist and have sane values.
|
/// Checks that all weights exist and have sane values.
|
||||||
// NOTE: If this test fails but you are sure that the generated values are fine,
|
// NOTE: If this test fails but you are sure that the generated values are fine,
|
||||||
// you can delete it.
|
// you can delete it.
|
||||||
#[test]
|
#[test]
|
||||||
fn bound() {
|
fn bound() {
|
||||||
// At least 1 µs.
|
// At least 1 µs.
|
||||||
assert!(
|
assert!(
|
||||||
W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS,
|
W::get().reads(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS,
|
||||||
"Read weight should be at least 1 µs."
|
"Read weight should be at least 1 µs."
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS,
|
W::get().writes(1).ref_time() >= constants::WEIGHT_REF_TIME_PER_MICROS,
|
||||||
"Write weight should be at least 1 µs."
|
"Write weight should be at least 1 µs."
|
||||||
);
|
);
|
||||||
// At most 1 ms.
|
// At most 1 ms.
|
||||||
assert!(
|
assert!(
|
||||||
W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
|
W::get().reads(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
|
||||||
"Read weight should be at most 1 ms."
|
"Read weight should be at most 1 ms."
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
|
W::get().writes(1).ref_time() <= constants::WEIGHT_REF_TIME_PER_MILLIS,
|
||||||
"Write weight should be at most 1 ms."
|
"Write weight should be at most 1 ms."
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
//! 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
|
||||||
@ -19,204 +18,204 @@ pub const CONSTANT_RATIO: f64 = 1.1717610304252650;
|
|||||||
|
|
||||||
/// Upper thresholds delimiting the bag list.
|
/// Upper thresholds delimiting the bag list.
|
||||||
pub const THRESHOLDS: [u64; 200] = [
|
pub const THRESHOLDS: [u64; 200] = [
|
||||||
368_934,
|
368_934,
|
||||||
432_302,
|
432_302,
|
||||||
506_555,
|
506_555,
|
||||||
593_561,
|
593_561,
|
||||||
695_512,
|
695_512,
|
||||||
814_974,
|
814_974,
|
||||||
954_955,
|
954_955,
|
||||||
1_118_979,
|
1_118_979,
|
||||||
1_311_176,
|
1_311_176,
|
||||||
1_536_385,
|
1_536_385,
|
||||||
1_800_276,
|
1_800_276,
|
||||||
2_109_493,
|
2_109_493,
|
||||||
2_471_822,
|
2_471_822,
|
||||||
2_896_385,
|
2_896_385,
|
||||||
3_393_871,
|
3_393_871,
|
||||||
3_976_806,
|
3_976_806,
|
||||||
4_659_866,
|
4_659_866,
|
||||||
5_460_249,
|
5_460_249,
|
||||||
6_398_107,
|
6_398_107,
|
||||||
7_497_052,
|
7_497_052,
|
||||||
8_784_753,
|
8_784_753,
|
||||||
10_293_631,
|
10_293_631,
|
||||||
12_061_676,
|
12_061_676,
|
||||||
14_133_402,
|
14_133_402,
|
||||||
16_560_970,
|
16_560_970,
|
||||||
19_405_499,
|
19_405_499,
|
||||||
22_738_608,
|
22_738_608,
|
||||||
26_644_215,
|
26_644_215,
|
||||||
31_220_653,
|
31_220_653,
|
||||||
36_583_145,
|
36_583_145,
|
||||||
42_866_704,
|
42_866_704,
|
||||||
50_229_533,
|
50_229_533,
|
||||||
58_857_009,
|
58_857_009,
|
||||||
68_966_350,
|
68_966_350,
|
||||||
80_812_081,
|
80_812_081,
|
||||||
94_692_447,
|
94_692_447,
|
||||||
110_956_919,
|
110_956_919,
|
||||||
130_014_994,
|
130_014_994,
|
||||||
152_346_503,
|
152_346_503,
|
||||||
178_513_695,
|
178_513_695,
|
||||||
209_175_391,
|
209_175_391,
|
||||||
245_103_572,
|
245_103_572,
|
||||||
287_202_814,
|
287_202_814,
|
||||||
336_533_065,
|
336_533_065,
|
||||||
394_336_331,
|
394_336_331,
|
||||||
462_067_946,
|
462_067_946,
|
||||||
541_433_213,
|
541_433_213,
|
||||||
634_430_340,
|
634_430_340,
|
||||||
743_400_749,
|
743_400_749,
|
||||||
871_088_028,
|
871_088_028,
|
||||||
1_020_707_005,
|
1_020_707_005,
|
||||||
1_196_024_692,
|
1_196_024_692,
|
||||||
1_401_455_126,
|
1_401_455_126,
|
||||||
1_642_170_503,
|
1_642_170_503,
|
||||||
1_924_231_401,
|
1_924_231_401,
|
||||||
2_254_739_369,
|
2_254_739_369,
|
||||||
2_642_015_726,
|
2_642_015_726,
|
||||||
3_095_811_069,
|
3_095_811_069,
|
||||||
3_627_550_768,
|
3_627_550_768,
|
||||||
4_250_622_626,
|
4_250_622_626,
|
||||||
4_980_713_948,
|
4_980_713_948,
|
||||||
5_836_206_508,
|
5_836_206_508,
|
||||||
6_838_639_352,
|
6_838_639_352,
|
||||||
8_013_251_094,
|
8_013_251_094,
|
||||||
9_389_615_359,
|
9_389_615_359,
|
||||||
11_002_385_368,
|
11_002_385_368,
|
||||||
12_892_166_416,
|
12_892_166_416,
|
||||||
15_106_538_204,
|
15_106_538_204,
|
||||||
17_701_252_772,
|
17_701_252_772,
|
||||||
20_741_638_188,
|
20_741_638_188,
|
||||||
24_304_243_336,
|
24_304_243_336,
|
||||||
28_478_765_215,
|
28_478_765_215,
|
||||||
33_370_307_274,
|
33_370_307_274,
|
||||||
39_102_025_637,
|
39_102_025_637,
|
||||||
45_818_229_852,
|
45_818_229_852,
|
||||||
53_688_016_224,
|
53_688_016_224,
|
||||||
62_909_525_212,
|
62_909_525_212,
|
||||||
73_714_930_086,
|
73_714_930_086,
|
||||||
86_376_282_435,
|
86_376_282_435,
|
||||||
101_212_361_710,
|
101_212_361_710,
|
||||||
118_596_701_249,
|
118_596_701_249,
|
||||||
138_966_992_861,
|
138_966_992_861,
|
||||||
162_836_106_750,
|
162_836_106_750,
|
||||||
190_805_004_236,
|
190_805_004_236,
|
||||||
223_577_868_374,
|
223_577_868_374,
|
||||||
261_979_833_426,
|
261_979_833_426,
|
||||||
306_977_759_566,
|
306_977_759_566,
|
||||||
359_704_575_867,
|
359_704_575_867,
|
||||||
421_487_804_467,
|
421_487_804_467,
|
||||||
493_882_984_074,
|
493_882_984_074,
|
||||||
578_712_834_328,
|
578_712_834_328,
|
||||||
678_113_147_073,
|
678_113_147_073,
|
||||||
794_586_559_959,
|
794_586_559_959,
|
||||||
931_065_566_260,
|
931_065_566_260,
|
||||||
1_090_986_347_314,
|
1_090_986_347_314,
|
||||||
1_278_375_286_509,
|
1_278_375_286_509,
|
||||||
1_497_950_342_990,
|
1_497_950_342_990,
|
||||||
1_755_239_837_428,
|
1_755_239_837_428,
|
||||||
2_056_721_640_548,
|
2_056_721_640_548,
|
||||||
2_409_986_268_826,
|
2_409_986_268_826,
|
||||||
2_823_927_993_670,
|
2_823_927_993_670,
|
||||||
3_308_968_775_710,
|
3_308_968_775_710,
|
||||||
3_877_320_662_271,
|
3_877_320_662_271,
|
||||||
4_543_293_254_512,
|
4_543_293_254_512,
|
||||||
5_323_653_985_431,
|
5_323_653_985_431,
|
||||||
6_238_050_279_596,
|
6_238_050_279_596,
|
||||||
7_309_504_223_464,
|
7_309_504_223_464,
|
||||||
8_564_992_200_784,
|
8_564_992_200_784,
|
||||||
10_036_124_086_775,
|
10_036_124_086_775,
|
||||||
11_759_939_101_395,
|
11_759_939_101_395,
|
||||||
13_779_838_359_189,
|
13_779_838_359_189,
|
||||||
16_146_677_594_857,
|
16_146_677_594_857,
|
||||||
18_920_047_576_494,
|
18_920_047_576_494,
|
||||||
22_169_774_443_928,
|
22_169_774_443_928,
|
||||||
25_977_677_746_713,
|
25_977_677_746_713,
|
||||||
30_439_630_444_544,
|
30_439_630_444_544,
|
||||||
35_667_972_735_463,
|
35_667_972_735_463,
|
||||||
41_794_340_485_686,
|
41_794_340_485_686,
|
||||||
48_972_979_473_452,
|
48_972_979_473_452,
|
||||||
57_384_628_890_807,
|
57_384_628_890_807,
|
||||||
67_241_071_879_663,
|
67_241_071_879_663,
|
||||||
78_790_467_672_613,
|
78_790_467_672_613,
|
||||||
92_323_599_587_750,
|
92_323_599_587_750,
|
||||||
108_181_196_185_512,
|
108_181_196_185_512,
|
||||||
126_762_509_914_973,
|
126_762_509_914_973,
|
||||||
148_535_369_237_262,
|
148_535_369_237_262,
|
||||||
174_047_957_312_051,
|
174_047_957_312_051,
|
||||||
203_942_613_803_381,
|
203_942_613_803_381,
|
||||||
238_972_007_297_872,
|
238_972_007_297_872,
|
||||||
280_018_085_514_148,
|
280_018_085_514_148,
|
||||||
328_114_280_419_768,
|
328_114_280_419_768,
|
||||||
384_471_527_321_912,
|
384_471_527_321_912,
|
||||||
450_508_753_023_899,
|
450_508_753_023_899,
|
||||||
527_888_600_658_885,
|
527_888_600_658_885,
|
||||||
618_559_290_657_806,
|
618_559_290_657_806,
|
||||||
724_803_671_800_312,
|
724_803_671_800_312,
|
||||||
849_296_697_324_749,
|
849_296_697_324_749,
|
||||||
995_172_773_194_022,
|
995_172_773_194_022,
|
||||||
1_166_104_674_168_996,
|
1_166_104_674_168_996,
|
||||||
1_366_396_014_587_981,
|
1_366_396_014_587_981,
|
||||||
1_601_089_602_022_588,
|
1_601_089_602_022_588,
|
||||||
1_876_094_401_869_165,
|
1_876_094_401_869_165,
|
||||||
2_198_334_309_509_284,
|
2_198_334_309_509_284,
|
||||||
2_575_922_475_729_812,
|
2_575_922_475_729_812,
|
||||||
3_018_365_574_456_765,
|
3_018_365_574_456_765,
|
||||||
3_536_803_155_725_606,
|
3_536_803_155_725_606,
|
||||||
4_144_288_110_164_365,
|
4_144_288_110_164_365,
|
||||||
4_856_115_306_345_371,
|
4_856_115_306_345_371,
|
||||||
5_690_206_675_227_153,
|
5_690_206_675_227_153,
|
||||||
6_667_562_437_096_890,
|
6_667_562_437_096_890,
|
||||||
7_812_789_831_717_443,
|
7_812_789_831_717_443,
|
||||||
9_154_722_663_709_264,
|
9_154_722_663_709_264,
|
||||||
10_727_147_261_685_494,
|
10_727_147_261_685_494,
|
||||||
12_569_653_128_876_154,
|
12_569_653_128_876_154,
|
||||||
14_728_629_702_380_078,
|
14_728_629_702_380_078,
|
||||||
17_258_434_316_813_044,
|
17_258_434_316_813_044,
|
||||||
20_222_760_778_595_608,
|
20_222_760_778_595_608,
|
||||||
23_696_243_007_970_824,
|
23_696_243_007_970_824,
|
||||||
27_766_334_124_227_376,
|
27_766_334_124_227_376,
|
||||||
32_535_508_284_536_868,
|
32_535_508_284_536_868,
|
||||||
38_123_840_712_898_664,
|
38_123_840_712_898_664,
|
||||||
44_672_030_877_514_808,
|
44_672_030_877_514_808,
|
||||||
52_344_944_932_226_008,
|
52_344_944_932_226_008,
|
||||||
61_335_766_611_338_904,
|
61_335_766_611_338_904,
|
||||||
71_870_861_086_426_040,
|
71_870_861_086_426_040,
|
||||||
84_215_474_244_181_664,
|
84_215_474_244_181_664,
|
||||||
98_680_410_878_114_672,
|
98_680_410_878_114_672,
|
||||||
115_629_859_933_328_176,
|
115_629_859_933_328_176,
|
||||||
135_490_563_823_405_696,
|
135_490_563_823_405_696,
|
||||||
158_762_562_678_613_984,
|
158_762_562_678_613_984,
|
||||||
186_031_784_037_248_448,
|
186_031_784_037_248_448,
|
||||||
217_984_794_955_336_608,
|
217_984_794_955_336_608,
|
||||||
255_426_087_953_905_344,
|
255_426_087_953_905_344,
|
||||||
299_298_336_018_362_496,
|
299_298_336_018_362_496,
|
||||||
350_706_126_617_443_648,
|
350_706_126_617_443_648,
|
||||||
410_943_772_301_709_248,
|
410_943_772_301_709_248,
|
||||||
481_527_898_079_096_320,
|
481_527_898_079_096_320,
|
||||||
564_235_626_031_673_920,
|
564_235_626_031_673_920,
|
||||||
661_149_318_561_518_720,
|
661_149_318_561_518_720,
|
||||||
774_709_006_782_606_976,
|
774_709_006_782_606_976,
|
||||||
907_773_824_067_321_216,
|
907_773_824_067_321_216,
|
||||||
1_063_693_991_482_207_616,
|
1_063_693_991_482_207_616,
|
||||||
1_246_395_167_516_354_560,
|
1_246_395_167_516_354_560,
|
||||||
1_460_477_285_806_034_432,
|
1_460_477_285_806_034_432,
|
||||||
1_711_330_369_328_773_120,
|
1_711_330_369_328_773_120,
|
||||||
2_005_270_236_962_732_544,
|
2_005_270_236_962_732_544,
|
||||||
2_349_697_519_144_566_784,
|
2_349_697_519_144_566_784,
|
||||||
2_753_283_986_220_526_592,
|
2_753_283_986_220_526_592,
|
||||||
3_226_190_880_747_145_216,
|
3_226_190_880_747_145_216,
|
||||||
3_780_324_750_772_868_096,
|
3_780_324_750_772_868_096,
|
||||||
4_429_637_225_307_749_376,
|
4_429_637_225_307_749_376,
|
||||||
5_190_476_279_536_719_872,
|
5_190_476_279_536_719_872,
|
||||||
6_081_997_833_707_842_560,
|
6_081_997_833_707_842_560,
|
||||||
7_126_648_048_669_730_816,
|
7_126_648_048_669_730_816,
|
||||||
8_350_728_460_987_448_320,
|
8_350_728_460_987_448_320,
|
||||||
9_785_058_186_248_239_104,
|
9_785_058_186_248_239_104,
|
||||||
11_465_749_863_089_412_096,
|
11_465_749_863_089_412_096,
|
||||||
13_435_118_874_171_990_016,
|
13_435_118_874_171_990_016,
|
||||||
15_742_748_735_885_697_024,
|
15_742_748_735_885_697_024,
|
||||||
18_446_744_073_709_551_615,
|
18_446_744_073_709_551_615,
|
||||||
];
|
];
|
||||||
|
@ -2,25 +2,34 @@ use super::*;
|
|||||||
use frame_support::{
|
use frame_support::{
|
||||||
parameter_types,
|
parameter_types,
|
||||||
traits::{
|
traits::{
|
||||||
EitherOf, EitherOfDiverse, MapSuccess, OriginTrait, TryWithMorphedArg,
|
tokens::pay::PayFromAccount, EitherOf, EitherOfDiverse, MapSuccess, OriginTrait,
|
||||||
tokens::pay::PayFromAccount,
|
TryWithMorphedArg,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
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, RuntimeEvent, Scheduler, DAYS, CSPR, AccountId, Balance,
|
RuntimeCall,
|
||||||
TreasuryAccount, Balances, Preimage, Runtime,
|
RuntimeEvent,
|
||||||
|
Scheduler,
|
||||||
|
TreasuryAccount,
|
||||||
|
CSPR,
|
||||||
|
DAYS,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod origins;
|
mod origins;
|
||||||
pub use origins::{
|
pub use origins::{
|
||||||
pallet_cult_origins, Geniuses, Degens, Zombies, Skeletons, Ghosts,
|
pallet_cult_origins, CultTreasurySpender, Degens, EnsureCanPromoteTo, EnsureCanRetainAt,
|
||||||
EnsureCanRetainAt, EnsureCanPromoteTo, EnsureCult, ToVoice, CultTreasurySpender,
|
EnsureCult, Geniuses, Ghosts, Skeletons, ToVoice, Zombies,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod tracks;
|
mod tracks;
|
||||||
@ -45,14 +54,10 @@ 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 = EitherOfDiverse<
|
type WhitelistOrigin =
|
||||||
EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>,
|
EitherOfDiverse<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Skeletons>;
|
||||||
Skeletons,
|
type DispatchWhitelistedOrigin =
|
||||||
>;
|
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>;
|
||||||
}
|
}
|
||||||
@ -81,7 +86,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;
|
||||||
@ -135,10 +140,13 @@ 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 = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, Skeletons>;
|
type ParamsOrigin =
|
||||||
|
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 = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, EnsureCanRetainAt>;
|
type ApproveOrigin =
|
||||||
type PromoteOrigin = EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, EnsureCanPromoteTo>;
|
EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, EnsureCanRetainAt>;
|
||||||
|
type PromoteOrigin =
|
||||||
|
EitherOf<EnsureRootWithSuccess<Self::AccountId, ConstU16<65535>>, EnsureCanPromoteTo>;
|
||||||
|
|
||||||
type EvidenceSize = ConstU32<65536>;
|
type EvidenceSize = ConstU32<65536>;
|
||||||
}
|
}
|
||||||
|
@ -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 crate::{Balance, CSPR};
|
|
||||||
use super::ranks;
|
use super::ranks;
|
||||||
|
use crate::{Balance, CSPR};
|
||||||
use frame_support::pallet_prelude::*;
|
use frame_support::pallet_prelude::*;
|
||||||
use pallet_ranked_collective::Rank;
|
use pallet_ranked_collective::Rank;
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::{Balance, BlockNumber, RuntimeOrigin, DAYS, CSPR, HOURS, MINUTES};
|
use crate::{Balance, BlockNumber, RuntimeOrigin, CSPR, DAYS, 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,7 +255,6 @@ 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 {
|
||||||
@ -347,7 +346,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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 primitives::{AccountId, AccountPublic};
|
|
||||||
use casper_runtime_constants::currency::CSPR;
|
use casper_runtime_constants::currency::CSPR;
|
||||||
|
use primitives::{AccountId, AccountPublic};
|
||||||
|
|
||||||
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::vec::Vec;
|
|
||||||
use sp_std::prelude::*;
|
use sp_std::prelude::*;
|
||||||
use sp_core::{sr25519, Pair, Public};
|
use sp_std::vec::Vec;
|
||||||
use sp_runtime::{Perbill, traits::IdentifyAccount};
|
|
||||||
|
|
||||||
#[derive(Encode, Clone)]
|
#[derive(Encode, Clone)]
|
||||||
struct PreparedNetworkData {
|
struct PreparedNetworkData {
|
||||||
@ -84,40 +84,69 @@ 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 {
|
(
|
||||||
chain_name: "ethereum-mainnet".into(),
|
1,
|
||||||
default_endpoint: "https://nd-422-757-666.p2pify.com/0a9d79d93fb2f4a4b1e04695da2b77a7/".into(),
|
PreparedNetworkData {
|
||||||
finality_delay: Some(40),
|
chain_name: "ethereum-mainnet".into(),
|
||||||
release_delay: Some(80),
|
default_endpoint:
|
||||||
network_type: Default::default(),
|
"https://nd-422-757-666.p2pify.com/0a9d79d93fb2f4a4b1e04695da2b77a7/".into(),
|
||||||
gatekeeper: "0x4d224452801aced8b2f0aebe155379bb5d594381".into(),
|
finality_delay: Some(40),
|
||||||
topic_name: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef".into(),
|
release_delay: Some(80),
|
||||||
incoming_fee: 0,
|
network_type: Default::default(),
|
||||||
outgoing_fee: 0,
|
gatekeeper: "0x4d224452801aced8b2f0aebe155379bb5d594381".into(),
|
||||||
}.encode()),
|
topic_name: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
|
||||||
(56, PreparedNetworkData {
|
.into(),
|
||||||
chain_name: "bnb-mainnet".into(),
|
incoming_fee: 0,
|
||||||
default_endpoint: "https://bsc-mainnet.core.chainstack.com/35848e183f3e3303c8cfeacbea831cab/".into(),
|
outgoing_fee: 0,
|
||||||
finality_delay: Some(20),
|
}
|
||||||
release_delay: Some(40),
|
.encode(),
|
||||||
network_type: Default::default(),
|
),
|
||||||
gatekeeper: "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82".into(),
|
(
|
||||||
topic_name: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef".into(),
|
56,
|
||||||
incoming_fee: 0,
|
PreparedNetworkData {
|
||||||
outgoing_fee: 0,
|
chain_name: "bnb-mainnet".into(),
|
||||||
}.encode())
|
default_endpoint:
|
||||||
|
"https://bsc-mainnet.core.chainstack.com/35848e183f3e3303c8cfeacbea831cab/"
|
||||||
|
.into(),
|
||||||
|
finality_delay: Some(20),
|
||||||
|
release_delay: Some(40),
|
||||||
|
network_type: Default::default(),
|
||||||
|
gatekeeper: "0x0E09FaBB73Bd3Ade0a17ECC321fD13a19e81cE82".into(),
|
||||||
|
topic_name: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
|
||||||
|
.into(),
|
||||||
|
incoming_fee: 0,
|
||||||
|
outgoing_fee: 0,
|
||||||
|
}
|
||||||
|
.encode(),
|
||||||
|
),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,7 +156,12 @@ fn casper_session_keys(
|
|||||||
authority_discovery: AuthorityDiscoveryId,
|
authority_discovery: AuthorityDiscoveryId,
|
||||||
slow_clap: SlowClapId,
|
slow_clap: SlowClapId,
|
||||||
) -> SessionKeys {
|
) -> SessionKeys {
|
||||||
SessionKeys { babe, grandpa, authority_discovery, slow_clap }
|
SessionKeys {
|
||||||
|
babe,
|
||||||
|
grandpa,
|
||||||
|
authority_discovery,
|
||||||
|
slow_clap,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testnet_config_genesis(
|
fn testnet_config_genesis(
|
||||||
@ -143,8 +177,7 @@ 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> =
|
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(casper_testnet_accounts);
|
||||||
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);
|
||||||
@ -218,7 +251,9 @@ 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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +264,9 @@ 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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -240,9 +277,11 @@ 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(serde_json::to_string(&patch)
|
Some(
|
||||||
.expect("serialization to json is expected to work; qed")
|
serde_json::to_string(&patch)
|
||||||
.into_bytes())
|
.expect("serialization to json is expected to work; qed")
|
||||||
|
.into_bytes(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a list of identifiers for available builtin `RuntimeGenesisConfig` presets.
|
/// Returns a list of identifiers for available builtin `RuntimeGenesisConfig` presets.
|
||||||
|
@ -1,8 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use frame_support::{
|
use frame_support::{dispatch::DispatchResultWithPostInfo, traits::PrivilegeCmp};
|
||||||
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};
|
||||||
@ -14,7 +11,8 @@ 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>> for AllianceProposalProvider<T, I>
|
impl<T, I> ProposalProvider<AccountIdOf<T>, HashOf<T>, ProposalOf<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,
|
||||||
@ -25,7 +23,12 @@ 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(who, threshold, proposal, length_bound)
|
pallet_collective::Pallet::<T, I>::do_propose_proposed(
|
||||||
|
who,
|
||||||
|
threshold,
|
||||||
|
proposal,
|
||||||
|
length_bound,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vote_proposal(
|
fn vote_proposal(
|
||||||
@ -61,7 +64,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) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghost-runtime-common"
|
name = "ghost-runtime-common"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
homepage.workspace = true
|
homepage.workspace = true
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
use primitives::{AccountId, Balance};
|
|
||||||
use pallet_treasury::ArgumentsFactory;
|
|
||||||
use sp_core::crypto::FromEntropy;
|
|
||||||
use frame_support::traits::tokens::{Pay, PaymentStatus};
|
use frame_support::traits::tokens::{Pay, PaymentStatus};
|
||||||
|
use pallet_treasury::ArgumentsFactory;
|
||||||
|
use primitives::{AccountId, Balance};
|
||||||
|
use sp_core::crypto::FromEntropy;
|
||||||
|
|
||||||
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()
|
||||||
}
|
}
|
||||||
@ -19,8 +21,16 @@ impl Pay for BenchmarkTreasuryPaymaster {
|
|||||||
type AssetKind = ();
|
type AssetKind = ();
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn pay(_: &Self::Beneficiary, _: Self::AssetKind, _: Self::Balance) -> Result<Self::Id, Self::Error> { Ok(()) }
|
fn pay(
|
||||||
fn check_payment(_: Self::Id) -> PaymentStatus { PaymentStatus::Success }
|
_: &Self::Beneficiary,
|
||||||
|
_: 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) {}
|
||||||
}
|
}
|
||||||
|
@ -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},
|
||||||
Perbill, BuildStorage,
|
BuildStorage, Perbill,
|
||||||
};
|
};
|
||||||
|
|
||||||
type Block = frame_system::mocking::MockingBlock<Test>;
|
type Block = frame_system::mocking::MockingBlock<Test>;
|
||||||
@ -172,7 +172,10 @@ 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> where I: 'a {
|
fn find_author<'a, I>(_: I) -> Option<AccountId>
|
||||||
|
where
|
||||||
|
I: 'a,
|
||||||
|
{
|
||||||
Some(TEST_ACCOUNT)
|
Some(TEST_ACCOUNT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -185,7 +188,9 @@ 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().build_storage::<Test>().unwrap();
|
let mut t = frame_system::GenesisConfig::default()
|
||||||
|
.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)
|
||||||
@ -196,8 +201,14 @@ 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 = <paller_balances::Pallet<Test> as frame_support::traits::fungible::Balanced<AccountId>>::issue(10);
|
let fee =
|
||||||
let tip = <paller_balances::Pallet<Test> as frame_support::traits::fungible::Balanced<AccountId>>::issue(20);
|
<paller_balances::Pallet<Test> as frame_support::traits::fungible::Balanced<
|
||||||
|
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);
|
||||||
@ -242,11 +253,23 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn era_payout_should_give_sensible_results() {
|
fn era_payout_should_give_sensible_results() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
era_payout(75, 100, Perquintill::from_percent(10), Perquintill::one(), 0, ),
|
era_payout(
|
||||||
|
75,
|
||||||
|
100,
|
||||||
|
Perquintill::from_percent(10),
|
||||||
|
Perquintill::one(),
|
||||||
|
0,
|
||||||
|
),
|
||||||
(10, 0)
|
(10, 0)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
era_payout(80, 100, Perquintill::from_percent(10), Perquintill::one(), 0, ),
|
era_payout(
|
||||||
|
80,
|
||||||
|
100,
|
||||||
|
Perquintill::from_percent(10),
|
||||||
|
Perquintill::one(),
|
||||||
|
0,
|
||||||
|
),
|
||||||
(6, 4)
|
(6, 4)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#![cfg_attr(not(feature = "std"), no_std)]
|
#![cfg_attr(not(feature = "std"), no_std)]
|
||||||
|
|
||||||
pub mod impls;
|
|
||||||
pub mod elections;
|
pub mod elections;
|
||||||
|
pub mod impls;
|
||||||
|
|
||||||
#[cfg(feature = "try-runtime")]
|
#[cfg(feature = "try-runtime")]
|
||||||
pub mod elections;
|
pub mod elections;
|
||||||
@ -10,7 +10,8 @@ pub mod elections;
|
|||||||
pub mod benchmarking;
|
pub mod benchmarking;
|
||||||
|
|
||||||
use frame_support::{
|
use frame_support::{
|
||||||
parameter_types, traits::ConstU32,
|
parameter_types,
|
||||||
|
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;
|
||||||
@ -92,8 +93,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,
|
impl_elections_weights, AVERAGE_ON_INITIALIZE_RATIO, MAXIMUM_BLOCK_WEIGHT,
|
||||||
MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO,
|
NORMAL_DISPATCH_RATIO,
|
||||||
};
|
};
|
||||||
use sp_runtime::{FixedPointNumber, Perquintill};
|
use sp_runtime::{FixedPointNumber, Perquintill};
|
||||||
|
|
||||||
@ -101,8 +102,7 @@ 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, RocksDbWeight,
|
BlockExecutionWeight, ExtrinsicBaseWeight, ParityDbWeight, RocksDbWeight,
|
||||||
ParityDbWeight,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
parameter_types! {
|
parameter_types! {
|
||||||
@ -129,7 +129,6 @@ 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`.
|
||||||
|
@ -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,7 +16,9 @@ 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().map(|(ctrl, l)| (ctrl, l.stash)).collect::<BTreeSet<_>>();
|
let all_stakers = Ledger::<T>::iter()
|
||||||
|
.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);
|
||||||
@ -70,15 +72,16 @@ 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() {
|
||||||
|
@ -80,6 +80,29 @@ extract_seed() {
|
|||||||
echo $seed
|
echo $seed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
downgrade_compiler_if_needed() {
|
||||||
|
# TODO: uncomment later
|
||||||
|
# echo "[+] fetching the latest ghost-node source code"
|
||||||
|
# git switch main
|
||||||
|
# git pull origin main
|
||||||
|
|
||||||
|
# 1.83.0 works fine, tested with:
|
||||||
|
# ...
|
||||||
|
# 1.87.0 throws errors during compilation
|
||||||
|
# 1.88.0 throws errors during compilation
|
||||||
|
LATEST_TESTED_VERSION=83
|
||||||
|
cargo_version=$(cargo --version | cut -d'.' -f2)
|
||||||
|
if [ "$cargo_version" -gt "$LATEST_TESTED_VERSION" ]; then
|
||||||
|
echo "[+] downgrading rustc compiler version to 1.83.0"
|
||||||
|
rustup default 1.83.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
|
||||||
|
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"
|
||||||
@ -195,22 +218,11 @@ if [[ $HARD_RESET = true ]]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cd $PROJECT_FOLDER
|
downgrade_compiler_if_needed
|
||||||
# TODO: uncomment later
|
|
||||||
# echo "[+] fetching the latest ghost-node source code"
|
|
||||||
# git switch main
|
|
||||||
# git pull origin main
|
|
||||||
|
|
||||||
# rustc version control, this works fine
|
|
||||||
# cargo --version | cut -d'.' -f2, if higher then do
|
|
||||||
# rustup default 1.83.0
|
|
||||||
# rustup target add wasm32-unknown-unknown --toolchain 1.83.0-x86_64-unknown-linux-gnu
|
|
||||||
# rustup component add rust-src --toolchain 1.83.0-x86_64-unknown-linux-gnu
|
|
||||||
#
|
|
||||||
# I think we need to do clean before recompilation
|
|
||||||
# cargo clean
|
|
||||||
|
|
||||||
cd $PROJECT_FOLDER
|
cd $PROJECT_FOLDER
|
||||||
|
echo "[+] clean build cache..."
|
||||||
|
cargo clean
|
||||||
echo "[+] starting build in 3 seconds..."
|
echo "[+] starting build in 3 seconds..."
|
||||||
sleep 3
|
sleep 3
|
||||||
cargo build $RELEASE $FEATURES
|
cargo build $RELEASE $FEATURES
|
||||||
@ -228,8 +240,9 @@ if [[ $HARD_RESET = true ]]; then
|
|||||||
echo "[+] ghost executable copied in '$EXECUTABLE_PATH' from '$TARGET'"
|
echo "[+] ghost executable copied in '$EXECUTABLE_PATH' from '$TARGET'"
|
||||||
echo "[+] specification '$SPECIFICATION_NAME.json' copied to '$SPECIFICATION_PATH'"
|
echo "[+] specification '$SPECIFICATION_NAME.json' copied to '$SPECIFICATION_PATH'"
|
||||||
|
|
||||||
echo "[+] starting ghost-node"
|
# TODO: uncomment later
|
||||||
sudo systemctl start ghost-node
|
# echo "[+] starting ghost-node"
|
||||||
|
# sudo systemctl start ghost-node
|
||||||
|
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
@ -312,13 +325,12 @@ 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
|
||||||
rustup update
|
downgrade_compiler_if_needed
|
||||||
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..."
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -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,27 +21,41 @@ 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(call, $nonce, $current_block, $period, $genesis, $signer))
|
Ok(ghost_sign_call(
|
||||||
|
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(call, $nonce, $current_block, $period, $genesis, $signer))
|
Ok(casper_sign_call(
|
||||||
|
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;
|
||||||
@ -50,7 +64,7 @@ macro_rules! identify_chain {
|
|||||||
let _ = $signer;
|
let _ = $signer;
|
||||||
|
|
||||||
Err("Unknown chain")
|
Err("Unknown chain")
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -105,7 +119,11 @@ 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 { client, dest, chain }
|
Self {
|
||||||
|
client,
|
||||||
|
dest,
|
||||||
|
chain,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,10 +177,9 @@ 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(sp_runtime::generic::Era::mortal(
|
frame_system::CheckMortality::<casper_runtime::Runtime>::from(
|
||||||
period,
|
sp_runtime::generic::Era::mortal(period, current_block),
|
||||||
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),
|
||||||
@ -189,7 +206,8 @@ 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> {
|
||||||
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
|
|
||||||
use ghost_slow_clap::sr25519::AuthorityId as SlowClapId;
|
|
||||||
use primitives::{AccountId, AccountPublic};
|
|
||||||
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
|
use authority_discovery_primitives::AuthorityId as AuthorityDiscoveryId;
|
||||||
use grandpa_primitives::AuthorityId as GrandpaId;
|
|
||||||
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;
|
||||||
#[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;
|
||||||
@ -58,7 +58,7 @@ pub type CasperChainSpec = sc_service::GenericChainSpec<(), Extensions>;
|
|||||||
pub type CasperChainSpec = GenericChainSpec;
|
pub type CasperChainSpec = GenericChainSpec;
|
||||||
|
|
||||||
pub fn casper_config() -> Result<CasperChainSpec, String> {
|
pub fn casper_config() -> Result<CasperChainSpec, String> {
|
||||||
CasperChainSpec::from_json_bytes(&include_bytes!("../chain-specs/casper.json")[..])
|
CasperChainSpec::from_json_bytes(&include_bytes!("../chain-specs/casper.json")[..])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "casper-native")]
|
#[cfg(feature = "casper-native")]
|
||||||
@ -76,7 +76,6 @@ 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,
|
||||||
@ -161,48 +160,60 @@ 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![(
|
||||||
(1, ghost_networks::NetworkData {
|
11155111,
|
||||||
chain_name: "ethereum-mainnet".into(),
|
ghost_networks::NetworkData {
|
||||||
|
chain_name: "sepolia-ethereum-testnet".into(),
|
||||||
default_endpoints: vec![
|
default_endpoints: vec![
|
||||||
"https://nd-422-757-666.p2pify.com/0a9d79d93fb2f4a4b1e04695da2b77a7/".into(),
|
"https://sepolia.drpc.org".into(),
|
||||||
|
"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://rpc-sepolia.rockx.com".into(),
|
||||||
|
"https://1rpc.io/sepolia".into(),
|
||||||
|
"https://0xrpc.io/sep".into(),
|
||||||
|
"https://eth-sepolia.api.onfinality.io/public".into(),
|
||||||
],
|
],
|
||||||
finality_delay: 40u64,
|
finality_delay: 40u64,
|
||||||
rate_limit_delay: 1_000u64,
|
rate_limit_delay: 3_000u64,
|
||||||
block_distance: 50u64,
|
block_distance: 20u64,
|
||||||
network_type: ghost_networks::NetworkType::Evm,
|
network_type: ghost_networks::NetworkType::Evm,
|
||||||
gatekeeper: "0x4d224452801aced8b2f0aebe155379bb5d594381".into(),
|
gatekeeper: "0xc85129A097773B7F8970a7364c928C05f265E6A1".into(),
|
||||||
topic_name: "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef".into(),
|
topic_name: "0x7ab52ec05c331e6257a3d705d6bea6e4c27277351764ad139209e06b203811a6".into(),
|
||||||
incoming_fee: 0u32,
|
incoming_fee: 69_000_000u32,
|
||||||
outgoing_fee: 0u32,
|
outgoing_fee: 0u32,
|
||||||
}.encode()),
|
}
|
||||||
(56, ghost_networks::NetworkData {
|
.encode(),
|
||||||
chain_name: "bnb-mainnet".into(),
|
)]
|
||||||
default_endpoints: vec![
|
|
||||||
"https://bsc-mainnet.core.chainstack.com/35848e183f3e3303c8cfeacbea831cab/".into(),
|
|
||||||
],
|
|
||||||
finality_delay: 20u64,
|
|
||||||
rate_limit_delay: 1_000u64,
|
|
||||||
block_distance: 50u64,
|
|
||||||
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
|
||||||
@ -220,14 +231,11 @@ 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
|
let endowed_accounts: Vec<AccountId> = endowed_accounts.unwrap_or_else(casper_testnet_accounts);
|
||||||
.unwrap_or_else(casper_testnet_accounts);
|
|
||||||
|
|
||||||
let ghost_accounts: Vec<(AccountId, u128, u8)> = ghost_accounts
|
let ghost_accounts: Vec<(AccountId, u128, u8)> = ghost_accounts.unwrap_or_default();
|
||||||
.unwrap_or_default();
|
|
||||||
|
|
||||||
let evm_networks: Vec<(u32, Vec<u8>)> = evm_networks
|
let evm_networks: Vec<(u32, Vec<u8>)> = evm_networks.unwrap_or_default();
|
||||||
.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;
|
||||||
@ -299,148 +307,6 @@ 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![
|
||||||
@ -448,28 +314,10 @@ 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<(
|
||||||
@ -486,13 +334,17 @@ fn casper_staging_config_genesis() -> serde_json::Value {
|
|||||||
// sfFXZmnDVnkQ781J2gbqUpi7K5KgMWMdM4eeii74xxGgKYnNN
|
// sfFXZmnDVnkQ781J2gbqUpi7K5KgMWMdM4eeii74xxGgKYnNN
|
||||||
hex!["507045c82be367f95408466cd054ca39bfa52697a3ef22809af14cf9de304f02"].into(),
|
hex!["507045c82be367f95408466cd054ca39bfa52697a3ef22809af14cf9de304f02"].into(),
|
||||||
// sfJeojACBa7WiH6tBwikBKAMU2oKmseEBD1GYUYATvfWuLcPa
|
// sfJeojACBa7WiH6tBwikBKAMU2oKmseEBD1GYUYATvfWuLcPa
|
||||||
hex!["daaaaab6a6e574099e24ae9bb75b543610edef9d374fa85a378edb573b47615f"].unchecked_into(),
|
hex!["daaaaab6a6e574099e24ae9bb75b543610edef9d374fa85a378edb573b47615f"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfFdtzNxJdeEkgHxvk144rJKxf7wcYvgX5tqfgZRutW9YvAKE
|
// sfFdtzNxJdeEkgHxvk144rJKxf7wcYvgX5tqfgZRutW9YvAKE
|
||||||
hex!["55446f9a7aa99ced06b317c80ce90d56b84e56526775683af2525969e8da0b64"].unchecked_into(),
|
hex!["55446f9a7aa99ced06b317c80ce90d56b84e56526775683af2525969e8da0b64"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfE8gsMYAjAJHk5gyYZN7AW6pfmJ7V9H7xxWto24nmhzCUXaQ
|
// sfE8gsMYAjAJHk5gyYZN7AW6pfmJ7V9H7xxWto24nmhzCUXaQ
|
||||||
hex!["12c14850562021eb99f58f90ab624fb6cfaf3ac9228a92f8b60115fe6a6af15a"].unchecked_into(),
|
hex!["12c14850562021eb99f58f90ab624fb6cfaf3ac9228a92f8b60115fe6a6af15a"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfE3GKSrKZzrZpdapJ2VGRpPor45T4D4i8QBZNumSNGqGv7PX
|
// sfE3GKSrKZzrZpdapJ2VGRpPor45T4D4i8QBZNumSNGqGv7PX
|
||||||
hex!["0e9e698c7b2bf5ce3861cb4bc4ddf9e200237c282025b093ada850d764d12a35"].unchecked_into(),
|
hex!["0e9e698c7b2bf5ce3861cb4bc4ddf9e200237c282025b093ada850d764d12a35"]
|
||||||
|
.unchecked_into(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
// sfHLqWNC4hMKHhwvPWmWcxZsDPhCTQKgh1Ap7pm3qML5GBTBa
|
// sfHLqWNC4hMKHhwvPWmWcxZsDPhCTQKgh1Ap7pm3qML5GBTBa
|
||||||
@ -500,27 +352,17 @@ fn casper_staging_config_genesis() -> serde_json::Value {
|
|||||||
// sfHLqWNC4hMKHhwvPWmWcxZsDPhCTQKgh1Ap7pm3qML5GBTBa
|
// sfHLqWNC4hMKHhwvPWmWcxZsDPhCTQKgh1Ap7pm3qML5GBTBa
|
||||||
hex!["a0ba0196e6ee7e6b5b0553035c5cb5c04e9725001b5732839d0529cbc00c9600"].into(),
|
hex!["a0ba0196e6ee7e6b5b0553035c5cb5c04e9725001b5732839d0529cbc00c9600"].into(),
|
||||||
// sfGA6tPPF8dAc8QpMCMjxitG3j8sXPhkdpm5bwz4UsXAApUiw
|
// sfGA6tPPF8dAc8QpMCMjxitG3j8sXPhkdpm5bwz4UsXAApUiw
|
||||||
hex!["6c4dd88b43e2011cf9a6a73d53446336ac9e04cdd4ca23587df63187ac455e49"].unchecked_into(),
|
hex!["6c4dd88b43e2011cf9a6a73d53446336ac9e04cdd4ca23587df63187ac455e49"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfGxQZXFUQH1AXv82rpjiJHFs7YsdEuVGdyvKiS2Tajpvw6Se
|
// sfGxQZXFUQH1AXv82rpjiJHFs7YsdEuVGdyvKiS2Tajpvw6Se
|
||||||
hex!["8f9ea20bf4a807a8e710f7559dece86e94672b5b361de157bdaa5c1f37849f8d"].unchecked_into(),
|
hex!["8f9ea20bf4a807a8e710f7559dece86e94672b5b361de157bdaa5c1f37849f8d"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfGz2enFUR22cQ5ey61MdtPqbCeEWZA1wsCFFSLGaK7vKnv8C
|
// sfGz2enFUR22cQ5ey61MdtPqbCeEWZA1wsCFFSLGaK7vKnv8C
|
||||||
hex!["90db5ed339a559ed157995a48d781f44c7df972dfba4bc855e4b59fa46438e17"].unchecked_into(),
|
hex!["90db5ed339a559ed157995a48d781f44c7df972dfba4bc855e4b59fa46438e17"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfEtwe5BoroNjkdLsvnjnMemUKiw8MS1X4YW8bepbbGvhS4LZ
|
// sfEtwe5BoroNjkdLsvnjnMemUKiw8MS1X4YW8bepbbGvhS4LZ
|
||||||
hex!["3481cdcbcf37a4669c29a78cf9ceb39383a10ef0a18b36b92d149fdd0c24ae00"].unchecked_into(),
|
hex!["3481cdcbcf37a4669c29a78cf9ceb39383a10ef0a18b36b92d149fdd0c24ae00"]
|
||||||
),
|
.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
|
||||||
@ -528,13 +370,17 @@ fn casper_staging_config_genesis() -> serde_json::Value {
|
|||||||
// sfG9iWUS7AKBzvqdz3uDZv7f1t79vvSTYL1VxzYPHjhmLnQVn
|
// sfG9iWUS7AKBzvqdz3uDZv7f1t79vvSTYL1VxzYPHjhmLnQVn
|
||||||
hex!["6c0283f4c688f0e75ad546c790bbd5961c1a6931543aa589f368f8272c44b758"].into(),
|
hex!["6c0283f4c688f0e75ad546c790bbd5961c1a6931543aa589f368f8272c44b758"].into(),
|
||||||
// sfGMUYXSjHgwGBpbGiHFoqT1DdJwZdHk49H5ViaQM7HUnayvZ
|
// sfGMUYXSjHgwGBpbGiHFoqT1DdJwZdHk49H5ViaQM7HUnayvZ
|
||||||
hex!["74fa7381a7a74b316afb6793a00387eed9d95d46a69866cbb316b5d9c918af0e"].unchecked_into(),
|
hex!["74fa7381a7a74b316afb6793a00387eed9d95d46a69866cbb316b5d9c918af0e"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfEWYhczV6PbmeNXZTcA4LvhpzvCfNMatYoSNKvDphmNaQzqB
|
// sfEWYhczV6PbmeNXZTcA4LvhpzvCfNMatYoSNKvDphmNaQzqB
|
||||||
hex!["236d2fa03f4ed8cb65de7e514d7540159b328f1c170dd402b094ad7fbf547218"].unchecked_into(),
|
hex!["236d2fa03f4ed8cb65de7e514d7540159b328f1c170dd402b094ad7fbf547218"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfDirg32ityDvrjxh4822unhP4qm4S9yTqN99gesN322swn7h
|
// sfDirg32ityDvrjxh4822unhP4qm4S9yTqN99gesN322swn7h
|
||||||
hex!["00946618c353e4c6546b87f9ca1089b846b0ea4658ee8e6d9d1200c24cb5ee27"].unchecked_into(),
|
hex!["00946618c353e4c6546b87f9ca1089b846b0ea4658ee8e6d9d1200c24cb5ee27"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfFZgp1Z5diFAZ16swuQD5GojGCsMMFVR19uWnCrppMLuYjRv
|
// sfFZgp1Z5diFAZ16swuQD5GojGCsMMFVR19uWnCrppMLuYjRv
|
||||||
hex!["520e74f8c5853ec8577932327ad3247656db25b74c79ad09adb431b271002401"].unchecked_into(),
|
hex!["520e74f8c5853ec8577932327ad3247656db25b74c79ad09adb431b271002401"]
|
||||||
|
.unchecked_into(),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
// sfHjtrXFzRmxwjE4rjVxFJXpvVv7furjdymZS7PQRFiANpodz
|
// sfHjtrXFzRmxwjE4rjVxFJXpvVv7furjdymZS7PQRFiANpodz
|
||||||
@ -542,125 +388,17 @@ fn casper_staging_config_genesis() -> serde_json::Value {
|
|||||||
// sfHjtrXFzRmxwjE4rjVxFJXpvVv7furjdymZS7PQRFiANpodz
|
// sfHjtrXFzRmxwjE4rjVxFJXpvVv7furjdymZS7PQRFiANpodz
|
||||||
hex!["b24feb55b2cac4b365a9245c2a97525b01bd1a594d2d42b91f6bc38c9c2e6517"].into(),
|
hex!["b24feb55b2cac4b365a9245c2a97525b01bd1a594d2d42b91f6bc38c9c2e6517"].into(),
|
||||||
// sfF5XWwvNPjZEsBz1HWs5Ys5zcE85UHnN1BV8TBBectqFQZRm
|
// sfF5XWwvNPjZEsBz1HWs5Ys5zcE85UHnN1BV8TBBectqFQZRm
|
||||||
hex!["3c944c704cae203619b9e7a5a4b6742736da6a8e76c762291bebdc7652cfec2f"].unchecked_into(),
|
hex!["3c944c704cae203619b9e7a5a4b6742736da6a8e76c762291bebdc7652cfec2f"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfDx3gj4wFHg3cK6bopnypHQ6TxW1VgyPsYVbXKhRHtLDLxQb
|
// sfDx3gj4wFHg3cK6bopnypHQ6TxW1VgyPsYVbXKhRHtLDLxQb
|
||||||
hex!["0aa3a88f6b777c95c3dfe7e997b76798413f16aa325f34824cae0c9102b281d5"].unchecked_into(),
|
hex!["0aa3a88f6b777c95c3dfe7e997b76798413f16aa325f34824cae0c9102b281d5"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfHXZbnZV3YWwnH28q2xumm7stvuC8LweYYxPNuHGonnX7QHL
|
// sfHXZbnZV3YWwnH28q2xumm7stvuC8LweYYxPNuHGonnX7QHL
|
||||||
hex!["a8e828d10cf7b74481b6e746e5532d4740ea8014a0d3d856540a59847f8a6b76"].unchecked_into(),
|
hex!["a8e828d10cf7b74481b6e746e5532d4740ea8014a0d3d856540a59847f8a6b76"]
|
||||||
|
.unchecked_into(),
|
||||||
// sfEaHBrBgeMhRTA3WHE9Nbyvn3h7xkhYKi7go4yo81L88o9zJ
|
// sfEaHBrBgeMhRTA3WHE9Nbyvn3h7xkhYKi7go4yo81L88o9zJ
|
||||||
hex!["2645f1f6820dd3a917eebbdab033088d8862477c1c14759b218685f9a0893377"].unchecked_into(),
|
hex!["2645f1f6820dd3a917eebbdab033088d8862477c1c14759b218685f9a0893377"]
|
||||||
),
|
.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(),
|
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -676,7 +414,6 @@ 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": {
|
||||||
@ -742,7 +479,9 @@ 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,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
tx_pool_api::OffchainTransactionPoolFactory,
|
|
||||||
sp_blockchain::HeaderBackend,
|
|
||||||
sc_service::{KeystoreContainer, RpcHandlers},
|
sc_service::{KeystoreContainer, RpcHandlers},
|
||||||
|
sp_blockchain::HeaderBackend,
|
||||||
telemetry::{Telemetry, TelemetryWorkerHandle},
|
telemetry::{Telemetry, TelemetryWorkerHandle},
|
||||||
|
tx_pool_api::OffchainTransactionPoolFactory,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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,27 +23,23 @@ 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,
|
ChainSpec, Configuration, Error as SubstrateServiceError, PruningMode, Role, RuntimeGenesis,
|
||||||
RuntimeGenesis, TFullBackend, TFullCallExecutor, TFullClient, TaskManager,
|
TFullBackend, TFullCallExecutor, TFullClient, TaskManager, TransactionPoolOptions,
|
||||||
TransactionPoolOptions,
|
|
||||||
};
|
};
|
||||||
|
pub use sp_api::{ApiRef, ConstructRuntimeApi, Core as CoreApi, ProvideRuntimeApi};
|
||||||
pub use sp_runtime::{
|
pub use sp_runtime::{
|
||||||
generic,
|
generic,
|
||||||
traits::{
|
traits::{self as runtime_traits, BlakeTwo256, Block as BlockT, Header as HeaderT, NumberFor},
|
||||||
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>;
|
||||||
@ -177,9 +173,13 @@ impl IdentifyVariant for Box<dyn ChainSpec> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn identify_chain(&self) -> Chain {
|
fn identify_chain(&self) -> Chain {
|
||||||
if self.is_ghost() { Chain::Ghost }
|
if self.is_ghost() {
|
||||||
else if self.is_casper() { Chain::Casper }
|
Chain::Ghost
|
||||||
else { Chain::Unknown }
|
} else if self.is_casper() {
|
||||||
|
Chain::Casper
|
||||||
|
} else {
|
||||||
|
Chain::Unknown
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -222,7 +222,9 @@ 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 { extra_pages: h as _ });
|
.map_or(DEFAULT_HEAP_ALLOC_STRATEGY, |h| HeapAllocStrategy::Static {
|
||||||
|
extra_pages: h as _,
|
||||||
|
});
|
||||||
|
|
||||||
let executor = WasmExecutor::builder()
|
let executor = WasmExecutor::builder()
|
||||||
.with_execution_method(config.wasm_method)
|
.with_execution_method(config.wasm_method)
|
||||||
@ -251,13 +253,25 @@ fn new_partial_basics(
|
|||||||
telemetry
|
telemetry
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(Basics { task_manager, client, backend, keystore_container, telemetry })
|
Ok(Basics {
|
||||||
|
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 { task_manager, backend, client, keystore_container, telemetry }: Basics,
|
Basics {
|
||||||
|
task_manager,
|
||||||
|
backend,
|
||||||
|
client,
|
||||||
|
keystore_container,
|
||||||
|
telemetry,
|
||||||
|
}: Basics,
|
||||||
select_chain: ChainSelection,
|
select_chain: ChainSelection,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
sc_service::PartialComponents<
|
sc_service::PartialComponents<
|
||||||
@ -272,11 +286,7 @@ fn new_partial<ChainSelection>(
|
|||||||
ghost_rpc::SubscriptionTaskExecutor,
|
ghost_rpc::SubscriptionTaskExecutor,
|
||||||
) -> Result<ghost_rpc::RpcExtension, SubstrateServiceError>,
|
) -> Result<ghost_rpc::RpcExtension, SubstrateServiceError>,
|
||||||
(
|
(
|
||||||
babe::BabeBlockImport<
|
babe::BabeBlockImport<Block, FullClient, FullGrandpaBlockImport<ChainSelection>>,
|
||||||
Block,
|
|
||||||
FullClient,
|
|
||||||
FullGrandpaBlockImport<ChainSelection>,
|
|
||||||
>,
|
|
||||||
grandpa::LinkHalf<Block, FullClient, ChainSelection>,
|
grandpa::LinkHalf<Block, FullClient, ChainSelection>,
|
||||||
babe::BabeLink<Block>,
|
babe::BabeLink<Block>,
|
||||||
),
|
),
|
||||||
@ -297,14 +307,13 @@ where
|
|||||||
client.clone(),
|
client.clone(),
|
||||||
);
|
);
|
||||||
|
|
||||||
let (grandpa_block_import, grandpa_link) =
|
let (grandpa_block_import, grandpa_link) = grandpa::block_import(
|
||||||
grandpa::block_import(
|
client.clone(),
|
||||||
client.clone(),
|
GRANDPA_JUSTIFICATION_PERIOD,
|
||||||
GRANDPA_JUSTIFICATION_PERIOD,
|
&(client.clone() as Arc<_>),
|
||||||
&(client.clone() as Arc<_>),
|
select_chain.clone(),
|
||||||
select_chain.clone(),
|
telemetry.as_ref().map(|x| x.handle()),
|
||||||
telemetry.as_ref().map(|x| x.handle()),
|
)?;
|
||||||
)?;
|
|
||||||
let justification_import = grandpa_block_import.clone();
|
let justification_import = grandpa_block_import.clone();
|
||||||
|
|
||||||
let babe_config = babe::configuration(&*client)?;
|
let babe_config = babe::configuration(&*client)?;
|
||||||
@ -312,27 +321,26 @@ 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) =
|
let (import_queue, babe_worker_handle) = babe::import_queue(babe::ImportQueueParams {
|
||||||
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)),
|
client: client.clone(),
|
||||||
client: client.clone(),
|
select_chain: select_chain.clone(),
|
||||||
select_chain: select_chain.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(
|
*timestamp,
|
||||||
*timestamp,
|
slot_duration,
|
||||||
slot_duration,
|
);
|
||||||
);
|
Ok((slot, timestamp))
|
||||||
Ok((slot, timestamp))
|
},
|
||||||
},
|
spawner: &task_manager.spawn_essential_handle(),
|
||||||
spawner: &task_manager.spawn_essential_handle(),
|
registry: config.prometheus_registry(),
|
||||||
registry: config.prometheus_registry(),
|
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
||||||
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
offchain_tx_pool_factory: OffchainTransactionPoolFactory::new(transaction_pool.clone()),
|
||||||
offchain_tx_pool_factory: OffchainTransactionPoolFactory::new(transaction_pool.clone()),
|
})?;
|
||||||
})?;
|
|
||||||
|
|
||||||
let justification_stream = grandpa_link.justification_stream();
|
let justification_stream = grandpa_link.justification_stream();
|
||||||
let shared_authority_set = grandpa_link.shared_authority_set().clone();
|
let shared_authority_set = grandpa_link.shared_authority_set().clone();
|
||||||
@ -353,10 +361,9 @@ 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 |
|
move |deny_unsafe,
|
||||||
deny_unsafe,
|
subscription_executor: ghost_rpc::SubscriptionTaskExecutor|
|
||||||
subscription_executor: ghost_rpc::SubscriptionTaskExecutor,
|
-> Result<ghost_rpc::RpcExtension, sc_service::Error> {
|
||||||
| -> 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(),
|
||||||
@ -428,8 +435,7 @@ 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 =
|
let mut backoff = sc_consensus_slots::BackoffAuthoringOnFinalizedHeadLagging::default();
|
||||||
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;
|
||||||
@ -446,7 +452,14 @@ 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::<_, _, sc_consensus::LongestChain<FullBackend, Block>, _, _, _,> {
|
let sc_service::PartialComponents::<
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
sc_consensus::LongestChain<FullBackend, Block>,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
_,
|
||||||
|
> {
|
||||||
client,
|
client,
|
||||||
backend,
|
backend,
|
||||||
mut task_manager,
|
mut task_manager,
|
||||||
@ -454,12 +467,7 @@ 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: (
|
other: (rpc_extensions_builder, import_setup, rpc_setup, mut telemetry),
|
||||||
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,
|
||||||
@ -476,7 +484,11 @@ 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.block_hash(0).ok().flatten().expect("Genesis block exists; qed");
|
let genesis_hash = client
|
||||||
|
.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);
|
||||||
@ -554,8 +566,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 {
|
||||||
@ -563,10 +575,7 @@ 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(
|
sc_sysinfo::initialize_hwbench_telemetry(telemetry_handle, hwbench),
|
||||||
telemetry_handle,
|
|
||||||
hwbench,
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -580,12 +589,14 @@ 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.event_stream("authority-discovery").filter_map(|e| async move {
|
network
|
||||||
match e {
|
.event_stream("authority-discovery")
|
||||||
Event::Dht(e) => Some(e),
|
.filter_map(|e| async move {
|
||||||
_ => None,
|
match e {
|
||||||
}
|
Event::Dht(e) => Some(e),
|
||||||
});
|
_ => None,
|
||||||
|
}
|
||||||
|
});
|
||||||
let (worker, _service) = sc_authority_discovery::new_worker_and_service_with_config(
|
let (worker, _service) = sc_authority_discovery::new_worker_and_service_with_config(
|
||||||
sc_authority_discovery::WorkerConfig {
|
sc_authority_discovery::WorkerConfig {
|
||||||
publish_non_global_ips: auth_disc_publish_non_global_ips,
|
publish_non_global_ips: auth_disc_publish_non_global_ips,
|
||||||
@ -597,7 +608,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(
|
||||||
@ -625,16 +636,14 @@ 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 |_, ()| {
|
create_inherent_data_providers: move |_, ()| async 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(
|
||||||
*timestamp,
|
*timestamp,
|
||||||
slot_duration,
|
slot_duration,
|
||||||
);
|
);
|
||||||
Ok((slot, timestamp))
|
Ok((slot, timestamp))
|
||||||
}
|
|
||||||
},
|
},
|
||||||
force_authoring,
|
force_authoring,
|
||||||
backoff_authoring_blocks,
|
backoff_authoring_blocks,
|
||||||
@ -646,7 +655,9 @@ 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.spawn_essential_handle().spawn_blocking("babe", None, babe);
|
task_manager
|
||||||
|
.spawn_essential_handle()
|
||||||
|
.spawn_blocking("babe", None, babe);
|
||||||
}
|
}
|
||||||
|
|
||||||
let keystore_opt = if role.is_authority() {
|
let keystore_opt = if role.is_authority() {
|
||||||
@ -711,8 +722,17 @@ 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 { client, backend, import_queue, task_manager, .. } =
|
let sc_service::PartialComponents {
|
||||||
new_partial::<sc_consensus::LongestChain<FullBackend, Block>>(&mut config, basics, chain_selection)?;
|
client,
|
||||||
|
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))
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
@ -720,22 +740,28 @@ 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<(Arc<FullClient>, Arc<FullBackend>, sc_consensus::BasicQueue<Block>, TaskManager), Error>
|
) -> Result<
|
||||||
{
|
(
|
||||||
|
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(
|
pub fn build_full(config: Configuration, params: NewFullParams) -> Result<NewFull, Error> {
|
||||||
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 =>
|
}
|
||||||
new_full::<sc_network::Litep2pNetworkBackend>(config, params),
|
sc_network::config::NetworkBackendType::Litep2p => {
|
||||||
|
new_full::<sc_network::Litep2pNetworkBackend>(config, params)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -750,7 +776,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)?;
|
||||||
|
@ -1,200 +0,0 @@
|
|||||||
|
|
||||||
### 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
|
|
@ -33,10 +33,7 @@ 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(
|
async fn build_chain(runtime: &str, base_path: &Path) -> Result<(), String> {
|
||||||
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())
|
||||||
@ -54,17 +51,15 @@ async fn build_chain(
|
|||||||
// 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).map(|x| x.success()).unwrap_or_default());
|
assert!(common::wait_for(&mut cmd, 30)
|
||||||
|
.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(
|
fn benchmark_block(runtime: &str, base_path: &Path, block: u32) -> Result<(), String> {
|
||||||
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])
|
||||||
@ -77,7 +72,7 @@ fn benchmark_block(
|
|||||||
.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(())
|
||||||
|
@ -3,10 +3,7 @@ use std::{process::Command, result::Result};
|
|||||||
|
|
||||||
static RUNTIMES: [&str; 2] = ["ghost", "casper"];
|
static RUNTIMES: [&str; 2] = ["ghost", "casper"];
|
||||||
|
|
||||||
static EXTRINSIC: [(&str, &str); 2] = [
|
static EXTRINSIC: [(&str, &str); 2] = [("system", "remark"), ("balances", "transfer_keep_alive")];
|
||||||
("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]
|
||||||
@ -25,22 +22,19 @@ 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(
|
|
||||||
runtime: &str,
|
fn benchmark_extrinsic(runtime: &str, pallet: &str, extrinsic: &str) -> Result<(), String> {
|
||||||
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(())
|
||||||
|
@ -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.
|
||||||
|
@ -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,7 +80,10 @@ 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!("Could not find WebSocket address in process output:\n{}", &data)
|
panic!(
|
||||||
|
"Could not find WebSocket address in process output:\n{}",
|
||||||
|
&data
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
(ws_url, data)
|
(ws_url, data)
|
||||||
|
@ -38,7 +38,9 @@ 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).map(|x| x.success()).unwrap_or_default());
|
assert!(common::wait_for(&mut cmd, 30)
|
||||||
|
.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());
|
||||||
|
|
||||||
|
@ -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,11 +33,14 @@ 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!(cmd.try_wait().unwrap().is_none(), "the process should still be running");
|
assert!(
|
||||||
|
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()),
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghost-remote-ext-tests-bags-list"
|
name = "ghost-remote-ext-tests-bags-list"
|
||||||
version = "1.0.0"
|
version = "1.0.1"
|
||||||
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
|
||||||
|
@ -57,28 +57,23 @@ async fn main() {
|
|||||||
|
|
||||||
match options.command {
|
match options.command {
|
||||||
(Command::CheckMigration) => {
|
(Command::CheckMigration) => {
|
||||||
migration::execute::<Runtime, Block>(
|
migration::execute::<Runtime, Block>(CSPR as u64, "CSPR", options.uri.clone())
|
||||||
CSPR as u64,
|
.await;
|
||||||
"CSPR",
|
}
|
||||||
options.uri.clone(),
|
|
||||||
).await;
|
|
||||||
},
|
|
||||||
(Command::SanityCheck) => {
|
(Command::SanityCheck) => {
|
||||||
try_state::execute::<Runtime, Block>(
|
try_state::execute::<Runtime, Block>(CSPR as u64, "CSPR", options.uri.clone())
|
||||||
CSPR as u64,
|
.await;
|
||||||
"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"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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.1"
|
version = "1.6.2"
|
||||||
build = "build.rs"
|
build = "build.rs"
|
||||||
authors.workspace = true
|
authors.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
use chain_spec_builder::{
|
use chain_spec_builder::{
|
||||||
generate_chain_spec_for_runtime, ChainSpecBuilder, ChainSpecBuilderCmd,
|
generate_chain_spec_for_runtime, ChainSpecBuilder, ChainSpecBuilderCmd, ConvertToRawCmd,
|
||||||
ConvertToRawCmd, DisplayPresetCmd, ListPresetsCmd, UpdateCodeCmd,
|
DisplayPresetCmd, ListPresetsCmd, UpdateCodeCmd, VerifyCmd,
|
||||||
VerifyCmd,
|
|
||||||
};
|
};
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use sc_chain_spec::{
|
|
||||||
update_code_in_json_chain_spec, GenericChainSpec,
|
|
||||||
GenesisConfigBuilderRuntimeCaller,
|
|
||||||
};
|
|
||||||
use ghost_staging_chain_spec_builder as chain_spec_builder;
|
use ghost_staging_chain_spec_builder as chain_spec_builder;
|
||||||
|
use sc_chain_spec::{
|
||||||
|
update_code_in_json_chain_spec, GenericChainSpec, GenesisConfigBuilderRuntimeCaller,
|
||||||
|
};
|
||||||
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}")),
|
||||||
_ => {},
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,16 +26,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 = serde_json::from_str::<serde_json::Value>(
|
let mut chain_spec_json =
|
||||||
&chain_spec.as_json(false)?
|
serde_json::from_str::<serde_json::Value>(&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())
|
||||||
@ -47,23 +45,27 @@ 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 { ref input_chain_spec }) => {
|
ChainSpecBuilderCmd::ConvertToRaw(ConvertToRawCmd {
|
||||||
|
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 = serde_json::from_str::<serde_json::Value>(
|
let chain_spec_json =
|
||||||
&chain_spec.as_json(false)?
|
serde_json::from_str::<serde_json::Value>(&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 { ref input_chain_spec }) => {
|
ChainSpecBuilderCmd::Verify(VerifyCmd {
|
||||||
|
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}"))?;
|
||||||
@ -77,13 +79,13 @@ fn inner_main() -> Result<(), String> {
|
|||||||
.map(|preset| {
|
.map(|preset| {
|
||||||
String::from(
|
String::from(
|
||||||
TryInto::<&str>::try_into(&preset)
|
TryInto::<&str>::try_into(&preset)
|
||||||
.unwrap_or_else(|_| "cannot display preset id")
|
.unwrap_or_else(|_| "cannot display preset id")
|
||||||
.to_string(),
|
.to_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,
|
||||||
@ -96,7 +98,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(())
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
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)]
|
||||||
@ -156,22 +154,23 @@ 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[..]);
|
||||||
@ -179,7 +178,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();
|
||||||
@ -190,7 +189,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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghost-voter-bags"
|
name = "ghost-voter-bags"
|
||||||
version = "0.3.6"
|
version = "0.3.7"
|
||||||
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
|
||||||
|
@ -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")]
|
||||||
@ -36,7 +36,7 @@ struct Opt {
|
|||||||
runtime: Runtime,
|
runtime: Runtime,
|
||||||
|
|
||||||
/// Where to write the output.
|
/// Where to write the output.
|
||||||
#[arg(short, long, value_name="FILE")]
|
#[arg(short, long, value_name = "FILE")]
|
||||||
output: PathBuf,
|
output: PathBuf,
|
||||||
|
|
||||||
/// The total issuance of the native currency (`value` * 10^18).
|
/// The total issuance of the native currency (`value` * 10^18).
|
||||||
@ -50,6 +50,12 @@ struct Opt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), std::io::Error> {
|
fn main() -> Result<(), std::io::Error> {
|
||||||
let Opt { n_bags, output, runtime, total_issuance, minimum_balance } = Opt::parse();
|
let Opt {
|
||||||
|
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)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghostkey"
|
name = "ghostkey"
|
||||||
version = "0.3.15"
|
version = "0.3.16"
|
||||||
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
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use ghost_client_cli::{VanityCmd, KeySubcommand};
|
use ghost_client_cli::{KeySubcommand, VanityCmd};
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
#[command(
|
#[command(name = "ghostkey", author = "f4t50", about = "Ghost Key Tool", version)]
|
||||||
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)]
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ghost-miner"
|
name = "ghost-miner"
|
||||||
version = "1.5.0"
|
version = "1.5.1"
|
||||||
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
|
||||||
|
@ -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,13 +30,16 @@ 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 { rpc: RpcClient::new(rpc), chain_api })
|
Ok(Self {
|
||||||
|
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.
|
||||||
|
122
utils/staking-miner/src/commands/dry_run.rs
Normal file
122
utils/staking-miner/src/commands/dry_run.rs
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
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(())
|
||||||
|
}
|
90
utils/staking-miner/src/commands/emergency_solution.rs
Normal file
90
utils/staking-miner/src/commands/emergency_solution.rs
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
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(())
|
||||||
|
}
|
7
utils/staking-miner/src/commands/mod.rs
Normal file
7
utils/staking-miner/src/commands/mod.rs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
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};
|
858
utils/staking-miner/src/commands/monitor.rs
Normal file
858
utils/staking-miner/src/commands/monitor.rs
Normal file
@ -0,0 +1,858 @@
|
|||||||
|
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
|
||||||
|
)))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -13,13 +13,10 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use frame_election_provider_support::{
|
use frame_election_provider_support::{Get, NposSolution, PhragMMS, SequentialPhragmen};
|
||||||
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,
|
usigned::TrimmingStatus, RawSolution, ReadySolution, SolutionOf, SolutionOrSnapshotSize,
|
||||||
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;
|
||||||
@ -29,12 +26,16 @@ 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 = frame_election_provider_support::Voter<AccountId, crate::static_types::MaxVotesPerVoter>;
|
type MinerVoterOf =
|
||||||
|
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<(AccountId, VoteWeight, BoundedVec<AccountId, crate::static_types::MaxVotesPerVoter>)>;
|
type Voters = Vec<(
|
||||||
|
AccountId,
|
||||||
|
VoteWeight,
|
||||||
|
BoundedVec<AccountId, crate::static_types::MaxVotesPerVoter>,
|
||||||
|
)>;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug, Debug)]
|
||||||
#[derive(Debug)]
|
|
||||||
struct EpmConstant {
|
struct EpmConstant {
|
||||||
epm: &'static str,
|
epm: &'static str,
|
||||||
constant: &'static str,
|
constant: &'static str,
|
||||||
@ -42,7 +43,10 @@ struct EpmConstant {
|
|||||||
|
|
||||||
impl EpmConstant {
|
impl EpmConstant {
|
||||||
const fn new(constant: &'static str) -> Self {
|
const fn new(constant: &'static str) -> Self {
|
||||||
Self { epm: EPM_PALLET_NAME, constant }
|
Self {
|
||||||
|
epm: EPM_PALLET_NAME,
|
||||||
|
constant,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn to_parts(self) -> (&'static str, &'static str) {
|
const fn to_parts(self) -> (&'static str, &'static str) {
|
||||||
@ -101,18 +105,24 @@ 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 { voters, voters_by_stake },
|
state: State {
|
||||||
_marker: PhantomData
|
voters,
|
||||||
|
voters_by_stake,
|
||||||
|
},
|
||||||
|
_marker: PhantomData,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some((_, idx)) = voters_by_stake.pop_first() else { break };
|
let Some((_, idx)) = voters_by_stake.pop_first() else {
|
||||||
|
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 {
|
||||||
@ -122,7 +132,9 @@ where
|
|||||||
targets.remove(&rm);
|
targets.remove(&rm);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Err(Error::Feasibility("Failed to pre-trim weight < T::MaxLength".to_string()));
|
return Err(Error::Feasibility(
|
||||||
|
"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> {
|
||||||
@ -139,7 +151,10 @@ where
|
|||||||
supports.retain(|a| a != &rm);
|
supports.retain(|a| a != &rm);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(State { voters, voters_by_stake })
|
Ok(State {
|
||||||
|
voters,
|
||||||
|
voters_by_stake,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_voters(&self) -> Voters {
|
pub fn to_voters(&self) -> Voters {
|
||||||
@ -197,28 +212,37 @@ 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(
|
Error::InvalidMetadata(format!(
|
||||||
format!("Decoding `{}` failed {}", std::any::type_name::<T>(), e)
|
"Decoding `{}` failed {}",
|
||||||
)
|
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).map_err(|e| {
|
let scale_result = to_scale_value(supports)
|
||||||
Error::DynamicTransaction(format!("Failed to encode `Supports`: {:?}", e))
|
.map_err(|e| Error::DynamicTransaction(format!("Failed to encode `Supports`: {:?}", e)))?;
|
||||||
})?;
|
Ok(subxt::dynamic::tx(
|
||||||
Ok(subxt::dynamic::tx(EPM_PALLET_NAME, "set_emergency_election_result", vec![scale_result]))
|
EPM_PALLET_NAME,
|
||||||
|
"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>(
|
||||||
solution: RawSolution<S>,
|
solution: RawSolution<S>,
|
||||||
) -> Result<DynamicPayload, Error> {
|
) -> Result<DynamicPayload, Error> {
|
||||||
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(EPM_PALLET_NAME, "submit", vec![scale_solution]))
|
Ok(subxt::dynamic::tx(
|
||||||
|
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>(
|
||||||
@ -227,7 +251,11 @@ 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(EPM_PALLET_NAME, "submit_unsigned", vec![scale_solution, scale_witness]))
|
Ok(subxt::dynamic::tx(
|
||||||
|
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>(
|
||||||
@ -244,7 +272,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()),
|
||||||
}
|
}
|
||||||
@ -263,7 +291,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()),
|
||||||
}
|
}
|
||||||
@ -274,7 +302,15 @@ pub async fn mine_solution<T>(
|
|||||||
targets: Vec<AccountId>,
|
targets: Vec<AccountId>,
|
||||||
voters: Voters,
|
voters: Voters,
|
||||||
desired_targets: u32,
|
desired_targets: u32,
|
||||||
) -> Result<(SolutionOf<T>, ElectionScore, SolutionOrSnapshotSize, TrimmingStatus), Error>
|
) -> Result<
|
||||||
|
(
|
||||||
|
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
|
||||||
@ -288,14 +324,18 @@ 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::<
|
Miner::<T>::mine_solution_with_snapshot::<PhragMMS<AccountId, Accuracy, Balancing>>(
|
||||||
PhragMMS<AccountId, Accuracy, Balancing>,
|
voters,
|
||||||
>(voters, targets, desired_targets)
|
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))),
|
||||||
@ -322,13 +362,21 @@ 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(&runtime::storage()::election_provider_multi_phase().desired_targets())
|
.fetch(
|
||||||
|
&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(&runtime::storage().election_provider_multi_phase().minimum_untrusted_score())
|
.fetch(
|
||||||
|
&runtime::storage()
|
||||||
|
.election_provider_multi_phase()
|
||||||
|
.minimum_untrusted_score(),
|
||||||
|
)
|
||||||
.await?
|
.await?
|
||||||
.map(|score| score.0);
|
.map(|score| score.0);
|
||||||
|
|
||||||
@ -339,7 +387,8 @@ 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 {
|
||||||
@ -368,14 +417,15 @@ 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 {
|
||||||
@ -425,9 +475,13 @@ 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 { solution: self.solution.clone(), score: self.score, round: self.round },
|
RawSolution {
|
||||||
|
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(),
|
||||||
@ -438,7 +492,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)))
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -483,7 +537,9 @@ 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.get().expect("shared client is configured as start; qed");
|
let client = SHARED_CLIENT
|
||||||
|
.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();
|
||||||
@ -499,7 +555,11 @@ pub async fn runtime_api_solution_weight<S: Encode + NposSolution + TypeInfo + '
|
|||||||
|
|
||||||
let bytes = client
|
let bytes = client
|
||||||
.rpc()
|
.rpc()
|
||||||
.state_call("TransactionPaymentCallApi_query_call_info", Some(&call_data), None)
|
.state_call(
|
||||||
|
"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())?;
|
||||||
|
@ -41,14 +41,17 @@ 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 { inner: self, start: None }
|
Timed {
|
||||||
|
inner: self,
|
||||||
|
start: None,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,15 +62,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);
|
||||||
|
|
||||||
@ -77,10 +80,11 @@ 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".to_string()
|
"Failed to downcast RPC error; this is a bug please file an issue"
|
||||||
|
.to_string(),
|
||||||
));
|
));
|
||||||
return;
|
return;
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match jsonrpsee_err {
|
match jsonrpsee_err {
|
||||||
@ -89,30 +93,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);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,10 +34,7 @@ use std::str::FromStr;
|
|||||||
use tokio::sync::oneshot;
|
use tokio::sync::oneshot;
|
||||||
use tracing_subscriber::EnvFilter;
|
use tracing_subscriber::EnvFilter;
|
||||||
|
|
||||||
use crate::{
|
use crate::{client::Client, opt::RuntimeVersion};
|
||||||
client::Client,
|
|
||||||
opt::RuntimeVersion,
|
|
||||||
};
|
|
||||||
|
|
||||||
#[derive(Debig, Clone, Parser)]
|
#[derive(Debig, Clone, Parser)]
|
||||||
#[cfg_attr(test, derive(PartialEq))]
|
#[cfg_attr(test, derive(PartialEq))]
|
||||||
@ -96,7 +93,12 @@ macro_rules! any_runtime {
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Error> {
|
async fn main() -> Result<(), Error> {
|
||||||
let Opt { uri, command, prometheus_port, log } = Opt::parse();
|
let Opt {
|
||||||
|
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();
|
||||||
|
|
||||||
@ -109,7 +111,9 @@ 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.set(client.clone()).expect("shared client only set once; qed");
|
SHARED_CLIENT
|
||||||
|
.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.
|
||||||
@ -203,7 +207,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 {
|
||||||
@ -218,10 +222,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;
|
||||||
@ -233,10 +237,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);
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,7 +266,8 @@ mod tests {
|
|||||||
"--delay",
|
"--delay",
|
||||||
"12",
|
"12",
|
||||||
"seq-phragmen",
|
"seq-phragmen",
|
||||||
]).unwrap();
|
])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
opt,
|
opt,
|
||||||
@ -293,7 +298,8 @@ mod tests {
|
|||||||
"--seed-or-path",
|
"--seed-or-path",
|
||||||
"//Alice",
|
"//Alice",
|
||||||
"prag-mms",
|
"prag-mms",
|
||||||
]).unwrap();
|
])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
opt,
|
opt,
|
||||||
@ -323,7 +329,8 @@ mod tests {
|
|||||||
"prag-mms",
|
"prag-mms",
|
||||||
"--iterations",
|
"--iterations",
|
||||||
"1337",
|
"1337",
|
||||||
]).unwrap();
|
])
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
opt,
|
opt,
|
||||||
|
@ -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 = serde_json::from_value::<String>(json)
|
let mut chain =
|
||||||
.expect("specName must be String; qed");
|
serde_json::from_value::<String>(json).expect("specName must be String; qed");
|
||||||
chain.make_ascii_lowercase();
|
chain.make_ascii_lowercase();
|
||||||
Chain::from_str(&chain)
|
Chain::from_str(&chain)
|
||||||
}
|
}
|
||||||
@ -96,8 +96,7 @@ impl From<subxt_rpc::RuntimeVersion> for RuntimeVersion {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
|
#[derive(Deserialize, Serialize, PartialEq, Debug, Clone, Debug)]
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct RuntimeVersion {
|
pub struct RuntimeVersion {
|
||||||
pub spec_name: String,
|
pub spec_name: String,
|
||||||
pub impl_name: String,
|
pub impl_name: String,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
pub use pallet_election_provider_multi_phase::{Miner, MinerConfig};
|
pub use pallet_election_provider_multi_phase::{Miner, MinerConfig};
|
||||||
pub use subxt::ext::sp_core;
|
pub use subxt::ext::sp_core;
|
||||||
|
|
||||||
pub use primitives::{AccountId, Header, Hash, Balance};
|
pub use primitives::{AccountId, Balance, Hash, Header};
|
||||||
|
|
||||||
// pub type AccountId = sp_runtime::AccountId32;
|
// pub type AccountId = sp_runtime::AccountId32;
|
||||||
// pub type Header = subxt::config::substrate::SubstrateHeader<u32, subxt::config::substrate::BlakeTwo256>;
|
// pub type Header = subxt::config::substrate::SubstrateHeader<u32, subxt::config::substrate::BlakeTwo256>;
|
||||||
@ -21,7 +21,8 @@ pub type RpcClient = subxt::backend::legacy::LegacyPrcMethods<subxt::SubstrateCo
|
|||||||
pub type ChainClient = subxt::OnlineClient<subxt::SubstrateConfig>;
|
pub type ChainClient = subxt::OnlineClient<subxt::SubstrateConfig>;
|
||||||
pub type Config = subxt::SubstrateConfig;
|
pub type Config = subxt::SubstrateConfig;
|
||||||
|
|
||||||
pub type SignedSubmission<S> = pallet_election_provider_multi_phase::SignedSubmission<AccountId, Balance, S>;
|
pub type SignedSubmission<S> =
|
||||||
|
pallet_election_provider_multi_phase::SignedSubmission<AccountId, Balance, S>;
|
||||||
|
|
||||||
#[subxt::subxt(
|
#[subxt::subxt(
|
||||||
runtime_metadata_path = "artifacts/metadata.scale",
|
runtime_metadata_path = "artifacts/metadata.scale",
|
||||||
|
@ -21,9 +21,15 @@ async fn serve_req(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
|
|||||||
.header(CONTENT_TYPE, encoder.format_type())
|
.header(CONTENT_TYPE, encoder.format_type())
|
||||||
.body(Body::from(buffer))
|
.body(Body::from(buffer))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
},
|
}
|
||||||
(&Method::GET, "/") => Response::builder().status(200).body(Body::from("")).unwrap(),
|
(&Method::GET, "/") => Response::builder()
|
||||||
_ => Response::builder().status(404).body(Body::from("")).unwrap(),
|
.status(200)
|
||||||
|
.body(Body::from(""))
|
||||||
|
.unwrap(),
|
||||||
|
_ => Response::builder()
|
||||||
|
.status(404)
|
||||||
|
.body(Body::from(""))
|
||||||
|
.unwrap(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(response)
|
Ok(response)
|
||||||
@ -75,35 +81,40 @@ mod hidden {
|
|||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_trim_started",
|
"staking_miner_trim_started",
|
||||||
"Number of started trimmed solutions",
|
"Number of started trimmed solutions",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static TRIMMED_SOLUTION_SUCCESS: Lazy<Counter> = Lazy::new(|| {
|
static TRIMMED_SOLUTION_SUCCESS: Lazy<Counter> = Lazy::new(|| {
|
||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_trim_success",
|
"staking_miner_trim_success",
|
||||||
"Number of successful trimmed solutions",
|
"Number of successful trimmed solutions",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static SUBMISSIONS_STARTED: Lazy<Counter> = Lazy::new(|| {
|
static SUBMISSIONS_STARTED: Lazy<Counter> = Lazy::new(|| {
|
||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_submissions_started",
|
"staking_miner_submissions_started",
|
||||||
"Number of submissions started",
|
"Number of submissions started",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static SUBMISSIONS_SUCCESS: Lazy<Counter> = Lazy::new(|| {
|
static SUBMISSIONS_SUCCESS: Lazy<Counter> = Lazy::new(|| {
|
||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_submissions_success",
|
"staking_miner_submissions_success",
|
||||||
"Number of submissions finished successfully",
|
"Number of submissions finished successfully",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static MINED_SOLUTION_DURATION: Lazy<Gauge> = Lazy::new(|| {
|
static MINED_SOLUTION_DURATION: Lazy<Gauge> = Lazy::new(|| {
|
||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_mining_duration_ms",
|
"staking_miner_mining_duration_ms",
|
||||||
"The mined solution time in milliseconds.",
|
"The mined solution time in milliseconds.",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static SUBMIT_SOLUTION_AND_WATCH_DURATION: Lazy<Gauge> = Lazy::new(|| {
|
static SUBMIT_SOLUTION_AND_WATCH_DURATION: Lazy<Gauge> = Lazy::new(|| {
|
||||||
@ -117,49 +128,56 @@ mod hidden {
|
|||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_balance",
|
"staking_miner_balance",
|
||||||
"The balance of the staking miner account",
|
"The balance of the staking miner account",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static SCORE_MINIMAL_STAKE: Lazy<Gauge> = Lazy::new(|| {
|
static SCORE_MINIMAL_STAKE: Lazy<Gauge> = Lazy::new(|| {
|
||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_score_minimal_stake",
|
"staking_miner_score_minimal_stake",
|
||||||
"The minimal winner, in terms of total backing stake",
|
"The minimal winner, in terms of total backing stake",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static SCORE_SUM_STAKE: Lazy<Gauge> = Lazy::new(|| {
|
static SCORE_SUM_STAKE: Lazy<Gauge> = Lazy::new(|| {
|
||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_score_sum_stake",
|
"staking_miner_score_sum_stake",
|
||||||
"The sum of the total backing of all winners",
|
"The sum of the total backing of all winners",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static SCORE_SUM_STAKE_SQUARED: Lazy<Gauge> = Lazy::new(|| {
|
static SCORE_SUM_STAKE_SQUARED: Lazy<Gauge> = Lazy::new(|| {
|
||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_score_sum_stake_squared",
|
"staking_miner_score_sum_stake_squared",
|
||||||
"The sum of the total backing of all winners, aka. the variance.",
|
"The sum of the total backing of all winners, aka. the variance.",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static RUNTIME_UPGRADES: Lazy<Counter> = Lazy::new(|| {
|
static RUNTIME_UPGRADES: Lazy<Counter> = Lazy::new(|| {
|
||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_runtime",
|
"staking_miner_runtime",
|
||||||
"Number of runtime upgrades performed",
|
"Number of runtime upgrades performed",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static SUBMISSION_LENGTH: Lazy<Gauge> = Lazy::new(|| {
|
static SUBMISSION_LENGTH: Lazy<Gauge> = Lazy::new(|| {
|
||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_solution_length_bytes",
|
"staking_miner_solution_length_bytes",
|
||||||
"Number of bytes in the solution submitted",
|
"Number of bytes in the solution submitted",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
static SUBMISSION_WEIGHT: Lazy<Gauge> = Lazy::new(|| {
|
static SUBMISSION_WEIGHT: Lazy<Gauge> = Lazy::new(|| {
|
||||||
register_counter!(opts!(
|
register_counter!(opts!(
|
||||||
"staking_miner_solution_weight",
|
"staking_miner_solution_weight",
|
||||||
"Weight of the solution submitted",
|
"Weight of the solution submitted",
|
||||||
)).unwrap()
|
))
|
||||||
|
.unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
pub fn on_runtime_upgrade() {
|
pub fn on_runtime_upgrade() {
|
||||||
|
@ -16,7 +16,10 @@ impl std::fmt::Display for Signer {
|
|||||||
|
|
||||||
impl Clone for Signer {
|
impl Clone for Signer {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self { pair: self.pair.clone(), signer: PairSigner::new(self.pair.clone()) }
|
Self {
|
||||||
|
pair: self.pair.clone(),
|
||||||
|
signer: PairSigner::new(self.pair.clone()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,10 @@ mod max_weight {
|
|||||||
|
|
||||||
impl MaxWeight {
|
impl MaxWeight {
|
||||||
pub fn get() -> Weight {
|
pub fn get() -> Weight {
|
||||||
Weight::from_parts(REF_TIME.load(Ordering::SeqCst), PROOF_SIZE.load(Ordering::SeqCst))
|
Weight::from_parts(
|
||||||
|
REF_TIME.load(Ordering::SeqCst),
|
||||||
|
PROOF_SIZE.load(Ordering::SeqCst),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,7 +87,7 @@ pub mod ghost {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MinerConfig;
|
pub struct MinerConfig;
|
||||||
impla pallet_election_provider_multi_phase::unsigned::MinerConfig for MinerConfig {
|
impl pallet_election_provider_multi_phase::unsigned::MinerConfig for MinerConfig {
|
||||||
type AccountId = AccountId;
|
type AccountId = AccountId;
|
||||||
type MaxLength = MaxLength;
|
type MaxLength = MaxLength;
|
||||||
type MaxWeight = MaxWeight;
|
type MaxWeight = MaxWeight;
|
||||||
@ -100,18 +103,23 @@ pub mod ghost {
|
|||||||
) -> Weight {
|
) -> Weight {
|
||||||
let Some(votes) = epm::mock_votes(
|
let Some(votes) = epm::mock_votes(
|
||||||
active_voters,
|
active_voters,
|
||||||
desired_targets.try_into().expect("Desired targets < u16::MAX"),
|
desired_targets
|
||||||
|
.try_into()
|
||||||
|
.expect("Desired targets < u16::MAX"),
|
||||||
) else {
|
) else {
|
||||||
return Weight::MAX;
|
return Weight::MAX;
|
||||||
};
|
};
|
||||||
|
|
||||||
let raw = RawSolution {
|
let raw = RawSolution {
|
||||||
solution: NposSolution16 { votes1: votes, ..Default::default() },
|
solution: NposSolution16 {
|
||||||
|
votes1: votes,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
if raw.solution.voter_count() != active_voters as usize ||
|
if raw.solution.voter_count() != active_voters as usize
|
||||||
raw.solution.unique_targets().len() != desired_targets as usize
|
|| raw.solution.unique_targets().len() != desired_targets as usize
|
||||||
{
|
{
|
||||||
return Weight::MAX;
|
return Weight::MAX;
|
||||||
}
|
}
|
||||||
@ -119,7 +127,8 @@ pub mod ghost {
|
|||||||
futures::executor::block_on(epm::runtime_api_solution_weight(
|
futures::executor::block_on(epm::runtime_api_solution_weight(
|
||||||
raw,
|
raw,
|
||||||
SolutionOrSnapshotSize { voters, targets },
|
SolutionOrSnapshotSize { voters, targets },
|
||||||
)).expect("solution_weight should work")
|
))
|
||||||
|
.expect("solution_weight should work")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -139,7 +148,7 @@ pub mod casper {
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MinerConfig;
|
pub struct MinerConfig;
|
||||||
impla pallet_election_provider_multi_phase::unsigned::MinerConfig for MinerConfig {
|
impl pallet_election_provider_multi_phase::unsigned::MinerConfig for MinerConfig {
|
||||||
type AccountId = AccountId;
|
type AccountId = AccountId;
|
||||||
type MaxLength = MaxLength;
|
type MaxLength = MaxLength;
|
||||||
type MaxWeight = MaxWeight;
|
type MaxWeight = MaxWeight;
|
||||||
@ -155,18 +164,23 @@ pub mod casper {
|
|||||||
) -> Weight {
|
) -> Weight {
|
||||||
let Some(votes) = epm::mock_votes(
|
let Some(votes) = epm::mock_votes(
|
||||||
active_voters,
|
active_voters,
|
||||||
desired_targets.try_into().expect("Desired targets < u16::MAX"),
|
desired_targets
|
||||||
|
.try_into()
|
||||||
|
.expect("Desired targets < u16::MAX"),
|
||||||
) else {
|
) else {
|
||||||
return Weight::MAX;
|
return Weight::MAX;
|
||||||
};
|
};
|
||||||
|
|
||||||
let raw = RawSolution {
|
let raw = RawSolution {
|
||||||
solution: NposSolution16 { votes1: votes, ..Default::default() },
|
solution: NposSolution16 {
|
||||||
|
votes1: votes,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
|
|
||||||
if raw.solution.voter_count() != active_voters as usize ||
|
if raw.solution.voter_count() != active_voters as usize
|
||||||
raw.solution.unique_targets().len() != desired_targets as usize
|
|| raw.solution.unique_targets().len() != desired_targets as usize
|
||||||
{
|
{
|
||||||
return Weight::MAX;
|
return Weight::MAX;
|
||||||
}
|
}
|
||||||
@ -174,7 +188,8 @@ pub mod casper {
|
|||||||
futures::executor::block_on(epm::runtime_api_solution_weight(
|
futures::executor::block_on(epm::runtime_api_solution_weight(
|
||||||
raw,
|
raw,
|
||||||
SolutionOrSnapshotSize { voters, targets },
|
SolutionOrSnapshotSize { voters, targets },
|
||||||
)).expect("solution_weight should work")
|
))
|
||||||
|
.expect("solution_weight should work")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user