diff --git a/config/default.yml b/config/default.yml index 007e6881..a5c41ca3 100644 --- a/config/default.yml +++ b/config/default.yml @@ -1,4 +1,5 @@ -NetworkMonitor: - network: livenet - host: localhost - port: 8333 +BitcoreNode: + NetworkMonitor: + network: livenet + host: localhost + port: 8333 diff --git a/index.js b/index.js index fe11a90c..3ad4398a 100755 --- a/index.js +++ b/index.js @@ -1,26 +1,19 @@ 'use strict'; - var config = require('config'); -var bitcore = require('bitcore'); - -var NetworkMonitor = require('./lib/networkmonitor'); -var EventBus = require('./lib/eventbus'); - - -var bus = new EventBus(); -var nm = NetworkMonitor.create(bus, config.get('NetworkMonitor')); - -bus.register(bitcore.Transaction, function(tx) { - console.log('Transaction:', tx.id); -}); - -bus.register(bitcore.Block, function(block) { - console.log('Block:', block.id); -}); - -nm.start(); - +var BitcoreNode = require('./lib/node.js'); +if (require.main === module) { + var node = BitcoreNode.create(config.get('BitcoreNode')); + node.start(); + node.on('error', function(err) { + if (err.code === 'ECONNREFUSED') { + console.log('Connection to bitcoind failed'); + } else { + console.log('Unrecognized error: ', err); + } + }); +} +module.exports = BitcoreNode; diff --git a/lib/eventbus.js b/lib/eventbus.js index 20da9316..2859d9a8 100644 --- a/lib/eventbus.js +++ b/lib/eventbus.js @@ -5,7 +5,7 @@ var bitcore = require('bitcore'); var Promise = require('bluebird'); var $ = bitcore.util.preconditions; var _ = bitcore.deps._; -var EventEmitter = require('events').EventEmitter; +var EventEmitter = require('eventemitter2').EventEmitter2; var util = require('util'); function EventBus() { diff --git a/lib/networkmonitor.js b/lib/networkmonitor.js index 2f5a442d..e0194b2f 100644 --- a/lib/networkmonitor.js +++ b/lib/networkmonitor.js @@ -1,7 +1,7 @@ 'use strict'; var util = require('util'); -var EventEmitter = require('events').EventEmitter; +var EventEmitter = require('eventemitter2').EventEmitter2; var bitcore = require('bitcore'); var Networks = bitcore.Networks; @@ -44,6 +44,10 @@ NetworkMonitor.prototype.setupPeer = function(peer) { peer.on('block', function(m) { self.bus.process(m.block); }); + peer.on('error', function(err) { + self.emit('error', err); + }); + }; NetworkMonitor.prototype.start = function() { diff --git a/lib/node.js b/lib/node.js new file mode 100644 index 00000000..198fbb76 --- /dev/null +++ b/lib/node.js @@ -0,0 +1,50 @@ +'use strict'; + +var util = require('util'); +var EventEmitter = require('eventemitter2').EventEmitter2; + +var bitcore = require('bitcore'); +var Unit = bitcore.Unit; +var $ = bitcore.util.preconditions; + +var NetworkMonitor = require('./networkmonitor'); +var EventBus = require('./eventbus'); + +var BitcoreNode = function(bus, nm) { + $.checkArgument(bus); + $.checkArgument(nm); + var self = this; + this.bus = bus; + this.nm = nm; + + this.bus.register(bitcore.Transaction, function(tx) { + var tout = Unit.fromSatoshis(tx.outputAmount).toBTC(); + console.log('Transaction:', tx.id); + console.log('\ttotal_out:', tout, 'BTC'); + }); + + this.bus.register(bitcore.Block, function(block) { + console.log('Block:', block.id); + }); + + this.bus.onAny(function(value) { + self.emit(this.event, value); + }); + this.nm.on('error', function(err) { + self.emit('error', err); + }); +}; +util.inherits(BitcoreNode, EventEmitter); + +BitcoreNode.create = function(opts) { + opts = opts || {}; + var bus = new EventBus(); + var nm = NetworkMonitor.create(bus, opts.NetworkMonitor); + return new BitcoreNode(bus, nm); +}; + +BitcoreNode.prototype.start = function() { + this.nm.start(); +}; + +module.exports = BitcoreNode; diff --git a/package.json b/package.json index 20437458..a349d3cc 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "compression": "^1.4.1", "cors": "^2.5.3", "cron": "^1.0.4", + "eventemitter2": "^0.4.14", "express": "4.11.1", "glob": "*", "js-yaml": "^3.2.7", diff --git a/test/eventbus.js b/test/eventbus.js index b890f290..8c4989e9 100644 --- a/test/eventbus.js +++ b/test/eventbus.js @@ -57,18 +57,20 @@ describe('EventBus', function() { bus.process(foo); }); var b1 = new BarEvent(); - b1.x = 42; + b1.y = 42; var b2 = new BarEvent(); - b2.x = 69; - it('foo returns two bars', function() { + b2.y = 69; + it('foo returns two bars', function(cb) { var bus = new EventBus(); var spy = sinon.spy(); bus.register(FooEvent, function() { return [b1, b2]; }); bus.register(BarEvent, spy); - bus.process(foo); - spy.callCount.should.equal(2); + bus.process(foo).then(function() { + spy.callCount.should.equal(2); + cb(); + }); }); it('foo returns two bars and emits external events', function(cb) { var bus = new EventBus(); @@ -104,7 +106,7 @@ describe('EventBus', function() { return Promise.resolve([b1, b2]).delay(1); }); bus.register(BarEvent, function(e) { - if (e.x === b1.x) { + if (e.y === b1.y) { throw err; } }); diff --git a/test/networkmonitor.js b/test/networkmonitor.js index f084e3f4..28660ca1 100644 --- a/test/networkmonitor.js +++ b/test/networkmonitor.js @@ -8,7 +8,7 @@ var sinon = require('sinon'); var util = require('util'); var Transaction = bitcore.Transaction; var Block = bitcore.Block; -var EventEmitter = require('events').EventEmitter; +var EventEmitter = require('eventemitter2').EventEmitter2; var NetworkMonitor = require('../lib/networkmonitor'); var EventBus = require('../lib/eventbus'); @@ -65,9 +65,16 @@ describe('NetworkMonitor', function() { nm.start.bind(nm).should.not.throw(); }); + it('broadcasts errors in underlying peer', function(cb) { + var nm = new NetworkMonitor(busMock, peerMock); + nm.on('error', cb); + nm.start(); + peerMock.emit('error'); + }); + it('broadcasts ready after start', function(cb) { var nm = new NetworkMonitor(busMock, peerMock); - nm.on('ready', cb) + nm.on('ready', cb); nm.start(); }); diff --git a/test/node.js b/test/node.js new file mode 100644 index 00000000..fe9ca6e8 --- /dev/null +++ b/test/node.js @@ -0,0 +1,49 @@ +'use strict'; + +var chai = require('chai'); +var should = chai.should(); +var sinon = require('sinon'); + +var Promise = require('bluebird'); +var EventEmitter = require('eventemitter2').EventEmitter2; +var BitcoreNode = require('../lib/node'); +var EventBus = require('../lib/eventbus'); +Promise.longStackTraces(); + +describe('BitcoreNode', function() { + + // mocks + var busMock, nmMock; + beforeEach(function() { + busMock = new EventBus(); + nmMock = new EventEmitter(); + nmMock.start = function() {}; + }); + describe('instantiates', function() { + it('from constructor', function() { + var node = new BitcoreNode(busMock, nmMock); + should.exist(node); + }); + + it('from create', function() { + var node = BitcoreNode.create(); + should.exist(node); + }); + }); + + it('starts', function() { + var node = new BitcoreNode(busMock, nmMock); + node.start.bind(node).should.not.throw(); + }); + + it('broadcasts errors from network monitor', function(cb) { + var node = new BitcoreNode(busMock, nmMock); + node.on('error', cb); + nmMock.emit('error'); + }); + it('exposes all events from the event bus', function(cb) { + var node = new BitcoreNode(busMock, nmMock); + node.on('foo', cb); + busMock.emit('foo'); + }); +});