Skip to content

Commit 137bf47

Browse files
fix: migrations for v2.3.0 (#627)
1 parent 81a1cc5 commit 137bf47

File tree

7 files changed

+249
-6
lines changed

7 files changed

+249
-6
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
pub mod v6;
22
// v7 was a failed migration and was reworked to v8
3-
pub mod v8;
3+
//pub mod v8;

substrate-node/pallets/pallet-tfgrid/src/migrations/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ pub mod v11;
44
pub mod v12;
55
pub mod v13;
66
pub mod v14;
7-
pub mod v15;
7+
//pub mod v15;

substrate-node/pallets/pallet-tfgrid/src/migrations/v14.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ pub fn fix_farming_policies_map_migration_<T: Config>() -> frame_support::weight
6262
info!(" >>> Migrating farming policies storage...");
6363

6464
let mut read_writes = 0;
65-
6665
FarmingPoliciesMap::<T>::translate::<FarmingPolicy<T::BlockNumber>, _>(|k, fp| {
6766
debug!("Farming policy #{:?}: start migrating", k);
6867
debug!(" id was: {:?}", fp.id);

substrate-node/pallets/pallet-tfgrid/src/migrations/v15.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,4 @@ pub fn migrate_twins<T: Config>() -> frame_support::weights::Weight {
8484

8585
// Return the weight consumed by the migration.
8686
T::DbWeight::get().reads_writes(read_writes, read_writes + 1)
87-
}
87+
}

substrate-node/runtime/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ pub use pallet_validator;
8080

8181
pub use pallet_dao;
8282

83+
pub mod migrations;
84+
8385
/// An index to a block.
8486
pub type BlockNumber = u32;
8587

@@ -765,8 +767,7 @@ pub type Executive = frame_executive::Executive<
765767
// `OnRuntimeUpgrade`.
766768
type Migrations = (
767769
pallet_tfgrid::migrations::v14::FixFarmingPoliciesMap<Runtime>,
768-
pallet_tfgrid::migrations::v15::MigrateTwinsV15<Runtime>,
769-
pallet_smart_contract::migrations::v8::FixTwinLockedBalances<Runtime>,
770+
migrations::tfgrid_v15_smart_contract_v8::Migrate<Runtime>,
770771
);
771772

772773
// follows Substrate's non destructive way of eliminating otherwise required
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub mod tfgrid_v15_smart_contract_v8;
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
use crate::pallet_smart_contract::{BalanceOf, Config, GRID_LOCK_ID};
2+
use crate::pallet_tfgrid::AccountIdOf;
3+
use crate::sp_api_hidden_includes_construct_runtime::hidden_include::traits::{
4+
Currency, LockableCurrency,
5+
};
6+
use crate::*;
7+
use frame_support::{
8+
pallet_prelude::OptionQuery,
9+
storage_alias,
10+
traits::OnRuntimeUpgrade,
11+
traits::{Get, WithdrawReasons},
12+
weights::Weight,
13+
Blake2_128Concat,
14+
};
15+
use log::{debug, info};
16+
use sp_std::{collections::btree_map::BTreeMap, marker::PhantomData};
17+
18+
#[cfg(feature = "try-runtime")]
19+
use codec::Decode;
20+
#[cfg(feature = "try-runtime")]
21+
use sp_std::vec::Vec;
22+
23+
// Storage alias from Twin v12
24+
#[storage_alias]
25+
pub type Twins<T: Config> = StorageMap<
26+
pallet_tfgrid::Pallet<T>,
27+
Blake2_128Concat,
28+
pallet_tfgrid::TwinIndex,
29+
pallet_tfgrid::migrations::types::v14::Twin<Vec<u8>, AccountIdOf<T>>,
30+
OptionQuery,
31+
>;
32+
33+
pub struct Migrate<T: Config>(PhantomData<T>);
34+
35+
impl<T: Config> OnRuntimeUpgrade for Migrate<T> {
36+
#[cfg(feature = "try-runtime")]
37+
fn pre_upgrade() -> Result<Vec<u8>, &'static str> {
38+
info!(
39+
"current pallet version: {:?}",
40+
pallet_tfgrid::PalletVersion::<T>::get()
41+
);
42+
assert!(
43+
pallet_tfgrid::PalletVersion::<T>::get()
44+
>= pallet_tfgrid::types::StorageVersion::V14Struct
45+
);
46+
47+
let twins_count: u64 = pallet_tfgrid::Twins::<T>::iter().count() as u64;
48+
log::info!(
49+
"🔎 MigrateTwinsV15 pre migration: Number of existing twins {:?}",
50+
twins_count
51+
);
52+
53+
info!("👥 TFGrid pallet to v14 passes PRE migrate checks ✅",);
54+
Ok(twins_count.encode())
55+
}
56+
57+
fn on_runtime_upgrade() -> Weight {
58+
let mut total_reads = 0;
59+
let mut total_writes = 0;
60+
if pallet_tfgrid::PalletVersion::<T>::get()
61+
== pallet_tfgrid::types::StorageVersion::V14Struct
62+
{
63+
let mut twins: BTreeMap<u32, pallet_tfgrid::types::Twin<AccountIdOf<T>>> =
64+
BTreeMap::new();
65+
66+
let (reads, writes) = migrate_tfgrid::<T>(&mut twins);
67+
total_reads += reads;
68+
total_writes += writes;
69+
70+
if pallet_smart_contract::PalletVersion::<T>::get()
71+
>= pallet_smart_contract::types::StorageVersion::V6
72+
&& pallet_smart_contract::PalletVersion::<T>::get()
73+
< pallet_smart_contract::types::StorageVersion::V8
74+
{
75+
let (reads, writes) = migrate_smart_contract::<T>(&twins);
76+
total_reads += reads;
77+
total_writes += writes;
78+
} else {
79+
info!(" >>> Unused Smart Contract pallet V8 migration");
80+
}
81+
82+
if twins.len() > 0 {
83+
let (reads, writes) = write_twins::<T>(&twins);
84+
total_reads += reads;
85+
total_writes += writes;
86+
}
87+
} else {
88+
info!(" >>> Unused TFGrid pallet V15 migration");
89+
}
90+
91+
T::DbWeight::get().reads_writes(total_reads, total_writes)
92+
}
93+
94+
#[cfg(feature = "try-runtime")]
95+
fn post_upgrade(pre_twins_count: Vec<u8>) -> Result<(), &'static str> {
96+
info!(
97+
"current pallet version: {:?}",
98+
pallet_tfgrid::PalletVersion::<T>::get()
99+
);
100+
assert!(
101+
pallet_tfgrid::PalletVersion::<T>::get()
102+
>= pallet_tfgrid::types::StorageVersion::V15Struct
103+
);
104+
105+
// Check number of twins against pre-check result
106+
let pre_twins_count: u64 = Decode::decode(&mut pre_twins_count.as_slice())
107+
.expect("the state parameter should be something that was generated by pre_upgrade");
108+
assert_eq!(
109+
pallet_tfgrid::Twins::<T>::iter().count() as u64,
110+
pre_twins_count,
111+
"Number of twins migrated does not match"
112+
);
113+
114+
info!(
115+
"👥 TFGrid pallet migration to {:?} passes POST migrate checks ✅",
116+
pallet_tfgrid::Pallet::<T>::pallet_version()
117+
);
118+
119+
Ok(())
120+
}
121+
}
122+
123+
pub fn write_twins<T: Config>(
124+
twins: &BTreeMap<u32, pallet_tfgrid::types::Twin<AccountIdOf<T>>>,
125+
) -> (u64, u64) {
126+
info!(" >>> Writing twins to storage...");
127+
for (twin_id, twin) in twins {
128+
pallet_tfgrid::Twins::<T>::insert(&twin_id, &twin);
129+
}
130+
// Update pallet storage version
131+
pallet_tfgrid::PalletVersion::<T>::set(pallet_tfgrid::types::StorageVersion::V15Struct);
132+
info!(" <<< Twin migration success, storage version upgraded");
133+
return (0, twins.len() as u64 + 1);
134+
}
135+
136+
pub fn migrate_tfgrid<T: Config>(
137+
twins: &mut BTreeMap<u32, pallet_tfgrid::types::Twin<AccountIdOf<T>>>,
138+
) -> (u64, u64) {
139+
info!(" >>> Migrating twin storage...");
140+
141+
let mut reads = 0;
142+
for (_twin_id, twin) in Twins::<T>::iter() {
143+
debug!("migrating twin: {:?}", twin);
144+
145+
let new_twin = pallet_tfgrid::types::Twin::<AccountIdOf<T>> {
146+
id: twin.id,
147+
account_id: twin.account_id,
148+
relay: None,
149+
entities: twin.entities,
150+
pk: None,
151+
};
152+
twins.insert(twin.id, new_twin);
153+
reads += 1;
154+
}
155+
156+
// Return the weight consumed by the migration.
157+
return (reads, 0);
158+
}
159+
160+
pub fn migrate_smart_contract<T: Config>(
161+
twins: &BTreeMap<u32, pallet_tfgrid::types::Twin<AccountIdOf<T>>>,
162+
) -> (u64, u64) {
163+
debug!(
164+
" >>> Starting contract pallet migration, pallet version: {:?}",
165+
pallet_smart_contract::PalletVersion::<T>::get()
166+
);
167+
168+
let mut reads = 0;
169+
let mut writes = 0;
170+
let mut twin_contract_locked_balances: BTreeMap<u32, BalanceOf<T>> = BTreeMap::new();
171+
// Fetch all locked balances based on the contract locks in storage and accumulate them by twin id
172+
for (ctr_id, l) in pallet_smart_contract::ContractLock::<T>::iter() {
173+
let ctr = pallet_smart_contract::Contracts::<T>::get(ctr_id);
174+
reads += 1;
175+
match ctr {
176+
Some(contract) => {
177+
if !twins.contains_key(&contract.twin_id) {
178+
debug!(
179+
"twins: {} does not exist, removing contract and lock",
180+
contract.twin_id
181+
);
182+
pallet_smart_contract::Contracts::<T>::remove(ctr_id);
183+
pallet_smart_contract::ContractLock::<T>::remove(ctr_id);
184+
writes += 2;
185+
} else {
186+
*twin_contract_locked_balances
187+
.entry(contract.twin_id)
188+
.or_default() += l.amount_locked;
189+
}
190+
}
191+
None => {
192+
debug!(
193+
"no contract found for contract lock {}, cleaning up lock..",
194+
ctr_id
195+
);
196+
writes += 1;
197+
pallet_smart_contract::ContractLock::<T>::remove(ctr_id);
198+
}
199+
}
200+
}
201+
202+
for (twin_id, twin) in twins {
203+
// If the twin needs to have some locked balance on his account because of running contracts
204+
// Check how much we can actually lock based on his current total balance
205+
// this will make sure the locked balance will not exceed the total balance on the twin's account
206+
let should_lock = twin_contract_locked_balances.get(&twin_id).map(|b| {
207+
debug!(
208+
"contract locked balance on twin {} account: {:?}",
209+
twin_id, b
210+
);
211+
(<T as Config>::Currency::total_balance(&twin.account_id)
212+
- <T as Config>::Currency::minimum_balance())
213+
.min(*b)
214+
});
215+
216+
if let Some(should_lock) = should_lock {
217+
debug!("we should lock: {:?}", should_lock);
218+
// Unlock all balance for the twin
219+
<T as Config>::Currency::remove_lock(GRID_LOCK_ID, &twin.account_id);
220+
writes += 1;
221+
222+
// Only do a set lock if we actually have to lock
223+
<T as Config>::Currency::set_lock(
224+
GRID_LOCK_ID,
225+
&twin.account_id,
226+
should_lock,
227+
WithdrawReasons::all(),
228+
);
229+
writes += 1;
230+
}
231+
}
232+
233+
// Update pallet storage version
234+
pallet_smart_contract::PalletVersion::<T>::set(
235+
pallet_smart_contract::types::StorageVersion::V8,
236+
);
237+
debug!(" <<< Storage version upgraded");
238+
239+
info!("👥 Smart Contract pallet to V8 succeeded");
240+
// Return the weight consumed by the migration.
241+
return (reads, writes + 1);
242+
}

0 commit comments

Comments
 (0)