chain: more refactoring.

This commit is contained in:
Christopher Jeffrey 2016-11-30 13:09:33 -08:00
parent ff5eddbebb
commit cfd7ec8a64
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD

View File

@ -1210,8 +1210,7 @@ Chain.prototype.add = co(function* add(block) {
Chain.prototype._add = co(function* add(block) {
var ret = new VerifyResult();
var initial = true;
var hash, height, checkpoint;
var orphan, entry, prev;
var hash, height, orphan, entry, prev;
while (block) {
hash = block.hash('hex');
@ -1236,11 +1235,21 @@ Chain.prototype._add = co(function* add(block) {
throw new VerifyError(block, 'duplicate', 'duplicate', 0);
}
// If the block is already known to be
// an orphan, ignore it.
// if (this.hasOrphan(hash)) {
// this.emit('orphan', block, block.getCoinbaseHeight());
// throw new VerifyError(block, 'duplicate', 'duplicate', 0);
// }
// The orphan chain may have forked.
// if (this.isOrphanFork(block))
// throw new VerifyError(block, 'invalid', 'bad-prevblk', 0);
// If the block is already known to be
// an orphan, ignore it.
orphan = this.orphan.map[block.prevBlock];
if (orphan) {
// The orphan chain forked.
if (orphan.hash('hex') !== hash) {
this.emit('fork', block,
block.getCoinbaseHeight(),
@ -1290,29 +1299,12 @@ Chain.prototype._add = co(function* add(block) {
if (height > this.bestHeight)
this.bestHeight = height;
// Verify the checkpoint.
if (this.options.useCheckpoints) {
checkpoint = this.network.checkpoints[height];
if (checkpoint) {
// Someone is either mining on top of
// an old block for no reason, or the
// consensus protocol is broken and
// there was a 20k+ block reorg.
if (hash !== checkpoint) {
this.logger.warning('Checkpoint mismatch!');
this.purgeOrphans();
this.emit('fork', block, height, checkpoint);
throw new VerifyError(block,
'checkpoint',
'checkpoint mismatch',
100);
}
this.emit('checkpoint', block, height);
}
// Verify a checkpoint if there is one.
if (!this.verifyCheckpoint(hash, height)) {
throw new VerifyError(block,
'checkpoint',
'checkpoint mismatch',
100);
}
// Explanation: we try to keep as much data
@ -1446,6 +1438,68 @@ Chain.prototype.finish = function finish(block, entry) {
time);
};
/**
* Test whether a block is a on a forked orphan chain.
* @private
* @param {Block} block
* @returns {Boolean}
*/
Chain.prototype.isOrphanFork = function isOrphanFork(block) {
var orphan = this.orphan.map[block.prevBlock];
if (!orphan)
return false;
assert(orphan.hash('hex') !== hash);
this.emit('fork', block,
block.getCoinbaseHeight(),
orphan.hash('hex'));
this.resolveOrphan(block.prevBlock);
this.storeOrphan(block);
return true;
};
/**
* Verify a block hash and height against the checkpoints.
* @private
* @param {Hash} hash
* @param {Number} height
* @returns {Boolean}
*/
Chain.prototype.verifyCheckpoint = function verifyCheckpoint(hash, height) {
var checkpoint;
if (!this.options.useCheckpoints)
return true;
checkpoint = this.network.checkpoints[height];
if (!checkpoint)
return true;
if (hash === checkpoint) {
this.emit('checkpoint', block, height);
return true;
}
// Someone is either mining on top of
// an old block for no reason, or the
// consensus protocol is broken and
// there was a 20k+ block reorg.
this.logger.warning('Checkpoint mismatch!');
this.purgeOrphans();
this.emit('fork', block, height, checkpoint);
return false;
};
/**
* Store an orphan.
* @private