From c11a9d54cba1817c82eca118b6042fc5d9aebcba Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 14 Dec 2023 18:32:28 +0100 Subject: [PATCH 01/10] chore: release v1.3 --- CHANGELOG.md | 33 +++++++++++++++++++++++++++++ Cargo.lock | 2 +- Cargo.toml | 4 ++-- src/main.rs | 54 ++++++++++++++++++----------------------------- src/opt.rs | 2 +- src/prometheus.rs | 2 ++ 6 files changed, 59 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 48b2388de..d2d98a970 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,39 @@ The format is based on [Keep a Changelog]. [Keep a Changelog]: http://keepachangelog.com/en/1.0.0/ +## [v1.3.0] - 2023-12-14 + +The main changes of this release are: +- Change the binary name to `polkadot-staking-miner` to publish on crates.io. +- Temporarly disable runtime upgrades more information below. +- Bump rust MSRV to 1.74 +- Change `submit_signed_solution` extrinsic to be mortal + +### Runtime upgrades are disabled + +Recently, we noticed that it may be possible that the runtime upgrades won't +upgrade the metadata because the actual runtime upgrade is applied to the block +after 'state_subscribeRuntimeVersion' emits an event. +For that reason, runtime upgrades are temporarily disabled, +and polkadot-staking-miner is terminated. + +To deal with runtime upgrades, it should be sufficient to restart the client and wait a +few seconds until another block is finalized to fetch the latest metadata or verify +that the runtime upgrade has been applied successfully. + +This is just a temporary fix and will be fixed in the next release. + +### [Changed] +- refactor: make solution extrinsic mortal ([#728](https://github.com/paritytech/staking-miner-v2/pull/728)) +- chore(deps): bump subxt, subxt-signer, scale-value ([#726](https://github.com/paritytech/staking-miner-v2/pull/726)) +- chore(deps): bump clap from 4.4.10 to 4.4.11 ([#721](https://github.com/paritytech/staking-miner-v2/pull/721)) +- chore(deps): bump tokio from 1.34.0 to 1.35.0 ([#724](https://github.com/paritytech/staking-miner-v2/pull/724)) +- chore(deps): bump once_cell from 1.18.0 to 1.19.0 ([#722](https://github.com/paritytech/staking-miner-v2/pull/722)) +- refactor: use `subxt-signer` to reduce the number of deps ([#720](https://github.com/paritytech/staking-miner-v2/pull/720)) +- chore(deps): bump clap from 4.4.8 to 4.4.10 ([#719](https://github.com/paritytech/staking-miner-v2/pull/719)) +- rename project to polkadot-staking-miner ([#717](https://github.com/paritytech/staking-miner-v2/pull/717)) + + ## [v1.2.0] - 2023-11-23 The major changes of this release: diff --git a/Cargo.lock b/Cargo.lock index 73a782f43..d01ca477d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3180,7 +3180,7 @@ checksum = "14e6ab3f592e6fb464fc9712d8d6e6912de6473954635fd76a589d832cffcbb0" [[package]] name = "polkadot-staking-miner" -version = "1.2.0" +version = "1.3.0" dependencies = [ "anyhow", "assert_cmd", diff --git a/Cargo.toml b/Cargo.toml index 9d0bdf348..fe1032013 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polkadot-staking-miner" -version = "1.2.0" +version = "1.3.0" authors = ["Parity Technologies "] edition = "2021" rust-version = "1.74.0" @@ -51,4 +51,4 @@ regex = "1" [features] default = [] -slow-tests = [] +slow-tests = [] \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 8a5e8492d..5b134fb77 100644 --- a/src/main.rs +++ b/src/main.rs @@ -127,7 +127,11 @@ 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::(); - tokio::spawn(runtime_upgrade_task(client.chain_api().clone(), tx_upgrade)); + tokio::spawn(runtime_upgrade_task( + client.chain_api().clone(), + tx_upgrade, + runtime_version.clone(), + )); let res = any_runtime!(chain, { let fut = match command { @@ -156,7 +160,7 @@ async fn main() -> Result<(), Error> { run_command(fut, rx_upgrade).await }); - log::info!(target: LOG_TARGET, "round of execution finished. outcome = {:?}", res); + log::debug!(target: LOG_TARGET, "round of execution finished. outcome = {:?}", res); res } @@ -206,49 +210,31 @@ async fn run_command( } /// Runs until the RPC connection fails or updating the metadata failed. -async fn runtime_upgrade_task(api: ChainClient, tx: oneshot::Sender) { +async fn runtime_upgrade_task(api: ChainClient, tx: oneshot::Sender, curr: RuntimeVersion) { + const ERR: &str = "Runtime upgrades are not supported at the moment, \ + see https://github.com/paritytech/polkadot-staking-miner/issues/731 how deal with that"; + let updater = api.updater(); let mut update_stream = match updater.runtime_updates().await { - Ok(u) => u, + Ok(update_stream) => update_stream, Err(e) => { let _ = tx.send(e.into()); - return + return; }, }; - 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 - }, - }; + while let Some(Ok(update)) = update_stream.next().await { + let new_version = update.runtime_version(); - let version = update.runtime_version().spec_version; - match updater.apply_update(update) { - Ok(()) => { - if let Err(e) = epm::update_metadata_constants(&api) { - let _ = tx.send(e); - return - } - prometheus::on_runtime_upgrade(); - log::info!(target: LOG_TARGET, "upgrade to v{} successful", version); - }, - Err(e) => { - log::debug!(target: LOG_TARGET, "upgrade to v{} failed: {:?}", version, e); - }, + let is_new_version = new_version.spec_version > curr.spec_version || + new_version.transaction_version > curr.transaction_version; + if is_new_version { + break; } } + + let _ = tx.send(Error::Other(ERR.to_string())); } #[cfg(test)] diff --git a/src/opt.rs b/src/opt.rs index 45430ee6b..3bac15e4a 100644 --- a/src/opt.rs +++ b/src/opt.rs @@ -119,7 +119,7 @@ impl From for RuntimeVersion { } } -#[derive(Deserialize, Serialize)] +#[derive(Deserialize, Serialize, PartialEq, Debug, Clone)] pub struct RuntimeVersion { pub spec_name: String, pub impl_name: String, diff --git a/src/prometheus.rs b/src/prometheus.rs index 18ce0376d..429ec3144 100644 --- a/src/prometheus.rs +++ b/src/prometheus.rs @@ -159,6 +159,7 @@ mod hidden { )) .unwrap() }); + #[allow(unused)] static RUNTIME_UPGRADES: Lazy = Lazy::new(|| { register_counter!(opts!( "staking_miner_runtime_upgrades", @@ -178,6 +179,7 @@ mod hidden { .unwrap() }); + #[allow(unused)] pub fn on_runtime_upgrade() { RUNTIME_UPGRADES.inc(); } From c11560a518de40daa2eaa1f31c87bd1eea53e42e Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 14 Dec 2023 18:34:43 +0100 Subject: [PATCH 02/10] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2d98a970..d138a360f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ The format is based on [Keep a Changelog]. ## [v1.3.0] - 2023-12-14 -The main changes of this release are: +The main changes of this release are as follows: - Change the binary name to `polkadot-staking-miner` to publish on crates.io. - Temporarly disable runtime upgrades more information below. - Bump rust MSRV to 1.74 From 6c4926ade38979eb169b5d2f7a17748c16c2ff33 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 14 Dec 2023 18:35:00 +0100 Subject: [PATCH 03/10] Update CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d138a360f..c506a0d85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,7 +36,6 @@ This is just a temporary fix and will be fixed in the next release. - chore(deps): bump clap from 4.4.8 to 4.4.10 ([#719](https://github.com/paritytech/staking-miner-v2/pull/719)) - rename project to polkadot-staking-miner ([#717](https://github.com/paritytech/staking-miner-v2/pull/717)) - ## [v1.2.0] - 2023-11-23 The major changes of this release: From 5ad9bdd5b110bd7a55626114ca1effd139386978 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Thu, 14 Dec 2023 18:42:42 +0100 Subject: [PATCH 04/10] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c506a0d85..35cb11c62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ Recently, we noticed that it may be possible that the runtime upgrades won't upgrade the metadata because the actual runtime upgrade is applied to the block after 'state_subscribeRuntimeVersion' emits an event. For that reason, runtime upgrades are temporarily disabled, -and polkadot-staking-miner is terminated. +and the polkadot-staking-miner is terminated if a runtime upgrade occurs. To deal with runtime upgrades, it should be sufficient to restart the client and wait a few seconds until another block is finalized to fetch the latest metadata or verify From 4b6aa43c290a0b674fae202a5965da8009af203e Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 15 Dec 2023 18:05:46 +0100 Subject: [PATCH 05/10] add back runtime upgrades --- CHANGELOG.md | 16 +-------- src/client.rs | 10 ++++-- src/main.rs | 94 +++++++++++++++++++++++++++++++++++++++------------ 3 files changed, 82 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2d98a970..6f07659e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,20 +11,7 @@ The main changes of this release are: - Temporarly disable runtime upgrades more information below. - Bump rust MSRV to 1.74 - Change `submit_signed_solution` extrinsic to be mortal - -### Runtime upgrades are disabled - -Recently, we noticed that it may be possible that the runtime upgrades won't -upgrade the metadata because the actual runtime upgrade is applied to the block -after 'state_subscribeRuntimeVersion' emits an event. -For that reason, runtime upgrades are temporarily disabled, -and polkadot-staking-miner is terminated. - -To deal with runtime upgrades, it should be sufficient to restart the client and wait a -few seconds until another block is finalized to fetch the latest metadata or verify -that the runtime upgrade has been applied successfully. - -This is just a temporary fix and will be fixed in the next release. +- A runtime upgrade bug was discovered and is fixed in this release. ### [Changed] - refactor: make solution extrinsic mortal ([#728](https://github.com/paritytech/staking-miner-v2/pull/728)) @@ -36,7 +23,6 @@ This is just a temporary fix and will be fixed in the next release. - chore(deps): bump clap from 4.4.8 to 4.4.10 ([#719](https://github.com/paritytech/staking-miner-v2/pull/719)) - rename project to polkadot-staking-miner ([#717](https://github.com/paritytech/staking-miner-v2/pull/717)) - ## [v1.2.0] - 2023-11-23 The major changes of this release: diff --git a/src/client.rs b/src/client.rs index e8733f20c..98464e0fe 100644 --- a/src/client.rs +++ b/src/client.rs @@ -9,6 +9,8 @@ pub struct Client { rpc: RpcClient, /// Access to chain APIs such as storage, events etc. chain_api: ChainClient, + /// Raw RPC client. + raw_rpc: RawRpcClient, } impl Client { @@ -36,8 +38,7 @@ impl Client { }; let chain_api = ChainClient::from_rpc_client(rpc.clone()).await?; - - Ok(Self { rpc: RpcClient::new(rpc), chain_api }) + Ok(Self { rpc: RpcClient::new(rpc.clone()), raw_rpc: rpc, chain_api }) } /// Get a reference to the RPC interface exposed by subxt. @@ -49,4 +50,9 @@ impl Client { pub fn chain_api(&self) -> &ChainClient { &self.chain_api } + + /// Get a reference to the raw rpc client API. + pub fn raw_rpc(&self) -> &RawRpcClient { + &self.raw_rpc + } } diff --git a/src/main.rs b/src/main.rs index 5b134fb77..934a8ded3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -39,10 +39,12 @@ mod prometheus; 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; @@ -127,11 +129,7 @@ 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::(); - tokio::spawn(runtime_upgrade_task( - client.chain_api().clone(), - tx_upgrade, - runtime_version.clone(), - )); + tokio::spawn(runtime_upgrade_task(client.clone(), tx_upgrade, runtime_version.spec_version)); let res = any_runtime!(chain, { let fut = match command { @@ -210,31 +208,85 @@ async fn run_command( } /// Runs until the RPC connection fails or updating the metadata failed. -async fn runtime_upgrade_task(api: ChainClient, tx: oneshot::Sender, curr: RuntimeVersion) { - const ERR: &str = "Runtime upgrades are not supported at the moment, \ - see https://github.com/paritytech/polkadot-staking-miner/issues/731 how deal with that"; - - let updater = api.updater(); +async fn runtime_upgrade_task(client: Client, tx: oneshot::Sender, mut spec_version: u32) { + use sp_core::storage::StorageChangeSet; + + async fn new_update_stream( + client: &Client, + ) -> Result>, 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 + } - let mut update_stream = match updater.runtime_updates().await { - Ok(update_stream) => update_stream, + let mut update_stream = match new_update_stream(&client).await { + Ok(s) => s, Err(e) => { - let _ = tx.send(e.into()); + _ = tx.send(e.into()); return; }, }; - while let Some(Ok(update)) = update_stream.next().await { - let new_version = update.runtime_version(); + 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(), + }; + continue; + }, + }; - let is_new_version = new_version.spec_version > curr.spec_version || - new_version.transaction_version > curr.transaction_version; - if is_new_version { - break; + 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 _ = tx.send(Error::Other(ERR.to_string())); + let _ = tx.send(close_err.into()); } #[cfg(test)] From f1dafa851b40403da847c669fe35fa174fd598db Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 15 Dec 2023 18:11:56 +0100 Subject: [PATCH 06/10] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 55ee8a166..a3be8d67e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ The main changes of this release are as follows: ### Runtime upgrade bug fixed. -Recently, we noticed that it may be possible that the runtime upgrades won't +Recently, we noticed that it can be possible that the runtime upgrades won't upgrade the metadata because the actual runtime upgrade is applied to the block after 'state_subscribeRuntimeVersion' emits an event. For that reason, the staking-miner now subscribes to `system().last_runtime_upgrade()` instead to fix that. From 09c482335211811be1d88c9bcca23469dd22daab Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 15 Dec 2023 18:12:32 +0100 Subject: [PATCH 07/10] Update CHANGELOG.md --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3be8d67e..1f9baab59 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,8 @@ The main changes of this release are as follows: Recently, we noticed that it can be possible that the runtime upgrades won't upgrade the metadata because the actual runtime upgrade is applied to the block after 'state_subscribeRuntimeVersion' emits an event. -For that reason, the staking-miner now subscribes to `system().last_runtime_upgrade()` instead to fix that. + +For that reason, the polkadot-staking-miner now subscribes to `system().last_runtime_upgrade()` instead to fix that. ### [Changed] - refactor: make solution extrinsic mortal ([#728](https://github.com/paritytech/staking-miner-v2/pull/728)) From 300503bfdb6546ef29c1711a4de7fa330b112e93 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 15 Dec 2023 18:16:27 +0100 Subject: [PATCH 08/10] Update src/prometheus.rs --- src/prometheus.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/prometheus.rs b/src/prometheus.rs index 429ec3144..ddf1952fe 100644 --- a/src/prometheus.rs +++ b/src/prometheus.rs @@ -159,7 +159,6 @@ mod hidden { )) .unwrap() }); - #[allow(unused)] static RUNTIME_UPGRADES: Lazy = Lazy::new(|| { register_counter!(opts!( "staking_miner_runtime_upgrades", From 31e9b3a751842860d4d3b36b11a10682ea6e15c8 Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 15 Dec 2023 18:25:11 +0100 Subject: [PATCH 09/10] Update src/prometheus.rs --- src/prometheus.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/prometheus.rs b/src/prometheus.rs index ddf1952fe..18ce0376d 100644 --- a/src/prometheus.rs +++ b/src/prometheus.rs @@ -178,7 +178,6 @@ mod hidden { .unwrap() }); - #[allow(unused)] pub fn on_runtime_upgrade() { RUNTIME_UPGRADES.inc(); } From f4e6753a4c96d02cc945cbe08414e8404affccaf Mon Sep 17 00:00:00 2001 From: Niklas Adolfsson Date: Fri, 15 Dec 2023 18:25:54 +0100 Subject: [PATCH 10/10] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f9baab59..d05cec27d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ The format is based on [Keep a Changelog]. [Keep a Changelog]: http://keepachangelog.com/en/1.0.0/ -## [v1.3.0] - 2023-12-14 +## [v1.3.0] - 2023-12-15 The main changes of this release are as follows: - Change the binary name to `polkadot-staking-miner` to publish on crates.io.