예제 #1
0
 /**
  * @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);
     }
 }
예제 #2
0
 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);
 }
예제 #3
0
 /**
  * @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;
     });
 }
예제 #4
0
 /**
  * @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]);
     });
 }
예제 #5
0
 /**
  * @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]);
 }
예제 #6
0
 /**
  * @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()]);
     }
 }
예제 #7
0
 /**
  * @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);
     }
 }
예제 #8
0
 /**
  * @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);
     }
 }
예제 #9
0
 /**
  * @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);
     }
 }
예제 #10
0
 /**
  * @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()]);
     }
 }
예제 #11
0
 /**
  * @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);
     });
 }
예제 #12
0
 /**
  * @param PeerState $state
  * @param Peer $peer
  * @param Ping $ping
  */
 public function onPing(PeerState $state, Peer $peer, Ping $ping)
 {
     $peer->pong($ping);
 }
예제 #13
0
 /**
  * @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;
 }
예제 #15
0
 /**
  * @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;
 }
예제 #16
0
 /**
  * @param \BitWasp\Bitcoin\Networking\Peer\Peer $peer
  */
 public function attachPeer(Peer $peer)
 {
     $peer->on('msg', function (Peer $peer, NetworkMessage $message) {
         $this->onPacket($peer, $message);
     });
 }