From 5aa508ae8a7e74ad1377d85f72bcc6e721d570d9 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Wed, 8 Jan 2014 14:50:37 -0300 Subject: [PATCH 1/2] sync working for the thing version of the models --- app/models/Block.js | 50 +++----------------------------- app/models/Transaction.js | 60 +++++++++++++++++++++++++-------------- Sync.js => lib/Sync.js | 21 +++++++++----- util/sync.js | 2 +- 4 files changed, 57 insertions(+), 76 deletions(-) rename Sync.js => lib/Sync.js (89%) diff --git a/app/models/Block.js b/app/models/Block.js index ee68b94..b176e7e 100644 --- a/app/models/Block.js +++ b/app/models/Block.js @@ -13,59 +13,17 @@ var Transaction = require('./Transaction'); * Block Schema */ var BlockSchema = new Schema({ + + // For now we keep this as short as possible + // More fields will be propably added as we move + // forward with the UX hash: { type: String, index: true, unique: true, }, - size: Number, - height: 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, - }, }); -BlockSchema.methods.explodeTransactions = function(next) { - - // console.log('exploding %s', this.hash, typeof this.tx); - - async.forEach( this.tx, - function(tx, callback) { - // console.log('procesing TX %s', tx); - Transaction.create({ txid: tx }, function(err) { - if (err && ! err.toString().match(/E11000/)) { - return callback(); - } - if (err) { - - return callback(err); - } - return callback(); - - }); - }, - function(err) { - if (err) return next(err); - return next(); - } - ); -}; /** * Validations diff --git a/app/models/Transaction.js b/app/models/Transaction.js index 566a480..f0f24c4 100644 --- a/app/models/Transaction.js +++ b/app/models/Transaction.js @@ -4,35 +4,20 @@ * Module dependencies. */ var mongoose = require('mongoose'), - Schema = mongoose.Schema; - + Schema = mongoose.Schema, + async = require('async'); /** */ var TransactionSchema = new Schema({ + // For now we keep this as short as possible + // More fields will be propably added as we move + // forward with the UX txid: { type: String, index: true, unique: true, }, - version: Number, - locktime: Number, - vin: { - type: Array, - default: [], - }, - vout: { - type: Array, - default: [], - }, - blockhash: { - type: String, - index: true, - default: null, - }, - confirmations: Number, - time: Number, - blocktime: Number, }); /** @@ -52,13 +37,44 @@ TransactionSchema.statics.fromID = function(txid, cb) { }).exec(cb); }; +TransactionSchema.statics.createFromArray = function(txs, next) { + + var that = this; + + if (!txs) return next(); + +// console.log('exploding ', txs); + + async.forEach( txs, + function(tx, callback) { + // console.log('procesing TX %s', tx); + that.create({ txid: tx }, function(err) { + if (err && ! err.toString().match(/E11000/)) { + return callback(); + } + if (err) { + + return callback(err); + } + return callback(); + + }); + }, + function(err) { + if (err) return next(err); + return next(); + } + ); +}; + + /* * virtual */ // ugly? new object every call? -TransactionSchema.virtual('date').get(function () { - return new Date(this.time); +TransactionSchema.virtual('info').get(function () { + }); module.exports = mongoose.model('Transaction', TransactionSchema); diff --git a/Sync.js b/lib/Sync.js similarity index 89% rename from Sync.js rename to lib/Sync.js index ae7d23e..e8be9b2 100644 --- a/Sync.js +++ b/lib/Sync.js @@ -1,5 +1,10 @@ require('classtool'); + +/* We dont sync any contents from TXs, only their IDs are stored */ + +var isSyncTxEnabled = 0; + function spec(b) { var mongoose = require('mongoose'); var util = require('util'); @@ -8,9 +13,9 @@ function spec(b) { var networks = require('bitcore/networks'); var async = require('async'); - var config = require('./config/config'); - var Block = require('./app/models/Block'); - var Transaction=require('./app/models/Transaction'); + var config = require('../config/config'); + var Block = require('../app/models/Block'); + var Transaction=require('../app/models/Transaction'); function Sync(config) { this.network = config.networkName == 'testnet' ? networks.testnet : networks.livenet; @@ -46,7 +51,7 @@ function spec(b) { } if (inBlock) { - inBlock.explodeTransactions(function (err) { + Transaction.createFromArray( blockInfo.result.tx,function (err) { return that.getNextBlock(blockInfo.result.nextblockhash, cb); }); } @@ -82,6 +87,8 @@ function spec(b) { } + // This is not currently used. Transactions are represented by txid only + // in mongodb Sync.prototype.syncTXs = function (reindex, cb) { var that = this; @@ -157,14 +164,14 @@ function spec(b) { function(cb){ if (opts.destroy) { console.log("Deleting Blocks..."); - return Block.remove().exec(cb); + return db.collections['blocks'].drop(cb); } return cb(); }, function(cb){ if (opts.destroy) { console.log("Deleting TXs..."); - return Transaction.remove().exec(cb); + return db.collections['transactions'].drop(cb); } return cb(); }, @@ -186,7 +193,7 @@ function spec(b) { } }, function(cb) { - if (! opts.skip_txs) { + if ( isSyncTxEnabled && ! opts.skip_txs) { that.syncTXs(opts.reindex, function(err) { if (err) { return cb(err); diff --git a/util/sync.js b/util/sync.js index 22d1a53..c13562a 100755 --- a/util/sync.js +++ b/util/sync.js @@ -6,7 +6,7 @@ require('buffertools').extend(); var SYNC_VERSION = '0.1'; var program = require('commander'); -var Sync = require('../Sync').class(); +var Sync = require('../lib/Sync').class(); program .version(SYNC_VERSION) From 08f106aa0c9e23da00a745731219ab7f7ccd9aa4 Mon Sep 17 00:00:00 2001 From: Matias Alejo Garcia Date: Wed, 8 Jan 2014 16:29:39 -0300 Subject: [PATCH 2/2] testing thin models --- app/models/Block.js | 43 +++++++++++++++++++++++++++++++++++---- app/models/Transaction.js | 31 +++++++++++++++++++++------- lib/Sync.js | 2 +- test/model/block.js | 41 +++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 12 deletions(-) create mode 100644 test/model/block.js diff --git a/app/models/Block.js b/app/models/Block.js index b176e7e..8705978 100644 --- a/app/models/Block.js +++ b/app/models/Block.js @@ -4,10 +4,11 @@ * Module dependencies. */ var mongoose = require('mongoose'), - Schema = mongoose.Schema; - -var async = require('async'); -var Transaction = require('./Transaction'); + Schema = mongoose.Schema, + async = require('async'), + RpcClient = require('bitcore/RpcClient').class(), + config = require('../../config/config') + ; /** * Block Schema @@ -52,4 +53,38 @@ BlockSchema.statics.fromHash = function(hash, cb) { }).exec(cb); }; + +BlockSchema.statics.fromHashWithInfo = function(hash, cb) { + this.fromHash(hash, function(err, block) { + if (err) return cb(err); + + block.getInfo(function(err) { return cb(err,block); } ); + }); +}; + + + +// TODO: Can we store the rpc instance in the Block object? +BlockSchema.methods.getInfo = function (next) { + + var that = this; + var rpc = new RpcClient(config.bitcoind); + + rpc.getBlock(this.hash, function(err, blockInfo) { + if (err) return next(err); + + /* + * Not sure this is the right way to do it. + * Any other way to lazy load a property in a mongoose object? + */ + + that.info = blockInfo.result; + + //console.log("THAT", that); + return next(null, that.info); + }); +}; + + + module.exports = mongoose.model('Block', BlockSchema); diff --git a/app/models/Transaction.js b/app/models/Transaction.js index f0f24c4..5d2a6ee 100644 --- a/app/models/Transaction.js +++ b/app/models/Transaction.js @@ -37,6 +37,14 @@ TransactionSchema.statics.fromID = function(txid, cb) { }).exec(cb); }; +TransactionSchema.statics.fromIDWithInfo = function(txid, cb) { + this.fromHash(hash, function(err, tx) { + if (err) return cb(err); + + tx.getInfo(function(err) { return cb(err,tx); } ); + }); +}; + TransactionSchema.statics.createFromArray = function(txs, next) { var that = this; @@ -68,13 +76,22 @@ TransactionSchema.statics.createFromArray = function(txs, next) { }; -/* - * virtual - */ -// ugly? new object every call? -TransactionSchema.virtual('info').get(function () { - -}); +TransactionSchema.methods.getInfo = function (next) { + + var that = this; + var rpc = new RpcClient(config.bitcoind); + + rpc.getRawTransaction(this.txid, function(err, txInfo) { + if (err) return next(err); + that.info = txInfo.result; + + //console.log("THAT", that); + return next(null, that.info); + }); +}; + + + module.exports = mongoose.model('Transaction', TransactionSchema); diff --git a/lib/Sync.js b/lib/Sync.js index e8be9b2..8254cd8 100644 --- a/lib/Sync.js +++ b/lib/Sync.js @@ -152,7 +152,7 @@ function spec(b) { mongoose.connect(config.db); var db = mongoose.connection; - this.rpc = new RpcClient(config.bitcoind); + this.rpc = new RpcClient(config.bitcoind); var that = this; diff --git a/test/model/block.js b/test/model/block.js new file mode 100644 index 0000000..88af38e --- /dev/null +++ b/test/model/block.js @@ -0,0 +1,41 @@ +#!/usr/bin/env node + +process.env.NODE_ENV = process.env.NODE_ENV || 'development'; + + +var TESTING_BLOCK = '0000000000b6288775bbd326bedf324ca8717a15191da58391535408205aada4'; + +var + mongoose= require('mongoose'), + assert = require('assert'), + config = require('../../config/config'), + Block = require('../../app/models/Block'); + +mongoose.connect(config.db); + +var db = mongoose.connection; + +describe('getInfo', function(){ + + var block_hash = TESTING_BLOCK; + + + db.on('error', console.error.bind(console, 'connection error:')); + + db.once('open', function (){ + + + var block2 = Block.fromHashWithInfo(block_hash, function(err, b2) { + if (err) done(err); + + console.log("Block obj:"); + console.log(b2); + console.log("Block.info:"); + console.log(b2.info); + db.close(); + done(); + }); + + }); +}); +