Skip to content

Commit

Permalink
Enrich api proposals (#278)
Browse files Browse the repository at this point in the history
* add dispute votes to api

* fmt

* return milestones in voting round

* fmt

* clippy

* fix benchmark build

* fmt
  • Loading branch information
f-gate authored Nov 30, 2023
1 parent a78759c commit 505f922
Show file tree
Hide file tree
Showing 14 changed files with 157 additions and 64 deletions.
6 changes: 3 additions & 3 deletions node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ async fn start_node_impl(
config: parachain_config,
keystore: params.keystore_container.keystore(),
backend,
network: network.clone(),
network,
sync_service: sync_service.clone(),
system_rpc_tx,
tx_handler_controller,
Expand Down Expand Up @@ -318,7 +318,7 @@ async fn start_node_impl(
&task_manager,
relay_chain_interface.clone(),
transaction_pool,
sync_service.clone(),
sync_service,
params.keystore_container.keystore(),
relay_chain_slot_duration,
para_id,
Expand Down Expand Up @@ -395,7 +395,7 @@ fn start_consensus(
client.clone(),
transaction_pool,
prometheus_registry,
telemetry.clone(),
telemetry,
);

let proposer = Proposer::new(proposer_factory);
Expand Down
5 changes: 5 additions & 0 deletions pallets/disputes/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,11 @@ pub mod pallet {
}
}

#[derive(Clone, Copy, PartialEq, Debug, Encode, Decode, TypeInfo)]
pub struct DisputeVotes<T> {
pub votes: T,
}

#[derive(Clone, Copy, PartialEq, Debug, Encode, Decode, TypeInfo)]
pub enum DisputeResult {
Success = 0,
Expand Down
2 changes: 1 addition & 1 deletion pallets/grants/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ pub mod pallet {
);

let mut contributions = BTreeMap::new();
let _ = assigned_approvers.iter().for_each(|approver_id| {
assigned_approvers.iter().for_each(|approver_id| {
contributions.insert(
approver_id.clone(),
Contribution {
Expand Down
8 changes: 4 additions & 4 deletions pallets/grants/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,10 +247,10 @@ impl pallet_disputes::traits::DisputeRaiser<AccountId> for MockDisputeRaiser {
type MaxJurySize = MaxJuryMembers;
type MaxSpecifics = MaxMilestonesPerProject;
fn raise_dispute(
dispute_key: Self::DisputeKey,
raised_by: AccountId,
jury: BoundedVec<AccountId, Self::MaxJurySize>,
specific_ids: BoundedVec<Self::SpecificId, Self::MaxSpecifics>,
_dispute_key: Self::DisputeKey,
_raised_by: AccountId,
_jury: BoundedVec<AccountId, Self::MaxJurySize>,
_specific_ids: BoundedVec<Self::SpecificId, Self::MaxSpecifics>,
) -> Result<(), DispatchError> {
Ok(())
}
Expand Down
2 changes: 1 addition & 1 deletion pallets/proposals/rpc/runtime-api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ sp_api::decl_runtime_apis! {
where AccountId: codec::Codec + Ord,
{
fn get_project_account_by_id(project_id: u32) -> AccountId;
fn get_all_project_data(project_id: u32) -> Option<(Vec<u8>, Vec<u8>)>;
fn get_all_project_data(project_id: u32) -> (Option<Vec<u8>>, Option<Vec<u8>>, Option<Vec<u8>>, Vec<u32>);
}
}
10 changes: 8 additions & 2 deletions pallets/proposals/rpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ where
#[method(name = "proposals_getProjectKitty")]
fn project_account_id(&self, project_id: u32) -> RpcResult<AccountId>;
#[method(name = "proposals_getAllProjectData")]
fn all_project_data(&self, project_id: u32) -> RpcResult<Option<(Vec<u8>, Vec<u8>)>>;
fn all_project_data(
&self,
project_id: u32,
) -> RpcResult<(Option<Vec<u8>>, Option<Vec<u8>>, Option<Vec<u8>>, Vec<u32>)>;
}

pub struct Proposals<C, B> {
Expand Down Expand Up @@ -76,7 +79,10 @@ where
api.get_project_account_by_id(at, project_id)
.map_err(runtime_error_into_rpc_err)
}
fn all_project_data(&self, project_id: u32) -> RpcResult<Option<(Vec<u8>, Vec<u8>)>> {
fn all_project_data(
&self,
project_id: u32,
) -> RpcResult<(Option<Vec<u8>>, Option<Vec<u8>>, Option<Vec<u8>>, Vec<u32>)> {
let api = self.client.runtime_api();
let at = self.client.info().best_hash;

Expand Down
14 changes: 8 additions & 6 deletions pallets/proposals/src/impls/pallet_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ impl<T: Config> Pallet<T> {
Ok::<(), DispatchError>(())
})?;

ProjectInVoting::<T>::insert(project_key, milestone_key, ());

Self::deposit_event(Event::MilestoneSubmitted(who, project_key, milestone_key));
Self::deposit_event(Event::VotingRoundCreated(project_key));
Ok(().into())
Expand Down Expand Up @@ -306,25 +308,25 @@ impl<T: Config> Pallet<T> {
}

pub(crate) fn close_voting_round(
project_key: ProjectKey,
_project_key: ProjectKey,
user_has_voted_key: (ProjectKey, RoundType, MilestoneKey),
) -> Result<(), DispatchError> {
let (project_key, _round_type, milestone_key) = user_has_voted_key;
// Prevent further voting.
let exp_block =
Rounds::<T>::take((project_key, user_has_voted_key.2), RoundType::VotingRound)
.ok_or(Error::<T>::VotingRoundNotStarted)?;
let exp_block = Rounds::<T>::take((project_key, milestone_key), RoundType::VotingRound)
.ok_or(Error::<T>::VotingRoundNotStarted)?;
// Prevent hook from calling.
RoundsExpiring::<T>::remove(exp_block);
// Allow future votes to occur on this milestone
IndividualVoteStore::<T>::try_mutate(project_key, |maybe_individual_votes| {
if let Some(individual_votes) = maybe_individual_votes {
individual_votes.clear_milestone_votes(user_has_voted_key.2);
individual_votes.clear_milestone_votes(milestone_key);
} else {
return Err(Error::<T>::IndividualVoteNotFound.into());
}
Ok::<(), DispatchError>(())
})?;

ProjectInVoting::<T>::remove(project_key, milestone_key);
Ok(())
}
}
Expand Down
17 changes: 17 additions & 0 deletions pallets/proposals/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,8 @@ pub mod pallet {
ValueQuery,
>;

// TODO: Check if this is in use.
/// A helper to find what projects / milestones are in a dispute.
#[pallet::storage]
pub type ProjectsInDispute<T> = StorageMap<
_,
Expand All @@ -219,6 +221,19 @@ pub mod pallet {
ValueQuery,
>;

/// Projects in Voting round.
/// A helper for the runtime api so we dont have to iterate over the Rounds Double map.
#[pallet::storage]
pub type ProjectInVoting<T> = StorageDoubleMap<
_,
Blake2_128Concat,
ProjectKey,
Blake2_128Concat,
MilestoneKey,
(),
ValueQuery,
>;

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
Expand Down Expand Up @@ -369,6 +384,8 @@ pub mod pallet {
individual_votes.clear_milestone_votes(*milestone_key);
}
});

ProjectInVoting::<T>::remove(project_key, milestone_key);
}
// Votes of no confidence do not finaliese automatically
RoundType::VoteOfNoConfidence => {
Expand Down
5 changes: 3 additions & 2 deletions pallets/proposals/src/test_utils.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::*;
use common_types::CurrencyId;
use frame_support::{assert_ok, BoundedVec};
use frame_support::BoundedVec;
use frame_system::EventRecord;
use orml_traits::{MultiCurrency, MultiReservableCurrency};
use orml_traits::MultiReservableCurrency;

use pallet_disputes::traits::DisputeHooks;
use sp_arithmetic::per_things::Percent;
Expand All @@ -13,6 +13,7 @@ use sp_std::convert::TryInto;

#[cfg(feature = "runtime-benchmarks")]
use frame_benchmarking::account;
use frame_support::assert_ok;
#[cfg(feature = "runtime-benchmarks")]
use sp_std::vec::Vec;

Expand Down
79 changes: 77 additions & 2 deletions pallets/proposals/src/tests/pallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -690,8 +690,7 @@ fn withdraw_only_transfers_approved_milestones() {
let alice_after = <Test as Config>::MultiCurrency::free_balance(CurrencyId::Native, &ALICE);
let expected_fee = <Test as Config>::ImbueFee::get().mul_floor(per_contribution * 2 / 10);
// total_contribution / number of milestones - fee
let alice_expected_balance =
alice_before + ((per_contribution * 2 / 10) as u128) - expected_fee as u128;
let alice_expected_balance = alice_before + (per_contribution * 2 / 10) - expected_fee;
assert_eq!(
alice_after, alice_expected_balance,
"Alice account is not the expected balance"
Expand Down Expand Up @@ -1074,3 +1073,79 @@ fn close_voting_round_works() {
.is_empty());
})
}

#[test]
fn project_in_voting_is_saved_on_submission() {
build_test_externality().execute_with(|| {
let cont = get_contributions::<Test>(vec![BOB], 100_000);
let prop_milestones = get_milestones(10);
let project_key =
create_and_fund_project::<Test>(ALICE, cont, prop_milestones, CurrencyId::Native)
.unwrap();

assert_ok!(Proposals::submit_milestone(
RuntimeOrigin::signed(ALICE),
project_key,
0
));
assert_ok!(Proposals::submit_milestone(
RuntimeOrigin::signed(ALICE),
project_key,
1
));

assert!(ProjectInVoting::<Test>::contains_key(project_key, 0));
assert!(ProjectInVoting::<Test>::contains_key(project_key, 1));
})
}

#[test]
fn project_in_voting_is_removed_on_init_hook() {
build_test_externality().execute_with(|| {
let cont = get_contributions::<Test>(vec![BOB], 100_000);
let prop_milestones = get_milestones(10);
let project_key =
create_and_fund_project::<Test>(ALICE, cont, prop_milestones, CurrencyId::Native)
.unwrap();

assert_ok!(Proposals::submit_milestone(
RuntimeOrigin::signed(ALICE),
project_key,
0
));

assert!(ProjectInVoting::<Test>::contains_key(project_key, 0));

run_to_block(
frame_system::Pallet::<Test>::block_number()
+ <Test as Config>::MilestoneVotingWindow::get(),
);

assert!(!ProjectInVoting::<Test>::contains_key(project_key, 0));
})
}

#[test]
fn project_in_voting_is_removed_on_milestone_autofinalisation() {
build_test_externality().execute_with(|| {
let cont = get_contributions::<Test>(vec![BOB], 100_000);
let prop_milestones = get_milestones(10);
let project_key =
create_and_fund_project::<Test>(ALICE, cont, prop_milestones, CurrencyId::Native)
.unwrap();

assert_ok!(Proposals::submit_milestone(
RuntimeOrigin::signed(ALICE),
project_key,
0
));
assert!(ProjectInVoting::<Test>::contains_key(project_key, 0));
assert_ok!(Proposals::vote_on_milestone(
RuntimeOrigin::signed(BOB),
project_key,
0,
true
));
assert!(!ProjectInVoting::<Test>::contains_key(project_key, 0));
})
}
4 changes: 2 additions & 2 deletions pallets/proposals/src/tests/refunds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ fn refund_check_refund_amount() {
let charlie_pre_creation =
<Test as Config>::MultiCurrency::free_balance(CurrencyId::Native, &CHARLIE);
let per_contribution = 100000u128;
let contributions = get_contributions::<Test>(vec![BOB, CHARLIE], per_contribution as u128);
let contributions = get_contributions::<Test>(vec![BOB, CHARLIE], per_contribution);
let milestones = get_milestones(10);
let project_key = create_and_fund_project::<Test>(
ALICE,
Expand Down Expand Up @@ -331,7 +331,7 @@ fn refund_takes_imbue_fee() {
);
let per_contribution = 500000u128;

let contributions = get_contributions::<Test>(vec![BOB, CHARLIE], per_contribution as u128);
let contributions = get_contributions::<Test>(vec![BOB, CHARLIE], per_contribution);
let milestones = get_milestones(10);
let project_key = create_and_fund_project::<Test>(
ALICE,
Expand Down
29 changes: 0 additions & 29 deletions pallets/proposals/src/todo

This file was deleted.

36 changes: 26 additions & 10 deletions runtime/imbue-kusama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1208,15 +1208,31 @@ impl_runtime_apis! {
ImbueProposals::project_account_id(project_id)
}

/// (Project<T>, ImmutableindividualVotes<T>)
fn get_all_project_data(project_key: u32) -> Option<(Vec<u8>, Vec<u8>)> {
use pallet_proposals::{Project, Projects, ImmutableIndividualVotes, IndividualVoteStore};

if let Some(project) = Projects::<Runtime>::get(project_key) {
IndividualVoteStore::<Runtime>::get(project_key).map(|individual_votes| (<Project<Runtime> as Encode>::encode(&project), <ImmutableIndividualVotes<Runtime> as Encode>::encode(&individual_votes)))
} else {
None
}
/// (Project<T>, ImmutableindividualVotes<T>, DisputeVotes<T>, MilestonesInVotingRound)
fn get_all_project_data(project_key: u32) -> (Option<Vec<u8>>, Option<Vec<u8>>, Option<Vec<u8>>, Vec<u32>) {
use pallet_proposals::{Project, Projects, ImmutableIndividualVotes, IndividualVoteStore, ProjectInVoting, MilestoneKey};
use pallet_disputes::{Disputes, DisputeVotes, BoundedVotes};

let project_encoded = Projects::<Runtime>::get(project_key).map(|p| <Project<Runtime> as Encode>::encode(&p));

let project_votes_encoded = IndividualVoteStore::<Runtime>::get(project_key).map(|i| <ImmutableIndividualVotes<Runtime> as Encode>::encode(&i));

let dispute_votes_encoded = match Disputes::<Runtime>::get(project_key) {
Some(d) => {
let dispute_votes: DisputeVotes<BoundedVotes<Runtime>> = DisputeVotes {
votes: d.votes
};
Some(<DisputeVotes<BoundedVotes<Runtime>> as Encode>::encode(&dispute_votes))
},
None => {None}
};

let milestones_in_voting = ProjectInVoting::<Runtime>::iter_prefix(project_key).map(|(milestone_key, _)|{
milestone_key
}).collect::<Vec<MilestoneKey>>();


(project_encoded, project_votes_encoded, dispute_votes_encoded, milestones_in_voting)
}
}

Expand Down Expand Up @@ -1325,7 +1341,7 @@ impl<T: pallet_fellowship::Config> pallet_fellowship::traits::SelectJury<Account
if index < keys.len() {
let key = &keys[index];
// Here weve gone in a circle! break.
if out.contains(&key) {
if out.contains(key) {
break;
}
if let Err(_) = out.try_push(key.clone()) {
Expand Down
4 changes: 2 additions & 2 deletions runtime/integration-tests/src/xcm_transfers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ use pallet_proposals::traits::ExternalRefundHandler;
#[test]
fn transfer_treasury_to_parachain_grant_escrow_address() {
let transfer_amount: Balance = ksm_amount(1);
let treasury_origin = TreasuryOrigin::Kusama;
let _treasury_origin = TreasuryOrigin::Kusama;
let kusama_treasury_address: AccountId = PalletId(*b"py/trsry").into_account_truncating();

Development::execute_with(|| {
Expand Down Expand Up @@ -133,7 +133,7 @@ fn transfer_ksm_to_relay_chain() {

#[test]
fn test_xcm_refund_handler_to_kusama() {
let treasury_origin = TreasuryOrigin::Kusama;
let _treasury_origin = TreasuryOrigin::Kusama;
let kusama_treasury_address: AccountId = PalletId(*b"py/trsry").into_account_truncating();
let _kusama_treasury_balance_before =
Kusama::account_data_of(kusama_treasury_address.clone()).free;
Expand Down

0 comments on commit 505f922

Please sign in to comment.