-
Notifications
You must be signed in to change notification settings - Fork 20
fix: SignedPhase is removed from metadata #803
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
4f3611e
9ca7a6d
160d57d
f0ea52a
b192a73
3dc9b2c
f522c1f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,6 +17,7 @@ | |
| //! The dry-run command. | ||
|
|
||
| use pallet_election_provider_multi_phase::RawSolution; | ||
| use subxt::config::DefaultExtrinsicParamsBuilder; | ||
|
|
||
| use crate::{ | ||
| client::Client, epm, error::Error, helpers::storage_at, opt::Solver, prelude::*, | ||
|
|
@@ -115,12 +116,8 @@ where | |
|
|
||
| let nonce = client.rpc().system_account_next_index(signer.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 params = DefaultExtrinsicParamsBuilder::new().nonce(nonce).build(); | ||
| let xt = client.chain_api().tx().create_signed(&tx, &*signer, params).await?; | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. changed API in subxt |
||
| 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())?; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,7 +29,7 @@ use clap::Parser; | |
| use codec::{Decode, Encode}; | ||
| use frame_election_provider_support::NposSolution; | ||
| use futures::future::TryFutureExt; | ||
| use jsonrpsee::core::Error as JsonRpseeError; | ||
| use jsonrpsee::core::ClientError as JsonRpseeError; | ||
| use pallet_election_provider_multi_phase::{RawSolution, SolutionOf}; | ||
| use sp_runtime::Perbill; | ||
| use std::{str::FromStr, sync::Arc}; | ||
|
|
@@ -163,7 +163,11 @@ impl FromStr for SubmissionStrategy { | |
| } | ||
| } | ||
|
|
||
| pub async fn monitor_cmd<T>(client: Client, config: MonitorConfig) -> Result<(), Error> | ||
| pub async fn monitor_cmd<T>( | ||
| client: Client, | ||
| config: MonitorConfig, | ||
| signed_phase_length: u64, | ||
| ) -> Result<(), Error> | ||
| where | ||
| T: MinerConfig<AccountId = AccountId, MaxVotesPerVoter = static_types::MaxVotesPerVoter> | ||
| + Send | ||
|
|
@@ -237,8 +241,15 @@ where | |
| 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 | ||
| if let Err(err) = mine_and_submit_solution::<T>( | ||
| at, | ||
| client2, | ||
| signer2, | ||
| config2, | ||
| submit_lock2, | ||
| signed_phase_length, | ||
| ) | ||
| .await | ||
| { | ||
| kill_main_task_if_critical_err(&tx2, err) | ||
| } | ||
|
|
@@ -264,6 +275,7 @@ async fn mine_and_submit_solution<T>( | |
| signer: Signer, | ||
| config: MonitorConfig, | ||
| submit_lock: Arc<Mutex<()>>, | ||
| signed_phase_len: u64, | ||
| ) -> Result<(), Error> | ||
| where | ||
| T: MinerConfig<AccountId = AccountId, MaxVotesPerVoter = static_types::MaxVotesPerVoter> | ||
|
|
@@ -437,6 +449,7 @@ where | |
| config.listen, | ||
| config.dry_run, | ||
| &at, | ||
| signed_phase_len, | ||
| ) | ||
| .timed() | ||
| .await | ||
|
|
@@ -530,26 +543,19 @@ async fn submit_and_watch_solution<T: MinerConfig + Send + Sync + 'static>( | |
| listen: Listen, | ||
| dry_run: bool, | ||
| at: &Header, | ||
| signed_phase_length: u64, | ||
| ) -> 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 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to double check: Instead of fetching the signed phase constant from the chain, we define our own signed phase in the static types.rs. And this is because the constant from the chain wasn't what we'd expect? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. from the PR description: its because the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the SignedPhase is removed from the metadata and it will impact the other chains as well when they update the |
||
| .chain_api() | ||
| .constants() | ||
| .at(&runtime::constants().election_provider_multi_phase().signed_phase())?; | ||
| // The extrinsic mortality length is static and it doesn't know when the signed phase ends. | ||
| let xt_cfg = DefaultExtrinsicParamsBuilder::default() | ||
| .mortal(at, signed_phase_len as u64) | ||
| .nonce(nonce) | ||
| .mortal(at, signed_phase_length) | ||
| .build(); | ||
|
|
||
| let xt = | ||
| client | ||
| .chain_api() | ||
| .tx() | ||
| .create_signed_with_nonce(&tx, &*signer, nonce as u64, xt_cfg)?; | ||
| let xt = client.chain_api().tx().create_signed(&tx, &*signer, xt_cfg).await?; | ||
|
|
||
| if dry_run { | ||
| let dry_run_bytes = client.rpc().dry_run(xt.encoded(), None).await?; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,12 +40,10 @@ mod signer; | |
| mod static_types; | ||
|
|
||
| use clap::Parser; | ||
| use codec::Decode; | ||
| use error::Error; | ||
| use futures::future::{BoxFuture, FutureExt}; | ||
| use prelude::*; | ||
| use std::str::FromStr; | ||
| use subxt::backend::rpc::RpcSubscription; | ||
| use tokio::sync::oneshot; | ||
| use tracing_subscriber::EnvFilter; | ||
|
|
||
|
|
@@ -93,17 +91,17 @@ macro_rules! any_runtime { | |
| match $chain { | ||
| $crate::opt::Chain::Polkadot => { | ||
| #[allow(unused)] | ||
| use $crate::static_types::polkadot::MinerConfig; | ||
| use $crate::static_types::polkadot::{MinerConfig, SIGNED_PHASE_LENGTH}; | ||
| $($code)* | ||
| }, | ||
| $crate::opt::Chain::Kusama => { | ||
| #[allow(unused)] | ||
| use $crate::static_types::kusama::MinerConfig; | ||
| use $crate::static_types::kusama::{MinerConfig, SIGNED_PHASE_LENGTH}; | ||
| $($code)* | ||
| }, | ||
| $crate::opt::Chain::Westend => { | ||
| #[allow(unused)] | ||
| use $crate::static_types::westend::MinerConfig; | ||
| use $crate::static_types::westend::{MinerConfig, SIGNED_PHASE_LENGTH}; | ||
| $($code)* | ||
| }, | ||
| } | ||
|
|
@@ -130,11 +128,12 @@ async fn main() -> Result<(), Error> { | |
| // Start a new tokio task to perform the runtime updates in the background. | ||
| // if this fails then the miner will be stopped and has to be re-started. | ||
| let (tx_upgrade, rx_upgrade) = oneshot::channel::<Error>(); | ||
| tokio::spawn(runtime_upgrade_task(client.clone(), tx_upgrade, runtime_version.spec_version)); | ||
| tokio::spawn(runtime_upgrade_task(client.chain_api().clone(), tx_upgrade)); | ||
|
|
||
| let res = any_runtime!(chain, { | ||
| let fut = match command { | ||
| Command::Monitor(cfg) => commands::monitor_cmd::<MinerConfig>(client, cfg).boxed(), | ||
| Command::Monitor(cfg) => | ||
| commands::monitor_cmd::<MinerConfig>(client, cfg, SIGNED_PHASE_LENGTH).boxed(), | ||
| Command::DryRun(cfg) => commands::dry_run_cmd::<MinerConfig>(client, cfg).boxed(), | ||
| Command::EmergencySolution(cfg) => | ||
| commands::emergency_solution_cmd::<MinerConfig>(client, cfg).boxed(), | ||
|
|
@@ -209,85 +208,49 @@ async fn run_command( | |
| } | ||
|
|
||
| /// Runs until the RPC connection fails or updating the metadata failed. | ||
| async fn runtime_upgrade_task(client: Client, tx: oneshot::Sender<Error>, mut spec_version: u32) { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this bug has been fixed in subxt and we can rely on that now :) |
||
| use sp_core::storage::StorageChangeSet; | ||
|
|
||
| async fn new_update_stream( | ||
| client: &Client, | ||
| ) -> Result<RpcSubscription<StorageChangeSet<Hash>>, subxt::Error> { | ||
| use sp_core::Bytes; | ||
| use subxt::rpc_params; | ||
|
|
||
| let storage_key = Bytes(runtime::storage().system().last_runtime_upgrade().to_root_bytes()); | ||
|
|
||
| client | ||
| .raw_rpc() | ||
| .subscribe( | ||
| "state_subscribeStorage", | ||
| rpc_params![vec![storage_key]], | ||
| "state_unsubscribeStorage", | ||
| ) | ||
| .await | ||
| } | ||
| async fn runtime_upgrade_task(client: ChainClient, tx: oneshot::Sender<Error>) { | ||
| let updater = client.updater(); | ||
|
|
||
| let mut update_stream = match new_update_stream(&client).await { | ||
| Ok(s) => s, | ||
| let mut update_stream = match updater.runtime_updates().await { | ||
| Ok(u) => u, | ||
| Err(e) => { | ||
| _ = tx.send(e.into()); | ||
| return; | ||
| let _ = tx.send(e.into()); | ||
| return | ||
| }, | ||
| }; | ||
|
|
||
| let close_err = loop { | ||
| let change_set = match update_stream.next().await { | ||
| Some(Ok(changes)) => changes, | ||
| Some(Err(err)) => break err.into(), | ||
| None => { | ||
| update_stream = match new_update_stream(&client).await { | ||
| Ok(sub) => sub, | ||
| Err(err) => break err.into(), | ||
| loop { | ||
| // if the runtime upgrade subscription fails then try establish a new one and if it fails quit. | ||
| let update = match update_stream.next().await { | ||
| Some(Ok(update)) => update, | ||
| _ => { | ||
| log::warn!(target: LOG_TARGET, "Runtime upgrade subscription failed"); | ||
| update_stream = match updater.runtime_updates().await { | ||
| Ok(u) => u, | ||
| Err(e) => { | ||
| let _ = tx.send(e.into()); | ||
| return | ||
| }, | ||
| }; | ||
| continue; | ||
| continue | ||
| }, | ||
| }; | ||
|
|
||
| let at = change_set.block; | ||
| assert!(change_set.changes.len() < 2, "Only one storage change per runtime upgrade"); | ||
| let Some(bytes) = change_set.changes.get(0).and_then(|v| v.1.clone()) else { continue }; | ||
| let next: runtime::runtime_types::frame_system::LastRuntimeUpgradeInfo = | ||
| match Decode::decode(&mut bytes.0.as_ref()) { | ||
| Ok(n) => n, | ||
| Err(e) => break e.into(), | ||
| }; | ||
|
|
||
| if next.spec_version > spec_version { | ||
| let metadata = match client.rpc().state_get_metadata(Some(at)).await { | ||
| Ok(m) => m, | ||
| Err(err) => break err.into(), | ||
| }; | ||
|
|
||
| let runtime_version = match client.rpc().state_get_runtime_version(Some(at)).await { | ||
| Ok(r) => r, | ||
| Err(err) => break err.into(), | ||
| }; | ||
|
|
||
| client.chain_api().set_metadata(metadata); | ||
| client.chain_api().set_runtime_version(subxt::backend::RuntimeVersion { | ||
| spec_version: runtime_version.spec_version, | ||
| transaction_version: runtime_version.transaction_version, | ||
| }); | ||
|
|
||
| spec_version = next.spec_version; | ||
| prometheus::on_runtime_upgrade(); | ||
|
|
||
| log::info!(target: LOG_TARGET, "Runtime upgraded to v{spec_version}"); | ||
| if let Err(e) = epm::update_metadata_constants(client.chain_api()) { | ||
| break e; | ||
| } | ||
| let version = update.runtime_version().spec_version; | ||
| match updater.apply_update(update) { | ||
| Ok(()) => { | ||
| if let Err(e) = epm::update_metadata_constants(&client) { | ||
| let _ = tx.send(e); | ||
| return | ||
| } | ||
| prometheus::on_runtime_upgrade(); | ||
| log::info!(target: LOG_TARGET, "upgrade to version: {} successful", version); | ||
| }, | ||
| Err(e) => { | ||
| log::debug!(target: LOG_TARGET, "upgrade to version: {} failed: {:?}", version, e); | ||
| }, | ||
| } | ||
| }; | ||
|
|
||
| let _ = tx.send(close_err.into()); | ||
| } | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not needed anymore