mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-07-22 03:15:42 +00:00
check runtime version in staking miner (#3628)
* check runtime version in staking miner * fmt * add short alias for things * fix fee * print length as well * fix build * review comments
This commit is contained in:
Generated
+10
@@ -10164,6 +10164,7 @@ dependencies = [
|
|||||||
"kusama-runtime",
|
"kusama-runtime",
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"log",
|
"log",
|
||||||
|
"pallet-balances",
|
||||||
"pallet-election-provider-multi-phase",
|
"pallet-election-provider-multi-phase",
|
||||||
"pallet-staking",
|
"pallet-staking",
|
||||||
"pallet-transaction-payment",
|
"pallet-transaction-payment",
|
||||||
@@ -10182,6 +10183,7 @@ dependencies = [
|
|||||||
"sp-runtime",
|
"sp-runtime",
|
||||||
"sp-version",
|
"sp-version",
|
||||||
"structopt",
|
"structopt",
|
||||||
|
"sub-tokens",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio 0.2.21",
|
"tokio 0.2.21",
|
||||||
"westend-runtime",
|
"westend-runtime",
|
||||||
@@ -10282,6 +10284,14 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sub-tokens"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "git+https://github.com/paritytech/substrate-debug-kit?branch=master#971b667963fdb0049dae349eaecbe22f4181e49f"
|
||||||
|
dependencies = [
|
||||||
|
"separator",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "substrate-bip39"
|
name = "substrate-bip39"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ thiserror = "1.0.26"
|
|||||||
remote-externalities = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
remote-externalities = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|
||||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-io = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-npos-elections = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
@@ -32,6 +33,7 @@ frame-support = { git = "https://github.com/paritytech/substrate", branch = "mas
|
|||||||
frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
frame-election-provider-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-election-provider-multi-phase = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-staking = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|
||||||
core-primitives = { package = "polkadot-core-primitives", path = "../../core-primitives" }
|
core-primitives = { package = "polkadot-core-primitives", path = "../../core-primitives" }
|
||||||
@@ -41,5 +43,7 @@ polkadot-runtime = { path = "../../runtime/polkadot" }
|
|||||||
kusama-runtime = { path = "../../runtime/kusama" }
|
kusama-runtime = { path = "../../runtime/kusama" }
|
||||||
westend-runtime = { path = "../../runtime/westend" }
|
westend-runtime = { path = "../../runtime/westend" }
|
||||||
|
|
||||||
|
sub-tokens = { git = "https://github.com/paritytech/substrate-debug-kit", branch = "master" }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ use crate::{
|
|||||||
params, prelude::*, rpc_helpers::*, signer::Signer, DryRunConfig, Error, SharedConfig, WsClient,
|
params, prelude::*, rpc_helpers::*, signer::Signer, DryRunConfig, Error, SharedConfig, WsClient,
|
||||||
};
|
};
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
|
use frame_support::traits::Currency;
|
||||||
|
|
||||||
/// Forcefully create the snapshot. This can be used to compute the election at anytime.
|
/// Forcefully create the snapshot. This can be used to compute the election at anytime.
|
||||||
fn force_create_snapshot<T: EPM::Config>(ext: &mut Ext) -> Result<(), Error> {
|
fn force_create_snapshot<T: EPM::Config>(ext: &mut Ext) -> Result<(), Error> {
|
||||||
@@ -35,18 +36,53 @@ fn force_create_snapshot<T: EPM::Config>(ext: &mut Ext) -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Helper method to print the encoded size of the snapshot.
|
/// Helper method to print the encoded size of the snapshot.
|
||||||
fn measure_snapshot_size<T: EPM::Config>(ext: &mut Ext) {
|
async fn print_info<T: EPM::Config>(
|
||||||
|
client: &WsClient,
|
||||||
|
ext: &mut Ext,
|
||||||
|
raw_solution: &EPM::RawSolution<EPM::SolutionOf<T>>,
|
||||||
|
extrinsic: sp_core::Bytes,
|
||||||
|
) where
|
||||||
|
<T as EPM::Config>::Currency: Currency<T::AccountId, Balance = Balance>,
|
||||||
|
{
|
||||||
ext.execute_with(|| {
|
ext.execute_with(|| {
|
||||||
log::info!(target: LOG_TARGET, "Metadata: {:?}", <EPM::Pallet<T>>::snapshot_metadata());
|
|
||||||
log::info!(
|
log::info!(
|
||||||
target: LOG_TARGET,
|
target: LOG_TARGET,
|
||||||
"Encoded Length: {:?}",
|
"Snapshot Metadata: {:?}",
|
||||||
|
<EPM::Pallet<T>>::snapshot_metadata()
|
||||||
|
);
|
||||||
|
log::info!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
"Snapshot Encoded Length: {:?}",
|
||||||
<EPM::Pallet<T>>::snapshot()
|
<EPM::Pallet<T>>::snapshot()
|
||||||
.expect("snapshot must exist before calling `measure_snapshot_size`")
|
.expect("snapshot must exist before calling `measure_snapshot_size`")
|
||||||
.encode()
|
.encode()
|
||||||
.len()
|
.len()
|
||||||
);
|
);
|
||||||
})
|
|
||||||
|
let snapshot_size =
|
||||||
|
<EPM::Pallet<T>>::snapshot_metadata().expect("snapshot must exist by now; qed.");
|
||||||
|
let deposit = EPM::Pallet::<T>::deposit_for(&raw_solution, snapshot_size);
|
||||||
|
log::info!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
"solution score {:?} / deposit {:?} / length {:?}",
|
||||||
|
&raw_solution.score.iter().map(|x| Token::from(*x)).collect::<Vec<_>>(),
|
||||||
|
Token::from(deposit),
|
||||||
|
raw_solution.encode().len(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
let info = rpc::<pallet_transaction_payment::RuntimeDispatchInfo<Balance>>(
|
||||||
|
client,
|
||||||
|
"payment_queryInfo",
|
||||||
|
params! { extrinsic },
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
log::info!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
"payment_queryInfo: (fee = {}) {:?}",
|
||||||
|
info.as_ref().map(|d| Token::from(d.partial_fee)).unwrap_or(Token::from(0)),
|
||||||
|
info,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find the stake threshold in order to have at most `count` voters.
|
/// Find the stake threshold in order to have at most `count` voters.
|
||||||
@@ -76,24 +112,40 @@ macro_rules! dry_run_cmd_for { ($runtime:ident) => { paste::paste! {
|
|||||||
signer: Signer,
|
signer: Signer,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
use $crate::[<$runtime _runtime_exports>]::*;
|
use $crate::[<$runtime _runtime_exports>]::*;
|
||||||
let mut ext = crate::create_election_ext::<Runtime, Block>(shared.uri.clone(), config.at, true).await?;
|
let mut ext = crate::create_election_ext::<Runtime, Block>(
|
||||||
|
shared.uri.clone(),
|
||||||
|
config.at,
|
||||||
|
vec!["Staking".to_string(), "System".to_string(), "Balances".to_string()]
|
||||||
|
).await?;
|
||||||
force_create_snapshot::<Runtime>(&mut ext)?;
|
force_create_snapshot::<Runtime>(&mut ext)?;
|
||||||
measure_snapshot_size::<Runtime>(&mut ext);
|
|
||||||
let (raw_solution, witness) = crate::mine_unchecked::<Runtime>(&mut ext, config.iterations, false)?;
|
|
||||||
log::info!(target: LOG_TARGET, "mined solution with {:?}", &raw_solution.score);
|
|
||||||
|
|
||||||
|
let (raw_solution, witness) = crate::mine_unchecked::<Runtime>(&mut ext, config.iterations, false)?;
|
||||||
let nonce = crate::get_account_info::<Runtime>(client, &signer.account, config.at)
|
let nonce = crate::get_account_info::<Runtime>(client, &signer.account, config.at)
|
||||||
.await?
|
.await?
|
||||||
.map(|i| i.nonce)
|
.map(|i| i.nonce)
|
||||||
.expect("signer account is checked to exist upon startup; it can only die if it \
|
.expect("signer account is checked to exist upon startup; it can only die if it \
|
||||||
transfers funds out of it, or get slashed. If it does not exist at this point, \
|
transfers funds out of it, or get slashed. If it does not exist at this point, \
|
||||||
it is likely due to a bug, or the signer got slashed. Terminating."
|
it is likely due to a bug, or the signer got slashed. Terminating."
|
||||||
);
|
);
|
||||||
let tip = 0 as Balance;
|
let tip = 0 as Balance;
|
||||||
let era = sp_runtime::generic::Era::Immortal;
|
let era = sp_runtime::generic::Era::Immortal;
|
||||||
let extrinsic = ext.execute_with(|| create_uxt(raw_solution, witness, signer.clone(), nonce, tip, era));
|
let extrinsic = ext.execute_with(|| create_uxt(raw_solution.clone(), witness, signer.clone(), nonce, tip, era));
|
||||||
|
|
||||||
let bytes = sp_core::Bytes(extrinsic.encode().to_vec());
|
let bytes = sp_core::Bytes(extrinsic.encode().to_vec());
|
||||||
|
print_info::<Runtime>(client, &mut ext, &raw_solution, bytes.clone()).await;
|
||||||
|
|
||||||
|
let feasibility_result = ext.execute_with(|| {
|
||||||
|
EPM::Pallet::<Runtime>::feasibility_check(raw_solution.clone(), EPM::ElectionCompute::Signed)
|
||||||
|
});
|
||||||
|
log::info!(target: LOG_TARGET, "feasibility result is {:?}", feasibility_result.map(|_| ()));
|
||||||
|
|
||||||
|
let dispatch_result = ext.execute_with(|| {
|
||||||
|
// manually tweak the phase.
|
||||||
|
EPM::CurrentPhase::<Runtime>::put(EPM::Phase::Signed);
|
||||||
|
EPM::Pallet::<Runtime>::submit(frame_system::RawOrigin::Signed(signer.account).into(), Box::new(raw_solution), witness)
|
||||||
|
});
|
||||||
|
log::info!(target: LOG_TARGET, "dispatch result is {:?}", dispatch_result);
|
||||||
|
|
||||||
let outcome = rpc_decode::<sp_runtime::ApplyExtrinsicResult>(client, "system_dryRun", params!{ bytes }).await?;
|
let outcome = rpc_decode::<sp_runtime::ApplyExtrinsicResult>(client, "system_dryRun", params!{ bytes }).await?;
|
||||||
log::info!(target: LOG_TARGET, "dry-run outcome is {:?}", outcome);
|
log::info!(target: LOG_TARGET, "dry-run outcome is {:?}", outcome);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ macro_rules! emergency_solution_cmd_for { ($runtime:ident) => { paste::paste! {
|
|||||||
shared: SharedConfig,
|
shared: SharedConfig,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
use $crate::[<$runtime _runtime_exports>]::*;
|
use $crate::[<$runtime _runtime_exports>]::*;
|
||||||
let mut ext = crate::create_election_ext::<Runtime, Block>(shared.uri.clone(), None, false).await?;
|
let mut ext = crate::create_election_ext::<Runtime, Block>(shared.uri.clone(), None, vec![]).await?;
|
||||||
ext.execute_with(|| {
|
ext.execute_with(|| {
|
||||||
assert!(EPM::Pallet::<Runtime>::current_phase().is_emergency());
|
assert!(EPM::Pallet::<Runtime>::current_phase().is_emergency());
|
||||||
// NOTE: this internally calls feasibility_check, but we just re-do it here as an easy way
|
// NOTE: this internally calls feasibility_check, but we just re-do it here as an easy way
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ mod signer;
|
|||||||
pub(crate) use prelude::*;
|
pub(crate) use prelude::*;
|
||||||
pub(crate) use signer::get_account_info;
|
pub(crate) use signer::get_account_info;
|
||||||
|
|
||||||
|
use frame_support::traits::Get;
|
||||||
use jsonrpsee_ws_client::{WsClient, WsClientBuilder};
|
use jsonrpsee_ws_client::{WsClient, WsClientBuilder};
|
||||||
use remote_externalities::{Builder, Mode, OnlineConfig};
|
use remote_externalities::{Builder, Mode, OnlineConfig};
|
||||||
use sp_runtime::traits::Block as BlockT;
|
use sp_runtime::traits::Block as BlockT;
|
||||||
@@ -93,8 +94,9 @@ macro_rules! construct_runtime_prelude {
|
|||||||
let address = <Runtime as frame_system::Config>::Lookup::unlookup(account.clone());
|
let address = <Runtime as frame_system::Config>::Lookup::unlookup(account.clone());
|
||||||
let extrinsic = UncheckedExtrinsic::new_signed(call, address, signature.into(), extra);
|
let extrinsic = UncheckedExtrinsic::new_signed(call, address, signature.into(), extra);
|
||||||
log::debug!(
|
log::debug!(
|
||||||
target: crate::LOG_TARGET, "constructed extrinsic {}",
|
target: crate::LOG_TARGET, "constructed extrinsic {} with length {}",
|
||||||
sp_core::hexdisplay::HexDisplay::from(&extrinsic.encode())
|
sp_core::hexdisplay::HexDisplay::from(&extrinsic.encode()),
|
||||||
|
extrinsic.encode().len(),
|
||||||
);
|
);
|
||||||
extrinsic
|
extrinsic
|
||||||
}
|
}
|
||||||
@@ -172,14 +174,17 @@ macro_rules! any_runtime {
|
|||||||
unsafe {
|
unsafe {
|
||||||
match $crate::RUNTIME {
|
match $crate::RUNTIME {
|
||||||
$crate::AnyRuntime::Polkadot => {
|
$crate::AnyRuntime::Polkadot => {
|
||||||
|
#[allow(unused)]
|
||||||
use $crate::polkadot_runtime_exports::*;
|
use $crate::polkadot_runtime_exports::*;
|
||||||
$($code)*
|
$($code)*
|
||||||
},
|
},
|
||||||
$crate::AnyRuntime::Kusama => {
|
$crate::AnyRuntime::Kusama => {
|
||||||
|
#[allow(unused)]
|
||||||
use $crate::kusama_runtime_exports::*;
|
use $crate::kusama_runtime_exports::*;
|
||||||
$($code)*
|
$($code)*
|
||||||
},
|
},
|
||||||
$crate::AnyRuntime::Westend => {
|
$crate::AnyRuntime::Westend => {
|
||||||
|
#[allow(unused)]
|
||||||
use $crate::westend_runtime_exports::*;
|
use $crate::westend_runtime_exports::*;
|
||||||
$($code)*
|
$($code)*
|
||||||
}
|
}
|
||||||
@@ -201,6 +206,7 @@ enum Error {
|
|||||||
AccountDoesNotExists,
|
AccountDoesNotExists,
|
||||||
IncorrectPhase,
|
IncorrectPhase,
|
||||||
AlreadySubmitted,
|
AlreadySubmitted,
|
||||||
|
VersionMismatch,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<sp_core::crypto::SecretStringError> for Error {
|
impl From<sp_core::crypto::SecretStringError> for Error {
|
||||||
@@ -270,14 +276,14 @@ struct DryRunConfig {
|
|||||||
#[derive(Debug, Clone, StructOpt)]
|
#[derive(Debug, Clone, StructOpt)]
|
||||||
struct SharedConfig {
|
struct SharedConfig {
|
||||||
/// The `ws` node to connect to.
|
/// The `ws` node to connect to.
|
||||||
#[structopt(long, default_value = DEFAULT_URI)]
|
#[structopt(long, short, default_value = DEFAULT_URI)]
|
||||||
uri: String,
|
uri: String,
|
||||||
|
|
||||||
/// The file from which we read the account seed.
|
/// The file from which we read the account seed.
|
||||||
///
|
///
|
||||||
/// WARNING: don't use an account with a large stash for this. Based on how the bot is
|
/// WARNING: don't use an account with a large stash for this. Based on how the bot is
|
||||||
/// configured, it might re-try lose funds through transaction fees/deposits.
|
/// configured, it might re-try lose funds through transaction fees/deposits.
|
||||||
#[structopt(long)]
|
#[structopt(long, short)]
|
||||||
account_seed: std::path::PathBuf,
|
account_seed: std::path::PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -291,34 +297,25 @@ struct Opt {
|
|||||||
command: Command,
|
command: Command,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build the `Ext` at `hash` with all the data of `ElectionProviderMultiPhase` and `Staking`
|
/// Build the Ext at hash with all the data of `ElectionProviderMultiPhase` and any additional
|
||||||
/// stored.
|
/// pallets.
|
||||||
async fn create_election_ext<T: EPM::Config, B: BlockT>(
|
async fn create_election_ext<T: EPM::Config, B: BlockT>(
|
||||||
uri: String,
|
uri: String,
|
||||||
at: Option<B::Hash>,
|
at: Option<B::Hash>,
|
||||||
with_staking: bool,
|
additional: Vec<String>,
|
||||||
) -> Result<Ext, Error> {
|
) -> Result<Ext, Error> {
|
||||||
use frame_support::{storage::generator::StorageMap, traits::PalletInfo};
|
use frame_support::{storage::generator::StorageMap, traits::PalletInfo};
|
||||||
use sp_core::hashing::twox_128;
|
use sp_core::hashing::twox_128;
|
||||||
|
|
||||||
|
let mut modules = vec![<T as frame_system::Config>::PalletInfo::name::<EPM::Pallet<T>>()
|
||||||
|
.expect("Pallet always has name; qed.")
|
||||||
|
.to_string()];
|
||||||
|
modules.extend(additional);
|
||||||
Builder::<B>::new()
|
Builder::<B>::new()
|
||||||
.mode(Mode::Online(OnlineConfig {
|
.mode(Mode::Online(OnlineConfig {
|
||||||
transport: uri.into(),
|
transport: uri.into(),
|
||||||
at,
|
at,
|
||||||
modules: if with_staking {
|
modules,
|
||||||
vec![
|
|
||||||
<T as frame_system::Config>::PalletInfo::name::<EPM::Pallet<T>>()
|
|
||||||
.expect("Pallet always has name; qed.")
|
|
||||||
.to_string(),
|
|
||||||
<T as frame_system::Config>::PalletInfo::name::<pallet_staking::Pallet<T>>()
|
|
||||||
.expect("Pallet always has name; qed.")
|
|
||||||
.to_string(),
|
|
||||||
]
|
|
||||||
} else {
|
|
||||||
vec![<T as frame_system::Config>::PalletInfo::name::<EPM::Pallet<T>>()
|
|
||||||
.expect("Pallet always has name; qed.")
|
|
||||||
.to_string()]
|
|
||||||
},
|
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}))
|
}))
|
||||||
.inject_hashed_prefix(&<frame_system::BlockHash<T>>::prefix_hash())
|
.inject_hashed_prefix(&<frame_system::BlockHash<T>>::prefix_hash())
|
||||||
@@ -386,6 +383,34 @@ fn mine_dpos<T: EPM::Config>(ext: &mut Ext) -> Result<(), Error> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn check_versions<T: frame_system::Config>(
|
||||||
|
client: &WsClient,
|
||||||
|
print: bool,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
let linked_version = T::Version::get();
|
||||||
|
let on_chain_version = rpc_helpers::rpc::<sp_version::RuntimeVersion>(
|
||||||
|
client,
|
||||||
|
"state_getRuntimeVersion",
|
||||||
|
params! {},
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.expect("runtime version RPC should always work; qed");
|
||||||
|
|
||||||
|
if print {
|
||||||
|
log::info!(target: LOG_TARGET, "linked version {:?}", linked_version);
|
||||||
|
log::info!(target: LOG_TARGET, "on-chain version {:?}", on_chain_version);
|
||||||
|
}
|
||||||
|
if linked_version != on_chain_version {
|
||||||
|
log::error!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
"VERSION MISMATCH: any transaction will fail with bad-proof"
|
||||||
|
);
|
||||||
|
Err(Error::VersionMismatch)
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
env_logger::Builder::from_default_env()
|
env_logger::Builder::from_default_env()
|
||||||
@@ -422,6 +447,8 @@ async fn main() {
|
|||||||
sp_core::crypto::set_default_ss58_version(
|
sp_core::crypto::set_default_ss58_version(
|
||||||
sp_core::crypto::Ss58AddressFormat::PolkadotAccount,
|
sp_core::crypto::Ss58AddressFormat::PolkadotAccount,
|
||||||
);
|
);
|
||||||
|
sub_tokens::dynamic::set_name("DOT");
|
||||||
|
sub_tokens::dynamic::set_decimal_points(10_000_000_000);
|
||||||
// safety: this program will always be single threaded, thus accessing global static is
|
// safety: this program will always be single threaded, thus accessing global static is
|
||||||
// safe.
|
// safe.
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -432,6 +459,8 @@ async fn main() {
|
|||||||
sp_core::crypto::set_default_ss58_version(
|
sp_core::crypto::set_default_ss58_version(
|
||||||
sp_core::crypto::Ss58AddressFormat::KusamaAccount,
|
sp_core::crypto::Ss58AddressFormat::KusamaAccount,
|
||||||
);
|
);
|
||||||
|
sub_tokens::dynamic::set_name("KSM");
|
||||||
|
sub_tokens::dynamic::set_decimal_points(1_000_000_000_000);
|
||||||
// safety: this program will always be single threaded, thus accessing global static is
|
// safety: this program will always be single threaded, thus accessing global static is
|
||||||
// safe.
|
// safe.
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -442,6 +471,8 @@ async fn main() {
|
|||||||
sp_core::crypto::set_default_ss58_version(
|
sp_core::crypto::set_default_ss58_version(
|
||||||
sp_core::crypto::Ss58AddressFormat::PolkadotAccount,
|
sp_core::crypto::Ss58AddressFormat::PolkadotAccount,
|
||||||
);
|
);
|
||||||
|
sub_tokens::dynamic::set_name("WND");
|
||||||
|
sub_tokens::dynamic::set_decimal_points(1_000_000_000_000);
|
||||||
// safety: this program will always be single threaded, thus accessing global static is
|
// safety: this program will always be single threaded, thus accessing global static is
|
||||||
// safe.
|
// safe.
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -455,6 +486,10 @@ async fn main() {
|
|||||||
}
|
}
|
||||||
log::info!(target: LOG_TARGET, "connected to chain {:?}", chain);
|
log::info!(target: LOG_TARGET, "connected to chain {:?}", chain);
|
||||||
|
|
||||||
|
let _ = any_runtime! {
|
||||||
|
check_versions::<Runtime>(&client, true).await
|
||||||
|
};
|
||||||
|
|
||||||
let signer_account = any_runtime! {
|
let signer_account = any_runtime! {
|
||||||
signer::read_signer_uri::<_, Runtime>(&shared.account_seed, &client)
|
signer::read_signer_uri::<_, Runtime>(&shared.account_seed, &client)
|
||||||
.await
|
.await
|
||||||
@@ -464,7 +499,6 @@ async fn main() {
|
|||||||
let outcome = any_runtime! {
|
let outcome = any_runtime! {
|
||||||
match command.clone() {
|
match command.clone() {
|
||||||
Command::Monitor(c) => monitor_cmd(&client, shared, c, signer_account).await,
|
Command::Monitor(c) => monitor_cmd(&client, shared, c, signer_account).await,
|
||||||
// --------------------^^ comes from the macro prelude, needs no generic.
|
|
||||||
Command::DryRun(c) => dry_run_cmd(&client, shared, c, signer_account).await,
|
Command::DryRun(c) => dry_run_cmd(&client, shared, c, signer_account).await,
|
||||||
Command::EmergencySolution => emergency_solution_cmd(shared.clone()).await,
|
Command::EmergencySolution => emergency_solution_cmd(shared.clone()).await,
|
||||||
}
|
}
|
||||||
@@ -477,7 +511,6 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
fn get_version<T: frame_system::Config>() -> sp_version::RuntimeVersion {
|
fn get_version<T: frame_system::Config>() -> sp_version::RuntimeVersion {
|
||||||
use frame_support::traits::Get;
|
|
||||||
T::Version::get()
|
T::Version::get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -86,6 +86,9 @@ macro_rules! monitor_cmd_for { ($runtime:tt) => { paste::paste! {
|
|||||||
let hash = now.hash();
|
let hash = now.hash();
|
||||||
log::debug!(target: LOG_TARGET, "new event at #{:?} ({:?})", now.number, hash);
|
log::debug!(target: LOG_TARGET, "new event at #{:?} ({:?})", now.number, hash);
|
||||||
|
|
||||||
|
// if the runtime version has changed, terminate
|
||||||
|
crate::check_versions::<Runtime>(client, false).await?;
|
||||||
|
|
||||||
// we prefer doing this check before fetching anything into a remote-ext.
|
// we prefer doing this check before fetching anything into a remote-ext.
|
||||||
if ensure_signed_phase::<Runtime, Block>(client, hash).await.is_err() {
|
if ensure_signed_phase::<Runtime, Block>(client, hash).await.is_err() {
|
||||||
log::debug!(target: LOG_TARGET, "phase closed, not interested in this block at all.");
|
log::debug!(target: LOG_TARGET, "phase closed, not interested in this block at all.");
|
||||||
@@ -99,7 +102,7 @@ macro_rules! monitor_cmd_for { ($runtime:tt) => { paste::paste! {
|
|||||||
// this will not be a solution.
|
// this will not be a solution.
|
||||||
|
|
||||||
// grab an externalities without staking, just the election snapshot.
|
// grab an externalities without staking, just the election snapshot.
|
||||||
let mut ext = crate::create_election_ext::<Runtime, Block>(shared.uri.clone(), Some(hash), false).await?;
|
let mut ext = crate::create_election_ext::<Runtime, Block>(shared.uri.clone(), Some(hash), vec![]).await?;
|
||||||
|
|
||||||
if ensure_no_previous_solution::<Runtime, Block>(&mut ext, &signer.account).await.is_err() {
|
if ensure_no_previous_solution::<Runtime, Block>(&mut ext, &signer.account).await.is_err() {
|
||||||
log::debug!(target: LOG_TARGET, "We already have a solution in this phase, skipping.");
|
log::debug!(target: LOG_TARGET, "We already have a solution in this phase, skipping.");
|
||||||
|
|||||||
@@ -46,3 +46,6 @@ pub type Ext = sp_io::TestExternalities;
|
|||||||
|
|
||||||
/// The key pair type being used. We "strongly" assume sr25519 for simplicity.
|
/// The key pair type being used. We "strongly" assume sr25519 for simplicity.
|
||||||
pub type Pair = sp_core::sr25519::Pair;
|
pub type Pair = sp_core::sr25519::Pair;
|
||||||
|
|
||||||
|
/// A dynamic token type used to represent account balances.
|
||||||
|
pub type Token = sub_tokens::dynamic::DynamicToken;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
//! Wrappers around creating a signer account.
|
//! Wrappers around creating a signer account.
|
||||||
|
|
||||||
use crate::{rpc_helpers, AccountId, Error, Index, Pair, WsClient, LOG_TARGET};
|
use crate::{prelude::*, rpc_helpers, AccountId, Error, Index, Pair, WsClient, LOG_TARGET};
|
||||||
use sp_core::crypto::Pair as _;
|
use sp_core::crypto::Pair as _;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
@@ -54,7 +54,11 @@ pub(crate) async fn get_account_info<T: frame_system::Config>(
|
|||||||
/// Read the signer account's URI from the given `path`.
|
/// Read the signer account's URI from the given `path`.
|
||||||
pub(crate) async fn read_signer_uri<
|
pub(crate) async fn read_signer_uri<
|
||||||
P: AsRef<Path>,
|
P: AsRef<Path>,
|
||||||
T: frame_system::Config<AccountId = AccountId, Index = Index>,
|
T: frame_system::Config<
|
||||||
|
AccountId = AccountId,
|
||||||
|
Index = Index,
|
||||||
|
AccountData = pallet_balances::AccountData<Balance>,
|
||||||
|
>,
|
||||||
>(
|
>(
|
||||||
path: P,
|
path: P,
|
||||||
client: &WsClient,
|
client: &WsClient,
|
||||||
@@ -69,6 +73,12 @@ pub(crate) async fn read_signer_uri<
|
|||||||
let _info = get_account_info::<T>(&client, &account, None)
|
let _info = get_account_info::<T>(&client, &account, None)
|
||||||
.await?
|
.await?
|
||||||
.ok_or(Error::AccountDoesNotExists)?;
|
.ok_or(Error::AccountDoesNotExists)?;
|
||||||
log::info!(target: LOG_TARGET, "loaded account {:?}, info: {:?}", &account, _info);
|
log::info!(
|
||||||
|
target: LOG_TARGET,
|
||||||
|
"loaded account {:?}, free: {:?}, info: {:?}",
|
||||||
|
&account,
|
||||||
|
Token::from(_info.data.free),
|
||||||
|
_info
|
||||||
|
);
|
||||||
Ok(Signer { account, pair, uri: uri.to_string() })
|
Ok(Signer { account, pair, uri: uri.to_string() })
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user