From f4fb471ace47720f5cbcaa63a7d9d83f9a51ea13 Mon Sep 17 00:00:00 2001 From: Ivan Socolsky Date: Mon, 30 Mar 2015 19:44:16 -0300 Subject: [PATCH] refactor code to make it testable --- lib/blockchainmonitor.js | 90 ++++++++++++++++++++++++++++++++++ lib/eventbroadcaster.js | 25 ---------- lib/notificationbroadcaster.js | 25 ++++++++++ lib/server.js | 6 +-- lib/wsapp.js | 87 ++++++-------------------------- 5 files changed, 133 insertions(+), 100 deletions(-) create mode 100644 lib/blockchainmonitor.js delete mode 100644 lib/eventbroadcaster.js create mode 100644 lib/notificationbroadcaster.js diff --git a/lib/blockchainmonitor.js b/lib/blockchainmonitor.js new file mode 100644 index 0000000..2b7bc1d --- /dev/null +++ b/lib/blockchainmonitor.js @@ -0,0 +1,90 @@ +'use strict'; + +var $ = require('preconditions').singleton(); +var _ = require('lodash'); +var async = require('async'); +var log = require('npmlog'); +log.debug = log.verbose; +var Uuid = require('uuid'); +var inherits = require('inherits'); +var events = require('events'); +var nodeutil = require('util'); + +var WalletUtils = require('bitcore-wallet-utils'); +var Bitcore = WalletUtils.Bitcore; +var WalletService = require('./server'); +var BlockExplorer = require('./blockexplorer'); + +var Notification = require('./model/notification'); + +function BlockchainMonitor() { + this.subscriptions = {}; + this.sockets = {}; + + this._initBlockExplorerSocket('insight', 'livenet'); + this._initBlockExplorerSocket('insight', 'testnet'); +}; + +nodeutil.inherits(BlockchainMonitor, events.EventEmitter); + +BlockchainMonitor.prototype._initBlockExplorerSocket = function(provider, network) { + var explorer = new BlockExplorer({ + provider: provider, + network: network, + }); + + this.sockets[network] = explorer.initSocket(); +}; + +BlockchainMonitor.prototype.subscribeAddresses = function(walletId, addresses) { + $.checkArgument(walletId); + + var self = this; + + if (!addresses || addresses.length == 0) return; + + function handlerFor(address, txid) { + var notification = Notification.create({ + walletId: this, + type: 'NewIncomingTx', + data: { + address: address, + txid: txid, + }, + }); + self.emit('notification', notification); + }; + + if (!self.subscriptions[walletId]) { + self.subscriptions[walletId] = { + addresses: [], + }; + }; + var addresses = [].concat(addresses); + var network = Bitcore.Address.fromString(addresses[0]).network.name; + var socket = self.sockets[network]; + _.each(addresses, function(address) { + self.subscriptions[walletId].addresses.push(address); + socket.emit('subscribe', address); + socket.on(address, _.bind(handlerFor, walletId, address)); + }); +}; + +BlockchainMonitor.prototype.subscribeWallet = function(walletService) { + var self = this; + + var walletId = walletService.walletId; + if (self.subscriptions[walletId]) return; + + walletService.getMainAddresses({}, function(err, addresses) { + if (err) { + delete self.subscriptions[walletId]; + log.warn('Could not subscribe to addresses for wallet ' + walletId); + return; + } + self.subscribeAddresses(walletService.walletId, _.pluck(addresses, 'address')); + }); +}; + + +module.exports = BlockchainMonitor; diff --git a/lib/eventbroadcaster.js b/lib/eventbroadcaster.js deleted file mode 100644 index e8ab506..0000000 --- a/lib/eventbroadcaster.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -var log = require('npmlog'); -log.debug = log.verbose; -var inherits = require('inherits'); -var events = require('events'); -var nodeutil = require('util'); - -function EventBroadcaster() {}; - -nodeutil.inherits(EventBroadcaster, events.EventEmitter); - -EventBroadcaster.prototype.broadcast = function(eventName, serviceInstance, args) { - this.emit(eventName, serviceInstance, args); -}; - -var _eventBroadcasterInstance; -EventBroadcaster.singleton = function() { - if (!_eventBroadcasterInstance) { - _eventBroadcasterInstance = new EventBroadcaster(); - } - return _eventBroadcasterInstance; -}; - -module.exports = EventBroadcaster.singleton(); diff --git a/lib/notificationbroadcaster.js b/lib/notificationbroadcaster.js new file mode 100644 index 0000000..692c43e --- /dev/null +++ b/lib/notificationbroadcaster.js @@ -0,0 +1,25 @@ +'use strict'; + +var log = require('npmlog'); +log.debug = log.verbose; +var inherits = require('inherits'); +var events = require('events'); +var nodeutil = require('util'); + +function NotificationBroadcaster() {}; + +nodeutil.inherits(NotificationBroadcaster, events.EventEmitter); + +NotificationBroadcaster.prototype.broadcast = function(eventName, notification) { + this.emit(eventName, notification); +}; + +var _instance; +NotificationBroadcaster.singleton = function() { + if (!_instance) { + _instance = new NotificationBroadcaster(); + } + return _instance; +}; + +module.exports = NotificationBroadcaster.singleton(); diff --git a/lib/server.js b/lib/server.js index 30fd40c..b5bb64e 100644 --- a/lib/server.js +++ b/lib/server.js @@ -14,7 +14,7 @@ var Address = Bitcore.Address; var ClientError = require('./clienterror'); var Utils = require('./utils'); var Storage = require('./storage'); -var EventBroadcaster = require('./eventbroadcaster'); +var NotificationBroadcaster = require('./notificationbroadcaster'); var BlockExplorer = require('./blockexplorer'); var Wallet = require('./model/wallet'); @@ -41,7 +41,7 @@ function WalletService() { }; WalletService.onNotification = function(func) { - EventBroadcaster.on('notification', func); + NotificationBroadcaster.on('notification', func); }; /** @@ -167,7 +167,7 @@ WalletService.prototype._verifySignature = function(text, signature, pubKey) { * @param {Object} args */ WalletService.prototype._emit = function(eventName, args) { - EventBroadcaster.broadcast(eventName, this, args); + NotificationBroadcaster.broadcast(eventName, args); }; /** diff --git a/lib/wsapp.js b/lib/wsapp.js index a2544d0..19b3a78 100644 --- a/lib/wsapp.js +++ b/lib/wsapp.js @@ -4,24 +4,19 @@ var $ = require('preconditions').singleton(); var _ = require('lodash'); var async = require('async'); var log = require('npmlog'); -var express = require('express'); -var querystring = require('querystring'); -var bodyParser = require('body-parser') +log.debug = log.verbose; var Uuid = require('uuid'); var WalletUtils = require('bitcore-wallet-utils'); var Bitcore = WalletUtils.Bitcore; var WalletService = require('./server'); -var BlockExplorer = require('./blockexplorer'); +var BlockchainMonitor = require('./blockchainmonitor') var Notification = require('./model/notification'); -log.debug = log.verbose; log.level = 'debug'; -var io; -var blockExplorerSockets = {}; -var subscriptions = {}; +var io, bcMonitor; var WsApp = function() {}; @@ -30,79 +25,27 @@ WsApp._unauthorized = function() { socket.disconnect(); }; -WsApp.subscribeAddresses = function(walletId, addresses) { - $.checkArgument(walletId); - - if (!addresses || addresses.length == 0) return; - - function handlerFor(address, txid) { - var notification = Notification.create({ - walletId: this, - type: 'NewIncomingTx', - data: { - address: address, - txid: txid, - }, - }); - WsApp._sendNotification(notification); - }; - - if (!subscriptions[walletId]) { - subscriptions[walletId] = { - addresses: [], - }; - }; - var addresses = [].concat(addresses); - var network = Bitcore.Address.fromString(addresses[0]).network; - var socket = blockExplorerSockets[network]; - _.each(addresses, function(address) { - subscriptions[walletId].addresses.push(address); - socket.emit('subscribe', address); - socket.on(address, _.bind(handlerFor, walletId, address)); - }); -}; - -WsApp.subscribeWallet = function(serviceInstance) { - var walletId = serviceInstance.walletId; - if (subscriptions[walletId]) return; - - serviceInstance.getMainAddresses({}, function(err, addresses) { - if (err) { - delete subscriptions[walletId]; - log.warn('Could not subscribe to addresses for wallet ' + serviceInstance.walletId); - return; - } - WsApp.subscribeAddresses(serviceInstance.walletId, _.pluck(addresses, 'address')); - }); -}; - -WsApp._sendNotification = function(notification) { +WsApp.handleNotification = function(service, notification) { if (notification.type == 'NewAddress') { - WsApp.subscribeAddresses(notification.walletId, notification.data.address); + self.subscribeAddresses(notification.walletId, notification.data.address); } io.to(notification.walletId).emit('notification', notification); }; -WsApp._initBlockExplorerSocket = function(provider, network) { - var explorer = new BlockExplorer({ - provider: provider, - network: network, - }); - - blockExplorerSockets[network] = explorer.initSocket(); -}; - WsApp.start = function(server) { io = require('socket.io')(server); - WsApp._initBlockExplorerSocket('insight', 'testnet'); - WsApp._initBlockExplorerSocket('insight', 'livenet'); + bcMonitor = new BlockchainMonitor(); - WalletService.onNotification(function(serviceInstance, notification) { - if (!notification.walletId) return; + function handleNotification(notification) { + if (notification.type == 'NewAddress') { + bcMonitor.subscribeAddresses(notification.walletId, notification.data.address); + } + io.to(notification.walletId).emit('notification', notification); + }; - WsApp._sendNotification(notification); - }); + bcMonitor.on('notification', handleNotification); + WalletService.onNotification(handleNotification); io.on('connection', function(socket) { socket.nonce = Uuid.v4(); @@ -117,7 +60,7 @@ WsApp.start = function(server) { socket.join(service.walletId); socket.emit('authorized'); - WsApp.subscribeWallet(service); + bcMonitor.subscribeWallet(service); }); }); });