8 changed files with 187 additions and 9 deletions
@ -0,0 +1,80 @@ |
|||||
|
var log = require('../util/log'); |
||||
|
var networks = require('../networks'); |
||||
|
var Address = require('./Address'); |
||||
|
var Peer = require('./Peer'); |
||||
|
var PeerManager = require('./PeerManager'); |
||||
|
var util = require('util'); |
||||
|
var EventEmitter = require('events').EventEmitter; |
||||
|
var preconditions = require('preconditions').singleton(); |
||||
|
|
||||
|
var NetworkMonitor = function(peerman) { |
||||
|
preconditions.checkArgument(peerman); |
||||
|
this.peerman = peerman; |
||||
|
this.init(); |
||||
|
} |
||||
|
|
||||
|
util.inherits(NetworkMonitor, EventEmitter); |
||||
|
|
||||
|
NetworkMonitor.create = function(config) { |
||||
|
var peerman = new PeerManager({ |
||||
|
network: config.networkName |
||||
|
}); |
||||
|
|
||||
|
peerman.addPeer(new Peer(config.host, config.port)); |
||||
|
return new NetworkMonitor(peerman); |
||||
|
}; |
||||
|
|
||||
|
NetworkMonitor.prototype.init = function() { |
||||
|
var self = this; |
||||
|
var handleInv = function(info) { |
||||
|
var invs = info.message.invs; |
||||
|
info.conn.sendGetData(invs); |
||||
|
}; |
||||
|
|
||||
|
var handleBlock = function(info) { |
||||
|
self.emit('block', info.message); |
||||
|
}; |
||||
|
|
||||
|
var handleTx = function(info) { |
||||
|
var tx = info.message.tx; |
||||
|
|
||||
|
var from = tx.getSendingAddresses(); |
||||
|
for (var i = 0; i < from.length; i++) { |
||||
|
var addr = from[i]; |
||||
|
self.emit('out:'+addr, tx); |
||||
|
} |
||||
|
var to = tx.getReceivingAddresses(); |
||||
|
for (var i = 0; i < to.length; i++) { |
||||
|
var addr = to[i]; |
||||
|
self.emit('in:'+addr, tx); |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
this.peerman.on('connection', function(conn) { |
||||
|
if (self.connection) throw new Error('Cant handle more than one connection'); |
||||
|
self.connection = conn; |
||||
|
conn.on('inv', handleInv); |
||||
|
conn.on('block', handleBlock); |
||||
|
conn.on('tx', handleTx); |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
NetworkMonitor.prototype.incoming = function(addrStr, callback) { |
||||
|
preconditions.checkArgument(Address.validate(addrStr)); |
||||
|
this.on('in:'+addrStr, callback); |
||||
|
}; |
||||
|
|
||||
|
NetworkMonitor.prototype.outgoing = function(addrStr, callback) { |
||||
|
preconditions.checkArgument(Address.validate(addrStr)); |
||||
|
this.on('out:'+addrStr, callback); |
||||
|
}; |
||||
|
|
||||
|
NetworkMonitor.prototype.start = function() { |
||||
|
this.peerman.start(); |
||||
|
}; |
||||
|
|
||||
|
NetworkMonitor.prototype.stop = function() { |
||||
|
this.peerman.stop(); |
||||
|
}; |
||||
|
|
||||
|
module.exports = NetworkMonitor; |
@ -0,0 +1,97 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
var chai = chai || require('chai'); |
||||
|
var bitcore = bitcore || require('../bitcore'); |
||||
|
var NetworkMonitor = bitcore.NetworkMonitor; |
||||
|
var EventEmitter = require('events').EventEmitter; |
||||
|
|
||||
|
var should = chai.should(); |
||||
|
|
||||
|
var nop = function() {}; |
||||
|
|
||||
|
describe('NetworkMonitor', function() { |
||||
|
var config = { |
||||
|
networkName: 'testnet', |
||||
|
host: 'localhost', |
||||
|
port: 18333 |
||||
|
}; |
||||
|
var fakePM = {}; |
||||
|
fakePM.on = nop; |
||||
|
it('should initialze the main object', function() { |
||||
|
should.exist(NetworkMonitor); |
||||
|
}); |
||||
|
it('should be able to instanciate', function() { |
||||
|
var nm = new NetworkMonitor(fakePM); |
||||
|
should.exist(nm); |
||||
|
}); |
||||
|
it('should be able to create instance', function() { |
||||
|
var nm = new NetworkMonitor.create(config); |
||||
|
should.exist(nm); |
||||
|
}); |
||||
|
it('should be able to start instance', function() { |
||||
|
var nm = new NetworkMonitor.create(config); |
||||
|
nm.start.bind(nm).should.not.throw(); |
||||
|
}); |
||||
|
it('should be able to stop instance', function() { |
||||
|
var nm = new NetworkMonitor.create(config); |
||||
|
nm.start(); |
||||
|
nm.stop.bind(nm).should.not.throw(); |
||||
|
}); |
||||
|
it('should be able to register listeners', function() { |
||||
|
var nm = new NetworkMonitor.create(config); |
||||
|
(function() { |
||||
|
nm.on('block', nop); |
||||
|
}).should.not.throw(); |
||||
|
(function() { |
||||
|
nm.incoming('n2tTCgsJPJBZZEKLiJx9KoU4idJQB37j9E', nop); |
||||
|
}).should.not.throw(); |
||||
|
(function() { |
||||
|
nm.outgoing('n2tTCgsJPJBZZEKLiJx9KoU4idJQB37j9E', nop); |
||||
|
}).should.not.throw(); |
||||
|
}); |
||||
|
var createConnectedNM = function() { |
||||
|
var nm = new NetworkMonitor.create(config); |
||||
|
var fakeConnection = new EventEmitter(); |
||||
|
nm.peerman.emit('connection', fakeConnection); |
||||
|
return nm; |
||||
|
}; |
||||
|
it('should store connection', function() { |
||||
|
var nm = createConnectedNM(); |
||||
|
should.exist(nm.connection); |
||||
|
}); |
||||
|
describe('block event', function() { |
||||
|
it('should be called on blocks', function(done) { |
||||
|
var nm = createConnectedNM(); |
||||
|
nm.on('block', function(m) { |
||||
|
should.exist(m); |
||||
|
done(); |
||||
|
}); |
||||
|
nm.connection.emit('block', { |
||||
|
message: 'test' |
||||
|
}); |
||||
|
}); |
||||
|
}); |
||||
|
describe('incoming tx event', function() { |
||||
|
it('should be called on incoming transactions', function(done) { |
||||
|
var nm = createConnectedNM(); |
||||
|
nm.incoming('n2tTCgsJPJBZZEKLiJx9KoU4idJQB37j9E', function(tx) { |
||||
|
should.exist(tx); |
||||
|
done(); |
||||
|
}); |
||||
|
var fakeTX = null; |
||||
|
nm.connection.emit('tx', { |
||||
|
message: { |
||||
|
tx: fakeTX |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
it('should not be called on outgoing transactions', function() { |
||||
|
}); |
||||
|
}); |
||||
|
describe('outgoing tx event', function() { |
||||
|
it('should be called on outgoing transactions', function() { |
||||
|
}); |
||||
|
it('should not be called on incoming transactions', function() { |
||||
|
}); |
||||
|
}); |
||||
|
}); |
Loading…
Reference in new issue