diff --git a/ceremonies/src/lib.rs b/ceremonies/src/lib.rs index 59341f36..c95e22fe 100644 --- a/ceremonies/src/lib.rs +++ b/ceremonies/src/lib.rs @@ -153,9 +153,8 @@ pub mod pallet { ) == Reputation::VerifiedUnlinked, Error::::AttendanceUnverifiedOrAlreadyUsed ); - if Self::verify_attendee_signature(p.clone()).is_err() { - return Err(>::BadProofOfAttendanceSignature.into()); - }; + + ensure!(p.verify_signature(), Error::::BadProofOfAttendanceSignature); // this reputation must now be burned so it can not be used again >::insert( @@ -1717,18 +1716,6 @@ impl Pallet { Ok(result) } - fn verify_attendee_signature( - proof: ProofOfAttendance, - ) -> DispatchResult { - match proof.attendee_signature.verify( - &(proof.prover_public, proof.ceremony_index).encode()[..], - &proof.attendee_public, - ) { - true => Ok(()), - false => Err(>::BadAttendeeSignature.into()), - } - } - pub fn get_meetup_location( cc: CommunityCeremony, meetup_idx: MeetupIndexType, diff --git a/ceremonies/src/tests.rs b/ceremonies/src/tests.rs index 4634c5ef..cd158ea5 100644 --- a/ceremonies/src/tests.rs +++ b/ceremonies/src/tests.rs @@ -131,14 +131,7 @@ fn prove_attendance( cindex: CeremonyIndexType, attendee: &sr25519::Pair, ) -> TestProofOfAttendance { - let msg = (prover.clone(), cindex); - ProofOfAttendance { - prover_public: prover, - community_identifier: cid, - ceremony_index: cindex, - attendee_public: account_id(attendee), - attendee_signature: Signature::from(attendee.sign(&msg.encode())), - } + TestProofOfAttendance::signed(prover, cid, cindex, attendee) } /// Wrapper for EncointerCeremonies::register_participant that reduces boilerplate code. diff --git a/primitives/src/ceremonies.rs b/primitives/src/ceremonies.rs index ac42459c..452bfdc9 100644 --- a/primitives/src/ceremonies.rs +++ b/primitives/src/ceremonies.rs @@ -21,8 +21,8 @@ use crate::communities::{CommunityIdentifier, Location}; use parity_scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; -use sp_core::{RuntimeDebug, H256}; -use sp_runtime::traits::{BlakeTwo256, Hash, IdentifyAccount, Verify}; +use sp_core::{Pair, RuntimeDebug}; +use sp_runtime::traits::{IdentifyAccount, Verify}; pub use crate::scheduler::CeremonyIndexType; @@ -213,6 +213,8 @@ impl CommunityReputation { } } +pub type AccountIdFor = <::Signer as IdentifyAccount>::AccountId; + #[derive( Encode, Decode, Copy, Clone, PartialEq, Eq, Default, RuntimeDebug, TypeInfo, MaxEncodedLen, )] @@ -226,17 +228,36 @@ pub struct ProofOfAttendance { pub attendee_signature: Signature, } -impl ProofOfAttendance { - /// get the hash of the proof without the attendee signature, - /// as the signature is non-deterministic. - pub fn hash(&self) -> H256 { - ( - self.prover_public.clone(), - self.ceremony_index, - self.community_identifier, - self.attendee_public.clone(), +impl ProofOfAttendance> +where + AccountIdFor: Clone + Encode, +{ + pub fn verify_signature(&self) -> bool { + self.attendee_signature.verify( + &(self.prover_public.clone(), self.ceremony_index).encode()[..], + &self.attendee_public, ) - .using_encoded(BlakeTwo256::hash) + } + + pub fn signed( + prover_public: AccountIdFor, + cid: CommunityIdentifier, + cindex: CeremonyIndexType, + attendee: &Signer, + ) -> Self + where + Signer: Pair, + Signature: From, + AccountIdFor: From, + { + let msg = (prover_public.clone(), cindex); + ProofOfAttendance { + prover_public, + community_identifier: cid, + ceremony_index: cindex, + attendee_public: attendee.public().into(), + attendee_signature: attendee.sign(&msg.encode()).into(), + } } } @@ -377,4 +398,18 @@ mod tests { assert!(claim.verify_signature()) } + + #[test] + fn proof_of_attendance_signing_works() { + let alice = AccountKeyring::Alice.pair(); + + let proof = ProofOfAttendance::::signed( + alice.public().into(), + Default::default(), + 1, + &alice, + ); + + assert!(proof.verify_signature()) + } }