Skip to content

Commit

Permalink
feat: added require length check in propose (#765)
Browse files Browse the repository at this point in the history
  • Loading branch information
GauravJain9 committed Mar 25, 2022
1 parent 3549f93 commit 2535e59
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 23 deletions.
3 changes: 2 additions & 1 deletion contracts/Core/BlockManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ contract BlockManager is Initializable, BlockStorage, StateManager, BlockManager
// Below line can't be tested since if not revealed staker most of the times reverts with "not elected"
require(voteManager.getEpochLastRevealed(proposerId) == epoch, "Cannot propose without revealing");
require(epochLastProposed[proposerId] != epoch, "Already proposed");
require(ids.length == medians.length, "Invalid block proposed");

uint256 biggestStake = voteManager.getStakeSnapshot(epoch, biggestStakerId);
if (sortedProposedBlockIds[epoch].length == 0) numProposedBlocks = 0;
Expand Down Expand Up @@ -151,7 +152,7 @@ contract BlockManager is Initializable, BlockStorage, StateManager, BlockManager
// reason to ignore : has to be done, as each vote will have diff weight
// slither-disable-next-line calls-loop
uint256 weight = voteManager.getVoteWeight(epoch, leafId, sortedValues[i]);
accWeight = accWeight + weight; // total influence revealed for this collection
accWeight = accWeight + weight;
if (disputes[epoch][msg.sender].median == 0 && accWeight > medianWeight) {
disputes[epoch][msg.sender].median = sortedValues[i];
}
Expand Down
2 changes: 1 addition & 1 deletion test/AssignCollectionsRandomly.js
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ describe('AssignCollectionsRandomly', function () {
await restoreSnapshot(snapshotId);
snapshotId = await takeSnapshot();

await adhocPropose(signers[1], [1, 4, 3, 5, 6, 7], [100, 200, 300, 400, 500, 600, 700], stakeManager, blockManager, voteManager);
await adhocPropose(signers[1], [1, 4, 3, 5, 6, 7], [100, 300, 400, 500, 600, 700], stakeManager, blockManager, voteManager);
await mineToNextState();
const epoch = await getEpoch();

Expand Down
82 changes: 66 additions & 16 deletions test/BlockManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const {

const { utils } = ethers;
const {
commit, reveal, propose, proposeWithDeviation, reset, calculateMedians, calculateInvalidMedians,
commit, reveal, propose, proposeWithDeviation, reset, calculateMedians, calculateInvalidMedians, getIdsRevealed,
} = require('./helpers/InternalEngine');

describe('BlockManager', function () {
Expand Down Expand Up @@ -489,12 +489,13 @@ describe('BlockManager', function () {
const iteration = await getIteration(voteManager, stakeManager, staker, biggestStake);
const medians = await calculateMedians(collectionManager);
medians[0] += 1;
const idsRevealed = await getIdsRevealed(collectionManager);

await blockManager.connect(signers[5]).propose(epoch,
[2, 3, 4, 9],
idsRevealed,
medians,
iteration,
biggestStakerId); // [ 200, 300, 400, 900 ]
biggestStakerId);
const proposedBlock = await blockManager.proposedBlocks(epoch, 0);
assertBNEqual(proposedBlock.proposerId, toBigNumber('5'), 'incorrect proposalID');
await reset();
Expand Down Expand Up @@ -866,8 +867,9 @@ describe('BlockManager', function () {
let iteration = await getIteration(voteManager, stakeManager, staker, biggestStake);
proposedBlocksIteration1[10] = iteration;
proposedBlocksIteration.push(iteration);
const idsRevealed = await getIdsRevealed(collectionManager);
await blockManager.connect(signers[10]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
iteration,
biggestStakerId); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand All @@ -877,7 +879,7 @@ describe('BlockManager', function () {
proposedBlocksIteration1[11] = iteration;
proposedBlocksIteration.push(iteration);
await blockManager.connect(signers[11]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
iteration,
biggestStakerId); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand All @@ -887,7 +889,7 @@ describe('BlockManager', function () {
proposedBlocksIteration1[12] = iteration;
proposedBlocksIteration.push(iteration);
await blockManager.connect(signers[12]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
iteration,
biggestStakerId); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand All @@ -897,7 +899,7 @@ describe('BlockManager', function () {
proposedBlocksIteration1[13] = iteration;
proposedBlocksIteration.push(iteration);
await blockManager.connect(signers[13]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
iteration,
biggestStakerId); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand All @@ -907,7 +909,7 @@ describe('BlockManager', function () {
proposedBlocksIteration1[14] = iteration;
proposedBlocksIteration.push(iteration);
await blockManager.connect(signers[14]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
iteration,
biggestStakerId); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand Down Expand Up @@ -988,8 +990,9 @@ describe('BlockManager', function () {

// Block with Mid Stake
const iteration = await getIteration(voteManager, stakeManager, staker, stakeMid);
const idsRevealed = await getIdsRevealed(collectionManager);
await blockManager.connect(signers[11]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
iteration,
stakerIds[4]); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand All @@ -1001,7 +1004,7 @@ describe('BlockManager', function () {
staker = await stakeManager.getStaker(stakerIdAcc14);
const iteration2 = await getIteration(voteManager, stakeManager, staker, stakeSmallest);
await blockManager.connect(signers[13]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
iteration2,
stakerIds[0]); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand All @@ -1012,7 +1015,7 @@ describe('BlockManager', function () {
staker = await stakeManager.getStaker(stakerIdAcc15);
const iteration3 = await getIteration(voteManager, stakeManager, staker, stakeMid);
await blockManager.connect(signers[14]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
iteration3,
stakerIds[4]); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand All @@ -1031,7 +1034,7 @@ describe('BlockManager', function () {

const iteration1 = await getIteration(voteManager, stakeManager, staker, stakeLargest);
await blockManager.connect(signers[12]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
iteration1,
stakerIds[3]); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand Down Expand Up @@ -1070,8 +1073,10 @@ describe('BlockManager', function () {
const stakeMid = (await voteManager.getStakeSnapshot(epoch, 8));
const iteration = await getIteration(voteManager, stakeManager, staker, stakeMid);
const medians = await calculateMedians(collectionManager);
const idsRevealed = await getIdsRevealed(collectionManager);

await blockManager.connect(signers[9]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
iteration,
8); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand All @@ -1080,7 +1085,7 @@ describe('BlockManager', function () {
staker = await stakeManager.getStaker(stakerIdAcc11);
const iteration1 = await getIteration(voteManager, stakeManager, staker, stakeMid);
await blockManager.connect(signers[8]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
iteration1,
8); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand Down Expand Up @@ -1206,9 +1211,11 @@ describe('BlockManager', function () {
proposeData.push({ id: (base + i), iteration });
}
proposeData.sort((a, b) => a.iteration - b.iteration);
const idsRevealed = await getIdsRevealed(collectionManager);

for (let i = 0; i < maxAltBlocks + 1; i++) {
await blockManager.connect(signers[(proposeData[i]).id]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
(proposeData[i]).iteration,
biggestStakerId); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand Down Expand Up @@ -1277,10 +1284,11 @@ describe('BlockManager', function () {
const iteration = await getIteration(voteManager, stakeManager, staker, biggestStake);
proposeData.push({ id: (base + i), iteration });
}
const idsRevealed = await getIdsRevealed(collectionManager);
proposeData.sort((a, b) => b.iteration - a.iteration);
for (let i = 0; i < maxAltBlocks + 1; i++) {
await blockManager.connect(signers[(proposeData[i]).id]).propose(epoch,
[0, 0, 0],
idsRevealed,
medians,
(proposeData[i]).iteration,
biggestStakerId); // [100, 201, 300, 400, 500, 600, 700, 800, 900]
Expand Down Expand Up @@ -1581,5 +1589,47 @@ describe('BlockManager', function () {
await commit(signers[19], 0, voteManager, collectionManager, secret, blockManager);
expect(await blockManager.isBlockConfirmed(epoch - 1)).to.be.true;
});
it('should not be able to propose ids with different length than medians and vice versa', async function () {
await mineToNextEpoch();
let epoch = await getEpoch();
let secret = '0x772d5c9e6d18ed15ce7ac8dbcbcbcbcbeecbcbc55555c082bea4ececececebbb';
await commit(signers[19], 0, voteManager, collectionManager, secret, blockManager);
await mineToNextState(); // reveal
await reveal(signers[19], 0, voteManager, stakeManager);
await mineToNextState(); // propose
let medians = await calculateMedians(collectionManager);
let idsRevealed = await getIdsRevealed(collectionManager);
idsRevealed.push(9); // intentionally making ids.length > medians.length
const stakerIdAcc19 = await stakeManager.stakerIds(signers[19].address);
let staker = await stakeManager.getStaker(stakerIdAcc19);
let { biggestStake, biggestStakerId } = await getBiggestStakeAndId(stakeManager, voteManager);
let iteration = await getIteration(voteManager, stakeManager, staker, biggestStake);
const tx1 = blockManager.connect(signers[19]).propose(epoch,
idsRevealed,
medians,
iteration,
biggestStakerId);
await assertRevert(tx1, 'Invalid block proposed');
await mineToNextEpoch();
epoch = await getEpoch();
secret = '0x772d5c9e6d18ed15ce78c8dbcbcbcbcbeecbcbc55555c082bea4ececececebbb';
await commit(signers[19], 0, voteManager, collectionManager, secret, blockManager);
await mineToNextState(); // reveal
await reveal(signers[19], 0, voteManager, stakeManager);
await mineToNextState(); // propose
medians = await calculateMedians(collectionManager);
idsRevealed = await getIdsRevealed(collectionManager);
medians.push(1000); // intentionally making ids.length < medians.length
staker = await stakeManager.getStaker(stakerIdAcc19);
biggestStake = (await getBiggestStakeAndId(stakeManager, voteManager)).biggestStake;
biggestStakerId = (await getBiggestStakeAndId(stakeManager, voteManager)).biggestStakerId;
iteration = await getIteration(voteManager, stakeManager, staker, biggestStake);
const tx2 = blockManager.connect(signers[19]).propose(epoch,
idsRevealed,
medians,
iteration,
biggestStakerId);
await assertRevert(tx2, 'Invalid block proposed');
});
});
});
23 changes: 18 additions & 5 deletions test/helpers/InternalEngine.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,9 @@ const reveal = async (signer, deviation, voteManager, stakeManager) => {
}
}
if (!flag) res[leafId].push(voteValue);
if (voteWeights[voteValue] === undefined) voteWeights[voteValue] = toBigNumber(0);
voteWeights[voteValue] = voteWeights[voteValue].add(influence);
if (voteWeights[leafId] === undefined) voteWeights[leafId] = {};
if (voteWeights[leafId][voteValue] === undefined) voteWeights[leafId][voteValue] = toBigNumber(0);
voteWeights[leafId][voteValue] = voteWeights[leafId][voteValue].add(influence);
helper[leafId] = true;
}
}
Expand Down Expand Up @@ -214,7 +215,7 @@ const proposeWithDeviation = async (signer, deviation, stakeManager, blockManage
let accWeight = toBigNumber(0);
res[j].sort();
for (let i = 0; i < res[j].length; i++) {
accWeight = accWeight.add(voteWeights[res[j][i]]);
accWeight = accWeight.add(voteWeights[j][res[j][i]]);
if (accWeight.gt((influenceSum[j].div(2)))) {
mediansValues.push(res[j][i] + deviation);
break;
Expand Down Expand Up @@ -245,7 +246,7 @@ const calculateMedians = async (collectionManager) => {
let accWeight = toBigNumber(0);
res[j].sort();
for (let i = 0; i < res[j].length; i++) {
accWeight = accWeight.add(voteWeights[res[j][i]]);
accWeight = accWeight.add(voteWeights[j][res[j][i]]);
if (accWeight.gt((influenceSum[j].div(2)))) {
mediansValues.push(res[j][i]);
break;
Expand All @@ -267,7 +268,7 @@ const calculateInvalidMedians = async (collectionManager, deviation) => {
let accWeight = toBigNumber(0);
res[j].sort();
for (let i = 0; i < res[j].length; i++) {
accWeight = accWeight.add(voteWeights[res[j][i]]);
accWeight = accWeight.add(voteWeights[j][res[j][i]]);
if (accWeight.gt((influenceSum[j].div(2)))) {
if (validLeafIdToBeDisputed === 0) {
validLeafIdToBeDisputed = j;
Expand Down Expand Up @@ -298,6 +299,17 @@ const getAnyAssignedIndex = async (signer) => {
return index;
};

const getIdsRevealed = async (collectionManager) => {
const idsRevealedThisEpoch = [];
const activeCollectionIds = await collectionManager.getActiveCollections();
for (let j = 0; j < activeCollectionIds.length; j++) {
if (Number(influenceSum[j]) !== 0) {
idsRevealedThisEpoch.push(activeCollectionIds[j]);
}
}
return idsRevealedThisEpoch;
};

const getRoot = async (signer) => (root[signer.address]);

const getCommitment = async (signer) => (commitments[signer.address]);
Expand All @@ -323,6 +335,7 @@ module.exports = {
getVoteValues,
getTreeRevealData,
getValuesArrayRevealed,
getIdsRevealed,
calculateMedians,
calculateInvalidMedians,
};

0 comments on commit 2535e59

Please sign in to comment.