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

Commit

Permalink
🐛 Fix forging enable condition for zero case
Browse files Browse the repository at this point in the history
  • Loading branch information
shuse2 committed Sep 13, 2021
1 parent a1e9c65 commit da95649
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 21 deletions.
48 changes: 27 additions & 21 deletions framework/src/node/forger/forger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,20 @@ const isSyncedWithNetwork = (lastBlockHeader: BlockHeader, forgingInput: ForgedI
);
};

interface ForgingInfo {
height: number;
maxHeightPrevoted: number;
maxHeightPreviouslyForged: number;
}

const isZeroForgingInfo = (info: ForgingInfo) =>
info.height === 0 && info.maxHeightPrevoted === 0 && info.maxHeightPreviouslyForged === 0;

const IsEqualForgingInfo = (info1: ForgingInfo, info2: ForgingInfo): boolean =>
info1.height === info2.height &&
info1.maxHeightPreviouslyForged === info2.maxHeightPreviouslyForged &&
info1.maxHeightPrevoted === info2.maxHeightPrevoted;

export class Forger {
private readonly _logger: Logger;
private readonly _db: KVStore;
Expand Down Expand Up @@ -223,30 +237,22 @@ export class Forger {
if (!isSyncedWithNetwork(lastBlockHeader, forgingInput)) {
throw new Error('Failed to enable forging as the node is not synced to the network.');
}
const forgerInfo = previouslyForgedMap.get(forgerAddress);
if (overwrite !== true) {
if (forgerInfo !== undefined && !IsEqualForgingInfo(forgerInfo, forgingInput)) {
throw new Error('Failed to enable forging due to contradicting forger info.');
}
if (forgerInfo === undefined && !isZeroForgingInfo(forgingInput)) {
throw new Error('Failed to enable forging due to missing forger info.');
}
}

if (
!overwrite &&
(height !== 0 || maxHeightPrevoted !== 0 || maxHeightPreviouslyForged !== 0)
forgerInfo === undefined ||
(overwrite === true &&
forgerInfo !== undefined &&
!IsEqualForgingInfo(forgingInput, forgerInfo))
) {
// check if forger info exists
if (!previouslyForgedMap.has(forgerAddress)) {
throw new Error('Failed to enable forging due to missing forger info.');
}
// check if forger info matches input
const forgerInfo = previouslyForgedMap.get(forgerAddress);
if (
forgerInfo?.height !== height ||
forgerInfo?.maxHeightPrevoted !== maxHeightPrevoted ||
forgerInfo?.maxHeightPreviouslyForged !== maxHeightPreviouslyForged
) {
throw new Error('Failed to enable forging due to contradicting forger info.');
}
} else {
previouslyForgedMap.set(forgerAddress, {
height,
maxHeightPrevoted,
maxHeightPreviouslyForged,
});
await setPreviouslyForgedMap(this._db, previouslyForgedMap);
this._logger.info(forgingInput, 'Updated forgerInfo');
}
Expand Down
14 changes: 14 additions & 0 deletions framework/test/unit/node/forger/forger.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,20 @@ describe('forger', () => {
).rejects.toThrow('Failed to enable forging due to missing forger info');
});

it('should fail when forger info exists and input is zero', async () => {
await expect(
forgeModule.updateForgingStatus(
getAddressFromPublicKey(Buffer.from(testDelegate.publicKey, 'hex')),
testDelegate.password,
true,
0,
0,
0,
false,
),
).rejects.toThrow('Failed to enable forging due to contradicting forger info');
});

it('should fail when height input is contradicting with saved forger info', async () => {
await expect(
forgeModule.updateForgingStatus(
Expand Down

0 comments on commit da95649

Please sign in to comment.