add getBlockHashesByTimestamp
This commit is contained in:
parent
696759849f
commit
eaee098cf0
|
@ -32,3 +32,14 @@ node.getBlock(blockHash, function(err, block) {
|
|||
//...
|
||||
});
|
||||
```
|
||||
|
||||
Get Block Hashes by Timestamp Range
|
||||
|
||||
```js
|
||||
var time1 = 1441911000; // Notice time is in seconds not milliseconds
|
||||
var time2 = 1441914000;
|
||||
|
||||
node.getBlockHashesByTimestamp(time1, time2, function(err, hashes) {
|
||||
//...
|
||||
});
|
||||
```
|
||||
|
|
|
@ -60,6 +60,10 @@ util.inherits(DB, Service);
|
|||
|
||||
DB.dependencies = ['bitcoind'];
|
||||
|
||||
DB.PREFIXES = {
|
||||
BLOCKS: 'blk'
|
||||
};
|
||||
|
||||
DB.prototype._setDataPath = function() {
|
||||
$.checkState(this.node.datadir, 'Node is expected to have a "datadir" property');
|
||||
var regtest = Networks.get('regtest');
|
||||
|
@ -177,6 +181,7 @@ DB.prototype.transactionHandler = function(txInfo) {
|
|||
DB.prototype.getAPIMethods = function() {
|
||||
var methods = [
|
||||
['getBlock', this, this.getBlock, 1],
|
||||
['getBlockHashesByTimestamp', this, this.getBlockHashesByTimestamp, 2],
|
||||
['getTransaction', this, this.getTransaction, 2],
|
||||
['getTransactionWithBlockInfo', this, this.getTransactionWithBlockInfo, 2],
|
||||
['sendTransaction', this, this.sendTransaction, 1],
|
||||
|
@ -194,6 +199,37 @@ DB.prototype.getBlock = function(hash, callback) {
|
|||
});
|
||||
};
|
||||
|
||||
DB.prototype.getBlockHashesByTimestamp = function(start, end, callback) {
|
||||
var hashes = [];
|
||||
|
||||
var stream = this.store.createReadStream({
|
||||
start: [DB.PREFIXES.BLOCKS, start].join('-'),
|
||||
end: [DB.PREFIXES.BLOCKS, end].join('-')
|
||||
});
|
||||
|
||||
stream.on('data', function(data) {
|
||||
hashes.push(data.value);
|
||||
});
|
||||
|
||||
var error;
|
||||
|
||||
stream.on('error', function(streamError) {
|
||||
if (streamError) {
|
||||
error = streamError;
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('close', function() {
|
||||
if (error) {
|
||||
return callback(error);
|
||||
}
|
||||
|
||||
callback(null, hashes);
|
||||
});
|
||||
|
||||
return stream;
|
||||
};
|
||||
|
||||
DB.prototype.getTransaction = function(txid, queryMempool, callback) {
|
||||
this.node.services.bitcoind.getTransaction(txid, queryMempool, function(err, txBuffer) {
|
||||
if (err) {
|
||||
|
@ -371,6 +407,13 @@ DB.prototype.runAllBlockHandlers = function(block, add, callback) {
|
|||
this.subscriptions.block[i].emit('block', block.hash);
|
||||
}
|
||||
|
||||
// Update block index
|
||||
operations.push({
|
||||
type: add ? 'put' : 'del',
|
||||
key: [DB.PREFIXES.BLOCKS, block.header.timestamp].join('-'),
|
||||
value: block.hash
|
||||
});
|
||||
|
||||
async.eachSeries(
|
||||
this.node.services,
|
||||
function(mod, next) {
|
||||
|
|
|
@ -369,6 +369,62 @@ describe('DB Service', function() {
|
|||
});
|
||||
});
|
||||
|
||||
describe('#getBlockHashesByTimestamp', function() {
|
||||
it('should get the correct block hashes', function(done) {
|
||||
var db = new DB(baseConfig);
|
||||
var readStream = new EventEmitter();
|
||||
db.store = {
|
||||
createReadStream: sinon.stub().returns(readStream)
|
||||
};
|
||||
|
||||
var block1 = {
|
||||
hash: '00000000050a6d07f583beba2d803296eb1e9d4980c4a20f206c584e89a4f02b',
|
||||
timestamp: 1441911909
|
||||
};
|
||||
|
||||
var block2 = {
|
||||
hash: '000000000383752a55a0b2891ce018fd0fdc0b6352502772b034ec282b4a1bf6',
|
||||
timestamp: 1441913112
|
||||
};
|
||||
|
||||
db.getBlockHashesByTimestamp(1441911000, 1441914000, function(err, hashes) {
|
||||
should.not.exist(err);
|
||||
hashes.should.deep.equal([block1.hash, block2.hash]);
|
||||
done();
|
||||
});
|
||||
|
||||
readStream.emit('data', {
|
||||
key: 'blk-' + block1.timestamp,
|
||||
value: block1.hash
|
||||
});
|
||||
|
||||
readStream.emit('data', {
|
||||
key: 'blk-' + block2.timestamp,
|
||||
value: block2.hash
|
||||
});
|
||||
|
||||
readStream.emit('close');
|
||||
});
|
||||
|
||||
it('should give an error if the stream has an error', function(done) {
|
||||
var db = new DB(baseConfig);
|
||||
var readStream = new EventEmitter();
|
||||
db.store = {
|
||||
createReadStream: sinon.stub().returns(readStream)
|
||||
};
|
||||
|
||||
db.getBlockHashesByTimestamp(1441911000, 1441914000, function(err, hashes) {
|
||||
should.exist(err);
|
||||
err.message.should.equal('error');
|
||||
done();
|
||||
});
|
||||
|
||||
readStream.emit('error', new Error('error'));
|
||||
|
||||
readStream.emit('close');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#getPrevHash', function() {
|
||||
it('should return prevHash from bitcoind', function(done) {
|
||||
var db = new DB(baseConfig);
|
||||
|
@ -650,10 +706,22 @@ describe('DB Service', function() {
|
|||
batch: sinon.stub().callsArg(1)
|
||||
};
|
||||
|
||||
var block = {
|
||||
hash: '00000000000000000d0aaf93e464ddeb503655a0750f8b9c6eed0bdf0ccfc863',
|
||||
header: {
|
||||
timestamp: 1441906365
|
||||
}
|
||||
};
|
||||
|
||||
it('should call blockHandler in all services and perform operations', function(done) {
|
||||
db.runAllBlockHandlers('block', true, function(err) {
|
||||
db.runAllBlockHandlers(block, true, function(err) {
|
||||
should.not.exist(err);
|
||||
db.store.batch.args[0][0].should.deep.equal(['op1', 'op2', 'op3', 'op4', 'op5']);
|
||||
var blockOp = {
|
||||
type: 'put',
|
||||
key: 'blk-1441906365',
|
||||
value: '00000000000000000d0aaf93e464ddeb503655a0750f8b9c6eed0bdf0ccfc863'
|
||||
}
|
||||
db.store.batch.args[0][0].should.deep.equal([blockOp, 'op1', 'op2', 'op3', 'op4', 'op5']);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
@ -663,7 +731,7 @@ describe('DB Service', function() {
|
|||
Service3.prototype.blockHandler = sinon.stub().callsArgWith(2, new Error('error'));
|
||||
db.node.services.service3 = new Service3();
|
||||
|
||||
db.runAllBlockHandlers('block', true, function(err) {
|
||||
db.runAllBlockHandlers(block, true, function(err) {
|
||||
should.exist(err);
|
||||
done();
|
||||
});
|
||||
|
@ -675,7 +743,7 @@ describe('DB Service', function() {
|
|||
service3: new Service3()
|
||||
};
|
||||
|
||||
db.runAllBlockHandlers('block', true, function(err) {
|
||||
db.runAllBlockHandlers(block, true, function(err) {
|
||||
should.not.exist(err);
|
||||
done();
|
||||
});
|
||||
|
@ -688,7 +756,7 @@ describe('DB Service', function() {
|
|||
};
|
||||
|
||||
(function() {
|
||||
db.runAllBlockHandlers('block', true, function(err) {
|
||||
db.runAllBlockHandlers(block, true, function(err) {
|
||||
should.not.exist(err);
|
||||
});
|
||||
}).should.throw('bitcore.ErrorInvalidArgument');
|
||||
|
@ -701,7 +769,7 @@ describe('DB Service', function() {
|
|||
db.node = {};
|
||||
db.node.services = {};
|
||||
var methods = db.getAPIMethods();
|
||||
methods.length.should.equal(5);
|
||||
methods.length.should.equal(6);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue