Esempio n. 1
0
 /**
  * @param Container $container
  */
 public function register(Container $container)
 {
     $headers = $this->node->headers();
     $headers->on('headers', function (HeadersBatch $batch) use($container) {
         /** @var DbInterface $db */
         $db = $container['db'];
         /** @var DebugInterface $debug */
         $debug = $container['debug'];
         if (count($batch->getIndices()) > 0) {
             $first = $batch->getIndices()[0];
             $prevIndex = $db->fetchIndex($first->getHeader()->getPrevBlock());
             $versionInfo = $db->findSuperMajorityInfoByHash($prevIndex->getHash());
             $forks = new Forks($this->params, $prevIndex, $versionInfo);
             $first = $forks->toArray();
             $changes = [];
             foreach ($batch->getIndices() as $index) {
                 $forks->next($index);
                 $new = $forks->toArray();
                 if ($first !== $new) {
                     $changes[] = [$index, $first, $new];
                     $first = $new;
                 }
             }
             foreach ($changes as $change) {
                 /** @var BlockIndexInterface $index */
                 list($index, $first, $features) = $change;
                 $debug->log('fork.new', ['hash' => $index->getHash()->getHex(), 'height' => $index->getHeight(), 'old' => $first, 'features' => $features]);
             }
         }
     });
 }
Esempio n. 2
0
 /**
  * @param ChainAccessInterface $chain
  * @param BlockIndexInterface $index
  * @param BlockIndexInterface $prevIndex
  * @param Forks $forks
  * @return $this
  */
 public function checkContextual(ChainAccessInterface $chain, BlockIndexInterface $index, BlockIndexInterface $prevIndex, Forks $forks)
 {
     $work = $this->getWorkRequired($chain, $prevIndex);
     $header = $index->getHeader();
     if ($this->math->cmp(gmp_init($header->getBits(), 10), gmp_init($work, 10)) != 0) {
         throw new \RuntimeException('Headers::CheckContextual(): invalid proof of work : ' . $header->getBits() . '? ' . $work);
     }
     if ($header->getVersion() < $forks->getMajorityVersion()) {
         echo $index->getHash()->getHex() . PHP_EOL;
         echo "Heaader: " . $header->getVersion() . "\nMajority: " . $forks->getMajorityVersion() . PHP_EOL;
         throw new \RuntimeException('Rejected version');
     }
     return $this;
 }
Esempio n. 3
0
 /**
  * @param HeaderChainViewInterface $headersView
  * @param BlockIndexInterface $index
  * @return Forks
  */
 public function prepareForks(HeaderChainViewInterface $headersView, BlockIndexInterface $index)
 {
     if ($this->forks instanceof Forks && $this->forks->isNext($index)) {
         $forks = $this->forks;
     } else {
         $versionInfo = $this->db->findSuperMajorityInfoByHash($index->getHeader()->getPrevBlock());
         $forks = $this->forks = new Forks($this->consensus->getParams(), $headersView->getLastBlock(), $versionInfo);
     }
     return $forks;
 }
Esempio n. 4
0
 /**
  * @param BlockHeaderInterface[] $headers
  * @return HeadersBatch
  */
 public function prepareBatch(array $headers)
 {
     $countHeaders = count($headers);
     if (0 === $countHeaders) {
         return new HeadersBatch($this->chains->best($this->math), []);
     }
     $bestPrev = null;
     $firstUnknown = null;
     $hashStorage = new HashStorage();
     foreach ($headers as $i => &$head) {
         if ($this->chains->isKnownHeader($head->getPrevBlock())) {
             $bestPrev = $head->getPrevBlock();
         }
         $hash = Hash::sha256d($head->getBuffer())->flip();
         $hashStorage->attach($head, $hash);
         if ($firstUnknown === null && !$this->chains->isKnownHeader($hash)) {
             $firstUnknown = $i;
         }
     }
     if (!$bestPrev instanceof BufferInterface) {
         throw new \RuntimeException('Headers::accept(): Unknown start header');
     }
     $view = $this->chains->isTip($bestPrev);
     if ($view === false) {
         throw new \RuntimeException('Headers::accept(): Unhandled fork');
     }
     $prevIndex = $view->getIndex();
     $access = $this->chains->access($view);
     $batch = [];
     if ($firstUnknown !== null) {
         $versionInfo = $this->db->findSuperMajorityInfoByView($view);
         $forks = new Forks($this->consensus->getParams(), $prevIndex, $versionInfo);
         for ($i = $firstUnknown; $i < $countHeaders; $i++) {
             /**
              * @var BufferInterface $hash
              * @var BlockHeaderInterface $header
              */
             $header = $headers[$i];
             $hash = $hashStorage[$header];
             $this->headerCheck->check($hash, $header);
             $index = $this->getNextIndex($hash, $prevIndex, $header);
             $forks->next($index);
             $this->headerCheck->checkContextual($access, $index, $prevIndex, $forks);
             $batch[] = $index;
             $prevIndex = $index;
         }
     }
     return new HeadersBatch($view, $batch);
 }