Skip to content
This repository has been archived by the owner on Jun 11, 2024. It is now read-only.

Fix random seed calculation - Closes #6381 #6382

Merged
merged 2 commits into from
May 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 5 additions & 17 deletions framework/src/modules/dpos/random_seed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,11 @@ const selectSeedReveals = ({

for (let i = fromHeight; i >= toHeight; i -= 1) {
const header = headersMap[i];
// If header does not exist in map, consider the seed reveal is invalid
// This happens when height is before genesis block (regenesis) or negative height in early round
if (!header) {
continue;
}
const blockRound = rounds.calcRound(header.height);

const lastForgedBlock = findPreviousHeaderOfDelegate(
Expand Down Expand Up @@ -123,29 +128,12 @@ export const generateRandomSeeds = (
): FixedLengthArray<RandomSeed, 2> => {
// Middle range of a round to validate
const middleThreshold = Math.floor(rounds.blocksPerRound / 2);
const lastBlockHeight = headers[0].height;
const startOfRound = rounds.calcRoundStartHeight(round);
const middleOfRound = rounds.calcRoundMiddleHeight(round);
const startOfLastRound = rounds.calcRoundStartHeight(round - 1);
const endOfLastRound = rounds.calcRoundEndHeight(round - 1);
const startOfSecondLastRound = rounds.calcRoundStartHeight(round - 2);

if (lastBlockHeight < middleOfRound) {
throw new Error(
`Random seed can't be calculated earlier in a round. Wait till you pass middle of round. Current height: ${lastBlockHeight.toString()}`,
);
}

if (round === 1) {
debug('Returning static value because current round is 1');
const randomSeed1ForFirstRound = strippedHash(
intToBuffer(middleThreshold + 1, NUMBER_BYTE_SIZE),
);
const randomSeed2ForFirstRound = strippedHash(intToBuffer(0, NUMBER_BYTE_SIZE));

return [randomSeed1ForFirstRound, randomSeed2ForFirstRound];
}

/**
* We need to build a map for current and last two rounds. To previously forged
* blocks we will use only current and last round. To validate seed reveal of
Expand Down
2 changes: 1 addition & 1 deletion framework/src/modules/dpos/rounds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export class Rounds {
}

public calcRoundEndHeight(round: number): number {
return (round < 1 ? 1 : round) * this.blocksPerRound;
return (round < 1 ? 0 : round) * this.blocksPerRound;
}

public calcRoundMiddleHeight(round: number): number {
Expand Down
18 changes: 0 additions & 18 deletions framework/test/unit/modules/dpos/random_seed.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import * as randomSeedsMultipleRounds from '../../../fixtures/dpos_random_seed_g
import * as randomSeedsInvalidSeedReveal from '../../../fixtures/dpos_random_seed_generation/dpos_random_seed_generation_invalid_seed_reveal.json';
import * as randomSeedsNotForgedEarlier from '../../../fixtures/dpos_random_seed_generation/dpos_random_seed_generation_not_forged_earlier.json';

import * as randomSeedNotPassedMiddle from '../../../fixtures/dpos_random_seed_generation/dpos_random_seed_generation_not_passed_middle_of_round.json';

import { generateRandomSeeds } from '../../../../src/modules/dpos/random_seed';
import { Rounds } from '../../../../src/modules/dpos/rounds';

Expand Down Expand Up @@ -49,22 +47,6 @@ describe('random_seed', () => {
];

describe('generateRandomSeeds', () => {
it('should throw error if called before middle of the round', () => {
// Arrange
const { config, input } = randomSeedNotPassedMiddle.testCases[0] as any;
rounds = new Rounds({
blocksPerRound: config.blocksPerRound,
});
const round = rounds.calcRound(input.blocks[input.blocks.length - 1].height);
const headers = generateHeadersFromTest(input.blocks);

// Act & Assert
expect(() => generateRandomSeeds(round, rounds, headers)).toThrow(
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`Random seed can't be calculated earlier in a round. Wait till you pass middle of round. Current height: ${input.blocks.length}`,
);
});

describe.each(testCases.map(testCase => [testCase.description, testCase]))(
'%s',
(_description, testCase) => {
Expand Down