diff --git a/integration/bitcoind.js b/integration/bitcoind.js index 5ba5634..279141c 100644 --- a/integration/bitcoind.js +++ b/integration/bitcoind.js @@ -39,7 +39,7 @@ var txHash = { describe('Integration with ' + network.name + ' bitcoind', function() { this.timeout(15000); - it.only('handshakes', function(cb) { + it('handshakes', function(cb) { var peer = new Peer('localhost', network); peer.once('version', function(m) { m.version.should.be.above(70000); @@ -84,11 +84,9 @@ describe('Integration with ' + network.name + ' bitcoind', function() { }); }); }); - it.only('handles addr', function(cb) { + it('handles addr', function(cb) { connect(function(peer) { peer.once('addr', function(message) { - console.log(message.serialize(network).toString('hex')); - console.log(message.getPayload().toString('hex')); message.addresses.forEach(function(address) { // console.log(address.ip.v4 + ':' + address.port); (address.time instanceof Date).should.equal(true); diff --git a/lib/messages.js b/lib/messages.js index 1ae678e..90d883c 100644 --- a/lib/messages.js +++ b/lib/messages.js @@ -254,28 +254,17 @@ Version.prototype.fromBuffer = function(payload) { */ this.relay = !!parser.readUInt8(); - console.log(this); $.checkState(parser.finished()); return this; }; -Version.writeAddr = function(addr, parser) { - if (_.isUndefined(addr)) { - parser.pad(26); - return; - } - parser.word64le(addr.services); - parser.put(addr.ip); - parser.word16be(addr.port); -}; - Version.prototype.getPayload = function() { var put = new Put(); put.word32le(this.version); put.word64le(1); // services put.word64le(Math.round(new Date().getTime() / 1000)); // timestamp - Version.writeAddr(this.addr_me, put); - Version.writeAddr(this.addr_you, put); + Addresses.writeAddr(this.addr_me, put); + Addresses.writeAddr(this.addr_you, put); put.put(this.nonce); put.varint(this.subversion.length); put.put(new Buffer(this.subversion, 'ascii')); @@ -475,26 +464,58 @@ function Addresses(addresses) { } util.inherits(Addresses, Message); +Addresses.writeAddr = function(addr, put) { + if (_.isUndefined(addr)) { + put.pad(26); + return; + } + put.word64le(addr.services); + Addresses.writeIP(addr.ip, put); + put.word16be(addr.port); +}; + +Addresses.writeIP = function(ip, put) { + $.checkArgument(ip.v6, 'Need ipv6 to write IP'); + var words = ip.v6.split(':').map(function(s) { + return new Buffer(s, 'hex'); + }); + for (var i = 0; i < words.length; i++) { + var word = words[i]; + put.put(word); + } +}; + +// http://en.wikipedia.org/wiki/IPv6#IPv4-mapped_IPv6_addresses Addresses.parseIP = function(parser) { - // parse the ipv6 to a string var ipv6 = []; - for (var a = 0; a < 6; a++) { - ipv6.push(parser.read(2).toString('hex')); + var ipv4 = []; + for (var a = 0; a < 8; a++) { + var word = parser.read(2); + ipv6.push(word.toString('hex')); + if (a >= 6) { + ipv4.push(word[0]); + ipv4.push(word[1]); + } } ipv6 = ipv6.join(':'); - - // parse the ipv4 to a string - var ipv4 = []; - for (var b = 0; b < 4; b++) { - ipv4.push(parser.read(1)[0]); - } ipv4 = ipv4.join('.'); + return { v6: ipv6, v4: ipv4 }; }; +Addresses.parseAddr = function(parser) { + var services = parser.readUInt64LEBN(); + var ip = Addresses.parseIP(parser); + var port = parser.readUInt16BE(); + return { + services: services, + ip: ip, + port: port + }; +}; Addresses.prototype.fromBuffer = function(payload) { var parser = new BufferReader(payload); @@ -503,18 +524,12 @@ Addresses.prototype.fromBuffer = function(payload) { this.addresses = []; for (var i = 0; i < addrCount; i++) { // TODO: Time actually depends on the version of the other peer (>=31402) - var time = new Date(parser.readUInt32LE() * 1000); - var services = parser.readUInt64LEBN(); - var ip = Addresses.parseIP(parser); - var port = parser.readUInt16BE(); - this.addresses.push({ - time: time, - services: services, - ip: ip, - port: port - }); + var addr = Addresses.parseAddr(parser); + addr.time = time; + + this.addresses.push(addr); } $.checkState(parser.finished()); @@ -526,10 +541,10 @@ Addresses.prototype.getPayload = function() { put.varint(this.addresses.length); for (var i = 0; i < this.addresses.length; i++) { - put.word32le(this.addresses[i].time); - put.word64le(this.addresses[i].services); - put.put(this.addresses[i].ip); - put.word16be(this.addresses[i].port); + var addr = this.addresses[i]; + put.word32le(addr.time); + Addresses.writeAddr(addr, put); + break; } return put.buffer();