--- a/pallets/common/src/erc.rs +++ b/pallets/common/src/erc.rs @@ -78,6 +78,8 @@ key: string, value: bytes, ) -> Result { + self.consume_store_reads_and_writes(1, 1)?; + let caller = T::CrossAccountId::from_eth(caller); let key = >::from(key) .try_into() @@ -92,6 +94,8 @@ /// /// @param key Property key. fn delete_collection_property(&mut self, caller: caller, key: string) -> Result<()> { + self.consume_store_reads_and_writes(1, 1)?; + let caller = T::CrossAccountId::from_eth(caller); let key = >::from(key) .try_into() @@ -123,6 +127,8 @@ /// /// @param sponsor Address of the sponsor from whose account funds will be debited for operations with the contract. fn set_collection_sponsor(&mut self, caller: caller, sponsor: address) -> Result { + self.consume_store_reads_and_writes(1, 1)?; + check_is_owner_or_admin(caller, self)?; let sponsor = T::CrossAccountId::from_eth(sponsor); @@ -141,6 +147,8 @@ caller: caller, sponsor: uint256, ) -> Result { + self.consume_store_reads_and_writes(1, 1)?; + check_is_owner_or_admin(caller, self)?; let sponsor = convert_uint256_to_cross_account::(sponsor); @@ -161,6 +169,8 @@ /// /// @dev After setting the sponsor for the collection, it must be confirmed with this function. fn confirm_collection_sponsorship(&mut self, caller: caller) -> Result { + self.consume_store_writes(1)?; + let caller = T::CrossAccountId::from_eth(caller); if !self .confirm_sponsorship(caller.as_sub()) @@ -173,6 +183,7 @@ /// Remove collection sponsor. fn remove_collection_sponsor(&mut self, caller: caller) -> Result { + self.consume_store_reads_and_writes(1, 1)?; check_is_owner_or_admin(caller, self)?; self.remove_sponsor().map_err(dispatch_to_evm::)?; save(self) @@ -209,6 +220,8 @@ /// @param value Value of the limit. #[solidity(rename_selector = "setCollectionLimit")] fn set_int_limit(&mut self, caller: caller, limit: string, value: uint32) -> Result { + self.consume_store_reads_and_writes(1, 1)?; + check_is_owner_or_admin(caller, self)?; let mut limits = self.limits.clone(); @@ -252,6 +265,8 @@ /// @param value Value of the limit. #[solidity(rename_selector = "setCollectionLimit")] fn set_bool_limit(&mut self, caller: caller, limit: string, value: bool) -> Result { + self.consume_store_reads_and_writes(1, 1)?; + check_is_owner_or_admin(caller, self)?; let mut limits = self.limits.clone(); @@ -289,6 +304,8 @@ caller: caller, new_admin: uint256, ) -> Result { + self.consume_store_writes(2)?; + let caller = T::CrossAccountId::from_eth(caller); let new_admin = convert_uint256_to_cross_account::(new_admin); >::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::)?; @@ -302,6 +319,8 @@ caller: caller, admin: uint256, ) -> Result { + self.consume_store_writes(2)?; + let caller = T::CrossAccountId::from_eth(caller); let admin = convert_uint256_to_cross_account::(admin); >::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::)?; @@ -311,6 +330,8 @@ /// Add collection admin. /// @param newAdmin Address of the added administrator. fn add_collection_admin(&mut self, caller: caller, new_admin: address) -> Result { + self.consume_store_writes(2)?; + let caller = T::CrossAccountId::from_eth(caller); let new_admin = T::CrossAccountId::from_eth(new_admin); >::toggle_admin(self, &caller, &new_admin, true).map_err(dispatch_to_evm::)?; @@ -321,6 +342,8 @@ /// /// @param admin Address of the removed administrator. fn remove_collection_admin(&mut self, caller: caller, admin: address) -> Result { + self.consume_store_writes(2)?; + let caller = T::CrossAccountId::from_eth(caller); let admin = T::CrossAccountId::from_eth(admin); >::toggle_admin(self, &caller, &admin, false).map_err(dispatch_to_evm::)?; @@ -332,6 +355,8 @@ /// @param enable If "true" degenerates to nesting: 'Owner' else to nesting: 'Disabled' #[solidity(rename_selector = "setCollectionNesting")] fn set_nesting_bool(&mut self, caller: caller, enable: bool) -> Result { + self.consume_store_reads_and_writes(1, 1)?; + check_is_owner_or_admin(caller, self)?; let mut permissions = self.collection.permissions.clone(); @@ -361,6 +386,8 @@ enable: bool, collections: Vec
, ) -> Result { + self.consume_store_reads_and_writes(1, 1)?; + if collections.is_empty() { return Err("no addresses provided".into()); } @@ -404,6 +431,8 @@ /// 0 for Normal /// 1 for AllowList fn set_collection_access(&mut self, caller: caller, mode: uint8) -> Result { + self.consume_store_reads_and_writes(1, 1)?; + check_is_owner_or_admin(caller, self)?; let permissions = CollectionPermissions { access: Some(match mode { @@ -437,6 +466,8 @@ /// /// @param user Address of a trusted user. fn add_to_collection_allow_list(&mut self, caller: caller, user: address) -> Result { + self.consume_store_writes(1)?; + let caller = T::CrossAccountId::from_eth(caller); let user = T::CrossAccountId::from_eth(user); >::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::)?; @@ -451,6 +482,8 @@ caller: caller, user: uint256, ) -> Result { + self.consume_store_writes(1)?; + let caller = T::CrossAccountId::from_eth(caller); let user = convert_uint256_to_cross_account::(user); Pallet::::toggle_allowlist(self, &caller, &user, true).map_err(dispatch_to_evm::)?; @@ -461,6 +494,8 @@ /// /// @param user Address of a removed user. fn remove_from_collection_allow_list(&mut self, caller: caller, user: address) -> Result { + self.consume_store_writes(1)?; + let caller = T::CrossAccountId::from_eth(caller); let user = T::CrossAccountId::from_eth(user); >::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::)?; @@ -475,6 +510,8 @@ caller: caller, user: uint256, ) -> Result { + self.consume_store_writes(1)?; + let caller = T::CrossAccountId::from_eth(caller); let user = convert_uint256_to_cross_account::(user); Pallet::::toggle_allowlist(self, &caller, &user, false).map_err(dispatch_to_evm::)?; @@ -485,6 +522,8 @@ /// /// @param mode Enable if "true". fn set_collection_mint_mode(&mut self, caller: caller, mode: bool) -> Result { + self.consume_store_reads_and_writes(1, 1)?; + check_is_owner_or_admin(caller, self)?; let permissions = CollectionPermissions { mint_mode: Some(mode), @@ -546,6 +585,8 @@ /// @dev Owner can be changed only by current owner /// @param newOwner new owner account fn set_owner(&mut self, caller: caller, new_owner: address) -> Result { + self.consume_store_writes(1)?; + let caller = T::CrossAccountId::from_eth(caller); let new_owner = T::CrossAccountId::from_eth(new_owner); self.set_owner_internal(caller, new_owner) @@ -557,6 +598,8 @@ /// @dev Owner can be changed only by current owner /// @param newOwner new owner substrate account fn set_owner_substrate(&mut self, caller: caller, new_owner: uint256) -> Result { + self.consume_store_writes(1)?; + let caller = T::CrossAccountId::from_eth(caller); let new_owner = convert_uint256_to_cross_account::(new_owner); self.set_owner_internal(caller, new_owner) @@ -572,6 +615,8 @@ // } } +/// ### Note +/// Do not forget to add: `self.consume_store_reads(1)?;` fn check_is_owner_or_admin( caller: caller, collection: &CollectionHandle, @@ -583,9 +628,9 @@ Ok(caller) } +/// ### Note +/// Do not forget to add: `self.consume_store_writes(1)?;` fn save(collection: &CollectionHandle) -> Result { - // TODO possibly delete for the lack of transaction - collection.consume_store_writes(1)?; collection .check_is_internal() .map_err(dispatch_to_evm::)?; --- a/pallets/common/src/lib.rs +++ b/pallets/common/src/lib.rs @@ -112,7 +112,6 @@ RmrkBoundedTheme, RmrkNftChild, CollectionPermissions, - SchemaVersion, }; pub use pallet::*; @@ -202,6 +201,21 @@ )) } + /// Consume gas for reading and writing. + pub fn consume_store_reads_and_writes( + &self, + reads: u64, + writes: u64, + ) -> evm_coder::execution::Result<()> { + let weight = ::DbWeight::get(); + let reads = weight.read.saturating_mul(reads); + let writes = weight.read.saturating_mul(writes); + self.recorder + .consume_gas(T::GasWeightMapping::weight_to_gas( + reads.saturating_add(writes), + )) + } + /// Save collection to storage. pub fn save(&self) -> DispatchResult { >::insert(self.id, &self.collection); @@ -310,6 +324,8 @@ } /// Changes collection owner to another account + /// #### Store read/writes + /// 1 writes fn set_owner_internal( &mut self, caller: T::CrossAccountId, @@ -1292,6 +1308,8 @@ } /// Toggle `user` participation in the `collection`'s allow list. + /// #### Store read/writes + /// 1 writes pub fn toggle_allowlist( collection: &CollectionHandle, sender: &T::CrossAccountId, @@ -1312,6 +1330,8 @@ } /// Toggle `user` participation in the `collection`'s admin list. + /// #### Store read/writes + /// 2 writes pub fn toggle_admin( collection: &CollectionHandle, sender: &T::CrossAccountId,