Fixed reorging.
This commit is contained in:
parent
02ff6c680c
commit
82dd1dfe3f
@ -18,6 +18,7 @@ var AddressService = function(options) {
|
||||
this._header = this.node.services.header;
|
||||
this._block = this.node.services.block;
|
||||
this._timestamp = this.node.services.timestamp;
|
||||
this._transaction = this.node.services.transaction;
|
||||
this._network = this.node.network;
|
||||
this._db = this.node.services.db;
|
||||
|
||||
|
||||
@ -565,7 +565,7 @@ HeaderService.prototype._detectReorg = function(block, callback) {
|
||||
var nextBlock = prevHash === self._lastHeader.hash;
|
||||
|
||||
// this is the last block the block service asked for
|
||||
if (prevHash === this.lastBlockQueried) {
|
||||
if (prevHash === this.lastBlockQueried && this.blockServiceSyncing) {
|
||||
return callback(null, false, true);
|
||||
}
|
||||
|
||||
@ -575,7 +575,7 @@ HeaderService.prototype._detectReorg = function(block, callback) {
|
||||
}
|
||||
|
||||
// could really be a reorg block
|
||||
var key = this._encoding.encodeHeaderHashKey(bcoin.util.revHex(block.prevBlock));
|
||||
var key = this._encoding.encodeHeaderHashKey(prevHash);
|
||||
|
||||
this._db.get(key, function(err, val) {
|
||||
|
||||
@ -621,28 +621,39 @@ HeaderService.prototype._detectStartupReorg = function(callback) {
|
||||
HeaderService.prototype._handleReorg = function(block, header, callback) {
|
||||
|
||||
var self = this;
|
||||
|
||||
self.getAllHeaders(function(err, headers) {
|
||||
|
||||
if (err || !headers) {
|
||||
return callback(err || new Error('Missing headers'));
|
||||
}
|
||||
|
||||
var header = headers.getIndex(self._originalTip.height);
|
||||
var originalTipHeader = headers.getIndex(self._originalTip.height);
|
||||
|
||||
assert(header, 'Atempted to get reorg header for the original tip: ' + self._originalTip.hash +
|
||||
' at height: ' + self._originalTip.height + ' but could not find in the database.');
|
||||
|
||||
var hash = header.hash;
|
||||
var hash = originalTipHeader.hash;
|
||||
|
||||
// reorg from new blocks
|
||||
if (block && header) {
|
||||
|
||||
hash = block.rhash();
|
||||
self._lastHeader = headers.get(header.prevHash);
|
||||
assert(self._lastHeader, 'Expected our reorg block to have a header entry, but it did not.');
|
||||
headers.set(hash, header); // appends to the end
|
||||
self.emit('reorg', hash, headers, block);
|
||||
return callback();
|
||||
|
||||
// this will ensure our own headers collection is correct
|
||||
return self._onReorg(block, headers, function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
self.emit('reorg', hash, headers, block);
|
||||
return callback();
|
||||
});
|
||||
}
|
||||
|
||||
// reorg from startup
|
||||
assert(hash, 'To reorg, we need a hash to reorg to.');
|
||||
self.emit('reorg', hash, headers);
|
||||
callback();
|
||||
@ -651,6 +662,41 @@ HeaderService.prototype._handleReorg = function(block, header, callback) {
|
||||
|
||||
};
|
||||
|
||||
HeaderService.prototype._onReorg = function(block, headers, callback) {
|
||||
|
||||
// this will be called when a new block (not historical) arrives and
|
||||
// has a common ancestor with a block that we already received.
|
||||
|
||||
var self = this;
|
||||
// remove the current last header from the db
|
||||
var ops = [
|
||||
{
|
||||
type: 'del',
|
||||
key: self._encoding.encodeHeaderHashKey(self._lastHeader.hash)
|
||||
},
|
||||
{
|
||||
type: 'del',
|
||||
key: self._encoding.encodeHeaderHeightKey(self._lastHeader.height)
|
||||
}
|
||||
];
|
||||
|
||||
self._db.batch(ops, function(err) {
|
||||
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
// set the last header to the common ancestor
|
||||
self._lastHeader = headers.get(bcoin.util.revHex(block.prevBlock));
|
||||
assert(self._lastHeader, 'Expected our reorg block to have a header entry, but it did not.');
|
||||
|
||||
// add the new block
|
||||
self._syncBlock(block, callback);
|
||||
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
HeaderService.prototype._setListeners = function() {
|
||||
|
||||
this._p2p.once('bestHeight', this._onBestHeight.bind(this));
|
||||
|
||||
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "bitcore-node",
|
||||
"version": "5.0.0-beta.5",
|
||||
"version": "5.0.0-beta.6",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
||||
@ -73,7 +73,7 @@ describe('Transaction Service', function() {
|
||||
|
||||
it('should process new blocks that come in from the block service', function(done) {
|
||||
|
||||
var _processTransaction = sandbox.stub(txService, '_processTransaction');
|
||||
var _processTransaction = sandbox.stub(txService, '_processTransaction').callsArgWith(2, null, {});
|
||||
|
||||
txService.onBlock(block, function(err, ops) {
|
||||
if (err) {
|
||||
@ -101,9 +101,9 @@ describe('Transaction Service', function() {
|
||||
});
|
||||
|
||||
|
||||
describe('#getInputValues', function() {
|
||||
describe('#_getInputValues', function() {
|
||||
|
||||
it('should add missing input values on a tx', function(done) {
|
||||
it('should get input values', function(done) {
|
||||
|
||||
var put = sandbox.stub().callsArgWith(2, null);
|
||||
txService._db = { put: put };
|
||||
@ -112,12 +112,12 @@ describe('Transaction Service', function() {
|
||||
|
||||
tx.__inputValues = [];
|
||||
|
||||
txService.getInputValues(tx, {}, function(err, tx) {
|
||||
txService._getInputValues(tx, {}, function(err, values) {
|
||||
|
||||
if (err) {
|
||||
return done(err);
|
||||
}
|
||||
tx.__inputValues.should.deep.equal([1139033, 1139033, 500000, 1139033]);
|
||||
values.should.deep.equal([1139033, 1139033, 500000, 1139033]);
|
||||
done();
|
||||
});
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user