/** * Initialize the block storage with genesis and chain * @param BlockHeaderInterface $header */ public function init(BlockHeaderInterface $header) { $hash = $header->getHash(); try { $this->db->fetchIndex($hash); } catch (\Exception $e) { $this->db->createIndexGenesis($header); } }
/** * @param ChainState $state * @param BlockHeaderInterface $header * @return BlockIndex */ public function accept(ChainState $state, BlockHeaderInterface $header) { $hash = $header->getHash(); if ($state->getChain()->containsHash($hash)) { // todo: check for rejected block return $this->db->fetchIndex($hash); } $prevIndex = $state->getChain()->getIndex(); $index = $this->headerCheck->check($header)->checkContextual($state, $header)->makeIndex($prevIndex, $header); $this->db->insertIndexBatch($prevIndex, [$index]); $state->getChain()->updateTip($index); return $index; }
/** * @param BlockIndex $prevIndex * @param BlockHeaderInterface $header * @return BlockIndex */ public function makeIndex(BlockIndex $prevIndex, BlockHeaderInterface $header) { return new BlockIndex($header->getHash()->getHex(), $this->math->add($prevIndex->getHeight(), 1), $this->math->add($this->pow->getWork($header->getBits()), $prevIndex->getWork()), $header); }
/** * @param BlockHeaderInterface $header * @return bool * @throws \Exception */ public function checkHeader(BlockHeaderInterface $header) { return $this->check($header->getHash(), $header->getBits()->getInt()); }
/** * Creates the Genesis block index * @param BlockHeaderInterface $header * @return bool */ public function createIndexGenesis(BlockHeaderInterface $header) { $stmtHeader = $this->dbh->prepare('INSERT INTO headerIndex ( hash, segment, height, work, version, prevBlock, merkleRoot, nBits, nTimestamp, nNonce ) VALUES ( :hash, :segment, :height, :work, :version, :prevBlock, :merkleRoot, :nBits, :nTimestamp, :nNonce ) '); if ($stmtHeader->execute(array('hash' => $header->getHash()->getBinary(), 'segment' => 0, 'height' => 0, 'work' => 0, 'version' => $header->getVersion(), 'prevBlock' => $header->getPrevBlock()->getBinary(), 'merkleRoot' => $header->getMerkleRoot()->getBinary(), 'nBits' => $header->getBits(), 'nTimestamp' => $header->getTimestamp(), 'nNonce' => $header->getNonce()))) { return true; } throw new \RuntimeException('Failed to update insert Genesis block index!'); }