Skip to content

Commit

Permalink
Merge pull request #444 from maraoz/add/NetworkMonitor
Browse files Browse the repository at this point in the history
Add NetworkMonitor class
  • Loading branch information
Ryan X. Charles committed Jul 24, 2014
2 parents 0f737b4 + b0d0c2b commit 0bcdb7c
Show file tree
Hide file tree
Showing 15 changed files with 806 additions and 39,388 deletions.
1 change: 1 addition & 0 deletions bitcore.js
Expand Up @@ -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;
4 changes: 4 additions & 0 deletions browser/build.js
Expand Up @@ -24,6 +24,7 @@ var modules = [
'lib/ECIES',
'lib/Electrum',
'lib/Message',
'lib/NetworkMonitor',
'lib/Opcode',
'lib/PayPro',
'lib/Peer',
Expand Down Expand Up @@ -101,6 +102,9 @@ var createBitcore = function(opts) {
b.require(opts.dir + 'bufferput', {
expose: 'bufferput'
});
b.require(opts.dir + 'events', {
expose: 'events'
});
b.require(opts.dir + 'buffers', {
expose: 'buffers'
});
Expand Down
39,769 changes: 407 additions & 39,362 deletions browser/bundle.js

Large diffs are not rendered by default.

29 changes: 29 additions & 0 deletions examples/NetworkMonitor.js
@@ -0,0 +1,29 @@
'use strict';

var run = function() {
// Replace '../bitcore' with 'bitcore' if you use this code elsewhere.
var bitcore = require('../bitcore');
var NetworkMonitor = bitcore.NetworkMonitor;

var config = {
networkName: 'testnet',
host: 'localhost',
port: 18333
};


var nm = new NetworkMonitor.create(config);
// monitor incoming transactions to http://tpfaucet.appspot.com/ donation address
nm.incoming('msj42CCGruhRsFrGATiUuh25dtxYtnpbTx', function(tx) {
console.log('Donation to tpfaucet! '+JSON.stringify(tx.getStandardizedObject()));
});

// connect to bitcoin network and start listening
nm.start();

};

module.exports.run = run;
if (require.main === module) {
run();
}
29 changes: 28 additions & 1 deletion lib/Address.js
Expand Up @@ -96,7 +96,7 @@ Address.fromScript = function(script, network) {
return new Address(version, hash);
};

//extract and address from scriptPubKey
//extract an address from scriptPubKey
Address.fromScriptPubKey = function(scriptPubKey, network) {

if (typeof scriptPubKey === 'string') {
Expand Down Expand Up @@ -182,5 +182,32 @@ Address.prototype.getScriptPubKey = function() {
return script;
};

Address.fromPubkeyHashScriptSig = function(scriptSig, network) {
return Address.fromPubKey(scriptSig.chunks[1], network);
};

//extract an address from scriptSig
Address.fromScriptSig = function(scriptSig, network) {
if (typeof scriptSig === 'string') {
scriptSig = new Script(new Buffer(scriptSig, 'hex'));
}
if (!network)
network = 'livenet';

var payload = scriptSig.chunks;
if (scriptSig.chunks.length === 2)
return Address.fromPubkeyHashScriptSig(scriptSig, network);
// TODO: support other scriptSig types
return null;
};

Address.getScriptPubKeyFor = function(s) {
return new Address(s).getScriptPubKey();
};

Address.validate = function(s) {
return new Address(s).isValid();
};


module.exports = Address;
2 changes: 1 addition & 1 deletion lib/Connection.js
Expand Up @@ -18,6 +18,7 @@ var doubleSha256 = util.twoSha256;
var SecureRandom = require('./SecureRandom');
var nonce = SecureRandom.getPseudoRandomBuffer(8);
var nodeUtil = require('util');
var EventEmitter = require('events').EventEmitter;

var BIP0031_VERSION = 60000;

Expand Down Expand Up @@ -59,7 +60,6 @@ function Connection(socket, peer, opts) {

this.setupHandlers();
}
var EventEmitter = require('events').EventEmitter;
nodeUtil.inherits(Connection, EventEmitter);
Connection.prototype.open = function(callback) {
if (typeof callback === 'function') this.once('connect', callback);
Expand Down
82 changes: 82 additions & 0 deletions lib/NetworkMonitor.js
@@ -0,0 +1,82 @@
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.networkName = peerman.config.network;
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;
self.emit('tx', tx);

var from = tx.getSendingAddresses(self.networkName);
for (var i = 0; i < from.length; i++) {
var addr = from[i];
self.emit('out:'+addr, tx);
}
var to = tx.getReceivingAddresses(self.networkName);
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;
27 changes: 26 additions & 1 deletion lib/Transaction.js
Expand Up @@ -10,7 +10,6 @@ var Parser = require('../util/BinaryParser');
var Step = require('step');
var buffertools = require('buffertools');
var error = require('../util/error');
var networks = require('../networks');
var WalletKey = require('./WalletKey');
var PrivateKey = require('./PrivateKey');

Expand Down Expand Up @@ -621,5 +620,31 @@ Transaction.prototype.isComplete = function() {
return ret;
};

Transaction.prototype.getReceivingAddresses = function(networkName) {
if (!networkName) networkName = 'livenet';
ret = [];
for (var i = 0; i<this.outs.length; i++) {
var o = this.outs[i];
var addr = Address.fromScriptPubKey(o.getScript(), networkName)[0].toString();
ret.push(addr);
}
return ret;
};
Transaction.prototype.getSendingAddresses = function(networkName) {
var ret = [];
if (!networkName) networkName = 'livenet';
for (var i = 0; i<this.ins.length; i++) {
var input = this.ins[i];
var scriptSig = input.getScript();
if (scriptSig.getBuffer().length === 0) {
ret.push(null);
continue;
}
var addr = Address.fromScriptSig(scriptSig, networkName);
ret.push(addr?addr.toString():null);
}
return ret;
};


module.exports = Transaction;
5 changes: 4 additions & 1 deletion lib/TransactionBuilder.js
Expand Up @@ -433,7 +433,9 @@ TransactionBuilder._mapKeys = function(keys) {
} else {
throw new Error('argument must be an array of strings (WIF format) or WalletKey objects');
}
walletKeyMap[wk.storeObj().addr] = wk;
var addr = wk.storeObj().addr;
walletKeyMap[addr] = wk;

}
return walletKeyMap;
};
Expand Down Expand Up @@ -751,6 +753,7 @@ TransactionBuilder.prototype.sign = function(keys) {
ins = tx.ins,
l = ins.length,
walletKeyMap = TransactionBuilder._mapKeys(keys);


for (var i = 0; i < l; i++) {
var input = this.inputMap[i];
Expand Down
6 changes: 5 additions & 1 deletion package.json
Expand Up @@ -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",
Expand All @@ -111,5 +112,8 @@
"license": "MIT",
"engines": {
"node": ">=0.10"
},
"devDependencies": {
"sinon": "^1.10.3"
}
}
2 changes: 2 additions & 0 deletions test/index.html
Expand Up @@ -10,6 +10,7 @@
<div id="mocha"></div>
<script src="../node_modules/mocha/mocha.js"></script>
<script src="../node_modules/chai/chai.js"></script>
<script src="../node_modules/sinon/pkg/sinon.js"></script>
<script>mocha.setup('bdd')</script>
<script src="../browser/bundle.js"></script>
<script src="../browser/testdata.js"></script>
Expand All @@ -31,6 +32,7 @@
<script src="test.main.js"></script>
<script src="test.Message.js"></script>
<script src="test.misc.js"></script>
<script src="test.NetworkMonitor.js"></script>
<script src="test.Opcode.js"></script>
<script src="test.PayPro.js"></script>
<script src="test.Peer.js"></script>
Expand Down
2 changes: 2 additions & 0 deletions test/test.Address.js
Expand Up @@ -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
});
});
Expand Down Expand Up @@ -212,6 +213,7 @@ describe('Address', function() {
var d = data[i];
var b = new Address(d[1]).getScriptPubKey().getBuffer();
b.toString('hex').should.equal(d[0]);
Address.getScriptPubKeyFor(d[1]).getBuffer().toString('hex').should.equal(d[0]);
}
});
});
Expand Down

0 comments on commit 0bcdb7c

Please sign in to comment.