--- a/Cargo.lock +++ b/Cargo.lock @@ -6818,11 +6818,15 @@ name = "pallet-unique" version = "0.1.0" dependencies = [ + "ethereum", + "evm-coder", "frame-benchmarking", "frame-support", "frame-system", "pallet-common", "pallet-evm", + "pallet-evm-coder-substrate", + "pallet-nonfungible", "parity-scale-codec 3.1.2", "scale-info", "serde", --- a/pallets/unique/Cargo.toml +++ b/pallets/unique/Cargo.toml @@ -33,6 +33,22 @@ limit-testing = ["up-data-structs/limit-testing"] ################################################################################ +# Standart Dependencies + +[dependencies.serde] +default-features = false +features = ['derive'] +version = '1.0.130' + +[dependencies.serde-json-core] +default-features = false +version = "0.4" + +[dependencies.ethereum] +version = "0.12.0" +default-features = false + +################################################################################ # Substrate Dependencies [dependencies.codec] @@ -66,15 +82,6 @@ # default-features = false # git = "https://github.com/paritytech/substrate" # branch = "polkadot-v0.9.21" - -[dependencies.serde] -default-features = false -features = ['derive'] -version = '1.0.130' - -[dependencies.serde-json-core] -default-features = false -version = "0.4" [dependencies.sp-runtime] default-features = false @@ -90,7 +97,6 @@ default-features = false git = "https://github.com/paritytech/substrate" branch = "polkadot-v0.9.21" - ################################################################################ # Local Dependencies @@ -101,3 +107,6 @@ ] } pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier", branch = "unique-polkadot-v0.9.21-logs" } pallet-common = { default-features = false, path = "../common" } +evm-coder = { default-features = false, path = '../../crates/evm-coder' } +pallet-evm-coder-substrate = { default-features = false, path = '../../pallets/evm-coder-substrate' } +pallet-nonfungible = { default-features = false, path = '../../pallets/nonfungible' } --- a/pallets/unique/src/eth/mod.rs +++ b/pallets/unique/src/eth/mod.rs @@ -14,100 +14,19 @@ // You should have received a copy of the GNU General Public License // along with Unique Network. If not, see . -pub mod sponsoring; - -use fp_evm::PrecompileResult; -use pallet_common::{ - CollectionById, - erc::CommonEvmHandler, - eth::{map_eth_to_id, map_eth_to_token_id}, -}; -use pallet_fungible::FungibleHandle; -use pallet_nonfungible::NonfungibleHandle; -use pallet_refungible::{RefungibleHandle, erc::RefungibleTokenHandle}; -use sp_std::borrow::ToOwned; -use sp_std::vec::Vec; -use sp_core::{H160, U256}; -use crate::{CollectionMode, Config, dispatch::Dispatched}; -use pallet_common::CollectionHandle; - -pub struct UniqueErcSupport(core::marker::PhantomData); - -impl pallet_evm::OnMethodCall for UniqueErcSupport { - fn is_reserved(target: &H160) -> bool { - map_eth_to_id(target).is_some() - } - fn is_used(target: &H160) -> bool { - map_eth_to_id(target) - .map(>::contains_key) - .unwrap_or(false) - } - fn get_code(target: &H160) -> Option> { - if let Some(collection_id) = map_eth_to_id(target) { - let collection = >::get(collection_id)?; - Some( - match collection.mode { - CollectionMode::NFT => >::CODE, - CollectionMode::Fungible(_) => >::CODE, - CollectionMode::ReFungible => >::CODE, - } - .to_owned(), - ) - } else if let Some((collection_id, _token_id)) = map_eth_to_token_id(target) { - let collection = >::get(collection_id)?; - if collection.mode != CollectionMode::ReFungible { - return None; - } - // TODO: check token existence - Some(>::CODE.to_owned()) - } else { - None - } - } - fn call( - source: &H160, - target: &H160, - gas_limit: u64, - input: &[u8], - value: U256, - ) -> Option { - if let Some(collection_id) = map_eth_to_id(target) { - let collection = >::new_with_gas_limit(collection_id, gas_limit)?; - let dispatched = Dispatched::dispatch(collection); - - match dispatched { - Dispatched::Fungible(h) => h.call(source, input, value), - Dispatched::Nonfungible(h) => h.call(source, input, value), - Dispatched::Refungible(h) => h.call(source, input, value), - } - } else if let Some((collection_id, token_id)) = map_eth_to_token_id(target) { - let collection = >::new_with_gas_limit(collection_id, gas_limit)?; - if collection.mode != CollectionMode::ReFungible { - return None; - } - - let handle = RefungibleHandle::cast(collection); - // TODO: check token existence - RefungibleTokenHandle(handle, token_id).call(source, input, value) - } else { - None - } - } -} - pub mod evm_collection { use core::marker::PhantomData; use evm_coder::{execution::*, generate_stubgen, solidity_interface, types::*, ToLog}; use ethereum as _; use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder}; - use pallet_evm::{OnMethodCall, PrecompileResult, account::CrossAccountId}; + use pallet_evm::{OnMethodCall, PrecompileResult, account::CrossAccountId, Pallet as PalletEvm}; use up_data_structs::{ CreateCollectionData, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH, MAX_COLLECTION_NAME_LENGTH, }; use frame_support::traits::Get; use sp_core::H160; - use pallet_common::{CollectionHandle, save_eth, pallet::CollectionById}; + use pallet_common::{CollectionHandle, CollectionById}; use sp_std::{vec::Vec, rc::Rc}; use alloc::format; @@ -121,13 +40,13 @@ type ContractAddress: Get; } - struct EvmCollectionHelper(Rc>); + struct EvmCollectionHelper(SubstrateRecorder); impl WithRecorder for EvmCollectionHelper { fn recorder(&self) -> &SubstrateRecorder { &self.0 } - fn into_recorder(self) -> Rc> { + fn into_recorder(self) -> SubstrateRecorder { self.0 } } @@ -171,10 +90,13 @@ .map_err(pallet_evm_coder_substrate::dispatch_to_evm::)?; let address = pallet_common::eth::collection_id_to_address(collection_id); - self.0.log_mirrored(EthCollectionEvent::CollectionCreated { - owner: *caller.as_eth(), - collection_id: address, - }); + >::deposit_log( + EthCollectionEvent::CollectionCreated { + owner: *caller.as_eth(), + collection_id: address, + } + .to_log(address), + ); Ok(address) } @@ -188,14 +110,14 @@ } } - struct EvmCollection(Rc>); + struct EvmCollection(H160, SubstrateRecorder); impl WithRecorder for EvmCollection { fn recorder(&self) -> &SubstrateRecorder { - &self.0 + &self.1 } - fn into_recorder(self) -> Rc> { - self.0 + fn into_recorder(self) -> SubstrateRecorder { + self.1 } } @@ -216,21 +138,23 @@ caller: caller, sponsor: address, ) -> Result { - let mut collection = collection_from_address(self.contract_address(caller).unwrap(), &self.0)?; + let mut collection = collection_from_address::(self.contract_address(caller).unwrap(), self.1.gas_left())?; check_is_owner(caller, &collection)?; let sponsor = T::CrossAccountId::from_eth(sponsor); collection.set_sponsor(sponsor.as_sub().clone()); - save_eth(collection) + collection.save().map_err(pallet_evm_coder_substrate::dispatch_to_evm::)?; + Ok(()) } fn confirm_sponsorship(&self, caller: caller) -> Result { - let mut collection = collection_from_address(self.contract_address(caller).unwrap(), &self.0)?; + let mut collection = collection_from_address::(self.contract_address(caller).unwrap(), self.1.gas_left())?; let caller = T::CrossAccountId::from_eth(caller); if !collection.confirm_sponsorship(caller.as_sub()) { return Err(Error::Revert("Caller is not set as sponsor".into())); } - save_eth(collection) + collection.save().map_err(pallet_evm_coder_substrate::dispatch_to_evm::)?; + Ok(()) } fn set_limits( @@ -238,17 +162,18 @@ caller: caller, limits_json: string, ) -> Result { - let mut collection = collection_from_address(self.contract_address(caller).unwrap(), &self.0)?; + let mut collection = collection_from_address::(self.contract_address(caller).unwrap(), self.1.gas_left())?; check_is_owner(caller, &collection)?; let limits = serde_json_core::from_str(limits_json.as_ref()) .map_err(|e| Error::Revert(format!("Parse JSON error: {}", e)))?; collection.limits = limits.0; - save_eth(collection) + collection.save().map_err(pallet_evm_coder_substrate::dispatch_to_evm::)?; + Ok(()) } fn contract_address(&self, _caller: caller) -> Result
{ - Ok(self.0.contract()) + Ok(self.0) } } @@ -258,12 +183,13 @@ fn collection_from_address( collection_address: address, - recorder: &Rc>, + gas_limit: u64 ) -> Result> { let collection_id = pallet_common::eth::map_eth_to_id(&collection_address) - .ok_or(Error::Revert("Contract is not an unique collection".into()))?; + .ok_or(Error::Revert("Contract is not an unique collection".into()))?; + let recorder = >::new(gas_limit); let collection = - pallet_common::CollectionHandle::new_with_recorder(collection_id, recorder.clone()) + pallet_common::CollectionHandle::new_with_recorder(collection_id, recorder) .ok_or(Error::Revert("Create collection handle error".into()))?; Ok(collection) } @@ -297,7 +223,7 @@ return None; } - let helpers = EvmCollectionHelper::(Rc::new(SubstrateRecorder::::new(*target, gas_left))); + let helpers = EvmCollectionHelper::(SubstrateRecorder::::new(gas_left)); pallet_evm_coder_substrate::call(*source, helpers, value, input) } @@ -331,7 +257,7 @@ return None; } - let helpers = EvmCollection::(Rc::new(SubstrateRecorder::::new(*target, gas_left))); + let helpers = EvmCollection::(*target, SubstrateRecorder::::new(gas_left)); pallet_evm_coder_substrate::call(*source, helpers, value, input) } --- a/pallets/unique/src/lib.rs +++ b/pallets/unique/src/lib.rs @@ -22,6 +22,8 @@ clippy::unused_unit )] +extern crate alloc; + use frame_support::{ decl_module, decl_storage, decl_error, decl_event, dispatch::DispatchResult, @@ -46,7 +48,7 @@ CollectionHandle, Pallet as PalletCommon, CommonWeightInfo, dispatch::dispatch_call, dispatch::CollectionDispatch, }; -pub use eth::evm_collection; +pub mod eth; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; --- a/runtime/quartz/src/lib.rs +++ b/runtime/quartz/src/lib.rs @@ -66,7 +66,6 @@ WeightToFeePolynomial, WeightToFeeCoefficient, WeightToFeeCoefficients, ConstantMultiplier, }, }; -use unique_runtime_common::dispatch::{CollectionDispatchT, CollectionDispatch}; use up_data_structs::*; // use pallet_contracts::weights::WeightInfo; // #[cfg(any(feature = "std", test))] @@ -79,8 +78,8 @@ }; use smallvec::smallvec; use codec::{Encode, Decode}; -use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping, OnMethodCall}; -use pallet_unique::evm_collection; +use pallet_unique::eth::evm_collection; +use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping}; use fp_rpc::TransactionStatus; use sp_runtime::{ traits::{BlockNumberProvider, Dispatchable, PostDispatchInfoOf, Saturating}, @@ -117,7 +116,15 @@ //use xcm_executor::traits::MatchesFungible; use sp_runtime::traits::CheckedConversion; -use unique_runtime_common::{impl_common_runtime_apis, types::*, constants::*}; +use unique_runtime_common::{ + impl_common_runtime_apis, + types::*, + constants::*, + dispatch::{CollectionDispatchT, CollectionDispatch}, + sponsoring::UniqueSponsorshipHandler, + eth_sponsoring::UniqueEthSponsorshipHandler, + weights::CommonWeights, +}; pub const RUNTIME_NAME: &str = "quartz"; pub const TOKEN_SYMBOL: &str = "QTZ"; @@ -894,6 +901,7 @@ impl pallet_unique::Config for Runtime { type Event = Event; type WeightInfo = pallet_unique::weights::SubstrateWeight; + type CommonWeightInfo = CommonWeights; } parameter_types! { @@ -915,11 +923,11 @@ // } type EvmSponsorshipHandler = ( - pallet_unique::UniqueEthSponsorshipHandler, + UniqueEthSponsorshipHandler, pallet_evm_contract_helpers::HelpersContractSponsoring, ); type SponsorshipHandler = ( - pallet_unique::UniqueSponsorshipHandler, + UniqueSponsorshipHandler, //pallet_contract_helpers::ContractSponsorshipHandler, pallet_evm_transaction_payment::BridgeSponsorshipHandler, ); --- a/runtime/unique/src/lib.rs +++ b/runtime/unique/src/lib.rs @@ -50,6 +50,7 @@ pub use pallet_balances::Call as BalancesCall; pub use pallet_evm::{ EnsureAddressTruncated, HashedAddressMapping, Runner, account::CrossAccountId as _, OnMethodCall, + Account as EVMAccount, FeeCalculator, GasWeightMapping, }; pub use frame_support::{ construct_runtime, match_types, @@ -84,8 +85,7 @@ }; use smallvec::smallvec; use codec::{Encode, Decode}; -use pallet_evm::{Account as EVMAccount, FeeCalculator, GasWeightMapping, OnMethodCall}; -use pallet_unique::evm_collection; +use pallet_unique::eth::evm_collection; use fp_rpc::TransactionStatus; use sp_runtime::{ traits::{BlockNumberProvider, Dispatchable, PostDispatchInfoOf, Saturating}, @@ -121,7 +121,15 @@ //use xcm_executor::traits::MatchesFungible; use sp_runtime::traits::CheckedConversion; -use unique_runtime_common::{impl_common_runtime_apis, types::*, constants::*}; +use unique_runtime_common::{ + impl_common_runtime_apis, + types::*, + constants::*, + dispatch::{CollectionDispatchT, CollectionDispatch}, + sponsoring::UniqueSponsorshipHandler, + eth_sponsoring::UniqueEthSponsorshipHandler, + weights::CommonWeights, +}; pub const RUNTIME_NAME: &str = "unique"; pub const TOKEN_SYMBOL: &str = "UNQ";