Fixed progress bar and added tests for getTransaction in
TransactionService.
This commit is contained in:
parent
6d95cd0302
commit
b6f56fb02b
@ -320,7 +320,7 @@ DB.prototype.loadTips = function(callback) {
|
||||
}
|
||||
|
||||
self[tip] = block;
|
||||
log.info('loaded tip, hash: ' + block.hash + ' height: ' + block.__height);
|
||||
log.info('loaded ' + tip + ', hash: ' + block.hash + ' height: ' + block.__height);
|
||||
next();
|
||||
|
||||
});
|
||||
|
||||
@ -7,7 +7,6 @@ var EventEmitter = require('events').EventEmitter;
|
||||
var async = require('async');
|
||||
var bitcore = require('bitcore-lib');
|
||||
var Block = bitcore.Block;
|
||||
var ProgressBar = require('progress');
|
||||
var index = require('../../index');
|
||||
var log = index.log;
|
||||
|
||||
@ -66,8 +65,7 @@ function Sync(node, db) {
|
||||
this.syncing = false;
|
||||
this.paused = false; //we can't sync while one of our indexes is reading/writing separate from us
|
||||
this.highWaterMark = 10;
|
||||
this.progressBar = null;
|
||||
this.lastReportedBlock = 0;
|
||||
this._lastReportedTime = Date.now();
|
||||
}
|
||||
|
||||
inherits(Sync, EventEmitter);
|
||||
@ -98,16 +96,6 @@ Sync.prototype.sync = function() {
|
||||
blockStream
|
||||
.pipe(processSerial);
|
||||
|
||||
self.lastReportedBlock = self.db.tip.__height;
|
||||
|
||||
self.progressBar = new ProgressBar('[:bar] :percent :current blks, :blockspersec blks/sec', {
|
||||
curr: self.lastReportedBlock,
|
||||
total: self.node.services.bitcoind.height,
|
||||
clear: true
|
||||
});
|
||||
|
||||
self.progressBarTimer = setInterval(self.reportStatus.bind(self), 1000);
|
||||
|
||||
processSerial.on('finish', self._onFinish.bind(self));
|
||||
|
||||
};
|
||||
@ -117,14 +105,6 @@ Sync.prototype._onFinish = function() {
|
||||
var self = this;
|
||||
self.syncing = false;
|
||||
|
||||
if (self.progressBar) {
|
||||
self.progressBar.terminate();
|
||||
}
|
||||
|
||||
if (self.progressBarTimer) {
|
||||
clearInterval(self.progressBarTimer);
|
||||
}
|
||||
|
||||
if (self.forkBlock) {
|
||||
self.db.handleReorg(self.forkBlock, function() {
|
||||
self.forkBlock = null;
|
||||
@ -134,6 +114,7 @@ Sync.prototype._onFinish = function() {
|
||||
}
|
||||
|
||||
self._startSubscriptions();
|
||||
self._reportStatus(true);
|
||||
self.emit('synced');
|
||||
|
||||
};
|
||||
@ -148,6 +129,7 @@ Sync.prototype._startSubscriptions = function() {
|
||||
self.bus = self.node.openBus({remoteAddress: 'localhost'});
|
||||
|
||||
self.bus.on('bitcoind/hashblock', function() {
|
||||
self._reportStatus();
|
||||
self.sync();
|
||||
});
|
||||
|
||||
@ -156,12 +138,9 @@ Sync.prototype._startSubscriptions = function() {
|
||||
|
||||
};
|
||||
|
||||
Sync.prototype.reportStatus = function() {
|
||||
if (process.stderr.isTTY) {
|
||||
var tick = this.db.tip.__height - this.lastReportedBlock;
|
||||
this.progressBar.tick(tick, { blockspersec: tick });
|
||||
this.lastReportedBlock = this.db.tip.__height;
|
||||
} else {
|
||||
Sync.prototype._reportStatus = function(override) {
|
||||
if (((Date.now() - this._lastReportedTime) > 1000) || override) {
|
||||
this._lastReportedTime = Date.now();
|
||||
log.info('Sync: current height is: ' + this.db.tip.__height);
|
||||
}
|
||||
};
|
||||
|
||||
@ -160,6 +160,7 @@ TransactionService.prototype.getTransaction = function(txid, options, callback)
|
||||
});
|
||||
}
|
||||
|
||||
txid = txid.toString('hex');
|
||||
var key = self.encoding.encodeTransactionKey(txid);
|
||||
|
||||
async.waterfall([
|
||||
@ -178,22 +179,16 @@ TransactionService.prototype.getTransaction = function(txid, options, callback)
|
||||
return next(null, tx);
|
||||
}
|
||||
if (!options || !options.queryMempool) {
|
||||
return next();
|
||||
return next(new Error('Transaction: ' + txid + ' not found in index'));
|
||||
}
|
||||
self.node.services.mempool.getTransaction(txid, function(err, tx) {
|
||||
if(err) {
|
||||
return next(err);
|
||||
}
|
||||
if (!tx) {
|
||||
return next();
|
||||
}
|
||||
self._getMissingInputValues(tx, next);
|
||||
if (err instanceof levelup.errors.NotFoundError) {
|
||||
return callback(new Error('Transaction: ' + txid + ' not found in index or mempool'));
|
||||
} else if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
self._getMissingInputValues(tx, next);
|
||||
});
|
||||
}, function(tx, next) {
|
||||
if (tx) {
|
||||
return next(null, tx);
|
||||
}
|
||||
self.node.services.bitcoind.getTransaction(txid, next);
|
||||
}], callback);
|
||||
};
|
||||
|
||||
|
||||
@ -60,7 +60,6 @@
|
||||
"mkdirp": "0.5.0",
|
||||
"multer": "^1.2.1",
|
||||
"path-is-absolute": "^1.0.0",
|
||||
"progress": "kleetus/node-progress#master",
|
||||
"semver": "^5.0.1",
|
||||
"socket.io": "^1.4.5",
|
||||
"socket.io-client": "^1.4.5",
|
||||
|
||||
@ -8,7 +8,7 @@ var path = require('path');
|
||||
var utils = require('./utils');
|
||||
var crypto = require('crypto');
|
||||
|
||||
var debug = false;
|
||||
var debug = true;
|
||||
var bitcoreDataDir = '/tmp/bitcore';
|
||||
var bitcoinDataDir = '/tmp/bitcoin';
|
||||
|
||||
|
||||
114
test/services/transaction/index.unit.js
Normal file
114
test/services/transaction/index.unit.js
Normal file
@ -0,0 +1,114 @@
|
||||
'use strict';
|
||||
|
||||
var should = require('chai').should();
|
||||
var sinon = require('sinon');
|
||||
var TransactionService = require('../../../lib/services/transaction');
|
||||
var levelup = require('levelup');
|
||||
|
||||
describe('Transaction Index', function() {
|
||||
|
||||
describe('Failures', function() {
|
||||
//if we miss indexing a tx, then this is very bad news. We have no good way of
|
||||
//recursively retrieving inputValues, timestamp of its block, and block's height
|
||||
it('should throw error if a transaction is not in the index', function(done) {
|
||||
var services = {
|
||||
db: {
|
||||
store: {
|
||||
get: sinon.stub().callsArgWith(1, new levelup.errors.NotFoundError())
|
||||
}
|
||||
}
|
||||
};
|
||||
var node = { node: { services: services }};
|
||||
var service = new TransactionService(node);
|
||||
|
||||
service.encoding = { encodeTransactionKey: function() { return 'key'; }};
|
||||
var tx = service.getTransaction('1234', {}, function(err, res) {
|
||||
err.should.be.an.instanceof(Error);
|
||||
err.message.should.equal('Transaction: 1234 not found in index');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('should search the mempool if opted for', function(done) {
|
||||
var getTransaction = sinon.stub().callsArgWith(1, new levelup.errors.NotFoundError());
|
||||
var services = {
|
||||
db: {
|
||||
store: {
|
||||
get: sinon.stub().callsArgWith(1, new levelup.errors.NotFoundError())
|
||||
}
|
||||
},
|
||||
mempool: {
|
||||
getTransaction: getTransaction
|
||||
}
|
||||
};
|
||||
var node = { node: { services: services }};
|
||||
var service = new TransactionService(node);
|
||||
|
||||
service.encoding = { encodeTransactionKey: function() { return 'key'; }};
|
||||
var tx = service.getTransaction('1234', { queryMempool: true }, function(err, res) {
|
||||
err.should.be.an.instanceof(Error);
|
||||
err.message.should.equal('Transaction: 1234 not found in index or mempool');
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
});
|
||||
|
||||
describe('Success', function() {
|
||||
it('should search main index', function(done) {
|
||||
var services = {
|
||||
db: {
|
||||
store: {
|
||||
get: sinon.stub().callsArgWith(1, null, 'tx')
|
||||
}
|
||||
}
|
||||
};
|
||||
var node = { node: { services: services }};
|
||||
var service = new TransactionService(node);
|
||||
|
||||
service.encoding = {
|
||||
encodeTransactionKey: function() { return 'key'; },
|
||||
decodeTransactionValue: function() { return 'value'; }
|
||||
};
|
||||
var tx = service.getTransaction('1234', {}, function(err, res) {
|
||||
if(err) {
|
||||
return done(err);
|
||||
}
|
||||
res.should.equal('value');
|
||||
done();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
it('should search mempool', function(done) {
|
||||
var missingInputs = sinon.stub().callsArgWith(1, null, 'tx');
|
||||
var getTransaction = sinon.stub().callsArgWith(1, null, 'tx');
|
||||
var services = {
|
||||
db: {
|
||||
store: {
|
||||
get: sinon.stub().callsArgWith(1, new levelup.errors.NotFoundError())
|
||||
}
|
||||
},
|
||||
mempool: {
|
||||
getTransaction: getTransaction
|
||||
}
|
||||
};
|
||||
var node = { node: { services: services }};
|
||||
var service = new TransactionService(node);
|
||||
|
||||
service.encoding = {
|
||||
encodeTransactionKey: function() { return 'key'; }
|
||||
};
|
||||
service._getMissingInputValues = missingInputs;
|
||||
var tx = service.getTransaction('1234', { queryMempool: true }, function(err, res) {
|
||||
if(err) {
|
||||
return done(err);
|
||||
}
|
||||
missingInputs.callCount.should.equal(1);
|
||||
res.should.equal('tx');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Loading…
Reference in New Issue
Block a user