From f96d4840cdf2d7b31b8beecd446e4e7ed56fab46 Mon Sep 17 00:00:00 2001 From: Trubnikov Sergey Date: Wed, 03 Aug 2022 15:48:32 +0000 Subject: [PATCH] path: Add sponsorship for CrossAccountId. --- --- a/pallets/evm-contract-helpers/src/eth.rs +++ b/pallets/evm-contract-helpers/src/eth.rs @@ -51,6 +51,33 @@ Ok(>::get(contract_address)) } + fn set_sponsor( + &mut self, + caller: caller, + contract_address: address, + sponsor: address, + ) -> Result { + Pallet::::set_sponsor( + &T::CrossAccountId::from_eth(caller), + contract_address, + &T::CrossAccountId::from_eth(sponsor), + ) + .map_err(dispatch_to_evm::)?; + Ok(()) + } + + fn confirm_sponsorship(&mut self, caller: caller, contract_address: address) -> Result { + Pallet::::confirm_sponsorship(&T::CrossAccountId::from_eth(caller), contract_address) + .map_err(dispatch_to_evm::)?; + Ok(()) + } + + fn get_sponsor(&self, contract_address: address) -> Result
{ + let sponsor = + Pallet::::get_sponsor(contract_address).ok_or("Contract has no sponsor")?; + Ok(*sponsor.as_eth()) + } + fn sponsoring_enabled(&self, contract_address: address) -> Result { Ok(>::sponsoring_mode(contract_address) != SponsoringModeT::Disabled) } @@ -190,6 +217,11 @@ return None; } + let sponsor = match >::get_sponsor(*contract) { + Some(sponsor) => sponsor, + None => return None, + }; + if mode == SponsoringModeT::Allowlisted && !>::allowed(*contract, *who.as_eth()) { return None; } @@ -206,7 +238,6 @@ >::insert(contract, who.as_eth(), block_number); - let sponsor = T::CrossAccountId::from_eth(*contract); Some(sponsor) } } --- a/pallets/evm-contract-helpers/src/lib.rs +++ b/pallets/evm-contract-helpers/src/lib.rs @@ -15,7 +15,6 @@ // 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::*; @@ -27,9 +26,11 @@ pub mod pallet { pub use super::*; use frame_support::pallet_prelude::*; + use pallet_evm_coder_substrate::DispatchResult; use sp_core::H160; use pallet_evm::account::CrossAccountId; use frame_system::pallet_prelude::BlockNumberFor; + use up_data_structs::SponsorshipState; #[pallet::config] pub trait Config: @@ -44,8 +45,8 @@ /// This method is only executable by owner. NoPermission, - /// Contract has no owner. - NoContractOwner, + /// No pending sponsor for contract. + NoPendingSponsor, } const STORAGE_VERSION: StorageVersion = StorageVersion::new(1); @@ -68,11 +69,19 @@ pub(super) type SelfSponsoring = StorageMap; + #[pallet::storage] + pub(super) type Sponsoring = StorageMap< + Hasher = Twox128, + Key = H160, + Value = SponsorshipState, + QueryKind = ValueQuery, + >; + /// Store for sponsoring mode. - /// + /// /// ### Usage /// Prefer to delete collection from storage if mode chaged to [`Disabled`](SponsoringModeT::Disabled). - /// + /// /// * **Key** - contract address. /// * **Value** - [`sponsoring mode`](SponsoringModeT). #[pallet::storage] @@ -80,7 +89,7 @@ StorageMap; /// Storage for sponsoring rate limit in blocks. - /// + /// /// * **Key** - contract address. /// * **Value** - amount of sponsored blocks. #[pallet::storage] @@ -103,16 +112,24 @@ >; /// Storege for contracts with [`Allowlisted`](SponsoringModeT::Allowlisted) sponsoring mode. - /// + /// /// ### Usage /// Prefer to delete collection from storage if mode chaged to non `Allowlisted`, than set **Value** to **false**. - /// + /// /// * **Key** - contract address. /// * **Value** - is contract in [`Allowlisted`](SponsoringModeT::Allowlisted) mode. #[pallet::storage] pub(super) type AllowlistEnabled = StorageMap; + /// Storage for users that allowed for sponsorship. + /// + /// ### Usage + /// Prefer to delete record from storage if user no more allowed for sponsorship. + /// + /// * **Key1** - contract address. + /// * **Key2** - user that allowed for sponsorship. + /// * **Value** - allowance for sponsorship. #[pallet::storage] pub(super) type Allowlist = StorageDoubleMap< Hasher1 = Twox128, @@ -127,14 +144,45 @@ impl Hooks> for Pallet { fn on_runtime_upgrade() -> Weight { let storage_version = StorageVersion::get::>(); - if storage_version < StorageVersion::new(1) { - } + if storage_version < StorageVersion::new(1) {} 0 } } impl Pallet { + pub fn set_sponsor( + sender: &T::CrossAccountId, + contract: H160, + sponsor: &T::CrossAccountId, + ) -> DispatchResult { + Pallet::::ensure_owner(contract, *sender.as_eth())?; + Sponsoring::::insert( + contract, + SponsorshipState::::Unconfirmed(sponsor.clone()), + ); + Ok(()) + } + + pub fn confirm_sponsorship(sender: &T::CrossAccountId, contract: H160) -> DispatchResult { + match Sponsoring::::get(contract) { + SponsorshipState::Unconfirmed(sponsor) => { + ensure!(sponsor == *sender, Error::::NoPermission); + Ok(()) + } + SponsorshipState::Disabled | SponsorshipState::Confirmed(_) => { + Err(Error::::NoPendingSponsor.into()) + } + } + } + + pub fn get_sponsor(contract: H160) -> Option { + match Sponsoring::::get(contract) { + SponsorshipState::Disabled | SponsorshipState::Unconfirmed(_) => None, + SponsorshipState::Confirmed(sponsor) => Some(sponsor), + } + } + pub fn sponsoring_mode(contract: H160) -> SponsoringModeT { >::get(contract) .or_else(|| { @@ -142,6 +190,7 @@ }) .unwrap_or_default() } + pub fn set_sponsoring_mode(contract: H160, mode: SponsoringModeT) { if mode == SponsoringModeT::Disabled { >::remove(contract); -- gitstuff