-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor and test: service staking optimization #135
Changes from 3 commits
40ab5e7
de4a4f3
eeee254
5233a15
83605bc
18bfc4d
8140d0f
267e13d
a424c5a
7b4af73
3cd4974
34a81d8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -352,60 +352,52 @@ abstract contract ServiceStakingBase is ERC721TokenReceiver, IErrorsRegistries { | |
uint256[][] memory serviceNonces | ||
) | ||
{ | ||
// Get the service Ids set length | ||
uint256 size = setServiceIds.length; | ||
serviceIds = new uint256[](size); | ||
|
||
// Record service Ids | ||
for (uint256 i = 0; i < size; ++i) { | ||
// Get current service Id | ||
serviceIds[i] = setServiceIds[i]; | ||
} | ||
|
||
// Check the last checkpoint timestamp and the liveness period | ||
// Check the last checkpoint timestamp and the liveness period, also check for available rewards to be not zero | ||
uint256 tsCheckpointLast = tsCheckpoint; | ||
if (block.timestamp - tsCheckpointLast >= livenessPeriod) { | ||
// Get available rewards and last checkpoint timestamp | ||
lastAvailableRewards = availableRewards; | ||
|
||
// If available rewards are not zero, proceed with staking calculation | ||
if (lastAvailableRewards > 0) { | ||
// Get necessary arrays | ||
eligibleServiceIds = new uint256[](size); | ||
eligibleServiceRewards = new uint256[](size); | ||
serviceNonces = new uint256[][](size); | ||
|
||
// Calculate each staked service reward eligibility | ||
for (uint256 i = 0; i < size; ++i) { | ||
// Get the service info | ||
ServiceInfo storage sInfo = mapServiceInfo[serviceIds[i]]; | ||
|
||
// Get current service multisig nonce | ||
serviceNonces[i] = _getMultisigNonces(sInfo.multisig); | ||
|
||
// Calculate the liveness nonce ratio | ||
// Get the last service checkpoint: staking start time or the global checkpoint timestamp | ||
uint256 serviceCheckpoint = tsCheckpointLast; | ||
uint256 ts = sInfo.tsStart; | ||
// Adjust the service checkpoint time if the service was staking less than the current staking period | ||
if (ts > serviceCheckpoint) { | ||
serviceCheckpoint = ts; | ||
} | ||
|
||
// Calculate the liveness ratio in 1e18 value | ||
// This subtraction is always positive or zero, as the last checkpoint can be at most block.timestamp | ||
ts = block.timestamp - serviceCheckpoint; | ||
bool ratioPass = _isRatioPass(serviceNonces[i], sInfo.nonces, ts); | ||
|
||
// Record the reward for the service if it has provided enough transactions | ||
if (ratioPass) { | ||
// Calculate the reward up until now and record its value for the corresponding service | ||
uint256 reward = rewardsPerSecond * ts; | ||
totalRewards += reward; | ||
eligibleServiceRewards[numServices] = reward; | ||
eligibleServiceIds[numServices] = serviceIds[i]; | ||
++numServices; | ||
} | ||
lastAvailableRewards = availableRewards; | ||
if (block.timestamp - tsCheckpointLast >= livenessPeriod && lastAvailableRewards > 0) { | ||
Comment on lines
+357
to
+358
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Merged that check in one: for the liveness period and available rewards. |
||
// Get the service Ids set length | ||
uint256 size = setServiceIds.length; | ||
|
||
// Get necessary arrays | ||
serviceIds = new uint256[](size); | ||
eligibleServiceIds = new uint256[](size); | ||
eligibleServiceRewards = new uint256[](size); | ||
serviceNonces = new uint256[][](size); | ||
|
||
// Calculate each staked service reward eligibility | ||
for (uint256 i = 0; i < size; ++i) { | ||
// Get current service Id | ||
serviceIds[i] = setServiceIds[i]; | ||
|
||
// Get the service info | ||
ServiceInfo storage sInfo = mapServiceInfo[serviceIds[i]]; | ||
|
||
// Get current service multisig nonce | ||
serviceNonces[i] = _getMultisigNonces(sInfo.multisig); | ||
|
||
// Calculate the liveness nonce ratio | ||
// Get the last service checkpoint: staking start time or the global checkpoint timestamp | ||
uint256 serviceCheckpoint = tsCheckpointLast; | ||
uint256 ts = sInfo.tsStart; | ||
// Adjust the service checkpoint time if the service was staking less than the current staking period | ||
if (ts > serviceCheckpoint) { | ||
serviceCheckpoint = ts; | ||
} | ||
|
||
// Calculate the liveness ratio in 1e18 value | ||
// This subtraction is always positive or zero, as the last checkpoint can be at most block.timestamp | ||
ts = block.timestamp - serviceCheckpoint; | ||
bool ratioPass = _isRatioPass(serviceNonces[i], sInfo.nonces, ts); | ||
|
||
// Record the reward for the service if it has provided enough transactions | ||
if (ratioPass) { | ||
// Calculate the reward up until now and record its value for the corresponding service | ||
uint256 reward = rewardsPerSecond * ts; | ||
totalRewards += reward; | ||
eligibleServiceRewards[numServices] = reward; | ||
eligibleServiceIds[numServices] = serviceIds[i]; | ||
++numServices; | ||
} | ||
} | ||
} | ||
|
@@ -508,7 +500,12 @@ abstract contract ServiceStakingBase is ERC721TokenReceiver, IErrorsRegistries { | |
} | ||
|
||
// Call the checkpoint | ||
(uint256[] memory serviceIds, , , , , ) = checkpoint(); | ||
(uint256[] memory serviceIds, , , , , bool success) = checkpoint(); | ||
|
||
// If the checkpoint was not successful, the serviceIds set is not returned and needs to be allocated | ||
if (!success) { | ||
serviceIds = getServiceIds(); | ||
} | ||
Comment on lines
-511
to
+508
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Checkpoint now might not return |
||
|
||
// Get the service index in the set of services | ||
// The index must always exist as the service is currently staked, otherwise it has no record in the map | ||
|
@@ -562,26 +559,44 @@ abstract contract ServiceStakingBase is ERC721TokenReceiver, IErrorsRegistries { | |
uint256[] memory eligibleServiceRewards, , ) = _calculateStakingRewards(); | ||
|
||
// If there are eligible services, proceed with staking calculation and update rewards for the service Id | ||
if (numServices > 0) { | ||
for (uint256 i = 0; i < numServices; ++i) { | ||
Comment on lines
-565
to
+562
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to check for the |
||
// Get the service index in the eligible service set and calculate its latest reward | ||
for (uint256 i = 0; i < eligibleServiceIds.length; ++i) { | ||
if (eligibleServiceIds[i] == serviceId) { | ||
// If total allocated rewards are not enough, adjust the reward value | ||
if (totalRewards > lastAvailableRewards) { | ||
reward += (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards; | ||
} else { | ||
reward += eligibleServiceRewards[i]; | ||
} | ||
break; | ||
if (eligibleServiceIds[i] == serviceId) { | ||
// If total allocated rewards are not enough, adjust the reward value | ||
if (totalRewards > lastAvailableRewards) { | ||
reward += (eligibleServiceRewards[i] * lastAvailableRewards) / totalRewards; | ||
} else { | ||
reward += eligibleServiceRewards[i]; | ||
} | ||
break; | ||
} | ||
} | ||
} | ||
|
||
/// @dev Gets staked service Ids. | ||
/// @return serviceIds Staked service Ids. | ||
function getServiceIds() public view returns (uint256[] memory serviceIds) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding the function that returns current staking |
||
// Get the number of service Ids | ||
uint256 size = setServiceIds.length; | ||
serviceIds = new uint256[](size); | ||
|
||
// Record service Ids | ||
for (uint256 i = 0; i < size; ++i) { | ||
serviceIds[i] = setServiceIds[i]; | ||
} | ||
} | ||
|
||
/// @dev Checks if the service is staked. | ||
/// @param serviceId. | ||
/// @return True, if the service is staked. | ||
function isServiceStaked(uint256 serviceId) external view returns (bool) { | ||
return mapServiceInfo[serviceId].tsStart > 0; | ||
/// @return isStaked True, if the service is staked. | ||
function isServiceStaked(uint256 serviceId) external view returns (bool isStaked) { | ||
isStaked = (mapServiceInfo[serviceId].tsStart > 0); | ||
} | ||
|
||
/// @dev Gets the next reward checkpoint timestamp. | ||
/// @return tsNext Next reward checkpoint timestamp. | ||
function getNextRewardCheckpointTimestamp() external view returns (uint256 tsNext) { | ||
// Last checkpoint timestamp plus the liveness period | ||
tsNext = tsCheckpoint + livenessPeriod; | ||
Comment on lines
+596
to
+600
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Getter of the next reward checkpoint timestamp - the agent can always compare with the |
||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't allocate
serviceIds
if the rewards calculation is not going to be successful.