lisk-framework
Version:
Lisk blockchain application platform
73 lines • 4.2 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.forkChoice = exports.isDifferentChain = exports.isTieBreak = exports.isDoubleForging = exports.isDuplicateBlock = exports.isIdenticalBlock = exports.isValidBlock = exports.isLastAppliedBlockReceivedWithinForgingSlot = exports.isBlockReceivedWithinForgingSlot = exports.forgingSlot = exports.ForkStatus = void 0;
var ForkStatus;
(function (ForkStatus) {
ForkStatus[ForkStatus["IDENTICAL_BLOCK"] = 1] = "IDENTICAL_BLOCK";
ForkStatus[ForkStatus["VALID_BLOCK"] = 2] = "VALID_BLOCK";
ForkStatus[ForkStatus["DOUBLE_FORGING"] = 3] = "DOUBLE_FORGING";
ForkStatus[ForkStatus["TIE_BREAK"] = 4] = "TIE_BREAK";
ForkStatus[ForkStatus["DIFFERENT_CHAIN"] = 5] = "DIFFERENT_CHAIN";
ForkStatus[ForkStatus["DISCARD"] = 6] = "DISCARD";
})(ForkStatus = exports.ForkStatus || (exports.ForkStatus = {}));
const forgingSlot = (slots, block) => slots.getSlotNumber(block.timestamp);
exports.forgingSlot = forgingSlot;
const isBlockReceivedWithinForgingSlot = (slots, { timestamp, receivedAt }) => slots.isWithinTimeslot(slots.getSlotNumber(timestamp), receivedAt !== null && receivedAt !== void 0 ? receivedAt : Math.floor(Date.now() / 1000));
exports.isBlockReceivedWithinForgingSlot = isBlockReceivedWithinForgingSlot;
const isLastAppliedBlockReceivedWithinForgingSlot = (slots, lastAppliedBlock) => {
if (!lastAppliedBlock.receivedAt) {
return true;
}
return (0, exports.isBlockReceivedWithinForgingSlot)(slots, lastAppliedBlock);
};
exports.isLastAppliedBlockReceivedWithinForgingSlot = isLastAppliedBlockReceivedWithinForgingSlot;
const isValidBlock = (lastBlock, currentBlock) => lastBlock.height + 1 === currentBlock.height && lastBlock.id.equals(currentBlock.previousBlockID);
exports.isValidBlock = isValidBlock;
const isIdenticalBlock = (lastBlock, currentBlock) => lastBlock.id.equals(currentBlock.id);
exports.isIdenticalBlock = isIdenticalBlock;
const isDuplicateBlock = (lastBlock, currentBlock) => lastBlock.height === currentBlock.height &&
lastBlock.maxHeightPrevoted === currentBlock.maxHeightPrevoted &&
lastBlock.previousBlockID.equals(currentBlock.previousBlockID);
exports.isDuplicateBlock = isDuplicateBlock;
const isDoubleForging = (lastBlock, currentBlock) => (0, exports.isDuplicateBlock)(lastBlock, currentBlock) &&
lastBlock.generatorAddress.equals(currentBlock.generatorAddress);
exports.isDoubleForging = isDoubleForging;
const isTieBreak = ({ slots, lastAppliedBlock, receivedBlock, }) => (0, exports.isDuplicateBlock)(lastAppliedBlock, receivedBlock) &&
(0, exports.forgingSlot)(slots, lastAppliedBlock) < (0, exports.forgingSlot)(slots, receivedBlock) &&
!(0, exports.isLastAppliedBlockReceivedWithinForgingSlot)(slots, lastAppliedBlock) &&
(0, exports.isBlockReceivedWithinForgingSlot)(slots, receivedBlock);
exports.isTieBreak = isTieBreak;
const isDifferentChain = (lastBlock, currentBlock) => {
const maxHeightPrevoted = lastBlock.maxHeightPrevoted || 0;
return (maxHeightPrevoted < currentBlock.maxHeightPrevoted ||
(lastBlock.height < currentBlock.height && maxHeightPrevoted === currentBlock.maxHeightPrevoted));
};
exports.isDifferentChain = isDifferentChain;
const forkChoice = (blockHeader, lastBlockHeader, slots) => {
const receivedBFTHeader = {
...blockHeader.toObject(),
receivedAt: Math.floor(Date.now() / 1000),
};
if ((0, exports.isValidBlock)(lastBlockHeader, blockHeader)) {
return ForkStatus.VALID_BLOCK;
}
if ((0, exports.isIdenticalBlock)(lastBlockHeader, blockHeader)) {
return ForkStatus.IDENTICAL_BLOCK;
}
if ((0, exports.isDoubleForging)(lastBlockHeader, blockHeader)) {
return ForkStatus.DOUBLE_FORGING;
}
if ((0, exports.isTieBreak)({
slots,
lastAppliedBlock: lastBlockHeader,
receivedBlock: receivedBFTHeader,
})) {
return ForkStatus.TIE_BREAK;
}
if ((0, exports.isDifferentChain)(lastBlockHeader, blockHeader)) {
return ForkStatus.DIFFERENT_CHAIN;
}
return ForkStatus.DISCARD;
};
exports.forkChoice = forkChoice;
//# sourceMappingURL=fork_choice_rule.js.map
;