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 LRU = require('lru-cache');
var assert = require('assert');
var constants = require('./constants');
var Service = function(options) {
EventEmitter.call(this);

View File

@ -14,7 +14,7 @@ var BlockHandler = require('./block_handler');
var LRU = require('lru-cache');
var utils = require('../../utils');
var _ = require('lodash');
var constants = require('../../constants');
var assert = require('assert');
var BlockService = function(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) {
if (!_.isArray(opts.operations)) {
@ -355,7 +360,8 @@ BlockService.prototype._setHandlers = function() {
self.p2p.once('bestHeight', function(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);
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');
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) {
var self = this;
self.get(self.dbPrefix + 'tip', self.dbOptions, function(err) {
if (err instanceof levelup.errors.NotFoundError) {
return callback();
} else if (err) {
// presupposition is that IF there is a database to open -and- there is a version key
// in the form below, it will be related to us and it must be equal to this service's version.
var versionBuf = Buffer.concat([ self.dbPrefix, new Buffer('version', 'utf8') ]);
self.get(versionBuf, self.dbOptions, function(err, buffer) {
if (err) {
return callback(err);
}
self.get(self.dbPrefix + 'version', self.dbOptions, function(err, buffer) {
var version;
if (err instanceof levelup.errors.NotFoundError) {
version = 1;
} else if (err) {
return callback(err);
} else {
version = buffer.readUInt32BE();
}
if (self.version !== version) {
var helpUrl = 'https://github.com/bitpay/bitcore-node/blob/master/docs/services/db.md#how-to-reindex';
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();
});
var version;
if (buffer) {
version = buffer.readUInt32BE();
}
if (self.version !== version) {
return callback(new Error('The version of the database "' + version + '" does not match the expected version "'));
}
callback();
});
};
@ -220,52 +216,68 @@ DB.prototype.getPublishEvents = function() {
DB.prototype.getPrefix = function(service, callback) {
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) {
self.get(self.dbPrefix + 'prefix-' + service, function(err, buffer) {
if(err) {
if(err.notFound) {
return next();
}
return next(err);
self.get(keyBuf, function(err, buf) {
if (err) {
return callback(err);
}
return callback(null, buffer);
if (!buf) {
return next();
}
callback(null, buf);
});
}
function getUnused(next) {
self.get(self.dbPrefix + 'nextUnused', function(err, buffer) {
self.get(unusedBuf, function(err, buffer) {
if(err) {
if(err.notFound) {
return next(null, new Buffer('0001', 'hex'));
}
return next(err);
return callback(err);
}
return next(null, buffer);
});
}
function putPrefix(buffer, next) {
self._store.put(self.dbPrefix + 'prefix-' + service, buffer, function(err) {
if(err) {
return next(err);
if(!buffer) {
return next(null, new Buffer('0001', 'hex'));
}
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) {
var prefix = buffer.readUInt16BE();
var nextUnused = new Buffer(2);
nextUnused.writeUInt16BE(prefix + 1);
self._store.put(self.dbPrefix + 'nextUnused', nextUnused, function(err) {
if(err) {
return next(err);
self._store.put(unusedBuf, nextUnused, function(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 service = this.node.services[key];
this.app.get('/info',
this._endpointGetInfo()
);
if(service.getRoutePrefix && service.setupRoutes) {
this.app.use('/' + this.node.services[key].getRoutePrefix(), subApp);
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;

View File

@ -5,7 +5,7 @@ var expect = chai.expect;
var async = require('async');
var BitcoinRPC = require('bitcoind-rpc');
var path = require('path');
var utils = require('./utils');
var Utils = require('./utils');
var debug = true;
var extraDebug = true;
@ -24,14 +24,12 @@ var rpcConfig = {
var bitcoin = {
args: {
datadir: bitcoinDataDir,
listen: 0,
listen: 1,
regtest: 1,
server: 1,
rpcuser: rpcConfig.user,
rpcpassword: rpcConfig.pass,
rpcport: rpcConfig.port,
zmqpubrawtx: 'tcp://127.0.0.1:38332',
zmqpubrawblock: 'tcp://127.0.0.1:38332'
rpcport: rpcConfig.port
},
datadir: bitcoinDataDir,
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'
],
servicesConfig: {
bitcoind: {
connect: [
p2p: {
peers: [
{
rpcconnect: rpcConfig.host,
rpcport: rpcConfig.port,
rpcuser: rpcConfig.user,
rpcpassword: rpcConfig.pass,
zmqpubrawtx: bitcoin.args.zmqpubrawtx
ip: { v4: '127.0.0.1' }
}
]
},
@ -91,9 +85,22 @@ var opts = {
bitcoreDataDir: bitcoreDataDir,
rpc: new BitcoinRPC(rpcConfig),
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() {
this.timeout(60000);
@ -103,16 +110,15 @@ describe('Block Operations', function() {
var self = this;
after(function(done) {
utils.cleanup(self.opts, done);
utils.cleanup(done);
});
before(function(done) {
self.opts = Object.assign({}, opts);
async.series([
utils.startBitcoind.bind(utils, self.opts),
utils.waitForBitcoinReady.bind(utils, self.opts),
utils.startBitcoreNode.bind(utils, self.opts),
utils.waitForBitcoreNode.bind(utils, self.opts)
utils.startBitcoind.bind(utils),
utils.waitForBitcoinReady.bind(utils),
utils.startBitcoreNode.bind(utils),
utils.waitForBitcoreNode.bind(utils)
], done);
});

View File

@ -52,6 +52,15 @@ TestWebService.prototype.setupRoutes = function(app) {
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() {