From c396bdd22f0e3080cb0b3e66780ff7e7e253ad15 Mon Sep 17 00:00:00 2001 From: Trubnikov Sergey Date: Tue, 02 Aug 2022 14:13:47 +0000 Subject: [PATCH] refactor: Chage Owner storage value type H160 -> CrossAccountId BREAKING CHANGE: changed `fn allowed` signature --- --- a/pallets/evm-contract-helpers/src/eth.rs +++ b/pallets/evm-contract-helpers/src/eth.rs @@ -15,8 +15,13 @@ // along with Unique Network. If not, see . use core::marker::PhantomData; -use evm_coder::{abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*}; -use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder}; +use evm_coder::{ + abi::AbiWriter, + execution::{Result, Error}, + generate_stubgen, solidity_interface, + types::*, +}; +use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder, dispatch_to_evm}; use pallet_evm::{ ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle, account::CrossAccountId, @@ -43,7 +48,10 @@ #[solidity_interface(name = "ContractHelpers")] impl ContractHelpers { fn contract_owner(&self, contract_address: address) -> Result
{ - Ok(>::get(contract_address)) + Ok(>::contract_owner(contract_address) + .map_err(dispatch_to_evm::)? + .as_eth() + .clone()) } fn sponsoring_enabled(&self, contract_address: address) -> Result { @@ -97,7 +105,7 @@ fn allowed(&self, contract_address: address, user: address) -> Result { self.0.consume_sload()?; - Ok(>::allowed(contract_address, user)) + Ok(>::allowed(contract_address, T::CrossAccountId::from_eth(user))) } fn allowlist_enabled(&self, contract_address: address) -> Result { @@ -141,7 +149,7 @@ fn call(handle: &mut impl PrecompileHandle) -> Option { // TODO: Extract to another OnMethodCall handler if >::get(handle.code_address()) - && !>::allowed(handle.code_address(), handle.context().caller) + && !>::allowed(handle.code_address(), T::CrossAccountId::from_eth(handle.context().caller)) { return Some(Err(PrecompileFailure::Revert { exit_status: ExitRevert::Reverted, @@ -170,7 +178,7 @@ pub struct HelpersOnCreate(PhantomData<*const T>); impl OnCreate for HelpersOnCreate { fn on_create(owner: H160, contract: H160) { - >::insert(contract, owner); + >::insert(contract, T::CrossAccountId::from_eth(owner)); } } @@ -184,7 +192,7 @@ return None; } - if mode == SponsoringModeT::Allowlisted && !>::allowed(call.0, *who.as_eth()) { + if mode == SponsoringModeT::Allowlisted && !>::allowed(call.0, who.clone()) { return None; } let block_number = >::block_number() as T::BlockNumber; --- a/pallets/evm-contract-helpers/src/lib.rs +++ b/pallets/evm-contract-helpers/src/lib.rs @@ -15,6 +15,7 @@ // along with Unique Network. If not, see . #![cfg_attr(not(feature = "std"), no_std)] +#![feature(is_some_with)] use codec::{Decode, Encode, MaxEncodedLen}; pub use pallet::*; @@ -25,9 +26,10 @@ #[frame_support::pallet] pub mod pallet { pub use super::*; - use evm_coder::execution::Result; use frame_support::pallet_prelude::*; use sp_core::H160; + use pallet_evm::account::CrossAccountId; + use frame_system::pallet_prelude::BlockNumberFor; #[pallet::config] pub trait Config: @@ -39,17 +41,31 @@ #[pallet::error] pub enum Error { - /// This method is only executable by owner + /// This method is only executable by owner. NoPermission, + + /// Contract has no owner. + NoContractOwner, } + const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); + /// Store owner for contract. + /// + /// * **Key** - contract address. + /// * **Value** - owner for contract. #[pallet::storage] - pub(super) type Owner = - StorageMap; + pub(super) type Owner = StorageMap< + Hasher = Twox128, + Key = H160, + Value = T::CrossAccountId, + QueryKind = OptionQuery, + >; #[pallet::storage] #[deprecated] @@ -57,10 +73,12 @@ StorageMap; #[pallet::storage] + #[deprecated] pub(super) type SponsoringMode = StorageMap; #[pallet::storage] + #[deprecated] pub(super) type SponsoringRateLimit = StorageMap< Hasher = Twox128, Key = H160, @@ -70,6 +88,7 @@ >; #[pallet::storage] + #[deprecated] pub(super) type SponsorBasket = StorageDoubleMap< Hasher1 = Twox128, Key1 = H160, @@ -80,10 +99,12 @@ >; #[pallet::storage] + #[deprecated] pub(super) type AllowlistEnabled = StorageMap; #[pallet::storage] + #[deprecated] pub(super) type Allowlist = StorageDoubleMap< Hasher1 = Twox128, Key1 = H160, @@ -93,6 +114,18 @@ QueryKind = ValueQuery, >; + #[pallet::hooks] + impl Hooks> for Pallet { + fn on_runtime_upgrade() -> Weight { + let storage_version = StorageVersion::get::>(); + if storage_version < StorageVersion::new(1) { + >::translate_values::(|address| Some(T::CrossAccountId::from_eth(address))); + } + + 0 + } + } + impl Pallet { pub fn sponsoring_mode(contract: H160) -> SponsoringModeT { >::get(contract) @@ -125,8 +158,9 @@ >::insert(contract, rate_limit); } - pub fn allowed(contract: H160, user: H160) -> bool { - >::get(&contract, &user) || >::get(&contract) == user + pub fn allowed(contract: H160, user: T::CrossAccountId) -> bool { + >::get(&contract, user.as_eth()) + || Pallet::::contract_owner(contract).is_ok_and(|owner| *owner == user) } pub fn toggle_allowlist(contract: H160, enabled: bool) { @@ -137,11 +171,17 @@ >::insert(contract, user, allowed); } - pub fn ensure_owner(contract: H160, user: H160) -> Result<()> { - ensure!(>::get(&contract) == user, "no permission"); + pub fn ensure_owner(contract: H160, user: H160) -> evm_coder::execution::Result<()> { + ensure!(Pallet::::contract_owner(contract).is_ok_and(|owner| *owner.as_eth() == user), "no permission"); Ok(()) } } + + impl Pallet { + pub fn contract_owner(contract: H160) -> Result { + Ok(>::get(contract).ok_or::>(Error::NoContractOwner)?) + } + } } #[derive(Encode, Decode, PartialEq, TypeInfo, MaxEncodedLen)] -- gitstuff