From 5361183a1907beefc706e84eabf6b909dda60268 Mon Sep 17 00:00:00 2001 From: Braydon Fuller Date: Thu, 27 Aug 2015 13:02:01 -0400 Subject: [PATCH] Use node as a reference in modules, db and chain. --- README.md | 2 +- integration/regtest-node.js | 2 +- lib/chain.js | 17 ++--- lib/db.js | 19 +++--- lib/module.js | 2 +- lib/modules/address.js | 26 ++++---- lib/node.js | 8 --- test/chain.unit.js | 45 +++++++++---- test/db.unit.js | 47 ++++++++----- test/modules/address.unit.js | 125 ++++++++++++++++++++++++----------- test/node.unit.js | 6 -- 11 files changed, 180 insertions(+), 119 deletions(-) diff --git a/README.md b/README.md index 10d5973f..75fb957d 100644 --- a/README.md +++ b/README.md @@ -353,7 +353,7 @@ MyModule.prototype.subscribeCustom = function(emitter, param) { MyModule.prototype.getData = function(arg1, callback) { // You can query the data by reading from the leveldb store on db - this.db.store.get(arg1, callback); + this.node.db.store.get(arg1, callback); }; module.exports = MyModule; diff --git a/integration/regtest-node.js b/integration/regtest-node.js index 0832e89f..b224b98f 100644 --- a/integration/regtest-node.js +++ b/integration/regtest-node.js @@ -101,7 +101,7 @@ describe('Node Functionality', function() { after(function(done) { this.timeout(20000); - node.db.bitcoind.stop(function(err, result) { + node.bitcoind.stop(function(err, result) { done(); }); }); diff --git a/lib/chain.js b/lib/chain.js index e3ddb36d..66a47777 100644 --- a/lib/chain.js +++ b/lib/chain.js @@ -34,9 +34,6 @@ function Chain(opts) { opts = {}; } - this.db = opts.db; - this.p2p = opts.p2p; - this.genesis = opts.genesis; this.genesisOptions = opts.genesisOptions; this.genesisWeight = new BN(0); @@ -102,18 +99,18 @@ Chain.prototype.initialize = function() { var self = this; // Does our database already have a tip? - self.db.getMetadata(function getMetadataCallback(err, metadata) { + self.node.db.getMetadata(function getMetadataCallback(err, metadata) { if(err) { return self.emit('error', err); } else if(!metadata || !metadata.tip) { self.tip = self.genesis; self.tip.__height = 0; self.tip.__weight = self.genesisWeight; - self.db.putBlock(self.genesis, function putBlockCallback(err) { + self.node.db.putBlock(self.genesis, function putBlockCallback(err) { if(err) { return self.emit('error', err); } - self.db._onChainAddBlock(self.genesis, function(err) { + self.node.db._onChainAddBlock(self.genesis, function(err) { if(err) { return self.emit('error', err); } @@ -125,7 +122,7 @@ Chain.prototype.initialize = function() { }); } else { metadata.tip = metadata.tip; - self.db.getBlock(metadata.tip, function getBlockCallback(err, tip) { + self.node.db.getBlock(metadata.tip, function getBlockCallback(err, tip) { if(err) { return self.emit('error', err); } @@ -155,7 +152,7 @@ Chain.prototype.startBuilder = function() { Chain.prototype.getWeight = function getWeight(blockHash, callback) { var self = this; - var blockIndex = self.db.bitcoind.getBlockIndex(blockHash); + var blockIndex = self.node.bitcoind.getBlockIndex(blockHash); setImmediate(function() { if (blockIndex) { @@ -218,7 +215,7 @@ Chain.prototype.getHashes = function getHashes(tipHash, callback) { } } else { // do a db call if we don't have it - self.db.getPrevHash(hash, function(err, prevHash) { + self.node.db.getPrevHash(hash, function(err, prevHash) { if(err) { return callback(err); } @@ -249,7 +246,7 @@ Chain.prototype.saveMetadata = function saveMetadata(callback) { self.lastSavedMetadata = new Date(); - self.db.putMetadata(metadata, callback); + self.node.db.putMetadata(metadata, callback); }; module.exports = Chain; diff --git a/lib/db.js b/lib/db.js index 7c5bfcb2..acbbe019 100644 --- a/lib/db.js +++ b/lib/db.js @@ -8,8 +8,6 @@ var leveldown = require('leveldown'); var bitcore = require('bitcore'); var Block = bitcore.Block; var $ = bitcore.util.preconditions; -var BufferReader = bitcore.encoding.BufferReader; -var BufferWriter = bitcore.encoding.BufferWriter; var index = require('./'); var errors = index.errors; var log = index.log; @@ -39,7 +37,6 @@ function DB(options) { } this.store = levelup(options.path, { db: levelupStore }); - this.chain = options.chain; this.txPrefix = options.txPrefix || DB.PREFIXES.TX; this.prevHashPrefix = options.prevHashPrefix || DB.PREFIXES.PREV_HASH; this.blockPrefix = options.blockPrefix || DB.PREFIXES.BLOCK; @@ -88,7 +85,7 @@ DB.prototype.start = function(callback) { this.addModule(this._modules[i]); } } - this.bitcoind.on('tx', this.transactionHandler.bind(this)); + this.node.bitcoind.on('tx', this.transactionHandler.bind(this)); this.emit('ready'); setImmediate(callback); }; @@ -102,7 +99,7 @@ DB.prototype.getBlock = function(hash, callback) { var self = this; // get block from bitcoind - this.bitcoind.getBlock(hash, function(err, blockData) { + this.node.bitcoind.getBlock(hash, function(err, blockData) { if(err) { return callback(err); } @@ -111,7 +108,7 @@ DB.prototype.getBlock = function(hash, callback) { }; DB.prototype.getPrevHash = function(blockHash, callback) { - var blockIndex = this.bitcoind.getBlockIndex(blockHash); + var blockIndex = this.node.bitcoind.getBlockIndex(blockHash); setImmediate(function() { if (blockIndex) { callback(null, blockIndex.prevHash); @@ -127,7 +124,7 @@ DB.prototype.putBlock = function(block, callback) { }; DB.prototype.getTransaction = function(txid, queryMempool, callback) { - this.bitcoind.getTransaction(txid, queryMempool, function(err, txBuffer) { + this.node.bitcoind.getTransaction(txid, queryMempool, function(err, txBuffer) { if(err) { return callback(err); } @@ -140,7 +137,7 @@ DB.prototype.getTransaction = function(txid, queryMempool, callback) { }; DB.prototype.getTransactionWithBlockInfo = function(txid, queryMempool, callback) { - this.bitcoind.getTransactionWithBlockInfo(txid, queryMempool, function(err, obj) { + this.node.bitcoind.getTransactionWithBlockInfo(txid, queryMempool, function(err, obj) { if(err) { return callback(err); } @@ -160,7 +157,7 @@ DB.prototype.sendTransaction = function(tx, callback) { $.checkArgument(typeof tx === 'string', 'Argument must be a hex string or Transaction'); try { - var txid = this.bitcoind.sendTransaction(tx); + var txid = this.node.bitcoind.sendTransaction(tx); return callback(null, txid); } catch(err) { return callback(err); @@ -171,7 +168,7 @@ DB.prototype.estimateFee = function(blocks, callback) { var self = this; setImmediate(function() { - callback(null, self.bitcoind.estimateFee(blocks)); + callback(null, self.node.bitcoind.estimateFee(blocks)); }); }; @@ -338,7 +335,7 @@ DB.prototype.getPublishEvents = function() { DB.prototype.addModule = function(Module) { var module = new Module({ - db: this + node: this.node }); $.checkArgumentType(module, BaseModule); this.modules.push(module); diff --git a/lib/module.js b/lib/module.js index 0f15fb3b..82471327 100644 --- a/lib/module.js +++ b/lib/module.js @@ -1,7 +1,7 @@ 'use strict'; var Module = function(options) { - this.db = options.db; + this.node = options.node; }; /** diff --git a/lib/modules/address.js b/lib/modules/address.js index eab79f1f..c333c6eb 100644 --- a/lib/modules/address.js +++ b/lib/modules/address.js @@ -21,7 +21,7 @@ var AddressModule = function(options) { this.subscriptions['address/transaction'] = {}; this.subscriptions['address/balance'] = {}; - this.db.bitcoind.on('tx', this.transactionHandler.bind(this)); + this.node.bitcoind.on('tx', this.transactionHandler.bind(this)); }; @@ -77,10 +77,10 @@ AddressModule.prototype.transactionOutputHandler = function(messages, tx, output } // Find the address for the output - var address = script.toAddress(this.db.network); + var address = script.toAddress(this.node.db.network); if (!address && script.isPublicKeyOut()) { var pubkey = script.chunks[0].buf; - address = Address.fromPublicKey(new PublicKey(pubkey), this.db.network); + address = Address.fromPublicKey(new PublicKey(pubkey), this.node.db.network); } else if (!address){ return; } @@ -157,10 +157,10 @@ AddressModule.prototype.blockHandler = function(block, addOutput, callback) { continue; } - var address = script.toAddress(this.db.network); + var address = script.toAddress(this.node.db.network); if (!address && script.isPublicKeyOut()) { var pubkey = script.chunks[0].buf; - address = Address.fromPublicKey(new PublicKey(pubkey), this.db.network); + address = Address.fromPublicKey(new PublicKey(pubkey), this.node.db.network); } else if (!address){ continue; } @@ -324,7 +324,7 @@ AddressModule.prototype.getOutputs = function(addressStr, queryMempool, callback var outputs = []; var key = [AddressModule.PREFIXES.OUTPUTS, addressStr].join('-'); - var stream = this.db.store.createReadStream({ + var stream = this.node.db.store.createReadStream({ start: key, end: key + '~' }); @@ -342,7 +342,7 @@ AddressModule.prototype.getOutputs = function(addressStr, queryMempool, callback satoshis: Number(value[0]), script: value[1], blockHeight: Number(value[2]), - confirmations: self.db.chain.tip.__height - Number(value[2]) + 1 + confirmations: self.node.chain.tip.__height - Number(value[2]) + 1 }; outputs.push(output); @@ -363,7 +363,7 @@ AddressModule.prototype.getOutputs = function(addressStr, queryMempool, callback } if(queryMempool) { - outputs = outputs.concat(self.db.bitcoind.getMempoolOutputs(addressStr)); + outputs = outputs.concat(self.node.bitcoind.getMempoolOutputs(addressStr)); } callback(null, outputs); @@ -430,7 +430,7 @@ AddressModule.prototype.isSpent = function(output, queryMempool, callback) { var txid = output.prevTxId ? output.prevTxId.toString('hex') : output.txid; setImmediate(function() { - callback(self.db.bitcoind.isSpent(txid, output.outputIndex)); + callback(self.node.bitcoind.isSpent(txid, output.outputIndex)); }); }; @@ -438,7 +438,7 @@ AddressModule.prototype.getSpendInfoForOutput = function(txid, outputIndex, call var self = this; var key = [AddressModule.PREFIXES.SPENTS, txid, outputIndex].join('-'); - this.db.store.get(key, function(err, value) { + this.node.db.store.get(key, function(err, value) { if(err) { return callback(err); } @@ -487,19 +487,19 @@ AddressModule.prototype.getAddressHistoryForAddress = function(address, queryMem return callback(null, txinfos[txid]); } - self.db.getTransactionWithBlockInfo(txid, queryMempool, function(err, transaction) { + self.node.db.getTransactionWithBlockInfo(txid, queryMempool, function(err, transaction) { if(err) { return callback(err); } - transaction.populateInputs(self.db, [], function(err) { + transaction.populateInputs(self.node.db, [], function(err) { if(err) { return callback(err); } var confirmations = 0; if(transaction.__height >= 0) { - confirmations = self.db.chain.tip.__height - transaction.__height; + confirmations = self.node.chain.tip.__height - transaction.__height; } txinfos[transaction.hash] = { diff --git a/lib/node.js b/lib/node.js index 2dd44358..7f39ab9b 100644 --- a/lib/node.js +++ b/lib/node.js @@ -25,7 +25,6 @@ function Node(config) { this.db = null; this.chain = null; - this.p2p = null; this.network = null; this._loadConfiguration(config); @@ -396,13 +395,6 @@ Node.prototype._loadAPI = function() { Node.prototype._initialize = function() { var self = this; - // DB References - this.db.chain = this.chain; - this.db.bitcoind = this.bitcoind; - - // Chain References - this.chain.db = this.db; - this._initializeBitcoind(); this._initializeDatabase(); this._initializeChain(); diff --git a/test/chain.unit.js b/test/chain.unit.js index 52bd03b2..5864eca3 100644 --- a/test/chain.unit.js +++ b/test/chain.unit.js @@ -52,7 +52,10 @@ describe('Bitcoin Chain', function() { db.mempool = { on: sinon.spy() }; - var chain = new Chain({db: db, genesis: {hash: 'genesis'}}); + var node = { + db: db + }; + var chain = new Chain({node: node, genesis: {hash: 'genesis'}}); chain.on('ready', function() { should.exist(chain.tip); @@ -79,7 +82,10 @@ describe('Bitcoin Chain', function() { db.mempool = { on: sinon.spy() }; - var chain = new Chain({db: db, genesis: {hash: 'genesis'}}); + var node = { + db: db + }; + var chain = new Chain({node: node, genesis: {hash: 'genesis'}}); chain.getHeightForBlock = sinon.stub().callsArgWith(1, null, 10); chain.getWeight = sinon.stub().callsArgWith(1, null, new BN(50)); chain.on('ready', function() { @@ -105,7 +111,10 @@ describe('Bitcoin Chain', function() { db.mempool = { on: sinon.spy() }; - var chain = new Chain({db: db, genesis: {hash: 'genesis'}}); + var node = { + db: db + }; + var chain = new Chain({node: node, genesis: {hash: 'genesis'}}); chain.on('error', function(error) { should.exist(error); error.message.should.equal('getMetadataError'); @@ -127,7 +136,10 @@ describe('Bitcoin Chain', function() { db.mempool = { on: sinon.spy() }; - var chain = new Chain({db: db, genesis: {hash: 'genesis'}}); + var node = { + db: db + }; + var chain = new Chain({node: node, genesis: {hash: 'genesis'}}); chain.on('error', function(error) { should.exist(error); error.message.should.equal('putBlockError'); @@ -149,7 +161,10 @@ describe('Bitcoin Chain', function() { db.mempool = { on: sinon.spy() }; - var chain = new Chain({db: db, genesis: {hash: 'genesis'}}); + var node = { + db: db + }; + var chain = new Chain({node: node, genesis: {hash: 'genesis'}}); chain.on('error', function(error) { should.exist(error); error.message.should.equal('getBlockError'); @@ -179,12 +194,12 @@ describe('Bitcoin Chain', function() { describe('#getWeight', function() { var work = '000000000000000000000000000000000000000000005a7b3c42ea8b844374e9'; var chain = new Chain(); - chain.db = { - bitcoind: { - getBlockIndex: sinon.stub().returns({ - chainWork: work - }) - } + chain.node = {}; + chain.node.db = {}; + chain.node.bitcoind = { + getBlockIndex: sinon.stub().returns({ + chainWork: work + }) }; it('should give the weight as a BN', function(done) { @@ -196,7 +211,7 @@ describe('Bitcoin Chain', function() { }); it('should give an error if the weight is undefined', function(done) { - chain.db.bitcoind.getBlockIndex = sinon.stub().returns(undefined); + chain.node.bitcoind.getBlockIndex = sinon.stub().returns(undefined); chain.getWeight('hash2', function(err, weight) { should.exist(err); done(); @@ -223,8 +238,12 @@ describe('Bitcoin Chain', function() { cb(null, prevHash); }; + var node = { + db: db + }; + var chain = new Chain({ - db: db, + node: node, genesis: genesisBlock }); diff --git a/test/db.unit.js b/test/db.unit.js index ff07c71e..c93f5d3f 100644 --- a/test/db.unit.js +++ b/test/db.unit.js @@ -22,7 +22,8 @@ describe('Bitcoin DB', function() { it('should emit ready', function(done) { var db = new DB({store: memdown}); db._modules = ['mod1', 'mod2']; - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { on: sinon.spy() }; db.addModule = sinon.spy(); @@ -51,7 +52,8 @@ describe('Bitcoin DB', function() { describe('#getTransaction', function() { it('will return a NotFound error', function(done) { var db = new DB({store: memdown}); - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { getTransaction: sinon.stub().callsArgWith(2, null, null) }; var txid = '7426c707d0e9705bdd8158e60983e37d0f5d63529086d6672b07d9238d5aa623'; @@ -62,7 +64,8 @@ describe('Bitcoin DB', function() { }); it('will return an error from bitcoind', function(done) { var db = new DB({store: memdown}); - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { getTransaction: sinon.stub().callsArgWith(2, new Error('test error')) }; var txid = '7426c707d0e9705bdd8158e60983e37d0f5d63529086d6672b07d9238d5aa623'; @@ -73,7 +76,8 @@ describe('Bitcoin DB', function() { }); it('will return an error from bitcoind', function(done) { var db = new DB({store: memdown}); - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { getTransaction: sinon.stub().callsArgWith(2, null, new Buffer(transactionData[0].hex, 'hex')) }; var txid = '7426c707d0e9705bdd8158e60983e37d0f5d63529086d6672b07d9238d5aa623'; @@ -91,7 +95,8 @@ describe('Bitcoin DB', function() { var db = new DB({store: memdown}); var blockBuffer = new Buffer(blockData, 'hex'); var expectedBlock = Block.fromBuffer(blockBuffer); - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { getBlock: sinon.stub().callsArgWith(1, null, blockBuffer) }; @@ -103,7 +108,9 @@ describe('Bitcoin DB', function() { }); }); it('should give an error when bitcoind.js gives an error', function(done) { - db.bitcoind.getBlock = sinon.stub().callsArgWith(1, new Error('error')); + db.node = {}; + db.node.bitcoind = {}; + db.node.bitcoind.getBlock = sinon.stub().callsArgWith(1, new Error('error')); db.getBlock('00000000000000000593b60d8b4f40fd1ec080bdb0817d475dae47b5f5b1f735', function(err, block) { should.exist(err); err.message.should.equal('error'); @@ -125,7 +132,8 @@ describe('Bitcoin DB', function() { describe('#getPrevHash', function() { it('should return prevHash from bitcoind', function(done) { var db = new DB({store: memdown}); - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { getBlockIndex: sinon.stub().returns({ prevHash: 'prevhash' }) @@ -140,7 +148,8 @@ describe('Bitcoin DB', function() { it('should give an error if bitcoind could not find it', function(done) { var db = new DB({store: memdown}); - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { getBlockIndex: sinon.stub().returns(null) }; @@ -161,7 +170,8 @@ describe('Bitcoin DB', function() { }; var db = new DB({store: memdown}); - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { getTransactionWithBlockInfo: sinon.stub().callsArgWith(2, null, info) }; @@ -174,7 +184,8 @@ describe('Bitcoin DB', function() { }); it('should give an error if one occurred', function(done) { var db = new DB({store: memdown}); - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { getTransactionWithBlockInfo: sinon.stub().callsArgWith(2, new Error('error')) }; @@ -188,7 +199,8 @@ describe('Bitcoin DB', function() { describe('#sendTransaction', function() { it('should give the txid on success', function(done) { var db = new DB({store: memdown}); - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { sendTransaction: sinon.stub().returns('txid') }; @@ -201,7 +213,8 @@ describe('Bitcoin DB', function() { }); it('should give an error if bitcoind threw an error', function(done) { var db = new DB({store: memdown}); - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { sendTransaction: sinon.stub().throws(new Error('error')) }; @@ -216,14 +229,15 @@ describe('Bitcoin DB', function() { describe("#estimateFee", function() { it('should pass along the fee from bitcoind', function(done) { var db = new DB({store: memdown}); - db.bitcoind = { + db.node = {}; + db.node.bitcoind = { estimateFee: sinon.stub().returns(1000) }; db.estimateFee(5, function(err, fee) { should.not.exist(err); fee.should.equal(1000); - db.bitcoind.estimateFee.args[0][0].should.equal(5); + db.node.bitcoind.estimateFee.args[0][0].should.equal(5); done(); }); }); @@ -391,11 +405,14 @@ describe('Bitcoin DB', function() { inherits(Module1, BaseModule); var db = new DB({store: memdown}); + var node = {}; + db.node = node; db.modules = []; db.addModule(Module1); db.modules.length.should.equal(1); - should.exist(db.modules[0].db); + should.exist(db.modules[0].node); + db.modules[0].node.should.equal(node); }); it('should throw an error if module is not an instance of BaseModule', function() { diff --git a/test/modules/address.unit.js b/test/modules/address.unit.js index 433074dd..6031de9b 100644 --- a/test/modules/address.unit.js +++ b/test/modules/address.unit.js @@ -16,11 +16,18 @@ var mockdb = { } }; +var mocknode = { + db: mockdb, + bitcoind: { + on: sinon.stub() + } +}; + describe('AddressModule', function() { describe('#getAPIMethods', function() { it('should return the correct methods', function() { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); var methods = am.getAPIMethods(); methods.length.should.equal(5); }); @@ -28,7 +35,7 @@ describe('AddressModule', function() { describe('#getPublishEvents', function() { it('will return an array of publish event objects', function() { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); am.subscribe = sinon.spy(); am.unsubscribe = sinon.spy(); var events = am.getPublishEvents(); @@ -64,7 +71,7 @@ describe('AddressModule', function() { it('create a message for an address', function() { var txBuf = new Buffer('01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000', 'hex'); var tx = bitcore.Transaction().fromBuffer(txBuf); - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); var address = '12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX'; var messages = {}; am.transactionOutputHandler(messages, tx, 0, true); @@ -80,7 +87,7 @@ describe('AddressModule', function() { describe('#transactionHandler', function() { it('will pass outputs to transactionOutputHandler and call transactionEventHandler', function() { var txBuf = new Buffer('01000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0704ffff001d0104ffffffff0100f2052a0100000043410496b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52da7589379515d4e0a604f8141781e62294721166bf621e73a82cbf2342c858eeac00000000', 'hex'); - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); var address = '12c6DSiU4Rq3P4ZxziKxzrL5LmMBrzjrJX'; var message = {}; am.transactionOutputHandler = function(messages) { @@ -151,7 +158,7 @@ describe('AddressModule', function() { var value64 = data[2].value; before(function() { - am = new AddressModule({db: db, network: 'livenet'}); + am = new AddressModule({node: mocknode, network: 'livenet'}); }); it('should create the correct operations when updating/adding outputs', function(done) { @@ -211,7 +218,7 @@ describe('AddressModule', function() { } }; - var am = new AddressModule({db: db, network: 'livenet'}); + var am = new AddressModule({node: mocknode, network: 'livenet'}); var block = { __height: 345003, @@ -245,7 +252,13 @@ describe('AddressModule', function() { on: sinon.stub() } }; - var am = new AddressModule({db: db, network: 'livenet'}); + var testnode = { + db: db, + bitcoind: { + on: sinon.stub() + } + }; + var am = new AddressModule({node: testnode, network: 'livenet'}); am.transactionEventHandler = sinon.spy(); am.balanceEventHandler = sinon.spy(); @@ -273,7 +286,7 @@ describe('AddressModule', function() { describe('#transactionEventHandler', function() { it('will emit a transaction if there is a subscriber', function(done) { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); var emitter = new EventEmitter(); am.subscriptions['address/transaction'] = { '1DzjESe6SLmAKVPLFMj6Sx1sWki3qt5i8N': [emitter] @@ -303,7 +316,7 @@ describe('AddressModule', function() { describe('#balanceEventHandler', function() { it('will emit a balance if there is a subscriber', function(done) { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); var emitter = new EventEmitter(); am.subscriptions['address/balance'] = { '1DzjESe6SLmAKVPLFMj6Sx1sWki3qt5i8N': [emitter] @@ -323,7 +336,7 @@ describe('AddressModule', function() { describe('#subscribe', function() { it('will add emitters to the subscribers array (transaction)', function() { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); var emitter = new EventEmitter(); var address = '1DzjESe6SLmAKVPLFMj6Sx1sWki3qt5i8N'; @@ -340,7 +353,7 @@ describe('AddressModule', function() { am.subscriptions['address/transaction'][address].should.deep.equal([emitter, emitter2]); }); it('will add an emitter to the subscribers array (balance)', function() { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); var emitter = new EventEmitter(); var name = 'address/balance'; var address = '1DzjESe6SLmAKVPLFMj6Sx1sWki3qt5i8N'; @@ -359,7 +372,7 @@ describe('AddressModule', function() { describe('#unsubscribe', function() { it('will remove emitter from subscribers array (transaction)', function() { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); var emitter = new EventEmitter(); var emitter2 = new EventEmitter(); var address = '1DzjESe6SLmAKVPLFMj6Sx1sWki3qt5i8N'; @@ -369,7 +382,7 @@ describe('AddressModule', function() { am.subscriptions['address/transaction'][address].should.deep.equal([emitter2]); }); it('will remove emitter from subscribers array (balance)', function() { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); var emitter = new EventEmitter(); var emitter2 = new EventEmitter(); var address = '1DzjESe6SLmAKVPLFMj6Sx1sWki3qt5i8N'; @@ -379,7 +392,7 @@ describe('AddressModule', function() { am.subscriptions['address/balance'][address].should.deep.equal([emitter2]); }); it('should unsubscribe from all addresses if no addresses are specified', function() { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); var emitter = new EventEmitter(); var emitter2 = new EventEmitter(); am.subscriptions['address/balance'] = { @@ -396,7 +409,7 @@ describe('AddressModule', function() { describe('#getBalance', function() { it('should sum up the unspent outputs', function(done) { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); var outputs = [ {satoshis: 1000}, {satoshis: 2000}, {satoshis: 3000} ]; @@ -409,7 +422,7 @@ describe('AddressModule', function() { }); it('will handle error from unspent outputs', function(done) { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); am.getUnspentOutputs = sinon.stub().callsArgWith(2, new Error('error')); am.getBalance('someaddress', false, function(err) { should.exist(err); @@ -423,24 +436,26 @@ describe('AddressModule', function() { describe('#getOutputs', function() { var am; var address = '1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W'; - var db = { - bitcoind: { - on: sinon.stub() - }, + var db = {}; + var testnode = { chain: { tip: { __height: 1 } + }, + db: db, + bitcoind: { + on: sinon.stub() } }; before(function() { - am = new AddressModule({db: db}); + am = new AddressModule({node: testnode}); }); it('should get outputs for an address', function(done) { var readStream1 = new EventEmitter(); - am.db.store = { + am.node.db.store = { createReadStream: sinon.stub().returns(readStream1) }; var mempoolOutputs = [ @@ -452,7 +467,7 @@ describe('AddressModule', function() { blockHeight: 352532 } ]; - am.db.bitcoind = { + am.node.bitcoind = { getMempoolOutputs: sinon.stub().returns(mempoolOutputs) }; @@ -495,7 +510,7 @@ describe('AddressModule', function() { it('should give an error if the readstream has an error', function(done) { var readStream2 = new EventEmitter(); - am.db.store = { + am.node.db.store = { createReadStream: sinon.stub().returns(readStream2) }; @@ -525,7 +540,13 @@ describe('AddressModule', function() { on: sinon.spy() } }; - var am = new AddressModule({db: db}); + var testnode = { + db: db, + bitcoind: { + on: sinon.stub() + } + }; + var am = new AddressModule({node: testnode}); am.getUnspentOutputsForAddress = function(address, queryMempool, callback) { var result = addresses[address]; if(result instanceof Error) { @@ -553,7 +574,13 @@ describe('AddressModule', function() { on: sinon.spy() } }; - var am = new AddressModule({db: db}); + var testnode = { + db: db, + bitcoind: { + on: sinon.stub() + } + }; + var am = new AddressModule({node: testnode}); am.getUnspentOutputsForAddress = function(address, queryMempool, callback) { var result = addresses[address]; if(result instanceof Error) { @@ -582,7 +609,13 @@ describe('AddressModule', function() { on: sinon.spy() } }; - var am = new AddressModule({db: db}); + var testnode = { + db: db, + bitcoind: { + on: sinon.stub() + } + }; + var am = new AddressModule({node: testnode}); am.getUnspentOutputsForAddress = function(address, queryMempool, callback) { var result = addresses[address]; if(result instanceof Error) { @@ -618,7 +651,7 @@ describe('AddressModule', function() { ]; var i = 0; - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); am.getOutputs = sinon.stub().callsArgWith(2, null, outputs); am.isUnspent = function(output, queryMempool, callback) { callback(!outputs[i].spent); @@ -634,7 +667,7 @@ describe('AddressModule', function() { }); }); it('should handle an error from getOutputs', function(done) { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); am.getOutputs = sinon.stub().callsArgWith(2, new Error('error')); am.getUnspentOutputsForAddress('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', false, function(err, outputs) { should.exist(err); @@ -643,7 +676,7 @@ describe('AddressModule', function() { }); }); it('should handle when there are no outputs', function(done) { - var am = new AddressModule({db: mockdb}); + var am = new AddressModule({node: mocknode}); am.getOutputs = sinon.stub().callsArgWith(2, null, []); am.getUnspentOutputsForAddress('1KiW1A4dx1oRgLHtDtBjcunUGkYtFgZ1W', false, function(err, outputs) { should.exist(err); @@ -658,7 +691,7 @@ describe('AddressModule', function() { var am; before(function() { - am = new AddressModule({db: mockdb}); + am = new AddressModule({node: mocknode}); }); it('should give true when isSpent() gives false', function(done) { @@ -693,9 +726,15 @@ describe('AddressModule', function() { on: sinon.stub() } }; + var testnode = { + db: db, + bitcoind: { + on: sinon.stub() + } + }; before(function() { - am = new AddressModule({db: db}); - am.db.bitcoind = { + am = new AddressModule({node: testnode}); + am.node.bitcoind = { isSpent: sinon.stub().returns(true), on: sinon.stub() }; @@ -714,12 +753,15 @@ describe('AddressModule', function() { var db = { store: { get: sinon.stub().callsArgWith(1, null, 'spendtxid:1') - }, + } + }; + var testnode = { + db: db, bitcoind: { on: sinon.stub() } }; - var am = new AddressModule({db: db}); + var am = new AddressModule({node: testnode}); am.getSpendInfoForOutput('txid', 3, function(err, info) { should.not.exist(err); info.txid.should.equal('spendtxid'); @@ -824,17 +866,20 @@ describe('AddressModule', function() { } } callback(new Error('tx ' + txid + ' not found')); - }, - bitcoind: { - on: sinon.stub() - }, + } + }; + var testnode = { chain: { tip: { __height: 1 } + }, + db: db, + bitcoind: { + on: sinon.stub() } }; - var am = new AddressModule({db: db}); + var am = new AddressModule({node: testnode}); am.getOutputs = sinon.stub().callsArgWith(2, null, incoming); am.getSpendInfoForOutput = function(txid, outputIndex, callback) { diff --git a/test/node.unit.js b/test/node.unit.js index 042a0c0f..35476fdf 100644 --- a/test/node.unit.js +++ b/test/node.unit.js @@ -528,12 +528,6 @@ describe('Bitcoind Node', function() { node._initialize(); - // references - node.db.chain.should.equal(node.chain); - node.db.bitcoind.should.equal(node.bitcoind); - node.chain.db.should.equal(node.db); - node.chain.db.should.equal(node.db); - // event handlers node._initializeBitcoind.callCount.should.equal(1); node._initializeDatabase.callCount.should.equal(1);