better wallet searching for spv. pool methods.

This commit is contained in:
Christopher Jeffrey 2016-01-02 03:44:25 -08:00
parent ff16271c1a
commit 7a8a7a5a2b
4 changed files with 106 additions and 15 deletions

View File

@ -215,6 +215,21 @@ Chain.prototype.resetHeight = function resetHeight(height) {
this.index.lastTs = this.index.ts[this.index.ts.length - 1];
};
Chain.prototype._heightByTime = function _heightByTime(ts) {
for (var i = this.index.ts.length - 1; i >= 0; i--) {
if (ts >= this.index.ts[i])
return this.index.heights[i];
}
return -1;
};
Chain.prototype.resetTime = function resetTime(ts) {
var height = this._heightByTime(ts);
if (height === -1)
return;
return this.resetHeight(height);
};
Chain.prototype._killFork = function _killFork(probe) {
var self = this;
var delta = 2 * 3600;

View File

@ -164,6 +164,21 @@ Chain.prototype.resetHeight = function resetHeight(height) {
});
};
Chain.prototype._heightByTime = function _heightByTime(ts) {
for (var i = this.index.entries.length - 1; i >= 0; i--) {
if (ts >= this.index.entries[i].ts)
return this.index.entries[i].height;
}
return -1;
};
Chain.prototype.resetTime = function resetTime(ts) {
var height = this._heightByTime(ts);
if (height === -1)
return;
return this.resetHeight(height);
};
Chain.prototype.add = function add(block) {
if (this.loading) {
this.once('load', function() {

View File

@ -425,7 +425,7 @@ Pool.prototype._loadRange = function _loadRange(hashes, force) {
last = hashes[hashes.length - 1];
hashes.slice(0, -1).forEach(function(hash) {
this.peers.load.loadBlocks([ hash ], last);
this.peers.load.loadBlocks([hash], last);
}, this);
};
@ -449,7 +449,7 @@ Pool.prototype._load = function _load() {
if (!self.peers.load)
self._addLoader();
else
self.peers.load.loadBlocks([ hash ]);
self.peers.load.loadBlocks([hash], 0);
};
// Load more blocks, starting from last hash
@ -734,11 +734,6 @@ Pool.prototype.addWallet = function addWallet(w, defaultTs) {
e = new EventEmitter();
if (w.loaded)
search(w.lastTs);
else
w.once('load', function() { search(w.lastTs) });
function search(ts) {
// Relay pending TXs
// NOTE: It is important to do it after search, because search could
@ -754,9 +749,15 @@ Pool.prototype.addWallet = function addWallet(w, defaultTs) {
if (!ts)
ts = defaultTs || ((+new Date / 1000) - 7 * 24 * 3600);
self.search(false, ts, e);
// self.search(false, ts, e);
self.searchWallet(ts);
}
if (w.loaded)
search(w.lastTs);
else
w.once('load', function() { search(w.lastTs) });
return e;
};
@ -796,6 +797,36 @@ Pool.prototype.unwatchWallet = function unwatchWallet(w) {
this.unwatch(w.getOwnPublicKey());
};
Pool.prototype.searchWallet = function(w) {
var self = this;
var ts;
if (!w) {
ts = this.wallets.reduce(function(ts, w) {
if (w.lastTs < ts)
return w.lastTs;
return ts;
}, Infinity);
assert(ts !== Infinity);
} else if (typeof w === 'number') {
ts = w;
} else {
if (!w.loaded) {
w.once('load', function() {
self.searchWallet(w.lastTs);
});
return;
}
ts = w.lastTs;
if (!ts)
ts = (+new Date / 1000) - 7 * 24 * 3600;
}
this.emit('debug', 'Wallet time: %s', new Date(ts * 1000));
this.chain.resetTime(ts);
};
Pool.prototype.search = function search(id, range, e) {
var self = this;
@ -833,6 +864,14 @@ Pool.prototype.search = function search(id, range, e) {
this.chain.hashesInRange(range.start, range.end, function(hashes, count) {
var waiting = count;
self.emit('debug',
'Search for %s (%s) hashes between %s and %s',
hashes.length,
count,
new Date(range.start * 1000).toISOString(),
new Date(range.end * 1000).toISOString()
);
if (id)
self.watch(id);
@ -841,7 +880,7 @@ Pool.prototype.search = function search(id, range, e) {
hashes = hashes.slice().reverse();
hashes.forEach(function(hash, i) {
// Get the block that is in index
self.chain.get(hash, true, function(block) {
self.chain.request.add(hash, function(block) {
loadBlock(block, hashes[i + 1]);
});
});
@ -853,7 +892,7 @@ Pool.prototype.search = function search(id, range, e) {
// Get block's prev and request it and all of it's parents up to
// the next known block hash
self.chain.get(block.prevBlock, block.prevBlock !== stop, function(prev) {
self.chain.request.add(block.prevBlock, function(prev) {
done();
// First hash loaded
@ -1002,10 +1041,26 @@ Pool.prototype._doRequests = function _doRequests() {
this.peers.load.getData(req);
};
Pool.prototype.getBlock = function getBlock(hash, cb) {
var type = this.options.fullNode ? 'block' : 'filtered';
if (this.chain.request.add(hash, cb)) {
this._request(type, hash, { force: true });
this._scheduleRequests();
}
};
Pool.prototype.sendBlock = function sendBlock(block) {
return this.sendTX(block);
};
Pool.prototype.getTX = function getTX(hash, range, cb) {
var self = this;
var cbs, tx, finished, req, delta;
if (this.options.fullNode)
return cb(new Error('Cannot get tx with full node'));
hash = utils.toHex(hash);
if (typeof range === 'function') {
@ -1017,7 +1072,7 @@ Pool.prototype.getTX = function getTX(hash, range, cb) {
if (this.validate.map[hash])
return this.validate.map[hash].push(cb);
cbs = [ cb ];
cbs = [cb];
this.validate.map[hash] = cbs;
// Add request without queueing it to get notification at the time of load
@ -1043,14 +1098,14 @@ Pool.prototype.getTX = function getTX(hash, range, cb) {
if (finished) {
delete self.validate.map[hash];
cbs.forEach(function(cb) {
cb(tx, range);
cb(null, tx, range);
});
return;
}
// Tried everything, but still no matches
if (empty)
return cb(null);
return cb(new Error('Not found.'));
// Not found yet, continue scanning
range.end = range.start;
@ -1146,7 +1201,7 @@ function LoadRequest(pool, type, hash, cb) {
this.pool = pool;
this.type = type;
this.hash = hash;
this.cbs = cb ? [ cb ] : [];
this.cbs = cb ? [cb] : [];
this.timer = null;
this.peer = null;
this.ts = +new Date();

View File

@ -453,6 +453,8 @@ function RequestCache() {
}
RequestCache.prototype.add = function add(id, cb) {
id = utils.toHex(id);
if (this.map[id]) {
this.map[id].push(cb);
return false;
@ -464,7 +466,11 @@ RequestCache.prototype.add = function add(id, cb) {
};
RequestCache.prototype.fullfill = function fullfill(id, err, data) {
var cbs = this.map[id];
var cbs;
id = utils.toHex(id);
cbs = this.map[id];
if (!this.map[id])
return;