more chain improvements.

This commit is contained in:
Christopher Jeffrey 2016-02-19 02:14:10 -08:00
parent 5f67f78170
commit 71557ba95c
2 changed files with 177 additions and 28 deletions

View File

@ -870,6 +870,19 @@ Chain.prototype.resetTime = function resetTime(ts) {
return this.resetHeight(entry.height);
};
Chain.prototype.resetTimeAsync = function resetTimeAsync(ts, callback) {
var self = this;
this.byTimeAsync(ts, function(err, entry) {
if (err)
return callback(err);
if (!entry)
return callback();
self.resetHeightAsync(entry.height, callback);
});
};
Chain.prototype.add = function add(initial, peer, callback) {
var self = this;
var host = peer ? peer.host : 'unknown';
@ -1232,21 +1245,6 @@ Chain.prototype.has = function has(hash) {
return false;
};
Chain.prototype.byHeight = function byHeight(height) {
if (height < 0 || height == null)
return;
return this.db.get(height);
};
Chain.prototype.byHash = function byHash(hash) {
if (utils.isBuffer(hash))
hash = utils.toHex(hash);
else if (hash.hash)
hash = hash.hash('hex');
return this.byHeight(this.db.getHeight(hash));
};
Chain.prototype.byTime = function byTime(ts) {
var start = 0;
var end = this.height + 1;
@ -1276,7 +1274,65 @@ Chain.prototype.byTime = function byTime(ts) {
return this.db.get(start);
};
Chain.prototype.byTimeAsync = function byTimeAsync(ts, callback) {
var self = this;
var start = 0;
var end = this.height + 1;
var pos, delta;
callback = utils.asyncify(callback);
function done(err, result) {
if (err)
return callback(err);
if (result)
return callback(null, result);
self.db.getAsync(start, callback);
}
if (ts >= this.tip.ts)
return done(null, this.tip);
// Do a binary search for a block
// mined within an hour of the
// timestamp.
(function next() {
if (start >= end)
return done();
pos = (start + end) >> 1;
self.db.getAsync(pos, function(err, entry) {
if (err)
return done(err);
delta = Math.abs(ts - entry.ts);
if (delta <= 60 * 60)
return done(null, entry);
if (ts < entry.ts) {
end = pos;
} else {
start = pos + 1;
}
next();
});
})();
};
Chain.prototype.hasBlock = function hasBlock(hash) {
if (typeof hash === 'number')
return this.db.has(hash);
if (utils.isBuffer(hash))
hash = utils.toHex(hash);
else if (hash.hash)
hash = hash.hash('hex');
return this.db.has(hash);
};
@ -1295,8 +1351,26 @@ Chain.prototype.hasPending = function hasPending(hash) {
Chain.prototype.getBlock = function getBlock(hash) {
if (typeof hash === 'number')
return this.byHeight(hash);
return this.byHash(hash);
return this.db.get(hash);
if (utils.isBuffer(hash))
hash = utils.toHex(hash);
else if (hash.hash)
hash = hash.hash('hex');
return this.db.get(hash);
};
Chain.prototype.getBlockAsync = function getBlockAsync(hash, callback) {
if (typeof hash === 'number')
return this.db.getAsync(hash, callback);
if (utils.isBuffer(hash))
hash = utils.toHex(hash);
else if (hash.hash)
hash = hash.hash('hex');
return this.db.getAsync(hash, callback);
};
Chain.prototype.getOrphan = function getOrphan(hash) {
@ -1319,7 +1393,7 @@ Chain.prototype.isFull = function isFull() {
return delta < 40 * 60;
};
Chain.prototype.fillPercent = function fillPercent() {
Chain.prototype.getProgress = function getProgress() {
if (!this.tip)
return 0;
return Math.min(1, this.tip.ts / (utils.now() - 40 * 60));
@ -1332,6 +1406,9 @@ Chain.prototype.hashRange = function hashRange(start, end) {
start = this.byTime(start);
end = this.byTime(end);
if (!end)
end = this.tip;
if (!start || !end)
return hashes;
@ -1341,6 +1418,59 @@ Chain.prototype.hashRange = function hashRange(start, end) {
return hashes;
};
Chain.prototype.hashRangeAsync = function hashRangeAsync(start, end, callback) {
var self = this;
var called;
function done(err, result) {
if (called)
return;
called = true;
callback(err, result);
}
this.byTimeAsync(start, function(err, start) {
if (err)
return done(err);
self.byTimeAsync(end, function(err, end) {
var hashes, i, pending;
if (err)
return done(err);
hashes = [];
if (!end)
end = self.tip;
if (!start || !end)
return done(null, hashes);
pending = (end.height + 1) - start.height;
for (i = start.height; i < end.height + 1; i++)
getHash(i);
function getHash(i) {
self.db.getAsync(i, function(err, entry) {
if (err)
return done(err);
if (!entry)
return done(new Error('No entry for hash range.'));
hashes.push(entry.hash);
if (!--pending)
return done(null, hashes);
});
}
});
});
};
Chain.prototype.getLocator = function getLocator(start) {
var hashes = [];
var top = this.height;
@ -1495,20 +1625,38 @@ Chain.prototype.getHeight = function getHeight(hash) {
};
Chain.prototype.getNextBlock = function getNextBlock(hash) {
var entry = this.byHash(hash);
var next;
var height = this.db.getHeight(hash);
var entry;
if (!entry)
return null;
next = entry.next;
if (!next)
if (height === -1)
return;
return next.hash;
entry = this.db.get(height + 1);
if (!entry)
return;
return entry.hash;
};
Chain.prototype.getNextBlockAsync = function getNextBlockAsync(hash, callback) {
var height = this.db.getHeight(hash);
if (height === -1)
return callback();
return this.db.getAsync(height + 1, function(err, entry) {
if (err)
return callback(err);
if (!entry)
return callback();
return callback(null, entry.hash);
});
};
Chain.prototype.getSize = function getSize() {
return this.db.count();
};
@ -1553,6 +1701,7 @@ Chain.prototype.getTarget = function getTarget(last, block) {
}
// Back 2 weeks
// NOTE: This is cached.
first = this.db.get(last.height - (network.powDiffInterval - 1));
assert(first);

View File

@ -674,7 +674,7 @@ Pool.prototype._handleBlock = function _handleBlock(block, peer, callback) {
if (added === 0)
return callback(null, false);
self.emit('chain-progress', self.chain.fillPercent(), peer);
self.emit('chain-progress', self.chain.getProgress(), peer);
if (self.chain.height % 20 === 0) {
utils.debug(