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

no changes

addedpallets/evm-transaction-payment/src/lib.rsdiffbeforeafterboth

no changes

modifiedpallets/nft/src/eth/sponsoring.rsdiffbeforeafterboth
1//! Implements EVM sponsoring logic via OnChargeEVMTransaction1//! Implements EVM sponsoring logic via OnChargeEVMTransaction
22
3use crate::{3use crate::{
4 Collection, ChainLimit, CollectionById, Config, NftTransferBasket, FungibleTransferBasket,4 ChainLimit, Collection, CollectionById, Config, FungibleTransferBasket, NftTransferBasket,
5 eth::account::EvmBackwardsAddressMapping,5 eth::{account::EvmBackwardsAddressMapping, map_eth_to_id},
6};6};
7use evm_coder::abi::AbiReader;7use evm_coder::{Call, abi::AbiReader};
8use frame_support::{8use frame_support::{
9 storage::{StorageMap, StorageDoubleMap, StorageValue},9 storage::{StorageMap, StorageDoubleMap, StorageValue},
10 traits::Currency,
11};10};
12use pallet_evm::{EVMCurrencyAdapter, WithdrawReason};
13use sp_core::{H160, U256};11use sp_core::H160;
14use sp_std::prelude::*;12use sp_std::prelude::*;
13use up_sponsorship::SponsorshipHandler;
15use super::{14use super::{
16 account::CrossAccountId,15 account::CrossAccountId,
17 erc::{UniqueFungibleCall, UniqueNFTCall, ERC721Call, ERC20Call, ERC721UniqueExtensionsCall},16 erc::{UniqueFungibleCall, UniqueNFTCall, ERC721Call, ERC20Call, ERC721UniqueExtensionsCall},
18};17};
19use core::convert::TryInto;18use core::convert::TryInto;
20
21type NegativeImbalanceOf<C, T> =
22 <C as Currency<<T as frame_system::Config>::AccountId>>::NegativeImbalance;19use core::marker::PhantomData;
23
24pub struct ChargeEvmTransaction;
25pub struct ChargeEvmLiquidityInfo<T>
26where
27 T: Config,
28 T: pallet_evm::Config,
29{
30 who: H160,
31 negative_imbalance: NegativeImbalanceOf<<T as Config>::Currency, T>,
32}
3320
34struct AnyError;21struct AnyError;
3522
46 .map_err(|_| AnyError)?33 .map_err(|_| AnyError)?
47 .ok_or(AnyError)?;34 .ok_or(AnyError)?;
48 match call {35 match call {
49 UniqueNFTCall::ERC721UniqueExtensions(ERC721UniqueExtensionsCall::Transfer {36 UniqueNFTCall::ERC721UniqueExtensions(
50 token_id,37 ERC721UniqueExtensionsCall::TransferNft { token_id, .. },
51 ..
52 })38 )
53 | UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, .. }) => {39 | UniqueNFTCall::ERC721(ERC721Call::TransferFrom { token_id, .. }) => {
118 Err(AnyError)104 Err(AnyError)
119}105}
120106
107pub struct NftEthSponsorshipHandler<T: Config>(PhantomData<*const T>);
121impl<T> pallet_evm::OnChargeEVMTransaction<T> for ChargeEvmTransaction108impl<T: Config> SponsorshipHandler<H160, (H160, Vec<u8>)> for NftEthSponsorshipHandler<T> {
122where
123 T: Config,
124 T: pallet_evm::Config,
125{
126 type LiquidityInfo = Option<ChargeEvmLiquidityInfo<T>>;
127
128 fn withdraw_fee(109 fn get_sponsor(who: &H160, call: &(H160, Vec<u8>)) -> Option<H160> {
129 who: &H160,
130 reason: WithdrawReason,
131 fee: U256,
132 ) -> Result<Self::LiquidityInfo, pallet_evm::Error<T>> {
133 let mut who_pays_fee = *who;
134 if let WithdrawReason::Call { target, input } = &reason {110 if let Some(collection_id) = map_eth_to_id(&call.0) {
135 if let Some(collection_id) = crate::eth::map_eth_to_id(target) {
136 if let Some(collection) = <CollectionById<T>>::get(collection_id) {111 if let Some(collection) = <CollectionById<T>>::get(collection_id) {
137 if let Some(sponsor) = collection.sponsorship.sponsor() {112 if !collection.sponsorship.confirmed() {
113 return None;
114 }
138 if try_sponsor(who, collection_id, &collection, input).is_ok() {115 if try_sponsor(who, collection_id, &collection, &call.1).is_ok() {
139 who_pays_fee =116 return collection
117 .sponsorship
118 .sponsor()
119 .cloned()
140 T::EvmBackwardsAddressMapping::from_account_id(sponsor.clone());120 .map(T::EvmBackwardsAddressMapping::from_account_id);
141 }121 }
142 }
143 }122 }
144 }123 }
145 }124 None
146
147 // TODO: Pay fee from substrate address
148 let negative_imbalance = EVMCurrencyAdapter::<<T as Config>::Currency, ()>::withdraw_fee(
149 &who_pays_fee,
150 reason,
151 fee,
152 )?;
153 Ok(negative_imbalance.map(|i| ChargeEvmLiquidityInfo {
154 who: who_pays_fee,
155 negative_imbalance: i,
156 }))
157 }125 }
158126}
159 fn correct_and_deposit_fee(
160 who: &H160,
161 corrected_fee: U256,
162 already_withdrawn: Self::LiquidityInfo,
163 ) -> Result<(), pallet_evm::Error<T>> {
164 EVMCurrencyAdapter::<<T as Config>::Currency, ()>::correct_and_deposit_fee(
165 &already_withdrawn.as_ref().map(|e| e.who).unwrap_or(*who),
166 corrected_fee,
167 already_withdrawn.map(|e| e.negative_imbalance),
168 )
169 }
170}
171127