difftreelog
Merge pull request #188 from UniqueNetwork/feature/evm-collection-calls
in: master
Test collection method calls from EVM
35 files changed
.maintain/scripts/compile_stub.shdiffbeforeafterbothno changes
.maintain/scripts/generate_api.shdiffbeforeafterbothno changes
Makefilediffbeforeafterboth1.PHONY: _eth_codegen2_eth_codegen:34.PHONY: regenerate_solidity5regenerate_solidity:6 PACKAGE=pallet-nft NAME=eth::erc::fungible_iface OUTPUT=./tests/src/eth/api/UniqueFungible.sol ./.maintain/scripts/generate_api.sh7 PACKAGE=pallet-nft NAME=eth::erc::nft_iface OUTPUT=./tests/src/eth/api/UniqueNFT.sol ./.maintain/scripts/generate_api.sh8 PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_iface OUTPUT=./tests/src/eth/api/ContractHelpers.sol ./.maintain/scripts/generate_api.sh910 PACKAGE=pallet-nft NAME=eth::erc::fungible_impl OUTPUT=./pallets/nft/src/eth/stubs/UniqueFungible.sol ./.maintain/scripts/generate_api.sh11 PACKAGE=pallet-nft NAME=eth::erc::nft_impl OUTPUT=./pallets/nft/src/eth/stubs/UniqueNFT.sol ./.maintain/scripts/generate_api.sh12 PACKAGE=pallet-evm-contract-helpers NAME=eth::contract_helpers_impl OUTPUT=./pallets/evm-contract-helpers/src/stubs/ContractHelpers.sol ./.maintain/scripts/generate_api.sh1314NFT_EVM_STUBS=./pallets/nft/src/eth/stubs15CONTRACT_HELPERS_STUBS=./pallets/evm-contract-helpers/src/stubs/1617$(NFT_EVM_STUBS)/UniqueFungible.raw: $(NFT_EVM_STUBS)/UniqueFungible.sol18 INPUT=$< OUTPUT=$@ ./.maintain/scripts/compile_stub.sh19$(NFT_EVM_STUBS)/UniqueNFT.raw: $(NFT_EVM_STUBS)/UniqueNFT.sol20 INPUT=$< OUTPUT=$@ ./.maintain/scripts/compile_stub.sh21$(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw: $(CONTRACT_HELPERS_STUBS)/ContractHelpers.sol22 INPUT=$< OUTPUT=$@ ./.maintain/scripts/compile_stub.sh2324evm_stubs: $(NFT_EVM_STUBS)/UniqueFungible.raw $(NFT_EVM_STUBS)/UniqueNFT.raw $(CONTRACT_HELPERS_STUBS)/ContractHelpers.raw251.PHONY: _bench26.PHONY: _bench2_bench:27_bench:crates/evm-coder-macros/src/to_log.rsdiffbeforeafterboth34 fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {34 fn expand_solidity_argument(&self) -> proc_macro2::TokenStream {35 let camel_name = &self.camel_name;35 let camel_name = &self.camel_name;36 let ty = &self.ty;36 let ty = &self.ty;37 let indexed = self.indexed;37 quote! {38 quote! {38 <NamedArgument<#ty>>::new(#camel_name)39 <SolidityEventArgument<#ty>>::new(#indexed, #camel_name)39 }40 }40 }41 }41}42}crates/evm-coder/src/lib.rsdiffbeforeafterboth61 fn call(&mut self, call: types::Msg<C>) -> execution::Result<AbiWriter>;61 fn call(&mut self, call: types::Msg<C>) -> execution::Result<AbiWriter>;62}62}6364#[macro_export]65macro_rules! generate_stubgen {66 ($name:ident, $decl:ident, $is_impl:literal) => {67 #[test]68 #[ignore]69 fn $name() {70 use sp_std::collections::btree_set::BTreeSet;71 let mut out = BTreeSet::new();72 $decl::generate_solidity_interface(&mut out, $is_impl);73 println!("=== SNIP START ===");74 println!("// SPDX-License-Identifier: OTHER");75 println!("// This code is automatically generated");76 println!();77 println!("pragma solidity >=0.8.0 <0.9.0;");78 println!();79 for b in out {80 println!("{}", b);81 }82 println!("=== SNIP END ===");83 }84 };85}638664#[cfg(test)]87#[cfg(test)]65mod tests {88mod tests {crates/evm-coder/src/solidity.rsdiffbeforeafterboth117 }117 }118}118}119120pub struct SolidityEventArgument<T>(pub bool, &'static str, PhantomData<*const T>);121122impl<T> SolidityEventArgument<T> {123 pub fn new(indexed: bool, name: &'static str) -> Self {124 Self(indexed, name, Default::default())125 }126}127128impl<T: SolidityTypeName> SolidityArguments for SolidityEventArgument<T> {129 fn solidity_name(&self, writer: &mut impl fmt::Write) -> fmt::Result {130 if !T::is_void() {131 T::solidity_name(writer)?;132 if self.0 {133 write!(writer, " indexed")?;134 }135 write!(writer, " {}", self.1)136 } else {137 Ok(())138 }139 }140 fn solidity_get(&self, writer: &mut impl fmt::Write) -> fmt::Result {141 writeln!(writer, "\t\t{};", self.1)142 }143 fn solidity_default(&self, writer: &mut impl fmt::Write) -> fmt::Result {144 T::solidity_default(writer)145 }146 fn len(&self) -> usize {147 if T::is_void() {148 0149 } else {150 1151 }152 }153}119154120impl SolidityArguments for () {155impl SolidityArguments for () {121 fn solidity_name(&self, _writer: &mut impl fmt::Write) -> fmt::Result {156 fn solidity_name(&self, _writer: &mut impl fmt::Write) -> fmt::Result {pallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth1use core::marker::PhantomData;1use core::marker::PhantomData;2use evm_coder::{abi::AbiWriter, execution::Result, solidity_interface, types::*};2use evm_coder::{abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*};3use pallet_evm_coder_substrate::SubstrateRecorder;3use pallet_evm_coder_substrate::SubstrateRecorder;4use pallet_evm::{ExitReason, ExitRevert, OnCreate, OnMethodCall, PrecompileOutput};4use pallet_evm::{ExitReason, ExitRevert, OnCreate, OnMethodCall, PrecompileOutput};5use sp_core::H160;5use sp_core::H160;141415#[solidity_interface(name = "ContractHelpers")]15#[solidity_interface(name = "ContractHelpers")]16impl<T: Config> ContractHelpers<T> {16impl<T: Config> ContractHelpers<T> {17 fn contract_owner(&self, contract: address) -> Result<address> {17 fn contract_owner(&self, contract_address: address) -> Result<address> {18 self.0.consume_sload()?;18 self.0.consume_sload()?;19 Ok(<Owner<T>>::get(contract))19 Ok(<Owner<T>>::get(contract_address))20 }20 }212122 fn sponsoring_enabled(&self, contract: address) -> Result<bool> {22 fn sponsoring_enabled(&self, contract_address: address) -> Result<bool> {23 self.0.consume_sload()?;23 self.0.consume_sload()?;24 Ok(<SelfSponsoring<T>>::get(contract))24 Ok(<SelfSponsoring<T>>::get(contract_address))25 }25 }262627 fn toggle_sponsoring(27 fn toggle_sponsoring(28 &mut self,28 &mut self,29 caller: caller,29 caller: caller,30 contract: address,30 contract_address: address,31 enabled: bool,31 enabled: bool,32 ) -> Result<void> {32 ) -> Result<void> {33 self.0.consume_sload()?;33 self.0.consume_sload()?;34 <Pallet<T>>::ensure_owner(contract, caller)?;34 <Pallet<T>>::ensure_owner(contract_address, caller)?;35 self.0.consume_sstore()?;35 self.0.consume_sstore()?;36 <Pallet<T>>::toggle_sponsoring(contract, enabled);36 <Pallet<T>>::toggle_sponsoring(contract_address, enabled);37 Ok(())37 Ok(())38 }38 }393940 fn set_sponsoring_rate_limit(40 fn set_sponsoring_rate_limit(41 &mut self,41 &mut self,42 caller: caller,42 caller: caller,43 contract: address,43 contract_address: address,44 rate_limit: uint32,44 rate_limit: uint32,45 ) -> Result<void> {45 ) -> Result<void> {46 self.0.consume_sload()?;46 self.0.consume_sload()?;47 <Pallet<T>>::ensure_owner(contract, caller)?;47 <Pallet<T>>::ensure_owner(contract_address, caller)?;48 self.0.consume_sstore()?;48 self.0.consume_sstore()?;49 <Pallet<T>>::set_sponsoring_rate_limit(contract, rate_limit.into());49 <Pallet<T>>::set_sponsoring_rate_limit(contract_address, rate_limit.into());50 Ok(())50 Ok(())51 }51 }525253 fn allowed(&self, contract: address, user: address) -> Result<bool> {53 fn allowed(&self, contract_address: address, user: address) -> Result<bool> {54 self.0.consume_sload()?;54 self.0.consume_sload()?;55 Ok(<Pallet<T>>::allowed(contract, user, true))55 Ok(<Pallet<T>>::allowed(contract_address, user, true))56 }56 }575758 fn allowlist_enabled(&self, contract: address) -> Result<bool> {58 fn allowlist_enabled(&self, contract_address: address) -> Result<bool> {59 self.0.consume_sload()?;59 self.0.consume_sload()?;60 Ok(<AllowlistEnabled<T>>::get(contract))60 Ok(<AllowlistEnabled<T>>::get(contract_address))61 }61 }626263 fn toggle_allowlist(63 fn toggle_allowlist(64 &mut self,64 &mut self,65 caller: caller,65 caller: caller,66 contract: address,66 contract_address: address,67 enabled: bool,67 enabled: bool,68 ) -> Result<void> {68 ) -> Result<void> {69 self.0.consume_sload()?;69 self.0.consume_sload()?;70 <Pallet<T>>::ensure_owner(contract, caller)?;70 <Pallet<T>>::ensure_owner(contract_address, caller)?;71 self.0.consume_sstore()?;71 self.0.consume_sstore()?;72 <Pallet<T>>::toggle_allowlist(contract, enabled);72 <Pallet<T>>::toggle_allowlist(contract_address, enabled);73 Ok(())73 Ok(())74 }74 }757576 fn toggle_allowed(76 fn toggle_allowed(77 &mut self,77 &mut self,78 caller: caller,78 caller: caller,79 contract: address,79 contract_address: address,80 user: address,80 user: address,81 allowed: bool,81 allowed: bool,82 ) -> Result<void> {82 ) -> Result<void> {83 self.0.consume_sload()?;83 self.0.consume_sload()?;84 <Pallet<T>>::ensure_owner(contract, caller)?;84 <Pallet<T>>::ensure_owner(contract_address, caller)?;85 self.0.consume_sstore()?;85 self.0.consume_sstore()?;86 <Pallet<T>>::toggle_allowed(contract, user, allowed);86 <Pallet<T>>::toggle_allowed(contract_address, user, allowed);87 Ok(())87 Ok(())88 }88 }89}89}130130131 fn get_code(contract: &sp_core::H160) -> Option<Vec<u8>> {131 fn get_code(contract: &sp_core::H160) -> Option<Vec<u8>> {132 (contract == &T::ContractAddress::get())132 (contract == &T::ContractAddress::get())133 .then(|| include_bytes!("./stubs/ContractHelpers.bin").to_vec())133 .then(|| include_bytes!("./stubs/ContractHelpers.raw").to_vec())134 }134 }135}135}136136163 }163 }164}164}165166generate_stubgen!(contract_helpers_impl, ContractHelpersCall, true);167generate_stubgen!(contract_helpers_iface, ContractHelpersCall, false);165168pallets/evm-contract-helpers/src/stubs/ContractHelpers.bindiffbeforeafterbothbinary blob — no preview
pallets/evm-contract-helpers/src/stubs/ContractHelpers.rawdiffbeforeafterbothbinary blob — no preview
pallets/evm-contract-helpers/src/stubs/ContractHelpers.soldiffbeforeafterboth1// SPDX-License-Identifier: OTHER2// This code is automatically generated34pragma solidity >=0.8.0 <0.9.0;56// Common stubs holder7contract Dummy {8 uint8 dummy;9 string stub_error = "this contract is implemented in native";10}111contract ContractHelpers {12contract ContractHelpers is Dummy {2 uint8 _dummmy = 0;3 address _dummy_addr = 0x0000000000000000000000000000000000000000;4 string stub_error = "this contract does not exists, contract helpers are implemented on substrate chain side";56 function contractOwner(address contract_address) public view returns (address) {13 function contractOwner(address contractAddress)14 public15 view16 returns (address)17 {7 require(false, stub_error);18 require(false, stub_error);8 contract_address;19 contractAddress;20 dummy;9 return _dummy_addr;21 return 0x0000000000000000000000000000000000000000;10 }22 }11 2312 function sponsoringEnabled(address contract_address) public view returns (bool) {24 function sponsoringEnabled(address contractAddress)25 public26 view27 returns (bool)28 {13 require(false, stub_error);29 require(false, stub_error);14 contract_address;30 contractAddress;15 _dummmy;31 dummy;16 return false;32 return false;17 }33 }18 3419 function toggleSponsoring(address contract_address, bool enabled) public {35 function toggleSponsoring(address contractAddress, bool enabled) public {20 require(false, stub_error);36 require(false, stub_error);21 contract_address;37 contractAddress;22 enabled;38 enabled;23 _dummmy = 0;39 dummy = 0;24 }40 }25 4142 function setSponsoringRateLimit(address contractAddress, uint32 rateLimit)43 public44 {45 require(false, stub_error);46 contractAddress;47 rateLimit;48 dummy = 0;49 }5051 function allowed(address contractAddress, address user)52 public53 view54 returns (bool)55 {56 require(false, stub_error);57 contractAddress;58 user;59 dummy;60 return false;61 }6263 function allowlistEnabled(address contractAddress)64 public65 view66 returns (bool)67 {68 require(false, stub_error);69 contractAddress;70 dummy;71 return false;72 }7326 function toggleAllowlist(address contract_address, bool enabled) public {74 function toggleAllowlist(address contractAddress, bool enabled) public {27 require(false, stub_error);75 require(false, stub_error);28 contract_address;76 contractAddress;29 enabled;77 enabled;30 _dummmy = 0;78 dummy = 0;31 }79 }32 8033 function toggleAllowed(address contract_address, address user, bool allowed) public {81 function toggleAllowed(82 address contractAddress,83 address user,84 bool allowed85 ) public {34 require(false, stub_error);86 require(false, stub_error);35 contract_address;87 contractAddress;36 user;88 user;37 allowed;89 allowed;38 _dummmy = 0;90 dummy = 0;39 }91 }40}92}93pallets/nft/src/eth/erc.rsdiffbeforeafterboth1use core::char::{decode_utf16, REPLACEMENT_CHARACTER};1use core::char::{decode_utf16, REPLACEMENT_CHARACTER};2use evm_coder::{ToLog, execution::Result, solidity, solidity_interface, types::*};2use evm_coder::{ToLog, execution::Result, generate_stubgen, solidity, solidity_interface, types::*};3use nft_data_structs::{CreateItemData, CreateNftData};3use nft_data_structs::{CreateItemData, CreateNftData};4use core::convert::TryInto;4use core::convert::TryInto;5use crate::{5use crate::{403#[solidity_interface(name = "UniqueFungible", is(ERC165, ERC20))]403#[solidity_interface(name = "UniqueFungible", is(ERC165, ERC20))]404impl<T: Config> CollectionHandle<T> {}404impl<T: Config> CollectionHandle<T> {}405406macro_rules! generate_code {407 ($name:ident, $decl:ident, $is_impl:literal) => {408 #[test]409 #[ignore]410 fn $name() {411 use sp_std::collections::btree_set::BTreeSet;412 let mut out = BTreeSet::new();413 $decl::generate_solidity_interface(&mut out, $is_impl);414 println!("=== SNIP START ===");415 println!("// SPDX-License-Identifier: OTHER");416 println!("// This code is automatically generated with `cargo test --package pallet-nft -- eth::erc::{} --exact --nocapture --ignored`", stringify!(name));417 println!();418 println!("pragma solidity >=0.8.0 <0.9.0;");419 println!();420 for b in out {421 println!("{}", b);422 }423 println!("=== SNIP END ===");424 }425 };426}427405428// Not a tests, but code generators406// Not a tests, but code generators429generate_code!(nft_impl, UniqueNFTCall, true);407generate_stubgen!(nft_impl, UniqueNFTCall, true);430generate_code!(nft_iface, UniqueNFTCall, false);408generate_stubgen!(nft_iface, UniqueNFTCall, false);431409432generate_code!(fungible_impl, UniqueFungibleCall, true);410generate_stubgen!(fungible_impl, UniqueFungibleCall, true);433generate_code!(fungible_iface, UniqueFungibleCall, false);411generate_stubgen!(fungible_iface, UniqueFungibleCall, false);434412pallets/nft/src/eth/mod.rsdiffbeforeafterboth96 .and_then(<CollectionById<T>>::get)96 .and_then(<CollectionById<T>>::get)97 .map(|collection| {97 .map(|collection| {98 match collection.mode {98 match collection.mode {99 CollectionMode::NFT => include_bytes!("stubs/ERC721.bin") as &[u8],99 CollectionMode::NFT => include_bytes!("stubs/UniqueNFT.raw") as &[u8],100 CollectionMode::Fungible(_) => include_bytes!("stubs/ERC20.bin") as &[u8],100 CollectionMode::Fungible(_) => {101 include_bytes!("stubs/UniqueFungible.raw") as &[u8]102 }101 CollectionMode::ReFungible => include_bytes!("stubs/ERC1633.bin") as &[u8],103 CollectionMode::ReFungible => {104 include_bytes!("stubs/UniqueRefungible.raw") as &[u8]105 }102 CollectionMode::Invalid => include_bytes!("stubs/Invalid.bin") as &[u8],106 CollectionMode::Invalid => include_bytes!("stubs/UniqueInvalid.raw") as &[u8],103 }107 }104 .to_owned()108 .to_owned()105 })109 })pallets/nft/src/eth/stubs/ERC1633.bindiffbeforeafterbothno changes
pallets/nft/src/eth/stubs/ERC20.bindiffbeforeafterbothbinary blob — no preview
pallets/nft/src/eth/stubs/ERC20.soldiffbeforeafterbothno changes
pallets/nft/src/eth/stubs/ERC721.bindiffbeforeafterbothbinary blob — no preview
pallets/nft/src/eth/stubs/ERC721.soldiffbeforeafterbothno changes
pallets/nft/src/eth/stubs/Invalid.bindiffbeforeafterbothno changes
pallets/nft/src/eth/stubs/UniqueFungible.rawdiffbeforeafterbothbinary blob — no preview
pallets/nft/src/eth/stubs/UniqueFungible.soldiffbeforeafterbothno changes
pallets/nft/src/eth/stubs/UniqueInvalid.rawdiffbeforeafterbothno changes
pallets/nft/src/eth/stubs/UniqueNFT.rawdiffbeforeafterbothbinary blob — no preview
pallets/nft/src/eth/stubs/UniqueNFT.soldiffbeforeafterbothno changes
pallets/nft/src/eth/stubs/UniqueRefungible.rawdiffbeforeafterbothno changes
tests/src/eth/api/ContractHelpers.soldiffbeforeafterbothno changes
tests/src/eth/api/UniqueFungible.soldiffbeforeafterbothno changes
tests/src/eth/api/UniqueNFT.soldiffbeforeafterbothno changes
tests/src/eth/proxy/UniqueFungibleProxy.abidiffbeforeafterbothno changes
tests/src/eth/proxy/UniqueFungibleProxy.bindiffbeforeafterbothno changes
tests/src/eth/proxy/UniqueFungibleProxy.soldiffbeforeafterbothno changes
tests/src/eth/proxy/UniqueNFTProxy.abidiffbeforeafterbothno changes
tests/src/eth/proxy/UniqueNFTProxy.bindiffbeforeafterbothno changes
tests/src/eth/proxy/UniqueNFTProxy.soldiffbeforeafterbothno changes
tests/src/eth/proxy/fungibleProxy.test.tsdiffbeforeafterbothno changes
tests/src/eth/proxy/nonFungibleProxy.test.tsdiffbeforeafterbothno changes