net: less banning for bip152.

This commit is contained in:
Christopher Jeffrey 2017-03-07 18:01:05 -08:00
parent cdbad54a8c
commit 11a2bc1356
No known key found for this signature in database
GPG Key ID: 8962AB9DE6666BBD
4 changed files with 83 additions and 34 deletions

View File

@ -93,7 +93,6 @@ CompactBlock.prototype.fromOptions = function fromOptions(options) {
this.sipKey = options.sipKey;
this.initKey();
this.init();
return this;
};
@ -159,8 +158,6 @@ CompactBlock.prototype.fromRaw = function fromRaw(data) {
this.ptx.push(new PrefilledTX(index, tx));
}
this.init();
return this;
};
@ -457,7 +454,8 @@ CompactBlock.prototype.init = function init() {
id = this.ids[i];
// Fails on siphash collision
assert(!this.idMap[id], 'Siphash collision.');
if (this.idMap[id])
return false;
this.idMap[id] = i + offset;
@ -466,6 +464,8 @@ CompactBlock.prototype.init = function init() {
// don't have lowlevel access to our hash
// table. Hopefully we don't get hashdos'd.
}
return true;
};
/**

View File

@ -956,19 +956,8 @@ Peer.prototype.sendHeaders = function sendHeaders(items) {
Peer.prototype.sendCompactBlock = function sendCompactBlock(block) {
var witness = this.compactWitness;
// Try again with a new nonce
// if we get a siphash collision.
for (;;) {
try {
block = BIP152.CompactBlock.fromBlock(block, witness);
} catch (e) {
continue;
}
break;
}
this.send(new packets.CmpctBlockPacket(block, witness));
var compact = BIP152.CompactBlock.fromBlock(block, witness);
this.send(new packets.CmpctBlockPacket(compact, witness));
};
/**
@ -1485,8 +1474,11 @@ Peer.prototype.blockType = function blockType() {
if (this.options.spv)
return invTypes.FILTERED_BLOCK;
if (this.options.compact && this.hasCompact())
if (this.options.compact
&& this.hasCompactSupport()
&& this.hasCompact()) {
return invTypes.CMPCT_BLOCK;
}
if (this.hasWitness())
return invTypes.WITNESS_BLOCK;
@ -1554,6 +1546,22 @@ Peer.prototype.getTX = function getTX(hashes) {
this.getItems(this.txType(), hashes);
};
/**
* Send `getdata` to peer for a single block.
* @param {Hash} hash
*/
Peer.prototype.getFullBlock = function getFullBlock(hash) {
var type = invTypes.BLOCK;
assert(!this.options.spv);
if (this.hasWitness())
type |= InvItem.WITNESS_FLAG;
this.getItems(type, [hash]);
};
/**
* Handle a packet payload.
* @method
@ -1937,8 +1945,8 @@ Peer.prototype.handleSendCmpct = co(function* handleSendCmpct(packet) {
}
this.logger.info(
'Peer initialized compact blocks (%s).',
this.hostname());
'Peer initialized compact blocks (mode=%d, version=%d) (%s).',
packet.mode, packet.version, this.hostname());
this.compactMode = packet.mode;
this.compactWitness = packet.version === 2;
@ -2139,16 +2147,23 @@ Peer.prototype.sendReject = function sendReject(code, reason, msg) {
*/
Peer.prototype.sendCompact = function sendCompact(mode) {
this.logger.info('Initializing compact blocks (%s).', this.hostname());
if (this.services & common.services.WITNESS) {
if (this.version >= common.COMPACT_WITNESS_VERSION) {
this.logger.info(
'Initializing witness compact blocks (%s).',
this.hostname());
this.send(new packets.SendCmpctPacket(mode, 2));
return;
}
}
this.send(new packets.SendCmpctPacket(mode, 1));
if (this.version >= common.COMPACT_VERSION) {
this.logger.info(
'Initializing normal compact blocks (%s).',
this.hostname());
this.send(new packets.SendCmpctPacket(mode, 1));
}
};
/**

View File

@ -1281,10 +1281,8 @@ Pool.prototype.handleOpen = co(function* handleOpen(peer) {
}
// We want compact blocks!
if (this.options.compact) {
if (peer.hasCompactSupport())
peer.sendCompact(this.options.blockMode);
}
if (this.options.compact)
peer.sendCompact(this.options.blockMode);
// Find some more peers.
if (!this.hosts.isFull())
@ -1710,6 +1708,7 @@ Pool.prototype.handleGetData = co(function* handleGetData(peer, packet) {
var notFound = [];
var txs = 0;
var blocks = 0;
var compact = 0;
var unknown = -1;
var i, j, item, tx, block, result, height;
@ -1817,6 +1816,7 @@ Pool.prototype.handleGetData = co(function* handleGetData(peer, packet) {
peer.sendCompactBlock(block);
blocks++;
compact++;
break;
default:
@ -1847,8 +1847,8 @@ Pool.prototype.handleGetData = co(function* handleGetData(peer, packet) {
if (blocks > 0) {
this.logger.debug(
'Served %d blocks with getdata (notfound=%d) (%s).',
blocks, notFound.length, peer.hostname());
'Served %d blocks with getdata (notfound=%d, cmpct=%d) (%s).',
blocks, notFound.length, compact, peer.hostname());
}
if (unknown !== -1) {
@ -2665,7 +2665,7 @@ Pool.prototype.handleCmpctBlock = co(function* handleCmpctBlock(peer, packet) {
return;
}
if (!peer.hasCompactSupport() && !peer.hasCompact()) {
if (!peer.hasCompactSupport() || !peer.hasCompact()) {
this.logger.info(
'Peer sent unsolicited cmpctblock (%s).',
peer.hostname());
@ -2713,6 +2713,25 @@ Pool.prototype.handleCmpctBlock = co(function* handleCmpctBlock(peer, packet) {
return;
}
try {
result = block.init();
} catch (e) {
this.logger.debug(
'Peer sent an invalid compact block (%s).',
peer.hostname());
peer.increaseBan(100);
return;
}
if (!result) {
this.logger.warning(
'Siphash collision for %s. Requesting full block (%s).',
block.rhash(), peer.hostname());
peer.getFullBlock(hash);
peer.increaseBan(10);
return;
}
result = block.fillMempool(witness, this.mempool);
if (result) {
@ -2785,6 +2804,11 @@ Pool.prototype.handleGetBlockTxn = co(function* handleGetBlockTxn(peer, packet)
return;
}
this.logger.debug(
'Sending blocktxn for %s to peer (%s).',
block.rhash(),
peer.hostname());
res = BIP152.TXResponse.fromBlock(block, req);
peer.send(new packets.BlockTxnPacket(res, peer.compactWitness));
@ -2816,10 +2840,12 @@ Pool.prototype.handleBlockTxn = co(function* handleBlockTxn(peer, packet) {
this.compactBlocks.remove(res.hash);
if (!block.fillMissing(res)) {
peer.increaseBan(100);
this.logger.warning(
'Peer sent non-full blocktxn (%s).',
'Peer sent non-full blocktxn for %s. Requesting full block (%s).',
block.rhash(),
peer.hostname());
peer.getFullBlock(res.hash);
peer.increaseBan(10);
return;
}
@ -3490,7 +3516,7 @@ Pool.prototype.getIP = co(function* getIP() {
method: 'GET',
uri: 'http://icanhazip.com',
expect: 'txt',
timeout: 3000
timeout: 2000
});
} catch (e) {
return yield this.getIP2();
@ -3523,7 +3549,7 @@ Pool.prototype.getIP2 = co(function* getIP2() {
method: 'GET',
uri: 'http://checkip.dyndns.org',
expect: 'html',
timeout: 3000
timeout: 2000
});
match = /IP Address:\s*([0-9a-f.:]+)/i.exec(res.body);

View File

@ -297,6 +297,8 @@ describe('Block', function() {
var map = {};
var i, tx, mempool, result;
assert(cblock1.init());
assert.equal(cblock1.toRaw().toString('hex'), cmpct1[0]);
assert.equal(cblock2.toRaw().toString('hex'), cmpct1[0]);
@ -334,6 +336,8 @@ describe('Block', function() {
var map = {};
var i, tx, mid, keys, mempool, result, req, res;
assert(cblock1.init());
assert.equal(cblock1.toRaw().toString('hex'), cmpct1[0]);
assert.equal(cblock2.toRaw().toString('hex'), cmpct1[0]);
@ -388,6 +392,8 @@ describe('Block', function() {
var map = {};
var i, tx, result, mempool;
assert(cblock1.init());
assert.equal(cblock1.toRaw().toString('hex'), cmpct2);
assert.equal(cblock2.toRaw().toString('hex'), cmpct2);
@ -423,6 +429,8 @@ describe('Block', function() {
var map = {};
var i, tx, mid, keys, mempool, result, req, res;
assert(cblock1.init());
assert.equal(cblock1.toRaw().toString('hex'), cmpct2);
assert.equal(cblock2.toRaw().toString('hex'), cmpct2);