difftreelog
refactor extract contracts logic to separate pallet
in: master
2 files changed
pallets/contract-helpers/src/lib.rsdiffbeforeafterboth1#![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}pallets/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(())
}