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

difftreelog

source

pallets/evm-transaction-payment/src/lib.rs3.6 KiBsourcehistory
1// 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#![deny(missing_docs)]2021use core::marker::PhantomData;22use fp_evm::WithdrawReason;23use frame_support::traits::IsSubType;24pub use pallet::*;25use pallet_evm::{account::CrossAccountId, EnsureAddressOrigin, FeeCalculator};26use sp_core::{H160, U256};27use sp_runtime::{TransactionOutcome, DispatchError};28use up_sponsorship::SponsorshipHandler;2930#[frame_support::pallet]31pub mod pallet {32	use super::*;3334	use sp_std::vec::Vec;3536	#[pallet::config]37	pub trait Config: frame_system::Config + pallet_evm::account::Config {38		/// Loosly-coupled handlers for evm call sponsoring39		type EvmSponsorshipHandler: SponsorshipHandler<Self::CrossAccountId, (H160, Vec<u8>), u128>;40	}4142	#[pallet::pallet]43	#[pallet::generate_store(pub(super) trait Store)]44	pub struct Pallet<T>(_);45}4647/// Implements [`fp_evm::TransactionValidityHack`], which provides sponsor address to pallet-evm48pub struct TransactionValidityHack<T: Config>(PhantomData<*const T>);49impl<T: Config> fp_evm::TransactionValidityHack<T::CrossAccountId> for TransactionValidityHack<T> {50	fn who_pays_fee(51		origin: H160,52		max_fee: U256,53		reason: &WithdrawReason,54	) -> Option<T::CrossAccountId> {55		match reason {56			WithdrawReason::Call { target, input } => {57				let origin_sub = T::CrossAccountId::from_eth(origin);58				T::EvmSponsorshipHandler::get_sponsor(59					&origin_sub,60					&(*target, input.clone()),61					&max_fee.as_u128(),62				)63			}64			_ => None,65		}66	}67}6869/// Implements sponsoring for evm calls performed from pallet-evm (via api.tx.ethereum.transact/api.tx.evm.call)70pub struct BridgeSponsorshipHandler<T>(PhantomData<T>);71impl<T, C> SponsorshipHandler<T::AccountId, C, u128> for BridgeSponsorshipHandler<T>72where73	T: Config + pallet_evm::Config,74	C: IsSubType<pallet_evm::Call<T>>,75{76	fn get_sponsor(who: &T::AccountId, call: &C, _fee_limit: &u128) -> Option<T::AccountId> {77		match call.is_sub_type()? {78			pallet_evm::Call::call {79				source,80				target,81				input,82				gas_limit,83				max_fee_per_gas,84				..85			} => {86				let _ = T::CallOrigin::ensure_address_origin(87					source,88					<frame_system::RawOrigin<T::AccountId>>::Signed(who.clone()).into(),89				)90				.ok()?;91				let who = T::CrossAccountId::from_sub(who.clone());92				let max_fee = max_fee_per_gas.saturating_mul((*gas_limit).into());93				// Effects from EvmSponsorshipHandler are applied by pallet_evm::runner94				// TODO: Should we implement simulation mode (test, but do not apply effects) in `up-sponsorship`?95				let sponsor = frame_support::storage::with_transaction(|| {96					TransactionOutcome::Rollback(Ok::<_, DispatchError>(97						T::EvmSponsorshipHandler::get_sponsor(98							&who,99							&(*target, input.clone()),100							&max_fee.try_into().unwrap(),101						),102					))103				})104				// FIXME: it may fail with DispatchError in case of depth limit105				.ok()??;106				Some(sponsor.as_sub().clone())107			}108			_ => None,109		}110	}111}