Skip to content

Commit 0a796cc

Browse files
committed
Taurus: Add storage migration for new domain registry fields
1 parent 9f3d7db commit 0a796cc

File tree

3 files changed

+302
-0
lines changed

3 files changed

+302
-0
lines changed

crates/pallet-domains/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod tests;
1212
pub mod block_tree;
1313
mod bundle_storage_fund;
1414
pub mod domain_registry;
15+
pub mod migration_v2_to_v3;
1516
pub mod runtime_registry;
1617
mod staking;
1718
mod staking_epoch;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,299 @@
1+
//! Migration module for pallet-domains storage version v2 to v3.
2+
//!
3+
//! TODO: remove this module after it has been deployed to Taurus.
4+
5+
use crate::{Config, Pallet};
6+
use frame_support::migrations::VersionedMigration;
7+
use frame_support::traits::UncheckedOnRuntimeUpgrade;
8+
use frame_support::weights::Weight;
9+
10+
pub type VersionCheckedMigrateDomainsV2ToV3<T> = VersionedMigration<
11+
2,
12+
3,
13+
VersionUncheckedMigrateV2ToV3<T>,
14+
Pallet<T>,
15+
<T as frame_system::Config>::DbWeight,
16+
>;
17+
18+
pub struct VersionUncheckedMigrateV2ToV3<T>(sp_std::marker::PhantomData<T>);
19+
impl<T: Config> UncheckedOnRuntimeUpgrade for VersionUncheckedMigrateV2ToV3<T> {
20+
fn on_runtime_upgrade() -> Weight {
21+
domain_registry_structure_migration::migrate_domain_registry_structure::<T>()
22+
}
23+
}
24+
25+
mod domain_registry_structure_migration {
26+
use crate::domain_registry::{DomainConfig as DomainConfigV3, DomainObject as DomainObjectV3};
27+
use crate::pallet::DomainRegistry as DomainRegistryV3;
28+
use crate::runtime_registry::DomainRuntimeInfo as DomainRuntimeInfoV3;
29+
use crate::{BalanceOf, BlockNumberFor, Config, Pallet, ReceiptHashFor};
30+
use codec::{Decode, Encode};
31+
use domain_runtime_primitives::{EVMChainId, MultiAccountId};
32+
use frame_support::pallet_prelude::{OptionQuery, TypeInfo, Weight};
33+
use frame_support::{storage_alias, Identity};
34+
use scale_info::prelude::string::String;
35+
use sp_core::Get;
36+
use sp_domains::{
37+
AutoIdDomainRuntimeConfig,
38+
DomainId,
39+
// changed in V3, but we use Into to convert to it
40+
// DomainRuntimeConfig as DomainRuntimeConfigV3,
41+
EvmDomainRuntimeConfig,
42+
OperatorAllowList,
43+
RuntimeId,
44+
};
45+
use sp_runtime::Vec;
46+
47+
#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)]
48+
pub struct DomainConfigV2<AccountId: Ord, Balance> {
49+
/// A user defined name for this domain, should be a human-readable UTF-8 encoded string.
50+
pub domain_name: String,
51+
/// A pointer to the `RuntimeRegistry` entry for this domain.
52+
pub runtime_id: RuntimeId,
53+
/// The max bundle size for this domain, may not exceed the system-wide `MaxDomainBlockSize` limit.
54+
pub max_bundle_size: u32,
55+
/// The max bundle weight for this domain, may not exceed the system-wide `MaxDomainBlockWeight` limit.
56+
pub max_bundle_weight: Weight,
57+
/// The probability of successful bundle in a slot (active slots coefficient). This defines the
58+
/// expected bundle production rate, must be `> 0` and `≤ 1`.
59+
pub bundle_slot_probability: (u64, u64),
60+
/// Allowed operators to operate for this domain.
61+
pub operator_allow_list: OperatorAllowList<AccountId>,
62+
// Initial balances for Domain.
63+
pub initial_balances: Vec<(MultiAccountId, Balance)>,
64+
}
65+
66+
/// Domain runtime specific information to create domain raw genesis.
67+
#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq, Copy)]
68+
#[allow(clippy::upper_case_acronyms)]
69+
pub enum DomainRuntimeInfoV2 {
70+
EVM { chain_id: EVMChainId },
71+
AutoId,
72+
}
73+
74+
#[derive(TypeInfo, Debug, Encode, Decode, Clone, PartialEq, Eq)]
75+
pub struct DomainObjectV2<Number, ReceiptHash, AccountId: Ord, Balance> {
76+
/// The address of the domain creator, used to validate updating the domain config.
77+
pub owner_account_id: AccountId,
78+
/// The consensus chain block number when the domain first instantiated.
79+
pub created_at: Number,
80+
/// The hash of the genesis execution receipt for this domain.
81+
pub genesis_receipt_hash: ReceiptHash,
82+
/// The domain config.
83+
pub domain_config: DomainConfigV2<AccountId, Balance>,
84+
/// Domain runtime specific information.
85+
pub domain_runtime_info: DomainRuntimeInfoV2,
86+
/// The amount of balance hold on the domain owner account
87+
pub domain_instantiation_deposit: Balance,
88+
}
89+
90+
#[storage_alias]
91+
pub(super) type DomainRegistry<T: Config> = StorageMap<
92+
Pallet<T>,
93+
Identity,
94+
DomainId,
95+
DomainObjectV2<
96+
BlockNumberFor<T>,
97+
ReceiptHashFor<T>,
98+
<T as frame_system::Config>::AccountId,
99+
BalanceOf<T>,
100+
>,
101+
OptionQuery,
102+
>;
103+
104+
pub(super) fn migrate_domain_registry_structure<T: Config>() -> Weight {
105+
let mut domain_count = 0;
106+
107+
DomainRegistryV3::<T>::translate_values::<
108+
DomainObjectV2<BlockNumberFor<T>, ReceiptHashFor<T>, T::AccountId, BalanceOf<T>>,
109+
_,
110+
>(|domain_object_v2| {
111+
domain_count += 1;
112+
113+
let (domain_runtime_config, domain_runtime_info) =
114+
match domain_object_v2.domain_runtime_info {
115+
DomainRuntimeInfoV2::EVM { chain_id } => {
116+
// Added in V3
117+
let domain_runtime_config = EvmDomainRuntimeConfig::default();
118+
(
119+
domain_runtime_config.clone().into(),
120+
DomainRuntimeInfoV3::Evm {
121+
chain_id,
122+
domain_runtime_config,
123+
},
124+
)
125+
}
126+
DomainRuntimeInfoV2::AutoId => {
127+
// Added in V3
128+
let domain_runtime_config = AutoIdDomainRuntimeConfig::default();
129+
(
130+
domain_runtime_config.clone().into(),
131+
DomainRuntimeInfoV3::AutoId {
132+
domain_runtime_config,
133+
},
134+
)
135+
}
136+
};
137+
138+
Some(DomainObjectV3 {
139+
owner_account_id: domain_object_v2.owner_account_id,
140+
created_at: domain_object_v2.created_at,
141+
genesis_receipt_hash: domain_object_v2.genesis_receipt_hash,
142+
domain_config: DomainConfigV3 {
143+
domain_name: domain_object_v2.domain_config.domain_name,
144+
runtime_id: domain_object_v2.domain_config.runtime_id,
145+
max_bundle_size: domain_object_v2.domain_config.max_bundle_size,
146+
max_bundle_weight: domain_object_v2.domain_config.max_bundle_weight,
147+
bundle_slot_probability: domain_object_v2.domain_config.bundle_slot_probability,
148+
operator_allow_list: domain_object_v2.domain_config.operator_allow_list,
149+
initial_balances: domain_object_v2.domain_config.initial_balances,
150+
// Added in V3
151+
domain_runtime_config,
152+
},
153+
domain_runtime_info,
154+
domain_instantiation_deposit: domain_object_v2.domain_instantiation_deposit,
155+
})
156+
});
157+
158+
// 1 read and 1 write per domain
159+
T::DbWeight::get().reads_writes(domain_count, domain_count)
160+
}
161+
}
162+
163+
#[cfg(test)]
164+
mod tests {
165+
use super::domain_registry_structure_migration::{
166+
migrate_domain_registry_structure, DomainConfigV2, DomainObjectV2, DomainRegistry,
167+
DomainRuntimeInfoV2,
168+
};
169+
use crate::domain_registry::{DomainConfig as DomainConfigV3, DomainObject as DomainObjectV3};
170+
use crate::pallet::DomainRegistry as DomainRegistryV3;
171+
use crate::runtime_registry::DomainRuntimeInfo as DomainRuntimeInfoV3;
172+
use crate::tests::{new_test_ext, Test};
173+
use sp_domains::{
174+
AutoIdDomainRuntimeConfig, DomainId, DomainRuntimeConfig as DomainRuntimeConfigV3,
175+
EvmDomainRuntimeConfig, OperatorAllowList, PermissionedActionAllowedBy,
176+
};
177+
178+
#[test]
179+
fn test_domain_registry_structure_migration_evm() {
180+
let mut ext = new_test_ext();
181+
let domain_id: DomainId = 0.into();
182+
let chain_id = 8u32.into();
183+
let domain = DomainObjectV2 {
184+
owner_account_id: 1u32.into(),
185+
created_at: 2u32.into(),
186+
genesis_receipt_hash: Default::default(),
187+
domain_config: DomainConfigV2 {
188+
domain_name: "test-evm-migrate".to_string(),
189+
runtime_id: 3u32,
190+
max_bundle_size: 4,
191+
max_bundle_weight: 5.into(),
192+
bundle_slot_probability: (6, 7),
193+
operator_allow_list: OperatorAllowList::Anyone,
194+
initial_balances: vec![],
195+
},
196+
domain_runtime_info: DomainRuntimeInfoV2::EVM { chain_id },
197+
domain_instantiation_deposit: 9u32.into(),
198+
};
199+
200+
ext.execute_with(|| DomainRegistry::<Test>::set(domain_id, Some(domain.clone())));
201+
202+
ext.commit_all().unwrap();
203+
204+
ext.execute_with(|| {
205+
let weights = migrate_domain_registry_structure::<Test>();
206+
assert_eq!(
207+
weights,
208+
<Test as frame_system::Config>::DbWeight::get().reads_writes(1, 1),
209+
);
210+
assert_eq!(
211+
DomainRegistryV3::<Test>::get(domain_id),
212+
Some(DomainObjectV3 {
213+
owner_account_id: domain.owner_account_id,
214+
created_at: domain.created_at,
215+
genesis_receipt_hash: domain.genesis_receipt_hash,
216+
domain_config: DomainConfigV3 {
217+
domain_name: domain.domain_config.domain_name,
218+
runtime_id: domain.domain_config.runtime_id,
219+
max_bundle_size: domain.domain_config.max_bundle_size,
220+
max_bundle_weight: domain.domain_config.max_bundle_weight,
221+
bundle_slot_probability: domain.domain_config.bundle_slot_probability,
222+
operator_allow_list: domain.domain_config.operator_allow_list,
223+
initial_balances: domain.domain_config.initial_balances,
224+
domain_runtime_config: DomainRuntimeConfigV3::Evm(EvmDomainRuntimeConfig {
225+
initial_contract_creation_allow_list:
226+
PermissionedActionAllowedBy::Anyone
227+
}),
228+
},
229+
domain_runtime_info: DomainRuntimeInfoV3::Evm {
230+
chain_id,
231+
domain_runtime_config: EvmDomainRuntimeConfig {
232+
initial_contract_creation_allow_list:
233+
PermissionedActionAllowedBy::Anyone
234+
},
235+
},
236+
domain_instantiation_deposit: domain.domain_instantiation_deposit,
237+
})
238+
);
239+
});
240+
}
241+
242+
#[test]
243+
fn test_domain_registry_structure_migration_auto_id() {
244+
let mut ext = new_test_ext();
245+
let domain_id: DomainId = 10.into();
246+
let domain = DomainObjectV2 {
247+
owner_account_id: 11u32.into(),
248+
created_at: 12u32.into(),
249+
genesis_receipt_hash: Default::default(),
250+
domain_config: DomainConfigV2 {
251+
domain_name: "test-auto-id-migrate".to_string(),
252+
runtime_id: 13u32,
253+
max_bundle_size: 14,
254+
max_bundle_weight: 15.into(),
255+
bundle_slot_probability: (16, 17),
256+
operator_allow_list: OperatorAllowList::Anyone,
257+
initial_balances: vec![],
258+
},
259+
domain_runtime_info: DomainRuntimeInfoV2::AutoId,
260+
domain_instantiation_deposit: 19u32.into(),
261+
};
262+
263+
ext.execute_with(|| DomainRegistry::<Test>::set(domain_id, Some(domain.clone())));
264+
265+
ext.commit_all().unwrap();
266+
267+
ext.execute_with(|| {
268+
let weights = migrate_domain_registry_structure::<Test>();
269+
assert_eq!(
270+
weights,
271+
<Test as frame_system::Config>::DbWeight::get().reads_writes(1, 1),
272+
);
273+
assert_eq!(
274+
DomainRegistryV3::<Test>::get(domain_id),
275+
Some(DomainObjectV3 {
276+
owner_account_id: domain.owner_account_id,
277+
created_at: domain.created_at,
278+
genesis_receipt_hash: domain.genesis_receipt_hash,
279+
domain_config: DomainConfigV3 {
280+
domain_name: domain.domain_config.domain_name,
281+
runtime_id: domain.domain_config.runtime_id,
282+
max_bundle_size: domain.domain_config.max_bundle_size,
283+
max_bundle_weight: domain.domain_config.max_bundle_weight,
284+
bundle_slot_probability: domain.domain_config.bundle_slot_probability,
285+
operator_allow_list: domain.domain_config.operator_allow_list,
286+
initial_balances: domain.domain_config.initial_balances,
287+
domain_runtime_config: DomainRuntimeConfigV3::AutoId(
288+
AutoIdDomainRuntimeConfig {}
289+
),
290+
},
291+
domain_runtime_info: DomainRuntimeInfoV3::AutoId {
292+
domain_runtime_config: AutoIdDomainRuntimeConfig {}
293+
},
294+
domain_instantiation_deposit: domain.domain_instantiation_deposit,
295+
})
296+
);
297+
});
298+
}
299+
}

crates/subspace-runtime/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,8 @@ pub type Executive = frame_executive::Executive<
979979
frame_system::ChainContext<Runtime>,
980980
Runtime,
981981
AllPalletsWithSystem,
982+
// TODO: remove once migration has been deployed to Taurus
983+
pallet_domains::migration_v2_to_v3::VersionCheckedMigrateDomainsV2ToV3<Runtime>,
982984
>;
983985

984986
fn extract_segment_headers(ext: &UncheckedExtrinsic) -> Option<Vec<SegmentHeader>> {

0 commit comments

Comments
 (0)