zombienet_orchestrator/tx_helper/
runtime_upgrade.rs1use subxt::{dynamic::Value, tx::TxStatus, OnlineClient, SubstrateConfig};
2use subxt_signer::sr25519::Keypair;
3use tracing::{debug, info};
4
5use crate::network::node::NetworkNode;
6
7pub async fn upgrade(
8 node: &NetworkNode,
9 wasm_data: &[u8],
10 sudo: &Keypair,
11) -> Result<(), anyhow::Error> {
12 debug!(
13 "Upgrading runtime, using node: {} with endpoting {}",
14 node.name(),
15 node.ws_uri
16 );
17 let api: OnlineClient<SubstrateConfig> = node.wait_client().await?;
18
19 let upgrade = subxt::dynamic::tx(
20 "System",
21 "set_code_without_checks",
22 vec![Value::from_bytes(wasm_data)],
23 );
24
25 let sudo_call = subxt::dynamic::tx(
26 "Sudo",
27 "sudo_unchecked_weight",
28 vec![
29 upgrade.into_value(),
30 Value::named_composite([
31 ("ref_time", Value::primitive(1.into())),
32 ("proof_size", Value::primitive(1.into())),
33 ]),
34 ],
35 );
36
37 let mut tx = api
38 .tx()
39 .sign_and_submit_then_watch_default(&sudo_call, sudo)
40 .await?;
41
42 while let Some(status) = tx.next().await {
45 let status = status?;
46 match &status {
47 TxStatus::InBestBlock(tx_in_block) | TxStatus::InFinalizedBlock(tx_in_block) => {
48 let _result = tx_in_block.wait_for_success().await?;
49 let block_status = if status.as_finalized().is_some() {
50 "Finalized"
51 } else {
52 "Best"
53 };
54 info!(
55 "[{}] In block: {:#?}",
56 block_status,
57 tx_in_block.block_hash()
58 );
59 },
60 TxStatus::Error { message }
61 | TxStatus::Invalid { message }
62 | TxStatus::Dropped { message } => {
63 return Err(anyhow::format_err!("Error submitting tx: {message}"));
64 },
65 _ => continue,
66 }
67 }
68
69 Ok(())
70}