fix orphan resolution.
This commit is contained in:
parent
9ddc23227c
commit
0dc1b1cc5f
@ -1759,7 +1759,7 @@ Chain.prototype.getOrphanRoot = function getOrphanRoot(hash) {
|
||||
else if (hash.hash)
|
||||
hash = hash.hash('hex');
|
||||
|
||||
root = hash;
|
||||
assert(hash);
|
||||
|
||||
while (this.orphan.bmap[hash]) {
|
||||
root = hash;
|
||||
@ -1769,23 +1769,6 @@ Chain.prototype.getOrphanRoot = function getOrphanRoot(hash) {
|
||||
return root;
|
||||
};
|
||||
|
||||
Chain.prototype.getOrphanSoil = function getOrphanSoil(hash) {
|
||||
var root;
|
||||
|
||||
if (utils.isBuffer(hash))
|
||||
hash = utils.toHex(hash);
|
||||
else if (hash.hash)
|
||||
hash = hash.hash('hex');
|
||||
|
||||
while (this.orphan.bmap[hash]) {
|
||||
root = this.orphan.bmap[hash];
|
||||
hash = this.orphan.bmap[hash].prevBlock;
|
||||
}
|
||||
|
||||
if (root)
|
||||
return root.prevBlock;
|
||||
};
|
||||
|
||||
Chain.prototype.getHeight = function getHeight(hash) {
|
||||
return this.db.getHeight(hash);
|
||||
};
|
||||
|
||||
@ -66,7 +66,7 @@ function Pool(options) {
|
||||
options.multiplePeers = true;
|
||||
} else {
|
||||
if (options.headers == null)
|
||||
options.headers = true;
|
||||
options.headers = false;
|
||||
if (options.multiplePeers == null)
|
||||
options.multiplePeers = false;
|
||||
}
|
||||
@ -262,13 +262,35 @@ Pool.prototype.resolveOrphan = function resolveOrphan(peer, top, orphan) {
|
||||
assert(orphan);
|
||||
this.chain.onFlush(function() {
|
||||
self.chain.getLocatorAsync(top, function(err, locator) {
|
||||
var root, soil;
|
||||
|
||||
if (err)
|
||||
throw err;
|
||||
|
||||
peer.getBlocks(
|
||||
locator,
|
||||
self.chain.getOrphanRoot(orphan)
|
||||
);
|
||||
root = self.chain.getOrphanRoot(orphan);
|
||||
|
||||
// Was probably resolved.
|
||||
if (!root) {
|
||||
utils.debug('Orphan root was already resolved.');
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the block that would resolve the chain.
|
||||
soil = self.chain.getOrphan(root).prevBlock;
|
||||
|
||||
// If we're already processing the block
|
||||
// that would resolve this, ignore.
|
||||
if (self.request.map[soil] || self.chain.hasPending(soil)) {
|
||||
utils.debug('Already processing orphan "soil".');
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.chain.has(soil)) {
|
||||
utils.debug('Already have orphan "soil". Race condition?');
|
||||
return;
|
||||
}
|
||||
|
||||
peer.getBlocks(locator, root);
|
||||
});
|
||||
});
|
||||
};
|
||||
@ -505,6 +527,7 @@ Pool.prototype.stopSync = function stopSync() {
|
||||
};
|
||||
|
||||
Pool.prototype._handleHeaders = function _handleHeaders(headers, peer) {
|
||||
var self = this;
|
||||
var i, header, last, block, blockPeer;
|
||||
|
||||
assert(this.options.headers);
|
||||
@ -524,39 +547,41 @@ Pool.prototype._handleHeaders = function _handleHeaders(headers, peer) {
|
||||
|
||||
this.emit('headers', headers);
|
||||
|
||||
for (i = 0; i < headers.length; i++) {
|
||||
block = bcoin.block(headers[i], 'header');
|
||||
blockPeer = peer;
|
||||
this.chain.onFlush(function() {
|
||||
for (i = 0; i < headers.length; i++) {
|
||||
block = bcoin.block(headers[i], 'header');
|
||||
blockPeer = peer;
|
||||
|
||||
// if (this.options.multiplePeers) {
|
||||
// if (this.peers.regular.length) {
|
||||
// blockPeer = this.peers.regular[i % (this.peers.regular.length + 1)];
|
||||
// if (!blockPeer)
|
||||
// blockPeer = this.peers.load;
|
||||
// }
|
||||
// }
|
||||
// if (self.options.multiplePeers) {
|
||||
// if (self.peers.regular.length) {
|
||||
// blockPeer = self.peers.regular[i % (self.peers.regular.length + 1)];
|
||||
// if (!blockPeer)
|
||||
// blockPeer = self.peers.load;
|
||||
// }
|
||||
// }
|
||||
|
||||
if (last && block.prevBlock !== last.hash('hex'))
|
||||
break;
|
||||
if (last && block.prevBlock !== last.hash('hex'))
|
||||
break;
|
||||
|
||||
if (!block.verify())
|
||||
break;
|
||||
if (!block.verify())
|
||||
break;
|
||||
|
||||
if (!this.chain.has(block))
|
||||
this.getData(blockPeer, this.block.type, block.hash('hex'));
|
||||
if (!self.chain.has(block))
|
||||
self.getData(blockPeer, self.block.type, block.hash('hex'));
|
||||
|
||||
last = block;
|
||||
}
|
||||
last = block;
|
||||
}
|
||||
|
||||
// Restart the getheaders process
|
||||
// Technically `last` is not indexed yet so
|
||||
// the locator hashes will not be entirely
|
||||
// accurate. However, it shouldn't matter
|
||||
// that much since FindForkInGlobalIndex
|
||||
// simply tries to find the latest block in
|
||||
// the peer's chain.
|
||||
if (last && headers.length === 2000)
|
||||
this.getHeaders(peer, last, null);
|
||||
// Restart the getheaders process
|
||||
// Technically `last` is not indexed yet so
|
||||
// the locator hashes will not be entirely
|
||||
// accurate. However, it shouldn't matter
|
||||
// that much since FindForkInGlobalIndex
|
||||
// simply tries to find the latest block in
|
||||
// the peer's chain.
|
||||
if (last && headers.length === 2000)
|
||||
self.getHeaders(peer, last, null);
|
||||
});
|
||||
|
||||
// Reset interval to avoid calling getheaders unnecessarily
|
||||
this._startInterval();
|
||||
@ -590,9 +615,6 @@ Pool.prototype._handleBlocks = function _handleBlocks(hashes, peer) {
|
||||
// Resolve orphan chain.
|
||||
if (self.chain.hasOrphan(hash)) {
|
||||
utils.debug('Peer sent a hash that is already a known orphan.');
|
||||
// var soil = self.chain.getOrphanSoil(hash);
|
||||
// if (self.request.map[soil] || self.chain.hasPending(soil))
|
||||
// break;
|
||||
self.resolveOrphan(peer, null, hash);
|
||||
continue;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user