peer: refactor.
This commit is contained in:
parent
757aeb84c0
commit
eb5d0cf972
@ -321,6 +321,16 @@ function BIP151(cipher) {
|
||||
|
||||
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.
|
||||
* @returns {Boolean}
|
||||
@ -608,7 +618,7 @@ BIP151.prototype.parse = function parse(data) {
|
||||
// varinti-clen(1) string-cmd(1) uint32-size(4) data(0)
|
||||
if (size < 6 || size > constants.MAX_MESSAGE * 3) {
|
||||
this.waiting = 4;
|
||||
this.emit('error', new Error('Bad packet size.'));
|
||||
this.error('Bad packet size.');
|
||||
return;
|
||||
}
|
||||
|
||||
@ -632,7 +642,7 @@ BIP151.prototype.parse = function parse(data) {
|
||||
|
||||
if (!this.input.verify(tag)) {
|
||||
this.input.sequence();
|
||||
this.emit('error', new Error('Bad tag.'));
|
||||
this.error('Bad tag.');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -125,7 +125,15 @@ CompactBlock.fromRaw = function fromRaw(data, enc) {
|
||||
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 i, id, lo, hi, ptx;
|
||||
|
||||
@ -530,7 +538,15 @@ TXResponse.fromBlock = function 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 i, tx;
|
||||
|
||||
|
||||
@ -353,7 +353,7 @@ VerackPacket.fromRaw = function fromRaw(data, enc) {
|
||||
* @exports PingPacket
|
||||
* @constructor
|
||||
* @param {BN?} nonce
|
||||
* @property {BN} nonce
|
||||
* @property {BN|null} nonce
|
||||
*/
|
||||
|
||||
function PingPacket(nonce) {
|
||||
@ -362,7 +362,7 @@ function PingPacket(nonce) {
|
||||
|
||||
Packet.call(this);
|
||||
|
||||
this.nonce = nonce || new bn(0);
|
||||
this.nonce = nonce || null;
|
||||
}
|
||||
|
||||
utils.inherits(PingPacket, Packet);
|
||||
@ -378,7 +378,8 @@ PingPacket.prototype.type = exports.types.PING;
|
||||
PingPacket.prototype.toRaw = function toRaw(writer) {
|
||||
var p = bcoin.writer(writer);
|
||||
|
||||
p.writeU64(this.nonce);
|
||||
if (this.nonce)
|
||||
p.writeU64(this.nonce);
|
||||
|
||||
if (!writer)
|
||||
p = p.render();
|
||||
@ -394,7 +395,8 @@ PingPacket.prototype.toRaw = function toRaw(writer) {
|
||||
|
||||
PingPacket.prototype.fromRaw = function fromRaw(data) {
|
||||
var p = bcoin.reader(data);
|
||||
this.nonce = p.readU64();
|
||||
if (p.left() >= 8)
|
||||
this.nonce = p.readU64();
|
||||
return this;
|
||||
};
|
||||
|
||||
@ -1702,7 +1704,7 @@ FilterLoadPacket.prototype.fromRaw = function fromRaw(data) {
|
||||
*/
|
||||
|
||||
FilterLoadPacket.prototype.fromFilter = function fromFilter(filter) {
|
||||
this.filter = filter;
|
||||
this.filter = filter.filter;
|
||||
this.n = filter.n;
|
||||
this.tweak = filter.tweak;
|
||||
this.update = filter.update;
|
||||
@ -2376,7 +2378,9 @@ CmpctBlockPacket.prototype.type = exports.types.CMPCTBLOCK;
|
||||
*/
|
||||
|
||||
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) {
|
||||
return this.response.toRaw(this.witness, writer);
|
||||
if (this.witness)
|
||||
return this.response.toRaw(writer);
|
||||
return this.response.toNormal(writer);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -72,11 +72,12 @@ Parser.prototype._init = function _init(str) {
|
||||
/**
|
||||
* Emit an error.
|
||||
* @private
|
||||
* @param {String} str
|
||||
* @param {...String} msg
|
||||
*/
|
||||
|
||||
Parser.prototype.error = function error(str) {
|
||||
this.emit('error', new Error(str));
|
||||
Parser.prototype.error = function error() {
|
||||
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) {
|
||||
this.waiting = 24;
|
||||
this.header = null;
|
||||
return this.error('Invalid checksum');
|
||||
return this.error(
|
||||
'Invalid checksum: %d != %d',
|
||||
checksum, this.header.checksum);
|
||||
}
|
||||
|
||||
try {
|
||||
@ -164,13 +167,13 @@ Parser.prototype.parseHeader = function parseHeader(data) {
|
||||
magic = data.readUInt32LE(0, true);
|
||||
|
||||
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
|
||||
for (i = 0; data[i + 4] !== 0 && i < 12; i++);
|
||||
|
||||
if (i === 12)
|
||||
return this.error('Not NULL-terminated cmd');
|
||||
return this.error('Non NULL-terminated command.');
|
||||
|
||||
cmd = data.toString('ascii', 4, 4 + i);
|
||||
|
||||
@ -178,7 +181,7 @@ Parser.prototype.parseHeader = function parseHeader(data) {
|
||||
|
||||
if (size > constants.MAX_MESSAGE) {
|
||||
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);
|
||||
|
||||
338
lib/net/peer.js
338
lib/net/peer.js
@ -400,7 +400,7 @@ Peer.prototype._onAck = function _onAck(err) {
|
||||
}
|
||||
|
||||
// Find some more peers.
|
||||
this.write(new packets.GetAddrPacket());
|
||||
this.send(new packets.GetAddrPacket());
|
||||
|
||||
// Relay our spv filter if we have one.
|
||||
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.
|
||||
*/
|
||||
@ -736,31 +727,62 @@ Peer.prototype.destroy = function destroy() {
|
||||
|
||||
/**
|
||||
* Write data to the peer's socket.
|
||||
* @param {Buffer} chunk
|
||||
* @param {Buffer} data
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Peer.prototype.write = function write(chunk) {
|
||||
Peer.prototype.write = function write(data) {
|
||||
if (this.destroyed)
|
||||
return false;
|
||||
|
||||
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.
|
||||
* @private
|
||||
* @param {String|Error} err
|
||||
* @param {...String|Error} err
|
||||
*/
|
||||
|
||||
Peer.prototype.error = function error(err, keep) {
|
||||
var i, args, msg;
|
||||
|
||||
if (this.destroyed)
|
||||
return;
|
||||
|
||||
if (typeof err === 'string')
|
||||
err = new Error(err);
|
||||
if (typeof err === 'string') {
|
||||
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 + ')';
|
||||
|
||||
@ -859,10 +881,12 @@ Peer.prototype.getData = function getData(items) {
|
||||
/**
|
||||
* Handle a packet payload.
|
||||
* @private
|
||||
* @param {Object} packet
|
||||
* @param {Packet} packet
|
||||
*/
|
||||
|
||||
Peer.prototype._onPacket = function onPacket(packet) {
|
||||
this.lastRecv = utils.ms();
|
||||
|
||||
if (this.bip151
|
||||
&& !this.bip151.completed
|
||||
&& packet.type !== packetTypes.ENCINIT
|
||||
@ -878,17 +902,16 @@ Peer.prototype._onPacket = function onPacket(packet) {
|
||||
this.bip150.complete(new Error('Message before auth.'));
|
||||
}
|
||||
|
||||
if (this.lastBlock && packet.type !== packetTypes.TX)
|
||||
this._flushMerkle();
|
||||
|
||||
this.lastRecv = utils.ms();
|
||||
if (this.lastBlock) {
|
||||
if (packet.type !== packetTypes.TX)
|
||||
this._flushMerkle();
|
||||
}
|
||||
|
||||
switch (packet.type) {
|
||||
case packetTypes.VERSION:
|
||||
return this._handleVersion(packet);
|
||||
case packetTypes.VERACK:
|
||||
this.fire(packet.cmd);
|
||||
break;
|
||||
return this._handleVerack(packet);
|
||||
case packetTypes.PING:
|
||||
return this._handlePing(packet);
|
||||
case packetTypes.PONG:
|
||||
@ -896,7 +919,7 @@ Peer.prototype._onPacket = function onPacket(packet) {
|
||||
case packetTypes.ALERT:
|
||||
return this._handleAlert(packet);
|
||||
case packetTypes.GETADDR:
|
||||
return this._handleGetAddr();
|
||||
return this._handleGetAddr(packet);
|
||||
case packetTypes.ADDR:
|
||||
return this._handleAddr(packet);
|
||||
case packetTypes.INV:
|
||||
@ -904,8 +927,7 @@ Peer.prototype._onPacket = function onPacket(packet) {
|
||||
case packetTypes.GETDATA:
|
||||
return this._handleGetData(packet);
|
||||
case packetTypes.NOTFOUND:
|
||||
this.fire(packet.cmd, packet.items);
|
||||
break;
|
||||
return this._handleNotFound(packet);
|
||||
case packetTypes.GETBLOCKS:
|
||||
return this._handleGetBlocks(packet);
|
||||
case packetTypes.GETHEADERS:
|
||||
@ -913,48 +935,29 @@ Peer.prototype._onPacket = function onPacket(packet) {
|
||||
case packetTypes.HEADERS:
|
||||
return this._handleHeaders(packet);
|
||||
case packetTypes.SENDHEADERS:
|
||||
this.preferHeaders = true;
|
||||
this.fire(packet.cmd);
|
||||
break;
|
||||
return this._handleSendHeaders(packet);
|
||||
case packetTypes.BLOCK:
|
||||
this.fire(packet.cmd, packet.block);
|
||||
break;
|
||||
return this._handleBlock(packet);
|
||||
case packetTypes.TX:
|
||||
if (this.lastBlock) {
|
||||
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;
|
||||
return this._handleTX(packet);
|
||||
case packetTypes.REJECT:
|
||||
return this._handleReject(packet);
|
||||
case packetTypes.MEMPOOL:
|
||||
return this._handleMempool();
|
||||
return this._handleMempool(packet);
|
||||
case packetTypes.FILTERLOAD:
|
||||
return this._handleFilterLoad(packet);
|
||||
case packetTypes.FILTERADD:
|
||||
return this._handleFilterAdd(packet);
|
||||
case packetTypes.FILTERCLEAR:
|
||||
return this._handleFilterClear();
|
||||
return this._handleFilterClear(packet);
|
||||
case packetTypes.MERKLEBLOCK:
|
||||
packet.block.verifyPartial();
|
||||
this.lastBlock = packet.block;
|
||||
this.waiting = packet.block.matches.length;
|
||||
if (this.waiting === 0)
|
||||
this._flushMerkle();
|
||||
break;
|
||||
return this._handleMerkleBlock(packet);
|
||||
case packetTypes.GETUTXOS:
|
||||
return this._handleGetUTXOs(packet);
|
||||
case packetTypes.UTXOS:
|
||||
return this._handleUTXOs(packet);
|
||||
case packetTypes.HAVEWITNESS:
|
||||
this.haveWitness = true;
|
||||
this.fire(packet.cmd);
|
||||
break;
|
||||
return this._handleHaveWitness(packet);
|
||||
case packetTypes.FEEFILTER:
|
||||
return this._handleFeeFilter(packet);
|
||||
case packetTypes.SENDCMPCT:
|
||||
@ -976,7 +979,9 @@ Peer.prototype._onPacket = function onPacket(packet) {
|
||||
case packetTypes.AUTHPROPOSE:
|
||||
return this._handleAuthPropose(packet);
|
||||
case packetTypes.UNKNOWN:
|
||||
this.logger.warning('Unknown packet: %s.', packet.cmd);
|
||||
return this._handleUnknown(packet);
|
||||
default:
|
||||
assert(false, 'Bad packet type.');
|
||||
break;
|
||||
}
|
||||
};
|
||||
@ -1008,7 +1013,7 @@ Peer.prototype.fire = function fire(cmd, payload) {
|
||||
/**
|
||||
* Handle `filterload` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {FilterLoadPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleFilterLoad = function _handleFilterLoad(packet) {
|
||||
@ -1024,7 +1029,7 @@ Peer.prototype._handleFilterLoad = function _handleFilterLoad(packet) {
|
||||
/**
|
||||
* Handle `filteradd` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {FilterAddPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleFilterAdd = function _handleFilterAdd(packet) {
|
||||
@ -1044,20 +1049,38 @@ Peer.prototype._handleFilterAdd = function _handleFilterAdd(packet) {
|
||||
/**
|
||||
* Handle `filterclear` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {FilterClearPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleFilterClear = function _handleFilterClear() {
|
||||
Peer.prototype._handleFilterClear = function _handleFilterClear(packet) {
|
||||
if (this.spvFilter)
|
||||
this.spvFilter.reset();
|
||||
|
||||
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.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {FeeFilterPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleFeeFilter = function _handleFeeFilter(packet) {
|
||||
@ -1076,7 +1099,7 @@ Peer.prototype._handleFeeFilter = function _handleFeeFilter(packet) {
|
||||
/**
|
||||
* Handle `utxos` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {UTXOsPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleUTXOs = function _handleUTXOs(utxos) {
|
||||
@ -1090,9 +1113,9 @@ Peer.prototype._handleUTXOs = function _handleUTXOs(utxos) {
|
||||
* @private
|
||||
*/
|
||||
|
||||
Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
|
||||
Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(packet) {
|
||||
var self = this;
|
||||
var unlock = this._lock(_handleGetUTXOs, [payload, utils.nop]);
|
||||
var unlock = this._lock(_handleGetUTXOs, [packet, utils.nop]);
|
||||
var utxos;
|
||||
|
||||
if (!unlock)
|
||||
@ -1115,17 +1138,17 @@ Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
|
||||
if (this.chain.db.options.spv)
|
||||
return done();
|
||||
|
||||
if (payload.prevout.length > 15)
|
||||
if (packet.prevout.length > 15)
|
||||
return done();
|
||||
|
||||
utxos = new packets.GetUTXOsPacket();
|
||||
|
||||
utils.forEachSerial(payload.prevout, function(prevout, next) {
|
||||
utils.forEachSerial(packet.prevout, function(prevout, next) {
|
||||
var hash = prevout.hash;
|
||||
var index = prevout.index;
|
||||
var coin;
|
||||
|
||||
if (self.mempool && payload.mempool) {
|
||||
if (self.mempool && packet.mempool) {
|
||||
coin = self.mempool.getCoin(hash, index);
|
||||
|
||||
if (coin) {
|
||||
@ -1161,22 +1184,33 @@ Peer.prototype._handleGetUTXOs = function _handleGetUTXOs(payload) {
|
||||
utxos.height = self.chain.height;
|
||||
utxos.tip = self.chain.tip.hash;
|
||||
|
||||
self.send(new packets.UTXOsPacket(utxos));
|
||||
self.send(utxos);
|
||||
|
||||
done();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle `getheaders` packet.
|
||||
* Handle `havewitness` packet.
|
||||
* @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 headers = [];
|
||||
var unlock = this._lock(_handleGetHeaders, [payload, utils.nop]);
|
||||
var unlock = this._lock(_handleGetHeaders, [packet, utils.nop]);
|
||||
|
||||
if (!unlock)
|
||||
return;
|
||||
@ -1228,7 +1262,7 @@ Peer.prototype._handleGetHeaders = function _handleGetHeaders(payload) {
|
||||
if (headers.length === 2000)
|
||||
return done();
|
||||
|
||||
if (entry.hash === payload.stop)
|
||||
if (entry.hash === packet.stop)
|
||||
return done();
|
||||
|
||||
entry.getNext(next);
|
||||
@ -1236,10 +1270,10 @@ Peer.prototype._handleGetHeaders = function _handleGetHeaders(payload) {
|
||||
});
|
||||
}
|
||||
|
||||
if (payload.locator.length === 0)
|
||||
return collect(null, payload.stop);
|
||||
if (packet.locator.length === 0)
|
||||
return collect(null, packet.stop);
|
||||
|
||||
this.chain.findLocator(payload.locator, function(err, hash) {
|
||||
this.chain.findLocator(packet.locator, function(err, hash) {
|
||||
if (err)
|
||||
return collect(err);
|
||||
|
||||
@ -1253,13 +1287,13 @@ Peer.prototype._handleGetHeaders = function _handleGetHeaders(payload) {
|
||||
/**
|
||||
* Handle `getblocks` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {GetBlocksPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleGetBlocks = function _handleGetBlocks(payload) {
|
||||
Peer.prototype._handleGetBlocks = function _handleGetBlocks(packet) {
|
||||
var self = this;
|
||||
var blocks = [];
|
||||
var unlock = this._lock(_handleGetBlocks, [payload, utils.nop]);
|
||||
var unlock = this._lock(_handleGetBlocks, [packet, utils.nop]);
|
||||
|
||||
if (!unlock)
|
||||
return;
|
||||
@ -1285,7 +1319,7 @@ Peer.prototype._handleGetBlocks = function _handleGetBlocks(payload) {
|
||||
if (this.chain.db.options.prune)
|
||||
return done();
|
||||
|
||||
this.chain.findLocator(payload.locator, function(err, tip) {
|
||||
this.chain.findLocator(packet.locator, function(err, tip) {
|
||||
if (err)
|
||||
return done(err);
|
||||
|
||||
@ -1302,7 +1336,7 @@ Peer.prototype._handleGetBlocks = function _handleGetBlocks(payload) {
|
||||
|
||||
blocks.push(new InvItem(constants.inv.BLOCK, hash));
|
||||
|
||||
if (hash === payload.stop)
|
||||
if (hash === packet.stop)
|
||||
return done();
|
||||
|
||||
if (blocks.length === 500) {
|
||||
@ -1319,7 +1353,7 @@ Peer.prototype._handleGetBlocks = function _handleGetBlocks(payload) {
|
||||
/**
|
||||
* Handle `version` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {VersionPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleVersion = function _handleVersion(version) {
|
||||
@ -1370,15 +1404,27 @@ Peer.prototype._handleVersion = function _handleVersion(version) {
|
||||
this.ignore();
|
||||
return;
|
||||
}
|
||||
this.request('havewitness', function(err) {
|
||||
return this.request('havewitness', function(err) {
|
||||
if (err) {
|
||||
self.error('Peer does not support segregated witness.');
|
||||
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())
|
||||
this.haveWitness = true;
|
||||
|
||||
@ -1391,16 +1437,26 @@ Peer.prototype._handleVersion = function _handleVersion(version) {
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle `mempool` packet.
|
||||
* Handle `verack` packet.
|
||||
* @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 items = [];
|
||||
var i, hashes;
|
||||
var unlock = this._lock(_handleMempool, [utils.nop]);
|
||||
var unlock = this._lock(_handleMempool, [packet, utils.nop]);
|
||||
|
||||
if (!unlock)
|
||||
return;
|
||||
@ -1485,7 +1541,7 @@ Peer.prototype._getItem = function _getItem(item, callback) {
|
||||
/**
|
||||
* Handle `getdata` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {GetDataPacket}
|
||||
*/
|
||||
|
||||
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.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {AddrPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleAddr = function _handleAddr(packet) {
|
||||
@ -1643,18 +1709,19 @@ Peer.prototype._handleAddr = function _handleAddr(packet) {
|
||||
/**
|
||||
* Handle `ping` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {PingPacket}
|
||||
*/
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handle `pong` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {PongPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handlePong = function _handlePong(packet) {
|
||||
@ -1693,10 +1760,10 @@ Peer.prototype._handlePong = function _handlePong(packet) {
|
||||
/**
|
||||
* Handle `getaddr` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {GetAddrPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleGetAddr = function _handleGetAddr() {
|
||||
Peer.prototype._handleGetAddr = function _handleGetAddr(packet) {
|
||||
var items = [];
|
||||
var i, addr;
|
||||
|
||||
@ -1739,7 +1806,7 @@ Peer.prototype._handleGetAddr = function _handleGetAddr() {
|
||||
/**
|
||||
* Handle `inv` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {InvPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleInv = function _handleInv(packet) {
|
||||
@ -1788,22 +1855,66 @@ Peer.prototype._handleInv = function _handleInv(packet) {
|
||||
/**
|
||||
* Handle `headers` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {HeadersPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleHeaders = function _handleHeaders(packet) {
|
||||
var headers = packet.items;
|
||||
|
||||
if (headers.length > 2000) {
|
||||
this.setMisbehavior(100);
|
||||
return;
|
||||
}
|
||||
|
||||
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.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {RejectPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleReject = function _handleReject(details) {
|
||||
@ -1826,7 +1937,7 @@ Peer.prototype._handleReject = function _handleReject(details) {
|
||||
/**
|
||||
* Handle `alert` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {AlertPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleAlert = function _handleAlert(alert) {
|
||||
@ -1837,7 +1948,7 @@ Peer.prototype._handleAlert = function _handleAlert(alert) {
|
||||
/**
|
||||
* Handle `encinit` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {EncinitPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleEncinit = function _handleEncinit(packet) {
|
||||
@ -1859,7 +1970,7 @@ Peer.prototype._handleEncinit = function _handleEncinit(packet) {
|
||||
/**
|
||||
* Handle `encack` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {EncackPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleEncack = function _handleEncack(packet) {
|
||||
@ -1879,7 +1990,7 @@ Peer.prototype._handleEncack = function _handleEncack(packet) {
|
||||
/**
|
||||
* Handle `authchallenge` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {AuthChallengePacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleAuthChallenge = function _handleAuthChallenge(packet) {
|
||||
@ -1903,7 +2014,7 @@ Peer.prototype._handleAuthChallenge = function _handleAuthChallenge(packet) {
|
||||
/**
|
||||
* Handle `authreply` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {AuthReplyPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleAuthReply = function _handleAuthReply(packet) {
|
||||
@ -1928,7 +2039,7 @@ Peer.prototype._handleAuthReply = function _handleAuthReply(packet) {
|
||||
/**
|
||||
* Handle `authpropose` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {AuthProposePacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleAuthPropose = function _handleAuthPropose(packet) {
|
||||
@ -1949,10 +2060,21 @@ Peer.prototype._handleAuthPropose = function _handleAuthPropose(packet) {
|
||||
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.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {SendCmpctPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleSendCmpct = function _handleSendCmpct(packet) {
|
||||
@ -1979,7 +2101,7 @@ Peer.prototype._handleSendCmpct = function _handleSendCmpct(packet) {
|
||||
/**
|
||||
* Handle `cmpctblock` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {CmpctBlockPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleCmpctBlock = function _handleCmpctBlock(packet) {
|
||||
@ -2019,7 +2141,7 @@ Peer.prototype._handleCmpctBlock = function _handleCmpctBlock(packet) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.send(block.toRequest());
|
||||
this.send(new packets.GetBlockTxnPacket(block.toRequest()));
|
||||
|
||||
this.logger.debug(
|
||||
'Received semi-full compact block %s (%s).',
|
||||
@ -2036,7 +2158,7 @@ Peer.prototype._handleCmpctBlock = function _handleCmpctBlock(packet) {
|
||||
/**
|
||||
* Handle `getblocktxn` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {GetBlockTxnPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(packet) {
|
||||
@ -2093,7 +2215,7 @@ Peer.prototype._handleGetBlockTxn = function _handleGetBlockTxn(packet) {
|
||||
/**
|
||||
* Handle `blocktxn` packet.
|
||||
* @private
|
||||
* @param {Object}
|
||||
* @param {BlockTxnPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype._handleBlockTxn = function _handleBlockTxn(packet) {
|
||||
@ -2120,7 +2242,7 @@ Peer.prototype._handleBlockTxn = function _handleBlockTxn(packet) {
|
||||
'Filled compact block %s (%s).',
|
||||
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.
|
||||
* @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) {
|
||||
|
||||
@ -166,6 +166,15 @@ MemBlock.prototype.toRaw = function toRaw() {
|
||||
return this.raw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Return serialized block data.
|
||||
* @returns {Buffer}
|
||||
*/
|
||||
|
||||
MemBlock.prototype.toNormal = function toNormal() {
|
||||
return this.raw;
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse the serialized block data
|
||||
* and create an actual {@link Block}.
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
/*!
|
||||
* packets.js - packets for bcoin
|
||||
* Copyright (c) 2014-2015, Fedor Indutny (MIT License)
|
||||
* netaddress.js - network address object for bcoin
|
||||
* Copyright (c) 2014-2016, Christopher Jeffrey (MIT License).
|
||||
* https://github.com/bcoin-org/bcoin
|
||||
*/
|
||||
@ -301,4 +300,8 @@ NetworkAddress.prototype.toRaw = function toRaw(full, writer) {
|
||||
return p;
|
||||
};
|
||||
|
||||
/*
|
||||
* Expose
|
||||
*/
|
||||
|
||||
module.exports = NetworkAddress;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user