private MessageData processFrame(final ByteBuf f, final int frameSize) {
    final int pad = padding16(frameSize);
    final int expectedSize = frameSize + pad + LENGTH_MAC;
    if (f.readableBytes() != expectedSize) {
      throw error("Expected %s bytes in header, got %s", expectedSize, f.readableBytes());
    }

    final byte[] frameData = new byte[frameSize + pad];
    final byte[] fMac = new byte[LENGTH_MAC];
    f.readBytes(frameData).readBytes(fMac);

    // Validate the frame's MAC.
    final byte[] fMacSeed = secrets.updateIngress(frameData).getIngressMac();
    final byte[] fMacSeedEnc = new byte[16];
    macEncryptor.processBlock(fMacSeed, 0, fMacSeedEnc, 0);
    byte[] expectedMac = secrets.updateIngress(xor(fMacSeedEnc, fMacSeed)).getIngressMac();
    expectedMac = Arrays.copyOf(expectedMac, LENGTH_MAC);

    validateMac(fMac, expectedMac);

    // Decrypt frame data.
    decryptor.processBytes(frameData, 0, frameData.length, frameData, 0);

    // Read the id.
    final Bytes idbv = RLP.decodeOne(Bytes.of(frameData[0]));
    final int id = idbv.isZero() || idbv.size() == 0 ? 0 : idbv.get(0);

    // Write message data to ByteBuf, decompressing as necessary
    final Bytes data;
    if (compressionEnabled) {
      final byte[] compressedMessageData = Arrays.copyOfRange(frameData, 1, frameData.length - pad);
      final int uncompressedLength = compressor.uncompressedLength(compressedMessageData);
      if (uncompressedLength >= LENGTH_MAX_MESSAGE_FRAME) {
        throw error("Message size %s in excess of maximum length.", uncompressedLength);
      }
      Bytes _data;
      try {
        final byte[] decompressedMessageData = compressor.decompress(compressedMessageData);
        _data = Bytes.wrap(decompressedMessageData);
        compressionSuccessful = true;
      } catch (final FramingException fe) {
        if (compressionSuccessful) {
          throw fe;
        } else {
          // OpenEthereum/Parity does not implement EIP-706
          // If failing on the first packet downgrade to uncompressed
          compressionEnabled = false;
          LOG.debug("Snappy decompression failed: downgrading to uncompressed");
          final int messageLength = frameSize - LENGTH_MESSAGE_ID;
          _data = Bytes.wrap(frameData, 1, messageLength);
        }
      }
      data = _data;
    } else {
      // Move data to a ByteBuf
      final int messageLength = frameSize - LENGTH_MESSAGE_ID;
      data = Bytes.wrap(frameData, 1, messageLength);
    }

    return new RawMessage(id, data);
  }
Parses, decrypts and performs MAC verification on a frame.

<p>This method expects a well-formed frame, sized according to the length indicated in this
packet's header.

@param f The buffer containing
@param frameSize The expected
ethereum/p2p/src/main/java/org/hyperledger/besu/ethereum/p2p/rlpx/framing/Framer.java