From 73af1b5ffc04cf50fe97149e303d8028128f211a Mon Sep 17 00:00:00 2001 From: Edwin Date: Wed, 6 Sep 2023 10:58:02 +0800 Subject: [PATCH] Vtoken voting test (#1031) * More tests * More tests * Rename `DelegatorTokenUnlockNotified` to `DelegatorVoteRemovedNotified` * Fix * More tests * More tests --- pallets/vtoken-voting/src/lib.rs | 11 +- pallets/vtoken-voting/src/mock.rs | 24 +- pallets/vtoken-voting/src/tests.rs | 383 ++++++++++++++++++++++++++++- 3 files changed, 404 insertions(+), 14 deletions(-) diff --git a/pallets/vtoken-voting/src/lib.rs b/pallets/vtoken-voting/src/lib.rs index 8a09d8173..0e9835054 100644 --- a/pallets/vtoken-voting/src/lib.rs +++ b/pallets/vtoken-voting/src/lib.rs @@ -175,7 +175,7 @@ pub mod pallet { poll_index: PollIndex, success: bool, }, - DelegatorTokenUnlockNotified { + DelegatorVoteRemovedNotified { vtoken: CurrencyIdOf, poll_index: PollIndex, success: bool, @@ -696,7 +696,7 @@ pub mod pallet { }, )?; } - Self::deposit_event(Event::::DelegatorTokenUnlockNotified { + Self::deposit_event(Event::::DelegatorVoteRemovedNotified { vtoken, poll_index, success, @@ -977,9 +977,14 @@ pub mod pallet { Some(ReferendumInfo::Completed(moment)) => { let locking_period = VoteLockingPeriod::::get(vtoken).ok_or(Error::::NoData)?; + ensure!( + T::RelaychainBlockNumberProvider::current_block_number() >= + moment.saturating_add(locking_period), + Error::::NotExpired + ); Ok(moment.saturating_add(locking_period)) }, - _ => Err(Error::::NotCompleted.into()), + _ => Err(Error::::NotExpired.into()), } } diff --git a/pallets/vtoken-voting/src/mock.rs b/pallets/vtoken-voting/src/mock.rs index c0100b08b..cef7c8516 100644 --- a/pallets/vtoken-voting/src/mock.rs +++ b/pallets/vtoken-voting/src/mock.rs @@ -39,7 +39,7 @@ use pallet_xcm::EnsureResponse; use sp_core::H256; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, ConstU32, IdentityLookup}, + traits::{BlakeTwo256, BlockNumberProvider, ConstU32, IdentityLookup}, }; use xcm::{prelude::*, v3::Weight as XcmWeight}; use xcm_builder::FixedWeightBounds; @@ -274,6 +274,26 @@ impl DerivativeAccountHandler for DerivativeAccount { } } +parameter_types! { + pub static RelaychainBlockNumber: BlockNumber = 1; +} + +pub struct RelaychainDataProvider; + +impl RelaychainDataProvider { + pub fn set_block_number(block: BlockNumber) { + RelaychainBlockNumber::set(block); + } +} + +impl BlockNumberProvider for RelaychainDataProvider { + type BlockNumber = BlockNumber; + + fn current_block_number() -> Self::BlockNumber { + RelaychainBlockNumber::get() + } +} + impl vtoken_voting::Config for Runtime { type RuntimeEvent = RuntimeEvent; type RuntimeOrigin = RuntimeOrigin; @@ -283,7 +303,7 @@ impl vtoken_voting::Config for Runtime { type ResponseOrigin = EnsureResponse; type XcmDestWeightAndFee = XcmDestWeightAndFee; type DerivativeAccount = DerivativeAccount; - type RelaychainBlockNumberProvider = System; + type RelaychainBlockNumberProvider = RelaychainDataProvider; type MaxVotes = ConstU32<3>; type ParachainId = ParachainId; type QueryTimeout = QueryTimeout; diff --git a/pallets/vtoken-voting/src/tests.rs b/pallets/vtoken-voting/src/tests.rs index 4ff5444d7..109e81998 100644 --- a/pallets/vtoken-voting/src/tests.rs +++ b/pallets/vtoken-voting/src/tests.rs @@ -71,6 +71,10 @@ fn response_success() -> Response { Response::DispatchResult(MaybeErrorCode::Success) } +fn response_fail() -> Response { + Response::DispatchResult(MaybeErrorCode::Error(BoundedVec::try_from(vec![0u8, 1u8]).unwrap())) +} + #[test] fn basic_voting_works() { new_test_ext().execute_with(|| { @@ -412,7 +416,7 @@ fn lock_amalgamation_valid_with_multiple_removed_votes() { } #[test] -fn errors_with_vote_work() { +fn errors_with_vote_works() { new_test_ext().execute_with(|| { let vtoken = VKSM; @@ -435,13 +439,213 @@ fn errors_with_vote_work() { }); } +#[test] +fn kill_referendum_works() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let poll_index = 3; + + assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(5, 1))); + assert_ok!(VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + ReferendumInfoOf::::Completed(1), + )); + assert_ok!(VtokenVoting::kill_referendum( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index + )); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ReferendumKilled { + vtoken, + poll_index, + })); + }); +} + +#[test] +fn kill_referendum_with_origin_signed_fails() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let poll_index = 3; + + assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(5, 1))); + assert_ok!(VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + ReferendumInfoOf::::Completed(1), + )); + assert_noop!( + VtokenVoting::kill_referendum(RuntimeOrigin::signed(ALICE), vtoken, poll_index), + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn set_delegator_role_works() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let derivative_index: DerivativeIndex = 100; + let role = aye(10, 3).into(); + + assert_ok!(VtokenVoting::set_delegator_role( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + derivative_index, + role, + )); + + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::DelegatorRoleSet { + vtoken, + role, + derivative_index, + })); + }); +} + +#[test] +fn set_referendum_status_works() { + new_test_ext().execute_with(|| { + let poll_index = 3; + let vtoken = VKSM; + let info = ReferendumInfo::Completed(3); + + assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); + assert_ok!(VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + info.clone(), + )); + + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ReferendumInfoSet { + vtoken, + poll_index, + info, + })); + }); +} + +#[test] +fn set_referendum_status_without_vote_should_fail() { + new_test_ext().execute_with(|| { + let poll_index = 3; + let vtoken = VKSM; + let info = ReferendumInfo::Completed(3); + + assert_noop!( + VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + info.clone(), + ), + Error::::NoData + ); + }); +} + +#[test] +fn set_referendum_status_with_origin_signed_should_fail() { + new_test_ext().execute_with(|| { + let poll_index = 3; + let vtoken = VKSM; + let info = ReferendumInfo::Completed(3); + + assert_noop!( + VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(ALICE), + vtoken, + poll_index, + info.clone(), + ), + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn set_vote_locking_period_works() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let locking_period = 100; + + assert_ok!(VtokenVoting::set_vote_locking_period( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + locking_period, + )); + + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::VoteLockingPeriodSet { + vtoken, + locking_period, + })); + }); +} + +#[test] +fn set_vote_locking_period_with_origin_signed_should_fail() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let locking_period = 100; + + assert_noop!( + VtokenVoting::set_vote_locking_period( + RuntimeOrigin::signed(ALICE), + vtoken, + locking_period, + ), + DispatchError::BadOrigin + ); + }); +} + +#[test] +fn set_undeciding_timeout_works() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let undeciding_timeout = 100; + + assert_ok!(VtokenVoting::set_undeciding_timeout( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + undeciding_timeout, + )); + + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::UndecidingTimeoutSet { + vtoken, + undeciding_timeout, + })); + }); +} + +#[test] +fn set_undeciding_timeout_with_origin_signed_should_fail() { + new_test_ext().execute_with(|| { + let vtoken = VKSM; + let undeciding_timeout = 100; + + assert_noop!( + VtokenVoting::set_undeciding_timeout( + RuntimeOrigin::signed(ALICE), + vtoken, + undeciding_timeout, + ), + DispatchError::BadOrigin + ); + }); +} + #[test] fn notify_vote_success_works() { new_test_ext().execute_with(|| { let poll_index = 3; let vtoken = VKSM; let query_id = 0; - let response = Response::DispatchResult(MaybeErrorCode::Success); + let response = response_success(); assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); assert_eq!(tally(vtoken, poll_index), Tally::from_parts(10, 0, 2)); @@ -452,7 +656,25 @@ fn notify_vote_success_works() { vote: aye(2, 5), })); - assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response)); + assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response.clone())); + System::assert_has_event(RuntimeEvent::VtokenVoting(Event::VoteNotified { + vtoken, + poll_index, + success: true, + })); + System::assert_has_event(RuntimeEvent::VtokenVoting(Event::ReferendumInfoCreated { + vtoken, + poll_index, + info: ReferendumInfo::Ongoing(ReferendumStatus { + submitted: Some(1), + tally: TallyOf::::from_parts(10, 0, 2), + }), + })); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); }); } @@ -462,9 +684,7 @@ fn notify_vote_fail_works() { let poll_index = 3; let vtoken = VKSM; let query_id = 0; - let response = Response::DispatchResult(MaybeErrorCode::Error( - BoundedVec::try_from(vec![0u8, 1u8]).unwrap(), - )); + let response = response_fail(); assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); assert_eq!(tally(vtoken, poll_index), Tally::from_parts(10, 0, 2)); @@ -475,7 +695,17 @@ fn notify_vote_fail_works() { vote: aye(2, 5), })); - assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response)); + assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response.clone())); + System::assert_has_event(RuntimeEvent::VtokenVoting(Event::VoteNotified { + vtoken, + poll_index, + success: false, + })); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); }); } @@ -483,8 +713,143 @@ fn notify_vote_fail_works() { fn notify_vote_with_no_data_works() { new_test_ext().execute_with(|| { let query_id = 0; - let response = Response::DispatchResult(MaybeErrorCode::Success); + let response = response_success(); + + assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response.clone())); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); + }); +} + +#[test] +fn notify_remove_delegator_vote_success_works() { + new_test_ext().execute_with(|| { + let poll_index = 3; + let vtoken = VKSM; + let mut query_id = 0; + let derivative_index = 3; + let response = response_success(); - assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response)); + assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); + assert_eq!(tally(vtoken, poll_index), Tally::from_parts(10, 0, 2)); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::Voted { + who: ALICE, + vtoken, + poll_index, + vote: aye(2, 5), + })); + assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response.clone())); + + assert_ok!(VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + ReferendumInfoOf::::Completed(3), + )); + assert_ok!(VtokenVoting::set_vote_locking_period( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + 10, + )); + + RelaychainDataProvider::set_block_number(15); + assert_ok!(VtokenVoting::remove_delegator_vote( + RuntimeOrigin::signed(ALICE), + vtoken, + poll_index, + derivative_index, + )); + + query_id = 1; + assert_ok!(VtokenVoting::notify_remove_delegator_vote( + origin_response(), + query_id, + response.clone() + )); + System::assert_has_event(RuntimeEvent::VtokenVoting(Event::DelegatorVoteRemovedNotified { + vtoken, + poll_index, + success: true, + })); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); + }); +} + +#[test] +fn notify_remove_delegator_vote_fail_works() { + new_test_ext().execute_with(|| { + let poll_index = 3; + let vtoken = VKSM; + let mut query_id = 0; + let derivative_index = 3; + let response = response_fail(); + + assert_ok!(VtokenVoting::vote(RuntimeOrigin::signed(ALICE), vtoken, poll_index, aye(2, 5))); + assert_eq!(tally(vtoken, poll_index), Tally::from_parts(10, 0, 2)); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::Voted { + who: ALICE, + vtoken, + poll_index, + vote: aye(2, 5), + })); + assert_ok!(VtokenVoting::notify_vote(origin_response(), query_id, response_success())); + + assert_ok!(VtokenVoting::set_referendum_status( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + poll_index, + ReferendumInfoOf::::Completed(3), + )); + assert_ok!(VtokenVoting::set_vote_locking_period( + RuntimeOrigin::signed(CONTROLLER), + vtoken, + 10, + )); + + RelaychainDataProvider::set_block_number(15); + assert_ok!(VtokenVoting::remove_delegator_vote( + RuntimeOrigin::signed(ALICE), + vtoken, + poll_index, + derivative_index, + )); + + query_id = 1; + assert_ok!(VtokenVoting::notify_remove_delegator_vote( + origin_response(), + query_id, + response.clone() + )); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); + }); +} + +#[test] +fn notify_remove_delegator_vote_with_no_data_works() { + new_test_ext().execute_with(|| { + let query_id = 0; + let response = response_success(); + + assert_ok!(VtokenVoting::notify_remove_delegator_vote( + origin_response(), + query_id, + response.clone(), + )); + System::assert_last_event(RuntimeEvent::VtokenVoting(Event::ResponseReceived { + responder: Parent.into(), + query_id, + response, + })); }); }