git.delta.rocks / unique-network / refs/commits / f8930f84e9cd

difftreelog

source

pallets/data-management/src/lib.rs5.7 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::{29		pallet_prelude::{*, DispatchResult},30		traits::IsType,31	};32	use frame_system::pallet_prelude::{*, OriginFor};33	use sp_core::{H160, H256};34	use sp_std::vec::Vec;35	use super::weights::WeightInfo;36	use pallet_evm::{PrecompileHandle, Pallet as PalletEvm};37	use pallet_identity::Registration;3839	#[pallet::config]40	pub trait Config: frame_system::Config + pallet_evm::Config + pallet_identity::Config {41		/// Weights42		type WeightInfo: WeightInfo;43		/// The overarching event type.44		type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;45	}4647	type SelfWeightOf<T> = <T as Config>::WeightInfo;4849	#[pallet::pallet]50	#[pallet::generate_store(pub(super) trait Store)]51	pub struct Pallet<T>(_);5253	#[pallet::event]54	pub enum Event<T: Config> {55		/// This event is used in benchmarking and can be used for tests56		TestEvent,57	}5859	#[pallet::error]60	pub enum Error<T> {61		/// Can only migrate to empty address.62		AccountNotEmpty,63		/// Migration of this account is not yet started, or already finished.64		AccountIsNotMigrating,65		/// Failed to decode event bytes66		BadEvent,67	}6869	#[pallet::storage]70	pub(super) type MigrationPending<T: Config> =71		StorageMap<Hasher = Twox64Concat, Key = H160, Value = bool, QueryKind = ValueQuery>;7273	#[pallet::call]74	impl<T: Config> Pallet<T> {75		/// Start contract migration, inserts contract stub at target address,76		/// and marks account as pending, allowing to insert storage77		#[pallet::call_index(0)]78		#[pallet::weight(<SelfWeightOf<T>>::begin())]79		pub fn begin(origin: OriginFor<T>, address: H160) -> DispatchResult {80			ensure_root(origin)?;81			ensure!(82				<PalletEvm<T>>::is_account_empty(&address) && !<MigrationPending<T>>::get(&address),83				<Error<T>>::AccountNotEmpty,84			);8586			<MigrationPending<T>>::insert(address, true);87			Ok(())88		}8990		/// Insert items into contract storage, this method can be called91		/// multiple times92		#[pallet::call_index(1)]93		#[pallet::weight(<SelfWeightOf<T>>::set_data(data.len() as u32))]94		pub fn set_data(95			origin: OriginFor<T>,96			address: H160,97			data: Vec<(H256, H256)>,98		) -> DispatchResult {99			ensure_root(origin)?;100			ensure!(101				<MigrationPending<T>>::get(&address),102				<Error<T>>::AccountIsNotMigrating,103			);104105			for (k, v) in data {106				<pallet_evm::AccountStorages<T>>::insert(&address, k, v);107			}108			Ok(())109		}110111		/// Finish contract migration, allows it to be called.112		/// It is not possible to alter contract storage via [`Self::set_data`]113		/// after this call.114		#[pallet::call_index(2)]115		#[pallet::weight(<SelfWeightOf<T>>::finish(code.len() as u32))]116		pub fn finish(origin: OriginFor<T>, address: H160, code: Vec<u8>) -> DispatchResult {117			ensure_root(origin)?;118			ensure!(119				<MigrationPending<T>>::get(&address),120				<Error<T>>::AccountIsNotMigrating,121			);122123			<pallet_evm::AccountCodes<T>>::insert(&address, code);124			<MigrationPending<T>>::remove(address);125			Ok(())126		}127128		/// Create ethereum events attached to the fake transaction129		#[pallet::call_index(3)]130		#[pallet::weight(<SelfWeightOf<T>>::insert_eth_logs(logs.len() as u32))]131		pub fn insert_eth_logs(origin: OriginFor<T>, logs: Vec<ethereum::Log>) -> DispatchResult {132			ensure_root(origin)?;133			for log in logs {134				<pallet_evm::Pallet<T>>::deposit_log(log);135			}136			// Transactions is created by FakeTransactionFinalizer137			Ok(())138		}139140		/// Create substrate events141		#[pallet::call_index(4)]142		#[pallet::weight(<SelfWeightOf<T>>::insert_events(events.len() as u32))]143		pub fn insert_events(origin: OriginFor<T>, events: Vec<Vec<u8>>) -> DispatchResult {144			ensure_root(origin)?;145			for event in events {146				<frame_system::Pallet<T>>::deposit_event(147					<T as frame_system::Config>::RuntimeEvent::decode(&mut event.as_slice())148						.map_err(|_| <Error<T>>::BadEvent)?,149				);150			}151			Ok(())152		}153154		/// Insert or remove identities.155		#[pallet::call_index(5)]156		#[pallet::weight(<SelfWeightOf<T>>::insert_events(identities.len() as u32))] // todo:collator weight157		pub fn insert_identities(158			origin: OriginFor<T>,159			identities: Vec<(160				T::AccountId,161				Option<Registration<pallet_identity::BalanceOf<T>, T::MaxRegistrars, T::MaxAdditionalFields>>,162			)>,163		) -> DispatchResult {164			ensure_root(origin)?;165			for identity in identities {166				<pallet_identity::IdentityOf<T>>::set(identity.0, identity.1);167			}168			Ok(())169		}170	}171172	/// Implements [`pallet_evm::OnMethodCall`], which reserves accounts with pending migration173	pub struct OnMethodCall<T>(PhantomData<T>);174	impl<T: Config> pallet_evm::OnMethodCall<T> for OnMethodCall<T> {175		fn is_reserved(contract: &H160) -> bool {176			<MigrationPending<T>>::get(&contract)177		}178179		fn is_used(_contract: &H160) -> bool {180			false181		}182183		fn call(_handle: &mut impl PrecompileHandle) -> Option<pallet_evm::PrecompileResult> {184			None185		}186187		fn get_code(_contract: &H160) -> Option<Vec<u8>> {188			None189		}190	}191}