Browse Source

Add veto for the pending execution proposal.

Shamil Gadelshin 5 years ago
parent
commit
b67925747f

+ 0 - 1
runtime-modules/proposals/codex/src/tests/mock.rs

@@ -247,7 +247,6 @@ impl staking::SessionInterface<u64> for Test {
 }
 
 impl crate::Trait for Test {
-    type SetValidatorCountProposalMinValidators = SetValidatorCountProposalMinValidators;
     type TextProposalMaxLength = TextProposalMaxLength;
     type RuntimeUpgradeWasmProposalMaxLength = RuntimeUpgradeWasmProposalMaxLength;
     type RuntimeUpgradeProposalAllowedProposers = RuntimeUpgradeProposalAllowedProposers;

+ 5 - 0
runtime-modules/proposals/codex/src/tests/mod.rs

@@ -828,6 +828,11 @@ fn assert_failed_set_storage_parameters_call(
 #[test]
 fn create_set_storage_role_parameters_proposal_fails_with_invalid_parameters() {
     initial_test_ext().execute_with(|| {
+        // {
+        //     let _imbalance = <Test as stake::Trait>::Currency::deposit_creating(&44, 50000);
+        // }
+        // assert_eq!(Balances::total_issuance(), 0);
+
         let mut role_parameters = RoleParameters::default();
         role_parameters.min_actors = 0;
         assert_failed_set_storage_parameters_call(

+ 27 - 3
runtime-modules/proposals/engine/src/lib.rs

@@ -279,11 +279,14 @@ decl_module! {
             ensure!(<Proposals<T>>::exists(proposal_id), Error::ProposalNotFound);
             let proposal = Self::proposals(proposal_id);
 
-            ensure!(matches!(proposal.status, ProposalStatus::Active{..}), Error::ProposalFinalized);
-
             // mutation
 
-            Self::finalize_proposal(proposal_id, ProposalDecisionStatus::Vetoed);
+            if <PendingExecutionProposalIds<T>>::exists(proposal_id) {
+                Self::veto_pending_execution_proposal(proposal_id, proposal);
+            } else {
+                ensure!(matches!(proposal.status, ProposalStatus::Active{..}), Error::ProposalFinalized);
+                Self::finalize_proposal(proposal_id, ProposalDecisionStatus::Vetoed);
+            }
         }
 
         /// Block finalization. Perform voting period check, vote result tally, approved proposals
@@ -510,6 +513,27 @@ impl<T: Trait> Module<T> {
             .collect() // compose output vector
     }
 
+    // Veto approved proposal during its grace period. Saves a new proposal status and removes
+    // proposal id from the 'PendingExecutionProposalIds'
+    fn veto_pending_execution_proposal(proposal_id: T::ProposalId, proposal: ProposalOf<T>) {
+        <PendingExecutionProposalIds<T>>::remove(proposal_id);
+
+        let vetoed_proposal_status = ProposalStatus::finalized(
+            ProposalDecisionStatus::Vetoed,
+            None,
+            None,
+            Self::current_block(),
+        );
+
+        <Proposals<T>>::insert(
+            proposal_id,
+            Proposal {
+                status: vetoed_proposal_status,
+                ..proposal
+            },
+        );
+    }
+
     // Executes approved proposal code
     fn execute_proposal(approved_proposal: ApprovedProposal<T>) {
         let proposal_code = Self::proposal_codes(approved_proposal.proposal_id);

+ 113 - 0
runtime-modules/proposals/engine/src/tests/mod.rs

@@ -819,6 +819,119 @@ fn proposal_execution_postponed_because_of_grace_period() {
     });
 }
 
+/*
+
+#[test]
+fn veto_proposal_succeeds() {
+    initial_test_ext().execute_with(|| {
+        // internal active proposal counter check
+        assert_eq!(<ActiveProposalCount>::get(), 0);
+
+        let parameters_fixture = ProposalParametersFixture::default();
+        let dummy_proposal =
+            DummyProposalFixture::default().with_parameters(parameters_fixture.params());
+        let proposal_id = dummy_proposal.create_proposal_and_assert(Ok(1)).unwrap();
+
+        // internal active proposal counter check
+        assert_eq!(<ActiveProposalCount>::get(), 1);
+
+        let veto_proposal = VetoProposalFixture::new(proposal_id);
+        veto_proposal.veto_and_assert(Ok(()));
+
+        let proposal = <crate::Proposals<Test>>::get(proposal_id);
+
+        assert_eq!(
+            proposal,
+            Proposal {
+                parameters: parameters_fixture.params(),
+                proposer_id: 1,
+                created_at: 1,
+                status: ProposalStatus::finalized_successfully(ProposalDecisionStatus::Vetoed, 1),
+                title: b"title".to_vec(),
+                description: b"description".to_vec(),
+                voting_results: VotingResults::default(),
+            }
+        );
+
+        // internal active proposal counter check
+        assert_eq!(<ActiveProposalCount>::get(), 0);
+    });
+}
+*/
+
+#[test]
+fn proposal_execution_vetoed_successfully_during_the_grace_period() {
+    initial_test_ext().execute_with(|| {
+        let parameters_fixture = ProposalParametersFixture::default().with_grace_period(2);
+        let dummy_proposal =
+            DummyProposalFixture::default().with_parameters(parameters_fixture.params());
+
+        let proposal_id = dummy_proposal.create_proposal_and_assert(Ok(1)).unwrap();
+
+        let mut vote_generator = VoteGenerator::new(proposal_id);
+        vote_generator.vote_and_assert_ok(VoteKind::Approve);
+        vote_generator.vote_and_assert_ok(VoteKind::Approve);
+        vote_generator.vote_and_assert_ok(VoteKind::Approve);
+        vote_generator.vote_and_assert_ok(VoteKind::Approve);
+
+        run_to_block_and_finalize(1);
+        run_to_block_and_finalize(2);
+
+        // check internal cache for proposal_id presense
+        assert!(<PendingExecutionProposalIds<Test>>::enumerate()
+            .find(|(x, _)| *x == proposal_id)
+            .is_some());
+
+        let proposal = <crate::Proposals<Test>>::get(proposal_id);
+
+        assert_eq!(
+            proposal,
+            Proposal {
+                parameters: parameters_fixture.params(),
+                proposer_id: 1,
+                created_at: 1,
+                status: ProposalStatus::approved(ApprovedProposalStatus::PendingExecution, 1),
+                title: b"title".to_vec(),
+                description: b"description".to_vec(),
+                voting_results: VotingResults {
+                    abstentions: 0,
+                    approvals: 4,
+                    rejections: 0,
+                    slashes: 0,
+                },
+            }
+        );
+
+        let veto_proposal = VetoProposalFixture::new(proposal_id);
+        veto_proposal.veto_and_assert(Ok(()));
+
+        let proposal = <crate::Proposals<Test>>::get(proposal_id);
+
+        assert_eq!(
+            proposal,
+            Proposal {
+                parameters: parameters_fixture.params(),
+                proposer_id: 1,
+                created_at: 1,
+                status: ProposalStatus::finalized_successfully(ProposalDecisionStatus::Vetoed, 2),
+                title: b"title".to_vec(),
+                description: b"description".to_vec(),
+                voting_results: VotingResults {
+                    abstentions: 0,
+                    approvals: 4,
+                    rejections: 0,
+                    slashes: 0,
+                },
+            }
+        );
+
+        // check internal cache for proposal_id presense
+        assert!(<PendingExecutionProposalIds<Test>>::enumerate()
+            .find(|(x, _)| *x == proposal_id)
+            .is_none());
+    });
+}
+
 #[test]
 fn proposal_execution_succeeds_after_the_grace_period() {
     initial_test_ext().execute_with(|| {

+ 0 - 1
runtime/src/lib.rs

@@ -868,7 +868,6 @@ impl proposals_codex::Trait for Runtime {
     type TextProposalMaxLength = TextProposalMaxLength;
     type RuntimeUpgradeWasmProposalMaxLength = RuntimeUpgradeWasmProposalMaxLength;
     type RuntimeUpgradeProposalAllowedProposers = RuntimeUpgradeProposalAllowedProposers;
-    type SetValidatorCountProposalMinValidators = SetValidatorCountProposalMinValidators;
 }
 
 construct_runtime!(