Skip to content

Commit

Permalink
fix(core-kernel): slot, round and forgingInfo calculation for dynamic…
Browse files Browse the repository at this point in the history
… block times (#4034)
  • Loading branch information
sebastijankuzner committed Sep 18, 2020
1 parent a027491 commit 2d3fe09
Show file tree
Hide file tree
Showing 7 changed files with 539 additions and 959 deletions.
533 changes: 130 additions & 403 deletions __tests__/unit/core-kernel/utils/calculate-forging-info.test.ts

Large diffs are not rendered by default.

@@ -1,7 +1,8 @@
import "jest-extended";

import { Managers } from "@arkecosystem/crypto";
import { calculateRound, isNewRound } from "@packages/core-kernel/src/utils/round-calculator";
import { Errors, Managers } from "@packages/crypto";
import { devnet } from "@packages/crypto/src/networks";

describe("Round Calculator", () => {
describe("calculateRound", () => {
Expand Down Expand Up @@ -30,25 +31,77 @@ describe("Round Calculator", () => {
expect(nextRound).toBe(Math.floor((i + 1) / activeDelegates) + 1);
}
});

it("should calculate correct round for each height in round", () => {
const milestones = [{ height: 1, activeDelegates: 4 }];

const config = { ...devnet, milestones };
Managers.configManager.setConfig(config);

const testVector = [
// Round 1
{ height: 1, round: 1, roundHeight: 1, nextRound: 1, activeDelegates: 4 },
{ height: 2, round: 1, roundHeight: 1, nextRound: 1, activeDelegates: 4 },
{ height: 3, round: 1, roundHeight: 1, nextRound: 1, activeDelegates: 4 },
{ height: 4, round: 1, roundHeight: 1, nextRound: 2, activeDelegates: 4 },
// Round 2
{ height: 5, round: 2, roundHeight: 5, nextRound: 2, activeDelegates: 4 },
{ height: 6, round: 2, roundHeight: 5, nextRound: 2, activeDelegates: 4 },
{ height: 7, round: 2, roundHeight: 5, nextRound: 2, activeDelegates: 4 },
{ height: 8, round: 2, roundHeight: 5, nextRound: 3, activeDelegates: 4 },
// Round 3
{ height: 9, round: 3, roundHeight: 9, nextRound: 3, activeDelegates: 4 },
{ height: 10, round: 3, roundHeight: 9, nextRound: 3, activeDelegates: 4 },
{ height: 11, round: 3, roundHeight: 9, nextRound: 3, activeDelegates: 4 },
{ height: 12, round: 3, roundHeight: 9, nextRound: 4, activeDelegates: 4 },
];

testVector.forEach((item) => {
const result = calculateRound(item.height);
expect(result.round).toBe(item.round);
expect(result.roundHeight).toBe(item.roundHeight);
expect(isNewRound(result.roundHeight)).toBeTrue();
expect(result.nextRound).toBe(item.nextRound);
expect(result.maxDelegates).toBe(item.activeDelegates);
});
});
});

describe("dynamic delegate count", () => {
it("should calculate the correct with dynamic delegate count", () => {
const milestones = [
{ height: 1, activeDelegates: 2 },
{ height: 3, activeDelegates: 3 },
{ height: 9, activeDelegates: 1 },
{ height: 12, activeDelegates: 3 },
];

const testVector = [
// Round 1 - milestone
{ height: 1, round: 1, roundHeight: 1, nextRound: 1, activeDelegates: 2 },
{ height: 2, round: 1, roundHeight: 1, nextRound: 2, activeDelegates: 2 },
// Round 2 - milestone change
{ height: 3, round: 2, roundHeight: 3, nextRound: 2, activeDelegates: 3 },
{ height: 6, round: 3, roundHeight: 6, nextRound: 4, activeDelegates: 1 },
{ height: 10, round: 7, roundHeight: 10, nextRound: 7, activeDelegates: 51 },
{ height: 112, round: 9, roundHeight: 112, nextRound: 10, activeDelegates: 1 },
{ height: 115, round: 12, roundHeight: 115, nextRound: 12, activeDelegates: 2 },
{ height: 131, round: 20, roundHeight: 131, nextRound: 20, activeDelegates: 51 },
{ height: 4, round: 2, roundHeight: 3, nextRound: 2, activeDelegates: 3 },
{ height: 5, round: 2, roundHeight: 3, nextRound: 3, activeDelegates: 3 },
// Round 3
{ height: 6, round: 3, roundHeight: 6, nextRound: 3, activeDelegates: 3 },
{ height: 7, round: 3, roundHeight: 6, nextRound: 3, activeDelegates: 3 },
{ height: 8, round: 3, roundHeight: 6, nextRound: 4, activeDelegates: 3 },
// Round 4 - 6 - milestone change
{ height: 9, round: 4, roundHeight: 9, nextRound: 5, activeDelegates: 1 },
{ height: 10, round: 5, roundHeight: 10, nextRound: 6, activeDelegates: 1 },
{ height: 11, round: 6, roundHeight: 11, nextRound: 7, activeDelegates: 1 },
// Round 7 - milestone change
{ height: 12, round: 7, roundHeight: 12, nextRound: 7, activeDelegates: 3 },
{ height: 13, round: 7, roundHeight: 12, nextRound: 7, activeDelegates: 3 },
{ height: 14, round: 7, roundHeight: 12, nextRound: 8, activeDelegates: 3 },
// Round 8
{ height: 15, round: 8, roundHeight: 15, nextRound: 8, activeDelegates: 3 },
];

const milestones = testVector.reduce((acc, vector) => acc.set(vector.height, vector), new Map());

Managers.configManager.set("milestones", [...milestones.values()]);

Managers.configManager.getMilestone = jest.fn().mockImplementation((height) => milestones.get(height));
const config = { ...devnet, milestones };
Managers.configManager.setConfig(config);

testVector.forEach(({ height, round, roundHeight, nextRound, activeDelegates }) => {
const result = calculateRound(height);
Expand All @@ -59,6 +112,23 @@ describe("Round Calculator", () => {
expect(result.maxDelegates).toBe(activeDelegates);
});
});

it("should throw if active delegates is not changed on new round", () => {
const milestones = [
{ height: 1, activeDelegates: 3 },
{ height: 3, activeDelegates: 4 }, // Next milestone should be 4
];

// @ts-ignore
Managers.configManager.validateMilestones = jest.fn();

const config = { ...devnet, milestones };
Managers.configManager.setConfig(config);

calculateRound(1);
calculateRound(2);
expect(() => calculateRound(3)).toThrowError(Errors.InvalidMilestoneConfigurationError);
});
});
});
});

0 comments on commit 2d3fe09

Please sign in to comment.