snowbridge_pallet_system/
migration.rs1use super::*;
5use frame_support::{
6 migrations::VersionedMigration,
7 pallet_prelude::*,
8 traits::{OnRuntimeUpgrade, UncheckedOnRuntimeUpgrade},
9 weights::Weight,
10};
11use log;
12use sp_std::marker::PhantomData;
13
14#[cfg(feature = "try-runtime")]
15use sp_runtime::TryRuntimeError;
16
17const LOG_TARGET: &str = "ethereum_system::migration";
18
19pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(1);
21
22pub mod v0 {
23 use super::*;
24
25 pub struct InitializeOnUpgrade<T, BridgeHubParaId, AssetHubParaId>(
26 PhantomData<(T, BridgeHubParaId, AssetHubParaId)>,
27 );
28
29 impl<T, BridgeHubParaId, AssetHubParaId> OnRuntimeUpgrade
30 for InitializeOnUpgrade<T, BridgeHubParaId, AssetHubParaId>
31 where
32 T: Config,
33 BridgeHubParaId: Get<u32>,
34 AssetHubParaId: Get<u32>,
35 {
36 fn on_runtime_upgrade() -> Weight {
37 if !Pallet::<T>::is_initialized() {
38 Pallet::<T>::initialize(
39 BridgeHubParaId::get().into(),
40 AssetHubParaId::get().into(),
41 )
42 .expect("infallible; qed");
43 log::info!(
44 target: LOG_TARGET,
45 "Ethereum system initialized."
46 );
47 T::DbWeight::get().reads_writes(2, 5)
48 } else {
49 log::info!(
50 target: LOG_TARGET,
51 "Ethereum system already initialized. Skipping."
52 );
53 T::DbWeight::get().reads(2)
54 }
55 }
56
57 #[cfg(feature = "try-runtime")]
58 fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
59 if !Pallet::<T>::is_initialized() {
60 log::info!(
61 target: LOG_TARGET,
62 "Agents and channels not initialized. Initialization will run."
63 );
64 } else {
65 log::info!(
66 target: LOG_TARGET,
67 "Agents and channels are initialized. Initialization will not run."
68 );
69 }
70 Ok(vec![])
71 }
72
73 #[cfg(feature = "try-runtime")]
74 fn post_upgrade(_: Vec<u8>) -> Result<(), TryRuntimeError> {
75 frame_support::ensure!(
76 Pallet::<T>::is_initialized(),
77 "Agents and channels were not initialized."
78 );
79 Ok(())
80 }
81 }
82}
83
84pub mod v1 {
85 use super::*;
86
87 #[cfg(feature = "try-runtime")]
88 use sp_core::U256;
89
90 pub struct FeePerGasMigration<T>(PhantomData<T>);
92
93 #[cfg(feature = "try-runtime")]
94 impl<T> FeePerGasMigration<T>
95 where
96 T: Config,
97 {
98 fn calculate_remote_fee_v1(params: &PricingParametersOf<T>) -> U256 {
100 use snowbridge_outbound_queue_primitives::v1::{
101 AgentExecuteCommand, Command, ConstantGasMeter, GasMeter,
102 };
103 let command = Command::AgentExecute {
104 agent_id: H256::zero(),
105 command: AgentExecuteCommand::TransferToken {
106 token: H160::zero(),
107 recipient: H160::zero(),
108 amount: 0,
109 },
110 };
111 let gas_used_at_most = ConstantGasMeter::maximum_gas_used_at_most(&command);
112 params
113 .fee_per_gas
114 .saturating_mul(gas_used_at_most.into())
115 .saturating_add(params.rewards.remote)
116 }
117
118 fn calculate_remote_fee_v2(params: &PricingParametersOf<T>) -> U256 {
120 use snowbridge_outbound_queue_primitives::v2::{Command, ConstantGasMeter, GasMeter};
121 let command = Command::UnlockNativeToken {
122 token: H160::zero(),
123 recipient: H160::zero(),
124 amount: 0,
125 };
126 let gas_used_at_most = ConstantGasMeter::maximum_dispatch_gas_used_at_most(&command);
127 params
128 .fee_per_gas
129 .saturating_mul(gas_used_at_most.into())
130 .saturating_add(params.rewards.remote)
131 }
132 }
133
134 const GAS_INCREASE_PERCENTAGE: u64 = 70;
136
137 impl<T> UncheckedOnRuntimeUpgrade for FeePerGasMigration<T>
138 where
139 T: Config,
140 {
141 fn on_runtime_upgrade() -> Weight {
142 let mut params = Pallet::<T>::parameters();
143
144 let old_fee_per_gas = params.fee_per_gas;
145
146 params.fee_per_gas = params.fee_per_gas * GAS_INCREASE_PERCENTAGE / 100;
149
150 log::info!(
151 target: LOG_TARGET,
152 "Fee per gas migrated from {old_fee_per_gas:?} to {0:?}.",
153 params.fee_per_gas,
154 );
155
156 PricingParameters::<T>::put(params);
157 T::DbWeight::get().reads_writes(1, 1)
158 }
159
160 #[cfg(feature = "try-runtime")]
161 fn pre_upgrade() -> Result<Vec<u8>, TryRuntimeError> {
162 use codec::Encode;
163
164 let params = Pallet::<T>::parameters();
165 let remote_fee_v1 = Self::calculate_remote_fee_v1(¶ms);
166 let remote_fee_v2 = Self::calculate_remote_fee_v2(¶ms);
167
168 log::info!(
169 target: LOG_TARGET,
170 "Pre fee per gas migration: pricing parameters = {params:?}, remote_fee_v1 = {remote_fee_v1:?}, remote_fee_v2 = {remote_fee_v2:?}"
171 );
172 Ok((params, remote_fee_v1, remote_fee_v2).encode())
173 }
174
175 #[cfg(feature = "try-runtime")]
176 fn post_upgrade(state: Vec<u8>) -> Result<(), TryRuntimeError> {
177 use codec::Decode;
178
179 let (old_params, old_remote_fee_v1, old_remote_fee_v2): (
180 PricingParametersOf<T>,
181 U256,
182 U256,
183 ) = Decode::decode(&mut &state[..]).unwrap();
184
185 let params = Pallet::<T>::parameters();
186 ensure!(old_params.exchange_rate == params.exchange_rate, "Exchange rate unchanged.");
187 ensure!(old_params.rewards == params.rewards, "Rewards unchanged.");
188 ensure!(
189 (old_params.fee_per_gas * GAS_INCREASE_PERCENTAGE / 100) == params.fee_per_gas,
190 "Fee per gas decreased."
191 );
192 ensure!(old_params.multiplier == params.multiplier, "Multiplier unchanged.");
193
194 let remote_fee_v1 = Self::calculate_remote_fee_v1(¶ms);
195 let remote_fee_v2 = Self::calculate_remote_fee_v2(¶ms);
196 ensure!(
197 remote_fee_v1 <= old_remote_fee_v1,
198 "The v1 remote fee can cover the cost of the previous fee."
199 );
200 ensure!(
201 remote_fee_v2 <= old_remote_fee_v2,
202 "The v2 remote fee can cover the cost of the previous fee."
203 );
204
205 log::info!(
206 target: LOG_TARGET,
207 "Post fee per gas migration: pricing parameters = {params:?} remote_fee_v1 = {remote_fee_v1:?} remote_fee_v2 = {remote_fee_v2:?}"
208 );
209 Ok(())
210 }
211 }
212}
213
214pub type FeePerGasMigrationV0ToV1<T> = VersionedMigration<
216 0,
217 1,
218 v1::FeePerGasMigration<T>,
219 Pallet<T>,
220 <T as frame_system::Config>::DbWeight,
221>;