/** * @param NetworkAddressInterface $remotePeer * @return \React\Promise\PromiseInterface */ public function connect(NetworkAddressInterface $remotePeer) { return $this->rawConnect($remotePeer)->then(function (Peer $peer) use($remotePeer) { return $peer->outboundHandshake($remotePeer, $this->params); })->then(function (Peer $peer) { $reqService = $this->params->getRequiredServices(); if ($reqService != 0) { if ($reqService != ($peer->getRemoteVersion()->getServices() & $reqService)) { return new RejectedPromise('peer does not satisfy required services'); } } return $peer; }); }
/** * @param NetworkAddressInterface $remotePeer * @param ConnectionParams $params * @return \React\Promise\Promise|\React\Promise\PromiseInterface */ public function outboundHandshake(NetworkAddressInterface $remotePeer, ConnectionParams $params) { $deferred = new Deferred(); $awaitVersion = true; $this->stream->on('close', function () use(&$awaitVersion, $deferred) { if ($awaitVersion) { $awaitVersion = false; $deferred->reject('peer disconnected'); } }); $this->on(Message::VERSION, function (Peer $peer, Version $version) use($params) { $this->remoteVersion = $version; $this->verack(); }); $this->on(Message::VERACK, function () use($deferred) { if (false === $this->exchangedVersion) { $this->exchangedVersion = true; $this->emit('ready', [$this]); $deferred->resolve($this); } }); $this->peerAddress = $remotePeer; $this->localVersion = $version = $params->produceVersion($this->msgs, $remotePeer); $this->connectionParams = $params; $this->send($version); return $deferred->promise(); }