Exemplo n.º 1
0
 /**
  * @param ChainState $state
  * @param BlockInterface $block
  * @param Headers $headers
  * @param UtxoIdx $utxoIdx
  * @return BlockIndex
  */
 public function accept(ChainState $state, BlockInterface $block, Headers $headers, UtxoIdx $utxoIdx)
 {
     $bestBlock = $state->getLastBlock();
     if ($bestBlock->getHash() !== $block->getHeader()->getPrevBlock()) {
         throw new \RuntimeException('Blocks:accept() Block does not extend this chain!');
     }
     $index = $headers->accept($state, $block->getHeader());
     $this->blockCheck->check($block)->checkContextual($block, $bestBlock);
     //$view = $utxoIdx->fetchView($state, $block);
     $view = $this->db->fetchUtxoView($block);
     $flagP2sh = $this->consensus->scriptVerifyPayToScriptHash($bestBlock->getHeader()->getTimestamp());
     $flags = new Flags($flagP2sh ? InterpreterInterface::VERIFY_P2SH : InterpreterInterface::VERIFY_NONE);
     $nInputs = 0;
     $nFees = 0;
     $nSigOps = 0;
     $txs = $block->getTransactions();
     foreach ($block->getTransactions() as $tx) {
         $nInputs += count($tx->getInputs());
         $nSigOps += $this->blockCheck->getLegacySigOps($tx);
         if ($nSigOps > $this->consensus->getParams()->getMaxBlockSigOps()) {
             throw new \RuntimeException('Blocks::accept() - too many sigops');
         }
         if (!$tx->isCoinbase()) {
             if ($flagP2sh) {
                 $nSigOps = $this->blockCheck->getP2shSigOps($view, $tx);
                 if ($nSigOps > $this->consensus->getParams()->getMaxBlockSigOps()) {
                     throw new \RuntimeException('Blocks::accept() - too many sigops');
                 }
             }
             $fee = $this->math->sub($view->getValueIn($this->math, $tx), $tx->getValueOut());
             $nFees = $this->math->add($nFees, $fee);
             $this->blockCheck->checkInputs($view, $tx, $index->getHeight(), $flags);
         }
     }
     $this->blockCheck->checkCoinbaseSubsidy($txs[0], $nFees, $index->getHeight());
     $this->db->insertBlock($block);
     $state->updateLastBlock($index);
     return $index;
 }