Skip to content

Commit f5b3338

Browse files
committed
fix(runtime update): wait until upgrade on chain
1 parent 2717609 commit f5b3338

File tree

3 files changed

+54
-17
lines changed

3 files changed

+54
-17
lines changed

subxt/src/backend/rpc/rpc_client.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -230,10 +230,7 @@ impl<Res: DeserializeOwned> Stream for RpcSubscription<Res> {
230230
mod jsonrpsee_helpers {
231231
pub use jsonrpsee::{
232232
client_transport::ws::{Receiver, Sender, Url, WsTransportClientBuilder},
233-
core::{
234-
client::{Client, ClientBuilder},
235-
Error,
236-
},
233+
core::{client::Client, Error},
237234
};
238235

239236
/// Build WS RPC client from URL

subxt/src/client/online_client.rs

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// see LICENSE for license details.
44

55
use super::{OfflineClient, OfflineClientT};
6+
use crate::config::Header;
67
use crate::custom_values::CustomValuesClient;
78
use crate::{
89
backend::{
@@ -437,17 +438,13 @@ impl<T: Config> RuntimeUpdaterStream<T> {
437438
Err(err) => return Some(Err(err)),
438439
};
439440

440-
let latest_block_ref = match self.client.backend().latest_finalized_block_ref().await {
441-
Ok(block_ref) => block_ref,
442-
Err(e) => return Some(Err(e)),
441+
let at = match wait_for_runtime_upgrade(&self.client, &runtime_version).await {
442+
Some(Ok(at)) => at,
443+
Some(Err(err)) => return Some(Err(err)),
444+
None => return None,
443445
};
444446

445-
let metadata = match OnlineClient::fetch_metadata(
446-
self.client.backend(),
447-
latest_block_ref.hash(),
448-
)
449-
.await
450-
{
447+
let metadata = match OnlineClient::fetch_metadata(self.client.backend(), at.hash()).await {
451448
Ok(metadata) => metadata,
452449
Err(err) => return Some(Err(err)),
453450
};
@@ -484,3 +481,49 @@ impl Update {
484481
&self.metadata
485482
}
486483
}
484+
485+
/// Helper to wait until the runtime upgrade is applied on at finalized block.
486+
async fn wait_for_runtime_upgrade<T: Config>(
487+
client: &OnlineClient<T>,
488+
runtime_version: &RuntimeVersion,
489+
) -> Option<Result<T::Header, Error>> {
490+
use scale_value::At;
491+
492+
let mut block_sub = match client.backend().stream_finalized_block_headers().await {
493+
Ok(s) => s,
494+
Err(err) => return Some(Err(err)),
495+
};
496+
497+
let head = loop {
498+
let (block, block_ref) = match block_sub.next().await? {
499+
Ok(n) => n,
500+
Err(err) => return Some(Err(err)),
501+
};
502+
503+
let key: Vec<scale_value::Value> = vec![];
504+
let addr = crate::dynamic::storage("System", "LastRuntimeUpgrade", key);
505+
506+
let chunk = match client.storage().at(block_ref).fetch(&addr).await {
507+
Ok(Some(v)) => v,
508+
Ok(None) => continue,
509+
Err(e) => return Some(Err(e)),
510+
};
511+
512+
let scale_val = match chunk.to_value() {
513+
Ok(v) => v,
514+
Err(e) => return Some(Err(e)),
515+
};
516+
517+
let spec_version = scale_val
518+
.at("spec_version")
519+
.and_then(|v| v.as_u128())
520+
.expect("specVersion should exist on RuntimeVersion; qed")
521+
as u32;
522+
523+
if spec_version >= runtime_version.spec_version {
524+
break block;
525+
}
526+
};
527+
528+
Some(Ok(head))
529+
}

testing/test-runtime/build.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,7 @@ async fn run() {
103103
mod client {
104104
pub use jsonrpsee::{
105105
client_transport::ws::{Receiver, Sender, Url, WsTransportClientBuilder},
106-
core::{
107-
client::{Client, ClientBuilder},
108-
Error,
109-
},
106+
core::{client::Client, Error},
110107
};
111108

112109
pub use jsonrpsee::core::{client::ClientT, rpc_params};

0 commit comments

Comments
 (0)