get blocks by date
This commit is contained in:
parent
2ae1cdbec2
commit
bc4672760c
124
lib/blocks.js
124
lib/blocks.js
@ -83,50 +83,108 @@ 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;
|
|
||||||
|
|
||||||
async.timesSeries(limit, function(n, next) {
|
|
||||||
self.node.getBlock(lastHash, function(err, block) {
|
|
||||||
if(err) {
|
|
||||||
return next(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
var info = self.node.services.bitcoind.getBlockIndex(block.hash);
|
|
||||||
block.__height = info.height;
|
|
||||||
blocks.push(block);
|
|
||||||
lastHash = BufferUtil.reverse(block.header.prevHash).toString('hex');
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
}, function(err) {
|
|
||||||
if(err) {
|
if(err) {
|
||||||
return common.handleErrors(err, res);
|
return common.handleErrors(err, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = {
|
hashes.reverse();
|
||||||
blocks: blocks.map(function(block) {
|
|
||||||
return {
|
|
||||||
height: block.__height,
|
|
||||||
size: block.toBuffer().length,
|
|
||||||
hash: block.hash,
|
|
||||||
time: block.header.time,
|
|
||||||
txlength: block.transactions.length,
|
|
||||||
poolInfo: {}
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
length: blocks.length,
|
|
||||||
pagination: {}
|
|
||||||
};
|
|
||||||
|
|
||||||
res.jsonp(data);
|
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) {
|
||||||
|
return next(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
var info = self.node.services.bitcoind.getBlockIndex(hash);
|
||||||
|
block.__height = info.height;
|
||||||
|
|
||||||
|
if(moreTs > block.header.timestamp) {
|
||||||
|
moreTs = block.header.timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
return next(null, block);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
function(err, blocks) {
|
||||||
|
if(err) {
|
||||||
|
return common.handleErrors(err, res);
|
||||||
|
}
|
||||||
|
|
||||||
|
blocks.sort(function(a, b) {
|
||||||
|
return b.__height - a.__height;
|
||||||
|
});
|
||||||
|
|
||||||
|
var data = {
|
||||||
|
blocks: blocks.map(function(block) {
|
||||||
|
return {
|
||||||
|
height: block.__height,
|
||||||
|
size: block.toBuffer().length,
|
||||||
|
hash: block.hash,
|
||||||
|
time: block.header.time,
|
||||||
|
txlength: block.transactions.length,
|
||||||
|
poolInfo: {}
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
length: blocks.length,
|
||||||
|
pagination: {
|
||||||
|
next: next,
|
||||||
|
prev: prev,
|
||||||
|
currentTs: lte - 1,
|
||||||
|
current: dateStr,
|
||||||
|
isToday: isToday,
|
||||||
|
more: more
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if(more) {
|
||||||
|
data.pagination.moreTs = moreTs;
|
||||||
|
}
|
||||||
|
|
||||||
|
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.
|
||||||
|
|||||||
@ -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'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user