diff --git a/Gruntfile.js b/Gruntfile.js index ab534a16..bd6d921e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,6 +1,16 @@ 'use strict'; module.exports = function(grunt) { + + + //Load NPM tasks + grunt.loadNpmTasks('grunt-contrib-watch'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + grunt.loadNpmTasks('grunt-mocha-test'); + grunt.loadNpmTasks('grunt-nodemon'); + grunt.loadNpmTasks('grunt-concurrent'); + grunt.loadNpmTasks('grunt-env'); + // Project Configuration grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), @@ -29,6 +39,11 @@ module.exports = function(grunt) { options: { livereload: true } + }, + test: { + // we monitor only app/models/* because we have test for models only now + files: ['test/**/*.js', 'test/*.js','app/models/*.js'], + tasks: ['test'], } }, jshint: { @@ -43,7 +58,7 @@ module.exports = function(grunt) { options: { reporter: 'spec', }, - src: ['test/*.js'] + src: ['test/**/*.js'], }, nodemon: { @@ -51,9 +66,9 @@ module.exports = function(grunt) { options: { file: 'server.js', args: [], - ignoredFiles: ['public/**'], + ignoredFiles: ['public/**', 'test/**'], watchedExtensions: ['js'], - nodeArgs: ['--debug'], + // nodeArgs: ['--debug'], delayTime: 1, env: { PORT: 3000 @@ -75,14 +90,6 @@ module.exports = function(grunt) { } }); - //Load NPM tasks - grunt.loadNpmTasks('grunt-contrib-watch'); - grunt.loadNpmTasks('grunt-contrib-jshint'); - grunt.loadNpmTasks('grunt-mocha-test'); - grunt.loadNpmTasks('grunt-nodemon'); - grunt.loadNpmTasks('grunt-concurrent'); - grunt.loadNpmTasks('grunt-env'); - //Making grunt default to force in order not to break the project. grunt.option('force', true); diff --git a/README.md b/README.md index ca751e31..9127bf9d 100644 --- a/README.md +++ b/README.md @@ -45,26 +45,34 @@ $ npm install -g bower http://localhost:3000 - - - - -## Prerequisites - Get bitcore from github repository: - $ git clone https://github.com/bitpay/bitcore.git - $ cd bitcore - $ npm install - - Run sync from mystery repository: - $ utils/sync.js - -check utils/sync.js --help for options. - - ## API A REST API is provided at /api. The entry points are: +### Prerequisites + Get bitcore from github repository: + + $ git clone https://github.com/bitpay/bitcore.git + + $ cd bitcore + + $ npm install + + Then create a symbolic link from this to your mystery repository. We need to + use bitcore from github, not with npm for now: + + $ cd mystery/node_modules + + $ rm -R bitcore + + $ ln -s /bitcore + + Run sync from mystery repository (to save blocks in MongoDB): + + $ utils/sync.js + + Check utils/sync.js --help for options. + ### Blocks ``` /api/block/[:hash] diff --git a/app/controllers/blocks.js b/app/controllers/blocks.js index 3a38d8dd..5381ec04 100644 --- a/app/controllers/blocks.js +++ b/app/controllers/blocks.js @@ -29,41 +29,56 @@ exports.show = function(req, res) { res.jsonp(req.block); }; -/** - * List of blocks at HomePage - */ -exports.last_blocks = function(req, res) { - Block.find().sort({time:-1}).limit(7).exec(function(err, blocks) { - if (err) { - res.render('error', { - status: 500 - }); - } else { - res.jsonp(blocks); - } - }); -}; - /** * List of blocks by date */ exports.list = function(req, res) { - var findParam = {}; + //helper to convert timestamps to yyyy-mm-dd format + var 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 + }; + + var dateStr; if (req.query.blockDate) { - findParam = {}; + dateStr = req.query.blockDate; + } else { + dateStr = formatTimestamp(new Date()); } + var gte = Math.round((new Date(dateStr)).getTime() / 1000); + + //pagination + var lte = gte + 86400; + var prev = formatTimestamp(new Date((gte - 86400) * 1000)); + var next = formatTimestamp(new Date(lte * 1000)); + Block - .find(findParam) - .limit(5) + .find({ + time: { + '$gte': gte, + '$lte': lte + } + }) .exec(function(err, blocks) { if (err) { res.render('error', { status: 500 }); } else { - res.jsonp(blocks); + res.jsonp({ + blocks: blocks, + pagination: { + next: next, + prev: prev, + current: dateStr + } + }); } }); }; + + diff --git a/app/controllers/transactions.js b/app/controllers/transactions.js index 6a4cffd3..caa66f13 100644 --- a/app/controllers/transactions.js +++ b/app/controllers/transactions.js @@ -16,7 +16,12 @@ var Transaction = require('../models/Transaction'); */ exports.transaction = function(req, res, next, txid) { Transaction.fromIdWithInfo(txid, function(err, tx) { - if (err) return next(err); + if (err) { + console.log(err); + res.status(404).send('Not found'); + return next(); + } + if (!tx) return next(new Error('Failed to load TX ' + txid)); req.transaction = tx.info; next(); @@ -25,9 +30,11 @@ exports.transaction = function(req, res, next, txid) { /** - * Show block */ exports.show = function(req, res) { - res.jsonp(req.transaction); + + if (req.transaction) { + res.jsonp(req.transaction); + } }; diff --git a/app/models/Block.js b/app/models/Block.js index a226c34a..7374943a 100644 --- a/app/models/Block.js +++ b/app/models/Block.js @@ -57,6 +57,7 @@ BlockSchema.statics.fromHash = function(hash, cb) { BlockSchema.statics.fromHashWithInfo = function(hash, cb) { this.fromHash(hash, function(err, block) { if (err) return cb(err); + if (!block) { return cb(new Error('Block not found')); } block.getInfo(function(err) { return cb(err,block); } ); }); diff --git a/app/models/Transaction.js b/app/models/Transaction.js index 02c0e51f..06009342 100644 --- a/app/models/Transaction.js +++ b/app/models/Transaction.js @@ -3,12 +3,18 @@ /** * Module dependencies. */ -var mongoose = require('mongoose'), - Schema = mongoose.Schema, - async = require('async'), - RpcClient = require('bitcore/RpcClient').class(), - config = require('../../config/config'); +var mongoose = require('mongoose'), + Schema = mongoose.Schema, + async = require('async'), + RpcClient = require('bitcore/RpcClient').class(), + Transaction = require('bitcore/Transaction').class(), + Address = require('bitcore/Address').class(), + networks = require('bitcore/networks'), + util = require('bitcore/util/util'), + bignum = require('bignum'), + config = require('../../config/config'); + /** */ @@ -41,10 +47,15 @@ TransactionSchema.statics.fromId = function(txid, cb) { }; TransactionSchema.statics.fromIdWithInfo = function(txid, cb) { + + // TODO Should we go to mongoDB first? Now, no extra information is stored at mongo. + this.fromId(txid, function(err, tx) { if (err) return cb(err); - tx.getInfo(function(err) { return cb(err,tx); } ); + if (!tx) { return cb(new Error('TX not found')); } + + tx.queryInfo(function(err) { return cb(err,tx); } ); }); }; @@ -68,18 +79,114 @@ TransactionSchema.statics.createFromArray = function(txs, next) { }; +TransactionSchema.methods.fillInputValues = function (tx, next) { -TransactionSchema.methods.getInfo = function (next) { + if (tx.isCoinBase()) return next(); + + if (! this.rpc) this.rpc = new RpcClient(config.bitcoind); var that = this; - var rpc = new RpcClient(config.bitcoind); + async.each(tx.ins, function(i, cb) { - rpc.getRawTransaction(this.txid, 1, function(err, txInfo) { + var outHash = i.getOutpointHash(); + var outIndex = i.getOutpointIndex(); + var outHashBase64 = outHash.reverse().toString('hex'); + + var c=0; + that.rpc.getRawTransaction(outHashBase64, function(err, txdata) { + var txin = new Transaction(); + + if (err || ! txdata.result) return cb( new Error('Input TX '+outHashBase64+' not found')); + + var b = new Buffer(txdata.result,'hex'); + txin.parse(b); + + + if ( txin.isCoinBase() ) { + return cb(); + } + + txin.outs.forEach( function(j) { + // console.log( c + ': ' + util.formatValue(j.v) ); + if (c === outIndex) { + i.value = j.v; + } + c++; + }); + return cb(); + }); + }, + function(err) { + return next(err); + } + ); +}; + +TransactionSchema.methods.queryInfo = function (next) { + + var that = this; + var network = ( config.network === 'testnet') ? networks.testnet : networks.livenet ; + this.rpc = new RpcClient(config.bitcoind); + + + this.rpc.getRawTransaction(this.txid, 1, function(err, txInfo) { if (err) return next(err); + that.info = txInfo.result; - //console.log("THAT", that); - return next(null, that.info); + // Transaction parsing + var b = new Buffer(txInfo.result.hex,'hex'); + var tx = new Transaction(); + tx.parse(b); + + that.fillInputValues(tx, function(err) { + + // Copy TX relevant values to .info + + var c = 0; + + + var valueIn = bignum(0); + var valueOut = bignum(0); + + if ( tx.isCoinBase() ) { + that.info.isCoinBase = true; + } + else { + tx.ins.forEach(function(i) { + + that.info.vin[c].value = util.formatValue(i.value); + var n = util.valueToBigInt(i.value).toNumber(); + valueIn = valueIn.add( n ); + + var scriptSig = i.getScript(); + var pubKey = scriptSig.simpleInPubKey(); + var pubKeyHash = util.sha256ripe160(pubKey); + var addr = new Address(network.addressPubkey, pubKeyHash); + var addrStr = addr.toString(); + + that.info.vin[c].addr = addrStr; + + c++; + }); + } + + tx.outs.forEach( function(i) { + var n = util.valueToBigInt(i.v).toNumber(); + valueOut = valueOut.add(n); + }); + + that.info.valueOut = valueOut / util.COIN; + + if ( !tx.isCoinBase() ) { + that.info.valueIn = valueIn / util.COIN; + that.info.feeds = (valueIn - valueOut) / util.COIN; + } + + that.info.size = b.length; + + return next(err, that.info); + }); }); }; diff --git a/app/views/includes/foot.jade b/app/views/includes/foot.jade index edca962e..2b10e086 100755 --- a/app/views/includes/foot.jade +++ b/app/views/includes/foot.jade @@ -1,7 +1,7 @@ #footer .container p.text-muted Place sticky footer content here. - + //script(type='text/javascript', src='/lib/jquery/jquery.min.js') //script(type='text/javascript', src='/lib/bootstrap/dist/js/bootstrap.min.js') @@ -10,6 +10,8 @@ script(type='text/javascript', src='/lib/angular/angular.js') script(type='text/javascript', src='/lib/angular-cookies/angular-cookies.js') script(type='text/javascript', src='/lib/angular-resource/angular-resource.js') script(type='text/javascript', src='/lib/angular-route/angular-route.js') +script(type='text/javascript', src='/lib/qrcode-generator/js/qrcode.js') +script(type='text/javascript', src='/lib/angular-qrcode/qrcode.js') //Angular UI script(type='text/javascript', src='/lib/angular-bootstrap/ui-bootstrap.js') @@ -23,6 +25,7 @@ script(type='text/javascript', src='/js/directives.js') script(type='text/javascript', src='/js/filters.js') //Application Services +script(type='text/javascript', src='/js/services/transactions.js') script(type='text/javascript', src='/js/services/blocks.js') script(type='text/javascript', src='/js/services/global.js') script(type='text/javascript', src='/js/services/index.js') @@ -31,4 +34,6 @@ script(type='text/javascript', src='/js/services/index.js') script(type='text/javascript', src='/js/controllers/index.js') script(type='text/javascript', src='/js/controllers/header.js') script(type='text/javascript', src='/js/controllers/blocks.js') +script(type='text/javascript', src='/js/controllers/transactions.js') +script(type='text/javascript', src='/js/controllers/address.js') script(type='text/javascript', src='/js/init.js') diff --git a/bower.json b/bower.json index 46be4c59..60f6edbd 100644 --- a/bower.json +++ b/bower.json @@ -9,6 +9,7 @@ "angular-route": "latest", "bootstrap": "3.0.3", "angular-bootstrap": "0.9.0", - "angular-ui-utils": "0.1.0" + "angular-ui-utils": "0.1.0", + "angular-qrcode": "latest" } -} \ No newline at end of file +} diff --git a/config/env/development.js b/config/env/development.js index 7211f937..f01f9fbb 100755 --- a/config/env/development.js +++ b/config/env/development.js @@ -11,5 +11,6 @@ module.exports = { protocol: 'http', host: process.env.BITCOIND_HOST || '127.0.0.1', port: process.env.BITCOIND_PORT || '18332', - } + }, + network: 'testnet', } diff --git a/config/env/test.js b/config/env/test.js index dabf6021..902efe9d 100755 --- a/config/env/test.js +++ b/config/env/test.js @@ -1,9 +1,16 @@ 'use strict'; module.exports = { - db: "mongodb://localhost/mystery-test", - port: 3001, + db: "mongodb://localhost/mystery-dev", app: { name: "Mystery - Test" - } -} \ No newline at end of file + }, + bitcoind: { + user: 'mystery', + pass: 'real_mystery', + protocol: 'http', + host: process.env.BITCOIND_HOST || '127.0.0.1', + port: process.env.BITCOIND_PORT || '8332', + }, + network: 'testnet', +} diff --git a/config/routes.js b/config/routes.js index ab4c9b18..83c7eb3c 100644 --- a/config/routes.js +++ b/config/routes.js @@ -9,12 +9,13 @@ module.exports = function(app) { //Block routes var blocks = require('../app/controllers/blocks'); app.get('/api/blocks', blocks.list); + + app.get('/api/block/:blockHash', blocks.show); app.param('blockHash', blocks.block); - app.get('/last_blocks', blocks.last_blocks); var transactions = require('../app/controllers/transactions'); - app.get('/tx/:txid', transactions.show); + app.get('/api/tx/:txid', transactions.show); app.param('txid', transactions.transaction); diff --git a/etc/bitcoind/bitcoin.conf b/etc/bitcoind/bitcoin.conf index b7df0070..936a9496 100644 --- a/etc/bitcoind/bitcoin.conf +++ b/etc/bitcoind/bitcoin.conf @@ -4,7 +4,8 @@ server=1 txindex=1 # Allow connections outsite localhost? -# rpcallowip=192.168.0.* +rpcallowip=192.168.1.* +rpcallowip='192.168.1.*' diff --git a/package.json b/package.json index b89a7a12..c9338fc8 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "async": "*", "classtool": "*", "commander": "*", + "bignum": "*", "express": "~3.4.7", "jade": "~1.0.2", "mongoose": "~3.8.3", diff --git a/public/css/common.css b/public/css/common.css index 7ca093ad..396601a7 100644 --- a/public/css/common.css +++ b/public/css/common.css @@ -40,6 +40,11 @@ body { padding-right: 15px; } -code { +.code { font-size: 80%; } + +.address { + font-size: 10px; +} + diff --git a/public/js/app.js b/public/js/app.js index 2b6bc682..cfc1f8cf 100755 --- a/public/js/app.js +++ b/public/js/app.js @@ -1,7 +1,9 @@ 'use strict'; -angular.module('mystery', ['ngCookies', 'ngResource', 'ngRoute', 'ui.bootstrap', 'ui.route', 'mystery.system', 'mystery.index', 'mystery.blocks']); +angular.module('mystery', ['ngCookies', 'ngResource', 'ngRoute', 'ui.bootstrap', 'ui.route', 'mystery.system', 'mystery.index', 'mystery.blocks', 'mystery.transactions', 'monospaced.qrcode', 'mystery.address']); angular.module('mystery.system', []); angular.module('mystery.index', []); angular.module('mystery.blocks', []); +angular.module('mystery.transactions', []); +angular.module('mystery.address', []); diff --git a/public/js/config.js b/public/js/config.js index 35fe3836..c1761605 100755 --- a/public/js/config.js +++ b/public/js/config.js @@ -7,6 +7,9 @@ angular.module('mystery').config(['$routeProvider', when('/block/:blockHash', { templateUrl: 'views/block.html' }). + when('/tx/:txId', { + templateUrl: 'views/transaction.html' + }). when('/', { templateUrl: 'views/index.html' }). @@ -14,7 +17,10 @@ angular.module('mystery').config(['$routeProvider', templateUrl: 'views/blocks/list.html' }). when('/blocks-date/:blockDate', { - templateUrl: 'views/blocks/list_date.html' + templateUrl: 'views/blocks/list.html' + }). + when('/address/:address', { + templateUrl: 'views/address.html' }). otherwise({ redirectTo: '/' diff --git a/public/js/controllers/address.js b/public/js/controllers/address.js new file mode 100644 index 00000000..e921d983 --- /dev/null +++ b/public/js/controllers/address.js @@ -0,0 +1,20 @@ +'use strict'; + +angular.module('mystery.address').controller('AddressController', ['$scope', function ($scope) { + + //example data + $scope.address = '1JmTTDcksW7A6GN7JnxuXkMAXsVN9zmgm1'; + $scope.hash160 = '77ad7d08aaa9cf489ea4e468eaeb892b85f71e27'; + $scope.transactions = [ + { + hash: '49a1d01759690476dbeec4a8efd969c09c6d4269ea2d88f4d9d4f098f021413c', + time: 1234123445, + amount: 0.3 + }, + { + hash: 'cce948b422a4d485900fb82e64458720eb89f545af3f07ddf7d18660f9f881e9', + time: 1234123445, + amount: 0.1 + } + ]; +}]); diff --git a/public/js/controllers/blocks.js b/public/js/controllers/blocks.js index 98e88010..7bb5c80b 100644 --- a/public/js/controllers/blocks.js +++ b/public/js/controllers/blocks.js @@ -3,17 +3,12 @@ angular.module('mystery.blocks').controller('BlocksController', ['$scope', '$routeParams', '$location', 'Global', 'Block', 'Blocks', function ($scope, $routeParams, $location, Global, Block, Blocks) { $scope.global = Global; - $scope.list_blocks = function() { - Blocks.query(function(blocks) { - $scope.blocks = blocks; - }); - }; - - $scope.list_blocks_date = function() { - Blocks.query({ + $scope.list = function() { + Blocks.get({ blockDate: $routeParams.blockDate - }, function(blocks) { - $scope.blocks = blocks; + }, function(res) { + $scope.blocks = res.blocks; + $scope.pagination = res.pagination; }); }; diff --git a/public/js/controllers/index.js b/public/js/controllers/index.js index bec0f0ad..60435269 100755 --- a/public/js/controllers/index.js +++ b/public/js/controllers/index.js @@ -2,9 +2,5 @@ angular.module('mystery.system').controller('IndexController', ['$scope', 'Global', 'Index', function ($scope, Global, Index) { $scope.global = Global; - $scope.last_blocks = function() { - Index.query(function(blocks) { - $scope.blocks = blocks; - }); - }; + $scope.index = Index; }]); diff --git a/public/js/controllers/transactions.js b/public/js/controllers/transactions.js new file mode 100644 index 00000000..53aaf925 --- /dev/null +++ b/public/js/controllers/transactions.js @@ -0,0 +1,14 @@ +'use strict'; + +angular.module('mystery.transactions').controller('transactionsController', ['$scope', '$routeParams', '$location', 'Global', 'Transaction', function ($scope, $routeParams, $location, Global, Transaction) { + $scope.global = Global; + + $scope.findOne = function() { + Transaction.get({ + txId: $routeParams.txId + }, function(tx) { + $scope.tx = tx; + }); + }; +}]); + diff --git a/public/js/services/index.js b/public/js/services/index.js index f961642e..08cb3ffa 100644 --- a/public/js/services/index.js +++ b/public/js/services/index.js @@ -1,5 +1,5 @@ 'use strict'; angular.module('mystery.index').factory('Index', ['$resource', function($resource) { - return $resource('/last_blocks'); + return $resource; }]); diff --git a/public/js/services/transactions.js b/public/js/services/transactions.js new file mode 100644 index 00000000..9edfacaf --- /dev/null +++ b/public/js/services/transactions.js @@ -0,0 +1,8 @@ +'use strict'; + +angular.module('mystery.transactions').factory('Transaction', ['$resource', function($resource) { + return $resource('/api/tx/:txId', { + txId: '@txId' + }); +}]); + diff --git a/public/views/address.html b/public/views/address.html new file mode 100644 index 00000000..45a01495 --- /dev/null +++ b/public/views/address.html @@ -0,0 +1,60 @@ +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + +
Address{{address}}
Hash160{{hash160}}
Total Output1 BTC
Total Input0.2 BTC
Current balance10.2 BTC
+
+
+ +
+
+

+ Transactions + transactions this address relates to +

+ + + + + + + + + + + + + + + + +
Transaction HashDatetimeTransacted amount
{{transaction.hash}}{{transaction.time | date:'medium'}}{{transaction.amount}} BTC
+
+
diff --git a/public/views/block.html b/public/views/block.html index 686a6ade..98d76ac9 100644 --- a/public/views/block.html +++ b/public/views/block.html @@ -1,23 +1,114 @@
+ +
+
+
+
+

Summary

+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Number Of Transactions--
Output Total--
Estimated Transaction Volume--
Transaction Fees--
Height{{block.height}}
Timestamp{{block.time * 1000 | date:'medium'}}
Received Time-- +
Relayed By--
Difficulty{{block.difficulty}}
Bits{{block.bits}}
Size{{block.size}}
Version{{block.version}}
Nonce{{block.nonce}}
+
+
+
+
+
+
+

Hashes

+
+
+ + + + + + + + + + + + + + + + + + + +
Hash{{block.hash}}
Previous Block{{block.previousblockhash}}
Next Block{{block.nextblockhash}}
Merkle Root{{block.merkleroot}}
+
+
+
+
+ +

Transactions Transactions contained within this block

- - - - - + - - - - - - - + + +
HeightAgeTransactionsConfirmationsSize (kB)Hash
{{block.height}}{{block.time | date:'short'}}{{block.tx.length }}{{block.confirmations}}{{block.size / 1024}}
{{tx}}
-
\ No newline at end of file + diff --git a/public/views/blocks/list.html b/public/views/blocks/list.html index f258705a..d8315692 100644 --- a/public/views/blocks/list.html +++ b/public/views/blocks/list.html @@ -1,10 +1,26 @@ -
+
-
    -
  • - {{block.hash}} {{block.time}} -
  • -
-
\ No newline at end of file + + + + + + + + + + + +
HashSolved at
{{block.hash}}{{block.time * 1000 | date:'medium'}}
+
diff --git a/public/views/blocks/list_date.html b/public/views/blocks/list_date.html deleted file mode 100644 index 349857cf..00000000 --- a/public/views/blocks/list_date.html +++ /dev/null @@ -1,10 +0,0 @@ -
- - -
diff --git a/public/views/index.html b/public/views/index.html index 953dc31b..469172a2 100644 --- a/public/views/index.html +++ b/public/views/index.html @@ -1,23 +1,8 @@
-
+ diff --git a/public/views/transaction.html b/public/views/transaction.html new file mode 100644 index 00000000..5c55a50f --- /dev/null +++ b/public/views/transaction.html @@ -0,0 +1,104 @@ +
+ + +
+ {{tx.txid}} +
+ + + + + + + + + + + + + + + + + + + + + +
Input Output
+ +
+ No Inputs (Newly Generated isCoinBasens) +
+
  +
+ +
+
+ + +
+ +
+
+
+
+

Summary

+
+
+ + + + + + + + + + + + + + + +
Size{{tx.size}} (bytes)
Received Time{{tx.time * 1000|date:'medium'}}
Reward From BlockNeed height to show (it links to block page)
+
+
+
+
+
+
+

Inputs and Outputs

+
+
+ + + + + + + + + + + + + + + +
Total Input{{tx.valueIn}} BTC
Total Output{{tx.valueOut}} BTC
Fees{{tx.feeds}} BTC
+
+
+
+
+
+ diff --git a/test/model/block.js b/test/model/block.js index 6a2b5f08..2d98ce00 100644 --- a/test/model/block.js +++ b/test/model/block.js @@ -3,7 +3,7 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'development'; -var TESTING_BLOCK = '0000000000b6288775bbd326bedf324ca8717a15191da58391535408205aada4'; +var TESTING_BLOCK = '000000000185678d3d7ecc9962c96418174431f93fe20bf216d5565272423f74'; var mongoose= require('mongoose'), @@ -14,12 +14,17 @@ var mongoose.connection.on('error', function(err) { console.log(err); }); +<<<<<<< HEAD describe('Block getInfo', function(){ +======= +describe('Block fromHashWithInfo', function(){ +>>>>>>> fd86e6d074c5aa4642172b221b9e6f69f3fd8634 before(function(done) { mongoose.connect(config.db); done(); }); +<<<<<<< HEAD after(function(done) { mongoose.connection.close(); @@ -34,12 +39,34 @@ describe('Block getInfo', function(){ done(); }); }); +======= + + after(function(done) { + mongoose.connection.close(); + done(); + }); + + + it('should poll block\'s info from mongoose', function(done) { + var block2 = Block.fromHashWithInfo(TESTING_BLOCK, function(err, b2) { + if (err) done(err); + + assert.equal(b2.hash, TESTING_BLOCK); + done(); + }); + }); + +>>>>>>> fd86e6d074c5aa4642172b221b9e6f69f3fd8634 it('should poll block\'s info from bitcoind', function(done) { var block2 = Block.fromHashWithInfo(TESTING_BLOCK, function(err, b2) { if (err) done(err); assert.equal(b2.info.hash, TESTING_BLOCK); +<<<<<<< HEAD assert.equal(b2.info.chainwork, '00000000000000000000000000000000000000000000000000446af21d50acd3'); +======= + assert.equal(b2.info.chainwork, '000000000000000000000000000000000000000000000000001b6dc969ffe847'); +>>>>>>> fd86e6d074c5aa4642172b221b9e6f69f3fd8634 done(); }); }); diff --git a/test/model/transaction.js b/test/model/transaction.js new file mode 100644 index 00000000..7c51ec71 --- /dev/null +++ b/test/model/transaction.js @@ -0,0 +1,64 @@ +#!/usr/bin/env node + +process.env.NODE_ENV = process.env.NODE_ENV || 'development'; + + + +var + mongoose= require('mongoose'), + assert = require('assert'), + config = require('../../config/config'), + Transaction = require('../../app/models/Transaction'); + + +mongoose.connection.on('error', function(err) { console.log(err); }); + +describe('Transaction fromIdWithInfo', function(){ + + before(function(done) { + mongoose.connect(config.db); + done(); + }); + + after(function(done) { + mongoose.connection.close(); + done(); + }); + + it('should pool tx\'s object from mongoose', function(done) { + var test_txid = '21798ddc9664ac0ef618f52b151dda82dafaf2e26d2bbef6cdaf55a6957ca237'; + Transaction.fromIdWithInfo(test_txid, function(err, tx) { + if (err) done(err); + assert.equal(tx.txid, test_txid); + assert(!tx.info.isCoinBase); + done(); + }); + }); + + it('should pool tx\'s info from bitcoind', function(done) { + var test_txid = '21798ddc9664ac0ef618f52b151dda82dafaf2e26d2bbef6cdaf55a6957ca237'; + Transaction.fromIdWithInfo(test_txid, function(err, tx) { + if (err) done(err); + assert.equal(tx.info.txid, test_txid); + assert.equal(tx.info.blockhash, '000000000185678d3d7ecc9962c96418174431f93fe20bf216d5565272423f74'); + assert.equal(tx.info.valueOut, 1.66174); + assert.equal(tx.info.feeds, 0.0005 ); + assert.equal(tx.info.size, 226 ); + assert(!tx.info.isCoinBase); + done(); + }); + }); + + it('test a coinbase TX', function(done) { + var test_txid2 = '2a104bab1782e9b6445583296d4a0ecc8af304e4769ceb64b890e8219c562399'; + Transaction.fromIdWithInfo(test_txid2, function(err, tx) { + if (err) done(err); + assert(tx.info.isCoinBase); + assert.equal(tx.info.txid, test_txid2); + assert(!tx.info.feeds); + done(); + }); + }); + +}); +