From b0f95d93ab8c78305e3f5d799ef8589874755d06 Mon Sep 17 00:00:00 2001 From: tenthirtyone Date: Tue, 15 Aug 2017 23:14:24 -0400 Subject: [PATCH] All API but tx & socket cleaned up, blocks db api done --- server/lib/api/block.js | 130 ++++++++++++++-------------------- server/lib/api/index.js | 13 +--- server/lib/api/status.js | 112 ++++++++++++++++------------- server/lib/api/transaction.js | 14 ++-- server/lib/db/blocks.js | 14 ++-- server/models/address.js | 6 +- server/models/block.js | 28 ++++---- server/models/input.js | 10 +-- server/models/output.js | 8 +-- server/models/transaction.js | 26 +++---- 10 files changed, 172 insertions(+), 189 deletions(-) diff --git a/server/lib/api/block.js b/server/lib/api/block.js index 2141347..fb64178 100644 --- a/server/lib/api/block.js +++ b/server/lib/api/block.js @@ -1,66 +1,44 @@ -const Block = require('../../models/block.js'); const logger = require('../logger'); - -const MAX_BLOCKS = 100; - -function getBlock(params, options, limit, cb) { - const defaultOptions = { _id: 0 }; - - if (!Number.isInteger(limit)) { - limit = MAX_BLOCKS; - } - - Object.assign(defaultOptions, options); - - Block.find( - params, - defaultOptions, - cb) - .sort({ height: -1 }) - .limit(limit); -} +const db = require('../db'); module.exports = function BlockAPI(router) { router.get('/block/:blockHash', (req, res) => { - getBlock( + db.blocks.getBlock( { hash: req.params.blockHash }, { rawBlock: 0 }, - MAX_BLOCKS, + 1, (err, block) => { if (err) { - res.status(501).send(); logger.log('err', err); + return res.status(404).send(); } - if (block[0]) { - const b = block[0]; - res.json({ - hash: b.hash, - size: b.size, - height: b.height, - version: b.version, - merkleroot: b.merkleRoot, - tx: b.txs, - time: b.ts, - nonce: b.nonce, - bits: b.bits.toString(16), - difficulty: 1, - chainwork: b.chainwork.toString(16), - confirmations: 0, - previousblockhash: b.prevBlock, - nextblockhash: 0, - reward: b.reward / 1e8, - isMainChain: true, - poolInfo: {}, - }); - } else { - res.status(404).send('Not Found'); - } + + return res.json({ + hash: block.hash, + size: block.size, + height: block.height, + version: block.version, + merkleroot: block.merkleRoot, + tx: block.txs, + time: block.ts, + nonce: block.nonce, + bits: block.bits.toString(16), + difficulty: 1, + chainwork: block.chainwork.toString(16), + confirmations: 0, + previousblockhash: block.prevBlock, + nextblockhash: 0, + reward: block.reward / 1e8, + isMainChain: true, + poolInfo: {}, + }); }); }); router.get('/blocks', (req, res) => { - const limit = parseInt(req.query.limit) || MAX_BLOCKS; - getBlock( + const limit = parseInt(req.query.limit) || 100; + + db.blocks.getBlocks( {}, { height: 1, size: 1, @@ -72,59 +50,59 @@ module.exports = function BlockAPI(router) { limit, (err, blocks) => { if (err) { - res.status(501).send(); - logger.log('err', err); - return; + logger.log('err', + `/blocks: ${err}`); + return res.status(404).send(); } - res.json({ + return res.json({ blocks: blocks.map(block => ({ - hash: block.hash, - height: block.height, - size: block.size, - time: block.ts, + hash: block.hash, + height: block.height, + size: block.size, + time: block.ts, txlength: block.txs.length, poolInfo: {}, })), - length: blocks.length, + length: blocks.length, pagination: {}, }); }); }); router.get('/rawblock/:blockHash', (req, res) => { - getBlock( - { hash: req.params.blockHash }, + const blockHash = req.params.blockHash || ''; + + db.blocks.getBlock( + { hash: blockHash }, { rawBlock: 1 }, - MAX_BLOCKS, + 1, (err, block) => { if (err) { - res.status(501).send(); - logger.log('err', err); + logger.log('err', + `/rawblock/:blockHash: ${err}`); + return res.status(404).send(); } - res.json(block[0]); + return res.json(block); }); }); router.get('/block-index/:height', (req, res) => { - let blockHeight = parseInt(req.params.height) || 1; + const blockHeight = parseInt(req.params.height) || 1; - getBlock( + db.blocks.getBlock( { height: blockHeight }, { hash: 1 }, - MAX_BLOCKS, + 1, (err, block) => { if (err) { - res.status(501).send(); - logger.log('err', err); - } - if (block[0]) { - res.json({ - blockHash: block[0].hash, - }); - } else { - res.status(404).send('Not Found'); + logger.log('err', + `/block-index/:height: ${err}`); + return res.status(404).send(); } + return res.json({ + blockHash: block.hash, + }); }); }); }; diff --git a/server/lib/api/index.js b/server/lib/api/index.js index 8af680b..dfe702c 100644 --- a/server/lib/api/index.js +++ b/server/lib/api/index.js @@ -13,18 +13,7 @@ app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()); // Serve insight ui front end from root dir public folder -app.use('/', express.static('./public')); -app.use('/:stuff', express.static('./public')); -app.use('/blocks', express.static('./public')); -app.use('/blocks/:blockhash', express.static('./public')); -app.use('/block-index', express.static('./public')); -app.use('/block-index/:height', express.static('./public')); -app.use('/blocks-date/:date', express.static('./public')); -app.use('/block/:blockhash', express.static('./public')); -app.use('/tx/:txid', express.static('./public')); -app.use('/address/:addr', express.static('./public')); -app.use('/status', express.static('./public')); -app.use('/status/:stuff', express.static('./public')); +app.use(express.static('./public')); app.set('json spaces', config.api.json_spaces); diff --git a/server/lib/api/status.js b/server/lib/api/status.js index 758e55a..a8f82b8 100644 --- a/server/lib/api/status.js +++ b/server/lib/api/status.js @@ -1,87 +1,99 @@ const request = require('request'); -const Block = require('../../models/block'); const pkg = require('../../package.json'); const config = require('../../config'); const netCfg = require('bcoin/lib/net/common'); const logger = require('../logger'); +const db = require('../db'); + +const API_URL = `http://${config.bcoin_http}:${config.bcoin['http-port']}/`; -// Here comes the ugly. Moo who haha function getStatus(cb) { - request(`http://${config.bcoin_http}:${config.bcoin['http-port']}/`, (err, localRes, body) => { + request(`${API_URL}`, (err, localRes, status) => { if (err) { logger.log('error', - `${err}`); + `getStatus ${err}`); + return cb(err); } try { - body = JSON.parse(body); + status = JSON.parse(status); } catch (e) { logger.log('error', - `${err}`); - cb(e); + `getStatus JSON.parse: ${e}`); + return cb(e); } - cb(null, body); + return cb(null, status); }); } - +// UI assigns Multiple Responsibilities depending on params module.exports = function statusAPI(router) { router.get('/status', (req, res) => { if (req.query.q === 'getLastBlockHash') { - Block.findOne({}, { 'hash': 1 }, { sort: { 'height': -1 } }, (err, block) => { - if (err) { - logger.log('error', - `${err}`); - res.status(501).send(err); - } else { - res.send({ + db.blocks.getBlock( + {}, + { hash: 1 }, + 1, + (err, block) => { + if (err) { + logger.log('error', + `${err}`); + return res.status(404).send(err); + } + return res.send({ syncTipHash: block.hash, lastblockhash: block.hash, }); - } - }); + }); } else { getStatus((err, status) => { if (err) { - res.status(501).send(err); - } else if (status) { - res.json({ - info: { - version: status.version, - protocolversion: netCfg.PROTOCOL_VERSION, - blocks: status.chain.height, - timeoffset: status.time.offset, - connections: status.pool.outbound, - proxy: '', - difficulty: 0, - testnet: status.network !== 'main', - relayfee: 0, - errors: '', - network: status.network, - }, - }); - } else { - res.send(); + logger.log('err' + `/status getStatus: ${err}`); + return res.status(404).send(err); } + if (!status) { + logger.log('err' + `/status getStatus: no Status`); + return res.status(404).send(); + } + res.json({ + info: { + version: status.version, + protocolversion: netCfg.PROTOCOL_VERSION, + blocks: status.chain.height, + timeoffset: status.time.offset, + connections: status.pool.outbound, + proxy: '', + difficulty: 0, + testnet: status.network !== 'main', + relayfee: 0, + errors: '', + network: status.network, + }, + }); }); } - }); router.get('/sync', (req, res) => { getStatus((err, status) => { if (err) { - res.status(501).send(err); - } else if (status) { - res.json({ - status: 'syncing', - blockChainHeight: status.chain.height, - syncPercentage: Math.round(status.chain.progress * 100), - height: status.chain.height, - error: null, - type: 'bcoin node', - }); - } else { - res.send(); + logger.log('err', + `/sync: ${err}`); + return res.status(404).send(err); } + if (!status) { + logger.log('err', + '/sync: no status'); + return res.status(404).send(); + } + res.json({ + status: status.chain.progress === 100 ? 'synced' : 'syncing', + blockChainHeight: status.chain.height, + syncPercentage: Math.round(status.chain.progress * 100), + height: status.chain.height, + error: null, + type: 'bcoin node', + }); }); }); diff --git a/server/lib/api/transaction.js b/server/lib/api/transaction.js index a7968b4..3a15609 100644 --- a/server/lib/api/transaction.js +++ b/server/lib/api/transaction.js @@ -47,7 +47,7 @@ module.exports = function transactionAPI(router) { 1, (err, block) => { if (err) { - res.status(501).send(); + res.status(404).send(); logger.log('err', err); } if (block[0]) { @@ -63,7 +63,7 @@ module.exports = function transactionAPI(router) { } catch (e) { logger.log('error', `${err}`); - res.status(501).send(); + res.status(404).send(); return; } if (!body || !body.hash) { @@ -112,7 +112,7 @@ module.exports = function transactionAPI(router) { 1, (err, block) => { if (err) { - res.status(501).send(); + res.status(404).send(); logger.log('err', err); } if (block[0]) { @@ -127,12 +127,12 @@ module.exports = function transactionAPI(router) { } catch (e) { logger.log('error', `${err}`); - res.status(501).send(); + res.status(404).send(); } if (!body.txs.length) { logger.log('error', `${'No tx results'}`); - res.status(501).send(); + res.status(404).send(); } const totalPages = Math.ceil(body.txs.length / MAX_TXS); body.txs = body.txs.slice(rangeStart, rangeEnd); @@ -167,7 +167,7 @@ module.exports = function transactionAPI(router) { 1, (err, block) => { if (err) { - res.status(501).send(); + res.status(404).send(); logger.log('err', err); } if (block[0]) { @@ -212,7 +212,7 @@ module.exports = function transactionAPI(router) { {}, (err, txs) => { if (err) { - res.status(501).send(); + res.status(404).send(); } res.json({ pagesTotal: 1, diff --git a/server/lib/db/blocks.js b/server/lib/db/blocks.js index cdc200c..be2ad62 100644 --- a/server/lib/db/blocks.js +++ b/server/lib/db/blocks.js @@ -3,7 +3,7 @@ const logger = require('../logger'); const config = require('../../config'); // move to config -const MAX_BLOCKS = 200; +const MAX_BLOCKS = 50; const blockTemplate = new Block(); function getBlocks(params, options, limit, cb) { @@ -12,13 +12,17 @@ function getBlocks(params, options, limit, cb) { Object.assign(defaultOptions, options); if (!Number.isInteger(limit)) { - limit = MAX_BLOCKS; + limit = 1; } if (limit > MAX_BLOCKS) { limit = MAX_BLOCKS; } + if (limit < 1) { + limit = 1; + } + Block.find( params, defaultOptions, @@ -28,10 +32,10 @@ function getBlocks(params, options, limit, cb) { `getBlocks: ${err}`); return cb(err); } - if (blocks.length > 0) { - return cb(null, blocks); + if (!blocks.length > 0) { + return cb({err: 'Block not found'}); } - return cb(null, [blockTemplate]); + return cb(null, blocks); }) .sort({ height: -1 }) .limit(limit); diff --git a/server/models/address.js b/server/models/address.js index 728b5f4..20fd32b 100644 --- a/server/models/address.js +++ b/server/models/address.js @@ -5,9 +5,9 @@ const Output = require('./output'); const Schema = mongoose.Schema; const AddressSchema = new Schema({ - address: String, - inputs: [Input.schema], - outputs: [Output.schema], + address: { type: String, default: '' }, + inputs: [Input.schema], + outputs: [Output.schema], }); const Address = mongoose.model('Address', AddressSchema); diff --git a/server/models/block.js b/server/models/block.js index 515fe70..38ba3aa 100644 --- a/server/models/block.js +++ b/server/models/block.js @@ -4,21 +4,21 @@ const Transaction = require('./transaction'); const Schema = mongoose.Schema; const BlockSchema = new Schema({ - hash: String, - height: Number, - size: Number, - version: Number, - prevBlock: String, - merkleRoot: String, - ts: Number, - bits: Number, - nonce: Number, + hash: { type: String, default: '' }, + height: { type: Number, default: 0 }, + size: { type: Number, default: 0 }, + version: { type: Number, default: 0 }, + prevBlock: { type: String, default: '' }, + merkleRoot: { type: String, default: '' }, + ts: { type: Number, default: 0 }, + bits: { type: Number, default: 0 }, + nonce: { type: Number, default: 0 }, txs: [Transaction.schema], - chainwork: Number, - reward: Number, - network: String, - poolInfo: Object, - rawBlock: String, + chainwork: { type: Number, default: 0 }, + reward: { type: Number, default: 0 }, + network: { type: String, default: '' }, + poolInfo: { type: Object, default: {} }, + rawBlock: { type: String, default: '' }, }, { toJSON: { virtuals: true, diff --git a/server/models/input.js b/server/models/input.js index 9f5f0a9..9f2c067 100644 --- a/server/models/input.js +++ b/server/models/input.js @@ -3,11 +3,11 @@ const mongoose = require('mongoose'); const Schema = mongoose.Schema; const InputSchema = new Schema({ - prevout: Object, - script: String, - witness: String, - sequence: Number, - address: String, + prevout: { type: Object, default: {} }, + script: { type: String, default: '' }, + witness: { type: String, default: '' }, + sequence: { type: Number, default: 0 }, + address: { type: String, default: '' }, }); const Input = mongoose.model('Input', InputSchema); diff --git a/server/models/output.js b/server/models/output.js index 709445b..65f2194 100644 --- a/server/models/output.js +++ b/server/models/output.js @@ -3,10 +3,10 @@ const mongoose = require('mongoose'); const Schema = mongoose.Schema; const OutputSchema = new Schema({ - address: String, - script: String, - value: Number, - type: String, + address: { type: String, default: '' }, + script: { type: String, default: '' }, + value: { type: Number, default: 0 }, + type: { type: String, default: '' }, }); const Output = mongoose.model('Output', OutputSchema); diff --git a/server/models/transaction.js b/server/models/transaction.js index 73c4f4d..0c5974b 100644 --- a/server/models/transaction.js +++ b/server/models/transaction.js @@ -5,21 +5,21 @@ const Output = require('./output'); const Schema = mongoose.Schema; const TransactionSchema = new Schema({ - hash: String, - witnessHash: String, - fee: Number, - rate: Number, - ps: Number, - height: Number, - block: String, - index: Number, - version: Number, - flag: Number, - lockTime: Number, + hash: { type: String, default: '' }, + witnessHash: { type: String, default: '' }, + fee: { type: Number, default: 0 }, + rate: { type: Number, default: 0 }, + ps: { type: Number, default: 0 }, + height: { type: Number, default: 0 }, + block: { type: String, default: '' }, + index: { type: Number, default: 0 }, + version: { type: Number, default: 0 }, + flag: { type: Number, default: 0 }, + lockTime: { type: Number, default: 0 }, inputs: [Input.schema], outputs: [Output.schema], - size: Number, - network: String, + size: { type: Number, default: 0 }, + network: { type: String, default: '' }, }); const Transaction = mongoose.model('Transaction', TransactionSchema);