From 1ad21a667c06b5c035464dedb4ac9b844a0e446b Mon Sep 17 00:00:00 2001 From: tenthirtyone Date: Tue, 8 Aug 2017 00:58:09 -0400 Subject: [PATCH] block txs partially wired up --- README.md | 1 + config/index.js | 2 +- lib/api/index.js | 10 ++-- lib/api/transaction.js | 108 ++++++++++++++++++++++++++++++++++++----- lib/parser/address.js | 4 +- lib/parser/block.js | 44 +++++++++++++++-- models/block.js | 5 +- package-lock.json | 107 ++++++++++++++++++++-------------------- package.json | 1 + 9 files changed, 208 insertions(+), 74 deletions(-) diff --git a/README.md b/README.md index e5a9094..a3f5215 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ https://docs.google.com/a/bit-pay.com/spreadsheets/d/1hDlf16F6zAxBrOC3ZdnvfRrSB9 * Mongo Models : Bcoin primitives. A Bcoin block primitive does not represent all of bitcore's data. 1. scriptpubkey asm 2. peer's best block height is learned on peer connect but not retained by the app. Block height is the current sync height +3. Multiple Outputs were overlooked in the mongo model # ToDo but not Required for a release * Reorg testing - Bcoin will handle this but we need to account for this in our mongo indexes. diff --git a/config/index.js b/config/index.js index 67d426d..87c365f 100644 --- a/config/index.js +++ b/config/index.js @@ -1,5 +1,5 @@ const config = { - start_node: false, + start_node: true, logging: 'debug', bcoin: { network: 'main', diff --git a/lib/api/index.js b/lib/api/index.js index c73a294..7437a30 100644 --- a/lib/api/index.js +++ b/lib/api/index.js @@ -1,5 +1,6 @@ -const express = require('express'); -const config = require('../../config'); +const express = require('express'); +const config = require('../../config'); + const app = express(); const api = express.Router(); @@ -28,4 +29,7 @@ app.use((req, res) => { }); }); -module.exports = app; +const server = require('http').Server(app); + + +module.exports = server; diff --git a/lib/api/transaction.js b/lib/api/transaction.js index d8b2611..846e974 100644 --- a/lib/api/transaction.js +++ b/lib/api/transaction.js @@ -1,7 +1,24 @@ +const Block = require('../../models/block.js'); const Transaction = require('../../models/transaction'); const logger = require('../logger'); -const MAX_TXS = 200; +const MAX_TXS = 20; +const MAX_BLOCKS = 1; + +// Shoe horned in. Not dry, also in blocks. Make db api later +function getBlock(params, options, cb) { + const defaultOptions = { _id: 0 }; + + Object.assign(defaultOptions, options); + + Block.find( + params, + defaultOptions, + cb) + .sort({ height: -1 }) + .limit(MAX_BLOCKS); +} + function getTransactions(params, options, cb) { const defaultOptions = { _id: 0 }; @@ -73,17 +90,86 @@ module.exports = function transactionAPI(router) { req.query.address; */ + if (req.query.block) { + getBlock( + { hash: req.query.block }, + { rawBlock: 0 }, + (err, block) => { + if (err) { + res.status(501).send(); + logger.log('err', err); + } + if (block[0]) { + const b = block[0]; + res.json({ + pagesTotal: 1, + txs: b.txs.map(tx => ({ + txid: tx.hash, + version: tx.version, + locktime: tx.locktime, + vin: tx.inputs.map(input => ({ + coinbase: input.script, + sequence: input.sequence, + n: 0, + })), + vout: tx.outputs.map(output => ({ + value: output.value / 1e8, + n: 0, + scriptPubKey: { + hex: '', + asm: '', + addresses: [output.address], + type: output.type, + }, + spentTxid: '', + spentIndex: 0, + spentHeight: 0, + })), + })), + }); + } else { + res.send(); + } + }); + } else if (req.query.address) { - getTransactions( - {}, - {}, - (err, txs) => { - if (err) { - res.status(501).send(); - } - res.send(txs); - }, - ); + } else { + getTransactions( + {}, + {}, + (err, txs) => { + if (err) { + res.status(501).send(); + } + res.json({ + pagesTotal: 1, + txs: txs.map(tx => ({ + txid: tx.hash, + version: tx.version, + locktime: tx.locktime, + vin: tx.inputs.map(input => ({ + coinbase: input.script, + sequence: input.sequence, + n: 0, + })), + vout: tx.outputs.map(output => ({ + value: output.value, + n: 0, + scriptPubKey: { + hex: '', + asm: '', + addresses: [output.address], + type: output.type, + }, + spentTxid: '', + spentIndex: 0, + spentHeight: 0, + })), + })), + }); + }, + ); + } }); router.get('/rawtx/:txid', (req, res) => { diff --git a/lib/parser/address.js b/lib/parser/address.js index c791a17..0c3616a 100644 --- a/lib/parser/address.js +++ b/lib/parser/address.js @@ -11,7 +11,7 @@ function parse(entry, txs) { tx.outputs.forEach((output) => { const outputJSON = output.toJSON(); - console.log(outputJSON); + //console.log(outputJSON); /* return new OutputModel({ address: outputJSON.address, @@ -22,7 +22,7 @@ function parse(entry, txs) { tx.inputs.forEach((input) => { const inputJSON = input.toJSON(); - console.log(inputJSON); + //console.log(inputJSON); /* return new InputModel({ prevout: inputJSON.prevout, script: inputJSON.script, diff --git a/lib/parser/block.js b/lib/parser/block.js index 3ee02e3..b19b2b9 100644 --- a/lib/parser/block.js +++ b/lib/parser/block.js @@ -1,4 +1,6 @@ const BlockModel = require('../../models/block'); +const InputModel = require('../../models/input'); +const OutputModel = require('../../models/output'); const config = require('../../config'); const util = require('../../lib/util'); const logger = require('../logger'); @@ -19,12 +21,48 @@ function parse(entry, block) { ts: blockJSON.ts, bits: blockJSON.bits, nonce: blockJSON.nonce, - txs: block.txs.map(tx => util.revHex(tx.hash().toString('hex'))), + txs: block.txs.map((tx) => { + const txJSON = tx.toJSON(); + return { + hash: txJSON.hash, + witnessHash: txJSON.witnessHash, + fee: txJSON.fee, + rate: txJSON.rate, + ps: txJSON.ps, + height: entry.height, + block: util.revHex(entry.hash), + ts: entry.ts, + date: txJSON.date, + index: txJSON.index, + version: txJSON.version, + flag: txJSON.flag, + inputs: tx.inputs.map((input) => { + const inputJSON = input.toJSON(); + return new InputModel({ + prevout: inputJSON.prevout, + script: inputJSON.script, + witness: inputJSON.witness, + sequence: inputJSON.sequence, + address: inputJSON.address, + }); + }), + outputs: tx.outputs.map((output) => { + const outputJSON = output.toJSON(); + return new OutputModel({ + address: outputJSON.address, + script: outputJSON.script, + value: outputJSON.value, + }); + }), + lockTime: txJSON.locktime, + chain: config.bcoin.network, + }; + }), chainwork: entry.chainwork, - reward: reward, + reward, network: config.bcoin.network, poolInfo: {}, - rawBlock: rawBlock, + rawBlock, }); newBlock.save((err) => { diff --git a/models/block.js b/models/block.js index 415eeba..3de6806 100644 --- a/models/block.js +++ b/models/block.js @@ -1,4 +1,5 @@ -const mongoose = require('mongoose'); +const mongoose = require('mongoose'); +const Transaction = require('./transaction'); const Schema = mongoose.Schema; @@ -12,7 +13,7 @@ const BlockSchema = new Schema({ ts: Number, bits: Number, nonce: Number, - txs: Array, + txs: [Transaction.schema], chainwork: Number, reward: Number, network: String, diff --git a/package-lock.json b/package-lock.json index f3d8784..5887bbc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -95,8 +95,7 @@ "backo2": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "optional": true + "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=" }, "balanced-match": { "version": "1.0.0", @@ -112,8 +111,7 @@ "base64id": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", - "optional": true + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" }, "bcoin": { "version": "1.0.0-beta.14", @@ -128,6 +126,22 @@ "secp256k1": "3.2.5", "socket.io": "2.0.1", "socket.io-client": "2.0.1" + }, + "dependencies": { + "socket.io": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.1.tgz", + "integrity": "sha1-BkwSUXhGLkd6bfI9L9rRjdHFkU8=", + "optional": true, + "requires": { + "debug": "2.6.8", + "engine.io": "3.1.0", + "object-assign": "4.1.1", + "socket.io-adapter": "1.1.1", + "socket.io-client": "2.0.1", + "socket.io-parser": "3.1.2" + } + } } }, "bcoin-native": { @@ -305,8 +319,7 @@ "component-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "optional": true + "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=" }, "component-emitter": { "version": "1.2.1", @@ -316,8 +329,7 @@ "component-inherit": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "optional": true + "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=" }, "concat-map": { "version": "0.0.1", @@ -515,7 +527,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.0.tgz", "integrity": "sha1-XKQ4486f28kVxKIcjdnhJmcG5X4=", - "optional": true, "requires": { "accepts": "1.3.3", "base64id": "1.0.0", @@ -530,7 +541,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.1.tgz", "integrity": "sha1-QVqYUrrbFPoAj6PvHjFgjbZ2EyU=", - "optional": true, "requires": { "component-emitter": "1.2.1", "component-inherit": "0.0.3", @@ -1373,14 +1383,12 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "optional": true + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" }, "object-component": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "optional": true + "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=" }, "on-finished": { "version": "2.3.0", @@ -1432,7 +1440,6 @@ "version": "0.0.3", "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", - "optional": true, "requires": { "better-assert": "1.0.2" } @@ -1441,7 +1448,6 @@ "version": "0.0.5", "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "optional": true, "requires": { "better-assert": "1.0.2" } @@ -1824,44 +1830,44 @@ } }, "socket.io": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.1.tgz", - "integrity": "sha1-BkwSUXhGLkd6bfI9L9rRjdHFkU8=", - "optional": true, + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.3.tgz", + "integrity": "sha1-Q1nwaiSTOua9CHeYr3jGgOrjReM=", "requires": { "debug": "2.6.8", "engine.io": "3.1.0", "object-assign": "4.1.1", - "socket.io-adapter": "1.1.0", - "socket.io-client": "2.0.1", + "socket.io-adapter": "1.1.1", + "socket.io-client": "2.0.3", "socket.io-parser": "3.1.2" + }, + "dependencies": { + "socket.io-client": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.3.tgz", + "integrity": "sha1-bK9K/5+FsZ/ZG2zhPWmttWT4hzs=", + "requires": { + "backo2": "1.0.2", + "base64-arraybuffer": "0.1.5", + "component-bind": "1.0.0", + "component-emitter": "1.2.1", + "debug": "2.6.8", + "engine.io-client": "3.1.1", + "has-cors": "1.1.0", + "indexof": "0.0.1", + "object-component": "0.0.3", + "parseqs": "0.0.5", + "parseuri": "0.0.5", + "socket.io-parser": "3.1.2", + "to-array": "0.1.4" + } + } } }, "socket.io-adapter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.0.tgz", - "integrity": "sha1-x6pGUB3VVsLLiiivj/lcC14dqkw=", - "optional": true, - "requires": { - "debug": "2.3.3" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "optional": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "optional": true - } - } + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", + "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=" }, "socket.io-client": { "version": "2.0.1", @@ -2041,8 +2047,7 @@ "to-array": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "optional": true + "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=" }, "tough-cookie": { "version": "2.3.2", @@ -2197,8 +2202,7 @@ "xmlhttprequest-ssl": { "version": "1.5.3", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", - "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", - "optional": true + "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=" }, "xtend": { "version": "4.0.1", @@ -2208,8 +2212,7 @@ "yeast": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "optional": true + "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=" } } } diff --git a/package.json b/package.json index e329d35..65ce2af 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "express": "^4.15.3", "mongoose": "^4.11.5", "request": "^2.81.0", + "socket.io": "^2.0.3", "winston": "^2.3.1" }, "devDependencies": {