better system to prevent DOSing.
This commit is contained in:
parent
a2c08d9692
commit
47af5987ae
@ -489,7 +489,7 @@ Block.prototype.verifyContext = function verifyContext() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Block.prototype.isGenesis = function isGenesis() {
|
Block.prototype.isGenesis = function isGenesis() {
|
||||||
return this.hash('hex') === utils.toHex(network.genesis._hash);
|
return this.hash('hex') === network.genesis.hash;
|
||||||
};
|
};
|
||||||
|
|
||||||
Block.prototype.getHeight = function getHeight() {
|
Block.prototype.getHeight = function getHeight() {
|
||||||
|
|||||||
@ -56,9 +56,9 @@ function Chain(options) {
|
|||||||
network: network.type,
|
network: network.type,
|
||||||
entries: [
|
entries: [
|
||||||
{
|
{
|
||||||
hash: utils.toHex(network.genesis._hash),
|
hash: network.genesis.hash,
|
||||||
version: network.genesis.version,
|
version: network.genesis.version,
|
||||||
prevBlock: utils.toHex(network.genesis.prevBlock),
|
prevBlock: network.genesis.prevBlock,
|
||||||
ts: network.genesis.ts,
|
ts: network.genesis.ts,
|
||||||
bits: network.genesis.bits,
|
bits: network.genesis.bits,
|
||||||
height: 0
|
height: 0
|
||||||
@ -302,9 +302,8 @@ Chain.prototype.add = function add(block, peer) {
|
|||||||
code = Chain.codes.invalid;
|
code = Chain.codes.invalid;
|
||||||
this.emit('invalid', {
|
this.emit('invalid', {
|
||||||
height: prevHeight + 1,
|
height: prevHeight + 1,
|
||||||
hash: hash,
|
hash: hash
|
||||||
peer: peer
|
}, peer);
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,9 +321,8 @@ Chain.prototype.add = function add(block, peer) {
|
|||||||
height: -1,
|
height: -1,
|
||||||
expected: this.orphan.map[prevHash].hash('hex'),
|
expected: this.orphan.map[prevHash].hash('hex'),
|
||||||
received: hash,
|
received: hash,
|
||||||
checkpoint: null,
|
checkpoint: null
|
||||||
peer: peer
|
}, peer);
|
||||||
});
|
|
||||||
code = Chain.codes.forked;
|
code = Chain.codes.forked;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -383,9 +381,8 @@ Chain.prototype.add = function add(block, peer) {
|
|||||||
height: prevHeight + 1,
|
height: prevHeight + 1,
|
||||||
expected: tip.hash,
|
expected: tip.hash,
|
||||||
received: hash,
|
received: hash,
|
||||||
checkpoint: null,
|
checkpoint: null
|
||||||
peer: peer
|
}, peer);
|
||||||
});
|
|
||||||
code = Chain.codes.forked;
|
code = Chain.codes.forked;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -397,9 +394,8 @@ Chain.prototype.add = function add(block, peer) {
|
|||||||
code = Chain.codes.invalid;
|
code = Chain.codes.invalid;
|
||||||
this.emit('invalid', {
|
this.emit('invalid', {
|
||||||
height: prevHeight + 1,
|
height: prevHeight + 1,
|
||||||
hash: hash,
|
hash: hash
|
||||||
peer: peer
|
}, peer);
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -422,8 +418,7 @@ Chain.prototype.add = function add(block, peer) {
|
|||||||
height: entry.height,
|
height: entry.height,
|
||||||
expected: network.checkpoints[entry.height],
|
expected: network.checkpoints[entry.height],
|
||||||
received: entry.hash,
|
received: entry.hash,
|
||||||
checkpoint: true,
|
checkpoint: true
|
||||||
peer: peer
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -483,17 +478,14 @@ Chain.prototype.add = function add(block, peer) {
|
|||||||
return total;
|
return total;
|
||||||
};
|
};
|
||||||
|
|
||||||
Chain.prototype.has = function has(hash, cb) {
|
Chain.prototype.has = function has(hash) {
|
||||||
if (this.loading) {
|
if (this.hasBlock(hash))
|
||||||
this.once('load', function() {
|
return true;
|
||||||
this.has(hash, noIndex, cb);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cb = utils.asyncify(cb);
|
if (this.hasOrphan(hash))
|
||||||
|
return true;
|
||||||
|
|
||||||
return cb(this.hasBlock(hash) || this.hasOrphan(hash));
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
Chain.prototype.byHeight = function byHeight(height) {
|
Chain.prototype.byHeight = function byHeight(height) {
|
||||||
|
|||||||
@ -113,7 +113,7 @@ Peer.prototype._init = function init() {
|
|||||||
|
|
||||||
this.socket.once('error', function(err) {
|
this.socket.once('error', function(err) {
|
||||||
self._error(err);
|
self._error(err);
|
||||||
self.emit('misbehave');
|
self.pool.misbehaving(self, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.socket.once('close', function() {
|
this.socket.once('close', function() {
|
||||||
@ -134,7 +134,7 @@ Peer.prototype._init = function init() {
|
|||||||
// Something is wrong here.
|
// Something is wrong here.
|
||||||
// Ignore this peer.
|
// Ignore this peer.
|
||||||
self.destroy();
|
self.destroy();
|
||||||
self.emit('misbehave');
|
self.pool.misbehaving(self, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.pool.options.fullNode) {
|
if (this.pool.options.fullNode) {
|
||||||
@ -156,7 +156,7 @@ Peer.prototype._init = function init() {
|
|||||||
if (err) {
|
if (err) {
|
||||||
self._error(err);
|
self._error(err);
|
||||||
self.destroy();
|
self.destroy();
|
||||||
self.emit('misbehave');
|
self.pool.misbehaving(self, 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self.ack = true;
|
self.ack = true;
|
||||||
|
|||||||
@ -12,6 +12,7 @@ var bcoin = require('../bcoin');
|
|||||||
var utils = bcoin.utils;
|
var utils = bcoin.utils;
|
||||||
var assert = utils.assert;
|
var assert = utils.assert;
|
||||||
var network = bcoin.protocol.network;
|
var network = bcoin.protocol.network;
|
||||||
|
var constants = bcoin.protocol.constants;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pool
|
* Pool
|
||||||
@ -40,9 +41,6 @@ function Pool(options) {
|
|||||||
|
|
||||||
this.originalSeeds = (options.seeds || network.seeds).map(utils.parseHost);
|
this.originalSeeds = (options.seeds || network.seeds).map(utils.parseHost);
|
||||||
this.setSeeds([]);
|
this.setSeeds([]);
|
||||||
this._priorityTries = {};
|
|
||||||
this._regularTries = {};
|
|
||||||
this._misbehaving = {};
|
|
||||||
|
|
||||||
this.storage = this.options.storage;
|
this.storage = this.options.storage;
|
||||||
this.destroyed = false;
|
this.destroyed = false;
|
||||||
@ -112,13 +110,21 @@ function Pool(options) {
|
|||||||
// Peers that are loading block ids
|
// Peers that are loading block ids
|
||||||
load: null,
|
load: null,
|
||||||
// All peers
|
// All peers
|
||||||
all: []
|
all: [],
|
||||||
|
// Misbehaving hosts
|
||||||
|
misbehaving: {},
|
||||||
|
// Attempts at using seed peers
|
||||||
|
tries: {
|
||||||
|
priority: {},
|
||||||
|
regular: {}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.block = {
|
this.block = {
|
||||||
bestHeight: 0,
|
bestHeight: 0,
|
||||||
bestHash: null,
|
bestHash: null,
|
||||||
type: this.options.fullNode ? 'block' : 'filtered'
|
type: this.options.fullNode ? 'block' : 'filtered',
|
||||||
|
invalid: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.request = {
|
this.request = {
|
||||||
@ -179,36 +185,36 @@ Pool.prototype._init = function _init() {
|
|||||||
self.emit('block', block, peer);
|
self.emit('block', block, peer);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.chain.on('fork', function(data) {
|
this.chain.on('fork', function(data, peer) {
|
||||||
self.emit('debug',
|
self.emit('debug',
|
||||||
'Fork at height %d: expected=%s received=%s checkpoint=%s peer=%s',
|
'Fork at height %d: expected=%s received=%s checkpoint=%s peer=%s',
|
||||||
data.height,
|
data.height,
|
||||||
utils.revHex(data.expected),
|
utils.revHex(data.expected),
|
||||||
utils.revHex(data.received),
|
utils.revHex(data.received),
|
||||||
data.checkpoint,
|
data.checkpoint,
|
||||||
data.peer ? data.peer.host : ''
|
peer ? peer.host : ''
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!data.peer)
|
if (!peer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
data.peer.destroy();
|
self.misbehaving(peer, 100);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.chain.on('invalid', function(data) {
|
this.chain.on('invalid', function(data, peer) {
|
||||||
self.emit('debug',
|
self.emit('debug',
|
||||||
'Invalid block at height: %d: hash=%s peer=%s',
|
'Invalid block at height: %d: hash=%s peer=%s',
|
||||||
data.height,
|
data.height,
|
||||||
utils.revHex(data.hash),
|
utils.revHex(data.hash),
|
||||||
data.peer ? data.peer.host : ''
|
peer ? peer.host : ''
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!data.peer)
|
self.block.invalid[data.hash] = true;
|
||||||
|
|
||||||
|
if (!peer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// We should technically use a ban score
|
self.misbehaving(peer, 100);
|
||||||
// here instead of killing the peer.
|
|
||||||
data.peer.destroy();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.options.wallets.forEach(function(w) {
|
this.options.wallets.forEach(function(w) {
|
||||||
@ -536,10 +542,12 @@ Pool.prototype._handleInv = function _handleInv(hashes, peer) {
|
|||||||
|
|
||||||
Pool.prototype._handleBlock = function _handleBlock(block, peer) {
|
Pool.prototype._handleBlock = function _handleBlock(block, peer) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
var requested, hasPrev;
|
||||||
|
|
||||||
var requested = this._response(block);
|
// Fulfill our request.
|
||||||
|
requested = this._response(block);
|
||||||
|
|
||||||
// Emulate bip37 - emit all the "watched" txs
|
// Emulate BIP37: emit all the filtered transactions.
|
||||||
if (this.options.fullNode && this.listeners('watched').length > 0) {
|
if (this.options.fullNode && this.listeners('watched').length > 0) {
|
||||||
block.txs.forEach(function(tx) {
|
block.txs.forEach(function(tx) {
|
||||||
if (self.isWatched(tx))
|
if (self.isWatched(tx))
|
||||||
@ -547,21 +555,39 @@ Pool.prototype._handleBlock = function _handleBlock(block, peer) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore if we already have
|
// Ensure the block was not invalid last time.
|
||||||
if (this.chain.has(block)) {
|
// Someone might be sending us bad blocks to DoS us.
|
||||||
this.emit('debug', 'Already have block %s (%s)', block.height, peer.host);
|
if (this.block.invalid[block.hash('hex')]) {
|
||||||
|
this.misbehaving(peer, 100);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure the block is valid
|
// Ensure this is not a continuation
|
||||||
|
// of an invalid chain.
|
||||||
|
if (this.block.invalid[block.prevBlock]) {
|
||||||
|
this.misbehaving(peer, 100);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore if we already have.
|
||||||
|
if (this.chain.has(block)) {
|
||||||
|
this.emit('debug', 'Already have block %s (%s)', block.height, peer.host);
|
||||||
|
this.misbehaving(peer, 1);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure the block is valid.
|
||||||
if (!block.verify()) {
|
if (!block.verify()) {
|
||||||
this.emit('debug',
|
this.emit('debug',
|
||||||
'Block verification failed for %s (%s)',
|
'Block verification failed for %s (%s)',
|
||||||
block.rhash, peer.host);
|
block.rhash, peer.host);
|
||||||
|
this.block.invalid[block.hash('hex')] = true;
|
||||||
|
this.misbehaving(peer, 100);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Someone is sending us blocks without us requesting them.
|
// Someone is sending us blocks without
|
||||||
|
// us requesting them.
|
||||||
if (!requested) {
|
if (!requested) {
|
||||||
this.emit('debug',
|
this.emit('debug',
|
||||||
'Recieved unrequested block: %s (%s)',
|
'Recieved unrequested block: %s (%s)',
|
||||||
@ -571,19 +597,40 @@ Pool.prototype._handleBlock = function _handleBlock(block, peer) {
|
|||||||
// Resolve orphan chain
|
// Resolve orphan chain
|
||||||
if (!this.options.headers) {
|
if (!this.options.headers) {
|
||||||
if (!this.chain.hasBlock(block.prevBlock)) {
|
if (!this.chain.hasBlock(block.prevBlock)) {
|
||||||
|
// Special case for genesis block.
|
||||||
|
if (block.isGenesis())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Make sure the peer doesn't send us
|
||||||
|
// more than 100 orphans every 3 minutes.
|
||||||
|
if (this.orphaning(peer)) {
|
||||||
|
this.misbehaving(peer, 100);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: If we were to emit new orphans here, we
|
// NOTE: If we were to emit new orphans here, we
|
||||||
// would not need to store full blocks as orphans.
|
// would not need to store full blocks as orphans.
|
||||||
// However, the listener would not be able to see
|
// However, the listener would not be able to see
|
||||||
// the height until later.
|
// the height until later.
|
||||||
if (this._addIndex(block, peer))
|
if (this._addIndex(block, peer))
|
||||||
this.emit('pool block', block, peer);
|
this.emit('pool block', block, peer);
|
||||||
|
|
||||||
this.peers.load.loadBlocks(
|
this.peers.load.loadBlocks(
|
||||||
this.chain.locatorHashes(),
|
this.chain.locatorHashes(),
|
||||||
this.chain.getOrphanRoot(block)
|
this.chain.getOrphanRoot(block)
|
||||||
);
|
);
|
||||||
|
|
||||||
this.emit('debug', 'Handled orphan %s (%s)', block.rhash, peer.host);
|
this.emit('debug', 'Handled orphan %s (%s)', block.rhash, peer.host);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!this.chain.hasBlock(block.prevBlock)) {
|
||||||
|
if (!this.options.multiplePeers) {
|
||||||
|
if (this.misbehaving(peer, 10))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add to index and emit/save
|
// Add to index and emit/save
|
||||||
@ -688,10 +735,6 @@ Pool.prototype._createPeer = function _createPeer(backoff, priority) {
|
|||||||
self.emit.apply(self, ['debug'].concat(args));
|
self.emit.apply(self, ['debug'].concat(args));
|
||||||
});
|
});
|
||||||
|
|
||||||
peer.once('misbehave', function() {
|
|
||||||
self._misbehaving[peer.host] = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
peer.on('reject', function(payload) {
|
peer.on('reject', function(payload) {
|
||||||
var data = utils.revHex(utils.toHex(payload.data));
|
var data = utils.revHex(utils.toHex(payload.data));
|
||||||
|
|
||||||
@ -1203,37 +1246,31 @@ Pool.prototype.search = function search(id, range, e) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Pool.prototype._request = function _request(type, hash, options, cb) {
|
Pool.prototype._request = function _request(type, hash, options, cb) {
|
||||||
var self = this;
|
|
||||||
|
|
||||||
// Optional `force`
|
|
||||||
if (typeof options === 'function') {
|
if (typeof options === 'function') {
|
||||||
cb = options;
|
cb = options;
|
||||||
options = {};
|
options = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options)
|
if (!options)
|
||||||
options = {};
|
options = {};
|
||||||
|
|
||||||
hash = utils.toHex(hash);
|
hash = utils.toHex(hash);
|
||||||
|
|
||||||
if (this.request.map[hash])
|
if (this.request.map[hash])
|
||||||
return this.request.map[hash].addCallback(cb);
|
return this.request.map[hash].addCallback(cb);
|
||||||
|
|
||||||
function next(has) {
|
|
||||||
if (has)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (self.destroyed)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var req = new LoadRequest(self, type, hash, cb);
|
|
||||||
req.add(options.noQueue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Block should be not in chain, or be requested
|
// Block should be not in chain, or be requested
|
||||||
// Do not use with headers-first
|
// Do not use with headers-first
|
||||||
if (!options.force && (type === 'block' || type === 'filtered'))
|
if (!options.force && (type === 'block' || type === 'filtered')) {
|
||||||
return this.chain.has(hash, next);
|
if (this.chain.has(hash))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
return next(false);
|
if (this.destroyed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var req = new LoadRequest(this, type, hash, cb);
|
||||||
|
req.add(options.noQueue);
|
||||||
};
|
};
|
||||||
|
|
||||||
Pool.prototype._response = function _response(entity) {
|
Pool.prototype._response = function _response(entity) {
|
||||||
@ -1498,7 +1535,10 @@ Pool.prototype.usableSeed = function usableSeed(priority, connecting) {
|
|||||||
var i, addr;
|
var i, addr;
|
||||||
var original = this.originalSeeds;
|
var original = this.originalSeeds;
|
||||||
var seeds = this.seeds;
|
var seeds = this.seeds;
|
||||||
var tries = priority ? this._priorityTries : this._regularTries;
|
var tries = this.peers.tries.regular;
|
||||||
|
|
||||||
|
if (priority)
|
||||||
|
tries = this.peers.tries.priority;
|
||||||
|
|
||||||
// Hang back if we don't have a loader peer yet.
|
// Hang back if we don't have a loader peer yet.
|
||||||
if (!connecting && !priority && (!this.peers.load || !this.peers.load.socket))
|
if (!connecting && !priority && (!this.peers.load || !this.peers.load.socket))
|
||||||
@ -1516,7 +1556,7 @@ Pool.prototype.usableSeed = function usableSeed(priority, connecting) {
|
|||||||
assert(addr.host);
|
assert(addr.host);
|
||||||
if (this.getPeer(addr))
|
if (this.getPeer(addr))
|
||||||
continue;
|
continue;
|
||||||
if (this._misbehaving[addr.host])
|
if (this.isMisbehaving(addr.host))
|
||||||
continue;
|
continue;
|
||||||
if (tries[addr.host])
|
if (tries[addr.host])
|
||||||
continue;
|
continue;
|
||||||
@ -1533,7 +1573,7 @@ Pool.prototype.usableSeed = function usableSeed(priority, connecting) {
|
|||||||
assert(addr.host);
|
assert(addr.host);
|
||||||
if (this.peers.load && this.getPeer(addr) === this.peers.load)
|
if (this.peers.load && this.getPeer(addr) === this.peers.load)
|
||||||
continue;
|
continue;
|
||||||
if (this._misbehaving[addr.host])
|
if (this.isMisbehaving(addr.host))
|
||||||
continue;
|
continue;
|
||||||
if (tries[addr.host])
|
if (tries[addr.host])
|
||||||
continue;
|
continue;
|
||||||
@ -1549,7 +1589,7 @@ Pool.prototype.usableSeed = function usableSeed(priority, connecting) {
|
|||||||
assert(addr.host);
|
assert(addr.host);
|
||||||
if (this.getPeer(addr))
|
if (this.getPeer(addr))
|
||||||
continue;
|
continue;
|
||||||
if (this._misbehaving[addr.host])
|
if (this.isMisbehaving(addr.host))
|
||||||
continue;
|
continue;
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
@ -1562,7 +1602,7 @@ Pool.prototype.usableSeed = function usableSeed(priority, connecting) {
|
|||||||
assert(addr.host);
|
assert(addr.host);
|
||||||
if (this.peers.load && this.getPeer(addr) === this.peers.load)
|
if (this.peers.load && this.getPeer(addr) === this.peers.load)
|
||||||
continue;
|
continue;
|
||||||
if (this._misbehaving[addr.host])
|
if (this.isMisbehaving(addr.host))
|
||||||
continue;
|
continue;
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
@ -1622,6 +1662,64 @@ Pool.prototype.removeSeed = function removeSeed(seed) {
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Pool.prototype.orphaning = function orphaning(peer) {
|
||||||
|
if (!peer._orphanTime)
|
||||||
|
peer._orphanTime = utils.now();
|
||||||
|
|
||||||
|
if (!peer._orphans)
|
||||||
|
peer._orphans = 0;
|
||||||
|
|
||||||
|
if (utils.now() > peer._orphanTime + 3 * 60) {
|
||||||
|
peer._orphans = 0;
|
||||||
|
peer._orphanTime = utils.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
peer._orphans += 1;
|
||||||
|
|
||||||
|
if (peer._orphans > 100)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Pool.prototype.misbehaving = function misbehaving(peer, dos) {
|
||||||
|
if (!peer._banscore)
|
||||||
|
peer._banscore = 0;
|
||||||
|
|
||||||
|
peer._banscore += dos;
|
||||||
|
|
||||||
|
if (peer._banscore >= constants.banScore) {
|
||||||
|
this.peers.misbehaving[peer.host] = utils.now();
|
||||||
|
this.emit('debug', 'Ban threshold exceeded for %s', peer.host);
|
||||||
|
peer.destroy();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Pool.prototype.isMisbehaving = function isMisbehaving(host) {
|
||||||
|
var peer, time;
|
||||||
|
|
||||||
|
if (host.host)
|
||||||
|
host = host.host;
|
||||||
|
|
||||||
|
time = this.peers.misbehaving[host];
|
||||||
|
|
||||||
|
if (time) {
|
||||||
|
if (utils.now() > time + constants.banTime) {
|
||||||
|
delete this.peers.misbehaving[host];
|
||||||
|
peer = this.getPeer(host);
|
||||||
|
if (peer)
|
||||||
|
peer._banscore = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
Pool.prototype.toJSON = function toJSON() {
|
Pool.prototype.toJSON = function toJSON() {
|
||||||
return {
|
return {
|
||||||
v: 1,
|
v: 1,
|
||||||
|
|||||||
@ -262,3 +262,6 @@ exports.userAgent = '/bcoin:' + exports.userVersion + '/';
|
|||||||
exports.coin = new bn(10000000).muln(10);
|
exports.coin = new bn(10000000).muln(10);
|
||||||
exports.cent = new bn(1000000);
|
exports.cent = new bn(1000000);
|
||||||
exports.maxMoney = new bn(21000000).mul(exports.coin);
|
exports.maxMoney = new bn(21000000).mul(exports.coin);
|
||||||
|
|
||||||
|
exports.banTime = 24 * 60 * 60;
|
||||||
|
exports.banScore = 100;
|
||||||
|
|||||||
@ -88,18 +88,17 @@ main.halvingInterval = 210000;
|
|||||||
// http://blockexplorer.com/rawblock/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
|
// http://blockexplorer.com/rawblock/000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f
|
||||||
main.genesis = {
|
main.genesis = {
|
||||||
version: 1,
|
version: 1,
|
||||||
_hash: utils.toArray(
|
hash: utils.revHex(
|
||||||
'000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f',
|
'000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'
|
||||||
'hex'
|
),
|
||||||
).reverse(),
|
prevBlock: utils.toHex(
|
||||||
prevBlock: [ 0, 0, 0, 0, 0, 0, 0, 0,
|
[ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0 ],
|
0, 0, 0, 0, 0, 0, 0, 0 ]),
|
||||||
merkleRoot: utils.toArray(
|
merkleRoot: utils.revHex(
|
||||||
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',
|
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
|
||||||
'hex'
|
),
|
||||||
).reverse(),
|
|
||||||
ts: 1231006505,
|
ts: 1231006505,
|
||||||
bits: 0x1d00ffff,
|
bits: 0x1d00ffff,
|
||||||
nonce: 2083236893
|
nonce: 2083236893
|
||||||
@ -113,9 +112,9 @@ main.preload = {
|
|||||||
network: main.type,
|
network: main.type,
|
||||||
entries: [
|
entries: [
|
||||||
{
|
{
|
||||||
hash: utils.toHex(main.genesis._hash),
|
hash: main.genesis.hash,
|
||||||
version: main.genesis.version,
|
version: main.genesis.version,
|
||||||
prevBlock: utils.toHex(main.genesis.prevBlock),
|
prevBlock: main.genesis.prevBlock,
|
||||||
ts: main.genesis.ts,
|
ts: main.genesis.ts,
|
||||||
bits: main.genesis.bits,
|
bits: main.genesis.bits,
|
||||||
height: 0
|
height: 0
|
||||||
@ -203,18 +202,17 @@ testnet.halvingInterval = 210000;
|
|||||||
// http://blockexplorer.com/testnet/rawblock/000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943
|
// http://blockexplorer.com/testnet/rawblock/000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943
|
||||||
testnet.genesis = {
|
testnet.genesis = {
|
||||||
version: 1,
|
version: 1,
|
||||||
_hash: utils.toArray(
|
hash: utils.revHex(
|
||||||
'000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943',
|
'000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943'
|
||||||
'hex'
|
),
|
||||||
).reverse(),
|
prevBlock: utils.toHex(
|
||||||
prevBlock: [ 0, 0, 0, 0, 0, 0, 0, 0,
|
[ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0 ],
|
0, 0, 0, 0, 0, 0, 0, 0 ]),
|
||||||
merkleRoot: utils.toArray(
|
merkleRoot: utils.revHex(
|
||||||
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',
|
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
|
||||||
'hex'
|
),
|
||||||
).reverse(),
|
|
||||||
ts: 1296688602,
|
ts: 1296688602,
|
||||||
bits: 0x1d00ffff,
|
bits: 0x1d00ffff,
|
||||||
nonce: 414098458
|
nonce: 414098458
|
||||||
@ -228,9 +226,9 @@ testnet.preload = {
|
|||||||
network: testnet.type,
|
network: testnet.type,
|
||||||
entries: [
|
entries: [
|
||||||
{
|
{
|
||||||
hash: utils.toHex(testnet.genesis._hash),
|
hash: testnet.genesis.hash,
|
||||||
version: testnet.genesis.version,
|
version: testnet.genesis.version,
|
||||||
prevBlock: utils.toHex(testnet.genesis.prevBlock),
|
prevBlock: testnet.genesis.prevBlock,
|
||||||
ts: testnet.genesis.ts,
|
ts: testnet.genesis.ts,
|
||||||
bits: testnet.genesis.bits,
|
bits: testnet.genesis.bits,
|
||||||
height: 0
|
height: 0
|
||||||
@ -300,18 +298,17 @@ regtest.halvingInterval = 150;
|
|||||||
|
|
||||||
regtest.genesis = {
|
regtest.genesis = {
|
||||||
version: 1,
|
version: 1,
|
||||||
_hash: utils.toArray(
|
hash: utils.revHex(
|
||||||
'0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206',
|
'0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206'
|
||||||
'hex'
|
),
|
||||||
).reverse(),
|
prevBlock: utils.toHex(
|
||||||
prevBlock: [ 0, 0, 0, 0, 0, 0, 0, 0,
|
[ 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0 ],
|
0, 0, 0, 0, 0, 0, 0, 0 ]),
|
||||||
merkleRoot: utils.toArray(
|
merkleRoot: utils.revHex(
|
||||||
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',
|
'4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b'
|
||||||
'hex'
|
),
|
||||||
).reverse(),
|
|
||||||
ts: 1296688602,
|
ts: 1296688602,
|
||||||
bits: 0x207fffff,
|
bits: 0x207fffff,
|
||||||
nonce: 2
|
nonce: 2
|
||||||
@ -325,9 +322,9 @@ regtest.preload = {
|
|||||||
network: regtest.type,
|
network: regtest.type,
|
||||||
entries: [
|
entries: [
|
||||||
{
|
{
|
||||||
hash: utils.toHex(regtest.genesis._hash),
|
hash: regtest.genesis.hash,
|
||||||
version: regtest.genesis.version,
|
version: regtest.genesis.version,
|
||||||
prevBlock: utils.toHex(regtest.genesis.prevBlock),
|
prevBlock: regtest.genesis.prevBlock,
|
||||||
ts: regtest.genesis.ts,
|
ts: regtest.genesis.ts,
|
||||||
bits: regtest.genesis.bits,
|
bits: regtest.genesis.bits,
|
||||||
height: 0
|
height: 0
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user