starting NetworkMonitor implementation

This commit is contained in:
Manuel Araoz 2014-07-19 12:21:22 -03:00
parent 0f737b4f00
commit 486f2ae1dc
8 changed files with 187 additions and 9 deletions

View File

@ -81,4 +81,5 @@ requireWhenAccessed('PeerManager', './lib/PeerManager');
requireWhenAccessed('Message', './lib/Message');
requireWhenAccessed('Electrum', './lib/Electrum');
requireWhenAccessed('Armory', './lib/Armory');
requireWhenAccessed('NetworkMonitor', './lib/NetworkMonitor');
module.exports.Buffer = Buffer;

View File

@ -182,5 +182,9 @@ Address.prototype.getScriptPubKey = function() {
return script;
};
Address.validate = function(s) {
return new Address(s).isValid();
};
module.exports = Address;

80
lib/NetworkMonitor.js Normal file
View File

@ -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;

View File

@ -84,7 +84,8 @@
"async": "~0.2.10",
"event-stream": "~3.1.5",
"gulp-concat": "~2.2.0",
"gulp": "~3.8.2"
"gulp": "~3.8.2",
"preconditions": "^1.0.7"
},
"testling": {
"harness": "mocha-bdd",

View File

@ -50,6 +50,7 @@ describe('Address', function() {
var s = a.toString();
a.isValid().should.equal(result);
Address.validate(address).should.equal(result);
s.should.equal(a.toString()); // check that validation doesn't change data
});
});

View File

@ -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() {
});
});
});

View File

@ -5,16 +5,10 @@ var bitcore = bitcore || require('../bitcore');
var should = chai.should();
var PeerManagerModule = bitcore.PeerManager;
var PeerManager;
var PeerManager = bitcore.PeerManager;
describe('PeerManager', function() {
it('should initialze the main object', function() {
should.exist(PeerManagerModule);
});
it('should be able to create class', function() {
PeerManager = PeerManagerModule;
should.exist(PeerManager);
});
it('should be able to create instance', function() {

View File

@ -48,7 +48,7 @@ function parse_test_transaction(entry) {
}
describe('Transaction', function() {
it('should initialze the main object', function() {
it('should initialize the main objects', function() {
should.exist(Transaction);
In = Transaction.In;
Out = Transaction.Out;