relay alerts.

This commit is contained in:
Christopher Jeffrey 2016-06-07 10:23:22 -07:00
parent fd01c23f4c
commit f2bc10726b
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
7 changed files with 77 additions and 25 deletions

View File

@ -144,6 +144,10 @@ Fullnode.prototype._init = function _init() {
}); });
} }
this.pool.on('alert', function(details) {
self.emit('alert', details);
});
this.on('tx', function(tx) { this.on('tx', function(tx) {
self.walletdb.addTX(tx, function(err) { self.walletdb.addTX(tx, function(err) {
if (err) if (err)

View File

@ -1556,20 +1556,24 @@ Peer.prototype._handleReject = function _handleReject(payload) {
}; };
Peer.prototype._handleAlert = function _handleAlert(details) { Peer.prototype._handleAlert = function _handleAlert(details) {
var hash = utils.dsha256(details.payload); this.invFilter.add(details.hash, 'hex');
var signature = details.signature;
if (!bcoin.ec.verify(hash, signature, this.network.alertKey)) {
bcoin.debug('Peer sent a phony alert packet (%s).', this.hostname);
// Let's look at it because why not?
bcoin.debug(details);
this.setMisbehavior(100);
return;
}
this.fire('alert', details); this.fire('alert', details);
}; };
/**
* Send an `alert` to peer.
* @param {AlertPacket} details
*/
Peer.prototype.sendAlert = function sendAlert(details) {
var data = bcoin.protocol.framer.alert(details);
if (!this.invFilter.added(details.hash, 'hex'))
return;
this.write(this.framer.packet('alert', data));
};
/** /**
* Send `getheaders` to peer. Note that unlike * Send `getheaders` to peer. Note that unlike
* `getblocks`, `getheaders` can have a null locator. * `getblocks`, `getheaders` can have a null locator.

View File

@ -988,10 +988,8 @@ Pool.prototype._createPeer = function _createPeer(options) {
self.emit('reject', payload, peer); self.emit('reject', payload, peer);
}); });
peer.on('alert', function(payload) { peer.on('alert', function(details) {
bcoin.debug('Received alert from peer (%s).', peer.hostname); self._handleAlert(details, peer);
bcoin.debug(payload);
self.emit('alert', payload, peer);
}); });
peer.on('notfound', function(items) { peer.on('notfound', function(items) {
@ -1077,6 +1075,44 @@ Pool.prototype._createPeer = function _createPeer(options) {
return peer; return peer;
}; };
Pool.prototype._handleAlert = function _handleAlert(details, peer) {
var hash = new Buffer(details.hash, 'hex');
var signature = details.signature;
var now = bcoin.now();
var i;
if (!this.rejects.added(hash))
return;
if (!bcoin.ec.verify(hash, signature, this.network.alertKey)) {
bcoin.debug('Peer sent a phony alert packet (%s).', peer.hostname);
// Let's look at it because why not?
bcoin.debug(details);
peer.setMisbehavior(100);
return;
}
if (now >= details.relayUntil || now >= details.expiration) {
bcoin.debug('Peer sent an expired alert packet (%s).', peer.hostname);
bcoin.debug(details);
return;
}
bcoin.debug('Received alert from peer (%s).', peer.hostname);
bcoin.debug(details);
if (this.peers.load)
this.peers.load.sendAlert(details);
for (i = 0; i < this.peers.regular.length; i++)
this.peers.regular[i].sendAlert(details);
for (i = 0; i < this.peers.leeches.length; i++)
this.peers.leeches[i].sendAlert(details);
this.emit('alert', details, peer);
};
Pool.prototype._handleTX = function _handleTX(tx, peer, callback) { Pool.prototype._handleTX = function _handleTX(tx, peer, callback) {
var self = this; var self = this;
var requested; var requested;

View File

@ -1193,7 +1193,7 @@ Framer.addr = function addr(hosts, writer) {
Framer.alert = function alert(data, writer) { Framer.alert = function alert(data, writer) {
var network = bcoin.network.get(data.network); var network = bcoin.network.get(data.network);
var key = data.key; var key = data.key;
var p, i, payload; var p, i, payload, hash;
if (!key && network.alertPrivateKey) if (!key && network.alertPrivateKey)
key = network.alertPrivateKey; key = network.alertPrivateKey;
@ -1225,12 +1225,20 @@ Framer.alert = function alert(data, writer) {
p = new BufferWriter(writer); p = new BufferWriter(writer);
p.writeVarBytes(payload); p.writeVarBytes(payload);
if (data.signature) if (data.signature) {
p.writeVarBytes(data.signature); p.writeVarBytes(data.signature);
else if (key) } else if (key) {
p.writeVarBytes(bcoin.ec.sign(utils.dsha256(payload), key)); hash = utils.dsha256(payload);
else p.writeVarBytes(bcoin.ec.sign(hash, key));
} else {
assert(false, 'No key or signature.'); assert(false, 'No key or signature.');
}
if (!data.hash) {
if (!hash)
hash = utils.dsha256(payload);
data.hash = hash.toString('hex');
}
if (!writer) if (!writer)
p = p.render(); p = p.render();

View File

@ -1276,6 +1276,7 @@ Parser.parseAlert = function parseAlert(p) {
reserved = p.readVarString('ascii'); reserved = p.readVarString('ascii');
return { return {
hash: utils.dsha256(payload).toString('hex'),
version: version, version: version,
relayUntil: relayUntil, relayUntil: relayUntil,
expiration: expiration, expiration: expiration,

View File

@ -101,6 +101,10 @@ SPVNode.prototype._init = function _init() {
}); });
} }
this.pool.on('alert', function(details) {
self.emit('alert', details);
});
this.on('tx', function(tx) { this.on('tx', function(tx) {
self.walletdb.addTX(tx, function(err) { self.walletdb.addTX(tx, function(err) {
if (err) if (err)

View File

@ -6,7 +6,6 @@
*/ */
var bcoin = require('./env'); var bcoin = require('./env');
var EventEmitter = require('events').EventEmitter;
var utils = require('./utils'); var utils = require('./utils');
/** /**
@ -27,8 +26,6 @@ function TimeData(limit) {
if (!(this instanceof TimeData)) if (!(this instanceof TimeData))
return new TimeData(limit); return new TimeData(limit);
EventEmitter.call(this);
if (limit == null) if (limit == null)
limit = 200; limit = 200;
@ -39,8 +36,6 @@ function TimeData(limit) {
this._checked = false; this._checked = false;
} }
utils.inherits(TimeData, EventEmitter);
/** /**
* Add time data. * Add time data.
* @param {String} host * @param {String} host