Connector::connect()   A
last analyzed

Complexity

Conditions 3
Paths 1

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3.0987

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 1
nop 1
dl 0
loc 15
ccs 7
cts 9
cp 0.7778
crap 3.0987
rs 9.9332
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitWasp\Bitcoin\Networking\Peer;
6
7
use BitWasp\Bitcoin\Networking\Messages\Factory as MsgFactory;
8
use BitWasp\Bitcoin\Networking\Structure\NetworkAddress;
9
use BitWasp\Bitcoin\Networking\Structure\NetworkAddressInterface;
10
use React\EventLoop\LoopInterface;
11
use React\Promise\RejectedPromise;
12
use React\Socket\ConnectionInterface;
13
14
class Connector
15
{
16
    /**
17
     * @var ConnectionParams
18
     */
19
    private $params;
20
21
    /**
22
     * @var MsgFactory
23
     */
24
    private $msgs;
25
26
    /**
27
     * @var LoopInterface
28
     */
29
    private $eventLoop;
30
31
    /**
32
     * @var \React\Socket\Connector
33
     */
34
    private $socketConnector;
35
36
    /**
37
     * Connector constructor.
38
     * @param MsgFactory $msgs
39
     * @param ConnectionParams $params
40
     * @param LoopInterface $loop
41
     * @param array $settings
42
     */
43 12
    public function __construct(MsgFactory $msgs, ConnectionParams $params, LoopInterface $loop, array $settings)
44
    {
45 12
        $this->params = $params;
46 12
        $this->msgs = $msgs;
47 12
        $this->eventLoop = $loop;
48 12
        $this->socketConnector = new \React\Socket\Connector($loop, $settings);
49 12
    }
50 8
51
    /**
52 12
     * @param NetworkAddressInterface $remotePeer
53 12
     * @return \React\Promise\PromiseInterface
54
     */
55
    public function rawConnect(NetworkAddressInterface $remotePeer)
56
    {
57
        return $this->socketConnector
58
            ->connect("tcp://{$remotePeer->getIp()->getHost()}:{$remotePeer->getPort()}")
59 12
            ->then(function (ConnectionInterface $stream) {
60
                $peer = new Peer($this->msgs, $this->eventLoop);
61 12
                $peer->setupStream($stream);
62 12
                return $peer;
63
            });
64 12
    }
65 12
66 12
    /**
67 12
     * @param NetworkAddress $remotePeer
68
     * @return \React\Promise\PromiseInterface
69
     */
70
    public function connect(NetworkAddress $remotePeer)
71
    {
72
        return $this
73
            ->rawConnect($remotePeer)
74 12
            ->then(function (Peer $peer) use ($remotePeer) {
75
                return $peer->outboundHandshake($remotePeer, $this->params);
76 8
            })->then(function (Peer $peer) {
77 12
                $reqService = $this->params->getRequiredServices();
78
                if ($reqService != 0) {
79 12
                    if ($reqService != ($peer->getRemoteVersion()->getServices() & $reqService)) {
80 12
                        return new RejectedPromise(new \RuntimeException('peer does not satisfy required services'));
81 9
                    }
82 9
                }
83
                
84
                return $peer;
85
            });
86
    }
87
}
88