difftreelog
chore add posibility to define different limits for methods in the future
in: master
2 files changed
pallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -263,7 +263,7 @@
}
fn get_sponsoring_fee_limit(&self, contract_address: address) -> Result<uint256> {
- Ok(<SponsoringFeeLimit<T>>::get(contract_address))
+ Ok(<SponsoringFeeLimit<T>>::get(contract_address, 0xffffffff))
}
/// Is specified user present in contract allow list
@@ -413,7 +413,7 @@
}
}
- let sponsored_fee_limit = <SponsoringFeeLimit<T>>::get(contract_address);
+ let sponsored_fee_limit = <SponsoringFeeLimit<T>>::get(contract_address, 0xffffffff);
if call_context.max_fee > sponsored_fee_limit {
return None;
pallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth1// 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#![warn(missing_docs)]2021use codec::{Decode, Encode, MaxEncodedLen};22pub use pallet::*;23pub use eth::*;24use scale_info::TypeInfo;25pub mod eth;2627#[frame_support::pallet]28pub mod pallet {29 pub use super::*;30 use crate::eth::ContractHelpersEvents;31 use frame_support::pallet_prelude::*;32 use pallet_evm_coder_substrate::DispatchResult;33 use sp_core::{H160, U256};34 use pallet_evm::{account::CrossAccountId, Pallet as PalletEvm};35 use up_data_structs::SponsorshipState;36 use evm_coder::ToLog;3738 #[pallet::config]39 pub trait Config:40 frame_system::Config + pallet_evm_coder_substrate::Config + pallet_evm::account::Config41 {42 /// Overarching event type.43 type Event: IsType<<Self as frame_system::Config>::Event> + From<Event<Self>>;4445 /// Address, under which magic contract will be available46 type ContractAddress: Get<H160>;4748 /// In case of enabled sponsoring, but no sponsoring rate limit set,49 /// this value will be used implicitly50 type DefaultSponsoringRateLimit: Get<Self::BlockNumber>;51 /// In case of enabled sponsoring, but no sponsoring fee limit set,52 /// this value will be used implicitly53 type DefaultSponsoringFeeLimit: Get<U256>;54 }5556 #[pallet::error]57 pub enum Error<T> {58 /// This method is only executable by contract owner59 NoPermission,6061 /// No pending sponsor for contract.62 NoPendingSponsor,63 }6465 #[pallet::pallet]66 #[pallet::generate_store(pub(super) trait Store)]67 pub struct Pallet<T>(_);6869 /// Store owner for contract.70 ///71 /// * **Key** - contract address.72 /// * **Value** - owner for contract.73 #[pallet::storage]74 pub(super) type Owner<T: Config> =75 StorageMap<Hasher = Twox128, Key = H160, Value = H160, QueryKind = ValueQuery>;7677 #[pallet::storage]78 #[deprecated]79 pub(super) type SelfSponsoring<T: Config> =80 StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;8182 /// Store for contract sponsorship state.83 ///84 /// * **Key** - contract address.85 /// * **Value** - sponsorship state.86 #[pallet::storage]87 pub(super) type Sponsoring<T: Config> = StorageMap<88 Hasher = Twox64Concat,89 Key = H160,90 Value = SponsorshipState<T::CrossAccountId>,91 QueryKind = ValueQuery,92 >;9394 /// Store for sponsoring mode.95 ///96 /// ### Usage97 /// Prefer to delete collection from storage if mode chaged to [`Disabled`](SponsoringModeT::Disabled).98 ///99 /// * **Key** - contract address.100 /// * **Value** - [`sponsoring mode`](SponsoringModeT).101 #[pallet::storage]102 pub(super) type SponsoringMode<T: Config> =103 StorageMap<Hasher = Twox128, Key = H160, Value = SponsoringModeT, QueryKind = OptionQuery>;104105 /// Storage for sponsoring rate limit in blocks.106 ///107 /// * **Key** - contract address.108 /// * **Value** - amount of sponsored blocks.109 #[pallet::storage]110 pub(super) type SponsoringRateLimit<T: Config> = StorageMap<111 Hasher = Twox128,112 Key = H160,113 Value = T::BlockNumber,114 QueryKind = ValueQuery,115 OnEmpty = T::DefaultSponsoringRateLimit,116 >;117118 /// Storage for last sponsored block.119 ///120 /// * **Key1** - contract address.121 /// * **Key2** - sponsored user address.122 /// * **Value** - last sponsored block number.123 #[pallet::storage]124 pub(super) type SponsoringFeeLimit<T: Config> = StorageMap<125 Hasher = Twox128,126 Key = H160,127 Value = U256,128 QueryKind = ValueQuery,129 OnEmpty = T::DefaultSponsoringFeeLimit,130 >;131132 #[pallet::storage]133 pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<134 Hasher1 = Twox128,135 Key1 = H160,136 Hasher2 = Twox128,137 Key2 = H160,138 Value = T::BlockNumber,139 QueryKind = OptionQuery,140 >;141142 /// Storege for contracts with [`Allowlisted`](SponsoringModeT::Allowlisted) sponsoring mode.143 ///144 /// ### Usage145 /// Prefer to delete collection from storage if mode chaged to non `Allowlisted`, than set **Value** to **false**.146 ///147 /// * **Key** - contract address.148 /// * **Value** - is contract in [`Allowlisted`](SponsoringModeT::Allowlisted) mode.149 #[pallet::storage]150 pub(super) type AllowlistEnabled<T: Config> =151 StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;152153 /// Storage for users that allowed for sponsorship.154 ///155 /// ### Usage156 /// Prefer to delete record from storage if user no more allowed for sponsorship.157 ///158 /// * **Key1** - contract address.159 /// * **Key2** - user that allowed for sponsorship.160 /// * **Value** - allowance for sponsorship.161 #[pallet::storage]162 pub(super) type Allowlist<T: Config> = StorageDoubleMap<163 Hasher1 = Twox128,164 Key1 = H160,165 Hasher2 = Twox128,166 Key2 = H160,167 Value = bool,168 QueryKind = ValueQuery,169 >;170171 #[pallet::event]172 #[pallet::generate_deposit(pub fn deposit_event)]173 pub enum Event<T: Config> {174 /// Contract sponsor was set.175 ContractSponsorSet(176 /// Contract address of the affected collection.177 H160,178 /// New sponsor address.179 T::AccountId,180 ),181182 /// New sponsor was confirm.183 ContractSponsorshipConfirmed(184 /// Contract address of the affected collection.185 H160,186 /// New sponsor address.187 T::AccountId,188 ),189190 /// Collection sponsor was removed.191 ContractSponsorRemoved(192 /// Contract address of the affected collection.193 H160,194 ),195 }196197 impl<T: Config> Pallet<T> {198 /// Get contract owner.199 pub fn contract_owner(contract: H160) -> H160 {200 <Owner<T>>::get(contract)201 }202203 /// Set `sponsor` for `contract`.204 ///205 /// `sender` must be owner of contract.206 pub fn set_sponsor(207 sender: &T::CrossAccountId,208 contract: H160,209 sponsor: &T::CrossAccountId,210 ) -> DispatchResult {211 Pallet::<T>::ensure_owner(contract, *sender.as_eth())?;212 Sponsoring::<T>::insert(213 contract,214 SponsorshipState::<T::CrossAccountId>::Unconfirmed(sponsor.clone()),215 );216217 <Pallet<T>>::deposit_event(Event::<T>::ContractSponsorSet(218 contract,219 sponsor.as_sub().clone(),220 ));221 <PalletEvm<T>>::deposit_log(222 ContractHelpersEvents::ContractSponsorSet {223 contract_address: contract,224 sponsor: *sponsor.as_eth(),225 }226 .to_log(contract),227 );228 Ok(())229 }230231 /// TO-DO232 ///233 ///234 pub fn force_set_sponsor(235 contract_address: H160,236 sponsor: &T::CrossAccountId,237 ) -> DispatchResult {238 Sponsoring::<T>::insert(239 contract_address,240 SponsorshipState::<T::CrossAccountId>::Confirmed(sponsor.clone()),241 );242243 let eth_sponsor = *sponsor.as_eth();244 let sub_sponsor = sponsor.as_sub().clone();245246 <Pallet<T>>::deposit_event(Event::<T>::ContractSponsorSet(247 contract_address,248 sub_sponsor.clone(),249 ));250 <PalletEvm<T>>::deposit_log(251 ContractHelpersEvents::ContractSponsorSet {252 contract_address,253 sponsor: eth_sponsor,254 }255 .to_log(contract_address),256 );257258 <Pallet<T>>::deposit_event(Event::<T>::ContractSponsorshipConfirmed(259 contract_address,260 sub_sponsor,261 ));262 <PalletEvm<T>>::deposit_log(263 ContractHelpersEvents::ContractSponsorshipConfirmed {264 contract_address,265 sponsor: eth_sponsor,266 }267 .to_log(contract_address),268 );269270 Ok(())271 }272273 /// Remove sponsor for `contract`.274 ///275 /// `sender` must be owner of contract.276 pub fn remove_sponsor(277 sender: &T::CrossAccountId,278 contract_address: H160,279 ) -> DispatchResult {280 Self::ensure_owner(contract_address, *sender.as_eth())?;281 Self::force_remove_sponsor(contract_address)282 }283284 /// TO-DO285 ///286 ///287 pub fn force_remove_sponsor(contract_address: H160) -> DispatchResult {288 Sponsoring::<T>::remove(contract_address);289290 Self::deposit_event(Event::<T>::ContractSponsorRemoved(contract_address));291 <PalletEvm<T>>::deposit_log(292 ContractHelpersEvents::ContractSponsorRemoved { contract_address }293 .to_log(contract_address),294 );295296 Ok(())297 }298299 /// Confirm sponsorship.300 ///301 /// `sender` must be same that set via [`set_sponsor`].302 pub fn confirm_sponsorship(303 sender: &T::CrossAccountId,304 contract_address: H160,305 ) -> DispatchResult {306 match Sponsoring::<T>::get(contract_address) {307 SponsorshipState::Unconfirmed(sponsor) => {308 ensure!(sponsor == *sender, Error::<T>::NoPermission);309 let eth_sponsor = *sponsor.as_eth();310 let sub_sponsor = sponsor.as_sub().clone();311 Sponsoring::<T>::insert(312 contract_address,313 SponsorshipState::<T::CrossAccountId>::Confirmed(sponsor),314 );315316 <Pallet<T>>::deposit_event(Event::<T>::ContractSponsorshipConfirmed(317 contract_address,318 sub_sponsor,319 ));320 <PalletEvm<T>>::deposit_log(321 ContractHelpersEvents::ContractSponsorshipConfirmed {322 contract_address,323 sponsor: eth_sponsor,324 }325 .to_log(contract_address),326 );327328 Ok(())329 }330 SponsorshipState::Disabled | SponsorshipState::Confirmed(_) => {331 Err(Error::<T>::NoPendingSponsor.into())332 }333 }334 }335336 /// Get sponsor.337 pub fn get_sponsor(contract: H160) -> Option<T::CrossAccountId> {338 match Sponsoring::<T>::get(contract) {339 SponsorshipState::Disabled | SponsorshipState::Unconfirmed(_) => None,340 SponsorshipState::Confirmed(sponsor) => Some(sponsor),341 }342 }343344 /// Get current sponsoring mode, performing lazy migration from legacy storage345 pub fn sponsoring_mode(contract: H160) -> SponsoringModeT {346 <SponsoringMode<T>>::get(contract)347 .or_else(|| {348 <SelfSponsoring<T>>::get(contract).then(|| SponsoringModeT::Allowlisted)349 })350 .unwrap_or_default()351 }352353 /// Reconfigure contract sponsoring mode354 pub fn set_sponsoring_mode(contract: H160, mode: SponsoringModeT) {355 if mode == SponsoringModeT::Disabled {356 <SponsoringMode<T>>::remove(contract);357 } else {358 <SponsoringMode<T>>::insert(contract, mode);359 }360 <SelfSponsoring<T>>::remove(contract)361 }362363 /// Set duration between two sponsored contract calls364 pub fn set_sponsoring_rate_limit(contract: H160, rate_limit: T::BlockNumber) {365 <SponsoringRateLimit<T>>::insert(contract, rate_limit);366 }367368 /// Set maximum for gas limit of transaction369 pub fn set_sponsoring_fee_limit(contract: H160, fee_limit: U256) {370 <SponsoringFeeLimit<T>>::insert(contract, fee_limit);371 }372373 /// Is user added to allowlist, or he is owner of specified contract374 pub fn allowed(contract: H160, user: H160) -> bool {375 <Allowlist<T>>::get(&contract, &user) || <Owner<T>>::get(&contract) == user376 }377378 /// Toggle contract allowlist access379 pub fn toggle_allowlist(contract: H160, enabled: bool) {380 <AllowlistEnabled<T>>::insert(contract, enabled)381 }382383 /// Toggle user presence in contract's allowlist384 pub fn toggle_allowed(contract: H160, user: H160, allowed: bool) {385 <Allowlist<T>>::insert(contract, user, allowed);386 }387388 /// Throw error if user is not allowed to reconfigure target contract389 pub fn ensure_owner(contract: H160, user: H160) -> DispatchResult {390 ensure!(<Owner<T>>::get(&contract) == user, Error::<T>::NoPermission);391 Ok(())392 }393 }394}395396/// Available contract sponsoring modes397#[derive(Encode, Decode, PartialEq, TypeInfo, MaxEncodedLen, Default)]398pub enum SponsoringModeT {399 /// Sponsoring is disabled400 #[default]401 Disabled,402 /// Only users from allowlist will be sponsored403 Allowlisted,404 /// All users will be sponsored405 Generous,406}407408impl SponsoringModeT {409 fn from_eth(v: u8) -> Option<Self> {410 Some(match v {411 0 => Self::Disabled,412 1 => Self::Allowlisted,413 2 => Self::Generous,414 _ => return None,415 })416 }417 fn to_eth(self) -> u8 {418 match self {419 SponsoringModeT::Disabled => 0,420 SponsoringModeT::Allowlisted => 1,421 SponsoringModeT::Generous => 2,422 }423 }424}