Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Commit

Permalink
fix restart issue of staking miner (#4073)
Browse files Browse the repository at this point in the history
Co-authored-by: Niklas Adolfsson <niklasadolfsson1@gmail.com>
  • Loading branch information
kianenigma and niklasad1 committed Oct 14, 2021
1 parent 9064024 commit 1844519
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 142 deletions.
4 changes: 2 additions & 2 deletions utils/staking-miner/src/dry_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ macro_rules! dry_run_cmd_for { ($runtime:ident) => { paste::paste! {
let mut ext = crate::create_election_ext::<Runtime, Block>(
shared.uri.clone(),
config.at,
vec!["Staking".to_string(), "System".to_string(), "Balances".to_string()]
vec!["Staking".to_string(), "System".to_string()],
).await?;
force_create_snapshot::<Runtime>(&mut ext)?;

let (raw_solution, witness) = crate::mine_with::<Runtime>(&config.solver, &mut ext)?;
let (raw_solution, witness) = crate::mine_with::<Runtime>(&config.solver, &mut ext, false)?;

let nonce = crate::get_account_info::<Runtime>(client, &signer.account, config.at)
.await?
Expand Down
22 changes: 16 additions & 6 deletions utils/staking-miner/src/emergency_solution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

//! The emergency-solution command.

use crate::{prelude::*, Error, SharedConfig};
use crate::{prelude::*, EmergencySolutionConfig, Error, SharedConfig};
use codec::Encode;
use frame_election_provider_support::SequentialPhragmen;
use std::io::Write;
Expand All @@ -25,25 +25,35 @@ macro_rules! emergency_solution_cmd_for { ($runtime:ident) => { paste::paste! {
/// Execute the emergency-solution command.
pub(crate) async fn [<emergency_solution_cmd_ $runtime>](
shared: SharedConfig,
config: EmergencySolutionConfig,
) -> Result<(), Error<$crate::[<$runtime _runtime_exports>]::Runtime>> {
use $crate::[<$runtime _runtime_exports>]::*;
let mut ext = crate::create_election_ext::<Runtime, Block>(shared.uri.clone(), None, vec![]).await?;
ext.execute_with(|| {
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
// to get a `ReadySolution`.
let (raw_solution, _) =
<EPM::Pallet<Runtime>>::mine_solution::<SequentialPhragmen<AccountId, sp_runtime::Perbill>>()?;
log::info!(target: LOG_TARGET, "mined solution with {:?}", &raw_solution.score);
let ready_solution = EPM::Pallet::<Runtime>::feasibility_check(raw_solution, EPM::ElectionCompute::Signed)?;
let encoded_ready = ready_solution.encode();
let mut ready_solution = EPM::Pallet::<Runtime>::feasibility_check(raw_solution, EPM::ElectionCompute::Signed)?;

// maybe truncate.
if let Some(take) = config.take {
log::info!(target: LOG_TARGET, "truncating {} winners to {}", ready_solution.supports.len(), take);
ready_solution.supports.sort_unstable_by_key(|(_, s)| s.total);
ready_solution.supports.truncate(take);
}

// write to file and stdout.
let encoded_support = ready_solution.supports.encode();
let mut solution_file = std::fs::File::create("solution.bin")?;
let mut supports_file = std::fs::File::create("solution.supports.bin")?;
solution_file.write_all(&encoded_ready)?;
supports_file.write_all(&encoded_support)?;
log::info!(target: LOG_TARGET, "ReadySolution: size {:?} / score = {:?}", encoded_ready.len(), ready_solution.score);

log::info!(target: LOG_TARGET, "ReadySolution: size {:?} / score = {:?}", ready_solution.encoded_size(), ready_solution.score);
log::trace!(target: LOG_TARGET, "Supports: {}", sp_core::hexdisplay::HexDisplay::from(&encoded_support));

Ok(())
})
}
Expand Down
103 changes: 59 additions & 44 deletions utils/staking-miner/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ enum Command {
/// Just compute a solution now, and don't submit it.
DryRun(DryRunConfig),
/// Provide a solution that can be submitted to the chain as an emergency response.
EmergencySolution,
EmergencySolution(EmergencySolutionConfig),
}

#[derive(Debug, Clone, StructOpt)]
Expand All @@ -291,39 +291,6 @@ enum Solvers {
},
}

/// Mine a solution with the given `solver`.
fn mine_with<T>(
solver: &Solvers,
ext: &mut Ext,
) -> Result<(EPM::RawSolution<EPM::SolutionOf<T>>, u32), Error<T>>
where
T: EPM::Config,
T::Solver: NposSolver<Error = sp_npos_elections::Error>,
{
use frame_election_provider_support::{PhragMMS, SequentialPhragmen};

match solver {
Solvers::SeqPhragmen { iterations } => {
BalanceIterations::set(*iterations);
mine_unchecked::<
T,
SequentialPhragmen<
<T as frame_system::Config>::AccountId,
sp_runtime::Perbill,
Balancing,
>,
>(ext, false)
},
Solvers::PhragMMS { iterations } => {
BalanceIterations::set(*iterations);
mine_unchecked::<
T,
PhragMMS<<T as frame_system::Config>::AccountId, sp_runtime::Perbill, Balancing>,
>(ext, false)
},
}
}

frame_support::parameter_types! {
/// Number of balancing iterations for a solution algorithm. Set based on the [`Solvers`] CLI
/// config.
Expand All @@ -341,16 +308,32 @@ struct MonitorConfig {
#[structopt(long, default_value = "head", possible_values = &["head", "finalized"])]
listen: String,

/// The solver algorithm to use.
#[structopt(subcommand)]
solver: Solvers,
}

#[derive(Debug, Clone, StructOpt)]
struct EmergencySolutionConfig {
/// The block hash at which scraping happens. If none is provided, the latest head is used.
#[structopt(long)]
at: Option<Hash>,

/// The solver algorithm to use.
#[structopt(subcommand)]
solver: Solvers,

/// The number of top backed winners to take. All are taken, if not provided.
take: Option<usize>,
}

#[derive(Debug, Clone, StructOpt)]
struct DryRunConfig {
/// The block hash at which scraping happens. If none is provided, the latest head is used.
#[structopt(long)]
at: Option<Hash>,

/// The solver algorithm to use.
#[structopt(subcommand)]
solver: Solvers,
}
Expand Down Expand Up @@ -407,9 +390,9 @@ async fn create_election_ext<T: EPM::Config, B: BlockT>(
.map_err(|why| Error::RemoteExternalities(why))
}

/// Compute the election at the given block number. It expects to NOT be `Phase::Off`. In other
/// words, the snapshot must exists on the given externalities.
fn mine_unchecked<T, S>(
/// Compute the election. It expects to NOT be `Phase::Off`. In other words, the snapshot must
/// exists on the given externalities.
fn mine_solution<T, S>(
ext: &mut Ext,
do_feasibility: bool,
) -> Result<(EPM::RawSolution<EPM::SolutionOf<T>>, u32), Error<T>>
Expand All @@ -434,6 +417,40 @@ where
})
}

/// Mine a solution with the given `solver`.
fn mine_with<T>(
solver: &Solvers,
ext: &mut Ext,
do_feasibility: bool,
) -> Result<(EPM::RawSolution<EPM::SolutionOf<T>>, u32), Error<T>>
where
T: EPM::Config,
T::Solver: NposSolver<Error = sp_npos_elections::Error>,
{
use frame_election_provider_support::{PhragMMS, SequentialPhragmen};

match solver {
Solvers::SeqPhragmen { iterations } => {
BalanceIterations::set(*iterations);
mine_solution::<
T,
SequentialPhragmen<
<T as frame_system::Config>::AccountId,
sp_runtime::Perbill,
Balancing,
>,
>(ext, do_feasibility)
},
Solvers::PhragMMS { iterations } => {
BalanceIterations::set(*iterations);
mine_solution::<
T,
PhragMMS<<T as frame_system::Config>::AccountId, sp_runtime::Perbill, Balancing>,
>(ext, do_feasibility)
},
}
}

#[allow(unused)]
fn mine_dpos<T: EPM::Config>(ext: &mut Ext) -> Result<(), Error<T>> {
ext.execute_with(|| {
Expand Down Expand Up @@ -474,7 +491,6 @@ fn mine_dpos<T: EPM::Config>(ext: &mut Ext) -> Result<(), Error<T>> {

pub(crate) async fn check_versions<T: frame_system::Config + EPM::Config>(
client: &WsClient,
print: bool,
) -> Result<(), Error<T>> {
let linked_version = T::Version::get();
let on_chain_version = rpc_helpers::rpc::<sp_version::RuntimeVersion>(
Expand All @@ -485,10 +501,9 @@ pub(crate) async fn check_versions<T: frame_system::Config + EPM::Config>(
.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);
}
log::debug!(target: LOG_TARGET, "linked version {:?}", linked_version);
log::debug!(target: LOG_TARGET, "on-chain version {:?}", on_chain_version);

if linked_version != on_chain_version {
log::error!(
target: LOG_TARGET,
Expand Down Expand Up @@ -576,7 +591,7 @@ async fn main() {
log::info!(target: LOG_TARGET, "connected to chain {:?}", chain);

any_runtime_unit! {
check_versions::<Runtime>(&client, true).await
check_versions::<Runtime>(&client).await
};

let signer_account = any_runtime! {
Expand All @@ -595,7 +610,7 @@ async fn main() {
.map_err(|e| {
log::error!(target: LOG_TARGET, "DryRun error: {:?}", e);
}),
Command::EmergencySolution => emergency_solution_cmd(shared.clone()).await
Command::EmergencySolution(c) => emergency_solution_cmd(shared.clone(), c).await
.map_err(|e| {
log::error!(target: LOG_TARGET, "EmergencySolution error: {:?}", e);
}),
Expand Down
Loading

0 comments on commit 1844519

Please sign in to comment.