diff --git a/app/lib/dal/fileDALs/BlockDAL.js b/app/lib/dal/fileDALs/BlockDAL.js index 78ab56000872354e278ae7061b3b78d184cf28e5..d51a57d84f1a0cea19df0102e9c5c2c2200a93e4 100644 --- a/app/lib/dal/fileDALs/BlockDAL.js +++ b/app/lib/dal/fileDALs/BlockDAL.js @@ -65,6 +65,7 @@ function BlockDAL(loki, rootFS, getLowerWindowBlock) { }); this.blocksDB = blocksDB; + this.forksDB = forksDB; this.collection = collection; this.getBlocks = (start, end) => { diff --git a/app/service/BlockchainService.js b/app/service/BlockchainService.js index 69b62c8926dc8ae39b1d808939742a5298a52b9f..b2b42d79f75c33170c6249d47c04efc62c76d9d1 100644 --- a/app/service/BlockchainService.js +++ b/app/service/BlockchainService.js @@ -19,7 +19,6 @@ var blockchainDao = require('../lib/blockchainDao'); var blockchainCtx = require('../lib/blockchainContext'); const CHECK_ALL_RULES = true; -const FROM_PULL = true; module.exports = function (conf, dal, PeeringService) { return new BlockchainService(conf, dal, PeeringService); @@ -128,6 +127,17 @@ function BlockchainService (conf, mainDAL, pair) { let last = branch[branch.length - 1]; if (other.number == last.number + 1 && other.previousHash == last.hash) { branch.push(other); + } else if (branch[1]) { + // We try to find out if another fork block can be forked + let diff = other.number - branch[0].number; + if (diff > 0 && branch[diff - 1] && branch[diff - 1].hash == other.previousHash) { + // We duplicate the branch, and we add the block to this second branch + branches.push(branch.slice()); + // First we remove the blocks that are not part of the fork + branch.splice(diff, branch.length - diff); + branch.push(other); + j++; + } } } } @@ -150,12 +160,12 @@ function BlockchainService (conf, mainDAL, pair) { // TODO prune all forks }); - this.submitBlock = function (obj, doCheck, fromPull) { + this.submitBlock = function (obj, doCheck) { return Q.Promise(function(resolve, reject){ // FIFO: only admit one block at a time blockFifo.push(function(blockIsProcessed) { return co(function *() { - let res = yield checkAndAddBlock(obj, doCheck, fromPull); + let res = yield checkAndAddBlock(obj, doCheck); resolve(res); blockIsProcessed(); }) @@ -167,7 +177,7 @@ function BlockchainService (conf, mainDAL, pair) { }); }; - function checkAndAddBlock(obj, doCheck, fromPull) { + function checkAndAddBlock(obj, doCheck) { return co(function *() { let existing = yield mainDAL.getBlockByNumberAndHashOrNull(obj.number, obj.hash); if (existing) { @@ -190,7 +200,7 @@ function BlockchainService (conf, mainDAL, pair) { throw 'Block out of fork window'; } let absolute = yield mainDAL.getAbsoluteBlockByNumberAndHash(obj.number, obj.hash); - if (absolute && !fromPull) { + if (absolute) { throw 'Already processed side block #' + obj.number + '-' + obj.hash; } let res = yield mainContext.addSideBlock(obj, doCheck); @@ -271,7 +281,7 @@ function BlockchainService (conf, mainDAL, pair) { for (let i = 0, len = chain.length; i < len; i++) { let block = chain[i]; logger.debug('SWITCH: apply side block #%s-%s -> #%s-%s...', block.number, block.hash, block.number - 1, block.previousHash); - yield checkAndAddBlock(block, CHECK_ALL_RULES, FROM_PULL); + yield checkAndAddBlock(block, CHECK_ALL_RULES); } }); } @@ -1260,6 +1270,10 @@ function BlockchainService (conf, mainDAL, pair) { } this.saveBlocksInMainBranch = (blocks, targetLastNumber) => co(function *() { + // VERY FIRST: parameters, otherwise we compute wrong variables such as UDTime + if (blocks[0].number == 0) { + yield that.saveParametersForRootBlock(blocks[0]); + } // Insert a bunch of blocks let lastPrevious = blocks[0].number == 0 ? null : yield mainDAL.getBlock(blocks[0].number - 1); let rootBlock = (blocks[0].number == 0 ? blocks[0] : null) || (yield mainDAL.getBlockOrNull(0)); diff --git a/app/service/PeeringService.js b/app/service/PeeringService.js index 4c3bd9219a603eba740bce19d154120277f63fa2..5bff84f83270d40d259f387f20d51c1a4bd0595d 100644 --- a/app/service/PeeringService.js +++ b/app/service/PeeringService.js @@ -14,8 +14,6 @@ var constants = require('../lib/constants'); var localValidator = require('../lib/localValidator'); var blockchainCtx = require('../lib/blockchainContext'); -const FROM_PULL = true; - function PeeringService(server, pair, dal) { var conf = server.conf; @@ -259,14 +257,14 @@ function PeeringService(server, pair, dal) { logger.info("Try with %s", p.getURL()); let node = yield Q.nfcall(p.connect); try { - let downloaded = yield Q.nfcall(node.blockchain.current); + let downloaded = yield Q.nfcall(node.blockchain.block, current.number + 1); if (!downloaded) { yield dal.setPeerDown(p.pubkey); } while (downloaded) { logger.info("Downloaded block #%s from peer %s", downloaded.number, p.getNamedURL()); downloaded = rawifyTransactions(downloaded); - let res = yield server.BlockchainService.submitBlock(downloaded, true, FROM_PULL); + let res = yield server.BlockchainService.submitBlock(downloaded, true); if (!res.fork) { let nowCurrent = yield dal.getCurrentBlockOrNull(); yield server.BlockchainService.tryToFork(nowCurrent); @@ -274,7 +272,7 @@ function PeeringService(server, pair, dal) { if (downloaded.number == 0) { downloaded = null; } else { - downloaded = yield Q.nfcall(node.blockchain.block, downloaded.number - 1); + downloaded = yield Q.nfcall(node.blockchain.block, downloaded.number + 1); } } } catch (err) {