peer: refactor.

This commit is contained in:
Christopher Jeffrey 2016-09-16 18:18:34 -07:00
parent 757aeb84c0
commit eb5d0cf972
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
7 changed files with 298 additions and 127 deletions

View File

@ -321,6 +321,16 @@ function BIP151(cipher) {
utils.inherits(BIP151, EventEmitter); utils.inherits(BIP151, EventEmitter);
/**
* Emit an error.
* @param {...String} msg
*/
BIP151.prototype.error = function error() {
var msg = utils.fmt.apply(utils, arguments);
this.emit('error', new Error(msg));
};
/** /**
* Test whether handshake has completed. * Test whether handshake has completed.
* @returns {Boolean} * @returns {Boolean}
@ -608,7 +618,7 @@ BIP151.prototype.parse = function parse(data) {
// varinti-clen(1) string-cmd(1) uint32-size(4) data(0) // varinti-clen(1) string-cmd(1) uint32-size(4) data(0)
if (size < 6 || size > constants.MAX_MESSAGE * 3) { if (size < 6 || size > constants.MAX_MESSAGE * 3) {
this.waiting = 4; this.waiting = 4;
this.emit('error', new Error('Bad packet size.')); this.error('Bad packet size.');
return; return;
} }
@ -632,7 +642,7 @@ BIP151.prototype.parse = function parse(data) {
if (!this.input.verify(tag)) { if (!this.input.verify(tag)) {
this.input.sequence(); this.input.sequence();
this.emit('error', new Error('Bad tag.')); this.error('Bad tag.');
return; return;
} }

View File

@ -125,7 +125,15 @@ CompactBlock.fromRaw = function fromRaw(data, enc) {
return new CompactBlock().fromRaw(data); return new CompactBlock().fromRaw(data);
}; };
CompactBlock.prototype.toRaw = function toRaw(witness, writer) { CompactBlock.prototype.toRaw = function toRaw(writer) {
return this.frame(true, writer);
};
CompactBlock.prototype.toNormal = function toNormal(writer) {
return this.frame(false, writer);
};
CompactBlock.prototype.frame = function frame(witness, writer) {
var p = bcoin.writer(writer); var p = bcoin.writer(writer);
var i, id, lo, hi, ptx; var i, id, lo, hi, ptx;
@ -530,7 +538,15 @@ TXResponse.fromBlock = function fromBlock(block, req) {
return new TXResponse().fromBlock(block, req); return new TXResponse().fromBlock(block, req);
}; };
TXResponse.prototype.toRaw = function toRaw(witness, writer) { TXResponse.prototype.toRaw = function toRaw(writer) {
return this.frame(true, writer);
};
TXResponse.prototype.toNormal = function toNormal(writer) {
return this.frame(false, writer);
};
TXResponse.prototype.frame = function frame(witness, writer) {
var p = bcoin.writer(writer); var p = bcoin.writer(writer);
var i, tx; var i, tx;

View File

@ -353,7 +353,7 @@ VerackPacket.fromRaw = function fromRaw(data, enc) {
* @exports PingPacket * @exports PingPacket
* @constructor * @constructor
* @param {BN?} nonce * @param {BN?} nonce
* @property {BN} nonce * @property {BN|null} nonce
*/ */
function PingPacket(nonce) { function PingPacket(nonce) {
@ -362,7 +362,7 @@ function PingPacket(nonce) {
Packet.call(this); Packet.call(this);
this.nonce = nonce || new bn(0); this.nonce = nonce || null;
} }
utils.inherits(PingPacket, Packet); utils.inherits(PingPacket, Packet);
@ -378,7 +378,8 @@ PingPacket.prototype.type = exports.types.PING;
PingPacket.prototype.toRaw = function toRaw(writer) { PingPacket.prototype.toRaw = function toRaw(writer) {
var p = bcoin.writer(writer); var p = bcoin.writer(writer);
p.writeU64(this.nonce); if (this.nonce)
p.writeU64(this.nonce);
if (!writer) if (!writer)
p = p.render(); p = p.render();
@ -394,7 +395,8 @@ PingPacket.prototype.toRaw = function toRaw(writer) {
PingPacket.prototype.fromRaw = function fromRaw(data) { PingPacket.prototype.fromRaw = function fromRaw(data) {
var p = bcoin.reader(data); var p = bcoin.reader(data);
this.nonce = p.readU64(); if (p.left() >= 8)
this.nonce = p.readU64();
return this; return this;
}; };
@ -1702,7 +1704,7 @@ FilterLoadPacket.prototype.fromRaw = function fromRaw(data) {
*/ */
FilterLoadPacket.prototype.fromFilter = function fromFilter(filter) { FilterLoadPacket.prototype.fromFilter = function fromFilter(filter) {
this.filter = filter; this.filter = filter.filter;
this.n = filter.n; this.n = filter.n;
this.tweak = filter.tweak; this.tweak = filter.tweak;
this.update = filter.update; this.update = filter.update;
@ -2376,7 +2378,9 @@ CmpctBlockPacket.prototype.type = exports.types.CMPCTBLOCK;
*/ */
CmpctBlockPacket.prototype.toRaw = function toRaw(writer) { CmpctBlockPacket.prototype.toRaw = function toRaw(writer) {
return this.block.toRaw(this.witness, writer); if (this.witness)
return this.block.toRaw(writer);
return this.block.toNormal(writer);
}; };
/** /**
@ -2489,7 +2493,9 @@ BlockTxnPacket.prototype.type = exports.types.BLOCKTXN;
*/ */
BlockTxnPacket.prototype.toRaw = function toRaw(writer) { BlockTxnPacket.prototype.toRaw = function toRaw(writer) {
return this.response.toRaw(this.witness, writer); if (this.witness)
return this.response.toRaw(writer);
return this.response.toNormal(writer);
}; };
/** /**

View File

@ -72,11 +72,12 @@ Parser.prototype._init = function _init(str) {
/** /**
* Emit an error. * Emit an error.
* @private * @private
* @param {String} str * @param {...String} msg
*/ */
Parser.prototype.error = function error(str) { Parser.prototype.error = function error() {
this.emit('error', new Error(str)); var msg = utils.fmt.apply(utils, arguments);
this.emit('error', new Error(msg));
}; };
/** /**
@ -135,7 +136,9 @@ Parser.prototype.parse = function parse(data) {
if (checksum !== this.header.checksum) { if (checksum !== this.header.checksum) {
this.waiting = 24; this.waiting = 24;
this.header = null; this.header = null;
return this.error('Invalid checksum'); return this.error(
'Invalid checksum: %d != %d',
checksum, this.header.checksum);
} }
try { try {
@ -164,13 +167,13 @@ Parser.prototype.parseHeader = function parseHeader(data) {
magic = data.readUInt32LE(0, true); magic = data.readUInt32LE(0, true);
if (magic !== this.network.magic) if (magic !== this.network.magic)
return this.error('Invalid magic value: ' + magic.toString(16)); return this.error('Invalid magic value: %s.', magic.toString(16));
// Count length of the cmd // Count length of the cmd
for (i = 0; data[i + 4] !== 0 && i < 12; i++); for (i = 0; data[i + 4] !== 0 && i < 12; i++);
if (i === 12) if (i === 12)
return this.error('Not NULL-terminated cmd'); return this.error('Non NULL-terminated command.');
cmd = data.toString('ascii', 4, 4 + i); cmd = data.toString('ascii', 4, 4 + i);
@ -178,7 +181,7 @@ Parser.prototype.parseHeader = function parseHeader(data) {
if (size > constants.MAX_MESSAGE) { if (size > constants.MAX_MESSAGE) {
this.waiting = 24; this.waiting = 24;
return this.error('Packet length too large: %dmb', utils.mb(size)); return this.error('Packet length too large: %dmb.', utils.mb(size));
} }
checksum = data.readUInt32LE(20, true); checksum = data.readUInt32LE(20, true);

View File

@ -400,7 +400,7 @@ Peer.prototype._onAck = function _onAck(err) {
} }
// Find some more peers. // Find some more peers.
this.write(new packets.GetAddrPacket()); this.send(new packets.GetAddrPacket());
// Relay our spv filter if we have one. // Relay our spv filter if we have one.
this.updateWatch(); this.updateWatch();
@ -595,15 +595,6 @@ Peer.prototype.sendHeaders = function sendHeaders(items) {
} }
}; };
/**
* Send a packet.
* @param {Packet} packet
*/
Peer.prototype.send = function send(packet) {
this.write(this.framer.packet(packet.cmd, packet.toRaw()));
};
/** /**
* Send a `version` packet. * Send a `version` packet.
*/ */
@ -736,31 +727,62 @@ Peer.prototype.destroy = function destroy() {
/** /**
* Write data to the peer's socket. * Write data to the peer's socket.
* @param {Buffer} chunk * @param {Buffer} data
* @returns {Boolean} * @returns {Boolean}
*/ */
Peer.prototype.write = function write(chunk) { Peer.prototype.write = function write(data) {
if (this.destroyed) if (this.destroyed)
return false; return false;
this.lastSend = utils.ms(); this.lastSend = utils.ms();
return this.socket.write(chunk); return this.socket.write(data);
};
/**
* Send a packet.
* @param {Packet} packet
*/
Peer.prototype.send = function send(packet) {
var checksum;
// Used cached hashes as the
// packet checksum for speed.
if (packet.type === packetTypes.TX) {
checksum = packet.witness
? packet.tx.witnessHash()
: packet.tx.hash();
}
this.write(this.framer.packet(packet.cmd, packet.toRaw(), checksum));
}; };
/** /**
* Emit an error and destroy the peer. * Emit an error and destroy the peer.
* @private * @private
* @param {String|Error} err * @param {...String|Error} err
*/ */
Peer.prototype.error = function error(err, keep) { Peer.prototype.error = function error(err, keep) {
var i, args, msg;
if (this.destroyed) if (this.destroyed)
return; return;
if (typeof err === 'string') if (typeof err === 'string') {
err = new Error(err); args = new Array(arguments.length);
for (i = 0; i < args.length; i++)
args[i] = arguments[i];
if (typeof args[args.length - 1] === 'boolean')
keep = args.pop();
msg = utils.fmt.apply(utils, args);
err = new Error(msg);
}
err.message += ' (' + this.hostname + ')'; err.message += ' (' + this.hostname + ')';
@ -859,10 +881,12 @@ Peer.prototype.getData = function getData(items) {
/** /**
* Handle a packet payload. * Handle a packet payload.
* @private * @private
* @param {Object} packet * @param {Packet} packet
*/ */
Peer.prototype._onPacket = function onPacket(packet) { Peer.prototype._onPacket = function onPacket(packet) {
this.lastRecv = utils.ms();
if (this.bip151 if (this.bip151
&& !this.bip151.completed && !this.bip151.completed
&& packet.type !== packetTypes.ENCINIT && packet.type !== packetTypes.ENCINIT
@ -878,17 +902,16 @@ Peer.prototype._onPacket = function onPacket(packet) {
this.bip150.complete(new Error('Message before auth.')); this.bip150.complete(new Error('Message before auth.'));
} }
if (this.lastBlock && packet.type !== packetTypes.TX) if (this.lastBlock) {
this._flushMerkle(); if (packet.type !== packetTypes.TX)
this._flushMerkle();
this.lastRecv = utils.ms(); }
switch (packet.type) { switch (packet.type) {
case packetTypes.VERSION: case packetTypes.VERSION:
return this._handleVersion(packet); return this._handleVersion(packet);
case packetTypes.VERACK: case packetTypes.VERACK:
this.fire(packet.cmd); return this._handleVerack(packet);
break;
case packetTypes.PING: case packetTypes.PING:
return this._handlePing(packet); return this._handlePing(packet);
case packetTypes.PONG: case packetTypes.PONG:
@ -896,7 +919,7 @@ Peer.prototype._onPacket = function onPacket(packet) {
case packetTypes.ALERT: case packetTypes.ALERT:
return this._handleAlert(packet); return this._handleAlert(packet);
case packetTypes.GETADDR: case packetTypes.GETADDR:
return this._handleGetAddr(); return this._handleGetAddr(packet);
case packetTypes.ADDR: case packetTypes.ADDR:
return this._handleAddr(packet); return this._handleAddr(packet);
case packetTypes.INV: case packetTypes.INV:
@ -904,8 +927,7 @@ Peer.prototype._onPacket = function onPacket(packet) {
case packetTypes.GETDATA: case packetTypes.GETDATA:
return this._handleGetData(packet); return this._handleGetData(packet);
case packetTypes.NOTFOUND: case packetTypes.NOTFOUND:
this.fire(packet.cmd, packet.items); return this._handleNotFound(packet);
break;
case packetTypes.GETBLOCKS: case packetTypes.GETBLOCKS:
return this._handleGetBlocks(packet); return this._handleGetBlocks(packet);
case packetTypes.GETHEADERS: case packetTypes.GETHEADERS:
@ -913,48 +935,29 @@ Peer.prototype._onPacket = function onPacket(packet) {
case packetTypes.HEADERS: case packetTypes.HEADERS:
return this._handleHeaders(packet); return this._handleHeaders(packet);
case packetTypes.SENDHEADERS: case packetTypes.SENDHEADERS:
this.preferHeaders = true; return this._handleSendHeaders(packet);
this.fire(packet.cmd);
break;
case packetTypes.BLOCK: case packetTypes.BLOCK:
this.fire(packet.cmd, packet.block); return this._handleBlock(packet);
break;
case packetTypes.TX: case packetTypes.TX:
if (this.lastBlock) { return this._handleTX(packet);
if (this.lastBlock.hasTX(packet.tx)) {
this.lastBlock.addTX(packet.tx);
if (--this.waiting === 0)
this._flushMerkle();
break;
}
}
this.fire(packet.cmd, packet.tx);
break;
case packetTypes.REJECT: case packetTypes.REJECT:
return this._handleReject(packet); return this._handleReject(packet);
case packetTypes.MEMPOOL: case packetTypes.MEMPOOL:
return this._handleMempool(); return this._handleMempool(packet);
case packetTypes.FILTERLOAD: case packetTypes.FILTERLOAD:
return this._handleFilterLoad(packet); return this._handleFilterLoad(packet);
case packetTypes.FILTERADD: case packetTypes.FILTERADD:
return this._handleFilterAdd(packet); return this._handleFilterAdd(packet);
case packetTypes.FILTERCLEAR: case packetTypes.FILTERCLEAR:
return this._handleFilterClear(); return this._handleFilterClear(packet);
case packetTypes.MERKLEBLOCK: case packetTypes.MERKLEBLOCK:
packet.block.verifyPartial(); return this._handleMerkleBlock(packet);
this.lastBlock = packet.block;
this.waiting = packet.block.matches.length;
if (this.waiting === 0)
this._flushMerkle();
break;
case packetTypes.GETUTXOS: case packetTypes.GETUTXOS:
return this._handleGetUTXOs(packet); return this._handleGetUTXOs(packet);
case packetTypes.UTXOS: case packetTypes.UTXOS:
return this._handleUTXOs(packet); return this._handleUTXOs(packet);
case packetTypes.HAVEWITNESS: case packetTypes.HAVEWITNESS:
this.haveWitness = true; return this._handleHaveWitness(packet);
this.fire(packet.cmd);
break;
case packetTypes.FEEFILTER: case packetTypes.FEEFILTER:
return this._handleFeeFilter(packet); return this._handleFeeFilter(packet);
case packetTypes.SENDCMPCT: case packetTypes.SENDCMPCT:
@ -976,7 +979,9 @@ Peer.prototype._onPacket = function onPacket(packet) {
case packetTypes.AUTHPROPOSE: case packetTypes.AUTHPROPOSE:
return this._handleAuthPropose(packet); return this._handleAuthPropose(packet);
case packetTypes.UNKNOWN: case packetTypes.UNKNOWN:
this.logger.warning('Unknown packet: %s.', packet.cmd); return this._handleUnknown(packet);
default:
assert(false, 'Bad packet type.');
break; break;
} }
}; };
@ -1008,7 +1013,7 @@ Peer.prototype.fire = function fire(cmd, payload) {
/** /**
* Handle `filterload` packet. * Handle `filterload` packet.
* @private * @private
* @param {Object} * @param {FilterLoadPacket}
*/ */
Peer.prototype._handleFilterLoad = function _handleFilterLoad(packet) { Peer.prototype._handleFilterLoad = function _handleFilterLoad(packet) {
@ -1024,7 +1029,7 @@ Peer.prototype._handleFilterLoad = function _handleFilterLoad(packet) {
/** /**
* Handle `filteradd` packet. * Handle `filteradd` packet.
* @private * @private
* @param {Object} * @param {FilterAddPacket}
*/ */
Peer.prototype._handleFilterAdd = function _handleFilterAdd(packet) { Peer.prototype._handleFilterAdd = function _handleFilterAdd(packet) {
@ -1044,20 +1049,38 @@ Peer.prototype._handleFilterAdd = function _handleFilterAdd(packet) {
/** /**
* Handle `filterclear` packet. * Handle `filterclear` packet.
* @private * @private
* @param {Object} * @param {FilterClearPacket}
*/ */
Peer.prototype._handleFilterClear = function _handleFilterClear() { Peer.prototype._handleFilterClear = function _handleFilterClear(packet) {
if (this.spvFilter) if (this.spvFilter)
this.spvFilter.reset(); this.spvFilter.reset();
this.relay = true; this.relay = true;
}; };
/**
* Handle `merkleblock` packet.
* @private
* @param {MerkleBlockPacket}
*/
Peer.prototype._handleMerkleBlock = function _handleMerkleBlock(packet) {
var block = packet.block;
block.verifyPartial();
this.lastBlock = block;
this.waiting = block.matches.length;
if (this.waiting === 0)
this._flushMerkle();
};
/** /**
* Handle `feefilter` packet. * Handle `feefilter` packet.
* @private * @private
* @param {Object} * @param {FeeFilterPacket}
*/ */
Peer.prototype._handleFeeFilter = function _handleFeeFilter(packet) { Peer.prototype._handleFeeFilter = function _handleFeeFilter(packet) {
@ -1076,7 +1099,7 @@ Peer.prototype._handleFeeFilter = function _handleFeeFilter(packet) {
/** /**
* Handle `utxos` packet. * Handle `utxos` packet.
* @private * @private
* @param {Object} * @param {UTXOsPacket}
*/ */
Peer.prototype._handleUTXOs = function _handleUTXOs(utxos) { Peer.prototype._handleUTXOs = function _handleUTXOs(utxos) {
@ -1090,9 +1113,9 @@ Peer.prototype._handleUTXOs = function _handleUTXOs(utxos) {
* @private * @private
*/ */
Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) { Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(packet) {
var self = this; var self = this;
var unlock = this._lock(_handleGetUTXOs, [payload, utils.nop]); var unlock = this._lock(_handleGetUTXOs, [packet, utils.nop]);
var utxos; var utxos;
if (!unlock) if (!unlock)
@ -1115,17 +1138,17 @@ Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
if (this.chain.db.options.spv) if (this.chain.db.options.spv)
return done(); return done();
if (payload.prevout.length > 15) if (packet.prevout.length > 15)
return done(); return done();
utxos = new packets.GetUTXOsPacket(); utxos = new packets.GetUTXOsPacket();
utils.forEachSerial(payload.prevout, function(prevout, next) { utils.forEachSerial(packet.prevout, function(prevout, next) {
var hash = prevout.hash; var hash = prevout.hash;
var index = prevout.index; var index = prevout.index;
var coin; var coin;
if (self.mempool && payload.mempool) { if (self.mempool && packet.mempool) {
coin = self.mempool.getCoin(hash, index); coin = self.mempool.getCoin(hash, index);
if (coin) { if (coin) {
@ -1161,22 +1184,33 @@ Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
utxos.height = self.chain.height; utxos.height = self.chain.height;
utxos.tip = self.chain.tip.hash; utxos.tip = self.chain.tip.hash;
self.send(new packets.UTXOsPacket(utxos)); self.send(utxos);
done(); done();
}); });
}; };
/** /**
* Handle `getheaders` packet. * Handle `havewitness` packet.
* @private * @private
* @param {Object} * @param {HaveWitnessPacket}
*/ */
Peer.prototype._handleGetHeaders = function _handleGetHeaders(payload) { Peer.prototype._handleHaveWitness = function _handleHaveWitness(packet) {
this.haveWitness = true;
this.fire('havewitness');
};
/**
* Handle `getheaders` packet.
* @private
* @param {GetHeadersPacket}
*/
Peer.prototype._handleGetHeaders = function _handleGetHeaders(packet) {
var self = this; var self = this;
var headers = []; var headers = [];
var unlock = this._lock(_handleGetHeaders, [payload, utils.nop]); var unlock = this._lock(_handleGetHeaders, [packet, utils.nop]);
if (!unlock) if (!unlock)
return; return;
@ -1228,7 +1262,7 @@ Peer.prototype._handleGetHeaders = function _handleGetHeaders(payload) {
if (headers.length === 2000) if (headers.length === 2000)
return done(); return done();
if (entry.hash === payload.stop) if (entry.hash === packet.stop)
return done(); return done();
entry.getNext(next); entry.getNext(next);
@ -1236,10 +1270,10 @@ Peer.prototype._handleGetHeaders = function _handleGetHeaders(payload) {
}); });
} }
if (payload.locator.length === 0) if (packet.locator.length === 0)
return collect(null, payload.stop); return collect(null, packet.stop);
this.chain.findLocator(payload.locator, function(err, hash) { this.chain.findLocator(packet.locator, function(err, hash) {
if (err) if (err)
return collect(err); return collect(err);
@ -1253,13 +1287,13 @@ Peer.prototype._handleGetHeaders = function _handleGetHeaders(payload) {
/** /**
* Handle `getblocks` packet. * Handle `getblocks` packet.
* @private * @private
* @param {Object} * @param {GetBlocksPacket}
*/ */
Peer.prototype._handleGetBlocks = function _handleGetBlocks(payload) { Peer.prototype._handleGetBlocks = function _handleGetBlocks(packet) {
var self = this; var self = this;
var blocks = []; var blocks = [];
var unlock = this._lock(_handleGetBlocks, [payload, utils.nop]); var unlock = this._lock(_handleGetBlocks, [packet, utils.nop]);
if (!unlock) if (!unlock)
return; return;
@ -1285,7 +1319,7 @@ Peer.prototype._handleGetBlocks = function _handleGetBlocks(payload) {
if (this.chain.db.options.prune) if (this.chain.db.options.prune)
return done(); return done();
this.chain.findLocator(payload.locator, function(err, tip) { this.chain.findLocator(packet.locator, function(err, tip) {
if (err) if (err)
return done(err); return done(err);
@ -1302,7 +1336,7 @@ Peer.prototype._handleGetBlocks = function _handleGetBlocks(payload) {
blocks.push(new InvItem(constants.inv.BLOCK, hash)); blocks.push(new InvItem(constants.inv.BLOCK, hash));
if (hash === payload.stop) if (hash === packet.stop)
return done(); return done();
if (blocks.length === 500) { if (blocks.length === 500) {
@ -1319,7 +1353,7 @@ Peer.prototype._handleGetBlocks = function _handleGetBlocks(payload) {
/** /**
* Handle `version` packet. * Handle `version` packet.
* @private * @private
* @param {Object} * @param {VersionPacket}
*/ */
Peer.prototype._handleVersion = function _handleVersion(version) { Peer.prototype._handleVersion = function _handleVersion(version) {
@ -1370,15 +1404,27 @@ Peer.prototype._handleVersion = function _handleVersion(version) {
this.ignore(); this.ignore();
return; return;
} }
this.request('havewitness', function(err) { return this.request('havewitness', function(err) {
if (err) { if (err) {
self.error('Peer does not support segregated witness.'); self.error('Peer does not support segregated witness.');
self.ignore(); self.ignore();
return;
} }
self._finishVersion(version);
}); });
} }
} }
this._finishVersion(version);
};
/**
* Finish handling `version` packet.
* @private
* @param {VersionPacket}
*/
Peer.prototype._finishVersion = function _finishVersion(version) {
if (version.hasWitness()) if (version.hasWitness())
this.haveWitness = true; this.haveWitness = true;
@ -1391,16 +1437,26 @@ Peer.prototype._handleVersion = function _handleVersion(version) {
}; };
/** /**
* Handle `mempool` packet. * Handle `verack` packet.
* @private * @private
* @param {Object} * @param {VerackPacket}
*/ */
Peer.prototype._handleMempool = function _handleMempool() { Peer.prototype._handleVerack = function _handleVerack(packet) {
this.fire('verack');
};
/**
* Handle `mempool` packet.
* @private
* @param {MempoolPacket}
*/
Peer.prototype._handleMempool = function _handleMempool(packet) {
var self = this; var self = this;
var items = []; var items = [];
var i, hashes; var i, hashes;
var unlock = this._lock(_handleMempool, [utils.nop]); var unlock = this._lock(_handleMempool, [packet, utils.nop]);
if (!unlock) if (!unlock)
return; return;
@ -1485,7 +1541,7 @@ Peer.prototype._getItem = function _getItem(item, callback) {
/** /**
* Handle `getdata` packet. * Handle `getdata` packet.
* @private * @private
* @param {Object} * @param {GetDataPacket}
*/ */
Peer.prototype._handleGetData = function _handleGetData(packet) { Peer.prototype._handleGetData = function _handleGetData(packet) {
@ -1617,10 +1673,20 @@ Peer.prototype._handleGetData = function _handleGetData(packet) {
}); });
}; };
/**
* Handle `notfound` packet.
* @private
* @param {NotFoundPacket}
*/
Peer.prototype._handleNotFound = function _handleNotFound(packet) {
this.fire('notfound', packet.items);
};
/** /**
* Handle `addr` packet. * Handle `addr` packet.
* @private * @private
* @param {Object} * @param {AddrPacket}
*/ */
Peer.prototype._handleAddr = function _handleAddr(packet) { Peer.prototype._handleAddr = function _handleAddr(packet) {
@ -1643,18 +1709,19 @@ Peer.prototype._handleAddr = function _handleAddr(packet) {
/** /**
* Handle `ping` packet. * Handle `ping` packet.
* @private * @private
* @param {Object} * @param {PingPacket}
*/ */
Peer.prototype._handlePing = function _handlePing(packet) { Peer.prototype._handlePing = function _handlePing(packet) {
this.send(new packets.PongPacket(packet.nonce)); if (packet.nonce)
this.send(new packets.PongPacket(packet.nonce));
this.fire('ping', this.minPing); this.fire('ping', this.minPing);
}; };
/** /**
* Handle `pong` packet. * Handle `pong` packet.
* @private * @private
* @param {Object} * @param {PongPacket}
*/ */
Peer.prototype._handlePong = function _handlePong(packet) { Peer.prototype._handlePong = function _handlePong(packet) {
@ -1693,10 +1760,10 @@ Peer.prototype._handlePong = function _handlePong(packet) {
/** /**
* Handle `getaddr` packet. * Handle `getaddr` packet.
* @private * @private
* @param {Object} * @param {GetAddrPacket}
*/ */
Peer.prototype._handleGetAddr = function _handleGetAddr() { Peer.prototype._handleGetAddr = function _handleGetAddr(packet) {
var items = []; var items = [];
var i, addr; var i, addr;
@ -1739,7 +1806,7 @@ Peer.prototype._handleGetAddr = function _handleGetAddr() {
/** /**
* Handle `inv` packet. * Handle `inv` packet.
* @private * @private
* @param {Object} * @param {InvPacket}
*/ */
Peer.prototype._handleInv = function _handleInv(packet) { Peer.prototype._handleInv = function _handleInv(packet) {
@ -1788,22 +1855,66 @@ Peer.prototype._handleInv = function _handleInv(packet) {
/** /**
* Handle `headers` packet. * Handle `headers` packet.
* @private * @private
* @param {Object} * @param {HeadersPacket}
*/ */
Peer.prototype._handleHeaders = function _handleHeaders(packet) { Peer.prototype._handleHeaders = function _handleHeaders(packet) {
var headers = packet.items; var headers = packet.items;
if (headers.length > 2000) { if (headers.length > 2000) {
this.setMisbehavior(100); this.setMisbehavior(100);
return; return;
} }
this.fire('headers', headers); this.fire('headers', headers);
}; };
/**
* Handle `sendheaders` packet.
* @private
* @param {SendHeadersPacket}
*/
Peer.prototype._handleSendHeaders = function _handleSendHeaders(packet) {
this.preferHeaders = true;
this.fire('sendheaders');
};
/**
* Handle `block` packet.
* @private
* @param {BlockPacket}
*/
Peer.prototype._handleBlock = function _handleBlock(packet) {
this.fire('block', packet.block);
};
/**
* Handle `tx` packet.
* @private
* @param {TXPacket}
*/
Peer.prototype._handleTX = function _handleTX(packet) {
var tx = packet.tx;
if (this.lastBlock) {
if (this.lastBlock.hasTX(tx)) {
this.lastBlock.addTX(tx);
if (--this.waiting === 0)
this._flushMerkle();
return;
}
}
this.fire('tx', tx);
};
/** /**
* Handle `reject` packet. * Handle `reject` packet.
* @private * @private
* @param {Object} * @param {RejectPacket}
*/ */
Peer.prototype._handleReject = function _handleReject(details) { Peer.prototype._handleReject = function _handleReject(details) {
@ -1826,7 +1937,7 @@ Peer.prototype._handleReject = function _handleReject(details) {
/** /**
* Handle `alert` packet. * Handle `alert` packet.
* @private * @private
* @param {Object} * @param {AlertPacket}
*/ */
Peer.prototype._handleAlert = function _handleAlert(alert) { Peer.prototype._handleAlert = function _handleAlert(alert) {
@ -1837,7 +1948,7 @@ Peer.prototype._handleAlert = function _handleAlert(alert) {
/** /**
* Handle `encinit` packet. * Handle `encinit` packet.
* @private * @private
* @param {Object} * @param {EncinitPacket}
*/ */
Peer.prototype._handleEncinit = function _handleEncinit(packet) { Peer.prototype._handleEncinit = function _handleEncinit(packet) {
@ -1859,7 +1970,7 @@ Peer.prototype._handleEncinit = function _handleEncinit(packet) {
/** /**
* Handle `encack` packet. * Handle `encack` packet.
* @private * @private
* @param {Object} * @param {EncackPacket}
*/ */
Peer.prototype._handleEncack = function _handleEncack(packet) { Peer.prototype._handleEncack = function _handleEncack(packet) {
@ -1879,7 +1990,7 @@ Peer.prototype._handleEncack = function _handleEncack(packet) {
/** /**
* Handle `authchallenge` packet. * Handle `authchallenge` packet.
* @private * @private
* @param {Object} * @param {AuthChallengePacket}
*/ */
Peer.prototype._handleAuthChallenge = function _handleAuthChallenge(packet) { Peer.prototype._handleAuthChallenge = function _handleAuthChallenge(packet) {
@ -1903,7 +2014,7 @@ Peer.prototype._handleAuthChallenge = function _handleAuthChallenge(packet) {
/** /**
* Handle `authreply` packet. * Handle `authreply` packet.
* @private * @private
* @param {Object} * @param {AuthReplyPacket}
*/ */
Peer.prototype._handleAuthReply = function _handleAuthReply(packet) { Peer.prototype._handleAuthReply = function _handleAuthReply(packet) {
@ -1928,7 +2039,7 @@ Peer.prototype._handleAuthReply = function _handleAuthReply(packet) {
/** /**
* Handle `authpropose` packet. * Handle `authpropose` packet.
* @private * @private
* @param {Object} * @param {AuthProposePacket}
*/ */
Peer.prototype._handleAuthPropose = function _handleAuthPropose(packet) { Peer.prototype._handleAuthPropose = function _handleAuthPropose(packet) {
@ -1949,10 +2060,21 @@ Peer.prototype._handleAuthPropose = function _handleAuthPropose(packet) {
this.fire('authpropose', packet.hash); this.fire('authpropose', packet.hash);
}; };
/**
* Handle an unknown packet.
* @private
* @param {UnknownPacket}
*/
Peer.prototype._handleUnknown = function _handleUnknown(packet) {
this.logger.warning('Unknown packet: %s.', packet.cmd);
this.fire('unknown', packet);
};
/** /**
* Handle `sendcmpct` packet. * Handle `sendcmpct` packet.
* @private * @private
* @param {Object} * @param {SendCmpctPacket}
*/ */
Peer.prototype._handleSendCmpct = function _handleSendCmpct(packet) { Peer.prototype._handleSendCmpct = function _handleSendCmpct(packet) {
@ -1979,7 +2101,7 @@ Peer.prototype._handleSendCmpct = function _handleSendCmpct(packet) {
/** /**
* Handle `cmpctblock` packet. * Handle `cmpctblock` packet.
* @private * @private
* @param {Object} * @param {CmpctBlockPacket}
*/ */
Peer.prototype._handleCmpctBlock = function _handleCmpctBlock(packet) { Peer.prototype._handleCmpctBlock = function _handleCmpctBlock(packet) {
@ -2019,7 +2141,7 @@ Peer.prototype._handleCmpctBlock = function _handleCmpctBlock(packet) {
return; return;
} }
this.send(block.toRequest()); this.send(new packets.GetBlockTxnPacket(block.toRequest()));
this.logger.debug( this.logger.debug(
'Received semi-full compact block %s (%s).', 'Received semi-full compact block %s (%s).',
@ -2036,7 +2158,7 @@ Peer.prototype._handleCmpctBlock = function _handleCmpctBlock(packet) {
/** /**
* Handle `getblocktxn` packet. * Handle `getblocktxn` packet.
* @private * @private
* @param {Object} * @param {GetBlockTxnPacket}
*/ */
Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(packet) { Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(packet) {
@ -2093,7 +2215,7 @@ Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(packet) {
/** /**
* Handle `blocktxn` packet. * Handle `blocktxn` packet.
* @private * @private
* @param {Object} * @param {BlockTxnPacket}
*/ */
Peer.prototype._handleBlockTxn = function _handleBlockTxn(packet) { Peer.prototype._handleBlockTxn = function _handleBlockTxn(packet) {
@ -2120,7 +2242,7 @@ Peer.prototype._handleBlockTxn = function _handleBlockTxn(packet) {
'Filled compact block %s (%s).', 'Filled compact block %s (%s).',
block.rhash, this.hostname); block.rhash, this.hostname);
this.emit('block', block.toBlock()); this.fire('block', block.toBlock());
}; };
/** /**
@ -2216,7 +2338,9 @@ Peer.prototype.sendMempool = function sendMempool() {
/** /**
* Send `reject` to peer. * Send `reject` to peer.
* @param {Object} reject - See {@link Framer.reject}. * @param {Number} code
* @param {String} reason
* @param {TX|Block} obj
*/ */
Peer.prototype.sendReject = function sendReject(code, reason, obj) { Peer.prototype.sendReject = function sendReject(code, reason, obj) {

View File

@ -166,6 +166,15 @@ MemBlock.prototype.toRaw = function toRaw() {
return this.raw; return this.raw;
}; };
/**
* Return serialized block data.
* @returns {Buffer}
*/
MemBlock.prototype.toNormal = function toNormal() {
return this.raw;
};
/** /**
* Parse the serialized block data * Parse the serialized block data
* and create an actual {@link Block}. * and create an actual {@link Block}.

View File

@ -1,6 +1,5 @@
/*! /*!
* packets.js - packets for bcoin * netaddress.js - network address object for bcoin
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
* Copyright (c) 2014-2016, Christopher Jeffrey (MIT License). * Copyright (c) 2014-2016, Christopher Jeffrey (MIT License).
* https://github.com/bcoin-org/bcoin * https://github.com/bcoin-org/bcoin
*/ */
@ -301,4 +300,8 @@ NetworkAddress.prototype.toRaw = function toRaw(full, writer) {
return p; return p;
}; };
/*
* Expose
*/
module.exports = NetworkAddress; module.exports = NetworkAddress;