get blocks by date

This commit is contained in:
Patrick Nagurny 2015-09-15 16:51:54 -04:00
parent 2ae1cdbec2
commit bc4672760c
2 changed files with 106 additions and 38 deletions

View File

@ -83,31 +83,67 @@ BlockController.prototype.blockIndex = function(req, res, next, height) {
BlockController.prototype.list = function(req, res) { BlockController.prototype.list = function(req, res) {
var self = this; var self = this;
// TODO actually get blocks by date instead of just the last blocks var dateStr;
// TODO pagination var todayStr = this.formatTimestamp(new Date());
var isToday;
if (req.query.blockDate) {
dateStr = req.query.blockDate;
isToday = dateStr === todayStr;
} else {
dateStr = todayStr;
isToday = true;
}
var gte = Math.round((new Date(dateStr)).getTime() / 1000);
//pagination
var lte = parseInt(req.query.startTimestamp) || gte + 86400;
var prev = this.formatTimestamp(new Date((gte - 86400) * 1000));
var next = lte ? this.formatTimestamp(new Date(lte * 1000)) : null;
var limit = parseInt(req.query.limit || BLOCK_LIMIT); var limit = parseInt(req.query.limit || BLOCK_LIMIT);
var more = false;
var moreTs = lte;
var blocks = []; self.node.services.db.getBlockHashesByTimestamp(gte, lte, function(err, hashes) {
var lastHash = this.node.services.db.tip.hash; if(err) {
return common.handleErrors(err, res);
}
async.timesSeries(limit, function(n, next) { hashes.reverse();
self.node.getBlock(lastHash, function(err, block) {
if(hashes.length > limit) {
more = true;
hashes = hashes.slice(0, limit);
}
async.mapSeries(
hashes,
function(hash, next) {
self.node.getBlock(hash, function(err, block) {
if(err) { if(err) {
return next(err); return next(err);
} }
var info = self.node.services.bitcoind.getBlockIndex(block.hash); var info = self.node.services.bitcoind.getBlockIndex(hash);
block.__height = info.height; block.__height = info.height;
blocks.push(block);
lastHash = BufferUtil.reverse(block.header.prevHash).toString('hex'); if(moreTs > block.header.timestamp) {
next(); moreTs = block.header.timestamp;
}
return next(null, block);
}); });
}, function(err) { },
function(err, blocks) {
if(err) { if(err) {
return common.handleErrors(err, res); return common.handleErrors(err, res);
} }
blocks.sort(function(a, b) {
return b.__height - a.__height;
});
var data = { var data = {
blocks: blocks.map(function(block) { blocks: blocks.map(function(block) {
return { return {
@ -120,13 +156,35 @@ BlockController.prototype.list = function(req, res) {
}; };
}), }),
length: blocks.length, length: blocks.length,
pagination: {} pagination: {
next: next,
prev: prev,
currentTs: lte - 1,
current: dateStr,
isToday: isToday,
more: more
}
}; };
if(more) {
data.pagination.moreTs = moreTs;
}
res.jsonp(data); res.jsonp(data);
}
);
}); });
}; };
//helper to convert timestamps to yyyy-mm-dd format
BlockController.prototype.formatTimestamp = function(date) {
var yyyy = date.getUTCFullYear().toString();
var mm = (date.getUTCMonth() + 1).toString(); // getMonth() is zero-based
var dd = date.getUTCDate().toString();
return yyyy + '-' + (mm[1] ? mm : '0' + mm[0]) + '-' + (dd[1] ? dd : '0' + dd[0]); //padding
};
BlockController.prototype.getBlockReward = function(height) { BlockController.prototype.getBlockReward = function(height) {
var halvings = Math.floor(height / 210000); var halvings = Math.floor(height / 210000);
// Force block reward to zero when right shift is undefined. // Force block reward to zero when right shift is undefined.

View File

@ -125,13 +125,24 @@ describe('Blocks', function() {
} }
], ],
"length": 2, "length": 2,
"pagination": {} "pagination": {
"current": "2015-08-30",
"currentTs": 1440979199,
"isToday": false,
"more": false,
"next": "2015-08-31",
"prev": "2015-08-29"
}
}; };
var stub = sinon.stub(); var stub = sinon.stub();
stub.onFirstCall().callsArgWith(1, null, bitcore.Block.fromBuffer(blocks['000000000008fbb2e358e382a6f6948b2da24563bba183af447e6e2542e8efc7'], 'hex')); stub.onFirstCall().callsArgWith(1, null, bitcore.Block.fromBuffer(blocks['000000000008fbb2e358e382a6f6948b2da24563bba183af447e6e2542e8efc7'], 'hex'));
stub.onSecondCall().callsArgWith(1, null, bitcore.Block.fromBuffer(blocks['00000000000006bd8fe9e53780323c0e85719eca771022e1eb6d10c62195c441'], 'hex')) stub.onSecondCall().callsArgWith(1, null, bitcore.Block.fromBuffer(blocks['00000000000006bd8fe9e53780323c0e85719eca771022e1eb6d10c62195c441'], 'hex'))
var hashes = [
'00000000000006bd8fe9e53780323c0e85719eca771022e1eb6d10c62195c441',
'000000000008fbb2e358e382a6f6948b2da24563bba183af447e6e2542e8efc7'
];
var node = { var node = {
getBlock: stub, getBlock: stub,
services: { services: {
@ -141,9 +152,7 @@ describe('Blocks', function() {
} }
}, },
db: { db: {
tip: { getBlockHashesByTimestamp: sinon.stub().callsArgWith(2, null, hashes)
hash: '000000000008fbb2e358e382a6f6948b2da24563bba183af447e6e2542e8efc7'
}
} }
} }
}; };
@ -153,7 +162,8 @@ describe('Blocks', function() {
var req = { var req = {
query: { query: {
limit: 2 limit: 2,
blockDate: '2015-08-30'
} }
}; };