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

difftreelog

refactor extract contracts logic to separate pallet

Yaroslav Bolyukin2021-06-24parent: #ee920c9.patch.diff
in: master

2 files changed

addedpallets/contract-helpers/src/lib.rsdiffbeforeafterboth
after · pallets/contract-helpers/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23pub use pallet::*;45#[frame_support::pallet]6pub mod pallet {7	use frame_support::sp_runtime::traits::StaticLookup;8	use frame_support::{pallet_prelude::*, traits::IsSubType};9	use frame_system::pallet_prelude::*;10	use pallet_contracts::chain_extension::UncheckedFrom;11	use sp_runtime::{12		traits::{DispatchInfoOf, Hash, PostDispatchInfoOf, SignedExtension},13		transaction_validity,14	};15	use sp_std::vec::Vec;16	use up_sponsorship::SponsorshipHandler;1718    #[pallet::error]19    pub enum Error<T> {20        /// Should be contract owner21        NoPermission,22    }2324	#[pallet::config]25	pub trait Config: frame_system::Config + pallet_contracts::Config {}2627	#[pallet::pallet]28	#[pallet::generate_store(pub(super) trait Store)]29	pub struct Pallet<T>(_);3031	#[pallet::storage]32	pub(super) type Owner<T: Config> = StorageMap<33		Hasher = Twox128,34		Key = T::AccountId,35		Value = T::AccountId,36		QueryKind = ValueQuery,37	>;3839	#[pallet::storage]40	pub(super) type AllowlistEnabled<T: Config> =41		StorageMap<Hasher = Twox128, Key = T::AccountId, Value = bool, QueryKind = ValueQuery>;4243	#[pallet::storage]44	pub(super) type Allowlist<T: Config> = StorageDoubleMap<45		Hasher1 = Twox128,46		Key1 = T::AccountId,47		Hasher2 = Twox64Concat,48		Key2 = T::AccountId,49		Value = bool,50		QueryKind = ValueQuery,51	>;5253	#[pallet::storage]54	pub(super) type SelfSponsoring<T: Config> =55		StorageMap<Hasher = Twox128, Key = T::AccountId, Value = bool, QueryKind = ValueQuery>;5657	#[pallet::storage]58	pub(super) type SponsoringRateLimit<T: Config> = StorageMap<59		Hasher = Twox128,60		Key = T::AccountId,61		Value = T::BlockNumber,62		QueryKind = ValueQuery,63	>;6465	#[pallet::storage]66	pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<67		Hasher1 = Twox128,68		Key1 = T::AccountId,69		Hasher2 = Twox128,70		Key2 = T::AccountId,71		Value = T::BlockNumber,72		QueryKind = ValueQuery,73	>;7475	#[pallet::call]76	impl<T: Config> Pallet<T> {77		#[pallet::weight(0)]78		fn toggle_sponsoring(79			origin: OriginFor<T>,80			contract: T::AccountId,81			sponsoring: bool,82		) -> DispatchResult {83			let sender = ensure_signed(origin)?;84			ensure!(<Owner<T>>::get(&contract) == sender, <Error<T>>::NoPermission);8586			if sponsoring {87				<SelfSponsoring<T>>::insert(contract, true);88			} else {89				<SelfSponsoring<T>>::remove(contract);90			}91			Ok(())92		}9394		#[pallet::weight(0)]95		fn toggle_allowlist(96			origin: OriginFor<T>,97			contract: T::AccountId,98			enabled: bool,99		) -> DispatchResult {100			let sender = ensure_signed(origin)?;101			ensure!(<Owner<T>>::get(&contract) == sender, <Error<T>>::NoPermission);102103			if enabled {104				<AllowlistEnabled<T>>::insert(contract, true);105			} else {106				<AllowlistEnabled<T>>::remove(contract);107			}108			Ok(())109		}110111		#[pallet::weight(0)]112		fn toggle_allowed(113			origin: OriginFor<T>,114			contract: T::AccountId,115			user: T::AccountId,116			allowed: bool,117		) -> DispatchResult {118			let sender = ensure_signed(origin)?;119			ensure!(<Owner<T>>::get(&contract) == sender, <Error<T>>::NoPermission);120121			if allowed {122				<Allowlist<T>>::insert(contract, user, true);123			} else {124				<Allowlist<T>>::remove(contract, user);125			}126			Ok(())127		}128129		#[pallet::weight(0)]130		fn set_sponsoring_rate_limit(131			origin: OriginFor<T>,132			contract: T::AccountId,133			rate_limit: T::BlockNumber,134		) -> DispatchResult {135			let sender = ensure_signed(origin)?;136			ensure!(<Owner<T>>::get(&contract) == sender, <Error<T>>::NoPermission);137138			<SponsoringRateLimit<T>>::insert(contract, rate_limit);139			Ok(())140		}141	}142143	#[derive(Encode, Decode, Clone, PartialEq, Eq)]144	pub struct ContractHelpersExtension<T>(PhantomData<T>);145	impl<T> core::fmt::Debug for ContractHelpersExtension<T> {146		fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {147			fmt.debug_struct("ContractHelpersExtension").finish()148		}149	}150151	type CodeHash<T> = <T as frame_system::Config>::Hash;152	impl<T> SignedExtension for ContractHelpersExtension<T>153	where154		T: Config + Send + Sync,155		T::Call: sp_runtime::traits::Dispatchable,156		T::Call: IsSubType<pallet_contracts::Call<T>>,157		T::AccountId: UncheckedFrom<T::Hash>,158		T::AccountId: AsRef<[u8]>,159	{160		const IDENTIFIER: &'static str = "ContractHelpers";161		type AccountId = T::AccountId;162		type Call = T::Call;163		type AdditionalSigned = ();164		type Pre = Option<(Self::AccountId, CodeHash<T>, Vec<u8>)>;165166		fn additional_signed(&self) -> Result<(), transaction_validity::TransactionValidityError> {167			Ok(())168		}169170		fn validate(171			&self,172			who: &T::AccountId,173			call: &Self::Call,174			_info: &DispatchInfoOf<Self::Call>,175			_len: usize,176		) -> transaction_validity::TransactionValidity {177			match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {178				Some(pallet_contracts::Call::call(dest, _value, _gas_limit, _data)) => {179					let called_contract: T::AccountId =180						T::Lookup::lookup((*dest).clone()).unwrap_or(T::AccountId::default());181					if <AllowlistEnabled<T>>::get(&called_contract) {182						if !<Allowlist<T>>::get(&called_contract, who)183							&& &<Owner<T>>::get(&called_contract) != who184						{185							return Err(transaction_validity::InvalidTransaction::Call.into());186						}187					}188				}189				_ => {}190			}191			Ok(transaction_validity::ValidTransaction::default())192		}193194		fn pre_dispatch(195			self,196			who: &Self::AccountId,197			call: &Self::Call,198			_info: &DispatchInfoOf<Self::Call>,199			_len: usize,200		) -> Result<Self::Pre, TransactionValidityError> {201			match IsSubType::<pallet_contracts::Call<T>>::is_sub_type(call) {202				Some(pallet_contracts::Call::instantiate(_, _, code_hash, _, salt)) => {203					Ok(Some((who.clone(), code_hash.clone(), salt.clone())))204				}205				Some(pallet_contracts::Call::instantiate_with_code(_, _, code, _, salt)) => {206					let code_hash = &T::Hashing::hash(&code);207					Ok(Some((who.clone(), code_hash.clone(), salt.clone())))208				}209				_ => Ok(None),210			}211		}212213		fn post_dispatch(214			pre: Self::Pre,215			_info: &DispatchInfoOf<Self::Call>,216			_post_info: &PostDispatchInfoOf<Self::Call>,217			_len: usize,218			_result: &DispatchResult,219		) -> Result<(), TransactionValidityError> {220			if let Some((who, code_hash, salt)) = pre {221				let new_contract_address =222					<pallet_contracts::Pallet<T>>::contract_address(&who, &code_hash, &salt);223				<Owner<T>>::insert(&new_contract_address, &who);224			}225226			Ok(())227		}228	}229230}
modifiedpallets/nft/src/lib.rsdiffbeforeafterboth
--- a/pallets/nft/src/lib.rs
+++ b/pallets/nft/src/lib.rs
@@ -343,21 +343,6 @@
         /// Variable metadata sponsoring
         /// Collection id (controlled?2), token id (controlled?2)
         pub VariableMetaDataBasket get(fn variable_meta_data_basket): double_map hasher(blake2_128_concat) CollectionId, hasher(blake2_128_concat) TokenId => Option<T::BlockNumber> = None;
-      
-        //#region Contract Sponsorship and Ownership
-        /// Contract address (real)
-        pub ContractOwner get(fn contract_owner): map hasher(twox_64_concat) T::AccountId => Option<T::AccountId>;
-        /// Contract address (real)
-        pub ContractSelfSponsoring get(fn contract_self_sponsoring): map hasher(twox_64_concat) T::AccountId => bool;
-        /// (Contract address(real), caller (real))
-        pub ContractSponsorBasket get(fn contract_sponsor_basket): map hasher(twox_64_concat) (T::AccountId, T::AccountId) => T::BlockNumber;
-        /// Contract address (real)
-        pub ContractSponsoringRateLimit get(fn contract_sponsoring_rate_limit): map hasher(twox_64_concat) T::AccountId => T::BlockNumber;
-        /// Contract address (real)
-        pub ContractWhiteListEnabled get(fn contract_white_list_enabled): map hasher(twox_64_concat) T::AccountId => bool; 
-        /// Contract address (real) => Whitelisted user (controlled?3)
-        pub ContractWhiteList get(fn contract_white_list): double_map hasher(twox_64_concat) T::AccountId, hasher(blake2_128_concat) T::AccountId => bool; 
-        //#endregion
     }
     add_extra_genesis {
         build(|config: &GenesisConfig<T>| {
@@ -1233,158 +1218,6 @@
             ensure_root(origin)?;
 
             <ChainLimit>::put(limits);
-            Ok(())
-        }
-
-        /// Enable smart contract self-sponsoring.
-        /// 
-        /// # Permissions
-        /// 
-        /// * Contract Owner
-        /// 
-        /// # Arguments
-        /// 
-        /// * contract address
-        /// * enable flag
-        /// 
-        #[weight = <T as Config>::WeightInfo::enable_contract_sponsoring()]
-        #[transactional]
-        pub fn enable_contract_sponsoring(
-            origin,
-            contract_address: T::AccountId,
-            enable: bool
-        ) -> DispatchResult {
-
-            let sender = ensure_signed(origin)?;
-
-            #[cfg(feature = "runtime-benchmarks")]
-            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());
-
-            Self::ensure_contract_owned(sender, &contract_address)?;
-
-            <ContractSelfSponsoring<T>>::insert(contract_address, enable);
-            Ok(())
-        }
-
-        /// Set the rate limit for contract sponsoring to specified number of blocks.
-        /// 
-        /// If not set (has the default value of 0 blocks), the sponsoring will be disabled. 
-        /// If set to the number B (for blocks), the transactions will be sponsored with a rate 
-        /// limit of B, i.e. fees for every transaction sent to this smart contract will be paid 
-        /// from contract endowment if there are at least B blocks between such transactions. 
-        /// Nonetheless, if transactions are sent more frequently, the fees are paid by the sender.
-        /// 
-        /// # Permissions
-        /// 
-        /// * Contract Owner
-        /// 
-        /// # Arguments
-        /// 
-        /// -`contract_address`: Address of the contract to sponsor
-        /// -`rate_limit`: Number of blocks to wait until the next sponsored transaction is allowed
-        /// 
-        #[weight = <T as Config>::WeightInfo::set_contract_sponsoring_rate_limit()]
-        #[transactional]
-        pub fn set_contract_sponsoring_rate_limit(
-            origin,
-            contract_address: T::AccountId,
-            rate_limit: T::BlockNumber
-        ) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
-
-            #[cfg(feature = "runtime-benchmarks")]
-            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());
-
-            Self::ensure_contract_owned(sender, &contract_address)?;
-            <ContractSponsoringRateLimit<T>>::insert(contract_address, rate_limit);
-            Ok(())
-        }
-
-        /// Enable the white list for a contract. Only addresses added to the white list with addToContractWhiteList will be able to call this smart contract.
-        /// 
-        /// # Permissions
-        /// 
-        /// * Address that deployed smart contract.
-        /// 
-        /// # Arguments
-        /// 
-        /// -`contract_address`: Address of the contract.
-        /// 
-        /// - `enable`: .  
-        #[weight = <T as Config>::WeightInfo::toggle_contract_white_list()]
-        #[transactional]
-        pub fn toggle_contract_white_list(
-            origin,
-            contract_address: T::AccountId,
-            enable: bool
-        ) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
-
-            #[cfg(feature = "runtime-benchmarks")]
-            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());
-
-            Self::ensure_contract_owned(sender, &contract_address)?;
-            if enable {
-                <ContractWhiteListEnabled<T>>::insert(contract_address, true);
-            } else {
-                <ContractWhiteListEnabled<T>>::remove(contract_address);
-            }
-            Ok(())
-        }
-        
-        /// Add an address to smart contract white list.
-        /// 
-        /// # Permissions
-        /// 
-        /// * Address that deployed smart contract.
-        /// 
-        /// # Arguments
-        /// 
-        /// -`contract_address`: Address of the contract.
-        ///
-        /// -`account_address`: Address to add.
-        #[weight = <T as Config>::WeightInfo::add_to_contract_white_list()]
-        #[transactional]
-        pub fn add_to_contract_white_list(
-            origin,
-            contract_address: T::AccountId,
-            account_address: T::AccountId
-        ) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
-
-            #[cfg(feature = "runtime-benchmarks")]
-            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());
-            
-            Self::ensure_contract_owned(sender, &contract_address)?;      
-            <ContractWhiteList<T>>::insert(contract_address, account_address, true);
-            Ok(())
-        }
-
-        /// Remove an address from smart contract white list.
-        /// 
-        /// # Permissions
-        /// 
-        /// * Address that deployed smart contract.
-        /// 
-        /// # Arguments
-        /// 
-        /// -`contract_address`: Address of the contract.
-        ///
-        /// -`account_address`: Address to remove.
-        #[weight = <T as Config>::WeightInfo::remove_from_contract_white_list()]
-        #[transactional]
-        pub fn remove_from_contract_white_list(
-            origin,
-            contract_address: T::AccountId,
-            account_address: T::AccountId
-        ) -> DispatchResult {
-            let sender = ensure_signed(origin)?;
-
-            #[cfg(feature = "runtime-benchmarks")]
-            <ContractOwner<T>>::insert(contract_address.clone(), sender.clone());
-
-            Self::ensure_contract_owned(sender, &contract_address)?;
-            <ContractWhiteList<T>>::remove(contract_address, account_address);
             Ok(())
         }