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);
|
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) {
|
Chain.prototype.add = function add(initial, peer, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
var host = peer ? peer.host : 'unknown';
|
var host = peer ? peer.host : 'unknown';
|
||||||
@ -1232,21 +1245,6 @@ Chain.prototype.has = function has(hash) {
|
|||||||
return false;
|
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) {
|
Chain.prototype.byTime = function byTime(ts) {
|
||||||
var start = 0;
|
var start = 0;
|
||||||
var end = this.height + 1;
|
var end = this.height + 1;
|
||||||
@ -1276,7 +1274,65 @@ Chain.prototype.byTime = function byTime(ts) {
|
|||||||
return this.db.get(start);
|
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) {
|
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);
|
return this.db.has(hash);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1295,8 +1351,26 @@ Chain.prototype.hasPending = function hasPending(hash) {
|
|||||||
|
|
||||||
Chain.prototype.getBlock = function getBlock(hash) {
|
Chain.prototype.getBlock = function getBlock(hash) {
|
||||||
if (typeof hash === 'number')
|
if (typeof hash === 'number')
|
||||||
return this.byHeight(hash);
|
return this.db.get(hash);
|
||||||
return this.byHash(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) {
|
Chain.prototype.getOrphan = function getOrphan(hash) {
|
||||||
@ -1319,7 +1393,7 @@ Chain.prototype.isFull = function isFull() {
|
|||||||
return delta < 40 * 60;
|
return delta < 40 * 60;
|
||||||
};
|
};
|
||||||
|
|
||||||
Chain.prototype.fillPercent = function fillPercent() {
|
Chain.prototype.getProgress = function getProgress() {
|
||||||
if (!this.tip)
|
if (!this.tip)
|
||||||
return 0;
|
return 0;
|
||||||
return Math.min(1, this.tip.ts / (utils.now() - 40 * 60));
|
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);
|
start = this.byTime(start);
|
||||||
end = this.byTime(end);
|
end = this.byTime(end);
|
||||||
|
|
||||||
|
if (!end)
|
||||||
|
end = this.tip;
|
||||||
|
|
||||||
if (!start || !end)
|
if (!start || !end)
|
||||||
return hashes;
|
return hashes;
|
||||||
|
|
||||||
@ -1341,6 +1418,59 @@ Chain.prototype.hashRange = function hashRange(start, end) {
|
|||||||
return hashes;
|
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) {
|
Chain.prototype.getLocator = function getLocator(start) {
|
||||||
var hashes = [];
|
var hashes = [];
|
||||||
var top = this.height;
|
var top = this.height;
|
||||||
@ -1495,20 +1625,38 @@ Chain.prototype.getHeight = function getHeight(hash) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Chain.prototype.getNextBlock = function getNextBlock(hash) {
|
Chain.prototype.getNextBlock = function getNextBlock(hash) {
|
||||||
var entry = this.byHash(hash);
|
var height = this.db.getHeight(hash);
|
||||||
var next;
|
var entry;
|
||||||
|
|
||||||
if (!entry)
|
if (height === -1)
|
||||||
return null;
|
|
||||||
|
|
||||||
next = entry.next;
|
|
||||||
|
|
||||||
if (!next)
|
|
||||||
return;
|
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() {
|
Chain.prototype.getSize = function getSize() {
|
||||||
return this.db.count();
|
return this.db.count();
|
||||||
};
|
};
|
||||||
@ -1553,6 +1701,7 @@ Chain.prototype.getTarget = function getTarget(last, block) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Back 2 weeks
|
// Back 2 weeks
|
||||||
|
// NOTE: This is cached.
|
||||||
first = this.db.get(last.height - (network.powDiffInterval - 1));
|
first = this.db.get(last.height - (network.powDiffInterval - 1));
|
||||||
|
|
||||||
assert(first);
|
assert(first);
|
||||||
|
|||||||
@ -674,7 +674,7 @@ Pool.prototype._handleBlock = function _handleBlock(block, peer, callback) {
|
|||||||
if (added === 0)
|
if (added === 0)
|
||||||
return callback(null, false);
|
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) {
|
if (self.chain.height % 20 === 0) {
|
||||||
utils.debug(
|
utils.debug(
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user