/** * @param ChainViewInterface $view * @param BufferInterface $hash */ public function updateBlockAvailability(ChainViewInterface $view, BufferInterface $hash) { if ($view->containsHash($hash)) { $this->save(self::INDEXBESTKNOWNBLOCK, $hash); } else { $this->save(self::HASHLASTUNKNOWNBLOCK, $hash); } }
/** * @param ChainViewInterface $headerChain * @param BufferInterface $startHash * @throws \RuntimeException * @throws \Exception * @return Inventory[] */ private function relativeNextInventory(ChainViewInterface $headerChain, BufferInterface $startHash) { if (!$headerChain->containsHash($startHash)) { throw new \RuntimeException('Hash not found in this chain'); } $startHeight = $headerChain->getHeightFromHash($startHash) + 1; $stopHeight = min($startHeight + self::DOWNLOAD_AMOUNT, $headerChain->getIndex()->getHeight()); $nInFlight = count($this->inFlight); $request = []; for ($i = $startHeight; $i < $stopHeight && $nInFlight < self::MAX_IN_FLIGHT; $i++) { $request[] = Inventory::block($headerChain->getHashFromHeight($i)); $nInFlight++; } return $request; }
/** * @param BufferInterface $hash * @return int */ public function getHeightFromHash(BufferInterface $hash) { if (!$this->containsHash($hash)) { throw new \RuntimeException('Hash not found'); } return $this->view->getHeightFromHash($hash); }
/** * @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 ChainViewInterface $view * @return GuidedChainView */ public function blocksView(ChainViewInterface $view) { return new GuidedChainView($this, $view, $this->segmentBlock->offsetGet($view->getSegment())); }
/** * @param ChainViewInterface $view * @param int $numAncestors * @return array */ public function findSuperMajorityInfoByView(ChainViewInterface $view, $numAncestors = 1000) { $tipHeight = $view->getIndex()->getHeight(); $min = max($tipHeight - $numAncestors, 0); $pointer = $tipHeight; $history = $view->getHistory(); $values = []; $query = []; $c = 0; while ($pointer !== $min && count($history) > 0) { /** * @var ChainSegment $segment */ $segment = array_pop($history); $end = $segment->getLast()->getHeight(); if ($end !== $pointer) { throw new \RuntimeException('Pointer inconsistent'); } $size = min($numAncestors, $end - $segment->getStart()); $start = $end - $size; $values['segid' . $c] = $segment->getId(); $values['heightlast' . $c] = $end; $values['heightstart' . $c] = $start; $query[] = "SELECT h.version from headerIndex h where h.segment = :segid" . $c . " AND h.height BETWEEN :heightstart" . $c . " AND :heightlast" . $c; $pointer -= $size; $c++; } $query = implode("UNION ALL", $query); $statement = $this->dbh->prepare($query); $statement->execute($values); $results = $statement->fetchAll(\PDO::FETCH_COLUMN); return $results; }
/** * @param Transactions $txIndex * @param BufferInterface $txid * @return TransactionInterface */ public function fetchTransaction(Transactions $txIndex, BufferInterface $txid) { return $txIndex->fetch($this->view->getIndex()->getHash(), $txid); }