From bbaaddb99d7b55cd893b88c83aa2d062ff919b9e Mon Sep 17 00:00:00 2001 From: Alex Rea Date: Tue, 20 Jun 2023 12:25:11 +0100 Subject: [PATCH] Make skill reputation scaling calculation more efficient --- contracts/colony/ColonyStorage.sol | 11 ++++++----- contracts/colonyNetwork/ColonyNetwork.sol | 12 ++++++++++++ contracts/colonyNetwork/IColonyNetwork.sol | 6 ++++++ docs/interfaces/icolonynetwork.md | 17 +++++++++++++++++ test/contracts-network/colony-permissions.js | 4 ++-- 5 files changed, 43 insertions(+), 7 deletions(-) diff --git a/contracts/colony/ColonyStorage.sol b/contracts/colony/ColonyStorage.sol index 191c18563a..8a3acc0604 100755 --- a/contracts/colony/ColonyStorage.sol +++ b/contracts/colony/ColonyStorage.sol @@ -366,13 +366,14 @@ contract ColonyStorage is ColonyDataTypes, ColonyNetworkDataTypes, DSMath, Commo } function getSkillReputationScaling(uint256 _skillId) public view returns (uint256) { - Skill memory skill = IColonyNetwork(colonyNetworkAddress).getSkill(_skillId); uint256 factor = WAD - skillReputationRateComplements[_skillId]; - while (skill.nParents > 0 && factor > 0) { - uint256 skillId = skill.parents[0]; - skill = IColonyNetwork(colonyNetworkAddress).getSkill(skillId); - factor = wmul(factor, WAD - skillReputationRateComplements[skillId]); + uint256[] memory allParents = IColonyNetwork(colonyNetworkAddress).getAllSkillParents(_skillId); + uint256 count; + + while (count < allParents.length && factor > 0) { + factor = wmul(factor, WAD - skillReputationRateComplements[allParents[count]]); + count +=1; } return factor; diff --git a/contracts/colonyNetwork/ColonyNetwork.sol b/contracts/colonyNetwork/ColonyNetwork.sol index 4fb7b19e00..2a6cf682f5 100644 --- a/contracts/colonyNetwork/ColonyNetwork.sol +++ b/contracts/colonyNetwork/ColonyNetwork.sol @@ -60,6 +60,18 @@ contract ColonyNetwork is ColonyDataTypes, BasicMetaTransaction, ColonyNetworkSt skill = skills[_skillId]; } + function getAllSkillParents(uint256 _skillId) public view returns (uint256[] memory){ + Skill storage skill = skills[_skillId]; + uint[] memory allParents = new uint256[](skill.nParents); + uint256 count; + for (uint256 count = 0; count < allParents.length; count += 1) { + allParents[count] = skill.parents[0]; + skill = skills[skill.parents[0]]; + } + + return allParents; + } + function getReputationRootHash() public view returns (bytes32) { return reputationRootHash; } diff --git a/contracts/colonyNetwork/IColonyNetwork.sol b/contracts/colonyNetwork/IColonyNetwork.sol index 3b2b90d2f8..ff2913e277 100644 --- a/contracts/colonyNetwork/IColonyNetwork.sol +++ b/contracts/colonyNetwork/IColonyNetwork.sol @@ -473,4 +473,10 @@ interface IColonyNetwork is ColonyNetworkDataTypes, IRecovery, IBasicMetaTransac /// @return numerator The numerator of the fraction reputation does down by every reputation cycle /// @return denominator The denominator of the fraction reputation does down by every reputation cycle function getColonyReputationDecayRate(address _colony) external view returns (uint256 numerator, uint256 denominator); + + /// @notice Called to get an array containing all parent skill ids of a skill + /// @param _skillId The skill id being queried + /// @return parents An array containing the ids of all parent skills + function getAllSkillParents(uint256 _skillId) external view returns (uint256[] memory parents); + } diff --git a/docs/interfaces/icolonynetwork.md b/docs/interfaces/icolonynetwork.md index 306b296608..b6d415a8ed 100644 --- a/docs/interfaces/icolonynetwork.md +++ b/docs/interfaces/icolonynetwork.md @@ -332,6 +332,23 @@ Set deprecation status for a skill |---|---|---| |_changed|bool|Whether the deprecated state was changed +### ▸ `getAllSkillParents(uint256 _skillId):uint256[] parents` + +Called to get an array containing all parent skill ids of a skill + + +**Parameters** + +|Name|Type|Description| +|---|---|---| +|_skillId|uint256|The skill id being queried + +**Return Parameters** + +|Name|Type|Description| +|---|---|---| +|parents|uint256[]|An array containing the ids of all parent skills + ### ▸ `getChildSkillId(uint256 _skillId, uint256 _childSkillIndex):uint256 _childSkillId` Get the id of the child skill at index `_childSkillIndex` for skill with Id `_skillId`. diff --git a/test/contracts-network/colony-permissions.js b/test/contracts-network/colony-permissions.js index 948b1b0bb4..e906c74caa 100644 --- a/test/contracts-network/colony-permissions.js +++ b/test/contracts-network/colony-permissions.js @@ -409,7 +409,7 @@ contract("ColonyPermissions", (accounts) => { }); it("should be able to apply reputation earned scaling to 150 layers of domains", async () => { - const N_LAYERS = 50; + const N_LAYERS = 150; await removeSubdomainLimit(colonyNetwork); await colony.addDomain(1, UINT256_MAX, 1); let domainCount = await colony.getDomainCount(); @@ -417,7 +417,7 @@ contract("ColonyPermissions", (accounts) => { const limit = domainCount + N_LAYERS; - // Limit currently appears to be ??? + // Limit currently appears to be about 160 for (let i = domainCount - 2; i < limit - 2; i += 1) { await colony.addDomain(1, i, i + 2); }