UNPKG

lisk-framework

Version:

Lisk blockchain application platform

73 lines 4.2 kB
"use strict"; 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