Esempio n. 1
0
 /**
  * @param Buffer $hash
  * @return BlockIndex
  */
 public function fetchIndex(Buffer $hash)
 {
     if (!$this->chainCache->containsHash($hash)) {
         throw new \RuntimeException('Index by this hash not known');
     }
     return $this->headers->fetch($hash);
 }
Esempio n. 2
0
 /**
  * BetterNode constructor.
  * @param ConfigProviderInterface $config
  * @param ParamsInterface $params
  * @param DbInterface $db
  */
 public function __construct(ConfigProviderInterface $config, ParamsInterface $params, DbInterface $db)
 {
     $math = Bitcoin::getMath();
     $adapter = Bitcoin::getEcAdapter($math);
     $this->chains = new ChainContainer($math, $params);
     $consensus = new Consensus($math, $params);
     $pow = new ProofOfWork($math, $params);
     $this->headers = new Index\Headers($db, $adapter, $this->chains, $consensus, $pow);
     $this->blocks = new Index\Blocks($db, $config, $adapter, $this->chains, $consensus);
     $this->transactions = new Index\Transactions($db);
     $genesis = $params->getGenesisBlock();
     $this->headers->init($genesis->getHeader());
     $this->blocks->init($genesis);
     $this->db = $db;
     $segments = $this->db->fetchChainSegments();
     foreach ($segments as $segment) {
         $this->chains->addSegment($segment);
     }
     $this->chains->initialize($this->db);
 }
Esempio n. 3
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;
 }
Esempio n. 4
0
 /**
  * @param Peer $peer
  * @param Headers $headers
  */
 public function onHeaders(Peer $peer, Headers $headers)
 {
     $state = $this->chain();
     $vHeaders = $headers->getHeaders();
     $count = count($vHeaders);
     if ($count === 0) {
         return;
     }
     $this->headers->acceptBatch($state, $vHeaders);
     $this->chains->checkTips();
     $last = end($vHeaders);
     $this->peerState->fetch($peer)->updateBlockAvailability($state, $last->getHash());
     if (2000 === $count) {
         $peer->getheaders($state->getHeadersLocator());
     }
     if ($count < 2000) {
         echo 'start download' . PHP_EOL;
         $this->blockDownload->start($state, $peer);
     }
 }
Esempio n. 5
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;
 }