net: refactor reject msg. broadcast orphans.
This commit is contained in:
parent
2d831ca5bd
commit
514e735a96
@ -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}
|
||||
|
||||
@ -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);
|
||||
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
@ -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);
|
||||
});
|
||||
|
||||
@ -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);
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Loading…
Reference in New Issue
Block a user