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._header = this.node.services.header;
|
||||||
this._block = this.node.services.block;
|
this._block = this.node.services.block;
|
||||||
this._timestamp = this.node.services.timestamp;
|
this._timestamp = this.node.services.timestamp;
|
||||||
|
this._transaction = this.node.services.transaction;
|
||||||
this._network = this.node.network;
|
this._network = this.node.network;
|
||||||
this._db = this.node.services.db;
|
this._db = this.node.services.db;
|
||||||
|
|
||||||
|
|||||||
@ -565,7 +565,7 @@ HeaderService.prototype._detectReorg = function(block, callback) {
|
|||||||
var nextBlock = prevHash === self._lastHeader.hash;
|
var nextBlock = prevHash === self._lastHeader.hash;
|
||||||
|
|
||||||
// this is the last block the block service asked for
|
// 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);
|
return callback(null, false, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -575,7 +575,7 @@ HeaderService.prototype._detectReorg = function(block, callback) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// could really be a reorg block
|
// 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) {
|
this._db.get(key, function(err, val) {
|
||||||
|
|
||||||
@ -621,28 +621,39 @@ HeaderService.prototype._detectStartupReorg = function(callback) {
|
|||||||
HeaderService.prototype._handleReorg = function(block, header, callback) {
|
HeaderService.prototype._handleReorg = function(block, header, callback) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
self.getAllHeaders(function(err, headers) {
|
self.getAllHeaders(function(err, headers) {
|
||||||
|
|
||||||
if (err || !headers) {
|
if (err || !headers) {
|
||||||
return callback(err || new Error('Missing 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 +
|
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.');
|
' 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) {
|
if (block && header) {
|
||||||
|
|
||||||
hash = block.rhash();
|
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
|
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.');
|
assert(hash, 'To reorg, we need a hash to reorg to.');
|
||||||
self.emit('reorg', hash, headers);
|
self.emit('reorg', hash, headers);
|
||||||
callback();
|
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() {
|
HeaderService.prototype._setListeners = function() {
|
||||||
|
|
||||||
this._p2p.once('bestHeight', this._onBestHeight.bind(this));
|
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",
|
"name": "bitcore-node",
|
||||||
"version": "5.0.0-beta.5",
|
"version": "5.0.0-beta.6",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@ -73,7 +73,7 @@ describe('Transaction Service', function() {
|
|||||||
|
|
||||||
it('should process new blocks that come in from the block service', function(done) {
|
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) {
|
txService.onBlock(block, function(err, ops) {
|
||||||
if (err) {
|
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);
|
var put = sandbox.stub().callsArgWith(2, null);
|
||||||
txService._db = { put: put };
|
txService._db = { put: put };
|
||||||
@ -112,12 +112,12 @@ describe('Transaction Service', function() {
|
|||||||
|
|
||||||
tx.__inputValues = [];
|
tx.__inputValues = [];
|
||||||
|
|
||||||
txService.getInputValues(tx, {}, function(err, tx) {
|
txService._getInputValues(tx, {}, function(err, values) {
|
||||||
|
|
||||||
if (err) {
|
if (err) {
|
||||||
return done(err);
|
return done(err);
|
||||||
}
|
}
|
||||||
tx.__inputValues.should.deep.equal([1139033, 1139033, 500000, 1139033]);
|
values.should.deep.equal([1139033, 1139033, 500000, 1139033]);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user