Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

Council motions for approving treasury proposals #694

Merged
merged 10 commits into from
Sep 10, 2018
Merged

Conversation

gavofyork
Copy link
Member

@gavofyork gavofyork commented Sep 8, 2018

Closes #680

  • Repot Permill and add constructors
  • Integrate treasury into demo runtime
  • Introduce EnsureOrigin trait for allowing parameterised origin-guards
  • Introduce system implementations of EnsureOrigin
  • Introduce council Members origin and an according implementation of EnsureOrigin
  • Introduce parameterisable origin guard for treasury
  • Introduce council_motions module that can dispatch from council origin
  • Integrate council_motions into demo runtime.
  • Tests.

@gavofyork gavofyork added the A0-please_review Pull request needs code review. label Sep 8, 2018
#[derive(Encode, Decode, Default, Copy, Clone, PartialEq, Eq)]
pub struct Permill(u32);

// TODO: impl Mul<Permill> for N where N: As<usize>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still todo; not introduced with this PR.

@gavofyork gavofyork changed the title Treasury in runtime, generic approve/reject Council motions for approving treasury proposals Sep 9, 2018
@@ -211,6 +211,12 @@ pub fn run<I, T>(args: I) -> error::Result<()> where
timestamp: Some(TimestampConfig {
period: 5, // 5 second block time.
}),
treasury: Some(TreasuryConfig {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double space


<Proposals<T>>::mutate(|proposals| proposals.push(proposal_hash));
<ProposalOf<T>>::insert(proposal_hash, *proposal);
<Voting<T>>::insert(proposal_hash, (threshold, vec![who.clone()], vec![]));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if threshold is less than 2? Does it makes sense at all?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 is technically fine (just means "one council member").

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, but the condition for the approval is:

let approved = yes_votes >= threshold;

then if threshold=1 then such a proposal should be accepted on creation, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indeed.

return Err("duplicate vote ignored")
}
if let Some(pos) = position_no {
voting.2.remove(pos);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we use swap_remove here and for the disapprove case?

}

let yes_votes = voting.1.len() as u32;
let no_votes = voting.2.len() as u32;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

voting.1 and voting.2 seems a little obscure to me here and above, consider introducing a separate structure.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an extra structure is fiddly to get right when you need to have it generic over an associated type of the configuration trait thanks to serde and compiler bugs.

return Err("duplicate vote ignored")
}
if let Some(pos) = position_yes {
voting.1.remove(pos);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would one want to change his mind?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

they might be female.

ducks :-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heh, but i still wonder if it's strictly necessary.

I'm a bit worried that it might be susceptible to be gamable somehow...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't see how...

Self::deposit_event(RawEvent::Voted(who, proposal, approve, yes_votes, no_votes));

let threshold = voting.0;
let potential_votes = <Council<T>>::active_council().len() as u32;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we care about changing the structure of the council?

As far as I can see, it's possible, but we don't check for that and the code seems to depend on this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you expand on that?
no_votes cannot ever be greater than potential_votes, right?

treasury: Some(TreasuryConfig {
proposal_bond: Permill::from_percent(5),
proposal_bond_minimum: 1_000_000,
spend_period: 12 * 60 * 24,
Copy link
Contributor

@pepyakin pepyakin Sep 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, this looks like a timestamp or something, but it's actually should be a BlockNumber

Copy link
Member Author

@gavofyork gavofyork Sep 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should not be a block number per se but rather a number of blocks for which the type is BlockNumber. in this case, we assume 12 blocks per minute (1 every 5 seconds), multiply by 60 and 24 to get approximately one day.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha, that's clear now!


ensure!(Self::is_councillor(&who), "voter not on council");

let mut voting = Self::voting(&proposal);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider there are two extrinsics that vote for the same proposal. The first one will lead to execution of proposal. What would happen with the second one?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

panic, and indeed, that should just be a bail.


let proposal_hash = T::Hashing::hash_of(&proposal);

ensure!(!<ProposalOf<T>>::exists(proposal_hash), "duplicate proposals not allowed");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that there is a (slight) chance of reusing votes.

Let's say that we have proposal P, 4 active councillors (c0..c3) and the following extrinsics were published:

  1. propose(c0, 2, P)
  2. vote(c1, H(P))
  3. vote(c2, H(P))
  4. vote(c3, H(P))

Now it seems that the 3rd extrinsic will panic, but let's assume that it's fixed by no-oping.

Some rogue councillor c0 can issue propose(c0, 2, P) extrinsic that has a slight chance to be applied before votes from c2 and c3 and thus use these votes for approving the second proposal. This would be more effective, if c0 also act as front-running validator.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i guess i can introduce a proposal index to ensure they're unique.

@gavofyork
Copy link
Member Author

@pepyakin ^^^

/// The actual value represented by the impl'ing type.
const VALUE: u32;
}
/// Type representingn the value 0 for the `Value` trait.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: representingn spelling mistake that repeats for all defintions.

type Event: From<Event<Self>> + Into<<Self as system::Trait>::Event>;
}

/// Origin for the system module.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we update this comment?

@gavofyork
Copy link
Member Author

@pepyakin ^^^

@gavofyork
Copy link
Member Author

@bkchr ^^^

@pepyakin pepyakin added A8-looksgood and removed A0-please_review Pull request needs code review. labels Sep 10, 2018
@gavofyork gavofyork merged commit d307019 into master Sep 10, 2018
@gavofyork gavofyork deleted the gav-council-origin branch September 10, 2018 14:03
liuchengxu pushed a commit to chainx-org/substrate that referenced this pull request Aug 23, 2021
* Add some tests

Signed-off-by: koushiro <[email protected]>

* Add test

Signed-off-by: koushiro <[email protected]>

* Cargo fmt

Signed-off-by: koushiro <[email protected]>

* Replace assert with assert_ok and assert_noop

Signed-off-by: koushiro <[email protected]>

* Cargo fmt

Signed-off-by: koushiro <[email protected]>
helin6 pushed a commit to boolnetwork/substrate that referenced this pull request Jul 25, 2023
* error: `RpcError` with custom client error

Signed-off-by: Alexandru Vasile <[email protected]>

* error: Add `SubscriptionDropped` and panic on param errors

Signed-off-by: Alexandru Vasile <[email protected]>

* Update subxt/src/rpc/rpc_client_t.rs

Co-authored-by: James Wilson <[email protected]>

* Apply rustfmt

Signed-off-by: Alexandru Vasile <[email protected]>

Signed-off-by: Alexandru Vasile <[email protected]>
Co-authored-by: James Wilson <[email protected]>
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants