async resets.

This commit is contained in:
Christopher Jeffrey 2016-02-19 05:54:23 -08:00
parent 053775ffac
commit 7df05b971d
2 changed files with 68 additions and 44 deletions

View File

@ -246,8 +246,11 @@ Chain.prototype._preload = function _preload(callback) {
stream.on('error', function(err) {
var start = Math.max(0, height - 2);
self.resetHeight(start);
return callback(err, start + 1);
self.resetHeightAsync(start, function(e) {
if (e)
throw e;
return callback(err, start + 1);
});
});
stream.on('data', function(data) {
@ -282,8 +285,11 @@ Chain.prototype._preload = function _preload(callback) {
if (lastEntry && entry.prevBlock !== lastEntry.hash) {
start = Math.max(0, height - 2);
stream.destroy();
self.resetHeight(start);
return callback(new Error('Corrupt headers.'), start + 1);
self.resetHeightAsync(start, function(e) {
if (e)
throw e;
return callback(new Error('Corrupt headers.'), start + 1);
});
}
// Verify the block headers. We don't want to
@ -291,8 +297,11 @@ Chain.prototype._preload = function _preload(callback) {
if (!block.verify()) {
start = Math.max(0, height - 2);
stream.destroy();
self.resetHeight(start);
return callback(new Error('Bad headers.'), start + 1);
self.resetHeightAsync(start, function(e) {
if (e)
throw e;
return callback(new Error('Bad headers.'), start + 1);
});
}
lastEntry = entry;
@ -768,31 +777,34 @@ Chain.prototype.revertHeight = function revertHeight(height, callback) {
if (chainHeight === height)
return done();
this.resetHeight(height);
if (!this.blockdb)
return done();
this.blockdb.getHeight(function(err, blockHeight) {
this.resetHeightAsync(height, function(err) {
if (err)
return done(err);
if (blockHeight < 0)
return done(new Error('Bad block height.'));
if (blockHeight < height)
return done(new Error('Cannot reset height.'));
if (blockHeight === height)
if (!self.blockdb)
return done();
self.blockdb.resetHeight(height, function(err) {
self.blockdb.getHeight(function(err, blockHeight) {
if (err)
return done(err);
return done();
}, function(block) {
self.emit('remove block', block);
if (blockHeight < 0)
return done(new Error('Bad block height.'));
if (blockHeight < height)
return done(new Error('Cannot reset height.'));
if (blockHeight === height)
return done();
self.blockdb.resetHeight(height, function(err) {
if (err)
return done(err);
return done();
}, function(block) {
self.emit('remove block', block);
});
});
});
};
@ -809,16 +821,19 @@ Chain.prototype._revertLast = function _revertLast(existing, callback) {
callback(err, result);
}
this.resetHeight(existing.height - 1);
this._removeBlock(existing.hash, function(err, existingBlock) {
this.resetHeightAsync(existing.height - 1, function(err) {
if (err)
return done(err);
if (existingBlock)
self.emit('remove block', existingBlock);
self._removeBlock(existing.hash, function(err, existingBlock) {
if (err)
return done(err);
return done();
if (existingBlock)
self.emit('remove block', existingBlock);
return done();
});
});
};
@ -859,8 +874,7 @@ Chain.prototype.syncHeight = function syncHeight(callback) {
if (blockHeight < chainHeight) {
utils.debug('BlockDB is higher than ChainDB. Syncing...');
self.resetHeight(blockHeight);
return done();
return self.resetHeightAsync(blockHeight, done);
}
if (blockHeight > chainHeight) {

View File

@ -295,7 +295,7 @@ ChainDB.prototype.getSync = function getSync(height) {
return entry;
};
ChainDB.prototype.getAsync = function getAsync(height, callback) {
ChainDB.prototype.getAsync = function getAsync(height, callback, force) {
var self = this;
callback = utils.asyncify(callback);
@ -312,8 +312,10 @@ ChainDB.prototype.getAsync = function getAsync(height, callback) {
if (height < 0 || height == null)
return callback();
if ((height + 1) * BLOCK_SIZE > this.size)
return callback();
if (!force) {
if ((height + 1) * BLOCK_SIZE > this.size)
return callback();
}
return this._readAsync(BLOCK_SIZE, height * BLOCK_SIZE, function(err, data) {
var entry;
@ -341,7 +343,11 @@ ChainDB.prototype.saveSync = function saveSync(entry) {
var raw, offset;
assert(entry.height >= 0);
assert(entry.height * BLOCK_SIZE === this.size);
if (entry.height * BLOCK_SIZE !== this.size) {
utils.debug('Warning attempt to write to height: %d/%d', this.height);
return;
}
// Cache the past 1001 blocks in memory
// (necessary for isSuperMajority)
@ -363,7 +369,11 @@ ChainDB.prototype.saveAsync = function saveAsync(entry, callback) {
callback = utils.asyncify(callback);
assert(entry.height >= 0);
assert(entry.height * BLOCK_SIZE === this.size);
if (entry.height * BLOCK_SIZE !== this.size) {
utils.debug('Warning attempt to write to height: %d/%d', this.height);
return callback();
}
// Cache the past 1001 blocks in memory
// (necessary for isSuperMajority)
@ -480,6 +490,13 @@ ChainDB.prototype.resetHeightAsync = function resetHeightAsync(height, callback)
assert(height <= count - 1);
assert(this.tip);
this.size = size;
this.highest = height;
this.tip = this.get(height);
assert(this.tip);
this.height = this.tip.height;
this.emit('tip', this.tip);
for (i = height + 1; i < count; i++)
dropEntry(i);
@ -493,7 +510,7 @@ ChainDB.prototype.resetHeightAsync = function resetHeightAsync(height, callback)
delete self.heightLookup[existing.hash];
if (!--pending)
done();
});
}, true);
}
function done(err) {
@ -514,13 +531,6 @@ ChainDB.prototype.resetHeightAsync = function resetHeightAsync(height, callback)
if (err)
return callback(err);
self.size = size;
self.highest = height;
self.tip = self.get(height);
assert(self.tip);
self.height = self.tip.height;
self.emit('tip', self.tip);
return callback();
});
}