From e3dbd429e7c78629a10b2decdda878e3a6bde883 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Fri, 17 Feb 2023 13:06:23 +0100 Subject: [PATCH 01/23] WIP --- gn-pallets/pallet-oracle/src/benchmarking.rs | 48 ++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/gn-pallets/pallet-oracle/src/benchmarking.rs b/gn-pallets/pallet-oracle/src/benchmarking.rs index 8b137891..17466eab 100644 --- a/gn-pallets/pallet-oracle/src/benchmarking.rs +++ b/gn-pallets/pallet-oracle/src/benchmarking.rs @@ -1 +1,49 @@ +use super::*; +use crate::Pallet as Oracle; +use frame_benchmarking::{benchmarks, whitelisted_caller}; +use frame_system::RawOrigin; + +benchmarks! { + register_operator { + let caller: T::AccountId = whitelisted_caller(); + }: _(RawOrigin::Signed(caller)) + verify { + assert_eq!(Oracle::::operators()[0], caller); + } + deregister_operator { + let operator: T::AccountId = whitelisted_caller(); + Oracle::::register_operator(RawOrigin::Signed(operator.clone()).into())?; + assert_eq!(Oracle::::operators()[0], caller); + }: _(RawOrigin::Signed(operator)) + verify { + } + // TODO it's hard to benchmark these as they are taking dynamic inputs + // and they are coupled with other pallets + //initiate_request { + // let caller: T::AccountId = whitelisted_caller(); + // let operator: T::AccountId = account("operator", 1, 123); + + // Oracle::::register_operator(RawOrigin::Signed(operator.clone()).into())?; + + // let spec_index = vec![0; 5]; + // let data_version = 987_u64; + // let data = ["this", "and", "that"].encode(); + // let fee = T::Currency::minimum_balance(); + //}: _(RawOrigin::Signed(caller), operator, spec_index, data_version, data, fee, + //verify { + //} + //callback { + // let b in 0..1000; + + // let caller: T::AccountId = whitelisted_caller(); + // let request_id = 128_u64; + // let operator: T::AccountId = account("operator", 1, 123); + + // Oracle::::register_operator(RawOrigin::Signed(operator.clone()).into())?; + // // TODO should add an initiate request + + //}: _(RawOrigin::Signed(caller), request_id, vec![0; b as usize]) + //verify { + //} +} From ea915bcc29667499fc2124461d19c3426b593bc2 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Mon, 20 Feb 2023 10:23:55 +0100 Subject: [PATCH 02/23] WIP. --- gn-pallets/pallet-oracle/Cargo.toml | 17 ++-- gn-pallets/pallet-oracle/src/benchmark.rs | 57 +++++++++++++ gn-pallets/pallet-oracle/src/benchmarking.rs | 49 ----------- gn-pallets/pallet-oracle/src/lib.rs | 52 ++++++------ gn-pallets/pallet-oracle/src/mock.rs | 20 +++-- gn-pallets/pallet-oracle/src/test/helpers.rs | 1 + gn-pallets/pallet-oracle/src/test/mod.rs | 88 ++++++++++++++------ gn-pallets/pallet-oracle/src/weights.rs | 7 ++ 8 files changed, 178 insertions(+), 113 deletions(-) create mode 100644 gn-pallets/pallet-oracle/src/benchmark.rs delete mode 100644 gn-pallets/pallet-oracle/src/benchmarking.rs diff --git a/gn-pallets/pallet-oracle/Cargo.toml b/gn-pallets/pallet-oracle/Cargo.toml index 3de19f2b..eb7e2d01 100644 --- a/gn-pallets/pallet-oracle/Cargo.toml +++ b/gn-pallets/pallet-oracle/Cargo.toml @@ -3,12 +3,14 @@ edition = "2021" name = "pallet-oracle" version = "0.0.0-alpha" -[package.metadata.docs.rs] -targets = ["x86_64-unknown-linux-gnu"] - [features] default = ["std"] -runtime-benchmarks = [] +runtime-benchmarks = [ + "frame-benchmarking/default", + "pallet-balances/default", + "sp-core/default", + "sp-runtime/default", +] std = [ "gn-common/std", "parity-scale-codec/std", @@ -27,12 +29,17 @@ gn-common = { version = "0.0.0-alpha", path = "../../gn-common", default-feature parity-scale-codec = { workspace = true, features = ["derive"] } scale-info = { workspace = true, features = ["derive"] } +# substrate pallets +pallet-balances = { workspace = true, optional = true } + # substrate frame -#frame-benchmarking = { workspace = true, optional = true } +frame-benchmarking = { workspace = true, optional = true } frame-support = { workspace = true } frame-system = { workspace = true } # substrate primitives +sp-core = { workspace = true, optional = true } +sp-runtime = { workspace = true, optional = true } sp-std = { workspace = true } [dev-dependencies] diff --git a/gn-pallets/pallet-oracle/src/benchmark.rs b/gn-pallets/pallet-oracle/src/benchmark.rs new file mode 100644 index 00000000..eda83fbe --- /dev/null +++ b/gn-pallets/pallet-oracle/src/benchmark.rs @@ -0,0 +1,57 @@ +use super::*; +use crate::Pallet as Oracle; +use crate::mock::MockCallback; + +use frame_benchmarking::{account, benchmarks, whitelisted_caller}; +use frame_system::RawOrigin; +use frame_support::dispatch::{ + DispatchResultWithPostInfo, PostDispatchInfo, UnfilteredDispatchable, +}; +use frame_support::pallet_prelude::Pays; +use frame_support::traits::Currency; +use parity_scale_codec::{Encode, Decode, EncodeLike}; +use scale_info::TypeInfo; + +const MAX_OPERATORS: u32 = 100; + +benchmarks! { + register_operator { + let n in 0 .. MAX_OPERATORS - 1 => register_operators::(n); + let operator: T::AccountId = account("operator", MAX_OPERATORS - 1, 999); + }: _(RawOrigin::Root, operator) + verify { + assert_eq!(Oracle::::operators().len(), MAX_OPERATORS as usize) + } + deregister_operator { + let n in 0 .. MAX_OPERATORS => register_operators::(n); + let operator: T::AccountId = account("operator", MAX_OPERATORS - 1, 999); + }: _(RawOrigin::Root, operator) + verify { + assert_eq!(Oracle::::operators().len(), MAX_OPERATORS as usize) + } + initiate_request { + let n in 50 .. 1000; + let caller: T::AccountId = whitelisted_caller(); + let operator: T::AccountId = account("operator", 1, 123); + + Oracle::::register_operator(RawOrigin::Root.into(), operator)?; + + let data = vec![128; n as usize]; + let fee = T::Currency::minimum_balance(); + let callback = MockCallback(std::marker::PhantomData); + }: _(RawOrigin::Signed(caller), callback, data, fee) + verify { + assert_eq!(Oracle::::request_identifier(), 1); + assert_eq!(Oracle::::next_operator(), 1); + } +} + +fn register_operators(n: u32) { + for i in 0..n { + let operator: T::AccountId = account("operator", i, 999); + Oracle::::register_operator(RawOrigin::Root.into(), operator).unwrap(); + } +} + +pub struct Pallet(crate::Pallet); +pub trait Config: crate::Config {} diff --git a/gn-pallets/pallet-oracle/src/benchmarking.rs b/gn-pallets/pallet-oracle/src/benchmarking.rs deleted file mode 100644 index 17466eab..00000000 --- a/gn-pallets/pallet-oracle/src/benchmarking.rs +++ /dev/null @@ -1,49 +0,0 @@ -use super::*; -use crate::Pallet as Oracle; - -use frame_benchmarking::{benchmarks, whitelisted_caller}; -use frame_system::RawOrigin; - -benchmarks! { - register_operator { - let caller: T::AccountId = whitelisted_caller(); - }: _(RawOrigin::Signed(caller)) - verify { - assert_eq!(Oracle::::operators()[0], caller); - } - deregister_operator { - let operator: T::AccountId = whitelisted_caller(); - Oracle::::register_operator(RawOrigin::Signed(operator.clone()).into())?; - assert_eq!(Oracle::::operators()[0], caller); - }: _(RawOrigin::Signed(operator)) - verify { - } - // TODO it's hard to benchmark these as they are taking dynamic inputs - // and they are coupled with other pallets - //initiate_request { - // let caller: T::AccountId = whitelisted_caller(); - // let operator: T::AccountId = account("operator", 1, 123); - - // Oracle::::register_operator(RawOrigin::Signed(operator.clone()).into())?; - - // let spec_index = vec![0; 5]; - // let data_version = 987_u64; - // let data = ["this", "and", "that"].encode(); - // let fee = T::Currency::minimum_balance(); - //}: _(RawOrigin::Signed(caller), operator, spec_index, data_version, data, fee, - //verify { - //} - //callback { - // let b in 0..1000; - - // let caller: T::AccountId = whitelisted_caller(); - // let request_id = 128_u64; - // let operator: T::AccountId = account("operator", 1, 123); - - // Oracle::::register_operator(RawOrigin::Signed(operator.clone()).into())?; - // // TODO should add an initiate request - - //}: _(RawOrigin::Signed(caller), request_id, vec![0; b as usize]) - //verify { - //} -} diff --git a/gn-pallets/pallet-oracle/src/lib.rs b/gn-pallets/pallet-oracle/src/lib.rs index ad2eeffb..55872970 100644 --- a/gn-pallets/pallet-oracle/src/lib.rs +++ b/gn-pallets/pallet-oracle/src/lib.rs @@ -20,8 +20,8 @@ #![deny(unused_crate_dependencies)] #[cfg(feature = "runtime-benchmarks")] -mod benchmarking; -#[cfg(test)] +mod benchmark; +#[cfg(any(test, feature = "runtime-benchmarks"))] mod mock; #[cfg(test)] mod test; @@ -58,6 +58,8 @@ pub mod pallet { // Period during which a request is valid #[pallet::constant] type ValidityPeriod: Get; + #[pallet::constant] + type MaxOperators: Get; type WeightInfo: WeightInfo; } @@ -89,6 +91,8 @@ pub mod pallet { InsufficientFee, /// Reserved balance is less than the specified fee for the request InsufficientReservedBalance, + /// Max allowed number of operators already registered + MaxOperatorsRegistered, } #[pallet::event] @@ -173,20 +177,19 @@ pub mod pallet { #[pallet::call] impl Pallet { /// Register a new Operator. - /// - /// Fails with `OperatorAlreadyRegistered` if this Operator (identified - /// by `origin`) has already been registered. #[pallet::call_index(0)] #[pallet::weight(T::WeightInfo::register_operator())] - pub fn register_operator(origin: OriginFor) -> DispatchResult { - let who: ::AccountId = ensure_signed(origin)?; + pub fn register_operator(origin: OriginFor, operator: T::AccountId) -> DispatchResult { + ensure_root(origin)?; Operators::::try_mutate(|operators| { - if operators.binary_search(&who).is_ok() { + if operators.len() == T::MaxOperators::get() as usize { + Err(Error::::MaxOperatorsRegistered.into()) + } else if operators.binary_search(&operator).is_ok() { Err(Error::::OperatorAlreadyRegistered.into()) } else { - operators.push(who.clone()); - Self::deposit_event(Event::OperatorRegistered(who)); + operators.push(operator.clone()); + Self::deposit_event(Event::OperatorRegistered(operator)); Ok(()) } }) @@ -195,11 +198,11 @@ pub mod pallet { /// Deregisters an already registered Operator #[pallet::call_index(1)] #[pallet::weight(T::WeightInfo::deregister_operator())] - pub fn deregister_operator(origin: OriginFor) -> DispatchResult { - let who: ::AccountId = ensure_signed(origin)?; + pub fn deregister_operator(origin: OriginFor, operator: T::AccountId) -> DispatchResult { + ensure_root(origin)?; Operators::::try_mutate(|operators| { - if let Ok(index) = operators.binary_search(&who) { + if let Ok(index) = operators.binary_search(&operator) { Self::deposit_event(Event::OperatorDeregistered(operators.remove(index))); Ok(()) } else { @@ -220,16 +223,15 @@ pub mod pallet { /// to listen to `OracleRequest` events. This event contains all the /// required information to perform the request and provide back /// the result. - // TODO check weight #[pallet::call_index(2)] - #[pallet::weight(50_000)] + #[pallet::weight(T::WeightInfo::initiate_request())] pub fn initiate_request( origin: OriginFor, callback: ::Callback, data: Vec, fee: BalanceOf, ) -> DispatchResult { - let who: ::AccountId = ensure_signed(origin)?; + let requester = ensure_signed(origin)?; let operators = Operators::::get(); if operators.is_empty() { @@ -246,7 +248,7 @@ pub mod pallet { // amount of fee is a good idea to disincentivize spam requests ensure!(fee >= T::MinimumFee::get(), Error::::InsufficientFee); - T::Currency::reserve(&who, fee)?; + T::Currency::reserve(&requester, fee)?; let request_id = NextRequestIdentifier::::get(); // Using `wrapping_add` to start at 0 when it reaches `u64::max_value()`. @@ -260,7 +262,7 @@ pub mod pallet { let now = frame_system::Pallet::::block_number(); let request = OracleRequest:: { - requester: who, + requester, operator: operator.clone(), callback: callback.clone(), data, @@ -285,23 +287,17 @@ pub mod pallet { /// back the result. Result is then dispatched back to the originator's /// callback. The fee reserved during `initiate_request` is transferred /// as soon as this callback is called. - //TODO check weight #[pallet::call_index(3)] - #[pallet::weight(50_000)] + #[pallet::weight((0, DispatchClass::Operational, Pays::No))] pub fn callback( origin: OriginFor, request_id: RequestIdentifier, result: Vec, ) -> DispatchResult { - let who: ::AccountId = ensure_signed(origin)?; + let signer = ensure_signed(origin)?; - ensure!( - Requests::::contains_key(request_id), - Error::::UnknownRequest - ); - // Unwrap is fine here because we check its existence in the previous line - let request = Requests::::get(request_id).unwrap(); - ensure!(request.operator == who, Error::::WrongOperator); + let request = Requests::::get(request_id).ok_or(Error::::UnknownRequest)?; + ensure!(request.operator == signer, Error::::WrongOperator); // NOTE: This should not be possible technically but it is here to be safe ensure!( diff --git a/gn-pallets/pallet-oracle/src/mock.rs b/gn-pallets/pallet-oracle/src/mock.rs index a39b0558..b1768be9 100644 --- a/gn-pallets/pallet-oracle/src/mock.rs +++ b/gn-pallets/pallet-oracle/src/mock.rs @@ -32,6 +32,7 @@ parameter_types! { pub const ExistentialDeposit: Balance = 1; pub const MinimumFee: Balance = 1; pub const ValidityPeriod: u64 = 10; + pub const MaxOperators: u32 = 4; } impl frame_system::Config for TestRuntime { @@ -77,27 +78,28 @@ impl pallet_oracle::Config for TestRuntime { type WeightInfo = (); type RuntimeEvent = RuntimeEvent; type Currency = pallet_balances::Pallet; - type Callback = MockCallback; + type Callback = MockCallback; type ValidityPeriod = ValidityPeriod; + type MaxOperators = MaxOperators; type MinimumFee = MinimumFee; } #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeInfo, Encode, Decode)] -pub struct MockCallback(pub bool); +pub struct MockCallback(pub std::marker::PhantomData); -impl EncodeLike for MockCallback {} +impl EncodeLike<()> for MockCallback {} -impl pallet_oracle::CallbackWithParameter for MockCallback { +impl pallet_oracle::CallbackWithParameter for MockCallback { fn with_result(&self, result: SpVec) -> Option { if result == [0, 0] { None } else { - Some(Self(true)) + Some(Self(std::marker::PhantomData)) } } } -impl UnfilteredDispatchable for MockCallback { +impl UnfilteredDispatchable for MockCallback { type RuntimeOrigin = ::RuntimeOrigin; fn dispatch_bypass_filter(self, _origin: Self::RuntimeOrigin) -> DispatchResultWithPostInfo { Ok(PostDispatchInfo { @@ -106,3 +108,9 @@ impl UnfilteredDispatchable for MockCallback { }) } } + +impl MockCallback { + pub fn new() -> Self { + Self(std::marker::PhantomData) + } +} diff --git a/gn-pallets/pallet-oracle/src/test/helpers.rs b/gn-pallets/pallet-oracle/src/test/helpers.rs index 94e61cc5..8769db65 100644 --- a/gn-pallets/pallet-oracle/src/test/helpers.rs +++ b/gn-pallets/pallet-oracle/src/test/helpers.rs @@ -39,6 +39,7 @@ pub fn minimum_fee() -> ::Balance { pub fn error_msg<'a>(error: DispatchError) -> &'a str { match error { DispatchError::Module(module_error) => module_error.message.unwrap(), + DispatchError::BadOrigin => "BadOrigin", _ => panic!("unexpected error"), } } diff --git a/gn-pallets/pallet-oracle/src/test/mod.rs b/gn-pallets/pallet-oracle/src/test/mod.rs index 16e66c7f..d39e38c0 100644 --- a/gn-pallets/pallet-oracle/src/test/mod.rs +++ b/gn-pallets/pallet-oracle/src/test/mod.rs @@ -6,6 +6,35 @@ use frame_support::traits::OnFinalize; use pallet_oracle::Event as OracleEvent; use parity_scale_codec::{Decode, Encode}; +#[test] +fn operator_management_by_non_root_origin_fails() { + new_test_ext().execute_with(|| { + System::set_block_number(1); + let failing_transactions = vec![ + ( + ::register_operator(RuntimeOrigin::none(), 0), + "BadOrigin", + ), + ( + ::register_operator(RuntimeOrigin::signed(0), 0), + "BadOrigin", + ), + ( + ::deregister_operator(RuntimeOrigin::none(), 0), + "BadOrigin", + ), + ( + ::deregister_operator(RuntimeOrigin::signed(1), 0), + "BadOrigin", + ), + ]; + + for (tx, raw_error_msg) in failing_transactions { + assert_eq!(error_msg(tx.unwrap_err()), raw_error_msg); + } + }); +} + #[test] fn operator_registration_valid() { new_test_ext().execute_with(|| { @@ -13,7 +42,7 @@ fn operator_registration_valid() { System::set_block_number(1); assert!(::operators().is_empty()); - assert!(::register_operator(RuntimeOrigin::signed(1)).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), 1).is_ok()); assert_eq!(last_event(), OracleEvent::OperatorRegistered(1)); assert_eq!(::operators(), vec![1]); }); @@ -22,24 +51,24 @@ fn operator_registration_valid() { #[test] fn operator_registration_invalid_operator_already_registered() { new_test_ext().execute_with(|| { - assert!(::register_operator(RuntimeOrigin::signed(1)).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), 1).is_ok()); assert_eq!(::operators(), vec![1]); // Operator already registered error - let error = ::register_operator(RuntimeOrigin::signed(1)).unwrap_err(); + let error = ::register_operator(RuntimeOrigin::root(), 1).unwrap_err(); assert_eq!(error_msg(error), "OperatorAlreadyRegistered"); assert_eq!(::operators(), vec![1]); }); } #[test] -fn operator_unregistration_valid() { +fn operator_deregistration_valid() { new_test_ext().execute_with(|| { // This is required for some reason otherwise the last_event() method fails System::set_block_number(1); - assert!(::register_operator(RuntimeOrigin::signed(1)).is_ok()); - assert!(::deregister_operator(RuntimeOrigin::signed(1)).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), 1).is_ok()); + assert!(::deregister_operator(RuntimeOrigin::root(), 1).is_ok()); assert!(::operators().is_empty()); assert_eq!(last_event(), OracleEvent::OperatorDeregistered(1)); @@ -50,7 +79,7 @@ fn operator_unregistration_valid() { fn operator_unregistration_invalid_unknown_operator() { new_test_ext().execute_with(|| { // Unknown operator error - let error = ::deregister_operator(RuntimeOrigin::signed(1)).unwrap_err(); + let error = ::deregister_operator(RuntimeOrigin::root(), 1).unwrap_err(); assert_eq!(error_msg(error), "UnknownOperator"); assert!(::operators().is_empty()); }); @@ -60,14 +89,14 @@ fn operator_unregistration_invalid_unknown_operator() { fn initiate_requests_valid() { new_test_ext().execute_with(|| { System::set_block_number(1); - let callback = MockCallback(false); + let callback = MockCallback::new(); let fee = minimum_fee(); let parameters = ("a", "b"); let data = parameters.encode(); let result = vec![10, 0, 0, 0]; let request_id = 0; - assert!(::register_operator(RuntimeOrigin::signed(ACCOUNT_0)).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); assert_eq!(last_event(), OracleEvent::OperatorRegistered(ACCOUNT_0)); assert!(::initiate_request( @@ -111,19 +140,28 @@ fn linear_request_delegation() { new_test_ext().execute_with(|| { System::set_block_number(1); + let operator = 9; let operator_0 = 10; let operator_1 = 11; let operator_2 = 12; let operator_3 = 13; let data = vec![]; - let callback = MockCallback(true); + let callback = MockCallback::new(); let fee = minimum_fee(); let mut request_id = 0; - assert!(::register_operator(RuntimeOrigin::signed(operator_0)).is_ok()); - assert!(::register_operator(RuntimeOrigin::signed(operator_1)).is_ok()); - assert!(::register_operator(RuntimeOrigin::signed(operator_2)).is_ok()); - assert!(::register_operator(RuntimeOrigin::signed(operator_3)).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), operator).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), operator_0).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), operator_1).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), operator_2).is_ok()); + assert_eq!( + error_msg( + ::register_operator(RuntimeOrigin::root(), operator_3).unwrap_err() + ), + "MaxOperatorsRegistered" + ); + assert!(::deregister_operator(RuntimeOrigin::root(), operator).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), operator_3).is_ok()); assert!(::initiate_request( RuntimeOrigin::signed(ACCOUNT_0), @@ -223,7 +261,7 @@ fn initiate_requests_invalid_unknown_operator() { new_test_ext().execute_with(|| { let error = ::initiate_request( RuntimeOrigin::signed(ACCOUNT_0), - MockCallback(false), + MockCallback::new(), vec![], minimum_fee(), ) @@ -235,10 +273,10 @@ fn initiate_requests_invalid_unknown_operator() { #[test] fn initiate_requests_invalid_insufficient_fee() { new_test_ext().execute_with(|| { - assert!(::register_operator(RuntimeOrigin::signed(ACCOUNT_0)).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); let error = ::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), - MockCallback(true), + MockCallback::new(), vec![], minimum_fee() - 1, ) @@ -251,10 +289,10 @@ fn initiate_requests_invalid_insufficient_fee() { #[test] fn initiate_requests_invalid_insufficient_balance_for_fee() { new_test_ext().execute_with(|| { - assert!(::register_operator(RuntimeOrigin::signed(ACCOUNT_0)).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); let error = ::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), - MockCallback(true), + MockCallback::new(), vec![], GENESIS_BALANCE + 1, ) @@ -266,10 +304,10 @@ fn initiate_requests_invalid_insufficient_balance_for_fee() { #[test] fn initiate_requests_invalid_wrong_operator() { new_test_ext().execute_with(|| { - assert!(::register_operator(RuntimeOrigin::signed(ACCOUNT_0)).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); assert!(::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), - MockCallback(true), + MockCallback::new(), vec![], minimum_fee(), ) @@ -291,10 +329,10 @@ fn unknown_request() { #[test] fn unknown_callback() { new_test_ext().execute_with(|| { - assert!(::register_operator(RuntimeOrigin::signed(ACCOUNT_0)).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); assert!(::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), - MockCallback(true), + MockCallback::new(), vec![], minimum_fee(), ) @@ -314,10 +352,10 @@ fn kill_request() { new_test_ext().execute_with(|| { let request_id = 0; - assert!(::register_operator(RuntimeOrigin::signed(ACCOUNT_0)).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); assert!(::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), - MockCallback(false), + MockCallback::new(), vec![], minimum_fee(), ) diff --git a/gn-pallets/pallet-oracle/src/weights.rs b/gn-pallets/pallet-oracle/src/weights.rs index 120c12ab..72d47ab5 100644 --- a/gn-pallets/pallet-oracle/src/weights.rs +++ b/gn-pallets/pallet-oracle/src/weights.rs @@ -54,6 +54,7 @@ use sp_std::marker::PhantomData; pub trait WeightInfo { fn register_operator() -> Weight; fn deregister_operator() -> Weight; + fn initiate_request() -> Weight; } /// Weights for pallet_oracle using the Substrate node and recommended hardware. @@ -71,6 +72,9 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + fn initiate_request() -> Weight { + Weight::from_parts(16_862_000, 16_862_000) + } } // For backwards compatibility and tests @@ -87,4 +91,7 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().writes(1)) } + fn initiate_request() -> Weight { + Weight::from_parts(16_862_000, 16_862_000) + } } From c27fa29051c2fe4e887549a439958541f8391937 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Mon, 20 Feb 2023 13:18:12 +0100 Subject: [PATCH 03/23] Oracle pallet benchmarks done. --- gn-pallets/pallet-oracle/Cargo.toml | 2 + gn-pallets/pallet-oracle/src/benchmark.rs | 55 ++++++++++++-------- gn-pallets/pallet-oracle/src/lib.rs | 4 +- gn-pallets/pallet-oracle/src/mock.rs | 29 ++++++++++- gn-pallets/pallet-oracle/src/test/helpers.rs | 17 ------ gn-pallets/pallet-oracle/src/test/mod.rs | 27 +++++++--- 6 files changed, 83 insertions(+), 51 deletions(-) diff --git a/gn-pallets/pallet-oracle/Cargo.toml b/gn-pallets/pallet-oracle/Cargo.toml index eb7e2d01..18529303 100644 --- a/gn-pallets/pallet-oracle/Cargo.toml +++ b/gn-pallets/pallet-oracle/Cargo.toml @@ -9,6 +9,7 @@ runtime-benchmarks = [ "frame-benchmarking/default", "pallet-balances/default", "sp-core/default", + "sp-io/default", "sp-runtime/default", ] std = [ @@ -40,6 +41,7 @@ frame-system = { workspace = true } # substrate primitives sp-core = { workspace = true, optional = true } sp-runtime = { workspace = true, optional = true } +sp-io = { workspace = true, optional = true } sp-std = { workspace = true } [dev-dependencies] diff --git a/gn-pallets/pallet-oracle/src/benchmark.rs b/gn-pallets/pallet-oracle/src/benchmark.rs index eda83fbe..46055e74 100644 --- a/gn-pallets/pallet-oracle/src/benchmark.rs +++ b/gn-pallets/pallet-oracle/src/benchmark.rs @@ -1,57 +1,66 @@ use super::*; use crate::Pallet as Oracle; -use crate::mock::MockCallback; use frame_benchmarking::{account, benchmarks, whitelisted_caller}; -use frame_system::RawOrigin; -use frame_support::dispatch::{ - DispatchResultWithPostInfo, PostDispatchInfo, UnfilteredDispatchable, -}; -use frame_support::pallet_prelude::Pays; use frame_support::traits::Currency; -use parity_scale_codec::{Encode, Decode, EncodeLike}; -use scale_info::TypeInfo; +use frame_system::RawOrigin; +use sp_core::Get; -const MAX_OPERATORS: u32 = 100; +const ACCOUNT: &str = "operator"; +const SEED: u32 = 999; benchmarks! { register_operator { - let n in 0 .. MAX_OPERATORS - 1 => register_operators::(n); - let operator: T::AccountId = account("operator", MAX_OPERATORS - 1, 999); + let max_operators = ::MaxOperators::get(); + let n in 1 .. ::MaxOperators::get() - 1 => register_operators::(n); + let operator: T::AccountId = account(ACCOUNT, max_operators - 1, SEED); }: _(RawOrigin::Root, operator) verify { - assert_eq!(Oracle::::operators().len(), MAX_OPERATORS as usize) + assert_eq!(Oracle::::operators().len(), (n + 1) as usize); } deregister_operator { - let n in 0 .. MAX_OPERATORS => register_operators::(n); - let operator: T::AccountId = account("operator", MAX_OPERATORS - 1, 999); + let max_operators = ::MaxOperators::get(); + let n in 1 .. ::MaxOperators::get(); + let operator = register_operators::(n); }: _(RawOrigin::Root, operator) verify { - assert_eq!(Oracle::::operators().len(), MAX_OPERATORS as usize) + assert_eq!(Oracle::::operators().len(), (n - 1) as usize) } initiate_request { let n in 50 .. 1000; let caller: T::AccountId = whitelisted_caller(); - let operator: T::AccountId = account("operator", 1, 123); + let operator: T::AccountId = account(ACCOUNT, 1, SEED); + + T::Currency::make_free_balance_be( + &caller, + >::Balance::from(100u32) + ); Oracle::::register_operator(RawOrigin::Root.into(), operator)?; let data = vec![128; n as usize]; let fee = T::Currency::minimum_balance(); - let callback = MockCallback(std::marker::PhantomData); + let callback = crate::mock::MockCallback::::new(); }: _(RawOrigin::Signed(caller), callback, data, fee) verify { assert_eq!(Oracle::::request_identifier(), 1); assert_eq!(Oracle::::next_operator(), 1); } + + impl_benchmark_test_suite!(Oracle, crate::mock::new_test_ext(), crate::mock::TestRuntime, extra = false); } -fn register_operators(n: u32) { - for i in 0..n { - let operator: T::AccountId = account("operator", i, 999); +fn register_operators(n: u32) -> T::AccountId { + let operators: Vec = (0..n) + .into_iter() + .map(|i| account(ACCOUNT, i, SEED)) + .collect(); + + let operator_0 = operators[0].clone(); + + for operator in operators { Oracle::::register_operator(RawOrigin::Root.into(), operator).unwrap(); } -} -pub struct Pallet(crate::Pallet); -pub trait Config: crate::Config {} + operator_0 +} diff --git a/gn-pallets/pallet-oracle/src/lib.rs b/gn-pallets/pallet-oracle/src/lib.rs index 55872970..4a2129e5 100644 --- a/gn-pallets/pallet-oracle/src/lib.rs +++ b/gn-pallets/pallet-oracle/src/lib.rs @@ -28,7 +28,7 @@ mod test; mod weights; pub use pallet::*; - + #[frame_support::pallet] pub mod pallet { use super::weights::WeightInfo; @@ -189,6 +189,7 @@ pub mod pallet { Err(Error::::OperatorAlreadyRegistered.into()) } else { operators.push(operator.clone()); + operators.sort(); // needed for binary search Self::deposit_event(Event::OperatorRegistered(operator)); Ok(()) } @@ -200,7 +201,6 @@ pub mod pallet { #[pallet::weight(T::WeightInfo::deregister_operator())] pub fn deregister_operator(origin: OriginFor, operator: T::AccountId) -> DispatchResult { ensure_root(origin)?; - Operators::::try_mutate(|operators| { if let Ok(index) = operators.binary_search(&operator) { Self::deposit_event(Event::OperatorDeregistered(operators.remove(index))); diff --git a/gn-pallets/pallet-oracle/src/mock.rs b/gn-pallets/pallet-oracle/src/mock.rs index b1768be9..b419cc90 100644 --- a/gn-pallets/pallet-oracle/src/mock.rs +++ b/gn-pallets/pallet-oracle/src/mock.rs @@ -1,3 +1,7 @@ +// This is to suppress weird unused warnings when run with the +// `runtime-benchmarks` feature flag enabled. It probably emanates from the +// `impl_benchmark_test_suite` macro. +//#![cfg_attr(feature = "runtime-benchmarks", allow(unused))] pub use crate as pallet_oracle; use frame_support::dispatch::{ @@ -109,8 +113,31 @@ impl UnfilteredDispatchable for MockCallback { } } +impl MockCallback { + pub fn new() -> ::Callback { + Decode::decode(&mut &[][..]).unwrap() + } +} + impl MockCallback { - pub fn new() -> Self { + pub fn test() -> Self { Self(std::marker::PhantomData) } } + +pub const GENESIS_BALANCE: ::Balance = 10; +pub const ACCOUNT_0: ::AccountId = 0; +pub const ACCOUNT_1: ::AccountId = 1; + +pub fn new_test_ext() -> sp_io::TestExternalities { + let mut storage = frame_system::GenesisConfig::default() + .build_storage::() + .unwrap(); + pallet_balances::GenesisConfig:: { + balances: vec![(ACCOUNT_0, GENESIS_BALANCE), (ACCOUNT_1, GENESIS_BALANCE)], + } + .assimilate_storage(&mut storage) + .unwrap(); + + sp_io::TestExternalities::new(storage) +} diff --git a/gn-pallets/pallet-oracle/src/test/helpers.rs b/gn-pallets/pallet-oracle/src/test/helpers.rs index 8769db65..f46b986a 100644 --- a/gn-pallets/pallet-oracle/src/test/helpers.rs +++ b/gn-pallets/pallet-oracle/src/test/helpers.rs @@ -1,23 +1,6 @@ use super::{pallet_oracle, RuntimeEvent, System, TestRuntime}; use frame_support::dispatch::DispatchError; -pub const GENESIS_BALANCE: ::Balance = 10; -pub const ACCOUNT_0: ::AccountId = 0; -pub const ACCOUNT_1: ::AccountId = 1; - -pub fn new_test_ext() -> sp_io::TestExternalities { - let mut storage = frame_system::GenesisConfig::default() - .build_storage::() - .unwrap(); - pallet_balances::GenesisConfig:: { - balances: vec![(ACCOUNT_0, GENESIS_BALANCE), (ACCOUNT_1, GENESIS_BALANCE)], - } - .assimilate_storage(&mut storage) - .unwrap(); - - sp_io::TestExternalities::new(storage) -} - pub fn last_event() -> pallet_oracle::Event { System::events() .into_iter() diff --git a/gn-pallets/pallet-oracle/src/test/mod.rs b/gn-pallets/pallet-oracle/src/test/mod.rs index d39e38c0..ad98617b 100644 --- a/gn-pallets/pallet-oracle/src/test/mod.rs +++ b/gn-pallets/pallet-oracle/src/test/mod.rs @@ -58,6 +58,9 @@ fn operator_registration_invalid_operator_already_registered() { let error = ::register_operator(RuntimeOrigin::root(), 1).unwrap_err(); assert_eq!(error_msg(error), "OperatorAlreadyRegistered"); assert_eq!(::operators(), vec![1]); + + assert!(::register_operator(RuntimeOrigin::root(), 0).is_ok()); + assert_eq!(::operators(), vec![0, 1]); }); } @@ -72,6 +75,14 @@ fn operator_deregistration_valid() { assert!(::operators().is_empty()); assert_eq!(last_event(), OracleEvent::OperatorDeregistered(1)); + + assert!(::register_operator(RuntimeOrigin::root(), 2).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), 0).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), 1).is_ok()); + assert!(::deregister_operator(RuntimeOrigin::root(), 0).is_ok()); + assert_eq!(::operators(), vec![1, 2]); + + assert_eq!(last_event(), OracleEvent::OperatorDeregistered(0)); }); } @@ -89,7 +100,7 @@ fn operator_unregistration_invalid_unknown_operator() { fn initiate_requests_valid() { new_test_ext().execute_with(|| { System::set_block_number(1); - let callback = MockCallback::new(); + let callback = MockCallback::test(); let fee = minimum_fee(); let parameters = ("a", "b"); let data = parameters.encode(); @@ -146,7 +157,7 @@ fn linear_request_delegation() { let operator_2 = 12; let operator_3 = 13; let data = vec![]; - let callback = MockCallback::new(); + let callback = MockCallback::test(); let fee = minimum_fee(); let mut request_id = 0; @@ -261,7 +272,7 @@ fn initiate_requests_invalid_unknown_operator() { new_test_ext().execute_with(|| { let error = ::initiate_request( RuntimeOrigin::signed(ACCOUNT_0), - MockCallback::new(), + MockCallback::test(), vec![], minimum_fee(), ) @@ -276,7 +287,7 @@ fn initiate_requests_invalid_insufficient_fee() { assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); let error = ::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), - MockCallback::new(), + MockCallback::test(), vec![], minimum_fee() - 1, ) @@ -292,7 +303,7 @@ fn initiate_requests_invalid_insufficient_balance_for_fee() { assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); let error = ::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), - MockCallback::new(), + MockCallback::test(), vec![], GENESIS_BALANCE + 1, ) @@ -307,7 +318,7 @@ fn initiate_requests_invalid_wrong_operator() { assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); assert!(::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), - MockCallback::new(), + MockCallback::test(), vec![], minimum_fee(), ) @@ -332,7 +343,7 @@ fn unknown_callback() { assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); assert!(::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), - MockCallback::new(), + MockCallback::test(), vec![], minimum_fee(), ) @@ -355,7 +366,7 @@ fn kill_request() { assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); assert!(::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), - MockCallback::new(), + MockCallback::test(), vec![], minimum_fee(), ) From 3c5b6b52ab4adbc87ccfadf8953e400bb58b2462 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Mon, 20 Feb 2023 14:08:00 +0100 Subject: [PATCH 04/23] WIP pallet_guild benchmarking --- gn-pallets/pallet-guild/Cargo.toml | 7 ++- gn-pallets/pallet-guild/src/benchmark.rs | 44 +++++++++++++++++++ gn-pallets/pallet-guild/src/benchmarking.rs | 1 - gn-pallets/pallet-guild/src/lib.rs | 2 +- gn-pallets/pallet-guild/src/mock.rs | 8 ++++ gn-pallets/pallet-guild/src/test/helpers.rs | 7 --- .../pallet-guild/src/test/join_and_leave.rs | 4 +- gn-pallets/pallet-guild/src/test/register.rs | 4 +- gn-pallets/pallet-oracle/src/mock.rs | 2 +- gn-runtime/src/lib.rs | 33 +++++++------- 10 files changed, 79 insertions(+), 33 deletions(-) create mode 100644 gn-pallets/pallet-guild/src/benchmark.rs delete mode 100644 gn-pallets/pallet-guild/src/benchmarking.rs diff --git a/gn-pallets/pallet-guild/Cargo.toml b/gn-pallets/pallet-guild/Cargo.toml index 7dffbc6c..2dd52b94 100644 --- a/gn-pallets/pallet-guild/Cargo.toml +++ b/gn-pallets/pallet-guild/Cargo.toml @@ -5,7 +5,10 @@ version = "0.0.0-alpha" [features] default = ["std"] -runtime-benchmarks = [] +runtime-benchmarks = [ + "frame-benchmarking/default", + "sp-core/default", +] std = [ "gn-common/std", "pallet-oracle/std", @@ -28,10 +31,12 @@ parity-scale-codec = { workspace = true, features = ["derive"] } scale-info = { workspace = true, features = ["derive"] } # substrate frame +frame-benchmarking = { workspace = true, optional = true } frame-support = { workspace = true } frame-system = { workspace = true } # substrate primitives +sp-core = { workspace = true, optional = true } sp-io = { workspace = true } sp-std = { workspace = true } diff --git a/gn-pallets/pallet-guild/src/benchmark.rs b/gn-pallets/pallet-guild/src/benchmark.rs new file mode 100644 index 00000000..1df3379b --- /dev/null +++ b/gn-pallets/pallet-guild/src/benchmark.rs @@ -0,0 +1,44 @@ +use super::*; +use crate::Pallet as Guild; + +use frame_benchmarking::{account, benchmarks, whitelisted_caller}; +use frame_system::RawOrigin; +use gn_common::identity::*; +use sp_core::Pair as PairT; + +const ACCOUNT: &str = "account"; +const SEED: u32 = 999; + +benchmarks! { + register { + let caller: T::AccountId = whitelisted_caller(); + + let seed = [12u8; 32]; + let msg = gn_common::utils::verification_msg(&caller); + let keypair = sp_core::ecdsa::Pair::from_seed_slice(&seed).unwrap(); + let signature = EcdsaSignature(keypair.sign(msg.as_ref()).0); + let pubkey = recover_prehashed(eth_hash_message(&msg), &signature).unwrap(); + let address: [u8; 20] = + sp_core::keccak_256(&pubkey.serialize_uncompressed()[1..])[12..] + .try_into() + .unwrap(); + + let identity = Identity::Address20(address); + let id_with_auth = IdentityWithAuth::Ecdsa(identity, signature); + let index = 1; + }: _(RawOrigin::Signed(caller.clone()), id_with_auth, index) + verify { + assert_eq!(Guild::::user_data(caller, index), Some(identity)); + } + create_guild { + let caller: T::AccountId = whitelisted_caller(); + let guild_name = [0u8; 32]; + let n in 0 .. 256; + let metadata = vec![0u8; n as usize]; + }: _(RawOrigin::Signed(caller), guild_name, metadata) + verify { + assert!(Guild::::guild_id(guild_name).is_some()); + } + + impl_benchmark_test_suite!(Guild, crate::mock::new_test_ext(), crate::mock::TestRuntime, extra = false); +} diff --git a/gn-pallets/pallet-guild/src/benchmarking.rs b/gn-pallets/pallet-guild/src/benchmarking.rs deleted file mode 100644 index 8b137891..00000000 --- a/gn-pallets/pallet-guild/src/benchmarking.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/gn-pallets/pallet-guild/src/lib.rs b/gn-pallets/pallet-guild/src/lib.rs index 9a29f092..53c87e19 100644 --- a/gn-pallets/pallet-guild/src/lib.rs +++ b/gn-pallets/pallet-guild/src/lib.rs @@ -6,7 +6,7 @@ pub use pallet::*; #[cfg(feature = "runtime-benchmarks")] -mod benchmarking; +mod benchmark; #[cfg(test)] mod mock; #[cfg(test)] diff --git a/gn-pallets/pallet-guild/src/mock.rs b/gn-pallets/pallet-guild/src/mock.rs index e2b39d9e..57e52c07 100644 --- a/gn-pallets/pallet-guild/src/mock.rs +++ b/gn-pallets/pallet-guild/src/mock.rs @@ -87,6 +87,7 @@ impl pallet_guild::Config for TestRuntime { impl pallet_oracle::Config for TestRuntime { type Currency = pallet_balances::Pallet; type Callback = pallet_guild::Call; + type MaxOperators = ConstU32<10>; type MinimumFee = MinimumFee; type RuntimeEvent = RuntimeEvent; type ValidityPeriod = ValidityPeriod; @@ -94,3 +95,10 @@ impl pallet_oracle::Config for TestRuntime { } impl pallet_randomness_collective_flip::Config for TestRuntime {} + +pub fn new_test_ext() -> sp_io::TestExternalities { + frame_system::GenesisConfig::default() + .build_storage::() + .unwrap() + .into() +} diff --git a/gn-pallets/pallet-guild/src/test/helpers.rs b/gn-pallets/pallet-guild/src/test/helpers.rs index d7861781..9f7006fe 100644 --- a/gn-pallets/pallet-guild/src/test/helpers.rs +++ b/gn-pallets/pallet-guild/src/test/helpers.rs @@ -7,13 +7,6 @@ const STARTING_BLOCK_NUM: u64 = 2; pub const METADATA: &[u8] = &[12u8; ::MaxSerializedLen::get() as usize]; -pub fn new_test_ext() -> sp_io::TestExternalities { - frame_system::GenesisConfig::default() - .build_storage::() - .unwrap() - .into() -} - pub fn init_chain() { for i in 0..STARTING_BLOCK_NUM { System::set_block_number(i); diff --git a/gn-pallets/pallet-guild/src/test/join_and_leave.rs b/gn-pallets/pallet-guild/src/test/join_and_leave.rs index 6db42b95..d484bd14 100644 --- a/gn-pallets/pallet-guild/src/test/join_and_leave.rs +++ b/gn-pallets/pallet-guild/src/test/join_and_leave.rs @@ -356,7 +356,7 @@ fn join_and_leave_unfiltered_role() { let role_id = ::role_id(guild_id, role_name).unwrap(); // register oracle operator - ::register_operator(RuntimeOrigin::signed(operator)).unwrap(); + ::register_operator(RuntimeOrigin::root(), operator).unwrap(); // register identity that requires oracle check ::register( RuntimeOrigin::signed(user), @@ -468,7 +468,7 @@ fn role_with_filtered_requirements() { let role_id_2 = ::role_id(guild_id, role_name_2).unwrap(); // register oracle operator - ::register_operator(RuntimeOrigin::signed(operator)).unwrap(); + ::register_operator(RuntimeOrigin::root(), operator).unwrap(); // register identity that requires oracle check ::register( diff --git a/gn-pallets/pallet-guild/src/test/register.rs b/gn-pallets/pallet-guild/src/test/register.rs index efe6293c..7ef3c261 100644 --- a/gn-pallets/pallet-guild/src/test/register.rs +++ b/gn-pallets/pallet-guild/src/test/register.rs @@ -167,7 +167,7 @@ fn successful_off_chain_registrations() { let id_auth_one = IdentityWithAuth::Other(id_one, auth); // register an operator first - ::register_operator(RuntimeOrigin::signed(operator)).unwrap(); + ::register_operator(RuntimeOrigin::root(), operator).unwrap(); // user registers id that requires off-chain verification ::register(RuntimeOrigin::signed(user), id_auth_zero, index).unwrap(); // pallet receives a dummy oracle answer @@ -223,7 +223,7 @@ fn successful_idenity_overrides() { let index = 1; // register an operator first - ::register_operator(RuntimeOrigin::signed(operator)).unwrap(); + ::register_operator(RuntimeOrigin::root(), operator).unwrap(); // user registers an off-chain-verified identity let identity_with_auth = IdentityWithAuth::Other(id_zero, auth); diff --git a/gn-pallets/pallet-oracle/src/mock.rs b/gn-pallets/pallet-oracle/src/mock.rs index b419cc90..4c90db5c 100644 --- a/gn-pallets/pallet-oracle/src/mock.rs +++ b/gn-pallets/pallet-oracle/src/mock.rs @@ -1,7 +1,7 @@ // This is to suppress weird unused warnings when run with the // `runtime-benchmarks` feature flag enabled. It probably emanates from the // `impl_benchmark_test_suite` macro. -//#![cfg_attr(feature = "runtime-benchmarks", allow(unused))] +#![cfg_attr(feature = "runtime-benchmarks", allow(unused))] pub use crate as pallet_oracle; use frame_support::dispatch::{ diff --git a/gn-runtime/src/lib.rs b/gn-runtime/src/lib.rs index b919ced2..4ddd282d 100644 --- a/gn-runtime/src/lib.rs +++ b/gn-runtime/src/lib.rs @@ -324,22 +324,21 @@ pub type Executive = frame_executive::Executive< AllPalletsWithSystem, >; -// TODO benchmarking issue -//#[cfg(feature = "runtime-benchmarks")] -//#[macro_use] -//extern crate frame_benchmarking; -// -//#[cfg(feature = "runtime-benchmarks")] -//mod benches { -// define_benchmarks!( -// [frame_benchmarking, BaselineBench::] -// [frame_system, SystemBench::] -// [pallet_balances, Balances] -// [pallet_timestamp, Timestamp] -// [pallet_guild, Guild] -// [pallet_oracle, Oracle] -// ); -//} +#[cfg(feature = "runtime-benchmarks")] +#[macro_use] +extern crate frame_benchmarking; + +#[cfg(feature = "runtime-benchmarks")] +mod benches { + define_benchmarks!( + [frame_benchmarking, BaselineBench::] + [frame_system, SystemBench::] + [pallet_balances, Balances] + [pallet_timestamp, Timestamp] + [pallet_guild, Guild] + [pallet_oracle, Oracle] + ); +} impl_runtime_apis! { impl sp_api::Core for Runtime { @@ -478,7 +477,6 @@ impl_runtime_apis! { } } - /* TODO benchmarking #[cfg(feature = "runtime-benchmarks")] impl frame_benchmarking::Benchmark for Runtime { fn benchmark_metadata(extra: bool) -> ( @@ -526,7 +524,6 @@ impl_runtime_apis! { Ok(batches) } } - */ #[cfg(all(feature = "try-runtime", feature = "std"))] impl frame_try_runtime::TryRuntime for Runtime { From 03d4a5be5eb290947241a0924c49e2d61fe1c20c Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Mon, 20 Feb 2023 18:12:27 +0100 Subject: [PATCH 05/23] Guild pallet benchmarks added. --- gn-pallets/pallet-guild/Cargo.toml | 8 + gn-pallets/pallet-guild/src/benchmark.rs | 246 ++++++++++++++++++-- gn-pallets/pallet-guild/src/lib.rs | 6 +- gn-pallets/pallet-guild/src/mock.rs | 13 ++ gn-pallets/pallet-guild/src/test/helpers.rs | 10 - gn-pallets/pallet-guild/src/test/mod.rs | 1 - gn-pallets/pallet-oracle/src/lib.rs | 4 +- gn-pallets/pallet-oracle/src/test/mod.rs | 4 +- 8 files changed, 259 insertions(+), 33 deletions(-) diff --git a/gn-pallets/pallet-guild/Cargo.toml b/gn-pallets/pallet-guild/Cargo.toml index 2dd52b94..1cf9ca1b 100644 --- a/gn-pallets/pallet-guild/Cargo.toml +++ b/gn-pallets/pallet-guild/Cargo.toml @@ -7,7 +7,10 @@ version = "0.0.0-alpha" default = ["std"] runtime-benchmarks = [ "frame-benchmarking/default", + "pallet-balances/default", + "pallet-randomness-collective-flip/default", "sp-core/default", + "sp-runtime/default", ] std = [ "gn-common/std", @@ -30,6 +33,10 @@ pallet-oracle = { version = "0.0.0-alpha", path = "../pallet-oracle", default-fe parity-scale-codec = { workspace = true, features = ["derive"] } scale-info = { workspace = true, features = ["derive"] } +# substrate pallets +pallet-balances = { workspace = true, optional = true } +pallet-randomness-collective-flip = { workspace = true, optional = true } + # substrate frame frame-benchmarking = { workspace = true, optional = true } frame-support = { workspace = true } @@ -38,6 +45,7 @@ frame-system = { workspace = true } # substrate primitives sp-core = { workspace = true, optional = true } sp-io = { workspace = true } +sp-runtime = { workspace = true, optional = true } sp-std = { workspace = true } [dev-dependencies] diff --git a/gn-pallets/pallet-guild/src/benchmark.rs b/gn-pallets/pallet-guild/src/benchmark.rs index 1df3379b..09284c01 100644 --- a/gn-pallets/pallet-guild/src/benchmark.rs +++ b/gn-pallets/pallet-guild/src/benchmark.rs @@ -3,8 +3,10 @@ use crate::Pallet as Guild; use frame_benchmarking::{account, benchmarks, whitelisted_caller}; use frame_system::RawOrigin; +use gn_common::filter::{Guild as GuildFilter, Logic as FilterLogic}; use gn_common::identity::*; -use sp_core::Pair as PairT; +use gn_common::merkle::Proof as MerkleProof; +use sp_core::{Get, Pair as PairT}; const ACCOUNT: &str = "account"; const SEED: u32 = 999; @@ -12,18 +14,7 @@ const SEED: u32 = 999; benchmarks! { register { let caller: T::AccountId = whitelisted_caller(); - - let seed = [12u8; 32]; - let msg = gn_common::utils::verification_msg(&caller); - let keypair = sp_core::ecdsa::Pair::from_seed_slice(&seed).unwrap(); - let signature = EcdsaSignature(keypair.sign(msg.as_ref()).0); - let pubkey = recover_prehashed(eth_hash_message(&msg), &signature).unwrap(); - let address: [u8; 20] = - sp_core::keccak_256(&pubkey.serialize_uncompressed()[1..])[12..] - .try_into() - .unwrap(); - - let identity = Identity::Address20(address); + let (identity, signature) = id_with_auth::(&caller); let id_with_auth = IdentityWithAuth::Ecdsa(identity, signature); let index = 1; }: _(RawOrigin::Signed(caller.clone()), id_with_auth, index) @@ -31,14 +22,241 @@ benchmarks! { assert_eq!(Guild::::user_data(caller, index), Some(identity)); } create_guild { + let n in 0 .. ::MaxSerializedLen::get(); + let caller: T::AccountId = whitelisted_caller(); let guild_name = [0u8; 32]; - let n in 0 .. 256; let metadata = vec![0u8; n as usize]; }: _(RawOrigin::Signed(caller), guild_name, metadata) verify { assert!(Guild::::guild_id(guild_name).is_some()); } + create_free_role { + let caller: T::AccountId = whitelisted_caller(); + let guild_name = [0u8; 32]; + let role_name = [0u8; 32]; + init_guild::(&caller, guild_name); + }: _(RawOrigin::Signed(caller), guild_name, role_name) + verify { + let guild_id = Guild::::guild_id(guild_name).unwrap(); + assert!(Guild::::role_id(guild_id, role_name).is_some()); + } + + create_role_with_allowlist { + let n in 1 .. ::MaxAllowlistLen::get(); + let r in 0 .. ::MaxReqsPerRole::get(); + let s in 0 .. ::MaxSerializedLen::get(); + + let caller: T::AccountId = whitelisted_caller(); + let guild_name = [0u8; 32]; + let role_name = [0u8; 32]; + init_guild::(&caller, guild_name); + + let allowlist = vec![Identity::Other([0u8; 64]); n as usize]; + let logic = vec![100u8; s as usize]; + let req = vec![200u8; s as usize]; + let serialized_requirements = (vec![req; r as usize], logic); + }: _(RawOrigin::Signed(caller), guild_name, role_name, allowlist, FilterLogic::And, Some(serialized_requirements)) + verify { + let guild_id = Guild::::guild_id(guild_name).unwrap(); + assert!(Guild::::role_id(guild_id, role_name).is_some()); + } + + create_child_role { + let r in 0 .. ::MaxReqsPerRole::get(); + let s in 0 .. ::MaxSerializedLen::get(); + + let caller: T::AccountId = whitelisted_caller(); + let guild_name = [0u8; 32]; + let role_name = [0u8; 32]; + let free_role_name = [1u8; 32]; + init_guild::(&caller, guild_name); + Guild::::create_free_role( + RawOrigin::Signed(caller.clone()).into(), + guild_name, + free_role_name, + ).unwrap(); + + let logic = vec![100u8; s as usize]; + let req = vec![200u8; s as usize]; + let serialized_requirements = (vec![req; r as usize], logic); + let filter = GuildFilter { + name: guild_name, + role: Some(free_role_name), + }; + }: _(RawOrigin::Signed(caller), guild_name, role_name, filter, FilterLogic::And, Some(serialized_requirements)) + verify { + let guild_id = Guild::::guild_id(guild_name).unwrap(); + assert!(Guild::::role_id(guild_id, role_name).is_some()); + } + + create_unfiltered_role { + let r in 0 .. ::MaxReqsPerRole::get(); + let s in 0 .. ::MaxSerializedLen::get(); + + let caller: T::AccountId = whitelisted_caller(); + let guild_name = [0u8; 32]; + let role_name = [0u8; 32]; + init_guild::(&caller, guild_name); + let logic = vec![100u8; s as usize]; + let req = vec![200u8; s as usize]; + let serialized_requirements = (vec![req; r as usize], logic); + }: _(RawOrigin::Signed(caller), guild_name, role_name, serialized_requirements) + verify { + let guild_id = Guild::::guild_id(guild_name).unwrap(); + assert!(Guild::::role_id(guild_id, role_name).is_some()); + } + + join { + let n = ::MaxAllowlistLen::get() as usize; + + // identity + let caller: T::AccountId = whitelisted_caller(); + let (identity, signature) = id_with_auth::(&caller); + let identity_with_auth = IdentityWithAuth::Ecdsa(identity, signature); + Guild::::register( + RawOrigin::Signed(caller.clone()).into(), + identity_with_auth, + 0, + ).unwrap(); + + // guild + let guild_name = [0u8; 32]; + let role_name = [0u8; 32]; + init_guild::(&caller, guild_name); + let mut allowlist = vec![Identity::Address20([0u8; 20]); n - 1]; + allowlist.push(identity); + + Guild::::create_role_with_allowlist( + RawOrigin::Signed(caller.clone()).into(), + guild_name, + role_name, + allowlist.clone(), + FilterLogic::And, + None, + ).unwrap(); + + // proof to the last element + let proof = MerkleProof::new(&allowlist, n - 1, 0); + + }: _(RawOrigin::Signed(caller.clone()), guild_name, role_name, Some(proof)) + verify { + let guild_id = Guild::::guild_id(guild_name).unwrap(); + let role_id = Guild::::role_id(guild_id, role_name).unwrap(); + assert!(Guild::::member(role_id, caller).is_some()); + } + + leave { + let caller: T::AccountId = whitelisted_caller(); + let (identity, signature) = id_with_auth::(&caller); + let identity_with_auth = IdentityWithAuth::Ecdsa(identity, signature); + + Guild::::register( + RawOrigin::Signed(caller.clone()).into(), + identity_with_auth, + 0, + ).unwrap(); + + let guild_name = [0u8; 32]; + let role_name = [0u8; 32]; + init_guild::(&caller, guild_name); + Guild::::create_free_role( + RawOrigin::Signed(caller.clone()).into(), + guild_name, + role_name, + ).unwrap(); + + Guild::::join( + RawOrigin::Signed(caller.clone()).into(), + guild_name, + role_name, + None, + ).unwrap(); + }: _(RawOrigin::Signed(caller.clone()), guild_name, role_name) + verify { + let guild_id = Guild::::guild_id(guild_name).unwrap(); + let role_id = Guild::::role_id(guild_id, role_name).unwrap(); + assert!(Guild::::member(role_id, caller).is_none()); + } + + request_oracle_check { + let r = ::MaxReqsPerRole::get() as usize; + let s = ::MaxSerializedLen::get() as usize; + + let caller: T::AccountId = whitelisted_caller(); + let user: T::AccountId = account(ACCOUNT, 123, SEED); + let operator: T::AccountId = account(ACCOUNT, 222, SEED); + let (identity, signature) = id_with_auth::(&user); + let identity_with_auth = IdentityWithAuth::Ecdsa(identity, signature); + + pallet_oracle::Pallet::::register_operator( + RawOrigin::Root.into(), + operator.clone() + ).unwrap(); + Guild::::register( + RawOrigin::Signed(user.clone()).into(), + identity_with_auth, + 0, + ).unwrap(); + + let guild_name = [0u8; 32]; + let role_name = [0u8; 32]; + init_guild::(&user, guild_name); + + let logic = vec![100u8; s as usize]; + let req = vec![200u8; s as usize]; + let serialized_requirements = (vec![req; r as usize], logic); + + Guild::::create_unfiltered_role( + RawOrigin::Signed(user.clone()).into(), + guild_name, + role_name, + serialized_requirements, + ).unwrap(); + + Guild::::join( + RawOrigin::Signed(user.clone()).into(), + guild_name, + role_name, + None, + ).unwrap(); + + pallet_oracle::Pallet::::callback( + RawOrigin::Signed(operator).into(), + 0, + vec![1] + ).unwrap(); + + }: _(RawOrigin::Signed(caller.clone()), user.clone(), guild_name, role_name) + verify { + let guild_id = Guild::::guild_id(guild_name).unwrap(); + let role_id = Guild::::role_id(guild_id, role_name).unwrap(); + assert!(Guild::::member(role_id, user).is_some()); + } impl_benchmark_test_suite!(Guild, crate::mock::new_test_ext(), crate::mock::TestRuntime, extra = false); } + +fn init_guild(caller: &T::AccountId, guild_name: [u8; 32]) { + crate::mock::init_chain(); + let metadata = vec![0u8; ::MaxSerializedLen::get() as usize]; + Guild::::create_guild( + RawOrigin::Signed(caller.clone()).into(), + guild_name, + metadata, + ) + .unwrap(); +} + +fn id_with_auth(caller: &T::AccountId) -> (Identity, EcdsaSignature) { + let seed = [12u8; 32]; + let msg = gn_common::utils::verification_msg(&caller); + let keypair = sp_core::ecdsa::Pair::from_seed_slice(&seed).unwrap(); + let signature = EcdsaSignature(keypair.sign(msg.as_ref()).0); + let pubkey = recover_prehashed(eth_hash_message(&msg), &signature).unwrap(); + let address: [u8; 20] = sp_core::keccak_256(&pubkey.serialize_uncompressed()[1..])[12..] + .try_into() + .unwrap(); + let identity = Identity::Address20(address); + (identity, signature) +} diff --git a/gn-pallets/pallet-guild/src/lib.rs b/gn-pallets/pallet-guild/src/lib.rs index 53c87e19..3fc9d90b 100644 --- a/gn-pallets/pallet-guild/src/lib.rs +++ b/gn-pallets/pallet-guild/src/lib.rs @@ -7,7 +7,7 @@ pub use pallet::*; #[cfg(feature = "runtime-benchmarks")] mod benchmark; -#[cfg(test)] +#[cfg(any(test, feature = "runtime-benchmarks"))] mod mock; #[cfg(test)] mod test; @@ -314,7 +314,7 @@ pub mod pallet { // could unknowingly add the user without checking on-chain filters // in the callback ensure!( - Self::member(role_id, &account).is_some(), + dbg!(Self::member(role_id, &account).is_some()), Error::::InvalidOracleRequest ); let role_data = Self::role(role_id).ok_or(Error::::RoleDoesNotExist)?; @@ -456,7 +456,7 @@ pub mod pallet { } #[pallet::call_index(9)] - #[pallet::weight(0)] + #[pallet::weight((0, DispatchClass::Operational, Pays::No))] pub fn callback(origin: OriginFor, result: SerializedData) -> DispatchResult { // NOTE this ensures that only the root can call this function via // a callback, see `frame_system::RawOrigin` diff --git a/gn-pallets/pallet-guild/src/mock.rs b/gn-pallets/pallet-guild/src/mock.rs index 57e52c07..d13d697e 100644 --- a/gn-pallets/pallet-guild/src/mock.rs +++ b/gn-pallets/pallet-guild/src/mock.rs @@ -1,6 +1,11 @@ +// This is to suppress weird unused warnings when run with the +// `runtime-benchmarks` feature flag enabled. It probably emanates from the +// `impl_benchmark_test_suite` macro. +#![cfg_attr(feature = "runtime-benchmarks", allow(unused))] pub use crate as pallet_guild; use frame_support::parameter_types; +use frame_support::traits::{OnFinalize, OnInitialize}; use sp_core::H256; use sp_runtime::testing::Header; use sp_runtime::traits::{BlakeTwo256, ConstU32, ConstU64, IdentityLookup}; @@ -102,3 +107,11 @@ pub fn new_test_ext() -> sp_io::TestExternalities { .unwrap() .into() } + +pub fn init_chain() { + for i in 0..2 { + System::set_block_number(i); + >::on_initialize(i); + >::on_finalize(i); + } +} diff --git a/gn-pallets/pallet-guild/src/test/helpers.rs b/gn-pallets/pallet-guild/src/test/helpers.rs index 9f7006fe..a0ba6ce3 100644 --- a/gn-pallets/pallet-guild/src/test/helpers.rs +++ b/gn-pallets/pallet-guild/src/test/helpers.rs @@ -2,19 +2,9 @@ use super::*; use gn_common::identity::{eth_hash_message, recover_prehashed, EcdsaSignature}; use sp_core::Pair as PairT; -const STARTING_BLOCK_NUM: u64 = 2; - pub const METADATA: &[u8] = &[12u8; ::MaxSerializedLen::get() as usize]; -pub fn init_chain() { - for i in 0..STARTING_BLOCK_NUM { - System::set_block_number(i); - >::on_initialize(i); - >::on_finalize(i); - } -} - pub fn last_event() -> pallet_guild::Event { System::events() .into_iter() diff --git a/gn-pallets/pallet-guild/src/test/mod.rs b/gn-pallets/pallet-guild/src/test/mod.rs index 32538d49..f62c6451 100644 --- a/gn-pallets/pallet-guild/src/test/mod.rs +++ b/gn-pallets/pallet-guild/src/test/mod.rs @@ -8,7 +8,6 @@ use helpers::*; use crate::mock::*; type AccountId = ::AccountId; -use frame_support::traits::{OnFinalize, OnInitialize}; use gn_common::{ identity::{Identity, IdentityWithAuth}, GuildName, RequestData, diff --git a/gn-pallets/pallet-oracle/src/lib.rs b/gn-pallets/pallet-oracle/src/lib.rs index 4a2129e5..f562c4b1 100644 --- a/gn-pallets/pallet-oracle/src/lib.rs +++ b/gn-pallets/pallet-oracle/src/lib.rs @@ -28,7 +28,7 @@ mod test; mod weights; pub use pallet::*; - + #[frame_support::pallet] pub mod pallet { use super::weights::WeightInfo; @@ -185,7 +185,7 @@ pub mod pallet { Operators::::try_mutate(|operators| { if operators.len() == T::MaxOperators::get() as usize { Err(Error::::MaxOperatorsRegistered.into()) - } else if operators.binary_search(&operator).is_ok() { + } else if operators.binary_search(&operator).is_ok() { Err(Error::::OperatorAlreadyRegistered.into()) } else { operators.push(operator.clone()); diff --git a/gn-pallets/pallet-oracle/src/test/mod.rs b/gn-pallets/pallet-oracle/src/test/mod.rs index ad98617b..1e6e3d3b 100644 --- a/gn-pallets/pallet-oracle/src/test/mod.rs +++ b/gn-pallets/pallet-oracle/src/test/mod.rs @@ -166,9 +166,7 @@ fn linear_request_delegation() { assert!(::register_operator(RuntimeOrigin::root(), operator_1).is_ok()); assert!(::register_operator(RuntimeOrigin::root(), operator_2).is_ok()); assert_eq!( - error_msg( - ::register_operator(RuntimeOrigin::root(), operator_3).unwrap_err() - ), + error_msg(::register_operator(RuntimeOrigin::root(), operator_3).unwrap_err()), "MaxOperatorsRegistered" ); assert!(::deregister_operator(RuntimeOrigin::root(), operator).is_ok()); From c79da4b90d87e5167b46ef15a975d966da5e6ba6 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Mon, 20 Feb 2023 18:46:32 +0100 Subject: [PATCH 06/23] WIP runtime tests. --- gn-pallets/pallet-guild/Cargo.toml | 15 ++++++++++----- gn-pallets/pallet-guild/src/lib.rs | 2 +- gn-pallets/pallet-oracle/Cargo.toml | 15 ++++++++++----- gn-pallets/pallet-oracle/src/mock.rs | 6 +++--- gn-runtime/Cargo.toml | 1 + gn-runtime/src/lib.rs | 1 + 6 files changed, 26 insertions(+), 14 deletions(-) diff --git a/gn-pallets/pallet-guild/Cargo.toml b/gn-pallets/pallet-guild/Cargo.toml index 1cf9ca1b..4c727d0b 100644 --- a/gn-pallets/pallet-guild/Cargo.toml +++ b/gn-pallets/pallet-guild/Cargo.toml @@ -6,20 +6,25 @@ version = "0.0.0-alpha" [features] default = ["std"] runtime-benchmarks = [ - "frame-benchmarking/default", - "pallet-balances/default", - "pallet-randomness-collective-flip/default", - "sp-core/default", - "sp-runtime/default", + "frame-benchmarking/runtime-benchmarks", + "pallet-balances", + "pallet-randomness-collective-flip", + "sp-core", + "sp-runtime", ] std = [ "gn-common/std", + "pallet-balances?/std", "pallet-oracle/std", + "pallet-randomness-collective-flip?/std", "parity-scale-codec/std", "scale-info/std", + "frame-benchmarking?/std", "frame-support/std", "frame-system/std", + "sp-core?/std", "sp-io/std", + "sp-runtime?/std", "sp-std/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/gn-pallets/pallet-guild/src/lib.rs b/gn-pallets/pallet-guild/src/lib.rs index 3fc9d90b..43dac364 100644 --- a/gn-pallets/pallet-guild/src/lib.rs +++ b/gn-pallets/pallet-guild/src/lib.rs @@ -314,7 +314,7 @@ pub mod pallet { // could unknowingly add the user without checking on-chain filters // in the callback ensure!( - dbg!(Self::member(role_id, &account).is_some()), + Self::member(role_id, &account).is_some(), Error::::InvalidOracleRequest ); let role_data = Self::role(role_id).ok_or(Error::::RoleDoesNotExist)?; diff --git a/gn-pallets/pallet-oracle/Cargo.toml b/gn-pallets/pallet-oracle/Cargo.toml index 18529303..49a36449 100644 --- a/gn-pallets/pallet-oracle/Cargo.toml +++ b/gn-pallets/pallet-oracle/Cargo.toml @@ -6,18 +6,23 @@ version = "0.0.0-alpha" [features] default = ["std"] runtime-benchmarks = [ - "frame-benchmarking/default", - "pallet-balances/default", - "sp-core/default", - "sp-io/default", - "sp-runtime/default", + "frame-benchmarking/runtime-benchmarks", + "pallet-balances", + "sp-core", + "sp-io", + "sp-runtime", ] std = [ "gn-common/std", + "pallet-balances?/std", "parity-scale-codec/std", "scale-info/std", + "frame-benchmarking?/std", "frame-support/std", "frame-system/std", + "sp-core?/std", + "sp-io?/std", + "sp-runtime?/std", "sp-std/std", ] try-runtime = ["frame-support/try-runtime"] diff --git a/gn-pallets/pallet-oracle/src/mock.rs b/gn-pallets/pallet-oracle/src/mock.rs index 4c90db5c..a6c93dfa 100644 --- a/gn-pallets/pallet-oracle/src/mock.rs +++ b/gn-pallets/pallet-oracle/src/mock.rs @@ -89,7 +89,7 @@ impl pallet_oracle::Config for TestRuntime { } #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeInfo, Encode, Decode)] -pub struct MockCallback(pub std::marker::PhantomData); +pub struct MockCallback(pub core::marker::PhantomData); impl EncodeLike<()> for MockCallback {} @@ -98,7 +98,7 @@ impl pallet_oracle::CallbackWithParameter for MockCallback { if result == [0, 0] { None } else { - Some(Self(std::marker::PhantomData)) + Some(Self(core::marker::PhantomData)) } } } @@ -121,7 +121,7 @@ impl MockCallback { impl MockCallback { pub fn test() -> Self { - Self(std::marker::PhantomData) + Self(core::marker::PhantomData) } } diff --git a/gn-runtime/Cargo.toml b/gn-runtime/Cargo.toml index 23f7aacf..d0cd5c90 100644 --- a/gn-runtime/Cargo.toml +++ b/gn-runtime/Cargo.toml @@ -24,6 +24,7 @@ runtime-benchmarks = [ std = [ "parity-scale-codec/std", "scale-info/std", + "frame-benchmarking?/std", "frame-executive/std", "frame-support/std", "frame-system/std", diff --git a/gn-runtime/src/lib.rs b/gn-runtime/src/lib.rs index 4ddd282d..e7a88587 100644 --- a/gn-runtime/src/lib.rs +++ b/gn-runtime/src/lib.rs @@ -268,6 +268,7 @@ impl pallet_oracle::Config for Runtime { type Currency = Balances; type Callback = pallet_guild::Call; type RuntimeEvent = RuntimeEvent; + type MaxOperators = ConstU32<10>; type MinimumFee = MinimumFee; type ValidityPeriod = ValidityPeriod; type WeightInfo = (); From b79c6ae3d9de97ab5beb2d09b30a7d15850df4cd Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Mon, 20 Feb 2023 20:52:38 +0100 Subject: [PATCH 07/23] Benchmarks build in runtime as well. --- gn-pallets/pallet-guild/Cargo.toml | 14 +---- gn-pallets/pallet-guild/src/benchmark.rs | 63 ++++++++++--------- gn-pallets/pallet-guild/src/lib.rs | 2 +- gn-pallets/pallet-guild/src/mock.rs | 14 ++--- .../pallet-guild/src/test/guild_and_role.rs | 5 -- .../pallet-guild/src/test/join_and_leave.rs | 5 -- gn-pallets/pallet-guild/src/test/mod.rs | 2 - gn-pallets/pallet-guild/src/test/register.rs | 4 -- gn-pallets/pallet-oracle/Cargo.toml | 11 ---- gn-pallets/pallet-oracle/src/benchmark.rs | 48 +++++++++++--- gn-pallets/pallet-oracle/src/lib.rs | 2 +- 11 files changed, 85 insertions(+), 85 deletions(-) diff --git a/gn-pallets/pallet-guild/Cargo.toml b/gn-pallets/pallet-guild/Cargo.toml index 4c727d0b..458bc954 100644 --- a/gn-pallets/pallet-guild/Cargo.toml +++ b/gn-pallets/pallet-guild/Cargo.toml @@ -7,24 +7,16 @@ version = "0.0.0-alpha" default = ["std"] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", - "pallet-balances", - "pallet-randomness-collective-flip", - "sp-core", - "sp-runtime", ] std = [ "gn-common/std", - "pallet-balances?/std", "pallet-oracle/std", - "pallet-randomness-collective-flip?/std", "parity-scale-codec/std", "scale-info/std", "frame-benchmarking?/std", "frame-support/std", "frame-system/std", - "sp-core?/std", "sp-io/std", - "sp-runtime?/std", "sp-std/std", ] try-runtime = ["frame-support/try-runtime"] @@ -40,7 +32,6 @@ scale-info = { workspace = true, features = ["derive"] } # substrate pallets pallet-balances = { workspace = true, optional = true } -pallet-randomness-collective-flip = { workspace = true, optional = true } # substrate frame frame-benchmarking = { workspace = true, optional = true } @@ -48,14 +39,11 @@ frame-support = { workspace = true } frame-system = { workspace = true } # substrate primitives -sp-core = { workspace = true, optional = true } sp-io = { workspace = true } -sp-runtime = { workspace = true, optional = true } sp-std = { workspace = true } [dev-dependencies] pallet-balances = { workspace = true, features = ["default"] } pallet-randomness-collective-flip = { workspace = true, features = ["default"] } -sp-core = { workspace = true, features = ["default"] } -sp-io = { workspace = true, features = ["default"] } +sp-core = { workspace = true } sp-runtime = { workspace = true, features = ["default"] } diff --git a/gn-pallets/pallet-guild/src/benchmark.rs b/gn-pallets/pallet-guild/src/benchmark.rs index 09284c01..a18936d6 100644 --- a/gn-pallets/pallet-guild/src/benchmark.rs +++ b/gn-pallets/pallet-guild/src/benchmark.rs @@ -2,11 +2,12 @@ use super::*; use crate::Pallet as Guild; use frame_benchmarking::{account, benchmarks, whitelisted_caller}; +use frame_support::traits::Get; use frame_system::RawOrigin; use gn_common::filter::{Guild as GuildFilter, Logic as FilterLogic}; use gn_common::identity::*; use gn_common::merkle::Proof as MerkleProof; -use sp_core::{Get, Pair as PairT}; +use sp_std::vec; const ACCOUNT: &str = "account"; const SEED: u32 = 999; @@ -14,10 +15,10 @@ const SEED: u32 = 999; benchmarks! { register { let caller: T::AccountId = whitelisted_caller(); - let (identity, signature) = id_with_auth::(&caller); - let id_with_auth = IdentityWithAuth::Ecdsa(identity, signature); + let (identity, signature) = id_with_auth::(); + let identity_with_auth = IdentityWithAuth::Ecdsa(identity, signature); let index = 1; - }: _(RawOrigin::Signed(caller.clone()), id_with_auth, index) + }: _(RawOrigin::Signed(caller.clone()), identity_with_auth, index) verify { assert_eq!(Guild::::user_data(caller, index), Some(identity)); } @@ -112,7 +113,7 @@ benchmarks! { // identity let caller: T::AccountId = whitelisted_caller(); - let (identity, signature) = id_with_auth::(&caller); + let (identity, signature) = id_with_auth::(); let identity_with_auth = IdentityWithAuth::Ecdsa(identity, signature); Guild::::register( RawOrigin::Signed(caller.clone()).into(), @@ -148,7 +149,7 @@ benchmarks! { leave { let caller: T::AccountId = whitelisted_caller(); - let (identity, signature) = id_with_auth::(&caller); + let (identity, signature) = id_with_auth::(); let identity_with_auth = IdentityWithAuth::Ecdsa(identity, signature); Guild::::register( @@ -184,9 +185,9 @@ benchmarks! { let s = ::MaxSerializedLen::get() as usize; let caller: T::AccountId = whitelisted_caller(); - let user: T::AccountId = account(ACCOUNT, 123, SEED); + let keeper: T::AccountId = account(ACCOUNT, 123, SEED); let operator: T::AccountId = account(ACCOUNT, 222, SEED); - let (identity, signature) = id_with_auth::(&user); + let (identity, signature) = id_with_auth::(); let identity_with_auth = IdentityWithAuth::Ecdsa(identity, signature); pallet_oracle::Pallet::::register_operator( @@ -194,28 +195,28 @@ benchmarks! { operator.clone() ).unwrap(); Guild::::register( - RawOrigin::Signed(user.clone()).into(), + RawOrigin::Signed(caller.clone()).into(), identity_with_auth, 0, ).unwrap(); let guild_name = [0u8; 32]; let role_name = [0u8; 32]; - init_guild::(&user, guild_name); + init_guild::(&caller, guild_name); - let logic = vec![100u8; s as usize]; - let req = vec![200u8; s as usize]; - let serialized_requirements = (vec![req; r as usize], logic); + let logic = vec![100u8; s]; + let req = vec![200u8; s]; + let serialized_requirements = (vec![req; r], logic); Guild::::create_unfiltered_role( - RawOrigin::Signed(user.clone()).into(), + RawOrigin::Signed(caller.clone()).into(), guild_name, role_name, serialized_requirements, ).unwrap(); Guild::::join( - RawOrigin::Signed(user.clone()).into(), + RawOrigin::Signed(caller.clone()).into(), guild_name, role_name, None, @@ -227,18 +228,20 @@ benchmarks! { vec![1] ).unwrap(); - }: _(RawOrigin::Signed(caller.clone()), user.clone(), guild_name, role_name) + }: _(RawOrigin::Signed(keeper.clone()), caller.clone(), guild_name, role_name) verify { let guild_id = Guild::::guild_id(guild_name).unwrap(); let role_id = Guild::::role_id(guild_id, role_name).unwrap(); - assert!(Guild::::member(role_id, user).is_some()); + assert!(Guild::::member(role_id, caller).is_some()); } impl_benchmark_test_suite!(Guild, crate::mock::new_test_ext(), crate::mock::TestRuntime, extra = false); } fn init_guild(caller: &T::AccountId, guild_name: [u8; 32]) { - crate::mock::init_chain(); + frame_system::Pallet::::set_block_number(::BlockNumber::from( + 1u32, + )); let metadata = vec![0u8; ::MaxSerializedLen::get() as usize]; Guild::::create_guild( RawOrigin::Signed(caller.clone()).into(), @@ -248,15 +251,17 @@ fn init_guild(caller: &T::AccountId, guild_name: [u8; 32]) { .unwrap(); } -fn id_with_auth(caller: &T::AccountId) -> (Identity, EcdsaSignature) { - let seed = [12u8; 32]; - let msg = gn_common::utils::verification_msg(&caller); - let keypair = sp_core::ecdsa::Pair::from_seed_slice(&seed).unwrap(); - let signature = EcdsaSignature(keypair.sign(msg.as_ref()).0); - let pubkey = recover_prehashed(eth_hash_message(&msg), &signature).unwrap(); - let address: [u8; 20] = sp_core::keccak_256(&pubkey.serialize_uncompressed()[1..])[12..] - .try_into() - .unwrap(); - let identity = Identity::Address20(address); - (identity, signature) +const ADDRESS: [u8; 20] = [ + 181, 107, 240, 94, 75, 219, 191, 204, 187, 168, 13, 127, 220, 79, 13, 235, 246, 21, 213, 11, +]; + +const SIGNATURE: [u8; 65] = [ + 252, 125, 173, 220, 20, 148, 251, 98, 222, 103, 168, 18, 25, 200, 32, 44, 130, 113, 16, 110, + 44, 102, 249, 87, 225, 146, 239, 99, 61, 41, 59, 116, 75, 60, 155, 227, 103, 131, 188, 167, + 198, 47, 72, 62, 166, 146, 182, 134, 9, 159, 28, 76, 188, 7, 20, 189, 106, 78, 47, 114, 17, 86, + 201, 32, 1, +]; + +fn id_with_auth() -> (Identity, EcdsaSignature) { + (Identity::Address20(ADDRESS), EcdsaSignature(SIGNATURE)) } diff --git a/gn-pallets/pallet-guild/src/lib.rs b/gn-pallets/pallet-guild/src/lib.rs index 43dac364..9ef7ffb0 100644 --- a/gn-pallets/pallet-guild/src/lib.rs +++ b/gn-pallets/pallet-guild/src/lib.rs @@ -7,7 +7,7 @@ pub use pallet::*; #[cfg(feature = "runtime-benchmarks")] mod benchmark; -#[cfg(any(test, feature = "runtime-benchmarks"))] +#[cfg(test)] mod mock; #[cfg(test)] mod test; diff --git a/gn-pallets/pallet-guild/src/mock.rs b/gn-pallets/pallet-guild/src/mock.rs index d13d697e..a3128767 100644 --- a/gn-pallets/pallet-guild/src/mock.rs +++ b/gn-pallets/pallet-guild/src/mock.rs @@ -1,7 +1,3 @@ -// This is to suppress weird unused warnings when run with the -// `runtime-benchmarks` feature flag enabled. It probably emanates from the -// `impl_benchmark_test_suite` macro. -#![cfg_attr(feature = "runtime-benchmarks", allow(unused))] pub use crate as pallet_guild; use frame_support::parameter_types; @@ -102,13 +98,17 @@ impl pallet_oracle::Config for TestRuntime { impl pallet_randomness_collective_flip::Config for TestRuntime {} pub fn new_test_ext() -> sp_io::TestExternalities { - frame_system::GenesisConfig::default() + let mut ext: sp_io::TestExternalities = frame_system::GenesisConfig::default() .build_storage::() .unwrap() - .into() + .into(); + ext.execute_with(|| { + init_chain(); + }); + ext } -pub fn init_chain() { +fn init_chain() { for i in 0..2 { System::set_block_number(i); >::on_initialize(i); diff --git a/gn-pallets/pallet-guild/src/test/guild_and_role.rs b/gn-pallets/pallet-guild/src/test/guild_and_role.rs index 4aaf1d4f..f10b7bf5 100644 --- a/gn-pallets/pallet-guild/src/test/guild_and_role.rs +++ b/gn-pallets/pallet-guild/src/test/guild_and_role.rs @@ -4,7 +4,6 @@ use gn_common::filter::{Filter, Guild as GuildFilter, Logic as FilterLogic}; #[test] fn guild_creation() { new_test_ext().execute_with(|| { - init_chain(); let signer = 4; let guild_name = [99u8; 32]; let max_serialized_len = @@ -44,7 +43,6 @@ fn guild_creation() { #[test] fn guild_with_free_roles() { new_test_ext().execute_with(|| { - init_chain(); let signer = 1; let guild_name = [11u8; 32]; let mut role_name = [22u8; 32]; @@ -141,7 +139,6 @@ fn role_with_allowlist_filter() { let mut role_id_1 = Default::default(); ext.execute_with(|| { - init_chain(); let signer = 1; let guild_name = [11u8; 32]; let role_name_0 = [0u8; 32]; @@ -279,7 +276,6 @@ fn role_with_allowlist_filter() { #[test] fn role_with_guild_filter() { new_test_ext().execute_with(|| { - init_chain(); let signer = 1; let guild_name_0 = [0u8; 32]; let guild_name_1 = [1u8; 32]; @@ -402,7 +398,6 @@ fn role_with_guild_filter() { #[test] fn unfiltered_role() { new_test_ext().execute_with(|| { - init_chain(); let signer = 1; let guild_name = [0u8; 32]; let role_name = [2u8; 32]; diff --git a/gn-pallets/pallet-guild/src/test/join_and_leave.rs b/gn-pallets/pallet-guild/src/test/join_and_leave.rs index d484bd14..498f9e4a 100644 --- a/gn-pallets/pallet-guild/src/test/join_and_leave.rs +++ b/gn-pallets/pallet-guild/src/test/join_and_leave.rs @@ -5,7 +5,6 @@ use gn_common::merkle::Proof as MerkleProof; #[test] fn join_and_leave_free_role() { new_test_ext().execute_with(|| { - init_chain(); let owner = 0; let user = 1; let guild_name = [0u8; 32]; @@ -87,7 +86,6 @@ fn join_and_leave_role_with_allowlist() { let mut ext = new_test_ext(); ext.execute_with(|| { - init_chain(); // user 1 registers let (address, signature) = dummy_ecdsa_id_with_auth(user_1, [1u8; 32]); allowlist.push(address); @@ -230,7 +228,6 @@ fn join_and_leave_role_with_filter() { }; new_test_ext().execute_with(|| { - init_chain(); dummy_guild(owner, g0); dummy_guild(owner, g1); ::create_free_role(RuntimeOrigin::signed(owner), g0, g0r0).unwrap(); @@ -339,7 +336,6 @@ fn join_and_leave_unfiltered_role() { let role_name = [1u8; 32]; new_test_ext().execute_with(|| { - init_chain(); let mut request_id = 0; // new guild with unfiltered role @@ -437,7 +433,6 @@ fn role_with_filtered_requirements() { let filter_logic_2 = FilterLogic::Or; new_test_ext().execute_with(|| { - init_chain(); let mut request_id = 0; // create guild with three roles diff --git a/gn-pallets/pallet-guild/src/test/mod.rs b/gn-pallets/pallet-guild/src/test/mod.rs index f62c6451..b96958bb 100644 --- a/gn-pallets/pallet-guild/src/test/mod.rs +++ b/gn-pallets/pallet-guild/src/test/mod.rs @@ -19,8 +19,6 @@ use sp_runtime::DispatchError; #[test] fn callback_can_only_be_called_by_root() { new_test_ext().execute_with(|| { - init_chain(); - let register_no_access = dummy_answer( vec![u8::from(false)], 0, diff --git a/gn-pallets/pallet-guild/src/test/register.rs b/gn-pallets/pallet-guild/src/test/register.rs index 7ef3c261..aca5683e 100644 --- a/gn-pallets/pallet-guild/src/test/register.rs +++ b/gn-pallets/pallet-guild/src/test/register.rs @@ -5,7 +5,6 @@ use sp_core::Pair as PairT; #[test] fn unsuccessful_registrations() { new_test_ext().execute_with(|| { - init_chain(); let user = 0; let max_identities = ::MaxIdentities::get(); @@ -97,7 +96,6 @@ fn unsuccessful_registrations() { #[test] fn successful_on_chain_registrations() { new_test_ext().execute_with(|| { - init_chain(); let user = 1; let mut index = 0; @@ -156,7 +154,6 @@ fn successful_on_chain_registrations() { #[test] fn successful_off_chain_registrations() { new_test_ext().execute_with(|| { - init_chain(); let operator = 0; let user = 1; let id_zero = Identity::Other([0u8; 64]); @@ -209,7 +206,6 @@ fn successful_off_chain_registrations() { #[test] fn successful_idenity_overrides() { new_test_ext().execute_with(|| { - init_chain(); let operator = 0; let user = 2; let seed = [12u8; 32]; diff --git a/gn-pallets/pallet-oracle/Cargo.toml b/gn-pallets/pallet-oracle/Cargo.toml index 49a36449..f56326da 100644 --- a/gn-pallets/pallet-oracle/Cargo.toml +++ b/gn-pallets/pallet-oracle/Cargo.toml @@ -7,22 +7,14 @@ version = "0.0.0-alpha" default = ["std"] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", - "pallet-balances", - "sp-core", - "sp-io", - "sp-runtime", ] std = [ "gn-common/std", - "pallet-balances?/std", "parity-scale-codec/std", "scale-info/std", "frame-benchmarking?/std", "frame-support/std", "frame-system/std", - "sp-core?/std", - "sp-io?/std", - "sp-runtime?/std", "sp-std/std", ] try-runtime = ["frame-support/try-runtime"] @@ -44,9 +36,6 @@ frame-support = { workspace = true } frame-system = { workspace = true } # substrate primitives -sp-core = { workspace = true, optional = true } -sp-runtime = { workspace = true, optional = true } -sp-io = { workspace = true, optional = true } sp-std = { workspace = true } [dev-dependencies] diff --git a/gn-pallets/pallet-oracle/src/benchmark.rs b/gn-pallets/pallet-oracle/src/benchmark.rs index 46055e74..4b1fa367 100644 --- a/gn-pallets/pallet-oracle/src/benchmark.rs +++ b/gn-pallets/pallet-oracle/src/benchmark.rs @@ -2,9 +2,15 @@ use super::*; use crate::Pallet as Oracle; use frame_benchmarking::{account, benchmarks, whitelisted_caller}; -use frame_support::traits::Currency; +use frame_support::dispatch::{ + DispatchResultWithPostInfo, PostDispatchInfo, UnfilteredDispatchable, +}; +use frame_support::pallet_prelude::Pays; +use frame_support::traits::{Currency, Get}; use frame_system::RawOrigin; -use sp_core::Get; +use parity_scale_codec::{Decode, Encode, EncodeLike}; +use scale_info::TypeInfo; +use sp_std::{vec, vec::Vec}; const ACCOUNT: &str = "operator"; const SEED: u32 = 999; @@ -40,7 +46,7 @@ benchmarks! { let data = vec![128; n as usize]; let fee = T::Currency::minimum_balance(); - let callback = crate::mock::MockCallback::::new(); + let callback = MockCallback::::test(); }: _(RawOrigin::Signed(caller), callback, data, fee) verify { assert_eq!(Oracle::::request_identifier(), 1); @@ -51,10 +57,7 @@ benchmarks! { } fn register_operators(n: u32) -> T::AccountId { - let operators: Vec = (0..n) - .into_iter() - .map(|i| account(ACCOUNT, i, SEED)) - .collect(); + let operators: Vec = (0..n).map(|i| account(ACCOUNT, i, SEED)).collect(); let operator_0 = operators[0].clone(); @@ -64,3 +67,34 @@ fn register_operators(n: u32) -> T::AccountId { operator_0 } + +#[derive(Clone, Copy, Debug, PartialEq, Eq, TypeInfo, Encode, Decode)] +pub struct MockCallback(pub core::marker::PhantomData); + +impl EncodeLike<()> for MockCallback {} + +impl CallbackWithParameter for MockCallback { + fn with_result(&self, result: Vec) -> Option { + if result == [0, 0] { + None + } else { + Some(Self(core::marker::PhantomData)) + } + } +} + +impl UnfilteredDispatchable for MockCallback { + type RuntimeOrigin = ::RuntimeOrigin; + fn dispatch_bypass_filter(self, _origin: Self::RuntimeOrigin) -> DispatchResultWithPostInfo { + Ok(PostDispatchInfo { + actual_weight: None, + pays_fee: Pays::No, + }) + } +} + +impl MockCallback { + pub fn test() -> ::Callback { + Decode::decode(&mut &[][..]).unwrap() + } +} diff --git a/gn-pallets/pallet-oracle/src/lib.rs b/gn-pallets/pallet-oracle/src/lib.rs index f562c4b1..10b4370c 100644 --- a/gn-pallets/pallet-oracle/src/lib.rs +++ b/gn-pallets/pallet-oracle/src/lib.rs @@ -21,7 +21,7 @@ #[cfg(feature = "runtime-benchmarks")] mod benchmark; -#[cfg(any(test, feature = "runtime-benchmarks"))] +#[cfg(test)] mod mock; #[cfg(test)] mod test; From 4151e3cb37ffc9cef2c532e95f277bb38cc8247a Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 21 Feb 2023 07:48:05 +0100 Subject: [PATCH 08/23] WIP. --- gn-client/artifacts/metadata.scale | Bin 42467 -> 42504 bytes gn-client/examples/guild/common.rs | 11 ++++++++--- gn-client/examples/guild/join.rs | 10 +++++----- gn-client/examples/guild/token.rs | 28 ++++++++++++++-------------- gn-client/src/tx/mod.rs | 15 ++++++++++++--- 5 files changed, 39 insertions(+), 25 deletions(-) diff --git a/gn-client/artifacts/metadata.scale b/gn-client/artifacts/metadata.scale index 4288c61598fe2405253a4c3300d5bb2a7f0c6684..c5ea6cbadeed6d98eee9427ee85172a94b8029aa 100644 GIT binary patch delta 200 zcmaESnyKRq(*{>7Qx-;r{DRb?#FG3X6-I*)D=Ww3XBo-?W$B{M_m(JEO|xvrf+#eItAmD_}~BVOmpD7&ur?0A&;s zb8_;_Q&SZ3N^_HdM&_r%Z7v4N6{RMoR4NofElf?BY%W!>S=m+DhmmKp`$Q7~17yQX M1h_VrPs|Yk0AY7Xod5s; delta 182 zcmeA;!}Rzx(*{>7Z3YH`grL;)%;J*NB85bSywq|9|AN$_#FG3XJqBJzx5UhxVukX| zk_?4}$rqg@V-gfH(-cZFGK=BL6f`nZQu9hO(=t<2mLydwB;*%mrf23QXewkR7Aqv? z6s0DnR4OE;rsgRWK`ly6(ep`3h4JF^p%!jlY4x0)QDO5$r)P|l&7}%9o46|bFmg) { +pub async fn register_operators( + api: Api, + root: Arc, + accounts: impl Iterator, +) { let register_operator_futures = accounts .map(|account| { + let payload = tx::register_operator(&account.substrate.account_id()); tx::send_owned_tx( api.clone(), - tx::register_operator(), - Arc::clone(&account.substrate), + tx::sudo(payload), + Arc::clone(&root), TxStatus::InBlock, ) }) diff --git a/gn-client/examples/guild/join.rs b/gn-client/examples/guild/join.rs index b1f43efe..dad36769 100644 --- a/gn-client/examples/guild/join.rs +++ b/gn-client/examples/guild/join.rs @@ -10,18 +10,18 @@ use std::sync::Arc; const RETRIES: u8 = 10; const SLEEP_DURATION_MS: u64 = 500; -pub async fn join(api: Api, alice: Arc) { - let operators = prefunded_accounts(api.clone(), Arc::clone(&alice), N_TEST_ACCOUNTS).await; +pub async fn join(api: Api, root: Arc) { + let operators = prefunded_accounts(api.clone(), Arc::clone(&root), N_TEST_ACCOUNTS).await; #[cfg(not(feature = "external-oracle"))] { let registering_operators = operators.values(); - register_operators(api.clone(), registering_operators).await; + register_operators(api.clone(), Arc::clone(&root), registering_operators).await; let registered_operators = query::registered_operators(api.clone()) .await .expect("failed to fetch registered operators"); for registered in ®istered_operators { - if registered != alice.account_id() { + if registered != root.account_id() { assert!(operators.get(registered).is_some()); } } @@ -63,7 +63,7 @@ pub async fn join(api: Api, alice: Arc) { assert_eq!(user_identity, expected); } - create_dummy_guilds(api.clone(), alice, operators.values()).await; + create_dummy_guilds(api.clone(), root, operators.values()).await; join_guilds(api.clone(), &operators).await; diff --git a/gn-client/examples/guild/token.rs b/gn-client/examples/guild/token.rs index ba706d92..c52fbc0e 100644 --- a/gn-client/examples/guild/token.rs +++ b/gn-client/examples/guild/token.rs @@ -29,7 +29,7 @@ const GNOSIS_ERC721_ID_1: &str = "5819774"; const ADDRESS: &str = "e43878ce78934fe8007748ff481f03b8ee3b97de"; const SIGNATURE: &str = "a7d8263c96a8bb689d462b2782a45b81f02777607c27d1b322a1c46910482e274320fbf353a543a1504dc3c0ded9c2930dffc4b15541d97da7b240f40416f12a1b"; -pub async fn token(api: Api, alice: Arc) { +pub async fn token(api: Api, root: Arc) { let mut signature = [0u8; 65]; hex::decode_to_slice(SIGNATURE, &mut signature).expect("this should not fail"); signature[64] -= 27; // ethereum's eip-115 normalization stuff @@ -37,30 +37,30 @@ pub async fn token(api: Api, alice: Arc) { hex::decode_to_slice(ADDRESS, &mut address).expect("this should not fail"); #[cfg(not(feature = "external-oracle"))] - let operators = prefunded_accounts(api.clone(), Arc::clone(&alice), N_TEST_ACCOUNTS).await; + let operators = prefunded_accounts(api.clone(), Arc::clone(&root), N_TEST_ACCOUNTS).await; #[cfg(not(feature = "external-oracle"))] { let registering_operators = operators.values(); - register_operators(api.clone(), registering_operators).await; + register_operators(api.clone(), Arc::clone(&root), registering_operators).await; let registered_operators = query::registered_operators(api.clone()) .await .expect("failed to fetch registered operators"); for registered in ®istered_operators { - if registered != alice.account_id() { + if registered != root.account_id() { assert!(operators.get(registered).is_some()); } } } - // register alice with test evm address + signature + // register root with test evm address + signature let evm_identity = IdentityWithAuth::Ecdsa(Identity::Address20(address), EcdsaSignature(signature)); let index = 0; let tx_payload = tx::register(evm_identity, index); - tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&alice)) + tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&root)) .await .expect("failed to register"); @@ -68,7 +68,7 @@ pub async fn token(api: Api, alice: Arc) { send_dummy_oracle_answers(api.clone(), &operators).await; loop { - let user_identity = query::user_identity(api.clone(), alice.account_id()) + let user_identity = query::user_identity(api.clone(), root.account_id()) .await .expect("failed to fetch user identities"); if user_identity.len() == 1 { @@ -137,28 +137,28 @@ pub async fn token(api: Api, alice: Arc) { }; let tx_payload = tx::create_guild(TOKEN_GUILD, vec![1, 2, 3]); - tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&alice)) + tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&root)) .await .expect("failed to create guild"); println!("GUILD CREATED"); let tx_payload = tx::create_unfiltered_role(TOKEN_GUILD, FIRST_ROLE, first_reqs).unwrap(); - tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&alice)) + tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&root)) .await .expect("failed to create guild"); println!("FIRST ROLE CREATED"); let tx_payload = tx::create_unfiltered_role(TOKEN_GUILD, SECOND_ROLE, second_reqs).unwrap(); - tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&alice)) + tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&root)) .await .expect("failed to create guild"); println!("SECOND ROLE CREATED"); let tx_payload = tx::join(TOKEN_GUILD, FIRST_ROLE, None); - tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&alice)) + tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&root)) .await .expect("failed to join guild"); @@ -175,7 +175,7 @@ pub async fn token(api: Api, alice: Arc) { .await .expect("failed to query members"); if members.len() == 1 { - assert_eq!(members.get(0).unwrap(), alice.account_id()); + assert_eq!(members.get(0).unwrap(), root.account_id()); break; } } @@ -183,7 +183,7 @@ pub async fn token(api: Api, alice: Arc) { println!("FIRST_ROLE JOINED"); let tx_payload = tx::join(TOKEN_GUILD, SECOND_ROLE, None); - tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&alice)) + tx::send_tx_in_block(api.clone(), &tx_payload, Arc::clone(&root)) .await .expect("failed to join guild"); @@ -200,7 +200,7 @@ pub async fn token(api: Api, alice: Arc) { .await .expect("failed to query members"); if members.len() == 1 { - assert_eq!(members.get(0).unwrap(), alice.account_id()); + assert_eq!(members.get(0).unwrap(), root.account_id()); break; } } diff --git a/gn-client/src/tx/mod.rs b/gn-client/src/tx/mod.rs index c448b69c..b400132b 100644 --- a/gn-client/src/tx/mod.rs +++ b/gn-client/src/tx/mod.rs @@ -16,18 +16,27 @@ use gn_common::identity::{Identity, IdentityWithAuth}; use gn_common::merkle::Proof as MerkleProof; use gn_common::{GuildName, RoleName}; use gn_engine::RequirementsWithLogic; -use subxt::tx::TxPayload; +use subxt::dynamic::Value; +use subxt::tx::{DynamicTxPayload, TxPayload}; use std::sync::Arc; +pub fn sudo<'a, 'b>(call: DynamicTxPayload<'a>) -> DynamicTxPayload<'b> { + subxt::dynamic::tx("Sudo", "sudo", vec![("call", call.into_value())]) +} + pub fn fund_account(account: &AccountId, amount: u128) -> impl TxPayload { runtime::tx() .balances() .transfer(MultiAddress::Id(account.clone()), amount) } -pub fn register_operator() -> impl TxPayload { - runtime::tx().oracle().register_operator() +pub fn register_operator<'a>(operator: &AccountId) -> DynamicTxPayload<'a> { + subxt::dynamic::tx( + "Oracle", + "register_operator", + vec![("operator", Value::from_bytes(operator))], + ) } pub fn oracle_callback(request_id: u64, data: Vec) -> impl TxPayload { From 3ae8aed045e3cd7556665c96f0cea75c30ca2bab Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 21 Feb 2023 12:43:21 +0100 Subject: [PATCH 09/23] Oracle pallet cleanup. --- gn-client/examples/guild/common.rs | 27 +- gn-pallets/pallet-oracle/src/lib.rs | 111 ++++++-- gn-pallets/pallet-oracle/src/test/mod.rs | 326 +++++++++++++++++------ gn-pallets/pallet-oracle/src/weights.rs | 14 + 4 files changed, 360 insertions(+), 118 deletions(-) diff --git a/gn-client/examples/guild/common.rs b/gn-client/examples/guild/common.rs index e2bf843f..ddb6d064 100644 --- a/gn-client/examples/guild/common.rs +++ b/gn-client/examples/guild/common.rs @@ -67,27 +67,24 @@ pub async fn prefunded_accounts( accounts } -#[cfg(not(feature = "external-oracle"))] pub async fn register_operators( api: Api, root: Arc, accounts: impl Iterator, ) { - let register_operator_futures = accounts - .map(|account| { - let payload = tx::register_operator(&account.substrate.account_id()); - tx::send_owned_tx( - api.clone(), - tx::sudo(payload), - Arc::clone(&root), - TxStatus::InBlock, - ) - }) - .collect::>(); - - try_join_all(register_operator_futures) + println!("registring operators"); + for (i, account) in accounts.enumerate() { + let payload = tx::register_operator(&account.substrate.account_id()); + tx::send_owned_tx( + api.clone(), + tx::sudo(payload), + Arc::clone(&root), + TxStatus::InBlock, + ) .await - .expect("failed to register operators"); + .unwrap(); + println!("operator {i} registered"); + } println!("operator registrations in block"); } diff --git a/gn-pallets/pallet-oracle/src/lib.rs b/gn-pallets/pallet-oracle/src/lib.rs index 10b4370c..cb1a789d 100644 --- a/gn-pallets/pallet-oracle/src/lib.rs +++ b/gn-pallets/pallet-oracle/src/lib.rs @@ -75,10 +75,12 @@ pub mod pallet { #[pallet::error] pub enum Error { - /// No oracle operator has registered yet - NoRegisteredOperators, + /// No oracle operator has been activated yet + NoActiveOperators, /// An operator is already registered. OperatorAlreadyRegistered, + /// An operator is already activated. + OperatorAlreadyActivated, /// Callback cannot be deserialized UnknownCallback, /// Manipulating an unknown operator @@ -112,10 +114,14 @@ pub mod pallet { fee: BalanceOf, result: SpVec, }, - /// A new operator has been registered + /// A new operator has been registered by the root OperatorRegistered(T::AccountId), - /// An existing operator has been unregistered + /// An existing operator has been deregistered by the root OperatorDeregistered(T::AccountId), + /// A registered operator has been activated + OperatorActivated(T::AccountId), + /// A registered operator has been deactivated + OperatorDeactivated(T::AccountId), /// A request didn't receive any result in time KillRequest(RequestIdentifier), KillRequestFailed(RequestIdentifier), @@ -130,8 +136,17 @@ pub mod pallet { /// an operator registers/deregisters. However, these events are /// anticipated to be much less frequent than user request events. #[pallet::storage] - #[pallet::getter(fn operators)] - pub type Operators = StorageValue<_, SpVec, ValueQuery>; + #[pallet::getter(fn operator)] + pub type RegisteredOperators = + StorageMap<_, Blake2_128Concat, T::AccountId, (), OptionQuery>; + + #[pallet::storage] + #[pallet::getter(fn num_registered_operators)] + pub type NumRegisteredOperators = StorageValue<_, u32, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn active_operators)] + pub type ActiveOperators = StorageValue<_, SpVec, ValueQuery>; #[pallet::storage] #[pallet::getter(fn request_identifier)] @@ -182,28 +197,78 @@ pub mod pallet { pub fn register_operator(origin: OriginFor, operator: T::AccountId) -> DispatchResult { ensure_root(origin)?; - Operators::::try_mutate(|operators| { - if operators.len() == T::MaxOperators::get() as usize { - Err(Error::::MaxOperatorsRegistered.into()) - } else if operators.binary_search(&operator).is_ok() { - Err(Error::::OperatorAlreadyRegistered.into()) + ensure!( + Self::num_registered_operators() < T::MaxOperators::get(), + Error::::MaxOperatorsRegistered + ); + + ensure!( + !RegisteredOperators::::contains_key(&operator), + Error::::OperatorAlreadyRegistered + ); + + RegisteredOperators::::insert(&operator, ()); + NumRegisteredOperators::::mutate(|val| *val = *val + 1); + Self::deposit_event(Event::OperatorRegistered(operator)); + Ok(()) + } + + /// Deregisters an already registered Operator + #[pallet::call_index(1)] + #[pallet::weight(T::WeightInfo::deregister_operator())] + pub fn deregister_operator(origin: OriginFor, operator: T::AccountId) -> DispatchResult { + ensure_root(origin)?; + + ensure!( + RegisteredOperators::::take(&operator).is_some(), + Error::::UnknownOperator + ); + + ActiveOperators::::mutate(|operators| { + if let Ok(index) = operators.binary_search(&operator) { + operators.remove(index); + } + }); + + NumRegisteredOperators::::mutate(|val| *val = *val - 1); + Self::deposit_event(Event::OperatorDeregistered(operator)); + Ok(()) + } + + #[pallet::call_index(2)] + #[pallet::weight(T::WeightInfo::activate_operator())] + pub fn activate_operator(origin: OriginFor) -> DispatchResult { + let operator = ensure_signed(origin)?; + + ensure!( + RegisteredOperators::::contains_key(&operator), + Error::::UnknownOperator + ); + + ActiveOperators::::try_mutate(|operators| { + if operators.binary_search(&operator).is_ok() { + Err(Error::::OperatorAlreadyActivated.into()) } else { operators.push(operator.clone()); operators.sort(); // needed for binary search - Self::deposit_event(Event::OperatorRegistered(operator)); + Self::deposit_event(Event::OperatorActivated(operator)); Ok(()) } }) } - /// Deregisters an already registered Operator - #[pallet::call_index(1)] - #[pallet::weight(T::WeightInfo::deregister_operator())] - pub fn deregister_operator(origin: OriginFor, operator: T::AccountId) -> DispatchResult { - ensure_root(origin)?; - Operators::::try_mutate(|operators| { + #[pallet::call_index(3)] + #[pallet::weight(T::WeightInfo::deactivate_operator())] + pub fn deactivate_operator(origin: OriginFor) -> DispatchResult { + let operator = ensure_signed(origin)?; + ensure!( + RegisteredOperators::::contains_key(&operator), + Error::::UnknownOperator + ); + ActiveOperators::::try_mutate(|operators| { if let Ok(index) = operators.binary_search(&operator) { - Self::deposit_event(Event::OperatorDeregistered(operators.remove(index))); + operators.remove(index); + Self::deposit_event(Event::OperatorDeactivated(operator)); Ok(()) } else { Err(Error::::UnknownOperator.into()) @@ -223,7 +288,7 @@ pub mod pallet { /// to listen to `OracleRequest` events. This event contains all the /// required information to perform the request and provide back /// the result. - #[pallet::call_index(2)] + #[pallet::call_index(4)] #[pallet::weight(T::WeightInfo::initiate_request())] pub fn initiate_request( origin: OriginFor, @@ -233,9 +298,9 @@ pub mod pallet { ) -> DispatchResult { let requester = ensure_signed(origin)?; - let operators = Operators::::get(); + let operators = ActiveOperators::::get(); if operators.is_empty() { - return Err(Error::::NoRegisteredOperators.into()); + return Err(Error::::NoActiveOperators.into()); } let next_operator = NextOperator::::get(); let operator = operators[next_operator as usize % operators.len()].clone(); @@ -287,7 +352,7 @@ pub mod pallet { /// back the result. Result is then dispatched back to the originator's /// callback. The fee reserved during `initiate_request` is transferred /// as soon as this callback is called. - #[pallet::call_index(3)] + #[pallet::call_index(5)] #[pallet::weight((0, DispatchClass::Operational, Pays::No))] pub fn callback( origin: OriginFor, diff --git a/gn-pallets/pallet-oracle/src/test/mod.rs b/gn-pallets/pallet-oracle/src/test/mod.rs index 1e6e3d3b..7222d690 100644 --- a/gn-pallets/pallet-oracle/src/test/mod.rs +++ b/gn-pallets/pallet-oracle/src/test/mod.rs @@ -7,7 +7,7 @@ use pallet_oracle::Event as OracleEvent; use parity_scale_codec::{Decode, Encode}; #[test] -fn operator_management_by_non_root_origin_fails() { +fn invalid_transactions_fail() { new_test_ext().execute_with(|| { System::set_block_number(1); let failing_transactions = vec![ @@ -27,6 +27,31 @@ fn operator_management_by_non_root_origin_fails() { ::deregister_operator(RuntimeOrigin::signed(1), 0), "BadOrigin", ), + ( + ::activate_operator(RuntimeOrigin::signed(1)), + "UnknownOperator", + ), + ( + ::deactivate_operator(RuntimeOrigin::signed(1)), + "UnknownOperator", + ), + ( + ::deregister_operator(RuntimeOrigin::root(), 1), + "UnknownOperator", + ), + ( + ::initiate_request( + RuntimeOrigin::signed(1), + MockCallback::test(), + vec![], + minimum_fee(), + ), + "NoActiveOperators", + ), + ( + ::callback(RuntimeOrigin::signed(ACCOUNT_0), 0, 10.encode()), + "UnknownRequest", + ), ]; for (tx, raw_error_msg) in failing_transactions { @@ -40,59 +65,146 @@ fn operator_registration_valid() { new_test_ext().execute_with(|| { // This is required for some reason otherwise the last_event() method fails System::set_block_number(1); - - assert!(::operators().is_empty()); - assert!(::register_operator(RuntimeOrigin::root(), 1).is_ok()); - assert_eq!(last_event(), OracleEvent::OperatorRegistered(1)); - assert_eq!(::operators(), vec![1]); + let operator = 1; + assert_eq!(::num_registered_operators(), 0); + assert!(::register_operator(RuntimeOrigin::root(), operator).is_ok()); + assert!(::operator(operator).is_some()); + assert_eq!(::num_registered_operators(), 1); + assert_eq!(last_event(), OracleEvent::OperatorRegistered(operator)); }); } #[test] fn operator_registration_invalid_operator_already_registered() { new_test_ext().execute_with(|| { - assert!(::register_operator(RuntimeOrigin::root(), 1).is_ok()); - assert_eq!(::operators(), vec![1]); + let operator_1 = 1; + let operator_2 = 2; + assert!(::register_operator(RuntimeOrigin::root(), operator_1).is_ok()); + assert!(::operator(operator_1).is_some()); + assert_eq!(::num_registered_operators(), 1); // Operator already registered error - let error = ::register_operator(RuntimeOrigin::root(), 1).unwrap_err(); + let error = ::register_operator(RuntimeOrigin::root(), operator_1).unwrap_err(); assert_eq!(error_msg(error), "OperatorAlreadyRegistered"); - assert_eq!(::operators(), vec![1]); + assert!(::operator(operator_1).is_some()); + assert_eq!(::num_registered_operators(), 1); - assert!(::register_operator(RuntimeOrigin::root(), 0).is_ok()); - assert_eq!(::operators(), vec![0, 1]); + assert!(::register_operator(RuntimeOrigin::root(), operator_2).is_ok()); + assert!(::operator(operator_1).is_some()); + assert!(::operator(operator_2).is_some()); + assert_eq!(::num_registered_operators(), 2); }); } #[test] fn operator_deregistration_valid() { new_test_ext().execute_with(|| { - // This is required for some reason otherwise the last_event() method fails System::set_block_number(1); + let operator_0 = 0; + let operator_1 = 1; + let operator_2 = 2; - assert!(::register_operator(RuntimeOrigin::root(), 1).is_ok()); - assert!(::deregister_operator(RuntimeOrigin::root(), 1).is_ok()); - assert!(::operators().is_empty()); + assert!(::register_operator(RuntimeOrigin::root(), operator_1).is_ok()); + assert!(::deregister_operator(RuntimeOrigin::root(), operator_1).is_ok()); + assert_eq!(::num_registered_operators(), 0); - assert_eq!(last_event(), OracleEvent::OperatorDeregistered(1)); + assert_eq!(last_event(), OracleEvent::OperatorDeregistered(operator_1)); - assert!(::register_operator(RuntimeOrigin::root(), 2).is_ok()); - assert!(::register_operator(RuntimeOrigin::root(), 0).is_ok()); - assert!(::register_operator(RuntimeOrigin::root(), 1).is_ok()); - assert!(::deregister_operator(RuntimeOrigin::root(), 0).is_ok()); - assert_eq!(::operators(), vec![1, 2]); + assert!(::register_operator(RuntimeOrigin::root(), operator_2).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), operator_0).is_ok()); + assert!(::register_operator(RuntimeOrigin::root(), operator_1).is_ok()); + assert!(::deregister_operator(RuntimeOrigin::root(), operator_0).is_ok()); + assert_eq!(::num_registered_operators(), 2); + assert!(::operator(operator_1).is_some()); + assert!(::operator(operator_2).is_some()); - assert_eq!(last_event(), OracleEvent::OperatorDeregistered(0)); + assert_eq!(last_event(), OracleEvent::OperatorDeregistered(operator_0)); }); } #[test] -fn operator_unregistration_invalid_unknown_operator() { +fn operator_activation_and_deactivation() { new_test_ext().execute_with(|| { - // Unknown operator error - let error = ::deregister_operator(RuntimeOrigin::root(), 1).unwrap_err(); - assert_eq!(error_msg(error), "UnknownOperator"); - assert!(::operators().is_empty()); + System::set_block_number(1); + let operator_0 = 0; + let operator_1 = 1; + let operator_2 = 2; + let operator_3 = 3; + let operator_4 = 4; + + ::register_operator(RuntimeOrigin::root(), operator_0).unwrap(); + ::register_operator(RuntimeOrigin::root(), operator_1).unwrap(); + ::register_operator(RuntimeOrigin::root(), operator_2).unwrap(); + + ::activate_operator(RuntimeOrigin::signed(operator_2)).unwrap(); + ::activate_operator(RuntimeOrigin::signed(operator_0)).unwrap(); + ::activate_operator(RuntimeOrigin::signed(operator_1)).unwrap(); + + assert_eq!(last_event(), OracleEvent::OperatorActivated(operator_1)); + assert_eq!( + ::active_operators(), + vec![operator_0, operator_1, operator_2] + ); + assert_eq!(::num_registered_operators(), 3); + + // deactivate operator_0 + ::deactivate_operator(RuntimeOrigin::signed(operator_0)).unwrap(); + + assert_eq!(last_event(), OracleEvent::OperatorDeactivated(operator_0)); + assert_eq!(::active_operators(), vec![operator_1, operator_2]); + assert_eq!(::num_registered_operators(), 3); + + // activate all registered operators (reactivate operator_0 + ::register_operator(RuntimeOrigin::root(), operator_3).unwrap(); + assert_eq!(::num_registered_operators(), 4); + ::activate_operator(RuntimeOrigin::signed(operator_3)).unwrap(); + ::activate_operator(RuntimeOrigin::signed(operator_0)).unwrap(); + assert_eq!( + ::active_operators(), + vec![operator_0, operator_1, operator_2, operator_3] + ); + + // not yet registered operator tries to activate + assert_eq!( + error_msg(::activate_operator(RuntimeOrigin::signed(operator_4)).unwrap_err()), + "UnknownOperator" + ); + + // deregister an activated operator + ::deregister_operator(RuntimeOrigin::root(), operator_1).unwrap(); + assert_eq!(::num_registered_operators(), 3); + assert_eq!( + ::active_operators(), + vec![operator_0, operator_2, operator_3] + ); + assert_eq!( + error_msg( + ::deactivate_operator(RuntimeOrigin::signed(operator_1)).unwrap_err() + ), + "UnknownOperator" + ); + // deregister a deactivated operator + ::deactivate_operator(RuntimeOrigin::signed(operator_2)).unwrap(); + assert_eq!(::active_operators(), vec![operator_0, operator_3]); + assert_eq!(::num_registered_operators(), 3); + ::deregister_operator(RuntimeOrigin::root(), operator_2).unwrap(); + assert_eq!(::num_registered_operators(), 2); + // deregistered tries to re-activate again + assert_eq!( + error_msg(::activate_operator(RuntimeOrigin::signed(operator_2)).unwrap_err()), + "UnknownOperator" + ); + // register a new operator + ::register_operator(RuntimeOrigin::root(), operator_4).unwrap(); + assert_eq!(::num_registered_operators(), 3); + ::register_operator(RuntimeOrigin::root(), operator_2).unwrap(); + assert_eq!(::num_registered_operators(), 4); + ::activate_operator(RuntimeOrigin::signed(operator_4)).unwrap(); + ::activate_operator(RuntimeOrigin::signed(operator_2)).unwrap(); + assert_eq!( + ::active_operators(), + vec![operator_0, operator_2, operator_3, operator_4] + ); }); } @@ -107,16 +219,18 @@ fn initiate_requests_valid() { let result = vec![10, 0, 0, 0]; let request_id = 0; - assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); + ::register_operator(RuntimeOrigin::root(), ACCOUNT_0).unwrap(); assert_eq!(last_event(), OracleEvent::OperatorRegistered(ACCOUNT_0)); + ::activate_operator(RuntimeOrigin::signed(ACCOUNT_0)).unwrap(); + assert_eq!(last_event(), OracleEvent::OperatorActivated(ACCOUNT_0)); - assert!(::initiate_request( + ::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), callback, data.clone(), fee, ) - .is_ok()); + .unwrap(); assert_eq!( last_event(), @@ -161,24 +275,34 @@ fn linear_request_delegation() { let fee = minimum_fee(); let mut request_id = 0; - assert!(::register_operator(RuntimeOrigin::root(), operator).is_ok()); - assert!(::register_operator(RuntimeOrigin::root(), operator_0).is_ok()); - assert!(::register_operator(RuntimeOrigin::root(), operator_1).is_ok()); - assert!(::register_operator(RuntimeOrigin::root(), operator_2).is_ok()); + ::register_operator(RuntimeOrigin::root(), operator).unwrap(); + ::register_operator(RuntimeOrigin::root(), operator_0).unwrap(); + ::register_operator(RuntimeOrigin::root(), operator_1).unwrap(); + ::register_operator(RuntimeOrigin::root(), operator_2).unwrap(); assert_eq!( error_msg(::register_operator(RuntimeOrigin::root(), operator_3).unwrap_err()), "MaxOperatorsRegistered" ); - assert!(::deregister_operator(RuntimeOrigin::root(), operator).is_ok()); - assert!(::register_operator(RuntimeOrigin::root(), operator_3).is_ok()); + assert_eq!( + ::num_registered_operators(), + ::MaxOperators::get() + ); + ::deregister_operator(RuntimeOrigin::root(), operator).unwrap(); + ::register_operator(RuntimeOrigin::root(), operator_3).unwrap(); + + // activate operators + ::activate_operator(RuntimeOrigin::signed(operator_0)).unwrap(); + ::activate_operator(RuntimeOrigin::signed(operator_1)).unwrap(); + ::activate_operator(RuntimeOrigin::signed(operator_2)).unwrap(); + ::activate_operator(RuntimeOrigin::signed(operator_3)).unwrap(); - assert!(::initiate_request( + ::initiate_request( RuntimeOrigin::signed(ACCOUNT_0), callback, data.clone(), fee, ) - .is_ok()); + .unwrap(); assert_eq!( last_event(), @@ -191,13 +315,13 @@ fn linear_request_delegation() { ); request_id += 1; - assert!(::initiate_request( + ::initiate_request( RuntimeOrigin::signed(ACCOUNT_0), callback, data.clone(), fee, ) - .is_ok()); + .unwrap(); assert_eq!( last_event(), @@ -210,13 +334,13 @@ fn linear_request_delegation() { ); request_id += 1; - assert!(::initiate_request( + ::initiate_request( RuntimeOrigin::signed(ACCOUNT_0), callback, data.clone(), fee, ) - .is_ok()); + .unwrap(); assert_eq!( last_event(), @@ -229,13 +353,13 @@ fn linear_request_delegation() { ); request_id += 1; - assert!(::initiate_request( + ::initiate_request( RuntimeOrigin::signed(ACCOUNT_0), callback, data.clone(), fee, ) - .is_ok()); + .unwrap(); assert_eq!( last_event(), @@ -248,10 +372,13 @@ fn linear_request_delegation() { ); request_id += 1; - assert!( - ::initiate_request(RuntimeOrigin::signed(ACCOUNT_0), callback, data, fee,) - .is_ok() - ); + ::initiate_request( + RuntimeOrigin::signed(ACCOUNT_0), + callback, + data.clone(), + fee, + ) + .unwrap(); assert_eq!( last_event(), @@ -262,27 +389,71 @@ fn linear_request_delegation() { fee, } ); - }); -} -#[test] -fn initiate_requests_invalid_unknown_operator() { - new_test_ext().execute_with(|| { - let error = ::initiate_request( + request_id += 1; + + // operator_1, and operator_2 deactivates + ::deactivate_operator(RuntimeOrigin::signed(operator_1)).unwrap(); + ::deactivate_operator(RuntimeOrigin::signed(operator_2)).unwrap(); + ::initiate_request( RuntimeOrigin::signed(ACCOUNT_0), - MockCallback::test(), - vec![], - minimum_fee(), + callback, + data.clone(), + fee, ) - .unwrap_err(); - assert_eq!(error_msg(error), "NoRegisteredOperators"); + .unwrap(); + assert_eq!( + last_event(), + OracleEvent::OracleRequest { + request_id, + operator: operator_3, + callback, + fee, + } + ); + + request_id += 1; + + // operator_0 is deregistered by root + ::deregister_operator(RuntimeOrigin::root(), operator_0).unwrap(); + assert_eq!(::active_operators(), vec![operator_3]); + ::initiate_request( + RuntimeOrigin::signed(ACCOUNT_0), + callback, + data.clone(), + fee, + ) + .unwrap(); + assert_eq!( + last_event(), + OracleEvent::OracleRequest { + request_id, + operator: operator_3, + callback, + fee, + } + ); + + request_id += 1; + + ::initiate_request(RuntimeOrigin::signed(ACCOUNT_0), callback, data, fee).unwrap(); + assert_eq!( + last_event(), + OracleEvent::OracleRequest { + request_id, + operator: operator_3, + callback, + fee, + } + ); }); } #[test] fn initiate_requests_invalid_insufficient_fee() { new_test_ext().execute_with(|| { - assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); + ::register_operator(RuntimeOrigin::root(), ACCOUNT_0).unwrap(); + ::activate_operator(RuntimeOrigin::signed(ACCOUNT_0)).unwrap(); let error = ::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), MockCallback::test(), @@ -298,7 +469,8 @@ fn initiate_requests_invalid_insufficient_fee() { #[test] fn initiate_requests_invalid_insufficient_balance_for_fee() { new_test_ext().execute_with(|| { - assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); + ::register_operator(RuntimeOrigin::root(), ACCOUNT_0).unwrap(); + ::activate_operator(RuntimeOrigin::signed(ACCOUNT_0)).unwrap(); let error = ::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), MockCallback::test(), @@ -313,39 +485,32 @@ fn initiate_requests_invalid_insufficient_balance_for_fee() { #[test] fn initiate_requests_invalid_wrong_operator() { new_test_ext().execute_with(|| { - assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); - assert!(::initiate_request( + ::register_operator(RuntimeOrigin::root(), ACCOUNT_0).unwrap(); + ::activate_operator(RuntimeOrigin::signed(ACCOUNT_0)).unwrap(); + ::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), MockCallback::test(), vec![], minimum_fee(), ) - .is_ok()); + .unwrap(); let error = ::callback(RuntimeOrigin::signed(99), 0, vec![1]).unwrap_err(); assert_eq!(error_msg(error), "WrongOperator"); }); } -#[test] -fn unknown_request() { - new_test_ext().execute_with(|| { - let error = - ::callback(RuntimeOrigin::signed(ACCOUNT_0), 0, 10.encode()).unwrap_err(); - assert_eq!(error_msg(error), "UnknownRequest"); - }); -} - #[test] fn unknown_callback() { new_test_ext().execute_with(|| { - assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); - assert!(::initiate_request( + ::register_operator(RuntimeOrigin::root(), ACCOUNT_0).unwrap(); + ::activate_operator(RuntimeOrigin::signed(ACCOUNT_0)).unwrap(); + ::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), MockCallback::test(), vec![], minimum_fee(), ) - .is_ok()); + .unwrap(); // Sending an empty result in this test runtime environment causes // MockCallback to return None for the `with_result` call. The // resulting None will trigger the UnknownCallback error. Note, that @@ -361,14 +526,15 @@ fn kill_request() { new_test_ext().execute_with(|| { let request_id = 0; - assert!(::register_operator(RuntimeOrigin::root(), ACCOUNT_0).is_ok()); - assert!(::initiate_request( + ::register_operator(RuntimeOrigin::root(), ACCOUNT_0).unwrap(); + ::activate_operator(RuntimeOrigin::signed(ACCOUNT_0)).unwrap(); + ::initiate_request( RuntimeOrigin::signed(ACCOUNT_1), MockCallback::test(), vec![], minimum_fee(), ) - .is_ok()); + .unwrap(); >::on_finalize( ::ValidityPeriod::get() - 1, diff --git a/gn-pallets/pallet-oracle/src/weights.rs b/gn-pallets/pallet-oracle/src/weights.rs index 72d47ab5..3c8e42bd 100644 --- a/gn-pallets/pallet-oracle/src/weights.rs +++ b/gn-pallets/pallet-oracle/src/weights.rs @@ -54,6 +54,8 @@ use sp_std::marker::PhantomData; pub trait WeightInfo { fn register_operator() -> Weight; fn deregister_operator() -> Weight; + fn activate_operator() -> Weight; + fn deactivate_operator() -> Weight; fn initiate_request() -> Weight; } @@ -72,6 +74,12 @@ impl WeightInfo for SubstrateWeight { .saturating_add(T::DbWeight::get().reads(1)) .saturating_add(T::DbWeight::get().writes(1)) } + fn activate_operator() -> Weight { + Weight::from_parts(16_862_000, 16_862_000) + } + fn deactivate_operator() -> Weight { + Weight::from_parts(16_862_000, 16_862_000) + } fn initiate_request() -> Weight { Weight::from_parts(16_862_000, 16_862_000) } @@ -91,6 +99,12 @@ impl WeightInfo for () { .saturating_add(RocksDbWeight::get().reads(1)) .saturating_add(RocksDbWeight::get().writes(1)) } + fn activate_operator() -> Weight { + Weight::from_parts(16_862_000, 16_862_000) + } + fn deactivate_operator() -> Weight { + Weight::from_parts(16_862_000, 16_862_000) + } fn initiate_request() -> Weight { Weight::from_parts(16_862_000, 16_862_000) } From 86b3d4f7f3dbb50185f824205e21638f42134b23 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 21 Feb 2023 13:05:03 +0100 Subject: [PATCH 10/23] Wip --- gn-pallets/pallet-oracle/src/benchmark.rs | 30 +++++++++++++++-------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/gn-pallets/pallet-oracle/src/benchmark.rs b/gn-pallets/pallet-oracle/src/benchmark.rs index 4b1fa367..955df900 100644 --- a/gn-pallets/pallet-oracle/src/benchmark.rs +++ b/gn-pallets/pallet-oracle/src/benchmark.rs @@ -22,15 +22,26 @@ benchmarks! { let operator: T::AccountId = account(ACCOUNT, max_operators - 1, SEED); }: _(RawOrigin::Root, operator) verify { - assert_eq!(Oracle::::operators().len(), (n + 1) as usize); + assert!(Oracle::::operator(operator).is_some()); } deregister_operator { let max_operators = ::MaxOperators::get(); + let n in 1 .. ::MaxOperators::get() - 1; + let operators = register_operators::(n); + }: _(RawOrigin::Root, operators[0].clone()) + verify { + assert!(Oracle::::operator(operators[0]).is_none()); + } + activate_operator { let n in 1 .. ::MaxOperators::get(); - let operator = register_operators::(n); - }: _(RawOrigin::Root, operator) + let operators = register_operators::(n); + for operator in operators.iter().skip(1) { + Oracle::::activate_operator(RawOrigin::Signed(operator.clone()).into()).unwrap(); + } + + }: _(RawOrigin::Signed(operators[0].clone())) verify { - assert_eq!(Oracle::::operators().len(), (n - 1) as usize) + assert_eq!(Oracle::::active_operators(), operators); } initiate_request { let n in 50 .. 1000; @@ -43,6 +54,7 @@ benchmarks! { ); Oracle::::register_operator(RawOrigin::Root.into(), operator)?; + Oracle::::activate_operator(RawOrigin::Signed(operator).into())?; let data = vec![128; n as usize]; let fee = T::Currency::minimum_balance(); @@ -56,16 +68,14 @@ benchmarks! { impl_benchmark_test_suite!(Oracle, crate::mock::new_test_ext(), crate::mock::TestRuntime, extra = false); } -fn register_operators(n: u32) -> T::AccountId { +fn register_operators(n: u32) -> Vec { let operators: Vec = (0..n).map(|i| account(ACCOUNT, i, SEED)).collect(); - let operator_0 = operators[0].clone(); - - for operator in operators { - Oracle::::register_operator(RawOrigin::Root.into(), operator).unwrap(); + for operator in &operators { + Oracle::::register_operator(RawOrigin::Root.into(), operator.clone()).unwrap(); } - operator_0 + operators } #[derive(Clone, Copy, Debug, PartialEq, Eq, TypeInfo, Encode, Decode)] From 5f18bdfaeef52cb261933aac8b4fabc05dae1d90 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 21 Feb 2023 17:31:40 +0100 Subject: [PATCH 11/23] Oracle benchmarks finished. --- gn-pallets/pallet-oracle/src/benchmark.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/gn-pallets/pallet-oracle/src/benchmark.rs b/gn-pallets/pallet-oracle/src/benchmark.rs index 955df900..074363f8 100644 --- a/gn-pallets/pallet-oracle/src/benchmark.rs +++ b/gn-pallets/pallet-oracle/src/benchmark.rs @@ -20,7 +20,7 @@ benchmarks! { let max_operators = ::MaxOperators::get(); let n in 1 .. ::MaxOperators::get() - 1 => register_operators::(n); let operator: T::AccountId = account(ACCOUNT, max_operators - 1, SEED); - }: _(RawOrigin::Root, operator) + }: _(RawOrigin::Root, operator.clone()) verify { assert!(Oracle::::operator(operator).is_some()); } @@ -30,19 +30,29 @@ benchmarks! { let operators = register_operators::(n); }: _(RawOrigin::Root, operators[0].clone()) verify { - assert!(Oracle::::operator(operators[0]).is_none()); + assert!(Oracle::::operator(operators[0].clone()).is_none()); } activate_operator { let n in 1 .. ::MaxOperators::get(); - let operators = register_operators::(n); + let mut operators = register_operators::(n); for operator in operators.iter().skip(1) { Oracle::::activate_operator(RawOrigin::Signed(operator.clone()).into()).unwrap(); } - }: _(RawOrigin::Signed(operators[0].clone())) verify { + operators.sort(); assert_eq!(Oracle::::active_operators(), operators); } + deactivate_operator { + let n in 1 .. ::MaxOperators::get(); + let operators = register_operators::(n); + for operator in &operators { + Oracle::::activate_operator(RawOrigin::Signed(operator.clone()).into()).unwrap(); + } + }: _(RawOrigin::Signed(operators[0].clone())) + verify { + assert!(!Oracle::::active_operators().contains(&operators[0])); + } initiate_request { let n in 50 .. 1000; let caller: T::AccountId = whitelisted_caller(); @@ -53,8 +63,8 @@ benchmarks! { >::Balance::from(100u32) ); - Oracle::::register_operator(RawOrigin::Root.into(), operator)?; - Oracle::::activate_operator(RawOrigin::Signed(operator).into())?; + Oracle::::register_operator(RawOrigin::Root.into(), operator.clone())?; + Oracle::::activate_operator(RawOrigin::Signed(operator.clone()).into())?; let data = vec![128; n as usize]; let fee = T::Currency::minimum_balance(); From af1e116cd2698715731ffb6dc802a78dc202da27 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 21 Feb 2023 17:36:27 +0100 Subject: [PATCH 12/23] Fixed guild benchmarks. --- gn-pallets/pallet-guild/src/benchmark.rs | 3 +++ gn-pallets/pallet-guild/src/test/join_and_leave.rs | 3 ++- gn-pallets/pallet-guild/src/test/register.rs | 5 +++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gn-pallets/pallet-guild/src/benchmark.rs b/gn-pallets/pallet-guild/src/benchmark.rs index a18936d6..ef7d848b 100644 --- a/gn-pallets/pallet-guild/src/benchmark.rs +++ b/gn-pallets/pallet-guild/src/benchmark.rs @@ -194,6 +194,9 @@ benchmarks! { RawOrigin::Root.into(), operator.clone() ).unwrap(); + pallet_oracle::Pallet::::activate_operator( + RawOrigin::Signed(operator.clone()).into(), + ).unwrap(); Guild::::register( RawOrigin::Signed(caller.clone()).into(), identity_with_auth, diff --git a/gn-pallets/pallet-guild/src/test/join_and_leave.rs b/gn-pallets/pallet-guild/src/test/join_and_leave.rs index 498f9e4a..f8b2ca26 100644 --- a/gn-pallets/pallet-guild/src/test/join_and_leave.rs +++ b/gn-pallets/pallet-guild/src/test/join_and_leave.rs @@ -353,6 +353,7 @@ fn join_and_leave_unfiltered_role() { // register oracle operator ::register_operator(RuntimeOrigin::root(), operator).unwrap(); + ::activate_operator(RuntimeOrigin::signed(operator)).unwrap(); // register identity that requires oracle check ::register( RuntimeOrigin::signed(user), @@ -464,7 +465,7 @@ fn role_with_filtered_requirements() { // register oracle operator ::register_operator(RuntimeOrigin::root(), operator).unwrap(); - + ::activate_operator(RuntimeOrigin::signed(operator)).unwrap(); // register identity that requires oracle check ::register( RuntimeOrigin::signed(user), diff --git a/gn-pallets/pallet-guild/src/test/register.rs b/gn-pallets/pallet-guild/src/test/register.rs index aca5683e..7b9cf1c9 100644 --- a/gn-pallets/pallet-guild/src/test/register.rs +++ b/gn-pallets/pallet-guild/src/test/register.rs @@ -39,7 +39,7 @@ fn unsuccessful_registrations() { IdentityWithAuth::Other(Identity::Other([0u8; 64]), [0u8; 64]), max_identities - 1, ), - "NoRegisteredOperators", + "NoActiveOperators", ), ( ::register( @@ -165,6 +165,7 @@ fn successful_off_chain_registrations() { // register an operator first ::register_operator(RuntimeOrigin::root(), operator).unwrap(); + ::activate_operator(RuntimeOrigin::signed(operator)).unwrap(); // user registers id that requires off-chain verification ::register(RuntimeOrigin::signed(user), id_auth_zero, index).unwrap(); // pallet receives a dummy oracle answer @@ -220,7 +221,7 @@ fn successful_idenity_overrides() { // register an operator first ::register_operator(RuntimeOrigin::root(), operator).unwrap(); - + ::activate_operator(RuntimeOrigin::signed(operator)).unwrap(); // user registers an off-chain-verified identity let identity_with_auth = IdentityWithAuth::Other(id_zero, auth); let request_data: RequestData = RequestData::Register { From 7d417eb8fde0acbf8ca61a66fa2d95a5c29245fa Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 21 Feb 2023 19:21:24 +0100 Subject: [PATCH 13/23] All tests pass. --- gn-client/artifacts/metadata.scale | Bin 42504 -> 42863 bytes gn-client/examples/guild/common.rs | 74 +++++++++++++++++++++++---- gn-client/examples/guild/join.rs | 38 +++++--------- gn-client/examples/guild/main.rs | 4 ++ gn-client/examples/guild/register.rs | 14 +++++ gn-client/examples/guild/token.rs | 19 +++---- gn-client/src/query/functions.rs | 15 +++++- gn-client/src/tx/mod.rs | 10 +++- gn-oracle/src/main.rs | 33 +++++++++--- 9 files changed, 151 insertions(+), 56 deletions(-) create mode 100644 gn-client/examples/guild/register.rs diff --git a/gn-client/artifacts/metadata.scale b/gn-client/artifacts/metadata.scale index c5ea6cbadeed6d98eee9427ee85172a94b8029aa..0c59d56f49ed728a55ec4d790ee019dcea0f4f90 100644 GIT binary patch delta 582 zcmeA;!}R_f(*`3eCJC3xbyhl)6RgU0ToRK@GRqQ6QseUrQi~Ex@{1Ul7<^JvF@>2K zCSSLTV`SNEW<8yWk#+Mq+j)$P3Y&B77cnyKm@MF^#G{Z@sZf%Us!)`lUozRqQIqk; z~jFEjZqf@_? zhKpZ5*s-ZFyNVeYSeE$ZE94g?Cg-Fo;B?;PQ%-KO2{2ubIYp_7DV1=4Gcd8VOn&Di zE(7mdT+&l67*2vjNa$JDqiaE_>$e&&V;^ z%q5bMbMpk38D7#7K0)vRhgn(7z{tX+60+I6{}iKngkNbc7A1@fB?1f}V1wpKMg~tt M76yjRj1$>K0SyDjO8@`> delta 229 zcmaEVj;Z4e(*`3eCIOepbyhl)6RgT7Gh4?oGHp(>p3cO`y!n^yJVr)|%`@#6F*0^c zwsBONoaLy=v%)b?A+;j2xFj<#eX^sYFjr|_QEEDnpIS6I%Sn}yW%2~4u*nC^awi8n zD@&_{_~i#drBhS<3sQ>`OY)0~85mfmOzw3S=YVV7;OsWp#6^&iX|kJ(5i>JO!{l`? z5|bypNB|97<6^+bI{B`P4kO!SE?0j>_Q_GMk&GOhx46#m;ulbXo65-G$+$Uv!YRhd NhW*N$yC*#n0RU;OP5}S_ diff --git a/gn-client/examples/guild/common.rs b/gn-client/examples/guild/common.rs index ddb6d064..ca363f07 100644 --- a/gn-client/examples/guild/common.rs +++ b/gn-client/examples/guild/common.rs @@ -13,6 +13,9 @@ use sp_keyring::AccountKeyring; use std::collections::BTreeMap; use std::sync::Arc; +const RETRIES: u8 = 10; +const SLEEP_DURATION_MS: u64 = 500; + pub struct Accounts { pub substrate: Arc, pub eth: LocalWallet, @@ -74,21 +77,72 @@ pub async fn register_operators( ) { println!("registring operators"); for (i, account) in accounts.enumerate() { - let payload = tx::register_operator(&account.substrate.account_id()); - tx::send_owned_tx( - api.clone(), - tx::sudo(payload), - Arc::clone(&root), - TxStatus::InBlock, - ) - .await - .unwrap(); - println!("operator {i} registered"); + let payload = tx::register_operator(account.substrate.account_id()); + tx::send_tx_in_block(api.clone(), &tx::sudo(payload), Arc::clone(&root)) + .await + .unwrap(); + println!("\toperator {i} registered"); } println!("operator registrations in block"); } +pub async fn activate_operators(api: Api, accounts: impl Iterator) { + println!("activating operators"); + let tx_futures = accounts + .map(|acc| { + tx::send_owned_tx( + api.clone(), + tx::activate_operator(), + Arc::clone(&acc.substrate), + TxStatus::InBlock, + ) + }) + .collect::>(); + + try_join_all(tx_futures).await.unwrap(); + + println!("operators activated"); +} + +pub async fn wait_for_active_operator(api: Api) { + let mut i = 0; + loop { + let active_operators = query::active_operators(api.clone()) + .await + .expect("failed to fetch active operators"); + if active_operators.is_empty() { + i += 1; + println!("waiting for active operators"); + if i == RETRIES { + panic!("no active operators found"); + } + tokio::time::sleep(std::time::Duration::from_millis(SLEEP_DURATION_MS)).await; + } else { + println!("found an active operator"); + break; + } + } +} + +pub async fn wait_for_oracle_answers(api: Api) { + let mut i = 0; + loop { + let oracle_requests = query::oracle_requests(api.clone(), PAGE_SIZE) + .await + .expect("failed to fetch oracle requests"); + if !oracle_requests.is_empty() { + i += 1; + if i == RETRIES { + panic!("ran out of retries while checking oracle requests") + } + tokio::time::sleep(std::time::Duration::from_millis(SLEEP_DURATION_MS)).await; + } else { + break; + } + } +} + pub async fn create_dummy_guilds( api: Api, signer: Arc, diff --git a/gn-client/examples/guild/join.rs b/gn-client/examples/guild/join.rs index dad36769..c121ea8b 100644 --- a/gn-client/examples/guild/join.rs +++ b/gn-client/examples/guild/join.rs @@ -7,47 +7,33 @@ use gn_common::pad::padded_id; use gn_test_data::*; use std::sync::Arc; -const RETRIES: u8 = 10; -const SLEEP_DURATION_MS: u64 = 500; - pub async fn join(api: Api, root: Arc) { let operators = prefunded_accounts(api.clone(), Arc::clone(&root), N_TEST_ACCOUNTS).await; #[cfg(not(feature = "external-oracle"))] { - let registering_operators = operators.values(); - register_operators(api.clone(), Arc::clone(&root), registering_operators).await; - let registered_operators = query::registered_operators(api.clone()) + register_operators(api.clone(), Arc::clone(&root), operators.values()).await; + activate_operators(api.clone(), operators.values()).await; + let active_operators = query::active_operators(api.clone()) .await - .expect("failed to fetch registered operators"); + .expect("failed to fetch active operators"); - for registered in ®istered_operators { - if registered != root.account_id() { - assert!(operators.get(registered).is_some()); - } + for active in &active_operators { + assert!(operators.get(active).is_some()); } } + #[cfg(not(feature = "external-oracle"))] + { + wait_for_active_operator(api.clone()).await; + } + register_users(api.clone(), &operators).await; #[cfg(not(feature = "external-oracle"))] send_dummy_oracle_answers(api.clone(), &operators).await; // wait for all transactions to be finalized - let mut i = 0; - loop { - let oracle_requests = query::oracle_requests(api.clone(), PAGE_SIZE) - .await - .expect("failed to fetch oracle requests"); - if !oracle_requests.is_empty() { - i += 1; - if i == RETRIES { - panic!("ran out of retries while checking oracle requests") - } - tokio::time::sleep(std::time::Duration::from_millis(SLEEP_DURATION_MS)).await; - } else { - break; - } - } + wait_for_oracle_answers(api.clone()).await; for (i, (id, accounts)) in operators.iter().enumerate() { let user_identity = query::user_identity(api.clone(), id) diff --git a/gn-client/examples/guild/main.rs b/gn-client/examples/guild/main.rs index f1adc017..7c6c2449 100644 --- a/gn-client/examples/guild/main.rs +++ b/gn-client/examples/guild/main.rs @@ -1,5 +1,6 @@ mod common; mod join; +mod register; mod token; use common::api_with_alice; @@ -12,6 +13,7 @@ use std::str::FromStr; enum Example { Join, Token, + Register, } impl FromStr for Example { @@ -19,6 +21,7 @@ impl FromStr for Example { fn from_str(s: &str) -> Result { match s { "join" => Ok(Self::Join), + "register" => Ok(Self::Register), "token" => Ok(Self::Token), _ => Err(format!("no example with name {s}")), } @@ -52,6 +55,7 @@ async fn main() { match opt.example { Example::Join => join::join(api, alice).await, + Example::Register => register::register(api, alice).await, Example::Token => token::token(api, alice).await, } } diff --git a/gn-client/examples/guild/register.rs b/gn-client/examples/guild/register.rs new file mode 100644 index 00000000..47342abe --- /dev/null +++ b/gn-client/examples/guild/register.rs @@ -0,0 +1,14 @@ +use gn_client::{ + tx::{self, Signer}, + Api, +}; + +use std::sync::Arc; + +pub async fn register(api: Api, root: Arc) { + let payload = tx::register_operator(root.account_id()); + tx::send_tx_in_block(api, &tx::sudo(payload), root) + .await + .unwrap(); + println!("root registered as operator"); +} diff --git a/gn-client/examples/guild/token.rs b/gn-client/examples/guild/token.rs index c52fbc0e..07e830a7 100644 --- a/gn-client/examples/guild/token.rs +++ b/gn-client/examples/guild/token.rs @@ -1,4 +1,3 @@ -#[cfg(not(feature = "external-oracle"))] use crate::common::*; use ethers::types::{Address, U256}; use gn_client::{ @@ -41,19 +40,21 @@ pub async fn token(api: Api, root: Arc) { #[cfg(not(feature = "external-oracle"))] { - let registering_operators = operators.values(); - register_operators(api.clone(), Arc::clone(&root), registering_operators).await; - let registered_operators = query::registered_operators(api.clone()) + register_operators(api.clone(), Arc::clone(&root), operators.values()).await; + activate_operators(api.clone(), operators.values()).await; + let active_operators = query::active_operators(api.clone()) .await - .expect("failed to fetch registered operators"); + .expect("failed to fetch active operators"); - for registered in ®istered_operators { - if registered != root.account_id() { - assert!(operators.get(registered).is_some()); - } + for active in &active_operators { + assert!(operators.get(active).is_some()); } } + #[cfg(feature = "external-oracle")] + { + wait_for_active_operator(api.clone()).await; + } // register root with test evm address + signature let evm_identity = IdentityWithAuth::Ecdsa(Identity::Address20(address), EcdsaSignature(signature)); diff --git a/gn-client/src/query/functions.rs b/gn-client/src/query/functions.rs index 725e609e..fded2380 100644 --- a/gn-client/src/query/functions.rs +++ b/gn-client/src/query/functions.rs @@ -9,8 +9,8 @@ use subxt::storage::address::{StorageHasher, StorageMapKey}; use std::collections::BTreeMap; -pub async fn registered_operators(api: Api) -> Result, SubxtError> { - let operators = runtime::storage().oracle().operators(); +pub async fn active_operators(api: Api) -> Result, SubxtError> { + let operators = runtime::storage().oracle().active_operators(); Ok(api .storage() .at(None) @@ -20,6 +20,17 @@ pub async fn registered_operators(api: Api) -> Result, SubxtError .unwrap_or_default()) } +pub async fn is_operator_registered(api: Api, id: &AccountId) -> Result { + let operator = runtime::storage().oracle().registered_operators(id); + Ok(api + .storage() + .at(None) + .await? + .fetch(&operator) + .await? + .is_some()) +} + pub async fn user_identity(api: Api, user_id: &AccountId) -> Result, SubxtError> { let mut i = 0u8; let mut identities = Vec::new(); diff --git a/gn-client/src/tx/mod.rs b/gn-client/src/tx/mod.rs index b400132b..28eff8a2 100644 --- a/gn-client/src/tx/mod.rs +++ b/gn-client/src/tx/mod.rs @@ -21,7 +21,7 @@ use subxt::tx::{DynamicTxPayload, TxPayload}; use std::sync::Arc; -pub fn sudo<'a, 'b>(call: DynamicTxPayload<'a>) -> DynamicTxPayload<'b> { +pub fn sudo<'a>(call: DynamicTxPayload<'_>) -> DynamicTxPayload<'a> { subxt::dynamic::tx("Sudo", "sudo", vec![("call", call.into_value())]) } @@ -39,6 +39,14 @@ pub fn register_operator<'a>(operator: &AccountId) -> DynamicTxPayload<'a> { ) } +pub fn activate_operator() -> impl TxPayload { + runtime::tx().oracle().activate_operator() +} + +pub fn deactivate_operator() -> impl TxPayload { + runtime::tx().oracle().deactivate_operator() +} + pub fn oracle_callback(request_id: u64, data: Vec) -> impl TxPayload { runtime::tx().oracle().callback(request_id, data) } diff --git a/gn-oracle/src/main.rs b/gn-oracle/src/main.rs index fa03d910..c5f05aff 100644 --- a/gn-oracle/src/main.rs +++ b/gn-oracle/src/main.rs @@ -39,9 +39,9 @@ struct Opt { /// Set operator account #[structopt(long = "id", default_value = "alice")] id: String, - /// Register as an oracle operator before starting to listen to events + /// Activate operator before starting to listen to events #[structopt(long)] - register: bool, + activate: bool, } #[tokio::main] @@ -54,7 +54,7 @@ async fn main() { // TODO: this will be read from the oracle's wallet for testing purposes we // are choosing from pre-funded accounts - let signer = Arc::new(Signer::new( + let operator = Arc::new(Signer::new( match opt.id.to_lowercase().as_str() { "bob" => AccountKeyring::Bob, "charlie" => AccountKeyring::Charlie, @@ -70,12 +70,29 @@ async fn main() { .await .expect("failed to start api client"); - if opt.register { - tx::send_tx_in_block(api.clone(), &tx::register_operator(), Arc::clone(&signer)) + if !query::is_operator_registered(api.clone(), operator.account_id()) + .await + .expect("failed to fetch operator info") + { + panic!("{} is not registered as an operator", operator.account_id()); + } + + if opt.activate { + tx::send_tx_in_block(api.clone(), &tx::activate_operator(), Arc::clone(&operator)) .await - .expect("failed to register operator"); + .expect("failed to activate operator"); - log::info!("operator registration request submitted"); + log::info!("operator activation request submitted"); + } + + let active = query::active_operators(api.clone()) + .await + .expect("failed to fetch active operators"); + if !active.contains(operator.account_id()) { + panic!( + "{} not activated. Run oracle with the '--activate' flag", + operator.account_id() + ); } let mut subscription = api @@ -95,7 +112,7 @@ async fn main() { event_details.as_event::().ok().flatten() }) .for_each(|oracle_request| { - submit_answer(api.clone(), Arc::clone(&signer), oracle_request) + submit_answer(api.clone(), Arc::clone(&operator), oracle_request) }); } Err(err) => log::error!("invalid block events: {err}"), From bbd6e80b99f5b3192a8d297c3b82e916e0bdb722 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 21 Feb 2023 21:01:13 +0100 Subject: [PATCH 14/23] Oracle pallet weights added. --- gn-pallets/pallet-oracle/src/benchmark.rs | 4 +- gn-pallets/pallet-oracle/src/lib.rs | 11 +- gn-pallets/pallet-oracle/src/weights.rs | 239 ++++++++++++++++------ gn-runtime/src/lib.rs | 4 +- start.sh | 1 - 5 files changed, 186 insertions(+), 73 deletions(-) diff --git a/gn-pallets/pallet-oracle/src/benchmark.rs b/gn-pallets/pallet-oracle/src/benchmark.rs index 074363f8..40e429b6 100644 --- a/gn-pallets/pallet-oracle/src/benchmark.rs +++ b/gn-pallets/pallet-oracle/src/benchmark.rs @@ -115,6 +115,8 @@ impl UnfilteredDispatchable for MockCallback { impl MockCallback { pub fn test() -> ::Callback { - Decode::decode(&mut &[][..]).unwrap() + let mut enc = vec![9]; + enc.extend(vec![1u8, 2, 3].encode()); + Decode::decode(&mut &enc[..]).unwrap() } } diff --git a/gn-pallets/pallet-oracle/src/lib.rs b/gn-pallets/pallet-oracle/src/lib.rs index cb1a789d..5ecdab11 100644 --- a/gn-pallets/pallet-oracle/src/lib.rs +++ b/gn-pallets/pallet-oracle/src/lib.rs @@ -28,6 +28,7 @@ mod test; mod weights; pub use pallet::*; +pub use weights::WeightInfo; #[frame_support::pallet] pub mod pallet { @@ -193,7 +194,7 @@ pub mod pallet { impl Pallet { /// Register a new Operator. #[pallet::call_index(0)] - #[pallet::weight(T::WeightInfo::register_operator())] + #[pallet::weight(T::WeightInfo::register_operator(T::MaxOperators::get()))] pub fn register_operator(origin: OriginFor, operator: T::AccountId) -> DispatchResult { ensure_root(origin)?; @@ -215,7 +216,7 @@ pub mod pallet { /// Deregisters an already registered Operator #[pallet::call_index(1)] - #[pallet::weight(T::WeightInfo::deregister_operator())] + #[pallet::weight(T::WeightInfo::deregister_operator(T::MaxOperators::get()))] pub fn deregister_operator(origin: OriginFor, operator: T::AccountId) -> DispatchResult { ensure_root(origin)?; @@ -236,7 +237,7 @@ pub mod pallet { } #[pallet::call_index(2)] - #[pallet::weight(T::WeightInfo::activate_operator())] + #[pallet::weight((T::WeightInfo::activate_operator(T::MaxOperators::get()), Pays::No))] pub fn activate_operator(origin: OriginFor) -> DispatchResult { let operator = ensure_signed(origin)?; @@ -258,7 +259,7 @@ pub mod pallet { } #[pallet::call_index(3)] - #[pallet::weight(T::WeightInfo::deactivate_operator())] + #[pallet::weight((T::WeightInfo::deactivate_operator(T::MaxOperators::get()), Pays::No))] pub fn deactivate_operator(origin: OriginFor) -> DispatchResult { let operator = ensure_signed(origin)?; ensure!( @@ -289,7 +290,7 @@ pub mod pallet { /// required information to perform the request and provide back /// the result. #[pallet::call_index(4)] - #[pallet::weight(T::WeightInfo::initiate_request())] + #[pallet::weight((T::WeightInfo::initiate_request(500), Pays::No))] pub fn initiate_request( origin: OriginFor, callback: ::Callback, diff --git a/gn-pallets/pallet-oracle/src/weights.rs b/gn-pallets/pallet-oracle/src/weights.rs index 3c8e42bd..dd6ce225 100644 --- a/gn-pallets/pallet-oracle/src/weights.rs +++ b/gn-pallets/pallet-oracle/src/weights.rs @@ -1,29 +1,14 @@ -// This file is part of Substrate. -// Copyright (C) 2022 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Autogenerated weights for pallet_oracle +//! Autogenerated weights for `pallet_oracle` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-09-23, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! HOSTNAME: `turbineblade`, CPU: `AMD Ryzen 5 3600 6-Core Processor` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 19.0.0 +//! DATE: 2023-02-21, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `razorblade`, CPU: `Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/release/node-template +// ./target/release/gn-node // benchmark // pallet // --chain @@ -38,10 +23,8 @@ // 50 // --repeat // 20 -// --template -// frame-weight-template.hbs // --output -// ./pallets/pallet-oracle/src/weights.rs +// ./gn-pallets/pallet-oracle/src/weights.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] @@ -50,62 +33,190 @@ use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; -/// Weight functions needed for pallet_oracle. pub trait WeightInfo { - fn register_operator() -> Weight; - fn deregister_operator() -> Weight; - fn activate_operator() -> Weight; - fn deactivate_operator() -> Weight; - fn initiate_request() -> Weight; + fn register_operator(n: u32, ) -> Weight; + fn deregister_operator(n: u32, ) -> Weight; + fn activate_operator(n: u32, ) -> Weight; + fn deactivate_operator(n: u32, ) -> Weight; + fn initiate_request(n: u32, ) -> Weight; } -/// Weights for pallet_oracle using the Substrate node and recommended hardware. +/// Weight functions for `pallet_oracle`. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - // Storage: Oracle Operators (r:1 w:1) - fn register_operator() -> Weight { - Weight::from_parts(16_972_000, 16_972_000) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) + /// Storage: Oracle NumRegisteredOperators (r:1 w:1) + /// Proof Skipped: Oracle NumRegisteredOperators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle RegisteredOperators (r:1 w:1) + /// Proof Skipped: Oracle RegisteredOperators (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[1, 9]`. + fn register_operator(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `77 + n * (25 ±0)` + // Estimated: `3120 + n * (50 ±0)` + // Minimum execution time: 21_815 nanoseconds. + Weight::from_parts(33_363_548, 3120) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(2)) + .saturating_add(Weight::from_proof_size(50).saturating_mul(n.into())) } - // Storage: Oracle Operators (r:1 w:1) - fn deregister_operator() -> Weight { - Weight::from_parts(16_862_000, 16_862_000) - .saturating_add(T::DbWeight::get().reads(1)) - .saturating_add(T::DbWeight::get().writes(1)) + /// Storage: Oracle RegisteredOperators (r:1 w:1) + /// Proof Skipped: Oracle RegisteredOperators (max_values: None, max_size: None, mode: Measured) + /// Storage: Oracle ActiveOperators (r:1 w:1) + /// Proof Skipped: Oracle ActiveOperators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle NumRegisteredOperators (r:1 w:1) + /// Proof Skipped: Oracle NumRegisteredOperators (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `n` is `[1, 9]`. + fn deregister_operator(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `72 + n * (34 ±0)` + // Estimated: `3681 + n * (102 ±0)` + // Minimum execution time: 22_749 nanoseconds. + Weight::from_parts(32_567_146, 3681) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + .saturating_add(Weight::from_proof_size(102).saturating_mul(n.into())) } - fn activate_operator() -> Weight { - Weight::from_parts(16_862_000, 16_862_000) + /// Storage: Oracle RegisteredOperators (r:1 w:0) + /// Proof Skipped: Oracle RegisteredOperators (max_values: None, max_size: None, mode: Measured) + /// Storage: Oracle ActiveOperators (r:1 w:1) + /// Proof Skipped: Oracle ActiveOperators (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `n` is `[1, 10]`. + fn activate_operator(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `95 + n * (66 ±0)` + // Estimated: `3124 + n * (136 ±0)` + // Minimum execution time: 23_000 nanoseconds. + Weight::from_parts(32_471_489, 3124) + // Standard Error: 56_513 + .saturating_add(Weight::from_ref_time(298_375).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_proof_size(136).saturating_mul(n.into())) } - fn deactivate_operator() -> Weight { - Weight::from_parts(16_862_000, 16_862_000) + /// Storage: Oracle RegisteredOperators (r:1 w:0) + /// Proof Skipped: Oracle RegisteredOperators (max_values: None, max_size: None, mode: Measured) + /// Storage: Oracle ActiveOperators (r:1 w:1) + /// Proof Skipped: Oracle ActiveOperators (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `n` is `[1, 10]`. + fn deactivate_operator(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `128 + n * (65 ±0)` + // Estimated: `3240 + n * (128 ±0)` + // Minimum execution time: 21_588 nanoseconds. + Weight::from_parts(30_203_793, 3240) + // Standard Error: 73_025 + .saturating_add(Weight::from_ref_time(321_732).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(2)) + .saturating_add(T::DbWeight::get().writes(1)) + .saturating_add(Weight::from_proof_size(128).saturating_mul(n.into())) } - fn initiate_request() -> Weight { - Weight::from_parts(16_862_000, 16_862_000) + /// Storage: Oracle ActiveOperators (r:1 w:0) + /// Proof Skipped: Oracle ActiveOperators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle NextOperator (r:1 w:1) + /// Proof Skipped: Oracle NextOperator (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle NextRequestIdentifier (r:1 w:1) + /// Proof Skipped: Oracle NextRequestIdentifier (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle Requests (r:0 w:1) + /// Proof Skipped: Oracle Requests (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[50, 1000]`. + fn initiate_request(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `153` + // Estimated: `2097` + // Minimum execution time: 27_835 nanoseconds. + Weight::from_parts(36_093_449, 2097) + // Standard Error: 931 + .saturating_add(Weight::from_ref_time(3_363).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) } } -// For backwards compatibility and tests impl WeightInfo for () { - // Storage: Oracle Operators (r:1 w:1) - fn register_operator() -> Weight { - Weight::from_parts(16_972_000, 16_972_000) - .saturating_add(RocksDbWeight::get().reads(1)) - .saturating_add(RocksDbWeight::get().writes(1)) + /// Storage: Oracle NumRegisteredOperators (r:1 w:1) + /// Proof Skipped: Oracle NumRegisteredOperators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle RegisteredOperators (r:1 w:1) + /// Proof Skipped: Oracle RegisteredOperators (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[1, 9]`. + fn register_operator(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `77 + n * (25 ±0)` + // Estimated: `3120 + n * (50 ±0)` + // Minimum execution time: 21_815 nanoseconds. + Weight::from_parts(33_363_548, 3120) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(2)) + .saturating_add(Weight::from_proof_size(50).saturating_mul(n.into())) } - // Storage: Oracle Operators (r:1 w:1) - fn deregister_operator() -> Weight { - Weight::from_parts(16_862_000, 16_862_000) - .saturating_add(RocksDbWeight::get().reads(1)) - .saturating_add(RocksDbWeight::get().writes(1)) + /// Storage: Oracle RegisteredOperators (r:1 w:1) + /// Proof Skipped: Oracle RegisteredOperators (max_values: None, max_size: None, mode: Measured) + /// Storage: Oracle ActiveOperators (r:1 w:1) + /// Proof Skipped: Oracle ActiveOperators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle NumRegisteredOperators (r:1 w:1) + /// Proof Skipped: Oracle NumRegisteredOperators (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `n` is `[1, 9]`. + fn deregister_operator(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `72 + n * (34 ±0)` + // Estimated: `3681 + n * (102 ±0)` + // Minimum execution time: 22_749 nanoseconds. + Weight::from_parts(32_567_146, 3681) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(3)) + .saturating_add(Weight::from_proof_size(102).saturating_mul(n.into())) } - fn activate_operator() -> Weight { - Weight::from_parts(16_862_000, 16_862_000) + /// Storage: Oracle RegisteredOperators (r:1 w:0) + /// Proof Skipped: Oracle RegisteredOperators (max_values: None, max_size: None, mode: Measured) + /// Storage: Oracle ActiveOperators (r:1 w:1) + /// Proof Skipped: Oracle ActiveOperators (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `n` is `[1, 10]`. + fn activate_operator(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `95 + n * (66 ±0)` + // Estimated: `3124 + n * (136 ±0)` + // Minimum execution time: 23_000 nanoseconds. + Weight::from_parts(32_471_489, 3124) + // Standard Error: 56_513 + .saturating_add(Weight::from_ref_time(298_375).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + .saturating_add(Weight::from_proof_size(136).saturating_mul(n.into())) } - fn deactivate_operator() -> Weight { - Weight::from_parts(16_862_000, 16_862_000) + /// Storage: Oracle RegisteredOperators (r:1 w:0) + /// Proof Skipped: Oracle RegisteredOperators (max_values: None, max_size: None, mode: Measured) + /// Storage: Oracle ActiveOperators (r:1 w:1) + /// Proof Skipped: Oracle ActiveOperators (max_values: Some(1), max_size: None, mode: Measured) + /// The range of component `n` is `[1, 10]`. + fn deactivate_operator(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `128 + n * (65 ±0)` + // Estimated: `3240 + n * (128 ±0)` + // Minimum execution time: 21_588 nanoseconds. + Weight::from_parts(30_203_793, 3240) + // Standard Error: 73_025 + .saturating_add(Weight::from_ref_time(321_732).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(2)) + .saturating_add(RocksDbWeight::get().writes(1)) + .saturating_add(Weight::from_proof_size(128).saturating_mul(n.into())) } - fn initiate_request() -> Weight { - Weight::from_parts(16_862_000, 16_862_000) + /// Storage: Oracle ActiveOperators (r:1 w:0) + /// Proof Skipped: Oracle ActiveOperators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle NextOperator (r:1 w:1) + /// Proof Skipped: Oracle NextOperator (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle NextRequestIdentifier (r:1 w:1) + /// Proof Skipped: Oracle NextRequestIdentifier (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle Requests (r:0 w:1) + /// Proof Skipped: Oracle Requests (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[50, 1000]`. + fn initiate_request(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `153` + // Estimated: `2097` + // Minimum execution time: 27_835 nanoseconds. + Weight::from_parts(36_093_449, 2097) + // Standard Error: 931 + .saturating_add(Weight::from_ref_time(3_363).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(3)) } } diff --git a/gn-runtime/src/lib.rs b/gn-runtime/src/lib.rs index e7a88587..95583ed5 100644 --- a/gn-runtime/src/lib.rs +++ b/gn-runtime/src/lib.rs @@ -137,7 +137,7 @@ parameter_types! { pub const SS58Prefix: u8 = 42; pub const ValidityPeriod: u32 = 50; pub const MinimumFee: u32 = 0; - pub const ExistentialDeposit: Balance = 500; + pub const ExistentialDeposit: Balance = 0; } // Configure FRAME pallets to include in runtime. @@ -271,7 +271,7 @@ impl pallet_oracle::Config for Runtime { type MaxOperators = ConstU32<10>; type MinimumFee = MinimumFee; type ValidityPeriod = ValidityPeriod; - type WeightInfo = (); + type WeightInfo = pallet_oracle::weights::SubstrateWeight; } // Create the runtime by composing the FRAME pallets that were previously configured. diff --git a/start.sh b/start.sh index 3a1eee2d..cd8a6676 100755 --- a/start.sh +++ b/start.sh @@ -51,7 +51,6 @@ elif [ $1 = "benchmark" ]; then --wasm-execution=compiled \ --steps 50 \ --repeat 20 \ - --template frame-weight-template.hbs \ --output ./gn-pallets/pallet-$pallet/src/weights.rs else echo "Invalid command" From 78c4afe8bd72b3e3a8e53e44b78b04dca2395f1e Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Tue, 21 Feb 2023 21:14:44 +0100 Subject: [PATCH 15/23] Free guild pallet calls. --- gn-pallets/pallet-guild/src/lib.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/gn-pallets/pallet-guild/src/lib.rs b/gn-pallets/pallet-guild/src/lib.rs index 9ef7ffb0..e63e4245 100644 --- a/gn-pallets/pallet-guild/src/lib.rs +++ b/gn-pallets/pallet-guild/src/lib.rs @@ -150,7 +150,7 @@ pub mod pallet { #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight(1000)] + #[pallet::weight((1000, Pays::No))] pub fn register( origin: OriginFor, identity_with_auth: IdentityWithAuth, @@ -201,7 +201,7 @@ pub mod pallet { } #[pallet::call_index(1)] - #[pallet::weight(10000000)] + #[pallet::weight((1000, Pays::No))] pub fn join( origin: OriginFor, guild_name: GuildName, @@ -284,7 +284,7 @@ pub mod pallet { } #[pallet::call_index(2)] - #[pallet::weight(10000000)] + #[pallet::weight((1000, Pays::No))] pub fn leave( origin: OriginFor, guild_name: GuildName, @@ -298,7 +298,7 @@ pub mod pallet { } #[pallet::call_index(3)] - #[pallet::weight(10000000)] + #[pallet::weight(1000)] pub fn request_oracle_check( origin: OriginFor, account: T::AccountId, @@ -353,7 +353,7 @@ pub mod pallet { } #[pallet::call_index(4)] - #[pallet::weight(10000000)] + #[pallet::weight((1000, Pays::No))] pub fn create_guild( origin: OriginFor, guild_name: GuildName, @@ -387,7 +387,7 @@ pub mod pallet { } #[pallet::call_index(5)] - #[pallet::weight(10000000)] + #[pallet::weight((1000, Pays::No))] pub fn create_free_role( origin: OriginFor, guild_name: GuildName, @@ -398,7 +398,7 @@ pub mod pallet { } #[pallet::call_index(6)] - #[pallet::weight(10000000)] + #[pallet::weight((1000, Pays::No))] pub fn create_role_with_allowlist( origin: OriginFor, guild_name: GuildName, @@ -422,7 +422,7 @@ pub mod pallet { } #[pallet::call_index(7)] - #[pallet::weight(10000000)] + #[pallet::weight((1000, Pays::No))] pub fn create_child_role( origin: OriginFor, guild_name: GuildName, @@ -444,7 +444,7 @@ pub mod pallet { } #[pallet::call_index(8)] - #[pallet::weight(10000000)] + #[pallet::weight((1000, Pays::No))] pub fn create_unfiltered_role( origin: OriginFor, guild_name: GuildName, From ffba6ac5935d2c0a9fba0e0857fd4562919698df Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Wed, 22 Feb 2023 07:47:09 +0100 Subject: [PATCH 16/23] Wip finishing touches. --- gn-common/Cargo.toml | 1 + gn-common/src/identity/auth.rs | 33 +- gn-pallets/pallet-guild/Cargo.toml | 1 + gn-pallets/pallet-guild/src/benchmark.rs | 24 +- gn-pallets/pallet-guild/src/lib.rs | 8 +- gn-pallets/pallet-guild/src/weights.rs | 474 +++++++++++++++++++---- gn-pallets/pallet-oracle/src/lib.rs | 4 +- 7 files changed, 451 insertions(+), 94 deletions(-) diff --git a/gn-common/Cargo.toml b/gn-common/Cargo.toml index a05d15e1..77886f93 100644 --- a/gn-common/Cargo.toml +++ b/gn-common/Cargo.toml @@ -13,6 +13,7 @@ std = [ "schnorrkel/std", "sha3/std", ] +test-sig = [] [dependencies] binary-merkle-tree = { version = "4.0.0", default-features = false } diff --git a/gn-common/src/identity/auth.rs b/gn-common/src/identity/auth.rs index 0cae82ef..715b20f0 100644 --- a/gn-common/src/identity/auth.rs +++ b/gn-common/src/identity/auth.rs @@ -102,6 +102,34 @@ pub fn eth_hash_message>(message: M) -> [u8; 32] { keccak256(ð_message) } +#[cfg(any(test, feature = "test-sig"))] +pub fn sign_prehashed(seed: [u8; 32], message: [u8; 32]) -> EcdsaSignature { + let secret = secp256k1::SecretKey::from_slice(&seed).expect("seed is 32 bytes; qed"); + let message = Message::from_slice(&message).expect("Message is 32 bytes; qed"); + + let (rec_id, sig) = Secp256k1::signing_only() + .sign_ecdsa_recoverable(&message, &secret) + .serialize_compact(); + let mut sig_bytes = [0u8; 65]; + sig_bytes[64] = rec_id.to_i32() as u8; + sig_bytes[0..64].copy_from_slice(&sig); + EcdsaSignature(sig_bytes) +} + +#[cfg(any(test, feature = "test-sig"))] +pub fn test_ecdsa_id_with_auth>( + seed: [u8; 32], + msg: M, +) -> (Identity, EcdsaSignature) { + let prehashed = eth_hash_message(msg); + let signature = sign_prehashed(seed, prehashed); + let pubkey = recover_prehashed(prehashed, &signature).unwrap(); + let address: [u8; 20] = keccak256(&pubkey.serialize_uncompressed()[1..])[12..] + .try_into() + .unwrap(); + (Identity::Address20(address), signature) +} + #[cfg(test)] mod test { use super::*; @@ -151,7 +179,10 @@ mod test { let id_with_auth = IdentityWithAuth::Ecdsa(sp_address, sp_signature); assert!(id_with_auth.verify(&msg)); - assert!(!id_with_auth.verify(b"wrong msg")) + assert!(!id_with_auth.verify(b"wrong msg")); + + let (address, signature) = test_ecdsa_id_with_auth(seed, &msg); + assert!(IdentityWithAuth::Ecdsa(address, signature).verify(&msg)); } #[tokio::test] diff --git a/gn-pallets/pallet-guild/Cargo.toml b/gn-pallets/pallet-guild/Cargo.toml index 458bc954..dd662c1e 100644 --- a/gn-pallets/pallet-guild/Cargo.toml +++ b/gn-pallets/pallet-guild/Cargo.toml @@ -7,6 +7,7 @@ version = "0.0.0-alpha" default = ["std"] runtime-benchmarks = [ "frame-benchmarking/runtime-benchmarks", + "gn-common/test-sig", ] std = [ "gn-common/std", diff --git a/gn-pallets/pallet-guild/src/benchmark.rs b/gn-pallets/pallet-guild/src/benchmark.rs index ef7d848b..28fb8b8b 100644 --- a/gn-pallets/pallet-guild/src/benchmark.rs +++ b/gn-pallets/pallet-guild/src/benchmark.rs @@ -15,7 +15,7 @@ const SEED: u32 = 999; benchmarks! { register { let caller: T::AccountId = whitelisted_caller(); - let (identity, signature) = id_with_auth::(); + let (identity, signature) = id_with_auth::(&caller); let identity_with_auth = IdentityWithAuth::Ecdsa(identity, signature); let index = 1; }: _(RawOrigin::Signed(caller.clone()), identity_with_auth, index) @@ -113,7 +113,7 @@ benchmarks! { // identity let caller: T::AccountId = whitelisted_caller(); - let (identity, signature) = id_with_auth::(); + let (identity, signature) = id_with_auth::(&caller); let identity_with_auth = IdentityWithAuth::Ecdsa(identity, signature); Guild::::register( RawOrigin::Signed(caller.clone()).into(), @@ -149,7 +149,7 @@ benchmarks! { leave { let caller: T::AccountId = whitelisted_caller(); - let (identity, signature) = id_with_auth::(); + let (identity, signature) = id_with_auth::(&caller); let identity_with_auth = IdentityWithAuth::Ecdsa(identity, signature); Guild::::register( @@ -187,7 +187,7 @@ benchmarks! { let caller: T::AccountId = whitelisted_caller(); let keeper: T::AccountId = account(ACCOUNT, 123, SEED); let operator: T::AccountId = account(ACCOUNT, 222, SEED); - let (identity, signature) = id_with_auth::(); + let (identity, signature) = id_with_auth::(&caller); let identity_with_auth = IdentityWithAuth::Ecdsa(identity, signature); pallet_oracle::Pallet::::register_operator( @@ -254,17 +254,7 @@ fn init_guild(caller: &T::AccountId, guild_name: [u8; 32]) { .unwrap(); } -const ADDRESS: [u8; 20] = [ - 181, 107, 240, 94, 75, 219, 191, 204, 187, 168, 13, 127, 220, 79, 13, 235, 246, 21, 213, 11, -]; - -const SIGNATURE: [u8; 65] = [ - 252, 125, 173, 220, 20, 148, 251, 98, 222, 103, 168, 18, 25, 200, 32, 44, 130, 113, 16, 110, - 44, 102, 249, 87, 225, 146, 239, 99, 61, 41, 59, 116, 75, 60, 155, 227, 103, 131, 188, 167, - 198, 47, 72, 62, 166, 146, 182, 134, 9, 159, 28, 76, 188, 7, 20, 189, 106, 78, 47, 114, 17, 86, - 201, 32, 1, -]; - -fn id_with_auth() -> (Identity, EcdsaSignature) { - (Identity::Address20(ADDRESS), EcdsaSignature(SIGNATURE)) +fn id_with_auth(caller: &T::AccountId) -> (Identity, EcdsaSignature) { + let seed = [2u8; 32]; + gn_common::identity::test_ecdsa_id_with_auth(seed, gn_common::utils::verification_msg(caller)) } diff --git a/gn-pallets/pallet-guild/src/lib.rs b/gn-pallets/pallet-guild/src/lib.rs index e63e4245..cacefb8b 100644 --- a/gn-pallets/pallet-guild/src/lib.rs +++ b/gn-pallets/pallet-guild/src/lib.rs @@ -150,7 +150,7 @@ pub mod pallet { #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight((1000, Pays::No))] + #[pallet::weight((T::WeightInfo::register(), Pays::No))] pub fn register( origin: OriginFor, identity_with_auth: IdentityWithAuth, @@ -201,7 +201,7 @@ pub mod pallet { } #[pallet::call_index(1)] - #[pallet::weight((1000, Pays::No))] + #[pallet::weight((T::WeightInfo::join(), Pays::No))] pub fn join( origin: OriginFor, guild_name: GuildName, @@ -284,7 +284,7 @@ pub mod pallet { } #[pallet::call_index(2)] - #[pallet::weight((1000, Pays::No))] + #[pallet::weight((T::WeightInfo::leave(), Pays::No))] pub fn leave( origin: OriginFor, guild_name: GuildName, @@ -298,7 +298,7 @@ pub mod pallet { } #[pallet::call_index(3)] - #[pallet::weight(1000)] + #[pallet::weight(T::WeightInfo::request_oracle_check())] pub fn request_oracle_check( origin: OriginFor, account: T::AccountId, diff --git a/gn-pallets/pallet-guild/src/weights.rs b/gn-pallets/pallet-guild/src/weights.rs index 7995a0dd..5782005d 100644 --- a/gn-pallets/pallet-guild/src/weights.rs +++ b/gn-pallets/pallet-guild/src/weights.rs @@ -1,29 +1,14 @@ -// This file is part of Substrate. -// Copyright (C) 2022 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Autogenerated weights for pallet_guild +//! Autogenerated weights for `pallet_guild` //! -//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-10-27, STEPS: `50`, REPEAT: 20, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! HOSTNAME: `turbineblade`, CPU: `AMD Ryzen 5 3600 6-Core Processor` +//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 19.0.0 +//! DATE: 2023-02-22, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! WORST CASE MAP SIZE: `1000000` +//! HOSTNAME: `razorblade`, CPU: `Intel(R) Core(TM) i5-10210U CPU @ 1.60GHz` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/release/node-template +// ./target/release/gn-node // benchmark // pallet // --chain @@ -38,75 +23,424 @@ // 50 // --repeat // 20 -// --template -// frame-weight-template.hbs // --output -// ./pallets/pallet-guild/src/weights.rs +// ./gn-pallets/pallet-guild/src/weights.rs #![cfg_attr(rustfmt, rustfmt_skip)] #![allow(unused_parens)] #![allow(unused_imports)] -use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; +use frame_support::{traits::Get, weights::Weight, constants::RocksDBWeight}; use sp_std::marker::PhantomData; -/// Weight functions needed for pallet_guild. pub trait WeightInfo { - fn create_guild(r: u64, ) -> Weight; - fn join_guild() -> Weight; + fn register() -> Weight; + fn create_guild(n: u32, ) -> Weight; + fn create_free_role() -> Weight; + fn create_role_with_allowlist(n: u32, r: u32, _s: u32, ) -> Weight; + fn create_child_role(r: u32, s: u32, ) -> Weight; + fn create_unfiltered_role(r: u32, s: u32, ) -> Weight; + fn join() -> Weight; + fn leave() -> Weight; + fn request_oracle_check() -> Weight; } -/// Weights for pallet_guild using the Substrate node and recommended hardware. +/// Weight functions for `pallet_guild`. pub struct SubstrateWeight(PhantomData); impl WeightInfo for SubstrateWeight { - // Storage: Guild Guilds (r:1 w:1) - // Storage: Guild Roles (r:0 w:2) - /// The range of component `r` is `[0, 100]`. - fn create_guild(r: u64, ) -> Weight { - Weight::from_parts(19_413_000, 19_413_000) - // Standard Error: 3_000 - .saturating_add(Weight::from_parts(2_651_000, 2_651_000).saturating_mul(r)) - .saturating_add(T::DbWeight::get().reads(1)) + /// Storage: Guild UserData (r:0 w:1) + /// Proof Skipped: Guild UserData (max_values: None, max_size: None, mode: Measured) + fn register() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 369_767 nanoseconds. + Weight::from_ref_time(392_263_000) .saturating_add(T::DbWeight::get().writes(1)) - .saturating_add(T::DbWeight::get().writes(r)) - } - // Storage: Guild Roles (r:1 w:0) - // Storage: Guild NextRequestIdentifier (r:1 w:1) - // Storage: Chainlink Operators (r:1 w:0) - // Storage: Chainlink NextOperator (r:1 w:1) - // Storage: Chainlink NextRequestIdentifier (r:1 w:1) - // Storage: Guild JoinRequests (r:0 w:1) - // Storage: Chainlink Requests (r:0 w:1) - fn join_guild() -> Weight { - Weight::from_parts(53_270_000, 53_270_000) + } + /// Storage: Guild GuildIdMap (r:1 w:1) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Nonce (r:1 w:1) + /// Proof Skipped: Guild Nonce (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Guild Guilds (r:0 w:1) + /// Proof Skipped: Guild Guilds (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[0, 256]`. + fn create_guild(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `115` + // Estimated: `6404` + // Minimum execution time: 26_721 nanoseconds. + Weight::from_parts(39_154_463, 6404) + // Standard Error: 3_905 + .saturating_add(Weight::from_ref_time(2_434).saturating_mul(n.into())) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(3)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:1) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Guilds (r:1 w:1) + /// Proof Skipped: Guild Guilds (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Nonce (r:1 w:1) + /// Proof Skipped: Guild Nonce (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Guild Roles (r:0 w:1) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + fn create_free_role() -> Weight { + // Proof Size summary in bytes: + // Measured: `678` + // Estimated: `14399` + // Minimum execution time: 46_699 nanoseconds. + Weight::from_parts(52_729_000, 14399) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:1) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Guilds (r:1 w:1) + /// Proof Skipped: Guild Guilds (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Nonce (r:1 w:1) + /// Proof Skipped: Guild Nonce (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Guild Roles (r:0 w:1) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[1, 128]`. + /// The range of component `r` is `[0, 10]`. + /// The range of component `s` is `[0, 256]`. + fn create_role_with_allowlist(n: u32, r: u32, _s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `678` + // Estimated: `14399` + // Minimum execution time: 77_201 nanoseconds. + Weight::from_parts(85_825_100, 14399) + // Standard Error: 32_487 + .saturating_add(Weight::from_ref_time(1_613_995).saturating_mul(n.into())) + // Standard Error: 392_769 + .saturating_add(Weight::from_ref_time(514_801).saturating_mul(r.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:2 w:1) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Guilds (r:1 w:1) + /// Proof Skipped: Guild Guilds (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Nonce (r:1 w:1) + /// Proof Skipped: Guild Nonce (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Guild Roles (r:0 w:1) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[0, 10]`. + /// The range of component `s` is `[0, 256]`. + fn create_child_role(r: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `894` + // Estimated: `17954` + // Minimum execution time: 53_095 nanoseconds. + Weight::from_parts(46_540_343, 17954) + // Standard Error: 138_192 + .saturating_add(Weight::from_ref_time(2_136_397).saturating_mul(r.into())) + // Standard Error: 5_670 + .saturating_add(Weight::from_ref_time(52_708).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(6)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:1) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Guilds (r:1 w:1) + /// Proof Skipped: Guild Guilds (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Nonce (r:1 w:1) + /// Proof Skipped: Guild Nonce (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Guild Roles (r:0 w:1) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[0, 10]`. + /// The range of component `s` is `[0, 256]`. + fn create_unfiltered_role(r: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `678` + // Estimated: `14399` + // Minimum execution time: 44_245 nanoseconds. + Weight::from_parts(55_627_418, 14399) + // Standard Error: 119_983 + .saturating_add(Weight::from_ref_time(266_588).saturating_mul(r.into())) + // Standard Error: 4_923 + .saturating_add(Weight::from_ref_time(20_540).saturating_mul(s.into())) + .saturating_add(T::DbWeight::get().reads(5)) + .saturating_add(T::DbWeight::get().writes(4)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:0) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild UserData (r:2 w:0) + /// Proof Skipped: Guild UserData (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Roles (r:1 w:0) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Members (r:0 w:1) + /// Proof Skipped: Guild Members (max_values: None, max_size: None, mode: Measured) + fn join() -> Weight { + // Proof Size summary in bytes: + // Measured: `656` + // Estimated: `15655` + // Minimum execution time: 54_580 nanoseconds. + Weight::from_parts(61_062_000, 15655) .saturating_add(T::DbWeight::get().reads(5)) - .saturating_add(T::DbWeight::get().writes(5)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:0) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild UserData (r:1 w:0) + /// Proof Skipped: Guild UserData (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Members (r:0 w:1) + /// Proof Skipped: Guild Members (max_values: None, max_size: None, mode: Measured) + fn leave() -> Weight { + // Proof Size summary in bytes: + // Measured: `579` + // Estimated: `9741` + // Minimum execution time: 35_492 nanoseconds. + Weight::from_parts(36_401_000, 9741) + .saturating_add(T::DbWeight::get().reads(3)) + .saturating_add(T::DbWeight::get().writes(1)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:0) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild UserData (r:1 w:0) + /// Proof Skipped: Guild UserData (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Members (r:1 w:0) + /// Proof Skipped: Guild Members (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Roles (r:1 w:0) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + /// Storage: Oracle ActiveOperators (r:1 w:0) + /// Proof Skipped: Oracle ActiveOperators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle NextOperator (r:1 w:1) + /// Proof Skipped: Oracle NextOperator (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle NextRequestIdentifier (r:1 w:1) + /// Proof Skipped: Oracle NextRequestIdentifier (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle Requests (r:0 w:1) + /// Proof Skipped: Oracle Requests (max_values: None, max_size: None, mode: Measured) + fn request_oracle_check() -> Weight { + // Proof Size summary in bytes: + // Measured: `3784` + // Estimated: `47916` + // Minimum execution time: 69_099 nanoseconds. + Weight::from_parts(78_144_000, 47916) + .saturating_add(T::DbWeight::get().reads(8)) + .saturating_add(T::DbWeight::get().writes(3)) } } -// For backwards compatibility and tests impl WeightInfo for () { - // Storage: Guild Guilds (r:1 w:1) - // Storage: Guild Roles (r:0 w:2) - /// The range of component `r` is `[0, 100]`. - fn create_guild(r: u64, ) -> Weight { - Weight::from_parts(19_413_000, 19_413_000) - // Standard Error: 3_000 - .saturating_add(Weight::from_parts(2_651_000, 2_651_000).saturating_mul(r)) - .saturating_add(RocksDbWeight::get().reads(1)) + /// Storage: Guild UserData (r:0 w:1) + /// Proof Skipped: Guild UserData (max_values: None, max_size: None, mode: Measured) + fn register() -> Weight { + // Proof Size summary in bytes: + // Measured: `0` + // Estimated: `0` + // Minimum execution time: 369_767 nanoseconds. + Weight::from_ref_time(392_263_000) .saturating_add(RocksDbWeight::get().writes(1)) - .saturating_add(RocksDbWeight::get().writes(r)) - } - // Storage: Guild Roles (r:1 w:0) - // Storage: Guild NextRequestIdentifier (r:1 w:1) - // Storage: Chainlink Operators (r:1 w:0) - // Storage: Chainlink NextOperator (r:1 w:1) - // Storage: Chainlink NextRequestIdentifier (r:1 w:1) - // Storage: Guild JoinRequests (r:0 w:1) - // Storage: Chainlink Requests (r:0 w:1) - fn join_guild() -> Weight { - Weight::from_parts(53_270_000, 53_270_000) + } + /// Storage: Guild GuildIdMap (r:1 w:1) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Nonce (r:1 w:1) + /// Proof Skipped: Guild Nonce (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Guild Guilds (r:0 w:1) + /// Proof Skipped: Guild Guilds (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[0, 256]`. + fn create_guild(n: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `115` + // Estimated: `6404` + // Minimum execution time: 26_721 nanoseconds. + Weight::from_parts(39_154_463, 6404) + // Standard Error: 3_905 + .saturating_add(Weight::from_ref_time(2_434).saturating_mul(n.into())) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(3)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:1) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Guilds (r:1 w:1) + /// Proof Skipped: Guild Guilds (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Nonce (r:1 w:1) + /// Proof Skipped: Guild Nonce (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Guild Roles (r:0 w:1) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + fn create_free_role() -> Weight { + // Proof Size summary in bytes: + // Measured: `678` + // Estimated: `14399` + // Minimum execution time: 46_699 nanoseconds. + Weight::from_parts(52_729_000, 14399) + .saturating_add(RocksDbWeight::get().reads(5)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:1) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Guilds (r:1 w:1) + /// Proof Skipped: Guild Guilds (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Nonce (r:1 w:1) + /// Proof Skipped: Guild Nonce (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Guild Roles (r:0 w:1) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + /// The range of component `n` is `[1, 128]`. + /// The range of component `r` is `[0, 10]`. + /// The range of component `s` is `[0, 256]`. + fn create_role_with_allowlist(n: u32, r: u32, _s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `678` + // Estimated: `14399` + // Minimum execution time: 77_201 nanoseconds. + Weight::from_parts(85_825_100, 14399) + // Standard Error: 32_487 + .saturating_add(Weight::from_ref_time(1_613_995).saturating_mul(n.into())) + // Standard Error: 392_769 + .saturating_add(Weight::from_ref_time(514_801).saturating_mul(r.into())) + .saturating_add(RocksDbWeight::get().reads(5)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:2 w:1) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Guilds (r:1 w:1) + /// Proof Skipped: Guild Guilds (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Nonce (r:1 w:1) + /// Proof Skipped: Guild Nonce (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Guild Roles (r:0 w:1) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[0, 10]`. + /// The range of component `s` is `[0, 256]`. + fn create_child_role(r: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `894` + // Estimated: `17954` + // Minimum execution time: 53_095 nanoseconds. + Weight::from_parts(46_540_343, 17954) + // Standard Error: 138_192 + .saturating_add(Weight::from_ref_time(2_136_397).saturating_mul(r.into())) + // Standard Error: 5_670 + .saturating_add(Weight::from_ref_time(52_708).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(6)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:1) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Guilds (r:1 w:1) + /// Proof Skipped: Guild Guilds (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Nonce (r:1 w:1) + /// Proof Skipped: Guild Nonce (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: RandomnessCollectiveFlip RandomMaterial (r:1 w:0) + /// Proof: RandomnessCollectiveFlip RandomMaterial (max_values: Some(1), max_size: Some(2594), added: 3089, mode: MaxEncodedLen) + /// Storage: Guild Roles (r:0 w:1) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + /// The range of component `r` is `[0, 10]`. + /// The range of component `s` is `[0, 256]`. + fn create_unfiltered_role(r: u32, s: u32, ) -> Weight { + // Proof Size summary in bytes: + // Measured: `678` + // Estimated: `14399` + // Minimum execution time: 44_245 nanoseconds. + Weight::from_parts(55_627_418, 14399) + // Standard Error: 119_983 + .saturating_add(Weight::from_ref_time(266_588).saturating_mul(r.into())) + // Standard Error: 4_923 + .saturating_add(Weight::from_ref_time(20_540).saturating_mul(s.into())) + .saturating_add(RocksDbWeight::get().reads(5)) + .saturating_add(RocksDbWeight::get().writes(4)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:0) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild UserData (r:2 w:0) + /// Proof Skipped: Guild UserData (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Roles (r:1 w:0) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Members (r:0 w:1) + /// Proof Skipped: Guild Members (max_values: None, max_size: None, mode: Measured) + fn join() -> Weight { + // Proof Size summary in bytes: + // Measured: `656` + // Estimated: `15655` + // Minimum execution time: 54_580 nanoseconds. + Weight::from_parts(61_062_000, 15655) .saturating_add(RocksDbWeight::get().reads(5)) - .saturating_add(RocksDbWeight::get().writes(5)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:0) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild UserData (r:1 w:0) + /// Proof Skipped: Guild UserData (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Members (r:0 w:1) + /// Proof Skipped: Guild Members (max_values: None, max_size: None, mode: Measured) + fn leave() -> Weight { + // Proof Size summary in bytes: + // Measured: `579` + // Estimated: `9741` + // Minimum execution time: 35_492 nanoseconds. + Weight::from_parts(36_401_000, 9741) + .saturating_add(RocksDbWeight::get().reads(3)) + .saturating_add(RocksDbWeight::get().writes(1)) + } + /// Storage: Guild GuildIdMap (r:1 w:0) + /// Proof Skipped: Guild GuildIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild RoleIdMap (r:1 w:0) + /// Proof Skipped: Guild RoleIdMap (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild UserData (r:1 w:0) + /// Proof Skipped: Guild UserData (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Members (r:1 w:0) + /// Proof Skipped: Guild Members (max_values: None, max_size: None, mode: Measured) + /// Storage: Guild Roles (r:1 w:0) + /// Proof Skipped: Guild Roles (max_values: None, max_size: None, mode: Measured) + /// Storage: Oracle ActiveOperators (r:1 w:0) + /// Proof Skipped: Oracle ActiveOperators (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle NextOperator (r:1 w:1) + /// Proof Skipped: Oracle NextOperator (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle NextRequestIdentifier (r:1 w:1) + /// Proof Skipped: Oracle NextRequestIdentifier (max_values: Some(1), max_size: None, mode: Measured) + /// Storage: Oracle Requests (r:0 w:1) + /// Proof Skipped: Oracle Requests (max_values: None, max_size: None, mode: Measured) + fn request_oracle_check() -> Weight { + // Proof Size summary in bytes: + // Measured: `3784` + // Estimated: `47916` + // Minimum execution time: 69_099 nanoseconds. + Weight::from_parts(78_144_000, 47916) + .saturating_add(RocksDbWeight::get().reads(8)) + .saturating_add(RocksDbWeight::get().writes(3)) } } diff --git a/gn-pallets/pallet-oracle/src/lib.rs b/gn-pallets/pallet-oracle/src/lib.rs index 5ecdab11..3894530a 100644 --- a/gn-pallets/pallet-oracle/src/lib.rs +++ b/gn-pallets/pallet-oracle/src/lib.rs @@ -25,7 +25,7 @@ mod benchmark; mod mock; #[cfg(test)] mod test; -mod weights; +pub mod weights; pub use pallet::*; pub use weights::WeightInfo; @@ -290,7 +290,7 @@ pub mod pallet { /// required information to perform the request and provide back /// the result. #[pallet::call_index(4)] - #[pallet::weight((T::WeightInfo::initiate_request(500), Pays::No))] + #[pallet::weight((T::WeightInfo::initiate_request(data.len() as u32), Pays::No))] pub fn initiate_request( origin: OriginFor, callback: ::Callback, From 5e58c7afa8cf6359502c88b4e5bc5614e29ee5d6 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Wed, 22 Feb 2023 08:59:55 +0100 Subject: [PATCH 17/23] Guild benchmarks finished. --- gn-pallets/pallet-guild/src/lib.rs | 37 +++++++++++++++++++------- gn-pallets/pallet-guild/src/weights.rs | 2 +- gn-pallets/pallet-oracle/src/lib.rs | 1 - 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/gn-pallets/pallet-guild/src/lib.rs b/gn-pallets/pallet-guild/src/lib.rs index cacefb8b..6dc28ef3 100644 --- a/gn-pallets/pallet-guild/src/lib.rs +++ b/gn-pallets/pallet-guild/src/lib.rs @@ -150,7 +150,7 @@ pub mod pallet { #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight((T::WeightInfo::register(), Pays::No))] + #[pallet::weight((::WeightInfo::register(), Pays::No))] pub fn register( origin: OriginFor, identity_with_auth: IdentityWithAuth, @@ -201,7 +201,7 @@ pub mod pallet { } #[pallet::call_index(1)] - #[pallet::weight((T::WeightInfo::join(), Pays::No))] + #[pallet::weight((::WeightInfo::join(), Pays::No))] pub fn join( origin: OriginFor, guild_name: GuildName, @@ -284,7 +284,7 @@ pub mod pallet { } #[pallet::call_index(2)] - #[pallet::weight((T::WeightInfo::leave(), Pays::No))] + #[pallet::weight((::WeightInfo::leave(), Pays::No))] pub fn leave( origin: OriginFor, guild_name: GuildName, @@ -298,7 +298,7 @@ pub mod pallet { } #[pallet::call_index(3)] - #[pallet::weight(T::WeightInfo::request_oracle_check())] + #[pallet::weight(::WeightInfo::request_oracle_check())] pub fn request_oracle_check( origin: OriginFor, account: T::AccountId, @@ -353,7 +353,7 @@ pub mod pallet { } #[pallet::call_index(4)] - #[pallet::weight((1000, Pays::No))] + #[pallet::weight((::WeightInfo::create_guild(metadata.len() as u32), Pays::No))] pub fn create_guild( origin: OriginFor, guild_name: GuildName, @@ -387,7 +387,7 @@ pub mod pallet { } #[pallet::call_index(5)] - #[pallet::weight((1000, Pays::No))] + #[pallet::weight((::WeightInfo::create_free_role(), Pays::No))] pub fn create_free_role( origin: OriginFor, guild_name: GuildName, @@ -398,7 +398,14 @@ pub mod pallet { } #[pallet::call_index(6)] - #[pallet::weight((1000, Pays::No))] + #[pallet::weight(( + ::WeightInfo::create_role_with_allowlist( + allowlist.len() as u32, + T::MaxReqsPerRole::get(), + T::MaxSerializedLen::get() + ), + Pays::No + ))] pub fn create_role_with_allowlist( origin: OriginFor, guild_name: GuildName, @@ -422,7 +429,13 @@ pub mod pallet { } #[pallet::call_index(7)] - #[pallet::weight((1000, Pays::No))] + #[pallet::weight(( + ::WeightInfo::create_child_role( + T::MaxReqsPerRole::get(), + T::MaxSerializedLen::get() + ), + Pays::No + ))] pub fn create_child_role( origin: OriginFor, guild_name: GuildName, @@ -444,7 +457,13 @@ pub mod pallet { } #[pallet::call_index(8)] - #[pallet::weight((1000, Pays::No))] + #[pallet::weight(( + ::WeightInfo::create_unfiltered_role( + requirements.0.len() as u32, + T::MaxSerializedLen::get() + ), + Pays::No + ))] pub fn create_unfiltered_role( origin: OriginFor, guild_name: GuildName, diff --git a/gn-pallets/pallet-guild/src/weights.rs b/gn-pallets/pallet-guild/src/weights.rs index 5782005d..709e1432 100644 --- a/gn-pallets/pallet-guild/src/weights.rs +++ b/gn-pallets/pallet-guild/src/weights.rs @@ -30,7 +30,7 @@ #![allow(unused_parens)] #![allow(unused_imports)] -use frame_support::{traits::Get, weights::Weight, constants::RocksDBWeight}; +use frame_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}}; use sp_std::marker::PhantomData; pub trait WeightInfo { diff --git a/gn-pallets/pallet-oracle/src/lib.rs b/gn-pallets/pallet-oracle/src/lib.rs index 3894530a..b47a1350 100644 --- a/gn-pallets/pallet-oracle/src/lib.rs +++ b/gn-pallets/pallet-oracle/src/lib.rs @@ -28,7 +28,6 @@ mod test; pub mod weights; pub use pallet::*; -pub use weights::WeightInfo; #[frame_support::pallet] pub mod pallet { From 7c6de8d0aa469c49c5afc3c530d573cc65fc9887 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Wed, 22 Feb 2023 09:28:46 +0100 Subject: [PATCH 18/23] Clippy fixes. --- gn-pallets/pallet-oracle/src/benchmark.rs | 2 +- gn-pallets/pallet-oracle/src/lib.rs | 4 ++-- gn-pallets/pallet-oracle/src/mock.rs | 6 ------ integr_test.py | 2 ++ 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/gn-pallets/pallet-oracle/src/benchmark.rs b/gn-pallets/pallet-oracle/src/benchmark.rs index 40e429b6..3e230c11 100644 --- a/gn-pallets/pallet-oracle/src/benchmark.rs +++ b/gn-pallets/pallet-oracle/src/benchmark.rs @@ -64,7 +64,7 @@ benchmarks! { ); Oracle::::register_operator(RawOrigin::Root.into(), operator.clone())?; - Oracle::::activate_operator(RawOrigin::Signed(operator.clone()).into())?; + Oracle::::activate_operator(RawOrigin::Signed(operator).into())?; let data = vec![128; n as usize]; let fee = T::Currency::minimum_balance(); diff --git a/gn-pallets/pallet-oracle/src/lib.rs b/gn-pallets/pallet-oracle/src/lib.rs index b47a1350..b0d14858 100644 --- a/gn-pallets/pallet-oracle/src/lib.rs +++ b/gn-pallets/pallet-oracle/src/lib.rs @@ -208,7 +208,7 @@ pub mod pallet { ); RegisteredOperators::::insert(&operator, ()); - NumRegisteredOperators::::mutate(|val| *val = *val + 1); + NumRegisteredOperators::::mutate(|val| *val += 1); Self::deposit_event(Event::OperatorRegistered(operator)); Ok(()) } @@ -230,7 +230,7 @@ pub mod pallet { } }); - NumRegisteredOperators::::mutate(|val| *val = *val - 1); + NumRegisteredOperators::::mutate(|val| *val -= 1); Self::deposit_event(Event::OperatorDeregistered(operator)); Ok(()) } diff --git a/gn-pallets/pallet-oracle/src/mock.rs b/gn-pallets/pallet-oracle/src/mock.rs index a6c93dfa..0ee15276 100644 --- a/gn-pallets/pallet-oracle/src/mock.rs +++ b/gn-pallets/pallet-oracle/src/mock.rs @@ -113,12 +113,6 @@ impl UnfilteredDispatchable for MockCallback { } } -impl MockCallback { - pub fn new() -> ::Callback { - Decode::decode(&mut &[][..]).unwrap() - } -} - impl MockCallback { pub fn test() -> Self { Self(core::marker::PhantomData) diff --git a/integr_test.py b/integr_test.py index abf5e183..e96d6838 100644 --- a/integr_test.py +++ b/integr_test.py @@ -74,6 +74,8 @@ def run_tests(*commands, timeout=300): def main(): try: node = start_node() + command = "cargo run --release --example guild -- --example register" + run_tests(command, timeout=20) oracle = start_oracle() oracle_monitor = Thread(target=monitor_oracle, args=(oracle, node,)) From 4abb21e44705ff4a945873c794dec15b71db8b3a Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Wed, 22 Feb 2023 09:29:24 +0100 Subject: [PATCH 19/23] Increased block time to 3 seconds. --- gn-runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gn-runtime/src/lib.rs b/gn-runtime/src/lib.rs index 95583ed5..c0e9cbcb 100644 --- a/gn-runtime/src/lib.rs +++ b/gn-runtime/src/lib.rs @@ -104,7 +104,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { /// up by `pallet_aura` to implement `fn slot_duration()`. /// /// Change this to adjust the block time. -pub const MILLISECS_PER_BLOCK: u64 = 2000; +pub const MILLISECS_PER_BLOCK: u64 = 3000; // NOTE: Currently it is not possible to change the slot duration after the chain has started. // Attempting to do so will brick block production. From 460265b593f6cd90bc00f437a014b023087c45c7 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Wed, 22 Feb 2023 09:54:20 +0100 Subject: [PATCH 20/23] Small integration test fix --- integr_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integr_test.py b/integr_test.py index e96d6838..87f31ec4 100644 --- a/integr_test.py +++ b/integr_test.py @@ -23,7 +23,7 @@ def start_node(): def start_oracle(): - oracle = Popen(['./target/release/gn-oracle', '--log', 'info', '--register'], + oracle = Popen(['./target/release/gn-oracle', '--log', 'info', '--activate'], stderr=PIPE, stdout=DEVNULL) start = time.time() From 36e5acc4827867c79555b6627c0ed2e6d5916ded Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Wed, 22 Feb 2023 10:04:57 +0100 Subject: [PATCH 21/23] timeout fix --- integr_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integr_test.py b/integr_test.py index 87f31ec4..2151e7e7 100644 --- a/integr_test.py +++ b/integr_test.py @@ -75,7 +75,7 @@ def main(): try: node = start_node() command = "cargo run --release --example guild -- --example register" - run_tests(command, timeout=20) + run_tests(command, timeout=90) oracle = start_oracle() oracle_monitor = Thread(target=monitor_oracle, args=(oracle, node,)) From bbaaa58bede5214af43c917d40b828516dbf92ae Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Wed, 22 Feb 2023 10:16:04 +0100 Subject: [PATCH 22/23] Remove unused warnings. --- gn-client/examples/guild/common.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gn-client/examples/guild/common.rs b/gn-client/examples/guild/common.rs index ca363f07..e4519c24 100644 --- a/gn-client/examples/guild/common.rs +++ b/gn-client/examples/guild/common.rs @@ -70,6 +70,7 @@ pub async fn prefunded_accounts( accounts } +#[cfg(not(feature = "external-oracle"))] pub async fn register_operators( api: Api, root: Arc, @@ -87,6 +88,7 @@ pub async fn register_operators( println!("operator registrations in block"); } +#[cfg(not(feature = "external-oracle"))] pub async fn activate_operators(api: Api, accounts: impl Iterator) { println!("activating operators"); let tx_futures = accounts From 95cf365799dd8179f4e77cde5e579dd068bd3968 Mon Sep 17 00:00:00 2001 From: PopcornPaws Date: Wed, 22 Feb 2023 10:29:13 +0100 Subject: [PATCH 23/23] Ran out of retries (increase sleep duration). --- gn-client/examples/guild/common.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gn-client/examples/guild/common.rs b/gn-client/examples/guild/common.rs index e4519c24..19778703 100644 --- a/gn-client/examples/guild/common.rs +++ b/gn-client/examples/guild/common.rs @@ -14,7 +14,7 @@ use std::collections::BTreeMap; use std::sync::Arc; const RETRIES: u8 = 10; -const SLEEP_DURATION_MS: u64 = 500; +const SLEEP_DURATION_MS: u64 = 1000; pub struct Accounts { pub substrate: Arc,