Skip to content

Commit

Permalink
feat(governance): add resolver id to application
Browse files Browse the repository at this point in the history
  • Loading branch information
saiintbrisson committed Jan 8, 2025
1 parent fd89c88 commit edec678
Show file tree
Hide file tree
Showing 15 changed files with 672 additions and 271 deletions.
69 changes: 0 additions & 69 deletions node/specs/main.json

This file was deleted.

7 changes: 5 additions & 2 deletions node/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ impl SubstrateCli for Cli {
fn load_spec(&self, id: &str) -> Result<Box<dyn sc_service::ChainSpec>, String> {
Ok(match id {
"dev" => Box::new(chain_spec::development_config()?),
"main" => Box::new(chain_spec::ChainSpec::from_json_bytes(
include_bytes!("../specs/main.json").as_ref(),
"main" | "mainnet" => Box::new(chain_spec::ChainSpec::from_json_bytes(
include_bytes!("../../data/mainnet/spec.json").as_ref(),
)?),
"testnet" => Box::new(chain_spec::ChainSpec::from_json_bytes(
include_bytes!("../../data/testnet/spec.json").as_ref(),
)?),
path => Box::new(chain_spec::ChainSpec::from_json_file(
std::path::PathBuf::from(path),
Expand Down
10 changes: 5 additions & 5 deletions pallets/emission0/src/weights.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
//! Autogenerated weights for `pallet_emission0`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 43.0.0
//! DATE: 2025-01-06, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! DATE: 2025-01-07, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `MacBook-Pro-de-Joao.local`, CPU: `<UNKNOWN>`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024`
Expand Down Expand Up @@ -64,8 +64,8 @@ impl<T: frame_system::Config> WeightInfo for SubstrateWeight<T> {
// Proof Size summary in bytes:
// Measured: `339`
// Estimated: `7638`
// Minimum execution time: 33_000_000 picoseconds.
Weight::from_parts(34_000_000, 7638)
// Minimum execution time: 23_000_000 picoseconds.
Weight::from_parts(24_000_000, 7638)
.saturating_add(T::DbWeight::get().reads(8_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
Expand Down Expand Up @@ -115,8 +115,8 @@ impl WeightInfo for () {
// Proof Size summary in bytes:
// Measured: `339`
// Estimated: `7638`
// Minimum execution time: 33_000_000 picoseconds.
Weight::from_parts(34_000_000, 7638)
// Minimum execution time: 23_000_000 picoseconds.
Weight::from_parts(24_000_000, 7638)
.saturating_add(RocksDbWeight::get().reads(8_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
Expand Down
166 changes: 116 additions & 50 deletions pallets/governance/src/application.rs
Original file line number Diff line number Diff line change
@@ -1,38 +1,75 @@
use crate::frame::traits::ExistenceRequirement;
use crate::{whitelist, AccountIdOf, AgentApplications, BalanceOf, Block};
use crate::{whitelist, AccountIdOf, AgentApplications, BalanceOf};
use codec::{Decode, Encode, MaxEncodedLen};
use polkadot_sdk::frame_election_provider_support::Get;
use polkadot_sdk::frame_support::dispatch::DispatchResult;
use polkadot_sdk::frame_support::traits::Currency;
use polkadot_sdk::frame_support::traits::WithdrawReasons;
use polkadot_sdk::frame_support::DebugNoBound;
use polkadot_sdk::sp_runtime::BoundedVec;
use polkadot_sdk::frame_support::{ensure, CloneNoBound, DebugNoBound};
use polkadot_sdk::polkadot_sdk_frame::prelude::BlockNumberFor;
use polkadot_sdk::sp_runtime::{BoundedVec, DispatchError};
use polkadot_sdk::sp_std::vec::Vec;
use scale_info::TypeInfo;

#[derive(DebugNoBound, TypeInfo, Decode, Encode, MaxEncodedLen)]
#[derive(CloneNoBound, DebugNoBound, TypeInfo, Decode, Encode, MaxEncodedLen)]
#[scale_info(skip_type_params(T))]
pub struct AgentApplication<T: crate::Config> {
pub id: u32,
pub payer_key: AccountIdOf<T>,
pub agent_key: AccountIdOf<T>,
pub data: BoundedVec<u8, T::MaxApplicationDataLength>,
pub cost: BalanceOf<T>,
pub expires_at: Block,
pub expires_at: BlockNumberFor<T>,
pub action: ApplicationAction,
pub status: ApplicationStatus,
pub status: ApplicationStatus<T>,
}

#[derive(DebugNoBound, Decode, Encode, TypeInfo, MaxEncodedLen, PartialEq, Eq)]
impl<T: crate::Config> AgentApplication<T> {
fn revoke(&mut self, revoked_by: T::AccountId) -> DispatchResult {
ensure!(
self.action == ApplicationAction::Add,
crate::Error::<T>::CannotRevokeRemoveApplication,
);

let previously_accepted_by = match &self.status {
ApplicationStatus::Resolved {
accepted: true,
resolved_by,
} => resolved_by,
_ => return Err(crate::Error::<T>::CannotRevokeUnresolvedApplication.into()),
};

self.status = ApplicationStatus::Revoked {
previously_accepted_by: previously_accepted_by.clone(),
revoked_by,
};

whitelist::remove_from_whitelist::<T>(self.agent_key.clone())?;

crate::Pallet::<T>::deposit_event(crate::Event::<T>::ApplicationRevoked(self.id));

Ok(())
}
}

#[derive(CloneNoBound, DebugNoBound, Decode, Encode, TypeInfo, MaxEncodedLen, PartialEq, Eq)]
pub enum ApplicationAction {
Add,
Remove,
}

#[derive(DebugNoBound, Decode, Encode, TypeInfo, MaxEncodedLen, PartialEq, Eq)]
pub enum ApplicationStatus {
#[derive(CloneNoBound, DebugNoBound, Decode, Encode, TypeInfo, MaxEncodedLen, PartialEq, Eq)]
#[scale_info(skip_type_params(T))]
pub enum ApplicationStatus<T: crate::Config> {
Open,
Resolved { accepted: bool },
Resolved {
accepted: bool,
resolved_by: AccountIdOf<T>,
},
Revoked {
previously_accepted_by: AccountIdOf<T>,
revoked_by: AccountIdOf<T>,
},
Expired,
}

Expand All @@ -42,18 +79,18 @@ pub fn submit_application<T: crate::Config>(
data: Vec<u8>,
removing: bool,
) -> DispatchResult {
if !removing && whitelist::is_whitelisted::<T>(&agent_key) {
return Err(crate::Error::<T>::AlreadyWhitelisted.into());
} else if removing && !whitelist::is_whitelisted::<T>(&agent_key) {
return Err(crate::Error::<T>::NotWhitelisted.into());
}

let action = if removing {
ApplicationAction::Remove
} else {
ApplicationAction::Add
};

if action == ApplicationAction::Add && whitelist::is_whitelisted::<T>(&agent_key) {
return Err(crate::Error::<T>::AlreadyWhitelisted.into());
} else if action == ApplicationAction::Remove && !whitelist::is_whitelisted::<T>(&agent_key) {
return Err(crate::Error::<T>::NotWhitelisted.into());
}

if exists_for_agent_key::<T>(&agent_key, &action) {
return Err(crate::Error::<T>::ApplicationKeyAlreadyUsed.into());
}
Expand All @@ -79,10 +116,7 @@ pub fn submit_application<T: crate::Config>(
return Err(crate::Error::<T>::InvalidApplicationDataLength.into());
}

let current_block: u64 =
TryInto::try_into(<polkadot_sdk::frame_system::Pallet<T>>::block_number())
.ok()
.expect("blockchain will not exceed 2^64 blocks; QED.");
let current_block = <polkadot_sdk::frame_system::Pallet<T>>::block_number();

let expires_at = current_block + config.agent_application_expiration;

Expand All @@ -108,30 +142,34 @@ pub fn submit_application<T: crate::Config>(
Ok(())
}

pub fn accept_application<T: crate::Config>(application_id: u32) -> DispatchResult {
let application = crate::AgentApplications::<T>::get(application_id)
.ok_or(crate::Error::<T>::ApplicationNotFound)?;

match application.action {
ApplicationAction::Add => {
crate::Whitelist::<T>::insert(application.agent_key.clone(), ());
crate::Pallet::<T>::deposit_event(crate::Event::<T>::WhitelistAdded(
application.agent_key,
));
}
ApplicationAction::Remove => {
crate::Whitelist::<T>::remove(&application.agent_key);
crate::Pallet::<T>::deposit_event(crate::Event::<T>::WhitelistRemoved(
application.agent_key,
));
pub fn accept_application<T: crate::Config>(
resolver: T::AccountId,
application_id: u32,
) -> DispatchResult {
let application = crate::AgentApplications::<T>::mutate(application_id, |app| {
if let Some(app) = app {
ensure!(
app.status == ApplicationStatus::Open,
crate::Error::<T>::ApplicationNotPending
);

app.status = ApplicationStatus::Resolved {
accepted: true,
resolved_by: resolver,
};

Ok(app.clone())
} else {
Err(DispatchError::from(crate::Error::<T>::ApplicationNotFound))
}
}
})?;

crate::AgentApplications::<T>::mutate(application_id, |application| {
if let Some(app) = application {
app.status = ApplicationStatus::Resolved { accepted: true };
let _ = match application.action {
ApplicationAction::Add => whitelist::add_to_whitelist::<T>(application.agent_key.clone()),
ApplicationAction::Remove => {
whitelist::remove_from_whitelist::<T>(application.agent_key.clone())
}
});
};

// Pay the application cost back to the applicant
let _ =
Expand All @@ -142,22 +180,50 @@ pub fn accept_application<T: crate::Config>(application_id: u32) -> DispatchResu
Ok(())
}

pub fn deny_application<T: crate::Config>(application_id: u32) -> DispatchResult {
let application = crate::AgentApplications::<T>::get(application_id)
.ok_or(crate::Error::<T>::ApplicationNotFound)?;

crate::AgentApplications::<T>::mutate(application_id, |application| {
if let Some(app) = application {
app.status = ApplicationStatus::Resolved { accepted: false };
pub fn deny_application<T: crate::Config>(
resolved_by: T::AccountId,
application_id: u32,
) -> DispatchResult {
let application = crate::AgentApplications::<T>::mutate(application_id, |app| {
if let Some(app) = app {
ensure!(
app.status == ApplicationStatus::Open,
crate::Error::<T>::ApplicationNotPending
);

app.status = ApplicationStatus::Resolved {
accepted: false,
resolved_by,
};

Ok(app.clone())
} else {
Err(DispatchError::from(crate::Error::<T>::ApplicationNotFound))
}
});
})?;

crate::Pallet::<T>::deposit_event(crate::Event::<T>::ApplicationDenied(application.id));

Ok(())
}

pub(crate) fn resolve_expired_applications<T: crate::Config>(current_block: Block) {
pub fn revoke_application<T: crate::Config>(
revoked_by: T::AccountId,
application_id: u32,
) -> DispatchResult {
crate::AgentApplications::<T>::mutate(application_id, |app| {
if let Some(app) = app {
app.revoke(revoked_by)?;
Ok(app.clone())
} else {
Err(DispatchError::from(crate::Error::<T>::ApplicationNotFound))
}
})?;

Ok(())
}

pub(crate) fn resolve_expired_applications<T: crate::Config>(current_block: BlockNumberFor<T>) {
for application in crate::AgentApplications::<T>::iter_values() {
if current_block < application.expires_at {
continue;
Expand Down
11 changes: 11 additions & 0 deletions pallets/governance/src/benchmarks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ benchmarks! {
create_application::<T>(&module_key);
}: _(RawOrigin::Signed(module_key.clone()), 0)

revoke_application {
let module_key: T::AccountId = account("ModuleKey", 0, 2);

crate::roles::manage_role::<T, crate::Curators<T>>(module_key.clone(), true, crate::Error::<T>::AlreadyCurator)
.expect("failed to add curator");

create_application::<T>(&module_key);
application::accept_application::<T>(module_key.clone(), 0)
.expect("failed to accept application");
}: _(RawOrigin::Signed(module_key.clone()), 0)

penalize_agent {
let module_key: T::AccountId = account("ModuleKey", 0, 2);

Expand Down
9 changes: 5 additions & 4 deletions pallets/governance/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
use codec::{Decode, Encode, MaxEncodedLen};
use polkadot_sdk::frame_election_provider_support::Get;
use polkadot_sdk::polkadot_sdk_frame::prelude::BlockNumberFor;
use polkadot_sdk::{frame_support::DebugNoBound, sp_runtime::Percent};
use scale_info::TypeInfo;

use crate::{BalanceOf, BlockAmount};
use crate::BalanceOf;

#[derive(Clone, TypeInfo, Decode, Encode, PartialEq, Eq, DebugNoBound, MaxEncodedLen)]
#[scale_info(skip_type_params(T))]
pub struct GovernanceConfiguration<T: crate::Config> {
pub proposal_cost: BalanceOf<T>,
pub proposal_expiration: BlockAmount,
pub proposal_expiration: BlockNumberFor<T>,
pub agent_application_cost: BalanceOf<T>,
pub agent_application_expiration: BlockAmount,
pub agent_application_expiration: BlockNumberFor<T>,
pub proposal_reward_treasury_allocation: Percent,
pub max_proposal_reward_treasury_allocation: BalanceOf<T>,
pub proposal_reward_interval: BlockAmount,
pub proposal_reward_interval: BlockNumberFor<T>,
}

impl<T: crate::Config> Default for GovernanceConfiguration<T> {
Expand Down
4 changes: 0 additions & 4 deletions pallets/governance/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,3 @@ pub(super) type BalanceOf<T> = <<T as crate::Config>::Currency as Currency<
>>::Balance;

pub(super) type AccountIdOf<T> = <T as polkadot_sdk::frame_system::Config>::AccountId;

pub(super) type Block = u64;

pub(super) type BlockAmount = u64;
Loading

0 comments on commit edec678

Please sign in to comment.