net: refactor reject msg. broadcast orphans.

This commit is contained in:
Christopher Jeffrey 2016-12-17 13:50:45 -08:00
parent 2d831ca5bd
commit 514e735a96
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
5 changed files with 77 additions and 34 deletions

View File

@ -1894,6 +1894,29 @@ RejectPacket.fromOptions = function fromOptions(options) {
return new RejectPacket().fromOptions(options);
};
/**
* Get uint256le hash if present.
* @returns {Hash}
*/
RejectPacket.prototype.rhash = function rhash() {
return this.hash ? util.revHex(this.hash) : null;
};
/**
* Get symbolic code.
* @returns {String}
*/
RejectPacket.prototype.getCode = function getCode() {
var code = constants.rejectByVal[this.code];
if (!code)
return this.code + '';
return code.toLowerCase();
};
/**
* Get serialization size.
* @returns {Number}

View File

@ -183,8 +183,8 @@ Peer.prototype._init = function init() {
try {
yield self.handlePacket(packet);
} catch (e) {
self.destroy();
self.error(e);
self.destroy();
}
}));
@ -195,8 +195,8 @@ Peer.prototype._init = function init() {
if (this.bip151) {
this.bip151.on('error', function(err) {
self.reject(null, 'malformed', 'error parsing message', 10);
self.error(err);
self.reject(null, 'malformed', 'error parsing message', 10);
});
this.bip151.on('rekey', function() {
self.logger.debug('Rekeying with peer (%s).', self.hostname);
@ -231,8 +231,8 @@ Peer.prototype.bind = function bind(socket) {
this.socket = socket;
this.socket.once('error', function(err) {
self.destroy();
self.error(err);
self.destroy();
switch (err.code) {
case 'ECONNREFUSED':
@ -250,10 +250,8 @@ Peer.prototype.bind = function bind(socket) {
});
this.socket.once('close', function() {
if (self.destroyed)
return;
self.destroy();
self.error('socket hangup');
self.destroy();
});
this.socket.on('drain', function() {
@ -332,7 +330,7 @@ Peer.prototype.open = co(function* open() {
yield this.finalize();
if (this.destroyed)
throw new Error('Peer was destroyed.');
throw new Error('Peer was destroyed before handshake.');
// Finally we can let the pool know
// that this peer is ready to go.
@ -348,8 +346,8 @@ Peer.prototype.tryOpen = co(function* tryOpen() {
try {
yield this.open();
} catch (e) {
this.destroy();
this.error(e);
this.destroy();
}
});
@ -917,8 +915,8 @@ Peer.prototype.write = function write(data) {
Peer.prototype.needsDrain = function needsDrain(size) {
if (this.maybeStall()) {
this.destroy();
this.error('Peer stalled (drain).');
this.destroy();
return;
}
@ -930,8 +928,8 @@ Peer.prototype.needsDrain = function needsDrain(size) {
'Peer is not reading: %dmb buffered (%s).',
util.mb(this.drainSize),
this.hostname);
this.destroy();
this.error('Peer stalled (drain).');
this.destroy();
}
};
@ -948,8 +946,8 @@ Peer.prototype.maybeStall = function maybeStall() {
return false;
this.drainSize = 0;
this.destroy();
this.error('Peer stalled.');
this.destroy();
return true;
};
@ -998,6 +996,9 @@ Peer.prototype.sendRaw = function sendRaw(cmd, body, checksum) {
Peer.prototype.error = function error(err) {
var i, args, msg;
if (this.destroyed)
return;
if (typeof err === 'string') {
args = new Array(arguments.length);

View File

@ -1385,23 +1385,13 @@ Pool.prototype.handleTXInv = function handleTXInv(txs, peer) {
*/
Pool.prototype.handleReject = function handleReject(reject, peer) {
var data, code;
if (reject.hash)
data = util.revHex(reject.hash);
code = constants.rejectByVal[reject.code];
if (code)
code = code.toLowerCase();
this.logger.warning(
'Received reject (%s): msg=%s code=%s reason=%s data=%s.',
'Received reject (%s): msg=%s code=%s reason=%s hash=%s.',
peer.hostname,
reject.message,
code || reject.code,
reject.getCode(),
reject.reason,
data || null);
reject.rhash());
this.emit('reject', reject, peer);
};

View File

@ -303,9 +303,13 @@ FullNode.prototype.scan = function scan(start, filter, iter) {
* @returns {Promise}
*/
FullNode.prototype.broadcast = function broadcast(item) {
return this.pool.broadcast(item);
};
FullNode.prototype.broadcast = co(function* broadcast(item) {
try {
yield this.pool.broadcast(item);
} catch (e) {
this.emit('error', e);
}
});
/**
* Verify a transaction, add it to the mempool, and broadcast.
@ -317,19 +321,40 @@ FullNode.prototype.broadcast = function broadcast(item) {
*/
FullNode.prototype.sendTX = co(function* sendTX(tx) {
var missing;
try {
yield this.mempool.addTX(tx);
missing = yield this.mempool.addTX(tx);
} catch (err) {
if (err.type === 'VerifyError') {
if (err.type === 'VerifyError' && err.score === 0) {
this._error(err);
this.logger.warning('Verification failed for tx: %s.', tx.txid());
this.logger.warning('Attempting to broadcast anyway...');
yield this.pool.broadcast(tx);
this.broadcast(tx);
return;
}
throw err;
}
if (missing) {
this.logger.warning('TX was orphaned in mempool: %s.', tx.txid());
// Avoid getting dos'd by bitcoind for now.
// See: https://github.com/bitcoin/bitcoin/issues/9182
// Once this fix is widely deployed, we can remove this.
if (tx.hasWitness()) {
this.logger.warning('Not broadcasting for now to avoid bitcoind DoS.');
return;
}
this.logger.warning('Attempting to broadcast anyway...');
this.broadcast(tx);
return;
}
// We need to announce by hand if
// we're running in selfish mode.
if (this.options.selfish)
this.pool.announceTX(tx);
});

View File

@ -282,9 +282,13 @@ SPVNode.prototype.watchBlock = co(function* watchBlock(entry, block) {
* @returns {Promise}
*/
SPVNode.prototype.broadcast = function broadcast(item) {
return this.pool.broadcast(item);
};
SPVNode.prototype.broadcast = co(function* broadcast(item) {
try {
yield this.pool.broadcast(item);
} catch (e) {
this.emit('error', e);
}
});
/**
* Broadcast a transaction (note that this will _not_ be verified
@ -295,7 +299,7 @@ SPVNode.prototype.broadcast = function broadcast(item) {
*/
SPVNode.prototype.sendTX = function sendTX(tx) {
return this.pool.broadcast(tx);
return this.broadcast(tx);
};
/**