difftreelog
feat Add events for set contract sponsoring.
in: master
7 files changed
Cargo.lockdiffbeforeafterboth--- a/Cargo.lock
+++ b/Cargo.lock
@@ -5735,6 +5735,7 @@
name = "pallet-evm-contract-helpers"
version = "0.2.0"
dependencies = [
+ "ethereum",
"evm-coder",
"fp-evm-mapping",
"frame-support",
pallets/evm-contract-helpers/Cargo.tomldiffbeforeafterboth--- a/pallets/evm-contract-helpers/Cargo.toml
+++ b/pallets/evm-contract-helpers/Cargo.toml
@@ -9,6 +9,7 @@
"derive",
] }
log = { default-features = false, version = "0.4.14" }
+ethereum = { version = "0.12.0", default-features = false }
# Substrate
frame-support = { default-features = false, git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.27" }
pallets/evm-contract-helpers/src/eth.rsdiffbeforeafterboth--- a/pallets/evm-contract-helpers/src/eth.rs
+++ b/pallets/evm-contract-helpers/src/eth.rs
@@ -17,7 +17,9 @@
//! Implementation of magic contract
use core::marker::PhantomData;
-use evm_coder::{abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*};
+use evm_coder::{
+ abi::AbiWriter, execution::Result, generate_stubgen, solidity_interface, types::*, ToLog,
+};
use pallet_evm_coder_substrate::{SubstrateRecorder, WithRecorder, dispatch_to_evm};
use pallet_evm::{
ExitRevert, OnCreate, OnMethodCall, PrecompileResult, PrecompileFailure, PrecompileHandle,
@@ -33,6 +35,37 @@
use up_sponsorship::SponsorshipHandler;
use sp_std::vec::Vec;
+/// Pallet events.
+#[derive(ToLog)]
+pub enum ContractHelpersEvents {
+ /// Contract sponsor was set.
+ ContractSponsorSet {
+ /// Contract address of the affected collection.
+ #[indexed]
+ contract: address,
+ /// New sponsor address.
+ #[indexed]
+ sponsor: address,
+ },
+
+ /// New sponsor was confirm.
+ ContractSponsorshipConfirmed {
+ /// Contract address of the affected collection.
+ #[indexed]
+ contract: address,
+ /// New sponsor address.
+ #[indexed]
+ sponsor: address,
+ },
+
+ /// Collection sponsor was removed.
+ ContractSponsorRemoved {
+ /// Contract address of the affected collection.
+ #[indexed]
+ contract: address,
+ },
+}
+
/// See [`ContractHelpersCall`]
pub struct ContractHelpers<T: Config>(SubstrateRecorder<T>);
impl<T: Config> WithRecorder<T> for ContractHelpers<T> {
@@ -46,7 +79,7 @@
}
/// @title Magic contract, which allows users to reconfigure other contracts
-#[solidity_interface(name = ContractHelpers)]
+#[solidity_interface(name = ContractHelpers, events(ContractHelpersEvents))]
impl<T: Config> ContractHelpers<T>
where
T::AccountId: AsRef<[u8; 32]>,
@@ -91,7 +124,7 @@
self.recorder().consume_sload()?;
self.recorder().consume_sstore()?;
- Pallet::<T>::self_sponsored_enable(&T::CrossAccountId::from_eth(caller), contract_address)
+ Pallet::<T>::force_set_sponsor(&T::CrossAccountId::from_eth(caller), contract_address)
.map_err(dispatch_to_evm::<T>)?;
Ok(())
pallets/evm-contract-helpers/src/lib.rsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// This file is part of Unique Network.34// Unique Network is free software: you can redistribute it and/or modify5// it under the terms of the GNU General Public License as published by6// the Free Software Foundation, either version 3 of the License, or7// (at your option) any later version.89// Unique Network is distributed in the hope that it will be useful,10// but WITHOUT ANY WARRANTY; without even the implied warranty of11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the12// GNU General Public License for more details.1314// You should have received a copy of the GNU General Public License15// along with Unique Network. If not, see <http://www.gnu.org/licenses/>.1617#![doc = include_str!("../README.md")]18#![cfg_attr(not(feature = "std"), no_std)]19#![deny(missing_docs)]2021use codec::{Decode, Encode, MaxEncodedLen};22pub use pallet::*;23pub use eth::*;24use scale_info::TypeInfo;25pub mod eth;2627#[frame_support::pallet]28pub mod pallet {29 pub use super::*;30 use frame_support::pallet_prelude::*;31 use pallet_evm_coder_substrate::DispatchResult;32 use sp_core::H160;33 use pallet_evm::account::CrossAccountId;34 use up_data_structs::SponsorshipState;3536 #[pallet::config]37 pub trait Config:38 frame_system::Config + pallet_evm_coder_substrate::Config + pallet_evm::account::Config39 {40 /// Address, under which magic contract will be available41 type ContractAddress: Get<H160>;42 /// In case of enabled sponsoring, but no sponsoring rate limit set,43 /// this value will be used implicitly44 type DefaultSponsoringRateLimit: Get<Self::BlockNumber>;45 }4647 #[pallet::error]48 pub enum Error<T> {49 /// This method is only executable by contract owner50 NoPermission,5152 /// No pending sponsor for contract.53 NoPendingSponsor,54 }5556 #[pallet::pallet]57 #[pallet::generate_store(pub(super) trait Store)]58 pub struct Pallet<T>(_);5960 /// Store owner for contract.61 ///62 /// * **Key** - contract address.63 /// * **Value** - owner for contract.64 #[pallet::storage]65 pub(super) type Owner<T: Config> =66 StorageMap<Hasher = Twox128, Key = H160, Value = H160, QueryKind = ValueQuery>;6768 #[pallet::storage]69 #[deprecated]70 pub(super) type SelfSponsoring<T: Config> =71 StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;7273 /// Store for contract sponsorship state.74 ///75 /// * **Key** - contract address.76 /// * **Value** - sponsorship state.77 #[pallet::storage]78 pub type Sponsoring<T: Config> = StorageMap<79 Hasher = Twox64Concat,80 Key = H160,81 Value = SponsorshipState<T::CrossAccountId>,82 QueryKind = ValueQuery,83 >;8485 /// Store for sponsoring mode.86 ///87 /// ### Usage88 /// Prefer to delete collection from storage if mode chaged to [`Disabled`](SponsoringModeT::Disabled).89 ///90 /// * **Key** - contract address.91 /// * **Value** - [`sponsoring mode`](SponsoringModeT).92 #[pallet::storage]93 pub(super) type SponsoringMode<T: Config> =94 StorageMap<Hasher = Twox128, Key = H160, Value = SponsoringModeT, QueryKind = OptionQuery>;9596 /// Storage for sponsoring rate limit in blocks.97 ///98 /// * **Key** - contract address.99 /// * **Value** - amount of sponsored blocks.100 #[pallet::storage]101 pub(super) type SponsoringRateLimit<T: Config> = StorageMap<102 Hasher = Twox128,103 Key = H160,104 Value = T::BlockNumber,105 QueryKind = ValueQuery,106 OnEmpty = T::DefaultSponsoringRateLimit,107 >;108109 /// Storage for last sponsored block.110 ///111 /// * **Key1** - contract address.112 /// * **Key2** - sponsored user address.113 /// * **Value** - last sponsored block number.114 #[pallet::storage]115 pub(super) type SponsorBasket<T: Config> = StorageDoubleMap<116 Hasher1 = Twox128,117 Key1 = H160,118 Hasher2 = Twox128,119 Key2 = H160,120 Value = T::BlockNumber,121 QueryKind = OptionQuery,122 >;123124 /// Storege for contracts with [`Allowlisted`](SponsoringModeT::Allowlisted) sponsoring mode.125 ///126 /// ### Usage127 /// Prefer to delete collection from storage if mode chaged to non `Allowlisted`, than set **Value** to **false**.128 ///129 /// * **Key** - contract address.130 /// * **Value** - is contract in [`Allowlisted`](SponsoringModeT::Allowlisted) mode.131 #[pallet::storage]132 pub(super) type AllowlistEnabled<T: Config> =133 StorageMap<Hasher = Twox128, Key = H160, Value = bool, QueryKind = ValueQuery>;134135 /// Storage for users that allowed for sponsorship.136 ///137 /// ### Usage138 /// Prefer to delete record from storage if user no more allowed for sponsorship.139 ///140 /// * **Key1** - contract address.141 /// * **Key2** - user that allowed for sponsorship.142 /// * **Value** - allowance for sponsorship.143 #[pallet::storage]144 pub(super) type Allowlist<T: Config> = StorageDoubleMap<145 Hasher1 = Twox128,146 Key1 = H160,147 Hasher2 = Twox128,148 Key2 = H160,149 Value = bool,150 QueryKind = ValueQuery,151 >;152153 impl<T: Config> Pallet<T> {154 /// Get contract owner.155 pub fn contract_owner(contract: H160) -> H160 {156 <Owner<T>>::get(contract)157 }158159 /// Set `sponsor` for `contract`.160 ///161 /// `sender` must be owner of contract.162 pub fn set_sponsor(163 sender: &T::CrossAccountId,164 contract: H160,165 sponsor: &T::CrossAccountId,166 ) -> DispatchResult {167 Pallet::<T>::ensure_owner(contract, *sender.as_eth())?;168 Sponsoring::<T>::insert(169 contract,170 SponsorshipState::<T::CrossAccountId>::Unconfirmed(sponsor.clone()),171 );172 Ok(())173 }174175 /// Set `contract` as self sponsored.176 ///177 /// `sender` must be owner of contract.178 pub fn self_sponsored_enable(sender: &T::CrossAccountId, contract: H160) -> DispatchResult {179 Pallet::<T>::ensure_owner(contract, *sender.as_eth())?;180 Sponsoring::<T>::insert(181 contract,182 SponsorshipState::<T::CrossAccountId>::Confirmed(T::CrossAccountId::from_eth(183 contract,184 )),185 );186 Ok(())187 }188189 /// Remove sponsor for `contract`.190 ///191 /// `sender` must be owner of contract.192 pub fn remove_sponsor(sender: &T::CrossAccountId, contract: H160) -> DispatchResult {193 Pallet::<T>::ensure_owner(contract, *sender.as_eth())?;194 Sponsoring::<T>::remove(contract);195 Ok(())196 }197198 /// Confirm sponsorship.199 ///200 /// `sender` must be same that set via [`set_sponsor`].201 pub fn confirm_sponsorship(sender: &T::CrossAccountId, contract: H160) -> DispatchResult {202 match Sponsoring::<T>::get(contract) {203 SponsorshipState::Unconfirmed(sponsor) => {204 ensure!(sponsor == *sender, Error::<T>::NoPermission);205 Sponsoring::<T>::insert(206 contract,207 SponsorshipState::<T::CrossAccountId>::Confirmed(sponsor),208 );209 Ok(())210 }211 SponsorshipState::Disabled | SponsorshipState::Confirmed(_) => {212 Err(Error::<T>::NoPendingSponsor.into())213 }214 }215 }216217 /// Get sponsor.218 pub fn get_sponsor(contract: H160) -> Option<T::CrossAccountId> {219 match Sponsoring::<T>::get(contract) {220 SponsorshipState::Disabled | SponsorshipState::Unconfirmed(_) => None,221 SponsorshipState::Confirmed(sponsor) => Some(sponsor),222 }223 }224225 /// Get current sponsoring mode, performing lazy migration from legacy storage226 pub fn sponsoring_mode(contract: H160) -> SponsoringModeT {227 <SponsoringMode<T>>::get(contract)228 .or_else(|| {229 <SelfSponsoring<T>>::get(contract).then(|| SponsoringModeT::Allowlisted)230 })231 .unwrap_or_default()232 }233234 /// Reconfigure contract sponsoring mode235 pub fn set_sponsoring_mode(contract: H160, mode: SponsoringModeT) {236 if mode == SponsoringModeT::Disabled {237 <SponsoringMode<T>>::remove(contract);238 } else {239 <SponsoringMode<T>>::insert(contract, mode);240 }241 <SelfSponsoring<T>>::remove(contract)242 }243244 /// Set duration between two sponsored contract calls245 pub fn set_sponsoring_rate_limit(contract: H160, rate_limit: T::BlockNumber) {246 <SponsoringRateLimit<T>>::insert(contract, rate_limit);247 }248249 /// Is user added to allowlist, or he is owner of specified contract250 pub fn allowed(contract: H160, user: H160) -> bool {251 <Allowlist<T>>::get(&contract, &user) || <Owner<T>>::get(&contract) == user252 }253254 /// Toggle contract allowlist access255 pub fn toggle_allowlist(contract: H160, enabled: bool) {256 <AllowlistEnabled<T>>::insert(contract, enabled)257 }258259 /// Toggle user presence in contract's allowlist260 pub fn toggle_allowed(contract: H160, user: H160, allowed: bool) {261 <Allowlist<T>>::insert(contract, user, allowed);262 }263264 /// Throw error if user is not allowed to reconfigure target contract265 pub fn ensure_owner(contract: H160, user: H160) -> DispatchResult {266 ensure!(<Owner<T>>::get(&contract) == user, Error::<T>::NoPermission);267 Ok(())268 }269 }270}271272/// Available contract sponsoring modes273#[derive(Encode, Decode, PartialEq, TypeInfo, MaxEncodedLen, Default)]274pub enum SponsoringModeT {275 /// Sponsoring is disabled276 #[default]277 Disabled,278 /// Only users from allowlist will be sponsored279 Allowlisted,280 /// All users will be sponsored281 Generous,282}283284impl SponsoringModeT {285 fn from_eth(v: u8) -> Option<Self> {286 Some(match v {287 0 => Self::Disabled,288 1 => Self::Allowlisted,289 2 => Self::Generous,290 _ => return None,291 })292 }293 fn to_eth(self) -> u8 {294 match self {295 SponsoringModeT::Disabled => 0,296 SponsoringModeT::Allowlisted => 1,297 SponsoringModeT::Generous => 2,298 }299 }300}runtime/common/config/ethereum.rsdiffbeforeafterboth--- a/runtime/common/config/ethereum.rs
+++ b/runtime/common/config/ethereum.rs
@@ -112,6 +112,7 @@
}
impl pallet_evm_contract_helpers::Config for Runtime {
+ type Event = Event;
type ContractAddress = HelpersContractAddress;
type DefaultSponsoringRateLimit = DefaultSponsoringRateLimit;
}
runtime/common/config/pallets/app_promotion.rsdiffbeforeafterboth--- a/runtime/common/config/pallets/app_promotion.rs
+++ b/runtime/common/config/pallets/app_promotion.rs
@@ -22,7 +22,7 @@
use frame_support::{parameter_types, PalletId};
use sp_arithmetic::Perbill;
use up_common::{
- constants::{ UNIQUE, RELAY_DAYS},
+ constants::{UNIQUE, RELAY_DAYS},
types::Balance,
};
runtime/common/construct_runtime/mod.rsdiffbeforeafterboth--- a/runtime/common/construct_runtime/mod.rs
+++ b/runtime/common/construct_runtime/mod.rs
@@ -85,7 +85,7 @@
Ethereum: pallet_ethereum::{Pallet, Config, Call, Storage, Event, Origin} = 101,
EvmCoderSubstrate: pallet_evm_coder_substrate::{Pallet, Storage} = 150,
- EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage} = 151,
+ EvmContractHelpers: pallet_evm_contract_helpers::{Pallet, Storage, Event<T>} = 151,
EvmTransactionPayment: pallet_evm_transaction_payment::{Pallet} = 152,
EvmMigration: pallet_evm_migration::{Pallet, Call, Storage} = 153,
}