From 09e3881c6bbf1a5c05d80ccab9c2555ecd3f0639 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9goire=20Henry?= Date: Wed, 21 Nov 2018 15:52:37 +0100 Subject: [PATCH] Alpha/Vote: do not allow multiple votes --- src/proto_alpha/lib_protocol/src/alpha_context.mli | 4 +++- src/proto_alpha/lib_protocol/src/amendment.ml | 4 +++- src/proto_alpha/lib_protocol/src/vote_storage.ml | 3 ++- src/proto_alpha/lib_protocol/src/vote_storage.mli | 3 ++- src/proto_alpha/lib_protocol/test/voting.ml | 7 +++++++ 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/proto_alpha/lib_protocol/src/alpha_context.mli b/src/proto_alpha/lib_protocol/src/alpha_context.mli index 227a07f6d..051d717b9 100644 --- a/src/proto_alpha/lib_protocol/src/alpha_context.mli +++ b/src/proto_alpha/lib_protocol/src/alpha_context.mli @@ -759,8 +759,10 @@ module Vote : sig val ballots_encoding : ballots Data_encoding.t + val has_recorded_ballot : + context -> public_key_hash -> bool Lwt.t val record_ballot: - context -> public_key_hash -> ballot -> context Lwt.t + context -> public_key_hash -> ballot -> context tzresult Lwt.t val get_ballots: context -> ballots tzresult Lwt.t val get_ballot_list: context -> (Signature.Public_key_hash.t * ballot) list Lwt.t val clear_ballots: context -> context Lwt.t diff --git a/src/proto_alpha/lib_protocol/src/amendment.ml b/src/proto_alpha/lib_protocol/src/amendment.ml index b42b901ba..f12b26618 100644 --- a/src/proto_alpha/lib_protocol/src/amendment.ml +++ b/src/proto_alpha/lib_protocol/src/amendment.ml @@ -227,9 +227,11 @@ let record_ballot ctxt delegate proposal ballot = Vote.get_current_proposal ctxt >>=? fun current_proposal -> fail_unless (Protocol_hash.equal proposal current_proposal) Invalid_proposal >>=? fun () -> + Vote.has_recorded_ballot ctxt delegate >>= fun has_ballot -> + fail_when has_ballot Unauthorized_ballot >>=? fun () -> Vote.in_listings ctxt delegate >>= fun in_listings -> if in_listings then - Vote.record_ballot ctxt delegate ballot >>= return + Vote.record_ballot ctxt delegate ballot else fail Unauthorized_ballot | Testing | Proposal -> diff --git a/src/proto_alpha/lib_protocol/src/vote_storage.ml b/src/proto_alpha/lib_protocol/src/vote_storage.ml index bc0ec37ee..23799dcc2 100644 --- a/src/proto_alpha/lib_protocol/src/vote_storage.ml +++ b/src/proto_alpha/lib_protocol/src/vote_storage.ml @@ -74,7 +74,8 @@ let ballots_encoding = (req "nay" int32) (req "pass" int32) -let record_ballot = Storage.Vote.Ballots.init_set +let has_recorded_ballot = Storage.Vote.Ballots.mem +let record_ballot = Storage.Vote.Ballots.init let get_ballots ctxt = Storage.Vote.Ballots.fold ctxt diff --git a/src/proto_alpha/lib_protocol/src/vote_storage.mli b/src/proto_alpha/lib_protocol/src/vote_storage.mli index cefd0830f..86994bfdb 100644 --- a/src/proto_alpha/lib_protocol/src/vote_storage.mli +++ b/src/proto_alpha/lib_protocol/src/vote_storage.mli @@ -45,9 +45,10 @@ type ballots = { val ballots_encoding : ballots Data_encoding.t +val has_recorded_ballot : Raw_context.t -> Signature.Public_key_hash.t -> bool Lwt.t val record_ballot: Raw_context.t -> Signature.Public_key_hash.t -> Vote_repr.ballot -> - Raw_context.t Lwt.t + Raw_context.t tzresult Lwt.t val get_ballots: Raw_context.t -> ballots tzresult Lwt.t val get_ballot_list : Raw_context.t -> (Signature.Public_key_hash.t * Vote_repr.ballot) list Lwt.t diff --git a/src/proto_alpha/lib_protocol/test/voting.ml b/src/proto_alpha/lib_protocol/test/voting.ml index 245720c44..6891b2483 100644 --- a/src/proto_alpha/lib_protocol/test/voting.ml +++ b/src/proto_alpha/lib_protocol/test/voting.ml @@ -201,6 +201,13 @@ let test_voting () = delegates >>=? fun operations -> Block.bake ~operations b >>=? fun b -> + Op.ballot (B b) del1 Protocol_hash.zero Vote.Nay >>=? fun op -> + Block.bake ~operations:[op] b >>= fun res -> + Assert.proto_error ~loc:__LOC__ res begin function + | Amendment.Unauthorized_ballot -> true + | _ -> false + end >>=? fun () -> + fold_left_s (fun v acc -> return Int32.(add v acc)) 0l rolls >>=? fun rolls_sum ->