-
Notifications
You must be signed in to change notification settings - Fork 20
Expand file tree
/
Copy pathemergency_solution.rs
More file actions
107 lines (87 loc) · 3.44 KB
/
emergency_solution.rs
File metadata and controls
107 lines (87 loc) · 3.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright 2021-2022 Parity Technologies (UK) Ltd.
// This file is part of Polkadot.
// Polkadot is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// Polkadot is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
//! The emergency-solution command.
use crate::{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 = 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(())
}