diff --git a/src/protocol-democracy.md b/src/protocol-democracy.md index 3eba018..b5c2af4 100644 --- a/src/protocol-democracy.md +++ b/src/protocol-democracy.md @@ -1,8 +1,8 @@ # Democracy -> *this feature is work in progress and not yet released. See [Governance](./decentralization-governance.md) to learn how it currently works* +> _this feature is work in progress and not yet released. See [Governance](./decentralization-governance.md) to learn how it currently works_ -The democracy module will bring decentralized governance to Encointer facilitating participants to take decisions. Such a **universal human suffrage** (one person one vote) governance shall render the current Encointer council obsolete. Examples of such decisions are the addition of new meetup locations to a community, an adjustment of the Demurrage rate or changes in the ceremony schdeule. +The democracy module will bring decentralized governance to Encointer facilitating participants to take decisions. Such a **universal human suffrage** (one person one vote) governance shall render the current Encointer council obsolete. Examples of such decisions are the addition of new meetup locations to a community, an adjustment of the Demurrage rate or changes in the ceremony schdeule. The decision making process should follow the subsidiarity principle, meaning that decisions should be taken on the lowest possible level. So for example, if a community wants to extend their region by adding some new meetup locations, only community members should be allowed to participate in the vote. @@ -18,49 +18,51 @@ Changes to the Encointer protocol are out of scope because they need to be decid These actions can only be decided upon by the quorum of all encointer communities globally -* Adjust ceremony schedule (can be adjusted anytime) - * [`next_phase`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/scheduler/src/lib.rs#L151): force progress to next ceremony phase - * [`push_by_one_day`](push_by_one_day): postpone next phase change by one day push_by_one_day - * [`set_phase_duration`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/scheduler/src/lib.rs#L173): adjust ceremony schedule phase durations - * [`set_next_phase_timestamp`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/scheduler/src/lib.rs#L184): arbitrarily define the time for next phase change -* Manage communities (can only be enacted during *Registering* phase) - * [`new_community`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L76): Register new communities - * [`purge_community`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L299): well... -* Manage Ceremony Parameters (may only make sense to enact during *Registering* phase) - * [`set_min_solar_trip_time_s`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L279): security parameter to calculate minimal location distance - * [`set_max_speed_mps`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L289): security parameter defining the maximal speed over ground of an adversary - * [`set_inactivity_timeout`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/ceremonies/src/lib.rs#L386): define how many ceremonies a community can be idle before getting purged - * [`set_endorsement_tickets_per_bootstrapper`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/ceremonies/src/lib.rs#L396): define how many endorsement tickets bootstrappers should get to invite people they trust - * [`set_reputation_lifetime`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/ceremonies/src/lib.rs#L396): define how long proof-of-personhood reputation is valid for and stored - * [`set_meetup_time_offset`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/ceremonies/src/lib.rs#L396): finetune meetup time difference to high sun -* Decide on Treasury Proposals +- Adjust ceremony schedule (can be adjusted anytime) + - [`next_phase`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/scheduler/src/lib.rs#L151): force progress to next ceremony phase + - [`push_by_one_day`](push_by_one_day): postpone next phase change by one day push_by_one_day + - [`set_phase_duration`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/scheduler/src/lib.rs#L173): adjust ceremony schedule phase durations + - [`set_next_phase_timestamp`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/scheduler/src/lib.rs#L184): arbitrarily define the time for next phase change +- Manage communities (can only be enacted during _Registering_ phase) + - [`new_community`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L76): Register new communities + - [`purge_community`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L299): well... +- Manage Ceremony Parameters (may only make sense to enact during _Registering_ phase) + - [`set_min_solar_trip_time_s`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L279): security parameter to calculate minimal location distance + - [`set_max_speed_mps`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L289): security parameter defining the maximal speed over ground of an adversary + - [`set_inactivity_timeout`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/ceremonies/src/lib.rs#L386): define how many ceremonies a community can be idle before getting purged + - [`set_endorsement_tickets_per_bootstrapper`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/ceremonies/src/lib.rs#L396): define how many endorsement tickets bootstrappers should get to invite people they trust + - [`set_reputation_lifetime`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/ceremonies/src/lib.rs#L396): define how long proof-of-personhood reputation is valid for and stored + - [`set_meetup_time_offset`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/ceremonies/src/lib.rs#L396): finetune meetup time difference to high sun +- Decide on Treasury Proposals ### Community Actions These actions can be decided per community for themselves -Only to be changed during *Registering* phase - * [`add_location`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L143): add meetup location for community - * [`remove_location`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L189): remove meetup location for community - * [`update_nominal_income`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L258): the amount of basic income per ceremony per person per community +Only to be changed during _Registering_ phase + +- [`add_location`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L143): add meetup location for community +- [`remove_location`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L189): remove meetup location for community +- [`update_nominal_income`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L258): the amount of basic income per ceremony per person per community Not strictly related to a particular ceremony phase. could be adjusted anytime. - * [`update_community_metadata`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L214): change name, currency, artwork IPFS cid for community - * [`update_demurrage`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L238): change how fast balances are demurraged per community + +- [`update_community_metadata`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L214): change name, currency, artwork IPFS cid for community +- [`update_demurrage`](https://github.com/encointer/pallets/blob/91cbd7c9c0d47c4a80c096d3b2b501625a6bb724/communities/src/lib.rs#L238): change how fast balances are demurraged per community ## Proposals -There is a set of predefined proposal *actions* that can be voted on (ie. set basic income to XY) +There is a set of predefined proposal _actions_ that can be voted on (ie. set basic income to XY) -Everyone can start a proposal on an *action* (ie. set basic income to 48 LEU) +Everyone can start a proposal on an _action_ (ie. set basic income to 48 LEU) -Every member of the community can use their reputation to vote on a proposal (the more reputation, the more voting power. Capped at *reputation_lifetime*) +Every member of the community can use their reputation to vote on a proposal (the more reputation, the more voting power. Capped at _reputation_lifetime_) A proposal gets approved if it is in a passing state (enough aye votes) for a long enough time period (confirmation period) There can be multiple proposals up for vote simultaneously, even on the same action -When a proposal gets approved, all other proposals on the same *action* get cancelled, to avoid conflicts +When a proposal gets approved, all other proposals on the same _action_ get cancelled, to avoid conflicts When a proposal A gets approved, its enactment will be scheduled to the beginning of the next ceremony cycle. Should another proposal B get approved after proposal A’s approval but before it’s enactment, proposal B will be scheduled for enactment and proposal A will be cancelled. @@ -72,13 +74,13 @@ The following examples will describe examples of how proposals change their stat Let -* Confirmation Period = 3 units, -* Proposal Lifetime = 12 units, -* X/Y denote X aye votes and Y total votes, -* O = Ongoing, -* C = Confirming, -* A = Approved, -* X = Cancelled. +- Confirmation Period = 3 units, +- Proposal Lifetime = 12 units, +- X/Y denote X aye votes and Y total votes, +- O = Ongoing, +- C = Confirming, +- A = Approved, +- X = Cancelled. For the sake of simplicity, we assume that just a simple majority is needed for a proposal to pass and there is no minimum vote required. @@ -98,3 +100,5 @@ If we want to relax this in the future, we would need to come up with a way to h In order to determine if a vote is passing, we use Positive Turnout Bias. In addition we enforce a minimum turnout of 5%. +### Tutorial +For a tutorial of the democracy module, please see the [Democracy Tutorial](./tutorials-democracy.md) \ No newline at end of file diff --git a/src/tutorials-democracy.md b/src/tutorials-democracy.md new file mode 100644 index 0000000..fcd425c --- /dev/null +++ b/src/tutorials-democracy.md @@ -0,0 +1,159 @@ +### Democracy Tutorial + +In this tutorial, we show a basic flow for two proposals in the democracy module using the CLI. On proposal will be approved and the other one will be rejected. + +Go to the encointer-node repo and open 2 terminals: + +Terminal 1: + +``` +git clone https://github.com/encointer/encointer-node.git +cd encointer-node && git fetch && git checkout origin/personhood-democracy-1-delivery +cd .. +git clone https://github.com/encointer/pallets.git +mv pallets/ encointer-pallets +cd encointer-pallets && git fetch && git checkout origin/polkadot-v1.0.0-pallets-v1.3.0-democracy +cd ../encointer-node + +cargo build --release +./target/release/encointer-node-notee --dev --enable-offchain-indexing true -lencointer=debug,parity_ws=warn +``` + +Terminal 2: + +``` +cd client +python -m venv env +source env/bin.activate +pip install requirements.txt +python bootstrap_demo_community.py +``` + +Continuing in Terminal 2, we first move to the start of the next cycle, in order for the reputations of the last cycle to become eligible for voting: + +``` +../target/release/encointer-client-notee next-phase +../target/release/encointer-client-notee next-phase +../target/release/encointer-client-notee next-phase +../target/release/encointer-client-notee listen -b 1 +``` + +After that, we submit two porposals for voting: + +``` +# Submitting proposal id 1, SetInactivityTimeout(8) +../target/release/encointer-client-notee submit-set-inactivity-timeout-proposal //Alice 8 +../target/release/encointer-client-notee listen -b 1 +# Submitting proposal id 2, UpdateNominalIncome(cid, 44) +../target/release/encointer-client-notee --cid sqm1v79dF6b submit-update-nominal-income-proposal //Alice 44 +``` + +We wait for the extrinsics to be in a block and list the proposals: + +``` +../target/release/encointer-client-notee listen -b 1 +../target/release/encointer-client-notee list-proposals +``` + +We expect to see the following output: + +``` +id: 1 +state: ProposalState::Ongoing +action: ProposalAction::SetInactivityTimeout(8) +start time: 1704685908002 +start cindex: 3 +electorate size: 3 +turnout: 0 +ayes: 0 +id: 2 +state: ProposalState::Ongoing +action: ProposalAction::UpdateNominalIncome(sqm1v79dF6b, 44) +start time: 1704685920000 +start cindex: 3 +electorate size: 3 +turnout: 0 +ayes: 0 +``` + +As an exmaple we show that Alice has 1 reputation and therefore a voting power of 1: +``` +../target/release/encointer-client-notee reputation //Alice +``` +which will yield: +``` +1, sqm1v79dF6b, Reputation::VerifiedUnlinked +``` +The same will hold for Bob and Charlie. + + +Then, we let the users vote for the porposals: + +``` +# Alice votes aye for proposal 1 +../target/release/encointer-client-notee vote //Alice 1 aye sqm1v79dF6b_1 +# Alice votes again aye for proposal 1, this vote will not count as she has already voted +../target/release/encointer-client-notee vote //Alice 1 aye sqm1v79dF6b_1 +# Bob votes aye for proposal 1 +../target/release/encointer-client-notee vote //Bob 1 aye sqm1v79dF6b_1 +# Charlie votes aye for proposal 1 +../target/release/encointer-client-notee vote //Charlie 1 aye sqm1v79dF6b_1 +# Alice votes nay for proposal 2 +../target/release/encointer-client-notee vote //Alice 2 nay sqm1v79dF6b_1 +# Bob votes nay for proposal 2 +../target/release/encointer-client-notee vote //Bob 2 nay sqm1v79dF6b_1 +# Charlie votes aye for proposal 2 +../target/release/encointer-client-notee vote //Charlie 2 aye sqm1v79dF6b_1 +``` + +Now, we wait for 5 blocks, as out confirmation period is 10 blocks and we already waited 6 blocks during voting: + +``` +../target/release/encointer-client-notee listen -b 5 +``` + +Now, we need to update the proposal state and check again the proposals and the enactment queue: + +``` +# Alice updates proposal state of proposal 1 +../target/release/encointer-client-notee update-proposal-state //Alice 1 +../target/release/encointer-client-notee list-proposals +../target/release/encointer-client-notee list-enactment-queue +``` + +For the proposals, we expect proposal 1 to be Approved: + +``` +id: 1 +state: ProposalState::Approved +action: ProposalAction::SetInactivityTimeout(8) +start time: 1704685908002 +start cindex: 3 +electorate size: 3 +turnout: 3 +ayes: 3 +id: 2 +state: ProposalState::Ongoing +action: ProposalAction::UpdateNominalIncome(sqm1v79dF6b, 44) +start time: 1704685920000 +start cindex: 3 +electorate size: 3 +turnout: 3 +ayes: 1 +``` + +And proposal 1 should be in the enactment queue, which means that it is scheduled for enactment at the start of the next cycle: + +``` +1 +``` + +We wait for another 10 blocks, such that the proposal lifetime of 20 blocks for proposal 2 elapses and we expect proposal 2 to be cancelled: + +``` +# Waiting 10 blocks... +../target/release/encointer-client-notee listen -b 10 +# Alice updates proposal state of proposal 2 +../target/release/encointer-client-notee update-proposal-state //Alice 2 +../target/release/encointer-client-notee list-proposals +``` \ No newline at end of file