diff --git a/crates/pink-drivers/system/lib.rs b/crates/pink-drivers/system/lib.rs index 40369ccdb7..21fc54446f 100755 --- a/crates/pink-drivers/system/lib.rs +++ b/crates/pink-drivers/system/lib.rs @@ -10,12 +10,28 @@ pub use system::System; mod system { use super::pink; use alloc::string::String; + use alloc::vec::Vec; use ink::{codegen::Env, storage::Mapping}; use pink::system::{CodeType, ContractDeposit, ContractDepositRef, DriverError, Error, Result}; use pink::{HookPoint, PinkEnvironment}; use this_crate::{version_tuple, VersionTuple}; + /// A new driver is set. + #[ink(event)] + pub struct DriverChanged { + #[ink(topic)] + name: String, + previous: Option, + current: AccountId, + } + + /// A new administrator is added. + #[ink(event)] + pub struct AdministratorAdded { + user: AccountId, + } + /// Pink's system contract. #[ink(storage)] pub struct System { @@ -23,8 +39,12 @@ mod system { owner: AccountId, /// The administrators administrators: Mapping, - /// The drivers + /// The drivers (deprecated) drivers: Mapping, + /// The drivers + drivers2: Mapping, + /// The history of drivers + drivers_history: Mapping>, } impl System { @@ -34,6 +54,8 @@ mod system { owner: Self::env().caller(), administrators: Default::default(), drivers: Default::default(), + drivers2: Default::default(), + drivers_history: Default::default(), } } @@ -96,7 +118,9 @@ mod system { #[ink(message)] fn grant_admin(&mut self, contract_id: AccountId) -> Result<()> { self.ensure_owner()?; - self.administrators.insert(contract_id, &()); + self.administrators.insert(&contract_id, &()); + self.env() + .emit_event(AdministratorAdded { user: contract_id }); Ok(()) } @@ -109,13 +133,36 @@ mod system { } _ => {} } - self.drivers.insert(name, &contract_id); + + let previous = self.get_driver2(name.clone()); + if let Some((block, previous)) = previous { + if previous == contract_id { + return Ok(()); + } + let mut history = self.drivers_history.get(&name).unwrap_or_default(); + history.push((block, previous)); + self.drivers_history.insert(&name, &history); + } + self.drivers2 + .insert(&name, &(self.env().block_number(), contract_id)); + self.env().emit_event(DriverChanged { + name, + previous: previous.map(|(_, id)| id), + current: contract_id, + }); Ok(()) } #[ink(message)] fn get_driver(&self, name: String) -> Option { - self.drivers.get(&name) + self.get_driver2(name).map(|(_, id)| id) + } + + #[ink(message)] + fn get_driver2(&self, name: String) -> Option<(BlockNumber, AccountId)> { + self.drivers2 + .get(&name) + .or_else(|| self.drivers.get(&name).map(|id| (0, id))) } #[ink(message)] @@ -222,6 +269,16 @@ mod system { fn code_exists(&self, code_hash: [u8; 32], code_type: CodeType) -> bool { pink::ext().code_exists(code_hash.into(), code_type.is_sidevm()) } + + #[ink(message)] + fn code_hash(&self, account: AccountId) -> Option { + self.env().code_hash(&account).ok() + } + + #[ink(message)] + fn driver_history(&self, name: String) -> Option> { + self.drivers_history.get(&name) + } } impl ContractDeposit for System { diff --git a/crates/pink-drivers/tokenomic/lib.rs b/crates/pink-drivers/tokenomic/lib.rs index eae5a575db..2989ca6e56 100755 --- a/crates/pink-drivers/tokenomic/lib.rs +++ b/crates/pink-drivers/tokenomic/lib.rs @@ -10,6 +10,13 @@ mod tokenomic { type Result = core::result::Result; + #[ink(event)] + pub struct WeightChanged { + #[ink(topic)] + contract_id: AccountId, + weight: u32, + } + #[ink(storage)] pub struct PhatTokenomic {} @@ -40,7 +47,12 @@ mod tokenomic { const CENTS: Balance = 10_000_000_000; let system = SystemRef::instance(); let weight = deposit / CENTS; - system.set_contract_weight(contract_id, weight.try_into().unwrap_or(u32::MAX))?; + let weight = weight.try_into().unwrap_or(u32::MAX); + system.set_contract_weight(contract_id.clone(), weight)?; + self.env().emit_event(WeightChanged { + contract_id, + weight + }); Ok(()) } } diff --git a/crates/pink/pink-extension/src/system.rs b/crates/pink/pink-extension/src/system.rs index 19699b6976..f06b166293 100644 --- a/crates/pink/pink-extension/src/system.rs +++ b/crates/pink/pink-extension/src/system.rs @@ -3,6 +3,7 @@ use pink_extension_macro as pink; use alloc::string::String; +use alloc::vec::Vec; use scale::{Decode, Encode}; use crate::{AccountId, Balance, Hash}; @@ -64,11 +65,13 @@ pub trait System { fn set_driver(&mut self, name: String, contract_id: AccountId) -> Result<()>; /// Get driver contract id for `name`. - /// - /// The caller must be the owner of the cluster or an administrator. #[ink(message)] fn get_driver(&self, name: String) -> Option; + /// Get driver contract id for `name` and the set block number. + #[ink(message)] + fn get_driver2(&self, name: String) -> Option<(crate::BlockNumber, AccountId)>; + /// Deploy a sidevm instance attached to a given contract. /// /// The caller must be an administrator. @@ -125,6 +128,14 @@ pub trait System { /// Check if the code is already uploaded to the cluster with given code hash. #[ink(message)] fn code_exists(&self, code_hash: Hash, code_type: CodeType) -> bool; + + /// Get the current code hash of given contract. + #[ink(message)] + fn code_hash(&self, account: AccountId) -> Option; + + /// Get the history of given driver. + #[ink(message)] + fn driver_history(&self, name: String) -> Option>; } /// Errors that can occur upon calling a driver contract.