Example #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;
 }
Example #2
0
 /**
  * @param BlockInterface $block
  * @param HeaderChainViewInterface $chainView
  * @param Headers $headers
  * @param bool $checkSignatures
  * @param bool $checkSize
  * @param bool $checkMerkleRoot
  * @return BlockIndexInterface
  */
 public function accept(BlockInterface $block, HeaderChainViewInterface $chainView, Headers $headers, $checkSignatures = true, $checkSize = true, $checkMerkleRoot = true)
 {
     $hash = $block->getHeader()->getHash();
     $index = $headers->accept($hash, $block->getHeader(), true);
     $outpointSerializer = new CachingOutPointSerializer();
     $txSerializer = new CachingTransactionSerializer(new TransactionInputSerializer($outpointSerializer));
     $blockSerializer = new CachingBlockSerializer($this->math, new BlockHeaderSerializer(), $txSerializer);
     $utxoSet = new UtxoSet($this->db, $outpointSerializer);
     $blockData = $this->prepareBatch($block, $txSerializer, $utxoSet);
     $this->blockCheck->check($block, $txSerializer, $blockSerializer, $checkSize, $checkMerkleRoot)->checkContextual($block, $chainView->getLastBlock());
     $forks = $this->prepareForks($chainView, $index);
     $this->checkBlockData($block, $blockData, $checkSignatures, $forks->getFlags(), $index->getHeight());
     $this->db->transaction(function () use($hash, $block, $blockSerializer, $utxoSet, $blockData) {
         $this->db->insertBlock($hash, $block, $blockSerializer);
         $utxoSet->applyBlock($blockData);
     });
     $chainView->blocks()->updateTip($index);
     $forks->next($index);
     $this->emit('block', [$index, $block, $blockData]);
     print_r($outpointSerializer->stats());
     return $index;
 }