private static Bytes serializeHeader(
      final BlockHeader header, final Supplier<Bytes> extraDataSerializer) {
    final BytesValueRLPOutput out = new BytesValueRLPOutput();
    out.startList();

    out.writeBytes(header.getParentHash());
    out.writeBytes(header.getOmmersHash());
    out.writeBytes(header.getCoinbase());
    out.writeBytes(header.getStateRoot());
    out.writeBytes(header.getTransactionsRoot());
    out.writeBytes(header.getReceiptsRoot());
    out.writeBytes(header.getLogsBloom());
    out.writeBytes(header.getDifficulty().toMinimalBytes());
    out.writeLongScalar(header.getNumber());
    out.writeLongScalar(header.getGasLimit());
    out.writeLongScalar(header.getGasUsed());
    out.writeLongScalar(header.getTimestamp());
    out.writeBytes(extraDataSerializer.get());
    out.writeBytes(header.getMixHash());
    out.writeLong(header.getNonce());
    header.getBaseFee().ifPresent(out::writeUInt256Scalar);
    out.endList();
    return out.encoded();
  }
Recovers the proposer's {@link Address} from the proposer seal.

@param header the block header that was signed by the proposer seal
@param cliqueExtraData the parsed CliqueExtraData from the header
@return the proposer address
consensus/clique/src/main/java/org/hyperledger/besu/consensus/clique/CliqueBlockHashing.java