diff --git a/lib/bcoin/peer.js b/lib/bcoin/peer.js index 63496d2a..14dcf449 100644 --- a/lib/bcoin/peer.js +++ b/lib/bcoin/peer.js @@ -27,6 +27,7 @@ function Peer(pool, createSocket, options) { this.version = null; this.destroyed = false; this.ack = false; + this.ts = null; this.options = options || {}; if (this.options.backoff) { @@ -69,6 +70,9 @@ module.exports = Peer; Peer.prototype._init = function init() { var self = this; + this.socket.once('connect', function() { + self.ts = Date.now() / 1000 | 0; + }); this.socket.once('error', function(err) { self._error(err); }); @@ -99,6 +103,7 @@ Peer.prototype._init = function init() { return self._error(err); self.ack = true; self.emit('ack'); + self.ts = Date.now() / 1000 | 0; }); }; @@ -314,13 +319,19 @@ Peer.prototype._handleGetData = function handleGetData(items) { }; Peer.prototype._handleAddr = function handleAddr(addrs) { + var now = Date.now(); addrs.forEach(function(addr) { + // bitcoind does this for some reason: + if (addr.ts <= 100000000 || addr.ts > now + 10 * 60) + addr.ts = now - 5 * 24 * 60 * 60; this.emit('addr', { - date: new Date(addr.date * 1000), - network: addr.network, - address: addr.ipv4, + date: new Date(addr.ts * 1000), + ts: addr.ts, + service: addr.service, ipv4: addr.ipv4, ipv6: addr.ipv6, + address: addr.ipv4, + address6: addr.ipv6, port: addr.port, host: addr.ipv4 + ':' + addr.port, host6: '[' + addr.ipv6 + ']:' + addr.port @@ -352,7 +363,8 @@ Peer.prototype._handleGetAddr = function handleGetAddr() { return; return { host: peer.socket.remoteAddress, - port: peer.socket.remotePort || 8333 + port: peer.socket.remotePort || 8333, + ts: peer.ts }; }).filter(function(peer) { if (!peer || ~used.indexOf(peer.host)) @@ -366,11 +378,12 @@ Peer.prototype._handleGetAddr = function handleGetAddr() { ipv4: ver === 4 ? ip : '127.0.0.1', ipv6: ver === 6 ? ip : '0000:0000:0000:0000:0000:0000:0000:ffff', port: peer.port, + ts: peer.ts, ver: ver }; }); - peers = peers.map(function(peer) { + var addrs = peers.map(function(peer) { if (peer.ver === 6) { while (peer.ipv6.split(':').length < 8) peer.ipv6 = '0000:' + peer.ipv6; @@ -387,7 +400,7 @@ Peer.prototype._handleGetAddr = function handleGetAddr() { return peer; }).filter(Boolean); - return this._write(this.framer.addr(peers)); + return this._write(this.framer.addr(addrs)); }; Peer.prototype._handleInv = function handleInv(items) { diff --git a/lib/bcoin/protocol/framer.js b/lib/bcoin/protocol/framer.js index 784fe38d..68ddf8bd 100644 --- a/lib/bcoin/protocol/framer.js +++ b/lib/bcoin/protocol/framer.js @@ -327,6 +327,7 @@ Framer.prototype.addr = function addr(peers) { var i = 0; var c = 0; var peer; + var start = (Date.now() / 1000 | 0) - process.uptime(); // count c += varint(p, peers.length, c); @@ -334,8 +335,8 @@ Framer.prototype.addr = function addr(peers) { for (; i < peers.length; i++) { peer = peers[i]; - // date - c += utils.writeU32(p, Date.now() / 1000 | 0, c); + // timestamp + c += utils.writeU32(p, peer.ts || start, c); // NODE_NETWORK service c += utils.writeU64(p, 1, c); diff --git a/lib/bcoin/protocol/parser.js b/lib/bcoin/protocol/parser.js index 69a5f305..929ba87f 100644 --- a/lib/bcoin/protocol/parser.js +++ b/lib/bcoin/protocol/parser.js @@ -356,7 +356,7 @@ Parser.prototype.parseAddr = function parseAddr(p) { return this._error('Invalid addr size'); var addrs = []; - var len, off, count, date, network, ipv4, ipv6, port, i; + var len, off, count, ts, service, ipv4, ipv6, port, i; // count len = readIntv(p, 0); @@ -365,11 +365,11 @@ Parser.prototype.parseAddr = function parseAddr(p) { p = p.slice(off); for (i = 0; i < count; i++) { - // date - LE - date = utils.readU32(p, 0); + // ts - LE + ts = utils.readU32(p, 0); // NODE_NETWORK service - LE - network = utils.readU64(p, 4); + service = utils.readU64(p, 4); // ipv6 - BE ipv6 = utils.toHex(p.slice(12, 24)); @@ -386,8 +386,8 @@ Parser.prototype.parseAddr = function parseAddr(p) { port = utils.readU16BE(p, 28); addrs.push({ - date: date, - network: network, + ts: ts, + service: service, ipv6: ipv6, ipv4: ipv4, port: port diff --git a/test/protocol-test.js b/test/protocol-test.js index 158e59e9..808cce94 100644 --- a/test/protocol-test.js +++ b/test/protocol-test.js @@ -34,12 +34,14 @@ describe('Protocol', function() { { ipv6: '0000:0000:0000:0000:0000:0000:0000:ffff', ipv4: '127.0.0.1', - port: 8333 + port: 8333, + ts: Date.now() / 1000 | 0 }, { ipv6: '0000:0000:0000:0000:0000:7f00:0001:ffff', ipv4: '10.0.0.1', - port: 18333 + port: 18333, + ts: Date.now() / 1000 | 0 } ]; @@ -54,37 +56,18 @@ describe('Protocol', function() { addr._ipv6 = '::' + addr._ipv6.split(':').slice(2).join(':'); }); - packetTest('addr', peers, function(payload) { - // XXX Legacy - if (!parser.parseAddr) { - var addrs = []; - bcoin.peer.prototype._handleAddr.call({ - emit: function(_, obj) { - addrs.push(obj); - } - }, payload); - payload = addrs; - payload.forEach(function(addr) { - addr.date = addr.date.getTime() / 1000 | 0; - delete addr.address; - delete addr.host; - delete addr.host6; - addr.ipv6 = '::' + addr.ipv6; - }); - } - assert.equal(typeof payload.length, 'number'); assert.equal(payload.length, 2); - assert.equal(typeof payload[0].date, 'number'); - assert.equal(payload[0].network, 1); + assert.equal(typeof payload[0].ts, 'number'); + assert.equal(payload[0].service, 1); assert.equal(payload[0].ipv6, peers[0]._ipv6); assert.equal(payload[0].ipv4, peers[0]._ipv4); assert.equal(payload[0].port, peers[0].port); - assert.equal(typeof payload[1].date, 'number'); - assert.equal(payload[1].network, 1); + assert.equal(typeof payload[1].ts, 'number'); + assert.equal(payload[1].service, 1); assert.equal(payload[1].ipv6, peers[1]._ipv6); assert.equal(payload[1].ipv4, peers[1]._ipv4); assert.equal(payload[1].port, peers[1].port);