pallet_torus0/
migrations.rs

1use polkadot_sdk::frame_support::{
2    migrations::VersionedMigration, traits::UncheckedOnRuntimeUpgrade, weights::Weight,
3};
4
5use crate::{Config, Pallet};
6
7pub mod v4 {
8    use super::*;
9    use crate::{Agent, Agents};
10    use scale_info::prelude::vec::Vec;
11
12    pub mod storage {
13        use codec::{Decode, Encode, MaxEncodedLen};
14        use polkadot_sdk::frame_support::{storage_alias, DebugNoBound, Identity};
15        use polkadot_sdk::polkadot_sdk_frame::prelude::BlockNumberFor;
16        use polkadot_sdk::sp_runtime::{BoundedVec, Percent};
17        use scale_info::TypeInfo;
18
19        use crate::AccountIdOf;
20
21        #[derive(DebugNoBound, Encode, Decode, MaxEncodedLen, TypeInfo)]
22        #[scale_info(skip_type_params(T))]
23        pub struct Agent<T: crate::Config> {
24            pub key: AccountIdOf<T>,
25            pub name: BoundedVec<u8, T::MaxAgentNameLengthConstraint>,
26            pub url: BoundedVec<u8, T::MaxAgentUrlLengthConstraint>,
27            pub metadata: BoundedVec<u8, T::MaxAgentMetadataLengthConstraint>,
28            pub weight_penalty_factor: Percent,
29            pub registration_block: BlockNumberFor<T>,
30            pub fees: crate::fee::ValidatorFee<T>,
31        }
32
33        #[storage_alias]
34        pub type Agents<T: crate::Config> =
35            StorageMap<crate::Pallet<T>, Identity, AccountIdOf<T>, Agent<T>>;
36    }
37
38    pub type Migration<T, W> = VersionedMigration<3, 4, MigrateToV4<T>, Pallet<T>, W>;
39    pub struct MigrateToV4<T>(core::marker::PhantomData<T>);
40    impl<T: Config> UncheckedOnRuntimeUpgrade for MigrateToV4<T> {
41        fn on_runtime_upgrade() -> Weight {
42            let old_agents = storage::Agents::<T>::iter().collect::<Vec<_>>();
43            let _ = storage::Agents::<T>::clear(u32::MAX, None);
44
45            for (id, old_agent) in old_agents {
46                Agents::<T>::insert(
47                    id,
48                    Agent {
49                        key: old_agent.key,
50                        name: old_agent.name,
51                        url: old_agent.url,
52                        metadata: old_agent.metadata,
53                        registration_block: old_agent.registration_block,
54                        weight_penalty_factor: old_agent.weight_penalty_factor,
55                        fees: old_agent.fees,
56                        last_update_block: old_agent.registration_block,
57                    },
58                )
59            }
60
61            Weight::zero()
62        }
63    }
64}
65
66pub mod v5 {
67    use pallet_torus0_api::NamespacePath;
68    use polkadot_sdk::{
69        frame_support::{migrations::VersionedMigration, traits::UncheckedOnRuntimeUpgrade},
70        sp_tracing::{error, info},
71        sp_weights::Weight,
72    };
73
74    use crate::{
75        burn::BurnConfiguration, namespace::NamespaceOwnership, Agents, BurnConfig, Config, Pallet,
76    };
77
78    pub mod storage {
79        use polkadot_sdk::frame_support::{pallet_prelude::*, storage_alias};
80
81        use crate::AccountIdOf;
82
83        #[storage_alias]
84        pub type Namespaces<T: crate::Config> = StorageDoubleMap<
85            crate::Pallet<T>,
86            Blake2_128Concat,
87            AccountIdOf<T>,
88            Blake2_128Concat,
89            pallet_torus0_api::NamespacePath,
90            crate::namespace::NamespaceMetadata<T>,
91        >;
92
93        #[storage_alias]
94        pub type NamespaceCount<T: crate::Config> =
95            StorageMap<crate::Pallet<T>, Blake2_128Concat, AccountIdOf<T>, u32, ValueQuery>;
96    }
97
98    pub type Migration<T, W> = VersionedMigration<4, 5, MigrateToV5<T>, Pallet<T>, W>;
99    pub struct MigrateToV5<T>(core::marker::PhantomData<T>);
100
101    impl<T: Config> UncheckedOnRuntimeUpgrade for MigrateToV5<T> {
102        fn on_runtime_upgrade() -> Weight {
103            BurnConfig::<T>::set(BurnConfiguration {
104                min_burn: 15000000000000000000,   // 15tors
105                max_burn: 1000000000000000000000, // 1000tors
106                max_registrations_per_interval: 16,
107                ..BurnConfig::<T>::get()
108            });
109
110            let _ = storage::Namespaces::<T>::clear(u32::MAX, None);
111            let _ = storage::NamespaceCount::<T>::clear(u32::MAX, None);
112
113            let path = NamespacePath::agent_root();
114            #[allow(deprecated)]
115            if let Err(err) =
116                crate::namespace::create_namespace0::<T>(NamespaceOwnership::System, path, false)
117            {
118                error!("failed to create root agent namespace: {err:?}");
119                return Weight::default();
120            }
121
122            info!("created root agent namespace");
123
124            for (id, agent) in Agents::<T>::iter() {
125                let old_name = agent.name.clone();
126                let Ok(agent_name) = core::str::from_utf8(&agent.name) else {
127                    error!("agent name is not utf-8: {:?}", agent.name);
128                    continue;
129                };
130
131                let agent_name = agent_name.trim().to_ascii_lowercase().replace(' ', "-");
132
133                let Ok(bounded_name) = agent_name.as_bytes().to_vec().try_into() else {
134                    error!("cannot lower case agent {agent_name:?}");
135                    continue;
136                };
137
138                let path = match NamespacePath::new_agent_root(agent_name.as_bytes()) {
139                    Ok(path) => path,
140                    Err(err) => {
141                        error!("cannot create path for agent {agent_name:?}: {err:?}");
142                        continue;
143                    }
144                };
145
146                Agents::<T>::mutate_extant(id.clone(), |agent| {
147                    agent.name = bounded_name;
148                });
149
150                #[allow(deprecated)]
151                if let Err(err) = crate::namespace::create_namespace0::<T>(
152                    NamespaceOwnership::Account(id.clone()),
153                    path.clone(),
154                    false,
155                ) {
156                    error!("cannot create namespace for agent {agent_name:?}: {err:?}");
157
158                    Agents::<T>::mutate_extant(id.clone(), |agent| {
159                        agent.name = old_name;
160                    });
161                } else {
162                    info!("created namespace entry for agent {agent_name:?}: {path:?}");
163                }
164            }
165
166            Weight::default()
167        }
168    }
169}