diff --git a/app/lib/blockchainContext.js b/app/lib/blockchainContext.js index e842ce59a5522440608f9659bd081da575325a5c..e5eb57ea4955aab169d2ba8850e38f05ccbc2cc1 100644 --- a/app/lib/blockchainContext.js +++ b/app/lib/blockchainContext.js @@ -106,7 +106,7 @@ function BlockchainContext(conf, dal) { this.revertBlock = (block) => co(function *() { let previousBlock = yield dal.getBlockByNumberAndHashOrNull(block.number - 1, block.previousHash || ''); // Set the block as SIDE block (equivalent to removal from main branch) - dal.blockDAL.setSideBlock(block, previousBlock); + yield dal.blockDAL.setSideBlock(block, previousBlock); yield undoCertifications(block); yield undoLinks(block); if (previousBlock) { @@ -308,13 +308,13 @@ function BlockchainContext(conf, dal) { } // Undo renew (only remove last membership IN document) for (let i = 0, len = block.actives.length; i < len; i++) { - let msRaw = block.joiners[i]; + let msRaw = block.actives[i]; let ms = Membership.statics.fromInline(msRaw, 'IN', conf.currency); yield dal.unRenewIdentity(ms.issuer); } // Undo leavers (forget about their last membership OUT document) for (let i = 0, len = block.leavers.length; i < len; i++) { - let msRaw = block.joiners[i]; + let msRaw = block.leavers[i]; let ms = Membership.statics.fromInline(msRaw, 'OUT', conf.currency); yield dal.unLeaveIdentity(ms.issuer); } diff --git a/app/lib/dal/fileDAL.js b/app/lib/dal/fileDAL.js index c5959b881965cb73b08a235dd9ec348c30072d6a..d5a3aa7eaedda3127e02f59682466afebbbaa7a4 100644 --- a/app/lib/dal/fileDAL.js +++ b/app/lib/dal/fileDAL.js @@ -295,10 +295,6 @@ function FileDAL(profile, home, localDir, myFS, parentFileDAL, dalName, loki) { this.getBlocksBetween = (start, end) => Q(this.blockDAL.getBlocks(Math.max(0, start), end)); - this.getLastSavedBlockFileNumber = function() { - return that.blockDAL.getLastSavedBlockFileNumber(); - }; - this.getBlockCurrent = function(done) { return that.blockDAL.getCurrent() .then(function(current) { diff --git a/app/lib/dal/fileDALs/BlockDAL.js b/app/lib/dal/fileDALs/BlockDAL.js index d2e1e0c8ab3dcee36e1e74d1f144ea6cea2d1643..39dfbc7619aabc2f2ee7126400e76dc3f7bf3180 100644 --- a/app/lib/dal/fileDALs/BlockDAL.js +++ b/app/lib/dal/fileDALs/BlockDAL.js @@ -66,12 +66,6 @@ function BlockDAL(loki, rootFS, getLowerWindowBlock) { this.blocksDB = blocksDB; this.collection = collection; - this.getLastSavedBlockFileNumber = () => { - let last = collection.chain().simplesort('number', true).limit(1).data()[0]; - if (last) return Q(last.number); - return Q(-1); - }; - this.getBlocks = (start, end) => { let lowerInLoki = collection.chain().simplesort('number').limit(1).data()[0]; let lokiBlocks = blocksDB.branchResultset().find({ @@ -168,7 +162,7 @@ function BlockDAL(loki, rootFS, getLowerWindowBlock) { return Q(block); }; - this.setSideBlock = (block, previousBlock) => { + this.setSideBlock = (block, previousBlock) => co(function *() { let existing = collection.find({ $and: [{ number: block.number @@ -181,7 +175,13 @@ function BlockDAL(loki, rootFS, getLowerWindowBlock) { collection.update(found); }); current = previousBlock; - }; + let lowerInLoki = collection.chain().simplesort('number').limit(1).data()[0]; + if (lowerInLoki.number > 0) { + let newLower = yield that.getBlock(lowerInLoki.number - 1); + yield rootFS.remove(pathOfBlock(newLower.number) + blockFileName(newLower.number) + '.json'); + collection.insert(newLower); + } + }); this.migrateOldBlocks = () => co(function *() { let number = yield getLowerWindowBlock(); diff --git a/app/lib/sync.js b/app/lib/sync.js index 9cb2661d0ffa48ba8f435e17a249daf2789e76c4..643c4a3b1c268dec46422f86f913d26615a0f8f4 100644 --- a/app/lib/sync.js +++ b/app/lib/sync.js @@ -50,7 +50,6 @@ module.exports = function Synchroniser (server, host, port, conf, interactive) { var node = yield getVucoin(host, port, vucoinOptions); logger.info('Sync started.'); - var lastSavedNumber = yield server.dal.getLastSavedBlockFileNumber(); var lCurrent = yield dal.getCurrentBlockOrNull(); //============ @@ -74,14 +73,14 @@ module.exports = function Synchroniser (server, host, port, conf, interactive) { // Prepare chunks of blocks to be downloaded var chunks = []; - for (let i = lastSavedNumber + 1; i <= remoteNumber; i = i + CONST_BLOCKS_CHUNK) { + for (let i = localNumber + 1; i <= remoteNumber; i = i + CONST_BLOCKS_CHUNK) { chunks.push([i, Math.min(i + CONST_BLOCKS_CHUNK - 1, remoteNumber)]); } // Prepare the array of download promises. The first is the promise of already downloaded blocks // which has not been applied yet. var toApply = [Q.defer()].concat(chunks.map(() => Q.defer())); - toApply[0].resolve([localNumber + 1, lastSavedNumber]); + toApply[0].resolve([localNumber + 1, localNumber]); // Chain download promises, and start download right now chunks.map((chunk, index) => @@ -132,7 +131,7 @@ module.exports = function Synchroniser (server, host, port, conf, interactive) { } // Specific treatment for nocautious - if (!cautious) { + if (!cautious && toApply.length > 1) { let lastChunk = yield toApplyNoCautious[toApplyNoCautious.length - 1].promise; let lastBlocks = lastChunk[2]; let lastBlock = lastBlocks[lastBlocks.length - 1]; diff --git a/bin/ucoind b/bin/ucoind index dffece8612d4db62093dfcbad54f4010cd893b44..cb11396b5bf399eceff327d80a95d1d4cf545f38 100755 --- a/bin/ucoind +++ b/bin/ucoind @@ -6,6 +6,7 @@ if (!~process.execArgv.indexOf('--harmony')) { } var async = require('async'); +var co = require('co'); var Q = require('q'); var _ = require('underscore'); var program = require('commander'); @@ -232,6 +233,46 @@ program }); })); +program + .command('revert [count]') + .description('Revert (undo + remove) the top [count] blocks from the blockchain. EXPERIMENTAL') + .action(service(function (count, server) { + co(function *() { + try { + for (let i = 0; i < count; i++) { + yield server.revert(); + } + } catch (err) { + logger.error('Error during revert:', err); + } + // Save DB + server.disconnect() + .catch(() => null) + .then(function(){ + process.exit(); + }); + }); + })); + +program + .command('revert-to [number]') + .description('Revert (undo + remove) top blockchain blocks until block #[number] is reached. EXPERIMENTAL') + .action(service(function (number, server) { + co(function *() { + try { + yield server.revertTo(number); + } catch (err) { + logger.error('Error during revert:', err); + } + // Save DB + server.disconnect() + .catch(() => null) + .then(function(){ + process.exit(); + }); + }); + })); + program .command('gen-next [host] [port] [diff]') .description('Tries to generate the next block of the blockchain') diff --git a/server.js b/server.js index 22fd7dec8bf6ea3ac7816275af332a549d575b1b..d7964400ed4dd745d8940d4c79c9300e0e83482d 100644 --- a/server.js +++ b/server.js @@ -352,6 +352,17 @@ function Server (dbConf, overrideConf) { this.revert = () => this.BlockchainService.revertCurrentBlock(); + this.revertTo = (number) => co(function *() { + let current = yield that.BlockchainService.current(); + for (let i = 0, count = current.number - number; i < count; i++) { + yield that.BlockchainService.revertCurrentBlock(); + } + if (current.number <= number) { + logger.warn('Already reached'); + } + that.BlockchainService.revertCurrentBlock(); + }); + this.singleWriteStream = function (onError, onSuccess) { return new TempStream(that, onError, onSuccess); };