Skip to content

Commit

Permalink
Move average calculation into a standalone func
Browse files Browse the repository at this point in the history
  • Loading branch information
thaarok committed Nov 7, 2024
1 parent 6523427 commit cff29d5
Showing 1 changed file with 33 additions and 26 deletions.
59 changes: 33 additions & 26 deletions contracts/sfc/SFC.sol
Original file line number Diff line number Diff line change
Expand Up @@ -933,35 +933,42 @@ contract SFC is Initializable, Ownable, Version {
if (normalisedUptime > 1 << 30) {
normalisedUptime = 1 << 30;
}
AverageUptime memory prev = prevSnapshot.averageUptime[validatorID];
AverageUptime memory cur;

if (prev.epochs == 0) {
// the only element for the average
cur.averageUptime = uint32(normalisedUptime);
} else {
uint64 n = prev.epochs + 1; // the number of elements for the average
uint64 tmp = (n - 1) * (prev.averageUptime) + uint64(normalisedUptime);

if (prev.remainder != 0) {
// apply remainder from the division in the previous iteration
tmp += (n * prev.remainder) / (n - 1);
}
AverageUptime memory previousAverage = prevSnapshot.averageUptime[validatorID];
snapshot.averageUptime[validatorID] = _addElementIntoAverageUptime(normalisedUptime, previousAverage);
}
}

cur.averageUptime = uint32(tmp / n);
cur.remainder = uint32(tmp % n);
}
function _addElementIntoAverageUptime(uint32 newValue, AverageUptime memory prev) private returns (AverageUptime memory) {
AverageUptime memory cur;
if (prev.epochs == 0) {
// the only element for the average
cur.averageUptime = uint32(newValue);
cur.epochs = 1;
return cur;
}

if (cur.averageUptime > 1 << 30) {
cur.averageUptime = 1 << 30;
}
if (prev.epochs < c.averageUptimeEpochsWindow()) {
cur.epochs = prev.epochs + 1;
} else {
cur.epochs = prev.epochs;
}
snapshot.averageUptime[validatorID] = cur;
// the number of elements to calculate the average from
uint64 n = prev.epochs + 1;
// use lemma to add new value into the average
uint64 tmp = (n - 1) * uint64(prev.averageUptime) + uint64(newValue);

// apply remainder from the division in the previous iteration to reduce error
if (prev.remainder != 0) {
tmp += (n * prev.remainder) / (n - 1);
}

cur.averageUptime = uint32(tmp / n);
cur.remainder = uint32(tmp % n);

if (cur.averageUptime > 1 << 30) {
cur.averageUptime = 1 << 30;
}
if (prev.epochs < c.averageUptimeEpochsWindow()) {
cur.epochs = prev.epochs + 1;
} else {
cur.epochs = prev.epochs;
}
return cur;
}

/// Create a new validator.
Expand Down

0 comments on commit cff29d5

Please sign in to comment.