All routes replaced. Stable but no tx inputs working.
This commit is contained in:
parent
31eecc5afe
commit
5a89cf17d2
@ -1,6 +1,7 @@
|
|||||||
const logger = require('../logger');
|
const logger = require('../logger');
|
||||||
const request = require('request');
|
const request = require('request');
|
||||||
const config = require('../../config');
|
const config = require('../../config');
|
||||||
|
const db = require('../db');
|
||||||
|
|
||||||
const API_URL = `http://${config.bcoin_http}:${config.bcoin['http-port']}`;
|
const API_URL = `http://${config.bcoin_http}:${config.bcoin['http-port']}`;
|
||||||
const TTL = config.api.request_ttl;
|
const TTL = config.api.request_ttl;
|
||||||
@ -8,8 +9,18 @@ const TTL = config.api.request_ttl;
|
|||||||
module.exports = function AddressAPI(router) {
|
module.exports = function AddressAPI(router) {
|
||||||
router.get('/addr/:addr', (req, res) => {
|
router.get('/addr/:addr', (req, res) => {
|
||||||
const addr = req.params.addr || '';
|
const addr = req.params.addr || '';
|
||||||
logger.log('debug',
|
/*
|
||||||
'Warning: Requesting data from Bcoin by address, may take some time');
|
db.txs.getTxByAddress(addr, 0, 999999999, (error, txs) => {
|
||||||
|
if (error) {
|
||||||
|
logger.log('err',
|
||||||
|
`getTxByBlock ${error}`);
|
||||||
|
return res.status(404).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(txs.count());
|
||||||
|
|
||||||
|
});
|
||||||
|
*/
|
||||||
// Get Bcoin data
|
// Get Bcoin data
|
||||||
return request(`${API_URL}/tx/address/${addr}`,
|
return request(`${API_URL}/tx/address/${addr}`,
|
||||||
{ timeout: TTL },
|
{ timeout: TTL },
|
||||||
|
|||||||
@ -19,9 +19,9 @@ module.exports = function transactionAPI(router) {
|
|||||||
if (err) {
|
if (err) {
|
||||||
logger.log('err',
|
logger.log('err',
|
||||||
`getTxById: ${err}`);
|
`getTxById: ${err}`);
|
||||||
return res.status(400).send();
|
return res.status(404).send();
|
||||||
}
|
}
|
||||||
console.log(transaction);
|
|
||||||
const tx = transaction;
|
const tx = transaction;
|
||||||
return res.send({
|
return res.send({
|
||||||
txid: tx.hash,
|
txid: tx.hash,
|
||||||
@ -31,6 +31,7 @@ module.exports = function transactionAPI(router) {
|
|||||||
locktime: tx.locktime,
|
locktime: tx.locktime,
|
||||||
blockhash: tx.block,
|
blockhash: tx.block,
|
||||||
fees: tx.fee / 1e8,
|
fees: tx.fee / 1e8,
|
||||||
|
size: tx.size,
|
||||||
confirmations: (height - tx.height) + 1,
|
confirmations: (height - tx.height) + 1,
|
||||||
valueOut: tx.outputs.reduce((sum, output) => sum + output.value, 0) / 1e8,
|
valueOut: tx.outputs.reduce((sum, output) => sum + output.value, 0) / 1e8,
|
||||||
vin: tx.inputs.map(input => ({
|
vin: tx.inputs.map(input => ({
|
||||||
@ -59,43 +60,32 @@ module.exports = function transactionAPI(router) {
|
|||||||
// get txs for blockhash, start with best height to calc confirmations
|
// get txs for blockhash, start with best height to calc confirmations
|
||||||
if (req.query.block) {
|
if (req.query.block) {
|
||||||
const height = db.blocks.bestHeight();
|
const height = db.blocks.bestHeight();
|
||||||
// Get Bcoin data
|
|
||||||
return request(`${API_URL}/block/${req.query.block}`,
|
db.txs.getTxCountByBlock(req.query.block, (err, count) => {
|
||||||
{ timeout: TTL },
|
if (err) {
|
||||||
(error, localRes, block) => {
|
logger.log('err',
|
||||||
|
`getTxByBlock ${err}`);
|
||||||
|
return res.status(404).send();
|
||||||
|
}
|
||||||
|
const totalPages = Math.ceil(count / MAX_TXS);
|
||||||
|
|
||||||
|
return db.txs.getTxByBlock(req.query.block, pageNum, MAX_TXS, (error, txs) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
logger.log('error',
|
logger.log('err',
|
||||||
`${error}`);
|
`getTxByBlock ${error}`);
|
||||||
return res.status(404).send();
|
return res.status(404).send();
|
||||||
}
|
}
|
||||||
// Catch JSON errors
|
|
||||||
try {
|
|
||||||
block = JSON.parse(block);
|
|
||||||
} catch (e) {
|
|
||||||
logger.log('error',
|
|
||||||
`${e}`);
|
|
||||||
return res.status(404).send();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (block.error) {
|
|
||||||
logger.log('error',
|
|
||||||
`${'No tx results'}`);
|
|
||||||
return res.status(404).send();
|
|
||||||
}
|
|
||||||
// Setup UI JSON
|
|
||||||
const totalPages = Math.ceil(block.txs.length / MAX_TXS);
|
|
||||||
block.txs = block.txs.slice(rangeStart, rangeEnd);
|
|
||||||
|
|
||||||
return res.send({
|
return res.send({
|
||||||
pagesTotal: totalPages,
|
pagesTotal: totalPages,
|
||||||
txs: block.txs.map(tx => ({
|
txs: txs.map(tx => ({
|
||||||
txid: tx.hash,
|
txid: tx.hash,
|
||||||
fees: tx.fee / 1e8,
|
fees: tx.fee / 1e8,
|
||||||
confirmations: (height - block.height) + 1,
|
size: tx.size,
|
||||||
|
confirmations: (height - tx.height) + 1,
|
||||||
valueOut: tx.outputs.reduce((sum, output) => sum + output.value, 0) / 1e8,
|
valueOut: tx.outputs.reduce((sum, output) => sum + output.value, 0) / 1e8,
|
||||||
vin: tx.inputs.map(input => ({
|
vin: tx.inputs.map(input => ({
|
||||||
addr: input.coin ? input.coin.address : '',
|
addr: input.address,
|
||||||
value: input.coin ? input.coin.value / 1e8 : 0,
|
value: input.value / 1e8,
|
||||||
})),
|
})),
|
||||||
vout: tx.outputs.map(output => ({
|
vout: tx.outputs.map(output => ({
|
||||||
scriptPubKey: {
|
scriptPubKey: {
|
||||||
@ -107,47 +97,37 @@ module.exports = function transactionAPI(router) {
|
|||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
} else if (req.query.address) {
|
} else if (req.query.address) {
|
||||||
// Get txs by address, start with best height to calc confirmations
|
// Get txs by address, start with best height to calc confirmations
|
||||||
const height = db.blocks.bestHeight();
|
const height = db.blocks.bestHeight();
|
||||||
const addr = req.query.address || '';
|
const addr = req.query.address || '';
|
||||||
|
|
||||||
logger.log('debug',
|
db.txs.getTxCountByAddress(req.query.address, (err, count) => {
|
||||||
'Warning: Requesting data from Bcoin by address, may take some time');
|
if (err) {
|
||||||
|
logger.log('err',
|
||||||
|
`getTxByBlock ${err}`);
|
||||||
|
return res.status(404).send();
|
||||||
|
}
|
||||||
|
const totalPages = Math.ceil(count / MAX_TXS);
|
||||||
|
|
||||||
return request(`${API_URL}/tx/address/${addr}`,
|
return db.txs.getTxByAddress(req.query.address, pageNum, MAX_TXS, (error, txs) => {
|
||||||
{ timeout: TTL },
|
|
||||||
(error, localRes, txs) => {
|
|
||||||
if (error) {
|
if (error) {
|
||||||
logger.log('error',
|
logger.log('err',
|
||||||
`${error}`);
|
`getTxByBlock ${error}`);
|
||||||
return res.status(404).send();
|
return res.status(404).send();
|
||||||
}
|
}
|
||||||
// Catch JSON errors
|
|
||||||
try {
|
|
||||||
txs = JSON.parse(txs);
|
|
||||||
} catch (e) {
|
|
||||||
logger.log('error',
|
|
||||||
`${e}`);
|
|
||||||
return res.status(404).send();
|
|
||||||
}
|
|
||||||
// Bcoin returns error as part of data object
|
|
||||||
if (txs.error) {
|
|
||||||
logger.log('error',
|
|
||||||
`${'No tx results'}`);
|
|
||||||
return res.status(404).send();
|
|
||||||
}
|
|
||||||
// Setup UI JSON
|
|
||||||
return res.send({
|
return res.send({
|
||||||
pagesTotal: 1,
|
pagesTotal: totalPages,
|
||||||
txs: txs.map(tx => ({
|
txs: txs.map(tx => ({
|
||||||
txid: tx.hash,
|
txid: tx.hash,
|
||||||
fees: tx.fee / 1e8,
|
fees: tx.fee / 1e8,
|
||||||
confirmations: (height - tx.height) + 1,
|
size: tx.size,
|
||||||
|
confirmations: (height - tx.height) + 1,
|
||||||
valueOut: tx.outputs.reduce((sum, output) => sum + output.value, 0) / 1e8,
|
valueOut: tx.outputs.reduce((sum, output) => sum + output.value, 0) / 1e8,
|
||||||
vin: tx.inputs.map(input => ({
|
vin: tx.inputs.map(input => ({
|
||||||
addr: input.coin ? input.coin.address : '',
|
addr: input.address,
|
||||||
value: input.coin ? input.coin.value / 1e8 : 0,
|
value: input.value / 1e8,
|
||||||
})),
|
})),
|
||||||
vout: tx.outputs.map(output => ({
|
vout: tx.outputs.map(output => ({
|
||||||
scriptPubKey: {
|
scriptPubKey: {
|
||||||
@ -159,9 +139,11 @@ module.exports = function transactionAPI(router) {
|
|||||||
})),
|
})),
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// Get last n txs
|
||||||
|
return res.status(404).send({ error: 'Block hash or address expected' });
|
||||||
}
|
}
|
||||||
// Get last n txs
|
|
||||||
return res.status(404).send({ error: 'Block hash or address expected' });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/rawtx/:txid', (req, res) => {
|
router.get('/rawtx/:txid', (req, res) => {
|
||||||
@ -178,7 +160,7 @@ module.exports = function transactionAPI(router) {
|
|||||||
if (err) {
|
if (err) {
|
||||||
logger.log('error',
|
logger.log('error',
|
||||||
`${err}`);
|
`${err}`);
|
||||||
res.status(400).send(err);
|
res.status(404).send(err);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,9 +2,11 @@ const Transactions = require('../../models/transaction.js');
|
|||||||
const logger = require('../logger');
|
const logger = require('../logger');
|
||||||
const config = require('../../config');
|
const config = require('../../config');
|
||||||
|
|
||||||
|
// Will be replaced with a more sophisticated api soon
|
||||||
|
|
||||||
const MAX_TXS = config.api.max_txs;
|
const MAX_TXS = config.api.max_txs;
|
||||||
|
|
||||||
function getTransactions(params, options, limit, cb) {
|
function getTransactions(params, options, limit, skip, cb) {
|
||||||
// Do not return mongo ids
|
// Do not return mongo ids
|
||||||
const defaultOptions = { _id: 0 };
|
const defaultOptions = { _id: 0 };
|
||||||
// Copy over mongo options
|
// Copy over mongo options
|
||||||
@ -36,12 +38,13 @@ function getTransactions(params, options, limit, cb) {
|
|||||||
}
|
}
|
||||||
return cb(null, txs);
|
return cb(null, txs);
|
||||||
})
|
})
|
||||||
.sort({ height: -1 })
|
.sort({ height: 1 })
|
||||||
|
.skip()
|
||||||
.limit(limit);
|
.limit(limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
function getTransaction(params, options, limit, cb) {
|
function getTransaction(params, options, limit, skip, cb) {
|
||||||
getTransactions(params, options, limit, (err, tx) => {
|
getTransactions(params, options, limit, skip, (err, tx) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.log('error',
|
logger.log('error',
|
||||||
`getTransaction: ${err.err}`);
|
`getTransaction: ${err.err}`);
|
||||||
@ -59,6 +62,7 @@ function getTxById(txid, cb) {
|
|||||||
{ hash: txid },
|
{ hash: txid },
|
||||||
{},
|
{},
|
||||||
1,
|
1,
|
||||||
|
0,
|
||||||
(err, transaction) => {
|
(err, transaction) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.log('err',
|
logger.log('err',
|
||||||
@ -69,6 +73,78 @@ function getTxById(txid, cb) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getTxByBlock(blockHash, page, limit, cb) {
|
||||||
|
getTransactions(
|
||||||
|
{ block: blockHash },
|
||||||
|
{},
|
||||||
|
limit,
|
||||||
|
page * limit,
|
||||||
|
(err, tx) => {
|
||||||
|
if (err) {
|
||||||
|
logger.log('error',
|
||||||
|
`getTxByBlock: ${err.err}`);
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
if (!tx.length > 0) {
|
||||||
|
return cb({ err: 'Tx not found' });
|
||||||
|
}
|
||||||
|
return cb(null, tx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTxByAddress(address, page, limit, cb) {
|
||||||
|
getTransactions(
|
||||||
|
{
|
||||||
|
$or: [
|
||||||
|
{ 'inputs.address': address },
|
||||||
|
{ 'outputs.address': address }],
|
||||||
|
},
|
||||||
|
{},
|
||||||
|
limit,
|
||||||
|
page * limit,
|
||||||
|
(err, tx) => {
|
||||||
|
if (err) {
|
||||||
|
logger.log('error',
|
||||||
|
`getTxByAddress: ${err.err}`);
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
if (!tx.length > 0) {
|
||||||
|
return cb({ err: 'Tx not found' });
|
||||||
|
}
|
||||||
|
return cb(null, tx);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTxCountByBlock(blockHash, cb) {
|
||||||
|
Transactions.count(
|
||||||
|
{ block: blockHash },
|
||||||
|
(err, count) => {
|
||||||
|
if (err) {
|
||||||
|
logger.log('err',
|
||||||
|
`getTxCountByBlock ${err}`);
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
return cb(null, count);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTxCountByAddress(address, cb) {
|
||||||
|
Transactions.count(
|
||||||
|
{ $or: [
|
||||||
|
{ 'inputs.address': address },
|
||||||
|
{ 'outputs.address': address }],
|
||||||
|
},
|
||||||
|
(err, count) => {
|
||||||
|
if (err) {
|
||||||
|
logger.log('err',
|
||||||
|
`getTxCountByAddress ${err}`);
|
||||||
|
return cb(err);
|
||||||
|
}
|
||||||
|
return cb(null, count);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function updateInput(txid, inputid, value, address) {
|
function updateInput(txid, inputid, value, address) {
|
||||||
Transactions.findOneAndUpdate(
|
Transactions.findOneAndUpdate(
|
||||||
{ _id: txid, 'inputs._id': inputid },
|
{ _id: txid, 'inputs._id': inputid },
|
||||||
@ -91,5 +167,9 @@ module.exports = {
|
|||||||
getTransaction,
|
getTransaction,
|
||||||
getTransactions,
|
getTransactions,
|
||||||
getTxById,
|
getTxById,
|
||||||
|
getTxByBlock,
|
||||||
|
getTxCountByBlock,
|
||||||
|
getTxByAddress,
|
||||||
|
getTxCountByAddress,
|
||||||
updateInput,
|
updateInput,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -24,6 +24,10 @@ function start() {
|
|||||||
db.blocks.bestHeight(entry.height);
|
db.blocks.bestHeight(entry.height);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
node.chain.on('full', (block) => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
node.on('error', (err) => {
|
node.on('error', (err) => {
|
||||||
logger.log('error',
|
logger.log('error',
|
||||||
`${err}`);
|
`${err}`);
|
||||||
|
|||||||
@ -6,6 +6,12 @@ const util = require('../../lib/util');
|
|||||||
const logger = require('../logger');
|
const logger = require('../logger');
|
||||||
const db = require('../db');
|
const db = require('../db');
|
||||||
|
|
||||||
|
// Bleh, Bcoin pulls in blocks 20 at a time
|
||||||
|
// Crappy delay for now otherwise async saves
|
||||||
|
// could miss a tx if an input refs a block within
|
||||||
|
// the last 20 that hasn't saved.
|
||||||
|
// Aggregate stuff will replace all of this.
|
||||||
|
|
||||||
function parse(entry, txs) {
|
function parse(entry, txs) {
|
||||||
txs.forEach((tx) => {
|
txs.forEach((tx) => {
|
||||||
const txJSON = tx.toJSON();
|
const txJSON = tx.toJSON();
|
||||||
@ -52,23 +58,6 @@ function parse(entry, txs) {
|
|||||||
if (err) {
|
if (err) {
|
||||||
logger.log('error', err.message);
|
logger.log('error', err.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
t.inputs.forEach((input) => {
|
|
||||||
const txid = input.prevout.hash;
|
|
||||||
const idx = input.prevout.index;
|
|
||||||
const addr = input.address;
|
|
||||||
if (txid !== '0000000000000000000000000000000000000000000000000000000000000000') {
|
|
||||||
db.txs.getTxById(txid, (err, tx) => {
|
|
||||||
if (err) {
|
|
||||||
logger.log('err',
|
|
||||||
`Tx Parser inputs.ForEach: ${err}`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
db.txs.updateInput(t._id, input._id, tx.outputs[idx].value, tx.outputs[idx].address);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
Loading…
Reference in New Issue
Block a user