From 4eba81a8c7973d1b83cf74924ec9dd54e53d663e Mon Sep 17 00:00:00 2001 From: Yaroslav Bolyukin Date: Mon, 30 May 2022 15:40:15 +0000 Subject: [PATCH] fix: evm nitpicks --- --- a/Cargo.lock +++ b/Cargo.lock @@ -4290,9 +4290,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -dependencies = [ - "spin", -] [[package]] name = "lazycell" @@ -5920,7 +5917,6 @@ "frame-benchmarking", "frame-support", "frame-system", - "lazy_static", "pallet-evm", "pallet-evm-coder-substrate", "parity-scale-codec 3.1.2", --- a/pallets/common/Cargo.toml +++ b/pallets/common/Cargo.toml @@ -27,7 +27,6 @@ scale-info = { version = "2.0.1", default-features = false, features = [ "derive", ] } -lazy_static = { version = "1.4.0", default-features = false, features = ["spin_no_std"] } [features] default = ["std"] --- a/pallets/common/src/erc.rs +++ b/pallets/common/src/erc.rs @@ -15,7 +15,7 @@ // along with Unique Network. If not, see . use evm_coder::{ - solidity_interface, + solidity_interface, solidity, types::*, execution::{Result, Error}, }; @@ -88,40 +88,64 @@ Ok(()) } - fn set_limit(&mut self, caller: caller, limit: string, value: string) -> Result { + #[solidity(rename_selector = "setLimit")] + fn set_int_limit(&mut self, caller: caller, limit: string, value: uint32) -> Result { check_is_owner(caller, self)?; let mut limits = self.limits.clone(); match limit.as_str() { "accountTokenOwnershipLimit" => { - limits.account_token_ownership_limit = parse_int(value)?; + limits.account_token_ownership_limit = Some(value); } "sponsoredDataSize" => { - limits.sponsored_data_size = parse_int(value)?; + limits.sponsored_data_size = Some(value); } "sponsoredDataRateLimit" => { - limits.sponsored_data_rate_limit = - Some(SponsoringRateLimit::Blocks(parse_int(value)?.unwrap())); + limits.sponsored_data_rate_limit = Some(SponsoringRateLimit::Blocks(value)); } "tokenLimit" => { - limits.token_limit = parse_int(value)?; + limits.token_limit = Some(value); } "sponsorTransferTimeout" => { - limits.sponsor_transfer_timeout = parse_int(value)?; + limits.sponsor_transfer_timeout = Some(value); } "sponsorApproveTimeout" => { - limits.sponsor_approve_timeout = parse_int(value)?; + limits.sponsor_approve_timeout = Some(value); } + _ => { + return Err(Error::Revert(format!( + "Unknown integer limit \"{}\"", + limit + ))) + } + } + self.limits = >::clamp_limits(self.mode.clone(), &self.limits, limits) + .map_err(dispatch_to_evm::)?; + save(self); + Ok(()) + } + + #[solidity(rename_selector = "setLimit")] + fn set_bool_limit(&mut self, caller: caller, limit: string, value: bool) -> Result { + check_is_owner(caller, self)?; + let mut limits = self.limits.clone(); + + match limit.as_str() { "ownerCanTransfer" => { - limits.owner_can_transfer = parse_bool(value)?; + limits.owner_can_transfer = Some(value); } "ownerCanDestroy" => { - limits.owner_can_destroy = parse_bool(value)?; + limits.owner_can_destroy = Some(value); } "transfersEnabled" => { - limits.transfers_enabled = parse_bool(value)?; + limits.transfers_enabled = Some(value); } - _ => return Err(Error::Revert(format!("Unknown limit \"{}\"", limit))), + _ => { + return Err(Error::Revert(format!( + "Unknown boolean limit \"{}\"", + limit + ))) + } } self.limits = >::clamp_limits(self.mode.clone(), &self.limits, limits) .map_err(dispatch_to_evm::)?; @@ -146,16 +170,9 @@ >::insert(collection.id, collection.collection.clone()); } -fn parse_int(value: string) -> Result> { - value - .parse::() - .map_err(|e| Error::Revert(format!("Int value \"{}\" parse error: {}", value, e))) - .map(|value| Some(value)) -} - -fn parse_bool(value: string) -> Result> { - value - .parse::() - .map_err(|e| Error::Revert(format!("Bool value \"{}\" parse error: {}", value, e))) - .map(|value| Some(value)) +pub fn token_uri_key() -> up_data_structs::PropertyKey { + b"tokenURI" + .to_vec() + .try_into() + .expect("length < limit; qed") } --- a/pallets/common/src/eth.rs +++ b/pallets/common/src/eth.rs @@ -17,14 +17,6 @@ use up_data_structs::CollectionId; use sp_core::H160; -lazy_static::lazy_static! { - pub static ref KEY_TOKEN_URI: up_data_structs::PropertyKey = { - let key: evm_coder::types::string = "tokenURI".into(); //TODO: make static - let key: up_data_structs::PropertyKey = key.into_bytes().try_into().expect("Can't create \"tokenURI\" key"); - key - }; -} - // 0x17c4e6453Cc49AAAaEACA894e6D9683e00000001 - collection 1 // TODO: Unhardcode prefix const ETH_COLLECTION_PREFIX: [u8; 16] = [ --- a/pallets/nonfungible/src/erc.rs +++ b/pallets/nonfungible/src/erc.rs @@ -22,14 +22,14 @@ use evm_coder::{ToLog, execution::*, generate_stubgen, solidity, solidity_interface, types::*, weight}; use frame_support::BoundedVec; use up_data_structs::{ - TokenId, SchemaVersion, PropertyPermission, PropertyKeyPermission, Property, CollectionId, - PropertyKey, CollectionPropertiesVec, + TokenId, PropertyPermission, PropertyKeyPermission, Property, CollectionId, PropertyKey, + CollectionPropertiesVec, }; use pallet_evm_coder_substrate::dispatch_to_evm; use sp_core::{H160, U256}; use sp_std::vec::Vec; use pallet_common::{ - erc::{CommonEvmHandler, PrecompileResult, CollectionCall}, + erc::{CommonEvmHandler, PrecompileResult, CollectionCall, token_uri_key}, CollectionHandle, CollectionPropertyPermissions, }; use pallet_evm::account::CrossAccountId; @@ -161,7 +161,7 @@ /// Returns token's const_metadata #[solidity(rename_selector = "tokenURI")] fn token_uri(&self, token_id: uint256) -> Result { - let key = pallet_common::eth::KEY_TOKEN_URI.clone(); + let key = token_uri_key(); if !has_token_permission::(self.id, &key) { return Err("No tokenURI permission".into()); } @@ -362,7 +362,7 @@ token_id: uint256, token_uri: string, ) -> Result { - let key = pallet_common::eth::KEY_TOKEN_URI.clone(); + let key = token_uri_key(); let permission = get_token_permission::(self.id, &key)?; if !permission.collection_admin { return Err("Operation is not allowed".into()); @@ -524,6 +524,7 @@ to: address, tokens: Vec<(uint256, string)>, ) -> Result { + let key = token_uri_key(); let caller = T::CrossAccountId::from_eth(caller); let to = T::CrossAccountId::from_eth(to); let mut expected_index = >::get(self.id) @@ -541,8 +542,19 @@ } expected_index = expected_index.checked_add(1).ok_or("item id overflow")?; + let mut properties = CollectionPropertiesVec::default(); + properties + .try_push(Property { + key: key.clone(), + value: token_uri + .into_bytes() + .try_into() + .map_err(|_| "token uri is too long")?, + }) + .map_err(|e| Error::Revert(alloc::format!("Can't add property: {:?}", e)))?; + data.push(CreateItemData:: { - properties: BoundedVec::default(), + properties, owner: to.clone(), }); } --- a/pallets/unique/src/eth/mod.rs +++ b/pallets/unique/src/eth/mod.rs @@ -15,29 +15,20 @@ // along with Unique Network. If not, see . use core::marker::PhantomData; -use evm_coder::{execution::*, generate_stubgen, solidity_interface, types::*, ToLog}; +use evm_coder::{execution::*, generate_stubgen, solidity_interface, weight, types::*}; use ethereum as _; use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder}; -use pallet_evm::{OnMethodCall, PrecompileResult, account::CrossAccountId, Pallet as PalletEvm}; +use pallet_evm::{OnMethodCall, PrecompileResult, account::CrossAccountId}; 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::CollectionById; +use pallet_common::{CollectionById, erc::token_uri_key}; +use crate::{SelfWeightOf, Config, weights::WeightInfo}; use sp_std::vec::Vec; use alloc::format; - -pub trait Config: - frame_system::Config - + pallet_evm_coder_substrate::Config - + pallet_evm::account::Config - + pallet_nonfungible::Config -{ - type ContractAddress: Get; -} struct EvmCollectionHelper(SubstrateRecorder); impl WithRecorder for EvmCollectionHelper { @@ -51,8 +42,9 @@ } #[solidity_interface(name = "CollectionHelper")] -impl EvmCollectionHelper { - fn create_721_collection( +impl EvmCollectionHelper { + #[weight(>::create_collection())] + fn create_nonfungible_collection( &self, caller: caller, name: string, @@ -77,7 +69,7 @@ .try_into() .map_err(|_| error_feild_too_long(stringify!(token_prefix), MAX_TOKEN_PREFIX_LENGTH))?; - let key = pallet_common::eth::KEY_TOKEN_URI.clone(); + let key = token_uri_key(); let permission = up_data_structs::PropertyPermission { mutable: true, collection_admin: true, @@ -102,13 +94,6 @@ .map_err(pallet_evm_coder_substrate::dispatch_to_evm::)?; let address = pallet_common::eth::collection_id_to_address(collection_id); - >::deposit_log( - EthCollectionEvent::CollectionCreated { - owner: *caller.as_eth(), - collection_id: address, - } - .to_log(address), - ); Ok(address) } @@ -122,18 +107,8 @@ } } -#[derive(ToLog)] -pub enum EthCollectionEvent { - CollectionCreated { - #[indexed] - owner: address, - #[indexed] - collection_id: address, - }, -} - pub struct CollectionHelperOnMethodCall(PhantomData<*const T>); -impl OnMethodCall for CollectionHelperOnMethodCall { +impl OnMethodCall for CollectionHelperOnMethodCall { fn is_reserved(contract: &sp_core::H160) -> bool { contract == &T::ContractAddress::get() } --- a/pallets/unique/src/lib.rs +++ b/pallets/unique/src/lib.rs @@ -30,17 +30,18 @@ ensure, weights::{Weight}, transactional, - pallet_prelude::{DispatchResultWithPostInfo, ConstU32}, + pallet_prelude::{DispatchResultWithPostInfo, ConstU32, Get}, BoundedVec, }; +use sp_core::H160; use scale_info::TypeInfo; use frame_system::{self as system, ensure_signed}; use sp_runtime::{sp_std::prelude::Vec}; use up_data_structs::{ MAX_COLLECTION_NAME_LENGTH, MAX_COLLECTION_DESCRIPTION_LENGTH, MAX_TOKEN_PREFIX_LENGTH, - AccessMode, CreateItemData, CollectionLimits, CollectionPermissions, CollectionId, - CollectionMode, TokenId, SponsorshipState, CreateCollectionData, CreateItemExData, budget, - Property, PropertyKey, PropertyKeyPermission, + CreateItemData, CollectionLimits, CollectionPermissions, CollectionId, CollectionMode, TokenId, + SponsorshipState, CreateCollectionData, CreateItemExData, budget, Property, PropertyKey, + PropertyKeyPermission, }; use pallet_evm::account::CrossAccountId; use pallet_common::{ @@ -74,6 +75,7 @@ /// Weight information for extrinsics in this pallet. type WeightInfo: WeightInfo; type CommonWeightInfo: CommonWeightInfo; + type ContractAddress: Get; } decl_event! { --- a/runtime/opal/src/lib.rs +++ b/runtime/opal/src/lib.rs @@ -917,6 +917,7 @@ type Event = Event; type WeightInfo = pallet_unique::weights::SubstrateWeight; type CommonWeightInfo = CommonWeights; + type ContractAddress = EvmCollectionHelperAddress; } parameter_types! { @@ -987,10 +988,6 @@ impl pallet_evm_contract_helpers::Config for Runtime { type ContractAddress = HelpersContractAddress; type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; -} - -impl pallet_unique::eth::Config for Runtime { - type ContractAddress = EvmCollectionHelperAddress; } construct_runtime!( --- a/runtime/quartz/src/lib.rs +++ b/runtime/quartz/src/lib.rs @@ -900,6 +900,7 @@ type Event = Event; type WeightInfo = pallet_unique::weights::SubstrateWeight; type CommonWeightInfo = CommonWeights; + type ContractAddress = EvmCollectionHelperAddress; } parameter_types! { @@ -970,10 +971,6 @@ impl pallet_evm_contract_helpers::Config for Runtime { type ContractAddress = HelpersContractAddress; type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; -} - -impl pallet_unique::eth::Config for Runtime { - type ContractAddress = EvmCollectionHelperAddress; } construct_runtime!( --- a/runtime/tests/src/lib.rs +++ b/runtime/tests/src/lib.rs @@ -16,7 +16,7 @@ #![allow(clippy::from_over_into)] -use sp_core::{H256, U256}; +use sp_core::{H160, H256, U256}; use frame_support::{ parameter_types, traits::{Everything, ConstU32, ConstU64}, @@ -245,10 +245,18 @@ type WeightInfo = (); } +parameter_types! { + // 0x6c4e9fe1ae37a41e93cee429e8e1881abdcbb54f + pub const EvmCollectionHelperAddress: H160 = H160([ + 0x6c, 0x4e, 0x9f, 0xe1, 0xae, 0x37, 0xa4, 0x1e, 0x93, 0xce, 0xe4, 0x29, 0xe8, 0xe1, 0x88, 0x1a, 0xbd, 0xcb, 0xb5, 0x4f, + ]); +} + impl pallet_unique::Config for Test { type Event = (); type WeightInfo = (); type CommonWeightInfo = CommonWeights; + type ContractAddress = EvmCollectionHelperAddress; } // Build genesis storage according to the mock runtime. --- a/runtime/unique/src/lib.rs +++ b/runtime/unique/src/lib.rs @@ -905,6 +905,7 @@ type Event = Event; type WeightInfo = pallet_unique::weights::SubstrateWeight; type CommonWeightInfo = CommonWeights; + type ContractAddress = EvmCollectionHelperAddress; } parameter_types! { @@ -975,10 +976,6 @@ impl pallet_evm_contract_helpers::Config for Runtime { type ContractAddress = HelpersContractAddress; type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit; -} - -impl pallet_unique::eth::Config for Runtime { - type ContractAddress = EvmCollectionHelperAddress; } construct_runtime!( -- gitstuff