sealed_vote.rs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. use codec::{Decode, Encode};
  2. use frame_support::ensure;
  3. use sp_std::vec::Vec;
  4. #[derive(Clone, Copy, Encode, Decode, Default)]
  5. pub struct SealedVote<AccountId, Stake, Hash, Vote>
  6. where
  7. Vote: Encode,
  8. Hash: PartialEq,
  9. AccountId: PartialEq,
  10. {
  11. pub voter: AccountId,
  12. pub commitment: Hash, // 32 bytes - salted hash of serialized Vote
  13. pub stake: Stake,
  14. vote: Option<Vote>, // will be set when unsealing
  15. }
  16. impl<AccountId, Stake, Hash, Vote> SealedVote<AccountId, Stake, Hash, Vote>
  17. where
  18. Vote: Encode,
  19. Hash: PartialEq,
  20. AccountId: PartialEq,
  21. {
  22. pub fn new(
  23. voter: AccountId,
  24. stake: Stake,
  25. commitment: Hash,
  26. ) -> SealedVote<AccountId, Stake, Hash, Vote> {
  27. SealedVote {
  28. voter,
  29. commitment,
  30. stake,
  31. vote: None,
  32. }
  33. }
  34. pub fn new_unsealed(
  35. voter: AccountId,
  36. stake: Stake,
  37. commitment: Hash,
  38. vote: Vote,
  39. ) -> SealedVote<AccountId, Stake, Hash, Vote> {
  40. SealedVote {
  41. voter,
  42. commitment,
  43. stake,
  44. vote: Some(vote),
  45. }
  46. }
  47. pub fn unseal(
  48. &mut self,
  49. vote: Vote,
  50. salt: &mut Vec<u8>,
  51. hasher: fn(&[u8]) -> Hash,
  52. ) -> Result<(), &'static str> {
  53. // only unseal once
  54. ensure!(self.is_not_revealed(), "vote already unsealed");
  55. // seralize the vote and append the salt
  56. let mut payload = vote.encode();
  57. payload.append(salt);
  58. // hash the payload, if it matches the commitment it is a valid revealing of the vote
  59. if self.commitment == hasher(&payload) {
  60. self.vote = Some(vote);
  61. Ok(())
  62. } else {
  63. Err("invalid salt")
  64. }
  65. }
  66. pub fn get_vote(&self) -> &Option<Vote> {
  67. &self.vote
  68. }
  69. pub fn is_owned_by(&self, someone: AccountId) -> bool {
  70. someone == self.voter
  71. }
  72. pub fn is_revealed(&self) -> bool {
  73. self.vote.is_some()
  74. }
  75. pub fn is_not_revealed(&self) -> bool {
  76. self.vote.is_none()
  77. }
  78. }