/** * @param Parser $parser * @return NetworkMessage * @throws \BitWasp\Buffertools\Exceptions\ParserOutOfRange * @throws \Exception */ public function fromParser(Parser &$parser) { list($netBytes, $command, $payloadSize, $checksum) = $this->getHeaderTemplate()->parse($parser); /** @var Buffer $netBytes */ /** @var Buffer $command */ /** @var int|string $payloadSize */ /** @var Buffer $checksum */ if ($netBytes->getHex() !== $this->network->getNetMagicBytes()) { throw new \RuntimeException('Invalid magic bytes for network'); } $buffer = $payloadSize > 0 ? $parser->readBytes($payloadSize) : new Buffer(); // Compare payload checksum against header value if (Hash::sha256d($buffer)->slice(0, 4)->getBinary() !== $checksum->getBinary()) { throw new \RuntimeException('Invalid packet checksum'); } $cmd = trim($command->getBinary()); switch ($cmd) { case 'version': $payload = $this->versionSerializer->parse($buffer); break; case 'verack': $payload = new VerAck(); break; case 'addr': $payload = $this->addrSerializer->parse($buffer); break; case 'inv': $payload = $this->invSerializer->parse($buffer); break; case 'getdata': $payload = $this->getDataSerializer->parse($buffer); break; case 'notfound': $payload = $this->notFoundSerializer->parse($buffer); break; case 'getblocks': $payload = $this->getBlocksSerializer->parse($buffer); break; case 'getheaders': $payload = $this->getHeadersSerializer->parse($buffer); break; case 'tx': $payload = new Tx($this->txSerializer->parse($buffer)); break; case 'block': $payload = new Block($this->blockSerializer->parse($buffer)); break; case 'headers': $payload = $this->headersSerializer->parse($buffer); break; case 'getaddr': $payload = new GetAddr(); break; case 'mempool': $payload = new MemPool(); break; case 'filterload': $payload = $this->filterLoadSerializer->parse($buffer); break; case 'filteradd': $payload = $this->filterAddSerializer->parse($buffer); break; case 'filterclear': $payload = new FilterClear(); break; case 'merkleblock': $payload = $this->merkleBlockSerializer->parse($buffer); break; case 'ping': $payload = $this->pingSerializer->parse($buffer); break; case 'pong': $payload = $this->pongSerializer->parse($buffer); break; case 'reject': $payload = $this->rejectSerializer->parse($buffer); break; case 'alert': $payload = $this->alertSerializer->parse($buffer); break; default: throw new \RuntimeException('Invalid command'); } return new NetworkMessage($this->network, $payload); }
/** * @param Parser $parser * @return NetworkMessage * @throws \BitWasp\Buffertools\Exceptions\ParserOutOfRange * @throws \Exception */ public function fromParser(Parser $parser) { list($netBytes, $command, $payloadSize, $checksum) = $this->getHeaderTemplate()->parse($parser); /** @var Buffer $netBytes */ /** @var Buffer $command */ /** @var int|string $payloadSize */ /** @var Buffer $checksum */ if ($netBytes->getHex() !== $this->network->getNetMagicBytes()) { throw new \RuntimeException('Invalid magic bytes for network'); } $buffer = $payloadSize > 0 ? $parser->readBytes($payloadSize) : new Buffer('', 0, $this->math); // Compare payload checksum against header value if (Hash::sha256d($buffer)->slice(0, 4)->getBinary() !== $checksum->getBinary()) { throw new \RuntimeException('Invalid packet checksum'); } $cmd = trim($command->getBinary()); switch ($cmd) { case Message::VERSION: $payload = $this->versionSerializer->parse($buffer); break; case Message::VERACK: $payload = new VerAck(); break; case Message::SENDHEADERS: $payload = new SendHeaders(); break; case Message::ADDR: $payload = $this->addrSerializer->parse($buffer); break; case Message::INV: $payload = $this->invSerializer->parse($buffer); break; case Message::GETDATA: $payload = $this->getDataSerializer->parse($buffer); break; case Message::NOTFOUND: $payload = $this->notFoundSerializer->parse($buffer); break; case Message::GETBLOCKS: $payload = $this->getBlocksSerializer->parse($buffer); break; case Message::GETHEADERS: $payload = $this->getHeadersSerializer->parse($buffer); break; case Message::TX: $payload = new Tx($this->txSerializer->parse($buffer)); break; case Message::BLOCK: $payload = new Block($this->blockSerializer->parse($buffer)); break; case Message::HEADERS: $payload = $this->headersSerializer->parse($buffer); break; case Message::GETADDR: $payload = new GetAddr(); break; case Message::MEMPOOL: $payload = new MemPool(); break; case Message::FEEFILTER: $payload = $this->feeFilterSerializer->parse($buffer); break; case Message::FILTERLOAD: $payload = $this->filterLoadSerializer->parse($buffer); break; case Message::FILTERADD: $payload = $this->filterAddSerializer->parse($buffer); break; case Message::FILTERCLEAR: $payload = new FilterClear(); break; case Message::MERKLEBLOCK: $payload = $this->merkleBlockSerializer->parse($buffer); break; case Message::PING: $payload = $this->pingSerializer->parse($buffer); break; case Message::PONG: $payload = $this->pongSerializer->parse($buffer); break; case Message::REJECT: $payload = $this->rejectSerializer->parse($buffer); break; case Message::ALERT: $payload = $this->alertSerializer->parse($buffer); break; default: throw new \RuntimeException('Invalid command'); } return new NetworkMessage($this->network, $payload); }