referrerpolicy=no-referrer-when-downgrade

pallet_xcm_bridge_hub/
migration.rs

1// Copyright (C) Parity Technologies (UK) Ltd.
2// This file is part of Parity Bridges Common.
3
4// Parity Bridges Common 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// Parity Bridges Common 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 Parity Bridges Common.  If not, see <http://www.gnu.org/licenses/>.
16
17//! A module that is responsible for migration of storage.
18
19use crate::{Config, Pallet, LOG_TARGET};
20use frame_support::{
21	traits::{Get, OnRuntimeUpgrade, StorageVersion},
22	weights::Weight,
23};
24use xcm::prelude::{InteriorLocation, Location};
25
26/// The in-code storage version.
27pub const STORAGE_VERSION: StorageVersion = StorageVersion::new(0);
28
29/// This migration does not modify storage but can be used to open a bridge and link it to the
30/// specified LaneId. This is useful when we want to open a bridge and use a custom LaneId instead
31/// of the pre-calculated one provided by the `fn open_bridge extrinsic`.
32/// Or perhaps if you want to ensure that your runtime (e.g., for testing) always has an open
33/// bridge.
34pub struct OpenBridgeForLane<
35	T,
36	I,
37	Lane,
38	CreateLane,
39	SourceRelativeLocation,
40	BridgedUniversalLocation,
41>(
42	core::marker::PhantomData<(
43		T,
44		I,
45		Lane,
46		CreateLane,
47		SourceRelativeLocation,
48		BridgedUniversalLocation,
49	)>,
50);
51impl<
52		T: Config<I>,
53		I: 'static,
54		Lane: Get<T::LaneId>,
55		CreateLane: Get<bool>,
56		SourceRelativeLocation: Get<Location>,
57		BridgedUniversalLocation: Get<InteriorLocation>,
58	> OnRuntimeUpgrade
59	for OpenBridgeForLane<T, I, Lane, CreateLane, SourceRelativeLocation, BridgedUniversalLocation>
60{
61	fn on_runtime_upgrade() -> Weight {
62		let bridge_origin_relative_location = SourceRelativeLocation::get();
63		let bridge_destination_universal_location = BridgedUniversalLocation::get();
64		let lane_id = Lane::get();
65		let create_lane = CreateLane::get();
66		tracing::info!(
67			target: LOG_TARGET,
68			?lane_id,
69			?create_lane,
70			?bridge_origin_relative_location,
71			?bridge_destination_universal_location,
72			"OpenBridgeForLane - going to open bridge"
73		);
74
75		let locations = match Pallet::<T, I>::bridge_locations(
76			bridge_origin_relative_location.clone(),
77			bridge_destination_universal_location.clone(),
78		) {
79			Ok(locations) => locations,
80			Err(e) => {
81				tracing::error!(
82					target: LOG_TARGET,
83					error=?e,
84					"OpenBridgeForLane - on_runtime_upgrade failed to construct bridge_locations"
85				);
86				return T::DbWeight::get().reads(0)
87			},
88		};
89
90		// check if already exists
91		if let Some((bridge_id, bridge)) = Pallet::<T, I>::bridge_by_lane_id(&lane_id) {
92			tracing::info!(
93				target: LOG_TARGET,
94				?bridge,
95				?bridge_id,
96				?lane_id,
97				"OpenBridgeForLane - already exist!"
98			);
99			if &bridge_id != locations.bridge_id() {
100				tracing::warn!(
101					target: LOG_TARGET,
102					?bridge,
103					?bridge_id,
104					?lane_id,
105					?bridge_origin_relative_location,
106					?bridge_destination_universal_location,
107					"OpenBridgeForLane - check you parameters, because a different bridge exist for requested!"
108				);
109			}
110
111			return T::DbWeight::get().reads(2)
112		}
113
114		if let Err(e) = Pallet::<T, I>::do_open_bridge(locations, lane_id, create_lane) {
115			tracing::error!(target: LOG_TARGET, error=?e, "OpenBridgeForLane - do_open_bridge failed");
116			T::DbWeight::get().reads(6)
117		} else {
118			tracing::info!(target: LOG_TARGET, "OpenBridgeForLane - do_open_bridge passed!");
119			T::DbWeight::get().reads_writes(6, 4)
120		}
121	}
122
123	#[cfg(feature = "try-runtime")]
124	fn post_upgrade(_state: sp_std::vec::Vec<u8>) -> Result<(), sp_runtime::DispatchError> {
125		let bridge_origin_relative_location = SourceRelativeLocation::get();
126		let bridge_destination_universal_location = BridgedUniversalLocation::get();
127		let lane_id = Lane::get();
128
129		// check that requested bridge is stored
130		let Ok(locations) = Pallet::<T, I>::bridge_locations(
131			bridge_origin_relative_location.clone(),
132			bridge_destination_universal_location.clone(),
133		) else {
134			return Err(sp_runtime::DispatchError::Other("Invalid locations!"))
135		};
136		let Some((bridge_id, _)) = Pallet::<T, I>::bridge_by_lane_id(&lane_id) else {
137			return Err(sp_runtime::DispatchError::Other("Missing bridge!"))
138		};
139		frame_support::ensure!(
140			locations.bridge_id() == &bridge_id,
141			"Bridge is not stored correctly!"
142		);
143
144		tracing::info!(
145			target: LOG_TARGET,
146			?lane_id,
147			?bridge_origin_relative_location,
148			?bridge_destination_universal_location,
149			"OpenBridgeForLane - post_upgrade found opened bridge"
150		);
151
152		Ok(())
153	}
154}