Bit-Wasp /
bitcoin-p2p-php
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace BitWasp\Bitcoin\Networking\Peer; |
||
| 4 | |||
| 5 | use BitWasp\Bitcoin\Networking\Structure\NetworkAddressInterface; |
||
| 6 | use Evenement\EventEmitter; |
||
| 7 | use React\Promise\Deferred; |
||
| 8 | |||
| 9 | class Manager extends EventEmitter |
||
| 10 | { |
||
| 11 | /** |
||
| 12 | * @var Connector |
||
| 13 | */ |
||
| 14 | private $connector; |
||
| 15 | |||
| 16 | /** |
||
| 17 | * @var Peer[] |
||
| 18 | */ |
||
| 19 | private $outPeers = []; |
||
| 20 | |||
| 21 | /** |
||
| 22 | * @var Peer[] |
||
| 23 | */ |
||
| 24 | private $inPeers = []; |
||
| 25 | |||
| 26 | /** |
||
| 27 | * @var int |
||
| 28 | */ |
||
| 29 | private $nOutPeers = 0; |
||
| 30 | |||
| 31 | /** |
||
| 32 | * @var int |
||
| 33 | */ |
||
| 34 | private $nInPeers = 0; |
||
| 35 | |||
| 36 | /** |
||
| 37 | * Manager constructor. |
||
| 38 | * @param Connector $connector |
||
| 39 | */ |
||
| 40 | public function __construct(Connector $connector) |
||
| 41 | { |
||
| 42 | $this->connector = $connector; |
||
| 43 | } |
||
| 44 | |||
| 45 | 12 | /** |
|
| 46 | * Store the newly connected peer, and trigger a new connection if they go away. |
||
| 47 | 12 | * |
|
| 48 | 12 | * @param Peer $peer |
|
| 49 | 12 | * @return Peer |
|
| 50 | */ |
||
| 51 | public function registerOutboundPeer(Peer $peer) |
||
| 52 | { |
||
| 53 | $next = $this->nOutPeers++; |
||
| 54 | $peer->on('close', function ($peer) use ($next) { |
||
| 55 | $this->emit('disconnect', [$peer]); |
||
| 56 | unset($this->outPeers[$next]); |
||
| 57 | 6 | }); |
|
| 58 | |||
| 59 | 6 | $this->outPeers[$next] = $peer; |
|
| 60 | $this->emit('outbound', [$peer]); |
||
| 61 | 3 | return $peer; |
|
| 62 | 3 | } |
|
| 63 | 6 | ||
| 64 | /** |
||
| 65 | 6 | * @param Peer $peer |
|
| 66 | 6 | */ |
|
| 67 | 6 | public function registerInboundPeer(Peer $peer) |
|
| 68 | { |
||
| 69 | $next = $this->nInPeers++; |
||
| 70 | $this->inPeers[$next] = $peer; |
||
| 71 | $peer->on('close', function () use ($next) { |
||
| 72 | unset($this->inPeers[$next]); |
||
| 73 | 3 | }); |
|
| 74 | $this->emit('inbound', [$peer]); |
||
| 75 | 3 | } |
|
| 76 | 3 | ||
| 77 | /** |
||
| 78 | * @param Listener $listener |
||
| 79 | 3 | * @return $this |
|
| 80 | 3 | */ |
|
| 81 | 3 | public function registerListener(Listener $listener) |
|
| 82 | { |
||
| 83 | $listener->on('connection', function (Peer $peer) { |
||
| 84 | $this->registerInboundPeer($peer); |
||
| 85 | }); |
||
| 86 | |||
| 87 | 3 | return $this; |
|
| 88 | } |
||
| 89 | |||
| 90 | 3 | /** |
|
| 91 | 3 | * @param NetworkAddressInterface $address |
|
| 92 | * @return \React\Promise\Promise|\React\Promise\PromiseInterface |
||
| 93 | 3 | * @throws \Exception |
|
| 94 | */ |
||
| 95 | public function connect(NetworkAddressInterface $address) |
||
| 96 | { |
||
| 97 | return $this->connector->connect($address); |
||
|
0 ignored issues
–
show
Bug
Compatibility
introduced
by
Loading history...
|
|||
| 98 | } |
||
| 99 | |||
| 100 | /** |
||
| 101 | * @param Locator $locator |
||
| 102 | * @return \React\Promise\ExtendedPromiseInterface|\React\Promise\Promise|static |
||
| 103 | */ |
||
| 104 | public function connectNextPeer(Locator $locator) |
||
| 105 | { |
||
| 106 | $deferred = new Deferred(); |
||
| 107 | |||
| 108 | // Otherwise, rely on the Locator. |
||
| 109 | try { |
||
| 110 | $deferred->resolve($locator->popAddress()); |
||
| 111 | } catch (\Exception $e) { |
||
| 112 | $locator->queryDnsSeeds()->then( |
||
| 113 | function () use ($deferred, $locator) { |
||
| 114 | $deferred->resolve($locator->popAddress()); |
||
| 115 | } |
||
| 116 | 6 | ); |
|
| 117 | } |
||
| 118 | 6 | ||
| 119 | 6 | return $deferred |
|
| 120 | 3 | ->promise() |
|
| 121 | 3 | ->then( |
|
| 122 | function (NetworkAddressInterface $address) { |
||
| 123 | 6 | return $this->connect($address)->then( |
|
| 124 | function (Peer $peer) { |
||
| 125 | 6 | $this->registerOutboundPeer($peer); |
|
| 126 | 6 | return $peer; |
|
| 127 | } |
||
| 128 | 6 | ); |
|
| 129 | 6 | } |
|
| 130 | ) |
||
| 131 | 2 | ->otherwise(function () use ($locator) { |
|
| 132 | 2 | return $this->connectNextPeer($locator); |
|
| 133 | 6 | }); |
|
| 134 | } |
||
| 135 | 6 | ||
| 136 | /** |
||
| 137 | * Create $n connections to clients available in the PeerLocator |
||
| 138 | * @param int $n |
||
| 139 | * |
||
| 140 | * @param Locator $locator |
||
| 141 | * @param $n |
||
| 142 | 6 | * @return null|\React\Promise\FulfilledPromise|\React\Promise\Promise|\React\Promise\PromiseInterface|\React\Promise\RejectedPromise|static |
|
| 143 | */ |
||
| 144 | 6 | public function connectToPeers(Locator $locator, $n) |
|
| 145 | { |
||
| 146 | $peers = []; |
||
| 147 | for ($i = 0; $i < $n; $i++) { |
||
| 148 | 6 | $peers[$i] = $this->connectNextPeer($locator); |
|
| 149 | 6 | } |
|
| 150 | |||
| 151 | return \React\Promise\all($peers); |
||
| 152 | } |
||
| 153 | } |
||
| 154 |