This commit is contained in:
Chris Kleeschulte 2017-06-05 15:59:19 -04:00
parent 09ff858e81
commit dae3c1de07
6 changed files with 105 additions and 88 deletions

View File

@ -4,6 +4,7 @@ var util = require('util');
var EventEmitter = require('events').EventEmitter; var EventEmitter = require('events').EventEmitter;
var LRU = require('lru-cache'); var LRU = require('lru-cache');
var assert = require('assert'); var assert = require('assert');
var constants = require('./constants');
var Service = function(options) { var Service = function(options) {
EventEmitter.call(this); EventEmitter.call(this);

View File

@ -14,7 +14,7 @@ var BlockHandler = require('./block_handler');
var LRU = require('lru-cache'); var LRU = require('lru-cache');
var utils = require('../../utils'); var utils = require('../../utils');
var _ = require('lodash'); var _ = require('lodash');
var constants = require('../../constants'); var assert = require('assert');
var BlockService = function(options) { var BlockService = function(options) {
BaseService.call(this, options); BaseService.call(this, options);
@ -124,6 +124,11 @@ BlockService.prototype._reportStatus = function(serviceName) {
}; };
BlockService.prototype._setTip = function(opts) {
this.tip.height = opts.block.height;
this.tip.hash = opts.block.hash;
};
BlockService.prototype.processBlockOperations = function(opts, callback) { BlockService.prototype.processBlockOperations = function(opts, callback) {
if (!_.isArray(opts.operations)) { if (!_.isArray(opts.operations)) {
@ -355,7 +360,8 @@ BlockService.prototype._setHandlers = function() {
self.p2p.once('bestHeight', function(height) { self.p2p.once('bestHeight', function(height) {
self._bestHeight = height; self._bestHeight = height;
self._loadTip(self._sync); console.log(self._bestHeight);
self._loadTip(self._sync.bind(self));
}); });

View File

@ -20,9 +20,9 @@ function DB(options) {
Service.call(this, options); Service.call(this, options);
this.version = 2; this.version = 1;
this.dbPrefix = '\u0000\u0000'; this.dbPrefix = new Buffer('00', 'hex');
$.checkState(this.node.network, 'Node is expected to have a "network" property'); $.checkState(this.node.network, 'Node is expected to have a "network" property');
this.network = this.node.network; this.network = this.node.network;
@ -58,35 +58,31 @@ DB.prototype._setDataPath = function() {
} }
}; };
// _checkVersion only governs db versions from bitcore-node >= 4.0
DB.prototype._checkVersion = function(callback) { DB.prototype._checkVersion = function(callback) {
var self = this; var self = this;
self.get(self.dbPrefix + 'tip', self.dbOptions, function(err) { // presupposition is that IF there is a database to open -and- there is a version key
if (err instanceof levelup.errors.NotFoundError) { // in the form below, it will be related to us and it must be equal to this service's version.
return callback();
} else if (err) { var versionBuf = Buffer.concat([ self.dbPrefix, new Buffer('version', 'utf8') ]);
self.get(versionBuf, self.dbOptions, function(err, buffer) {
if (err) {
return callback(err); return callback(err);
} }
self.get(self.dbPrefix + 'version', self.dbOptions, function(err, buffer) {
var version; var version;
if (err instanceof levelup.errors.NotFoundError) {
version = 1; if (buffer) {
} else if (err) { version = buffer.readUInt32BE();
return callback(err); }
} else {
version = buffer.readUInt32BE(); if (self.version !== version) {
} return callback(new Error('The version of the database "' + version + '" does not match the expected version "'));
if (self.version !== version) { }
var helpUrl = 'https://github.com/bitpay/bitcore-node/blob/master/docs/services/db.md#how-to-reindex'; callback();
return callback(new Error(
'The version of the database "' + version + '" does not match the expected version "' +
self.version + '". A recreation of "' + self.dataPath + '" (can take several hours) is ' +
'required or to switch versions of software to match. Please see ' + helpUrl +
' for more information.'
));
}
callback();
});
}); });
}; };
@ -220,52 +216,68 @@ DB.prototype.getPublishEvents = function() {
DB.prototype.getPrefix = function(service, callback) { DB.prototype.getPrefix = function(service, callback) {
var self = this; var self = this;
var keyBuf = Buffer.concat([ self.dbPrefix, new Buffer('prefix-', 'utf8'), new Buffer(service, 'utf8') ]);
var unusedBuf = Buffer.concat([ self.dbPrefix, new Buffer('nextUnused', 'utf8') ]);
function getPrefix(next) { function getPrefix(next) {
self.get(self.dbPrefix + 'prefix-' + service, function(err, buffer) {
if(err) { self.get(keyBuf, function(err, buf) {
if(err.notFound) {
return next(); if (err) {
} return callback(err);
return next(err);
} }
return callback(null, buffer); if (!buf) {
return next();
}
callback(null, buf);
}); });
} }
function getUnused(next) { function getUnused(next) {
self.get(self.dbPrefix + 'nextUnused', function(err, buffer) {
self.get(unusedBuf, function(err, buffer) {
if(err) { if(err) {
if(err.notFound) { return callback(err);
return next(null, new Buffer('0001', 'hex'));
}
return next(err);
} }
return next(null, buffer); if(!buffer) {
}); return next(null, new Buffer('0001', 'hex'));
}
function putPrefix(buffer, next) {
self._store.put(self.dbPrefix + 'prefix-' + service, buffer, function(err) {
if(err) {
return next(err);
} }
next(null, buffer); next(null, buffer);
}); });
} }
function putPrefix(buffer, next) {
self._store.put(keyBuf, buffer, function(err) {
if (err) {
return callback(err);
}
next(null, buffer);
});
}
function putUnused(buffer, next) { function putUnused(buffer, next) {
var prefix = buffer.readUInt16BE(); var prefix = buffer.readUInt16BE();
var nextUnused = new Buffer(2); var nextUnused = new Buffer(2);
nextUnused.writeUInt16BE(prefix + 1); nextUnused.writeUInt16BE(prefix + 1);
self._store.put(self.dbPrefix + 'nextUnused', nextUnused, function(err) { self._store.put(unusedBuf, nextUnused, function(err) {
if(err) {
return next(err); if (err) {
return callback(err);
} }
return next(null, buffer); next(null, buffer);
}); });
} }

View File

@ -103,10 +103,6 @@ WebService.prototype.setupAllRoutes = function() {
var subApp = new express(); var subApp = new express();
var service = this.node.services[key]; var service = this.node.services[key];
this.app.get('/info',
this._endpointGetInfo()
);
if(service.getRoutePrefix && service.setupRoutes) { if(service.getRoutePrefix && service.setupRoutes) {
this.app.use('/' + this.node.services[key].getRoutePrefix(), subApp); this.app.use('/' + this.node.services[key].getRoutePrefix(), subApp);
this.node.services[key].setupRoutes(subApp, express); this.node.services[key].setupRoutes(subApp, express);
@ -279,17 +275,4 @@ WebService.prototype.transformHttpsOptions = function() {
}; };
}; };
WebService.prototype._endpointGetInfo = function() {
var self = this;
return function(req, res) {
res.jsonp({
result: 'ok',
dbheight: self.node.services.block.tip.__height,
dbhash: self.node.services.block.tip.hash,
networkHeight: self.node.services.bitcoind.height,
networkHash: self.node.services.bitcoind.tiphash
});
};
};
module.exports = WebService; module.exports = WebService;

View File

@ -5,7 +5,7 @@ var expect = chai.expect;
var async = require('async'); var async = require('async');
var BitcoinRPC = require('bitcoind-rpc'); var BitcoinRPC = require('bitcoind-rpc');
var path = require('path'); var path = require('path');
var utils = require('./utils'); var Utils = require('./utils');
var debug = true; var debug = true;
var extraDebug = true; var extraDebug = true;
@ -24,14 +24,12 @@ var rpcConfig = {
var bitcoin = { var bitcoin = {
args: { args: {
datadir: bitcoinDataDir, datadir: bitcoinDataDir,
listen: 0, listen: 1,
regtest: 1, regtest: 1,
server: 1, server: 1,
rpcuser: rpcConfig.user, rpcuser: rpcConfig.user,
rpcpassword: rpcConfig.pass, rpcpassword: rpcConfig.pass,
rpcport: rpcConfig.port, rpcport: rpcConfig.port
zmqpubrawtx: 'tcp://127.0.0.1:38332',
zmqpubrawblock: 'tcp://127.0.0.1:38332'
}, },
datadir: bitcoinDataDir, datadir: bitcoinDataDir,
exec: 'bitcoind', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcoind exec: 'bitcoind', //if this isn't on your PATH, then provide the absolute path, e.g. /usr/local/bin/bitcoind
@ -54,14 +52,10 @@ var bitcore = {
'block-test' 'block-test'
], ],
servicesConfig: { servicesConfig: {
bitcoind: { p2p: {
connect: [ peers: [
{ {
rpcconnect: rpcConfig.host, ip: { v4: '127.0.0.1' }
rpcport: rpcConfig.port,
rpcuser: rpcConfig.user,
rpcpassword: rpcConfig.pass,
zmqpubrawtx: bitcoin.args.zmqpubrawtx
} }
] ]
}, },
@ -91,9 +85,22 @@ var opts = {
bitcoreDataDir: bitcoreDataDir, bitcoreDataDir: bitcoreDataDir,
rpc: new BitcoinRPC(rpcConfig), rpc: new BitcoinRPC(rpcConfig),
blockHeight: 0, blockHeight: 0,
initialHeight: 150 initialHeight: 150,
path: '/test/info',
errorFilter: function(req, res) {
try {
var info = JSON.parse(res);
if (info.result) {
return;
}
} catch(e) {
return e;
}
}
}; };
var utils = new Utils(opts);
describe('Block Operations', function() { describe('Block Operations', function() {
this.timeout(60000); this.timeout(60000);
@ -103,16 +110,15 @@ describe('Block Operations', function() {
var self = this; var self = this;
after(function(done) { after(function(done) {
utils.cleanup(self.opts, done); utils.cleanup(done);
}); });
before(function(done) { before(function(done) {
self.opts = Object.assign({}, opts);
async.series([ async.series([
utils.startBitcoind.bind(utils, self.opts), utils.startBitcoind.bind(utils),
utils.waitForBitcoinReady.bind(utils, self.opts), utils.waitForBitcoinReady.bind(utils),
utils.startBitcoreNode.bind(utils, self.opts), utils.startBitcoreNode.bind(utils),
utils.waitForBitcoreNode.bind(utils, self.opts) utils.waitForBitcoreNode.bind(utils)
], done); ], done);
}); });

View File

@ -52,6 +52,15 @@ TestWebService.prototype.setupRoutes = function(app) {
res.status(200).jsonp({ utxos: utxos }); res.status(200).jsonp({ utxos: utxos });
}); });
}); });
app.get('/info', function(req, res) {
var tip = self.node.services.block.tip;
console.log(tip);
if (tip) {
return res.status(200).jsonp({ tip: JSON.stringify(tip) });
}
return res.status(503).end();
});
}; };
TestWebService.prototype.getRoutePrefix = function() { TestWebService.prototype.getRoutePrefix = function() {