1
// Copyright (C) Moondance Labs Ltd.
2
// This file is part of Tanssi.
3

            
4
// Tanssi is free software: you can redistribute it and/or modify
5
// it under the terms of the GNU General Public License as published by
6
// the Free Software Foundation, either version 3 of the License, or
7
// (at your option) any later version.
8

            
9
// Tanssi is distributed in the hope that it will be useful,
10
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
// GNU General Public License for more details.
13

            
14
// You should have received a copy of the GNU General Public License
15
// along with Tanssi.  If not, see <http://www.gnu.org/licenses/>
16

            
17
//! # Migrations
18
//!
19
//! This module acts as a registry where each migration is defined. Each migration should implement
20
//! the "Migration" trait declared in the pallet-migrations crate.
21

            
22
use {
23
    frame_support::{
24
        pallet_prelude::GetStorageVersion,
25
        traits::{OnRuntimeUpgrade, PalletInfoAccess},
26
        weights::Weight,
27
    },
28
    pallet_migrations::{GetMigrations, Migration},
29
    sp_core::{Get, H160},
30
    sp_std::{marker::PhantomData, prelude::*},
31
    tanssi_runtime_common::migrations::{
32
        PolkadotXcmMigrationFixVersion, XcmpQueueMigrationFixVersion, XcmpQueueMigrationV3,
33
        XcmpQueueMigrationV4,
34
    },
35
};
36

            
37
pub struct MigratePrecompileXcmDummyCode<T>(pub PhantomData<T>);
38
impl<T> Migration for MigratePrecompileXcmDummyCode<T>
39
where
40
    T: pallet_evm::Config,
41
    T: frame_system::Config,
42
{
43
177
    fn friendly_name(&self) -> &str {
44
177
        "TM_MigratePrecompileXcmCode"
45
177
    }
46

            
47
    fn migrate(&self, _available_weight: Weight) -> Weight {
48
        log::info!("Performing migration: TM_MigratePrecompileXcmCode");
49
        let revert_bytecode = vec![0x60, 0x00, 0x60, 0x00, 0xFD];
50

            
51
        let db_weights = T::DbWeight::get();
52

            
53
        // Pallet-xcm precompile address
54
        let address = H160::from_low_u64_be(2052);
55
        let _ = pallet_evm::Pallet::<T>::create_account(address, revert_bytecode.clone(), None);
56

            
57
        // reads: <Suicided<T>> and <AccountCodes<T>>
58
        // writes: <AccountCodesMetadata<T>> and <AccountCodes<T>>
59
        db_weights.reads_writes(2, 2)
60
    }
61

            
62
    /// Run a standard pre-runtime test. This works the same way as in a normal runtime upgrade.
63
    #[cfg(feature = "try-runtime")]
64
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
65
        log::info!("Performing TM_MigratePrecompileXcmCode - pre_upgrade");
66

            
67
        let address = H160::from_low_u64_be(2052);
68
        assert!(pallet_evm::AccountCodes::<T>::get(address).is_empty());
69
        Ok(vec![])
70
    }
71

            
72
    /// Run a standard post-runtime test. This works the same way as in a normal runtime upgrade.
73
    #[cfg(feature = "try-runtime")]
74
    fn post_upgrade(&self, _: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
75
        log::info!("Performing TM_MigratePrecompileXcmCode - post_upgrade");
76

            
77
        let revert_bytecode = vec![0x60, 0x00, 0x60, 0x00, 0xFD];
78
        let address = H160::from_low_u64_be(2052);
79
        assert_eq!(pallet_evm::AccountCodes::<T>::get(address), revert_bytecode);
80
        Ok(())
81
    }
82
}
83

            
84
pub struct MigratePrecompileProxyDummyCode<T>(pub PhantomData<T>);
85
impl<T> Migration for MigratePrecompileProxyDummyCode<T>
86
where
87
    T: pallet_evm::Config,
88
    T: frame_system::Config,
89
{
90
177
    fn friendly_name(&self) -> &str {
91
177
        "TM_MigratePrecompileProxyCode"
92
177
    }
93

            
94
    fn migrate(&self, _available_weight: Weight) -> Weight {
95
        log::info!("Performing migration: TM_MigratePrecompileProxyCode");
96
        let revert_bytecode = vec![0x60, 0x00, 0x60, 0x00, 0xFD];
97

            
98
        let db_weights = T::DbWeight::get();
99

            
100
        // Pallet-xcm precompile address
101
        let address = H160::from_low_u64_be(2053);
102
        let _ = pallet_evm::Pallet::<T>::create_account(address, revert_bytecode.clone(), None);
103

            
104
        // reads: <Suicided<T>> and <AccountCodes<T>>
105
        // writes: <AccountCodesMetadata<T>> and <AccountCodes<T>>
106
        db_weights.reads_writes(2, 2)
107
    }
108

            
109
    /// Run a standard pre-runtime test. This works the same way as in a normal runtime upgrade.
110
    #[cfg(feature = "try-runtime")]
111
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
112
        log::info!("Performing TM_MigratePrecompileProxyCode - pre_upgrade");
113

            
114
        let address = H160::from_low_u64_be(2053);
115
        assert!(pallet_evm::AccountCodes::<T>::get(address).is_empty());
116
        Ok(vec![])
117
    }
118

            
119
    /// Run a standard post-runtime test. This works the same way as in a normal runtime upgrade.
120
    #[cfg(feature = "try-runtime")]
121
    fn post_upgrade(&self, _: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
122
        log::info!("Performing TM_MigratePrecompileProxyCode - post_upgrade");
123

            
124
        let revert_bytecode = vec![0x60, 0x00, 0x60, 0x00, 0xFD];
125
        let address = H160::from_low_u64_be(2053);
126
        assert_eq!(pallet_evm::AccountCodes::<T>::get(address), revert_bytecode);
127
        Ok(())
128
    }
129
}
130

            
131
pub struct TemplateMigrations<Runtime, XcmpQueue, PolkadotXcm>(
132
    PhantomData<(Runtime, XcmpQueue, PolkadotXcm)>,
133
);
134

            
135
pub struct MigrateToLatestXcmVersion<Runtime>(PhantomData<Runtime>);
136
impl<Runtime> Migration for MigrateToLatestXcmVersion<Runtime>
137
where
138
    pallet_xcm::migration::MigrateToLatestXcmVersion<Runtime>:
139
        frame_support::traits::OnRuntimeUpgrade,
140
{
141
177
    fn friendly_name(&self) -> &str {
142
177
        "MM_MigrateToLatestXcmVersion"
143
177
    }
144

            
145
    fn migrate(&self, _available_weight: Weight) -> Weight {
146
        pallet_xcm::migration::MigrateToLatestXcmVersion::<Runtime>::on_runtime_upgrade()
147
    }
148

            
149
    #[cfg(feature = "try-runtime")]
150
    fn pre_upgrade(&self) -> Result<Vec<u8>, sp_runtime::DispatchError> {
151
        pallet_xcm::migration::MigrateToLatestXcmVersion::<Runtime>::pre_upgrade()
152
    }
153

            
154
    #[cfg(feature = "try-runtime")]
155
    fn post_upgrade(&self, state: Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
156
        pallet_xcm::migration::MigrateToLatestXcmVersion::<Runtime>::post_upgrade(state)
157
    }
158
}
159

            
160
impl<Runtime, XcmpQueue, PolkadotXcm> GetMigrations
161
    for TemplateMigrations<Runtime, XcmpQueue, PolkadotXcm>
162
where
163
    PolkadotXcm: GetStorageVersion + PalletInfoAccess + 'static,
164
    XcmpQueue: GetStorageVersion + PalletInfoAccess + 'static,
165
    Runtime: pallet_evm::Config,
166
    Runtime: frame_system::Config,
167
    Runtime: cumulus_pallet_xcmp_queue::Config,
168
    Runtime: pallet_xcm_executor_utils::Config,
169
    Runtime: pallet_xcm::Config,
170
{
171
177
    fn get_migrations() -> Vec<Box<dyn Migration>> {
172
177
        // let migrate_precompiles = MigratePrecompileDummyCode::<Runtime>(Default::default());
173
177
        let migrate_polkadot_xcm_v1 =
174
177
            PolkadotXcmMigrationFixVersion::<Runtime, PolkadotXcm>(Default::default());
175
177
        let migrate_xcmp_queue_v2 =
176
177
            XcmpQueueMigrationFixVersion::<Runtime, XcmpQueue>(Default::default());
177
177
        let migrate_xcmp_queue_v3 = XcmpQueueMigrationV3::<Runtime>(Default::default());
178
177
        let migrate_xcmp_queue_v4 = XcmpQueueMigrationV4::<Runtime>(Default::default());
179
177
        let migrate_xcm_executor_utils_v4 =
180
177
            pallet_xcm_executor_utils::migrations::MigrateToV1::<Runtime>(Default::default());
181
177
        let migrate_pallet_xcm_v4 = MigrateToLatestXcmVersion::<Runtime>(Default::default());
182
177
        let migrate_precompile_proxy_code =
183
177
            MigratePrecompileProxyDummyCode::<Runtime>(Default::default());
184
177
        let migrate_precompile_xcm_code =
185
177
            MigratePrecompileXcmDummyCode::<Runtime>(Default::default());
186
177
        vec![
187
177
            // Applied in runtime 400
188
177
            // Box::new(migrate_precompiles),
189
177
            Box::new(migrate_polkadot_xcm_v1),
190
177
            Box::new(migrate_xcmp_queue_v2),
191
177
            Box::new(migrate_xcmp_queue_v3),
192
177
            Box::new(migrate_xcmp_queue_v4),
193
177
            Box::new(migrate_xcm_executor_utils_v4),
194
177
            Box::new(migrate_pallet_xcm_v4),
195
177
            Box::new(migrate_precompile_proxy_code),
196
177
            Box::new(migrate_precompile_xcm_code),
197
177
        ]
198
177
    }
199
}