check current bc tip

This commit is contained in:
Matias Alejo Garcia 2016-12-09 16:39:54 -03:00
parent 2cff530072
commit 61ed4c803a
No known key found for this signature in database
GPG Key ID: 02470DB551277AB3
4 changed files with 109 additions and 39 deletions

View File

@ -181,38 +181,87 @@ BlockchainMonitor.prototype._handleTxOuts = function(data) {
}); });
}; };
BlockchainMonitor.prototype._processBlock = function(network, hash, cb) {
BlockchainMonitor.prototype._processBlockData = function(network, data, cb) {
var self = this; var self = this;
//1. check block is not reorg var block = new Bitcore.Block(new Buffer(data.rawblock, 'hex'));
//2. doProcessBlock log.debug('Processing block ' + network + ' ' + block.hash);
this.explorers[network].getBlock(hash, function(err, data) {
var txs = block.toObject().transactions;
var allAddresses = {};
_.each(txs, function(tx) {
_.each(tx.outputs, function(o) {
if (o.script) {
var s = new Bitcore.Script(new Buffer(o.script, 'hex'));
var a = s.toAddress(network);
if (a) {
allAddresses[a] = true;
}
}
});
});
allAddresses = _.keys(allAddresses);
async.eachLimit(allAddresses, 10, function(address, i_cb) {
self.storage.updateLastUsedOn(address, i_cb);
}, function(err) {
if (err) return cb(err); if (err) return cb(err);
log.debug('Processing block ' + network + ' ' + hash); return cb(null, block);
var block = new Bitcore.Block(new Buffer(data.rawblock, 'hex'));
var txs = block.toObject().transactions;
var allAddresses = {};
_.each(txs, function(tx) {
_.each(tx.outputs, function(o) {
if (o.script) {
var s = new Bitcore.Script(new Buffer(o.script, 'hex'));
var a = s.toAddress(network);
if (a) {
allAddresses[a] = true;
}
}
});
});
allAddresses = _.keys(allAddresses);
async.eachLimit(allAddresses, 10, function(address, i_cb) {
self.storage.updateLastUsedOn(address, i_cb);
}, cb);
}); });
}; };
BlockchainMonitor.prototype._fetchAndProcessBlock = function(network, hash, cb) {
var self = this;
this.explorers[network].getBlock(hash, function(err, data) {
if (err) return cb(err);
self._processBlockData(network, data, cb);
});
};
BlockchainMonitor.prototype._processBlockchainSince = function(network, hash, cb) {
var self = this;
self.storage.getTip(network, function(err, data) {
if (err) return cb(err);
if (!data) {
log.error('No Tip recorded for ' + network);
return cb('No Tip recorded');
}
var tip = data.hash;
log.debug('', 'Last processed tip for %s was: %s on ', network, tip, (new Date(1000*data.updateOn)).toString() );
self._fetchAndProcessBlock(network, hash, function(err, block){
if (err) return cb(err);
// TODO CRITICAL
if (!block) {
log.error('', 'Block from notification no found! %s %s', network, hash);
return cb('Block not found!');
};
var header = block.header.toObject();
if (header.prevHash != tip) {
log.info ('', 'Notified block\'s prevhash does not match stored hash... Processing');
} else {
self.storage.updateTip(network, hash, cb);
}
});
});
};
BlockchainMonitor.prototype._handleIncomingTx = function(data) { BlockchainMonitor.prototype._handleIncomingTx = function(data) {
this._handleTxId(data); this._handleTxId(data);
this._handleTxOuts(data); this._handleTxOuts(data);
@ -231,12 +280,10 @@ BlockchainMonitor.prototype._handleNewBlock = function(network, hash) {
}, },
}); });
self._processBlock(network, hash, function() { self._processBlockchainSince(network, hash, function() {
self.storage.updateTip(function() { self.storage.softResetAllTxHistoryCache(function() {
self.storage.softResetAllTxHistoryCache(function() { self._storeAndBroadcastNotification(notification, function(err) {
self._storeAndBroadcastNotification(notification, function(err) { return;
return;
});
}); });
}); });
}) })

View File

@ -624,23 +624,33 @@ Storage.prototype.getTxHistoryCache = function(walletId, from, to, cb) {
}; };
Storage.prototype.updateTip = function(hash, cb) { Storage.prototype.updateTip = function(network, hash, cb) {
this.db.collection(collections.CACHE).update({ this.db.collection(collections.CACHE).update({
type: 'blochainTip', type: 'tip',
key: network,
}, { }, {
$set: { $set: {
hash:hash, hash: hash,
updatedOn: Math.floor(Date.now() / 1000),
} }
}, { }, {
upsert: true, upsert: true,
}, cb); }, cb);
}; };
Storage.prototype.getTip = function(network,cb) {
this.db.collection(collections.CACHE).findOne({
type: 'tip',
key: network,
}, cb);
};
Storage.prototype.softResetAllTxHistoryCache = function(cb) { Storage.prototype.softResetAllTxHistoryCache = function(cb) {
this.db.collection(collections.CACHE).remove({ this.db.collection(collections.CACHE).remove({
type: 'historyCacheStatus', type: 'historyCacheStatus',
}, { }, {
multi: true, multi: true,
}, cb); }, cb);
}; };

View File

@ -144,17 +144,30 @@ describe('Blockchain monitor', function() {
rawblock: TestData.block.rawblock rawblock: TestData.block.rawblock
}); });
var fakeAddresses= TestData.block.addresses.splice(0, 3);
server.storage.getTip = sinon.stub().yields(null, {
hash: TestData.block.prev,
updatedOn: Date.now(),
});
var fakeAddresses = TestData.block.addresses.splice(0, 3);
server.getWallet({}, function(err, wallet) { server.getWallet({}, function(err, wallet) {
should.not.exist(err); should.not.exist(err);
var aLongTimeAgo = Date.now() - (1000 * 10 * 86400);
var clock = sinon.useFakeTimers(aLongTimeAgo, 'Date');
helpers.insertFakeAddresses(server, wallet, fakeAddresses, function(err) { helpers.insertFakeAddresses(server, wallet, fakeAddresses, function(err) {
should.not.exist(err); should.not.exist(err);
clock.restore();
socket.handlers['block'](incoming); socket.handlers['block'](incoming);
setTimeout(function() { setTimeout(function() {
storage.fetchRecentAddresses(wallet.id, (Date.now() / 1000) - 100, function(err, addr) { storage.fetchRecentAddresses(wallet.id, (Date.now() / 1000) - 100, function(err, addr) {
_.pluck(addr,'address').should.be.deep.equal(fakeAddresses); _.pluck(addr, 'address').should.be.deep.equal(fakeAddresses);
done(); done();
}); });
}, 50); }, 50);

View File

@ -296,4 +296,4 @@ var addresses = [ 'mzrj4QmPhk98vc2yQw42uCsgwfBjVzPPLM',
module.exports.keyPair = keyPair; module.exports.keyPair = keyPair;
module.exports.copayers = copayers; module.exports.copayers = copayers;
module.exports.history = history; module.exports.history = history;
module.exports.block = { rawblock: rawblock, addresses: addresses}; module.exports.block = { rawblock: rawblock, addresses: addresses, prev: '0000000000001e5b4b49aef6109a1ceeee9d4f628882bce97e06aa0f2889aee1'};