/** * @param BlockInterface $block * @return $this */ public function check(BlockInterface $block) { $header = $block->getHeader(); if ($block->getMerkleRoot() !== $header->getMerkleRoot()) { throw new \RuntimeException('Blocks::check(): failed to verify merkle root'); } $transactions = $block->getTransactions(); $txCount = count($transactions); if ($txCount == 0 || $block->getBuffer()->getSize() > $this->params->maxBlockSizeBytes()) { throw new \RuntimeException('Blocks::check(): Zero transactions, or block exceeds max size'); } // The first transaction is coinbase, and only the first transaction is coinbase. if (!$transactions[0]->isCoinbase()) { throw new \RuntimeException('Blocks::check(): First transaction was not coinbase'); } for ($i = 1; $i < $txCount; $i++) { if ($transactions->offsetGet($i)->isCoinbase()) { throw new \RuntimeException('Blocks::check(): more than one coinbase'); } } $nSigOps = 0; foreach ($transactions as $transaction) { if (!$this->checkTransaction($transaction)) { throw new \RuntimeException('Blocks::check(): failed checkTransaction'); } $nSigOps += $this->getLegacySigOps($transaction); } if ($this->math->cmp($nSigOps, $this->params->getMaxBlockSigOps()) > 0) { throw new \RuntimeException('Blocks::check(): out-of-bounds sigop count'); } return $this; }