peer: refactor version packet handling.
This commit is contained in:
parent
212a69697e
commit
db49f44c8a
@ -532,10 +532,10 @@ RPC.prototype.getpeerinfo = co(function* getpeerinfo(args) {
|
||||
? (peer.lastPong - peer.lastPing) / 1000
|
||||
: -1,
|
||||
minping: peer.minPing !== -1 ? peer.minPing / 1000 : -1,
|
||||
version: peer.version ? peer.version.version : 0,
|
||||
subver: peer.version ? peer.version.agent : '',
|
||||
version: peer.version,
|
||||
subver: peer.agent,
|
||||
inbound: !peer.outbound,
|
||||
startingheight: peer.version ? peer.version.height : -1,
|
||||
startingheight: peer.height,
|
||||
banscore: peer.banScore,
|
||||
inflight: peer.requestMap.keys().map(util.revHex),
|
||||
whitelisted: false
|
||||
|
||||
@ -333,15 +333,10 @@ BIP150.prototype.findAuthorized = function findAuthorized(hash) {
|
||||
*/
|
||||
|
||||
BIP150.prototype.destroy = function destroy() {
|
||||
if (this.timeout != null) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
}
|
||||
if (!this.job)
|
||||
return;
|
||||
|
||||
if (this.onAuth) {
|
||||
this.removeListener('auth', this.onAuth);
|
||||
this.onAuth = null;
|
||||
}
|
||||
this.reject(new Error('BIP150 stream was destroyed.'));
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -547,15 +547,10 @@ BIP151.prototype._wait = function wait(timeout, resolve, reject) {
|
||||
*/
|
||||
|
||||
BIP151.prototype.destroy = function destroy() {
|
||||
if (this.timeout != null) {
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = null;
|
||||
}
|
||||
if (!this.job)
|
||||
return;
|
||||
|
||||
if (this.onShake) {
|
||||
this.removeListener('handshake', this.onShake);
|
||||
this.onShake = null;
|
||||
}
|
||||
this.reject(new Error('BIP151 stream was destroyed.'));
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@ -25,6 +25,38 @@ exports.PROTOCOL_VERSION = 70015;
|
||||
|
||||
exports.MIN_VERSION = 70001;
|
||||
|
||||
/**
|
||||
* Minimum version for getheaders.
|
||||
* @const {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.HEADERS_VERSION = 31800;
|
||||
|
||||
/**
|
||||
* Minimum version for bip37.
|
||||
* @const {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.BLOOM_VERSION = 70011;
|
||||
|
||||
/**
|
||||
* Minimum version for bip152.
|
||||
* @const {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.SENDHEADERS_VERSION = 7012;
|
||||
|
||||
/**
|
||||
* Minimum version for bip152.
|
||||
* @const {Number}
|
||||
* @default
|
||||
*/
|
||||
|
||||
exports.COMPACT_VERSION = 70014;
|
||||
|
||||
/**
|
||||
* Service bits.
|
||||
* @enum {Number}
|
||||
|
||||
@ -59,18 +59,17 @@ exports.types = {
|
||||
MERKLEBLOCK: 21,
|
||||
GETUTXOS: 22,
|
||||
UTXOS: 23,
|
||||
HAVEWITNESS: 24,
|
||||
FEEFILTER: 25,
|
||||
SENDCMPCT: 26,
|
||||
CMPCTBLOCK: 27,
|
||||
GETBLOCKTXN: 28,
|
||||
BLOCKTXN: 29,
|
||||
ENCINIT: 30,
|
||||
ENCACK: 31,
|
||||
AUTHCHALLENGE: 32,
|
||||
AUTHREPLY: 33,
|
||||
AUTHPROPOSE: 34,
|
||||
UNKNOWN: 35,
|
||||
FEEFILTER: 24,
|
||||
SENDCMPCT: 25,
|
||||
CMPCTBLOCK: 26,
|
||||
GETBLOCKTXN: 27,
|
||||
BLOCKTXN: 28,
|
||||
ENCINIT: 29,
|
||||
ENCACK: 30,
|
||||
AUTHCHALLENGE: 31,
|
||||
AUTHREPLY: 32,
|
||||
AUTHPROPOSE: 33,
|
||||
UNKNOWN: 34,
|
||||
// Internal
|
||||
INTERNAL: 100,
|
||||
DATA: 101
|
||||
@ -283,71 +282,6 @@ VersionPacket.prototype.toRaw = function toRaw() {
|
||||
return this.toWriter(new StaticWriter(size)).render();
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the NETWORK service bit is set.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
VersionPacket.prototype.hasNetwork = function hasNetwork() {
|
||||
return (this.services & common.services.NETWORK) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the BLOOM service bit is set.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
VersionPacket.prototype.hasBloom = function hasBloom() {
|
||||
return this.version >= 70011
|
||||
&& (this.services & common.services.BLOOM) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the GETUTXO service bit is set.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
VersionPacket.prototype.hasUTXO = function hasUTXO() {
|
||||
return (this.services & common.services.GETUTXO) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the WITNESS service bit is set.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
VersionPacket.prototype.hasWitness = function hasWitness() {
|
||||
return (this.services & common.services.WITNESS) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether required services are available.
|
||||
* @param {Number} services
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
VersionPacket.prototype.hasServices = function hasServices(services) {
|
||||
return (this.services & services) === services;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the protocol version supports getheaders.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
VersionPacket.prototype.hasHeaders = function hasHeaders() {
|
||||
return this.version >= 31800;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the protocol version supports bip152.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
VersionPacket.prototype.hasCompact = function hasCompact() {
|
||||
return this.version >= 70014;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inject properties from buffer reader.
|
||||
* @private
|
||||
@ -2821,47 +2755,6 @@ UTXOsPacket.fromRaw = function fromRaw(data, enc) {
|
||||
return new UTXOsPacket().fromRaw(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a `havewitness` packet.
|
||||
* @exports HaveWitnessPacket
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
function HaveWitnessPacket() {
|
||||
if (!(this instanceof HaveWitnessPacket))
|
||||
return new HaveWitnessPacket();
|
||||
|
||||
Packet.call(this);
|
||||
}
|
||||
|
||||
util.inherits(HaveWitnessPacket, Packet);
|
||||
|
||||
HaveWitnessPacket.prototype.cmd = 'havewitness';
|
||||
HaveWitnessPacket.prototype.type = exports.types.HAVEWITNESS;
|
||||
|
||||
/**
|
||||
* Instantiate havewitness packet from buffer reader.
|
||||
* @param {BufferReader} br
|
||||
* @returns {HaveWitnessPacket}
|
||||
*/
|
||||
|
||||
HaveWitnessPacket.fromReader = function fromReader(br) {
|
||||
return new HaveWitnessPacket().fromReader(br);
|
||||
};
|
||||
|
||||
/**
|
||||
* Instantiate havewitness packet from serialized data.
|
||||
* @param {Buffer} data
|
||||
* @param {String?} enc
|
||||
* @returns {HaveWitnessPacket}
|
||||
*/
|
||||
|
||||
HaveWitnessPacket.fromRaw = function fromRaw(data, enc) {
|
||||
if (typeof data === 'string')
|
||||
data = new Buffer(data, enc);
|
||||
return new HaveWitnessPacket().fromRaw(data);
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a `feefilter` packet.
|
||||
* @exports FeeFilterPacket
|
||||
@ -3973,8 +3866,6 @@ exports.fromRaw = function fromRaw(cmd, data) {
|
||||
return GetUTXOsPacket.fromRaw(data);
|
||||
case 'utxos':
|
||||
return UTXOsPacket.fromRaw(data);
|
||||
case 'havewitness':
|
||||
return HaveWitnessPacket.fromRaw(data);
|
||||
case 'feefilter':
|
||||
return FeeFilterPacket.fromRaw(data);
|
||||
case 'sendcmpct':
|
||||
@ -4029,7 +3920,6 @@ exports.FilterClearPacket = FilterClearPacket;
|
||||
exports.MerkleBlockPacket = MerkleBlockPacket;
|
||||
exports.GetUTXOsPacket = GetUTXOsPacket;
|
||||
exports.UTXOsPacket = UTXOsPacket;
|
||||
exports.HaveWitnessPacket = HaveWitnessPacket;
|
||||
exports.FeeFilterPacket = FeeFilterPacket;
|
||||
exports.SendCmpctPacket = SendCmpctPacket;
|
||||
exports.CmpctBlockPacket = CmpctBlockPacket;
|
||||
|
||||
147
lib/net/peer.js
147
lib/net/peer.js
@ -28,6 +28,7 @@ var TX = require('../primitives/tx');
|
||||
var encoding = require('../utils/encoding');
|
||||
var errors = require('../protocol/errors');
|
||||
var NetAddress = require('../primitives/netaddress');
|
||||
var services = common.services;
|
||||
var invTypes = InvItem.types;
|
||||
var packetTypes = packets.types;
|
||||
var VerifyResult = errors.VerifyResult;
|
||||
@ -48,15 +49,13 @@ var VerifyResult = errors.VerifyResult;
|
||||
* @property {Framer} framer
|
||||
* @property {Chain} chain
|
||||
* @property {Mempool} mempool
|
||||
* @property {Object?} version - Version packet payload.
|
||||
* @property {Number} version
|
||||
* @property {Boolean} destroyed
|
||||
* @property {Boolean} ack - Whether verack has been received.
|
||||
* @property {Boolean} connected
|
||||
* @property {Number} ts
|
||||
* @property {Boolean} preferHeaders - Whether the peer has
|
||||
* requested getheaders.
|
||||
* @property {Boolean} haveWitness - Whether the peer supports segwit,
|
||||
* either notified via service bits or deprecated `havewitness` packet.
|
||||
* @property {Hash?} hashContinue - The block hash at which to continue
|
||||
* the sync for the peer.
|
||||
* @property {Bloom?} spvFilter - The _peer's_ bloom spvFilter.
|
||||
@ -94,6 +93,7 @@ function Peer(pool) {
|
||||
this.connected = false;
|
||||
this.destroyed = false;
|
||||
this.ack = false;
|
||||
this.handshake = false;
|
||||
this.ts = 0;
|
||||
this.lastSend = 0;
|
||||
this.lastRecv = 0;
|
||||
@ -103,12 +103,14 @@ function Peer(pool) {
|
||||
this.banScore = 0;
|
||||
this.invQueue = [];
|
||||
|
||||
this.version = null;
|
||||
this.version = -1;
|
||||
this.services = 0;
|
||||
this.height = -1;
|
||||
this.agent = null;
|
||||
this.noRelay = false;
|
||||
this.preferHeaders = false;
|
||||
this.haveWitness = false;
|
||||
this.hashContinue = null;
|
||||
this.spvFilter = null;
|
||||
this.noRelay = false;
|
||||
this.feeRate = -1;
|
||||
this.bip151 = null;
|
||||
this.bip150 = null;
|
||||
@ -490,6 +492,8 @@ Peer.prototype.initStall = function initStall() {
|
||||
*/
|
||||
|
||||
Peer.prototype.initBIP151 = co(function* initBIP151() {
|
||||
assert(!this.destroyed);
|
||||
|
||||
// Send encinit. Wait for handshake to complete.
|
||||
if (!this.bip151)
|
||||
return;
|
||||
@ -523,9 +527,12 @@ Peer.prototype.initBIP151 = co(function* initBIP151() {
|
||||
*/
|
||||
|
||||
Peer.prototype.initBIP150 = co(function* initBIP150() {
|
||||
if (!this.bip151 || !this.bip150)
|
||||
assert(!this.destroyed);
|
||||
|
||||
if (!this.bip150)
|
||||
return;
|
||||
|
||||
assert(this.bip151);
|
||||
assert(!this.bip150.completed);
|
||||
|
||||
if (!this.bip151.handshake)
|
||||
@ -562,34 +569,29 @@ Peer.prototype.initVersion = co(function* initVersion() {
|
||||
// Say hello.
|
||||
this.sendVersion();
|
||||
|
||||
// Advertise our address.
|
||||
if (!this.pool.address.isNull()
|
||||
&& !this.options.selfish
|
||||
&& this.pool.server) {
|
||||
this.send(new packets.AddrPacket([this.pool.address]));
|
||||
}
|
||||
|
||||
if (!this.ack) {
|
||||
yield this.wait(packetTypes.VERACK, 10000);
|
||||
assert(this.ack);
|
||||
}
|
||||
|
||||
// Wait for _their_ version.
|
||||
if (!this.version) {
|
||||
if (this.version === -1) {
|
||||
this.logger.debug(
|
||||
'Peer sent a verack without a version (%s).',
|
||||
this.hostname);
|
||||
|
||||
yield this.wait(packetTypes.VERSION, 10000);
|
||||
|
||||
assert(this.version);
|
||||
assert(this.version !== -1);
|
||||
}
|
||||
|
||||
this.logger.debug('Received verack (%s).', this.hostname);
|
||||
this.handshake = true;
|
||||
|
||||
this.logger.debug('Version handshake complete (%s).', this.hostname);
|
||||
});
|
||||
|
||||
/**
|
||||
* Handle `ack` event (called on verack).
|
||||
* Finalize peer after handshake.
|
||||
* @private
|
||||
*/
|
||||
|
||||
@ -608,15 +610,22 @@ Peer.prototype.finalize = co(function* finalize() {
|
||||
self.flushInv();
|
||||
}, Peer.INV_INTERVAL);
|
||||
|
||||
// Advertise our address.
|
||||
if (!this.pool.address.isNull()
|
||||
&& !this.options.selfish
|
||||
&& this.options.listen) {
|
||||
this.send(new packets.AddrPacket([this.pool.address]));
|
||||
}
|
||||
|
||||
// Ask for headers-only.
|
||||
if (this.options.headers) {
|
||||
if (this.version.version >= 70012)
|
||||
if (this.version >= common.SENDHEADERS_VERSION)
|
||||
this.send(new packets.SendHeadersPacket());
|
||||
}
|
||||
|
||||
// We want compact blocks!
|
||||
if (this.options.compact) {
|
||||
if (this.version.version >= 70014)
|
||||
if (this.version >= common.COMPACT_VERSION)
|
||||
this.sendCompact();
|
||||
}
|
||||
|
||||
@ -656,7 +665,7 @@ Peer.prototype.announceBlock = function announceBlock(blocks) {
|
||||
var inv = [];
|
||||
var i, block;
|
||||
|
||||
if (!this.ack)
|
||||
if (!this.handshake)
|
||||
return;
|
||||
|
||||
if (this.destroyed)
|
||||
@ -709,7 +718,7 @@ Peer.prototype.announceTX = function announceTX(txs) {
|
||||
var inv = [];
|
||||
var i, tx, hash, entry;
|
||||
|
||||
if (!this.ack)
|
||||
if (!this.handshake)
|
||||
return;
|
||||
|
||||
if (this.destroyed)
|
||||
@ -796,7 +805,7 @@ Peer.prototype.sendInv = function sendInv(items) {
|
||||
var hasBlock = false;
|
||||
var i, item;
|
||||
|
||||
if (!this.ack)
|
||||
if (!this.handshake)
|
||||
return;
|
||||
|
||||
if (this.destroyed)
|
||||
@ -857,7 +866,7 @@ Peer.prototype.flushInv = function flushInv() {
|
||||
Peer.prototype.sendHeaders = function sendHeaders(items) {
|
||||
var i, item, chunk;
|
||||
|
||||
if (!this.ack)
|
||||
if (!this.handshake)
|
||||
return;
|
||||
|
||||
if (this.destroyed)
|
||||
@ -918,10 +927,10 @@ Peer.prototype.sendGetAddr = function sendGetAddr() {
|
||||
*/
|
||||
|
||||
Peer.prototype.sendPing = function sendPing() {
|
||||
if (!this.version)
|
||||
if (!this.handshake)
|
||||
return;
|
||||
|
||||
if (this.version.version <= 60000) {
|
||||
if (this.version <= 60000) {
|
||||
this.send(new packets.PingPacket());
|
||||
return;
|
||||
}
|
||||
@ -942,7 +951,7 @@ Peer.prototype.sendPing = function sendPing() {
|
||||
*/
|
||||
|
||||
Peer.prototype.updateWatch = function updateWatch() {
|
||||
if (!this.ack)
|
||||
if (!this.handshake)
|
||||
return;
|
||||
|
||||
if (!this.options.spv)
|
||||
@ -957,7 +966,7 @@ Peer.prototype.updateWatch = function updateWatch() {
|
||||
*/
|
||||
|
||||
Peer.prototype.sendFeeRate = function sendFeeRate(rate) {
|
||||
if (!this.ack)
|
||||
if (!this.handshake)
|
||||
return;
|
||||
|
||||
this.send(new packets.FeeFilterPacket(rate));
|
||||
@ -1321,7 +1330,7 @@ Peer.prototype.blockType = function blockType() {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.haveWitness)
|
||||
if (this.hasWitness())
|
||||
return invTypes.WITNESS_BLOCK;
|
||||
|
||||
return invTypes.BLOCK;
|
||||
@ -1333,7 +1342,7 @@ Peer.prototype.blockType = function blockType() {
|
||||
*/
|
||||
|
||||
Peer.prototype.txType = function txType() {
|
||||
if (this.haveWitness)
|
||||
if (this.hasWitness())
|
||||
return invTypes.WITNESS_TX;
|
||||
|
||||
return invTypes.TX;
|
||||
@ -1434,7 +1443,7 @@ Peer.prototype.onPacket = co(function* onPacket(packet) {
|
||||
&& !this.bip151.completed
|
||||
&& packet.type !== packetTypes.ENCINIT
|
||||
&& packet.type !== packetTypes.ENCACK) {
|
||||
this.bip151.complete(new Error('Message before handshake.'));
|
||||
this.bip151.reject(new Error('Message before handshake.'));
|
||||
}
|
||||
|
||||
if (this.bip150
|
||||
@ -1442,7 +1451,7 @@ Peer.prototype.onPacket = co(function* onPacket(packet) {
|
||||
&& packet.type !== packetTypes.AUTHCHALLENGE
|
||||
&& packet.type !== packetTypes.AUTHREPLY
|
||||
&& packet.type !== packetTypes.AUTHPROPOSE) {
|
||||
this.bip150.complete(new Error('Message before auth.'));
|
||||
this.bip150.reject(new Error('Message before auth.'));
|
||||
}
|
||||
|
||||
if (this.lastMerkle) {
|
||||
@ -1525,9 +1534,6 @@ Peer.prototype.onPacket = co(function* onPacket(packet) {
|
||||
case packetTypes.UTXOS:
|
||||
yield this.handleUTXOs(packet);
|
||||
break;
|
||||
case packetTypes.HAVEWITNESS:
|
||||
yield this.handleHaveWitness(packet);
|
||||
break;
|
||||
case packetTypes.FEEFILTER:
|
||||
yield this.handleFeeFilter(packet);
|
||||
break;
|
||||
@ -1750,17 +1756,6 @@ Peer.prototype.handleGetUTXOs = co(function* handleGetUTXOs(packet) {
|
||||
this.send(utxos);
|
||||
});
|
||||
|
||||
/**
|
||||
* Handle `havewitness` packet.
|
||||
* @private
|
||||
* @param {HaveWitnessPacket}
|
||||
*/
|
||||
|
||||
Peer.prototype.handleHaveWitness = co(function* handleHaveWitness(packet) {
|
||||
this.haveWitness = true;
|
||||
this.emit('havewitness');
|
||||
});
|
||||
|
||||
/**
|
||||
* Handle `getheaders` packet.
|
||||
* @private
|
||||
@ -1860,39 +1855,42 @@ Peer.prototype.handleGetBlocks = co(function* handleGetBlocks(packet) {
|
||||
*/
|
||||
|
||||
Peer.prototype.handleVersion = co(function* handleVersion(packet) {
|
||||
if (this.version)
|
||||
if (this.version !== -1)
|
||||
throw new Error('Peer sent a duplicate version.');
|
||||
|
||||
this.version = packet;
|
||||
this.version = packet.version;
|
||||
this.services = packet.services;
|
||||
this.height = packet.height;
|
||||
this.agent = packet.agent;
|
||||
this.noRelay = packet.noRelay;
|
||||
|
||||
if (this.options.witness)
|
||||
this.haveWitness = packet.hasWitness();
|
||||
|
||||
if (!this.network.selfConnect) {
|
||||
if (util.equal(packet.nonce, this.pool.nonce))
|
||||
throw new Error('We connected to ourself. Oops.');
|
||||
}
|
||||
|
||||
if (packet.version < common.MIN_VERSION)
|
||||
if (this.version < common.MIN_VERSION)
|
||||
throw new Error('Peer does not support required protocol version.');
|
||||
|
||||
if (this.outbound) {
|
||||
if (!packet.hasNetwork())
|
||||
if (!(this.services & services.NETWORK))
|
||||
throw new Error('Peer does not support network services.');
|
||||
|
||||
if (this.options.headers) {
|
||||
if (!packet.hasHeaders())
|
||||
if (this.version < common.HEADERS_VERSION)
|
||||
throw new Error('Peer does not support getheaders.');
|
||||
}
|
||||
|
||||
if (this.options.spv) {
|
||||
if (!packet.hasBloom())
|
||||
if (!(this.services & services.BLOOM))
|
||||
throw new Error('Peer does not support BIP37.');
|
||||
|
||||
if (this.version < common.BLOOM_VERSION)
|
||||
throw new Error('Peer does not support BIP37.');
|
||||
}
|
||||
|
||||
if (this.options.witness) {
|
||||
if (!this.haveWitness)
|
||||
if (!(this.services & services.WITNESS))
|
||||
throw new Error('Peer does not support segregated witness.');
|
||||
}
|
||||
}
|
||||
@ -1911,6 +1909,7 @@ Peer.prototype.handleVersion = co(function* handleVersion(packet) {
|
||||
Peer.prototype.handleVerack = co(function* handleVerack(packet) {
|
||||
this.ack = true;
|
||||
this.emit('verack');
|
||||
this.logger.debug('Received verack (%s).', this.hostname);
|
||||
});
|
||||
|
||||
/**
|
||||
@ -2797,7 +2796,7 @@ Peer.prototype.handleBlockTxn = co(function* handleBlockTxn(packet) {
|
||||
*/
|
||||
|
||||
Peer.prototype.sendAlert = function sendAlert(alert) {
|
||||
if (!this.ack)
|
||||
if (!this.handshake)
|
||||
return;
|
||||
|
||||
if (!this.invFilter.added(alert.hash()))
|
||||
@ -2872,13 +2871,10 @@ Peer.prototype.sendGetBlocks = function getBlocks(locator, stop) {
|
||||
*/
|
||||
|
||||
Peer.prototype.sendMempool = function sendMempool() {
|
||||
if (!this.ack)
|
||||
if (!this.handshake)
|
||||
return;
|
||||
|
||||
if (!this.version)
|
||||
return;
|
||||
|
||||
if (!this.version.hasBloom()) {
|
||||
if (!(this.services & services.BLOOM)) {
|
||||
this.logger.debug(
|
||||
'Cannot request mempool for non-bloom peer (%s).',
|
||||
this.hostname);
|
||||
@ -3026,16 +3022,16 @@ Peer.prototype.sync = co(function* sync() {
|
||||
if (!this.pool.syncing)
|
||||
return;
|
||||
|
||||
if (!this.ack)
|
||||
if (!this.handshake)
|
||||
return;
|
||||
|
||||
if (this.syncSent)
|
||||
return;
|
||||
|
||||
if (!this.version.hasNetwork())
|
||||
if (!(this.services & services.NETWORK))
|
||||
return;
|
||||
|
||||
if (this.options.witness && !this.haveWitness)
|
||||
if (this.options.witness && !this.hasWitness())
|
||||
return;
|
||||
|
||||
if (!this.isLoader()) {
|
||||
@ -3063,6 +3059,25 @@ Peer.prototype.sync = co(function* sync() {
|
||||
return yield this.getBlocks();
|
||||
});
|
||||
|
||||
/**
|
||||
* Test whether required services are available.
|
||||
* @param {Number} services
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Peer.prototype.hasServices = function hasServices(services) {
|
||||
return (this.services & services) === services;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the WITNESS service bit is set.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
Peer.prototype.hasWitness = function hasWitness() {
|
||||
return (this.services & services.WITNESS) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Inspect the peer.
|
||||
* @returns {String}
|
||||
@ -3070,7 +3085,7 @@ Peer.prototype.sync = co(function* sync() {
|
||||
|
||||
Peer.prototype.inspect = function inspect() {
|
||||
return '<Peer:'
|
||||
+ ' ack=' + this.ack
|
||||
+ ' handshake=' + this.handshake
|
||||
+ ' host=' + this.hostname
|
||||
+ ' outbound=' + this.outbound
|
||||
+ ' ping=' + this.minPing
|
||||
|
||||
@ -747,10 +747,10 @@ Pool.prototype.handleOpen = function handleOpen(peer) {
|
||||
if (!peer.outbound)
|
||||
return;
|
||||
|
||||
this.hosts.markAck(peer.hostname, peer.version.services);
|
||||
this.hosts.markAck(peer.hostname, peer.services);
|
||||
|
||||
// If we don't have an ack'd loader yet, use this peer.
|
||||
if (!this.peers.load || !this.peers.load.ack)
|
||||
if (!this.peers.load || !this.peers.load.handshake)
|
||||
this.setLoader(peer);
|
||||
};
|
||||
|
||||
@ -1091,7 +1091,7 @@ Pool.prototype._handleBlockInv = co(function* handleBlockInv(peer, hashes) {
|
||||
if (!this.chain.synced && !peer.isLoader())
|
||||
return;
|
||||
|
||||
if (this.options.witness && !peer.haveWitness)
|
||||
if (this.options.witness && !peer.hasWitness())
|
||||
return;
|
||||
|
||||
// Request headers instead.
|
||||
@ -1543,7 +1543,7 @@ Pool.prototype.getBlock = function getBlock(peer, hash) {
|
||||
if (!this.loaded)
|
||||
return;
|
||||
|
||||
if (!peer.ack)
|
||||
if (!peer.handshake)
|
||||
throw new Error('Peer handshake not complete (getdata).');
|
||||
|
||||
if (peer.destroyed)
|
||||
@ -1596,7 +1596,7 @@ Pool.prototype.getTX = function getTX(peer, hashes) {
|
||||
if (!this.loaded)
|
||||
return;
|
||||
|
||||
if (!peer.ack)
|
||||
if (!peer.handshake)
|
||||
throw new Error('Peer handshake not complete (getdata).');
|
||||
|
||||
if (peer.destroyed)
|
||||
|
||||
@ -95,42 +95,6 @@ NetAddress.fromOptions = function fromOptions(options) {
|
||||
return new NetAddress().fromOptions(options);
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the NETWORK service bit is set.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.hasNetwork = function hasNetwork() {
|
||||
return (this.services & common.services.NETWORK) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the BLOOM service bit is set.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.hasBloom = function hasBloom() {
|
||||
return (this.services & common.services.BLOOM) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the GETUTXO service bit is set.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.hasUTXO = function hasUTXO() {
|
||||
return (this.services & common.services.GETUTXO) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether the WITNESS service bit is set.
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
|
||||
NetAddress.prototype.hasWitness = function hasWitness() {
|
||||
return (this.services & common.services.WITNESS) !== 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Test whether required services are available.
|
||||
* @param {Number} services
|
||||
|
||||
Loading…
Reference in New Issue
Block a user