예제 #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
 /**
  * @param ChainState $state
  * @param Buffer $hash
  */
 public function updateBlockAvailability(ChainState $state, Buffer $hash)
 {
     $chain = $state->getChain();
     if ($chain->containsHash($hash)) {
         echo 'update peers BESTKNOWN block (' . $chain->getHeightFromHash($hash) . ')' . PHP_EOL;
         $this->save(self::INDEXBESTKNOWNBLOCK, $hash);
     } else {
         echo 'update peers HASH UNKNOWN block' . PHP_EOL;
         $this->save(self::HASHLASTUNKNOWNBLOCK, $hash);
     }
 }
예제 #3
0
 /**
  * @param ChainState $state
  * @param Buffer $startHash
  * @throws \RuntimeException
  * @throws \Exception
  * @return array
  */
 private function relativeNextInventory(ChainState $state, Buffer $startHash)
 {
     $best = $state->getChain();
     if (!$best->containsHash($startHash)) {
         throw new \RuntimeException('Hash not found in this chain');
     }
     $startHeight = $best->getHeightFromHash($startHash) + 1;
     $stopHeight = min($startHeight + self::DOWNLOAD_AMOUNT, $best->getIndex()->getHeight());
     $nInFlight = count($this->inFlight);
     $request = [];
     for ($i = $startHeight; $i < $stopHeight && $nInFlight < self::MAX_IN_FLIGHT; $i++) {
         $request[] = Inventory::block($best->getHashFromHeight($i));
         $nInFlight++;
     }
     return $request;
 }
예제 #4
0
 /**
  * @param ChainState $state
  * @return int|string
  */
 public function getWorkRequired(ChainState $state)
 {
     $math = $this->math;
     $index = $state->getChain()->getIndex();
     if ($math->cmp($math->mod($math->add($index->getHeight(), 1), $this->params->powRetargetInterval()), 0) != 0) {
         // No change in difficulty
         return $index->getHeader()->getBits()->getInt();
     }
     // Retarget
     $heightLastRetarget = $math->sub($index->getHeight(), $math->sub($this->params->powRetargetInterval(), 1));
     $lastTime = $state->getChain()->fetchAncestor($heightLastRetarget)->getHeader()->getTimestamp();
     return $this->calculateNextWorkRequired($index, $lastTime);
 }
예제 #5
0
 /**
  * @param ChainState $state
  * @param BlockHeaderInterface[] $headers
  * @return bool
  * @throws \Exception
  */
 public function acceptBatch(ChainState $state, array $headers)
 {
     $tip = $state->getChain();
     $batch = array();
     $startIndex = $tip->getIndex();
     foreach ($headers as $header) {
         if ($tip->containsHash($header->getHash())) {
             continue;
         }
         $prevIndex = $tip->getIndex();
         if ($prevIndex->getHash() !== $header->getPrevBlock()) {
             throw new \RuntimeException('Header mismatch, header.prevBlock does not refer to tip');
         }
         $index = $this->headerCheck->check($header)->checkContextual($state, $header)->makeIndex($prevIndex, $header);
         $tip->updateTip($index);
         $batch[] = $tip->getIndex();
     }
     // Do a batch update of the chain
     if (count($batch) > 0) {
         $this->db->insertIndexBatch($startIndex, $batch);
         unset($batch);
     }
     return true;
 }
예제 #6
0
 public function compareChainStateWork(ChainState $a, ChainState $b)
 {
     return $this->adapter->getMath()->cmp($a->getChain()->getIndex()->getWork(), $b->getChain()->getIndex()->getWork());
 }