From 92266a26a42c9fa490383f50b2624a96a0430fa4 Mon Sep 17 00:00:00 2001 From: Alain Brenzikofer Date: Tue, 27 Feb 2024 10:48:28 +0100 Subject: [PATCH] noshow tolerance works --- ceremonies/src/lib.rs | 9 ++--- ceremonies/src/tests.rs | 34 +++++++++++++++---- democracy/src/tests.rs | 66 ++++++++++++++++++------------------ primitives/src/ceremonies.rs | 11 ++++-- primitives/src/scheduler.rs | 11 ------ 5 files changed, 75 insertions(+), 56 deletions(-) diff --git a/ceremonies/src/lib.rs b/ceremonies/src/lib.rs index c95e22fe..e5e81c0d 100644 --- a/ceremonies/src/lib.rs +++ b/ceremonies/src/lib.rs @@ -150,17 +150,18 @@ pub mod pallet { Self::participant_reputation( (p.community_identifier, p.ceremony_index), &p.attendee_public - ) == Reputation::VerifiedUnlinked, + ) + .is_verified_and_unlinked_for_cindex(cindex), Error::::AttendanceUnverifiedOrAlreadyUsed ); ensure!(p.verify_signature(), Error::::BadProofOfAttendanceSignature); - // this reputation must now be burned so it can not be used again + // this reputation must now be flagged so it can not be used again in the same cycle >::insert( (p.community_identifier, p.ceremony_index), &p.attendee_public, - Reputation::VerifiedLinked, + Reputation::VerifiedLinked(cindex), ); // register participant as reputable >::insert( @@ -253,7 +254,7 @@ pub mod pallet { ); ensure!( - Self::participant_reputation(cc, &sender) == Reputation::VerifiedLinked, + Self::participant_reputation(cc, &sender) == Reputation::VerifiedLinked(cindex), Error::::ReputationMustBeLinked ); diff --git a/ceremonies/src/tests.rs b/ceremonies/src/tests.rs index 7e14575d..c28ced0f 100644 --- a/ceremonies/src/tests.rs +++ b/ceremonies/src/tests.rs @@ -1252,7 +1252,7 @@ fn register_with_reputation_works() { ); assert_eq!( EncointerCeremonies::participant_reputation((cid, cindex - 1), account_id(&zoran)), - Reputation::VerifiedLinked + Reputation::VerifiedLinked(cindex) ); // double signing (re-using reputation) fails @@ -1268,6 +1268,28 @@ fn register_with_reputation_works() { register(account_id(&yuri), cid, Some(proof)), Error::::AttendanceUnverifiedOrAlreadyUsed ); + + // tolerate no shows + // no meetup will succeed in this cycle, still we want reputation to be valid for the next cycle + run_to_next_phase(); + run_to_next_phase(); + run_to_next_phase(); + let cindex = EncointerScheduler::current_ceremony_index(); + println!("cindex {cindex}"); + + let proof = prove_attendance(account_id(&zoran_new), cid, cindex - 2, &zoran); + assert_ok!(register(account_id(&zoran_new), cid, Some(proof))); + assert_eq!( + EncointerCeremonies::participant_reputation((cid, cindex - 2), account_id(&zoran)), + Reputation::VerifiedLinked(cindex) + ); + + // double signing (re-using reputation) fails + let proof_second = prove_attendance(account_id(&yuri), cid, cindex - 2, &zoran); + assert_err!( + register(account_id(&yuri), cid, Some(proof_second)), + Error::::AttendanceUnverifiedOrAlreadyUsed + ); }); } @@ -2658,7 +2680,7 @@ fn unregister_participant_works_with_reputables() { ); assert_eq!( EncointerCeremonies::participant_reputation((cid, cindex - 1), &alice), - Reputation::VerifiedLinked + Reputation::VerifiedLinked(cindex) ); assert_ok!(EncointerCeremonies::unregister_participant( @@ -2699,7 +2721,7 @@ fn unregister_participant_fails_with_reputables_and_wrong_reputation() { ); assert_eq!( EncointerCeremonies::participant_reputation((cid, cindex - 1), &alice), - Reputation::VerifiedLinked + Reputation::VerifiedLinked(cindex) ); assert_err!( @@ -3276,7 +3298,7 @@ fn has_reputation_works() { assert_eq!(EncointerCeremonies::has_reputation(&alice, &cid), false); // reputation type qualifies - EncointerCeremonies::fake_reputation((cid, 1), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 1), &alice, Reputation::VerifiedLinked(1)); assert_eq!(EncointerCeremonies::has_reputation(&alice, &cid), true); @@ -3397,7 +3419,7 @@ fn validate_reputation_works() { // fails because too old EncointerCeremonies::fake_reputation((cid, 2), &alice, Reputation::VerifiedUnlinked); assert_eq!(EncointerCeremonies::validate_reputation(&alice, &cid, 2), false); - EncointerCeremonies::fake_reputation((cid, 2), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 2), &alice, Reputation::VerifiedLinked(2)); assert_eq!(EncointerCeremonies::validate_reputation(&alice, &cid, 2), false); // fails because not verifieds @@ -3409,7 +3431,7 @@ fn validate_reputation_works() { // passes EncointerCeremonies::fake_reputation((cid, 7), &alice, Reputation::VerifiedUnlinked); assert_eq!(EncointerCeremonies::validate_reputation(&alice, &cid, 7), true); - EncointerCeremonies::fake_reputation((cid, 7), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 7), &alice, Reputation::VerifiedLinked(7)); assert_eq!(EncointerCeremonies::validate_reputation(&alice, &cid, 7), true); }); } diff --git a/democracy/src/tests.rs b/democracy/src/tests.rs index c3c55325..e93e8165 100644 --- a/democracy/src/tests.rs +++ b/democracy/src/tests.rs @@ -100,11 +100,11 @@ fn proposal_submission_works() { let alice = alice(); // invalid - EncointerCeremonies::fake_reputation((cid, 2), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 2), &alice, Reputation::VerifiedLinked(0)); // valid - EncointerCeremonies::fake_reputation((cid, 3), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 3), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked(0)); let proposal_action = ProposalAction::UpdateNominalIncome(cid, NominalIncomeType::from(100u32)); @@ -185,7 +185,7 @@ fn eligible_reputations_works_with_different_reputations() { Ok(1) ); - EncointerCeremonies::fake_reputation((cid2, 3), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid2, 3), &alice, Reputation::VerifiedLinked(0)); assert_eq!( EncointerDemocracy::validate_and_commit_reputations( 1, @@ -201,7 +201,7 @@ fn eligible_reputations_works_with_different_reputations() { EncointerCeremonies::fake_reputation((cid3, 4), &alice, Reputation::Unverified); EncointerCeremonies::fake_reputation((cid3, 5), &alice, Reputation::UnverifiedReputable); EncointerCeremonies::fake_reputation((cid4, 4), &alice, Reputation::VerifiedUnlinked); - EncointerCeremonies::fake_reputation((cid4, 3), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid4, 3), &alice, Reputation::VerifiedLinked(0)); assert_eq!( EncointerDemocracy::validate_and_commit_reputations( 1, @@ -225,7 +225,7 @@ fn eligible_reputations_works_with_used_reputations() { proposal_action )); - EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked(0)); // commit reputation EncointerDemocracy::validate_and_commit_reputations( @@ -235,7 +235,7 @@ fn eligible_reputations_works_with_used_reputations() { ) .ok(); - EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked(0)); assert_eq!( EncointerDemocracy::validate_and_commit_reputations( @@ -260,7 +260,7 @@ fn eligible_reputations_works_with_inexistent_reputations() { proposal_action )); - EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked(0)); assert_eq!( EncointerDemocracy::validate_and_commit_reputations( @@ -287,8 +287,8 @@ fn eligible_reputations_works_with_cids() { proposal_action )); - EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid2, 5), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid2, 5), &alice, Reputation::VerifiedLinked(0)); assert_eq!( EncointerDemocracy::validate_and_commit_reputations( @@ -313,9 +313,9 @@ fn eligible_reputations_fails_with_invalid_cindex() { proposal_action )); - EncointerCeremonies::fake_reputation((cid, 1), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid, 6), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 1), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid, 6), &alice, Reputation::VerifiedLinked(0)); assert_eq!( EncointerDemocracy::validate_and_commit_reputations( @@ -339,8 +339,8 @@ fn voting_works() { ProposalAction::SetInactivityTimeout(InactivityTimeoutType::from(100u32)); EncointerCeremonies::fake_reputation((cid, 3), &alice, Reputation::Unverified); - EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked(0)); assert_err!( EncointerDemocracy::vote( @@ -369,9 +369,9 @@ fn voting_works() { assert_eq!(tally.ayes, 2); EncointerCeremonies::fake_reputation((cid2, 4), &alice, Reputation::Unverified); - EncointerCeremonies::fake_reputation((cid2, 5), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid, 2), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid2, 6), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid2, 5), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid, 2), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid2, 6), &alice, Reputation::VerifiedLinked(0)); assert_ok!(EncointerDemocracy::vote( RuntimeOrigin::signed(alice.clone()), @@ -500,7 +500,7 @@ fn do_update_proposal_state_works() { EncointerCeremonies::fake_reputation( (cid, 5), &account_id(&p), - Reputation::VerifiedLinked, + Reputation::VerifiedLinked(0), ); } @@ -563,9 +563,9 @@ fn update_proposal_state_extrinsic_works() { let alice = alice(); let cid = register_test_community::(None, 10.0, 10.0); - EncointerCeremonies::fake_reputation((cid, 3), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 3), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked(0)); assert_ok!(EncointerDemocracy::submit_proposal( RuntimeOrigin::signed(alice.clone()), @@ -591,11 +591,11 @@ fn test_get_electorate_works() { let alice = alice(); let bob = bob(); - EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid2, 3), &bob, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid2, 4), &bob, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid2, 5), &bob, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid2, 3), &bob, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid2, 4), &bob, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid2, 5), &bob, Reputation::VerifiedLinked(0)); let proposal_action = ProposalAction::SetInactivityTimeout(8); assert_ok!(EncointerDemocracy::submit_proposal( @@ -627,7 +627,7 @@ fn is_passing_works() { EncointerCeremonies::fake_reputation( (cid, 5), &account_id(&p), - Reputation::VerifiedLinked, + Reputation::VerifiedLinked(0), ); } @@ -703,10 +703,10 @@ fn proposal_happy_flow() { let cid2 = register_test_community::(None, 10.0, 10.0); let alice = alice(); - EncointerCeremonies::fake_reputation((cid, 3), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked); - EncointerCeremonies::fake_reputation((cid2, 3), &alice, Reputation::VerifiedLinked); + EncointerCeremonies::fake_reputation((cid, 3), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid, 4), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid, 5), &alice, Reputation::VerifiedLinked(0)); + EncointerCeremonies::fake_reputation((cid2, 3), &alice, Reputation::VerifiedLinked(0)); let proposal_action = ProposalAction::UpdateNominalIncome(cid, NominalIncomeType::from(13037u32)); diff --git a/primitives/src/ceremonies.rs b/primitives/src/ceremonies.rs index 24816c71..b39221d3 100644 --- a/primitives/src/ceremonies.rs +++ b/primitives/src/ceremonies.rs @@ -16,7 +16,7 @@ use crate::communities::{CommunityIdentifier, Location}; pub use crate::scheduler::CeremonyIndexType; -use crate::scheduler::{CeremonyIndexShort, CeremonyPhaseType}; +use crate::scheduler::CeremonyPhaseType; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; #[cfg(feature = "serde_derive")] @@ -58,13 +58,20 @@ pub enum Reputation { } impl Reputation { - pub fn is_verified(self) -> bool { + pub fn is_verified(&self) -> bool { match self { Self::VerifiedLinked(_) => true, Self::VerifiedUnlinked => true, _ => false, } } + pub fn is_verified_and_unlinked_for_cindex(&self, cindex: CeremonyIndexType) -> bool { + match self { + Self::VerifiedUnlinked => true, + Self::VerifiedLinked(c) => *c != cindex, + _ => false, + } + } } #[derive(Encode, Decode, Copy, Clone, PartialEq, Eq, RuntimeDebug, TypeInfo, MaxEncodedLen)] diff --git a/primitives/src/scheduler.rs b/primitives/src/scheduler.rs index 0a86ec4c..e24547b8 100644 --- a/primitives/src/scheduler.rs +++ b/primitives/src/scheduler.rs @@ -22,17 +22,6 @@ use serde::{Deserialize, Serialize}; pub type CeremonyIndexType = u32; -/// a very short type for ceremony index which can be wrapped in an enum variant -#[derive(Default, Encode, Decode, Copy, Clone, PartialEq, Eq, Debug, TypeInfo, MaxEncodedLen)] -#[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] -pub struct CeremonyIndexShort(u8); - -impl From for CeremonyIndexShort { - fn from(cindex: CeremonyIndexType) -> Self { - Self((cindex % 256) as u8) - } -} - #[derive(Default, Encode, Decode, Copy, Clone, PartialEq, Eq, Debug, TypeInfo, MaxEncodedLen)] #[cfg_attr(feature = "serde_derive", derive(Serialize, Deserialize))] pub enum CeremonyPhaseType {