git.delta.rocks / unique-network / refs/commits / 3833b2da5ea7

difftreelog

source

pallets/evm-migration/src/lib.rs3.9 KiBsourcehistory
1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617#![doc = include_str!("../README.md")]18#![cfg_attr(not(feature = "std"), no_std)]19#![deny(missing_docs)]2021pub use pallet::*;22#[cfg(feature = "runtime-benchmarks")]23pub mod benchmarking;24pub mod weights;2526#[frame_support::pallet]27pub mod pallet {28	use frame_support::pallet_prelude::*;29	use frame_system::pallet_prelude::*;30	use sp_core::{H160, H256};31	use sp_std::vec::Vec;32	use super::weights::WeightInfo;33	use pallet_evm::{PrecompileHandle, Pallet as PalletEvm};3435	#[pallet::config]36	pub trait Config: frame_system::Config + pallet_evm::Config {37		/// Weights38		type WeightInfo: WeightInfo;39	}4041	type SelfWeightOf<T> = <T as Config>::WeightInfo;4243	#[pallet::pallet]44	#[pallet::generate_store(pub(super) trait Store)]45	pub struct Pallet<T>(_);4647	#[pallet::error]48	pub enum Error<T> {49		/// Can only migrate to empty address.50		AccountNotEmpty,51		/// Migration of this account is not yet started, or already finished.52		AccountIsNotMigrating,53	}5455	#[pallet::storage]56	pub(super) type MigrationPending<T: Config> =57		StorageMap<Hasher = Twox64Concat, Key = H160, Value = bool, QueryKind = ValueQuery>;5859	#[pallet::call]60	impl<T: Config> Pallet<T> {61		/// Start contract migration, inserts contract stub at target address,62		/// and marks account as pending, allowing to insert storage63		#[pallet::weight(<SelfWeightOf<T>>::begin())]64		pub fn begin(origin: OriginFor<T>, address: H160) -> DispatchResult {65			ensure_root(origin)?;66			ensure!(67				<PalletEvm<T>>::is_account_empty(&address) && !<MigrationPending<T>>::get(&address),68				<Error<T>>::AccountNotEmpty,69			);7071			<MigrationPending<T>>::insert(address, true);72			Ok(())73		}7475		/// Insert items into contract storage, this method can be called76		/// multiple times77		#[pallet::weight(<SelfWeightOf<T>>::set_data(data.len() as u32))]78		pub fn set_data(79			origin: OriginFor<T>,80			address: H160,81			data: Vec<(H256, H256)>,82		) -> DispatchResult {83			ensure_root(origin)?;84			ensure!(85				<MigrationPending<T>>::get(&address),86				<Error<T>>::AccountIsNotMigrating,87			);8889			for (k, v) in data {90				<pallet_evm::AccountStorages<T>>::insert(&address, k, v);91			}92			Ok(())93		}9495		/// Finish contract migration, allows it to be called.96		/// It is not possible to alter contract storage via [`Self::set_data`]97		/// after this call.98		#[pallet::weight(<SelfWeightOf<T>>::finish(code.len() as u32))]99		pub fn finish(origin: OriginFor<T>, address: H160, code: Vec<u8>) -> DispatchResult {100			ensure_root(origin)?;101			ensure!(102				<MigrationPending<T>>::get(&address),103				<Error<T>>::AccountIsNotMigrating,104			);105106			<pallet_evm::AccountCodes<T>>::insert(&address, code);107			<MigrationPending<T>>::remove(address);108			Ok(())109		}110	}111112	/// Implements [`pallet_evm::OnMethodCall`], which reserves accounts with pending migration113	pub struct OnMethodCall<T>(PhantomData<T>);114	impl<T: Config> pallet_evm::OnMethodCall<T> for OnMethodCall<T> {115		fn is_reserved(contract: &H160) -> bool {116			<MigrationPending<T>>::get(&contract)117		}118119		fn is_used(_contract: &H160) -> bool {120			false121		}122123		fn call(_handle: &mut impl PrecompileHandle) -> Option<pallet_evm::PrecompileResult> {124			None125		}126127		fn get_code(_contract: &H160) -> Option<Vec<u8>> {128			None129		}130	}131}