git.delta.rocks / unique-network / refs/commits / 82bedeffe28d

difftreelog

fix evm sponsoring allowlist handling

Yaroslav Bolyukin2021-11-18parent: #dd1406b.patch.diff
in: master

2 files changed

modifiedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -59,7 +59,8 @@
 
 	fn allowed(&self, contract_address: address, user: address) -> Result<bool> {
 		self.0.consume_sload()?;
-		Ok(<Pallet<T>>::allowed(contract_address, user, true))
+		Ok(<Pallet<T>>::allowed(contract_address, user)
+			|| !<AllowlistEnabled<T>>::get(contract_address))
 	}
 
 	fn allowlist_enabled(&self, contract_address: address) -> Result<bool> {
@@ -113,7 +114,7 @@
 		value: sp_core::U256,
 	) -> Option<PrecompileOutput> {
 		// TODO: Extract to another OnMethodCall handler
-		if !<Pallet<T>>::allowed(*target, *source, true) {
+		if <AllowlistEnabled<T>>::get(target) && !<Pallet<T>>::allowed(*target, *source) {
 			return Some(PrecompileOutput {
 				exit_status: ExitReason::Revert(ExitRevert::Reverted),
 				cost: 0,
@@ -151,22 +152,26 @@
 pub struct HelpersContractSponsoring<T: Config>(PhantomData<*const T>);
 impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for HelpersContractSponsoring<T> {
 	fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {
-		if <SelfSponsoring<T>>::get(&call.0) && <Pallet<T>>::allowed(call.0, *who, false) {
-			let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
-			if let Some(last_tx_block) = <SponsorBasket<T>>::get(&call.0, who) {
-				let rate_limit = <SponsoringRateLimit<T>>::get(&call.0);
-				let limit_time = last_tx_block + rate_limit;
+		if !<SelfSponsoring<T>>::get(&call.0) {
+			return None;
+		}
+		if !<Pallet<T>>::allowed(call.0, *who) {
+			return None;
+		}
+		let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
 
-				if block_number > limit_time {
-					<SponsorBasket<T>>::insert(&call.0, who, block_number);
-					return Some(call.0);
-				}
-			} else {
-				<SponsorBasket<T>>::insert(&call.0, who, block_number);
-				return Some(call.0);
+		if let Some(last_tx_block) = <SponsorBasket<T>>::get(&call.0, who) {
+			let limit = <SponsoringRateLimit<T>>::get(&call.0);
+
+			let timeout = last_tx_block + limit.into();
+			if block_number < timeout {
+				return None;
 			}
 		}
-		None
+
+		<SponsorBasket<T>>::insert(&call.0, who, block_number);
+
+		Some(call.0)
 	}
 }
 
modifiedpallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth
before · pallets/evm-contract-helpers/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23pub use pallet::*;4pub use eth::*;5pub mod eth;67#[frame_support::pallet]8pub mod pallet {9	use evm_coder::execution::Result;10	use frame_support::pallet_prelude::*;11	use sp_core::H160;1213	#[pallet::config]14	pub trait Config: frame_system::Config + pallet_evm_coder_substrate::Config {15		type ContractAddress: Get<H160>;16		type DefaultSponsoringRateLimit: Get<Self::BlockNumber>;17	}1819	#[pallet::error]20	pub enum Error<T> {21		/// This method is only executable by owner22		NoPermission,23	}2425	#[pallet::pallet]26	#[pallet::generate_store(pub(super) trait Store)]27	pub struct Pallet<T>(_);2829	#[pallet::storage]30	pub(super) type Owner<T: Config> =31		StorageMap<Hasher = Twox128, Key = H160, Value = H160, QueryKind = ValueQuery>;3233	#[pallet::storage]34	pub(super) type SelfSponsoring<T: Config> =35		StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;3637	#[pallet::storage]38	pub(super) type SponsoringRateLimit<T: Config> = StorageMap<39		Hasher = Twox128,40		Key = H160,41		Value = T::BlockNumber,42		QueryKind = ValueQuery,43		OnEmpty = T::DefaultSponsoringRateLimit,44	>;4546	#[pallet::storage]47	pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<48		Hasher1 = Twox128,49		Key1 = H160,50		Hasher2 = Twox128,51		Key2 = H160,52		Value = T::BlockNumber,53		QueryKind = OptionQuery,54	>;5556	#[pallet::storage]57	pub(super) type AllowlistEnabled<T: Config> =58		StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;5960	#[pallet::storage]61	pub(super) type Allowlist<T: Config> = StorageDoubleMap<62		Hasher1 = Twox128,63		Key1 = H160,64		Hasher2 = Twox128,65		Key2 = H160,66		Value = bool,67		QueryKind = ValueQuery,68	>;6970	impl<T: Config> Pallet<T> {71		pub fn toggle_sponsoring(contract: H160, enabled: bool) {72			<SelfSponsoring<T>>::insert(contract, enabled);73		}7475		pub fn set_sponsoring_rate_limit(contract: H160, rate_limit: T::BlockNumber) {76			<SponsoringRateLimit<T>>::insert(contract, rate_limit);77		}7879		/// Default is returned if allowlist is disabled80		pub fn allowed(contract: H160, user: H160, default: bool) -> bool {81			if !<AllowlistEnabled<T>>::get(contract) {82				return default;83			}84			<Allowlist<T>>::get(&contract, &user) || <Owner<T>>::get(&contract) == user85		}8687		pub fn toggle_allowlist(contract: H160, enabled: bool) {88			<AllowlistEnabled<T>>::insert(contract, enabled)89		}9091		pub fn toggle_allowed(contract: H160, user: H160, allowed: bool) {92			<Allowlist<T>>::insert(contract, user, allowed);93		}9495		pub fn ensure_owner(contract: H160, user: H160) -> Result<()> {96			ensure!(<Owner<T>>::get(&contract) == user, "no permission");97			Ok(())98		}99	}100}
after · pallets/evm-contract-helpers/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23pub use pallet::*;4pub use eth::*;5pub mod eth;67#[frame_support::pallet]8pub mod pallet {9	use evm_coder::execution::Result;10	use frame_support::pallet_prelude::*;11	use sp_core::H160;1213	#[pallet::config]14	pub trait Config: frame_system::Config + pallet_evm_coder_substrate::Config {15		type ContractAddress: Get<H160>;16		type DefaultSponsoringRateLimit: Get<Self::BlockNumber>;17	}1819	#[pallet::error]20	pub enum Error<T> {21		/// This method is only executable by owner22		NoPermission,23	}2425	#[pallet::pallet]26	#[pallet::generate_store(pub(super) trait Store)]27	pub struct Pallet<T>(_);2829	#[pallet::storage]30	pub(super) type Owner<T: Config> =31		StorageMap<Hasher = Twox128, Key = H160, Value = H160, QueryKind = ValueQuery>;3233	#[pallet::storage]34	pub(super) type SelfSponsoring<T: Config> =35		StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;3637	#[pallet::storage]38	pub(super) type SponsoringRateLimit<T: Config> = StorageMap<39		Hasher = Twox128,40		Key = H160,41		Value = T::BlockNumber,42		QueryKind = ValueQuery,43		OnEmpty = T::DefaultSponsoringRateLimit,44	>;4546	#[pallet::storage]47	pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<48		Hasher1 = Twox128,49		Key1 = H160,50		Hasher2 = Twox128,51		Key2 = H160,52		Value = T::BlockNumber,53		QueryKind = OptionQuery,54	>;5556	#[pallet::storage]57	pub(super) type AllowlistEnabled<T: Config> =58		StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;5960	#[pallet::storage]61	pub(super) type Allowlist<T: Config> = StorageDoubleMap<62		Hasher1 = Twox128,63		Key1 = H160,64		Hasher2 = Twox128,65		Key2 = H160,66		Value = bool,67		QueryKind = ValueQuery,68	>;6970	impl<T: Config> Pallet<T> {71		pub fn toggle_sponsoring(contract: H160, enabled: bool) {72			<SelfSponsoring<T>>::insert(contract, enabled);73		}7475		pub fn set_sponsoring_rate_limit(contract: H160, rate_limit: T::BlockNumber) {76			<SponsoringRateLimit<T>>::insert(contract, rate_limit);77		}7879		pub fn allowed(contract: H160, user: H160) -> bool {80			<Allowlist<T>>::get(&contract, &user) || <Owner<T>>::get(&contract) == user81		}8283		pub fn toggle_allowlist(contract: H160, enabled: bool) {84			<AllowlistEnabled<T>>::insert(contract, enabled)85		}8687		pub fn toggle_allowed(contract: H160, user: H160, allowed: bool) {88			<Allowlist<T>>::insert(contract, user, allowed);89		}9091		pub fn ensure_owner(contract: H160, user: H160) -> Result<()> {92			ensure!(<Owner<T>>::get(&contract) == user, "no permission");93			Ok(())94		}95	}96}