Skip to content

Commit

Permalink
Assign Assets Randomly (#206)
Browse files Browse the repository at this point in the history
* AssignJobsRandomly

* tests

* refractoring tests

* linting fixes

* Tests added, Finalize Dispute Fixed, Rewards and Peanlty fixed, Migrations Updated

* lint fixes

* linting fixes

* Merge Errors

* lint fixes

Co-authored-by: Hrishikesh Huilgolkar <[email protected]>
  • Loading branch information
0xcuriousapple and hrishikeshio authored Jul 27, 2021
1 parent fb770e7 commit 034b303
Show file tree
Hide file tree
Showing 15 changed files with 671 additions and 133 deletions.
7 changes: 3 additions & 4 deletions contracts/Core/BlockManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ contract BlockManager is Initializable, ACL, BlockStorage {
require(sorted[i] > lastVisited, "sorted[i] is not greater than lastVisited");
lastVisited = sorted[i];
accWeight = accWeight + (voteManager.getVoteWeight(epoch, assetId, sorted[i]));

if (disputes[epoch][msg.sender].median == 0 && accWeight > medianWeight) {
disputes[epoch][msg.sender].median = sorted[i];
}
Expand All @@ -116,17 +115,17 @@ contract BlockManager is Initializable, ACL, BlockStorage {
disputes[epoch][msg.sender] = Structs.Dispute(0, 0, 0, 0);
}

function finalizeDispute(uint256 epoch, uint256 blockId) external initialized checkEpoch(epoch) checkState(parameters.dispute()) {
function finalizeDispute (uint256 epoch, uint256 blockId, uint256 assetPosInBlock)
public initialized checkEpoch(epoch) checkState(parameters.dispute()) {
uint256 assetId = disputes[epoch][msg.sender].assetId;
require(
disputes[epoch][msg.sender].accWeight == voteManager.getTotalInfluenceRevealed(epoch, assetId),
"Total influence revealed doesnt match"
);
uint256 median = disputes[epoch][msg.sender].median;
uint256 proposerId = proposedBlocks[epoch][blockId].proposerId;
//
require(median > 0, "median can not be zero");
if (proposedBlocks[epoch][blockId].medians[assetId] != median) {
if (proposedBlocks[epoch][blockId].medians[assetPosInBlock] != median) {
proposedBlocks[epoch][blockId].valid = false;
stakeManager.slash(proposerId, msg.sender, epoch);
} else {
Expand Down
9 changes: 7 additions & 2 deletions contracts/Core/Parameters.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import "./ACL.sol";
contract Parameters is ACL {
// constant type can be readjusted to some smaller type than uint256 for saving gas (storage variable packing).
// penalty not reveal = 0.01% per epch

uint256 public penaltyNotRevealNum = 1;
uint256 public penaltyNotRevealDenom = 10000;
uint256 public slashPenaltyNum = 10000;
Expand All @@ -23,7 +22,8 @@ contract Parameters is ACL {
uint256 public withdrawReleasePeriod = 5;
uint256 public resetLockPenalty = 1;
uint256 public maxAge = 100 * 10000;

// Note : maxAssetsPerStaker should be less than total no of jobs
uint256 public maxAssetsPerStaker = 2;
bool public escapeHatchEnabled = true;

uint32 private constant _COMMIT = 0;
Expand Down Expand Up @@ -107,6 +107,11 @@ contract Parameters is ACL {
aggregationRange = _aggregationRange;
}


function setmaxAssetsPerStaker(uint256 _maxAssetsPerStaker) external onlyRole(DEFAULT_ADMIN_ROLE) {
maxAssetsPerStaker = _maxAssetsPerStaker;
}

function setMaxAge(uint256 _maxAge) external onlyRole(DEFAULT_ADMIN_ROLE) {
maxAge = _maxAge;
}
Expand Down
23 changes: 17 additions & 6 deletions contracts/Core/RewardManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -129,13 +129,24 @@ contract RewardManager is Initializable, ACL, RewardStorage {
if (mediansLastEpoch.length > 0) {
uint256 penalty = 0;
for (uint256 i = 0; i < mediansLastEpoch.length; i++) {
uint256 voteLastEpoch = voteManager.getVote(epochLastRevealed, thisStaker.id, i).value;
Structs.Vote memory voteLastEpoch = voteManager.getVote(
epochLastRevealed,
thisStaker.id,
_block.ids[i] - 1
);
uint256 medianLastEpoch = mediansLastEpoch[i];

if (voteLastEpoch > medianLastEpoch) {
penalty = penalty + (previousAge * (voteLastEpoch - medianLastEpoch)**2) / medianLastEpoch**2;
} else {
penalty = penalty + (previousAge * (medianLastEpoch - voteLastEpoch)**2) / medianLastEpoch**2;

if (voteLastEpoch.weight > 0) {
if (voteLastEpoch.value > medianLastEpoch) {
penalty = penalty +
(previousAge * (voteLastEpoch.value - medianLastEpoch)**2)
/medianLastEpoch**2;
} else {
penalty = penalty +
(previousAge*(medianLastEpoch - voteLastEpoch.value)**2)
/medianLastEpoch**2;

}
}
}

Expand Down
34 changes: 25 additions & 9 deletions contracts/Core/VoteManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ import "./interface/IParameters.sol";
import "./interface/IStakeManager.sol";
import "./interface/IRewardManager.sol";
import "./interface/IBlockManager.sol";
import "./interface/IAssetManager.sol";
import "./storage/VoteStorage.sol";
import "../Initializable.sol";
import "./ACL.sol";
import "../lib/Random.sol";

contract VoteManager is Initializable, ACL, VoteStorage {
IParameters public parameters;
IStakeManager public stakeManager;
IRewardManager public rewardManager;
IBlockManager public blockManager;
IAssetManager public assetManager;

event Committed(uint256 epoch, uint256 stakerId, bytes32 commitment, uint256 timestamp);
event Revealed(uint256 epoch, uint256 stakerId, uint256 stake, uint256[] values, uint256 timestamp);
event Revealed(uint256 epoch, uint256 stakerId, uint256 stake, Structs.AssignedAsset[] values, uint256 timestamp);

modifier checkEpoch(uint256 epoch) {
require(epoch == parameters.getEpoch(), "incorrect epoch");
Expand All @@ -33,12 +36,14 @@ contract VoteManager is Initializable, ACL, VoteStorage {
address stakeManagerAddress,
address rewardManagerAddress,
address blockManagerAddress,
address parametersAddress
address parametersAddress,
address assetManagerAddress
) external initializer onlyRole(DEFAULT_ADMIN_ROLE) {
stakeManager = IStakeManager(stakeManagerAddress);
rewardManager = IRewardManager(rewardManagerAddress);
blockManager = IBlockManager(blockManagerAddress);
parameters = IParameters(parametersAddress);
assetManager = IAssetManager(assetManagerAddress);
}

function commit(uint256 epoch, bytes32 commitment) external initialized checkEpoch(epoch) checkState(parameters.commit()) {
Expand All @@ -64,7 +69,7 @@ contract VoteManager is Initializable, ACL, VoteStorage {
function reveal(
uint256 epoch,
bytes32 root,
uint256[] memory values,
Structs.AssignedAsset [] memory values,
bytes32[][] memory proofs,
bytes32 secret,
address stakerAddress
Expand All @@ -74,17 +79,21 @@ contract VoteManager is Initializable, ACL, VoteStorage {
Structs.Staker memory thisStaker = stakeManager.getStaker(thisStakerId);
require(commitments[epoch][thisStakerId] != 0x0, "not commited or already revealed");
require(keccak256(abi.encodePacked(epoch, root, secret)) == commitments[epoch][thisStakerId], "incorrect secret/value");

require(values.length == parameters.maxAssetsPerStaker(), "Revealed assets not equal to required assets per staker");

//if revealing self
if (msg.sender == stakerAddress) {
require(parameters.getState() == parameters.reveal(), "Not reveal state");
require(thisStaker.stake > 0, "nonpositive stake");
for (uint256 i = 0; i < values.length; i++) {
require(MerkleProof.verify(proofs[i], root, keccak256(abi.encodePacked(values[i]))), "invalid merkle proof");
uint256 influence = stakeManager.getInfluence(thisStakerId);
votes[epoch][thisStakerId][i] = Structs.Vote(values[i], thisStaker.stake);
voteWeights[epoch][i][values[i]] = voteWeights[epoch][i][values[i]] + influence;
totalInfluenceRevealed[epoch][i] = totalInfluenceRevealed[epoch][i] + influence;
if (votes[epoch][thisStakerId][values[i].id - 1].weight == 0) { // If Job Not Revealed before
require(isAssetAllotedToStaker(thisStakerId, i, values[i].id), "Revealed asset not alloted");
require(MerkleProof.verify(proofs[i], root, keccak256(abi.encodePacked(values[i].value))), "invalid merkle proof");
uint256 influence = stakeManager.getInfluence(thisStakerId);
votes[epoch][thisStakerId][values[i].id-1] = Structs.Vote(values[i].value, thisStaker.stake);
voteWeights[epoch][values[i].id-1][values[i].value] = voteWeights[epoch][values[i].id-1][values[i].value] + influence;
totalInfluenceRevealed[epoch][values[i].id-1] = totalInfluenceRevealed[epoch][values[i].id-1] + influence;
}
}

commitments[epoch][thisStakerId] = 0x0;
Expand All @@ -99,6 +108,13 @@ contract VoteManager is Initializable, ACL, VoteStorage {
}
}

function isAssetAllotedToStaker(uint256 stakerId, uint256 iteration, uint256 assetId) public view initialized returns (bool)
{
// numBlocks = 10, max= numAssets, seed = iteration+stakerId, epochLength
if ((Random.prng(10, assetManager.getNumAssets(), keccak256(abi.encode( iteration + stakerId)), parameters.epochLength())+(1)) == assetId) return true;
return false;
}

function getCommitment(uint256 epoch, uint256 stakerId) public view returns (bytes32) {
//epoch -> stakerid -> commitment
return (commitments[epoch][stakerId]);
Expand Down
1 change: 1 addition & 0 deletions contracts/Core/interface/IAssetManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ interface IAssetManager {
uint256[] memory jobIDs,
uint256 result
);
function getNumAssets() external view returns(uint256);
}
2 changes: 2 additions & 0 deletions contracts/Core/interface/IParameters.sol
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ interface IParameters {
function slashPenaltyNum() external view returns (uint256);

function slashPenaltyDenom() external view returns (uint256);

function maxAssetsPerStaker() external view returns (uint256);

function getEpoch() external view returns (uint256);

Expand Down
1 change: 1 addition & 0 deletions contracts/Core/interface/IVoteManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ interface IVoteManager {
function reveal(
uint256 epoch,
bytes32 root,
uint256[] calldata assetIds,
uint256[] calldata values,
bytes32[][] calldata proofs,
bytes32 secret,
Expand Down
7 changes: 6 additions & 1 deletion contracts/lib/Structs.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,9 @@ library Structs {
uint256 result;
uint256 assetType;
}
}

struct AssignedAsset {
uint256 id;
uint256 value;
}
}
2 changes: 1 addition & 1 deletion migrations/src/7_deploy_vote_manager.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
const { deployContract } = require('../migrationHelpers');

const deployVoteManager = async () => {
await deployContract('VoteManager');
await deployContract('VoteManager', ['Random']);
};

module.exports = async () => {
Expand Down
3 changes: 2 additions & 1 deletion migrations/src/postDeploymentSetup.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ module.exports = async () => {

pendingTransactions.push(await blockManager.initialize(stakeManagerAddress, rewardManagerAddress, voteManagerAddress,
assetManagerAddress, parametersAddress));
pendingTransactions.push(await voteManager.initialize(stakeManagerAddress, rewardManagerAddress, blockManagerAddress, parametersAddress));
pendingTransactions.push(await voteManager.initialize(stakeManagerAddress, rewardManagerAddress, blockManagerAddress,
parametersAddress, assetManagerAddress));
pendingTransactions.push(await stakeManager.initialize(RAZORAddress, rewardManagerAddress, voteManagerAddress, parametersAddress));
pendingTransactions.push(await rewardManager.initialize(stakeManagerAddress, voteManagerAddress, blockManagerAddress, parametersAddress));

Expand Down
Loading

0 comments on commit 034b303

Please sign in to comment.