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

difftreelog

refactor extract evm transaction payment

Yaroslav Bolyukin2021-07-27parent: #60ea0ef.patch.diff
in: master

3 files changed

addedpallets/evm-transaction-payment/Cargo.tomldiffbeforeafterboth
--- /dev/null
+++ b/pallets/evm-transaction-payment/Cargo.toml
@@ -0,0 +1,37 @@
+[package]
+name = "pallet-evm-transaction-payment"
+version = "0.1.0"
+edition = "2018"
+
+[dependencies]
+frame-support = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+frame-system = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-runtime = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-std = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-io = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+sp-core = { default-features = false, version = '3.0.0', git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.8' }
+pallet-evm = { default-features = false, version = "5.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+fp-evm = { default-features = false, version = "2.0.0", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+pallet-ethereum = { default-features = false, version = "3.0.0-dev", git = "https://github.com/uniquenetwork/frontier.git", branch = "injected-transactions-parachain" }
+up-sponsorship = { default-features = false, path = '../../primitives/sponsorship' }
+
+[dependencies.codec]
+default-features = false
+features = ['derive']
+package = 'parity-scale-codec'
+version = '2.0.0'
+
+[features]
+default = ["std"]
+std = [
+    "frame-support/std",
+    "frame-system/std",
+    "sp-runtime/std",
+    "sp-std/std",
+    "sp-io/std",
+    "sp-core/std",
+    "pallet-evm/std",
+    "pallet-ethereum/std",
+    "fp-evm/std",
+    "up-sponsorship/std",
+]
addedpallets/evm-transaction-payment/src/lib.rsdiffbeforeafterboth
after · pallets/evm-transaction-payment/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23pub use pallet::*;45#[frame_support::pallet]6pub mod pallet {7	use core::marker::PhantomData;8	use frame_support::traits::Currency;9	use pallet_evm::EVMCurrencyAdapter;10	use fp_evm::WithdrawReason;11	use sp_core::{H160, U256};12	use sp_runtime::TransactionOutcome;13	use up_sponsorship::SponsorshipHandler;14	use sp_std::vec::Vec;1516	type NegativeImbalanceOf<C, T> =17		<C as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;1819	#[pallet::config]20	pub trait Config: frame_system::Config {21		type SponsorshipHandler: SponsorshipHandler<H160, (H160, Vec<u8>)>;22		type Currency: Currency<Self::AccountId>;23	}2425	#[pallet::pallet]26	#[pallet::generate_store(pub(super) trait Store)]27	pub struct Pallet<T>(_);2829	pub struct ChargeEvmLiquidityInfo<T>30	where31		T: Config,32		T: pallet_evm::Config,33	{34		who: H160,35		negative_imbalance: NegativeImbalanceOf<<T as Config>::Currency, T>,36	}3738	pub struct TransactionValidityHack<T: Config>(PhantomData<*const T>);39	impl<T: Config> fp_evm::TransactionValidityHack for TransactionValidityHack<T> {40		fn who_pays_fee(origin: H160, reason: &WithdrawReason) -> Option<H160> {41			match reason {42				WithdrawReason::Call { target, input } => {43					// This method is only used for checking, we shouldn't touch storage in it44					frame_support::storage::with_transaction(|| {45						TransactionOutcome::Rollback(T::SponsorshipHandler::get_sponsor(46							&origin,47							&(*target, input.clone()),48						))49					})50				}51				_ => None,52			}53		}54	}5556	pub struct OnChargeTransaction<T: Config>(PhantomData<*const T>);57	impl<T> pallet_evm::OnChargeEVMTransaction<T> for OnChargeTransaction<T>58	where59		T: Config,60		T: pallet_evm::Config,61	{62		type LiquidityInfo = Option<ChargeEvmLiquidityInfo<T>>;6364		fn withdraw_fee(65			who: &H160,66			reason: WithdrawReason,67			fee: U256,68		) -> core::result::Result<Self::LiquidityInfo, pallet_evm::Error<T>> {69			let mut who_pays_fee = *who;70			if let WithdrawReason::Call { target, input } = &reason {71				who_pays_fee = T::SponsorshipHandler::get_sponsor(who, &(*target, input.clone()))72					.unwrap_or(who_pays_fee);73			}74			let negative_imbalance =75				EVMCurrencyAdapter::<<T as Config>::Currency, ()>::withdraw_fee(76					&who_pays_fee,77					reason,78					fee,79				)?;80			Ok(negative_imbalance.map(|i| ChargeEvmLiquidityInfo {81				who: who_pays_fee,82				negative_imbalance: i,83			}))84		}8586		fn correct_and_deposit_fee(87			who: &H160,88			corrected_fee: U256,89			already_withdrawn: Self::LiquidityInfo,90		) -> core::result::Result<(), pallet_evm::Error<T>> {91			EVMCurrencyAdapter::<<T as Config>::Currency, ()>::correct_and_deposit_fee(92				&already_withdrawn.as_ref().map(|e| e.who).unwrap_or(*who),93				corrected_fee,94				already_withdrawn.map(|e| e.negative_imbalance),95			)96		}97	}98}
modifiedpallets/nft/src/eth/sponsoring.rsdiffbeforeafterboth
--- a/pallets/nft/src/eth/sponsoring.rs
+++ b/pallets/nft/src/eth/sponsoring.rs
@@ -1,35 +1,22 @@
 //! Implements EVM sponsoring logic via OnChargeEVMTransaction
 
 use crate::{
-	Collection, ChainLimit, CollectionById, Config, NftTransferBasket, FungibleTransferBasket,
-	eth::account::EvmBackwardsAddressMapping,
+	ChainLimit, Collection, CollectionById, Config, FungibleTransferBasket, NftTransferBasket,
+	eth::{account::EvmBackwardsAddressMapping, map_eth_to_id},
 };
-use evm_coder::abi::AbiReader;
+use evm_coder::{Call, abi::AbiReader};
 use frame_support::{
 	storage::{StorageMap, StorageDoubleMap, StorageValue},
-	traits::Currency,
 };
-use pallet_evm::{EVMCurrencyAdapter, WithdrawReason};
-use sp_core::{H160, U256};
+use sp_core::H160;
 use sp_std::prelude::*;
+use up_sponsorship::SponsorshipHandler;
 use super::{
 	account::CrossAccountId,
 	erc::{UniqueFungibleCall, UniqueNFTCall, ERC721Call, ERC20Call, ERC721UniqueExtensionsCall},
 };
 use core::convert::TryInto;
-
-type NegativeImbalanceOf<C, T> =
-	<C as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;
-
-pub struct ChargeEvmTransaction;
-pub struct ChargeEvmLiquidityInfo<T>
-where
-	T: Config,
-	T: pallet_evm::Config,
-{
-	who: H160,
-	negative_imbalance: NegativeImbalanceOf<<T as Config>::Currency, T>,
-}
+use core::marker::PhantomData;
 
 struct AnyError;
 
@@ -46,10 +33,9 @@
 				.map_err(|_| AnyError)?
 				.ok_or(AnyError)?;
 			match call {
-				UniqueNFTCall::ERC721UniqueExtensions(ERC721UniqueExtensionsCall::Transfer {
-					token_id,
-					..
-				})
+				UniqueNFTCall::ERC721UniqueExtensions(
+					ERC721UniqueExtensionsCall::TransferNft { token_id, .. },
+				)
 				| UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, .. }) => {
 					let token_id: u32 = token_id.try_into().map_err(|_| AnyError)?;
 					let block_number = <frame_system::Pallet<T>>::block_number() as T::BlockNumber;
@@ -118,53 +104,23 @@
 	Err(AnyError)
 }
 
-impl<T> pallet_evm::OnChargeEVMTransaction<T> for ChargeEvmTransaction
-where
-	T: Config,
-	T: pallet_evm::Config,
-{
-	type LiquidityInfo = Option<ChargeEvmLiquidityInfo<T>>;
-
-	fn withdraw_fee(
-		who: &H160,
-		reason: WithdrawReason,
-		fee: U256,
-	) -> Result<Self::LiquidityInfo, pallet_evm::Error<T>> {
-		let mut who_pays_fee = *who;
-		if let WithdrawReason::Call { target, input } = &reason {
-			if let Some(collection_id) = crate::eth::map_eth_to_id(target) {
-				if let Some(collection) = <CollectionById<T>>::get(collection_id) {
-					if let Some(sponsor) = collection.sponsorship.sponsor() {
-						if try_sponsor(who, collection_id, &collection, input).is_ok() {
-							who_pays_fee =
-								T::EvmBackwardsAddressMapping::from_account_id(sponsor.clone());
-						}
-					}
+pub struct NftEthSponsorshipHandler<T: Config>(PhantomData<*const T>);
+impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for NftEthSponsorshipHandler<T> {
+	fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {
+		if let Some(collection_id) = map_eth_to_id(&call.0) {
+			if let Some(collection) = <CollectionById<T>>::get(collection_id) {
+				if !collection.sponsorship.confirmed() {
+					return None;
+				}
+				if try_sponsor(who, collection_id, &collection, &call.1).is_ok() {
+					return collection
+						.sponsorship
+						.sponsor()
+						.cloned()
+						.map(T::EvmBackwardsAddressMapping::from_account_id);
 				}
 			}
 		}
-
-		// TODO: Pay fee from substrate address
-		let negative_imbalance = EVMCurrencyAdapter::<<T as Config>::Currency, ()>::withdraw_fee(
-			&who_pays_fee,
-			reason,
-			fee,
-		)?;
-		Ok(negative_imbalance.map(|i| ChargeEvmLiquidityInfo {
-			who: who_pays_fee,
-			negative_imbalance: i,
-		}))
-	}
-
-	fn correct_and_deposit_fee(
-		who: &H160,
-		corrected_fee: U256,
-		already_withdrawn: Self::LiquidityInfo,
-	) -> Result<(), pallet_evm::Error<T>> {
-		EVMCurrencyAdapter::<<T as Config>::Currency, ()>::correct_and_deposit_fee(
-			&already_withdrawn.as_ref().map(|e| e.who).unwrap_or(*who),
-			corrected_fee,
-			already_withdrawn.map(|e| e.negative_imbalance),
-		)
+		None
 	}
 }