From dffbd41ba47ee55447b28b40f1326506f5b51f1e Mon Sep 17 00:00:00 2001 From: Bernhard Scholz Date: Tue, 29 Oct 2024 22:33:39 +1100 Subject: [PATCH] added deactivation procedure --- contracts/sfc/ConstantsManager.sol | 5 +++-- contracts/sfc/SFC.sol | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/contracts/sfc/ConstantsManager.sol b/contracts/sfc/ConstantsManager.sol index 03de8fa..870dd9b 100644 --- a/contracts/sfc/ConstantsManager.sol +++ b/contracts/sfc/ConstantsManager.sol @@ -32,10 +32,11 @@ contract ConstantsManager is Ownable { uint256 public targetGasPowerPerSecond; uint256 public gasPriceBalancingCounterweight; - // number of epochs for counting the average uptime of validators + // epoch threshold for stop counting alive epochs (avoid diminishing impact of new uptimes) and + // is also the minimum number of epochs necessary for enabling the deactivation. int32 public numEpochsAliveThreshold; - // minimum average uptime + // minimum average uptime in Q1.30 format; acceptable bounds [0,0.9] int32 public minAverageUptime; /** diff --git a/contracts/sfc/SFC.sol b/contracts/sfc/SFC.sol index 1e8efb2..4f9d14c 100644 --- a/contracts/sfc/SFC.sol +++ b/contracts/sfc/SFC.sol @@ -381,12 +381,14 @@ contract SFC is SFCBase, Version { ) internal { for (uint256 i = 0; i < validatorIDs.length; i++) { uint256 validatorID = validatorIDs[i]; + // compute normalised uptime as a percentage in the Q1.30 fixed-point format uint256 normalisedUptime = uptimes[i] * (1 << 30)/ epochDuration; if (normalisedUptime < 0) { normalisedUptime = 0; } else if (normalisedUptime > 1 << 30) { normalisedUptime = 1 << 30; } + // update average uptime data structure // Assumes that if in the previous snapshot the validator // does not exist, the map returns zero. int32 n = prevSnapshot.averageData[validatorID].numEpochsAlive; @@ -410,6 +412,12 @@ contract SFC is SFCBase, Version { if (n < c.numEpochsAliveThreshold()) { snapshot.averageData[validatorID].numEpochsAlive = n + 1; } + // remove validator if average uptime drops below min average uptime + // (by setting minAverageUptime to zero, this check is ignored) + if (int32(tmp) < c.minAverageUptime() && n >= c.numEpochsAliveThreshold() ) { + _setValidatorDeactivated(validatorIDs[i], OFFLINE_BIT); + _syncValidator(validatorIDs[i], false); + } } }