Coverage Summary for Class: ABICallElection (co.rsk.peg)
Class |
Class, %
|
Method, %
|
Line, %
|
ABICallElection |
0%
(0/1)
|
0%
(0/8)
|
0%
(0/32)
|
1 /*
2 * This file is part of RskJ
3 * Copyright (C) 2017 RSK Labs Ltd.
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 package co.rsk.peg;
20
21 import co.rsk.core.RskAddress;
22
23 import java.util.*;
24
25 /**
26 * Representation of a given state of the election
27 * of an ABI function call by a series of known
28 * and authorized electors.
29 *
30 * @author Ariel Mendelzon
31 */
32 public class ABICallElection {
33 private AddressBasedAuthorizer authorizer;
34 private Map<ABICallSpec, List<RskAddress>> votes;
35
36 public ABICallElection(AddressBasedAuthorizer authorizer, Map<ABICallSpec, List<RskAddress>> votes) {
37 this.authorizer = authorizer;
38 this.votes = votes;
39 validate();
40 }
41
42 public ABICallElection(AddressBasedAuthorizer authorizer) {
43 this.authorizer = authorizer;
44 this.votes = new HashMap<>();
45 }
46
47 public Map<ABICallSpec, List<RskAddress>> getVotes() {
48 return votes;
49 }
50
51 public void clear() {
52 this.votes = new HashMap<>();
53 }
54
55 /**
56 * Register voter's vote for callSpec
57 * @param callSpec the call spec the voter is voting for
58 * @param voter the voter's key
59 * @return whether the voting succeeded
60 */
61 public boolean vote(ABICallSpec callSpec, RskAddress voter) {
62 if (!authorizer.isAuthorized(voter)) {
63 return false;
64 }
65
66 if (!votes.containsKey(callSpec)) {
67 votes.put(callSpec, new ArrayList<>());
68 }
69
70 List<RskAddress> callVoters = votes.get(callSpec);
71
72 if (callVoters.contains(voter)) {
73 return false;
74 }
75
76 callVoters.add(voter);
77 return true;
78 }
79
80 /**
81 * Returns the election winner abi call spec, or null if there's none
82 * The vote authorizer determines the number of participants,
83 * whereas this class determines the number of votes that
84 * conforms a win
85 * @return the winner abi call spec
86 */
87 public ABICallSpec getWinner() {
88 for (Map.Entry<ABICallSpec, List<RskAddress>> specVotes : votes.entrySet()) {
89 if (specVotes.getValue().size() >= authorizer.getRequiredAuthorizedKeys()) {
90 return specVotes.getKey();
91 }
92 }
93
94 return null;
95 }
96
97 /**
98 * Removes the entry votes for the current winner of the election
99 */
100 public void clearWinners() {
101 ABICallSpec winner = getWinner();
102 if (winner != null) {
103 votes.remove(winner);
104 }
105 }
106
107 private void validate() {
108 // Make sure all the votes are authorized
109 for (Map.Entry<ABICallSpec, List<RskAddress>> specVotes : votes.entrySet()) {
110 for (RskAddress vote : specVotes.getValue()) {
111 if (!authorizer.isAuthorized(vote)) {
112 throw new RuntimeException("Unauthorized voter");
113 }
114 }
115 }
116 }
117 }