From 79c446389b544a7e9e647fef11bdee0ea97a1b45 Mon Sep 17 00:00:00 2001 From: Derek Colley Date: Sun, 28 Jul 2024 11:27:04 +0100 Subject: [PATCH] add alerts --- .gitignore | 1 + Cargo.lock | 17 ++ pallets/ibp-alert/Cargo.toml | 60 ++++++ pallets/ibp-alert/src/benchmarking.rs | 35 ++++ pallets/ibp-alert/src/impls.rs | 9 + pallets/ibp-alert/src/lib.rs | 266 ++++++++++++++++++++++++++ pallets/ibp-alert/src/mock.rs | 62 ++++++ pallets/ibp-alert/src/tests.rs | 27 +++ pallets/ibp-alert/src/weights.rs | 98 ++++++++++ pallets/ibp-check/src/lib.rs | 79 ++++---- pallets/ibp-service/src/lib.rs | 4 +- runtime/Cargo.toml | 1 + runtime/src/lib.rs | 12 ++ 13 files changed, 630 insertions(+), 41 deletions(-) create mode 100644 .gitignore create mode 100644 pallets/ibp-alert/Cargo.toml create mode 100644 pallets/ibp-alert/src/benchmarking.rs create mode 100644 pallets/ibp-alert/src/impls.rs create mode 100644 pallets/ibp-alert/src/lib.rs create mode 100644 pallets/ibp-alert/src/mock.rs create mode 100644 pallets/ibp-alert/src/tests.rs create mode 100644 pallets/ibp-alert/src/weights.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2f7896d --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +target/ diff --git a/Cargo.lock b/Cargo.lock index 7585e3b..e5f1821 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4609,6 +4609,7 @@ dependencies = [ "pallet-aura", "pallet-balances", "pallet-grandpa", + "pallet-ibp-alert", "pallet-ibp-check", "pallet-ibp-member", "pallet-ibp-service", @@ -4877,6 +4878,22 @@ dependencies = [ "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-v1.9.0)", ] +[[package]] +name = "pallet-ibp-alert" +version = "0.0.1-poc" +dependencies = [ + "frame-benchmarking", + "frame-support", + "frame-system", + "pallet-ibp-member", + "pallet-ibp-service", + "parity-scale-codec", + "scale-info", + "sp-core", + "sp-io", + "sp-runtime", +] + [[package]] name = "pallet-ibp-check" version = "0.0.1-poc" diff --git a/pallets/ibp-alert/Cargo.toml b/pallets/ibp-alert/Cargo.toml new file mode 100644 index 0000000..53d5248 --- /dev/null +++ b/pallets/ibp-alert/Cargo.toml @@ -0,0 +1,60 @@ +[package] +name = "pallet-ibp-alert" +description = "FRAME pallet template for defining custom runtime logic." +version = "0.0.1-poc" +license = "MIT-0" +authors.workspace = true +homepage.workspace = true +repository.workspace = true +edition.workspace = true +publish = false + +[lints] +workspace = true + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.6.1", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.10.0", default-features = false, features = [ + "derive", +] } + +# frame deps +frame-benchmarking = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.9.0", default-features = false, optional = true } +frame-support = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.9.0", default-features = false } +frame-system = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.9.0", default-features = false } +pallet-ibp-member = { path = "../ibp-member", default-features = false } +pallet-ibp-service = { path = "../ibp-service", default-features = false } + +[dev-dependencies] +sp-core = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.9.0" } +sp-io = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.9.0" } +sp-runtime = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.9.0" } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-benchmarking?/std", + "frame-support/std", + "frame-system/std", + "scale-info/std", + "sp-core/std", + "sp-io/std", + "sp-runtime/std", +] +runtime-benchmarks = [ + "frame-benchmarking/runtime-benchmarks", + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "sp-runtime/runtime-benchmarks", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "sp-runtime/try-runtime", +] diff --git a/pallets/ibp-alert/src/benchmarking.rs b/pallets/ibp-alert/src/benchmarking.rs new file mode 100644 index 0000000..5a26241 --- /dev/null +++ b/pallets/ibp-alert/src/benchmarking.rs @@ -0,0 +1,35 @@ +//! Benchmarking setup for pallet-template +#![cfg(feature = "runtime-benchmarks")] +use super::*; + +#[allow(unused)] +use crate::Pallet as Template; +use frame_benchmarking::v2::*; +use frame_system::RawOrigin; + +#[benchmarks] +mod benchmarks { + use super::*; + + #[benchmark] + fn do_something() { + let value = 100u32.into(); + let caller: T::AccountId = whitelisted_caller(); + #[extrinsic_call] + do_something(RawOrigin::Signed(caller), value); + + assert_eq!(Something::::get(), Some(value)); + } + + #[benchmark] + fn cause_error() { + Something::::put(100u32); + let caller: T::AccountId = whitelisted_caller(); + #[extrinsic_call] + cause_error(RawOrigin::Signed(caller)); + + assert_eq!(Something::::get(), Some(101u32)); + } + + impl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/pallets/ibp-alert/src/impls.rs b/pallets/ibp-alert/src/impls.rs new file mode 100644 index 0000000..762a4eb --- /dev/null +++ b/pallets/ibp-alert/src/impls.rs @@ -0,0 +1,9 @@ + +use super::*; +use sp_staking::{Agent, DelegationInterface, DelegationMigrator, Delegator, OnStakingUpdate}; + +impl DelegationInterface for Pallet { + // type Balance = BalanceOf; + type AccountId = T::AccountId; + +} diff --git a/pallets/ibp-alert/src/lib.rs b/pallets/ibp-alert/src/lib.rs new file mode 100644 index 0000000..56eaea9 --- /dev/null +++ b/pallets/ibp-alert/src/lib.rs @@ -0,0 +1,266 @@ +//! IBP HealthCheck Pallet + +// We make sure this pallet uses `no_std` for compiling to Wasm. +#![cfg_attr(not(feature = "std"), no_std)] + +use codec::{ Decode, Encode, MaxEncodedLen }; +use scale_info::TypeInfo; +use frame_support::{ + traits::ConstU32, + BoundedVec, +}; + + +// FRAME pallets require their own "mock runtimes" to be able to run unit tests. This module +// contains a mock runtime specific for testing this pallet's functionality. +#[cfg(test)] +mod mock; + +// This module contains the unit tests for this pallet. +// Learn about pallet unit testing here: https://docs.substrate.io/test/unit-testing/ +#[cfg(test)] +mod tests; + +// Every callable function or "dispatchable" a pallet exposes must have weight values that correctly +// estimate a dispatchable's execution time. The benchmarking module is used to calculate weights +// for each dispatchable and generates this pallet's weight.rs file. Learn more about benchmarking here: https://docs.substrate.io/test/benchmark/ +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; +pub mod weights; +pub use weights::*; + +use pallet_ibp_member::Pallet as MemberPallet; +use pallet_ibp_service::Pallet as ServicePallet; + +pub type DomainId = BoundedVec>; +pub type AlertType = BoundedVec>; + +// #[derive(Clone, Debug, Encode, Decode, PartialEq, Eq, TypeInfo, MaxEncodedLen)] +// pub enum AlertType { +// HostDown, +// ServiceDown, +// InstanceDown, +// BlackboxProbeFailed, +// BlackboxProbeHttpFailure, +// NoIncomingConnection, +// BlockFinalizationLaggingBehind, +// BlackboxSslCertificateWillExpireSoon, +// SubstrateServiceTooManyRestarts, +// Other, +// } + +// impl Default for AlertType { +// fn default() -> Self { +// AlertType::Other +// } +// } + + +// All pallet logic is defined in its own module and must be annotated by the `pallet` attribute. +#[frame_support::pallet] +pub mod pallet { + // Import various useful types required by all FRAME pallets. + use super::*; + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + use pallet_ibp_service::{ServiceId, ServiceStatus}; + use pallet_ibp_service::Error::ServiceNotFound; + use pallet_ibp_member::MemberStatus; + use pallet_ibp_member::Error::MemberNotFound; + + // The `Pallet` struct serves as a placeholder to implement traits, methods and dispatchables + // (`Call`s) in this pallet. + #[pallet::pallet] + #[pallet::without_storage_info] + pub struct Pallet(_); + + /// The pallet's configuration trait. + /// + /// All our types and constants a pallet depends on must be declared here. + /// These types are defined generically and made concrete when the pallet is declared in the + /// `runtime/src/lib.rs` file of your chain. + #[pallet::config] + pub trait Config: frame_system::Config + pallet_ibp_member::Config + pallet_ibp_service::Config { + /// The overarching runtime event type. + type RuntimeEvent: From> + IsType<::RuntimeEvent>; + /// A type representing the weights required by the dispatchables of this pallet. + // type WeightInfo: WeightInfo; + type AlertKey: Parameter + Member + TypeInfo + MaxEncodedLen; + } + + #[derive(Encode, Decode, Clone, PartialEq, Eq, MaxEncodedLen, TypeInfo)] + #[scale_info(skip_type_params(T))] + pub struct AlertKey { + monitor_id: T::AccountId, + alert_id: u64 + } + + #[derive(Debug, Encode, Decode, Clone, PartialEq, Eq, MaxEncodedLen, TypeInfo)] + #[scale_info(skip_type_params(T))] + pub struct AlertData { + // monitor Id: unique identifier for the monitor, string + pub monitor_id: T::AccountId, + // external alert Id: unique identifier for the alert, string(maxlen = 64) + pub alert_id: u64, + // member Id: unique identifier for the member, string + pub member_id: T::AccountId, + // domain Id: unique identifier for the domain, string + pub domain_id: DomainId, + // service Id: unique identifier for the service, string + pub service_id: ServiceId, + // service type; enum ['RPC', 'BOOT'] + pub alert_type: AlertType + } + + /// storage for this pallet. + #[pallet::storage] + #[pallet::getter(fn alerts)] + pub type Alerts = StorageMap<_, Blake2_128Concat, AlertKey, AlertData, OptionQuery>; + + + /// Events that functions in this pallet can emit. + /// + /// Events are a simple means of indicating to the outside world (such as dApps, chain explorers + /// or other users) that some notable update in the runtime has occurred. In a FRAME pallet, the + /// documentation for each event field and its parameters is added to a node's metadata so it + /// can be used by external interfaces or tools. + /// + /// The `generate_deposit` macro generates a function on `Pallet` called `deposit_event` which + /// will convert the event type of your pallet into `RuntimeEvent` (declared in the pallet's + /// [`Config`] trait) and deposit it using [`frame_system::Pallet::deposit_event`]. + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + AlertRegistered(T::AccountId, ServiceId, DomainId, AlertType), + AlertCleared(T::AccountId, ServiceId, DomainId, AlertType), + } + + /// Errors that can be returned by this pallet. + /// + /// Errors tell users that something went wrong so it's important that their naming is + /// informative. Similar to events, error documentation is added to a node's metadata so it's + /// equally important that they have helpful documentation associated with them. + /// + /// This type of runtime error can be up to 4 bytes in size should you want to return additional + /// information. + #[pallet::error] + pub enum Error { + AlertNotFound, + MemberNotFound, + MemberNotActive, + ServiceNotFound, + ServiceNotActive, + // Must be monitor to register alerts + NotAMonitor, + // Must be curator to clear alerts + NotACurator, + // Must be original monitor or curator to clear alerts + BadOriginOrNotACurator, + // check for service membership level + ServiceMembershipLevelMismatch, + } + + /// The pallet's dispatchable functions ([`Call`]s). + /// + /// Dispatchable functions allows users to interact with the pallet and invoke state changes. + /// These functions materialize as "extrinsics", which are often compared to transactions. + /// They must always return a `DispatchResult` and be annotated with a weight and call index. + /// + /// The [`call_index`] macro is used to explicitly + /// define an index for calls in the [`Call`] enum. This is useful for pallets that may + /// introduce new dispatchables over time. If the order of a dispatchable changes, its index + /// will also change which will break backwards compatibility. + /// + /// The [`weight`] macro is used to assign a weight to each call. + #[pallet::call] + impl Pallet { + + #[pallet::call_index(0)] + #[pallet::weight(10_000)] + pub fn register_alert( + origin: OriginFor, + alert_id: u64, + member_id: T::AccountId, + service_id: ServiceId, + domain_id: DomainId, + alert_type: AlertType + ) -> DispatchResult { + let sender: T::AccountId = ensure_signed(origin)?; + // only monitors can register health checks + ensure!(MemberPallet::::monitors(&sender), Error::::NotAMonitor); + // ensure member exists + let member = MemberPallet::::members(&member_id).ok_or(MemberNotFound)?; + if member.status != MemberStatus::Active { + return Err(Error::::MemberNotActive.into()); + } + // ensure service exists + let service = ServicePallet::::services(&service_id).ok_or(ServiceNotFound)?; + if service.status != ServiceStatus::Active { + return Err(Error::::ServiceNotActive.into()); + } + // check member.level GE service.membershipLevel + // ensure!(member.level >= service.level, Error::::ServiceMembershipLevelMismatch); + // let level = ServiceMembershipLevel::Zero; + // let status = ServiceStatus::Locked; + // let service_id = id.clone(); + let alert_data: AlertData = AlertData { + alert_id, + monitor_id: sender.clone(), + member_id: member_id.clone(), + service_id: service_id.clone(), + domain_id: domain_id.clone(), + alert_type: alert_type.clone() + }; + let key: AlertKey = AlertKey { monitor_id: sender.clone(), alert_id }; + // let key = ( sender.clone(), alert_id ); + // store the alert + Alerts::::insert(key, alert_data); + Self::deposit_event(Event::AlertRegistered(member_id, service_id, domain_id, alert_type)); + Ok(()) + } + + #[pallet::call_index(1)] + #[pallet::weight(10_000)] + pub fn clear_alert( + origin: OriginFor, + alert_id: u64 + ) -> DispatchResult { + let sender = ensure_signed(origin)?; + // get the alert by (monitor, Id) + let key: AlertKey = AlertKey { monitor_id: sender.clone(), alert_id }; + // let key = ( sender.clone(), alert_id ); + let alert: AlertData = Alerts::::get(key.clone()).ok_or(Error::::AlertNotFound)?; + // only original monitor or curator can clear alerts + ensure!( + alert.monitor_id == sender || MemberPallet::::curators(&sender), + Error::::BadOriginOrNotACurator + ); + // delete the alert + Alerts::::remove(key); + Self::deposit_event(Event::AlertCleared(sender, alert.service_id, alert.domain_id, alert.alert_type)); + Ok(()) + } + + #[pallet::call_index(20)] + #[pallet::weight(10_000)] + pub fn clear_monitor_alert( + origin: OriginFor, + monitor_id: T::AccountId, + alert_id: u64 + ) -> DispatchResult { + let sender = ensure_signed(origin)?; + // only curators can force clear alerts + ensure!(MemberPallet::::curators(&sender), Error::::NotACurator); + // get the alert by (monitor, Id) + let key: AlertKey = AlertKey { monitor_id, alert_id }; + // let key = ( monitor_id, alert_id ); + let alert: AlertData = Alerts::::get(key.clone()).ok_or(Error::::AlertNotFound)?; + // delete the alert + Alerts::::remove(key); + Self::deposit_event(Event::AlertCleared(sender, alert.service_id, alert.domain_id, alert.alert_type)); + Ok(()) + } + + } +} diff --git a/pallets/ibp-alert/src/mock.rs b/pallets/ibp-alert/src/mock.rs new file mode 100644 index 0000000..060b43b --- /dev/null +++ b/pallets/ibp-alert/src/mock.rs @@ -0,0 +1,62 @@ +use crate::{self as pallet_template, MemberStatus}; +use frame_support::{ + derive_impl, + traits::{ConstU16, ConstU64}, +}; +use sp_core::H256; +use sp_runtime::{ + traits::{BlakeTwo256, IdentityLookup}, + BuildStorage, +}; + +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test + { + System: frame_system, + TemplateModule: pallet_template, + } +); + +#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)] +impl frame_system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Nonce = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Block = Block; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = ConstU16<42>; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +impl pallet_template::Config for Test { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + // type AccountId = u64; + type MemberStatus = u64; + type MembershipLevel = u64; + type MemberData = (MemberStatus, MembershipLevel); +} + +// Build genesis storage according to the mock runtime. +pub fn new_test_ext() -> sp_io::TestExternalities { + frame_system::GenesisConfig::::default().build_storage().unwrap().into() +} diff --git a/pallets/ibp-alert/src/tests.rs b/pallets/ibp-alert/src/tests.rs new file mode 100644 index 0000000..83e4bea --- /dev/null +++ b/pallets/ibp-alert/src/tests.rs @@ -0,0 +1,27 @@ +use crate::{mock::*, Error, Event, Something}; +use frame_support::{assert_noop, assert_ok}; + +#[test] +fn it_works_for_default_value() { + new_test_ext().execute_with(|| { + // Go past genesis block so events get deposited + System::set_block_number(1); + // Dispatch a signed extrinsic. + assert_ok!(TemplateModule::do_something(RuntimeOrigin::signed(1), 42)); + // Read pallet storage and assert an expected result. + assert_eq!(Something::::get(), Some(42)); + // Assert that the correct event was deposited + System::assert_last_event(Event::SomethingStored { something: 42, who: 1 }.into()); + }); +} + +#[test] +fn correct_error_for_none_value() { + new_test_ext().execute_with(|| { + // Ensure the expected error is thrown when no value is present. + assert_noop!( + TemplateModule::cause_error(RuntimeOrigin::signed(1)), + Error::::NoneValue + ); + }); +} diff --git a/pallets/ibp-alert/src/weights.rs b/pallets/ibp-alert/src/weights.rs new file mode 100644 index 0000000..a99889f --- /dev/null +++ b/pallets/ibp-alert/src/weights.rs @@ -0,0 +1,98 @@ + +//! Autogenerated weights for pallet_template +//! +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev +//! DATE: 2023-04-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `Alexs-MacBook-Pro-2.local`, CPU: `` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 + +// Executed Command: +// ../../target/release/node-template +// benchmark +// pallet +// --chain +// dev +// --pallet +// pallet_template +// --extrinsic +// * +// --steps=50 +// --repeat=20 +// --wasm-execution=compiled +// --output +// pallets/template/src/weights.rs +// --template +// ../../.maintain/frame-weight-template.hbs + +#![cfg_attr(rustfmt, rustfmt_skip)] +#![allow(unused_parens)] +#![allow(unused_imports)] + +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use core::marker::PhantomData; + +/// Weight functions needed for pallet_template. +pub trait WeightInfo { + fn do_something() -> Weight; + fn cause_error() -> Weight; +} + +/// Weights for pallet_template using the Substrate node and recommended hardware. +pub struct SubstrateWeight(PhantomData); +impl WeightInfo for SubstrateWeight { + // fn register_member() -> Weight { + // // Proof Size summary in bytes: + // // Measured: `0` + // // Estimated: `0` + // // Minimum execution time: 8_000_000 picoseconds. + // Weight::from_parts(10_000, 0) + // .saturating_add(T::DbWeight::get().writes(1_u64)) + // } + /// Storage: TemplateModule Something (r:0 w:1) + /// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn do_something() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 0) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } + /// Storage: TemplateModule Something (r:1 w:1) + /// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn cause_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `32` + // Estimated: `1489` + // Minimum execution time: 6_000_000 picoseconds. + Weight::from_parts(6_000_000, 1489) + .saturating_add(T::DbWeight::get().reads(1_u64)) + .saturating_add(T::DbWeight::get().writes(1_u64)) + } +} + +// For backwards compatibility and tests +impl WeightInfo for () { + /// Storage: TemplateModule Something (r:0 w:1) + /// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn do_something() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 8_000_000 picoseconds. + Weight::from_parts(9_000_000, 0) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } + /// Storage: TemplateModule Something (r:1 w:1) + /// Proof: TemplateModule Something (max_values: Some(1), max_size: Some(4), added: 499, mode: MaxEncodedLen) + fn cause_error() -> Weight { + // Proof Size summary in bytes: + // Measured: `32` + // Estimated: `1489` + // Minimum execution time: 6_000_000 picoseconds. + Weight::from_parts(6_000_000, 1489) + .saturating_add(RocksDbWeight::get().reads(1_u64)) + .saturating_add(RocksDbWeight::get().writes(1_u64)) + } +} diff --git a/pallets/ibp-check/src/lib.rs b/pallets/ibp-check/src/lib.rs index fd60181..fecf27f 100644 --- a/pallets/ibp-check/src/lib.rs +++ b/pallets/ibp-check/src/lib.rs @@ -98,6 +98,7 @@ pub mod pallet { } #[derive(Default, Debug, Encode, Decode, Clone, PartialEq, Eq, MaxEncodedLen, TypeInfo)] + #[scale_info(skip_type_params(T))] pub struct HealthCheckData { // member Id: unique identifier for the member, string pub member_id: T::AccountId, @@ -119,36 +120,36 @@ pub mod pallet { // } // } - // /// storage for this pallet. + // /// storage for this pallet. // #[pallet::storage] - // pub type Checks = StorageMap<_, Blake2_128Concat, T::AccountId, HealthCheckData, ValueQuery>; + // pub type Checks = StorageMap<_, Blake2_128Concat, T::AccountId, HealthCheckData, ValueQuery>; /// Events that functions in this pallet can emit. - /// - /// Events are a simple means of indicating to the outside world (such as dApps, chain explorers - /// or other users) that some notable update in the runtime has occurred. In a FRAME pallet, the - /// documentation for each event field and its parameters is added to a node's metadata so it - /// can be used by external interfaces or tools. - /// - /// The `generate_deposit` macro generates a function on `Pallet` called `deposit_event` which - /// will convert the event type of your pallet into `RuntimeEvent` (declared in the pallet's - /// [`Config`] trait) and deposit it using [`frame_system::Pallet::deposit_event`]. - #[pallet::event] - #[pallet::generate_deposit(pub(super) fn deposit_event)] - pub enum Event { + /// + /// Events are a simple means of indicating to the outside world (such as dApps, chain explorers + /// or other users) that some notable update in the runtime has occurred. In a FRAME pallet, the + /// documentation for each event field and its parameters is added to a node's metadata so it + /// can be used by external interfaces or tools. + /// + /// The `generate_deposit` macro generates a function on `Pallet` called `deposit_event` which + /// will convert the event type of your pallet into `RuntimeEvent` (declared in the pallet's + /// [`Config`] trait) and deposit it using [`frame_system::Pallet::deposit_event`]. + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { HealthCheckRegistered(T::AccountId, ServiceId, HealthCheckType, HealthCheckStatus), - } + } - /// Errors that can be returned by this pallet. - /// - /// Errors tell users that something went wrong so it's important that their naming is - /// informative. Similar to events, error documentation is added to a node's metadata so it's - /// equally important that they have helpful documentation associated with them. - /// - /// This type of runtime error can be up to 4 bytes in size should you want to return additional - /// information. - #[pallet::error] - pub enum Error { + /// Errors that can be returned by this pallet. + /// + /// Errors tell users that something went wrong so it's important that their naming is + /// informative. Similar to events, error documentation is added to a node's metadata so it's + /// equally important that they have helpful documentation associated with them. + /// + /// This type of runtime error can be up to 4 bytes in size should you want to return additional + /// information. + #[pallet::error] + pub enum Error { NotAMonitor, MemberNotFound, ServiceNotFound, @@ -157,20 +158,20 @@ pub mod pallet { ServiceMembershipLevelMismatch, } - /// The pallet's dispatchable functions ([`Call`]s). - /// - /// Dispatchable functions allows users to interact with the pallet and invoke state changes. - /// These functions materialize as "extrinsics", which are often compared to transactions. - /// They must always return a `DispatchResult` and be annotated with a weight and call index. - /// - /// The [`call_index`] macro is used to explicitly - /// define an index for calls in the [`Call`] enum. This is useful for pallets that may - /// introduce new dispatchables over time. If the order of a dispatchable changes, its index - /// will also change which will break backwards compatibility. - /// - /// The [`weight`] macro is used to assign a weight to each call. - #[pallet::call] - impl Pallet { + /// The pallet's dispatchable functions ([`Call`]s). + /// + /// Dispatchable functions allows users to interact with the pallet and invoke state changes. + /// These functions materialize as "extrinsics", which are often compared to transactions. + /// They must always return a `DispatchResult` and be annotated with a weight and call index. + /// + /// The [`call_index`] macro is used to explicitly + /// define an index for calls in the [`Call`] enum. This is useful for pallets that may + /// introduce new dispatchables over time. If the order of a dispatchable changes, its index + /// will also change which will break backwards compatibility. + /// + /// The [`weight`] macro is used to assign a weight to each call. + #[pallet::call] + impl Pallet { #[pallet::call_index(0)] #[pallet::weight(10_000)] diff --git a/pallets/ibp-service/src/lib.rs b/pallets/ibp-service/src/lib.rs index 1323ff2..155bd8e 100644 --- a/pallets/ibp-service/src/lib.rs +++ b/pallets/ibp-service/src/lib.rs @@ -10,8 +10,6 @@ use frame_support::{ BoundedVec, }; -pub use pallet::*; - // FRAME pallets require their own "mock runtimes" to be able to run unit tests. This module // contains a mock runtime specific for testing this pallet's functionality. #[cfg(test)] @@ -366,3 +364,5 @@ pub mod pallet { } } + +pub use pallet::*; diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index a9e15bb..42fd41e 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -77,6 +77,7 @@ pallet-template = { path = "../pallets/template", default-features = false } pallet-ibp-member = { path = "../pallets/ibp-member", default-features = false } pallet-ibp-service = { path = "../pallets/ibp-service", default-features = false } pallet-ibp-check = { path = "../pallets/ibp-check", default-features = false } +pallet-ibp-alert = { path = "../pallets/ibp-alert", default-features = false } [build-dependencies] substrate-wasm-builder = { git = "https://github.com/paritytech/polkadot-sdk.git", tag = "polkadot-v1.9.0", optional = true } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 5f4dbea..2ec1eca 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -47,6 +47,8 @@ pub use pallet_template; /// Import the IBP Member pallet. pub use pallet_ibp_member; pub use pallet_ibp_service; +pub use pallet_ibp_check; +pub use pallet_ibp_alert; /// An index to a block. pub type BlockNumber = u32; @@ -278,6 +280,12 @@ impl pallet_ibp_check::Config for Runtime { type WeightInfo = pallet_ibp_check::weights::SubstrateWeight; } +/// Configure the IBP Alert pallet in pallets/ibp-alert. +impl pallet_ibp_alert::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + // type WeightInfo = pallet_ibp_alert::weights::SubstrateWeight; +} + // Create the runtime by composing the FRAME pallets that were previously configured. #[frame_support::runtime] mod runtime { @@ -332,6 +340,10 @@ mod runtime { #[runtime::pallet_index(10)] pub type IbpCheck = pallet_ibp_check; + // Include the custom logic from the IBP Alert pallet in the runtime. + #[runtime::pallet_index(11)] + pub type IbpAlert = pallet_ibp_alert; + } /// The address format for describing accounts.