Added the checkpoints back in.
This commit is contained in:
parent
408243de4b
commit
07a4b706c7
@ -482,6 +482,7 @@ BlockService.prototype._onBlock = function(block) {
|
|||||||
BlockService.prototype._setListeners = function() {
|
BlockService.prototype._setListeners = function() {
|
||||||
|
|
||||||
this._header.once('headers', this._onAllHeaders.bind(this));
|
this._header.once('headers', this._onAllHeaders.bind(this));
|
||||||
|
this._header.on('reorg', this._handleReorg.bind(this));
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,7 @@ var HeaderService = function(options) {
|
|||||||
|
|
||||||
this.subscriptions = {};
|
this.subscriptions = {};
|
||||||
this.subscriptions.block = [];
|
this.subscriptions.block = [];
|
||||||
|
this._checkpoint = options.checkpoint || 2000;
|
||||||
this.GENESIS_HASH = constants.BITCOIN_GENESIS_HASH[this.node.network];
|
this.GENESIS_HASH = constants.BITCOIN_GENESIS_HASH[this.node.network];
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,9 +94,10 @@ HeaderService.prototype.start = function(callback) {
|
|||||||
function(tip, next) {
|
function(tip, next) {
|
||||||
self._tip = tip;
|
self._tip = tip;
|
||||||
self._originalTip = {
|
self._originalTip = {
|
||||||
height: self._tip.height,
|
hash: self._tip.hash,
|
||||||
hash: self._tip.hash
|
height: self._tip.height
|
||||||
};
|
};
|
||||||
|
|
||||||
if (self._tip.height === 0) {
|
if (self._tip.height === 0) {
|
||||||
|
|
||||||
var genesisHeader = {
|
var genesisHeader = {
|
||||||
@ -128,9 +130,6 @@ HeaderService.prototype.start = function(callback) {
|
|||||||
return callback(err);
|
return callback(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self._headers.size > 0) {
|
|
||||||
self._tip.hash = self._headers.getLastIndex().hash;
|
|
||||||
}
|
|
||||||
self._setListeners();
|
self._setListeners();
|
||||||
self._startSubscriptions();
|
self._startSubscriptions();
|
||||||
callback();
|
callback();
|
||||||
@ -224,7 +223,7 @@ HeaderService.prototype._onHeaders = function(headers) {
|
|||||||
value: self._encoding.encodeHeaderValue(header)
|
value: self._encoding.encodeHeaderValue(header)
|
||||||
});
|
});
|
||||||
prevHeader = header;
|
prevHeader = header;
|
||||||
self._headers.set(header.hash, header);
|
self._headers.set(header.hash, header, header.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
var tipOps = utils.encodeTip(self._tip, self.name);
|
var tipOps = utils.encodeTip(self._tip, self.name);
|
||||||
@ -243,24 +242,33 @@ HeaderService.prototype._onHeaders = function(headers) {
|
|||||||
|
|
||||||
log.debug('Header Service: download complete.');
|
log.debug('Header Service: download complete.');
|
||||||
|
|
||||||
// have we reorg'ed since we've been shutdown?
|
// at this point, we can check our header list to see if our starting tip diverged from the tip
|
||||||
if (self._tip.height > 0) {
|
// that we have now
|
||||||
|
if (self._detectReorg()) {
|
||||||
var headerHash = self._headers.getIndex(self._tip.height).hash;
|
self._handleReorg();
|
||||||
if (self._tip.hash !== headerHash) {
|
return;
|
||||||
|
|
||||||
self.emit('reorg', headerHash, self._headers);
|
|
||||||
return;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug('Header Service: emitting headers to block service.');
|
log.debug('Header Service: emitting headers to block service.');
|
||||||
self.emit('headers', self._headers);
|
self.emit('headers', self._headers);
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
HeaderService.prototype._detectReorg = function() {
|
||||||
|
// is our original tip's height and hash the same after we rewound by the checkpoint amount of blocks
|
||||||
|
// and re-imported? If so, then we've reorg'ed since we've been shut down.
|
||||||
|
if (this._originalTip.hash !== this._headers.getIndex(this._originalTip.height).hash) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
HeaderService.prototype._handleReorg = function() {
|
||||||
|
this.emit('reorg', this._headers.getIndex(this._originalTip.height).hash, this._headers);
|
||||||
|
};
|
||||||
|
|
||||||
HeaderService.prototype._setListeners = function() {
|
HeaderService.prototype._setListeners = function() {
|
||||||
|
|
||||||
this._p2p.once('bestHeight', this._onBestHeight.bind(this));
|
this._p2p.once('bestHeight', this._onBestHeight.bind(this));
|
||||||
@ -287,10 +295,10 @@ HeaderService.prototype._startSync = function() {
|
|||||||
|
|
||||||
HeaderService.prototype._sync = function() {
|
HeaderService.prototype._sync = function() {
|
||||||
|
|
||||||
log.debug('Header Service: download progress: ' + this._tip.height + '/' +
|
log.debug('Header Service: download progress: ' + this._tip.height + '/' +
|
||||||
this._bestHeight + ' (' + (this._tip.height / this._bestHeight*100).toFixed(2) + '%)');
|
this._bestHeight + ' (' + (this._tip.height / this._bestHeight*100).toFixed(2) + '%)');
|
||||||
|
|
||||||
this._p2p.getHeaders({ startHash: this._tip.hash });
|
this._p2p.getHeaders({ startHash: this._tip.hash });
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -302,8 +310,14 @@ HeaderService.prototype._getPersistedHeaders = function(callback) {
|
|||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
var startingHeight = self._tip.height;
|
||||||
|
if (self._tip.height > self._checkpoint) {
|
||||||
|
self._tip.height -= self._checkpoint;
|
||||||
|
}
|
||||||
|
var removalOps = [];
|
||||||
|
|
||||||
var start = self._encoding.encodeHeaderKey(0);
|
var start = self._encoding.encodeHeaderKey(0);
|
||||||
var end = self._encoding.encodeHeaderKey(self._tip.height + 1);
|
var end = self._encoding.encodeHeaderKey(startingHeight + 1);
|
||||||
|
|
||||||
log.debug('Getting persisted headers from genesis block to block ' + (self._tip.height + 1));
|
log.debug('Getting persisted headers from genesis block to block ' + (self._tip.height + 1));
|
||||||
|
|
||||||
@ -320,14 +334,24 @@ HeaderService.prototype._getPersistedHeaders = function(callback) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
stream.on('data', function(data) {
|
stream.on('data', function(data) {
|
||||||
self._headers.set(self._encoding.decodeHeaderKey(data.key).hash, self._encoding.decodeHeaderValue(data.value));
|
var header = self._encoding.decodeHeaderValue(data.value);
|
||||||
|
// any records with a height greater than our current tip height can be scheduled for removal
|
||||||
|
if (header.height > self._tip.height) {
|
||||||
|
removalOps.push({
|
||||||
|
type: 'del',
|
||||||
|
key: data.key
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self._headers.set(self._encoding.decodeHeaderKey(data.key).hash, header, header.height);
|
||||||
});
|
});
|
||||||
|
|
||||||
stream.on('end', function() {
|
stream.on('end', function() {
|
||||||
if (streamErr) {
|
if (streamErr) {
|
||||||
return streamErr;
|
return streamErr;
|
||||||
}
|
}
|
||||||
callback();
|
self._tip.hash = self._headers.getIndex(self._tip.height).hash;
|
||||||
|
self._db.batch(removalOps, callback);
|
||||||
});
|
});
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@ -76,9 +76,14 @@ utils.SimpleMap = function SimpleMap() {
|
|||||||
return array[object[key]];
|
return array[object[key]];
|
||||||
};
|
};
|
||||||
|
|
||||||
this.set = function (key, value) {
|
this.set = function (key, value, pos) {
|
||||||
object[key] = array.length;
|
object[key] = array.length;
|
||||||
array.push(value);
|
|
||||||
|
if (pos >= 0) {
|
||||||
|
array[pos] = value;
|
||||||
|
} else {
|
||||||
|
array.push(value);
|
||||||
|
}
|
||||||
|
|
||||||
this.size = array.length;
|
this.size = array.length;
|
||||||
this.length = array.length;
|
this.length = array.length;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user