more chain improvements.
This commit is contained in:
parent
5f67f78170
commit
71557ba95c
@ -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);
|
||||
|
||||
@ -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(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user