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