block: check block argument and fix caching

Checks that the argument sent to the endpoint for /block/ and /rawblock/ is
a 64 character hexadecimal string (blockHash), otherwise will return 404.

Uses a long cache header for for the /rawblock/ endpoint since the result will not
change, and a short cache header for the /block/ endpoint since this data references
other blocks in the chain that can change.
This commit is contained in:
Braydon Fuller 2016-05-26 11:21:36 -04:00
parent 4317f67a2b
commit 667a38053b
3 changed files with 25 additions and 9 deletions

View File

@ -51,7 +51,7 @@ The unspent outputs format now has `satoshis` and `height`:
```
The `timestamp` property will only be set for unconfirmed transactions and `height` can be used for determining block order. The `confirmationsFromCache` is nolonger set or necessary, confirmation count is only cached for the time between blocks.
There is a new `GET` endpoint or raw blocks at `/rawblock/<blockArg>`, where `blockArg` can be hash or height:
There is a new `GET` endpoint or raw blocks at `/rawblock/<blockHash>`:
Response format:
```

View File

@ -2,6 +2,7 @@
var async = require('async');
var bitcore = require('bitcore-lib');
var _ = bitcore.deps._;
var pools = require('../pools.json');
var BN = bitcore.crypto.BN;
var LRU = require('lru-cache');
@ -33,6 +34,22 @@ var BLOCK_LIMIT = 200;
BlockController.DEFAULT_BLOCKSUMMARY_CACHE_SIZE = 1000000;
BlockController.DEFAULT_BLOCK_CACHE_SIZE = 1000;
function isHexadecimal(hash) {
if (!_.isString(hash)) {
return false;
}
return /^[0-9a-fA-F]+$/.test(hash);
}
BlockController.prototype.checkBlockHash = function(req, res, next) {
var self = this;
var hash = req.params.blockHash;
if (hash.length < 64 || !isHexadecimal(hash)) {
return self.common.handleErrors(null, res);
}
next();
};
/**
* Find block by hash ...
*/
@ -72,9 +89,9 @@ BlockController.prototype.block = function(req, res, next) {
*/
BlockController.prototype.rawBlock = function(req, res, next) {
var self = this;
var blockArg = req.params.blockArg;
var blockHash = req.params.blockHash;
self.node.getRawBlock(blockArg, function(err, blockBuffer) {
self.node.getRawBlock(blockHash, function(err, blockBuffer) {
if((err && err.code === -5) || (err && err.code === -8)) {
return self.common.handleErrors(null, res);
} else if(err) {

View File

@ -154,19 +154,18 @@ InsightAPI.prototype.setupRoutes = function(app) {
var blocks = new BlockController(blockOptions);
app.get('/blocks', this.cacheShort(), blocks.list.bind(blocks));
app.get('/block/:blockHash', this.cacheLong(), blocks.show.bind(blocks));
app.get('/block/:blockHash', this.cacheShort(), blocks.checkBlockHash.bind(blocks), blocks.show.bind(blocks));
app.param('blockHash', blocks.block.bind(blocks));
app.get('/rawblock/:blockArg', this.cacheLong(), blocks.showRaw.bind(blocks));
app.param('blockArg', blocks.rawBlock.bind(blocks));
app.get('/rawblock/:blockHash', this.cacheLong(), blocks.checkBlockHash.bind(blocks), blocks.showRaw.bind(blocks));
app.param('blockHash', blocks.rawBlock.bind(blocks));
app.get('/block-index/:height', this.cacheLong(), blocks.blockIndex.bind(blocks));
app.get('/block-index/:height', this.cacheShort(), blocks.blockIndex.bind(blocks));
app.param('height', blocks.blockIndex.bind(blocks));
// Transaction routes
var transactions = new TxController(this.node);
app.get('/tx/:txid', this.cacheLong(), transactions.show.bind(transactions));
app.get('/tx/:txid', this.cacheShort(), transactions.show.bind(transactions));
app.param('txid', transactions.transaction.bind(transactions));
app.get('/txs', this.cacheShort(), transactions.list.bind(transactions));
app.post('/tx/send', transactions.send.bind(transactions));