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

difftreelog

build update frontier

Yaroslav Bolyukin2021-11-26parent: #f2dde26.patch.diff
in: master

14 files changed

modifiedcrates/evm-coder/Cargo.tomldiffbeforeafterboth
--- a/crates/evm-coder/Cargo.toml
+++ b/crates/evm-coder/Cargo.toml
@@ -7,8 +7,8 @@
 evm-coder-macros = { path = "../evm-coder-macros" }
 primitive-types = { version = "0.10.1", default-features = false }
 hex-literal = "0.3.3"
-ethereum = { version = "0.9", git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false }
-evm-core = { default-features = false, git = "https://github.com/uniquenetwork/evm.git", branch="precompile-output-parachain" }
+ethereum = { version = "0.10.0", default-features = false }
+evm-core = { default-features = false, git = "https://github.com/uniquenetwork/evm.git", branch = "unique-weights" }
 impl-trait-for-tuples = "0.2.1"
 
 [dev-dependencies]
modifiedpallets/common/src/erc.rsdiffbeforeafterboth
--- a/pallets/common/src/erc.rs
+++ b/pallets/common/src/erc.rs
@@ -1,4 +1,5 @@
 pub use pallet_evm::PrecompileOutput;
+pub use pallet_evm::PrecompileResult;
 use sp_core::{H160, U256};
 
 /// Does not always represent a full collection, for RFT it is either
@@ -6,5 +7,5 @@
 pub trait CommonEvmHandler {
 	const CODE: &'static [u8];
 
-	fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileOutput>;
+	fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileResult>;
 }
modifiedpallets/evm-coder-substrate/Cargo.tomldiffbeforeafterboth
--- a/pallets/evm-coder-substrate/Cargo.toml
+++ b/pallets/evm-coder-substrate/Cargo.toml
@@ -9,7 +9,7 @@
 ] }
 sp-std = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' }
 sp-core = { default-features = false, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' }
-ethereum = { version = "0.9", git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false }
+ethereum = { version = "0.10.0", default-features = false }
 evm-coder = { default-features = false, path = "../../crates/evm-coder" }
 pallet-ethereum = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" }
 pallet-evm = { default-features = false, git = "https://github.com/uniquenetwork/frontier.git", branch = "unique-polkadot-v0.9.12-weights" }
modifiedpallets/evm-coder-substrate/src/lib.rsdiffbeforeafterboth
before · pallets/evm-coder-substrate/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23#[cfg(not(feature = "std"))]4extern crate alloc;5// #[cfg(feature = "runtime-benchmarks")]6// pub mod benchmarking;78pub use pallet::*;910#[frame_support::pallet]11pub mod pallet {12	#[cfg(not(feature = "std"))]13	use alloc::format;1415	use evm_coder::{16		ToLog,17		abi::{AbiReader, AbiWrite, AbiWriter},18		execution::{self, Result},19		types::{Msg, value},20	};21	use frame_support::{ensure};22	use pallet_evm::{23		ExitError, ExitReason, ExitRevert, ExitSucceed, PrecompileOutput, GasWeightMapping,24	};25	use frame_system::ensure_signed;26	pub use frame_support::dispatch::DispatchResult;27	use pallet_ethereum::EthereumTransactionSender;28	use sp_std::cell::RefCell;29	use sp_std::vec::Vec;30	use sp_core::{H160, H256};31	use ethereum::Log;32	use frame_support::{pallet_prelude::*, traits::PalletInfo};33	use frame_system::pallet_prelude::*;3435	/// DispatchError is opaque, but we need to somehow extract correct error in case of OutOfGas failure36	/// So we have this pallet, which defines OutOfGas error, and knews its own id to check if DispatchError37	/// is thrown because of it38	///39	/// These errors shouldn't end in extrinsic results, as they only used in evm execution path40	#[pallet::error]41	pub enum Error<T> {42		OutOfGas,43		OutOfFund,44	}4546	#[pallet::config]47	pub trait Config: frame_system::Config {48		type EthereumTransactionSender: pallet_ethereum::EthereumTransactionSender;49		type GasWeightMapping: pallet_evm::GasWeightMapping;50	}5152	#[pallet::pallet]53	pub struct Pallet<T>(_);5455	#[pallet::call]56	impl<T: Config> Pallet<T> {57		#[pallet::weight(0)]58		pub fn empty_call(origin: OriginFor<T>) -> DispatchResult {59			let _sender = ensure_signed(origin)?;60			Ok(())61		}62	}6364	// From instabul hardfork configuration: https://github.com/rust-blockchain/evm/blob/fd4fd6acc0ca3208d6770fdb3ba407c94cdf97c6/runtime/src/lib.rs#L28465	pub const G_SLOAD_WORD: u64 = 800;66	pub const G_SSTORE_WORD: u64 = 20000;6768	pub fn generate_transaction() -> ethereum::TransactionV0 {69		use ethereum::{TransactionV0, TransactionAction, TransactionSignature};70		TransactionV0 {71			nonce: 0.into(),72			gas_price: 0.into(),73			gas_limit: 0.into(),74			action: TransactionAction::Call(H160([0; 20])),75			value: 0.into(),76			// zero selector, this transaction always has same sender, so all data should be acquired from logs77			input: Vec::from([0, 0, 0, 0]),78			// if v is not 27 - then we need to pass some other validity checks79			signature: TransactionSignature::new(27, H256([0x88; 32]), H256([0x88; 32])).unwrap(),80		}81	}8283	#[derive(Default)]84	pub struct SubstrateRecorder<T: Config> {85		contract: H160,86		logs: RefCell<Vec<Log>>,87		initial_gas: u64,88		gas_limit: RefCell<u64>,89		_phantom: PhantomData<*const T>,90	}9192	impl<T: Config> SubstrateRecorder<T> {93		pub fn new(contract: H160, gas_limit: u64) -> Self {94			Self {95				contract,96				logs: RefCell::new(Vec::new()),97				initial_gas: gas_limit,98				gas_limit: RefCell::new(gas_limit),99				_phantom: PhantomData,100			}101		}102103		pub fn is_empty(&self) -> bool {104			self.logs.borrow().is_empty()105		}106		// TODO: Replace with real storage in pallet-ethereum,107		// same way as it is done with frame_system's Events108		/// Doesn't consumes any gas, should be used after consume_log_sub109		pub fn log(&self, log: impl ToLog) {110			self.logs.borrow_mut().push(log.to_log(self.contract));111		}112		pub fn retrieve_logs(self) -> Vec<Log> {113			self.logs.into_inner()114		}115116		pub fn gas_left(&self) -> u64 {117			*self.gas_limit.borrow()118		}119		pub fn consume_sload_sub(&self) -> DispatchResult {120			self.consume_gas_sub(G_SLOAD_WORD)121		}122		pub fn consume_sstores_sub(&self, amount: usize) -> DispatchResult {123			self.consume_gas_sub(G_SSTORE_WORD.saturating_mul(amount as u64))124		}125		pub fn consume_sstore_sub(&self) -> DispatchResult {126			self.consume_gas_sub(G_SSTORE_WORD)127		}128		pub fn consume_gas_sub(&self, gas: u64) -> DispatchResult {129			ensure!(gas != u64::MAX, Error::<T>::OutOfGas);130			let mut gas_limit = self.gas_limit.borrow_mut();131			ensure!(gas <= *gas_limit, Error::<T>::OutOfGas);132			*gas_limit -= gas;133			Ok(())134		}135136		pub fn consume_sload(&self) -> Result<()> {137			self.consume_gas(G_SLOAD_WORD)138		}139		pub fn consume_sstore(&self) -> Result<()> {140			self.consume_gas(G_SSTORE_WORD)141		}142		pub fn consume_gas(&self, gas: u64) -> Result<()> {143			if gas == u64::MAX {144				return Err(execution::Error::Error(ExitError::OutOfGas));145			}146			let mut gas_limit = self.gas_limit.borrow_mut();147			if gas > *gas_limit {148				return Err(execution::Error::Error(ExitError::OutOfGas));149			}150			*gas_limit -= gas;151			Ok(())152		}153		pub fn return_gas(&self, gas: u64) {154			let mut gas_limit = self.gas_limit.borrow_mut();155			*gas_limit += gas;156		}157158		pub fn evm_to_precompile_output(159			self,160			result: evm_coder::execution::Result<Option<AbiWriter>>,161		) -> Option<PrecompileOutput> {162			use evm_coder::execution::Error;163			let (writer, reason) = match result {164				Ok(Some(v)) => (v, ExitReason::Succeed(ExitSucceed::Returned)),165				Ok(None) => return None,166				Err(Error::Revert(e)) => {167					let mut writer = AbiWriter::new_call(evm_coder::fn_selector!(Error(string)));168					(&e as &str).abi_write(&mut writer);169170					(writer, ExitReason::Revert(ExitRevert::Reverted))171				}172				Err(Error::Fatal(f)) => (AbiWriter::new(), ExitReason::Fatal(f)),173				Err(Error::Error(e)) => (AbiWriter::new(), ExitReason::Error(e)),174			};175176			Some(PrecompileOutput {177				cost: self.initial_gas - self.gas_left(),178				exit_status: reason,179				logs: self.retrieve_logs(),180				output: writer.finish(),181			})182		}183184		pub fn submit_logs(self) {185			let logs = self.retrieve_logs();186			if logs.is_empty() {187				return;188			}189			T::EthereumTransactionSender::submit_logs_transaction(190				Default::default(),191				generate_transaction(),192				logs,193			)194		}195	}196197	pub fn dispatch_to_evm<T: Config>(err: DispatchError) -> evm_coder::execution::Error {198		use evm_coder::execution::Error as ExError;199		match err {200			DispatchError::Module { index, error, .. }201				if index202					== T::PalletInfo::index::<Pallet<T>>()203						.expect("evm-coder-substrate is a pallet, which should be added to runtime")204						as u8 =>205			{206				match error {207					v if v == Error::<T>::OutOfGas.as_u8() => ExError::Error(ExitError::OutOfGas),208					v if v == Error::<T>::OutOfFund.as_u8() => ExError::Error(ExitError::OutOfFund),209					_ => unreachable!("this pallet only defines two possible errors"),210				}211			}212			DispatchError::Module {213				message: Some(msg), ..214			} => ExError::Revert(msg.into()),215			DispatchError::Module { index, error, .. } => {216				ExError::Revert(format!("error {} in pallet {}", error, index))217			}218			e => ExError::Revert(format!("substrate error: {:?}", e)),219		}220	}221222	pub trait WithRecorder<T: Config> {223		fn recorder(&self) -> &SubstrateRecorder<T>;224		fn into_recorder(self) -> SubstrateRecorder<T>;225	}226227	/// Helper to simplify implementing bridge between evm-coder definitions and pallet-evm228	pub fn call<229		T: Config,230		C: evm_coder::Call + evm_coder::Weighted,231		E: evm_coder::Callable<C> + WithRecorder<T>,232	>(233		caller: H160,234		mut e: E,235		value: value,236		input: &[u8],237	) -> Option<PrecompileOutput> {238		let result = call_internal(caller, &mut e, value, input);239		e.into_recorder().evm_to_precompile_output(result)240	}241242	fn call_internal<243		T: Config,244		C: evm_coder::Call + evm_coder::Weighted,245		E: evm_coder::Callable<C> + WithRecorder<T>,246	>(247		caller: H160,248		e: &mut E,249		value: value,250		input: &[u8],251	) -> evm_coder::execution::Result<Option<AbiWriter>> {252		let (selector, mut reader) = AbiReader::new_call(input)?;253		let call = C::parse(selector, &mut reader)?;254		if call.is_none() {255			return Ok(None);256		}257		let call = call.unwrap();258259		let dispatch_info = call.weight();260		e.recorder()261			.consume_gas(T::GasWeightMapping::weight_to_gas(dispatch_info.weight))?;262263		match e.call(Msg {264			call,265			caller,266			value,267		}) {268			Ok(v) => {269				let unspent = v.post_info.calc_unspent(&dispatch_info);270				e.recorder()271					.return_gas(T::GasWeightMapping::weight_to_gas(unspent));272				Ok(Some(v.data))273			}274			Err(v) => {275				let unspent = v.post_info.calc_unspent(&dispatch_info);276				e.recorder()277					.return_gas(T::GasWeightMapping::weight_to_gas(unspent));278				Err(v.data)279			}280		}281	}282}
after · pallets/evm-coder-substrate/src/lib.rs
1#![cfg_attr(not(feature = "std"), no_std)]23#[cfg(not(feature = "std"))]4extern crate alloc;5// #[cfg(feature = "runtime-benchmarks")]6// pub mod benchmarking;78pub use pallet::*;910#[frame_support::pallet]11pub mod pallet {12	#[cfg(not(feature = "std"))]13	use alloc::format;1415	use evm_coder::{16		ToLog,17		abi::{AbiReader, AbiWrite, AbiWriter},18		execution::{self, Result},19		types::{Msg, value},20	};21	use frame_support::{ensure};22	use pallet_evm::{23		ExitError, ExitRevert, ExitSucceed, GasWeightMapping, PrecompileFailure, PrecompileOutput,24		PrecompileResult,25	};26	use frame_system::ensure_signed;27	pub use frame_support::dispatch::DispatchResult;28	use pallet_ethereum::EthereumTransactionSender;29	use sp_std::cell::RefCell;30	use sp_std::vec::Vec;31	use sp_core::{H160, H256};32	use ethereum::Log;33	use frame_support::{pallet_prelude::*, traits::PalletInfo};34	use frame_system::pallet_prelude::*;3536	/// DispatchError is opaque, but we need to somehow extract correct error in case of OutOfGas failure37	/// So we have this pallet, which defines OutOfGas error, and knews its own id to check if DispatchError38	/// is thrown because of it39	///40	/// These errors shouldn't end in extrinsic results, as they only used in evm execution path41	#[pallet::error]42	pub enum Error<T> {43		OutOfGas,44		OutOfFund,45	}4647	#[pallet::config]48	pub trait Config: frame_system::Config {49		type EthereumTransactionSender: pallet_ethereum::EthereumTransactionSender;50		type GasWeightMapping: pallet_evm::GasWeightMapping;51	}5253	#[pallet::pallet]54	pub struct Pallet<T>(_);5556	#[pallet::call]57	impl<T: Config> Pallet<T> {58		#[pallet::weight(0)]59		pub fn empty_call(origin: OriginFor<T>) -> DispatchResult {60			let _sender = ensure_signed(origin)?;61			Ok(())62		}63	}6465	// From instabul hardfork configuration: https://github.com/rust-blockchain/evm/blob/fd4fd6acc0ca3208d6770fdb3ba407c94cdf97c6/runtime/src/lib.rs#L28466	pub const G_SLOAD_WORD: u64 = 800;67	pub const G_SSTORE_WORD: u64 = 20000;6869	pub fn generate_transaction() -> ethereum::TransactionV0 {70		use ethereum::{TransactionV0, TransactionAction, TransactionSignature};71		TransactionV0 {72			nonce: 0.into(),73			gas_price: 0.into(),74			gas_limit: 0.into(),75			action: TransactionAction::Call(H160([0; 20])),76			value: 0.into(),77			// zero selector, this transaction always has same sender, so all data should be acquired from logs78			input: Vec::from([0, 0, 0, 0]),79			// if v is not 27 - then we need to pass some other validity checks80			signature: TransactionSignature::new(27, H256([0x88; 32]), H256([0x88; 32])).unwrap(),81		}82	}8384	#[derive(Default)]85	pub struct SubstrateRecorder<T: Config> {86		contract: H160,87		logs: RefCell<Vec<Log>>,88		initial_gas: u64,89		gas_limit: RefCell<u64>,90		_phantom: PhantomData<*const T>,91	}9293	impl<T: Config> SubstrateRecorder<T> {94		pub fn new(contract: H160, gas_limit: u64) -> Self {95			Self {96				contract,97				logs: RefCell::new(Vec::new()),98				initial_gas: gas_limit,99				gas_limit: RefCell::new(gas_limit),100				_phantom: PhantomData,101			}102		}103104		pub fn is_empty(&self) -> bool {105			self.logs.borrow().is_empty()106		}107		// TODO: Replace with real storage in pallet-ethereum,108		// same way as it is done with frame_system's Events109		/// Doesn't consumes any gas, should be used after consume_log_sub110		pub fn log(&self, log: impl ToLog) {111			self.logs.borrow_mut().push(log.to_log(self.contract));112		}113		pub fn retrieve_logs(self) -> Vec<Log> {114			self.logs.into_inner()115		}116117		pub fn gas_left(&self) -> u64 {118			*self.gas_limit.borrow()119		}120		pub fn consume_sload_sub(&self) -> DispatchResult {121			self.consume_gas_sub(G_SLOAD_WORD)122		}123		pub fn consume_sstores_sub(&self, amount: usize) -> DispatchResult {124			self.consume_gas_sub(G_SSTORE_WORD.saturating_mul(amount as u64))125		}126		pub fn consume_sstore_sub(&self) -> DispatchResult {127			self.consume_gas_sub(G_SSTORE_WORD)128		}129		pub fn consume_gas_sub(&self, gas: u64) -> DispatchResult {130			ensure!(gas != u64::MAX, Error::<T>::OutOfGas);131			let mut gas_limit = self.gas_limit.borrow_mut();132			ensure!(gas <= *gas_limit, Error::<T>::OutOfGas);133			*gas_limit -= gas;134			Ok(())135		}136137		pub fn consume_sload(&self) -> Result<()> {138			self.consume_gas(G_SLOAD_WORD)139		}140		pub fn consume_sstore(&self) -> Result<()> {141			self.consume_gas(G_SSTORE_WORD)142		}143		pub fn consume_gas(&self, gas: u64) -> Result<()> {144			if gas == u64::MAX {145				return Err(execution::Error::Error(ExitError::OutOfGas));146			}147			let mut gas_limit = self.gas_limit.borrow_mut();148			if gas > *gas_limit {149				return Err(execution::Error::Error(ExitError::OutOfGas));150			}151			*gas_limit -= gas;152			Ok(())153		}154		pub fn return_gas(&self, gas: u64) {155			let mut gas_limit = self.gas_limit.borrow_mut();156			*gas_limit += gas;157		}158159		pub fn evm_to_precompile_output(160			self,161			result: evm_coder::execution::Result<Option<AbiWriter>>,162		) -> Option<PrecompileResult> {163			use evm_coder::execution::Error;164			Some(match result {165				Ok(Some(v)) => Ok(PrecompileOutput {166					exit_status: ExitSucceed::Returned,167					cost: self.initial_gas - self.gas_left(),168					logs: self.retrieve_logs(),169					output: v.finish(),170				}),171				Ok(None) => return None,172				Err(Error::Revert(e)) => {173					let mut writer = AbiWriter::new_call(evm_coder::fn_selector!(Error(string)));174					(&e as &str).abi_write(&mut writer);175176					Err(PrecompileFailure::Revert {177						exit_status: ExitRevert::Reverted,178						cost: self.initial_gas - self.gas_left(),179						output: writer.finish(),180					})181				}182				Err(Error::Fatal(f)) => Err(f.into()),183				Err(Error::Error(e)) => Err(e.into()),184			})185		}186187		pub fn submit_logs(self) {188			let logs = self.retrieve_logs();189			if logs.is_empty() {190				return;191			}192			T::EthereumTransactionSender::submit_logs_transaction(193				Default::default(),194				generate_transaction(),195				logs,196			)197		}198	}199200	pub fn dispatch_to_evm<T: Config>(err: DispatchError) -> evm_coder::execution::Error {201		use evm_coder::execution::Error as ExError;202		match err {203			DispatchError::Module { index, error, .. }204				if index205					== T::PalletInfo::index::<Pallet<T>>()206						.expect("evm-coder-substrate is a pallet, which should be added to runtime")207						as u8 =>208			{209				match error {210					v if v == Error::<T>::OutOfGas.as_u8() => ExError::Error(ExitError::OutOfGas),211					v if v == Error::<T>::OutOfFund.as_u8() => ExError::Error(ExitError::OutOfFund),212					_ => unreachable!("this pallet only defines two possible errors"),213				}214			}215			DispatchError::Module {216				message: Some(msg), ..217			} => ExError::Revert(msg.into()),218			DispatchError::Module { index, error, .. } => {219				ExError::Revert(format!("error {} in pallet {}", error, index))220			}221			e => ExError::Revert(format!("substrate error: {:?}", e)),222		}223	}224225	pub trait WithRecorder<T: Config> {226		fn recorder(&self) -> &SubstrateRecorder<T>;227		fn into_recorder(self) -> SubstrateRecorder<T>;228	}229230	/// Helper to simplify implementing bridge between evm-coder definitions and pallet-evm231	pub fn call<232		T: Config,233		C: evm_coder::Call + evm_coder::Weighted,234		E: evm_coder::Callable<C> + WithRecorder<T>,235	>(236		caller: H160,237		mut e: E,238		value: value,239		input: &[u8],240	) -> Option<PrecompileResult> {241		let result = call_internal(caller, &mut e, value, input);242		e.into_recorder().evm_to_precompile_output(result)243	}244245	fn call_internal<246		T: Config,247		C: evm_coder::Call + evm_coder::Weighted,248		E: evm_coder::Callable<C> + WithRecorder<T>,249	>(250		caller: H160,251		e: &mut E,252		value: value,253		input: &[u8],254	) -> evm_coder::execution::Result<Option<AbiWriter>> {255		let (selector, mut reader) = AbiReader::new_call(input)?;256		let call = C::parse(selector, &mut reader)?;257		if call.is_none() {258			return Ok(None);259		}260		let call = call.unwrap();261262		let dispatch_info = call.weight();263		e.recorder()264			.consume_gas(T::GasWeightMapping::weight_to_gas(dispatch_info.weight))?;265266		match e.call(Msg {267			call,268			caller,269			value,270		}) {271			Ok(v) => {272				let unspent = v.post_info.calc_unspent(&dispatch_info);273				e.recorder()274					.return_gas(T::GasWeightMapping::weight_to_gas(unspent));275				Ok(Some(v.data))276			}277			Err(v) => {278				let unspent = v.post_info.calc_unspent(&dispatch_info);279				e.recorder()280					.return_gas(T::GasWeightMapping::weight_to_gas(unspent));281				Err(v.data)282			}283		}284	}285}
modifiedpallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth
--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -1,7 +1,10 @@
 use core::marker::PhantomData;
 use evm_coder::{abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*};
 use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder};
-use pallet_evm::{ExitReason, ExitRevert, OnCreate, OnMethodCall, PrecompileOutput};
+use pallet_evm::{
+	ExitReason, ExitRevert, OnCreate, OnMethodCall, PrecompileOutput, PrecompileResult,
+	PrecompileFailure,
+};
 use sp_core::H160;
 use crate::{
 	AllowlistEnabled, Config, Owner, Pallet, SelfSponsoring, SponsorBasket, SponsoringRateLimit,
@@ -109,19 +112,18 @@
 		gas_left: u64,
 		input: &[u8],
 		value: sp_core::U256,
-	) -> Option<PrecompileOutput> {
+	) -> Option<PrecompileResult> {
 		// TODO: Extract to another OnMethodCall handler
 		if <AllowlistEnabled<T>>::get(target) && !<Pallet<T>>::allowed(*target, *source) {
-			return Some(PrecompileOutput {
-				exit_status: ExitReason::Revert(ExitRevert::Reverted),
+			return Some(Err(PrecompileFailure::Revert {
+				exit_status: ExitRevert::Reverted,
 				cost: 0,
 				output: {
 					let mut writer = AbiWriter::new_call(evm_coder::fn_selector!(Error(string)));
 					writer.string("Target contract is allowlisted");
 					writer.finish()
 				},
-				logs: sp_std::vec![],
-			});
+			}));
 		}
 
 		if target != &T::ContractAddress::get() {
modifiedpallets/evm-migration/src/lib.rsdiffbeforeafterboth
--- a/pallets/evm-migration/src/lib.rs
+++ b/pallets/evm-migration/src/lib.rs
@@ -98,7 +98,7 @@
 			_gas_left: u64,
 			_input: &[u8],
 			_value: sp_core::U256,
-		) -> Option<pallet_evm::PrecompileOutput> {
+		) -> Option<pallet_evm::PrecompileResult> {
 			None
 		}
 
modifiedpallets/fungible/Cargo.tomldiffbeforeafterboth
--- a/pallets/fungible/Cargo.toml
+++ b/pallets/fungible/Cargo.toml
@@ -19,7 +19,7 @@
 nft-data-structs = { default-features = false, path = '../../primitives/nft' }
 evm-coder = { default-features = false, path = '../../crates/evm-coder' }
 pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }
-ethereum = { git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false }
+ethereum = { version = "0.10.0", default-features = false }
 frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' }
 scale-info = { version = "1.0.0", default-features = false, features = [
     "derive",
modifiedpallets/fungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/fungible/src/erc.rs
+++ b/pallets/fungible/src/erc.rs
@@ -2,7 +2,7 @@
 use core::convert::TryInto;
 use evm_coder::{ToLog, execution::*, generate_stubgen, solidity_interface, types::*, weight};
 use nft_data_structs::CollectionMode;
-use pallet_common::erc::CommonEvmHandler;
+use pallet_common::erc::{CommonEvmHandler, PrecompileResult};
 use sp_core::{H160, U256};
 use sp_std::vec::Vec;
 use pallet_common::account::CrossAccountId;
@@ -127,7 +127,7 @@
 impl<T: Config> CommonEvmHandler for FungibleHandle<T> {
 	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueFungible.raw");
 
-	fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileOutput> {
+	fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileResult> {
 		call::<T, UniqueFungibleCall<T>, _>(*source, self, value, input)
 	}
 }
modifiedpallets/nft/Cargo.tomldiffbeforeafterboth
--- a/pallets/nft/Cargo.toml
+++ b/pallets/nft/Cargo.toml
@@ -131,7 +131,7 @@
 scale-info = { version = "1.0.0", default-features = false, features = [
     "derive",
 ] }
-ethereum = { version = "0.9", git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false }
+ethereum = { version = "0.10.0", default-features = false }
 rlp = { default-features = false, version = "0.5.0" }
 sp-api = { default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.12" }
 
modifiedpallets/nft/src/eth/mod.rsdiffbeforeafterboth
--- a/pallets/nft/src/eth/mod.rs
+++ b/pallets/nft/src/eth/mod.rs
@@ -1,5 +1,6 @@
 pub mod sponsoring;
 
+use fp_evm::PrecompileResult;
 use pallet_common::{
 	CollectionById,
 	erc::CommonEvmHandler,
@@ -10,7 +11,6 @@
 use pallet_refungible::{RefungibleHandle, erc::RefungibleTokenHandle};
 use sp_std::borrow::ToOwned;
 use sp_std::vec::Vec;
-use pallet_evm::{PrecompileOutput};
 use sp_core::{H160, U256};
 use crate::{CollectionMode, Config, dispatch::Dispatched};
 use pallet_common::CollectionHandle;
@@ -54,7 +54,7 @@
 		gas_limit: u64,
 		input: &[u8],
 		value: U256,
-	) -> Option<PrecompileOutput> {
+	) -> Option<PrecompileResult> {
 		if let Some(collection_id) = map_eth_to_id(target) {
 			let collection = <CollectionHandle<T>>::new_with_gas_limit(collection_id, gas_limit)?;
 			let dispatched = Dispatched::dispatch(collection);
modifiedpallets/nft/src/eth/sponsoring.rsdiffbeforeafterboth
--- a/pallets/nft/src/eth/sponsoring.rs
+++ b/pallets/nft/src/eth/sponsoring.rs
@@ -27,7 +27,7 @@
 		let (method_id, mut reader) = AbiReader::new_call(&call.1).ok()?;
 		match &collection.mode {
 			crate::CollectionMode::NFT => {
-				let call = UniqueNFTCall::parse(method_id, &mut reader).ok()??;
+				let call = <UniqueNFTCall<T>>::parse(method_id, &mut reader).ok()??;
 				match call {
 					UniqueNFTCall::ERC721UniqueExtensions(
 						ERC721UniqueExtensionsCall::Transfer { token_id, .. },
@@ -49,7 +49,7 @@
 				}
 			}
 			crate::CollectionMode::Fungible(_) => {
-				let call = UniqueFungibleCall::parse(method_id, &mut reader).ok()??;
+				let call = <UniqueFungibleCall<T>>::parse(method_id, &mut reader).ok()??;
 				#[allow(clippy::single_match)]
 				match call {
 					UniqueFungibleCall::ERC20(ERC20Call::Transfer { .. }) => {
modifiedpallets/nonfungible/Cargo.tomldiffbeforeafterboth
--- a/pallets/nonfungible/Cargo.toml
+++ b/pallets/nonfungible/Cargo.toml
@@ -19,7 +19,7 @@
 nft-data-structs = { default-features = false, path = '../../primitives/nft' }
 evm-coder = { default-features = false, path = '../../crates/evm-coder' }
 pallet-evm-coder-substrate = { default-features = false, path = '../evm-coder-substrate' }
-ethereum = { git = "https://github.com/purestake/ethereum", branch = "joshy-scale-info", default-features = false }
+ethereum = { version = "0.10.0", default-features = false }
 frame-benchmarking = { default-features = false, optional = true, git = 'https://github.com/paritytech/substrate.git', branch = 'polkadot-v0.9.12' }
 scale-info = { version = "1.0.0", default-features = false, features = [
     "derive",
modifiedpallets/nonfungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/nonfungible/src/erc.rs
+++ b/pallets/nonfungible/src/erc.rs
@@ -8,7 +8,10 @@
 use pallet_evm_coder_substrate::dispatch_to_evm;
 use sp_core::{H160, U256};
 use sp_std::{vec::Vec, vec};
-use pallet_common::{account::CrossAccountId, erc::CommonEvmHandler};
+use pallet_common::{
+	account::CrossAccountId,
+	erc::{CommonEvmHandler, PrecompileResult},
+};
 use pallet_evm_coder_substrate::call;
 use pallet_common::erc::PrecompileOutput;
 
@@ -434,7 +437,7 @@
 impl<T: Config> CommonEvmHandler for NonfungibleHandle<T> {
 	const CODE: &'static [u8] = include_bytes!("./stubs/UniqueNFT.raw");
 
-	fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileOutput> {
+	fn call(self, source: &H160, input: &[u8], value: U256) -> Option<PrecompileResult> {
 		call::<T, UniqueNFTCall<T>, _>(*source, self, value, input)
 	}
 }
modifiedpallets/refungible/src/erc.rsdiffbeforeafterboth
--- a/pallets/refungible/src/erc.rs
+++ b/pallets/refungible/src/erc.rs
@@ -11,7 +11,7 @@
 		_source: &sp_core::H160,
 		_input: &[u8],
 		_value: sp_core::U256,
-	) -> Option<pallet_common::erc::PrecompileOutput> {
+	) -> Option<pallet_common::erc::PrecompileResult> {
 		// TODO: Implement RFT variant of ERC721
 		None
 	}
@@ -27,7 +27,7 @@
 		_source: &sp_core::H160,
 		_input: &[u8],
 		_value: sp_core::U256,
-	) -> Option<pallet_common::erc::PrecompileOutput> {
+	) -> Option<pallet_common::erc::PrecompileResult> {
 		// TODO: Implement RFT variant of ERC20
 		None
 	}