Skip to content

Commit

Permalink
Verify block slot window
Browse files Browse the repository at this point in the history
  • Loading branch information
ralfshift committed Jan 8, 2018
1 parent f72907c commit a1f5f91
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 0 deletions.
1 change: 1 addition & 0 deletions helpers/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ module.exports = {
activeDelegates: 101,
addressLength: 208,
blockHeaderLength: 248,
blockSlotWindow: 5, // window in which a slot could be accepted
blockTime: 27000,
blockReceiptTimeOut: 27*2, // 2 blocks
confirmationLength: 77,
Expand Down
4 changes: 4 additions & 0 deletions modules/blocks/process.js
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,10 @@ __private.receiveForkOne = function (block, lastBlock, cb) {
return setImmediate(seriesCb);
}
},
// Verify block slot window
function (seriesCb) {
modules.delegates.validateBlockSlot(tmp_block, seriesCb);
},
// Delete last 2 blocks
modules.blocks.chain.deleteLastBlock,
modules.blocks.chain.deleteLastBlock
Expand Down
66 changes: 66 additions & 0 deletions modules/blocks/verify.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use strict';

var async = require('async');
var _ = require('lodash');
var BlockReward = require('../../logic/blockReward.js');
var constants = require('../../helpers/constants.js');
var crypto = require('crypto');
Expand All @@ -11,6 +12,7 @@ var exceptions = require('../../helpers/exceptions.js');
var modules, library, self, __private = {};

__private.blockReward = new BlockReward();
__private.lastNBlockIds = [];

function Verify (logger, block, transaction, db) {
library = {
Expand Down Expand Up @@ -326,6 +328,68 @@ __private.verifyBlockSlot = function (block, lastBlock, result) {
return result;
};

/**
* Verify block is not one of the last {constants.blockSlotWindow} saved blocks
*
* @private
* @method verifyAgainstLastNBlockIds
* @param {Object} block Target block
* @param {Object} result Verification results
* @return {Object} result Verification results
* @return {boolean} result.verified Indicator that verification passed
* @return {Array} result.errors Array of validation errors
*/
__private.verifyAgainstLastNBlockIds = function (block, result) {
if (__private.lastNBlockIds.indexOf(block.id) !== -1) {
result.errors.push('Block already exists in chain');
};

return result;
};

/**
* Verify block slot window according to application time
*
* @private
* @method verifyBlockSlotWindow
* @param {Object} block Target block
* @return {Object} result Verification results
* @return {boolean} result.verified Indicator that verification passed
* @return {Array} result.errors Array of validation errors
*/
__private.verifyBlockSlotWindow = function (block, result) {
var currentApplicationSlot = slots.getSlotNumber();
var blockSlot = slots.getSlotNumber(block.timestamp);

// Reject block if it's slot is older than constants.blockSlotWindow
if (currentApplicationSlot - blockSlot > constants.blockSlotWindow) {
result.errors.push('Block slot is too old');
}

// Reject block if it's slot is in the future
if (currentApplicationSlot < blockSlot) {
result.errors.push('Block slot is in the future');
}

return result;
};

Verify.prototype.onBlockchainReady = function () {
return library.db.query(sql.loadLastNBlockIds, {limit: constants.blockSlotWindow}).then(function (blockIds) {
__private.lastNBlockIds = _.map(blockIds, 'id');
}).catch(function (err) {
library.logger.error('Unable to load last ' + constants.blockSlotWindow + ' block ids');
library.logger.error(err);
});
};

Verify.prototype.onNewBlock = function (block) {
__private.lastNBlockIds.push(block.id);
if (__private.lastNBlockIds.length > constants.blockSlotWindow) {
__private.lastNBlockIds.shift();
}
};

/**
* Verify block before fork detection and return all possible errors related to block
*
Expand All @@ -345,6 +409,8 @@ Verify.prototype.verifyReceipt = function (block) {

result = __private.verifySignature(block, result);
result = __private.verifyPreviousBlock(block, result);
result = __private.verifyAgainstLastNBlockIds(block, result);
result = __private.verifyBlockSlotWindow(block, result);
result = __private.verifyVersion(block, result);
result = __private.verifyReward(block, result);
result = __private.verifyId(block, result);
Expand Down
2 changes: 2 additions & 0 deletions sql/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ var BlocksSql = {
loadBlocksOffset: 'SELECT * FROM full_blocks_list WHERE "b_height" >= ${offset} AND "b_height" < ${limit} ORDER BY "b_height", "t_rowId"',

loadLastBlock: 'SELECT * FROM full_blocks_list WHERE "b_height" = (SELECT MAX("height") FROM blocks) ORDER BY "b_height", "t_rowId"',

loadLastNBlockIds: 'SELECT "id" FROM blocks ORDER BY "height" DESC LIMIT ${limit}',

getBlockId: 'SELECT "id" FROM blocks WHERE "id" = ${id}',

Expand Down

0 comments on commit a1f5f91

Please sign in to comment.