git.delta.rocks / unique-network / refs/commits / 4a3d8395a0e4

difftreelog

feat sponsor evm transactions coming from substrate

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

2 files changed

modifiedpallets/evm-transaction-payment/src/lib.rsdiffbeforeafterboth
before · pallets/evm-transaction-payment/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23pub use pallet::*;4use up_evm_mapping::EvmBackwardsAddressMapping;56#[frame_support::pallet]7pub mod pallet {8	use core::marker::PhantomData;9	use frame_support::traits::Currency;10	use pallet_evm::EVMCurrencyAdapter;11	use fp_evm::WithdrawReason;12	use sp_core::{H160, U256};13	use sp_runtime::TransactionOutcome;14	use up_sponsorship::SponsorshipHandler;15	use sp_std::vec::Vec;1617	type NegativeImbalanceOf<C, T> =18		<C as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;1920	#[pallet::config]21	pub trait Config: frame_system::Config {22		type SponsorshipHandler: SponsorshipHandler<H160, (H160, Vec<u8>)>;23		type Currency: Currency<Self::AccountId>;24		type EvmBackwardsAddressMapping: EvmBackwardsAddressMapping<Self::AccountId>;25	}2627	#[pallet::pallet]28	#[pallet::generate_store(pub(super) trait Store)]29	pub struct Pallet<T>(_);3031	pub struct ChargeEvmLiquidityInfo<T>32	where33		T: Config,34		T: pallet_evm::Config,35	{36		who: H160,37		negative_imbalance: NegativeImbalanceOf<<T as Config>::Currency, T>,38	}3940	pub struct TransactionValidityHack<T: Config>(PhantomData<*const T>);41	impl<T: Config> fp_evm::TransactionValidityHack for TransactionValidityHack<T> {42		fn who_pays_fee(origin: H160, reason: &WithdrawReason) -> Option<H160> {43			match reason {44				WithdrawReason::Call { target, input } => {45					// This method is only used for checking, we shouldn't touch storage in it46					frame_support::storage::with_transaction(|| {47						TransactionOutcome::Rollback(T::SponsorshipHandler::get_sponsor(48							&origin,49							&(*target, input.clone()),50						))51					})52				}53				_ => None,54			}55		}56	}5758	pub struct OnChargeTransaction<T: Config>(PhantomData<*const T>);59	impl<T> pallet_evm::OnChargeEVMTransaction<T> for OnChargeTransaction<T>60	where61		T: Config,62		T: pallet_evm::Config,63	{64		type LiquidityInfo = Option<ChargeEvmLiquidityInfo<T>>;6566		fn withdraw_fee(67			who: &H160,68			reason: WithdrawReason,69			fee: U256,70		) -> core::result::Result<Self::LiquidityInfo, pallet_evm::Error<T>> {71			let mut who_pays_fee = *who;72			if let WithdrawReason::Call { target, input } = &reason {73				who_pays_fee = T::SponsorshipHandler::get_sponsor(who, &(*target, input.clone()))74					.unwrap_or(who_pays_fee);75			}76			let negative_imbalance =77				EVMCurrencyAdapter::<<T as Config>::Currency, ()>::withdraw_fee(78					&who_pays_fee,79					reason,80					fee,81				)?;82			Ok(negative_imbalance.map(|i| ChargeEvmLiquidityInfo {83				who: who_pays_fee,84				negative_imbalance: i,85			}))86		}8788		fn correct_and_deposit_fee(89			who: &H160,90			corrected_fee: U256,91			already_withdrawn: Self::LiquidityInfo,92		) {93			<EVMCurrencyAdapter<<T as Config>::Currency, ()> as pallet_evm::OnChargeEVMTransaction<T>>::correct_and_deposit_fee(94				&already_withdrawn.as_ref().map(|e| e.who).unwrap_or(*who),95				corrected_fee,96				already_withdrawn.map(|e| e.negative_imbalance),97			)98		}99	}100}
after · pallets/evm-transaction-payment/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23use core::marker::PhantomData;4use fp_evm::WithdrawReason;5use frame_support::traits::{Currency, IsSubType};6pub use pallet::*;7use pallet_evm::{EVMCurrencyAdapter, EnsureAddressOrigin};8use sp_core::{H160, U256};9use sp_runtime::TransactionOutcome;10use up_sponsorship::SponsorshipHandler;11use up_evm_mapping::EvmBackwardsAddressMapping;12use pallet_evm::AddressMapping;1314#[frame_support::pallet]15pub mod pallet {16	use super::*;1718	use frame_support::traits::Currency;19	use sp_std::vec::Vec;2021	#[pallet::config]22	pub trait Config: frame_system::Config {23		type EvmSponsorshipHandler: SponsorshipHandler<H160, (H160, Vec<u8>)>;24		type Currency: Currency<Self::AccountId>;25		type EvmBackwardsAddressMapping: EvmBackwardsAddressMapping<Self::AccountId>;26		type EvmAddressMapping: AddressMapping<Self::AccountId>;27	}2829	#[pallet::pallet]30	#[pallet::generate_store(pub(super) trait Store)]31	pub struct Pallet<T>(_);32}3334type NegativeImbalanceOf<C, T> =35	<C as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;3637pub struct ChargeEvmLiquidityInfo<T>38where39	T: Config,40	T: pallet_evm::Config,41{42	who: H160,43	negative_imbalance: NegativeImbalanceOf<<T as Config>::Currency, T>,44}4546pub struct TransactionValidityHack<T: Config>(PhantomData<*const T>);47impl<T: Config> fp_evm::TransactionValidityHack for TransactionValidityHack<T> {48	fn who_pays_fee(origin: H160, reason: &WithdrawReason) -> Option<H160> {49		match reason {50			WithdrawReason::Call { target, input } => {51				// This method is only used for checking, we shouldn't touch storage in it52				frame_support::storage::with_transaction(|| {53					TransactionOutcome::Rollback(T::EvmSponsorshipHandler::get_sponsor(54						&origin,55						&(*target, input.clone()),56					))57				})58			}59			_ => None,60		}61	}62}63pub struct OnChargeTransaction<T: Config>(PhantomData<*const T>);64impl<T> pallet_evm::OnChargeEVMTransaction<T> for OnChargeTransaction<T>65where66	T: Config,67	T: pallet_evm::Config,68{69	type LiquidityInfo = Option<ChargeEvmLiquidityInfo<T>>;7071	fn withdraw_fee(72		who: &H160,73		reason: WithdrawReason,74		fee: U256,75	) -> core::result::Result<Self::LiquidityInfo, pallet_evm::Error<T>> {76		let mut who_pays_fee = *who;77		if let WithdrawReason::Call { target, input } = &reason {78			who_pays_fee = T::EvmSponsorshipHandler::get_sponsor(who, &(*target, input.clone()))79				.unwrap_or(who_pays_fee);80		}81		let negative_imbalance = EVMCurrencyAdapter::<<T as Config>::Currency, ()>::withdraw_fee(82			&who_pays_fee,83			reason,84			fee,85		)?;86		Ok(negative_imbalance.map(|i| ChargeEvmLiquidityInfo {87			who: who_pays_fee,88			negative_imbalance: i,89		}))90	}9192	fn correct_and_deposit_fee(93		who: &H160,94		corrected_fee: U256,95		already_withdrawn: Self::LiquidityInfo,96	) {97		<EVMCurrencyAdapter<<T as Config>::Currency, ()> as pallet_evm::OnChargeEVMTransaction<T>>::correct_and_deposit_fee(98			&already_withdrawn.as_ref().map(|e| e.who).unwrap_or(*who),99			corrected_fee,100			already_withdrawn.map(|e| e.negative_imbalance),101		)102	}103}104105/// Implements sponsoring for evm calls performed from pallet-evm (via api.tx.ethereum.transact/api.tx.evm.call)106pub struct BridgeSponsorshipHandler<T>(PhantomData<T>);107impl<T, C> SponsorshipHandler<T::AccountId, C> for BridgeSponsorshipHandler<T>108where109	T: Config + pallet_evm::Config,110	C: IsSubType<pallet_evm::Call<T>>,111{112	fn get_sponsor(who: &T::AccountId, call: &C) -> Option<T::AccountId> {113		match call.is_sub_type()? {114			pallet_evm::Call::call {115				source,116				target,117				input,118				..119			} => {120				let _ = T::CallOrigin::ensure_address_origin(121					source,122					<frame_system::RawOrigin<T::AccountId>>::Signed(who.clone()).into(),123				)124				.ok()?;125				let who = T::EvmBackwardsAddressMapping::from_account_id(who.clone());126				// Effects from EvmSponsorshipHandler are applied in OnChargeEvmTransaction by pallet_evm::runner127				// TODO: Should we implement simulation mode (test, but do not apply effects) in `up-sponsorship`?128				let sponsor = frame_support::storage::with_transaction(|| {129					TransactionOutcome::Rollback(T::EvmSponsorshipHandler::get_sponsor(130						&who,131						&(target.clone(), input.clone()),132					))133				})?;134				let sponsor = T::EvmAddressMapping::into_account_id(sponsor);135				Some(sponsor)136			}137			_ => None,138		}139	}140}
modifiedruntime/src/lib.rsdiffbeforeafterboth
--- a/runtime/src/lib.rs
+++ b/runtime/src/lib.rs
@@ -777,20 +777,14 @@
 	pub const MaxScheduledPerBlock: u32 = 50;
 }
 
-pub struct Sponsoring;
-impl SponsoringResolve<AccountId, Call> for Sponsoring {
-	fn resolve(who: &AccountId, call: &Call) -> Option<AccountId>
-	where
-		Call: Dispatchable<Info = DispatchInfo>,
-		AccountId: AsRef<[u8]>,
-	{
-		pallet_nft_transaction_payment::Module::<Runtime>::withdraw_type(who, call)
-	}
-}
-
+type EvmSponsorshipHandler = (
+	pallet_nft::NftEthSponsorshipHandler<Runtime>,
+	pallet_evm_contract_helpers::HelpersContractSponsoring<Runtime>,
+);
 type SponsorshipHandler = (
 	pallet_nft::NftSponsorshipHandler<Runtime>,
 	//pallet_contract_helpers::ContractSponsorshipHandler<Runtime>,
+	pallet_evm_transaction_payment::BridgeSponsorshipHandler<Runtime>,
 );
 
 impl pallet_unq_scheduler::Config for Runtime {
@@ -806,16 +800,14 @@
 }
 
 impl pallet_evm_transaction_payment::Config for Runtime {
-	type SponsorshipHandler = (
-		pallet_nft::NftEthSponsorshipHandler<Self>,
-		pallet_evm_contract_helpers::HelpersContractSponsoring<Self>,
-	);
+	type EvmSponsorshipHandler = EvmSponsorshipHandler;
 	type Currency = Balances;
+	type EvmAddressMapping = HashedAddressMapping<Self::Hashing>;
 	type EvmBackwardsAddressMapping = up_evm_mapping::MapBackwardsAddressTruncated;
 }
 
 impl pallet_nft_charge_transaction::Config for Runtime {
-	type SponsorshipHandler = pallet_nft::NftSponsorshipHandler<Runtime>;
+	type SponsorshipHandler = SponsorshipHandler;
 }
 
 // impl pallet_contract_helpers::Config for Runtime {