zombienet_orchestrator/tx_helper/
parachain.rs

1use anyhow::anyhow;
2use subxt::{
3    dynamic::Value,
4    ext::{codec::Encode, scale_value::value},
5    tx::DynamicPayload,
6    OnlineClient, PolkadotConfig,
7};
8
9/// Fetches the genesis header from a parachain node
10pub async fn fetch_genesis_header(
11    client: &OnlineClient<PolkadotConfig>,
12) -> Result<Vec<u8>, anyhow::Error> {
13    let genesis_hash = client.genesis_hash();
14    let header = client
15        .backend()
16        .block_header(genesis_hash)
17        .await?
18        .ok_or_else(|| anyhow!("Failed to fetch genesis header"))?;
19    Ok(header.encode())
20}
21
22/// Fetches the validation code from a parachain node
23pub async fn fetch_validation_code(
24    client: &OnlineClient<PolkadotConfig>,
25) -> Result<Vec<u8>, anyhow::Error> {
26    let code_key = sp_core::storage::well_known_keys::CODE;
27    client
28        .storage()
29        .at_latest()
30        .await?
31        .fetch_raw(code_key)
32        .await?
33        .ok_or_else(|| anyhow!("Failed to fetch validation code"))
34}
35
36/// Creates a sudo call to deregister a validator
37pub fn create_deregister_validator_call(stash_account: Value) -> DynamicPayload {
38    let deregister_call = subxt::dynamic::tx(
39        "ValidatorManager",
40        "deregister_validators",
41        vec![Value::unnamed_composite(vec![stash_account])],
42    );
43
44    subxt::dynamic::tx("Sudo", "sudo", vec![deregister_call.into_value()])
45}
46
47/// Creates a sudo call to register a validator
48pub fn create_register_validator_call(stash_account: Value) -> DynamicPayload {
49    let register_call = subxt::dynamic::tx(
50        "ValidatorManager",
51        "register_validators",
52        vec![Value::unnamed_composite(vec![stash_account])],
53    );
54
55    subxt::dynamic::tx("Sudo", "sudo", vec![register_call.into_value()])
56}
57
58/// Creates a sudo batch call to register a parachain with trusted validation code
59pub fn create_register_para_call(
60    genesis_header: &[u8],
61    validation_code: &[u8],
62    para_id: u32,
63    registrar_account: Value,
64) -> DynamicPayload {
65    let genesis_head_value = Value::from_bytes(genesis_header);
66    let validation_code_value = Value::from_bytes(validation_code);
67    let validation_code_for_trusted = Value::from_bytes(validation_code);
68
69    let add_trusted_code_call = subxt::dynamic::tx(
70        "Paras",
71        "add_trusted_validation_code",
72        vec![validation_code_for_trusted],
73    );
74
75    let force_register_call = subxt::dynamic::tx(
76        "Registrar",
77        "force_register",
78        vec![
79            registrar_account,
80            Value::u128(0),
81            Value::u128(para_id as u128),
82            genesis_head_value,
83            validation_code_value,
84        ],
85    );
86
87    let calls = Value::unnamed_composite(vec![
88        add_trusted_code_call.into_value(),
89        force_register_call.into_value(),
90    ]);
91
92    subxt::dynamic::tx(
93        "Sudo",
94        "sudo",
95        vec![value! {
96            Utility( batch { calls: calls})
97        }],
98    )
99}