Exemple #1
0
 /**
  * @param ChainAccessInterface $chain
  * @param BlockIndexInterface $prevIndex
  * @return int
  */
 public function getWorkRequired(ChainAccessInterface $chain, BlockIndexInterface $prevIndex)
 {
     $params = $this->consensus->getParams();
     if (($prevIndex->getHeight() + 1) % $params->powRetargetInterval() !== 0) {
         // No change in difficulty
         return $prevIndex->getHeader()->getBits();
     }
     // Re-target
     $heightLastRetarget = $prevIndex->getHeight() - ($params->powRetargetInterval() - 1);
     $lastTime = $chain->fetchAncestor($heightLastRetarget)->getHeader()->getTimestamp();
     return $this->consensus->calculateNextWorkRequired($prevIndex, $lastTime);
 }
 /**
  * @return ChainSegment[]
  */
 public function getHistory()
 {
     $height = $this->index->getHeight();
     $history = [];
     foreach ($this->getHistory() as $segment) {
         if ($segment->getLast()->getHeight() <= $height) {
             $history[] = $segment;
         } else {
             break;
         }
     }
     return $history;
 }
Exemple #3
0
 /**
  *
  */
 private function update()
 {
     $header = $this->index->getHeader();
     // Check all active features
     if ($header->getTimestamp() >= $this->params->p2shActivateTime()) {
         $this->p2sh = true;
     }
     $hash = $this->index->getHash()->getBinary();
     $this->bip30 = !($this->index->getHeight() == 91842 && $hash == pack("H*", "00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec") || $this->index->getHeight() == 91880 && $hash == pack("H*", "00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721"));
     $highest = $this->majorityVersion();
     if ($highest >= 2) {
         $this->bip34 = true;
     }
     if ($highest >= 3) {
         $this->derSig = true;
     }
     if ($highest >= 4) {
         $this->cltv = true;
     }
     // Calculate flags
     $this->flags = $this->p2sh ? InterpreterInterface::VERIFY_NONE : InterpreterInterface::VERIFY_P2SH;
     if ($this->derSig) {
         $this->flags |= InterpreterInterface::VERIFY_DERSIG;
     }
     if ($this->cltv) {
         $this->flags |= InterpreterInterface::VERIFY_CHECKLOCKTIMEVERIFY;
     }
 }
Exemple #4
0
 /**
  * @param BlockIndexInterface $index
  * @return bool
  */
 public function isNext(BlockIndexInterface $index)
 {
     if (false === $this->hash->equals($index->getHeader()->getPrevBlock())) {
         return false;
     }
     if (false === ($index->getHeight() == $this->height + 1)) {
         return false;
     }
     return true;
 }
Exemple #5
0
 /**
  * @param ChainStateInterface $chain
  * @param BlockIndexInterface $prevIndex
  * @return int|string
  */
 public function getWorkRequired(ChainStateInterface $chain, BlockIndexInterface $prevIndex)
 {
     $math = $this->math;
     if ($math->cmp($math->mod($math->add($prevIndex->getHeight(), 1), $this->params->powRetargetInterval()), 0) !== 0) {
         // No change in difficulty
         return $prevIndex->getHeader()->getBits()->getInt();
     }
     // Re-target
     $heightLastRetarget = $math->sub($prevIndex->getHeight(), $math->sub($this->params->powRetargetInterval(), 1));
     $lastTime = $chain->fetchAncestor($heightLastRetarget)->getHeader()->getTimestamp();
     return $this->calculateNextWorkRequired($prevIndex, $lastTime);
 }
Exemple #6
0
 /**
  * @param BufferInterface $hash
  * @param BlockIndexInterface $prevIndex
  * @param BlockHeaderInterface $header
  * @return BlockIndex
  */
 public function getNextIndex(BufferInterface $hash, BlockIndexInterface $prevIndex, BlockHeaderInterface $header)
 {
     return new BlockIndex($hash, $prevIndex->getHeight() + 1, $this->math->toString($this->math->add($this->proofOfWork->getWork($header->getBits()), gmp_init($prevIndex->getWork()))), $header);
 }
Exemple #7
0
 /**
  * @param BlockIndexInterface $index
  * @return array
  */
 public function convertIndexToArray(BlockIndexInterface $index)
 {
     $header = $index->getHeader();
     return ['height' => $index->getHeight(), 'hash' => $index->getHash()->getHex(), 'work' => $index->getWork(), 'version' => $header->getVersion(), 'prevBlock' => $header->getPrevBlock()->getHex(), 'merkleRoot' => $header->getMerkleRoot()->getHex(), 'nBits' => $header->getBits(), 'nTimestamp' => $header->getTimestamp(), 'nNonce' => $header->getNonce()];
 }
Exemple #8
0
 /**
  * @param BlockIndexInterface $index
  * @param BlockInterface $block
  * @param BlockData $blockData
  */
 public function logBlock(BlockIndexInterface $index, BlockInterface $block, BlockData $blockData)
 {
     echo count($blockData->remainingNew) . "created and " . count($blockData->requiredOutpoints) . " destroyed\n";
     $this->log('block', ['hash' => $index->getHash()->getHex(), 'height' => $index->getHeight(), 'txs' => count($block->getTransactions()), 'nFees' => gmp_strval($blockData->nFees, 10), 'nSigOps' => $blockData->nSigOps, 'utxos' => ['created' => count($blockData->remainingNew), 'removed' => count($blockData->requiredOutpoints)]]);
 }
Exemple #9
0
 /**
  * @param BlockInterface $block
  * @param BlockIndexInterface $prevBlockIndex
  * @return $this
  */
 public function checkContextual(BlockInterface $block, BlockIndexInterface $prevBlockIndex)
 {
     $newHeight = $prevBlockIndex->getHeight() + 1;
     $newTime = $block->getHeader()->getTimestamp();
     foreach ($block->getTransactions() as $transaction) {
         if (!$this->checkTransactionIsFinal($transaction, $newHeight, $newTime)) {
             throw new \RuntimeException('Block contains a non-final transaction');
         }
     }
     return $this;
 }