@@ -13,8 +13,6 @@ contract KeyGenHistory is UpgradeabilityAdmin, IKeyGenHistory {
13
13
// WARNING: since this contract is upgradeable, do not remove
14
14
// existing storage variables and do not change their types!
15
15
16
- // the current validator addresses
17
- address [] public validatorSet;
18
16
mapping (address => bytes ) public parts;
19
17
mapping (address => bytes []) public acks;
20
18
@@ -27,6 +25,16 @@ contract KeyGenHistory is UpgradeabilityAdmin, IKeyGenHistory {
27
25
/// @dev The address of the `ValidatorSetHbbft` contract.
28
26
IValidatorSetHbbft public validatorSetContract;
29
27
28
+ /// @dev round counter for key generation rounds.
29
+ /// in an ideal world, every key generation only requires one try,
30
+ /// and all validators manage to write their acks and parts,
31
+ /// so it is possible to achieve this goal in round 0.
32
+ /// in the real world, there are failures,
33
+ /// this mechanics helps covering that,
34
+ /// by revoking transactions, that were targeted for an earlier key gen round.
35
+ /// more infos: https://github.com/DMDcoin/hbbft-posdao-contracts/issues/106
36
+ uint256 public currentKeyGenRound;
37
+
30
38
event NewValidatorsSet (address [] newValidatorSet );
31
39
32
40
/// @dev Ensures the `initialize` function was called before.
@@ -55,6 +63,14 @@ contract KeyGenHistory is UpgradeabilityAdmin, IKeyGenHistory {
55
63
_;
56
64
}
57
65
66
+ /// @dev ensures that Key Generation functions are called with wrong _epoch
67
+ /// parameter to prevent old and wrong transactions get picked up.
68
+ modifier onlyCorrectRound (uint _roundCounter ) {
69
+ require (currentKeyGenRound == _roundCounter,
70
+ "Key Generation function called with wrong _roundCounter parameter. " );
71
+ _;
72
+ }
73
+
58
74
/// @dev Clears the state (acks and parts of previous validators.
59
75
/// @param _prevValidators The list of previous validators.
60
76
function clearPrevKeyGenState (address [] calldata _prevValidators )
@@ -69,6 +85,19 @@ contract KeyGenHistory is UpgradeabilityAdmin, IKeyGenHistory {
69
85
numberOfAcksWritten = 0 ;
70
86
}
71
87
88
+ function notifyKeyGenFailed ()
89
+ external
90
+ onlyValidatorSet {
91
+ currentKeyGenRound = currentKeyGenRound + 1 ;
92
+ }
93
+
94
+ function notifyNewEpoch ()
95
+ external
96
+ onlyValidatorSet {
97
+ currentKeyGenRound = 1 ;
98
+ }
99
+
100
+
72
101
function initialize (
73
102
address _validatorSetContract ,
74
103
address [] memory _validators ,
@@ -85,17 +114,19 @@ contract KeyGenHistory is UpgradeabilityAdmin, IKeyGenHistory {
85
114
require (_validatorSetContract != address (0 ), "Validator contract address cannot be 0. " );
86
115
87
116
validatorSetContract = IValidatorSetHbbft (_validatorSetContract);
88
- validatorSet = _validators;
89
117
90
118
for (uint256 i = 0 ; i < _validators.length ; i++ ) {
91
119
parts[_validators[i]] = _parts[i];
92
120
acks[_validators[i]] = _acks[i];
93
121
}
122
+
123
+ currentKeyGenRound = 1 ;
94
124
}
95
125
96
- function writePart (uint256 _upcommingEpoch , bytes memory _part )
126
+ function writePart (uint256 _upcommingEpoch , uint256 _roundCounter , bytes memory _part )
97
127
public
98
- onlyUpcommingEpoch (_upcommingEpoch) {
128
+ onlyUpcommingEpoch (_upcommingEpoch)
129
+ onlyCorrectRound (_roundCounter) {
99
130
// It can only be called by a new validator which is elected but not yet finalized...
100
131
// ...or by a validator which is already in the validator set.
101
132
require (validatorSetContract.isPendingValidator (msg .sender ), "Sender is not a pending validator " );
@@ -104,9 +135,10 @@ contract KeyGenHistory is UpgradeabilityAdmin, IKeyGenHistory {
104
135
numberOfPartsWritten++ ;
105
136
}
106
137
107
- function writeAcks (uint256 _upcommingEpoch , bytes [] memory _acks )
138
+ function writeAcks (uint256 _upcommingEpoch , uint256 _roundCounter , bytes [] memory _acks )
108
139
public
109
- onlyUpcommingEpoch (_upcommingEpoch) {
140
+ onlyUpcommingEpoch (_upcommingEpoch)
141
+ onlyCorrectRound (_roundCounter) {
110
142
// It can only be called by a new validator which is elected but not yet finalized...
111
143
// ...or by a validator which is already in the validator set.
112
144
require (validatorSetContract.isPendingValidator (msg .sender ), "Sender is not a pending validator " );
@@ -129,6 +161,13 @@ contract KeyGenHistory is UpgradeabilityAdmin, IKeyGenHistory {
129
161
return acks[val].length ;
130
162
}
131
163
164
+ function getCurrentKeyGenRound ()
165
+ external
166
+ view
167
+ returns (uint256 ) {
168
+ return currentKeyGenRound;
169
+ }
170
+
132
171
function getNumberOfKeyFragmentsWritten ()
133
172
external
134
173
view
0 commit comments