difftreelog
build update frontier
in: master
14 files changed
crates/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]
pallets/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>;
}
pallets/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" }
pallets/evm-coder-substrate/src/lib.rsdiffbeforeafterboth1#![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}pallets/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() {
pallets/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
}
pallets/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",
pallets/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)
}
}
pallets/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" }
pallets/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);
pallets/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 { .. }) => {
pallets/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",
pallets/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)
}
}
pallets/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
}