/** * @param ChainState $state * @param ChainCache $chainView * @param Peer $peer * @param Inventory[] $items */ public function advertised(ChainState $state, ChainCache $chainView, Peer $peer, array $items) { $chain = $state->getChain(); $fetch = []; $lastUnknown = null; foreach ($items as $inv) { $hash = $inv->getHash(); if ($chain->containsHash($hash)) { if (!$chainView->containsHash($hash)) { $fetch[] = $inv; } } else { $lastUnknown = $hash; } } if (null !== $lastUnknown) { echo "send headers\n"; $peer->getheaders($state->getHeadersLocator($lastUnknown)); $this->peerState->fetch($peer)->updateBlockAvailability($state, $lastUnknown); } if (count($fetch) > 0) { echo 'SEND GETDATA:' . count($fetch) . '\\n'; $peer->getdata($fetch); } }
public function testPeer() { $localhost = '127.0.0.1'; $localport = '8333'; $remotehost = '127.0.0.1'; $remoteport = '9999'; $loop = new StreamSelectLoop(); $dnsResolverFactory = new \React\Dns\Resolver\Factory(); $dns = $dnsResolverFactory->createCached('8.8.8.8', $loop); $reactServer = new Server($loop); $network = Bitcoin::getDefaultNetwork(); $client = new NetworkAddress(Buffer::hex('0000000000000001'), $localhost, $localport); $server = new NetworkAddress(Buffer::hex('0000000000000001'), $remotehost, $remoteport); $msgs = new Factory($network, new Random()); $serverReceivedConnection = false; $serverListener = new Listener($server, $msgs, $reactServer, $loop); $serverListener->on('connection', function (Peer $peer) use(&$serverReceivedConnection, &$serverListener) { $peer->close(); $serverReceivedConnection = true; }); $serverListener->listen($server->getPort()); $connector = new Connector($loop, $dns); $clientConnection = new Peer($client, $msgs, $loop); $clientConnection->connect($connector, $server)->then(function (Peer $peer) use($serverListener, &$loop) { $peer->close(); $serverListener->close(); }); $loop->run(); $this->assertTrue($serverReceivedConnection); }
/** * @param NetworkAddressInterface $remotePeer * @return \React\Promise\PromiseInterface */ public function rawConnect(NetworkAddressInterface $remotePeer) { return $this->socketConnector->create($remotePeer->getIp()->getHost(), $remotePeer->getPort())->then(function (Stream $stream) { $peer = new Peer($this->msgs, $this->eventLoop); $peer->setupStream($stream); return $peer; }); }
/** * @param Peer $peer */ public function add(Peer $peer) { $counter = $this->c++; $this->storage[$counter] = $peer; $peer->on('close', function () use($counter) { unset($this->storage[$counter]); }); }
/** * @param Peer $peer */ public function registerInboundPeer(Peer $peer) { $next = $this->nInPeers++; $this->inPeers[$next] = $peer; $peer->on('close', function () use($next) { unset($this->inPeers[$next]); }); $this->emit('inbound', [$peer]); }
/** * @param PeerState $state * @param Peer $peer * @param GetHeaders $getHeaders */ public function onGetHeaders(PeerState $state, Peer $peer, GetHeaders $getHeaders) { return; $chain = $this->node->chain(); if ($chain->getIndex()->getHeader()->getTimestamp() >= time() - 60 * 60 * 24) { $locator = $getHeaders->getLocator(); if (count($locator->getHashes()) === 0) { $start = $locator->getHashStop(); } else { $start = $this->db->findFork($chain, $locator); } $headers = $this->db->fetchNextHeaders($start); $peer->headers($headers); $this->debug->log('peer.sentheaders', ['count' => count($headers), 'start' => $start->getHex()]); } }
/** * @param ChainViewInterface $headerChain * @param Peer $peer */ public function requestNextBlocks(ChainViewInterface $headerChain, Peer $peer) { if (null === $this->lastRequested) { $nextData = $this->nextInventory($headerChain); } else { $nextData = $this->relativeNextInventory($headerChain, $this->lastRequested); } if (count($nextData) > 0) { $last = null; foreach ($nextData as $inv) { $last = $inv->getHash(); $this->inFlight[$last->getBinary()] = 1; } $this->lastRequested = $last; $peer->getdata($nextData); } }
/** * @param ChainState $state * @param Peer $peer * @throws \RuntimeException * @throws \Exception */ public function requestNextBlocks(ChainState $state, Peer $peer) { /** @var Inventory[] $nextData */ if (null === $this->lastRequested) { $nextData = $this->nextInventory($state); } else { $nextData = $this->relativeNextInventory($state, $this->lastRequested); } if (count($nextData) > 0) { $last = null; foreach ($nextData as $inv) { $last = $inv->getHash(); $this->inFlight[$last->getHex()] = 1; } $this->lastRequested = $last; $peer->getdata($nextData); } }
/** * @param ChainViewInterface $headerChain * @param GuidedChainView $blockChain * @param Peer $peer * @param array $items */ public function advertised(ChainViewInterface $headerChain, GuidedChainView $blockChain, Peer $peer, array $items) { $fetch = []; $lastUnknown = null; foreach ($items as $inv) { $hash = $inv->getHash(); if ($headerChain->containsHash($hash)) { if (!$blockChain->containsHash($hash)) { $fetch[] = $inv; } } else { $lastUnknown = $hash; } } if (null !== $lastUnknown) { $peer->getheaders($headerChain->getHeadersLocator($lastUnknown)); $this->peerState->fetch($peer)->updateBlockAvailability($headerChain, $lastUnknown); } }
/** * @param PeerState $state * @param Peer $peer * @param Headers $headersMsg */ public function onHeaders(PeerState $state, Peer $peer, Headers $headersMsg) { $headers = $this->node->headers(); try { $vHeaders = $headersMsg->getHeaders(); $batch = $headers->prepareBatch($vHeaders); $count = count($batch->getIndices()); if ($count > 0) { $headers->applyBatch($batch); $view = $batch->getTip(); $indices = $batch->getIndices(); $indexLast = end($indices); $state->updateBlockAvailability($view, $indexLast->getHash()); if ($count >= 1999) { $peer->getheaders($view->getHeadersLocator()); } } $this->emit('headers', [$state, $peer, $batch]); } catch (\Exception $e) { $this->debug->log('error.onHeaders', ['error' => $e->getMessage(), 'trace' => $e->getTraceAsString()]); } }
/** * @param Peer $peer */ public function initPeer(Peer $peer) { $self = $this; $peer->on('inv', array($self, 'onInv')); $peer->on('tx', array($self, 'onTx')); $peer->on('block', array($self, 'onBlock')); $this->on('tx', function (TransactionInterface $tx) { $this->processTransaction($tx); }); }
/** * @param PeerState $state * @param Peer $peer * @param Ping $ping */ public function onPing(PeerState $state, Peer $peer, Ping $ping) { $peer->pong($ping); }
/** * @param Peer $peer * @return bool */ public function checkAcceptablePeer(Peer $peer) { $remote = $peer->getRemoteVersion(); if ($remote->getVersion() < Protocol::GETHEADERS) { return false; } if ($this->config->getItem('config', 'download_blocks', true) && $remote->getServices() & Services::NETWORK == 0) { return false; } return true; }
/** * @param Peer $sender * @param TransactionSignatureInterface $txSig * @return TransactionSignatureInterface */ public function fixSig(Peer $sender, TransactionSignatureInterface $txSig, &$wasMalleated = false) { $sig = $txSig->getSignature(); if (!$this->adapter->validateSignatureElement($sig->getS(), true)) { $ip = $sender->getRemoteAddr()->getIp(); if (!isset($this->violators[$ip])) { $this->violators[$sender->getRemoteAddr()->getIp()] = 1; } else { $this->violators[$sender->getRemoteAddr()->getIp()]++; } $wasMalleated = true; $this->counter++; $txSig = new TransactionSignature($this->adapter, new Signature($this->adapter, $sig->getR(), $this->math->sub($this->order, $sig->getS())), $txSig->getHashType()); if (!$this->adapter->validateSignatureElement($txSig->getSignature()->getS(), true)) { die('failed to produce a low-s signature'); } } return $txSig; }
/** * @param Peer $peer * @param GetHeaders $getHeaders */ public function onGetHeaders(Peer $peer, GetHeaders $getHeaders) { return; $chain = $this->chain()->getChain(); $locator = $getHeaders->getLocator(); if (count($locator->getHashes()) === 0) { $start = $locator->getHashStop()->getHex(); } else { $start = $this->db->findFork($chain, $locator); } $headers = $this->db->fetchNextHeaders($start); $peer->headers($headers); echo 'Sending from ' . $start . ' + ' . count($headers) . ' headers ' . PHP_EOL; }
/** * @param \BitWasp\Bitcoin\Networking\Peer\Peer $peer */ public function attachPeer(Peer $peer) { $peer->on('msg', function (Peer $peer, NetworkMessage $message) { $this->onPacket($peer, $message); }); }