From a156ee0040e7fc050ad6b1a3062ae637a19af1b1 Mon Sep 17 00:00:00 2001 From: Trubnikov Sergey Date: Thu, 17 Nov 2022 06:18:25 +0000 Subject: [PATCH] refactor: Make implementations of Abi* for EthCrossAccount via AbiCoder macro --- --- a/.maintain/scripts/generate_abi.sh +++ b/.maintain/scripts/generate_abi.sh @@ -4,6 +4,7 @@ dir=$PWD tmp=$(mktemp -d) +echo "Tmp file: $tmp/input.sol" cd $tmp cp $dir/$INPUT input.sol solcjs --abi -p input.sol --- a/crates/evm-coder/src/abi/impls.rs +++ b/crates/evm-coder/src/abi/impls.rs @@ -120,42 +120,6 @@ } } -impl sealed::CanBePlacedInVec for EthCrossAccount {} - -impl AbiType for EthCrossAccount { - const SIGNATURE: SignatureUnit = make_signature!(new fixed("(address,uint256)")); - - fn is_dynamic() -> bool { - address::is_dynamic() || uint256::is_dynamic() - } - - fn size() -> usize { -
::size() + ::size() - } -} - -impl AbiRead for EthCrossAccount { - fn abi_read(reader: &mut AbiReader) -> Result { - let size = if !EthCrossAccount::is_dynamic() { - Some(::size()) - } else { - None - }; - let mut subresult = reader.subresult(size)?; - let eth =
::abi_read(&mut subresult)?; - let sub = ::abi_read(&mut subresult)?; - - Ok(EthCrossAccount { eth, sub }) - } -} - -impl AbiWrite for EthCrossAccount { - fn abi_write(&self, writer: &mut AbiWriter) { - self.eth.abi_write(writer); - self.sub.abi_write(writer); - } -} - impl sealed::CanBePlacedInVec for Property {} impl AbiType for Property { --- a/crates/evm-coder/src/lib.rs +++ b/crates/evm-coder/src/lib.rs @@ -93,6 +93,7 @@ pub use evm_coder_procedural::solidity; /// See [`solidity_interface`] pub use evm_coder_procedural::weight; +pub use evm_coder_procedural::AbiCoder; pub use sha3_const; /// Derives [`ToLog`] for enum @@ -119,7 +120,6 @@ #[cfg(not(feature = "std"))] use alloc::{vec::Vec}; - use pallet_evm::account::CrossAccountId; use primitive_types::{U256, H160, H256}; pub type address = H160; @@ -185,73 +185,7 @@ #[must_use] pub fn is_empty(&self) -> bool { self.len() == 0 - } - } - - #[derive(Debug, Default)] - pub struct EthCrossAccount { - pub(crate) eth: address, - pub(crate) sub: uint256, - } - - impl EthCrossAccount { - pub fn from_sub_cross_account(cross_account_id: &T::CrossAccountId) -> Self - where - T: pallet_evm::Config, - T::AccountId: AsRef<[u8; 32]>, - { - if cross_account_id.is_canonical_substrate() { - Self { - eth: Default::default(), - sub: convert_cross_account_to_uint256::(cross_account_id), - } - } else { - Self { - eth: *cross_account_id.as_eth(), - sub: Default::default(), - } - } - } - - pub fn into_sub_cross_account(&self) -> crate::execution::Result - where - T: pallet_evm::Config, - T::AccountId: From<[u8; 32]>, - { - if self.eth == Default::default() && self.sub == Default::default() { - Err("All fields of cross account is zeroed".into()) - } else if self.eth == Default::default() { - Ok(convert_uint256_to_cross_account::(self.sub)) - } else if self.sub == Default::default() { - Ok(T::CrossAccountId::from_eth(self.eth)) - } else { - Err("All fields of cross account is non zeroed".into()) - } } - } - - /// Convert `CrossAccountId` to `uint256`. - pub fn convert_cross_account_to_uint256( - from: &T::CrossAccountId, - ) -> uint256 - where - T::AccountId: AsRef<[u8; 32]>, - { - let slice = from.as_sub().as_ref(); - uint256::from_big_endian(slice) - } - - /// Convert `uint256` to `CrossAccountId`. - pub fn convert_uint256_to_cross_account( - from: uint256, - ) -> T::CrossAccountId - where - T::AccountId: From<[u8; 32]>, - { - let mut new_admin_arr = [0_u8; 32]; - from.to_big_endian(&mut new_admin_arr); - let account_id = T::AccountId::from(new_admin_arr); - T::CrossAccountId::from_sub(account_id) } #[derive(Debug, Default)] --- a/crates/evm-coder/src/solidity.rs +++ b/crates/evm-coder/src/solidity.rs @@ -145,7 +145,7 @@ } } -mod sealed { +pub mod sealed { /// Not every type should be directly placed in vec. /// Vec encoding is not memory efficient, as every item will be padded /// to 32 bytes. @@ -156,7 +156,6 @@ impl sealed::CanBePlacedInVec for uint256 {} impl sealed::CanBePlacedInVec for string {} impl sealed::CanBePlacedInVec for address {} -impl sealed::CanBePlacedInVec for EthCrossAccount {} impl sealed::CanBePlacedInVec for Property {} impl SolidityTypeName for Vec { @@ -171,61 +170,6 @@ write!(writer, "new ")?; T::solidity_name(writer, tc)?; write!(writer, "[](0)") - } -} - -impl SolidityTupleType for EthCrossAccount { - fn names(tc: &TypeCollector) -> Vec { - let mut collected = Vec::with_capacity(Self::len()); - { - let mut out = string::new(); - address::solidity_name(&mut out, tc).expect("no fmt error"); - collected.push(out); - } - { - let mut out = string::new(); - uint256::solidity_name(&mut out, tc).expect("no fmt error"); - collected.push(out); - } - collected - } - - fn len() -> usize { - 2 - } -} - -impl SolidityTypeName for EthCrossAccount { - fn solidity_name(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result { - write!(writer, "{}", tc.collect_struct::()) - } - - fn is_simple() -> bool { - false - } - - fn solidity_default(writer: &mut impl fmt::Write, tc: &TypeCollector) -> fmt::Result { - write!(writer, "{}(", tc.collect_struct::())?; - address::solidity_default(writer, tc)?; - write!(writer, ",")?; - uint256::solidity_default(writer, tc)?; - write!(writer, ")") - } -} - -impl StructCollect for EthCrossAccount { - fn name() -> String { - "EthCrossAccount".into() - } - - fn declaration() -> String { - let mut str = String::new(); - writeln!(str, "/// @dev Cross account struct").unwrap(); - writeln!(str, "struct {} {{", Self::name()).unwrap(); - writeln!(str, "\taddress eth;").unwrap(); - writeln!(str, "\tuint256 sub;").unwrap(); - writeln!(str, "}}").unwrap(); - str } } --- a/pallets/common/src/erc.rs +++ b/pallets/common/src/erc.rs @@ -16,6 +16,7 @@ //! This module contains the implementation of pallet methods for evm. +pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId}; use evm_coder::{ abi::AbiType, solidity_interface, solidity, ToLog, @@ -24,7 +25,6 @@ execution::{Result, Error}, weight, }; -pub use pallet_evm::{PrecompileOutput, PrecompileResult, PrecompileHandle, account::CrossAccountId}; use pallet_evm_coder_substrate::dispatch_to_evm; use sp_std::vec::Vec; use up_data_structs::{ @@ -35,7 +35,8 @@ use crate::{ Pallet, CollectionHandle, Config, CollectionProperties, SelfWeightOf, - eth::convert_cross_account_to_uint256, weights::WeightInfo, + eth::{EthCrossAccount, convert_cross_account_to_uint256}, + weights::WeightInfo, }; /// Events for ethereum collection helper. --- a/pallets/common/src/eth.rs +++ b/pallets/common/src/eth.rs @@ -16,7 +16,10 @@ //! The module contains a number of functions for converting and checking ethereum identifiers. -use evm_coder::types::{uint256, address}; +use evm_coder::{ + AbiCoder, + types::{uint256, address}, +}; pub use pallet_evm::{Config, account::CrossAccountId}; use sp_core::H160; use up_data_structs::CollectionId; @@ -109,3 +112,111 @@ Err("All fields of cross account is non zeroed".into()) } } + +#[derive(Debug, Default, AbiCoder)] +pub struct EthCrossAccount { + pub(crate) eth: address, + pub(crate) sub: uint256, +} + +impl EthCrossAccount { + pub fn from_sub_cross_account(cross_account_id: &T::CrossAccountId) -> Self + where + T: pallet_evm::account::Config, + T::AccountId: AsRef<[u8; 32]>, + { + if cross_account_id.is_canonical_substrate() { + Self { + eth: Default::default(), + sub: convert_cross_account_to_uint256::(cross_account_id), + } + } else { + Self { + eth: *cross_account_id.as_eth(), + sub: Default::default(), + } + } + } + + pub fn into_sub_cross_account(&self) -> evm_coder::execution::Result + where + T: pallet_evm::account::Config, + T::AccountId: From<[u8; 32]>, + { + if self.eth == Default::default() && self.sub == Default::default() { + Err("All fields of cross account is zeroed".into()) + } else if self.eth == Default::default() { + Ok(convert_uint256_to_cross_account::(self.sub)) + } else if self.sub == Default::default() { + Ok(T::CrossAccountId::from_eth(self.eth)) + } else { + Err("All fields of cross account is non zeroed".into()) + } + } +} + +impl ::evm_coder::solidity::sealed::CanBePlacedInVec for EthCrossAccount {} +impl ::evm_coder::solidity::SolidityTupleType for EthCrossAccount { + fn names(tc: &::evm_coder::solidity::TypeCollector) -> Vec { + let mut collected = + Vec::with_capacity(::len()); + { + let mut out = String::new(); +
::solidity_name(&mut out, tc) + .expect("no fmt error"); + collected.push(out); + } + { + let mut out = String::new(); + ::solidity_name(&mut out, tc) + .expect("no fmt error"); + collected.push(out); + } + collected + } + + fn len() -> usize { + 2 + } +} +impl ::evm_coder::solidity::SolidityTypeName for EthCrossAccount { + fn solidity_name( + writer: &mut impl ::core::fmt::Write, + tc: &::evm_coder::solidity::TypeCollector, + ) -> ::core::fmt::Result { + write!(writer, "{}", tc.collect_struct::()) + } + + fn is_simple() -> bool { + false + } + + fn solidity_default( + writer: &mut impl ::core::fmt::Write, + tc: &::evm_coder::solidity::TypeCollector, + ) -> ::core::fmt::Result { + write!(writer, "{}(", tc.collect_struct::())?; + address::solidity_default(writer, tc)?; + write!(writer, ",")?; + uint256::solidity_default(writer, tc)?; + write!(writer, ")") + } +} + +impl ::evm_coder::solidity::StructCollect for EthCrossAccount { + fn name() -> String { + "EthCrossAccount".into() + } + + fn declaration() -> String { + use std::fmt::Write; + + let mut str = String::new(); + writeln!(str, "/// @dev Cross account struct").unwrap(); + writeln!(str, "struct {} {{", Self::name()).unwrap(); + writeln!(str, "\taddress eth;").unwrap(); + writeln!(str, "\tuint256 sub;").unwrap(); + writeln!(str, "}}").unwrap(); + str + } +} --- a/pallets/fungible/src/erc.rs +++ b/pallets/fungible/src/erc.rs @@ -24,12 +24,15 @@ weight, }; use up_data_structs::CollectionMode; -use pallet_common::erc::{CommonEvmHandler, PrecompileResult}; +use pallet_common::{ + CollectionHandle, + erc::{CommonEvmHandler, PrecompileResult, CollectionCall}, + eth::EthCrossAccount, +}; use sp_std::vec::Vec; use pallet_evm::{account::CrossAccountId, PrecompileHandle}; use pallet_evm_coder_substrate::{call, dispatch_to_evm}; use pallet_structure::{SelfWeightOf as StructureWeight, weights::WeightInfo as _}; -use pallet_common::{CollectionHandle, erc::CollectionCall}; use sp_core::Get; use crate::{ --- a/pallets/nonfungible/src/erc.rs +++ b/pallets/nonfungible/src/erc.rs @@ -36,8 +36,9 @@ use pallet_evm_coder_substrate::dispatch_to_evm; use sp_std::vec::Vec; use pallet_common::{ + CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations, erc::{CommonEvmHandler, PrecompileResult, CollectionCall, static_property::key}, - CollectionHandle, CollectionPropertyPermissions, CommonCollectionOperations, + eth::EthCrossAccount, }; use pallet_evm::{account::CrossAccountId, PrecompileHandle}; use pallet_evm_coder_substrate::call; --- a/pallets/refungible/src/erc.rs +++ b/pallets/refungible/src/erc.rs @@ -33,6 +33,7 @@ use pallet_common::{ CollectionHandle, CollectionPropertyPermissions, erc::{CommonEvmHandler, CollectionCall, static_property::key}, + eth::EthCrossAccount, CommonCollectionOperations, }; use pallet_evm::{account::CrossAccountId, PrecompileHandle}; -- gitstuff