chain: more refactoring.
This commit is contained in:
parent
ff5eddbebb
commit
cfd7ec8a64
@ -1210,8 +1210,7 @@ Chain.prototype.add = co(function* add(block) {
|
|||||||
Chain.prototype._add = co(function* add(block) {
|
Chain.prototype._add = co(function* add(block) {
|
||||||
var ret = new VerifyResult();
|
var ret = new VerifyResult();
|
||||||
var initial = true;
|
var initial = true;
|
||||||
var hash, height, checkpoint;
|
var hash, height, orphan, entry, prev;
|
||||||
var orphan, entry, prev;
|
|
||||||
|
|
||||||
while (block) {
|
while (block) {
|
||||||
hash = block.hash('hex');
|
hash = block.hash('hex');
|
||||||
@ -1236,11 +1235,21 @@ Chain.prototype._add = co(function* add(block) {
|
|||||||
throw new VerifyError(block, 'duplicate', 'duplicate', 0);
|
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
|
// If the block is already known to be
|
||||||
// an orphan, ignore it.
|
// an orphan, ignore it.
|
||||||
orphan = this.orphan.map[block.prevBlock];
|
orphan = this.orphan.map[block.prevBlock];
|
||||||
if (orphan) {
|
if (orphan) {
|
||||||
// The orphan chain forked.
|
|
||||||
if (orphan.hash('hex') !== hash) {
|
if (orphan.hash('hex') !== hash) {
|
||||||
this.emit('fork', block,
|
this.emit('fork', block,
|
||||||
block.getCoinbaseHeight(),
|
block.getCoinbaseHeight(),
|
||||||
@ -1290,29 +1299,12 @@ Chain.prototype._add = co(function* add(block) {
|
|||||||
if (height > this.bestHeight)
|
if (height > this.bestHeight)
|
||||||
this.bestHeight = height;
|
this.bestHeight = height;
|
||||||
|
|
||||||
// Verify the checkpoint.
|
// Verify a checkpoint if there is one.
|
||||||
if (this.options.useCheckpoints) {
|
if (!this.verifyCheckpoint(hash, height)) {
|
||||||
checkpoint = this.network.checkpoints[height];
|
throw new VerifyError(block,
|
||||||
if (checkpoint) {
|
'checkpoint',
|
||||||
// Someone is either mining on top of
|
'checkpoint mismatch',
|
||||||
// an old block for no reason, or the
|
100);
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Explanation: we try to keep as much data
|
// Explanation: we try to keep as much data
|
||||||
@ -1446,6 +1438,68 @@ Chain.prototype.finish = function finish(block, entry) {
|
|||||||
time);
|
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.
|
* Store an orphan.
|
||||||
* @private
|
* @private
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user