diff --git a/control/src/lib.rs b/control/src/lib.rs index fa8a498ab..519694afb 100755 --- a/control/src/lib.rs +++ b/control/src/lib.rs @@ -49,6 +49,11 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { + type Event: From> + + IsType<::Event> + + Into<::Event>; + + /// The units in which we record balances. type Balance: Member + Parameter + AtLeast32BitUnsigned @@ -58,6 +63,7 @@ pub mod pallet { + MaxEncodedLen + TypeInfo; + /// The currency ID type type CurrencyId: Member + Parameter + Default @@ -67,105 +73,152 @@ pub mod pallet { + MaxEncodedLen + TypeInfo; + /// Weight information for extrinsics in this module. type WeightInfo: frame_system::weights::WeightInfo; - type Event: From> - + IsType<::Event> - + Into<::Event>; + + /// Multi-currency support for asset management. type Currency: MultiCurrency + MultiReservableCurrency; + /// The ID for this pallet. #[pallet::constant] type PalletId: Get; + + /// The Game3 Foundation Treasury AccountId. #[pallet::constant] type Game3FoundationTreasury: Get; + + /// The GameDAO Treasury AccountId. #[pallet::constant] type GameDAOTreasury: Get; + /// The max number of DAOs created per one account. #[pallet::constant] type MaxDAOsPerAccount: Get; + + /// The max number of members per one DAO. #[pallet::constant] type MaxMembersPerDAO: Get; + #[pallet::constant] type MaxCreationsPerBlock: Get; + /// The CurrencyId which is used as a protokol token. #[pallet::constant] type ProtocolTokenId: Get; + + /// The CurrencyId which is used as a payment token. #[pallet::constant] type PaymentTokenId: Get; + /// The min amount of the deposit which is locked during Org creation (in Protocol tokens). #[pallet::constant] type MinimumDeposit: Get; } - /// Get an Org by its hash + /// Org by its id. + /// + /// Org: map Hash => Org #[pallet::storage] pub(super) type Orgs = StorageMap<_, Blake2_128Concat, T::Hash, Org, ValueQuery>; - /// Get an Org by its nonce + /// Org id by its nonce. + /// + /// OrgByNonce: map u128 => Hash #[pallet::storage] pub(super) type OrgByNonce = StorageMap<_, Blake2_128Concat, u128, T::Hash>; - /// Org settings + /// Org config by its id. + /// + /// OrgConfiguration: map Hash => OrgConfig #[pallet::storage] pub(super) type OrgConfiguration = StorageMap<_, Blake2_128Concat, T::Hash, OrgConfig, OptionQuery>; - /// Global Org State + /// Org state (Inactive | Active | Locked) by org id. + /// + /// OrgState: map Hash => ControlState #[pallet::storage] pub(super) type OrgState = StorageMap<_, Blake2_128Concat, T::Hash, ControlState, ValueQuery, GetDefault>; - /// Access model + /// Org access model (Open | Voting | Controller) by org Hash (id). + /// + /// OrgAccess: map Hash => AccessModel #[pallet::storage] pub(super) type OrgAccess = StorageMap<_, Blake2_128Concat, T::Hash, AccessModel, ValueQuery>; - /// Members of a Org + /// Org members list by org id. + /// + /// OrgMembers: map Hash => Vec #[pallet::storage] pub(super) type OrgMembers = StorageMap<_, Blake2_128Concat, T::Hash, Vec, ValueQuery>; - /// Membercount of a Org + /// Org members count by org id. + /// + /// OrgMemberCount: map Hash => u64 #[pallet::storage] pub(super) type OrgMemberCount = StorageMap<_, Blake2_128Concat, T::Hash, u64, ValueQuery>; - /// Member state for a Org + /// Member state (Inactive | Active ...) by org Hash and member account. + /// + /// OrgMemberState: map (Hash, AccountId) => ControlMemberState #[pallet::storage] pub(super) type OrgMemberState = StorageMap<_, Blake2_128Concat, (T::Hash, T::AccountId), ControlMemberState, ValueQuery, GetDefault>; - /// Memberships by AccountId + /// Org list where account is a member. + /// + /// Memberships: map AccountId => Vec #[pallet::storage] pub(super) type Memberships = StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; - /// Creator of an Org + /// Creator account of an Org. + /// + /// OrgCreator: map Hash => AccountId #[pallet::storage] pub(super) type OrgCreator = StorageMap<_, Blake2_128Concat, T::Hash, T::AccountId, ValueQuery>; - /// Controller of an Org + /// Controller account of an Org. + /// + /// OrgController: map Hash => AccountId #[pallet::storage] pub(super) type OrgController = StorageMap<_, Blake2_128Concat, T::Hash, T::AccountId, ValueQuery>; - /// Treasury of an Org + /// Treasury account of an Org. + /// + /// OrgTreasury: map Hash => AccountId #[pallet::storage] pub(super) type OrgTreasury = StorageMap<_, Blake2_128Concat, T::Hash, T::AccountId, ValueQuery>; - /// Orgs created by account + /// Orgs created by account. + /// + /// OrgsCreated: map AccountId => Vec #[pallet::storage] pub(super) type OrgsCreated = StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; - /// Number of Orgs created by account + /// Number of Orgs created by account. + /// + /// OrgsByCreatedCount: map AccountId => u64 #[pallet::storage] pub(super) type OrgsByCreatedCount = StorageMap<_, Blake2_128Concat, T::AccountId, u64, ValueQuery>; - /// Orgs controlled by account + /// Orgs controlled by account. + /// + /// OrgsControlled: map AccountId => Vec #[pallet::storage] pub(super) type OrgsControlled = StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; - /// Number of Orgs controlled by account + /// Number of Orgs controlled by account. + /// + /// OrgsControlledCount: map AccountId => u64 #[pallet::storage] pub(super) type OrgsControlledCount = StorageMap<_, Blake2_128Concat, T::AccountId, u64, ValueQuery>; - /// the goode olde nonce + /// Nonce. Increase per each org creation. + /// + /// Nonce: u128 #[pallet::storage] #[pallet::getter(fn nonce)] pub(super) type Nonce = StorageValue<_, u128, ValueQuery>; @@ -206,6 +259,7 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { + /// Org was successfully created. OrgCreated { sender_id: T::AccountId, org_id: T::Hash, @@ -213,66 +267,78 @@ pub mod pallet { created_at: T::BlockNumber, realm_index: u64, }, + /// Org was successfully updated. OrgUpdated(T::AccountId, T::Hash, T::BlockNumber), + /// Org was enabled and it's state become Active. OrgEnabled(T::Hash), + /// Org was disabled and it's state become Inactive. OrgDisabled(T::Hash), + /// A member has been added to the Org. AddMember { org_id: T::Hash, account_id: T::AccountId, added_at: T::BlockNumber, }, + /// Member's state has been changed. UpdateMember(T::Hash, T::AccountId, T::BlockNumber), + /// A member has been removed from the Org. RemoveMember { org_id: T::Hash, account_id: T::AccountId, removed_at: T::BlockNumber, }, + /// Controller's state has been changed. ControllerUpdated(T::Hash, T::AccountId), + /// Account is a member of the Org. IsAMember { org_id: T::Hash, account_id: T::AccountId, }, - Message(Vec), } #[pallet::error] pub enum Error { - /// Org Exists + /// Org Exists. OrganizationExists, - /// Org Unknown + /// Org Unknown. OrganizationUnknown, - /// Org Inactive + /// Org Inactive. OrganizationInactive, - /// Insufficient Balance to create Org + /// Insufficient Balance to create Org. BalanceTooLow, - /// Member Add Overflow + /// Member Add Overflow. MemberAddOverflow, - /// Membership Limit Reached + /// Membership Limit Reached. MembershipLimitReached, - /// Member Exists + /// Member Exists. MemberExists, - /// Member Unknonw + /// Member Unknonw. MemberUnknown, - /// Duplicate Address + /// Duplicate Address. DuplicateAddress, - /// Unknown Error + /// Unknown Error. UnknownError, - /// Guru Meditation + /// Guru Meditation. GuruMeditation, - /// Treasury account already exists + /// Treasury account already exists. TreasuryExists, - /// Minimum deposit to Treasury too low - MinimumDepositTooLow, - /// Organization already exists - OrgExists + /// Minimum deposit to Treasury too low. + MinimumDepositTooLow } #[pallet::call] impl Pallet { - // Enable Org - // currently root, layer supervisor - // enables an org to be used - // org_id: an organisations hash + /// Enable Org + /// + /// Enables an Org to be used and changes it's state to Active. + /// Root origin only. + /// + /// Parameters: + /// `org_id`: Org hash. + /// + /// Emits `OrgEnabled` event when successful. + /// + /// Weight: `O(1)` #[pallet::weight(1_000_000)] pub fn enable_org(origin: OriginFor, org_id: T::Hash) -> DispatchResult { ensure_root(origin)?; @@ -281,10 +347,17 @@ pub mod pallet { Ok(()) } - // Disable Org - // currently root, layer supervisor - // disables an org to be used - // org_id: an organisations hash + /// Disable Org + /// + /// Disables an Org to be used and changes it's state to Inactive. + /// Root origin only. + /// + /// Parameters: + /// `org_id`: Org hash. + /// + /// Emits `OrgDisabled` event when successful. + /// + /// Weight: `O(1)` #[pallet::weight(1_000_000)] pub fn disable_org(origin: OriginFor, org_id: T::Hash) -> DispatchResult { ensure_root(origin)?; @@ -293,25 +366,27 @@ pub mod pallet { Ok(()) } - /// Create Org - /// create an on chain organisation - /// - /// - `creator`: creator - /// - `controller`: current controller - /// - `name`: Org name - /// - `cid`: IPFS - /// - `org_type`: individual | legal Org | dao - /// - `access`: anyDAO can join | only member can add | only - /// - `fee_model`: only TX by OS | fees are reserved | fees are moved to treasury - /// - `fee`: fee - /// - `gov_asset`: control assets to empower actors - /// - `pay_asset`: - /// - `member_limit`: max members, if 0 == no limit - /// - `deposit`: initial deposit for the org treasury + /// Create an on chain organisation + /// + /// Parameters: + /// - `origin`: Org creator. + /// - `controller_id`: Org controller. + /// - `name`: Org name. + /// - `cid`: IPFS content identifier. + /// - `org_type`: Individual | Company | Dao | Hybrid. + /// - `access`: Open (anyone can join) | Voting (membership voting) | + /// Controller (controller invites). + /// - `fee_model`: NoFees | Reserve (amount reserved in user account) | + /// Transfer (amount transfered to Org treasury). + /// - `fee`: fees amount to be applied to new members based on fee model (in Protocol tokens). + /// - `gov_asset`: control assets to empower actors. + /// - `pay_asset`: asset used for payments. + /// - `member_limit`: max members, if 0 == no limit. + /// - `deposit`: initial deposit for the org treasury (in Protocol tokens). /// /// Emits `OrgCreated` event when successful. /// - /// Weight: + /// Weight: `O(1)` #[pallet::weight(5_000_000)] #[transactional] pub fn create_org( @@ -348,7 +423,7 @@ pub mod pallet { ensure!(!>::account_exists(&treasury_account_id), Error::::TreasuryExists); let org_id = T::Hashing::hash_of(&treasury_account_id); - ensure!(!Orgs::::contains_key(&org_id), Error::::OrgExists); + ensure!(!Orgs::::contains_key(&org_id), Error::::OrganizationExists); Self::do_create_org( sender.clone(), org_id.clone(), controller_id.clone(), treasury_account_id.clone(), name, cid, @@ -370,12 +445,13 @@ pub mod pallet { /// Add Member to Org /// + /// Parameters: /// - `org_id`: Org id /// - `account`: Account to be added /// /// Emits `AddMember` event when successful. /// - /// Weight: + /// Weight: `O(1)` #[pallet::weight(1_000_000)] pub fn add_member(origin: OriginFor, org_id: T::Hash, account_id: T::AccountId) -> DispatchResult { ensure_signed(origin)?; @@ -392,14 +468,15 @@ pub mod pallet { Ok(()) } - /// Remove Member from Org + /// Remove member from Org /// + /// Parameters: /// - `org_id`: Org id /// - `account`: Account to be removed /// /// Emits `RemoveMember` event when successful. /// - /// Weight: + /// Weight: `O(1)` #[pallet::weight(1_000_000)] pub fn remove_member(origin: OriginFor, org_id: T::Hash, account_id: T::AccountId) -> DispatchResult { ensure_signed(origin)?; @@ -419,13 +496,18 @@ pub mod pallet { // TODO: fn update_state(origin: OriginFor, org_id: T::Hash, state: u8), // Disable an org - /// Check membership + // TODO: No state changes for this extrinsic, do we need it at all? + + /// Checks membership + /// + /// Checks if origin is a member of the Org. /// - /// - `org_id`: Org id + /// Parameters: + /// - `org_id`: Org hash /// /// Emits `IsAMember` event when successful. /// - /// Weight: + /// Weight: `O(1)` #[pallet::weight(1_000_000)] pub fn check_membership(origin: OriginFor, org_id: T::Hash) -> DispatchResult { let caller = ensure_signed(origin)?; @@ -477,7 +559,28 @@ impl Pallet { // Ok(()) // } - + + /// Create and store a new Org + /// + /// Transfers deposit from creator to the Org treasury. + /// + /// Parameters: + /// - `creator`: Org creator. + /// - `controller_id`: Org controller. + /// - `treasury_id`: Org treasury. + /// - `name`: Org name. + /// - `cid`: IPFS content identifier. + /// - `org_type`: Individual | Company | Dao | Hybrid. + /// - `access`: Open (anyone can join) | Voting (membership voting) | + /// Controller (controller invites). + /// - `fee_model`: NoFees | Reserve (amount reserved in user account) | + /// Transfer (amount transfered to Org treasury). + /// - `fee`: + /// - `gov_asset`: control assets to empower actors. + /// - `pay_asset`: asset used for payments. + /// - `member_limit`: max members, if 0 == no limit. + /// - `deposit`: initial deposit for the org treasury. + /// - `nonce`: current Nonce. fn do_create_org( creator: T::AccountId, org_id: T::Hash, @@ -637,6 +740,12 @@ impl Pallet { Ok(()) } + /// Update member's state + /// + /// Parameters: + /// - `org_id`: Org id. + /// - `account_id`: Member account id. + /// - `member_state`: Inactive | Active | Pending | Kicked | Banned | Exited. fn set_member_state(org_id: T::Hash, account_id: T::AccountId, member_state: ControlMemberState) -> DispatchResult { // TODO: we would like to update member state based on voting result ensure!(Orgs::::contains_key(&org_id), Error::::OrganizationUnknown); @@ -711,6 +820,11 @@ impl Pallet { } } + /// Remove member from Org. + /// + /// Parameters: + /// - `org_id`: Org id. + /// - `account_id`: Member account id. fn do_remove_member(org_id: T::Hash, account_id: T::AccountId) -> DispatchResult { // existence ensure!(Orgs::::contains_key(&org_id), Error::::OrganizationUnknown); diff --git a/flow/src/lib.rs b/flow/src/lib.rs index 57b9efb56..7909e63ed 100644 --- a/flow/src/lib.rs +++ b/flow/src/lib.rs @@ -87,6 +87,11 @@ pub mod pallet { #[pallet::config] pub trait Config: frame_system::Config { + type Event: From> + + IsType<::Event> + + Into<::Event>; + + /// The units in which we record balances. type Balance: Member + Parameter + AtLeast32BitUnsigned @@ -95,7 +100,8 @@ pub mod pallet { + MaybeSerializeDeserialize + MaxEncodedLen + TypeInfo; - + + /// The currency ID type type CurrencyId: Member + Parameter + Default @@ -104,38 +110,51 @@ pub mod pallet { + MaybeSerializeDeserialize + MaxEncodedLen + TypeInfo; - - // type Moment: AtLeast32Bit + Parameter + Default + Copy; - + + /// Weight information for extrinsics in this module. type WeightInfo: frame_system::weights::WeightInfo; - type Event: From> - + IsType<::Event> - + Into<::Event>; + /// Multi-currency support for asset management. type Currency: MultiCurrency + MultiReservableCurrency; + type UnixTime: UnixTime; + type Control: ControlTrait; + /// The GameDAO Treasury AccountId. #[pallet::constant] type GameDAOTreasury: Get; + /// The min length of a campaign name. #[pallet::constant] type MinNameLength: Get; + + /// The max length of a campaign name. #[pallet::constant] type MaxNameLength: Get; #[pallet::constant] type MaxCampaignsPerAddress: Get; + + /// The max number of campaigns per one block. #[pallet::constant] type MaxCampaignsPerBlock: Get; + + /// The max number of contributions per one block. #[pallet::constant] type MaxContributionsPerBlock: Get; + + /// The max number of contributors for processing in one block (batch size) + /// during Campaign finalization. #[pallet::constant] type MaxContributorsProcessing: Get; + /// The min number of blocks for campaign duration. #[pallet::constant] type MinCampaignDuration: Get; + + /// The max number of blocks for campaign duration. #[pallet::constant] type MaxCampaignDuration: Get; #[pallet::constant] @@ -143,16 +162,23 @@ pub mod pallet { #[pallet::constant] type MinContribution: Get; + /// The CurrencyId which is used as a protokol token. #[pallet::constant] type ProtocolTokenId: Get; + + /// The CurrencyId which is used as a payment token. #[pallet::constant] type PaymentTokenId: Get; + /// The amount of comission to be paid from the Org treasury to GameDAO treasury + /// after successfull Campaign finalization #[pallet::constant] type CampaignFee: Get; } - /// Campaign + /// Campaign by its id. + /// + /// Campaigns: map Hash => Campaign #[pallet::storage] pub(super) type Campaigns = StorageMap< _, @@ -162,90 +188,156 @@ pub mod pallet { ValueQuery, >; - /// Associated Body + /// Org id by campaign id. + /// + /// CampaignOrg: map Hash => Hash #[pallet::storage] pub(super) type CampaignOrg = StorageMap<_, Blake2_128Concat, T::Hash, T::Hash, ValueQuery>; - /// Get Campaign Owner (body controller) by campaign id + /// Campaign owner (org controller) by campaign id. + /// + /// CampaignOwner: map Hash => AccountId #[pallet::storage] pub(super) type CampaignOwner = StorageMap<_, Blake2_128Concat, T::Hash, T::AccountId, OptionQuery>; - /// Get Campaign Admin (supervision) by campaign id + /// Campaign admin (supervision) by campaign id. + /// + /// CampaignAdmin: map Hash => AccountId #[pallet::storage] pub(super) type CampaignAdmin = StorageMap<_, Blake2_128Concat, T::Hash, T::AccountId, OptionQuery>; - /// Campaign state - /// 0 init, 1 active, 2 paused, 3 complete success, 4 complete failed, 5 - /// authority lock + /// Campaign state by campaign id. + /// 0 init, 1 active, 2 paused, 3 complete success, 4 complete failed, 5 authority lock + /// + /// CampaignState: map Hash => FlowState #[pallet::storage] pub(super) type CampaignState = StorageMap<_, Blake2_128Concat, T::Hash, FlowState, ValueQuery, GetDefault>; - /// Get Campaigns for a certain state + /// List of campaign by certain campaign state. + /// 0 init, 1 active, 2 paused, 3 complete success, 4 complete failed, 5 authority lock + /// + /// CampaignsByState: map FlowState => Vec #[pallet::storage] pub(super) type CampaignsByState = StorageMap<_, Blake2_128Concat, FlowState, Vec, ValueQuery>; - /// Campaigns ending in block x + /// Campaigns ending in block x. + /// + /// CampaignsByBlock: map BlockNumber => Vec #[pallet::storage] pub(super) type CampaignsByBlock = StorageMap<_, Blake2_128Concat, T::BlockNumber, Vec, ValueQuery>; - /// Total number of campaigns -> all campaigns + /// Total number of campaigns -> campaign id. + /// + /// CampaignsArray: map u64 => Hash #[pallet::storage] pub(super) type CampaignsArray = StorageMap<_, Blake2_128Concat, u64, T::Hash, ValueQuery>; + + /// Total number of campaigns. + /// + /// CampaignsArray: u64 #[pallet::storage] pub type CampaignsCount = StorageValue<_, u64, ValueQuery>; + + /// Campaign id -> total number of campaigns. + /// + /// CampaignsArray: map Hash => u64 #[pallet::storage] pub(super) type CampaignsIndex = StorageMap<_, Blake2_128Concat, T::Hash, u64, ValueQuery>; - /// Number of contributors processed + /// Offset value - number of processed and sucessfully finalized contributions. + /// Used during campaign finalization for processing contributors in batches. + /// When MaxContributorsProcessing is achieved, set this offset to save the progress. + /// + /// ContributorsFinalized: map Hash => u32 #[pallet::storage] pub(super) type ContributorsFinalized = StorageMap<_, Blake2_128Concat, T::Hash, u32, ValueQuery, GetDefault>; + + /// Offset value - number of processed and reverted contributions. + /// + /// ContributorsReverted: map Hash => u32 #[pallet::storage] pub(super) type ContributorsReverted = StorageMap<_, Blake2_128Concat, T::Hash, u32, ValueQuery, GetDefault>; - // caller owned campaigns -> my campaigns + /// Campaign id by org id. + /// + /// CampaignsOwnedArray: map Hash => Hash #[pallet::storage] pub(super) type CampaignsOwnedArray = StorageMap<_, Blake2_128Concat, T::Hash, T::Hash, ValueQuery>; + // TODO: rename? + + /// Total number of campaigns by org id. + /// + /// CampaignsOwnedCount: map Hash => u64 #[pallet::storage] pub(super) type CampaignsOwnedCount = StorageMap<_, Blake2_128Concat, T::Hash, u64, ValueQuery>; + + /// (org id, campaign id) -> total number of campaigns. + /// + /// CampaignsOwnedIndex: map (Hash, Hash) => u64 #[pallet::storage] pub(super) type CampaignsOwnedIndex = StorageMap<_, Blake2_128Concat, (T::Hash, T::Hash), u64, ValueQuery>; - /// campaigns contributed by accountid + /// The list of campaigns contributed by account id. + /// + /// CampaignsContributed: map AccountId => Vec #[pallet::storage] pub(super) type CampaignsContributed = StorageMap<_, Blake2_128Concat, T::AccountId, Vec, ValueQuery>; - /// campaigns related to an organisation + /// Campaigns related to an organisation. + /// + /// CampaignsByOrg: map Hash => Vec #[pallet::storage] pub(super) type CampaignsByOrg = StorageMap<_, Blake2_128Concat, T::Hash, Vec, ValueQuery>; - // caller contributed campaigns -> contributed campaigns + /// (account id, total number of campaigns contributed by account id) -> campaign id. + /// + /// CampaignsContributedArray: map (AccountId, u64) => Hash #[pallet::storage] pub(super) type CampaignsContributedArray = StorageMap<_, Blake2_128Concat, (T::AccountId, u64), T::Hash, ValueQuery>; + + /// Total number of campaigns contributed by account id. + /// + /// CampaignsContributedCount: map AccountId => u64 #[pallet::storage] pub(super) type CampaignsContributedCount = StorageMap<_, Blake2_128Concat, T::AccountId, u64, ValueQuery>; + + /// (account id, campaign id) -> total number of campaigns contributed by account id. + /// + /// CampaignsContributedIndex: map (AccountId, Hash) => u64 #[pallet::storage] pub(super) type CampaignsContributedIndex = StorageMap<_, Blake2_128Concat, (T::AccountId, T::Hash), u64, ValueQuery>; - // Total contributions balance per campaign + /// Total contributions balance per campaign. + /// + /// CampaignBalance: map Hash => Balance #[pallet::storage] pub(super) type CampaignBalance = StorageMap<_, Blake2_128Concat, T::Hash, T::Balance, ValueQuery>; - // Contributions per user + /// Total contribution made by account id for particular campaign. + /// (campaign id, account id) -> contribution. + /// + /// CampaignContribution: map (Hash, AccountId) => Balance #[pallet::storage] pub(super) type CampaignContribution = StorageMap<_, Blake2_128Concat, (T::Hash, T::AccountId), T::Balance, ValueQuery>; - // Contributors + /// Campaign contributors by campaign id. + /// + /// CampaignContributors: map Hash => Vec #[pallet::storage] pub(super) type CampaignContributors = StorageMap<_, Blake2_128Concat, T::Hash, Vec, ValueQuery>; + + /// Total number of contributors for particular campaign. + /// + /// CampaignContributors: map Hash => u64 #[pallet::storage] pub(super) type CampaignContributorsCount = StorageMap<_, Blake2_128Concat, T::Hash, u64, ValueQuery>; @@ -253,7 +345,9 @@ pub mod pallet { // CampaignMaxCampaignDuration get(fn get_max_duration) config(): T::BlockNumber // = T::BlockNumber::from(T::MaxCampaignDuration::get()); - // Campaign nonce, increases per created campaign + /// Nonce. Increase per each campaign creation. + /// + /// Nonce: u128 #[pallet::storage] #[pallet::getter(fn nonce)] pub(super) type Nonce = StorageValue<_, u128, ValueQuery>; @@ -261,9 +355,11 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { + /// Campaign was destroyed. CampaignDestroyed { campaign_id: T::Hash, }, + /// Campaign was successfully created. CampaignCreated { campaign_id: T::Hash, creator: T::AccountId, @@ -273,34 +369,40 @@ pub mod pallet { expiry: T::BlockNumber, name: Vec, }, + /// Campaign was contributed. CampaignContributed { campaign_id: T::Hash, sender: T::AccountId, contribution: T::Balance, block_number: T::BlockNumber, }, + /// Campaign was finalized. CampaignFinalized { campaign_id: T::Hash, campaign_balance: T::Balance, block_number: T::BlockNumber, success: bool, }, + /// Campaign failed - successfully reverted. CampaignFailed { campaign_id: T::Hash, campaign_balance: T::Balance, block_number: T::BlockNumber, success: bool, }, + /// Campaign is in the middle of reverting process. CampaignReverting { campaign_id: T::Hash, campaign_balance: T::Balance, block_number: T::BlockNumber, }, + /// Campaign is in the middle of finalization process. CampaignFinalising { campaign_id: T::Hash, campaign_balance: T::Balance, block_number: T::BlockNumber, }, + /// Campaign was updated with a new state. CampaignUpdated { campaign_id: T::Hash, state: FlowState, @@ -311,74 +413,73 @@ pub mod pallet { #[pallet::error] pub enum Error { - // - // general - /// Must contribute at least the minimum amount of Campaigns + + // general + /// Must contribute at least the minimum amount of campaigns. ContributionTooSmall, /// Balance too low. BalanceTooLow, - /// Treasury Balance Too Low + /// Treasury balance too low. TreasuryBalanceTooLow, - /// The Campaign id specified does not exist + /// The campaign id specified does not exist. InvalidId, - /// The Campaign's contribution period has ended; no more contributions - /// will be accepted + /// The campaign's contribution period has ended; no more contributions + /// will be accepted. ContributionPeriodOver, /// You may not withdraw or dispense Campaigns while the Campaign is - /// still active + /// still active. CampaignStillActive, - /// You cannot withdraw Campaigns because you have not contributed any + /// You cannot withdraw Campaigns because you have not contributed any. NoContribution, /// You cannot dissolve a Campaign that has not yet completed its - /// retirement period + /// retirement period. CampaignNotRetired, - /// Campaign expired + /// Campaign expired. CampaignExpired, - /// Cannot dispense Campaigns from an unsuccessful Campaign + /// Cannot dispense Campaigns from an unsuccessful Campaign. UnsuccessfulCampaign, - // // create - /// Campaign must end after it starts + /// Campaign must end after it starts. EndTooEarly, - /// Campaign expiry has be lower than the block number limit + /// Campaign expiry has be lower than the block number limit. EndTooLate, - /// Max campaigns per block exceeded + /// Max campaigns per block exceeded. CampaignsPerBlockExceeded, - /// Name too long + /// Name too long. NameTooLong, - /// Name too short + /// Name too short. NameTooShort, - /// Deposit exceeds the campaign target + /// Deposit exceeds the campaign target. DepositTooHigh, - /// Campaign id exists + /// Campaign id exists. IdExists, // // mint - /// Overflow adding a new campaign to total fundings + /// Overflow adding a new campaign to total fundings. AddCampaignOverflow, - /// Overflow adding a new owner + /// Overflow adding a new owner. AddOwnedOverflow, - /// Overflow adding to the total number of contributors of a camapaign + /// Overflow adding to the total number of contributors of a camapaign. UpdateContributorOverflow, - /// Overflow adding to the total number of contributions of a camapaign + /// Overflow adding to the total number of contributions of a camapaign. AddContributionOverflow, - /// Campaign owner unknown + /// Campaign owner unknown. OwnerUnknown, - /// Campaign admin unknown + /// Campaign admin unknown. AdminUnknown, - /// Cannot contribute to owned campaign + /// Cannot contribute to owned campaign. NoContributionToOwnCampaign, - /// Guru Meditation + /// Guru Meditation. GuruMeditation, - /// Zou are not authorized for this call + /// Zou are not authorized for this call. AuthorizationError, - /// Contributions not allowed + /// Contributions not allowed. NoContributionsAllowed, - /// Id Unknown + /// Id Unknown. IdUnknown, - /// Transfer Error + /// Transfer Error. TransferError, } @@ -402,8 +503,8 @@ pub mod pallet { impl Pallet { /// Create campaign /// - /// - `org`: - /// - `admin`: Campaign admin. Supervision, should be dao provided! + /// - `org_id`: + /// - `admin_id`: Campaign admin. Supervision, should be dao provided! /// - `treasury`: /// - `name`: Campaign name /// - `target`: @@ -411,13 +512,13 @@ pub mod pallet { /// - `expiry`: /// - `protocol`: /// - `governance`: - /// - `cid`: IPFS + /// - `cid`: IPFS content identifier. /// - `token_symbol`: /// - `token_name`: /// /// Emits `CampaignCreated` event when successful. /// - /// Weight: + /// Weight: `O(1)` #[pallet::weight(5_000_000)] #[transactional] pub fn create_campaign( diff --git a/sense/src/lib.rs b/sense/src/lib.rs index 03c9dc472..decdf7032 100644 --- a/sense/src/lib.rs +++ b/sense/src/lib.rs @@ -10,6 +10,7 @@ //! SENSE //! This pallet aggregates datapoints to reflect user experience and behaviour. +//! Sense Properties: Experience, Reputation and Trust. #![cfg_attr(not(feature = "std"), no_std)] #[warn(unused_imports)] use frame_support::{dispatch::DispatchResult, pallet_prelude::*}; @@ -82,31 +83,41 @@ pub mod pallet { #[pallet::generate_store(pub(super) trait Store)] pub struct Pallet(_); + /// Sense Entity of the account. + /// + /// SenseEntity: map AccountId => Entity #[pallet::storage] #[pallet::getter(fn entity)] - pub(super) type SenseEntity = StorageMap< - _, - Blake2_128Concat, - T::AccountId, - Entity, - ValueQuery, - >; + pub(super) type SenseEntity = StorageMap<_, Blake2_128Concat, T::AccountId, + Entity, ValueQuery>; + /// Experience property of the account. + /// + /// SenseEntity: map AccountId => EntityProperty #[pallet::storage] #[pallet::getter(fn xp)] pub(super) type SenseXP = StorageMap<_, Blake2_128Concat, T::AccountId, EntityProperty, ValueQuery>; + /// Reputation property of the account. + /// + /// SenseEntity: map AccountId => EntityProperty #[pallet::storage] #[pallet::getter(fn rep)] pub(super) type SenseREP = StorageMap<_, Blake2_128Concat, T::AccountId, EntityProperty, ValueQuery>; + /// Trust property of the account. + /// + /// SenseEntity: map AccountId => EntityProperty #[pallet::storage] #[pallet::getter(fn trust)] pub(super) type SenseTrust = StorageMap<_, Blake2_128Concat, T::AccountId, EntityProperty, ValueQuery>; + /// Nonce. Increase per each entity creation. + /// + /// Nonce: u128 #[pallet::storage] #[pallet::getter(fn nonce)] pub type Nonce = StorageValue<_, u128, ValueQuery>; @@ -114,56 +125,71 @@ pub mod pallet { #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { + /// New Sense Entity was created. EntityInit(T::AccountId, T::BlockNumber), + /// Experience property was updated. EntityMutateXP(T::AccountId, T::BlockNumber), + /// Reputation property was updated. EntityMutateREP(T::AccountId, T::BlockNumber), + /// Trust property was updated. EntityMutateTrust(T::AccountId, T::BlockNumber), } - // Errors inform users that something went wrong. #[pallet::error] pub enum Error { - /// Entity Exists + /// Entity exists. EntityExists, - /// Entity Unknown + /// Entity unknown. EntityUnknown, - /// Guru Meditation + /// Guru Meditation. GuruMeditation, - /// Param Limit Exceed + /// Param limit exceed. ParamLimitExceed, - /// Invalid Param + /// Invalid param. InvalidParam, + /// Overflow adding a value to the entity property + EntityPropertyOverflow, } #[pallet::call] impl Pallet { + + /// Create a Sense Entity for the account. + /// + /// Parameters: + /// - `account_id`: account id. + /// - `cid`: IPFS content identifier. + /// + /// Emits `EntityInit` event when successful. + /// + /// Weight: `O(1)` #[pallet::weight(::WeightInfo::create_entity())] pub fn create_entity( origin: OriginFor, - account: T::AccountId, + account_id: T::AccountId, cid: Vec, ) -> DispatchResult { ensure_root(origin)?; ensure!(cid.len() > 0, Error::::InvalidParam); ensure!(cid.len() <= MAX_STRING_FIELD_LENGTH, Error::::ParamLimitExceed); - ensure!(!>::contains_key(&account), Error::::EntityExists); + ensure!(!>::contains_key(&account_id), Error::::EntityExists); let current_block = >::block_number(); let index = >::get(); - let entity = Entity::new(account.clone(), current_block, index, cid.clone()); + let entity = Entity::new(account_id.clone(), current_block, index, cid.clone()); let xp = EntityProperty { value: 0, mutated: current_block.clone() }; let rep = EntityProperty { value: 0, mutated: current_block.clone() }; let trust = EntityProperty { value: 0, mutated: current_block.clone() }; - >::insert(account.clone(), xp); - >::insert(account.clone(), rep); - >::insert(account.clone(), trust); - >::insert(account.clone(), entity); + >::insert(account_id.clone(), xp); + >::insert(account_id.clone(), rep); + >::insert(account_id.clone(), trust); + >::insert(account_id.clone(), entity); // TODO: safe increment, checked_add >::mutate(|n| *n += 1); - Self::deposit_event(Event::EntityInit(account, current_block)); + Self::deposit_event(Event::EntityInit(account_id, current_block)); Ok(()) } @@ -176,67 +202,93 @@ pub mod pallet { // all: governance // sudo ( until its removal ) + /// Modifies an Experience property of the account. + /// + /// Parameters: + /// - `account_id`: account id. + /// - `cid`: IPFS content identifier. + /// + /// Emits `EntityMutateXP` event when successful. + /// + /// Weight: `O(1)` #[pallet::weight(::WeightInfo::mod_xp())] - pub fn mod_xp(origin: OriginFor, account: T::AccountId, value: u8) -> DispatchResult { + pub fn mod_xp(origin: OriginFor, account_id: T::AccountId, value: u8) -> DispatchResult { ensure_root(origin)?; - ensure!(>::contains_key(&account), Error::::EntityUnknown); + ensure!(>::contains_key(&account_id), Error::::EntityUnknown); let now = >::block_number(); let v = u64::from(value); - let current = Self::xp(&account); + let current = Self::xp(&account_id); let updated = EntityProperty { - value: current.value.checked_add(v).ok_or(Error::::GuruMeditation)?, + value: current.value.checked_add(v).ok_or(Error::::EntityPropertyOverflow)?, mutated: now.clone(), }; - >::insert(account.clone(), updated); + >::insert(account_id.clone(), updated); - Self::deposit_event(Event::EntityMutateXP(account, now)); + Self::deposit_event(Event::EntityMutateXP(account_id, now)); Ok(()) } + /// Modifies a Reputation property of the account. + /// + /// Parameters: + /// - `account_id`: account id. + /// - `cid`: IPFS content identifier. + /// + /// Emits `EntityMutateREP` event when successful. + /// + /// Weight: `O(1)` #[pallet::weight(::WeightInfo::mod_rep())] - pub fn mod_rep(origin: OriginFor, account: T::AccountId, value: u8) -> DispatchResult { + pub fn mod_rep(origin: OriginFor, account_id: T::AccountId, value: u8) -> DispatchResult { ensure_root(origin)?; - ensure!(>::contains_key(&account), Error::::EntityUnknown); + ensure!(>::contains_key(&account_id), Error::::EntityUnknown); let now = >::block_number(); let v = u64::from(value); - let current = Self::rep(&account); + let current = Self::rep(&account_id); let updated = EntityProperty { - value: current.value.checked_add(v).ok_or(Error::::GuruMeditation)?, + value: current.value.checked_add(v).ok_or(Error::::EntityPropertyOverflow)?, mutated: now.clone(), }; - >::insert(account.clone(), updated); + >::insert(account_id.clone(), updated); - Self::deposit_event(Event::EntityMutateREP(account, now)); + Self::deposit_event(Event::EntityMutateREP(account_id, now)); Ok(()) } + /// Modifies a Trust property of the account. + /// + /// Parameters: + /// - `account_id`: account id. + /// - `cid`: IPFS content identifier. + /// + /// Emits `EntityMutateTrust` event when successful. + /// + /// Weight: `O(1)` #[pallet::weight(::WeightInfo::mod_trust())] - pub fn mod_trust(origin: OriginFor, account: T::AccountId, value: u8) -> DispatchResult { + pub fn mod_trust(origin: OriginFor, account_id: T::AccountId, value: u8) -> DispatchResult { ensure_root(origin)?; - ensure!(>::contains_key(&account), Error::::EntityUnknown); + ensure!(>::contains_key(&account_id), Error::::EntityUnknown); let now = >::block_number(); let v = u64::from(value); - let current = Self::trust(&account); + let current = Self::trust(&account_id); let updated = EntityProperty { - value: current.value.checked_add(v).ok_or(Error::::GuruMeditation)?, + value: current.value.checked_add(v).ok_or(Error::::EntityPropertyOverflow)?, mutated: now, }; - >::insert(account.clone(), updated); + >::insert(account_id.clone(), updated); - Self::deposit_event(Event::EntityMutateTrust(account, now)); + Self::deposit_event(Event::EntityMutateTrust(account_id, now)); Ok(()) } - // TODO: - // generic mod for all properties + // TODO: generic mod for all properties } }