From 1c96756743206fa0301dccab1b51f28708dad6aa Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 6 Jan 2014 19:02:33 -0300 Subject: [PATCH 1/9] getblock working! --- config/env/development.js | 7 ++++++- config/routes.js | 6 ++++-- package.json | 1 + util/get_block.js | 12 +++++------- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/config/env/development.js b/config/env/development.js index 0ef298cc..2ddf0dc0 100755 --- a/config/env/development.js +++ b/config/env/development.js @@ -4,5 +4,10 @@ module.exports = { db: "mongodb://localhost/mystery-dev", app: { name: "Mystery - Development" + }, + bitcoind: { + user: 'mystery', + pass: 'real_mystery', + protocol: 'http', } -} \ No newline at end of file +} diff --git a/config/routes.js b/config/routes.js index 182a2162..1f75a0ef 100644 --- a/config/routes.js +++ b/config/routes.js @@ -6,7 +6,9 @@ module.exports = function(app) { var index = require('../app/controllers/index'); app.get('/', index.render); - //TX routes - // + //Block routes + var blocks = require('model/app/controllers/blocks'); + app.get('/block/:block_hash', blocks.show); + }; diff --git a/package.json b/package.json index be95e6ec..0188d4d5 100644 --- a/package.json +++ b/package.json @@ -32,6 +32,7 @@ "postinstall": "node node_modules/bower/bin/bower install" }, "dependencies": { + "classtool": "*", "express": "~3.4.7", "jade": "~1.0.2", "mongoose": "~3.8.3", diff --git a/util/get_block.js b/util/get_block.js index 27880d8f..783d7cf7 100755 --- a/util/get_block.js +++ b/util/get_block.js @@ -1,17 +1,15 @@ #!/usr/bin/env node - - +process.env.NODE_ENV = process.env.NODE_ENV || 'development'; var RpcClient = require('../node_modules/bitcore/RpcClient').class(); +var config = require('../config/config'); + var block_hash = process.argv[2] || '0000000000b6288775bbd326bedf324ca8717a15191da58391535408205aada4'; -var rpc = new RpcClient({ - user: 'mystery', - pass: 'real_mystery', - protocol: 'http', -}); + +var rpc = new RpcClient(config.bitcoind); var block = rpc.getBlock(block_hash, function(err, block) { From e79e81fe4b4cb164959aa3f68728be4e5fc766d0 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Mon, 6 Jan 2014 23:50:29 -0300 Subject: [PATCH 2/9] block syncing working! --- app/models/Block.js | 68 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 +- util/sync.js | 64 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 app/models/Block.js create mode 100755 util/sync.js diff --git a/app/models/Block.js b/app/models/Block.js new file mode 100644 index 00000000..94404267 --- /dev/null +++ b/app/models/Block.js @@ -0,0 +1,68 @@ +'use strict'; + +/** + * Module dependencies. + */ +var mongoose = require('mongoose'), + Schema = mongoose.Schema; + + +/** + * Block Schema + */ +var BlockSchema = new Schema({ + hash: { + type: String, + index: true, + unique: true, + }, + size: Number, + confirmations: Number, + version: Number, + merkleroot: String, + tx: [ String ], + time: Date, + nonce: Number, + bits: String, + difficulty: Number, + chainwork: String, + previousblockhash: { + type: String, + index: true, + unique: true, + }, + nextblockhash: { + type: String, + index: true, + unique: true, + }, +}); + +/** + * Validations + */ + +/* +BlockSchema.path('title').validate(function(title) { + return title.length; +},'Title cannot be blank'); +*/ + +/** + * Statics + */ + +BlockSchema.statics.load = function(id, cb) { + this.findOne({ + _id: id + }).exec(cb); +}; + + +BlockSchema.statics.fromHash = function(hash, cb) { + this.findOne({ + hash: hash, + }).exec(cb); +}; + +module.exports = mongoose.model('Block', BlockSchema); diff --git a/package.json b/package.json index 0188d4d5..b235128d 100644 --- a/package.json +++ b/package.json @@ -38,6 +38,7 @@ "mongoose": "~3.8.3", "lodash": "~2.4.1", "bower": "~1.2.8", - "bitcore": "*" + "bitcore": "*", + "buffertools": "*" } } diff --git a/util/sync.js b/util/sync.js new file mode 100755 index 00000000..9fe5a5b2 --- /dev/null +++ b/util/sync.js @@ -0,0 +1,64 @@ +#!/usr/bin/env node + +process.env.NODE_ENV = process.env.NODE_ENV || 'development'; +require('buffertools').extend(); + +var RpcClient = require('../node_modules/bitcore/RpcClient').class(); +var networks = require('../node_modules/bitcore/networks'); + +var Block = require('../app/models/Block'); +var config = require('../config/config'); +var mongoose = require('mongoose'); + +var networkName = process.argv[2] || 'testnet'; +var genesisBlockHash = networks.testnet.genesisBlock.hash.reverse().toString('hex'); + + +function syncBlocks(blockHash) { + + rpc.getBlock(blockHash, function(err, blockInfo) { + if (err) { + console.log(err); + throw(err); + } + + if ( ! ( blockInfo.result.height % 1000) ) + console.log("Height:" + blockInfo.result.height); + + Block.create( blockInfo.result, function(err, inBlock) { + + if (err && err.toString().match(/E11000/)) { +// console.log("\twas there. Skipping"); + return syncBlocks(blockInfo.result.nextblockhash); + } + + if (err) throw(err); + + if (inBlock.nextblockhash && ! inBlock.nextblockhash.match(/^0+$/) ) { + syncBlocks(inBlock.nextblockhash) + } + else { + mongoose.connection.close(); + } + + }); + }); + +} + + +mongoose.connect(config.db); + +var db = mongoose.connection; +var rpc = new RpcClient(config.bitcoind); + + +db.on('error', console.error.bind(console, 'connection error:')); +db.once('open', function callback () { + + syncBlocks(genesisBlockHash); + +}); + + + From b1a439e688c67dce8e7fd79a3e1e6745eb57f830 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 7 Jan 2014 09:11:01 -0300 Subject: [PATCH 3/9] add percentage status to sync --- util/sync.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/util/sync.js b/util/sync.js index 2cb5d5ee..78991deb 100755 --- a/util/sync.js +++ b/util/sync.js @@ -3,6 +3,7 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'development'; require('buffertools').extend(); +var util = require('util'); var RpcClient = require('../node_modules/bitcore/RpcClient').class(); var networks = require('../node_modules/bitcore/networks'); @@ -26,8 +27,11 @@ function getNextBlock(blockHash,cb) { return cb(err); } - if ( ! ( blockInfo.result.height % 1000) ) - console.log("Height:" + blockInfo.result.height); + if ( ! ( blockInfo.result.height % 1000) ) { + var h = blockInfo.result.height, + d = blockInfo.result.confirmations; + console.log( util.format("Height: %d/%d [%d%%]", h, d, 100*h/(h+d))); + } Block.create( blockInfo.result, function(err, inBlock) { From f9e33647091d245f8581b99c6c4f451e28079efe Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Tue, 7 Jan 2014 09:43:04 -0300 Subject: [PATCH 4/9] better readme --- README.md | 98 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 91 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 35ff00c2..0bf63f1b 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,101 @@ -mystery -======= +# Mystery + +Project description. + +## Prerequisites +* Node.js - Download and Install [Node.js](http://www.nodejs.org/download/). You can also follow [this gist](https://gist.github.com/isaacs/579814) for a quick and easy way to install Node.js and npm +* MongoDB - Download and Install [MongoDB](http://www.mongodb.org/downloads) - Make sure it's running on the default port (27017). + +### Tools Prerequisites +* NPM - Node.js package manager, should be installed when you install node.js. +* Grunt - Download and Install [Grunt](http://gruntjs.com). +* Bower - Web package manager, installing [Bower](http://bower.io/) is simple when you have npm: + +``` +$ npm install -g bower +``` + +## Additional Packages +* Express - Defined as npm module in the [package.json](package.json) file. +* Mongoose - Defined as npm module in the [package.json](package.json) file. +* AngularJS - Defined as bower module in the [bower.json](bower.json) file. +* Twitter Bootstrap - Defined as bower module in the [bower.json](bower.json) file. +* UI Bootstrap - Defined as bower module in the [bower.json](bower.json) file. + +## Quick Install + The quickest way to get started with MEAN is to clone the project and utilize it like this: + + Grunt Command Line Interface: + + $ sudo npm -g install grunt-cli + + Install dependencies: + + $ npm install + + We use [Grunt](https://github.com/gruntjs/grunt-cli) to start the server: + + $ grunt + + When not using grunt you can use (for example in production): + + $ node server + + Then open a browser and go to: + + http://localhost:3000 -## Install +## Troubleshooting +If you did not get all library during grunt command, please use the follow command: -- sudo npm -g i grunt-cli -- npm i -- grunt + $ bower install +## Configuration +All configuration is specified in the [config](config/) folder, particularly the [config.js](config/config.js) file and the [env](config/env/) files. Here you will need to specify your application name and database name. -## bitcoind configuration +### bitcoind There is a bitcoind configuration sample at: ``` etc/mystery/bitcoin.conf ``` + +### Environmental Settings + +There are three environments provided by default, __development__, __test__, and __production__. Each of these environments has the following configuration options: +* __db__ - This is the name of the MongoDB database to use, and is set by default to __mystery-dev__ for the development environment. +* __app.name__ - This is the name of your app or website, and can be different for each environment. You can tell which environment you are running by looking at the TITLE attribute that your app generates. + +To run with a different environment, just specify NODE_ENV as you call grunt: + + $ NODE_ENV=test grunt + +If you are using node instead of grunt, it is very similar: + + $ NODE_ENV=test node server + +## Github +[Mystery](https://github.com/bitpay/mystery) + +## License +(The MIT License) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. From 9feb87ddf2f3a3aeb15a70706f608535c60e1a8b Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 7 Jan 2014 09:48:31 -0300 Subject: [PATCH 5/9] API for blocks v0.1 working! --- app/controllers/blocks.js | 33 +++++++++++++++++++++++++++++++++ app/models/Block.js | 20 ++++++++++---------- config/routes.js | 7 +++++-- util/sync.js | 6 +++--- 4 files changed, 51 insertions(+), 15 deletions(-) create mode 100644 app/controllers/blocks.js diff --git a/app/controllers/blocks.js b/app/controllers/blocks.js new file mode 100644 index 00000000..fdef6655 --- /dev/null +++ b/app/controllers/blocks.js @@ -0,0 +1,33 @@ +'use strict'; + + +var Block = require('../models/Block'); +//, _ = require('lodash'); + + + +/** + * Module dependencies. + */ + + +/** + * Find block by hash ... + */ +exports.block = function(req, res, next, hash) { + Block.fromHash(hash, function(err, block) { + if (err) return next(err); + if (!block) return next(new Error('Failed to load block ' + hash)); + req.block = block; + next(); + }); +}; + + +/** + * Show block + */ +exports.show = function(req, res) { + res.jsonp(req.block); +}; + diff --git a/app/models/Block.js b/app/models/Block.js index 94404267..53272b52 100644 --- a/app/models/Block.js +++ b/app/models/Block.js @@ -11,8 +11,8 @@ var mongoose = require('mongoose'), * Block Schema */ var BlockSchema = new Schema({ - hash: { - type: String, + hash: { + type: String, index: true, unique: true, }, @@ -27,12 +27,12 @@ var BlockSchema = new Schema({ difficulty: Number, chainwork: String, previousblockhash: { - type: String, + type: String, index: true, unique: true, }, nextblockhash: { - type: String, + type: String, index: true, unique: true, }, @@ -53,16 +53,16 @@ BlockSchema.path('title').validate(function(title) { */ BlockSchema.statics.load = function(id, cb) { - this.findOne({ - _id: id - }).exec(cb); + this.findOne({ + _id: id + }).exec(cb); }; BlockSchema.statics.fromHash = function(hash, cb) { - this.findOne({ - hash: hash, - }).exec(cb); + this.findOne({ + hash: hash, + }).exec(cb); }; module.exports = mongoose.model('Block', BlockSchema); diff --git a/config/routes.js b/config/routes.js index 1f75a0ef..7150af08 100644 --- a/config/routes.js +++ b/config/routes.js @@ -8,7 +8,10 @@ module.exports = function(app) { //Block routes - var blocks = require('model/app/controllers/blocks'); - app.get('/block/:block_hash', blocks.show); + var blocks = require('../app/controllers/blocks'); + app.get('/block/:blockHash', blocks.show); + + + app.param('blockHash', blocks.block); }; diff --git a/util/sync.js b/util/sync.js index 78991deb..9aff4453 100755 --- a/util/sync.js +++ b/util/sync.js @@ -40,7 +40,7 @@ function getNextBlock(blockHash,cb) { return cb(err); } - return getNextBlock(blockInfo.result.nextblockhash); + return getNextBlock(blockInfo.result.nextblockhash, cb); }); }); @@ -49,7 +49,7 @@ function getNextBlock(blockHash,cb) { function syncBlocks(network, cb) { - Block.findOne({}, {}, { sort: { 'height' : -1 } }, function(err, block) { + Block.findOne({}, {}, { sort: { 'confirmations' : 1 } }, function(err, block) { if (err) { return cb(err); } @@ -63,7 +63,7 @@ function syncBlocks(network, cb) { ; - console.log('Starting at hash' + nextHash); + console.log('Starting at hash: ' + nextHash); getNextBlock(nextHash, cb); }); } From cb57249d0835417c334670ce7f931c902c9efd26 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 7 Jan 2014 09:50:56 -0300 Subject: [PATCH 6/9] readme.md updated for API --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 0bf63f1b..14863737 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,19 @@ $ npm install -g bower http://localhost:3000 + + +## API + +### Blocks +``` + /block/[:hash] + /block/00000000a967199a2fad0877433c93df785a8d8ce062e5f9b451cd1397bdbf62 +``` + + + + ## Troubleshooting If you did not get all library during grunt command, please use the follow command: From 54969b2f58dc2e87ea88557e9d30d34db2dcc507 Mon Sep 17 00:00:00 2001 From: Gustavo Cortez Date: Tue, 7 Jan 2014 10:18:45 -0300 Subject: [PATCH 7/9] added previous step for run sync blocks in documentation. --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index 14863737..d63e2591 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,15 @@ $ npm install -g bower ## API + +## 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 ### Blocks ``` From c375d718abc9674417484345732016cf3cf6bfe6 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 7 Jan 2014 10:43:50 -0300 Subject: [PATCH 8/9] development config --- config/env/development.js | 1 + 1 file changed, 1 insertion(+) diff --git a/config/env/development.js b/config/env/development.js index 2ddf0dc0..969bd386 100755 --- a/config/env/development.js +++ b/config/env/development.js @@ -9,5 +9,6 @@ module.exports = { user: 'mystery', pass: 'real_mystery', protocol: 'http', + host: process.env.BITCOIND_HOST || '127.0.0.1', } } From 89657e971e535418387e3532979d33d1e22a687d Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Tue, 7 Jan 2014 10:56:53 -0300 Subject: [PATCH 9/9] BITCOIND_HOST and BITCOIND_PORT env variabled --- README.md | 5 ++++- config/env/development.js | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d63e2591..eb30b464 100644 --- a/README.md +++ b/README.md @@ -78,11 +78,14 @@ All configuration is specified in the [config](config/) folder, particularly the ### bitcoind - There is a bitcoind configuration sample at: +There is a bitcoind configuration sample at: ``` etc/mystery/bitcoin.conf ``` +If you want to use a external bitcoind server set BITCOIND_HOST / BITCOIND_PORT enviroment variables. Make sure that bitcoind is configured to accept incomming connections using 'rpcallowip' decribed in https://en.bitcoin.it/wiki/Running_Bitcoin. + + ### Environmental Settings There are three environments provided by default, __development__, __test__, and __production__. Each of these environments has the following configuration options: diff --git a/config/env/development.js b/config/env/development.js index 969bd386..6836a43c 100755 --- a/config/env/development.js +++ b/config/env/development.js @@ -10,5 +10,6 @@ module.exports = { pass: 'real_mystery', protocol: 'http', host: process.env.BITCOIND_HOST || '127.0.0.1', + port: process.env.BITCOIND_PORT || '8332', } }