Skip to content

Commit 220c601

Browse files
committed
fix: precompute total stake per epoch on rollover.
1 parent c92d556 commit 220c601

File tree

2 files changed

+14
-29
lines changed

2 files changed

+14
-29
lines changed

protocol-units/settlement/mcr/contracts/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ This directory contains the implementation of the MRC settlement smart contract.
77
forge test
88
```
99

10-
There is a long-running test cover over 50 epochs. It will take about a minute and a half to complete on most machines.
10+
There is a long-running test covering over 50 epochs. It will likely take a few seconds to run.
1111

1212
# Implementation
1313
## Description

protocol-units/settlement/mcr/contracts/src/MCR.sol

+13-28
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ contract MCR {
4242
// preserved records of unstake by address per epoch
4343
mapping(uint256 => mapping( address => uint256)) public epochUnstakes;
4444

45+
// track the total stake of the epoch (computed at rollover)
46+
mapping(uint256 => uint256) public epochTotalStake;
47+
4548
// map each block height to an epoch
4649
mapping(uint256 => uint256) public blockHeightEpochAssignments;
4750

@@ -81,26 +84,6 @@ contract MCR {
8184
return BlockCommitment(height, commitment, blockId);
8285
}
8386

84-
// gets the the genesis stake required
85-
function getGenesisStakeRequired() public view returns (uint256) {
86-
return genesisStakeRequired;
87-
}
88-
89-
// gets the the genesis stake accumulated
90-
function getGenesisStakeAccumulated() public view returns (uint256) {
91-
return genesisStakeAccumulated;
92-
}
93-
94-
// gets the epoch duration
95-
function getEpochDuration() public view returns (uint256) {
96-
return epochDuration;
97-
}
98-
99-
// gets the leading block tolerance
100-
function getLeadingBlockTolerance() public view returns (uint256) {
101-
return leadingBlockTolerance;
102-
}
103-
10487
// gets whether the genesis ceremony has ended
10588
function hasGenesisCeremonyEnded() public view returns (bool) {
10689
return genesisStakeAccumulated >= genesisStakeRequired;
@@ -148,12 +131,7 @@ contract MCR {
148131

149132
// gets the total stake for a given epoch
150133
function getTotalStakeForEpoch(uint256 epoch) public view returns (uint256) {
151-
152-
uint256 totalStake = 0;
153-
for (uint256 i = 0; i < validators.length(); i++){
154-
totalStake += getStakeAtEpoch(validators.at(i), epoch);
155-
}
156-
return totalStake;
134+
return epochTotalStake[epoch];
157135
}
158136

159137
// gets the total stake for the current epoch
@@ -206,7 +184,9 @@ contract MCR {
206184
// roll over the genesis epoch to a timestamp epoch
207185
for (uint256 i = 0; i < validators.length(); i++){
208186
address validatorAddress = validators.at(i);
209-
epochStakes[getCurrentEpoch()][validatorAddress] = epochStakes[0][validatorAddress];
187+
uint256 stake = epochStakes[0][validatorAddress];
188+
epochStakes[getCurrentEpoch()][validatorAddress] = stake;
189+
epochTotalStake[getCurrentEpoch()] += stake;
210190
}
211191

212192

@@ -249,6 +229,9 @@ contract MCR {
249229
// the amount of stake rolled over is stake[currentEpoch] - unstake[nextEpoch]
250230
epochStakes[epochNumber + 1][validatorAddress] += epochStakes[epochNumber][validatorAddress] - epochUnstakes[epochNumber + 1][validatorAddress];
251231

232+
// also precompute the total stake for the epoch
233+
epochTotalStake[epochNumber + 1] += epochStakes[epochNumber + 1][validatorAddress];
234+
252235
// the unstake is then paid out
253236
// note: this is the only place this takes place
254237
// there's not risk of double payout, so long as rollOverValidator is only called once per epoch
@@ -307,6 +290,8 @@ contract MCR {
307290
// note: we could keep track of seen commitments in a set
308291
// but since the operations we're doing are very cheap, the set actually adds overhead
309292

293+
uint256 supermajority = (2 * getTotalStakeForEpoch(blockEpoch))/3;
294+
310295
// iterate over the validator set
311296
for (uint256 i = 0; i < validators.length(); i++){
312297

@@ -318,7 +303,7 @@ contract MCR {
318303
// check the total stake on the commitment
319304
uint256 totalStakeOnCommitment = commitmentStakes[blockCommitment.height][blockCommitment.commitment];
320305

321-
if (totalStakeOnCommitment > (2 * getTotalStakeForEpoch(blockEpoch))/3 ) {
306+
if (totalStakeOnCommitment > supermajority) {
322307

323308
// accept the block commitment (this may trigger a roll over of the epoch)
324309
acceptBlockCommitment(blockCommitment, blockEpoch);

0 commit comments

Comments
 (0)