From caf9dce305008c654e8ba0071b21cd1646e38d35 Mon Sep 17 00:00:00 2001 From: gatsey Date: Wed, 21 Sep 2022 15:05:06 +0100 Subject: [PATCH 01/19] added traits for profile --- pallets/profile/src/traits.rs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 pallets/profile/src/traits.rs diff --git a/pallets/profile/src/traits.rs b/pallets/profile/src/traits.rs new file mode 100644 index 0000000000..b8763c366d --- /dev/null +++ b/pallets/profile/src/traits.rs @@ -0,0 +1,21 @@ + // Copyright (C) 2022 UNIVERSALDOT FOUNDATION. +// 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. + + pub trait Reputable { + fn calculate_reputation() -> i32; + + fn calculate_ + + } \ No newline at end of file From f4f8bc791ae1ab34428f200ac963cc213e5f19c5 Mon Sep 17 00:00:00 2001 From: gatsey Date: Wed, 21 Sep 2022 15:36:32 +0100 Subject: [PATCH 02/19] started reputation pallet added trait to pallet profile --- pallets/profile/Cargo.toml | 3 +- pallets/profile/src/lib.rs | 5 +- pallets/reputation/Cargo.toml | 39 ++++++++++++ pallets/reputation/README.md | 1 + pallets/reputation/src/benchmarking.rs | 20 +++++++ pallets/reputation/src/impls.rs | 0 pallets/reputation/src/lib.rs | 49 +++++++++++++++ pallets/reputation/src/mock.rs | 59 +++++++++++++++++++ pallets/reputation/src/tests.rs | 2 + pallets/{profile => reputation}/src/traits.rs | 13 +++- 10 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 pallets/reputation/Cargo.toml create mode 100644 pallets/reputation/README.md create mode 100644 pallets/reputation/src/benchmarking.rs create mode 100644 pallets/reputation/src/impls.rs create mode 100644 pallets/reputation/src/lib.rs create mode 100644 pallets/reputation/src/mock.rs create mode 100644 pallets/reputation/src/tests.rs rename pallets/{profile => reputation}/src/traits.rs (68%) diff --git a/pallets/profile/Cargo.toml b/pallets/profile/Cargo.toml index 58a2cb794f..44e5d0b351 100644 --- a/pallets/profile/Cargo.toml +++ b/pallets/profile/Cargo.toml @@ -21,7 +21,8 @@ frame-support = { version = "4.0.0-dev", default-features = false, git = "https: frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } sp-std = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } log = { version = "0.4.14", default-features = false } -pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } +pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } +pallet-reputation = { version = "4.0.0-dev", default-features = false, path = "../pallet-reputation" } [dev-dependencies] sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } diff --git a/pallets/profile/src/lib.rs b/pallets/profile/src/lib.rs index 74c3ad373c..a47444a985 100644 --- a/pallets/profile/src/lib.rs +++ b/pallets/profile/src/lib.rs @@ -85,7 +85,7 @@ pub mod pallet { use frame_support::traits::Currency; use scale_info::TypeInfo; use crate::weights::WeightInfo; - + use pallet_reputation::Reputation; // Account, Balance are used in Profile Struct type AccountOf = ::AccountId; @@ -133,6 +133,9 @@ pub mod pallet { /// A bound on number of completed tasks for Profile. #[pallet::constant] type MaxCompletedTasksLen: Get + MaxEncodedLen + TypeInfo; + + /// The handler for reputation in the system. + type Reputation: Reputation; } #[pallet::pallet] diff --git a/pallets/reputation/Cargo.toml b/pallets/reputation/Cargo.toml new file mode 100644 index 0000000000..6e200f8b0b --- /dev/null +++ b/pallets/reputation/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "pallet-reputation" +version = "4.0.0-dev" +description = "FRAME pallet for deriving the reputation of a given entity." +authors = ["UNIVERSALDOT FOUNDATION "] +homepage = "https://universaldot.foundation" +edition = "2021" +license = "Apache-2.0" +publish = false +repository = "https://github.com/UniversalDot/pallets" + +[package.metadata.docs.rs] +targets = ["x86_64-unknown-linux-gnu"] + +[dependencies] +codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = [ + "derive", +] } +scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } + +[dev-dependencies] +sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } +sp-io = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } +sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-benchmarking/std", + "frame-support/std", + "frame-system/std", + "scale-info/std", +] +runtime-benchmarks = ["frame-benchmarking/runtime-benchmarks"] +try-runtime = ["frame-support/try-runtime"] diff --git a/pallets/reputation/README.md b/pallets/reputation/README.md new file mode 100644 index 0000000000..8d751a4220 --- /dev/null +++ b/pallets/reputation/README.md @@ -0,0 +1 @@ +License: Unlicense \ No newline at end of file diff --git a/pallets/reputation/src/benchmarking.rs b/pallets/reputation/src/benchmarking.rs new file mode 100644 index 0000000000..d496a9fc89 --- /dev/null +++ b/pallets/reputation/src/benchmarking.rs @@ -0,0 +1,20 @@ +//! Benchmarking setup for pallet-template + +use super::*; + +#[allow(unused)] +use crate::Pallet as Template; +use frame_benchmarking::{benchmarks, whitelisted_caller}; +use frame_system::RawOrigin; + +benchmarks! { + do_something { + let s in 0 .. 100; + let caller: T::AccountId = whitelisted_caller(); + }: _(RawOrigin::Signed(caller), s) + verify { + assert_eq!(Something::::get(), Some(s)); + } + + impl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test); +} diff --git a/pallets/reputation/src/impls.rs b/pallets/reputation/src/impls.rs new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs new file mode 100644 index 0000000000..7aa3bb6548 --- /dev/null +++ b/pallets/reputation/src/lib.rs @@ -0,0 +1,49 @@ +#![cfg_attr(not(feature = "std"), no_std)] + +/// Edit this file to define custom logic or remove it if it is not needed. +/// Learn more about FRAME and the core library of Substrate FRAME pallets: +/// +pub use pallet::*; + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +#[cfg(feature = "runtime-benchmarks")] +mod benchmarking; + +#[frame_support::pallet] +pub mod pallet { + use frame_support::pallet_prelude::*; + use frame_system::pallet_prelude::*; + + #[pallet::pallet] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + #[pallet::config] + pub trait Config: frame_system::Config { + type Event: From> + IsType<::Event>; + } + + #[pallet::storage] + #[pallet::getter(fn something)] + pub type Something = StorageValue<_, u32>; + + #[pallet::event] + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + } + + #[pallet::error] + pub enum Error { + } + + #[pallet::call] + impl Pallet { + + + } +} diff --git a/pallets/reputation/src/mock.rs b/pallets/reputation/src/mock.rs new file mode 100644 index 0000000000..e03f37b2ee --- /dev/null +++ b/pallets/reputation/src/mock.rs @@ -0,0 +1,59 @@ +use crate as pallet_template; +use frame_support::traits::{ConstU16, ConstU64}; +use frame_system as system; +use sp_core::H256; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, +}; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system, + TemplateModule: pallet_template, + } +); + +impl system::Config for Test { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type Origin = Origin; + type Call = Call; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = u64; + type Lookup = IdentityLookup; + type Header = Header; + type Event = Event; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = (); + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = ConstU16<42>; + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +impl pallet_template::Config for Test { + type Event = Event; +} + +// Build genesis storage according to the mock runtime. +pub fn new_test_ext() -> sp_io::TestExternalities { + system::GenesisConfig::default().build_storage::().unwrap().into() +} diff --git a/pallets/reputation/src/tests.rs b/pallets/reputation/src/tests.rs new file mode 100644 index 0000000000..bc3b5fc27a --- /dev/null +++ b/pallets/reputation/src/tests.rs @@ -0,0 +1,2 @@ +use crate::{mock::*, Error}; +use frame_support::{assert_noop, assert_ok}; diff --git a/pallets/profile/src/traits.rs b/pallets/reputation/src/traits.rs similarity index 68% rename from pallets/profile/src/traits.rs rename to pallets/reputation/src/traits.rs index b8763c366d..3acc104a8b 100644 --- a/pallets/profile/src/traits.rs +++ b/pallets/reputation/src/traits.rs @@ -13,9 +13,16 @@ // See the License for the specific language governing permissions and // limitations under the License. +use sp_runtime::Bounded; + pub trait Reputable { - fn calculate_reputation() -> i32; - fn calculate_ + /// Calculate the reputation of a voter. + fn calculate_reputation() -> i32; + + /// Calculate the credibility of the voter, it is used to determine how to weigh the votes. + /// Must return a value between 0 and 1000 higher is better + fn calculate_credibility() -> u16 + } + - } \ No newline at end of file From d7a28049d78a27326f0030c8c76ae1db07c5eab2 Mon Sep 17 00:00:00 2001 From: gatsey Date: Wed, 21 Sep 2022 17:53:31 +0100 Subject: [PATCH 03/19] added basic pallet structure --- pallets/reputation/src/lib.rs | 35 +++++++++++++++++++++++++++++--- pallets/reputation/src/tests.rs | 5 +++++ pallets/reputation/src/traits.rs | 21 ++++++++++++++----- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index 7aa3bb6548..cb93631423 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -4,6 +4,8 @@ /// Learn more about FRAME and the core library of Substrate FRAME pallets: /// pub use pallet::*; +pub type ReputationUnit = i32; +pub type CredibilityUnit = u32; #[cfg(test)] mod mock; @@ -26,11 +28,17 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { type Event: From> + IsType<::Event>; + type WeightInfo: WeightInfo; } #[pallet::storage] - #[pallet::getter(fn something)] - pub type Something = StorageValue<_, u32>; + #[pallet::getter(fn reputation_of)] + pub type ReputationOf = StorageMap<_, Twox64Concat, T::AccountId, ReputationUnit, ValueQuery>; + + #[pallet::storage] + #[pallet::getter(fn credibility_of)] + pub type CredibilityOf = StorageMap<_, Twox64Concat, T::AccountId, CredibilityUnit, ValueQuery>; + #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -39,11 +47,32 @@ pub mod pallet { #[pallet::error] pub enum Error { + ReputationAlreadyExists{who: T::AccountId}, + CannotRemoveNothing{who: T::AccountId}, + } - #[pallet::call] impl Pallet { + + pub fn create_reputation_record(account: T::AccountId, default_reputation: ReputationUnit) -> DispatchResult<(), DispatchError> { + let rep_record = reputation_of(&account); + ensure!(rep_record.is_none(), Error::::ReputationAlreadyExists); + + ReputationOf::::insert(account, default_reputation); + Ok(()) + } + + pub fn remove_reputation_record(account: T::AccountId) -> DispatchResult<(), DispatchError> { + let rep_record = reputation_of(&account); + ensure!(rep_record.is_some(), Error::::CannotRemoveNothing); + + ReputationOf::::remove(account); + Ok(()) + } + + } + } diff --git a/pallets/reputation/src/tests.rs b/pallets/reputation/src/tests.rs index bc3b5fc27a..5654ed5c08 100644 --- a/pallets/reputation/src/tests.rs +++ b/pallets/reputation/src/tests.rs @@ -1,2 +1,7 @@ use crate::{mock::*, Error}; use frame_support::{assert_noop, assert_ok}; + + +#[test] +fn test_add_duplicate_reputation() { +} diff --git a/pallets/reputation/src/traits.rs b/pallets/reputation/src/traits.rs index 3acc104a8b..dcfb5098de 100644 --- a/pallets/reputation/src/traits.rs +++ b/pallets/reputation/src/traits.rs @@ -13,16 +13,27 @@ // See the License for the specific language governing permissions and // limitations under the License. -use sp_runtime::Bounded; - - pub trait Reputable { + pub trait Reputable { /// Calculate the reputation of a voter. - fn calculate_reputation() -> i32; + pub fn calculate_reputation(item: HasReputation) -> ReputationUnit; /// Calculate the credibility of the voter, it is used to determine how to weigh the votes. /// Must return a value between 0 and 1000 higher is better - fn calculate_credibility() -> u16 + pub fn calculate_credibility(item: HasCredibility) -> u16; + } +pub trait HasReputation { + + /// Return the reputation for a given struct. + pub fn get_reputation() -> ReputationUnit; +} + +pub trait HasCredibility { + + /// Return the credibility for a given struct. + pub fn get_credibility() -> u16; +} + From b4d680efad091b9cd977c8565bae2e4e976113e8 Mon Sep 17 00:00:00 2001 From: gatsey Date: Wed, 21 Sep 2022 18:52:57 +0100 Subject: [PATCH 04/19] dancing with compiler, add generic params to rep traits --- pallets/profile/Cargo.toml | 1 - pallets/reputation/Cargo.toml | 14 ++++++------ pallets/reputation/README.md | 1 - pallets/reputation/src/lib.rs | 38 ++++++++++++++++++-------------- pallets/reputation/src/traits.rs | 15 ++++++++++++- runtime/Cargo.toml | 1 + 6 files changed, 43 insertions(+), 27 deletions(-) delete mode 100644 pallets/reputation/README.md diff --git a/pallets/profile/Cargo.toml b/pallets/profile/Cargo.toml index 44e5d0b351..94602f7260 100644 --- a/pallets/profile/Cargo.toml +++ b/pallets/profile/Cargo.toml @@ -22,7 +22,6 @@ frame-system = { version = "4.0.0-dev", default-features = false, git = "https:/ sp-std = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } log = { version = "0.4.14", default-features = false } pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } -pallet-reputation = { version = "4.0.0-dev", default-features = false, path = "../pallet-reputation" } [dev-dependencies] sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } diff --git a/pallets/reputation/Cargo.toml b/pallets/reputation/Cargo.toml index 6e200f8b0b..18358abaaa 100644 --- a/pallets/reputation/Cargo.toml +++ b/pallets/reputation/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-reputation" -version = "4.0.0-dev" +version = "0.7.0" description = "FRAME pallet for deriving the reputation of a given entity." authors = ["UNIVERSALDOT FOUNDATION "] homepage = "https://universaldot.foundation" @@ -17,14 +17,14 @@ codec = { package = "parity-scale-codec", version = "3.0.0", default-features = "derive", ] } scale-info = { version = "2.1.1", default-features = false, features = ["derive"] } -frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } -frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } -frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } +frame-benchmarking = { version = "4.0.0-dev", default-features = false, optional = true, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } +frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } +frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } [dev-dependencies] -sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } -sp-io = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } -sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.28" } +sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } +sp-io = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } +sp-runtime = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } [features] default = ["std"] diff --git a/pallets/reputation/README.md b/pallets/reputation/README.md deleted file mode 100644 index 8d751a4220..0000000000 --- a/pallets/reputation/README.md +++ /dev/null @@ -1 +0,0 @@ -License: Unlicense \ No newline at end of file diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index cb93631423..670ada116c 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -4,8 +4,6 @@ /// Learn more about FRAME and the core library of Substrate FRAME pallets: /// pub use pallet::*; -pub type ReputationUnit = i32; -pub type CredibilityUnit = u32; #[cfg(test)] mod mock; @@ -19,7 +17,13 @@ mod benchmarking; #[frame_support::pallet] pub mod pallet { use frame_support::pallet_prelude::*; - use frame_system::pallet_prelude::*; + use frame_system::{ + pallet_prelude::*, + WeightInfo + }; + pub type ReputationUnit = i32; + pub type CredibilityUnit = u32; + pub type Score = u16; #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] @@ -29,15 +33,16 @@ pub mod pallet { pub trait Config: frame_system::Config { type Event: From> + IsType<::Event>; type WeightInfo: WeightInfo; + type Reputable: WeightInfo; } #[pallet::storage] #[pallet::getter(fn reputation_of)] - pub type ReputationOf = StorageMap<_, Twox64Concat, T::AccountId, ReputationUnit, ValueQuery>; + pub type ReputationOf = StorageMap<_, Twox64Concat, T::AccountId, ReputationUnit, OptionQuery>; #[pallet::storage] #[pallet::getter(fn credibility_of)] - pub type CredibilityOf = StorageMap<_, Twox64Concat, T::AccountId, CredibilityUnit, ValueQuery>; + pub type CredibilityOf = StorageMap<_, Twox64Concat, T::AccountId, CredibilityUnit, OptionQuery>; #[pallet::event] @@ -46,33 +51,32 @@ pub mod pallet { } #[pallet::error] - pub enum Error { - ReputationAlreadyExists{who: T::AccountId}, - CannotRemoveNothing{who: T::AccountId}, + pub enum Error { + ReputationAlreadyExists, + CannotRemoveNothing } impl Pallet { - - pub fn create_reputation_record(account: T::AccountId, default_reputation: ReputationUnit) -> DispatchResult<(), DispatchError> { - let rep_record = reputation_of(&account); + pub fn create_reputation_record(account: T::AccountId, default_reputation: ReputationUnit) -> DispatchResult { + let rep_record = Self::reputation_of(&account); ensure!(rep_record.is_none(), Error::::ReputationAlreadyExists); ReputationOf::::insert(account, default_reputation); Ok(()) } - pub fn remove_reputation_record(account: T::AccountId) -> DispatchResult<(), DispatchError> { - let rep_record = reputation_of(&account); + pub fn remove_reputation_record(account: T::AccountId) -> DispatchResult { + let rep_record = Self::reputation_of(&account); ensure!(rep_record.is_some(), Error::::CannotRemoveNothing); ReputationOf::::remove(account); Ok(()) } - - - + pub fn handle_reputation_change(account: T::AccountId) -> DispatchResult { + + Ok(()) + } } - } diff --git a/pallets/reputation/src/traits.rs b/pallets/reputation/src/traits.rs index dcfb5098de..3d4202a959 100644 --- a/pallets/reputation/src/traits.rs +++ b/pallets/reputation/src/traits.rs @@ -13,10 +13,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +use crate::{ + ReputationUnit, + CredibilityUnit, + Score, +} + pub trait Reputable { /// Calculate the reputation of a voter. - pub fn calculate_reputation(item: HasReputation) -> ReputationUnit; + pub fn calculate_reputation(item: N, scores: P) -> ReputationUnit + where N: HasCredibility + HasReputation, + P: Scored; /// Calculate the credibility of the voter, it is used to determine how to weigh the votes. /// Must return a value between 0 and 1000 higher is better @@ -24,6 +32,11 @@ } +pub trait Scored { + pub fn collect_scores() -> Vec + +} + pub trait HasReputation { diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index ad3668a02e..049def4ac1 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -55,6 +55,7 @@ pallet-did = { path = "../pallets/did", version = '0.7.0', default-features = fa pallet-grant = { path = "../pallets/grant", version = '0.0.1', default-features = false } pallet-profile = { path = "../pallets/profile", version = '0.7.0', default-features = false } pallet-task = { path = "../pallets/task", version = '0.7.0', default-features = false } +pallet-reputation = { path = "../pallets/reputation", version = '0.7.0', default-features = false } [build-dependencies] substrate-wasm-builder = { version = "5.0.0-dev", git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } From d7586fa6a0af0f42ff4b48ee0033f73a2536c64f Mon Sep 17 00:00:00 2001 From: gatsey Date: Wed, 21 Sep 2022 19:15:55 +0100 Subject: [PATCH 05/19] linking up traits fixing errs --- pallets/reputation/src/lib.rs | 5 ++++- pallets/reputation/src/traits.rs | 15 +++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index 670ada116c..447759b80b 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -13,6 +13,7 @@ mod tests; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; +pub mod traits; #[frame_support::pallet] pub mod pallet { @@ -21,9 +22,11 @@ pub mod pallet { pallet_prelude::*, WeightInfo }; + pub type ReputationUnit = i32; pub type CredibilityUnit = u32; pub type Score = u16; + use crate::traits::*; #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] @@ -33,7 +36,7 @@ pub mod pallet { pub trait Config: frame_system::Config { type Event: From> + IsType<::Event>; type WeightInfo: WeightInfo; - type Reputable: WeightInfo; + type ReputationHandler: WeightInfo; } #[pallet::storage] diff --git a/pallets/reputation/src/traits.rs b/pallets/reputation/src/traits.rs index 3d4202a959..5fbe98099a 100644 --- a/pallets/reputation/src/traits.rs +++ b/pallets/reputation/src/traits.rs @@ -17,36 +17,35 @@ use crate::{ ReputationUnit, CredibilityUnit, Score, -} +}; - pub trait Reputable { + pub trait ReputationHandler { /// Calculate the reputation of a voter. - pub fn calculate_reputation(item: N, scores: P) -> ReputationUnit + fn calculate_reputation(item: N, scores: P) -> ReputationUnit where N: HasCredibility + HasReputation, P: Scored; /// Calculate the credibility of the voter, it is used to determine how to weigh the votes. /// Must return a value between 0 and 1000 higher is better - pub fn calculate_credibility(item: HasCredibility) -> u16; + fn calculate_credibility(item: T) -> u16; } pub trait Scored { - pub fn collect_scores() -> Vec - + fn collect_scores() -> Vec; } pub trait HasReputation { /// Return the reputation for a given struct. - pub fn get_reputation() -> ReputationUnit; + fn get_reputation() -> ReputationUnit; } pub trait HasCredibility { /// Return the credibility for a given struct. - pub fn get_credibility() -> u16; + fn get_credibility() -> u16; } From 692d64033ad503cafa7107948b7f0196e9abcbe3 Mon Sep 17 00:00:00 2001 From: gatsey Date: Wed, 21 Sep 2022 19:26:14 +0100 Subject: [PATCH 06/19] added rep struct --- pallets/reputation/src/lib.rs | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index 447759b80b..e9baa72a06 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -28,9 +28,20 @@ pub mod pallet { pub type Score = u16; use crate::traits::*; + pub const MAX_CREDIBILITY: CredibilityUnit = 1000; + #[pallet::pallet] #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); + + #[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + #[scale_info(skip_type_params(T))] + pub struct Rep { + reputation: ReputationUnit, + credibility: CredibilityUnit, + aggregate_rating: u64, + num_of_ratings: u64, + } #[pallet::config] pub trait Config: frame_system::Config { @@ -41,12 +52,7 @@ pub mod pallet { #[pallet::storage] #[pallet::getter(fn reputation_of)] - pub type ReputationOf = StorageMap<_, Twox64Concat, T::AccountId, ReputationUnit, OptionQuery>; - - #[pallet::storage] - #[pallet::getter(fn credibility_of)] - pub type CredibilityOf = StorageMap<_, Twox64Concat, T::AccountId, CredibilityUnit, OptionQuery>; - + pub type RepInfoOf = StorageMap<_, Twox64Concat, T::AccountId, Rep, OptionQuery>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -65,7 +71,14 @@ pub mod pallet { let rep_record = Self::reputation_of(&account); ensure!(rep_record.is_none(), Error::::ReputationAlreadyExists); - ReputationOf::::insert(account, default_reputation); + let rep = Rep { + reputation: default_reputation, + credibility: MAX_CREDIBILITY / 2, + aggregate_rating: Default::default(), + num_of_ratings: Default::default(), + }; + + RepInfoOf::::insert(account, rep); Ok(()) } @@ -73,7 +86,7 @@ pub mod pallet { let rep_record = Self::reputation_of(&account); ensure!(rep_record.is_some(), Error::::CannotRemoveNothing); - ReputationOf::::remove(account); + RepInfoOf::::remove(account); Ok(()) } From 05a0f63212e7552642687f942ad671e81647d4d5 Mon Sep 17 00:00:00 2001 From: gatsey Date: Wed, 21 Sep 2022 19:39:50 +0100 Subject: [PATCH 07/19] moved struc to impls --- pallets/reputation/src/impls.rs | 28 ++++++++++++++++++++++++++++ pallets/reputation/src/lib.rs | 15 ++++----------- pallets/reputation/src/traits.rs | 4 ++-- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/pallets/reputation/src/impls.rs b/pallets/reputation/src/impls.rs index e69de29bb2..0f753c64df 100644 --- a/pallets/reputation/src/impls.rs +++ b/pallets/reputation/src/impls.rs @@ -0,0 +1,28 @@ +use crate::traits::*; +use crate::{CredibilityUnit, ReputationUnit}; +use frame_support::pallet_prelude::*; + + +#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] +pub struct Rep { + pub reputation: ReputationUnit, + pub credibility: CredibilityUnit, + pub aggregate_rating: u64, + pub num_of_ratings: u64, +} + + +impl HasCredibility for Rep + { + fn get_credibility(&self) -> CredibilityUnit { + self.credibility + } + +} + +impl HasReputation for Rep +{ + fn get_reputation(&self) -> ReputationUnit { + self.reputation + } +} \ No newline at end of file diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index e9baa72a06..373d86dc39 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -13,7 +13,9 @@ mod tests; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; -pub mod traits; +mod traits; +mod impls; + #[frame_support::pallet] pub mod pallet { @@ -27,6 +29,7 @@ pub mod pallet { pub type CredibilityUnit = u32; pub type Score = u16; use crate::traits::*; + use crate::impls::Rep; pub const MAX_CREDIBILITY: CredibilityUnit = 1000; @@ -34,15 +37,6 @@ pub mod pallet { #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); - #[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] - #[scale_info(skip_type_params(T))] - pub struct Rep { - reputation: ReputationUnit, - credibility: CredibilityUnit, - aggregate_rating: u64, - num_of_ratings: u64, - } - #[pallet::config] pub trait Config: frame_system::Config { type Event: From> + IsType<::Event>; @@ -63,7 +57,6 @@ pub mod pallet { pub enum Error { ReputationAlreadyExists, CannotRemoveNothing - } impl Pallet { diff --git a/pallets/reputation/src/traits.rs b/pallets/reputation/src/traits.rs index 5fbe98099a..557dfbd1f7 100644 --- a/pallets/reputation/src/traits.rs +++ b/pallets/reputation/src/traits.rs @@ -40,12 +40,12 @@ pub trait Scored { pub trait HasReputation { /// Return the reputation for a given struct. - fn get_reputation() -> ReputationUnit; + fn get_reputation(&self) -> ReputationUnit; } pub trait HasCredibility { /// Return the credibility for a given struct. - fn get_credibility() -> u16; + fn get_credibility(&self) -> CredibilityUnit; } From c942876f363e3a0043a75862fac642d98e5ff231 Mon Sep 17 00:00:00 2001 From: gatsey Date: Fri, 23 Sep 2022 15:05:15 +0100 Subject: [PATCH 08/19] improving the traits, adding the reputationhandler to pallet profile --- pallets/profile/Cargo.toml | 1 + pallets/profile/src/lib.rs | 6 ++++-- pallets/reputation/src/impls.rs | 16 +++++++++++++--- pallets/reputation/src/lib.rs | 4 ++-- pallets/reputation/src/traits.rs | 15 ++++++++++++--- runtime/src/lib.rs | 1 + 6 files changed, 33 insertions(+), 10 deletions(-) diff --git a/pallets/profile/Cargo.toml b/pallets/profile/Cargo.toml index 94602f7260..6c7573e7d7 100644 --- a/pallets/profile/Cargo.toml +++ b/pallets/profile/Cargo.toml @@ -22,6 +22,7 @@ frame-system = { version = "4.0.0-dev", default-features = false, git = "https:/ sp-std = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } log = { version = "0.4.14", default-features = false } pallet-balances = { version = "4.0.0-dev", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } +pallet-reputation = { version = "0.7.0", default-features = false, path = "../reputation"} [dev-dependencies] sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } diff --git a/pallets/profile/src/lib.rs b/pallets/profile/src/lib.rs index a47444a985..f970d6c006 100644 --- a/pallets/profile/src/lib.rs +++ b/pallets/profile/src/lib.rs @@ -77,6 +77,7 @@ mod tests; mod benchmarking; pub mod weights; + #[frame_support::pallet] pub mod pallet { use frame_support::{dispatch::DispatchResult, storage::bounded_vec::BoundedVec, pallet_prelude::*}; @@ -85,7 +86,7 @@ pub mod pallet { use frame_support::traits::Currency; use scale_info::TypeInfo; use crate::weights::WeightInfo; - use pallet_reputation::Reputation; + use pallet_reputation::traits::ReputationHandler; // Account, Balance are used in Profile Struct type AccountOf = ::AccountId; @@ -134,8 +135,9 @@ pub mod pallet { #[pallet::constant] type MaxCompletedTasksLen: Get + MaxEncodedLen + TypeInfo; + //TODO: /// The handler for reputation in the system. - type Reputation: Reputation; + type Reputation: ReputationHandler; } #[pallet::pallet] diff --git a/pallets/reputation/src/impls.rs b/pallets/reputation/src/impls.rs index 0f753c64df..8c13eb0c36 100644 --- a/pallets/reputation/src/impls.rs +++ b/pallets/reputation/src/impls.rs @@ -4,15 +4,18 @@ use frame_support::pallet_prelude::*; #[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub struct Rep { +pub struct Reputable { pub reputation: ReputationUnit, pub credibility: CredibilityUnit, pub aggregate_rating: u64, pub num_of_ratings: u64, + pub account: T::AccountId, } +pub struct ReputationHandler; -impl HasCredibility for Rep + +impl HasCredibility for Reputable { fn get_credibility(&self) -> CredibilityUnit { self.credibility @@ -20,9 +23,16 @@ impl HasCredibility for Rep } -impl HasReputation for Rep +impl HasReputation for Reputable { fn get_reputation(&self) -> ReputationUnit { self.reputation } +} + +impl HasAccountId for Reputable +{ + fn get_account_id(&self) -> T::AccountId { + self.account + } } \ No newline at end of file diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index 373d86dc39..6abd0a7541 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -13,8 +13,8 @@ mod tests; #[cfg(feature = "runtime-benchmarks")] mod benchmarking; -mod traits; -mod impls; +pub mod traits; +pub mod impls; #[frame_support::pallet] diff --git a/pallets/reputation/src/traits.rs b/pallets/reputation/src/traits.rs index 557dfbd1f7..4491989eca 100644 --- a/pallets/reputation/src/traits.rs +++ b/pallets/reputation/src/traits.rs @@ -18,20 +18,25 @@ use crate::{ CredibilityUnit, Score, }; +use frame_support::inherent::Vec; - pub trait ReputationHandler { +/// Trait used to handle the reputation of a system. +/// Opinionated so that the user must submit some for of credibility rating. +/// This should be used to weigh the votes of a consumer against their credibility. + pub trait ReputationHandler { /// Calculate the reputation of a voter. fn calculate_reputation(item: N, scores: P) -> ReputationUnit - where N: HasCredibility + HasReputation, + where N: HasCredibility + HasReputation + HasAccountId, P: Scored; /// Calculate the credibility of the voter, it is used to determine how to weigh the votes. /// Must return a value between 0 and 1000 higher is better - fn calculate_credibility(item: T) -> u16; + fn calculate_credibility(item: N) -> u16; } + //TODO: bounded vec pub trait Scored { fn collect_scores() -> Vec; } @@ -49,3 +54,7 @@ pub trait HasCredibility { fn get_credibility(&self) -> CredibilityUnit; } +pub trait HasAccountId { + fn get_account_id(&self) -> T::AccountId; +} + diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 4728e7f87b..a0a2d04564 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -354,6 +354,7 @@ impl pallet_profile::Config for Runtime { type MaxInterestsLen = MaxInterestsLen; type MaxAdditionalInformationLen = MaxAdditionalInformationLen; type MaxCompletedTasksLen = MaxCompletedTasksLen; + type ReputationHandler = (); } impl pallet_grant::Config for Runtime { From 3a01ef02de1e6d5b5e7a4b413ec08ed73105b2d8 Mon Sep 17 00:00:00 2001 From: gatsey Date: Mon, 26 Sep 2022 11:01:32 +0100 Subject: [PATCH 09/19] fixed impls, modified traits, added rate entity function --- pallets/reputation/src/impls.rs | 26 ++++++++++------------- pallets/reputation/src/lib.rs | 36 ++++++++++++++++++++++++++------ pallets/reputation/src/traits.rs | 16 +++++--------- 3 files changed, 46 insertions(+), 32 deletions(-) diff --git a/pallets/reputation/src/impls.rs b/pallets/reputation/src/impls.rs index 8c13eb0c36..64d6154570 100644 --- a/pallets/reputation/src/impls.rs +++ b/pallets/reputation/src/impls.rs @@ -1,38 +1,34 @@ + use crate::traits::*; -use crate::{CredibilityUnit, ReputationUnit}; +use crate::pallet::{CredibilityUnit, ReputationUnit, Reputable}; use frame_support::pallet_prelude::*; -#[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] -pub struct Reputable { - pub reputation: ReputationUnit, - pub credibility: CredibilityUnit, - pub aggregate_rating: u64, - pub num_of_ratings: u64, - pub account: T::AccountId, -} pub struct ReputationHandler; -impl HasCredibility for Reputable - { +impl HasCredibility for Reputable +where T: frame_system::Config +{ fn get_credibility(&self) -> CredibilityUnit { self.credibility } } -impl HasReputation for Reputable +impl HasReputation for Reputable +where T: frame_system::Config { fn get_reputation(&self) -> ReputationUnit { self.reputation } } -impl HasAccountId for Reputable +impl HasAccountId for Reputable +where T: frame_system::Config { - fn get_account_id(&self) -> T::AccountId { - self.account + fn get_account_id(&self) -> &T::AccountId { + &self.account } } \ No newline at end of file diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index 6abd0a7541..950cd829ea 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -28,8 +28,7 @@ pub mod pallet { pub type ReputationUnit = i32; pub type CredibilityUnit = u32; pub type Score = u16; - use crate::traits::*; - use crate::impls::Rep; + use crate::traits::ReputationHandler; pub const MAX_CREDIBILITY: CredibilityUnit = 1000; @@ -37,16 +36,26 @@ pub mod pallet { #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); + #[derive(Clone, Encode, Decode, PartialEq, RuntimeDebug, TypeInfo, MaxEncodedLen)] + #[scale_info(skip_type_params(T))] + pub struct Reputable { + pub reputation: ReputationUnit, + pub credibility: CredibilityUnit, + pub aggregate_rating: u64, + pub num_of_ratings: u64, + pub account: T::AccountId, + } + #[pallet::config] pub trait Config: frame_system::Config { type Event: From> + IsType<::Event>; type WeightInfo: WeightInfo; - type ReputationHandler: WeightInfo; + type ReputationHandler: ReputationHandler; } #[pallet::storage] #[pallet::getter(fn reputation_of)] - pub type RepInfoOf = StorageMap<_, Twox64Concat, T::AccountId, Rep, OptionQuery>; + pub type RepInfoOf = StorageMap<_, Twox64Concat, T::AccountId, Reputable, OptionQuery>; #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] @@ -60,11 +69,14 @@ pub mod pallet { } impl Pallet { + + /// Creates a reputation record for a given account id. pub fn create_reputation_record(account: T::AccountId, default_reputation: ReputationUnit) -> DispatchResult { let rep_record = Self::reputation_of(&account); ensure!(rep_record.is_none(), Error::::ReputationAlreadyExists); - let rep = Rep { + let rep = Reputable { + account: account.clone(), reputation: default_reputation, credibility: MAX_CREDIBILITY / 2, aggregate_rating: Default::default(), @@ -75,6 +87,7 @@ pub mod pallet { Ok(()) } + /// Remove a reputation record from storage. pub fn remove_reputation_record(account: T::AccountId) -> DispatchResult { let rep_record = Self::reputation_of(&account); ensure!(rep_record.is_some(), Error::::CannotRemoveNothing); @@ -83,8 +96,19 @@ pub mod pallet { Ok(()) } - pub fn handle_reputation_change(account: T::AccountId) -> DispatchResult { + /// Rate the entity and adjust the reputation and credibility as defined by the ReputationHandler. + pub fn rate_entity(account: &T::AccountId, ratings: &Vec) -> DispatchResult { + + let mut record: Reputable = RepInfoOf::::get(account); + let new_credibility = T::ReputationHander::calculate_credibility(record, ratings); + let new_reputation = T::ReputationHandler::calculate_reputation(record, ratings); + + record.reputation = new_reputation; + record.num_of_ratings += ratings.len(); + aggregate_rating += ratings.iter().sum(); + credibility = new_credibility; + let _ = RepInfoOf::::insert(account, record) Ok(()) } } diff --git a/pallets/reputation/src/traits.rs b/pallets/reputation/src/traits.rs index 4491989eca..23b85a92b6 100644 --- a/pallets/reputation/src/traits.rs +++ b/pallets/reputation/src/traits.rs @@ -25,23 +25,17 @@ use frame_support::inherent::Vec; /// This should be used to weigh the votes of a consumer against their credibility. pub trait ReputationHandler { - /// Calculate the reputation of a voter. - fn calculate_reputation(item: N, scores: P) -> ReputationUnit + /// Calculate the new reputation of a voter based of a new score given. + fn calculate_reputation(item: &N, score: &Vec) -> ReputationUnit where N: HasCredibility + HasReputation + HasAccountId, P: Scored; - /// Calculate the credibility of the voter, it is used to determine how to weigh the votes. + /// Calculate the new credibility of the voter, it is used to determine how to weigh the votes. /// Must return a value between 0 and 1000 higher is better - fn calculate_credibility(item: N) -> u16; + fn calculate_credibility(item: &N, score: &Vec) -> u16; } - //TODO: bounded vec -pub trait Scored { - fn collect_scores() -> Vec; -} - - pub trait HasReputation { /// Return the reputation for a given struct. @@ -55,6 +49,6 @@ pub trait HasCredibility { } pub trait HasAccountId { - fn get_account_id(&self) -> T::AccountId; + fn get_account_id(&self) -> &T::AccountId; } From f917f41b5e24af9b8c7b77684f7d26820af811be Mon Sep 17 00:00:00 2001 From: gatsey Date: Mon, 26 Sep 2022 11:50:39 +0100 Subject: [PATCH 10/19] added events for reputation --- pallets/reputation/src/impls.rs | 8 ++++++-- pallets/reputation/src/lib.rs | 18 ++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/pallets/reputation/src/impls.rs b/pallets/reputation/src/impls.rs index 64d6154570..26b3a18971 100644 --- a/pallets/reputation/src/impls.rs +++ b/pallets/reputation/src/impls.rs @@ -3,10 +3,14 @@ use crate::traits::*; use crate::pallet::{CredibilityUnit, ReputationUnit, Reputable}; use frame_support::pallet_prelude::*; - - pub struct ReputationHandler; +impl ReputationHandler for ReputationHandler +where T: frame_system::Config +{ + +} + impl HasCredibility for Reputable where T: frame_system::Config diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index 950cd829ea..5d73093001 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -60,6 +60,9 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { + ReputationRecordCreated{who: &AccountId} + ReputationRecordRemoved{who: &AccountId} + EntityRated{who: &AccountId} } #[pallet::error] @@ -84,6 +87,7 @@ pub mod pallet { }; RepInfoOf::::insert(account, rep); + Self::deposit_event(Event::ReputationRecordCreated{who: account}); Ok(()) } @@ -93,22 +97,24 @@ pub mod pallet { ensure!(rep_record.is_some(), Error::::CannotRemoveNothing); RepInfoOf::::remove(account); + Self::deposit_event(Event::ReputationRecordRemoved{who: account}); + Ok(()) } - /// Rate the entity and adjust the reputation and credibility as defined by the ReputationHandler. - pub fn rate_entity(account: &T::AccountId, ratings: &Vec) -> DispatchResult { + /// Rate the account and adjust the reputation and credibility as defined by the ReputationHandler. + pub fn rate_account(account: &T::AccountId, ratings: &Vec) -> DispatchResult { let mut record: Reputable = RepInfoOf::::get(account); let new_credibility = T::ReputationHander::calculate_credibility(record, ratings); - let new_reputation = T::ReputationHandler::calculate_reputation(record, ratings); + let new_reputation = T::ReputationHandler:: (record, ratings); record.reputation = new_reputation; record.num_of_ratings += ratings.len(); - aggregate_rating += ratings.iter().sum(); - credibility = new_credibility; + record.aggregate_rating += ratings.iter().sum(); + record.credibility = new_credibility; - let _ = RepInfoOf::::insert(account, record) + let _ = RepInfoOf::::insert(account, record); Ok(()) } } From 8d3ebfc30aeb9562b8f1be065954ceb5b1445d9f Mon Sep 17 00:00:00 2001 From: gatsey Date: Mon, 26 Sep 2022 13:20:18 +0100 Subject: [PATCH 11/19] fixed compile issues, readablility imporved --- pallets/reputation/src/impls.rs | 24 ++++++++++++++++----- pallets/reputation/src/lib.rs | 37 ++++++++++++++++++-------------- pallets/reputation/src/traits.rs | 9 ++++---- 3 files changed, 44 insertions(+), 26 deletions(-) diff --git a/pallets/reputation/src/impls.rs b/pallets/reputation/src/impls.rs index 26b3a18971..8a5a0db983 100644 --- a/pallets/reputation/src/impls.rs +++ b/pallets/reputation/src/impls.rs @@ -1,14 +1,28 @@ -use crate::traits::*; -use crate::pallet::{CredibilityUnit, ReputationUnit, Reputable}; +use crate::{ + pallet::{CredibilityUnit, ReputationUnit, Reputable, Rating}, + traits::{HasReputation, HasCredibility, HasAccountId} + +}; use frame_support::pallet_prelude::*; + + pub struct ReputationHandler; -impl ReputationHandler for ReputationHandler -where T: frame_system::Config -{ +impl crate::traits::ReputationHandler for ReputationHandler { + fn calculate_credibility(entity: &N, ratings: &Vec) -> CredibilityUnit + where N: HasCredibility + { + CredibilityUnit::default() + } + + fn calculate_reputation(entity: &N, ratings: &Vec) -> ReputationUnit + where N: HasCredibility + HasReputation + HasAccountId + { + ReputationUnit::default() + } } diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index 5d73093001..96d2e0812c 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -27,7 +27,7 @@ pub mod pallet { pub type ReputationUnit = i32; pub type CredibilityUnit = u32; - pub type Score = u16; + pub type Rating = u8; use crate::traits::ReputationHandler; pub const MAX_CREDIBILITY: CredibilityUnit = 1000; @@ -60,21 +60,22 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { - ReputationRecordCreated{who: &AccountId} - ReputationRecordRemoved{who: &AccountId} - EntityRated{who: &AccountId} + ReputationRecordCreated{who: T::AccountId}, + ReputationRecordRemoved{who: T::AccountId}, + AccountRated{who: T::AccountId}, } #[pallet::error] - pub enum Error { + pub enum Error { ReputationAlreadyExists, - CannotRemoveNothing + CannotRemoveNothing, + RecordNotFound } impl Pallet { /// Creates a reputation record for a given account id. - pub fn create_reputation_record(account: T::AccountId, default_reputation: ReputationUnit) -> DispatchResult { + pub fn create_reputation_record(account: &T::AccountId, default_reputation: ReputationUnit) -> DispatchResult { let rep_record = Self::reputation_of(&account); ensure!(rep_record.is_none(), Error::::ReputationAlreadyExists); @@ -87,7 +88,7 @@ pub mod pallet { }; RepInfoOf::::insert(account, rep); - Self::deposit_event(Event::ReputationRecordCreated{who: account}); + Self::deposit_event(Event::ReputationRecordCreated{who: account.clone()}); Ok(()) } @@ -96,8 +97,8 @@ pub mod pallet { let rep_record = Self::reputation_of(&account); ensure!(rep_record.is_some(), Error::::CannotRemoveNothing); - RepInfoOf::::remove(account); - Self::deposit_event(Event::ReputationRecordRemoved{who: account}); + RepInfoOf::::remove(&account); + Self::deposit_event(Event::ReputationRecordRemoved{who: account.clone()}); Ok(()) } @@ -105,16 +106,20 @@ pub mod pallet { /// Rate the account and adjust the reputation and credibility as defined by the ReputationHandler. pub fn rate_account(account: &T::AccountId, ratings: &Vec) -> DispatchResult { - let mut record: Reputable = RepInfoOf::::get(account); - let new_credibility = T::ReputationHander::calculate_credibility(record, ratings); - let new_reputation = T::ReputationHandler:: (record, ratings); + let mut record: Reputable = RepInfoOf::::get(account).ok_or(Error::::RecordNotFound).unwrap(); + + let new_credibility = T::ReputationHandler::calculate_credibility(&record, ratings); + let new_reputation = T::ReputationHandler::calculate_reputation(&record, ratings); + let ratings_sum = ratings.iter().map(|i| *i as u64).sum(); record.reputation = new_reputation; - record.num_of_ratings += ratings.len(); - record.aggregate_rating += ratings.iter().sum(); + record.num_of_ratings.saturating_add(ratings.len() as u64); + record.aggregate_rating.saturating_add(ratings_sum); record.credibility = new_credibility; - let _ = RepInfoOf::::insert(account, record); + let _ = RepInfoOf::::insert(&account, record); + + Self::deposit_event(Event::AccountRated{who: account.clone()}); Ok(()) } } diff --git a/pallets/reputation/src/traits.rs b/pallets/reputation/src/traits.rs index 23b85a92b6..69e8ea6708 100644 --- a/pallets/reputation/src/traits.rs +++ b/pallets/reputation/src/traits.rs @@ -16,7 +16,7 @@ use crate::{ ReputationUnit, CredibilityUnit, - Score, + Rating, }; use frame_support::inherent::Vec; @@ -26,13 +26,12 @@ use frame_support::inherent::Vec; pub trait ReputationHandler { /// Calculate the new reputation of a voter based of a new score given. - fn calculate_reputation(item: &N, score: &Vec) -> ReputationUnit - where N: HasCredibility + HasReputation + HasAccountId, - P: Scored; + fn calculate_reputation(item: &N, score: &Vec) -> ReputationUnit + where N: HasCredibility + HasReputation + HasAccountId; /// Calculate the new credibility of the voter, it is used to determine how to weigh the votes. /// Must return a value between 0 and 1000 higher is better - fn calculate_credibility(item: &N, score: &Vec) -> u16; + fn calculate_credibility(item: &N, score: &Vec) -> CredibilityUnit; } From 86bfc24166c15ade5056310334892d38e89d5997 Mon Sep 17 00:00:00 2001 From: gatsey Date: Mon, 26 Sep 2022 15:58:44 +0100 Subject: [PATCH 12/19] tests, mock, simple impl --- pallets/reputation/src/impls.rs | 7 +++++ pallets/reputation/src/lib.rs | 10 +++---- pallets/reputation/src/mock.rs | 22 ++++++++++++--- pallets/reputation/src/tests.rs | 49 +++++++++++++++++++++++++++++++-- 4 files changed, 77 insertions(+), 11 deletions(-) diff --git a/pallets/reputation/src/impls.rs b/pallets/reputation/src/impls.rs index 8a5a0db983..2795b7917f 100644 --- a/pallets/reputation/src/impls.rs +++ b/pallets/reputation/src/impls.rs @@ -21,6 +21,13 @@ impl crate::traits::ReputationHandler for Reputation fn calculate_reputation(entity: &N, ratings: &Vec) -> ReputationUnit where N: HasCredibility + HasReputation + HasAccountId { + let mut rep = entity.get_reputation(); + + let _: Vec<_> = ratings.iter().map(|r|{ + let diff: i32 = *r as i32 - 3i32; + rep += diff; + + }).collect::<_>(); ReputationUnit::default() } } diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index 96d2e0812c..3b3ad7727f 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -49,8 +49,8 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { type Event: From> + IsType<::Event>; - type WeightInfo: WeightInfo; type ReputationHandler: ReputationHandler; + type DefaultReputation: Get; } #[pallet::storage] @@ -75,13 +75,13 @@ pub mod pallet { impl Pallet { /// Creates a reputation record for a given account id. - pub fn create_reputation_record(account: &T::AccountId, default_reputation: ReputationUnit) -> DispatchResult { + pub fn create_reputation_record(account: &T::AccountId) -> DispatchResult { let rep_record = Self::reputation_of(&account); ensure!(rep_record.is_none(), Error::::ReputationAlreadyExists); let rep = Reputable { account: account.clone(), - reputation: default_reputation, + reputation: T::DefaultReputation::get(), credibility: MAX_CREDIBILITY / 2, aggregate_rating: Default::default(), num_of_ratings: Default::default(), @@ -113,8 +113,8 @@ pub mod pallet { let ratings_sum = ratings.iter().map(|i| *i as u64).sum(); record.reputation = new_reputation; - record.num_of_ratings.saturating_add(ratings.len() as u64); - record.aggregate_rating.saturating_add(ratings_sum); + record.num_of_ratings = record.num_of_ratings.saturating_add(ratings.len() as u64); + record.aggregate_rating = record.aggregate_rating.saturating_add(ratings_sum); record.credibility = new_credibility; let _ = RepInfoOf::::insert(&account, record); diff --git a/pallets/reputation/src/mock.rs b/pallets/reputation/src/mock.rs index e03f37b2ee..6e6a745dac 100644 --- a/pallets/reputation/src/mock.rs +++ b/pallets/reputation/src/mock.rs @@ -1,11 +1,18 @@ -use crate as pallet_template; -use frame_support::traits::{ConstU16, ConstU64}; +use crate as pallet_reputation; +use frame_support::{ + traits::{ConstU16, ConstU64}, + parameter_types, +}; use frame_system as system; use sp_core::H256; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, }; +use crate::{ + impls::ReputationHandler, +}; + type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; @@ -18,7 +25,7 @@ frame_support::construct_runtime!( UncheckedExtrinsic = UncheckedExtrinsic, { System: frame_system, - TemplateModule: pallet_template, + Reputation: pallet_reputation, } ); @@ -49,10 +56,17 @@ impl system::Config for Test { type MaxConsumers = frame_support::traits::ConstU32<16>; } -impl pallet_template::Config for Test { +parameter_types! { + pub DefaultReputation: i32 = 0; +} + +impl pallet_reputation::Config for Test { type Event = Event; + type ReputationHandler = ReputationHandler; + type DefaultReputation = DefaultReputation; } + // Build genesis storage according to the mock runtime. pub fn new_test_ext() -> sp_io::TestExternalities { system::GenesisConfig::default().build_storage::().unwrap().into() diff --git a/pallets/reputation/src/tests.rs b/pallets/reputation/src/tests.rs index 5654ed5c08..3dc43d228a 100644 --- a/pallets/reputation/src/tests.rs +++ b/pallets/reputation/src/tests.rs @@ -1,7 +1,52 @@ -use crate::{mock::*, Error}; +use crate::{mock::*, Error, RepInfoOf}; use frame_support::{assert_noop, assert_ok}; + + +#[test] +fn test_reputation_can_be_created() { + new_test_ext().execute_with(|| { + assert_ok!(Reputation::create_reputation_record(&0)); + assert!(RepInfoOf::::get(0).is_some()); + }); +} + #[test] -fn test_add_duplicate_reputation() { +fn test_reputation_can_be_removed() { + new_test_ext().execute_with(|| { + assert_ok!(Reputation::create_reputation_record(&0)); + assert!(RepInfoOf::::get(0).is_some()); + + assert_ok!(Reputation::remove_reputation_record(0u64)); + + assert!(RepInfoOf::::get(0).is_none()); + }); } + +#[test] +fn duplicate_records_cannot_be_created() { + new_test_ext().execute_with(|| { + assert_ok!(Reputation::create_reputation_record(&0)); + assert!(RepInfoOf::::get(0).is_some()); + assert_noop!(Reputation::create_reputation_record(&0), Error::::ReputationAlreadyExists); + }); +} + +#[test] +fn placeholder_rep_function_works() { + new_test_ext().execute_with(|| { + assert_ok!(Reputation::create_reputation_record(&0)); + assert_ok!(Reputation::rate_account(&0, &vec![0u8, 0u8])); + + let rep_record = RepInfoOf::::get(0).unwrap(); + assert!(rep_record.reputation == (-4)); + + assert_ok!(Reputation::rate_account(&0, &vec![5u8, 5u8])); + assert!(rep_record.reputation == 0); + + assert_ok!(Reputation::rate_account(&0, &vec![5u8, 5u8])); + assert!(rep_record.reputation == 4); + + }); +} \ No newline at end of file From 841616b40954d595d46e1dfc584f3da92aa08a91 Mon Sep 17 00:00:00 2001 From: gatsey Date: Mon, 26 Sep 2022 16:04:03 +0100 Subject: [PATCH 13/19] fixed test --- pallets/reputation/src/impls.rs | 4 ++-- pallets/reputation/src/tests.rs | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pallets/reputation/src/impls.rs b/pallets/reputation/src/impls.rs index 2795b7917f..1784721879 100644 --- a/pallets/reputation/src/impls.rs +++ b/pallets/reputation/src/impls.rs @@ -26,9 +26,9 @@ impl crate::traits::ReputationHandler for Reputation let _: Vec<_> = ratings.iter().map(|r|{ let diff: i32 = *r as i32 - 3i32; rep += diff; - }).collect::<_>(); - ReputationUnit::default() + + rep } } diff --git a/pallets/reputation/src/tests.rs b/pallets/reputation/src/tests.rs index 3dc43d228a..4a78d3bd44 100644 --- a/pallets/reputation/src/tests.rs +++ b/pallets/reputation/src/tests.rs @@ -37,15 +37,18 @@ fn duplicate_records_cannot_be_created() { fn placeholder_rep_function_works() { new_test_ext().execute_with(|| { assert_ok!(Reputation::create_reputation_record(&0)); - assert_ok!(Reputation::rate_account(&0, &vec![0u8, 0u8])); + assert_ok!(Reputation::rate_account(&0, &vec![1u8, 1u8])); let rep_record = RepInfoOf::::get(0).unwrap(); assert!(rep_record.reputation == (-4)); assert_ok!(Reputation::rate_account(&0, &vec![5u8, 5u8])); + let rep_record = RepInfoOf::::get(0).unwrap(); assert!(rep_record.reputation == 0); + assert_ok!(Reputation::rate_account(&0, &vec![5u8, 5u8])); + let rep_record = RepInfoOf::::get(0).unwrap(); assert!(rep_record.reputation == 4); }); From ad8a9493421ba4e2760670b11d1de10d7d676a9c Mon Sep 17 00:00:00 2001 From: gatsey Date: Mon, 26 Sep 2022 16:21:50 +0100 Subject: [PATCH 14/19] added documentation and commetns for pallet-reputaton --- pallets/reputation/src/lib.rs | 51 ++++++++++++++++++++++++++++++-- pallets/reputation/src/tests.rs | 18 +++++++---- pallets/reputation/src/traits.rs | 4 +-- pallets/task/src/tests.rs | 2 +- 4 files changed, 64 insertions(+), 11 deletions(-) diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index 3b3ad7727f..ffac42d81c 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -1,8 +1,33 @@ +// This file is part of Substrate. + +// Copyright (C) 2022 UNIVERSALDOT FOUNDATION. +// 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. + +//! # Reputation Pallet +//! +//! ## Version: 0.0.1 +//! +//! ## Overview +//! +//! Given an account id, create some way of recording the reputation of that entity. +//! Implementation assumes that ratings will be given by another credible accountid. +//! +//! implementation incomplete. + #![cfg_attr(not(feature = "std"), no_std)] -/// Edit this file to define custom logic or remove it if it is not needed. -/// Learn more about FRAME and the core library of Substrate FRAME pallets: -/// pub use pallet::*; #[cfg(test)] @@ -41,6 +66,7 @@ pub mod pallet { pub struct Reputable { pub reputation: ReputationUnit, pub credibility: CredibilityUnit, + // The aggregate of all ratings pub aggregate_rating: u64, pub num_of_ratings: u64, pub account: T::AccountId, @@ -49,7 +75,11 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { type Event: From> + IsType<::Event>; + + /// The trait that defines how the pallet deals with reputation and credibility. type ReputationHandler: ReputationHandler; + + /// The default reputation of an account. type DefaultReputation: Get; } @@ -60,15 +90,21 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { + /// Reputation record created. ReputationRecordCreated{who: T::AccountId}, + /// Reputation record removed. ReputationRecordRemoved{who: T::AccountId}, + /// Account rated. AccountRated{who: T::AccountId}, } #[pallet::error] pub enum Error { + /// You cannot create duplicate reputation records. ReputationAlreadyExists, + /// Reputation record does not exist. CannotRemoveNothing, + /// Reputation Record not found. RecordNotFound } @@ -76,9 +112,12 @@ pub mod pallet { /// Creates a reputation record for a given account id. pub fn create_reputation_record(account: &T::AccountId) -> DispatchResult { + + // Ensure that a record does not exist. let rep_record = Self::reputation_of(&account); ensure!(rep_record.is_none(), Error::::ReputationAlreadyExists); + // Instantiate and insert into storage. let rep = Reputable { account: account.clone(), reputation: T::DefaultReputation::get(), @@ -94,9 +133,12 @@ pub mod pallet { /// Remove a reputation record from storage. pub fn remove_reputation_record(account: T::AccountId) -> DispatchResult { + + // Ensure record exists. let rep_record = Self::reputation_of(&account); ensure!(rep_record.is_some(), Error::::CannotRemoveNothing); + // Remove from storage. RepInfoOf::::remove(&account); Self::deposit_event(Event::ReputationRecordRemoved{who: account.clone()}); @@ -106,12 +148,15 @@ pub mod pallet { /// Rate the account and adjust the reputation and credibility as defined by the ReputationHandler. pub fn rate_account(account: &T::AccountId, ratings: &Vec) -> DispatchResult { + // Get the old record. let mut record: Reputable = RepInfoOf::::get(account).ok_or(Error::::RecordNotFound).unwrap(); + // Calculate the new totals as defined in the ReputationHandle. let new_credibility = T::ReputationHandler::calculate_credibility(&record, ratings); let new_reputation = T::ReputationHandler::calculate_reputation(&record, ratings); let ratings_sum = ratings.iter().map(|i| *i as u64).sum(); + // Update the record and insert into storage. record.reputation = new_reputation; record.num_of_ratings = record.num_of_ratings.saturating_add(ratings.len() as u64); record.aggregate_rating = record.aggregate_rating.saturating_add(ratings_sum); diff --git a/pallets/reputation/src/tests.rs b/pallets/reputation/src/tests.rs index 4a78d3bd44..6f19e39d46 100644 --- a/pallets/reputation/src/tests.rs +++ b/pallets/reputation/src/tests.rs @@ -2,11 +2,11 @@ use crate::{mock::*, Error, RepInfoOf}; use frame_support::{assert_noop, assert_ok}; - - #[test] fn test_reputation_can_be_created() { new_test_ext().execute_with(|| { + + // Assert reputation can be created. assert_ok!(Reputation::create_reputation_record(&0)); assert!(RepInfoOf::::get(0).is_some()); }); @@ -15,11 +15,13 @@ fn test_reputation_can_be_created() { #[test] fn test_reputation_can_be_removed() { new_test_ext().execute_with(|| { + + // Assert reputation can be created. assert_ok!(Reputation::create_reputation_record(&0)); assert!(RepInfoOf::::get(0).is_some()); + // Assert reputation can be removed. assert_ok!(Reputation::remove_reputation_record(0u64)); - assert!(RepInfoOf::::get(0).is_none()); }); } @@ -27,8 +29,12 @@ fn test_reputation_can_be_removed() { #[test] fn duplicate_records_cannot_be_created() { new_test_ext().execute_with(|| { + + // Assert one record can be created. assert_ok!(Reputation::create_reputation_record(&0)); assert!(RepInfoOf::::get(0).is_some()); + + // Assert the same AccountId cannot. assert_noop!(Reputation::create_reputation_record(&0), Error::::ReputationAlreadyExists); }); } @@ -36,9 +42,12 @@ fn duplicate_records_cannot_be_created() { #[test] fn placeholder_rep_function_works() { new_test_ext().execute_with(|| { + + // Setup default state. assert_ok!(Reputation::create_reputation_record(&0)); - assert_ok!(Reputation::rate_account(&0, &vec![1u8, 1u8])); + // Assert logic follows as described in: https://github.com/UniversalDot/universal-dot-node/issues/37 + assert_ok!(Reputation::rate_account(&0, &vec![1u8, 1u8])); let rep_record = RepInfoOf::::get(0).unwrap(); assert!(rep_record.reputation == (-4)); @@ -46,7 +55,6 @@ fn placeholder_rep_function_works() { let rep_record = RepInfoOf::::get(0).unwrap(); assert!(rep_record.reputation == 0); - assert_ok!(Reputation::rate_account(&0, &vec![5u8, 5u8])); let rep_record = RepInfoOf::::get(0).unwrap(); assert!(rep_record.reputation == 4); diff --git a/pallets/reputation/src/traits.rs b/pallets/reputation/src/traits.rs index 69e8ea6708..a437463a78 100644 --- a/pallets/reputation/src/traits.rs +++ b/pallets/reputation/src/traits.rs @@ -21,8 +21,8 @@ use crate::{ use frame_support::inherent::Vec; /// Trait used to handle the reputation of a system. -/// Opinionated so that the user must submit some for of credibility rating. -/// This should be used to weigh the votes of a consumer against their credibility. +/// Opinionated so that the user must submit a credibility rating. +/// This should be used to weigh the votes of a consumer's reputation against their credibility. pub trait ReputationHandler { /// Calculate the new reputation of a voter based of a new score given. diff --git a/pallets/task/src/tests.rs b/pallets/task/src/tests.rs index 6d4d5a2d7c..555c1a1be2 100644 --- a/pallets/task/src/tests.rs +++ b/pallets/task/src/tests.rs @@ -362,7 +362,7 @@ fn task_can_be_updated_only_by_one_who_created_it(){ // Get task identifier let task_id = Task::tasks_owned(*TED)[0]; - + // Throw error when someone other than creator tries to update task assert_noop!(Task::update_task(Origin::signed(*ALICE), task_id, title(), spec(), BUDGET2, get_deadline(1), attachments2(), keywords2(), None), Error::::OnlyInitiatorUpdatesTask); }); From 1b49754e37fc94eeb0ebb00ee2b2d49f4405a7ca Mon Sep 17 00:00:00 2001 From: gatsey Date: Tue, 27 Sep 2022 09:56:06 +0100 Subject: [PATCH 15/19] added pallet reputation to profile and tasks --- pallets/profile/src/lib.rs | 39 ++++++++------------------------- pallets/reputation/src/impls.rs | 7 +++--- pallets/reputation/src/lib.rs | 5 ++++- pallets/task/Cargo.toml | 1 + pallets/task/src/lib.rs | 16 ++++++-------- runtime/src/lib.rs | 2 +- 6 files changed, 26 insertions(+), 44 deletions(-) diff --git a/pallets/profile/src/lib.rs b/pallets/profile/src/lib.rs index f970d6c006..776a88bb32 100644 --- a/pallets/profile/src/lib.rs +++ b/pallets/profile/src/lib.rs @@ -86,7 +86,11 @@ pub mod pallet { use frame_support::traits::Currency; use scale_info::TypeInfo; use crate::weights::WeightInfo; - use pallet_reputation::traits::ReputationHandler; + use pallet_reputation::{ + traits::ReputationHandler, + Pallet as ReputationPallet, + Rating + }; // Account, Balance are used in Profile Struct type AccountOf = ::AccountId; @@ -102,7 +106,6 @@ pub mod pallet { pub name: BoundedVec, pub interests: BoundedVec, pub balance: Option>, - pub reputation: u32, pub available_hours_per_week: u8, pub additional_information: Option>, } @@ -134,10 +137,6 @@ pub mod pallet { /// A bound on number of completed tasks for Profile. #[pallet::constant] type MaxCompletedTasksLen: Get + MaxEncodedLen + TypeInfo; - - //TODO: - /// The handler for reputation in the system. - type Reputation: ReputationHandler; } #[pallet::pallet] @@ -267,7 +266,6 @@ pub mod pallet { name, interests, balance: Some(balance), - reputation: 0, available_hours_per_week, additional_information, }; @@ -281,6 +279,7 @@ pub mod pallet { // Initialize completed tasks list with default value. >::insert(owner, BoundedVec::default()); + ReputationPallet::::create_reputation_record(owner); // Increase profile count let new_count = Self::profile_count().checked_add(1).ok_or(>::ProfileCountOverflow)?; @@ -322,6 +321,8 @@ pub mod pallet { // Remove profile from storage >::remove(owner); + ReputationPallet::::remove_reputation_record(owner); + // Reduce profile count let new_count = Self::profile_count().saturating_sub(1); >::put(new_count); @@ -329,21 +330,7 @@ pub mod pallet { Ok(()) } - // Public function that adds reputation to a profile - pub fn add_reputation(owner: &T::AccountId) -> Result<(), DispatchError> { - - // Get current profile - let mut profile = Self::profiles(owner).ok_or(>::NoProfileCreated)?; - - // Increase reputation - profile.increase_reputation(); - - // Insert into storage a new profile - >::insert(owner, profile); - - Ok(()) - } - + // Public function that check if user has a profile pub fn has_profile(owner: &T::AccountId) -> Result { @@ -369,14 +356,6 @@ pub mod pallet { // Change the reputation on a Profile (TODO MVP2: Improve reputation functions) impl Profile { - pub fn increase_reputation(&mut self) { - self.reputation += 1; - } - - pub fn decrease_reputation(&mut self) { - self.reputation -= 1; - } - pub fn change_interests(&mut self, new_interests: BoundedVec) { self.interests = new_interests; } diff --git a/pallets/reputation/src/impls.rs b/pallets/reputation/src/impls.rs index 1784721879..024ab3a897 100644 --- a/pallets/reputation/src/impls.rs +++ b/pallets/reputation/src/impls.rs @@ -4,9 +4,10 @@ use crate::{ traits::{HasReputation, HasCredibility, HasAccountId} }; -use frame_support::pallet_prelude::*; - - +use frame_support::{ + pallet_prelude::*, + inherent::Vec +}; pub struct ReputationHandler; diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index ffac42d81c..342381f3f0 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -44,7 +44,10 @@ pub mod impls; #[frame_support::pallet] pub mod pallet { - use frame_support::pallet_prelude::*; + use frame_support::{ + pallet_prelude::*, + inherent::Vec + }; use frame_system::{ pallet_prelude::*, WeightInfo diff --git a/pallets/task/Cargo.toml b/pallets/task/Cargo.toml index a0ca055416..86beb1b0e9 100644 --- a/pallets/task/Cargo.toml +++ b/pallets/task/Cargo.toml @@ -27,6 +27,7 @@ sp-std = { version = "4.0.0", default-features = false, git = "https://github.co # universal pallet-profile = { path = "../profile", version = "0.7.0", default-features = false } +pallet-reputation = { path = "../reputation", version = "0.7.0", default-features = false } pallet-dao = { path = "../dao", version = "0.7.0", default-features = false } sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } diff --git a/pallets/task/src/lib.rs b/pallets/task/src/lib.rs index 464abc5ab1..6ef3f93a69 100644 --- a/pallets/task/src/lib.rs +++ b/pallets/task/src/lib.rs @@ -134,6 +134,8 @@ pub mod pallet { traits::Organization, traits }; + + use pallet_reputation::Rating; #[cfg(feature = "std")] use frame_support::serde::{Deserialize, Serialize}; @@ -790,7 +792,7 @@ pub mod pallet { >::insert(task_id, task); // Reward reputation points to profiles who created/completed a task - Self::handle_reputation(task_id)?; + Self::handle_reputation(task.status)?; // remove task once accepted >::remove(task_id); @@ -881,15 +883,11 @@ pub mod pallet { } // Handles reputation update for profiles - fn handle_reputation(task_id: &T::Hash) -> Result<(), DispatchError> { - - // Check if task exists - let task = Self::tasks(&task_id).ok_or(>::TaskNotExist)?; - + fn handle_reputation(task_status: &TaskStatus, ratings: &Vec) -> Result<(), DispatchError> { // Ensure that reputation is added only when task is in status Accepted - if task.status == TaskStatus::Accepted { - pallet_profile::Pallet::::add_reputation(&task.initiator)?; - pallet_profile::Pallet::::add_reputation(&task.volunteer)?; + if task_status == TaskStatus::Accepted { + // TODO:pallet_profile::Pallet::::add_reputation(&task.initiator)?; + pallet_reputation::Pallet::::rate_account(&task.volunteer, ratings); } Ok(()) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index a0a2d04564..92bab65938 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -50,6 +50,7 @@ use pallet_transaction_payment::CurrencyAdapter; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; pub use sp_runtime::{Perbill, Permill}; +pub use pallet_reputation::impls::ReputationHandler; pub const MILLICENTS: Balance = 1_000_000_000; @@ -354,7 +355,6 @@ impl pallet_profile::Config for Runtime { type MaxInterestsLen = MaxInterestsLen; type MaxAdditionalInformationLen = MaxAdditionalInformationLen; type MaxCompletedTasksLen = MaxCompletedTasksLen; - type ReputationHandler = (); } impl pallet_grant::Config for Runtime { From 1cc84596fdfdb566ad47757c7ac743a22d3eba2c Mon Sep 17 00:00:00 2001 From: gatsey Date: Wed, 28 Sep 2022 10:59:18 +0100 Subject: [PATCH 16/19] plumbing the reputation into the pallets, fixing up test environment --- node/src/chain_spec.rs | 1 + pallets/profile/src/lib.rs | 4 ++-- pallets/profile/src/mock.rs | 22 +++++++++++++++++++--- pallets/reputation/src/benchmarking.rs | 20 -------------------- pallets/reputation/src/impls.rs | 13 ++++++++----- pallets/reputation/src/lib.rs | 7 +++++-- pallets/reputation/src/mock.rs | 7 ++++++- pallets/reputation/src/tests.rs | 8 ++++---- pallets/reputation/src/traits.rs | 11 ++++++----- pallets/task/Cargo.toml | 2 +- pallets/task/src/lib.rs | 19 ++++++++++--------- pallets/task/src/mock.rs | 15 +++++++++++++++ runtime/src/lib.rs | 14 ++++++++++++++ 13 files changed, 91 insertions(+), 52 deletions(-) delete mode 100644 pallets/reputation/src/benchmarking.rs diff --git a/node/src/chain_spec.rs b/node/src/chain_spec.rs index cba3df4751..207d2ea65a 100644 --- a/node/src/chain_spec.rs +++ b/node/src/chain_spec.rs @@ -153,5 +153,6 @@ fn testnet_genesis( }, transaction_payment: Default::default(), treasury: Default::default(), + } } diff --git a/pallets/profile/src/lib.rs b/pallets/profile/src/lib.rs index 776a88bb32..8f76a42f44 100644 --- a/pallets/profile/src/lib.rs +++ b/pallets/profile/src/lib.rs @@ -112,7 +112,7 @@ pub mod pallet { /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] - pub trait Config: frame_system::Config { + pub trait Config: frame_system::Config + pallet_reputation::Config { /// Because this pallet emits events, it depends on the runtime's definition of an event. type Event: From> + IsType<::Event>; @@ -321,7 +321,7 @@ pub mod pallet { // Remove profile from storage >::remove(owner); - ReputationPallet::::remove_reputation_record(owner); + ReputationPallet::::remove_reputation_record(owner.clone()); // Reduce profile count let new_count = Self::profile_count().saturating_sub(1); diff --git a/pallets/profile/src/mock.rs b/pallets/profile/src/mock.rs index 5be42d0ea0..989c4b2d41 100644 --- a/pallets/profile/src/mock.rs +++ b/pallets/profile/src/mock.rs @@ -22,9 +22,10 @@ frame_support::construct_runtime!( NodeBlock = Block, UncheckedExtrinsic = UncheckedExtrinsic, { - System: frame_system::{Pallet, Call, Config, Storage, Event}, - Profile: pallet_profile::{Pallet, Call, Storage, Event}, - Balances: pallet_balances::{Pallet, Call, Storage, Config, Event}, + System: frame_system, + Profile: pallet_profile, + Balances: pallet_balances, + Reputation: pallet_reputation, } ); @@ -97,6 +98,21 @@ impl pallet_balances::Config for Test { type WeightInfo = (); } +parameter_types! { + #[derive(TypeInfo, MaxEncodedLen, Encode)] + pub MaximumRatingsPer: u32 = 5; + + pub DefaultReputation: i32 = 0; +} + +impl pallet_reputation::Config for Test { + type Event = Event; + type ReputationHandler = pallet_reputation::impls::ReputationHandler; + type DefaultReputation = DefaultReputation; + type MaximumRatingsPer = MaximumRatingsPer; +} + + // Build genesis storage according to the mock runtime. pub(crate) fn new_test_ext() -> sp_io::TestExternalities { let mut t = frame_system::GenesisConfig::default().build_storage::().unwrap(); diff --git a/pallets/reputation/src/benchmarking.rs b/pallets/reputation/src/benchmarking.rs deleted file mode 100644 index d496a9fc89..0000000000 --- a/pallets/reputation/src/benchmarking.rs +++ /dev/null @@ -1,20 +0,0 @@ -//! Benchmarking setup for pallet-template - -use super::*; - -#[allow(unused)] -use crate::Pallet as Template; -use frame_benchmarking::{benchmarks, whitelisted_caller}; -use frame_system::RawOrigin; - -benchmarks! { - do_something { - let s in 0 .. 100; - let caller: T::AccountId = whitelisted_caller(); - }: _(RawOrigin::Signed(caller), s) - verify { - assert_eq!(Something::::get(), Some(s)); - } - - impl_benchmark_test_suite!(Template, crate::mock::new_test_ext(), crate::mock::Test); -} diff --git a/pallets/reputation/src/impls.rs b/pallets/reputation/src/impls.rs index 024ab3a897..aee801dacf 100644 --- a/pallets/reputation/src/impls.rs +++ b/pallets/reputation/src/impls.rs @@ -6,20 +6,23 @@ use crate::{ }; use frame_support::{ pallet_prelude::*, - inherent::Vec + inherent::Vec, + BoundedVec }; pub struct ReputationHandler; -impl crate::traits::ReputationHandler for ReputationHandler { +impl crate::traits::ReputationHandler for ReputationHandler +where T: frame_system::Config + crate::Config +{ - fn calculate_credibility(entity: &N, ratings: &Vec) -> CredibilityUnit + fn calculate_credibility(entity: &N, ratings: &BoundedVec) -> CredibilityUnit where N: HasCredibility { CredibilityUnit::default() } - fn calculate_reputation(entity: &N, ratings: &Vec) -> ReputationUnit + fn calculate_reputation(entity: &N, ratings: &BoundedVec) -> ReputationUnit where N: HasCredibility + HasReputation + HasAccountId { let mut rep = entity.get_reputation(); @@ -29,7 +32,7 @@ impl crate::traits::ReputationHandler for Reputation rep += diff; }).collect::<_>(); - rep + rep.try_into().expect("input vec is bounded, output is same length; qed") } } diff --git a/pallets/reputation/src/lib.rs b/pallets/reputation/src/lib.rs index 342381f3f0..3201c90757 100644 --- a/pallets/reputation/src/lib.rs +++ b/pallets/reputation/src/lib.rs @@ -46,7 +46,7 @@ pub mod impls; pub mod pallet { use frame_support::{ pallet_prelude::*, - inherent::Vec + BoundedVec }; use frame_system::{ pallet_prelude::*, @@ -84,6 +84,9 @@ pub mod pallet { /// The default reputation of an account. type DefaultReputation: Get; + + /// Maximum number of ratings per action + type MaximumRatingsPer: Get + MaxEncodedLen + TypeInfo; } #[pallet::storage] @@ -149,7 +152,7 @@ pub mod pallet { } /// Rate the account and adjust the reputation and credibility as defined by the ReputationHandler. - pub fn rate_account(account: &T::AccountId, ratings: &Vec) -> DispatchResult { + pub fn rate_account(account: &T::AccountId, ratings: &BoundedVec) -> DispatchResult { // Get the old record. let mut record: Reputable = RepInfoOf::::get(account).ok_or(Error::::RecordNotFound).unwrap(); diff --git a/pallets/reputation/src/mock.rs b/pallets/reputation/src/mock.rs index 6e6a745dac..533ddc1120 100644 --- a/pallets/reputation/src/mock.rs +++ b/pallets/reputation/src/mock.rs @@ -2,6 +2,7 @@ use crate as pallet_reputation; use frame_support::{ traits::{ConstU16, ConstU64}, parameter_types, + pallet_prelude::*, }; use frame_system as system; use sp_core::H256; @@ -57,13 +58,17 @@ impl system::Config for Test { } parameter_types! { + #[derive(TypeInfo, MaxEncodedLen, Encode)] + pub MaximumRatingsPer: u32 = 5; + pub DefaultReputation: i32 = 0; -} +} impl pallet_reputation::Config for Test { type Event = Event; type ReputationHandler = ReputationHandler; type DefaultReputation = DefaultReputation; + type MaximumRatingsPer = MaximumRatingsPer; } diff --git a/pallets/reputation/src/tests.rs b/pallets/reputation/src/tests.rs index 6f19e39d46..32792c3431 100644 --- a/pallets/reputation/src/tests.rs +++ b/pallets/reputation/src/tests.rs @@ -1,5 +1,5 @@ use crate::{mock::*, Error, RepInfoOf}; -use frame_support::{assert_noop, assert_ok}; +use frame_support::{assert_noop, assert_ok, bounded_vec}; #[test] @@ -47,15 +47,15 @@ fn placeholder_rep_function_works() { assert_ok!(Reputation::create_reputation_record(&0)); // Assert logic follows as described in: https://github.com/UniversalDot/universal-dot-node/issues/37 - assert_ok!(Reputation::rate_account(&0, &vec![1u8, 1u8])); + assert_ok!(Reputation::rate_account(&0, &bounded_vec![1u8, 1u8])); let rep_record = RepInfoOf::::get(0).unwrap(); assert!(rep_record.reputation == (-4)); - assert_ok!(Reputation::rate_account(&0, &vec![5u8, 5u8])); + assert_ok!(Reputation::rate_account(&0, &bounded_vec![5u8, 5u8])); let rep_record = RepInfoOf::::get(0).unwrap(); assert!(rep_record.reputation == 0); - assert_ok!(Reputation::rate_account(&0, &vec![5u8, 5u8])); + assert_ok!(Reputation::rate_account(&0, &bounded_vec![5u8, 5u8])); let rep_record = RepInfoOf::::get(0).unwrap(); assert!(rep_record.reputation == 4); diff --git a/pallets/reputation/src/traits.rs b/pallets/reputation/src/traits.rs index a437463a78..27fa2252d9 100644 --- a/pallets/reputation/src/traits.rs +++ b/pallets/reputation/src/traits.rs @@ -18,20 +18,21 @@ use crate::{ CredibilityUnit, Rating, }; -use frame_support::inherent::Vec; +use frame_support::BoundedVec; /// Trait used to handle the reputation of a system. /// Opinionated so that the user must submit a credibility rating. /// This should be used to weigh the votes of a consumer's reputation against their credibility. - pub trait ReputationHandler { - +pub trait ReputationHandler +where T: frame_system::Config + crate::Config +{ /// Calculate the new reputation of a voter based of a new score given. - fn calculate_reputation(item: &N, score: &Vec) -> ReputationUnit + fn calculate_reputation(item: &N, score: &BoundedVec) -> ReputationUnit where N: HasCredibility + HasReputation + HasAccountId; /// Calculate the new credibility of the voter, it is used to determine how to weigh the votes. /// Must return a value between 0 and 1000 higher is better - fn calculate_credibility(item: &N, score: &Vec) -> CredibilityUnit; + fn calculate_credibility(item: &N, score: &BoundedVec) -> CredibilityUnit; } diff --git a/pallets/task/Cargo.toml b/pallets/task/Cargo.toml index 86beb1b0e9..240ab7c6e8 100644 --- a/pallets/task/Cargo.toml +++ b/pallets/task/Cargo.toml @@ -27,7 +27,7 @@ sp-std = { version = "4.0.0", default-features = false, git = "https://github.co # universal pallet-profile = { path = "../profile", version = "0.7.0", default-features = false } -pallet-reputation = { path = "../reputation", version = "0.7.0", default-features = false } +pallet-reputation = { path = "../reputation", version = "0.7.0", default-features = false } pallet-dao = { path = "../dao", version = "0.7.0", default-features = false } sp-core = { version = "6.0.0", default-features = false, git = "https://github.com/paritytech/substrate.git", branch = "polkadot-v0.9.27" } diff --git a/pallets/task/src/lib.rs b/pallets/task/src/lib.rs index 6ef3f93a69..5451ebb565 100644 --- a/pallets/task/src/lib.rs +++ b/pallets/task/src/lib.rs @@ -82,6 +82,7 @@ //! - `accept_task` - Function used to accept completed task. //! Inputs: //! - task_id: T::Hash, +//! - ratings: BoundedVec //! After the task is accepted, its data is removed from storage. //! //! - `reject_task` - Function used to reject an already completed task. @@ -185,7 +186,7 @@ pub mod pallet { /// Configure the pallet by specifying the parameters and types on which it depends. #[pallet::config] - pub trait Config: frame_system::Config + pallet_profile::Config { + pub trait Config: frame_system::Config + pallet_reputation::Config + pallet_profile::Config { /// Because this pallet emits events, it depends on the runtime's definition of an event. type Event: From> + IsType<::Event>; @@ -461,7 +462,7 @@ pub mod pallet { /// Function to accept a completed task. [origin, task_id] #[transactional] #[pallet::weight(::WeightInfo::accept_task(0,0))] - pub fn accept_task(origin: OriginFor, task_id: T::Hash) -> DispatchResult { + pub fn accept_task(origin: OriginFor, task_id: T::Hash, ratings: BoundedVec) -> DispatchResult { // Check that the extrinsic was signed and get the signer. let signer = ensure_signed(origin)?; @@ -477,7 +478,7 @@ pub mod pallet { ::Currency::transfer(&signer, &task.volunteer, task.budget, ExistenceRequirement::AllowDeath)?; // Accept task and update storage. - Self::accept_completed_task(&signer, &mut task, &task_id)?; + Self::accept_completed_task(&signer, &mut task, &task_id, &ratings)?; // Add task to completed tasks list of volunteer's profile. pallet_profile::Pallet::::add_task_to_completed_tasks(&task.volunteer, task_id)?; @@ -776,7 +777,7 @@ pub mod pallet { } // Internal helper function, checks Must be called before calling this function. - fn accept_completed_task(task_initiator: &T::AccountId, task: &mut Task, task_id: &T::Hash) -> Result<(), DispatchError> { + fn accept_completed_task(task_initiator: &T::AccountId, task: &mut Task, task_id: &T::Hash, ratings: &BoundedVec) -> Result<(), DispatchError> { // Remove from ownership >::try_mutate(&task_initiator, |owned| { @@ -789,10 +790,10 @@ pub mod pallet { // Update task state task.status = TaskStatus::Accepted; - >::insert(task_id, task); + >::insert(task_id, &*task); // Reward reputation points to profiles who created/completed a task - Self::handle_reputation(task.status)?; + Self::handle_reputation(&task.status, &task.volunteer, &ratings)?; // remove task once accepted >::remove(task_id); @@ -883,11 +884,11 @@ pub mod pallet { } // Handles reputation update for profiles - fn handle_reputation(task_status: &TaskStatus, ratings: &Vec) -> Result<(), DispatchError> { + fn handle_reputation(task_status: &TaskStatus, account: &T::AccountId, ratings: &BoundedVec) -> Result<(), DispatchError> { // Ensure that reputation is added only when task is in status Accepted - if task_status == TaskStatus::Accepted { + if *task_status == TaskStatus::Accepted { // TODO:pallet_profile::Pallet::::add_reputation(&task.initiator)?; - pallet_reputation::Pallet::::rate_account(&task.volunteer, ratings); + pallet_reputation::Pallet::::rate_account(account, ratings); } Ok(()) diff --git a/pallets/task/src/mock.rs b/pallets/task/src/mock.rs index 58b80a0b11..161fb20553 100644 --- a/pallets/task/src/mock.rs +++ b/pallets/task/src/mock.rs @@ -33,6 +33,7 @@ frame_support::construct_runtime!( Profile: pallet_profile::{Pallet, Call, Storage, Event}, Time: pallet_timestamp::{Pallet, Call, Storage, Inherent}, Task: pallet_task::{Pallet, Call, Storage, Event}, + Reputation: pallet_reputation::{Pallet, Storage, Event}, } ); @@ -202,6 +203,20 @@ impl pallet_task::traits::Organization for Test { } } +parameter_types! { + #[derive(TypeInfo, MaxEncodedLen, Encode)] + pub MaximumRatingsPer: u32 = 5; + + pub DefaultReputation: i32 = 0; +} + +impl pallet_reputation::Config for Test { + type Event = Event; + type ReputationHandler = pallet_reputation::impls::ReputationHandler; + type DefaultReputation = DefaultReputation; + type MaximumRatingsPer = MaximumRatingsPer; +} + pub static ALICE : Lazy = Lazy::new(||{sr25519::Public::from_raw([1u8; 32])}); pub static BOB : Lazy = Lazy::new(||{sr25519::Public::from_raw([2u8; 32])}); pub static TED : Lazy = Lazy::new(||{sr25519::Public::from_raw([10u8; 32])}); diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 92bab65938..ea17f08f2e 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -421,6 +421,20 @@ impl pallet_treasury::Config for Runtime { type SpendOrigin = frame_support::traits::NeverEnsureOrigin; } +parameter_types! { + pub DefaultReputation: i32 = 0; + + #[derive(TypeInfo, MaxEncodedLen, Encode)] + pub MaximumRatingsPer: u32 = 5; +} + +impl pallet_reputation::Config for Runtime { + type Event = Event; + type ReputationHandler = pallet_reputation::impls::ReputationHandler; + type DefaultReputation = DefaultReputation; + type MaximumRatingsPer = MaximumRatingsPer; +} + // Create the runtime by composing the FRAME pallets that were previously configured. construct_runtime!( From 8782305567d7bdc60d07922f12245d00e295541c Mon Sep 17 00:00:00 2001 From: gatsey Date: Wed, 28 Sep 2022 22:42:28 +0100 Subject: [PATCH 17/19] fixed tests for profile, dao, task --- pallets/dao/Cargo.toml | 1 + pallets/dao/src/mock.rs | 16 +++++++++++++++ pallets/profile/src/tests.rs | 8 +++++++- pallets/task/src/tests.rs | 40 ++++++++++++++++++++++-------------- runtime/src/lib.rs | 1 + 5 files changed, 50 insertions(+), 16 deletions(-) diff --git a/pallets/dao/Cargo.toml b/pallets/dao/Cargo.toml index eed508cab2..92f789585c 100644 --- a/pallets/dao/Cargo.toml +++ b/pallets/dao/Cargo.toml @@ -28,6 +28,7 @@ sp-core = { version = "6.0.0", default-features = false, git = "https://github.c # universal pallet-did = { path = "../did", package = "pallet-did", default-features = false } pallet-profile = { path = "../profile", version = "0.7.0", default-features = false } +pallet-reputation = { path = "../reputation", version = "0.7.0", default-features = false } # dev dependencies [dev-dependencies] diff --git a/pallets/dao/src/mock.rs b/pallets/dao/src/mock.rs index cdcc1c162a..84e920c72b 100644 --- a/pallets/dao/src/mock.rs +++ b/pallets/dao/src/mock.rs @@ -27,6 +27,7 @@ frame_support::construct_runtime!( Did: pallet_did::{Pallet, Call, Storage, Event}, Dao: pallet_dao::{Pallet, Call, Storage, Event}, Profile: pallet_profile::{Pallet, Call, Storage, Event}, + Reputation: pallet_reputation, } ); pub type Moment = u64; @@ -160,6 +161,21 @@ impl pallet_balances::Config for Test { type WeightInfo = (); } +parameter_types! { + #[derive(TypeInfo, MaxEncodedLen, Encode)] + pub MaximumRatingsPer: u32 = 5; + + pub DefaultReputation: i32 = 0; +} + +impl pallet_reputation::Config for Test { + type Event = Event; + type ReputationHandler = pallet_reputation::impls::ReputationHandler; + type DefaultReputation = DefaultReputation; + type MaximumRatingsPer = MaximumRatingsPer; +} + + // Build genesis storage according to the mock runtime. pub fn new_test_ext() -> sp_io::TestExternalities { let storage = system::GenesisConfig::default().build_storage::().unwrap(); diff --git a/pallets/profile/src/tests.rs b/pallets/profile/src/tests.rs index 58f0428a60..823bcc7636 100644 --- a/pallets/profile/src/tests.rs +++ b/pallets/profile/src/tests.rs @@ -2,6 +2,10 @@ use core::convert::TryInto; use frame_support::storage::bounded_vec::BoundedVec; use crate::{mock::*, Error}; use frame_support::{assert_noop, assert_ok}; +use pallet_reputation::{ + RepInfoOf, + Reputable, +}; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Constants and Functions used in TESTS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -51,12 +55,14 @@ fn verify_inputs_outputs_to_profile(){ // Get profile for current account let profile = Profile::profiles(10).expect("should found the profile"); + let maybe_reputation: Option> = RepInfoOf::::get(10); + assert!(maybe_reputation.is_some()); // Ensure that profile properties are assigned correctly assert_eq!(profile.name.into_inner(), &[1, 4]); - assert_eq!(profile.reputation, 0); assert_eq!(profile.interests.into_inner(), &[2,4]); assert_eq!(profile.available_hours_per_week, 40_u8); + assert_eq!(maybe_reputation.unwrap().reputation, 0i32); }); } diff --git a/pallets/task/src/tests.rs b/pallets/task/src/tests.rs index 555c1a1be2..c3555b4c0b 100644 --- a/pallets/task/src/tests.rs +++ b/pallets/task/src/tests.rs @@ -5,6 +5,7 @@ use frame_support::traits::fungible::Inspect; use frame_support::storage::bounded_vec::BoundedVec; use frame_support::{assert_noop, assert_ok, traits::{UnixTime, Hooks}}; use sp_core::H256; +use pallet_reputation::RepInfoOf; // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< Constants and Functions used in TESTS >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> @@ -61,6 +62,11 @@ fn additional_info() -> BoundedVec { vec![1u8, 4].try_into().unwrap() } +fn get_ratings() -> BoundedVec { + // +2 rating overall + vec![0, 5, 5].try_into().expect("test") +} + fn get_deadline(multiple: u64) -> u64 { // deadline is current time + 1 hour let deadline =