/** * @param BlockIndex $index */ public function add(BlockIndex $index) { if ($index->getHeader()->getPrevBlock() !== $this->getHash($index->getHeight() - 1)->getHex()) { throw new \RuntimeException('ChainCache: New BlockIndex does not refer to last'); } $binary = hex2bin($index->getHash()); $this->hashByHeight[] = $binary; $this->heightByHash[$binary] = $index->getHeight(); }
/** * @param BlockIndex $index */ public function updateLastBlock(BlockIndex $index) { if ($this->lastBlock->getHash() !== $index->getHeader()->getPrevBlock()) { throw new \RuntimeException('UpdateLastBlock: Block does not extend this chain'); } if ($this->lastBlock->getHeight() != $index->getHeight() - 1) { throw new \RuntimeException('UpdateLastBlock: Incorrect chain height' . ($index->getHeight() - 1)); } $this->lastBlock = $index; }
public function testBlockIndex() { $headerHex = '0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4a29ab5f49ffff001d1dac2b7c'; $header = BlockHeaderFactory::fromHex($headerHex); $hash = $header->getHash(); $height = 0; $work = 0; $index = new BlockIndex($hash, $height, $work, $header); $this->assertEquals($hash, $index->getHash()); $this->assertEquals($height, $index->getHeight()); $this->assertEquals($work, $index->getWork()); $this->assertSame($header, $index->getHeader()); }
/** * @param BlockIndex $prevIndex * @param $timeFirstBlock * @return int|string */ public function calculateNextWorkRequired(BlockIndex $prevIndex, $timeFirstBlock) { $header = $prevIndex->getHeader(); $math = $this->math; $timespan = $math->sub($header->getTimestamp(), $timeFirstBlock); $lowest = $math->div($this->params->powTargetTimespan(), 4); $highest = $math->mul($this->params->powTargetTimespan(), 4); if ($math->cmp($timespan, $lowest) < 0) { $timespan = $lowest; } if ($math->cmp($timespan, $highest) > 0) { $timespan = $highest; } $target = $math->compact()->set($header->getBits()->getInt()); $limit = $this->math->compact()->set($this->params->powBitsLimit()); $new = bcdiv(bcmul($target, $timespan), $this->params->powTargetTimespan()); if ($math->cmp($new, $limit) > 0) { $new = $limit; } return $math->compact()->read($new, false); }
/** * @param BlockIndex $index * @return bool */ public function insertIndexGenesis(BlockIndex $index) { if ($this->debug) { echo "db: called insertIndexGenesis\n"; } $stmt = $this->dbh->prepare("\n INSERT INTO headerIndex (\n hash, height, work, version, prevBlock, merkleRoot, nBits, nTimestamp, nNonce, lft, rgt\n ) VALUES (\n :hash, :height, :work, :version, :prevBlock, :merkleRoot, :nBits, :nTimestamp, :nNonce, :lft, :rgt\n )\n "); $header = $index->getHeader(); var_dump($index); if ($stmt->execute(array('hash' => $index->getHash(), 'height' => $index->getHeight(), 'work' => $index->getWork(), 'version' => $header->getVersion(), 'prevBlock' => $header->getPrevBlock(), 'merkleRoot' => $header->getMerkleRoot(), 'nBits' => $header->getBits()->getInt(), 'nTimestamp' => $header->getTimestamp(), 'nNonce' => $header->getNonce(), 'lft' => 1, 'rgt' => 2))) { return true; } throw new \RuntimeException('Failed to update insert Genesis block!'); }
/** * @param BlockIndex $index */ public function updateTip(BlockIndex $index) { if ($this->index->getHash() !== $index->getHeader()->getPrevBlock()) { throw new \RuntimeException('Header: Header does not extend this chain'); } if ($index->getHeight() - 1 != $this->index->getHeight()) { throw new \RuntimeException('Header: Incorrect chain height'); } $this->chainCache->add($index); $this->index = $index; }