docs: function Peer(options) {
    /* jshint maxstatements: 26 */
    /* jshint maxcomplexity: 8 */
  
    if (!(this instanceof Peer)) {
      return new Peer(options);
    }
  
    if (options.socket) {
      this.socket = options.socket;
      this.host = this.socket.remoteAddress;
      this.port = this.socket.remotePort;
      this.status = Peer.STATUS.CONNECTED;
      this._addSocketEventHandlers();
    } else {
      this.host = options.host || 'localhost';
      this.status = Peer.STATUS.DISCONNECTED;
      this.port = options.port;
    }
  
    this.network = Networks.get(options.network) || Networks.defaultNetwork;
  
    if (!this.port) {
      this.port = this.network.port;
    }
  
    this.messages = options.messages || new Messages({
      network: this.network,
      Block: bitcore.Block,
      Transaction: bitcore.Transaction
    });
  
    this.dataBuffer = new Buffers();
  
    this.version = 0;
    this.bestHeight = 0;
    this.subversion = null;
    this.relay = options.relay === false ? false : true;
  
    this.versionSent = false;
  
    // set message handlers
    var self = this;
    this.on('verack', function() {
      self.status = Peer.STATUS.READY;
      self.emit('ready');
    });
  
    this.on('version', function(message) {
      self.version = message.version;
      self.subversion = message.subversion;
      self.bestHeight = message.startHeight;
  
      var verackResponse = self.messages.VerAck();
      self.sendMessage(verackResponse);
  
      if(!self.versionSent) {
        self._sendVersion();
      }
    });
  
    this.on('ping', function(message) {
      self._sendPong(message.nonce);
    });
  
    return this;
  
  }