Add QuicPacketNumber class.

QuicPacketNumber has a sentinel value which represents an uninitialized packet number.
Operators cannot be applied to uninitialized packet numbers.

Merge internal change: 230715749

Change-Id: I2d8d9e93407946e5eb03e493a76639224b990407
Reviewed-on: https://chromium-review.googlesource.com/c/1439801
Reviewed-by: Zhongyi Shi <[email protected]>
Reviewed-by: Guido Urdaneta <[email protected]>
Commit-Queue: Fan Yang <[email protected]>
Cr-Commit-Position: refs/heads/master@{#626726}
diff --git a/net/BUILD.gn b/net/BUILD.gn
index c85a3b3..853c946 100644
--- a/net/BUILD.gn
+++ b/net/BUILD.gn
@@ -1416,6 +1416,8 @@
       "third_party/quic/core/quic_packet_creator.h",
       "third_party/quic/core/quic_packet_generator.cc",
       "third_party/quic/core/quic_packet_generator.h",
+      "third_party/quic/core/quic_packet_number.cc",
+      "third_party/quic/core/quic_packet_number.h",
       "third_party/quic/core/quic_packet_writer.h",
       "third_party/quic/core/quic_packets.cc",
       "third_party/quic/core/quic_packets.h",
@@ -5179,6 +5181,7 @@
     "third_party/quic/core/quic_one_block_arena_test.cc",
     "third_party/quic/core/quic_packet_creator_test.cc",
     "third_party/quic/core/quic_packet_generator_test.cc",
+    "third_party/quic/core/quic_packet_number_test.cc",
     "third_party/quic/core/quic_received_packet_manager_test.cc",
     "third_party/quic/core/quic_sent_packet_manager_test.cc",
     "third_party/quic/core/quic_server_id_test.cc",
diff --git a/net/http/http_proxy_client_socket_wrapper_unittest.cc b/net/http/http_proxy_client_socket_wrapper_unittest.cc
index 3e3d842..153491a 100644
--- a/net/http/http_proxy_client_socket_wrapper_unittest.cc
+++ b/net/http/http_proxy_client_socket_wrapper_unittest.cc
@@ -161,13 +161,13 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructSettingsPacket(
-      quic::QuicPacketNumber packet_number) {
+      uint64_t packet_number) {
     return client_maker_.MakeInitialSettingsPacket(packet_number,
                                                    &header_stream_offset_);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectRequestPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       RequestPriority priority) {
     spdy::SpdyHeaderBlock block;
     PopulateConnectRequestIR(&block);
@@ -178,7 +178,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructServerConnectReplyPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool fin) {
     spdy::SpdyHeaderBlock block;
     block[":status"] = "200";
@@ -189,11 +189,11 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicRstStreamErrorCode error_code,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked) {
     return client_maker_.MakeAckAndRstPacket(
         packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
         largest_received, smallest_received, least_unacked, kSendFeedback);
diff --git a/net/quic/bidirectional_stream_quic_impl_unittest.cc b/net/quic/bidirectional_stream_quic_impl_unittest.cc
index 882c04e..119c7e7 100644
--- a/net/quic/bidirectional_stream_quic_impl_unittest.cc
+++ b/net/quic/bidirectional_stream_quic_impl_unittest.cc
@@ -548,7 +548,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
       bool fin,
       quic::QuicStreamOffset offset,
@@ -562,7 +562,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
       bool fin,
       quic::QuicStreamOffset offset,
@@ -574,7 +574,7 @@
   // Construct a data packet with multiple data frames
   std::unique_ptr<quic::QuicReceivedPacket>
   ConstructClientMultipleDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
       bool fin,
       quic::QuicStreamOffset offset,
@@ -589,7 +589,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool fin,
       RequestPriority request_priority,
       size_t* spdy_headers_frame_length) {
@@ -599,7 +599,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestHeadersPacketInner(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool fin,
       RequestPriority request_priority,
@@ -611,7 +611,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestHeadersPacketInner(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool fin,
       RequestPriority request_priority,
@@ -632,7 +632,7 @@
 
   std::unique_ptr<quic::QuicReceivedPacket>
   ConstructRequestHeadersAndMultipleDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool fin,
       RequestPriority request_priority,
       quic::QuicStreamOffset* header_stream_offset,
@@ -651,7 +651,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool fin,
       spdy::SpdyHeaderBlock response_headers,
       size_t* spdy_headers_frame_length,
@@ -662,7 +662,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacketInner(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool fin,
       spdy::SpdyHeaderBlock response_headers,
@@ -674,7 +674,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseTrailersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool fin,
       spdy::SpdyHeaderBlock trailers,
       size_t* spdy_headers_frame_length,
@@ -685,25 +685,25 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamPacket(
-      quic::QuicPacketNumber packet_number) {
+      uint64_t packet_number) {
     return ConstructRstStreamCancelledPacket(packet_number, !kIncludeVersion, 0,
                                              &client_maker_);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructServerRstStreamPacket(
-      quic::QuicPacketNumber packet_number) {
+      uint64_t packet_number) {
     return ConstructRstStreamCancelledPacket(packet_number, !kIncludeVersion, 0,
                                              &server_maker_);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructClientEarlyRstStreamPacket(
-      quic::QuicPacketNumber packet_number) {
+      uint64_t packet_number) {
     return ConstructRstStreamCancelledPacket(packet_number, kIncludeVersion, 0,
                                              &client_maker_);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructRstStreamCancelledPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool include_version,
       size_t bytes_written,
       QuicTestPacketMaker* maker) {
@@ -716,10 +716,10 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket>
-  ConstructClientAckAndRstStreamPacket(quic::QuicPacketNumber packet_number,
-                                       quic::QuicPacketNumber largest_received,
-                                       quic::QuicPacketNumber smallest_received,
-                                       quic::QuicPacketNumber least_unacked) {
+  ConstructClientAckAndRstStreamPacket(uint64_t packet_number,
+                                       uint64_t largest_received,
+                                       uint64_t smallest_received,
+                                       uint64_t least_unacked) {
     return client_maker_.MakeAckAndRstPacket(
         packet_number, !kIncludeVersion, stream_id_,
         quic::QUIC_STREAM_CANCELLED, largest_received, smallest_received,
@@ -727,11 +727,11 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool fin,
       quic::QuicStreamOffset offset,
       quic::QuicStringPiece data,
@@ -747,11 +747,11 @@
 
   std::unique_ptr<quic::QuicReceivedPacket>
   ConstructAckAndMultipleDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool fin,
       quic::QuicStreamOffset offset,
       const std::vector<std::string> data_writes) {
@@ -765,27 +765,27 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked) {
     return client_maker_.MakeAckPacket(packet_number, largest_received,
                                        smallest_received, least_unacked,
                                        !kIncludeCongestionFeedback);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked) {
     return server_maker_.MakeAckPacket(packet_number, largest_received,
                                        smallest_received, least_unacked,
                                        !kIncludeCongestionFeedback);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamOffset* offset) {
     return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
   }
diff --git a/net/quic/mock_decrypter.cc b/net/quic/mock_decrypter.cc
index 347efe3..717797b 100644
--- a/net/quic/mock_decrypter.cc
+++ b/net/quic/mock_decrypter.cc
@@ -40,7 +40,7 @@
 }
 
 bool MockDecrypter::DecryptPacket(QuicTransportVersion version,
-                                  QuicPacketNumber /*packet_number*/,
+                                  uint64_t /*packet_number*/,
                                   QuicStringPiece associated_data,
                                   QuicStringPiece ciphertext,
                                   char* output,
diff --git a/net/quic/mock_decrypter.h b/net/quic/mock_decrypter.h
index adb818c..0466a49 100644
--- a/net/quic/mock_decrypter.h
+++ b/net/quic/mock_decrypter.h
@@ -34,7 +34,7 @@
   bool SetDiversificationNonce(
       const quic::DiversificationNonce& nonce) override;
   bool DecryptPacket(quic::QuicTransportVersion version,
-                     quic::QuicPacketNumber packet_number,
+                     uint64_t packet_number,
                      quic::QuicStringPiece associated_data,
                      quic::QuicStringPiece ciphertext,
                      char* output,
diff --git a/net/quic/mock_encrypter.cc b/net/quic/mock_encrypter.cc
index d4f7e536..333b3e4 100644
--- a/net/quic/mock_encrypter.cc
+++ b/net/quic/mock_encrypter.cc
@@ -30,7 +30,7 @@
 }
 
 bool MockEncrypter::EncryptPacket(QuicTransportVersion version,
-                                  QuicPacketNumber /*packet_number*/,
+                                  uint64_t /*packet_number*/,
                                   QuicStringPiece associated_data,
                                   QuicStringPiece plaintext,
                                   char* output,
diff --git a/net/quic/mock_encrypter.h b/net/quic/mock_encrypter.h
index 786babfc..133a751 100644
--- a/net/quic/mock_encrypter.h
+++ b/net/quic/mock_encrypter.h
@@ -29,7 +29,7 @@
   bool SetNoncePrefix(quic::QuicStringPiece nonce_prefix) override;
   bool SetIV(quic::QuicStringPiece iv) override;
   bool EncryptPacket(quic::QuicTransportVersion version,
-                     quic::QuicPacketNumber packet_number,
+                     uint64_t packet_number,
                      quic::QuicStringPiece associated_data,
                      quic::QuicStringPiece plaintext,
                      char* output,
diff --git a/net/quic/quic_connection_logger.cc b/net/quic/quic_connection_logger.cc
index c10dd4f9..6f1f0589 100644
--- a/net/quic/quic_connection_logger.cc
+++ b/net/quic/quic_connection_logger.cc
@@ -58,7 +58,7 @@
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
   dict->SetInteger("transmission_type", transmission_type);
   dict->SetKey("packet_number",
-               NetLogNumberValue(serialized_packet.packet_number));
+               NetLogNumberValue(serialized_packet.packet_number.ToUint64()));
   dict->SetInteger("size", serialized_packet.encrypted_length);
   dict->SetKey("sent_time_us", NetLogNumberValue(sent_time.ToDebuggingValue()));
   return std::move(dict);
@@ -69,8 +69,10 @@
     quic::QuicPacketNumber new_packet_number,
     NetLogCaptureMode /* capture_mode */) {
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-  dict->SetKey("old_packet_number", NetLogNumberValue(old_packet_number));
-  dict->SetKey("new_packet_number", NetLogNumberValue(new_packet_number));
+  dict->SetKey("old_packet_number",
+               NetLogNumberValue(old_packet_number.ToUint64()));
+  dict->SetKey("new_packet_number",
+               NetLogNumberValue(new_packet_number.ToUint64()));
   return std::move(dict);
 }
 
@@ -81,7 +83,7 @@
     NetLogCaptureMode /*capture_mode*/) {
   auto dict = std::make_unique<base::DictionaryValue>();
   dict->SetInteger("transmission_type", transmission_type);
-  dict->SetKey("packet_number", NetLogNumberValue(packet_number));
+  dict->SetKey("packet_number", NetLogNumberValue(packet_number.ToUint64()));
   dict->SetKey("detection_time_us",
                NetLogNumberValue(detection_time.ToDebuggingValue()));
   return dict;
@@ -91,7 +93,7 @@
     quic::QuicPacketNumber packet_number,
     NetLogCaptureMode /* capture_mode */) {
   std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
-  dict->SetKey("packet_number", NetLogNumberValue(packet_number));
+  dict->SetKey("packet_number", NetLogNumberValue(packet_number.ToUint64()));
   return std::move(dict);
 }
 
@@ -103,7 +105,8 @@
                   header->destination_connection_id.ToString());
   dict->SetInteger("reset_flag", header->reset_flag);
   dict->SetInteger("version_flag", header->version_flag);
-  dict->SetKey("packet_number", NetLogNumberValue(header->packet_number));
+  dict->SetKey("packet_number",
+               NetLogNumberValue(header->packet_number.ToUint64()));
   return std::move(dict);
 }
 
@@ -122,7 +125,8 @@
     const quic::QuicAckFrame* frame,
     NetLogCaptureMode /* capture_mode */) {
   auto dict = std::make_unique<base::DictionaryValue>();
-  dict->SetKey("largest_observed", NetLogNumberValue(frame->largest_acked));
+  dict->SetKey("largest_observed",
+               NetLogNumberValue(frame->largest_acked.ToUint64()));
   dict->SetKey("delta_time_largest_observed_us",
                NetLogNumberValue(frame->ack_delay_time.ToMicroseconds()));
 
@@ -133,7 +137,7 @@
     for (quic::QuicPacketNumber packet = frame->packets.Min();
          packet < frame->largest_acked; ++packet) {
       if (!frame->packets.Contains(packet)) {
-        missing->GetList().push_back(NetLogNumberValue(packet));
+        missing->GetList().push_back(NetLogNumberValue(packet.ToUint64()));
       }
     }
   }
@@ -143,7 +147,7 @@
   const quic::PacketTimeVector& received_times = frame->received_packet_times;
   for (auto it = received_times.begin(); it != received_times.end(); ++it) {
     auto info = std::make_unique<base::DictionaryValue>();
-    info->SetKey("packet_number", NetLogNumberValue(it->first));
+    info->SetKey("packet_number", NetLogNumberValue(it->first.ToUint64()));
     info->SetKey("received", NetLogNumberValue(it->second.ToDebuggingValue()));
     received->Append(std::move(info));
   }
@@ -202,7 +206,8 @@
     NetLogCaptureMode /* capture_mode */) {
   auto dict = std::make_unique<base::DictionaryValue>();
   auto sent_info = std::make_unique<base::DictionaryValue>();
-  sent_info->SetKey("least_unacked", NetLogNumberValue(frame->least_unacked));
+  sent_info->SetKey("least_unacked",
+                    NetLogNumberValue(frame->least_unacked.ToUint64()));
   dict->Set("sent_info", std::move(sent_info));
   return std::move(dict);
 }
@@ -295,11 +300,9 @@
     const NetLogWithSource& net_log)
     : net_log_(net_log),
       session_(session),
-      last_received_packet_number_(0),
       last_received_packet_size_(0),
       no_packet_received_after_ping_(false),
       previous_received_packet_size_(0),
-      largest_received_packet_number_(0),
       num_out_of_order_received_packets_(0),
       num_out_of_order_large_received_packets_(0),
       num_packets_received_(0),
@@ -508,7 +511,7 @@
     quic::QuicTime sent_time) {
   if (!net_log_is_capturing_)
     return;
-  if (original_packet_number == 0) {
+  if (!original_packet_number.IsInitialized()) {
     net_log_.AddEvent(
         NetLogEventType::QUIC_SESSION_PACKET_SENT,
         base::Bind(&NetLogQuicPacketSentCallback, serialized_packet,
@@ -596,9 +599,14 @@
 void QuicConnectionLogger::OnPacketHeader(
     const quic::QuicPacketHeader& header) {
   ++num_packets_received_;
-  if (largest_received_packet_number_ < header.packet_number) {
-    quic::QuicPacketNumber delta =
-        header.packet_number - largest_received_packet_number_;
+  if (!largest_received_packet_number_.IsInitialized() ||
+      largest_received_packet_number_ < header.packet_number) {
+    // TODO(fayang): Fix this as this check assume the first received packet
+    // is 1.
+    uint64_t delta = header.packet_number.ToUint64();
+    if (largest_received_packet_number_.IsInitialized()) {
+      delta = header.packet_number - largest_received_packet_number_;
+    }
     if (delta > 1) {
       // There is a gap between the largest packet previously received and
       // the current packet.  This indicates either loss, or out-of-order
@@ -609,10 +617,13 @@
     }
     largest_received_packet_number_ = header.packet_number;
   }
-  if (header.packet_number < received_packets_.size()) {
-    received_packets_[static_cast<size_t>(header.packet_number)] = true;
+  // TODO(fayang): Fix this as this check assume the first received packet is 1.
+  if (header.packet_number < quic::QuicPacketNumber(received_packets_.size())) {
+    received_packets_[static_cast<size_t>(header.packet_number.ToUint64())] =
+        true;
   }
-  if (header.packet_number < last_received_packet_number_) {
+  if (last_received_packet_number_.IsInitialized() &&
+      header.packet_number < last_received_packet_number_) {
     ++num_out_of_order_received_packets_;
     if (previous_received_packet_size_ < last_received_packet_size_)
       ++num_out_of_order_large_received_packets_;
@@ -621,10 +632,18 @@
         static_cast<base::HistogramBase::Sample>(last_received_packet_number_ -
                                                  header.packet_number));
   } else if (no_packet_received_after_ping_) {
-    UMA_HISTOGRAM_COUNTS_1M(
-        "Net.QuicSession.PacketGapReceivedNearPing",
-        static_cast<base::HistogramBase::Sample>(header.packet_number -
-                                                 last_received_packet_number_));
+    if (!last_received_packet_number_.IsInitialized()) {
+      // TODO(fayang): Fix this as this check assume the first received packet
+      // is 1.
+      UMA_HISTOGRAM_COUNTS_1M("Net.QuicSession.PacketGapReceivedNearPing",
+                              static_cast<base::HistogramBase::Sample>(
+                                  header.packet_number.ToUint64()));
+    } else {
+      UMA_HISTOGRAM_COUNTS_1M(
+          "Net.QuicSession.PacketGapReceivedNearPing",
+          static_cast<base::HistogramBase::Sample>(
+              header.packet_number - last_received_packet_number_));
+    }
     no_packet_received_after_ping_ = false;
   }
   last_received_packet_number_ = header.packet_number;
@@ -642,9 +661,12 @@
 
 void QuicConnectionLogger::OnAckFrame(const quic::QuicAckFrame& frame) {
   const size_t kApproximateLargestSoloAckBytes = 100;
-  if (last_received_packet_number_ < received_acks_.size() &&
+  // TODO(fayang): Fix this as this check assume the first received packet is 1.
+  if (last_received_packet_number_ <
+          quic::QuicPacketNumber(received_acks_.size()) &&
       last_received_packet_size_ < kApproximateLargestSoloAckBytes) {
-    received_acks_[static_cast<size_t>(last_received_packet_number_)] = true;
+    received_acks_[static_cast<size_t>(
+        last_received_packet_number_.ToUint64())] = true;
   }
 
   if (!net_log_is_capturing_)
@@ -823,10 +845,14 @@
 }
 
 float QuicConnectionLogger::ReceivedPacketLossRate() const {
-  if (largest_received_packet_number_ <= num_packets_received_)
+  // TODO(fayang): Fix this as this check assume the first received packet is 1.
+  if (!largest_received_packet_number_.IsInitialized() ||
+      largest_received_packet_number_ <=
+          quic::QuicPacketNumber(num_packets_received_))
     return 0.0f;
-  float num_received = largest_received_packet_number_ - num_packets_received_;
-  return num_received / largest_received_packet_number_;
+  float num_received =
+      largest_received_packet_number_.ToUint64() - num_packets_received_;
+  return num_received / largest_received_packet_number_.ToUint64();
 }
 
 void QuicConnectionLogger::OnRttChanged(quic::QuicTime::Delta rtt) const {
@@ -849,7 +875,9 @@
   // histogram.  (e.g., if we only got 5 packets, but lost 1, we'd otherwise
   // record a 20% loss in this histogram!). We may still get some strange data
   // (1 loss in 22 is still high :-/).
-  if (largest_received_packet_number_ <= 21)
+  // TODO(fayang): Fix this as this check assume the first received packet is 1.
+  if (!largest_received_packet_number_.IsInitialized() ||
+      largest_received_packet_number_ <= quic::QuicPacketNumber(21))
     return;
 
   string prefix("Net.QuicSession.PacketLossRate_");
diff --git a/net/quic/quic_http_stream_test.cc b/net/quic/quic_http_stream_test.cc
index b414c978..5b8049b3 100644
--- a/net/quic/quic_http_stream_test.cc
+++ b/net/quic/quic_http_stream_test.cc
@@ -368,7 +368,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> InnerConstructDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -380,7 +380,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructClientDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
       bool fin,
       quic::QuicStreamOffset offset,
@@ -392,7 +392,7 @@
 
   std::unique_ptr<quic::QuicReceivedPacket>
   ConstructClientMultipleDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
       bool fin,
       quic::QuicStreamOffset offset,
@@ -402,7 +402,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
       bool fin,
       quic::QuicStreamOffset offset,
@@ -413,7 +413,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -426,7 +426,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> InnerConstructRequestHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -444,7 +444,7 @@
 
   std::unique_ptr<quic::QuicReceivedPacket>
   ConstructRequestHeadersAndDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -462,7 +462,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestAndRstPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -482,7 +482,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructRequestHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool fin,
       RequestPriority request_priority,
       size_t* spdy_headers_frame_length) {
@@ -492,7 +492,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> InnerConstructResponseHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool fin,
       size_t* spdy_headers_frame_length) {
@@ -503,7 +503,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool fin,
       size_t* spdy_headers_frame_length) {
     return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
@@ -511,7 +511,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket>
-  ConstructResponseHeadersPacketWithOffset(quic::QuicPacketNumber packet_number,
+  ConstructResponseHeadersPacketWithOffset(uint64_t packet_number,
                                            bool fin,
                                            size_t* spdy_headers_frame_length,
                                            quic::QuicStreamOffset* offset) {
@@ -521,7 +521,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructResponseTrailersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool fin,
       spdy::SpdyHeaderBlock trailers,
       size_t* spdy_headers_frame_length,
@@ -532,21 +532,19 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamPacket(
-      quic::QuicPacketNumber packet_number) {
+      uint64_t packet_number) {
     return client_maker_.MakeRstPacket(packet_number, true, stream_id_,
                                        quic::QUIC_RST_ACKNOWLEDGEMENT);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket>
-  ConstructClientRstStreamCancelledPacket(
-      quic::QuicPacketNumber packet_number) {
+  ConstructClientRstStreamCancelledPacket(uint64_t packet_number) {
     return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
                                        stream_id_, quic::QUIC_STREAM_CANCELLED);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket>
-  ConstructClientRstStreamVaryMismatchPacket(
-      quic::QuicPacketNumber packet_number) {
+  ConstructClientRstStreamVaryMismatchPacket(uint64_t packet_number) {
     return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
                                        promise_id_,
                                        quic::QUIC_PROMISE_VARY_MISMATCH);
@@ -554,7 +552,7 @@
 
   std::unique_ptr<quic::QuicReceivedPacket>
   ConstructClientRstStreamVaryMismatchAndRequestHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -572,10 +570,10 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked) {
     return client_maker_.MakeAckAndRstPacket(
         packet_number, !kIncludeVersion, stream_id_,
         quic::QUIC_STREAM_CANCELLED, largest_received, smallest_received,
@@ -583,7 +581,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool include_version) {
     return client_maker_.MakeRstPacket(packet_number, include_version,
                                        stream_id_,
@@ -591,32 +589,32 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstStreamPacket(
-      quic::QuicPacketNumber packet_number) {
+      uint64_t packet_number) {
     return ConstructAckAndRstStreamPacket(packet_number, 2, 1, 2);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructClientAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked) {
     return client_maker_.MakeAckPacket(packet_number, largest_received,
                                        smallest_received, least_unacked,
                                        !kIncludeCongestionFeedback);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked) {
     return server_maker_.MakeAckPacket(packet_number, largest_received,
                                        smallest_received, least_unacked,
                                        !kIncludeCongestionFeedback);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
       quic::QuicStreamId id,
       quic::QuicStreamId parent_stream_id,
@@ -2306,7 +2304,7 @@
   quic::QuicStreamOffset header_stream_offset = 0;
   AddWrite(ConstructInitialSettingsPacket(&header_stream_offset));
 
-  quic::QuicPacketNumber client_packet_number = 2;
+  uint64_t client_packet_number = 2;
   if (client_headers_include_h2_stream_dependency_ &&
       version_ >= quic::QUIC_VERSION_43) {
     AddWrite(ConstructClientPriorityPacket(
diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
index 379078a..e13c474 100644
--- a/net/quic/quic_network_transaction_unittest.cc
+++ b/net/quic/quic_network_transaction_unittest.cc
@@ -313,38 +313,38 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructClientConnectionClosePacket(quic::QuicPacketNumber num) {
+  ConstructClientConnectionClosePacket(uint64_t num) {
     return client_maker_.MakeConnectionClosePacket(
         num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructServerConnectionClosePacket(quic::QuicPacketNumber num) {
+  ConstructServerConnectionClosePacket(uint64_t num) {
     return server_maker_.MakeConnectionClosePacket(
         num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerGoAwayPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       quic::QuicErrorCode error_code,
       std::string reason_phrase) {
     return server_maker_.MakeGoAwayPacket(num, error_code, reason_phrase);
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked) {
     return client_maker_.MakeAckPacket(packet_number, largest_received,
                                        smallest_received, least_unacked, true);
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       quic::QuicTime::Delta ack_delay_time) {
     return client_maker_.MakeAckPacket(packet_number, largest_received,
                                        smallest_received, least_unacked, true,
@@ -352,19 +352,19 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndRstPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked) {
     return client_maker_.MakeAckAndRstPacket(
         num, false, stream_id, error_code, largest_received, smallest_received,
         least_unacked, true);
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
       size_t bytes_written) {
@@ -373,22 +373,21 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructClientAckAndConnectionClosePacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+  ConstructClientAckAndConnectionClosePacket(uint64_t packet_number,
+                                             uint64_t largest_received,
+                                             uint64_t smallest_received,
+                                             uint64_t least_unacked) {
     return client_maker_.MakeAckPacket(packet_number, largest_received,
                                        smallest_received, least_unacked, true);
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
   ConstructClientAckAndConnectionClosePacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       quic::QuicTime::Delta delta_time_largest_observed,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       quic::QuicErrorCode quic_error,
       const std::string& quic_error_details) {
     return client_maker_.MakeAckAndConnectionClosePacket(
@@ -397,7 +396,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerRstPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code) {
@@ -406,22 +405,22 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamOffset* offset) {
     return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructServerAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked) {
     return server_maker_.MakeAckPacket(packet_number, largest_received,
                                        smallest_received, least_unacked, false);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructClientPriorityPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
       quic::QuicStreamId id,
       quic::QuicStreamId parent_stream_id,
@@ -434,11 +433,11 @@
 
   std::unique_ptr<quic::QuicEncryptedPacket>
   ConstructClientAckAndPriorityFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       const std::vector<QuicTestPacketMaker::Http2StreamDependency>&
           priority_frames,
       quic::QuicStreamOffset* offset) {
@@ -477,7 +476,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -488,7 +487,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -500,7 +499,7 @@
 
   std::unique_ptr<quic::QuicEncryptedPacket>
   ConstructClientMultipleDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -512,12 +511,12 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckAndDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool include_version,
       quic::QuicStreamId stream_id,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool fin,
       quic::QuicStreamOffset offset,
       quic::QuicStringPiece data) {
@@ -528,12 +527,12 @@
 
   std::unique_ptr<quic::QuicEncryptedPacket>
   ConstructClientAckAndMultipleDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool include_version,
       quic::QuicStreamId stream_id,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool fin,
       quic::QuicStreamOffset offset,
       const std::vector<std::string> data_writes) {
@@ -543,7 +542,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientForceHolDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -554,7 +553,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
+  ConstructClientRequestHeadersPacket(uint64_t packet_number,
                                       quic::QuicStreamId stream_id,
                                       bool should_include_version,
                                       bool fin,
@@ -565,7 +564,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
+  ConstructClientRequestHeadersPacket(uint64_t packet_number,
                                       quic::QuicStreamId stream_id,
                                       bool should_include_version,
                                       bool fin,
@@ -577,7 +576,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
+  ConstructClientRequestHeadersPacket(uint64_t packet_number,
                                       quic::QuicStreamId stream_id,
                                       bool should_include_version,
                                       bool fin,
@@ -590,7 +589,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
+  ConstructClientRequestHeadersPacket(uint64_t packet_number,
                                       quic::QuicStreamId stream_id,
                                       bool should_include_version,
                                       bool fin,
@@ -607,7 +606,7 @@
 
   std::unique_ptr<quic::QuicReceivedPacket>
   ConstructClientRequestHeadersAndDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -626,7 +625,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructClientMultipleDataFramesPacket(quic::QuicPacketNumber packet_number,
+  ConstructClientMultipleDataFramesPacket(uint64_t packet_number,
                                           quic::QuicStreamId stream_id,
                                           bool should_include_version,
                                           bool fin,
@@ -637,7 +636,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerPushPromisePacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       quic::QuicStreamId promised_stream_id,
       bool should_include_version,
@@ -650,7 +649,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
+  ConstructServerResponseHeadersPacket(uint64_t packet_number,
                                        quic::QuicStreamId stream_id,
                                        bool should_include_version,
                                        bool fin,
@@ -661,7 +660,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
+  ConstructServerResponseHeadersPacket(uint64_t packet_number,
                                        quic::QuicStreamId stream_id,
                                        bool should_include_version,
                                        bool fin,
@@ -1244,7 +1243,7 @@
   spdy::SpdySerializedFrame spdy_frame =
       response_framer.SerializeFrame(headers_frame);
 
-  quic::QuicPacketNumber packet_number = 1;
+  uint64_t packet_number = 1;
   size_t chunk_size = 1200;
   for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
     size_t len = std::min(chunk_size, spdy_frame.size() - offset);
@@ -1303,7 +1302,7 @@
   spdy::SpdySerializedFrame spdy_frame =
       response_framer.SerializeFrame(headers_frame);
 
-  quic::QuicPacketNumber packet_number = 1;
+  uint64_t packet_number = 1;
   size_t chunk_size = 1200;
   for (size_t offset = 0; offset < spdy_frame.size(); offset += chunk_size) {
     size_t len = std::min(chunk_size, spdy_frame.size() - offset);
@@ -6379,7 +6378,7 @@
 
   MockQuicData mock_quic_data;
   quic::QuicStreamOffset header_stream_offset = 0;
-  quic::QuicPacketNumber client_packet_number = 1;
+  uint64_t client_packet_number = 1;
   mock_quic_data.AddWrite(
       SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
                                                   &header_stream_offset));
@@ -6470,7 +6469,7 @@
 
   MockQuicData mock_quic_data;
   quic::QuicStreamOffset header_stream_offset = 0;
-  quic::QuicPacketNumber client_packet_number = 1;
+  uint64_t client_packet_number = 1;
   // Initial SETTINGS frame.
   mock_quic_data.AddWrite(
       SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
@@ -6725,7 +6724,7 @@
 
   MockQuicData mock_quic_data;
   quic::QuicStreamOffset header_stream_offset = 0;
-  quic::QuicPacketNumber client_packet_number = 1;
+  uint64_t client_packet_number = 1;
   mock_quic_data.AddWrite(
       SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
                                                   &header_stream_offset));
@@ -6983,7 +6982,7 @@
         expiration, supported_versions_);
   }
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
+  ConstructClientRequestHeadersPacket(uint64_t packet_number,
                                       quic::QuicStreamId stream_id,
                                       bool should_include_version,
                                       quic::QuicStreamOffset* offset,
@@ -6993,7 +6992,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
+  ConstructClientRequestHeadersPacket(uint64_t packet_number,
                                       quic::QuicStreamId stream_id,
                                       bool should_include_version,
                                       quic::QuicStreamId parent_stream_id,
@@ -7009,7 +7008,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructClientRequestHeadersPacket(quic::QuicPacketNumber packet_number,
+  ConstructClientRequestHeadersPacket(uint64_t packet_number,
                                       quic::QuicStreamId stream_id,
                                       bool should_include_version,
                                       QuicTestPacketMaker* maker) {
@@ -7018,7 +7017,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
+  ConstructServerResponseHeadersPacket(uint64_t packet_number,
                                        quic::QuicStreamId stream_id,
                                        quic::QuicStreamOffset* offset,
                                        QuicTestPacketMaker* maker) {
@@ -7028,7 +7027,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructServerResponseHeadersPacket(quic::QuicPacketNumber packet_number,
+  ConstructServerResponseHeadersPacket(uint64_t packet_number,
                                        quic::QuicStreamId stream_id,
                                        QuicTestPacketMaker* maker) {
     return ConstructServerResponseHeadersPacket(packet_number, stream_id,
@@ -7036,7 +7035,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructServerDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       QuicTestPacketMaker* maker) {
     quic::QuicString header = "";
@@ -7051,17 +7050,17 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       QuicTestPacketMaker* maker) {
     return maker->MakeAckPacket(packet_number, largest_received,
                                 smallest_received, least_unacked, true);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamOffset* offset,
       QuicTestPacketMaker* maker) {
     return maker->MakeInitialSettingsPacket(packet_number, offset);
@@ -7406,7 +7405,7 @@
 
   MockQuicData mock_quic_data;
   quic::QuicStreamOffset header_stream_offset = 0;
-  quic::QuicPacketNumber client_packet_number = 1;
+  uint64_t client_packet_number = 1;
   mock_quic_data.AddWrite(
       SYNCHRONOUS, ConstructInitialSettingsPacket(client_packet_number++,
                                                   &header_stream_offset));
diff --git a/net/quic/quic_proxy_client_socket_unittest.cc b/net/quic/quic_proxy_client_socket_unittest.cc
index 8641a65..05fe8469 100644
--- a/net/quic/quic_proxy_client_socket_unittest.cc
+++ b/net/quic/quic_proxy_client_socket_unittest.cc
@@ -261,28 +261,28 @@
   // Helper functions for constructing packets sent by the client
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructSettingsPacket(
-      quic::QuicPacketNumber packet_number) {
+      uint64_t packet_number) {
     return client_maker_.MakeInitialSettingsPacket(packet_number,
                                                    &header_stream_offset_);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicRstStreamErrorCode error_code,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked) {
     return client_maker_.MakeAckAndRstPacket(
         packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
         largest_received, smallest_received, least_unacked, kSendFeedback);
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndRstPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicRstStreamErrorCode error_code,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       size_t bytes_written) {
     return client_maker_.MakeAckAndRstPacket(
         packet_number, !kIncludeVersion, client_data_stream_id1_, error_code,
@@ -291,7 +291,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructRstPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicRstStreamErrorCode error_code,
       size_t bytes_written) {
     return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
@@ -300,7 +300,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectRequestPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       RequestPriority request_priority = LOWEST) {
     spdy::SpdyHeaderBlock block;
     PopulateConnectRequestIR(&block);
@@ -311,7 +311,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructConnectAuthRequestPacket(
-      quic::QuicPacketNumber packet_number) {
+      uint64_t packet_number) {
     spdy::SpdyHeaderBlock block;
     PopulateConnectRequestIR(&block);
     block["proxy-authorization"] = "Basic Zm9vOmJhcg==";
@@ -322,7 +322,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamOffset offset,
       quic::QuicStringPiece data) {
     return client_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
@@ -330,7 +330,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructMultipleDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamOffset offset,
       const std::vector<std::string> data_writes) {
     return client_maker_.MakeMultipleDataFramesPacket(
@@ -339,10 +339,10 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructAckAndDataPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       quic::QuicStreamOffset offset,
       quic::QuicStringPiece data) {
     return client_maker_.MakeAckAndDataPacket(
@@ -353,10 +353,10 @@
 
   std::unique_ptr<quic::QuicReceivedPacket>
   ConstructAckAndMultipleDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       quic::QuicStreamOffset offset,
       const std::vector<std::string> data_writes) {
     return client_maker_.MakeAckAndMultipleDataFramesPacket(
@@ -366,10 +366,10 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked) {
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked) {
     return client_maker_.MakeAckPacket(packet_number, largest_received,
                                        smallest_received, least_unacked,
                                        kSendFeedback);
@@ -378,7 +378,7 @@
   // Helper functions for constructing packets sent by the server
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructServerRstPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicRstStreamErrorCode error_code,
       size_t bytes_written) {
     return server_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
@@ -387,7 +387,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamOffset offset,
       quic::QuicStringPiece data) {
     return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
@@ -395,7 +395,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructServerDataFinPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamOffset offset,
       quic::QuicStringPiece data) {
     return server_maker_.MakeDataPacket(packet_number, client_data_stream_id1_,
@@ -403,7 +403,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructServerConnectReplyPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool fin) {
     spdy::SpdyHeaderBlock block;
     block[":status"] = "200";
@@ -414,8 +414,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket>
-  ConstructServerConnectAuthReplyPacket(quic::QuicPacketNumber packet_number,
-                                        bool fin) {
+  ConstructServerConnectAuthReplyPacket(uint64_t packet_number, bool fin) {
     spdy::SpdyHeaderBlock block;
     block[":status"] = "407";
     block["proxy-authenticate"] = "Basic realm=\"MyRealm1\"";
@@ -425,9 +424,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket>
-  ConstructServerConnectRedirectReplyPacket(
-      quic::QuicPacketNumber packet_number,
-      bool fin) {
+  ConstructServerConnectRedirectReplyPacket(uint64_t packet_number, bool fin) {
     spdy::SpdyHeaderBlock block;
     block[":status"] = "302";
     block["location"] = kRedirectUrl;
@@ -438,8 +435,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket>
-  ConstructServerConnectErrorReplyPacket(quic::QuicPacketNumber packet_number,
-                                         bool fin) {
+  ConstructServerConnectErrorReplyPacket(uint64_t packet_number, bool fin) {
     spdy::SpdyHeaderBlock block;
     block[":status"] = "500";
 
diff --git a/net/quic/quic_stream_factory_test.cc b/net/quic/quic_stream_factory_test.cc
index b1aeb42e..72ca1eb7 100644
--- a/net/quic/quic_stream_factory_test.cc
+++ b/net/quic/quic_stream_factory_test.cc
@@ -421,13 +421,13 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket>
-  ConstructClientConnectionClosePacket(quic::QuicPacketNumber num) {
+  ConstructClientConnectionClosePacket(uint64_t num) {
     return client_maker_.MakeConnectionClosePacket(
         num, false, quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED, "Time to panic!");
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructClientRstPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicRstStreamErrorCode error_code) {
     quic::QuicStreamId stream_id =
         GetNthClientInitiatedBidirectionalStreamId(0);
@@ -453,7 +453,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin) {
@@ -468,7 +468,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       quic::QuicStreamId parent_stream_id,
       bool should_include_version,
@@ -485,7 +485,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructGetRequestPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -496,7 +496,7 @@
   }
 
   std::unique_ptr<quic::QuicEncryptedPacket> ConstructOkResponsePacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin) {
@@ -512,7 +512,7 @@
   }
 
   std::unique_ptr<quic::QuicReceivedPacket> ConstructInitialSettingsPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamOffset* offset) {
     return client_maker_.MakeInitialSettingsPacket(packet_number, offset);
   }
@@ -7837,7 +7837,7 @@
   QuicStreamFactoryPeer::SetYieldAfterPackets(factory_.get(), 0);
 
   MockQuicData socket_data;
-  socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(0));
+  socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
   socket_data.AddRead(ASYNC, OK);
   socket_data.AddSocketDataToFactory(socket_factory_.get());
 
@@ -7886,7 +7886,7 @@
       factory_.get(), quic::QuicTime::Delta::FromMilliseconds(-1));
 
   MockQuicData socket_data;
-  socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(0));
+  socket_data.AddRead(SYNCHRONOUS, ConstructClientConnectionClosePacket(1));
   socket_data.AddRead(ASYNC, OK);
   socket_data.AddSocketDataToFactory(socket_factory_.get());
 
diff --git a/net/quic/quic_test_packet_maker.cc b/net/quic/quic_test_packet_maker.cc
index 09c2c44..d0e5fcd8 100644
--- a/net/quic/quic_test_packet_maker.cc
+++ b/net/quic/quic_test_packet_maker.cc
@@ -18,9 +18,9 @@
 namespace test {
 namespace {
 
-quic::QuicAckFrame MakeAckFrame(quic::QuicPacketNumber largest_observed) {
+quic::QuicAckFrame MakeAckFrame(uint64_t largest_observed) {
   quic::QuicAckFrame ack;
-  ack.largest_acked = largest_observed;
+  ack.largest_acked = quic::QuicPacketNumber(largest_observed);
   return ack;
 }
 
@@ -56,7 +56,7 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeConnectivityProbingPacket(quic::QuicPacketNumber num,
+QuicTestPacketMaker::MakeConnectivityProbingPacket(uint64_t num,
                                                    bool include_version) {
   quic::QuicPacketHeader header;
   header.destination_connection_id = connection_id_;
@@ -67,7 +67,7 @@
   header.version_flag = ShouldIncludeVersion(include_version);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = num;
+  header.packet_number = quic::QuicPacketNumber(num);
 
   quic::QuicFramer framer(quic::test::SupportedVersions(quic::ParsedQuicVersion(
                               quic::PROTOCOL_QUIC_CRYPTO, version_)),
@@ -103,7 +103,7 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakePingPacket(
-    quic::QuicPacketNumber num,
+    uint64_t num,
     bool include_version) {
   quic::QuicPacketHeader header;
   header.destination_connection_id = connection_id_;
@@ -114,14 +114,14 @@
   header.version_flag = ShouldIncludeVersion(include_version);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = num;
+  header.packet_number = quic::QuicPacketNumber(num);
 
   quic::QuicPingFrame ping;
   return MakePacket(header, quic::QuicFrame(ping));
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeDummyCHLOPacket(quic::QuicPacketNumber packet_num) {
+QuicTestPacketMaker::MakeDummyCHLOPacket(uint64_t packet_num) {
   encryption_level_ = quic::ENCRYPTION_NONE;
   SetLongHeaderType(quic::INITIAL);
   InitializeHeader(packet_num, /*include_version=*/true);
@@ -144,12 +144,11 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeAckAndPingPacket(
-    quic::QuicPacketNumber num,
-    bool include_version,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked) {
+QuicTestPacketMaker::MakeAckAndPingPacket(uint64_t num,
+                                          bool include_version,
+                                          uint64_t largest_received,
+                                          uint64_t smallest_received,
+                                          uint64_t least_unacked) {
   quic::QuicPacketHeader header;
   header.destination_connection_id = connection_id_;
   header.destination_connection_id_length = GetDestinationConnectionIdLength();
@@ -159,16 +158,17 @@
   header.version_flag = ShouldIncludeVersion(include_version);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = num;
+  header.packet_number = quic::QuicPacketNumber(num);
 
   quic::QuicAckFrame ack(MakeAckFrame(largest_received));
   ack.ack_delay_time = quic::QuicTime::Delta::Zero();
-  for (quic::QuicPacketNumber i = smallest_received; i <= largest_received;
-       ++i) {
-    ack.received_packet_times.push_back(std::make_pair(i, clock_->Now()));
+  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
+    ack.received_packet_times.push_back(
+        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
   }
   if (largest_received > 0) {
-    ack.packets.AddRange(1, largest_received + 1);
+    ack.packets.AddRange(quic::QuicPacketNumber(1),
+                         quic::QuicPacketNumber(largest_received + 1));
   }
   quic::QuicFrames frames;
   frames.push_back(quic::QuicFrame(&ack));
@@ -176,7 +176,7 @@
 
   quic::QuicStopWaitingFrame stop_waiting;
   if (version_ == quic::QUIC_VERSION_35) {
-    stop_waiting.least_unacked = least_unacked;
+    stop_waiting.least_unacked = quic::QuicPacketNumber(least_unacked);
     frames.push_back(quic::QuicFrame(&stop_waiting));
     DVLOG(1) << "Adding frame: " << frames.back();
   }
@@ -188,7 +188,7 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeRstPacket(
-    quic::QuicPacketNumber num,
+    uint64_t num,
     bool include_version,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code) {
@@ -196,7 +196,7 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeRstPacket(
-    quic::QuicPacketNumber num,
+    uint64_t num,
     bool include_version,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code,
@@ -210,7 +210,7 @@
   header.version_flag = ShouldIncludeVersion(include_version);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = num;
+  header.packet_number = quic::QuicPacketNumber(num);
 
   quic::QuicFrames frames;
 
@@ -229,7 +229,7 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeStreamIdBlockedPacket(quic::QuicPacketNumber num,
+QuicTestPacketMaker::MakeStreamIdBlockedPacket(uint64_t num,
                                                bool include_version,
                                                quic::QuicStreamId stream_id) {
   quic::QuicPacketHeader header;
@@ -241,7 +241,7 @@
   header.version_flag = ShouldIncludeVersion(include_version);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = num;
+  header.packet_number = quic::QuicPacketNumber(num);
 
   quic::QuicStreamIdBlockedFrame frame(1, stream_id);
   DVLOG(1) << "Adding frame: " << quic::QuicFrame(frame);
@@ -249,7 +249,7 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeMaxStreamIdPacket(quic::QuicPacketNumber num,
+QuicTestPacketMaker::MakeMaxStreamIdPacket(uint64_t num,
                                            bool include_version,
                                            quic::QuicStreamId stream_id) {
   quic::QuicPacketHeader header;
@@ -261,7 +261,7 @@
   header.version_flag = ShouldIncludeVersion(include_version);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = num;
+  header.packet_number = quic::QuicPacketNumber(num);
 
   quic::QuicMaxStreamIdFrame frame(1, stream_id);
   DVLOG(1) << "Adding frame: " << quic::QuicFrame(frame);
@@ -270,7 +270,7 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRstAndRequestHeadersPacket(
-    quic::QuicPacketNumber num,
+    uint64_t num,
     bool include_version,
     quic::QuicStreamId rst_stream_id,
     quic::QuicRstStreamErrorCode rst_error_code,
@@ -317,13 +317,13 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeAckAndRstPacket(
-    quic::QuicPacketNumber num,
+    uint64_t num,
     bool include_version,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked,
+    uint64_t largest_received,
+    uint64_t smallest_received,
+    uint64_t least_unacked,
     bool send_feedback) {
   return MakeAckAndRstPacket(num, include_version, stream_id, error_code,
                              largest_received, smallest_received, least_unacked,
@@ -332,13 +332,13 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeAckAndRstPacket(
-    quic::QuicPacketNumber num,
+    uint64_t num,
     bool include_version,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked,
+    uint64_t largest_received,
+    uint64_t smallest_received,
+    uint64_t least_unacked,
     bool send_feedback,
     size_t bytes_written) {
   quic::QuicPacketHeader header;
@@ -350,16 +350,17 @@
   header.version_flag = ShouldIncludeVersion(include_version);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = num;
+  header.packet_number = quic::QuicPacketNumber(num);
 
   quic::QuicAckFrame ack(MakeAckFrame(largest_received));
   ack.ack_delay_time = quic::QuicTime::Delta::Zero();
-  for (quic::QuicPacketNumber i = smallest_received; i <= largest_received;
-       ++i) {
-    ack.received_packet_times.push_back(std::make_pair(i, clock_->Now()));
+  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
+    ack.received_packet_times.push_back(
+        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
   }
   if (largest_received > 0) {
-    ack.packets.AddRange(1, largest_received + 1);
+    ack.packets.AddRange(quic::QuicPacketNumber(1),
+                         quic::QuicPacketNumber(largest_received + 1));
   }
   quic::QuicFrames frames;
   frames.push_back(quic::QuicFrame(&ack));
@@ -367,7 +368,7 @@
 
   quic::QuicStopWaitingFrame stop_waiting;
   if (version_ == quic::QUIC_VERSION_35) {
-    stop_waiting.least_unacked = least_unacked;
+    stop_waiting.least_unacked = quic::QuicPacketNumber(least_unacked);
     frames.push_back(quic::QuicFrame(&stop_waiting));
     DVLOG(1) << "Adding frame: " << frames.back();
   }
@@ -389,14 +390,14 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRstAckAndConnectionClosePacket(
-    quic::QuicPacketNumber num,
+    uint64_t num,
     bool include_version,
     quic::QuicStreamId stream_id,
     quic::QuicRstStreamErrorCode error_code,
     quic::QuicTime::Delta ack_delay_time,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked,
+    uint64_t largest_received,
+    uint64_t smallest_received,
+    uint64_t least_unacked,
     quic::QuicErrorCode quic_error,
     const std::string& quic_error_details) {
   quic::QuicPacketHeader header;
@@ -408,7 +409,7 @@
   header.version_flag = ShouldIncludeVersion(include_version);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = num;
+  header.packet_number = quic::QuicPacketNumber(num);
 
   quic::QuicFrames frames;
   quic::QuicRstStreamFrame rst(1, stream_id, error_code, 0);
@@ -426,19 +427,20 @@
 
   quic::QuicAckFrame ack(MakeAckFrame(largest_received));
   ack.ack_delay_time = ack_delay_time;
-  for (quic::QuicPacketNumber i = smallest_received; i <= largest_received;
-       ++i) {
-    ack.received_packet_times.push_back(std::make_pair(i, clock_->Now()));
+  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
+    ack.received_packet_times.push_back(
+        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
   }
   if (largest_received > 0) {
-    ack.packets.AddRange(1, largest_received + 1);
+    ack.packets.AddRange(quic::QuicPacketNumber(1),
+                         quic::QuicPacketNumber(largest_received + 1));
   }
   frames.push_back(quic::QuicFrame(&ack));
   DVLOG(1) << "Adding frame: " << frames.back();
 
   quic::QuicStopWaitingFrame stop_waiting;
   if (version_ == quic::QUIC_VERSION_35) {
-    stop_waiting.least_unacked = least_unacked;
+    stop_waiting.least_unacked = quic::QuicPacketNumber(least_unacked);
     frames.push_back(quic::QuicFrame(&stop_waiting));
     DVLOG(1) << "Adding frame: " << frames.back();
   }
@@ -455,12 +457,12 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeAckAndConnectionClosePacket(
-    quic::QuicPacketNumber num,
+    uint64_t num,
     bool include_version,
     quic::QuicTime::Delta ack_delay_time,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked,
+    uint64_t largest_received,
+    uint64_t smallest_received,
+    uint64_t least_unacked,
     quic::QuicErrorCode quic_error,
     const std::string& quic_error_details) {
   quic::QuicPacketHeader header;
@@ -472,16 +474,17 @@
   header.version_flag = ShouldIncludeVersion(include_version);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = num;
+  header.packet_number = quic::QuicPacketNumber(num);
 
   quic::QuicAckFrame ack(MakeAckFrame(largest_received));
   ack.ack_delay_time = ack_delay_time;
-  for (quic::QuicPacketNumber i = smallest_received; i <= largest_received;
-       ++i) {
-    ack.received_packet_times.push_back(std::make_pair(i, clock_->Now()));
+  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
+    ack.received_packet_times.push_back(
+        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
   }
   if (largest_received > 0) {
-    ack.packets.AddRange(1, largest_received + 1);
+    ack.packets.AddRange(quic::QuicPacketNumber(1),
+                         quic::QuicPacketNumber(largest_received + 1));
   }
   quic::QuicFrames frames;
   frames.push_back(quic::QuicFrame(&ack));
@@ -489,7 +492,7 @@
 
   quic::QuicStopWaitingFrame stop_waiting;
   if (version_ == quic::QUIC_VERSION_35) {
-    stop_waiting.least_unacked = least_unacked;
+    stop_waiting.least_unacked = quic::QuicPacketNumber(least_unacked);
     frames.push_back(quic::QuicFrame(&stop_waiting));
     DVLOG(1) << "Adding frame: " << frames.back();
   }
@@ -506,7 +509,7 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeConnectionClosePacket(
-    quic::QuicPacketNumber num,
+    uint64_t num,
     bool include_version,
     quic::QuicErrorCode quic_error,
     const std::string& quic_error_details) {
@@ -519,7 +522,7 @@
   header.version_flag = ShouldIncludeVersion(include_version);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = num;
+  header.packet_number = quic::QuicPacketNumber(num);
 
   quic::QuicConnectionCloseFrame close;
   close.error_code = quic_error;
@@ -528,7 +531,7 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeGoAwayPacket(
-    quic::QuicPacketNumber num,
+    uint64_t num,
     quic::QuicErrorCode error_code,
     std::string reason_phrase) {
   quic::QuicPacketHeader header;
@@ -540,7 +543,7 @@
   header.version_flag = ShouldIncludeVersion(false);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = num;
+  header.packet_number = quic::QuicPacketNumber(num);
 
   quic::QuicGoAwayFrame goaway;
   goaway.error_code = error_code;
@@ -550,10 +553,10 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
-    quic::QuicPacketNumber packet_number,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked,
+    uint64_t packet_number,
+    uint64_t largest_received,
+    uint64_t smallest_received,
+    uint64_t least_unacked,
     bool send_feedback) {
   return MakeAckPacket(packet_number, 1, largest_received, smallest_received,
                        least_unacked, send_feedback,
@@ -561,11 +564,11 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
-    quic::QuicPacketNumber packet_number,
-    quic::QuicPacketNumber first_received,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked,
+    uint64_t packet_number,
+    uint64_t first_received,
+    uint64_t largest_received,
+    uint64_t smallest_received,
+    uint64_t least_unacked,
     bool send_feedback) {
   return MakeAckPacket(packet_number, first_received, largest_received,
                        smallest_received, least_unacked, send_feedback,
@@ -573,10 +576,10 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
-    quic::QuicPacketNumber packet_number,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked,
+    uint64_t packet_number,
+    uint64_t largest_received,
+    uint64_t smallest_received,
+    uint64_t least_unacked,
     bool send_feedback,
     quic::QuicTime::Delta ack_delay_time) {
   return MakeAckPacket(packet_number, 1, largest_received, smallest_received,
@@ -584,11 +587,11 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
-    quic::QuicPacketNumber packet_number,
-    quic::QuicPacketNumber first_received,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked,
+    uint64_t packet_number,
+    uint64_t first_received,
+    uint64_t largest_received,
+    uint64_t smallest_received,
+    uint64_t least_unacked,
     bool send_feedback,
     quic::QuicTime::Delta ack_delay_time) {
   quic::QuicPacketHeader header;
@@ -600,17 +603,18 @@
   header.version_flag = ShouldIncludeVersion(false);
   header.long_packet_type = long_header_type_;
   header.packet_number_length = GetPacketNumberLength();
-  header.packet_number = packet_number;
+  header.packet_number = quic::QuicPacketNumber(packet_number);
 
   quic::QuicAckFrame ack(MakeAckFrame(largest_received));
   ack.ack_delay_time = ack_delay_time;
-  for (quic::QuicPacketNumber i = smallest_received; i <= largest_received;
-       ++i) {
-    ack.received_packet_times.push_back(std::make_pair(i, clock_->Now()));
+  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
+    ack.received_packet_times.push_back(
+        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
   }
   if (largest_received > 0) {
     DCHECK_GE(largest_received, first_received);
-    ack.packets.AddRange(first_received, largest_received + 1);
+    ack.packets.AddRange(quic::QuicPacketNumber(first_received),
+                         quic::QuicPacketNumber(largest_received + 1));
   }
   quic::QuicFramer framer(quic::test::SupportedVersions(quic::ParsedQuicVersion(
                               quic::PROTOCOL_QUIC_CRYPTO, version_)),
@@ -622,7 +626,7 @@
 
   quic::QuicStopWaitingFrame stop_waiting;
   if (version_ == quic::QUIC_VERSION_35) {
-    stop_waiting.least_unacked = least_unacked;
+    stop_waiting.least_unacked = quic::QuicPacketNumber(least_unacked);
     frames.push_back(quic::QuicFrame(&stop_waiting));
     DVLOG(1) << "Adding frame: " << frames.back();
   }
@@ -641,7 +645,7 @@
 
 // Returns a newly created packet to send kData on stream 1.
 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeDataPacket(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     bool should_include_version,
     bool fin,
@@ -655,7 +659,7 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeMultipleDataFramesPacket(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     bool should_include_version,
     bool fin,
@@ -675,26 +679,26 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeAckAndDataPacket(
-    quic::QuicPacketNumber packet_number,
-    bool include_version,
-    quic::QuicStreamId stream_id,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked,
-    bool fin,
-    quic::QuicStreamOffset offset,
-    quic::QuicStringPiece data) {
+QuicTestPacketMaker::MakeAckAndDataPacket(uint64_t packet_number,
+                                          bool include_version,
+                                          quic::QuicStreamId stream_id,
+                                          uint64_t largest_received,
+                                          uint64_t smallest_received,
+                                          uint64_t least_unacked,
+                                          bool fin,
+                                          quic::QuicStreamOffset offset,
+                                          quic::QuicStringPiece data) {
   InitializeHeader(packet_number, include_version);
 
   quic::QuicAckFrame ack(MakeAckFrame(largest_received));
   ack.ack_delay_time = quic::QuicTime::Delta::Zero();
-  for (quic::QuicPacketNumber i = smallest_received; i <= largest_received;
-       ++i) {
-    ack.received_packet_times.push_back(std::make_pair(i, clock_->Now()));
+  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
+    ack.received_packet_times.push_back(
+        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
   }
   if (largest_received > 0) {
-    ack.packets.AddRange(1, largest_received + 1);
+    ack.packets.AddRange(quic::QuicPacketNumber(1),
+                         quic::QuicPacketNumber(largest_received + 1));
   }
   quic::QuicFrames frames;
   frames.push_back(quic::QuicFrame(&ack));
@@ -702,7 +706,7 @@
 
   quic::QuicStopWaitingFrame stop_waiting;
   if (version_ == quic::QUIC_VERSION_35) {
-    stop_waiting.least_unacked = least_unacked;
+    stop_waiting.least_unacked = quic::QuicPacketNumber(least_unacked);
     frames.push_back(quic::QuicFrame(&stop_waiting));
     DVLOG(1) << "Adding frame: " << frames.back();
   }
@@ -716,12 +720,12 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeAckAndMultipleDataFramesPacket(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     bool include_version,
     quic::QuicStreamId stream_id,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked,
+    uint64_t largest_received,
+    uint64_t smallest_received,
+    uint64_t least_unacked,
     bool fin,
     quic::QuicStreamOffset offset,
     const std::vector<std::string>& data_writes) {
@@ -729,12 +733,13 @@
 
   quic::QuicAckFrame ack(MakeAckFrame(largest_received));
   ack.ack_delay_time = quic::QuicTime::Delta::Zero();
-  for (quic::QuicPacketNumber i = smallest_received; i <= largest_received;
-       ++i) {
-    ack.received_packet_times.push_back(std::make_pair(i, clock_->Now()));
+  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
+    ack.received_packet_times.push_back(
+        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
   }
   if (largest_received > 0) {
-    ack.packets.AddRange(1, largest_received + 1);
+    ack.packets.AddRange(quic::QuicPacketNumber(1),
+                         quic::QuicPacketNumber(largest_received + 1));
   }
   quic::QuicFrames frames;
   frames.push_back(quic::QuicFrame(&ack));
@@ -742,7 +747,7 @@
 
   quic::QuicStopWaitingFrame stop_waiting;
   if (version_ == quic::QUIC_VERSION_35) {
-    stop_waiting.least_unacked = least_unacked;
+    stop_waiting.least_unacked = quic::QuicPacketNumber(least_unacked);
     frames.push_back(quic::QuicFrame(&stop_waiting));
     DVLOG(1) << "Adding frame: " << frames.back();
   }
@@ -760,7 +765,7 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRequestHeadersAndMultipleDataFramesPacket(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     bool should_include_version,
     bool fin,
@@ -807,7 +812,7 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRequestHeadersPacket(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     bool should_include_version,
     bool fin,
@@ -824,7 +829,7 @@
 // Will also update the value after packet creation.
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRequestHeadersPacket(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     bool should_include_version,
     bool fin,
@@ -842,7 +847,7 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRequestHeadersPacketAndSaveData(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     bool should_include_version,
     bool fin,
@@ -877,7 +882,7 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRequestHeadersAndRstPacket(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     bool should_include_version,
     bool fin,
@@ -948,7 +953,7 @@
 // |spdy_headers_frame_length|.
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeRequestHeadersPacketWithOffsetTracking(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     bool should_include_version,
     bool fin,
@@ -965,7 +970,7 @@
 // Will also update the value after packet creation.
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakePushPromisePacket(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     quic::QuicStreamId promised_stream_id,
     bool should_include_version,
@@ -997,13 +1002,12 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeForceHolDataPacket(
-    quic::QuicPacketNumber packet_number,
-    quic::QuicStreamId stream_id,
-    bool should_include_version,
-    bool fin,
-    quic::QuicStreamOffset* offset,
-    quic::QuicStringPiece data) {
+QuicTestPacketMaker::MakeForceHolDataPacket(uint64_t packet_number,
+                                            quic::QuicStreamId stream_id,
+                                            bool should_include_version,
+                                            bool fin,
+                                            quic::QuicStreamOffset* offset,
+                                            quic::QuicStringPiece data) {
   spdy::SpdyDataIR spdy_data(stream_id, data);
   spdy_data.set_fin(fin);
   spdy::SpdySerializedFrame spdy_frame(
@@ -1020,7 +1024,7 @@
 // Will also update the value after packet creation.
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeResponseHeadersPacket(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     bool should_include_version,
     bool fin,
@@ -1052,7 +1056,7 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeResponseHeadersPacket(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     bool should_include_version,
     bool fin,
@@ -1067,7 +1071,7 @@
 // |spdy_headers_frame_length|.
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeResponseHeadersPacketWithOffsetTracking(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamId stream_id,
     bool should_include_version,
     bool fin,
@@ -1145,7 +1149,7 @@
   return encrypted.Clone();
 }
 
-void QuicTestPacketMaker::InitializeHeader(quic::QuicPacketNumber packet_number,
+void QuicTestPacketMaker::InitializeHeader(uint64_t packet_number,
                                            bool should_include_version) {
   header_.destination_connection_id = connection_id_;
   header_.destination_connection_id_length = GetDestinationConnectionIdLength();
@@ -1155,13 +1159,12 @@
   header_.version_flag = ShouldIncludeVersion(should_include_version);
   header_.long_packet_type = long_header_type_;
   header_.packet_number_length = GetPacketNumberLength();
-  header_.packet_number = packet_number;
+  header_.packet_number = quic::QuicPacketNumber(packet_number);
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakeInitialSettingsPacket(
-    quic::QuicPacketNumber packet_number,
-    quic::QuicStreamOffset* offset) {
+QuicTestPacketMaker::MakeInitialSettingsPacket(uint64_t packet_number,
+                                               quic::QuicStreamOffset* offset) {
   std::string unused_data;
   return MakeInitialSettingsPacketAndSaveData(packet_number, offset,
                                               &unused_data);
@@ -1169,7 +1172,7 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeInitialSettingsPacketAndSaveData(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     quic::QuicStreamOffset* offset,
     std::string* stream_data) {
   spdy::SpdySettingsIR settings_frame;
@@ -1193,7 +1196,7 @@
 }
 
 std::unique_ptr<quic::QuicReceivedPacket>
-QuicTestPacketMaker::MakePriorityPacket(quic::QuicPacketNumber packet_number,
+QuicTestPacketMaker::MakePriorityPacket(uint64_t packet_number,
                                         bool should_include_version,
                                         quic::QuicStreamId id,
                                         quic::QuicStreamId parent_stream_id,
@@ -1223,21 +1226,22 @@
 
 std::unique_ptr<quic::QuicReceivedPacket>
 QuicTestPacketMaker::MakeAckAndMultiplePriorityFramesPacket(
-    quic::QuicPacketNumber packet_number,
+    uint64_t packet_number,
     bool should_include_version,
-    quic::QuicPacketNumber largest_received,
-    quic::QuicPacketNumber smallest_received,
-    quic::QuicPacketNumber least_unacked,
+    uint64_t largest_received,
+    uint64_t smallest_received,
+    uint64_t least_unacked,
     const std::vector<Http2StreamDependency>& priority_frames,
     quic::QuicStreamOffset* offset) {
   quic::QuicAckFrame ack(MakeAckFrame(largest_received));
   ack.ack_delay_time = quic::QuicTime::Delta::Zero();
-  for (quic::QuicPacketNumber i = smallest_received; i <= largest_received;
-       ++i) {
-    ack.received_packet_times.push_back(std::make_pair(i, clock_->Now()));
+  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
+    ack.received_packet_times.push_back(
+        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
   }
   if (largest_received > 0) {
-    ack.packets.AddRange(1, largest_received + 1);
+    ack.packets.AddRange(quic::QuicPacketNumber(1),
+                         quic::QuicPacketNumber(largest_received + 1));
   }
   quic::QuicFrames frames;
   frames.push_back(quic::QuicFrame(&ack));
@@ -1245,7 +1249,7 @@
 
   quic::QuicStopWaitingFrame stop_waiting;
   if (version_ == quic::QUIC_VERSION_35) {
-    stop_waiting.least_unacked = least_unacked;
+    stop_waiting.least_unacked = quic::QuicPacketNumber(least_unacked);
     frames.push_back(quic::QuicFrame(&stop_waiting));
     DVLOG(1) << "Adding frame: " << frames.back();
   }
diff --git a/net/quic/quic_test_packet_maker.h b/net/quic/quic_test_packet_maker.h
index 33b8d365..0504966 100644
--- a/net/quic/quic_test_packet_maker.h
+++ b/net/quic/quic_test_packet_maker.h
@@ -49,45 +49,45 @@
 
   void set_hostname(const std::string& host);
   std::unique_ptr<quic::QuicReceivedPacket> MakeConnectivityProbingPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version);
   std::unique_ptr<quic::QuicReceivedPacket> MakePingPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version);
   std::unique_ptr<quic::QuicReceivedPacket> MakeDummyCHLOPacket(
-      quic::QuicPacketNumber packet_num);
+      uint64_t packet_num);
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndPingPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked);
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeStreamIdBlockedPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
       quic::QuicStreamId stream_id);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeMaxStreamIdPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
       quic::QuicStreamId stream_id);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRstPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRstPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
       size_t bytes_written);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRstAndRequestHeadersPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
       quic::QuicStreamId rst_stream_id,
       quic::QuicRstStreamErrorCode rst_error_code,
@@ -100,126 +100,126 @@
       quic::QuicStreamOffset* offset);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndRstPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool send_feedback);
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndRstPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool send_feedback,
       size_t bytes_written);
   std::unique_ptr<quic::QuicReceivedPacket> MakeRstAckAndConnectionClosePacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
       quic::QuicStreamId stream_id,
       quic::QuicRstStreamErrorCode error_code,
       quic::QuicTime::Delta delta_time_largest_observed,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       quic::QuicErrorCode quic_error,
       const std::string& quic_error_details);
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndConnectionClosePacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
       quic::QuicTime::Delta delta_time_largest_observed,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       quic::QuicErrorCode quic_error,
       const std::string& quic_error_details);
   std::unique_ptr<quic::QuicReceivedPacket> MakeConnectionClosePacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       bool include_version,
       quic::QuicErrorCode quic_error,
       const std::string& quic_error_details);
   std::unique_ptr<quic::QuicReceivedPacket> MakeGoAwayPacket(
-      quic::QuicPacketNumber num,
+      uint64_t num,
       quic::QuicErrorCode error_code,
       std::string reason_phrase);
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool send_feedback);
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber first_received,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t packet_number,
+      uint64_t first_received,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool send_feedback);
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t packet_number,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool send_feedback,
       quic::QuicTime::Delta ack_delay_time);
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckPacket(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicPacketNumber first_received,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t packet_number,
+      uint64_t first_received,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool send_feedback,
       quic::QuicTime::Delta ack_delay_time);
   std::unique_ptr<quic::QuicReceivedPacket> MakeDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
       quic::QuicStreamOffset offset,
       quic::QuicStringPiece data);
   std::unique_ptr<quic::QuicReceivedPacket> MakeForceHolDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
       quic::QuicStreamOffset* offset,
       quic::QuicStringPiece data);
   std::unique_ptr<quic::QuicReceivedPacket> MakeMultipleDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
       quic::QuicStreamOffset offset,
       const std::vector<std::string>& data_writes);
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndDataPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool include_version,
       quic::QuicStreamId stream_id,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool fin,
       quic::QuicStreamOffset offset,
       quic::QuicStringPiece data);
   std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndMultipleDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool include_version,
       quic::QuicStreamId stream_id,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       bool fin,
       quic::QuicStreamOffset offset,
       const std::vector<std::string>& data);
 
   std::unique_ptr<quic::QuicReceivedPacket>
   MakeRequestHeadersAndMultipleDataFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -233,7 +233,7 @@
   // If |spdy_headers_frame_length| is non-null, it will be set to the size of
   // the SPDY headers frame created for this packet.
   std::unique_ptr<quic::QuicReceivedPacket> MakeRequestHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -243,7 +243,7 @@
       size_t* spdy_headers_frame_length);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRequestHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -255,7 +255,7 @@
 
   // Saves the serialized QUIC stream data in |stream_data|.
   std::unique_ptr<quic::QuicReceivedPacket> MakeRequestHeadersPacketAndSaveData(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -267,7 +267,7 @@
       std::string* stream_data);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeRequestHeadersAndRstPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -283,7 +283,7 @@
   // |spdy_headers_frame_length|.
   std::unique_ptr<quic::QuicReceivedPacket>
   MakeRequestHeadersPacketWithOffsetTracking(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -295,7 +295,7 @@
   // If |spdy_headers_frame_length| is non-null, it will be set to the size of
   // the SPDY headers frame created for this packet.
   std::unique_ptr<quic::QuicReceivedPacket> MakePushPromisePacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       quic::QuicStreamId promised_stream_id,
       bool should_include_version,
@@ -307,7 +307,7 @@
   // If |spdy_headers_frame_length| is non-null, it will be set to the size of
   // the SPDY headers frame created for this packet.
   std::unique_ptr<quic::QuicReceivedPacket> MakeResponseHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -316,7 +316,7 @@
       quic::QuicStreamOffset* offset);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakeResponseHeadersPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamId stream_id,
       bool should_include_version,
       bool fin,
@@ -326,29 +326,28 @@
   // Convenience method for calling MakeResponseHeadersPacket with nullptr for
   // |spdy_headers_frame_length|.
   std::unique_ptr<quic::QuicReceivedPacket>
-  MakeResponseHeadersPacketWithOffsetTracking(
-      quic::QuicPacketNumber packet_number,
-      quic::QuicStreamId stream_id,
-      bool should_include_version,
-      bool fin,
-      spdy::SpdyHeaderBlock headers,
-      quic::QuicStreamOffset* offset);
+  MakeResponseHeadersPacketWithOffsetTracking(uint64_t packet_number,
+                                              quic::QuicStreamId stream_id,
+                                              bool should_include_version,
+                                              bool fin,
+                                              spdy::SpdyHeaderBlock headers,
+                                              quic::QuicStreamOffset* offset);
 
   // Creates a packet containing the initial SETTINGS frame, and saves the
   // headers stream offset into |offset|.
   std::unique_ptr<quic::QuicReceivedPacket> MakeInitialSettingsPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       quic::QuicStreamOffset* offset);
 
   // Same as above, but also saves the serialized QUIC stream data in
   // |stream_data|.
   std::unique_ptr<quic::QuicReceivedPacket>
-  MakeInitialSettingsPacketAndSaveData(quic::QuicPacketNumber packet_number,
+  MakeInitialSettingsPacketAndSaveData(uint64_t packet_number,
                                        quic::QuicStreamOffset* offset,
                                        std::string* stream_data);
 
   std::unique_ptr<quic::QuicReceivedPacket> MakePriorityPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
       quic::QuicStreamId id,
       quic::QuicStreamId parent_stream_id,
@@ -357,11 +356,11 @@
 
   std::unique_ptr<quic::QuicReceivedPacket>
   MakeAckAndMultiplePriorityFramesPacket(
-      quic::QuicPacketNumber packet_number,
+      uint64_t packet_number,
       bool should_include_version,
-      quic::QuicPacketNumber largest_received,
-      quic::QuicPacketNumber smallest_received,
-      quic::QuicPacketNumber least_unacked,
+      uint64_t largest_received,
+      uint64_t smallest_received,
+      uint64_t least_unacked,
       const std::vector<Http2StreamDependency>& priority_frames,
       quic::QuicStreamOffset* offset);
 
@@ -391,8 +390,7 @@
       const quic::QuicPacketHeader& header,
       const quic::QuicFrames& frames);
 
-  void InitializeHeader(quic::QuicPacketNumber packet_number,
-                        bool should_include_version);
+  void InitializeHeader(uint64_t packet_number, bool should_include_version);
 
   spdy::SpdySerializedFrame MakeSpdyHeadersFrame(
       quic::QuicStreamId stream_id,
diff --git a/net/third_party/quic/core/chlo_extractor_test.cc b/net/third_party/quic/core/chlo_extractor_test.cc
index fbd1b96..fbb9c55 100644
--- a/net/third_party/quic/core/chlo_extractor_test.cc
+++ b/net/third_party/quic/core/chlo_extractor_test.cc
@@ -52,7 +52,7 @@
     header_.version = AllSupportedVersions().front();
     header_.reset_flag = false;
     header_.packet_number_length = PACKET_4BYTE_PACKET_NUMBER;
-    header_.packet_number = 1;
+    header_.packet_number = QuicPacketNumber(1);
   }
 
   void MakePacket(const QuicStreamFrame& stream_frame) {
diff --git a/net/third_party/quic/core/congestion_control/bandwidth_sampler.cc b/net/third_party/quic/core/congestion_control/bandwidth_sampler.cc
index 461b227..5d482cdf 100644
--- a/net/third_party/quic/core/congestion_control/bandwidth_sampler.cc
+++ b/net/third_party/quic/core/congestion_control/bandwidth_sampler.cc
@@ -18,9 +18,7 @@
       total_bytes_sent_at_last_acked_packet_(0),
       last_acked_packet_sent_time_(QuicTime::Zero()),
       last_acked_packet_ack_time_(QuicTime::Zero()),
-      last_sent_packet_(0),
       is_app_limited_(false),
-      end_of_app_limited_phase_(0),
       connection_state_map_() {}
 
 BandwidthSampler::~BandwidthSampler() {}
diff --git a/net/third_party/quic/core/congestion_control/bandwidth_sampler_test.cc b/net/third_party/quic/core/congestion_control/bandwidth_sampler_test.cc
index 56c9795f..19e6f7d 100644
--- a/net/third_party/quic/core/congestion_control/bandwidth_sampler_test.cc
+++ b/net/third_party/quic/core/congestion_control/bandwidth_sampler_test.cc
@@ -40,54 +40,55 @@
   BandwidthSampler sampler_;
   QuicByteCount bytes_in_flight_;
 
-  void SendPacketInner(QuicPacketNumber packet_number,
+  void SendPacketInner(uint64_t packet_number,
                        QuicByteCount bytes,
                        HasRetransmittableData has_retransmittable_data) {
-    sampler_.OnPacketSent(clock_.Now(), packet_number, bytes, bytes_in_flight_,
-                          has_retransmittable_data);
+    sampler_.OnPacketSent(clock_.Now(), QuicPacketNumber(packet_number), bytes,
+                          bytes_in_flight_, has_retransmittable_data);
     if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA) {
       bytes_in_flight_ += bytes;
     }
   }
 
-  void SendPacket(QuicPacketNumber packet_number) {
+  void SendPacket(uint64_t packet_number) {
     SendPacketInner(packet_number, kRegularPacketSize,
                     HAS_RETRANSMITTABLE_DATA);
   }
 
-  BandwidthSample AckPacketInner(QuicPacketNumber packet_number) {
-    QuicByteCount size =
-        BandwidthSamplerPeer::GetPacketSize(sampler_, packet_number);
+  BandwidthSample AckPacketInner(uint64_t packet_number) {
+    QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
+        sampler_, QuicPacketNumber(packet_number));
     bytes_in_flight_ -= size;
-    return sampler_.OnPacketAcknowledged(clock_.Now(), packet_number);
+    return sampler_.OnPacketAcknowledged(clock_.Now(),
+                                         QuicPacketNumber(packet_number));
   }
 
   // Acknowledge receipt of a packet and expect it to be not app-limited.
-  QuicBandwidth AckPacket(QuicPacketNumber packet_number) {
+  QuicBandwidth AckPacket(uint64_t packet_number) {
     BandwidthSample sample = AckPacketInner(packet_number);
     EXPECT_FALSE(sample.is_app_limited);
     return sample.bandwidth;
   }
 
-  void LosePacket(QuicPacketNumber packet_number) {
-    QuicByteCount size =
-        BandwidthSamplerPeer::GetPacketSize(sampler_, packet_number);
+  void LosePacket(uint64_t packet_number) {
+    QuicByteCount size = BandwidthSamplerPeer::GetPacketSize(
+        sampler_, QuicPacketNumber(packet_number));
     bytes_in_flight_ -= size;
-    sampler_.OnPacketLost(packet_number);
+    sampler_.OnPacketLost(QuicPacketNumber(packet_number));
   }
 
   // Sends one packet and acks it.  Then, send 20 packets.  Finally, send
   // another 20 packets while acknowledging previous 20.
   void Send40PacketsAndAckFirst20(QuicTime::Delta time_between_packets) {
     // Send 20 packets at a constant inter-packet time.
-    for (QuicPacketNumber i = 1; i <= 20; i++) {
+    for (int i = 1; i <= 20; i++) {
       SendPacket(i);
       clock_.AdvanceTime(time_between_packets);
     }
 
     // Ack packets 1 to 20, while sending new packets at the same rate as
     // before.
-    for (QuicPacketNumber i = 1; i <= 20; i++) {
+    for (int i = 1; i <= 20; i++) {
       AckPacket(i);
       SendPacket(i + 20);
       clock_.AdvanceTime(time_between_packets);
@@ -102,7 +103,7 @@
       QuicBandwidth::FromBytesPerSecond(kRegularPacketSize * 100);
 
   // Send packets at the constant bandwidth.
-  for (QuicPacketNumber i = 1; i < 20; i++) {
+  for (int i = 1; i < 20; i++) {
     SendPacket(i);
     clock_.AdvanceTime(time_between_packets);
     QuicBandwidth current_sample = AckPacket(i);
@@ -110,7 +111,7 @@
   }
 
   // Send packets at the exponentially decreasing bandwidth.
-  for (QuicPacketNumber i = 20; i < 25; i++) {
+  for (int i = 20; i < 25; i++) {
     time_between_packets = time_between_packets * 2;
     expected_bandwidth = expected_bandwidth * 0.5;
 
@@ -135,7 +136,7 @@
 
   // Ack the packets 21 to 40, arriving at the correct bandwidth.
   QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
-  for (QuicPacketNumber i = 21; i <= 40; i++) {
+  for (int i = 21; i <= 40; i++) {
     last_bandwidth = AckPacket(i);
     EXPECT_EQ(expected_bandwidth, last_bandwidth);
     clock_.AdvanceTime(time_between_packets);
@@ -152,14 +153,14 @@
       QuicBandwidth::FromKBytesPerSecond(kRegularPacketSize) * 0.5;
 
   // Send 20 packets, each 1 ms apart.
-  for (QuicPacketNumber i = 1; i <= 20; i++) {
+  for (int i = 1; i <= 20; i++) {
     SendPacket(i);
     clock_.AdvanceTime(time_between_packets);
   }
 
   // Ack packets 1 to 20, losing every even-numbered packet, while sending new
   // packets at the same rate as before.
-  for (QuicPacketNumber i = 1; i <= 20; i++) {
+  for (int i = 1; i <= 20; i++) {
     if (i % 2 == 0) {
       AckPacket(i);
     } else {
@@ -171,7 +172,7 @@
 
   // Ack the packets 21 to 40 with the same loss pattern.
   QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
-  for (QuicPacketNumber i = 21; i <= 40; i++) {
+  for (int i = 21; i <= 40; i++) {
     if (i % 2 == 0) {
       last_bandwidth = AckPacket(i);
       EXPECT_EQ(expected_bandwidth, last_bandwidth);
@@ -196,7 +197,7 @@
 
   // Send 20 packets, each 1 ms apart. Every even packet is not congestion
   // controlled.
-  for (QuicPacketNumber i = 1; i <= 20; i++) {
+  for (int i = 1; i <= 20; i++) {
     SendPacketInner(
         i, kRegularPacketSize,
         i % 2 == 0 ? HAS_RETRANSMITTABLE_DATA : NO_RETRANSMITTABLE_DATA);
@@ -208,7 +209,7 @@
 
   // Ack packets 2 to 21, ignoring every even-numbered packet, while sending new
   // packets at the same rate as before.
-  for (QuicPacketNumber i = 1; i <= 20; i++) {
+  for (int i = 1; i <= 20; i++) {
     if (i % 2 == 0) {
       AckPacket(i);
     }
@@ -220,7 +221,7 @@
 
   // Ack the packets 22 to 41 with the same congestion controlled pattern.
   QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
-  for (QuicPacketNumber i = 21; i <= 40; i++) {
+  for (int i = 21; i <= 40; i++) {
     if (i % 2 == 0) {
       last_bandwidth = AckPacket(i);
       EXPECT_EQ(expected_bandwidth, last_bandwidth);
@@ -251,7 +252,7 @@
   QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
   QuicTime::Delta ridiculously_small_time_delta =
       QuicTime::Delta::FromMicroseconds(20);
-  for (QuicPacketNumber i = 21; i <= 40; i++) {
+  for (int i = 21; i <= 40; i++) {
     last_bandwidth = AckPacket(i);
     clock_.AdvanceTime(ridiculously_small_time_delta);
   }
@@ -272,7 +273,7 @@
   // Ack the packets 21 to 40 in the reverse order, while sending packets 41 to
   // 60.
   QuicBandwidth last_bandwidth = QuicBandwidth::Zero();
-  for (QuicPacketNumber i = 0; i < 20; i++) {
+  for (int i = 0; i < 20; i++) {
     last_bandwidth = AckPacket(40 - i);
     EXPECT_EQ(expected_bandwidth, last_bandwidth);
     SendPacket(41 + i);
@@ -280,7 +281,7 @@
   }
 
   // Ack the packets 41 to 60, now in the regular order.
-  for (QuicPacketNumber i = 41; i <= 60; i++) {
+  for (int i = 41; i <= 60; i++) {
     last_bandwidth = AckPacket(i);
     EXPECT_EQ(expected_bandwidth, last_bandwidth);
     clock_.AdvanceTime(time_between_packets);
@@ -301,7 +302,7 @@
   // We are now app-limited. Ack 21 to 40 as usual, but do not send anything for
   // now.
   sampler_.OnAppLimited();
-  for (QuicPacketNumber i = 21; i <= 40; i++) {
+  for (int i = 21; i <= 40; i++) {
     QuicBandwidth current_sample = AckPacket(i);
     EXPECT_EQ(expected_bandwidth, current_sample);
     clock_.AdvanceTime(time_between_packets);
@@ -311,14 +312,14 @@
   clock_.AdvanceTime(QuicTime::Delta::FromSeconds(1));
 
   // Send packets 41 to 60, all of which would be marked as app-limited.
-  for (QuicPacketNumber i = 41; i <= 60; i++) {
+  for (int i = 41; i <= 60; i++) {
     SendPacket(i);
     clock_.AdvanceTime(time_between_packets);
   }
 
   // Ack packets 41 to 60, while sending packets 61 to 80.  41 to 60 should be
   // app-limited and underestimate the bandwidth due to that.
-  for (QuicPacketNumber i = 41; i <= 60; i++) {
+  for (int i = 41; i <= 60; i++) {
     BandwidthSample sample = AckPacketInner(i);
     EXPECT_TRUE(sample.is_app_limited);
     EXPECT_LT(sample.bandwidth, 0.7f * expected_bandwidth);
@@ -329,7 +330,7 @@
 
   // Run out of packets, and then ack packet 61 to 80, all of which should have
   // correct non-app-limited samples.
-  for (QuicPacketNumber i = 61; i <= 80; i++) {
+  for (int i = 61; i <= 80; i++) {
     QuicBandwidth last_bandwidth = AckPacket(i);
     EXPECT_EQ(expected_bandwidth, last_bandwidth);
     clock_.AdvanceTime(time_between_packets);
@@ -349,7 +350,7 @@
   const QuicBandwidth real_bandwidth =
       QuicBandwidth::FromBytesAndTimeDelta(num_bytes, rtt);
 
-  for (QuicPacketNumber i = 1; i <= 10; i++) {
+  for (int i = 1; i <= 10; i++) {
     SendPacket(i);
     clock_.AdvanceTime(time_between_packets);
   }
@@ -357,7 +358,7 @@
   clock_.AdvanceTime(rtt - num_packets * time_between_packets);
 
   QuicBandwidth last_sample = QuicBandwidth::Zero();
-  for (QuicPacketNumber i = 1; i <= 10; i++) {
+  for (int i = 1; i <= 10; i++) {
     QuicBandwidth sample = AckPacket(i);
     EXPECT_GT(sample, last_sample);
     last_sample = sample;
@@ -385,9 +386,9 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
 
   EXPECT_EQ(5u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  sampler_.RemoveObsoletePackets(4);
+  sampler_.RemoveObsoletePackets(QuicPacketNumber(4));
   EXPECT_EQ(2u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
-  sampler_.OnPacketLost(4);
+  sampler_.OnPacketLost(QuicPacketNumber(4));
   EXPECT_EQ(1u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
   AckPacket(5);
   EXPECT_EQ(0u, BandwidthSamplerPeer::GetNumberOfTrackedPackets(sampler_));
diff --git a/net/third_party/quic/core/congestion_control/bbr_sender.cc b/net/third_party/quic/core/congestion_control/bbr_sender.cc
index cb736e2..1d00ce68 100644
--- a/net/third_party/quic/core/congestion_control/bbr_sender.cc
+++ b/net/third_party/quic/core/congestion_control/bbr_sender.cc
@@ -87,8 +87,6 @@
       random_(random),
       mode_(STARTUP),
       round_trip_count_(0),
-      last_sent_packet_(0),
-      current_round_trip_end_(0),
       max_bandwidth_(kBandwidthWindowSize, QuicBandwidth::Zero(), 0),
       max_ack_height_(kBandwidthWindowSize, 0, 0),
       aggregation_epoch_start_time_(QuicTime::Zero()),
@@ -122,7 +120,6 @@
       has_non_app_limited_sample_(false),
       flexible_app_limited_(false),
       recovery_state_(NOT_IN_RECOVERY),
-      end_recovery_at_(0),
       recovery_window_(max_congestion_window_),
       is_app_limited_recovery_(false),
       slower_startup_(false),
@@ -460,7 +457,8 @@
 }
 
 bool BbrSender::UpdateRoundTripCounter(QuicPacketNumber last_acked_packet) {
-  if (last_acked_packet > current_round_trip_end_) {
+  if (!current_round_trip_end_.IsInitialized() ||
+      last_acked_packet > current_round_trip_end_) {
     round_trip_count_++;
     current_round_trip_end_ = last_sent_packet_;
     return true;
@@ -748,7 +746,7 @@
     return;
   }
   // Slow the pacing rate in STARTUP once loss has ever been detected.
-  const bool has_ever_detected_loss = end_recovery_at_ > 0;
+  const bool has_ever_detected_loss = end_recovery_at_.IsInitialized();
   if (slower_startup_ && has_ever_detected_loss &&
       has_non_app_limited_sample_) {
     pacing_rate_ = kStartupAfterLossGain * BandwidthEstimate();
diff --git a/net/third_party/quic/core/congestion_control/bbr_sender_test.cc b/net/third_party/quic/core/congestion_control/bbr_sender_test.cc
index 85c1c01..313725d 100644
--- a/net/third_party/quic/core/congestion_control/bbr_sender_test.cc
+++ b/net/third_party/quic/core/congestion_control/bbr_sender_test.cc
@@ -1094,7 +1094,7 @@
   QuicBandwidth pacing_rate = original_pacing_rate;
   const QuicByteCount original_cwnd = sender_->GetCongestionWindow();
   LostPacketVector lost_packets;
-  lost_packets.push_back(LostPacket(0, kMaxPacketSize));
+  lost_packets.push_back(LostPacket(QuicPacketNumber(), kMaxPacketSize));
   QuicPacketNumber largest_sent =
       bbr_sender_.connection()->sent_packet_manager().GetLargestSentPacket();
   for (QuicPacketNumber packet_number =
@@ -1144,7 +1144,7 @@
   QuicBandwidth pacing_rate = original_pacing_rate;
   const QuicByteCount original_cwnd = sender_->GetCongestionWindow();
   LostPacketVector lost_packets;
-  lost_packets.push_back(LostPacket(0, kMaxPacketSize));
+  lost_packets.push_back(LostPacket(QuicPacketNumber(), kMaxPacketSize));
   QuicPacketNumber largest_sent =
       bbr_sender_.connection()->sent_packet_manager().GetLargestSentPacket();
   for (QuicPacketNumber packet_number =
diff --git a/net/third_party/quic/core/congestion_control/general_loss_algorithm.cc b/net/third_party/quic/core/congestion_control/general_loss_algorithm.cc
index 8420f3d9..9af4179 100644
--- a/net/third_party/quic/core/congestion_control/general_loss_algorithm.cc
+++ b/net/third_party/quic/core/congestion_control/general_loss_algorithm.cc
@@ -31,7 +31,6 @@
 
 GeneralLossAlgorithm::GeneralLossAlgorithm(LossDetectionType loss_type)
     : loss_detection_timeout_(QuicTime::Zero()),
-      largest_lost_(0),
       least_in_flight_(1),
       faster_detect_loss_(GetQuicReloadableFlag(quic_faster_detect_loss)) {
   SetLossDetectionType(loss_type);
@@ -39,7 +38,7 @@
 
 void GeneralLossAlgorithm::SetLossDetectionType(LossDetectionType loss_type) {
   loss_detection_timeout_ = QuicTime::Zero();
-  largest_sent_on_spurious_retransmit_ = kInvalidPacketNumber;
+  largest_sent_on_spurious_retransmit_.Clear();
   loss_type_ = loss_type;
   reordering_shift_ = loss_type == kAdaptiveTime
                           ? kDefaultAdaptiveLossDelayShift
@@ -49,7 +48,7 @@
     QUIC_RELOADABLE_FLAG_COUNT(quic_eighth_rtt_loss_detection);
     reordering_shift_ = 3;
   }
-  largest_previously_acked_ = kInvalidPacketNumber;
+  largest_previously_acked_.Clear();
 }
 
 LossDetectionType GeneralLossAlgorithm::GetLossDetectionType() const {
@@ -91,7 +90,7 @@
   QuicPacketNumber packet_number = unacked_packets.GetLeastUnacked();
   auto it = unacked_packets.begin();
   if (faster_detect_loss_) {
-    if (least_in_flight_ >= packet_number) {
+    if (least_in_flight_.IsInitialized() && least_in_flight_ >= packet_number) {
       if (least_in_flight_ > unacked_packets.largest_sent_packet() + 1) {
         QUIC_BUG << "least_in_flight: " << least_in_flight_
                  << " is greater than largest_sent_packet + 1: "
@@ -103,9 +102,9 @@
       }
     }
     // Clear least_in_flight_.
-    least_in_flight_ = kInvalidPacketNumber;
+    least_in_flight_.Clear();
   } else {
-    if (largest_lost_ >= packet_number) {
+    if (largest_lost_.IsInitialized() && largest_lost_ >= packet_number) {
       if (largest_lost_ > unacked_packets.largest_sent_packet()) {
         QUIC_BUG << "largest_lost: " << largest_lost_
                  << " is greater than largest_sent_packet: "
@@ -132,7 +131,8 @@
     } else if (loss_type_ == kLazyFack) {
       // Require two in order acks to invoke FACK, which avoids spuriously
       // retransmitting packets when one packet is reordered by a large amount.
-      if (largest_newly_acked > largest_previously_acked_ &&
+      if (largest_previously_acked_.IsInitialized() &&
+          largest_newly_acked > largest_previously_acked_ &&
           largest_previously_acked_ > packet_number &&
           largest_previously_acked_ - packet_number >=
               (kNumberOfNacksBeforeRetransmission - 1)) {
@@ -150,7 +150,7 @@
       QuicTime when_lost = it->sent_time + loss_delay;
       if (time < when_lost) {
         loss_detection_timeout_ = when_lost;
-        if (least_in_flight_ == kInvalidPacketNumber) {
+        if (!least_in_flight_.IsInitialized()) {
           // At this point, packet_number is in flight and not detected as lost.
           least_in_flight_ = packet_number;
         }
@@ -166,18 +166,19 @@
       packets_lost->push_back(LostPacket(packet_number, it->bytes_sent));
       continue;
     }
-    if (least_in_flight_ == kInvalidPacketNumber) {
+    if (!least_in_flight_.IsInitialized()) {
       // At this point, packet_number is in flight and not detected as lost.
       least_in_flight_ = packet_number;
     }
   }
-  if (least_in_flight_ == kInvalidPacketNumber) {
+  if (!least_in_flight_.IsInitialized()) {
     // There is no in flight packet.
     least_in_flight_ = largest_newly_acked + 1;
   }
   largest_previously_acked_ = largest_newly_acked;
   if (!packets_lost->empty()) {
-    DCHECK_LT(largest_lost_, packets_lost->back().packet_number);
+    DCHECK(!largest_lost_.IsInitialized() ||
+           largest_lost_ < packets_lost->back().packet_number);
     largest_lost_ = packets_lost->back().packet_number;
   }
 }
@@ -212,7 +213,8 @@
     return;
   }
 
-  if (spurious_retransmission <= largest_sent_on_spurious_retransmit_) {
+  if (largest_sent_on_spurious_retransmit_.IsInitialized() &&
+      spurious_retransmission <= largest_sent_on_spurious_retransmit_) {
     return;
   }
   largest_sent_on_spurious_retransmit_ = unacked_packets.largest_sent_packet();
diff --git a/net/third_party/quic/core/congestion_control/general_loss_algorithm_test.cc b/net/third_party/quic/core/congestion_control/general_loss_algorithm_test.cc
index daaba8d..1e3b99bc 100644
--- a/net/third_party/quic/core/congestion_control/general_loss_algorithm_test.cc
+++ b/net/third_party/quic/core/congestion_control/general_loss_algorithm_test.cc
@@ -35,33 +35,39 @@
     QuicStreamFrame frame;
     frame.stream_id = QuicUtils::GetHeadersStreamId(
         CurrentSupportedVersions()[0].transport_version);
-    SerializedPacket packet(packet_number, PACKET_1BYTE_PACKET_NUMBER, nullptr,
-                            kDefaultLength, false, false);
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
     packet.retransmittable_frames.push_back(QuicFrame(frame));
-    unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, clock_.Now(),
-                                   true);
+    unacked_packets_.AddSentPacket(&packet, QuicPacketNumber(),
+                                   NOT_RETRANSMISSION, clock_.Now(), true);
   }
 
-  void SendAckPacket(QuicPacketNumber packet_number) {
-    SerializedPacket packet(packet_number, PACKET_1BYTE_PACKET_NUMBER, nullptr,
-                            kDefaultLength, true, false);
-    unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, clock_.Now(),
-                                   false);
+  void SendAckPacket(uint64_t packet_number) {
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            true, false);
+    unacked_packets_.AddSentPacket(&packet, QuicPacketNumber(),
+                                   NOT_RETRANSMISSION, clock_.Now(), false);
   }
 
   void VerifyLosses(uint64_t largest_newly_acked,
                     const AckedPacketVector& packets_acked,
                     const std::vector<uint64_t>& losses_expected) {
-    if (largest_newly_acked > unacked_packets_.largest_acked()) {
-      unacked_packets_.IncreaseLargestAcked(largest_newly_acked);
+    if (!unacked_packets_.largest_acked().IsInitialized() ||
+        QuicPacketNumber(largest_newly_acked) >
+            unacked_packets_.largest_acked()) {
+      unacked_packets_.IncreaseLargestAcked(
+          QuicPacketNumber(largest_newly_acked));
     }
     LostPacketVector lost_packets;
     loss_algorithm_.DetectLosses(unacked_packets_, clock_.Now(), rtt_stats_,
-                                 largest_newly_acked, packets_acked,
-                                 &lost_packets);
+                                 QuicPacketNumber(largest_newly_acked),
+                                 packets_acked, &lost_packets);
     ASSERT_EQ(losses_expected.size(), lost_packets.size());
     for (size_t i = 0; i < losses_expected.size(); ++i) {
-      EXPECT_EQ(lost_packets[i].packet_number, losses_expected[i]);
+      EXPECT_EQ(lost_packets[i].packet_number,
+                QuicPacketNumber(losses_expected[i]));
     }
   }
 
@@ -79,18 +85,21 @@
   }
   AckedPacketVector packets_acked;
   // No loss on one ack.
-  unacked_packets_.RemoveFromInFlight(2);
-  packets_acked.push_back(AckedPacket(2, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(2), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   // No loss on two acks.
-  unacked_packets_.RemoveFromInFlight(3);
-  packets_acked.push_back(AckedPacket(3, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(3, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(3), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(3, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   // Loss on three acks.
-  unacked_packets_.RemoveFromInFlight(4);
-  packets_acked.push_back(AckedPacket(4, kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(4), kMaxPacketSize, QuicTime::Zero()));
   VerifyLosses(4, packets_acked, {1});
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
 }
@@ -105,12 +114,15 @@
   }
   AckedPacketVector packets_acked;
   // Nack the first packet 3 times in a single StretchAck.
-  unacked_packets_.RemoveFromInFlight(2);
-  packets_acked.push_back(AckedPacket(2, kMaxPacketSize, QuicTime::Zero()));
-  unacked_packets_.RemoveFromInFlight(3);
-  packets_acked.push_back(AckedPacket(3, kMaxPacketSize, QuicTime::Zero()));
-  unacked_packets_.RemoveFromInFlight(4);
-  packets_acked.push_back(AckedPacket(4, kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(2), kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(3), kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(4), kMaxPacketSize, QuicTime::Zero()));
   VerifyLosses(4, packets_acked, {1});
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
 }
@@ -124,8 +136,9 @@
   }
   AckedPacketVector packets_acked;
   // Nack the first packet 3 times in an AckFrame with three missing packets.
-  unacked_packets_.RemoveFromInFlight(4);
-  packets_acked.push_back(AckedPacket(4, kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(4), kMaxPacketSize, QuicTime::Zero()));
   VerifyLosses(4, packets_acked, {1});
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
 }
@@ -138,9 +151,10 @@
   }
   AckedPacketVector packets_acked;
   // Early retransmit when the final packet gets acked and the first is nacked.
-  unacked_packets_.RemoveFromInFlight(2);
-  packets_acked.push_back(AckedPacket(2, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(2), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   EXPECT_EQ(clock_.Now() + 1.25 * rtt_stats_.smoothed_rtt(),
             loss_algorithm_.GetLossTimeout());
@@ -162,9 +176,9 @@
   AckedPacketVector packets_acked;
   // Early retransmit when the final packet gets acked and 1.25 RTTs have
   // elapsed since the packets were sent.
-  unacked_packets_.RemoveFromInFlight(kNumSentPackets);
-  packets_acked.push_back(
-      AckedPacket(kNumSentPackets, kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(kNumSentPackets));
+  packets_acked.push_back(AckedPacket(QuicPacketNumber(kNumSentPackets),
+                                      kMaxPacketSize, QuicTime::Zero()));
   // This simulates a single ack following multiple missing packets with FACK.
   VerifyLosses(kNumSentPackets, packets_acked, {1, 2});
   packets_acked.clear();
@@ -190,14 +204,15 @@
   }
   AckedPacketVector packets_acked;
   // Neuter packet 1.
-  unacked_packets_.RemoveRetransmittability(1);
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
   clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
 
   // Early retransmit when the final packet gets acked and the first is nacked.
-  unacked_packets_.IncreaseLargestAcked(2);
-  unacked_packets_.RemoveFromInFlight(2);
-  packets_acked.push_back(AckedPacket(2, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(2), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
   EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
             loss_algorithm_.GetLossTimeout());
 }
@@ -211,10 +226,11 @@
   clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
 
   // Early retransmit when the final packet gets acked and the first is nacked.
-  unacked_packets_.IncreaseLargestAcked(2);
-  unacked_packets_.RemoveFromInFlight(2);
-  packets_acked.push_back(AckedPacket(2, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(2), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   EXPECT_EQ(clock_.Now() + 0.25 * rtt_stats_.smoothed_rtt(),
             loss_algorithm_.GetLossTimeout());
@@ -237,9 +253,10 @@
   AckedPacketVector packets_acked;
   // Wait another RTT and ack 2.
   clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
-  unacked_packets_.IncreaseLargestAcked(2);
-  unacked_packets_.RemoveFromInFlight(2);
-  packets_acked.push_back(AckedPacket(2, kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(2), kMaxPacketSize, QuicTime::Zero()));
   VerifyLosses(2, packets_acked, {1});
 }
 
@@ -253,18 +270,21 @@
   }
   AckedPacketVector packets_acked;
   // No loss on one ack.
-  unacked_packets_.RemoveFromInFlight(2);
-  packets_acked.push_back(AckedPacket(2, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(2), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   // No loss on two acks.
-  unacked_packets_.RemoveFromInFlight(3);
-  packets_acked.push_back(AckedPacket(3, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(3, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(3), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(3, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   // Loss on three acks.
-  unacked_packets_.RemoveFromInFlight(4);
-  packets_acked.push_back(AckedPacket(4, kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(4), kMaxPacketSize, QuicTime::Zero()));
   VerifyLosses(4, packets_acked, {1});
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
 }
@@ -281,19 +301,23 @@
   }
   AckedPacketVector packets_acked;
   // Nack the first packet 3 times in a single StretchAck.
-  unacked_packets_.RemoveFromInFlight(2);
-  packets_acked.push_back(AckedPacket(2, kMaxPacketSize, QuicTime::Zero()));
-  unacked_packets_.RemoveFromInFlight(3);
-  packets_acked.push_back(AckedPacket(3, kMaxPacketSize, QuicTime::Zero()));
-  unacked_packets_.RemoveFromInFlight(4);
-  packets_acked.push_back(AckedPacket(4, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(4, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(2), kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(3), kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(4), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   // The timer isn't set because we expect more acks.
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
   // Process another ack and then packet 1 will be lost.
-  unacked_packets_.RemoveFromInFlight(5);
-  packets_acked.push_back(AckedPacket(5, kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(5), kMaxPacketSize, QuicTime::Zero()));
   VerifyLosses(5, packets_acked, {1});
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
 }
@@ -308,15 +332,17 @@
   }
   AckedPacketVector packets_acked;
   // Nack the first packet 3 times in an AckFrame with three missing packets.
-  unacked_packets_.RemoveFromInFlight(4);
-  packets_acked.push_back(AckedPacket(4, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(4, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(4), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(4, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   // The timer isn't set because we expect more acks.
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
   // Process another ack and then packet 1 and 2 will be lost.
-  unacked_packets_.RemoveFromInFlight(5);
-  packets_acked.push_back(AckedPacket(5, kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(5), kMaxPacketSize, QuicTime::Zero()));
   VerifyLosses(5, packets_acked, {1, 2});
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
 }
@@ -330,10 +356,11 @@
     SendDataPacket(i);
   }
   AckedPacketVector packets_acked;
-  unacked_packets_.RemoveFromInFlight(2);
-  packets_acked.push_back(AckedPacket(2, kMaxPacketSize, QuicTime::Zero()));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(2), kMaxPacketSize, QuicTime::Zero()));
   for (size_t i = 1; i < 500; ++i) {
-    VerifyLosses(2, packets_acked, std::vector<QuicPacketNumber>{});
+    VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
     packets_acked.clear();
   }
   if (GetQuicReloadableFlag(quic_eighth_rtt_loss_detection)) {
@@ -357,9 +384,10 @@
   // Expect the timer to not be set.
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
   // The packet should not be lost until 1.25 RTTs pass.
-  unacked_packets_.RemoveFromInFlight(2);
-  packets_acked.push_back(AckedPacket(2, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(2), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   if (GetQuicReloadableFlag(quic_eighth_rtt_loss_detection)) {
     // Expect the timer to be set to 0.25 RTT's in the future.
@@ -370,7 +398,7 @@
     EXPECT_EQ(0.25 * rtt_stats_.smoothed_rtt(),
               loss_algorithm_.GetLossTimeout() - clock_.Now());
   }
-  VerifyLosses(2, packets_acked, std::vector<QuicPacketNumber>{});
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
   clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
   VerifyLosses(2, packets_acked, {1});
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
@@ -388,16 +416,17 @@
   // Expect the timer to not be set.
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
   // The packet should not be lost without a nack.
-  unacked_packets_.RemoveFromInFlight(1);
-  packets_acked.push_back(AckedPacket(1, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(1, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(1), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(1, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   // The timer should still not be set.
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
   clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
-  VerifyLosses(1, packets_acked, std::vector<QuicPacketNumber>{});
+  VerifyLosses(1, packets_acked, std::vector<uint64_t>{});
   clock_.AdvanceTime(rtt_stats_.smoothed_rtt());
-  VerifyLosses(1, packets_acked, std::vector<QuicPacketNumber>{});
+  VerifyLosses(1, packets_acked, std::vector<uint64_t>{});
 
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
 }
@@ -414,9 +443,10 @@
   // Expect the timer to not be set.
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
   // The packet should not be lost until 1.25 RTTs pass.
-  unacked_packets_.RemoveFromInFlight(10);
-  packets_acked.push_back(AckedPacket(10, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(10, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(10));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(10), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(10, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   if (GetQuicReloadableFlag(quic_eighth_rtt_loss_detection)) {
     // Expect the timer to be set to 0.25 RTT's in the future.
@@ -445,9 +475,10 @@
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
   // The packet should not be lost until 1.25 RTTs pass.
 
-  unacked_packets_.RemoveFromInFlight(10);
-  packets_acked.push_back(AckedPacket(10, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(10, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(10));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(10), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(10, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   if (GetQuicReloadableFlag(quic_eighth_rtt_loss_detection)) {
     // Expect the timer to be set to 0.25 RTT's in the future.
@@ -461,10 +492,11 @@
   clock_.AdvanceTime(0.25 * rtt_stats_.smoothed_rtt());
   // Now ack packets 1 to 9 and ensure the timer is no longer set and no packets
   // are lost.
-  for (QuicPacketNumber i = 1; i <= 9; ++i) {
-    unacked_packets_.RemoveFromInFlight(i);
-    packets_acked.push_back(AckedPacket(i, kMaxPacketSize, QuicTime::Zero()));
-    VerifyLosses(i, packets_acked, std::vector<QuicPacketNumber>{});
+  for (uint64_t i = 1; i <= 9; ++i) {
+    unacked_packets_.RemoveFromInFlight(QuicPacketNumber(i));
+    packets_acked.push_back(
+        AckedPacket(QuicPacketNumber(i), kMaxPacketSize, QuicTime::Zero()));
+    VerifyLosses(i, packets_acked, std::vector<uint64_t>{});
     packets_acked.clear();
     EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
   }
@@ -484,14 +516,15 @@
   // Expect the timer to not be set.
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
   // Packet 1 should not be lost until 1/16 RTTs pass.
-  unacked_packets_.RemoveFromInFlight(2);
-  packets_acked.push_back(AckedPacket(2, kMaxPacketSize, QuicTime::Zero()));
-  VerifyLosses(2, packets_acked, std::vector<QuicPacketNumber>{});
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  packets_acked.push_back(
+      AckedPacket(QuicPacketNumber(2), kMaxPacketSize, QuicTime::Zero()));
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
   packets_acked.clear();
   // Expect the timer to be set to 1/16 RTT's in the future.
   EXPECT_EQ(rtt_stats_.smoothed_rtt() * (1.0f / 16),
             loss_algorithm_.GetLossTimeout() - clock_.Now());
-  VerifyLosses(2, packets_acked, std::vector<QuicPacketNumber>{});
+  VerifyLosses(2, packets_acked, std::vector<uint64_t>{});
   clock_.AdvanceTime(rtt_stats_.smoothed_rtt() * (1.0f / 16));
   VerifyLosses(2, packets_acked, {1});
   EXPECT_EQ(QuicTime::Zero(), loss_algorithm_.GetLossTimeout());
@@ -508,13 +541,13 @@
     clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(1));
   }
   loss_algorithm_.SpuriousRetransmitDetected(unacked_packets_, clock_.Now(),
-                                             rtt_stats_, 11);
+                                             rtt_stats_, QuicPacketNumber(11));
   EXPECT_EQ(1, loss_algorithm_.reordering_shift());
 
   // Detect another spurious retransmit and ensure the threshold doesn't
   // increase again.
   loss_algorithm_.SpuriousRetransmitDetected(unacked_packets_, clock_.Now(),
-                                             rtt_stats_, 12);
+                                             rtt_stats_, QuicPacketNumber(12));
   EXPECT_EQ(1, loss_algorithm_.reordering_shift());
 }
 
diff --git a/net/third_party/quic/core/congestion_control/hybrid_slow_start.cc b/net/third_party/quic/core/congestion_control/hybrid_slow_start.cc
index 29d07a1..16a5f4b 100644
--- a/net/third_party/quic/core/congestion_control/hybrid_slow_start.cc
+++ b/net/third_party/quic/core/congestion_control/hybrid_slow_start.cc
@@ -24,8 +24,6 @@
 HybridSlowStart::HybridSlowStart()
     : started_(false),
       hystart_found_(NOT_FOUND),
-      last_sent_packet_number_(0),
-      end_packet_number_(0),
       rtt_sample_count_(0),
       current_min_rtt_(QuicTime::Delta::Zero()) {}
 
@@ -56,7 +54,7 @@
 }
 
 bool HybridSlowStart::IsEndOfRound(QuicPacketNumber ack) const {
-  return end_packet_number_ <= ack;
+  return !end_packet_number_.IsInitialized() || end_packet_number_ <= ack;
 }
 
 bool HybridSlowStart::ShouldExitSlowStart(QuicTime::Delta latest_rtt,
diff --git a/net/third_party/quic/core/congestion_control/hybrid_slow_start_test.cc b/net/third_party/quic/core/congestion_control/hybrid_slow_start_test.cc
index 2ff614d5..5118e87 100644
--- a/net/third_party/quic/core/congestion_control/hybrid_slow_start_test.cc
+++ b/net/third_party/quic/core/congestion_control/hybrid_slow_start_test.cc
@@ -24,8 +24,8 @@
 };
 
 TEST_F(HybridSlowStartTest, Simple) {
-  QuicPacketNumber packet_number = 1;
-  QuicPacketNumber end_packet_number = 3;
+  QuicPacketNumber packet_number(1);
+  QuicPacketNumber end_packet_number(3);
   slow_start_->StartReceiveRound(end_packet_number);
 
   EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
@@ -39,7 +39,7 @@
   // Test without a new registered end_packet_number;
   EXPECT_TRUE(slow_start_->IsEndOfRound(packet_number++));
 
-  end_packet_number = 20;
+  end_packet_number = QuicPacketNumber(20);
   slow_start_->StartReceiveRound(end_packet_number);
   while (packet_number < end_packet_number) {
     EXPECT_FALSE(slow_start_->IsEndOfRound(packet_number++));
@@ -52,7 +52,7 @@
   // RTT of 60ms the detection will happen at 67.5 ms.
   const int kHybridStartMinSamples = 8;  // Number of acks required to trigger.
 
-  QuicPacketNumber end_packet_number = 1;
+  QuicPacketNumber end_packet_number(1);
   slow_start_->StartReceiveRound(end_packet_number++);
 
   // Will not trigger since our lowest RTT in our burst is the same as the long
diff --git a/net/third_party/quic/core/congestion_control/pacing_sender_test.cc b/net/third_party/quic/core/congestion_control/pacing_sender_test.cc
index 5648b14..1aeeabe 100644
--- a/net/third_party/quic/core/congestion_control/pacing_sender_test.cc
+++ b/net/third_party/quic/core/congestion_control/pacing_sender_test.cc
@@ -50,7 +50,7 @@
     if (burst_size == 0) {
       EXPECT_CALL(*mock_sender_, OnCongestionEvent(_, _, _, _, _));
       LostPacketVector lost_packets;
-      lost_packets.push_back(LostPacket(1, kMaxPacketSize));
+      lost_packets.push_back(LostPacket(QuicPacketNumber(1), kMaxPacketSize));
       AckedPacketVector empty;
       pacing_sender_->OnCongestionEvent(true, 1234, clock_.Now(), empty,
                                         lost_packets);
@@ -320,7 +320,7 @@
 
   // Losing a packet will set clear burst tokens.
   LostPacketVector lost_packets;
-  lost_packets.push_back(LostPacket(1, kMaxPacketSize));
+  lost_packets.push_back(LostPacket(QuicPacketNumber(1), kMaxPacketSize));
   AckedPacketVector empty_acked;
   EXPECT_CALL(*mock_sender_,
               OnCongestionEvent(true, kMaxPacketSize, _, IsEmpty(), _));
diff --git a/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes.cc b/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
index d5279ba..02f4bf4 100644
--- a/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
+++ b/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes.cc
@@ -38,9 +38,6 @@
       stats_(stats),
       reno_(reno),
       num_connections_(kDefaultNumConnections),
-      largest_sent_packet_number_(kInvalidPacketNumber),
-      largest_acked_packet_number_(kInvalidPacketNumber),
-      largest_sent_at_last_cutback_(kInvalidPacketNumber),
       min4_mode_(false),
       last_cutback_exited_slowstart_(false),
       slow_start_large_reduction_(false),
@@ -151,8 +148,12 @@
                                         QuicByteCount acked_bytes,
                                         QuicByteCount prior_in_flight,
                                         QuicTime event_time) {
-  largest_acked_packet_number_ =
-      std::max(acked_packet_number, largest_acked_packet_number_);
+  if (largest_acked_packet_number_.IsInitialized()) {
+    largest_acked_packet_number_ =
+        std::max(acked_packet_number, largest_acked_packet_number_);
+  } else {
+    largest_acked_packet_number_ = acked_packet_number;
+  }
   if (InRecovery()) {
     if (!no_prr_) {
       // PRR is used when in recovery.
@@ -184,7 +185,8 @@
     // PRR is used when in recovery.
     prr_.OnPacketSent(bytes);
   }
-  DCHECK_LT(largest_sent_packet_number_, packet_number);
+  DCHECK(!largest_sent_packet_number_.IsInitialized() ||
+         largest_sent_packet_number_ < packet_number);
   largest_sent_packet_number_ = packet_number;
   hybrid_slow_start_.OnPacketSent(packet_number);
 }
@@ -240,8 +242,9 @@
 }
 
 bool TcpCubicSenderBytes::InRecovery() const {
-  return largest_acked_packet_number_ <= largest_sent_at_last_cutback_ &&
-         largest_acked_packet_number_ != kInvalidPacketNumber;
+  return largest_acked_packet_number_.IsInitialized() &&
+         largest_sent_at_last_cutback_.IsInitialized() &&
+         largest_acked_packet_number_ <= largest_sent_at_last_cutback_;
 }
 
 bool TcpCubicSenderBytes::ShouldSendProbingPacket() const {
@@ -249,7 +252,7 @@
 }
 
 void TcpCubicSenderBytes::OnRetransmissionTimeout(bool packets_retransmitted) {
-  largest_sent_at_last_cutback_ = kInvalidPacketNumber;
+  largest_sent_at_last_cutback_.Clear();
   if (!packets_retransmitted) {
     return;
   }
@@ -298,7 +301,8 @@
                                        QuicByteCount prior_in_flight) {
   // TCP NewReno (RFC6582) says that once a loss occurs, any losses in packets
   // already sent should be treated as a single loss event, since it's expected.
-  if (packet_number <= largest_sent_at_last_cutback_) {
+  if (largest_sent_at_last_cutback_.IsInitialized() &&
+      packet_number <= largest_sent_at_last_cutback_) {
     if (last_cutback_exited_slowstart_) {
       ++stats_->slowstart_packets_lost;
       stats_->slowstart_bytes_lost += lost_bytes;
@@ -414,9 +418,9 @@
 void TcpCubicSenderBytes::OnConnectionMigration() {
   hybrid_slow_start_.Restart();
   prr_ = PrrSender();
-  largest_sent_packet_number_ = kInvalidPacketNumber;
-  largest_acked_packet_number_ = kInvalidPacketNumber;
-  largest_sent_at_last_cutback_ = kInvalidPacketNumber;
+  largest_sent_packet_number_.Clear();
+  largest_acked_packet_number_.Clear();
+  largest_sent_at_last_cutback_.Clear();
   last_cutback_exited_slowstart_ = false;
   cubic_.ResetCubicState();
   num_acked_packets_ = 0;
diff --git a/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc b/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
index d35b6a9..2da2328 100644
--- a/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
+++ b/net/third_party/quic/core/congestion_control/tcp_cubic_sender_bytes_test.cc
@@ -69,8 +69,9 @@
     int packets_sent = 0;
     bool can_send = sender_->CanSend(bytes_in_flight_);
     while (can_send) {
-      sender_->OnPacketSent(clock_.Now(), bytes_in_flight_, packet_number_++,
-                            kDefaultTCPMSS, HAS_RETRANSMITTABLE_DATA);
+      sender_->OnPacketSent(clock_.Now(), bytes_in_flight_,
+                            QuicPacketNumber(packet_number_++), kDefaultTCPMSS,
+                            HAS_RETRANSMITTABLE_DATA);
       ++packets_sent;
       bytes_in_flight_ += kDefaultTCPMSS;
       can_send = sender_->CanSend(bytes_in_flight_);
@@ -87,7 +88,8 @@
     for (int i = 0; i < n; ++i) {
       ++acked_packet_number_;
       acked_packets.push_back(
-          AckedPacket(acked_packet_number_, kDefaultTCPMSS, QuicTime::Zero()));
+          AckedPacket(QuicPacketNumber(acked_packet_number_), kDefaultTCPMSS,
+                      QuicTime::Zero()));
     }
     sender_->OnCongestionEvent(true, bytes_in_flight_, clock_.Now(),
                                acked_packets, lost_packets);
@@ -102,7 +104,8 @@
     LostPacketVector lost_packets;
     for (int i = 0; i < n; ++i) {
       ++acked_packet_number_;
-      lost_packets.push_back(LostPacket(acked_packet_number_, packet_length));
+      lost_packets.push_back(
+          LostPacket(QuicPacketNumber(acked_packet_number_), packet_length));
     }
     sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
                                acked_packets, lost_packets);
@@ -113,7 +116,8 @@
   void LosePacket(uint64_t packet_number) {
     AckedPacketVector acked_packets;
     LostPacketVector lost_packets;
-    lost_packets.push_back(LostPacket(packet_number, kDefaultTCPMSS));
+    lost_packets.push_back(
+        LostPacket(QuicPacketNumber(packet_number), kDefaultTCPMSS));
     sender_->OnCongestionEvent(false, bytes_in_flight_, clock_.Now(),
                                acked_packets, lost_packets);
     bytes_in_flight_ -= kDefaultTCPMSS;
@@ -122,7 +126,7 @@
   const QuicTime::Delta one_ms_;
   MockClock clock_;
   std::unique_ptr<TcpCubicSenderBytesPeer> sender_;
-  QuicPacketNumber packet_number_;
+  uint64_t packet_number_;
   uint64_t acked_packet_number_;
   QuicByteCount bytes_in_flight_;
 };
@@ -779,7 +783,8 @@
   LostPacketVector missing_packets;
   for (uint64_t i = 1; i < kDefaultMaxCongestionWindowPackets; ++i) {
     acked_packets.clear();
-    acked_packets.push_back(AckedPacket(i, 1350, QuicTime::Zero()));
+    acked_packets.push_back(
+        AckedPacket(QuicPacketNumber(i), 1350, QuicTime::Zero()));
     sender->OnCongestionEvent(true, sender->GetCongestionWindow(), clock_.Now(),
                               acked_packets, missing_packets);
   }
diff --git a/net/third_party/quic/core/frames/quic_ack_frame.cc b/net/third_party/quic/core/frames/quic_ack_frame.cc
index 9cd370e..c240fe1 100644
--- a/net/third_party/quic/core/frames/quic_ack_frame.cc
+++ b/net/third_party/quic/core/frames/quic_ack_frame.cc
@@ -12,20 +12,29 @@
 namespace quic {
 
 namespace {
+
 const QuicPacketCount kMaxPrintRange = 128;
+
+uint64_t PacketNumberIntervalLength(
+    const QuicInterval<QuicPacketNumber>& interval) {
+  if (interval.Empty()) {
+    return 0u;
+  }
+  return interval.max() - interval.min();
+}
 }  // namespace
 
 bool IsAwaitingPacket(const QuicAckFrame& ack_frame,
                       QuicPacketNumber packet_number,
                       QuicPacketNumber peer_least_packet_awaiting_ack) {
-  DCHECK_NE(kInvalidPacketNumber, packet_number);
-  return packet_number >= peer_least_packet_awaiting_ack &&
+  DCHECK(packet_number.IsInitialized());
+  return (!peer_least_packet_awaiting_ack.IsInitialized() ||
+          packet_number >= peer_least_packet_awaiting_ack) &&
          !ack_frame.packets.Contains(packet_number);
 }
 
 QuicAckFrame::QuicAckFrame()
-    : largest_acked(kInvalidPacketNumber),
-      ack_delay_time(QuicTime::Delta::Infinite()),
+    : ack_delay_time(QuicTime::Delta::Infinite()),
       ecn_counters_populated(false),
       ect_0_count(0),
       ect_1_count(0),
@@ -57,7 +66,7 @@
 }
 
 void QuicAckFrame::Clear() {
-  largest_acked = kInvalidPacketNumber;
+  largest_acked.Clear();
   ack_delay_time = QuicTime::Delta::Infinite();
   received_packet_times.clear();
   packets.Clear();
@@ -74,7 +83,7 @@
     default;
 
 void PacketNumberQueue::Add(QuicPacketNumber packet_number) {
-  if (packet_number == kInvalidPacketNumber) {
+  if (!packet_number.IsInitialized()) {
     return;
   }
   // Check if the deque is empty
@@ -152,8 +161,7 @@
 
 void PacketNumberQueue::AddRange(QuicPacketNumber lower,
                                  QuicPacketNumber higher) {
-  if (lower == kInvalidPacketNumber || higher == kInvalidPacketNumber ||
-      lower >= higher) {
+  if (!lower.IsInitialized() || !higher.IsInitialized() || lower >= higher) {
     return;
   }
   if (packet_number_deque_.empty()) {
@@ -192,7 +200,7 @@
 }
 
 bool PacketNumberQueue::RemoveUpTo(QuicPacketNumber higher) {
-  if (higher == kInvalidPacketNumber || Empty()) {
+  if (!higher.IsInitialized() || Empty()) {
     return false;
   }
   const QuicPacketNumber old_min = Min();
@@ -226,7 +234,7 @@
 }
 
 bool PacketNumberQueue::Contains(QuicPacketNumber packet_number) const {
-  if (packet_number == kInvalidPacketNumber || packet_number_deque_.empty()) {
+  if (!packet_number.IsInitialized() || packet_number_deque_.empty()) {
     return false;
   }
   if (packet_number_deque_.front().min() > packet_number ||
@@ -258,7 +266,7 @@
 QuicPacketCount PacketNumberQueue::NumPacketsSlow() const {
   QuicPacketCount n_packets = 0;
   for (QuicInterval<QuicPacketNumber> interval : packet_number_deque_) {
-    n_packets += interval.Length();
+    n_packets += PacketNumberIntervalLength(interval);
   }
   return n_packets;
 }
@@ -285,7 +293,7 @@
 
 QuicPacketCount PacketNumberQueue::LastIntervalLength() const {
   DCHECK(!Empty());
-  return packet_number_deque_.back().Length();
+  return PacketNumberIntervalLength(packet_number_deque_.back());
 }
 
 // Largest min...max range for packet numbers where we print the numbers
diff --git a/net/third_party/quic/core/frames/quic_frames_test.cc b/net/third_party/quic/core/frames/quic_frames_test.cc
index fc67e10..fd4091b 100644
--- a/net/third_party/quic/core/frames/quic_frames_test.cc
+++ b/net/third_party/quic/core/frames/quic_frames_test.cc
@@ -27,12 +27,13 @@
 
 TEST_F(QuicFramesTest, AckFrameToString) {
   QuicAckFrame frame;
-  frame.largest_acked = 5;
+  frame.largest_acked = QuicPacketNumber(5);
   frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
-  frame.packets.Add(4);
-  frame.packets.Add(5);
+  frame.packets.Add(QuicPacketNumber(4));
+  frame.packets.Add(QuicPacketNumber(5));
   frame.received_packet_times = {
-      {6, QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
+      {QuicPacketNumber(6),
+       QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
   std::ostringstream stream;
   stream << frame;
   EXPECT_EQ(
@@ -45,11 +46,12 @@
 
 TEST_F(QuicFramesTest, BigAckFrameToString) {
   QuicAckFrame frame;
-  frame.largest_acked = 500;
+  frame.largest_acked = QuicPacketNumber(500);
   frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(3);
-  frame.packets.AddRange(4, 501);
+  frame.packets.AddRange(QuicPacketNumber(4), QuicPacketNumber(501));
   frame.received_packet_times = {
-      {500, QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
+      {QuicPacketNumber(500),
+       QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(7)}};
   std::ostringstream stream;
   stream << frame;
   EXPECT_EQ(
@@ -213,7 +215,7 @@
 
 TEST_F(QuicFramesTest, StopWaitingFrameToString) {
   QuicStopWaitingFrame frame;
-  frame.least_unacked = 2;
+  frame.least_unacked = QuicPacketNumber(2);
   std::ostringstream stream;
   stream << frame;
   EXPECT_EQ("{ least_unacked: 2 }\n", stream.str());
@@ -223,69 +225,84 @@
 
 TEST_F(QuicFramesTest, IsAwaitingPacket) {
   QuicAckFrame ack_frame1;
-  ack_frame1.largest_acked = 10u;
-  ack_frame1.packets.AddRange(1, 11);
-  EXPECT_TRUE(IsAwaitingPacket(ack_frame1, 11u, 0u));
-  EXPECT_FALSE(IsAwaitingPacket(ack_frame1, 1u, 0u));
+  ack_frame1.largest_acked = QuicPacketNumber(10u);
+  ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(11));
+  EXPECT_TRUE(
+      IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
+  EXPECT_FALSE(
+      IsAwaitingPacket(ack_frame1, QuicPacketNumber(1u), QuicPacketNumber()));
 
-  ack_frame1.packets.Add(12);
-  EXPECT_TRUE(IsAwaitingPacket(ack_frame1, 11u, 0u));
+  ack_frame1.packets.Add(QuicPacketNumber(12));
+  EXPECT_TRUE(
+      IsAwaitingPacket(ack_frame1, QuicPacketNumber(11u), QuicPacketNumber()));
 
   QuicAckFrame ack_frame2;
-  ack_frame2.largest_acked = 100u;
-  ack_frame2.packets.AddRange(21, 100);
-  EXPECT_FALSE(IsAwaitingPacket(ack_frame2, 11u, 20u));
-  EXPECT_FALSE(IsAwaitingPacket(ack_frame2, 80u, 20u));
-  EXPECT_TRUE(IsAwaitingPacket(ack_frame2, 101u, 20u));
+  ack_frame2.largest_acked = QuicPacketNumber(100u);
+  ack_frame2.packets.AddRange(QuicPacketNumber(21), QuicPacketNumber(100));
+  EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(11u),
+                                QuicPacketNumber(20u)));
+  EXPECT_FALSE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(80u),
+                                QuicPacketNumber(20u)));
+  EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
+                               QuicPacketNumber(20u)));
 
-  ack_frame2.packets.AddRange(102, 200);
-  EXPECT_TRUE(IsAwaitingPacket(ack_frame2, 101u, 20u));
+  ack_frame2.packets.AddRange(QuicPacketNumber(102), QuicPacketNumber(200));
+  EXPECT_TRUE(IsAwaitingPacket(ack_frame2, QuicPacketNumber(101u),
+                               QuicPacketNumber(20u)));
 }
 
 TEST_F(QuicFramesTest, AddPacket) {
   QuicAckFrame ack_frame1;
-  ack_frame1.packets.Add(1);
-  ack_frame1.packets.Add(99);
+  ack_frame1.packets.Add(QuicPacketNumber(1));
+  ack_frame1.packets.Add(QuicPacketNumber(99));
 
   EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
-  EXPECT_EQ(1u, ack_frame1.packets.Min());
-  EXPECT_EQ(99u, ack_frame1.packets.Max());
+  EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
 
   std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(1, 2));
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(99, 100));
+  expected_intervals.emplace_back(
+      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(99), QuicPacketNumber(100)));
 
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
       ack_frame1.packets.begin(), ack_frame1.packets.end());
 
   EXPECT_EQ(expected_intervals, actual_intervals);
 
-  ack_frame1.packets.Add(20);
+  ack_frame1.packets.Add(QuicPacketNumber(20));
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
       ack_frame1.packets.begin(), ack_frame1.packets.end());
 
   std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2;
-  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(1, 2));
-  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(20, 21));
-  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(99, 100));
+  expected_intervals2.emplace_back(
+      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
+  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(20), QuicPacketNumber(21)));
+  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(99), QuicPacketNumber(100)));
 
   EXPECT_EQ(3u, ack_frame1.packets.NumIntervals());
   EXPECT_EQ(expected_intervals2, actual_intervals2);
 
-  ack_frame1.packets.Add(19);
-  ack_frame1.packets.Add(21);
+  ack_frame1.packets.Add(QuicPacketNumber(19));
+  ack_frame1.packets.Add(QuicPacketNumber(21));
 
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals3(
       ack_frame1.packets.begin(), ack_frame1.packets.end());
 
   std::vector<QuicInterval<QuicPacketNumber>> expected_intervals3;
-  expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(1, 2));
-  expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(19, 22));
-  expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(99, 100));
+  expected_intervals3.emplace_back(
+      QuicInterval<QuicPacketNumber>(QuicPacketNumber(1), QuicPacketNumber(2)));
+  expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(19), QuicPacketNumber(22)));
+  expected_intervals3.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(99), QuicPacketNumber(100)));
 
   EXPECT_EQ(expected_intervals3, actual_intervals3);
 
-  ack_frame1.packets.Add(20);
+  ack_frame1.packets.Add(QuicPacketNumber(20));
 
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals4(
       ack_frame1.packets.begin(), ack_frame1.packets.end());
@@ -293,37 +310,44 @@
   EXPECT_EQ(expected_intervals3, actual_intervals4);
 
   QuicAckFrame ack_frame2;
-  ack_frame2.packets.Add(20);
-  ack_frame2.packets.Add(40);
-  ack_frame2.packets.Add(60);
-  ack_frame2.packets.Add(10);
-  ack_frame2.packets.Add(80);
+  ack_frame2.packets.Add(QuicPacketNumber(20));
+  ack_frame2.packets.Add(QuicPacketNumber(40));
+  ack_frame2.packets.Add(QuicPacketNumber(60));
+  ack_frame2.packets.Add(QuicPacketNumber(10));
+  ack_frame2.packets.Add(QuicPacketNumber(80));
 
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals5(
       ack_frame2.packets.begin(), ack_frame2.packets.end());
 
   std::vector<QuicInterval<QuicPacketNumber>> expected_intervals5;
-  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(10, 11));
-  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(20, 21));
-  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(40, 41));
-  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(60, 61));
-  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(80, 81));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(10), QuicPacketNumber(11)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(20), QuicPacketNumber(21)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(40), QuicPacketNumber(41)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(60), QuicPacketNumber(61)));
+  expected_intervals5.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(80), QuicPacketNumber(81)));
 
   EXPECT_EQ(expected_intervals5, actual_intervals5);
 }
 
 TEST_F(QuicFramesTest, AddInterval) {
   QuicAckFrame ack_frame1;
-  ack_frame1.packets.AddRange(1, 10);
-  ack_frame1.packets.AddRange(50, 100);
+  ack_frame1.packets.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
+  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
 
   EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
-  EXPECT_EQ(1u, ack_frame1.packets.Min());
-  EXPECT_EQ(99u, ack_frame1.packets.Max());
+  EXPECT_EQ(QuicPacketNumber(1u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
 
   std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(1, 10));
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(50, 100));
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(1), QuicPacketNumber(10)));
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(50), QuicPacketNumber(100)));
 
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
       ack_frame1.packets.begin(), ack_frame1.packets.end());
@@ -331,48 +355,58 @@
   EXPECT_EQ(expected_intervals, actual_intervals);
 
   // Ensure adding a range within the existing ranges fails.
-  EXPECT_QUIC_BUG(ack_frame1.packets.AddRange(20, 30), "");
+  EXPECT_QUIC_BUG(
+      ack_frame1.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(30)),
+      "");
 
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
       ack_frame1.packets.begin(), ack_frame1.packets.end());
 
   std::vector<QuicInterval<QuicPacketNumber>> expected_intervals2;
-  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(1, 10));
-  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(50, 100));
+  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(1), QuicPacketNumber(10)));
+  expected_intervals2.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(50), QuicPacketNumber(100)));
 
   EXPECT_EQ(expected_intervals2.size(), ack_frame1.packets.NumIntervals());
   EXPECT_EQ(expected_intervals2, actual_intervals2);
 
   // Add ranges at both ends.
   QuicAckFrame ack_frame2;
-  ack_frame2.packets.AddRange(20, 25);
-  ack_frame2.packets.AddRange(40, 45);
-  ack_frame2.packets.AddRange(60, 65);
-  ack_frame2.packets.AddRange(10, 15);
-  ack_frame2.packets.AddRange(80, 85);
+  ack_frame2.packets.AddRange(QuicPacketNumber(20), QuicPacketNumber(25));
+  ack_frame2.packets.AddRange(QuicPacketNumber(40), QuicPacketNumber(45));
+  ack_frame2.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(65));
+  ack_frame2.packets.AddRange(QuicPacketNumber(10), QuicPacketNumber(15));
+  ack_frame2.packets.AddRange(QuicPacketNumber(80), QuicPacketNumber(85));
 
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals8(
       ack_frame2.packets.begin(), ack_frame2.packets.end());
 
   std::vector<QuicInterval<QuicPacketNumber>> expected_intervals8;
-  expected_intervals8.emplace_back(QuicInterval<QuicPacketNumber>(10, 15));
-  expected_intervals8.emplace_back(QuicInterval<QuicPacketNumber>(20, 25));
-  expected_intervals8.emplace_back(QuicInterval<QuicPacketNumber>(40, 45));
-  expected_intervals8.emplace_back(QuicInterval<QuicPacketNumber>(60, 65));
-  expected_intervals8.emplace_back(QuicInterval<QuicPacketNumber>(80, 85));
+  expected_intervals8.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(10), QuicPacketNumber(15)));
+  expected_intervals8.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(20), QuicPacketNumber(25)));
+  expected_intervals8.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(40), QuicPacketNumber(45)));
+  expected_intervals8.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(60), QuicPacketNumber(65)));
+  expected_intervals8.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(80), QuicPacketNumber(85)));
 
   EXPECT_EQ(expected_intervals8, actual_intervals8);
 }
 
 TEST_F(QuicFramesTest, AddAdjacentForward) {
   QuicAckFrame ack_frame1;
-  ack_frame1.packets.Add(49);
-  ack_frame1.packets.AddRange(50, 60);
-  ack_frame1.packets.AddRange(60, 70);
-  ack_frame1.packets.AddRange(70, 100);
+  ack_frame1.packets.Add(QuicPacketNumber(49));
+  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
+  ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
+  ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
 
   std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(49, 100));
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(49), QuicPacketNumber(100)));
 
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
       ack_frame1.packets.begin(), ack_frame1.packets.end());
@@ -382,13 +416,14 @@
 
 TEST_F(QuicFramesTest, AddAdjacentReverse) {
   QuicAckFrame ack_frame1;
-  ack_frame1.packets.AddRange(70, 100);
-  ack_frame1.packets.AddRange(60, 70);
-  ack_frame1.packets.AddRange(50, 60);
-  ack_frame1.packets.Add(49);
+  ack_frame1.packets.AddRange(QuicPacketNumber(70), QuicPacketNumber(100));
+  ack_frame1.packets.AddRange(QuicPacketNumber(60), QuicPacketNumber(70));
+  ack_frame1.packets.AddRange(QuicPacketNumber(50), QuicPacketNumber(60));
+  ack_frame1.packets.Add(QuicPacketNumber(49));
 
   std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(49, 100));
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(49), QuicPacketNumber(100)));
 
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
       ack_frame1.packets.begin(), ack_frame1.packets.end());
@@ -398,19 +433,19 @@
 
 TEST_F(QuicFramesTest, RemoveSmallestInterval) {
   QuicAckFrame ack_frame1;
-  ack_frame1.largest_acked = 100u;
-  ack_frame1.packets.AddRange(51, 60);
-  ack_frame1.packets.AddRange(71, 80);
-  ack_frame1.packets.AddRange(91, 100);
+  ack_frame1.largest_acked = QuicPacketNumber(100u);
+  ack_frame1.packets.AddRange(QuicPacketNumber(51), QuicPacketNumber(60));
+  ack_frame1.packets.AddRange(QuicPacketNumber(71), QuicPacketNumber(80));
+  ack_frame1.packets.AddRange(QuicPacketNumber(91), QuicPacketNumber(100));
   ack_frame1.packets.RemoveSmallestInterval();
   EXPECT_EQ(2u, ack_frame1.packets.NumIntervals());
-  EXPECT_EQ(71u, ack_frame1.packets.Min());
-  EXPECT_EQ(99u, ack_frame1.packets.Max());
+  EXPECT_EQ(QuicPacketNumber(71u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
 
   ack_frame1.packets.RemoveSmallestInterval();
   EXPECT_EQ(1u, ack_frame1.packets.NumIntervals());
-  EXPECT_EQ(91u, ack_frame1.packets.Min());
-  EXPECT_EQ(99u, ack_frame1.packets.Max());
+  EXPECT_EQ(QuicPacketNumber(91u), ack_frame1.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), ack_frame1.packets.Max());
 }
 
 class PacketNumberQueueTest : public QuicTest {};
@@ -418,85 +453,85 @@
 // Tests that a queue contains the expected data after calls to Add().
 TEST_F(PacketNumberQueueTest, AddRange) {
   PacketNumberQueue queue;
-  queue.AddRange(1, 51);
-  queue.Add(53);
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(51));
+  queue.Add(QuicPacketNumber(53));
 
-  EXPECT_FALSE(queue.Contains(0));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
   for (int i = 1; i < 51; ++i) {
-    EXPECT_TRUE(queue.Contains(i));
+    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
   }
-  EXPECT_FALSE(queue.Contains(51));
-  EXPECT_FALSE(queue.Contains(52));
-  EXPECT_TRUE(queue.Contains(53));
-  EXPECT_FALSE(queue.Contains(54));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(52)));
+  EXPECT_TRUE(queue.Contains(QuicPacketNumber(53)));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(54)));
   EXPECT_EQ(51u, queue.NumPacketsSlow());
-  EXPECT_EQ(1u, queue.Min());
-  EXPECT_EQ(53u, queue.Max());
+  EXPECT_EQ(QuicPacketNumber(1u), queue.Min());
+  EXPECT_EQ(QuicPacketNumber(53u), queue.Max());
 
-  queue.Add(70);
-  EXPECT_EQ(70u, queue.Max());
+  queue.Add(QuicPacketNumber(70));
+  EXPECT_EQ(QuicPacketNumber(70u), queue.Max());
 }
 
 // Tests Contains function
 TEST_F(PacketNumberQueueTest, Contains) {
   PacketNumberQueue queue;
-  EXPECT_FALSE(queue.Contains(0));
-  queue.AddRange(5, 10);
-  queue.Add(20);
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
+  queue.AddRange(QuicPacketNumber(5), QuicPacketNumber(10));
+  queue.Add(QuicPacketNumber(20));
 
   for (int i = 1; i < 5; ++i) {
-    EXPECT_FALSE(queue.Contains(i));
+    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
   }
 
   for (int i = 5; i < 10; ++i) {
-    EXPECT_TRUE(queue.Contains(i));
+    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
   }
   for (int i = 10; i < 20; ++i) {
-    EXPECT_FALSE(queue.Contains(i));
+    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
   }
-  EXPECT_TRUE(queue.Contains(20));
-  EXPECT_FALSE(queue.Contains(21));
+  EXPECT_TRUE(queue.Contains(QuicPacketNumber(20)));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(21)));
 
   PacketNumberQueue queue2;
-  EXPECT_FALSE(queue2.Contains(1));
+  EXPECT_FALSE(queue2.Contains(QuicPacketNumber(1)));
   for (int i = 1; i < 51; ++i) {
-    queue2.Add(2 * i);
+    queue2.Add(QuicPacketNumber(2 * i));
   }
-  EXPECT_FALSE(queue2.Contains(0));
+  EXPECT_FALSE(queue2.Contains(QuicPacketNumber()));
   for (int i = 1; i < 51; ++i) {
     if (i % 2 == 0) {
-      EXPECT_TRUE(queue2.Contains(i));
+      EXPECT_TRUE(queue2.Contains(QuicPacketNumber(i)));
     } else {
-      EXPECT_FALSE(queue2.Contains(i));
+      EXPECT_FALSE(queue2.Contains(QuicPacketNumber(i)));
     }
   }
-  EXPECT_FALSE(queue2.Contains(101));
+  EXPECT_FALSE(queue2.Contains(QuicPacketNumber(101)));
 }
 
 // Tests that a queue contains the expected data after calls to RemoveUpTo().
 TEST_F(PacketNumberQueueTest, Removal) {
   PacketNumberQueue queue;
-  EXPECT_FALSE(queue.Contains(51));
-  queue.AddRange(1, 100);
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber(51)));
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
 
-  EXPECT_TRUE(queue.RemoveUpTo(51));
-  EXPECT_FALSE(queue.RemoveUpTo(51));
+  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(51)));
+  EXPECT_FALSE(queue.RemoveUpTo(QuicPacketNumber(51)));
 
-  EXPECT_FALSE(queue.Contains(0));
+  EXPECT_FALSE(queue.Contains(QuicPacketNumber()));
   for (int i = 1; i < 51; ++i) {
-    EXPECT_FALSE(queue.Contains(i));
+    EXPECT_FALSE(queue.Contains(QuicPacketNumber(i)));
   }
   for (int i = 51; i < 100; ++i) {
-    EXPECT_TRUE(queue.Contains(i));
+    EXPECT_TRUE(queue.Contains(QuicPacketNumber(i)));
   }
   EXPECT_EQ(49u, queue.NumPacketsSlow());
-  EXPECT_EQ(51u, queue.Min());
-  EXPECT_EQ(99u, queue.Max());
+  EXPECT_EQ(QuicPacketNumber(51u), queue.Min());
+  EXPECT_EQ(QuicPacketNumber(99u), queue.Max());
 
   PacketNumberQueue queue2;
-  queue2.AddRange(1, 5);
-  EXPECT_TRUE(queue2.RemoveUpTo(3));
-  EXPECT_TRUE(queue2.RemoveUpTo(50));
+  queue2.AddRange(QuicPacketNumber(1), QuicPacketNumber(5));
+  EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(3)));
+  EXPECT_TRUE(queue2.RemoveUpTo(QuicPacketNumber(50)));
   EXPECT_TRUE(queue2.Empty());
 }
 
@@ -506,8 +541,8 @@
   EXPECT_TRUE(queue.Empty());
   EXPECT_EQ(0u, queue.NumPacketsSlow());
 
-  queue.AddRange(1, 100);
-  EXPECT_TRUE(queue.RemoveUpTo(100));
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
+  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(100)));
   EXPECT_TRUE(queue.Empty());
   EXPECT_EQ(0u, queue.NumPacketsSlow());
 }
@@ -518,29 +553,30 @@
   PacketNumberQueue queue;
   oss << queue;
 
-  queue.Add(1);
-  queue.AddRange(50, 100);
+  queue.Add(QuicPacketNumber(1));
+  queue.AddRange(QuicPacketNumber(50), QuicPacketNumber(100));
   oss << queue;
 }
 
 // Tests that the iterators returned from a packet queue iterate over the queue.
 TEST_F(PacketNumberQueueTest, Iterators) {
   PacketNumberQueue queue;
-  queue.AddRange(1, 100);
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
 
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
       queue.begin(), queue.end());
 
   PacketNumberQueue queue2;
   for (int i = 1; i < 100; i++) {
-    queue2.AddRange(i, i + 1);
+    queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
   }
 
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals2(
       queue2.begin(), queue2.end());
 
   std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(1, 100));
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(1), QuicPacketNumber(100)));
   EXPECT_EQ(expected_intervals, actual_intervals);
   EXPECT_EQ(expected_intervals, actual_intervals2);
   EXPECT_EQ(actual_intervals, actual_intervals2);
@@ -548,10 +584,10 @@
 
 TEST_F(PacketNumberQueueTest, ReversedIterators) {
   PacketNumberQueue queue;
-  queue.AddRange(1, 100);
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(100));
   PacketNumberQueue queue2;
   for (int i = 1; i < 100; i++) {
-    queue2.AddRange(i, i + 1);
+    queue2.AddRange(QuicPacketNumber(i), QuicPacketNumber(i + 1));
   }
   const std::vector<QuicInterval<QuicPacketNumber>> actual_intervals(
       queue.rbegin(), queue.rend());
@@ -559,7 +595,8 @@
       queue2.rbegin(), queue2.rend());
 
   std::vector<QuicInterval<QuicPacketNumber>> expected_intervals;
-  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(1, 100));
+  expected_intervals.emplace_back(QuicInterval<QuicPacketNumber>(
+      QuicPacketNumber(1), QuicPacketNumber(100)));
 
   EXPECT_EQ(expected_intervals, actual_intervals);
   EXPECT_EQ(expected_intervals, actual_intervals2);
@@ -567,7 +604,7 @@
 
   PacketNumberQueue queue3;
   for (int i = 1; i < 20; i++) {
-    queue3.Add(2 * i);
+    queue3.Add(QuicPacketNumber(2 * i));
   }
 
   auto begin = queue3.begin();
@@ -583,17 +620,17 @@
 
 TEST_F(PacketNumberQueueTest, IntervalLengthAndRemoveInterval) {
   PacketNumberQueue queue;
-  queue.AddRange(1, 10);
-  queue.AddRange(20, 30);
-  queue.AddRange(40, 50);
+  queue.AddRange(QuicPacketNumber(1), QuicPacketNumber(10));
+  queue.AddRange(QuicPacketNumber(20), QuicPacketNumber(30));
+  queue.AddRange(QuicPacketNumber(40), QuicPacketNumber(50));
   EXPECT_EQ(3u, queue.NumIntervals());
   EXPECT_EQ(10u, queue.LastIntervalLength());
 
-  EXPECT_TRUE(queue.RemoveUpTo(25));
+  EXPECT_TRUE(queue.RemoveUpTo(QuicPacketNumber(25)));
   EXPECT_EQ(2u, queue.NumIntervals());
   EXPECT_EQ(10u, queue.LastIntervalLength());
-  EXPECT_EQ(25u, queue.Min());
-  EXPECT_EQ(49u, queue.Max());
+  EXPECT_EQ(QuicPacketNumber(25u), queue.Min());
+  EXPECT_EQ(QuicPacketNumber(49u), queue.Max());
 }
 
 }  // namespace
diff --git a/net/third_party/quic/core/frames/quic_stop_waiting_frame.cc b/net/third_party/quic/core/frames/quic_stop_waiting_frame.cc
index a89160f..f2486d5 100644
--- a/net/third_party/quic/core/frames/quic_stop_waiting_frame.cc
+++ b/net/third_party/quic/core/frames/quic_stop_waiting_frame.cc
@@ -8,7 +8,7 @@
 
 namespace quic {
 
-QuicStopWaitingFrame::QuicStopWaitingFrame() : least_unacked(0) {}
+QuicStopWaitingFrame::QuicStopWaitingFrame() {}
 
 QuicStopWaitingFrame::~QuicStopWaitingFrame() {}
 
diff --git a/net/third_party/quic/core/http/quic_server_session_base.cc b/net/third_party/quic/core/http/quic_server_session_base.cc
index 0a9fad0f..8d97ae241 100644
--- a/net/third_party/quic/core/http/quic_server_session_base.cc
+++ b/net/third_party/quic/core/http/quic_server_session_base.cc
@@ -30,8 +30,7 @@
       helper_(helper),
       bandwidth_resumption_enabled_(false),
       bandwidth_estimate_sent_to_client_(QuicBandwidth::Zero()),
-      last_scup_time_(QuicTime::Zero()),
-      last_scup_packet_number_(0) {}
+      last_scup_time_(QuicTime::Zero()) {}
 
 QuicServerSessionBase::~QuicServerSessionBase() {}
 
@@ -112,9 +111,15 @@
   int64_t srtt_ms =
       sent_packet_manager.GetRttStats()->smoothed_rtt().ToMilliseconds();
   int64_t now_ms = (now - last_scup_time_).ToMilliseconds();
-  int64_t packets_since_last_scup =
-      connection()->sent_packet_manager().GetLargestSentPacket() -
-      last_scup_packet_number_;
+  int64_t packets_since_last_scup = 0;
+  const QuicPacketNumber largest_sent_packet =
+      connection()->sent_packet_manager().GetLargestSentPacket();
+  if (largest_sent_packet.IsInitialized()) {
+    packets_since_last_scup =
+        last_scup_packet_number_.IsInitialized()
+            ? largest_sent_packet - last_scup_packet_number_
+            : largest_sent_packet.ToUint64();
+  }
   if (now_ms < (kMinIntervalBetweenServerConfigUpdatesRTTs * srtt_ms) ||
       now_ms < kMinIntervalBetweenServerConfigUpdatesMs ||
       packets_since_last_scup < kMinPacketsBetweenServerConfigUpdates) {
diff --git a/net/third_party/quic/core/http/quic_server_session_base_test.cc b/net/third_party/quic/core/http/quic_server_session_base_test.cc
index 07520d37..238e04ab 100644
--- a/net/third_party/quic/core/http/quic_server_session_base_test.cc
+++ b/net/third_party/quic/core/http/quic_server_session_base_test.cc
@@ -499,10 +499,11 @@
 
   // Bandwidth estimate has now changed sufficiently, enough time has passed,
   // and enough packets have been sent.
-  SerializedPacket packet(1 + kMinPacketsBetweenServerConfigUpdates,
-                          PACKET_4BYTE_PACKET_NUMBER, nullptr, 1000, false,
-                          false);
-  sent_packet_manager->OnPacketSent(&packet, 0, now, NOT_RETRANSMISSION,
+  SerializedPacket packet(
+      QuicPacketNumber(1) + kMinPacketsBetweenServerConfigUpdates,
+      PACKET_4BYTE_PACKET_NUMBER, nullptr, 1000, false, false);
+  sent_packet_manager->OnPacketSent(&packet, QuicPacketNumber(), now,
+                                    NOT_RETRANSMISSION,
                                     HAS_RETRANSMITTABLE_DATA);
 
   // Verify that the proto has exactly the values we expect.
diff --git a/net/third_party/quic/core/packet_number_indexed_queue.h b/net/third_party/quic/core/packet_number_indexed_queue.h
index 7b2b354c..afa1ccd 100644
--- a/net/third_party/quic/core/packet_number_indexed_queue.h
+++ b/net/third_party/quic/core/packet_number_indexed_queue.h
@@ -37,8 +37,7 @@
 template <typename T>
 class PacketNumberIndexedQueue {
  public:
-  PacketNumberIndexedQueue()
-      : number_of_present_entries_(0), first_packet_(kInvalidPacketNumber) {}
+  PacketNumberIndexedQueue() : number_of_present_entries_(0) {}
 
   // Retrieve the entry associated with the packet number.  Returns the pointer
   // to the entry in case of success, or nullptr if the entry does not exist.
@@ -75,7 +74,7 @@
   // empty.
   QuicPacketNumber last_packet() const {
     if (IsEmpty()) {
-      return kInvalidPacketNumber;
+      return QuicPacketNumber();
     }
     return first_packet_ + entries_.size() - 1;
   }
@@ -129,14 +128,14 @@
 template <typename... Args>
 bool PacketNumberIndexedQueue<T>::Emplace(QuicPacketNumber packet_number,
                                           Args&&... args) {
-  if (packet_number == kInvalidPacketNumber) {
+  if (!packet_number.IsInitialized()) {
     QUIC_BUG << "Try to insert an uninitialized packet number";
     return false;
   }
 
   if (IsEmpty()) {
     DCHECK(entries_.empty());
-    DCHECK_EQ(kInvalidPacketNumber, first_packet_);
+    DCHECK(!first_packet_.IsInitialized());
 
     entries_.emplace_back(std::forward<Args>(args)...);
     number_of_present_entries_ = 1;
@@ -183,14 +182,14 @@
     first_packet_++;
   }
   if (entries_.empty()) {
-    first_packet_ = kInvalidPacketNumber;
+    first_packet_.Clear();
   }
 }
 
 template <typename T>
 auto PacketNumberIndexedQueue<T>::GetEntryWrapper(
     QuicPacketNumber packet_number) const -> const EntryWrapper* {
-  if (packet_number == kInvalidPacketNumber || IsEmpty() ||
+  if (!packet_number.IsInitialized() || IsEmpty() ||
       packet_number < first_packet_) {
     return nullptr;
   }
diff --git a/net/third_party/quic/core/packet_number_indexed_queue_test.cc b/net/third_party/quic/core/packet_number_indexed_queue_test.cc
index 606617a..7993357 100644
--- a/net/third_party/quic/core/packet_number_indexed_queue_test.cc
+++ b/net/third_party/quic/core/packet_number_indexed_queue_test.cc
@@ -23,156 +23,156 @@
 
 TEST_F(PacketNumberIndexedQueueTest, InitialState) {
   EXPECT_TRUE(queue_.IsEmpty());
-  EXPECT_EQ(0u, queue_.first_packet());
-  EXPECT_EQ(0u, queue_.last_packet());
+  EXPECT_FALSE(queue_.first_packet().IsInitialized());
+  EXPECT_FALSE(queue_.last_packet().IsInitialized());
   EXPECT_EQ(0u, queue_.number_of_present_entries());
   EXPECT_EQ(0u, queue_.entry_slots_used());
 }
 
 TEST_F(PacketNumberIndexedQueueTest, InsertingContinuousElements) {
-  ASSERT_TRUE(queue_.Emplace(1001, "one"));
-  EXPECT_EQ("one", *queue_.GetEntry(1001));
+  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1001), "one"));
+  EXPECT_EQ("one", *queue_.GetEntry(QuicPacketNumber(1001)));
 
-  ASSERT_TRUE(queue_.Emplace(1002, "two"));
-  EXPECT_EQ("two", *queue_.GetEntry(1002));
+  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1002), "two"));
+  EXPECT_EQ("two", *queue_.GetEntry(QuicPacketNumber(1002)));
 
   EXPECT_FALSE(queue_.IsEmpty());
-  EXPECT_EQ(1001u, queue_.first_packet());
-  EXPECT_EQ(1002u, queue_.last_packet());
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1002u), queue_.last_packet());
   EXPECT_EQ(2u, queue_.number_of_present_entries());
   EXPECT_EQ(2u, queue_.entry_slots_used());
 }
 
 TEST_F(PacketNumberIndexedQueueTest, InsertingOutOfOrder) {
-  queue_.Emplace(1001, "one");
+  queue_.Emplace(QuicPacketNumber(1001), "one");
 
-  ASSERT_TRUE(queue_.Emplace(1003, "three"));
-  EXPECT_EQ(nullptr, queue_.GetEntry(1002));
-  EXPECT_EQ("three", *queue_.GetEntry(1003));
+  ASSERT_TRUE(queue_.Emplace(QuicPacketNumber(1003), "three"));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1002)));
+  EXPECT_EQ("three", *queue_.GetEntry(QuicPacketNumber(1003)));
 
-  EXPECT_EQ(1001u, queue_.first_packet());
-  EXPECT_EQ(1003u, queue_.last_packet());
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
   EXPECT_EQ(2u, queue_.number_of_present_entries());
   EXPECT_EQ(3u, queue_.entry_slots_used());
 
-  ASSERT_FALSE(queue_.Emplace(1002, "two"));
+  ASSERT_FALSE(queue_.Emplace(QuicPacketNumber(1002), "two"));
 }
 
 TEST_F(PacketNumberIndexedQueueTest, InsertingIntoPast) {
-  queue_.Emplace(1001, "one");
-  EXPECT_FALSE(queue_.Emplace(1000, "zero"));
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1000), "zero"));
 }
 
 TEST_F(PacketNumberIndexedQueueTest, InsertingDuplicate) {
-  queue_.Emplace(1001, "one");
-  EXPECT_FALSE(queue_.Emplace(1001, "one"));
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1001), "one"));
 }
 
 TEST_F(PacketNumberIndexedQueueTest, RemoveInTheMiddle) {
-  queue_.Emplace(1001, "one");
-  queue_.Emplace(1002, "two");
-  queue_.Emplace(1003, "three");
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(1002), "two");
+  queue_.Emplace(QuicPacketNumber(1003), "three");
 
-  ASSERT_TRUE(queue_.Remove(1002));
-  EXPECT_EQ(nullptr, queue_.GetEntry(1002));
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1002)));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1002)));
 
-  EXPECT_EQ(1001u, queue_.first_packet());
-  EXPECT_EQ(1003u, queue_.last_packet());
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
   EXPECT_EQ(2u, queue_.number_of_present_entries());
   EXPECT_EQ(3u, queue_.entry_slots_used());
 
-  EXPECT_FALSE(queue_.Emplace(1002, "two"));
-  EXPECT_TRUE(queue_.Emplace(1004, "four"));
+  EXPECT_FALSE(queue_.Emplace(QuicPacketNumber(1002), "two"));
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(1004), "four"));
 }
 
 TEST_F(PacketNumberIndexedQueueTest, RemoveAtImmediateEdges) {
-  queue_.Emplace(1001, "one");
-  queue_.Emplace(1002, "two");
-  queue_.Emplace(1003, "three");
-  ASSERT_TRUE(queue_.Remove(1001));
-  EXPECT_EQ(nullptr, queue_.GetEntry(1001));
-  ASSERT_TRUE(queue_.Remove(1003));
-  EXPECT_EQ(nullptr, queue_.GetEntry(1003));
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(1002), "two");
+  queue_.Emplace(QuicPacketNumber(1003), "three");
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1001)));
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1003)));
+  EXPECT_EQ(nullptr, queue_.GetEntry(QuicPacketNumber(1003)));
 
-  EXPECT_EQ(1002u, queue_.first_packet());
-  EXPECT_EQ(1003u, queue_.last_packet());
+  EXPECT_EQ(QuicPacketNumber(1002u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(1003u), queue_.last_packet());
   EXPECT_EQ(1u, queue_.number_of_present_entries());
   EXPECT_EQ(2u, queue_.entry_slots_used());
 
-  EXPECT_TRUE(queue_.Emplace(1004, "four"));
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(1004), "four"));
 }
 
 TEST_F(PacketNumberIndexedQueueTest, RemoveAtDistantFront) {
-  queue_.Emplace(1001, "one");
-  queue_.Emplace(1002, "one (kinda)");
-  queue_.Emplace(2001, "two");
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(1002), "one (kinda)");
+  queue_.Emplace(QuicPacketNumber(2001), "two");
 
-  EXPECT_EQ(1001u, queue_.first_packet());
-  EXPECT_EQ(2001u, queue_.last_packet());
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
   EXPECT_EQ(3u, queue_.number_of_present_entries());
   EXPECT_EQ(1001u, queue_.entry_slots_used());
 
-  ASSERT_TRUE(queue_.Remove(1002));
-  EXPECT_EQ(1001u, queue_.first_packet());
-  EXPECT_EQ(2001u, queue_.last_packet());
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1002)));
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
   EXPECT_EQ(2u, queue_.number_of_present_entries());
   EXPECT_EQ(1001u, queue_.entry_slots_used());
 
-  ASSERT_TRUE(queue_.Remove(1001));
-  EXPECT_EQ(2001u, queue_.first_packet());
-  EXPECT_EQ(2001u, queue_.last_packet());
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
   EXPECT_EQ(1u, queue_.number_of_present_entries());
   EXPECT_EQ(1u, queue_.entry_slots_used());
 }
 
 TEST_F(PacketNumberIndexedQueueTest, RemoveAtDistantBack) {
-  queue_.Emplace(1001, "one");
-  queue_.Emplace(2001, "two");
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(2001), "two");
 
-  EXPECT_EQ(1001u, queue_.first_packet());
-  EXPECT_EQ(2001u, queue_.last_packet());
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
 
-  ASSERT_TRUE(queue_.Remove(2001));
-  EXPECT_EQ(1001u, queue_.first_packet());
-  EXPECT_EQ(2001u, queue_.last_packet());
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(2001)));
+  EXPECT_EQ(QuicPacketNumber(1001u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(2001u), queue_.last_packet());
 }
 
 TEST_F(PacketNumberIndexedQueueTest, ClearAndRepopulate) {
-  queue_.Emplace(1001, "one");
-  queue_.Emplace(2001, "two");
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  queue_.Emplace(QuicPacketNumber(2001), "two");
 
-  ASSERT_TRUE(queue_.Remove(1001));
-  ASSERT_TRUE(queue_.Remove(2001));
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(2001)));
   EXPECT_TRUE(queue_.IsEmpty());
-  EXPECT_EQ(0u, queue_.first_packet());
-  EXPECT_EQ(0u, queue_.last_packet());
+  EXPECT_FALSE(queue_.first_packet().IsInitialized());
+  EXPECT_FALSE(queue_.last_packet().IsInitialized());
 
-  EXPECT_TRUE(queue_.Emplace(101, "one"));
-  EXPECT_TRUE(queue_.Emplace(201, "two"));
-  EXPECT_EQ(101u, queue_.first_packet());
-  EXPECT_EQ(201u, queue_.last_packet());
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(101), "one"));
+  EXPECT_TRUE(queue_.Emplace(QuicPacketNumber(201), "two"));
+  EXPECT_EQ(QuicPacketNumber(101u), queue_.first_packet());
+  EXPECT_EQ(QuicPacketNumber(201u), queue_.last_packet());
 }
 
 TEST_F(PacketNumberIndexedQueueTest, FailToRemoveElementsThatNeverExisted) {
-  ASSERT_FALSE(queue_.Remove(1000));
-  queue_.Emplace(1001, "one");
-  ASSERT_FALSE(queue_.Remove(1000));
-  ASSERT_FALSE(queue_.Remove(1002));
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1000)));
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1000)));
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1002)));
 }
 
 TEST_F(PacketNumberIndexedQueueTest, FailToRemoveElementsTwice) {
-  queue_.Emplace(1001, "one");
-  ASSERT_TRUE(queue_.Remove(1001));
-  ASSERT_FALSE(queue_.Remove(1001));
-  ASSERT_FALSE(queue_.Remove(1001));
+  queue_.Emplace(QuicPacketNumber(1001), "one");
+  ASSERT_TRUE(queue_.Remove(QuicPacketNumber(1001)));
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1001)));
+  ASSERT_FALSE(queue_.Remove(QuicPacketNumber(1001)));
 }
 
 TEST_F(PacketNumberIndexedQueueTest, ConstGetter) {
-  queue_.Emplace(1001, "one");
+  queue_.Emplace(QuicPacketNumber(1001), "one");
   const auto& const_queue = queue_;
 
-  EXPECT_EQ("one", *const_queue.GetEntry(1001));
-  EXPECT_EQ(nullptr, const_queue.GetEntry(1002));
+  EXPECT_EQ("one", *const_queue.GetEntry(QuicPacketNumber(1001)));
+  EXPECT_EQ(nullptr, const_queue.GetEntry(QuicPacketNumber(1002)));
 }
 
 }  // namespace
diff --git a/net/third_party/quic/core/quic_connection.cc b/net/third_party/quic/core/quic_connection.cc
index 3c261c19..7b0fc5a8 100644
--- a/net/third_party/quic/core/quic_connection.cc
+++ b/net/third_party/quic/core/quic_connection.cc
@@ -245,15 +245,12 @@
       peer_address_(initial_peer_address),
       direct_peer_address_(initial_peer_address),
       active_effective_peer_migration_type_(NO_CHANGE),
-      highest_packet_sent_before_effective_peer_migration_(0),
       last_packet_decrypted_(false),
       last_size_(0),
       current_packet_data_(nullptr),
       last_decrypted_packet_level_(ENCRYPTION_NONE),
       should_last_packet_instigate_acks_(false),
       was_last_packet_missing_(false),
-      largest_seen_packet_with_ack_(0),
-      largest_seen_packet_with_stop_waiting_(0),
       max_undecryptable_packets_(0),
       max_tracked_packets_(kMaxTrackedPackets),
       pending_version_negotiation_packet_(false),
@@ -784,7 +781,7 @@
       // Packets should have the version flag till version negotiation is
       // done.
       QuicString error_details =
-          QuicStrCat(ENDPOINT, "Packet ", header.packet_number,
+          QuicStrCat(ENDPOINT, "Packet ", header.packet_number.ToUint64(),
                      " without version flag before version negotiated.");
       QUIC_DLOG(WARNING) << error_details;
       CloseConnection(QUIC_INVALID_VERSION, error_details,
@@ -842,7 +839,8 @@
   current_effective_peer_migration_type_ = NO_CHANGE;
 
   if (perspective_ == Perspective::IS_CLIENT) {
-    if (header.packet_number > received_packet_manager_.GetLargestObserved()) {
+    if (!received_packet_manager_.GetLargestObserved().IsInitialized() ||
+        header.packet_number > received_packet_manager_.GetLargestObserved()) {
       // Update peer_address_ and effective_peer_address_ immediately for
       // client connections.
       direct_peer_address_ = last_packet_source_address_;
@@ -946,22 +944,25 @@
   QUIC_DVLOG(1) << ENDPOINT
                 << "OnAckFrameStart, largest_acked: " << largest_acked;
 
-  if (last_header_.packet_number <= largest_seen_packet_with_ack_) {
+  if (largest_seen_packet_with_ack_.IsInitialized() &&
+      last_header_.packet_number <= largest_seen_packet_with_ack_) {
     QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
     return true;
   }
 
-  if (largest_acked > sent_packet_manager_.GetLargestSentPacket()) {
+  if (!sent_packet_manager_.GetLargestSentPacket().IsInitialized() ||
+      largest_acked > sent_packet_manager_.GetLargestSentPacket()) {
     QUIC_DLOG(WARNING) << ENDPOINT
                        << "Peer's observed unsent packet:" << largest_acked
                        << " vs " << sent_packet_manager_.GetLargestSentPacket();
-    // We got an error for data we have not sent.
+    // We got an ack for data we have not sent.
     CloseConnection(QUIC_INVALID_ACK_DATA, "Largest observed too high.",
                     ConnectionCloseBehavior::SEND_CONNECTION_CLOSE_PACKET);
     return false;
   }
 
-  if (largest_acked > sent_packet_manager_.GetLargestObserved()) {
+  if (!sent_packet_manager_.GetLargestObserved().IsInitialized() ||
+      largest_acked > sent_packet_manager_.GetLargestObserved()) {
     visitor_->OnForwardProgressConfirmed();
   } else if (largest_acked < sent_packet_manager_.GetLargestObserved()) {
     QUIC_LOG(INFO) << ENDPOINT << "Peer's largest_observed packet decreased:"
@@ -986,7 +987,8 @@
   DCHECK(connected_);
   QUIC_DVLOG(1) << ENDPOINT << "OnAckRange: [" << start << ", " << end << ")";
 
-  if (last_header_.packet_number <= largest_seen_packet_with_ack_) {
+  if (largest_seen_packet_with_ack_.IsInitialized() &&
+      last_header_.packet_number <= largest_seen_packet_with_ack_) {
     QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
     return true;
   }
@@ -1001,7 +1003,8 @@
   QUIC_DVLOG(1) << ENDPOINT << "OnAckTimestamp: [" << packet_number << ", "
                 << timestamp.ToDebuggingValue() << ")";
 
-  if (last_header_.packet_number <= largest_seen_packet_with_ack_) {
+  if (largest_seen_packet_with_ack_.IsInitialized() &&
+      last_header_.packet_number <= largest_seen_packet_with_ack_) {
     QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
     return true;
   }
@@ -1014,7 +1017,8 @@
   DCHECK(connected_);
   QUIC_DVLOG(1) << ENDPOINT << "OnAckFrameEnd, start: " << start;
 
-  if (last_header_.packet_number <= largest_seen_packet_with_ack_) {
+  if (largest_seen_packet_with_ack_.IsInitialized() &&
+      last_header_.packet_number <= largest_seen_packet_with_ack_) {
     QUIC_DLOG(INFO) << ENDPOINT << "Received an old ack frame: ignoring";
     return true;
   }
@@ -1053,7 +1057,8 @@
   if (no_stop_waiting_frames_) {
     return true;
   }
-  if (last_header_.packet_number <= largest_seen_packet_with_stop_waiting_) {
+  if (largest_seen_packet_with_stop_waiting_.IsInitialized() &&
+      last_header_.packet_number <= largest_seen_packet_with_stop_waiting_) {
     QUIC_DLOG(INFO) << ENDPOINT
                     << "Received an old stop waiting frame: ignoring";
     return true;
@@ -1131,8 +1136,10 @@
 
 const char* QuicConnection::ValidateStopWaitingFrame(
     const QuicStopWaitingFrame& stop_waiting) {
-  if (stop_waiting.least_unacked <
-      received_packet_manager_.peer_least_packet_awaiting_ack()) {
+  if (received_packet_manager_.peer_least_packet_awaiting_ack()
+          .IsInitialized() &&
+      stop_waiting.least_unacked <
+          received_packet_manager_.peer_least_packet_awaiting_ack()) {
     QUIC_DLOG(ERROR)
         << ENDPOINT
         << "Peer's sent low least_unacked: " << stop_waiting.least_unacked
@@ -1441,8 +1448,10 @@
   if (was_missing) {
     // Only ack immediately if an ACK frame was sent with a larger
     // largest acked than the newly received packet number.
-    if (last_header_.packet_number <
-        sent_packet_manager_.unacked_packets().largest_sent_largest_acked()) {
+    const QuicPacketNumber largest_sent_largest_acked =
+        sent_packet_manager_.unacked_packets().largest_sent_largest_acked();
+    if (largest_sent_largest_acked.IsInitialized() &&
+        last_header_.packet_number < largest_sent_largest_acked) {
       ack_queued_ = true;
     }
   }
@@ -1450,7 +1459,10 @@
   if (should_last_packet_instigate_acks_ && !ack_queued_) {
     ++num_retransmittable_packets_received_since_last_ack_sent_;
     if (ack_mode_ != TCP_ACKING &&
-        last_header_.packet_number > min_received_before_ack_decimation_) {
+        // TODO(fayang): Fix this as this check assumes the first received
+        // packet is 1.
+        last_header_.packet_number >
+            QuicPacketNumber(min_received_before_ack_decimation_)) {
       // Ack up to 10 packets at once unless ack decimation is unlimited.
       if (!unlimited_ack_decimation_ &&
           num_retransmittable_packets_received_since_last_ack_sent_ >=
@@ -1530,8 +1542,9 @@
 void QuicConnection::CloseIfTooManyOutstandingSentPackets() {
   // This occurs if we don't discard old packets we've seen fast enough. It's
   // possible largest observed is less than leaset unacked.
-  if (sent_packet_manager_.GetLargestObserved() >
-      sent_packet_manager_.GetLeastUnacked() + max_tracked_packets_) {
+  if (sent_packet_manager_.GetLargestObserved().IsInitialized() &&
+      sent_packet_manager_.GetLargestObserved() >
+          sent_packet_manager_.GetLeastUnacked() + max_tracked_packets_) {
     CloseConnection(
         QUIC_TOO_MANY_OUTSTANDING_SENT_PACKETS,
         QuicStrCat("More than ", max_tracked_packets_, " outstanding."),
@@ -1790,8 +1803,10 @@
       << ", highest_packet_sent_before_effective_peer_migration_ = "
       << highest_packet_sent_before_effective_peer_migration_;
   if (active_effective_peer_migration_type_ != NO_CHANGE &&
-      sent_packet_manager_.GetLargestObserved() >
-          highest_packet_sent_before_effective_peer_migration_) {
+      sent_packet_manager_.GetLargestObserved().IsInitialized() &&
+      (!highest_packet_sent_before_effective_peer_migration_.IsInitialized() ||
+       sent_packet_manager_.GetLargestObserved() >
+           highest_packet_sent_before_effective_peer_migration_)) {
     if (perspective_ == Perspective::IS_SERVER) {
       OnEffectivePeerMigrationValidated();
     }
@@ -1886,7 +1901,7 @@
     QUIC_RESTART_FLAG_COUNT_N(quic_enable_accept_random_ipn, 2, 2);
     // Configured to accept any packet number in range 1...0x7fffffff
     // as initial packet number.
-    if (last_header_.packet_number != kInvalidPacketNumber) {
+    if (last_header_.packet_number.IsInitialized()) {
       // The last packet's number is not 0. Ensure that this packet
       // is reasonably close to where it should be.
       if (!Near(header.packet_number, last_header_.packet_number)) {
@@ -1899,10 +1914,9 @@
       }
     } else {
       // The "last packet's number" is 0, meaning that this packet is the first
-      // one received. Ensure it is in range 1..kMaxRandomInitialPacketNumber,
+      // one received. Ensure it is in range 1..MaxRandomInitialPacketNumber(),
       // inclusive.
-      if ((header.packet_number == kInvalidPacketNumber) ||
-          (header.packet_number > kMaxRandomInitialPacketNumber)) {
+      if ((header.packet_number > MaxRandomInitialPacketNumber())) {
         // packet number is bad.
         QUIC_DLOG(INFO) << ENDPOINT << "Initial packet " << header.packet_number
                         << " out of bounds.  Discarding";
@@ -1916,21 +1930,29 @@
     // Count those that would have been accepted if FLAGS..random_ipn
     // were true -- to detect/diagnose potential issues prior to
     // enabling the flag.
-    if ((header.packet_number > 1) &&
-        (header.packet_number <= kMaxRandomInitialPacketNumber)) {
+    if ((header.packet_number > QuicPacketNumber(1)) &&
+        (header.packet_number <= MaxRandomInitialPacketNumber())) {
       QUIC_CODE_COUNT_N(had_possibly_random_ipn, 2, 2);
     }
-
-    if (!Near(header.packet_number, last_header_.packet_number)) {
+    bool out_of_bound =
+        last_header_.packet_number.IsInitialized()
+            ? !Near(header.packet_number, last_header_.packet_number)
+            // TODO(fayang): Fix this as this check assume the first received
+            // packet is 1.
+            : header.packet_number > QuicPacketNumber(kMaxPacketGap);
+    if (out_of_bound) {
       QUIC_DLOG(INFO) << ENDPOINT << "Packet " << header.packet_number
                       << " out of bounds.  Discarding";
       QuicStringPiece packet_data = GetCurrentPacket();
       const size_t kMaxPacketLengthInErrorDetails = 64;
       CloseConnection(
           QUIC_INVALID_PACKET_HEADER,
-          QuicStrCat("Packet number out of bounds. last_pkn=",
-                     last_header_.packet_number,
-                     ", current_pkn=", header.packet_number,
+          QuicStrCat("Packet number out of bounds. ",
+                     last_header_.packet_number.IsInitialized()
+                         ? QuicStrCat("last_pkn=",
+                                      last_header_.packet_number.ToUint64())
+                         : "first received packet",
+                     ", current_pkn=", header.packet_number.ToUint64(),
                      ", current_pkt_len=", packet_data.length(),
                      ", current_hdr=",
                      QuicTextUtils::HexEncode(
@@ -2132,7 +2154,8 @@
     ++stats_.packets_discarded;
     return true;
   }
-  if (packet->packet_number < sent_packet_manager_.GetLargestSentPacket()) {
+  if (sent_packet_manager_.GetLargestSentPacket().IsInitialized() &&
+      packet->packet_number < sent_packet_manager_.GetLargestSentPacket()) {
     QUIC_BUG << "Attempt to write packet:" << packet->packet_number
              << " after:" << sent_packet_manager_.GetLargestSentPacket();
     QUIC_CLIENT_HISTOGRAM_COUNTS("QuicSession.NumQueuedPacketsAtOutOfOrder",
@@ -2420,7 +2443,7 @@
 
   if (transport_version() != QUIC_VERSION_35) {
     if (serialized_packet->retransmittable_frames.empty() &&
-        serialized_packet->original_packet_number == kInvalidPacketNumber) {
+        !serialized_packet->original_packet_number.IsInitialized()) {
       // Increment consecutive_num_packets_with_no_retransmittable_frames_ if
       // this packet is a new transmission with no retransmittable frames.
       ++consecutive_num_packets_with_no_retransmittable_frames_;
@@ -3237,7 +3260,7 @@
     QUIC_BUG << "No migration underway.";
     return;
   }
-  highest_packet_sent_before_effective_peer_migration_ = 0;
+  highest_packet_sent_before_effective_peer_migration_.Clear();
   active_effective_peer_migration_type_ = NO_CHANGE;
 }
 
@@ -3391,8 +3414,9 @@
   }
 
   current_packet_content_ = NOT_PADDED_PING;
-  if (last_header_.packet_number ==
-      received_packet_manager_.GetLargestObserved()) {
+  if (received_packet_manager_.GetLargestObserved().IsInitialized() &&
+      last_header_.packet_number ==
+          received_packet_manager_.GetLargestObserved()) {
     direct_peer_address_ = last_packet_source_address_;
     if (current_effective_peer_migration_type_ != NO_CHANGE) {
       // Start effective peer migration immediately when the current packet is
diff --git a/net/third_party/quic/core/quic_connection_test.cc b/net/third_party/quic/core/quic_connection_test.cc
index 29d1001..bead8334 100644
--- a/net/third_party/quic/core/quic_connection_test.cc
+++ b/net/third_party/quic/core/quic_connection_test.cc
@@ -583,10 +583,11 @@
     char buffer[kMaxPacketSize];
     size_t encrypted_length =
         QuicConnectionPeer::GetFramer(this)->EncryptPayload(
-            ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize);
+            ENCRYPTION_NONE, QuicPacketNumber(packet_number), *packet, buffer,
+            kMaxPacketSize);
     SerializedPacket serialized_packet(
-        packet_number, PACKET_4BYTE_PACKET_NUMBER, buffer, encrypted_length,
-        has_ack, has_pending_frames);
+        QuicPacketNumber(packet_number), PACKET_4BYTE_PACKET_NUMBER, buffer,
+        encrypted_length, has_ack, has_pending_frames);
     if (retransmittable == HAS_RETRANSMITTABLE_DATA) {
       serialized_packet.retransmittable_frames.push_back(
           QuicFrame(QuicStreamFrame()));
@@ -923,7 +924,7 @@
 
   QuicPacketNumber least_unacked() {
     if (writer_->stop_waiting_frames().empty()) {
-      return 0;
+      return QuicPacketNumber();
     }
     return writer_->stop_waiting_frames()[0].least_unacked;
   }
@@ -1016,14 +1017,14 @@
         peer_framer_.perspective() == Perspective::IS_SERVER) {
       header.destination_connection_id_length = PACKET_0BYTE_CONNECTION_ID;
     }
-    header.packet_number = number;
+    header.packet_number = QuicPacketNumber(number);
     QuicFrames frames;
     frames.push_back(frame);
     std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
 
     char buffer[kMaxPacketSize];
-    size_t encrypted_length =
-        framer_.EncryptPayload(level, number, *packet, buffer, kMaxPacketSize);
+    size_t encrypted_length = framer_.EncryptPayload(
+        level, QuicPacketNumber(number), *packet, buffer, kMaxPacketSize);
     connection_.ProcessUdpPacket(
         kSelfAddress, kPeerAddress,
         QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
@@ -1034,6 +1035,17 @@
     return ProcessDataPacketAtLevel(number, false, ENCRYPTION_NONE);
   }
 
+  size_t ProcessDataPacket(QuicPacketNumber packet_number) {
+    return ProcessDataPacketAtLevel(packet_number, false, ENCRYPTION_NONE);
+  }
+
+  size_t ProcessDataPacketAtLevel(QuicPacketNumber packet_number,
+                                  bool has_stop_waiting,
+                                  EncryptionLevel level) {
+    return ProcessDataPacketAtLevel(packet_number.ToUint64(), has_stop_waiting,
+                                    level);
+  }
+
   size_t ProcessDataPacketAtLevel(uint64_t number,
                                   bool has_stop_waiting,
                                   EncryptionLevel level) {
@@ -1041,7 +1053,7 @@
         ConstructDataPacket(number, has_stop_waiting));
     char buffer[kMaxPacketSize];
     size_t encrypted_length = peer_framer_.EncryptPayload(
-        level, number, *packet, buffer, kMaxPacketSize);
+        level, QuicPacketNumber(number), *packet, buffer, kMaxPacketSize);
     connection_.ProcessUdpPacket(
         kSelfAddress, kPeerAddress,
         QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
@@ -1054,8 +1066,9 @@
   void ProcessClosePacket(uint64_t number) {
     std::unique_ptr<QuicPacket> packet(ConstructClosePacket(number));
     char buffer[kMaxPacketSize];
-    size_t encrypted_length = peer_framer_.EncryptPayload(
-        ENCRYPTION_NONE, number, *packet, buffer, kMaxPacketSize);
+    size_t encrypted_length =
+        peer_framer_.EncryptPayload(ENCRYPTION_NONE, QuicPacketNumber(number),
+                                    *packet, buffer, kMaxPacketSize);
     connection_.ProcessUdpPacket(
         kSelfAddress, kPeerAddress,
         QuicReceivedPacket(buffer, encrypted_length, QuicTime::Zero(), false));
@@ -1106,7 +1119,11 @@
   }
 
   void ProcessAckPacket(uint64_t packet_number, QuicAckFrame* frame) {
-    QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, packet_number - 1);
+    if (packet_number > 1) {
+      QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, packet_number - 1);
+    } else {
+      QuicPacketCreatorPeer::ClearPacketNumber(&peer_creator_);
+    }
     ProcessFramePacket(QuicFrame(frame));
   }
 
@@ -1130,7 +1147,8 @@
   }
 
   bool IsMissing(uint64_t number) {
-    return IsAwaitingPacket(*outgoing_ack(), number, 0);
+    return IsAwaitingPacket(*outgoing_ack(), QuicPacketNumber(number),
+                            QuicPacketNumber());
   }
 
   std::unique_ptr<QuicPacket> ConstructPacket(const QuicPacketHeader& header,
@@ -1152,7 +1170,7 @@
         peer_framer_.perspective() == Perspective::IS_SERVER) {
       header.destination_connection_id_length = PACKET_0BYTE_CONNECTION_ID;
     }
-    header.packet_number = number;
+    header.packet_number = QuicPacketNumber(number);
 
     QuicFrames frames;
     frames.push_back(QuicFrame(frame1_));
@@ -1179,7 +1197,7 @@
     // Set connection_id to peer's in memory representation as this connection
     // close packet is created by peer_framer.
     header.destination_connection_id = connection_id_;
-    header.packet_number = number;
+    header.packet_number = QuicPacketNumber(number);
     if (peer_framer_.transport_version() > QUIC_VERSION_43 &&
         peer_framer_.perspective() == Perspective::IS_SERVER) {
       header.destination_connection_id_length = PACKET_0BYTE_CONNECTION_ID;
@@ -1203,7 +1221,7 @@
 
   const QuicStopWaitingFrame InitStopWaitingFrame(uint64_t least_unacked) {
     QuicStopWaitingFrame frame;
-    frame.least_unacked = least_unacked;
+    frame.least_unacked = QuicPacketNumber(least_unacked);
     return frame;
   }
 
@@ -1211,10 +1229,17 @@
   // |largest_acked|, except |missing|.
   // REQUIRES: 1 <= |missing| < |largest_acked|
   QuicAckFrame ConstructAckFrame(uint64_t largest_acked, uint64_t missing) {
-    if (missing == 1) {
+    return ConstructAckFrame(QuicPacketNumber(largest_acked),
+                             QuicPacketNumber(missing));
+  }
+
+  QuicAckFrame ConstructAckFrame(QuicPacketNumber largest_acked,
+                                 QuicPacketNumber missing) {
+    if (missing == QuicPacketNumber(1)) {
       return InitAckFrame({{missing + 1, largest_acked + 1}});
     }
-    return InitAckFrame({{1, missing}, {missing + 1, largest_acked + 1}});
+    return InitAckFrame(
+        {{QuicPacketNumber(1), missing}, {missing + 1, largest_acked + 1}});
   }
 
   // Undo nacking a packet within the frame.
@@ -1230,7 +1255,7 @@
     // Call ProcessDataPacket rather than ProcessPacket, as we should not get a
     // packet call to the visitor.
     if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
-      ProcessDataPacket(kMaxRandomInitialPacketNumber + 6000);
+      ProcessDataPacket(MaxRandomInitialPacketNumber() + 6000);
     } else {
       ProcessDataPacket(6000);
     }
@@ -1275,8 +1300,8 @@
       const QuicPacketCount packets_between_probes_base) {
     QuicConnectionPeer::SetPacketsBetweenMtuProbes(&connection_,
                                                    packets_between_probes_base);
-    QuicConnectionPeer::SetNextMtuProbeAt(&connection_,
-                                          packets_between_probes_base);
+    QuicConnectionPeer::SetNextMtuProbeAt(
+        &connection_, QuicPacketNumber(packets_between_probes_base));
   }
 
   bool IsDefaultTestConfiguration() {
@@ -1942,7 +1967,7 @@
   QuicPacketHeader header;
   header.destination_connection_id = connection_id_;
   header.version_flag = true;
-  header.packet_number = 1;
+  header.packet_number = QuicPacketNumber(1);
 
   QuicFrames frames;
   QuicPaddingFrame padding;
@@ -1951,7 +1976,7 @@
   std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
   char buffer[kMaxPacketSize];
   size_t encrypted_length = peer_framer_.EncryptPayload(
-      ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize);
+      ENCRYPTION_NONE, QuicPacketNumber(12), *packet, buffer, kMaxPacketSize);
   EXPECT_EQ(kMaxPacketSize, encrypted_length);
 
   framer_.set_version(version());
@@ -1975,7 +2000,7 @@
   QuicPacketHeader header;
   header.destination_connection_id = connection_id_;
   header.version_flag = true;
-  header.packet_number = 1;
+  header.packet_number = QuicPacketNumber(1);
 
   QuicFrames frames;
   QuicPaddingFrame padding;
@@ -1984,7 +2009,7 @@
   std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
   char buffer[kMaxPacketSize];
   size_t encrypted_length = peer_framer_.EncryptPayload(
-      ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize);
+      ENCRYPTION_NONE, QuicPacketNumber(12), *packet, buffer, kMaxPacketSize);
   EXPECT_EQ(kMaxPacketSize, encrypted_length);
 
   framer_.set_version(version());
@@ -2024,15 +2049,15 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   ProcessPacket(1);
-  EXPECT_EQ(1u, LargestAcked(*outgoing_ack()));
+  EXPECT_EQ(QuicPacketNumber(1u), LargestAcked(*outgoing_ack()));
   EXPECT_EQ(1u, outgoing_ack()->packets.NumIntervals());
 
   ProcessPacket(2);
-  EXPECT_EQ(2u, LargestAcked(*outgoing_ack()));
+  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(*outgoing_ack()));
   EXPECT_EQ(1u, outgoing_ack()->packets.NumIntervals());
 
   ProcessPacket(3);
-  EXPECT_EQ(3u, LargestAcked(*outgoing_ack()));
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(*outgoing_ack()));
   EXPECT_EQ(1u, outgoing_ack()->packets.NumIntervals());
 }
 
@@ -2040,17 +2065,17 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   ProcessPacket(3);
-  EXPECT_EQ(3u, LargestAcked(*outgoing_ack()));
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(*outgoing_ack()));
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
   ProcessPacket(2);
-  EXPECT_EQ(3u, LargestAcked(*outgoing_ack()));
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(*outgoing_ack()));
   EXPECT_FALSE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
   ProcessPacket(1);
-  EXPECT_EQ(3u, LargestAcked(*outgoing_ack()));
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(*outgoing_ack()));
   EXPECT_FALSE(IsMissing(2));
   EXPECT_FALSE(IsMissing(1));
 }
@@ -2059,14 +2084,14 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   ProcessPacket(3);
-  EXPECT_EQ(3u, LargestAcked(*outgoing_ack()));
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(*outgoing_ack()));
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
   // Send packet 3 again, but do not set the expectation that
   // the visitor OnStreamFrame() will be called.
   ProcessDataPacket(3);
-  EXPECT_EQ(3u, LargestAcked(*outgoing_ack()));
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(*outgoing_ack()));
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 }
@@ -2075,16 +2100,16 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
 
   ProcessPacket(3);
-  EXPECT_EQ(3u, LargestAcked(*outgoing_ack()));
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(*outgoing_ack()));
   EXPECT_TRUE(IsMissing(2));
   EXPECT_TRUE(IsMissing(1));
 
   ProcessPacket(2);
-  EXPECT_EQ(3u, LargestAcked(*outgoing_ack()));
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(*outgoing_ack()));
   EXPECT_TRUE(IsMissing(1));
 
   ProcessPacket(5);
-  EXPECT_EQ(5u, LargestAcked(*outgoing_ack()));
+  EXPECT_EQ(QuicPacketNumber(5u), LargestAcked(*outgoing_ack()));
   EXPECT_TRUE(IsMissing(1));
   EXPECT_TRUE(IsMissing(4));
 
@@ -2108,7 +2133,7 @@
   // Call ProcessDataPacket rather than ProcessPacket, as we should not get a
   // packet call to the visitor.
   if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
-    ProcessDataPacket(kMaxRandomInitialPacketNumber + 6000);
+    ProcessDataPacket(MaxRandomInitialPacketNumber() + 6000);
   } else {
     ProcessDataPacket(6000);
   }
@@ -2458,36 +2483,36 @@
 TEST_P(QuicConnectionTest, BasicSending) {
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
-  ProcessDataPacket(QuicPacketNumber(1));
-  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, QuicPacketNumber(2));
+  ProcessDataPacket(1);
+  QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
   QuicPacketNumber last_packet;
   SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);  // Packet 1
-  EXPECT_EQ(1u, last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
   SendAckPacketToPeer();  // Packet 2
 
   if (GetParam().no_stop_waiting) {
     // Expect no stop waiting frame is sent.
-    EXPECT_EQ(0u, least_unacked());
+    EXPECT_FALSE(least_unacked().IsInitialized());
   } else {
-    EXPECT_EQ(1u, least_unacked());
+    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
   }
 
   SendAckPacketToPeer();  // Packet 3
   if (GetParam().no_stop_waiting) {
     // Expect no stop waiting frame is sent.
-    EXPECT_EQ(0u, least_unacked());
+    EXPECT_FALSE(least_unacked().IsInitialized());
   } else {
-    EXPECT_EQ(1u, least_unacked());
+    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
   }
 
   SendStreamDataToPeer(1, "bar", 3, NO_FIN, &last_packet);  // Packet 4
-  EXPECT_EQ(4u, last_packet);
+  EXPECT_EQ(QuicPacketNumber(4u), last_packet);
   SendAckPacketToPeer();  // Packet 5
   if (GetParam().no_stop_waiting) {
     // Expect no stop waiting frame is sent.
-    EXPECT_EQ(0u, least_unacked());
+    EXPECT_FALSE(least_unacked().IsInitialized());
   } else {
-    EXPECT_EQ(1u, least_unacked());
+    EXPECT_EQ(QuicPacketNumber(1u), least_unacked());
   }
 
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
@@ -2501,9 +2526,9 @@
   // ack for 4.
   if (GetParam().no_stop_waiting) {
     // Expect no stop waiting frame is sent.
-    EXPECT_EQ(0u, least_unacked());
+    EXPECT_FALSE(least_unacked().IsInitialized());
   } else {
-    EXPECT_EQ(4u, least_unacked());
+    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
   }
 
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
@@ -2513,34 +2538,34 @@
   ProcessAckPacket(&frame2);  // Acks don't instigate acks.
 
   // Verify that we did not send an ack.
-  EXPECT_EQ(6u, writer_->header().packet_number);
+  EXPECT_EQ(QuicPacketNumber(6u), writer_->header().packet_number);
 
   // So the last ack has not changed.
   if (GetParam().no_stop_waiting) {
     // Expect no stop waiting frame is sent.
-    EXPECT_EQ(0u, least_unacked());
+    EXPECT_FALSE(least_unacked().IsInitialized());
   } else {
-    EXPECT_EQ(4u, least_unacked());
+    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
   }
 
   // If we force an ack, we shouldn't change our retransmit state.
   SendAckPacketToPeer();  // Packet 7
   if (GetParam().no_stop_waiting) {
     // Expect no stop waiting frame is sent.
-    EXPECT_EQ(0u, least_unacked());
+    EXPECT_FALSE(least_unacked().IsInitialized());
   } else {
-    EXPECT_EQ(7u, least_unacked());
+    EXPECT_EQ(QuicPacketNumber(7u), least_unacked());
   }
 
   // But if we send more data it should.
   SendStreamDataToPeer(1, "eep", 6, NO_FIN, &last_packet);  // Packet 8
-  EXPECT_EQ(8u, last_packet);
+  EXPECT_EQ(QuicPacketNumber(8u), last_packet);
   SendAckPacketToPeer();  // Packet 9
   if (GetParam().no_stop_waiting) {
     // Expect no stop waiting frame is sent.
-    EXPECT_EQ(0u, least_unacked());
+    EXPECT_FALSE(least_unacked().IsInitialized());
   } else {
-    EXPECT_EQ(7u, least_unacked());
+    EXPECT_EQ(QuicPacketNumber(7u), least_unacked());
   }
 }
 
@@ -2857,7 +2882,7 @@
   // Lose a packet and ensure it triggers retransmission.
   QuicAckFrame nack_two = ConstructAckFrame(3, 2);
   LostPacketVector lost_packets;
-  lost_packets.push_back(LostPacket(2, kMaxPacketSize));
+  lost_packets.push_back(LostPacket(QuicPacketNumber(2), kMaxPacketSize));
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(SetArgPointee<5>(lost_packets));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
@@ -3106,7 +3131,7 @@
   BlockOnNextWrite();
 
   LostPacketVector lost_packets;
-  lost_packets.push_back(LostPacket(2, kMaxPacketSize));
+  lost_packets.push_back(LostPacket(QuicPacketNumber(2), kMaxPacketSize));
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(SetArgPointee<5>(lost_packets));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
@@ -3121,7 +3146,8 @@
 
   // Unblock the socket and attempt to send the queued packets. We will always
   // send the retransmission.
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 4, _, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(4), _, _))
+      .Times(1);
 
   writer_->SetWritable();
   connection_.OnCanWrite();
@@ -3278,14 +3304,15 @@
   // Process packet number 1. Can not call ProcessPacket or ProcessDataPacket
   // here, because they will fire the alarm after QuicConnection::ProcessPacket
   // is returned.
-  const QuicPacketNumber received_packet_num = 1;
+  const uint64_t received_packet_num = 1;
   const bool has_stop_waiting = false;
   const EncryptionLevel level = ENCRYPTION_NONE;
   std::unique_ptr<QuicPacket> packet(
       ConstructDataPacket(received_packet_num, has_stop_waiting));
   char buffer[kMaxPacketSize];
-  size_t encrypted_length = peer_framer_.EncryptPayload(
-      level, received_packet_num, *packet, buffer, kMaxPacketSize);
+  size_t encrypted_length =
+      peer_framer_.EncryptPayload(level, QuicPacketNumber(received_packet_num),
+                                  *packet, buffer, kMaxPacketSize);
   connection_.ProcessUdpPacket(
       kSelfAddress, kPeerAddress,
       QuicReceivedPacket(buffer, encrypted_length, clock_.Now(), false));
@@ -3355,12 +3382,13 @@
 
   // Ack 15, nack 1-14.
 
-  QuicAckFrame nack = InitAckFrame({{15, 16}});
+  QuicAckFrame nack =
+      InitAckFrame({{QuicPacketNumber(15), QuicPacketNumber(16)}});
 
   // 14 packets have been NACK'd and lost.
   LostPacketVector lost_packets;
   for (int i = 1; i < 15; ++i) {
-    lost_packets.push_back(LostPacket(i, kMaxPacketSize));
+    lost_packets.push_back(LostPacket(QuicPacketNumber(i), kMaxPacketSize));
   }
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(SetArgPointee<5>(lost_packets));
@@ -3381,16 +3409,16 @@
   QuicPacketCreatorPeer::SetPacketNumber(&peer_creator_, 2);
   QuicPacketNumber last_packet;
   SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);  // Packet 1
-  EXPECT_EQ(1u, last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
   SendStreamDataToPeer(3, "foo", 0, NO_FIN, &last_packet);  // Packet 2
-  EXPECT_EQ(2u, last_packet);
+  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
   SendAckPacketToPeer();                                    // Packet 3
   SendStreamDataToPeer(5, "foo", 0, NO_FIN, &last_packet);  // Packet 4
-  EXPECT_EQ(4u, last_packet);
+  EXPECT_EQ(QuicPacketNumber(4u), last_packet);
   SendStreamDataToPeer(1, "foo", 3, NO_FIN, &last_packet);  // Packet 5
-  EXPECT_EQ(5u, last_packet);
+  EXPECT_EQ(QuicPacketNumber(5u), last_packet);
   SendStreamDataToPeer(3, "foo", 3, NO_FIN, &last_packet);  // Packet 6
-  EXPECT_EQ(6u, last_packet);
+  EXPECT_EQ(QuicPacketNumber(6u), last_packet);
 
   // Client will ack packets 1, 2, [!3], 4, 5.
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
@@ -3419,25 +3447,25 @@
   // Verify that our internal state has least-unacked as 2, because we're still
   // waiting for a potential ack for 2.
 
-  EXPECT_EQ(2u, stop_waiting()->least_unacked);
+  EXPECT_EQ(QuicPacketNumber(2u), stop_waiting()->least_unacked);
 
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
   frame = InitAckFrame(2);
   ProcessAckPacket(&frame);
-  EXPECT_EQ(3u, stop_waiting()->least_unacked);
+  EXPECT_EQ(QuicPacketNumber(3u), stop_waiting()->least_unacked);
 
   // When we send an ack, we make sure our least-unacked makes sense.  In this
   // case since we're not waiting on an ack for 2 and all packets are acked, we
   // set it to 3.
   SendAckPacketToPeer();  // Packet 3
   // Least_unacked remains at 3 until another ack is received.
-  EXPECT_EQ(3u, stop_waiting()->least_unacked);
+  EXPECT_EQ(QuicPacketNumber(3u), stop_waiting()->least_unacked);
   if (GetParam().no_stop_waiting) {
     // Expect no stop waiting frame is sent.
-    EXPECT_EQ(0u, least_unacked());
+    EXPECT_FALSE(least_unacked().IsInitialized());
   } else {
     // Check that the outgoing ack had its packet number as least_unacked.
-    EXPECT_EQ(3u, least_unacked());
+    EXPECT_EQ(QuicPacketNumber(3u), least_unacked());
   }
 
   // Ack the ack, which updates the rtt and raises the least unacked.
@@ -3446,13 +3474,13 @@
   ProcessAckPacket(&frame);
 
   SendStreamDataToPeer(1, "bar", 3, NO_FIN, nullptr);  // Packet 4
-  EXPECT_EQ(4u, stop_waiting()->least_unacked);
+  EXPECT_EQ(QuicPacketNumber(4u), stop_waiting()->least_unacked);
   SendAckPacketToPeer();  // Packet 5
   if (GetParam().no_stop_waiting) {
     // Expect no stop waiting frame is sent.
-    EXPECT_EQ(0u, least_unacked());
+    EXPECT_FALSE(least_unacked().IsInitialized());
   } else {
-    EXPECT_EQ(4u, least_unacked());
+    EXPECT_EQ(QuicPacketNumber(4u), least_unacked());
   }
 
   // Send two data packets at the end, and ensure if the last one is acked,
@@ -3461,30 +3489,31 @@
   SendStreamDataToPeer(1, "bar", 9, NO_FIN, nullptr);  // Packet 7
 
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  frame = InitAckFrame({{1, 5}, {7, 8}});
+  frame = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)},
+                        {QuicPacketNumber(7), QuicPacketNumber(8)}});
   ProcessAckPacket(&frame);
 
-  EXPECT_EQ(6u, stop_waiting()->least_unacked);
+  EXPECT_EQ(QuicPacketNumber(6u), stop_waiting()->least_unacked);
 }
 
 TEST_P(QuicConnectionTest, TLP) {
   connection_.SetMaxTailLossProbes(1);
 
   SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
-  EXPECT_EQ(1u, stop_waiting()->least_unacked);
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
   QuicTime retransmission_time =
       connection_.GetRetransmissionAlarm()->deadline();
   EXPECT_NE(QuicTime::Zero(), retransmission_time);
 
-  EXPECT_EQ(1u, writer_->header().packet_number);
+  EXPECT_EQ(QuicPacketNumber(1u), writer_->header().packet_number);
   // Simulate the retransmission alarm firing and sending a tlp,
   // so send algorithm's OnRetransmissionTimeout is not called.
   clock_.AdvanceTime(retransmission_time - clock_.Now());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2u, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _));
   connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(2u, writer_->header().packet_number);
+  EXPECT_EQ(QuicPacketNumber(2u), writer_->header().packet_number);
   // We do not raise the high water mark yet.
-  EXPECT_EQ(1u, stop_waiting()->least_unacked);
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
 }
 
 TEST_P(QuicConnectionTest, RTO) {
@@ -3493,18 +3522,18 @@
   QuicTime default_retransmission_time =
       clock_.ApproximateNow() + DefaultRetransmissionTime();
   SendStreamDataToPeer(3, "foo", 0, NO_FIN, nullptr);
-  EXPECT_EQ(1u, stop_waiting()->least_unacked);
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
 
-  EXPECT_EQ(1u, writer_->header().packet_number);
+  EXPECT_EQ(QuicPacketNumber(1u), writer_->header().packet_number);
   EXPECT_EQ(default_retransmission_time,
             connection_.GetRetransmissionAlarm()->deadline());
   // Simulate the retransmission alarm firing.
   clock_.AdvanceTime(DefaultRetransmissionTime());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2u, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2), _, _));
   connection_.GetRetransmissionAlarm()->Fire();
-  EXPECT_EQ(2u, writer_->header().packet_number);
+  EXPECT_EQ(QuicPacketNumber(2u), writer_->header().packet_number);
   // We do not raise the high water mark yet.
-  EXPECT_EQ(1u, stop_waiting()->least_unacked);
+  EXPECT_EQ(QuicPacketNumber(1u), stop_waiting()->least_unacked);
 }
 
 TEST_P(QuicConnectionTest, RetransmitWithSameEncryptionLevel) {
@@ -3527,8 +3556,10 @@
 
   {
     InSequence s;
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 3, _, _));
-    EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 4, _, _));
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, _, QuicPacketNumber(3), _, _));
+    EXPECT_CALL(*send_algorithm_,
+                OnPacketSent(_, _, QuicPacketNumber(4), _, _));
   }
 
   // Manually mark both packets for retransmission.
@@ -3700,7 +3731,7 @@
 
   // Process an encrypted packet which can not yet be decrypted which should
   // result in the packet being buffered.
-  for (QuicPacketNumber i = 1; i <= 100; ++i) {
+  for (uint64_t i = 1; i <= 100; ++i) {
     ProcessDataPacketAtLevel(i, !kHasStopWaiting, ENCRYPTION_INITIAL);
   }
 
@@ -3842,7 +3873,7 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMicroseconds(20));
   QuicPacketNumber last_packet;
   SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_EQ(1u, last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
   // This will be the updated deadline for the connection to idle time out.
   QuicTime new_ddl = clock_.ApproximateNow() +
                      QuicTime::Delta::FromSeconds(kInitialIdleTimeoutSecs - 1);
@@ -3894,12 +3925,12 @@
   // execution until manually adjusted.
   QuicPacketNumber last_packet;
   SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_EQ(1u, last_packet);
+  EXPECT_EQ(QuicPacketNumber(1u), last_packet);
 
   // Advance the time and send the second packet to the peer.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
   SendStreamDataToPeer(1, "foo", 0, NO_FIN, &last_packet);
-  EXPECT_EQ(2u, last_packet);
+  EXPECT_EQ(QuicPacketNumber(2u), last_packet);
 
   if (GetQuicReloadableFlag(
           quic_fix_time_of_first_packet_sent_after_receiving)) {
@@ -4086,7 +4117,7 @@
       .WillOnce(SaveArg<3>(&mtu_probe_size));
   connection_.SendMtuDiscoveryPacket(new_mtu);
   EXPECT_EQ(new_mtu, mtu_probe_size);
-  EXPECT_EQ(1u, creator_->packet_number());
+  EXPECT_EQ(QuicPacketNumber(1u), creator_->packet_number());
 
   // Send more than MTU worth of data.  No acknowledgement was received so far,
   // so the MTU should be at its old value.
@@ -4097,7 +4128,7 @@
       .WillOnce(SaveArg<3>(&size_before_mtu_change))
       .WillOnce(Return());
   connection_.SendStreamDataWithString(3, data, 0, FIN);
-  EXPECT_EQ(3u, creator_->packet_number());
+  EXPECT_EQ(QuicPacketNumber(3u), creator_->packet_number());
   EXPECT_EQ(kDefaultMaxPacketSize, size_before_mtu_change);
 
   // Acknowledge all packets so far.
@@ -4110,7 +4141,7 @@
   // Send the same data again.  Check that it fits into a single packet now.
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _)).Times(1);
   connection_.SendStreamDataWithString(3, data, 0, FIN);
-  EXPECT_EQ(4u, creator_->packet_number());
+  EXPECT_EQ(QuicPacketNumber(4u), creator_->packet_number());
 }
 
 // Tests whether MTU discovery does not happen when it is not explicitly enabled
@@ -4156,7 +4187,7 @@
   EXPECT_EQ(kMtuDiscoveryTargetPacketSizeHigh, probe_size);
 
   const QuicPacketNumber probe_packet_number =
-      kFirstSendingPacketNumber + packets_between_probes_base;
+      FirstSendingPacketNumber() + packets_between_probes_base;
   ASSERT_EQ(probe_packet_number, creator_->packet_number());
 
   // Acknowledge all packets sent so far.
@@ -4218,12 +4249,13 @@
                                                  mtu_discovery_packets.end());
       QuicPacketNumber max_packet = *max_element(mtu_discovery_packets.begin(),
                                                  mtu_discovery_packets.end());
-      ack.packets.AddRange(1, min_packet);
-      ack.packets.AddRange(max_packet + 1, creator_->packet_number() + 1);
+      ack.packets.AddRange(QuicPacketNumber(1), min_packet);
+      ack.packets.AddRange(QuicPacketNumber(max_packet + 1),
+                           creator_->packet_number() + 1);
       ack.largest_acked = creator_->packet_number();
 
     } else {
-      ack.packets.AddRange(1, creator_->packet_number() + 1);
+      ack.packets.AddRange(QuicPacketNumber(1), creator_->packet_number() + 1);
       ack.largest_acked = creator_->packet_number();
     }
 
@@ -4245,11 +4277,12 @@
   // Ensure the number of packets between probes grows exponentially by checking
   // it against the closed-form expression for the packet number.
   ASSERT_EQ(kMtuDiscoveryAttempts, mtu_discovery_packets.size());
-  for (QuicPacketNumber i = 0; i < kMtuDiscoveryAttempts; i++) {
+  for (uint64_t i = 0; i < kMtuDiscoveryAttempts; i++) {
     // 2^0 + 2^1 + 2^2 + ... + 2^n = 2^(n + 1) - 1
     const QuicPacketCount packets_between_probes =
         packets_between_probes_base * ((1 << (i + 1)) - 1);
-    EXPECT_EQ(packets_between_probes + (i + 1), mtu_discovery_packets[i]);
+    EXPECT_EQ(QuicPacketNumber(packets_between_probes + (i + 1)),
+              mtu_discovery_packets[i]);
   }
 
   EXPECT_FALSE(connection_.GetMtuDiscoveryAlarm()->IsSet());
@@ -4286,7 +4319,7 @@
   EXPECT_EQ(mtu_limit, probe_size);
 
   const QuicPacketNumber probe_sequence_number =
-      kFirstSendingPacketNumber + packets_between_probes_base;
+      FirstSendingPacketNumber() + packets_between_probes_base;
   ASSERT_EQ(probe_sequence_number, creator_->packet_number());
 
   // Acknowledge all packets sent so far.
@@ -4481,7 +4514,7 @@
   const QuicTime final_timeout = rto_time + initial_idle_timeout;
   clock_.AdvanceTime(rto_time - clock_.Now());
   ASSERT_EQ(rto_time, clock_.Now());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2u, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _));
   connection_.GetRetransmissionAlarm()->Fire();
 
   // Advance to the original timeout and fire the alarm. The connection should
@@ -4618,7 +4651,7 @@
   // Retransmit the packet via tail loss probe.
   clock_.AdvanceTime(connection_.GetRetransmissionAlarm()->deadline() -
                      clock_.Now());
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 2u, _, _));
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _));
   connection_.GetRetransmissionAlarm()->Fire();
 
   // This time, we should time out and send a connection close due to the TLP.
@@ -4835,6 +4868,7 @@
   // Test that if we send a packet without delay, it is not queued.
   QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
   std::unique_ptr<QuicPacket> packet = ConstructDataPacket(1, !kHasStopWaiting);
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _));
   connection_.SendPacket(ENCRYPTION_NONE, 1, std::move(packet),
                          HAS_RETRANSMITTABLE_DATA, false, false);
@@ -4847,6 +4881,7 @@
   QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
   EXPECT_CALL(visitor_, OnConnectionClosed(_, _, _)).Times(1);
   std::unique_ptr<QuicPacket> packet = ConstructDataPacket(1, !kHasStopWaiting);
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
   writer_->SetShouldWriteFail();
   connection_.SendPacket(ENCRYPTION_NONE, 1, std::move(packet),
                          HAS_RETRANSMITTABLE_DATA, false, false);
@@ -4855,8 +4890,10 @@
 TEST_P(QuicConnectionTest, SendSchedulerEAGAIN) {
   QuicFramerPeer::SetPerspective(&peer_framer_, Perspective::IS_CLIENT);
   std::unique_ptr<QuicPacket> packet = ConstructDataPacket(1, !kHasStopWaiting);
+  QuicPacketCreatorPeer::SetPacketNumber(creator_, 1);
   BlockOnNextWrite();
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(2u), _, _))
+      .Times(0);
   connection_.SendPacket(ENCRYPTION_NONE, 1, std::move(packet),
                          HAS_RETRANSMITTABLE_DATA, false, false);
   EXPECT_EQ(1u, connection_.NumQueuedPackets());
@@ -5108,7 +5145,7 @@
   frame1_.stream_id = 3;
 
   // Process all the initial packets in order so there aren't missing packets.
-  QuicPacketNumber kFirstDecimatedPacket = 101;
+  uint64_t kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
     ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
@@ -5224,7 +5261,7 @@
   // default delayed ack time.
   ack_time = clock_.ApproximateNow() +
              QuicTime::Delta::FromMilliseconds(kMinRttMs / 4);
-  QuicPacketNumber kFirstDecimatedPacket = 101;
+  uint64_t kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 4; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
     ProcessDataPacketAtLevel(4 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
@@ -5300,7 +5337,7 @@
   frame1_.stream_id = 3;
 
   // Process all the initial packets in order so there aren't missing packets.
-  QuicPacketNumber kFirstDecimatedPacket = 101;
+  uint64_t kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
     ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
@@ -5353,7 +5390,7 @@
   frame1_.stream_id = 3;
 
   // Process all the initial packets in order so there aren't missing packets.
-  QuicPacketNumber kFirstDecimatedPacket = 101;
+  uint64_t kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
     ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
@@ -5416,7 +5453,7 @@
   frame1_.stream_id = 3;
 
   // Process all the initial packets in order so there aren't missing packets.
-  QuicPacketNumber kFirstDecimatedPacket = 101;
+  uint64_t kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
     ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
@@ -5485,7 +5522,7 @@
   frame1_.stream_id = 3;
 
   // Process all the initial packets in order so there aren't missing packets.
-  QuicPacketNumber kFirstDecimatedPacket = 101;
+  uint64_t kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
     ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
@@ -5574,7 +5611,7 @@
   frame1_.stream_id = 3;
 
   // Process all the initial packets in order so there aren't missing packets.
-  QuicPacketNumber kFirstDecimatedPacket = 101;
+  uint64_t kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
     ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
@@ -5647,7 +5684,7 @@
   frame1_.stream_id = 3;
 
   // Process all the initial packets in order so there aren't missing packets.
-  QuicPacketNumber kFirstDecimatedPacket = 101;
+  uint64_t kFirstDecimatedPacket = 101;
   for (unsigned int i = 0; i < kFirstDecimatedPacket - 1; ++i) {
     EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
     ProcessDataPacketAtLevel(1 + i, !kHasStopWaiting, ENCRYPTION_INITIAL);
@@ -5844,7 +5881,7 @@
   EXPECT_EQ(1u, writer_->stream_frames().size());
   EXPECT_EQ(1u, writer_->padding_frames().size());
   ASSERT_FALSE(writer_->ack_frames().empty());
-  EXPECT_EQ(2u, LargestAcked(writer_->ack_frames().front()));
+  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
 
@@ -5873,7 +5910,7 @@
   EXPECT_EQ(1u, writer_->stream_frames().size());
   EXPECT_EQ(1u, writer_->padding_frames().size());
   ASSERT_FALSE(writer_->ack_frames().empty());
-  EXPECT_EQ(2u, LargestAcked(writer_->ack_frames().front()));
+  EXPECT_EQ(QuicPacketNumber(2u), LargestAcked(writer_->ack_frames().front()));
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
 
@@ -5888,7 +5925,7 @@
   // Ack the second packet, which will retransmit the first packet.
   QuicAckFrame ack = ConstructAckFrame(2, 1);
   LostPacketVector lost_packets;
-  lost_packets.push_back(LostPacket(1, kMaxPacketSize));
+  lost_packets.push_back(LostPacket(QuicPacketNumber(1), kMaxPacketSize));
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(SetArgPointee<5>(lost_packets));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
@@ -5927,7 +5964,7 @@
     EXPECT_FALSE(writer_->stop_waiting_frames().empty());
   }
   EXPECT_FALSE(writer_->ack_frames().empty());
-  EXPECT_EQ(3u, LargestAcked(writer_->ack_frames().front()));
+  EXPECT_EQ(QuicPacketNumber(3u), LargestAcked(writer_->ack_frames().front()));
   EXPECT_EQ(1u, writer_->stream_frames().size());
   EXPECT_FALSE(connection_.GetAckAlarm()->IsSet());
 }
@@ -5950,7 +5987,8 @@
   EXPECT_FALSE(connection_.connected());
   EXPECT_FALSE(connection_.CanWriteStreamData());
   std::unique_ptr<QuicPacket> packet = ConstructDataPacket(1, !kHasStopWaiting);
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(0);
   connection_.SendPacket(ENCRYPTION_NONE, 1, std::move(packet),
                          HAS_RETRANSMITTABLE_DATA, false, false);
 }
@@ -5969,7 +6007,8 @@
   EXPECT_FALSE(connection_.connected());
   EXPECT_FALSE(connection_.CanWriteStreamData());
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(0);
 
   EXPECT_QUIC_BUG(connection_.SendConnectivityProbingPacket(
                       writer_.get(), connection_.peer_address()),
@@ -5987,7 +6026,8 @@
   // affects the probing_writer which is not the default.
   EXPECT_CALL(visitor_, OnWriteBlocked()).Times(0);
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(1);
   connection_.SendConnectivityProbingPacket(&probing_writer,
                                             connection_.peer_address());
 }
@@ -6003,7 +6043,8 @@
   // writer to send connectivity probes.
   EXPECT_CALL(visitor_, OnWriteBlocked()).Times(1);
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(1);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(1);
   connection_.SendConnectivityProbingPacket(writer_.get(),
                                             connection_.peer_address());
 }
@@ -6017,7 +6058,8 @@
   // sent.
   EXPECT_CALL(visitor_, OnConnectionClosed(_, _, _)).Times(0);
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(0);
   connection_.SendConnectivityProbingPacket(&probing_writer,
                                             connection_.peer_address());
 }
@@ -6031,7 +6073,8 @@
   // sent.
   EXPECT_CALL(visitor_, OnConnectionClosed(_, _, _)).Times(0);
 
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, 1, _, _)).Times(0);
+  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, QuicPacketNumber(1), _, _))
+      .Times(0);
   connection_.SendConnectivityProbingPacket(writer_.get(),
                                             connection_.peer_address());
 }
@@ -6144,14 +6187,14 @@
   QuicPacketHeader header;
   header.destination_connection_id = connection_id_;
   header.version_flag = true;
-  header.packet_number = 12;
+  header.packet_number = QuicPacketNumber(12);
 
   QuicFrames frames;
   frames.push_back(QuicFrame(frame1_));
   std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
   char buffer[kMaxPacketSize];
-  size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
-                                                   buffer, kMaxPacketSize);
+  size_t encrypted_length = framer_.EncryptPayload(
+      ENCRYPTION_NONE, QuicPacketNumber(12), *packet, buffer, kMaxPacketSize);
 
   framer_.set_version(version());
   // Writer's framer's perspective is client, so that it needs to have the right
@@ -6190,14 +6233,14 @@
   QuicPacketHeader header;
   header.destination_connection_id = connection_id_;
   header.version_flag = true;
-  header.packet_number = 12;
+  header.packet_number = QuicPacketNumber(12);
 
   QuicFrames frames;
   frames.push_back(QuicFrame(frame1_));
   std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
   char buffer[kMaxPacketSize];
-  size_t encrypted_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
-                                                   buffer, kMaxPacketSize);
+  size_t encrypted_length = framer_.EncryptPayload(
+      ENCRYPTION_NONE, QuicPacketNumber(12), *packet, buffer, kMaxPacketSize);
 
   framer_.set_version(version());
   BlockOnNextWrite();
@@ -6243,14 +6286,14 @@
   QuicPacketHeader header;
   header.destination_connection_id = connection_id_;
   header.version_flag = true;
-  header.packet_number = 12;
+  header.packet_number = QuicPacketNumber(12);
 
   QuicFrames frames;
   frames.push_back(QuicFrame(frame1_));
   std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
   char buffer[kMaxPacketSize];
-  size_t encryped_length = framer_.EncryptPayload(ENCRYPTION_NONE, 12, *packet,
-                                                  buffer, kMaxPacketSize);
+  size_t encryped_length = framer_.EncryptPayload(
+      ENCRYPTION_NONE, QuicPacketNumber(12), *packet, buffer, kMaxPacketSize);
 
   framer_.set_version(version());
   set_perspective(Perspective::IS_SERVER);
@@ -6297,14 +6340,14 @@
   QuicPacketHeader header;
   header.destination_connection_id = connection_id_;
   header.destination_connection_id_length = PACKET_0BYTE_CONNECTION_ID;
-  header.packet_number = 12;
+  header.packet_number = QuicPacketNumber(12);
   header.version_flag = false;
   QuicFrames frames;
   frames.push_back(QuicFrame(frame1_));
   std::unique_ptr<QuicPacket> packet(ConstructPacket(header, frames));
   char buffer[kMaxPacketSize];
   size_t encrypted_length = peer_framer_.EncryptPayload(
-      ENCRYPTION_NONE, 12, *packet, buffer, kMaxPacketSize);
+      ENCRYPTION_NONE, QuicPacketNumber(12), *packet, buffer, kMaxPacketSize);
   ASSERT_NE(0u, encrypted_length);
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(1);
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
@@ -6355,11 +6398,13 @@
   connection_.GetRetransmissionAlarm()->Fire();
 
   // Retransmit due to explicit nacks.
-  QuicAckFrame nack_three = InitAckFrame({{2, 3}, {4, 5}});
+  QuicAckFrame nack_three =
+      InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)},
+                    {QuicPacketNumber(4), QuicPacketNumber(5)}});
 
   LostPacketVector lost_packets;
-  lost_packets.push_back(LostPacket(1, kMaxPacketSize));
-  lost_packets.push_back(LostPacket(3, kMaxPacketSize));
+  lost_packets.push_back(LostPacket(QuicPacketNumber(1), kMaxPacketSize));
+  lost_packets.push_back(LostPacket(QuicPacketNumber(3), kMaxPacketSize));
   EXPECT_CALL(*loss_algorithm_, DetectLosses(_, _, _, _, _, _))
       .WillOnce(SetArgPointee<5>(lost_packets));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
@@ -6395,7 +6440,7 @@
   if (peer_framer_.transport_version() > QUIC_VERSION_43) {
     header.destination_connection_id_length = PACKET_0BYTE_CONNECTION_ID;
   }
-  header.packet_number = 1;
+  header.packet_number = QuicPacketNumber(1);
   header.version_flag = false;
 
   QuicConnectionCloseFrame qccf;
@@ -6408,7 +6453,7 @@
   EXPECT_TRUE(nullptr != packet);
   char buffer[kMaxPacketSize];
   size_t encrypted_length = peer_framer_.EncryptPayload(
-      ENCRYPTION_NONE, 1, *packet, buffer, kMaxPacketSize);
+      ENCRYPTION_NONE, QuicPacketNumber(1), *packet, buffer, kMaxPacketSize);
 
   EXPECT_CALL(visitor_, OnConnectionClosed(QUIC_PEER_GOING_AWAY, _,
                                            ConnectionCloseSource::FROM_PEER));
@@ -6490,7 +6535,7 @@
 
 TEST_P(QuicConnectionTest, OnPacketHeaderDebugVisitor) {
   QuicPacketHeader header;
-  header.packet_number = 1;
+  header.packet_number = QuicPacketNumber(1);
   if (GetParam().version.transport_version > QUIC_VERSION_43) {
     header.form = IETF_QUIC_LONG_HEADER_PACKET;
   }
@@ -6730,7 +6775,8 @@
       EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
     }
     EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-    QuicAckFrame frame = InitAckFrame({{1u + 2u * i, 2u + 2u * i}});
+    QuicAckFrame frame = InitAckFrame(
+        {{QuicPacketNumber(1u + 2u * i), QuicPacketNumber(2u + 2u * i)}});
     ProcessAckPacket(&frame);
     EXPECT_TRUE(connection_.GetPathDegradingAlarm()->IsSet());
     // Check the deadline of the path degrading alarm.
@@ -6745,7 +6791,7 @@
       // degrading alarm.
       clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
       EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-      frame = InitAckFrame({{2, 3}});
+      frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
       ProcessAckPacket(&frame);
       EXPECT_FALSE(connection_.GetPathDegradingAlarm()->IsSet());
     } else {
@@ -6800,7 +6846,8 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame = InitAckFrame({{1, 2}});
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(&frame);
   // No more retransmittable packets on the wire, so the path degrading alarm
   // should be cancelled, and the ping alarm should be set to the
@@ -6863,7 +6910,8 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame = InitAckFrame({{1u, 2u}});
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPathDegradingAlarm()->IsSet());
   // Check the deadline of the path degrading alarm.
@@ -6928,7 +6976,8 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame = InitAckFrame({{1u, 2u}});
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPathDegradingAlarm()->IsSet());
   // Check the deadline of the path degrading alarm.
@@ -6958,7 +7007,7 @@
   // degrading. And will set a timer to detect new path degrading.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  frame = InitAckFrame({{2, 3}});
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
   ProcessAckPacket(&frame);
   EXPECT_FALSE(connection_.IsPathDegrading());
   EXPECT_TRUE(connection_.GetPathDegradingAlarm()->IsSet());
@@ -6981,7 +7030,8 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame = InitAckFrame({{1u, 2u}});
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1u), QuicPacketNumber(2u)}});
   ProcessAckPacket(&frame);
   EXPECT_FALSE(connection_.IsPathDegrading());
   EXPECT_FALSE(connection_.GetPathDegradingAlarm()->IsSet());
@@ -7316,7 +7366,8 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame = InitAckFrame({{1, 2}});
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.sent_packet_manager().HasInFlightPackets());
   // The ping alarm is set for the ping timeout, not the shorter
@@ -7333,7 +7384,7 @@
   // the wire.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  frame = InitAckFrame({{2, 3}});
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
   EXPECT_EQ(clock_.ApproximateNow() + retransmittable_on_wire_timeout,
@@ -7343,7 +7394,7 @@
   // the ping alarm.
   QuicTime prev_deadline = connection_.GetPingAlarm()->deadline();
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  frame = InitAckFrame({{2, 3}});
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
   EXPECT_EQ(prev_deadline, connection_.GetPingAlarm()->deadline());
@@ -7400,7 +7451,8 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  QuicAckFrame frame = InitAckFrame({{1, 2}});
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
   EXPECT_EQ(clock_.ApproximateNow() + retransmittable_on_wire_timeout,
@@ -7418,7 +7470,7 @@
   // the wire.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
-  frame = InitAckFrame({{2, 3}});
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
   ProcessAckPacket(&frame);
   EXPECT_TRUE(connection_.GetPingAlarm()->IsSet());
   EXPECT_EQ(clock_.ApproximateNow() + retransmittable_on_wire_timeout,
@@ -7458,13 +7510,14 @@
   EXPECT_CALL(visitor_, OnSuccessfulVersionNegotiation(_));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
   EXPECT_CALL(visitor_, OnForwardProgressConfirmed());
-  QuicAckFrame frame = InitAckFrame({{1, 2}});
+  QuicAckFrame frame =
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(&frame);
 
   // Ack packet 1 again. largest_acked remains at 1, so
   // OnForwardProgressConfirmed() should not be called.
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
-  frame = InitAckFrame({{1, 2}});
+  frame = InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(2)}});
   ProcessAckPacket(&frame);
 
   // Ack packet 2. This increases the largest_acked to 2, so
@@ -7472,7 +7525,7 @@
   clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(5));
   EXPECT_CALL(*send_algorithm_, OnCongestionEvent(true, _, _, _, _));
   EXPECT_CALL(visitor_, OnForwardProgressConfirmed());
-  frame = InitAckFrame({{2, 3}});
+  frame = InitAckFrame({{QuicPacketNumber(2), QuicPacketNumber(3)}});
   ProcessAckPacket(&frame);
 }
 
@@ -7661,7 +7714,7 @@
   std::unique_ptr<QuicPacket> packet(ConstructDataPacket(2, !kHasStopWaiting));
   char buffer[kMaxPacketSize];
   size_t encrypted_length = peer_framer_.EncryptPayload(
-      ENCRYPTION_NONE, 2, *packet, buffer, kMaxPacketSize);
+      ENCRYPTION_NONE, QuicPacketNumber(2), *packet, buffer, kMaxPacketSize);
   // Make sure no stream frame is processed.
   EXPECT_CALL(visitor_, OnStreamFrame(_)).Times(0);
   connection_.ProcessUdpPacket(
diff --git a/net/third_party/quic/core/quic_constants.cc b/net/third_party/quic/core/quic_constants.cc
index 807b1e8..1a755ba 100644
--- a/net/third_party/quic/core/quic_constants.cc
+++ b/net/third_party/quic/core/quic_constants.cc
@@ -11,4 +11,15 @@
 const char* const kEPIDGoogleFrontEnd = "GFE";
 const char* const kEPIDGoogleFrontEnd0 = "GFE0";
 
+QuicPacketNumber MaxRandomInitialPacketNumber() {
+  static const QuicPacketNumber kMaxRandomInitialPacketNumber =
+      QuicPacketNumber(0x7fffffff);
+  return kMaxRandomInitialPacketNumber;
+}
+
+QuicPacketNumber FirstSendingPacketNumber() {
+  static const QuicPacketNumber kFirstSendingPacketNumber = QuicPacketNumber(1);
+  return kFirstSendingPacketNumber;
+}
+
 }  // namespace quic
diff --git a/net/third_party/quic/core/quic_constants.h b/net/third_party/quic/core/quic_constants.h
index e4b7d63..f17b6d2 100644
--- a/net/third_party/quic/core/quic_constants.h
+++ b/net/third_party/quic/core/quic_constants.h
@@ -193,7 +193,7 @@
 
 // For When using Random Initial Packet Numbers, they can start
 // anyplace in the range 1...((2^31)-1) or 0x7fffffff
-const QuicPacketNumber kMaxRandomInitialPacketNumber = 0x7fffffff;
+QUIC_EXPORT_PRIVATE QuicPacketNumber MaxRandomInitialPacketNumber();
 
 // Used to represent an invalid or no control frame id.
 const QuicControlFrameId kInvalidControlFrameId = 0;
@@ -227,10 +227,7 @@
 // Packet number of first sending packet of a connection. Please note, this
 // cannot be used as first received packet because peer can choose its starting
 // packet number.
-const QuicPacketNumber kFirstSendingPacketNumber = 1;
-
-// Used to represent an invalid packet number.
-const QuicPacketNumber kInvalidPacketNumber = 0;
+QUIC_EXPORT_PRIVATE QuicPacketNumber FirstSendingPacketNumber();
 
 // Used by clients to tell if a public reset is sent from a Google frontend.
 QUIC_EXPORT_PRIVATE extern const char* const kEPIDGoogleFrontEnd;
diff --git a/net/third_party/quic/core/quic_dispatcher.cc b/net/third_party/quic/core/quic_dispatcher.cc
index 0ce7869..96b5aaf 100644
--- a/net/third_party/quic/core/quic_dispatcher.cc
+++ b/net/third_party/quic/core/quic_dispatcher.cc
@@ -513,27 +513,29 @@
   }
 
   // initial packet number of 0 is always invalid.
-  if (header.packet_number == kInvalidPacketNumber) {
+  if (!header.packet_number.IsInitialized()) {
     return kFateTimeWait;
   }
   if (GetQuicRestartFlag(quic_enable_accept_random_ipn)) {
     QUIC_RESTART_FLAG_COUNT_N(quic_enable_accept_random_ipn, 1, 2);
     // Accepting Initial Packet Numbers in 1...((2^31)-1) range... check
     // maximum accordingly.
-    if (header.packet_number > kMaxRandomInitialPacketNumber) {
+    if (header.packet_number > MaxRandomInitialPacketNumber()) {
       return kFateTimeWait;
     }
   } else {
     // Count those that would have been accepted if FLAGS..random_ipn
     // were true -- to detect/diagnose potential issues prior to
     // enabling the flag.
-    if ((header.packet_number > kMaxReasonableInitialPacketNumber) &&
-        (header.packet_number <= kMaxRandomInitialPacketNumber)) {
+    if ((header.packet_number >
+         QuicPacketNumber(kMaxReasonableInitialPacketNumber)) &&
+        (header.packet_number <= MaxRandomInitialPacketNumber())) {
       QUIC_CODE_COUNT_N(had_possibly_random_ipn, 1, 2);
     }
     // Check that the sequence number is within the range that the client is
     // expected to send before receiving a response from the server.
-    if (header.packet_number > kMaxReasonableInitialPacketNumber) {
+    if (header.packet_number >
+        QuicPacketNumber(kMaxReasonableInitialPacketNumber)) {
       return kFateTimeWait;
     }
   }
diff --git a/net/third_party/quic/core/quic_dispatcher.h b/net/third_party/quic/core/quic_dispatcher.h
index bd80f62..56bbd5f 100644
--- a/net/third_party/quic/core/quic_dispatcher.h
+++ b/net/third_party/quic/core/quic_dispatcher.h
@@ -110,7 +110,7 @@
   // send a handshake and then up to 50 or so data packets, and then it may
   // resend the handshake packet up to 10 times.  (Retransmitted packets are
   // sent with unique packet numbers.)
-  static const QuicPacketNumber kMaxReasonableInitialPacketNumber = 100;
+  static const uint64_t kMaxReasonableInitialPacketNumber = 100;
   static_assert(kMaxReasonableInitialPacketNumber >=
                     kInitialCongestionWindow + 10,
                 "kMaxReasonableInitialPacketNumber is unreasonably small "
diff --git a/net/third_party/quic/core/quic_dispatcher_test.cc b/net/third_party/quic/core/quic_dispatcher_test.cc
index 8f6aa01..c79f6c1 100644
--- a/net/third_party/quic/core/quic_dispatcher_test.cc
+++ b/net/third_party/quic/core/quic_dispatcher_test.cc
@@ -676,7 +676,7 @@
   SetQuicRestartFlag(quic_enable_accept_random_ipn, true);
   ProcessPacket(client_address, connection_id, true, SerializeCHLO(),
                 PACKET_8BYTE_CONNECTION_ID, PACKET_4BYTE_PACKET_NUMBER,
-                kMaxRandomInitialPacketNumber +
+                MaxRandomInitialPacketNumber().ToUint64() +
                     QuicDispatcher::kMaxReasonableInitialPacketNumber + 1);
 }
 
@@ -1956,7 +1956,7 @@
 
   // Process another |kDefaultMaxUndecryptablePackets| + 1 data packets. The
   // last one should be dropped.
-  for (QuicPacketNumber packet_number = 2;
+  for (uint64_t packet_number = 2;
        packet_number <= kDefaultMaxUndecryptablePackets + 2; ++packet_number) {
     ProcessPacket(client_addr_, last_connection_id, true, "data packet");
   }
diff --git a/net/third_party/quic/core/quic_framer.cc b/net/third_party/quic/core/quic_framer.cc
index 6304730c..eb90e2d 100644
--- a/net/third_party/quic/core/quic_framer.cc
+++ b/net/third_party/quic/core/quic_framer.cc
@@ -142,6 +142,14 @@
   return (Delta(target, a) < Delta(target, b)) ? a : b;
 }
 
+uint64_t PacketNumberIntervalLength(
+    const QuicInterval<QuicPacketNumber>& interval) {
+  if (interval.Empty()) {
+    return 0u;
+  }
+  return interval.max() - interval.min();
+}
+
 QuicPacketNumberLength ReadSequenceNumberLength(uint8_t flags) {
   switch (flags & PACKET_FLAGS_8BYTE_PACKET) {
     case PACKET_FLAGS_8BYTE_PACKET:
@@ -322,6 +330,12 @@
   return static_cast<uint8_t>(length - kConnectionIdLengthAdjustment);
 }
 
+bool IsValidPacketNumberLength(QuicPacketNumberLength packet_number_length) {
+  size_t length = packet_number_length;
+  return length == 1 || length == 2 || length == 4 || length == 6 ||
+         length == 8;
+}
+
 }  // namespace
 
 QuicFramer::QuicFramer(const ParsedQuicVersionVector& supported_versions,
@@ -329,7 +343,6 @@
                        Perspective perspective)
     : visitor_(nullptr),
       error_(QUIC_NO_ERROR),
-      largest_packet_number_(kInvalidPacketNumber),
       last_serialized_connection_id_(EmptyQuicConnectionId()),
       last_version_label_(0),
       last_header_form_(GOOGLE_QUIC_PACKET),
@@ -1255,7 +1268,7 @@
   } else {
     // Append an random packet number.
     QuicPacketNumber random_packet_number =
-        QuicRandom::GetInstance()->RandUint64() % 255 + 1;
+        QuicPacketNumber(QuicRandom::GetInstance()->RandUint64() % 255 + 1);
     if (!AppendPacketNumber(PACKET_1BYTE_PACKET_NUMBER, random_packet_number,
                             &writer)) {
       return nullptr;
@@ -1477,7 +1490,7 @@
       return RaiseError(QUIC_INVALID_PACKET_HEADER);
     }
 
-    if (full_packet_number == kInvalidPacketNumber) {
+    if (full_packet_number == 0u) {
       if (IsIetfStatelessResetPacket(*header)) {
         // This is a stateless reset packet.
         QuicIetfStatelessResetPacket packet(
@@ -1488,7 +1501,7 @@
       set_detailed_error("packet numbers cannot be 0.");
       return RaiseError(QUIC_INVALID_PACKET_HEADER);
     }
-    header->packet_number = full_packet_number;
+    header->packet_number = QuicPacketNumber(full_packet_number);
   }
 
   // A nonce should only present in SHLO from the server to the client when
@@ -1531,8 +1544,12 @@
 
   // Update the largest packet number after we have decrypted the packet
   // so we are confident is not attacker controlled.
-  largest_packet_number_ =
-      std::max(header->packet_number, largest_packet_number_);
+  if (largest_packet_number_.IsInitialized()) {
+    largest_packet_number_ =
+        std::max(header->packet_number, largest_packet_number_);
+  } else {
+    largest_packet_number_ = header->packet_number;
+  }
 
   if (!visitor_->OnPacketHeader(*header)) {
     // The visitor suppresses further processing of the packet.
@@ -1593,8 +1610,12 @@
 
   // Update the largest packet number after we have decrypted the packet
   // so we are confident is not attacker controlled.
-  largest_packet_number_ =
-      std::max(header->packet_number, largest_packet_number_);
+  if (largest_packet_number_.IsInitialized()) {
+    largest_packet_number_ =
+        std::max(header->packet_number, largest_packet_number_);
+  } else {
+    largest_packet_number_ = header->packet_number;
+  }
 
   if (!visitor_->OnPacketHeader(*header)) {
     // The visitor suppresses further processing of the packet.
@@ -1869,12 +1890,12 @@
   // epoch_delta is the delta between epochs the packet number was serialized
   // with, so the correct value is likely the same epoch as the last sequence
   // number or an adjacent epoch.
-  if (base_packet_number == kInvalidPacketNumber) {
+  if (!base_packet_number.IsInitialized()) {
     return packet_number;
   }
   const uint64_t epoch_delta = UINT64_C(1) << (8 * packet_number_length);
-  uint64_t next_packet_number = base_packet_number + 1;
-  uint64_t epoch = base_packet_number & ~(epoch_delta - 1);
+  uint64_t next_packet_number = base_packet_number.ToUint64() + 1;
+  uint64_t epoch = base_packet_number.ToUint64() & ~(epoch_delta - 1);
   uint64_t prev_epoch = epoch - epoch_delta;
   uint64_t next_epoch = epoch + epoch_delta;
 
@@ -1976,11 +1997,15 @@
 QuicPacketNumberLength QuicFramer::GetMinPacketNumberLength(
     QuicTransportVersion version,
     QuicPacketNumber packet_number) {
-  if (packet_number < 1 << (PACKET_1BYTE_PACKET_NUMBER * 8)) {
+  DCHECK(packet_number.IsInitialized());
+  if (packet_number < QuicPacketNumber(1 << (PACKET_1BYTE_PACKET_NUMBER * 8))) {
     return PACKET_1BYTE_PACKET_NUMBER;
-  } else if (packet_number < 1 << (PACKET_2BYTE_PACKET_NUMBER * 8)) {
+  } else if (packet_number <
+             QuicPacketNumber(1 << (PACKET_2BYTE_PACKET_NUMBER * 8))) {
     return PACKET_2BYTE_PACKET_NUMBER;
-  } else if (packet_number < UINT64_C(1) << (PACKET_4BYTE_PACKET_NUMBER * 8)) {
+  } else if (packet_number <
+             QuicPacketNumber(UINT64_C(1)
+                              << (PACKET_4BYTE_PACKET_NUMBER * 8))) {
     return PACKET_4BYTE_PACKET_NUMBER;
   } else {
     return PACKET_6BYTE_PACKET_NUMBER;
@@ -2018,7 +2043,7 @@
   new_ack_info.first_block_length = frame.packets.LastIntervalLength();
   auto itr = frame.packets.rbegin();
   QuicPacketNumber previous_start = itr->min();
-  new_ack_info.max_block_length = itr->Length();
+  new_ack_info.max_block_length = PacketNumberIntervalLength(*itr);
   ++itr;
 
   // Don't do any more work after getting information for 256 ACK blocks; any
@@ -2031,8 +2056,8 @@
     new_ack_info.num_ack_blocks +=
         (total_gap + std::numeric_limits<uint8_t>::max() - 1) /
         std::numeric_limits<uint8_t>::max();
-    new_ack_info.max_block_length =
-        std::max(new_ack_info.max_block_length, interval.Length());
+    new_ack_info.max_block_length = std::max(
+        new_ack_info.max_block_length, PacketNumberIntervalLength(interval));
   }
   return new_ack_info;
 }
@@ -2048,11 +2073,11 @@
     return RaiseError(QUIC_INVALID_PACKET_HEADER);
   }
 
-  if (full_packet_number == kInvalidPacketNumber) {
+  if (full_packet_number == 0u) {
     set_detailed_error("packet numbers cannot be 0.");
     return RaiseError(QUIC_INVALID_PACKET_HEADER);
   }
-  header->packet_number = full_packet_number;
+  header->packet_number = QuicPacketNumber(full_packet_number);
 
   if (!visitor_->OnUnauthenticatedHeader(*header)) {
     set_detailed_error(
@@ -2907,7 +2932,7 @@
   }
 
   if (!visitor_->OnAckFrameStart(
-          largest_acked,
+          QuicPacketNumber(largest_acked),
           ack_delay_time_us == kUFloat16MaxValue
               ? QuicTime::Delta::Infinite()
               : QuicTime::Delta::FromMicroseconds(ack_delay_time_us))) {
@@ -2958,8 +2983,9 @@
     return false;
   }
 
-  QuicPacketNumber first_received = largest_acked + 1 - first_block_length;
-  if (!visitor_->OnAckRange(first_received, largest_acked + 1)) {
+  uint64_t first_received = largest_acked + 1 - first_block_length;
+  if (!visitor_->OnAckRange(QuicPacketNumber(first_received),
+                            QuicPacketNumber(largest_acked + 1))) {
     // The visitor suppresses further processing of the packet. Although
     // this is not a parsing error, returns false as this is in middle
     // of processing an ack frame,
@@ -2995,8 +3021,9 @@
 
       first_received -= (gap + current_block_length);
       if (current_block_length > 0) {
-        if (!visitor_->OnAckRange(first_received,
-                                  first_received + current_block_length)) {
+        if (!visitor_->OnAckRange(
+                QuicPacketNumber(first_received),
+                QuicPacketNumber(first_received) + current_block_length)) {
           // The visitor suppresses further processing of the packet. Although
           // this is not a parsing error, returns false as this is in middle
           // of processing an ack frame,
@@ -3013,13 +3040,13 @@
     return false;
   }
 
-  if (!ProcessTimestampsInAckFrame(num_received_packets, largest_acked,
-                                   reader)) {
+  if (!ProcessTimestampsInAckFrame(num_received_packets,
+                                   QuicPacketNumber(largest_acked), reader)) {
     return false;
   }
 
   // Done processing the ACK frame.
-  return visitor_->OnAckFrameEnd(first_received);
+  return visitor_->OnAckFrameEnd(QuicPacketNumber(first_received));
 }
 
 bool QuicFramer::ProcessTimestampsInAckFrame(uint8_t num_received_packets,
@@ -3122,7 +3149,8 @@
     ack_frame->ect_1_count = 0;
     ack_frame->ecn_ce_count = 0;
   }
-  if (!visitor_->OnAckFrameStart(largest_acked, ack_frame->ack_delay_time)) {
+  if (!visitor_->OnAckFrameStart(QuicPacketNumber(largest_acked),
+                                 ack_frame->ack_delay_time)) {
     // The visitor suppresses further processing of the packet. Although this is
     // not a parsing error, returns false as this is in middle of processing an
     // ACK frame.
@@ -3147,8 +3175,8 @@
   }
   // Calculate the packets being acked in the first block.
   //  +1 because AddRange implementation requires [low,high)
-  QuicPacketNumber block_high = largest_acked + 1;
-  QuicPacketNumber block_low = largest_acked - ack_block_value;
+  uint64_t block_high = largest_acked + 1;
+  uint64_t block_low = largest_acked - ack_block_value;
 
   // ack_block_value is the number of packets preceding the
   // largest_acked packet which are in the block being acked. Thus,
@@ -3162,7 +3190,8 @@
     return false;
   }
 
-  if (!visitor_->OnAckRange(block_low, block_high)) {
+  if (!visitor_->OnAckRange(QuicPacketNumber(block_low),
+                            QuicPacketNumber(block_high))) {
     // The visitor suppresses further processing of the packet. Although
     // this is not a parsing error, returns false as this is in middle
     // of processing an ACK frame.
@@ -3215,7 +3244,8 @@
     // Calculate the low end of the new nth ack block. The +1 is
     // because the encoded value is the blocksize-1.
     block_low = block_high - 1 - ack_block_value;
-    if (!visitor_->OnAckRange(block_low, block_high)) {
+    if (!visitor_->OnAckRange(QuicPacketNumber(block_low),
+                              QuicPacketNumber(block_high))) {
       // The visitor suppresses further processing of the packet. Although
       // this is not a parsing error, returns false as this is in middle
       // of processing an ACK frame.
@@ -3227,7 +3257,7 @@
     ack_block_count--;
   }
 
-  return visitor_->OnAckFrameEnd(block_low);
+  return visitor_->OnAckFrameEnd(QuicPacketNumber(block_low));
 }
 
 bool QuicFramer::ProcessStopWaitingFrame(QuicDataReader* reader,
@@ -3239,7 +3269,7 @@
     set_detailed_error("Unable to read least unacked delta.");
     return false;
   }
-  if (header.packet_number < least_unacked_delta) {
+  if (header.packet_number.ToUint64() < least_unacked_delta) {
     set_detailed_error("Invalid unacked delta.");
     return false;
   }
@@ -3458,9 +3488,10 @@
                                   size_t total_len,
                                   size_t buffer_len,
                                   char* buffer) {
+  DCHECK(packet_number.IsInitialized());
   size_t output_length = 0;
   if (!encrypter_[level]->EncryptPacket(
-          version_.transport_version, packet_number,
+          version_.transport_version, packet_number.ToUint64(),
           QuicStringPiece(buffer, ad_len),  // Associated data
           QuicStringPiece(buffer + ad_len, total_len - ad_len),  // Plaintext
           buffer + ad_len,  // Destination buffer
@@ -3477,6 +3508,7 @@
                                   const QuicPacket& packet,
                                   char* buffer,
                                   size_t buffer_len) {
+  DCHECK(packet_number.IsInitialized());
   DCHECK(encrypter_[level] != nullptr);
 
   QuicStringPiece associated_data =
@@ -3488,7 +3520,7 @@
   // Encrypt the plaintext into the buffer.
   size_t output_length = 0;
   if (!encrypter_[level]->EncryptPacket(
-          version_.transport_version, packet_number, associated_data,
+          version_.transport_version, packet_number.ToUint64(), associated_data,
           packet.Plaintext(version_.transport_version), buffer + ad_len,
           &output_length, buffer_len - ad_len)) {
     RaiseError(QUIC_ENCRYPTION_FAILURE);
@@ -3530,8 +3562,9 @@
       header.nonce != nullptr, header.packet_number_length);
 
   bool success = decrypter_->DecryptPacket(
-      version_.transport_version, header.packet_number, associated_data,
-      encrypted, decrypted_buffer, decrypted_length, buffer_length);
+      version_.transport_version, header.packet_number.ToUint64(),
+      associated_data, encrypted, decrypted_buffer, decrypted_length,
+      buffer_length);
   if (success) {
     visitor_->OnDecryptedPacket(decrypter_level_);
   } else if (alternative_decrypter_ != nullptr) {
@@ -3553,8 +3586,9 @@
 
     if (try_alternative_decryption) {
       success = alternative_decrypter_->DecryptPacket(
-          version_.transport_version, header.packet_number, associated_data,
-          encrypted, decrypted_buffer, decrypted_length, buffer_length);
+          version_.transport_version, header.packet_number.ToUint64(),
+          associated_data, encrypted, decrypted_buffer, decrypted_length,
+          buffer_length);
     }
     if (success) {
       visitor_->OnDecryptedPacket(alternative_decrypter_level_);
@@ -3587,7 +3621,7 @@
   // Type byte, largest_acked, and delay_time are straight-forward.
   size_t ack_frame_size = kQuicFrameTypeSize;
   QuicPacketNumber largest_acked = LargestAcked(frame);
-  ack_frame_size += QuicDataWriter::GetVarInt62Len(largest_acked);
+  ack_frame_size += QuicDataWriter::GetVarInt62Len(largest_acked.ToUint64());
   uint64_t ack_delay_time_us;
   ack_delay_time_us = frame.ack_delay_time.ToMicroseconds();
   ack_delay_time_us = ack_delay_time_us >> kIetfAckTimestampShift;
@@ -3684,7 +3718,7 @@
   QuicPacketNumberLength largest_acked_length =
       GetMinPacketNumberLength(version_.transport_version, LargestAcked(ack));
   QuicPacketNumberLength ack_block_length = GetMinPacketNumberLength(
-      version_.transport_version, ack_info.max_block_length);
+      version_.transport_version, QuicPacketNumber(ack_info.max_block_length));
 
   ack_size =
       GetMinAckFrameSize(version_.transport_version, largest_acked_length);
@@ -3914,12 +3948,13 @@
 bool QuicFramer::AppendPacketNumber(QuicPacketNumberLength packet_number_length,
                                     QuicPacketNumber packet_number,
                                     QuicDataWriter* writer) {
-  size_t length = packet_number_length;
-  if (length != 1 && length != 2 && length != 4 && length != 6 && length != 8) {
-    QUIC_BUG << "Invalid packet_number_length: " << length;
+  DCHECK(packet_number.IsInitialized());
+  if (!IsValidPacketNumberLength(packet_number_length)) {
+    QUIC_BUG << "Invalid packet_number_length: " << packet_number_length;
     return false;
   }
-  return writer->WriteBytesToUInt64(packet_number_length, packet_number);
+  return writer->WriteBytesToUInt64(packet_number_length,
+                                    packet_number.ToUint64());
 }
 
 // static
@@ -3950,8 +3985,16 @@
                                 QuicPacketNumberLength length_length,
                                 uint64_t length,
                                 QuicDataWriter* writer) {
+  if (length == 0) {
+    if (!IsValidPacketNumberLength(length_length)) {
+      QUIC_BUG << "Invalid packet_number_length: " << length_length;
+      return false;
+    }
+    return writer->WriteUInt8(gap) &&
+           writer->WriteBytesToUInt64(length_length, length);
+  }
   return writer->WriteUInt8(gap) &&
-         AppendPacketNumber(length_length, length, writer);
+         AppendPacketNumber(length_length, QuicPacketNumber(length), writer);
 }
 
 bool QuicFramer::AppendStreamFrame(const QuicStreamFrame& frame,
@@ -4152,8 +4195,9 @@
   QuicPacketNumber largest_acked = LargestAcked(frame);
   QuicPacketNumberLength largest_acked_length =
       GetMinPacketNumberLength(version_.transport_version, largest_acked);
-  QuicPacketNumberLength ack_block_length = GetMinPacketNumberLength(
-      version_.transport_version, new_ack_info.max_block_length);
+  QuicPacketNumberLength ack_block_length =
+      GetMinPacketNumberLength(version_.transport_version,
+                               QuicPacketNumber(new_ack_info.max_block_length));
   // Calculate available bytes for timestamps and ack blocks.
   int32_t available_timestamp_and_ack_block_bytes =
       writer->capacity() - writer->length() - ack_block_length -
@@ -4212,7 +4256,8 @@
   }
 
   // First ack block length.
-  if (!AppendPacketNumber(ack_block_length, new_ack_info.first_block_length,
+  if (!AppendPacketNumber(ack_block_length,
+                          QuicPacketNumber(new_ack_info.first_block_length),
                           writer)) {
     return false;
   }
@@ -4264,8 +4309,8 @@
           total_gap -
           (num_encoded_gaps - 1) * std::numeric_limits<uint8_t>::max();
       // Append the final ACK block with a non-empty size.
-      if (!AppendAckBlock(last_gap, ack_block_length, interval.Length(),
-                          writer)) {
+      if (!AppendAckBlock(last_gap, ack_block_length,
+                          PacketNumberIntervalLength(interval), writer)) {
         return false;
       }
       ++num_ack_blocks_written;
@@ -4357,11 +4402,11 @@
                                         const QuicStopWaitingFrame& frame,
                                         QuicDataWriter* writer) {
   DCHECK_GE(QUIC_VERSION_43, version_.transport_version);
-  DCHECK(frame.least_unacked != kInvalidPacketNumber &&
+  DCHECK(frame.least_unacked.IsInitialized() &&
          header.packet_number >= frame.least_unacked);
-  const QuicPacketNumber least_unacked_delta =
+  const uint64_t least_unacked_delta =
       header.packet_number - frame.least_unacked;
-  const QuicPacketNumber length_shift = header.packet_number_length * 8;
+  const uint64_t length_shift = header.packet_number_length * 8;
 
   if (least_unacked_delta >> length_shift > 0) {
     QUIC_BUG << "packet_number_length " << header.packet_number_length
@@ -4371,8 +4416,12 @@
              << " version:" << version_.transport_version;
     return false;
   }
-  if (!AppendPacketNumber(header.packet_number_length, least_unacked_delta,
-                          writer)) {
+  if (least_unacked_delta == 0) {
+    return writer->WriteBytesToUInt64(header.packet_number_length,
+                                      least_unacked_delta);
+  }
+  if (!AppendPacketNumber(header.packet_number_length,
+                          QuicPacketNumber(least_unacked_delta), writer)) {
     QUIC_BUG << " seq failed: " << header.packet_number_length;
     return false;
   }
@@ -4439,7 +4488,7 @@
   }
 
   QuicPacketNumber largest_acked = LargestAcked(frame);
-  if (!writer->WriteVarInt62(largest_acked)) {
+  if (!writer->WriteVarInt62(largest_acked.ToUint64())) {
     set_detailed_error("No room for largest-acked in ack frame");
     return false;
   }
@@ -4493,9 +4542,9 @@
   // Case 2 or 3
   auto itr = frame.packets.rbegin();
 
-  QuicPacketNumber ack_block_largest = largest_acked;
+  QuicPacketNumber ack_block_largest(largest_acked);
   QuicPacketNumber ack_block_smallest;
-  if ((itr->max() - 1) == largest_acked) {
+  if ((itr->max() - 1) == QuicPacketNumber(largest_acked)) {
     // If largest_acked + 1 is equal to the Max() of the first Interval
     // in the QuicAckFrame then the first Interval is the first ack block of the
     // frame; remaining Intervals are additional ack blocks.  The QuicAckFrame's
diff --git a/net/third_party/quic/core/quic_framer_test.cc b/net/third_party/quic/core/quic_framer_test.cc
index 43cde29..1bcb821b 100644
--- a/net/third_party/quic/core/quic_framer_test.cc
+++ b/net/third_party/quic/core/quic_framer_test.cc
@@ -51,10 +51,11 @@
   return TestConnectionId(UINT64_C(0xFEDCBA9876543211));
 }
 
-const QuicPacketNumber kPacketNumber = UINT64_C(0x12345678);
-const QuicPacketNumber kSmallLargestObserved = UINT16_C(0x1234);
-const QuicPacketNumber kSmallMissingPacket = UINT16_C(0x1233);
-const QuicPacketNumber kLeastUnacked = UINT64_C(0x012345670);
+const QuicPacketNumber kPacketNumber = QuicPacketNumber(UINT64_C(0x12345678));
+const QuicPacketNumber kSmallLargestObserved =
+    QuicPacketNumber(UINT16_C(0x1234));
+const QuicPacketNumber kSmallMissingPacket = QuicPacketNumber(UINT16_C(0x1233));
+const QuicPacketNumber kLeastUnacked = QuicPacketNumber(UINT64_C(0x012345670));
 const QuicStreamId kStreamId = UINT64_C(0x01020304);
 // Note that the high 4 bits of the stream offset must be less than 0x40
 // in order to ensure that the value can be encoded using VarInt62 encoding.
@@ -65,7 +66,7 @@
 // This is the largest packet number that can be represented in IETF QUIC
 // varint62 format.
 const QuicPacketNumber kLargestIetfLargestObserved =
-    UINT64_C(0x3fffffffffffffff);
+    QuicPacketNumber(UINT64_C(0x3fffffffffffffff));
 // Encodings for the two bits in a VarInt62 that
 // describe the length of the VarInt61. For binary packet
 // formats in this file, the convention is to code the
@@ -90,7 +91,7 @@
                      size_t* output_length,
                      size_t max_output_length) override {
     version_ = version;
-    packet_number_ = packet_number;
+    packet_number_ = QuicPacketNumber(packet_number);
     associated_data_ = QuicString(associated_data);
     plaintext_ = QuicString(plaintext);
     memcpy(output, plaintext.data(), plaintext.length());
@@ -136,7 +137,7 @@
                      size_t* output_length,
                      size_t max_output_length) override {
     version_ = version;
-    packet_number_ = packet_number;
+    packet_number_ = QuicPacketNumber(packet_number);
     associated_data_ = QuicString(associated_data);
     ciphertext_ = QuicString(ciphertext);
     memcpy(output, ciphertext.data(), ciphertext.length());
@@ -631,12 +632,17 @@
 
 TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochStart) {
   // A few quick manual sanity checks.
-  CheckCalculatePacketNumber(UINT64_C(1), UINT64_C(0));
-  CheckCalculatePacketNumber(kEpoch + 1, kMask);
-  CheckCalculatePacketNumber(kEpoch, kMask);
+  CheckCalculatePacketNumber(UINT64_C(1), QuicPacketNumber());
+  CheckCalculatePacketNumber(kEpoch + 1, QuicPacketNumber(kMask));
+  CheckCalculatePacketNumber(kEpoch, QuicPacketNumber(kMask));
+  for (uint64_t j = 0; j < 10; j++) {
+    CheckCalculatePacketNumber(j, QuicPacketNumber());
+    CheckCalculatePacketNumber(kEpoch - 1 - j, QuicPacketNumber());
+  }
 
   // Cases where the last number was close to the start of the range.
-  for (QuicPacketNumber last = 0; last < 10; last++) {
+  for (QuicPacketNumber last = QuicPacketNumber(1); last < QuicPacketNumber(10);
+       last++) {
     // Small numbers should not wrap (even if they're out of order).
     for (uint64_t j = 0; j < 10; j++) {
       CheckCalculatePacketNumber(j, last);
@@ -652,7 +658,7 @@
 TEST_P(QuicFramerTest, CalculatePacketNumberFromWireNearEpochEnd) {
   // Cases where the last number was close to the end of the range
   for (uint64_t i = 0; i < 10; i++) {
-    QuicPacketNumber last = kEpoch - i;
+    QuicPacketNumber last = QuicPacketNumber(kEpoch - i);
 
     // Small numbers should wrap.
     for (uint64_t j = 0; j < 10; j++) {
@@ -673,7 +679,7 @@
   const uint64_t cur_epoch = 2 * kEpoch;
   // Cases where the last number was close to the start of the range
   for (uint64_t i = 0; i < 10; i++) {
-    QuicPacketNumber last = cur_epoch + i;
+    QuicPacketNumber last = QuicPacketNumber(cur_epoch + i);
     // Small number should not wrap (even if they're out of order).
     for (uint64_t j = 0; j < 10; j++) {
       CheckCalculatePacketNumber(cur_epoch + j, last);
@@ -692,7 +698,7 @@
   const uint64_t next_epoch = 3 * kEpoch;
   // Cases where the last number was close to the end of the range
   for (uint64_t i = 0; i < 10; i++) {
-    QuicPacketNumber last = next_epoch - 1 - i;
+    QuicPacketNumber last = QuicPacketNumber(next_epoch - 1 - i);
 
     // Small numbers should wrap.
     for (uint64_t j = 0; j < 10; j++) {
@@ -715,7 +721,7 @@
   for (uint64_t i = 0; i < 10; i++) {
     // Subtract 1, because the expected next packet number is 1 more than the
     // last packet number.
-    QuicPacketNumber last = max_number - i - 1;
+    QuicPacketNumber last = QuicPacketNumber(max_number - i - 1);
 
     // Small numbers should not wrap, because they have nowhere to go.
     for (uint64_t j = 0; j < 10; j++) {
@@ -2639,7 +2645,7 @@
 
   EXPECT_EQ(QUIC_NO_ERROR, framer_.error());
   ASSERT_TRUE(visitor_.header_.get());
-  EXPECT_EQ(0u, visitor_.header_->packet_number);
+  EXPECT_FALSE(visitor_.header_->packet_number.IsInitialized());
 }
 
 TEST_P(QuicFramerTest, AckFrameOneAckBlock) {
@@ -3175,7 +3181,8 @@
   const QuicAckFrame& frame = *visitor_.ack_frames_[0];
   EXPECT_EQ(1u, frame.packets.NumIntervals());
   EXPECT_EQ(kLargestIetfLargestObserved, LargestAcked(frame));
-  EXPECT_EQ(kLargestIetfLargestObserved, frame.packets.NumPacketsSlow());
+  EXPECT_EQ(kLargestIetfLargestObserved.ToUint64(),
+            frame.packets.NumPacketsSlow());
 }
 
 // This test looks for a malformed ack where
@@ -6244,9 +6251,9 @@
 
   // Use kSmallLargestObserved to make this test finished in a short time.
   QuicAckFrame ack_frame =
-      InitAckFrame({{1, 5},
-                    {10, 500},
-                    {900, kSmallMissingPacket},
+      InitAckFrame({{QuicPacketNumber(1), QuicPacketNumber(5)},
+                    {QuicPacketNumber(10), QuicPacketNumber(500)},
+                    {QuicPacketNumber(900), kSmallMissingPacket},
                     {kSmallMissingPacket + 1, kSmallLargestObserved + 1}});
   ack_frame.ack_delay_time = QuicTime::Delta::Zero();
 
@@ -6437,9 +6444,9 @@
   ack_frame.ack_delay_time = QuicTime::Delta::Zero();
   // 300 ack blocks.
   for (size_t i = 2; i < 2 * 300; i += 2) {
-    ack_frame.packets.Add(i);
+    ack_frame.packets.Add(QuicPacketNumber(i));
   }
-  ack_frame.packets.AddRange(600, kSmallLargestObserved + 1);
+  ack_frame.packets.AddRange(QuicPacketNumber(600), kSmallLargestObserved + 1);
 
   QuicFrames frames = {QuicFrame(&ack_frame)};
 
@@ -9110,10 +9117,10 @@
       QuicEncryptedPacket(buffer, encrypted_length, false)));
   ASSERT_EQ(1u, visitor_.ack_frames_.size());
   QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(600u, LargestAcked(processed_ack_frame));
+  EXPECT_EQ(QuicPacketNumber(600u), LargestAcked(processed_ack_frame));
   ASSERT_EQ(256u, processed_ack_frame.packets.NumPacketsSlow());
-  EXPECT_EQ(90u, processed_ack_frame.packets.Min());
-  EXPECT_EQ(600u, processed_ack_frame.packets.Max());
+  EXPECT_EQ(QuicPacketNumber(90u), processed_ack_frame.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(600u), processed_ack_frame.packets.Max());
 }
 
 TEST_P(QuicFramerTest, AckTruncationSmallPacket) {
@@ -9150,10 +9157,10 @@
       QuicEncryptedPacket(buffer, encrypted_length, false)));
   ASSERT_EQ(1u, visitor_.ack_frames_.size());
   QuicAckFrame& processed_ack_frame = *visitor_.ack_frames_[0];
-  EXPECT_EQ(600u, LargestAcked(processed_ack_frame));
+  EXPECT_EQ(QuicPacketNumber(600u), LargestAcked(processed_ack_frame));
   ASSERT_EQ(240u, processed_ack_frame.packets.NumPacketsSlow());
-  EXPECT_EQ(122u, processed_ack_frame.packets.Min());
-  EXPECT_EQ(600u, processed_ack_frame.packets.Max());
+  EXPECT_EQ(QuicPacketNumber(122u), processed_ack_frame.packets.Min());
+  EXPECT_EQ(QuicPacketNumber(600u), processed_ack_frame.packets.Max());
 }
 
 TEST_P(QuicFramerTest, CleanTruncation) {
diff --git a/net/third_party/quic/core/quic_ietf_framer_test.cc b/net/third_party/quic/core/quic_ietf_framer_test.cc
index b92ff40..35ca93d8 100644
--- a/net/third_party/quic/core/quic_ietf_framer_test.cc
+++ b/net/third_party/quic/core/quic_ietf_framer_test.cc
@@ -728,35 +728,187 @@
 // Testing for the IETF ACK framer.
 // clang-format off
 struct ack_frame ack_frame_variants[] = {
-  { 90000, false, 0, 0, 0, {{1000, 2001}}, IETF_ACK },
-  { 0, false, 0, 0, 0, {{1000, 2001}}, IETF_ACK },
-  { 1, false, 0, 0, 0, {{1, 2}, {5, 6}}, IETF_ACK },
-  { 63, false, 0, 0, 0, {{1, 2}, {5, 6}}, IETF_ACK },
-  { 64, false, 0, 0, 0, {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}},
-    IETF_ACK},
-  { 10000, false, 0, 0, 0, {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}},
-    IETF_ACK},
-  { 100000000, false, 0, 0, 0,
-    {{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}, {11, 12}},
-    IETF_ACK},
-  { 0, false, 0, 0, 0, {{1, 65}}, IETF_ACK },
-  { 9223372036854775807, false, 0, 0, 0, {{1, 11}, {74, 138}}, IETF_ACK },
-  // This ack is for packets 60 & 125. There are 64 packets in the gap.
-  // The encoded value is gap_size - 1, or 63. Crosses a VarInt62 encoding
-  // boundary...
-  { 1, false, 0, 0, 0, {{60, 61}, {125, 126}}, IETF_ACK },
-  { 2, false, 0, 0, 0, {{ 1, 65}, {129, 130}}, IETF_ACK },
-  { 3, false, 0, 0, 0, {{ 1, 65}, {129, 195}}, IETF_ACK },
-  { 4, false, 0, 0, 0, {{ 1, 65}, {129, 194}}, IETF_ACK },
-  { 5, false, 0, 0, 0, {{ 1, 65}, {129, 193}}, IETF_ACK },
-  { 6, false, 0, 0, 0, {{ 1, 65}, {129, 192}}, IETF_ACK },
-  // declare some ack_ecn frames to try.
-  { 6, false, 100, 200, 300, {{ 1, 65}, {129, 192}}, IETF_ACK },
-  { 6, true, 100, 200, 300, {{ 1, 65}, {129, 192}}, IETF_ACK_ECN },
-  { 6, true, 100, 0, 0, {{ 1, 65}, {129, 192}}, IETF_ACK_ECN },
-  { 6, true, 0, 200, 0, {{ 1, 65}, {129, 192}}, IETF_ACK_ECN },
-  { 6, true, 0, 0, 300, {{ 1, 65}, {129, 192}}, IETF_ACK_ECN },
-  { 6, true, 0, 0, 0, {{ 1, 65}, {129, 192}}, IETF_ACK },
+    {90000,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1000), QuicPacketNumber(2001)}},
+     IETF_ACK},
+    {0,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1000), QuicPacketNumber(2001)}},
+     IETF_ACK},
+    {1,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(2)},
+      {QuicPacketNumber(5), QuicPacketNumber(6)}},
+     IETF_ACK},
+    {63,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(2)},
+      {QuicPacketNumber(5), QuicPacketNumber(6)}},
+     IETF_ACK},
+    {64,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(2)},
+      {QuicPacketNumber(3), QuicPacketNumber(4)},
+      {QuicPacketNumber(5), QuicPacketNumber(6)},
+      {QuicPacketNumber(7), QuicPacketNumber(8)},
+      {QuicPacketNumber(9), QuicPacketNumber(10)},
+      {QuicPacketNumber(11), QuicPacketNumber(12)}},
+     IETF_ACK},
+    {10000,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(2)},
+      {QuicPacketNumber(3), QuicPacketNumber(4)},
+      {QuicPacketNumber(5), QuicPacketNumber(6)},
+      {QuicPacketNumber(7), QuicPacketNumber(8)},
+      {QuicPacketNumber(9), QuicPacketNumber(10)},
+      {QuicPacketNumber(11), QuicPacketNumber(12)}},
+     IETF_ACK},
+    {100000000,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(2)},
+      {QuicPacketNumber(3), QuicPacketNumber(4)},
+      {QuicPacketNumber(5), QuicPacketNumber(6)},
+      {QuicPacketNumber(7), QuicPacketNumber(8)},
+      {QuicPacketNumber(9), QuicPacketNumber(10)},
+      {QuicPacketNumber(11), QuicPacketNumber(12)}},
+     IETF_ACK},
+    {0,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)}},
+     IETF_ACK},
+    {9223372036854775807,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(11)},
+      {QuicPacketNumber(74), QuicPacketNumber(138)}},
+     IETF_ACK},
+    // This ack is for packets 60 & 125. There are 64 packets in the gap.
+    // The encoded value is gap_size - 1, or 63. Crosses a VarInt62 encoding
+    // boundary...
+    {1,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(60), QuicPacketNumber(61)},
+      {QuicPacketNumber(125), QuicPacketNumber(126)}},
+     IETF_ACK},
+    {2,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)},
+      {QuicPacketNumber(129), QuicPacketNumber(130)}},
+     IETF_ACK},
+    {3,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)},
+      {QuicPacketNumber(129), QuicPacketNumber(195)}},
+     IETF_ACK},
+    {4,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)},
+      {QuicPacketNumber(129), QuicPacketNumber(194)}},
+     IETF_ACK},
+    {5,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)},
+      {QuicPacketNumber(129), QuicPacketNumber(193)}},
+     IETF_ACK},
+    {6,
+     false,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)},
+      {QuicPacketNumber(129), QuicPacketNumber(192)}},
+     IETF_ACK},
+    // declare some ack_ecn frames to try.
+    {6,
+     false,
+     100,
+     200,
+     300,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)},
+      {QuicPacketNumber(129), QuicPacketNumber(192)}},
+     IETF_ACK},
+    {6,
+     true,
+     100,
+     200,
+     300,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)},
+      {QuicPacketNumber(129), QuicPacketNumber(192)}},
+     IETF_ACK_ECN},
+    {6,
+     true,
+     100,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)},
+      {QuicPacketNumber(129), QuicPacketNumber(192)}},
+     IETF_ACK_ECN},
+    {6,
+     true,
+     0,
+     200,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)},
+      {QuicPacketNumber(129), QuicPacketNumber(192)}},
+     IETF_ACK_ECN},
+    {6,
+     true,
+     0,
+     0,
+     300,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)},
+      {QuicPacketNumber(129), QuicPacketNumber(192)}},
+     IETF_ACK_ECN},
+    {6,
+     true,
+     0,
+     0,
+     0,
+     {{QuicPacketNumber(1), QuicPacketNumber(65)},
+      {QuicPacketNumber(129), QuicPacketNumber(192)}},
+     IETF_ACK},
 };
 // clang-format on
 
@@ -782,7 +934,7 @@
                         NETWORK_BYTE_ORDER);
 
   QuicAckFrame transmit_frame;
-  transmit_frame.largest_acked = 1;
+  transmit_frame.largest_acked = QuicPacketNumber(1);
   transmit_frame.ack_delay_time = QuicTime::Delta::FromMicroseconds(0);
 
   size_t expected_size =
diff --git a/net/third_party/quic/core/quic_packet_creator.cc b/net/third_party/quic/core/quic_packet_creator.cc
index 9fa7532..d629bc1 100644
--- a/net/third_party/quic/core/quic_packet_creator.cc
+++ b/net/third_party/quic/core/quic_packet_creator.cc
@@ -52,7 +52,7 @@
       connection_id_length_(PACKET_8BYTE_CONNECTION_ID),
       packet_size_(0),
       connection_id_(connection_id),
-      packet_(kInvalidPacketNumber,
+      packet_(QuicPacketNumber(),
               PACKET_1BYTE_PACKET_NUMBER,
               nullptr,
               0,
@@ -132,7 +132,7 @@
       packet_.packet_number + 1 - least_packet_awaited_by_peer;
   const uint64_t delta = std::max(current_delta, max_packets_in_flight);
   packet_.packet_number_length = QuicFramer::GetMinPacketNumberLength(
-      framer_->transport_version(), delta * 4);
+      framer_->transport_version(), QuicPacketNumber(delta * 4));
 }
 
 bool QuicPacketCreator::ConsumeData(QuicStreamId id,
@@ -342,14 +342,14 @@
   packet_.has_stop_waiting = false;
   packet_.has_crypto_handshake = NOT_HANDSHAKE;
   packet_.num_padding_bytes = 0;
-  packet_.original_packet_number = kInvalidPacketNumber;
+  packet_.original_packet_number.Clear();
   if (!can_set_transmission_type_ || ShouldSetTransmissionTypeForNextFrame()) {
     packet_.transmission_type = NOT_RETRANSMISSION;
   }
   packet_.encrypted_buffer = nullptr;
   packet_.encrypted_length = 0;
   DCHECK(packet_.retransmittable_frames.empty());
-  packet_.largest_acked = kInvalidPacketNumber;
+  packet_.largest_acked.Clear();
   needs_full_padding_ = false;
 }
 
@@ -663,7 +663,7 @@
 
 // TODO(b/74062209): Make this a public method of framer?
 SerializedPacket QuicPacketCreator::NoPacket() {
-  return SerializedPacket(kInvalidPacketNumber, PACKET_1BYTE_PACKET_NUMBER,
+  return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,
                           nullptr, 0, false, false);
 }
 
@@ -707,8 +707,8 @@
   } else {
     header->nonce = nullptr;
   }
-  if (packet_.packet_number == kInvalidPacketNumber) {
-    packet_.packet_number = kFirstSendingPacketNumber;
+  if (!packet_.packet_number.IsInitialized()) {
+    packet_.packet_number = FirstSendingPacketNumber();
   } else {
     ++packet_.packet_number;
   }
diff --git a/net/third_party/quic/core/quic_packet_creator_test.cc b/net/third_party/quic/core/quic_packet_creator_test.cc
index 4694ebf..fb73ce10 100644
--- a/net/third_party/quic/core/quic_packet_creator_test.cc
+++ b/net/third_party/quic/core/quic_packet_creator_test.cc
@@ -227,9 +227,10 @@
       int num_padding_bytes,
       EncryptionLevel encryption_level,
       QuicPacketNumberLength packet_number_length) {
-    return QuicPendingRetransmission(
-        1u, NOT_RETRANSMISSION, retransmittable_frames, has_crypto_handshake,
-        num_padding_bytes, encryption_level, packet_number_length);
+    return QuicPendingRetransmission(QuicPacketNumber(1u), NOT_RETRANSMISSION,
+                                     retransmittable_frames,
+                                     has_crypto_handshake, num_padding_bytes,
+                                     encryption_level, packet_number_length);
   }
 
   bool IsDefaultTestConfiguration() {
@@ -268,8 +269,7 @@
   for (int i = ENCRYPTION_NONE; i < NUM_ENCRYPTION_LEVELS; ++i) {
     EncryptionLevel level = static_cast<EncryptionLevel>(i);
     creator_.set_encryption_level(level);
-    frames_.push_back(
-        QuicFrame(new QuicAckFrame(InitAckFrame(QuicPacketNumber(1)))));
+    frames_.push_back(QuicFrame(new QuicAckFrame(InitAckFrame(1))));
     frames_.push_back(QuicFrame(QuicStreamFrame(
         QuicUtils::GetCryptoStreamId(client_framer_.transport_version()), false,
         0u, QuicStringPiece())));
@@ -513,8 +513,8 @@
   frames.push_back(QuicFrame(&frame));
   SerializedPacket serialized = SerializeAllFrames(frames);
   EXPECT_EQ(ENCRYPTION_NONE, serialized.encryption_level);
-  ASSERT_EQ(1u, serialized.packet_number);
-  ASSERT_EQ(1u, creator_.packet_number());
+  ASSERT_EQ(QuicPacketNumber(1u), serialized.packet_number);
+  ASSERT_EQ(QuicPacketNumber(1u), creator_.packet_number());
 
   InSequence s;
   EXPECT_CALL(framer_visitor_, OnPacket());
@@ -1016,28 +1016,33 @@
   }
 
   QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64);
-  creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
   EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
             QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
 
   QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256);
-  creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
   EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
             QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
 
   QuicPacketCreatorPeer::SetPacketNumber(&creator_, 64 * 256 * 256);
-  creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
   EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
             QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
 
   QuicPacketCreatorPeer::SetPacketNumber(&creator_,
                                          UINT64_C(64) * 256 * 256 * 256 * 256);
-  creator_.UpdatePacketNumberLength(2, 10000 / kDefaultMaxPacketSize);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(2),
+                                    10000 / kDefaultMaxPacketSize);
   EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
             QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
 }
 
 TEST_P(QuicPacketCreatorTest, UpdatePacketSequenceNumberLengthCwnd) {
+  QuicPacketCreatorPeer::SetPacketNumber(&creator_, 1);
   if (GetParam().version.transport_version > QUIC_VERSION_43 &&
       GetParam().version.transport_version != QUIC_VERSION_99) {
     EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
@@ -1048,21 +1053,24 @@
               QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
   }
 
-  creator_.UpdatePacketNumberLength(1, 10000 / kDefaultMaxPacketSize);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
+                                    10000 / kDefaultMaxPacketSize);
   EXPECT_EQ(PACKET_1BYTE_PACKET_NUMBER,
             QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
 
-  creator_.UpdatePacketNumberLength(1, 10000 * 256 / kDefaultMaxPacketSize);
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
+                                    10000 * 256 / kDefaultMaxPacketSize);
   EXPECT_EQ(PACKET_2BYTE_PACKET_NUMBER,
             QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
 
-  creator_.UpdatePacketNumberLength(1,
+  creator_.UpdatePacketNumberLength(QuicPacketNumber(1),
                                     10000 * 256 * 256 / kDefaultMaxPacketSize);
   EXPECT_EQ(PACKET_4BYTE_PACKET_NUMBER,
             QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
 
   creator_.UpdatePacketNumberLength(
-      1, UINT64_C(1000) * 256 * 256 * 256 * 256 / kDefaultMaxPacketSize);
+      QuicPacketNumber(1),
+      UINT64_C(1000) * 256 * 256 * 256 * 256 / kDefaultMaxPacketSize);
   EXPECT_EQ(PACKET_6BYTE_PACKET_NUMBER,
             QuicPacketCreatorPeer::GetPacketNumberLength(&creator_));
 }
@@ -1181,7 +1189,7 @@
   ASSERT_EQ(1u, retransmittable.size());
   EXPECT_EQ(STREAM_FRAME, retransmittable[0].type);
   EXPECT_TRUE(serialized_packet_.has_ack);
-  EXPECT_EQ(10u, serialized_packet_.largest_acked);
+  EXPECT_EQ(QuicPacketNumber(10u), serialized_packet_.largest_acked);
   DeleteSerializedPacket();
 
   EXPECT_FALSE(creator_.HasPendingFrames());
@@ -1466,7 +1474,9 @@
 // failure. While this test is not applicable to versions other than version 99,
 // it should still work. Hence, it is not made version-specific.
 TEST_P(QuicPacketCreatorTest, IetfAckGapErrorRegression) {
-  QuicAckFrame ack_frame = InitAckFrame({{60, 61}, {125, 126}});
+  QuicAckFrame ack_frame =
+      InitAckFrame({{QuicPacketNumber(60), QuicPacketNumber(61)},
+                    {QuicPacketNumber(125), QuicPacketNumber(126)}});
   frames_.push_back(QuicFrame(&ack_frame));
   SerializeAllFrames(frames_);
 }
diff --git a/net/third_party/quic/core/quic_packet_generator_test.cc b/net/third_party/quic/core/quic_packet_generator_test.cc
index ab3b28728..f1d6201 100644
--- a/net/third_party/quic/core/quic_packet_generator_test.cc
+++ b/net/third_party/quic/core/quic_packet_generator_test.cc
@@ -155,7 +155,7 @@
                    &delegate_,
                    &producer_),
         creator_(QuicPacketGeneratorPeer::GetPacketCreator(&generator_)),
-        ack_frame_(InitAckFrame(QuicPacketNumber(1))) {
+        ack_frame_(InitAckFrame(1)) {
     EXPECT_CALL(delegate_, GetPacketBuffer()).WillRepeatedly(Return(nullptr));
     creator_->SetEncrypter(
         ENCRYPTION_FORWARD_SECURE,
diff --git a/net/third_party/quic/core/quic_packet_number.cc b/net/third_party/quic/core/quic_packet_number.cc
new file mode 100644
index 0000000..ea6456b6
--- /dev/null
+++ b/net/third_party/quic/core/quic_packet_number.cc
@@ -0,0 +1,87 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quic/core/quic_packet_number.h"
+
+namespace quic {
+namespace {
+const uint64_t kUninitializedPacketNumber = 0;
+}  // namespace
+
+QuicPacketNumber::QuicPacketNumber()
+    : packet_number_(kUninitializedPacketNumber) {}
+
+QuicPacketNumber::QuicPacketNumber(uint64_t packet_number)
+    : packet_number_(packet_number) {
+  DCHECK_NE(kUninitializedPacketNumber, packet_number)
+      << "Use default constructor for uninitialized packet number";
+}
+
+void QuicPacketNumber::Clear() {
+  packet_number_ = kUninitializedPacketNumber;
+}
+
+uint64_t QuicPacketNumber::Hash() const {
+  DCHECK(IsInitialized());
+  return packet_number_;
+}
+
+uint64_t QuicPacketNumber::ToUint64() const {
+  DCHECK(IsInitialized());
+  return packet_number_;
+}
+
+bool QuicPacketNumber::IsInitialized() const {
+  return packet_number_ != kUninitializedPacketNumber;
+}
+
+QuicPacketNumber& QuicPacketNumber::operator++() {
+  DCHECK(IsInitialized() && ToUint64() < std::numeric_limits<uint64_t>::max());
+  packet_number_++;
+  return *this;
+}
+
+QuicPacketNumber QuicPacketNumber::operator++(int) {
+  DCHECK(IsInitialized() && ToUint64() < std::numeric_limits<uint64_t>::max());
+  QuicPacketNumber previous(*this);
+  packet_number_++;
+  return previous;
+}
+
+QuicPacketNumber& QuicPacketNumber::operator--() {
+  DCHECK(IsInitialized() && ToUint64() > 1);
+  packet_number_--;
+  return *this;
+}
+
+QuicPacketNumber QuicPacketNumber::operator--(int) {
+  DCHECK(IsInitialized() && ToUint64() > 1);
+  QuicPacketNumber previous(*this);
+  packet_number_--;
+  return previous;
+}
+
+QuicPacketNumber& QuicPacketNumber::operator+=(uint64_t delta) {
+  DCHECK(IsInitialized() &&
+         std::numeric_limits<uint64_t>::max() - ToUint64() >= delta);
+  packet_number_ += delta;
+  return *this;
+}
+
+QuicPacketNumber& QuicPacketNumber::operator-=(uint64_t delta) {
+  DCHECK(IsInitialized() && ToUint64() > delta);
+  packet_number_ -= delta;
+  return *this;
+}
+
+std::ostream& operator<<(std::ostream& os, const QuicPacketNumber& p) {
+  if (p.IsInitialized()) {
+    os << p.packet_number_;
+  } else {
+    os << "uninitialized";
+  }
+  return os;
+}
+
+}  // namespace quic
diff --git a/net/third_party/quic/core/quic_packet_number.h b/net/third_party/quic/core/quic_packet_number.h
new file mode 100644
index 0000000..c78ea37
--- /dev/null
+++ b/net/third_party/quic/core/quic_packet_number.h
@@ -0,0 +1,137 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef NET_THIRD_PARTY_QUIC_CORE_QUIC_PACKET_NUMBER_H_
+#define NET_THIRD_PARTY_QUIC_CORE_QUIC_PACKET_NUMBER_H_
+
+#include <limits>
+#include <ostream>
+
+#include "net/third_party/quic/platform/api/quic_export.h"
+#include "net/third_party/quic/platform/api/quic_logging.h"
+#include "net/third_party/quic/platform/api/quic_string.h"
+#include "net/third_party/quic/platform/api/quic_uint128.h"
+
+namespace quic {
+
+// QuicPacketNumber can either initialized or uninitialized. An initialized
+// packet number is simply an ordinal number. A sentinel value is used to
+// represent an uninitialized packet number.
+class QUIC_EXPORT_PRIVATE QuicPacketNumber {
+ public:
+  // Construct an uninitialized packet number.
+  QuicPacketNumber();
+  // Construct a packet number from uint64_t. |packet_number| cannot equal the
+  // sentinel value.
+  explicit QuicPacketNumber(uint64_t packet_number);
+
+  // Packet number becomes uninitialized after calling this function.
+  void Clear();
+
+  // REQUIRES: IsInitialized() == true.
+  uint64_t Hash() const;
+
+  // Converts packet number to uint64_t.
+  // REQUIRES: IsInitialized() == true.
+  uint64_t ToUint64() const;
+
+  // Returns true if packet number is considered initialized.
+  bool IsInitialized() const;
+
+  // REQUIRES: IsInitialized() == true && ToUint64() <
+  // numeric_limits<uint64_t>::max().
+  QuicPacketNumber& operator++();
+  QuicPacketNumber operator++(int);
+  // REQUIRES: IsInitialized() == true && ToUint64() > 1.
+  QuicPacketNumber& operator--();
+  QuicPacketNumber operator--(int);
+
+  // REQUIRES: IsInitialized() == true && numeric_limits<uint64_t>::max() -
+  // ToUint64() >= |delta|.
+  QuicPacketNumber& operator+=(uint64_t delta);
+  // REQUIRES: IsInitialized() == true && ToUint64() > |delta|.
+  QuicPacketNumber& operator-=(uint64_t delta);
+
+  QUIC_EXPORT_PRIVATE friend std::ostream& operator<<(
+      std::ostream& os,
+      const QuicPacketNumber& p);
+
+ private:
+  // All following operators REQUIRE operands.Initialized() == true.
+  friend inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs);
+  friend inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs);
+
+  // REQUIRES: numeric_limits<uint64_t>::max() - lhs.ToUint64() >= |delta|.
+  friend inline QuicPacketNumber operator+(QuicPacketNumber lhs,
+                                           uint64_t delta);
+  // REQUIRES: lhs.ToUint64() > |delta|.
+  friend inline QuicPacketNumber operator-(QuicPacketNumber lhs,
+                                           uint64_t delta);
+  // REQUIRES: lhs >= rhs.
+  friend inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs);
+
+  uint64_t packet_number_;
+};
+
+class QuicPacketNumberHash {
+ public:
+  uint64_t operator()(QuicPacketNumber packet_number) const noexcept {
+    return packet_number.Hash();
+  }
+};
+
+inline bool operator==(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
+  return lhs.packet_number_ == rhs.packet_number_;
+}
+
+inline bool operator!=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
+  return lhs.packet_number_ != rhs.packet_number_;
+}
+
+inline bool operator<(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
+  return lhs.packet_number_ < rhs.packet_number_;
+}
+
+inline bool operator<=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
+  return lhs.packet_number_ <= rhs.packet_number_;
+}
+
+inline bool operator>(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
+  return lhs.packet_number_ > rhs.packet_number_;
+}
+
+inline bool operator>=(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  DCHECK(lhs.IsInitialized() && rhs.IsInitialized()) << lhs << " vs. " << rhs;
+  return lhs.packet_number_ >= rhs.packet_number_;
+}
+
+inline QuicPacketNumber operator+(QuicPacketNumber lhs, uint64_t delta) {
+  DCHECK(lhs.IsInitialized() &&
+         std::numeric_limits<uint64_t>::max() - lhs.ToUint64() >= delta);
+  return QuicPacketNumber(lhs.packet_number_ + delta);
+}
+
+inline QuicPacketNumber operator-(QuicPacketNumber lhs, uint64_t delta) {
+  DCHECK(lhs.IsInitialized() && lhs.ToUint64() > delta);
+  return QuicPacketNumber(lhs.packet_number_ - delta);
+}
+
+inline uint64_t operator-(QuicPacketNumber lhs, QuicPacketNumber rhs) {
+  DCHECK(lhs.IsInitialized() && rhs.IsInitialized() && lhs >= rhs)
+      << lhs << " vs. " << rhs;
+  return lhs.packet_number_ - rhs.packet_number_;
+}
+
+}  // namespace quic
+
+#endif  // NET_THIRD_PARTY_QUIC_CORE_QUIC_PACKET_NUMBER_H_
diff --git a/net/third_party/quic/core/quic_packet_number_test.cc b/net/third_party/quic/core/quic_packet_number_test.cc
new file mode 100644
index 0000000..ded7ba6
--- /dev/null
+++ b/net/third_party/quic/core/quic_packet_number_test.cc
@@ -0,0 +1,49 @@
+// Copyright (c) 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "net/third_party/quic/core/quic_packet_number.h"
+
+#include "net/third_party/quic/platform/api/quic_test.h"
+
+namespace quic {
+
+namespace test {
+
+namespace {
+
+TEST(QuicPacketNumberTest, BasicTest) {
+  QuicPacketNumber num;
+  EXPECT_FALSE(num.IsInitialized());
+
+  QuicPacketNumber num2(10);
+  EXPECT_TRUE(num2.IsInitialized());
+  EXPECT_EQ(10u, num2.ToUint64());
+  EXPECT_EQ(10u, num2.Hash());
+  num2.Clear();
+  EXPECT_FALSE(num2.IsInitialized());
+
+  QuicPacketNumber num3(std::numeric_limits<uint64_t>::max());
+  EXPECT_TRUE(num3.IsInitialized());
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(), num3.ToUint64());
+  EXPECT_EQ(std::numeric_limits<uint64_t>::max(), num3.Hash());
+  num3.Clear();
+  EXPECT_FALSE(num3.IsInitialized());
+}
+
+TEST(QuicPacketNumberTest, Operators) {
+  QuicPacketNumber num(100);
+  EXPECT_EQ(QuicPacketNumber(100), num++);
+  EXPECT_EQ(QuicPacketNumber(101), num);
+  EXPECT_EQ(QuicPacketNumber(101), num--);
+  EXPECT_EQ(QuicPacketNumber(100), num);
+
+  EXPECT_EQ(QuicPacketNumber(101), ++num);
+  EXPECT_EQ(QuicPacketNumber(100), --num);
+}
+
+}  // namespace
+
+}  // namespace test
+
+}  // namespace quic
diff --git a/net/third_party/quic/core/quic_packets.cc b/net/third_party/quic/core/quic_packets.cc
index 0047fd7..34e95e5 100644
--- a/net/third_party/quic/core/quic_packets.cc
+++ b/net/third_party/quic/core/quic_packets.cc
@@ -77,7 +77,6 @@
       version(
           ParsedQuicVersion(PROTOCOL_UNSUPPORTED, QUIC_VERSION_UNSUPPORTED)),
       nonce(nullptr),
-      packet_number(kInvalidPacketNumber),
       form(GOOGLE_QUIC_PACKET),
       long_packet_type(INITIAL),
       possible_stateless_reset_token(0) {}
@@ -294,9 +293,7 @@
       encryption_level(ENCRYPTION_NONE),
       has_ack(has_ack),
       has_stop_waiting(has_stop_waiting),
-      transmission_type(NOT_RETRANSMISSION),
-      original_packet_number(kInvalidPacketNumber),
-      largest_acked(kInvalidPacketNumber) {}
+      transmission_type(NOT_RETRANSMISSION) {}
 
 SerializedPacket::SerializedPacket(const SerializedPacket& other) = default;
 
@@ -327,7 +324,7 @@
   }
   serialized_packet->encrypted_buffer = nullptr;
   serialized_packet->encrypted_length = 0;
-  serialized_packet->largest_acked = kInvalidPacketNumber;
+  serialized_packet->largest_acked.Clear();
 }
 
 char* CopyBuffer(const SerializedPacket& packet) {
diff --git a/net/third_party/quic/core/quic_received_packet_manager.cc b/net/third_party/quic/core/quic_received_packet_manager.cc
index 53f1043..aad7aa9 100644
--- a/net/third_party/quic/core/quic_received_packet_manager.cc
+++ b/net/third_party/quic/core/quic_received_packet_manager.cc
@@ -25,8 +25,7 @@
 }  // namespace
 
 QuicReceivedPacketManager::QuicReceivedPacketManager(QuicConnectionStats* stats)
-    : peer_least_packet_awaiting_ack_(0),
-      ack_frame_updated_(false),
+    : ack_frame_updated_(false),
       max_ack_ranges_(0),
       time_largest_observed_(QuicTime::Zero()),
       save_timestamps_(false),
@@ -44,7 +43,8 @@
   }
   ack_frame_updated_ = true;
 
-  if (LargestAcked(ack_frame_) > packet_number) {
+  if (LargestAcked(ack_frame_).IsInitialized() &&
+      LargestAcked(ack_frame_) > packet_number) {
     // Record how out of order stats.
     ++stats_->packets_reordered;
     stats_->max_sequence_reordering =
@@ -55,7 +55,8 @@
     stats_->max_time_reordering_us =
         std::max(stats_->max_time_reordering_us, reordering_time_us);
   }
-  if (packet_number > LargestAcked(ack_frame_)) {
+  if (!LargestAcked(ack_frame_).IsInitialized() ||
+      packet_number > LargestAcked(ack_frame_)) {
     ack_frame_.largest_acked = packet_number;
     time_largest_observed_ = receipt_time;
   }
@@ -77,7 +78,8 @@
 }
 
 bool QuicReceivedPacketManager::IsMissing(QuicPacketNumber packet_number) {
-  return packet_number < LargestAcked(ack_frame_) &&
+  return LargestAcked(ack_frame_).IsInitialized() &&
+         packet_number < LargestAcked(ack_frame_) &&
          !ack_frame_.packets.Contains(packet_number);
 }
 
@@ -120,9 +122,14 @@
 
 void QuicReceivedPacketManager::DontWaitForPacketsBefore(
     QuicPacketNumber least_unacked) {
+  if (!least_unacked.IsInitialized()) {
+    return;
+  }
   // ValidateAck() should fail if peer_least_packet_awaiting_ack shrinks.
-  DCHECK_LE(peer_least_packet_awaiting_ack_, least_unacked);
-  if (least_unacked > peer_least_packet_awaiting_ack_) {
+  DCHECK(!peer_least_packet_awaiting_ack_.IsInitialized() ||
+         peer_least_packet_awaiting_ack_ <= least_unacked);
+  if (!peer_least_packet_awaiting_ack_.IsInitialized() ||
+      least_unacked > peer_least_packet_awaiting_ack_) {
     peer_least_packet_awaiting_ack_ = least_unacked;
     bool packets_updated = ack_frame_.packets.RemoveUpTo(least_unacked);
     if (packets_updated) {
@@ -132,14 +139,23 @@
     }
   }
   DCHECK(ack_frame_.packets.Empty() ||
+         !peer_least_packet_awaiting_ack_.IsInitialized() ||
          ack_frame_.packets.Min() >= peer_least_packet_awaiting_ack_);
 }
 
 bool QuicReceivedPacketManager::HasMissingPackets() const {
-  return ack_frame_.packets.NumIntervals() > 1 ||
-         (!ack_frame_.packets.Empty() &&
-          ack_frame_.packets.Min() >
-              std::max(QuicPacketNumber(1), peer_least_packet_awaiting_ack_));
+  if (ack_frame_.packets.Empty()) {
+    return false;
+  }
+  if (ack_frame_.packets.NumIntervals() > 1) {
+    return true;
+  }
+  // TODO(fayang): Fix this as this check assumes first sent packet by peer
+  // is 1.
+  return ack_frame_.packets.Min() >
+         (peer_least_packet_awaiting_ack_.IsInitialized()
+              ? peer_least_packet_awaiting_ack_
+              : QuicPacketNumber(1));
 }
 
 bool QuicReceivedPacketManager::HasNewMissingPackets() const {
diff --git a/net/third_party/quic/core/quic_received_packet_manager_test.cc b/net/third_party/quic/core/quic_received_packet_manager_test.cc
index cfa42ff..4440e52 100644
--- a/net/third_party/quic/core/quic_received_packet_manager_test.cc
+++ b/net/third_party/quic/core/quic_received_packet_manager_test.cc
@@ -42,14 +42,13 @@
     received_manager_.set_save_timestamps(true);
   }
 
-  void RecordPacketReceipt(QuicPacketNumber packet_number) {
+  void RecordPacketReceipt(uint64_t packet_number) {
     RecordPacketReceipt(packet_number, QuicTime::Zero());
   }
 
-  void RecordPacketReceipt(QuicPacketNumber packet_number,
-                           QuicTime receipt_time) {
+  void RecordPacketReceipt(uint64_t packet_number, QuicTime receipt_time) {
     QuicPacketHeader header;
-    header.packet_number = packet_number;
+    header.packet_number = QuicPacketNumber(packet_number);
     received_manager_.RecordPacketReceived(header, receipt_time);
   }
 
@@ -63,20 +62,20 @@
 
 TEST_P(QuicReceivedPacketManagerTest, DontWaitForPacketsBefore) {
   QuicPacketHeader header;
-  header.packet_number = 2u;
+  header.packet_number = QuicPacketNumber(2u);
   received_manager_.RecordPacketReceived(header, QuicTime::Zero());
-  header.packet_number = 7u;
+  header.packet_number = QuicPacketNumber(7u);
   received_manager_.RecordPacketReceived(header, QuicTime::Zero());
-  EXPECT_TRUE(received_manager_.IsAwaitingPacket(3u));
-  EXPECT_TRUE(received_manager_.IsAwaitingPacket(6u));
-  received_manager_.DontWaitForPacketsBefore(4);
-  EXPECT_FALSE(received_manager_.IsAwaitingPacket(3u));
-  EXPECT_TRUE(received_manager_.IsAwaitingPacket(6u));
+  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
+  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
+  received_manager_.DontWaitForPacketsBefore(QuicPacketNumber(4));
+  EXPECT_FALSE(received_manager_.IsAwaitingPacket(QuicPacketNumber(3u)));
+  EXPECT_TRUE(received_manager_.IsAwaitingPacket(QuicPacketNumber(6u)));
 }
 
 TEST_P(QuicReceivedPacketManagerTest, GetUpdatedAckFrame) {
   QuicPacketHeader header;
-  header.packet_number = 2u;
+  header.packet_number = QuicPacketNumber(2u);
   QuicTime two_ms = QuicTime::Zero() + QuicTime::Delta::FromMilliseconds(2);
   EXPECT_FALSE(received_manager_.ack_frame_updated());
   received_manager_.RecordPacketReceived(header, two_ms);
@@ -99,11 +98,11 @@
   // And received packet times won't have change.
   EXPECT_EQ(1u, ack.ack_frame->received_packet_times.size());
 
-  header.packet_number = 999u;
+  header.packet_number = QuicPacketNumber(999u);
   received_manager_.RecordPacketReceived(header, two_ms);
-  header.packet_number = 4u;
+  header.packet_number = QuicPacketNumber(4u);
   received_manager_.RecordPacketReceived(header, two_ms);
-  header.packet_number = 1000u;
+  header.packet_number = QuicPacketNumber(1000u);
   received_manager_.RecordPacketReceived(header, two_ms);
   EXPECT_TRUE(received_manager_.ack_frame_updated());
   ack = received_manager_.GetUpdatedAckFrame(two_ms);
@@ -134,11 +133,16 @@
     EXPECT_TRUE(received_manager_.ack_frame_updated());
     received_manager_.GetUpdatedAckFrame(QuicTime::Zero());
     EXPECT_GE(10u, received_manager_.ack_frame().packets.NumIntervals());
-    EXPECT_EQ(1u + 2 * i, received_manager_.ack_frame().packets.Max());
+    EXPECT_EQ(QuicPacketNumber(1u + 2 * i),
+              received_manager_.ack_frame().packets.Max());
     for (int j = 0; j < std::min(10, i + 1); ++j) {
-      EXPECT_TRUE(
-          received_manager_.ack_frame().packets.Contains(1 + (i - j) * 2));
-      EXPECT_FALSE(received_manager_.ack_frame().packets.Contains((i - j) * 2));
+      ASSERT_GE(i, j);
+      EXPECT_TRUE(received_manager_.ack_frame().packets.Contains(
+          QuicPacketNumber(1 + (i - j) * 2)));
+      if (i > j) {
+        EXPECT_FALSE(received_manager_.ack_frame().packets.Contains(
+            QuicPacketNumber((i - j) * 2)));
+      }
     }
   }
 }
diff --git a/net/third_party/quic/core/quic_sent_packet_manager.cc b/net/third_party/quic/core/quic_sent_packet_manager.cc
index e3258685..07420b47 100644
--- a/net/third_party/quic/core/quic_sent_packet_manager.cc
+++ b/net/third_party/quic/core/quic_sent_packet_manager.cc
@@ -86,7 +86,6 @@
       loss_algorithm_(&general_loss_algorithm_),
       general_loss_algorithm_(loss_type),
       n_connection_simulation_(false),
-      first_rto_transmission_(0),
       consecutive_rto_count_(0),
       consecutive_tlp_count_(0),
       consecutive_crypto_retransmission_count_(0),
@@ -103,10 +102,8 @@
           QuicTime::Delta::FromMilliseconds(kMinRetransmissionTimeMs)),
       ietf_style_tlp_(false),
       ietf_style_2x_tlp_(false),
-      largest_newly_acked_(0),
       largest_mtu_acked_(0),
       handshake_confirmed_(false),
-      largest_packet_peer_knows_is_acked_(0),
       delayed_ack_time_(
           QuicTime::Delta::FromMilliseconds(kDefaultDelayedAckTimeMs)),
       rtt_updated_(false),
@@ -452,7 +449,7 @@
   } else {
     // Clear the recorded first packet sent after loss when version or
     // encryption changes.
-    transmission_info->retransmission = kInvalidPacketNumber;
+    transmission_info->retransmission.Clear();
   }
 }
 
@@ -479,7 +476,7 @@
     return;
   }
   QuicPacketNumber retransmission = info.retransmission;
-  while (retransmission != kInvalidPacketNumber) {
+  while (retransmission.IsInitialized()) {
     const QuicTransmissionInfo& retransmit_info =
         unacked_packets_.GetTransmissionInfo(retransmission);
     retransmission = retransmit_info.retransmission;
@@ -529,7 +526,7 @@
     return packet_number;
   }
   QuicPacketNumber retransmission = transmission_info.retransmission;
-  while (retransmission != kInvalidPacketNumber) {
+  while (retransmission.IsInitialized()) {
     packet_number = retransmission;
     retransmission =
         unacked_packets_.GetTransmissionInfo(retransmission).retransmission;
@@ -607,12 +604,12 @@
     TransmissionType transmission_type,
     HasRetransmittableData has_retransmittable_data) {
   QuicPacketNumber packet_number = serialized_packet->packet_number;
-  DCHECK_LT(0u, packet_number);
+  DCHECK_LE(FirstSendingPacketNumber(), packet_number);
   DCHECK(!unacked_packets_.IsUnacked(packet_number));
   QUIC_BUG_IF(serialized_packet->encrypted_length == 0)
       << "Cannot send empty packets.";
 
-  if (original_packet_number != kInvalidPacketNumber) {
+  if (original_packet_number.IsInitialized()) {
     pending_retransmissions_.erase(original_packet_number);
   }
 
@@ -758,7 +755,7 @@
     }
     // Abandon non-retransmittable data that's in flight to ensure it doesn't
     // fill up the congestion window.
-    bool has_retransmissions = it->retransmission != kInvalidPacketNumber;
+    bool has_retransmissions = it->retransmission.IsInitialized();
     if (session_decides_what_to_write()) {
       has_retransmissions = it->state != OUTSTANDING;
     }
@@ -1051,21 +1048,23 @@
   DCHECK_LE(largest_acked, unacked_packets_.largest_sent_packet());
   rtt_updated_ =
       MaybeUpdateRTT(largest_acked, ack_delay_time, ack_receive_time);
-  DCHECK_GE(largest_acked, unacked_packets_.largest_acked());
+  DCHECK(!unacked_packets_.largest_acked().IsInitialized() ||
+         largest_acked >= unacked_packets_.largest_acked());
   last_ack_frame_.ack_delay_time = ack_delay_time;
   acked_packets_iter_ = last_ack_frame_.packets.rbegin();
 }
 
 void QuicSentPacketManager::OnAckRange(QuicPacketNumber start,
                                        QuicPacketNumber end) {
-  if (end > last_ack_frame_.largest_acked + 1) {
+  if (!last_ack_frame_.largest_acked.IsInitialized() ||
+      end > last_ack_frame_.largest_acked + 1) {
     // Largest acked increases.
     unacked_packets_.IncreaseLargestAcked(end - 1);
     last_ack_frame_.largest_acked = end - 1;
   }
   // Drop ack ranges which ack packets below least_unacked.
   QuicPacketNumber least_unacked = unacked_packets_.GetLeastUnacked();
-  if (end <= least_unacked) {
+  if (least_unacked.IsInitialized() && end <= least_unacked) {
     return;
   }
   start = std::max(start, least_unacked);
@@ -1079,6 +1078,9 @@
       // Check if end is above the current range. If so add newly acked packets
       // in descending order.
       packets_acked_.push_back(AckedPacket(acked, 0, QuicTime::Zero()));
+      if (acked == FirstSendingPacketNumber()) {
+        break;
+      }
     }
     if (acked_packets_iter_ == last_ack_frame_.packets.rend() ||
         start > acked_packets_iter_->min()) {
@@ -1125,9 +1127,13 @@
     QUIC_DVLOG(1) << ENDPOINT << "Got an ack for packet "
                   << acked_packet.packet_number;
     last_ack_frame_.packets.Add(acked_packet.packet_number);
-    if (info->largest_acked > kInvalidPacketNumber) {
-      largest_packet_peer_knows_is_acked_ =
-          std::max(largest_packet_peer_knows_is_acked_, info->largest_acked);
+    if (info->largest_acked.IsInitialized()) {
+      if (largest_packet_peer_knows_is_acked_.IsInitialized()) {
+        largest_packet_peer_knows_is_acked_ =
+            std::max(largest_packet_peer_knows_is_acked_, info->largest_acked);
+      } else {
+        largest_packet_peer_knows_is_acked_ = info->largest_acked;
+      }
     }
     // If data is associated with the most recent transmission of this
     // packet, then inform the caller.
diff --git a/net/third_party/quic/core/quic_sent_packet_manager.h b/net/third_party/quic/core/quic_sent_packet_manager.h
index ed0ea8f..0400986a 100644
--- a/net/third_party/quic/core/quic_sent_packet_manager.h
+++ b/net/third_party/quic/core/quic_sent_packet_manager.h
@@ -368,7 +368,9 @@
     LOSS_MODE,
   };
 
-  typedef QuicLinkedHashMap<QuicPacketNumber, TransmissionType>
+  typedef QuicLinkedHashMap<QuicPacketNumber,
+                            TransmissionType,
+                            QuicPacketNumberHash>
       PendingRetransmissionMap;
 
   // Returns the current retransmission mode.
diff --git a/net/third_party/quic/core/quic_sent_packet_manager_test.cc b/net/third_party/quic/core/quic_sent_packet_manager_test.cc
index b3414f2..f41d1fb6 100644
--- a/net/third_party/quic/core/quic_sent_packet_manager_test.cc
+++ b/net/third_party/quic/core/quic_sent_packet_manager_test.cc
@@ -38,7 +38,8 @@
 
 // Matcher to check that the packet number matches the second argument.
 MATCHER(PacketNumberEq, "") {
-  return ::testing::get<0>(arg).packet_number == ::testing::get<1>(arg);
+  return ::testing::get<0>(arg).packet_number ==
+         QuicPacketNumber(::testing::get<1>(arg));
 }
 
 class MockDebugDelegate : public QuicSentPacketManager::DebugDelegate {
@@ -55,23 +56,25 @@
 class QuicSentPacketManagerTest : public QuicTestWithParam<bool> {
  public:
   void RetransmitCryptoPacket(uint64_t packet_number) {
-    EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, BytesInFlight(), packet_number, kDefaultLength,
-                             HAS_RETRANSMITTABLE_DATA));
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
     SerializedPacket packet(CreatePacket(packet_number, false));
     packet.retransmittable_frames.push_back(
         QuicFrame(QuicStreamFrame(1, false, 0, QuicStringPiece())));
     packet.has_crypto_handshake = IS_HANDSHAKE;
-    manager_.OnPacketSent(&packet, 0, clock_.Now(), HANDSHAKE_RETRANSMISSION,
-                          HAS_RETRANSMITTABLE_DATA);
+    manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                          HANDSHAKE_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
   }
 
   void RetransmitDataPacket(uint64_t packet_number, TransmissionType type) {
-    EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, BytesInFlight(), packet_number, kDefaultLength,
-                             HAS_RETRANSMITTABLE_DATA));
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
     SerializedPacket packet(CreatePacket(packet_number, true));
-    manager_.OnPacketSent(&packet, 0, clock_.Now(), type,
+    manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(), type,
                           HAS_RETRANSMITTABLE_DATA);
   }
 
@@ -110,7 +113,7 @@
   QuicByteCount BytesInFlight() {
     return QuicSentPacketManagerPeer::GetBytesInFlight(&manager_);
   }
-  void VerifyUnackedPackets(QuicPacketNumber* packets, size_t num_packets) {
+  void VerifyUnackedPackets(uint64_t* packets, size_t num_packets) {
     if (num_packets == 0) {
       EXPECT_TRUE(manager_.unacked_packets().empty());
       EXPECT_EQ(0u, QuicSentPacketManagerPeer::GetNumRetransmittablePackets(
@@ -119,15 +122,14 @@
     }
 
     EXPECT_FALSE(manager_.unacked_packets().empty());
-    EXPECT_EQ(packets[0], manager_.GetLeastUnacked());
+    EXPECT_EQ(QuicPacketNumber(packets[0]), manager_.GetLeastUnacked());
     for (size_t i = 0; i < num_packets; ++i) {
       EXPECT_TRUE(QuicSentPacketManagerPeer::IsUnacked(&manager_, packets[i]))
           << packets[i];
     }
   }
 
-  void VerifyRetransmittablePackets(QuicPacketNumber* packets,
-                                    size_t num_packets) {
+  void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) {
     EXPECT_EQ(
         num_packets,
         QuicSentPacketManagerPeer::GetNumRetransmittablePackets(&manager_));
@@ -167,17 +169,17 @@
 
   // |packets_acked| and |packets_lost| should be in packet number order.
   void ExpectAcksAndLosses(bool rtt_updated,
-                           QuicPacketNumber* packets_acked,
+                           uint64_t* packets_acked,
                            size_t num_packets_acked,
-                           QuicPacketNumber* packets_lost,
+                           uint64_t* packets_lost,
                            size_t num_packets_lost) {
     std::vector<QuicPacketNumber> ack_vector;
     for (size_t i = 0; i < num_packets_acked; ++i) {
-      ack_vector.push_back(packets_acked[i]);
+      ack_vector.push_back(QuicPacketNumber(packets_acked[i]));
     }
     std::vector<QuicPacketNumber> lost_vector;
     for (size_t i = 0; i < num_packets_lost; ++i) {
-      lost_vector.push_back(packets_lost[i]);
+      lost_vector.push_back(QuicPacketNumber(packets_lost[i]));
     }
     EXPECT_CALL(*send_algorithm_,
                 OnCongestionEvent(rtt_updated, _, _,
@@ -218,26 +220,30 @@
       if (!is_lost) {
         return;
       }
-      EXPECT_CALL(*send_algorithm_,
-                  OnPacketSent(_, BytesInFlight(), new_packet_number,
-                               kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+      EXPECT_CALL(
+          *send_algorithm_,
+          OnPacketSent(_, BytesInFlight(), QuicPacketNumber(new_packet_number),
+                       kDefaultLength, HAS_RETRANSMITTABLE_DATA));
       SerializedPacket packet(CreatePacket(new_packet_number, true));
-      manager_.OnPacketSent(&packet, 0, clock_.Now(), transmission_type,
-                            HAS_RETRANSMITTABLE_DATA);
+      manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                            transmission_type, HAS_RETRANSMITTABLE_DATA);
       return;
     }
     EXPECT_TRUE(manager_.HasPendingRetransmissions());
     QuicPendingRetransmission next_retransmission =
         manager_.NextPendingRetransmission();
-    EXPECT_EQ(old_packet_number, next_retransmission.packet_number);
+    EXPECT_EQ(QuicPacketNumber(old_packet_number),
+              next_retransmission.packet_number);
     EXPECT_EQ(transmission_type, next_retransmission.transmission_type);
 
-    EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, BytesInFlight(), new_packet_number,
-                             kDefaultLength, HAS_RETRANSMITTABLE_DATA));
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(new_packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
     SerializedPacket packet(CreatePacket(new_packet_number, false));
-    manager_.OnPacketSent(&packet, old_packet_number, clock_.Now(),
-                          transmission_type, HAS_RETRANSMITTABLE_DATA);
+    manager_.OnPacketSent(&packet, QuicPacketNumber(old_packet_number),
+                          clock_.Now(), transmission_type,
+                          HAS_RETRANSMITTABLE_DATA);
     EXPECT_TRUE(QuicSentPacketManagerPeer::IsRetransmission(&manager_,
                                                             new_packet_number));
   }
@@ -247,8 +253,9 @@
   }
 
   SerializedPacket CreatePacket(uint64_t packet_number, bool retransmittable) {
-    SerializedPacket packet(packet_number, PACKET_4BYTE_PACKET_NUMBER, nullptr,
-                            kDefaultLength, false, false);
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_4BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
     if (retransmittable) {
       packet.retransmittable_frames.push_back(
           QuicFrame(QuicStreamFrame(kStreamId, false, 0, QuicStringPiece())));
@@ -258,22 +265,24 @@
 
   void SendDataPacket(uint64_t packet_number) {
     EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, BytesInFlight(), packet_number, _, _));
+                OnPacketSent(_, BytesInFlight(),
+                             QuicPacketNumber(packet_number), _, _));
     SerializedPacket packet(CreateDataPacket(packet_number));
-    manager_.OnPacketSent(&packet, 0, clock_.Now(), NOT_RETRANSMISSION,
-                          HAS_RETRANSMITTABLE_DATA);
+    manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                          NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
   }
 
   void SendCryptoPacket(uint64_t packet_number) {
-    EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, BytesInFlight(), packet_number, kDefaultLength,
-                             HAS_RETRANSMITTABLE_DATA));
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
     SerializedPacket packet(CreatePacket(packet_number, false));
     packet.retransmittable_frames.push_back(
         QuicFrame(QuicStreamFrame(1, false, 0, QuicStringPiece())));
     packet.has_crypto_handshake = IS_HANDSHAKE;
-    manager_.OnPacketSent(&packet, 0, clock_.Now(), NOT_RETRANSMISSION,
-                          HAS_RETRANSMITTABLE_DATA);
+    manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                          NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
     if (manager_.session_decides_what_to_write()) {
       EXPECT_CALL(notifier_, HasUnackedCryptoData())
           .WillRepeatedly(Return(true));
@@ -281,21 +290,23 @@
   }
 
   void SendAckPacket(uint64_t packet_number, uint64_t largest_acked) {
-    EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, BytesInFlight(), packet_number, kDefaultLength,
-                             NO_RETRANSMITTABLE_DATA));
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, BytesInFlight(), QuicPacketNumber(packet_number),
+                     kDefaultLength, NO_RETRANSMITTABLE_DATA));
     SerializedPacket packet(CreatePacket(packet_number, false));
-    packet.largest_acked = largest_acked;
-    manager_.OnPacketSent(&packet, 0, clock_.Now(), NOT_RETRANSMISSION,
-                          NO_RETRANSMITTABLE_DATA);
+    packet.largest_acked = QuicPacketNumber(largest_acked);
+    manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                          NOT_RETRANSMISSION, NO_RETRANSMITTABLE_DATA);
   }
 
   // Based on QuicConnection's WritePendingRetransmissions.
   void RetransmitNextPacket(uint64_t retransmission_packet_number) {
     EXPECT_TRUE(manager_.HasPendingRetransmissions());
-    EXPECT_CALL(*send_algorithm_,
-                OnPacketSent(_, _, retransmission_packet_number, kDefaultLength,
-                             HAS_RETRANSMITTABLE_DATA));
+    EXPECT_CALL(
+        *send_algorithm_,
+        OnPacketSent(_, _, QuicPacketNumber(retransmission_packet_number),
+                     kDefaultLength, HAS_RETRANSMITTABLE_DATA));
     const QuicPendingRetransmission pending =
         manager_.NextPendingRetransmission();
     SerializedPacket packet(CreatePacket(retransmission_packet_number, false));
@@ -317,9 +328,9 @@
   VerifyUnackedPackets(nullptr, 0);
   SendDataPacket(1);
 
-  QuicPacketNumber unacked[] = {1};
+  uint64_t unacked[] = {1};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
-  QuicPacketNumber retransmittable[] = {1};
+  uint64_t retransmittable[] = {1};
   VerifyRetransmittablePackets(retransmittable,
                                QUIC_ARRAYSIZE(retransmittable));
 }
@@ -329,9 +340,9 @@
   RetransmitAndSendPacket(1, 2);
 
   EXPECT_TRUE(QuicSentPacketManagerPeer::IsRetransmission(&manager_, 2));
-  QuicPacketNumber unacked[] = {1, 2};
+  uint64_t unacked[] = {1, 2};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
-  std::vector<QuicPacketNumber> retransmittable;
+  std::vector<uint64_t> retransmittable;
   if (manager_.session_decides_what_to_write()) {
     retransmittable = {1, 2};
   } else {
@@ -346,14 +357,15 @@
 
   // Ack 2 but not 1.
   ExpectAck(2);
-  manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(2, 3);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   if (manager_.session_decides_what_to_write()) {
     EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
   }
   // Packet 1 is unacked, pending, but not retransmittable.
-  QuicPacketNumber unacked[] = {1};
+  uint64_t unacked[] = {1};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
   VerifyRetransmittablePackets(nullptr, 0);
@@ -376,8 +388,9 @@
   }
   // Ack 1.
   ExpectAck(1);
-  manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(1, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   // There should no longer be a pending retransmission.
@@ -385,7 +398,7 @@
 
   if (manager_.session_decides_what_to_write()) {
     EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-    QuicPacketNumber unacked[] = {2};
+    uint64_t unacked[] = {2};
     VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
     // We do not know packet 2 is a spurious retransmission until it gets acked.
   } else {
@@ -415,7 +428,7 @@
   // There should no longer be a pending retransmission.
   EXPECT_FALSE(manager_.HasPendingRetransmissions());
 
-  QuicPacketNumber unacked[] = {1};
+  uint64_t unacked[] = {1};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyRetransmittablePackets(nullptr, 0);
   EXPECT_EQ(0u, stats_.packets_spuriously_retransmitted);
@@ -429,14 +442,15 @@
 
   // Ack 1 but not 2.
   ExpectAck(1);
-  manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(1, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   if (manager_.session_decides_what_to_write()) {
     EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
   }
   // 2 remains unacked, but no packets have retransmittable data.
-  QuicPacketNumber unacked[] = {2};
+  uint64_t unacked[] = {2};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
   VerifyRetransmittablePackets(nullptr, 0);
@@ -444,8 +458,9 @@
     // Ack 2 causes 2 be considered as spurious retransmission.
     EXPECT_CALL(notifier_, OnFrameAcked(_, _)).WillOnce(Return(false));
     ExpectAck(2);
-    manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now());
-    manager_.OnAckRange(1, 3);
+    manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
     EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   }
 
@@ -460,8 +475,9 @@
 
   // First, ACK packet 1 which makes packet 2 non-retransmittable.
   ExpectAck(1);
-  manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(1, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   SendDataPacket(3);
@@ -471,15 +487,17 @@
 
   // Next, NACK packet 2 three times.
   ExpectAck(3);
-  manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(3, 4);
-  manager_.OnAckRange(1, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   ExpectAck(4);
-  manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(3, 5);
-  manager_.OnAckRange(1, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   ExpectAckAndLoss(true, 5, 2);
@@ -492,14 +510,15 @@
       EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
     }
   }
-  manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(3, 6);
-  manager_.OnAckRange(1, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   if (manager_.session_decides_what_to_write() &&
       GetQuicReloadableFlag(quic_fix_mark_for_loss_retransmission)) {
-    QuicPacketNumber unacked[] = {2};
+    uint64_t unacked[] = {2};
     VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   } else {
     // No packets remain unacked.
@@ -529,12 +548,13 @@
   // send algorithm is not informed that it has been ACK'd.
   ExpectUpdatedRtt(1);
   EXPECT_CALL(*send_algorithm_, RevertRetransmissionTimeout());
-  manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(1, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   // Since 2 was marked for retransmit, when 1 is acked, 2 is kept for RTT.
-  QuicPacketNumber unacked[] = {2};
+  uint64_t unacked[] = {2};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
   VerifyRetransmittablePackets(nullptr, 0);
@@ -565,8 +585,9 @@
 
   // Ack 1 but not 2 or 3.
   ExpectAck(1);
-  manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(1, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   if (manager_.session_decides_what_to_write()) {
     // Frames in packets 2 and 3 are acked.
@@ -576,7 +597,7 @@
   }
 
   // 2 and 3 remain unacked, but no packets have retransmittable data.
-  QuicPacketNumber unacked[] = {2, 3};
+  uint64_t unacked[] = {2, 3};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
   VerifyRetransmittablePackets(nullptr, 0);
@@ -589,20 +610,22 @@
         .WillOnce(Return(false))
         .WillRepeatedly(Return(true));
   }
-  QuicPacketNumber acked[] = {3, 4};
+  uint64_t acked[] = {3, 4};
   ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(3, 5);
-  manager_.OnAckRange(1, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
-  QuicPacketNumber unacked2[] = {2};
+  uint64_t unacked2[] = {2};
   VerifyUnackedPackets(unacked2, QUIC_ARRAYSIZE(unacked2));
   EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
 
   SendDataPacket(5);
   ExpectAckAndLoss(true, 5, 2);
-  EXPECT_CALL(debug_delegate, OnPacketLoss(2, LOSS_RETRANSMISSION, _));
+  EXPECT_CALL(debug_delegate,
+              OnPacketLoss(QuicPacketNumber(2), LOSS_RETRANSMISSION, _));
   if (manager_.session_decides_what_to_write()) {
     // Frames in all packets are acked.
     EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
@@ -612,14 +635,15 @@
       EXPECT_CALL(notifier_, OnFrameLost(_)).Times(1);
     }
   }
-  manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(3, 6);
-  manager_.OnAckRange(1, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   if (manager_.session_decides_what_to_write() &&
       GetQuicReloadableFlag(quic_fix_mark_for_loss_retransmission)) {
-    QuicPacketNumber unacked[] = {2};
+    uint64_t unacked[] = {2};
     VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   } else {
     VerifyUnackedPackets(nullptr, 0);
@@ -646,8 +670,9 @@
   {
     ExpectAck(1);
     EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-    manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
-    manager_.OnAckRange(1, 2);
+    manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
     EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   }
 
@@ -657,22 +682,25 @@
   {
     ExpectAck(4);
     EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-    manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now());
-    manager_.OnAckRange(4, 5);
-    manager_.OnAckRange(1, 2);
+    manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(5));
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
     EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
     RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
   }
 
   // Ack 3, which causes SpuriousRetransmitDetected to be called.
   {
-    QuicPacketNumber acked[] = {3};
+    uint64_t acked[] = {3};
     ExpectAcksAndLosses(false, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
     EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-    EXPECT_CALL(*loss_algorithm, SpuriousRetransmitDetected(_, _, _, 5));
-    manager_.OnAckFrameStart(4, QuicTime::Delta::Infinite(), clock_.Now());
-    manager_.OnAckRange(3, 5);
-    manager_.OnAckRange(1, 2);
+    EXPECT_CALL(*loss_algorithm,
+                SpuriousRetransmitDetected(_, _, _, QuicPacketNumber(5)));
+    manager_.OnAckFrameStart(QuicPacketNumber(4), QuicTime::Delta::Infinite(),
+                             clock_.Now());
+    manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(5));
+    manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
     EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
     if (manager_.session_decides_what_to_write()) {
       // Ack 3 will not cause 5 be considered as a spurious retransmission. Ack
@@ -681,57 +709,60 @@
       ExpectAck(5);
       EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
       EXPECT_CALL(notifier_, OnFrameAcked(_, _)).WillOnce(Return(false));
-      manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now());
-      manager_.OnAckRange(3, 6);
-      manager_.OnAckRange(1, 2);
+      manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                               clock_.Now());
+      manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
+      manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
       EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
     }
   }
 }
 
 TEST_P(QuicSentPacketManagerTest, GetLeastUnacked) {
-  EXPECT_EQ(1u, manager_.GetLeastUnacked());
+  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
 }
 
 TEST_P(QuicSentPacketManagerTest, GetLeastUnackedUnacked) {
   SendDataPacket(1);
-  EXPECT_EQ(1u, manager_.GetLeastUnacked());
+  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
 }
 
 TEST_P(QuicSentPacketManagerTest, AckAckAndUpdateRtt) {
-  EXPECT_EQ(0u, manager_.largest_packet_peer_knows_is_acked());
+  EXPECT_FALSE(manager_.largest_packet_peer_knows_is_acked().IsInitialized());
   SendDataPacket(1);
   SendAckPacket(2, 1);
 
   // Now ack the ack and expect an RTT update.
-  QuicPacketNumber acked[] = {1, 2};
+  uint64_t acked[] = {1, 2};
   ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(2, QuicTime::Delta::FromMilliseconds(5),
-                           clock_.Now());
-  manager_.OnAckRange(1, 3);
+  manager_.OnAckFrameStart(QuicPacketNumber(2),
+                           QuicTime::Delta::FromMilliseconds(5), clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(3));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
-  EXPECT_EQ(1u, manager_.largest_packet_peer_knows_is_acked());
+  EXPECT_EQ(QuicPacketNumber(1), manager_.largest_packet_peer_knows_is_acked());
 
   SendAckPacket(3, 3);
 
   // Now ack the ack and expect only an RTT update.
-  QuicPacketNumber acked2[] = {3};
+  uint64_t acked2[] = {3};
   ExpectAcksAndLosses(true, acked2, QUIC_ARRAYSIZE(acked2), nullptr, 0);
-  manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(1, 4);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(4));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
-  EXPECT_EQ(3u, manager_.largest_packet_peer_knows_is_acked());
+  EXPECT_EQ(QuicPacketNumber(3u),
+            manager_.largest_packet_peer_knows_is_acked());
 }
 
 TEST_P(QuicSentPacketManagerTest, Rtt) {
-  QuicPacketNumber packet_number = 1;
   QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(20);
-  SendDataPacket(packet_number);
+  SendDataPacket(1);
   clock_.AdvanceTime(expected_rtt);
 
-  ExpectAck(packet_number);
-  manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(1, 2);
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
 }
@@ -740,15 +771,14 @@
   // Expect that the RTT is equal to the local time elapsed, since the
   // ack_delay_time is larger than the local time elapsed
   // and is hence invalid.
-  QuicPacketNumber packet_number = 1;
   QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
-  SendDataPacket(packet_number);
+  SendDataPacket(1);
   clock_.AdvanceTime(expected_rtt);
 
-  ExpectAck(packet_number);
-  manager_.OnAckFrameStart(1, QuicTime::Delta::FromMilliseconds(11),
-                           clock_.Now());
-  manager_.OnAckRange(1, 2);
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1),
+                           QuicTime::Delta::FromMilliseconds(11), clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
 }
@@ -756,14 +786,14 @@
 TEST_P(QuicSentPacketManagerTest, RttWithInfiniteDelta) {
   // Expect that the RTT is equal to the local time elapsed, since the
   // ack_delay_time is infinite, and is hence invalid.
-  QuicPacketNumber packet_number = 1;
   QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
-  SendDataPacket(packet_number);
+  SendDataPacket(1);
   clock_.AdvanceTime(expected_rtt);
 
-  ExpectAck(packet_number);
-  manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(1, 2);
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
 }
@@ -771,14 +801,14 @@
 TEST_P(QuicSentPacketManagerTest, RttZeroDelta) {
   // Expect that the RTT is the time between send and receive since the
   // ack_delay_time is zero.
-  QuicPacketNumber packet_number = 1;
   QuicTime::Delta expected_rtt = QuicTime::Delta::FromMilliseconds(10);
-  SendDataPacket(packet_number);
+  SendDataPacket(1);
   clock_.AdvanceTime(expected_rtt);
 
-  ExpectAck(packet_number);
-  manager_.OnAckFrameStart(1, QuicTime::Delta::Zero(), clock_.Now());
-  manager_.OnAckRange(1, 2);
+  ExpectAck(1);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   EXPECT_EQ(expected_rtt, manager_.GetRttStats()->latest_rtt());
 }
@@ -787,8 +817,7 @@
   QuicSentPacketManagerPeer::SetMaxTailLossProbes(&manager_, 2);
 
   // Send 1 packet.
-  QuicPacketNumber packet_number = 1;
-  SendDataPacket(packet_number);
+  SendDataPacket(1);
 
   // The first tail loss probe retransmits 1 packet.
   manager_.OnRetransmissionTimeout();
@@ -827,8 +856,9 @@
   // Ack the third and ensure the first two are still pending.
   ExpectAck(3);
 
-  manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(3, 4);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   EXPECT_TRUE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
@@ -836,8 +866,8 @@
   // Acking two more packets will lose both of them due to nacks.
   SendDataPacket(4);
   SendDataPacket(5);
-  QuicPacketNumber acked[] = {4, 5};
-  QuicPacketNumber lost[] = {1, 2};
+  uint64_t acked[] = {4, 5};
+  uint64_t lost[] = {1, 2};
   ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), lost,
                       QUIC_ARRAYSIZE(lost));
   if (manager_.session_decides_what_to_write()) {
@@ -849,8 +879,9 @@
       EXPECT_CALL(notifier_, OnFrameLost(_)).Times(2);
     }
   }
-  manager_.OnAckFrameStart(5, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(3, 6);
+  manager_.OnAckFrameStart(QuicPacketNumber(5), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   EXPECT_FALSE(manager_.HasPendingRetransmissions());
@@ -942,7 +973,7 @@
     EXPECT_TRUE(manager_.HasPendingRetransmissions());
     RetransmitNextPacket(103);
   }
-  QuicPacketNumber largest_acked = 103;
+  QuicPacketNumber largest_acked = QuicPacketNumber(103);
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
   EXPECT_CALL(*send_algorithm_,
               OnCongestionEvent(
@@ -971,8 +1002,9 @@
       EXPECT_CALL(notifier_, OnFrameLost(_)).Times(101);
     }
   }
-  manager_.OnAckFrameStart(103, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(103, 104);
+  manager_.OnAckFrameStart(QuicPacketNumber(103), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(103), QuicPacketNumber(104));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   // All packets before 103 should be lost.
   if (manager_.session_decides_what_to_write()) {
@@ -1029,15 +1061,16 @@
 
   // Now ack the two crypto packets and the speculatively encrypted request,
   // and ensure the first four crypto packets get abandoned, but not lost.
-  QuicPacketNumber acked[] = {3, 4, 5, 8, 9};
+  uint64_t acked[] = {3, 4, 5, 8, 9};
   ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
   if (manager_.session_decides_what_to_write()) {
     EXPECT_CALL(notifier_, HasUnackedCryptoData())
         .WillRepeatedly(Return(false));
   }
-  manager_.OnAckFrameStart(9, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(8, 10);
-  manager_.OnAckRange(3, 6);
+  manager_.OnAckFrameStart(QuicPacketNumber(9), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(8), QuicPacketNumber(10));
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(6));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
@@ -1087,9 +1120,11 @@
     RetransmitDataPacket(12, ALL_UNACKED_RETRANSMISSION);
   } else {
     ASSERT_TRUE(manager_.HasPendingRetransmissions());
-    EXPECT_EQ(6u, manager_.NextPendingRetransmission().packet_number);
+    EXPECT_EQ(QuicPacketNumber(6u),
+              manager_.NextPendingRetransmission().packet_number);
     RetransmitNextPacket(8);
-    EXPECT_EQ(7u, manager_.NextPendingRetransmission().packet_number);
+    EXPECT_EQ(QuicPacketNumber(7u),
+              manager_.NextPendingRetransmission().packet_number);
     RetransmitNextPacket(9);
     EXPECT_TRUE(manager_.HasPendingRetransmissions());
     // Send 3 more data packets and ensure the least unacked is raised.
@@ -1099,19 +1134,20 @@
     EXPECT_FALSE(manager_.HasPendingRetransmissions());
   }
 
-  EXPECT_EQ(1u, manager_.GetLeastUnacked());
+  EXPECT_EQ(QuicPacketNumber(1u), manager_.GetLeastUnacked());
   // Least unacked isn't raised until an ack is received, so ack the
   // crypto packets.
-  QuicPacketNumber acked[] = {8, 9};
+  uint64_t acked[] = {8, 9};
   ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(9, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(8, 10);
+  manager_.OnAckFrameStart(QuicPacketNumber(9), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(8), QuicPacketNumber(10));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   if (manager_.session_decides_what_to_write()) {
     EXPECT_CALL(notifier_, HasUnackedCryptoData())
         .WillRepeatedly(Return(false));
   }
-  EXPECT_EQ(10u, manager_.GetLeastUnacked());
+  EXPECT_EQ(QuicPacketNumber(10u), manager_.GetLeastUnacked());
 }
 
 TEST_P(QuicSentPacketManagerTest, CryptoHandshakeSpuriousRetransmission) {
@@ -1141,19 +1177,20 @@
 
   // Now ack the second crypto packet, and ensure the first gets removed, but
   // the third does not.
-  QuicPacketNumber acked[] = {2};
+  uint64_t acked[] = {2};
   ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
   if (manager_.session_decides_what_to_write()) {
     EXPECT_CALL(notifier_, HasUnackedCryptoData())
         .WillRepeatedly(Return(false));
     EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
   }
-  manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(2, 3);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
-  QuicPacketNumber unacked[] = {3};
+  uint64_t unacked[] = {3};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
 }
 
@@ -1211,7 +1248,7 @@
   } else {
     // Packet 2 is useful because it does not get retransmitted and still has
     // retransmittable frames.
-    QuicPacketNumber unacked[] = {1, 2};
+    uint64_t unacked[] = {1, 2};
     VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
     EXPECT_TRUE(manager_.HasPendingRetransmissions());
   }
@@ -1257,7 +1294,7 @@
     EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
   }
   EXPECT_FALSE(QuicSentPacketManagerPeer::HasUnackedCryptoPackets(&manager_));
-  QuicPacketNumber unacked[] = {1, 2, 3};
+  uint64_t unacked[] = {1, 2, 3};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyRetransmittablePackets(nullptr, 0);
   EXPECT_FALSE(manager_.HasPendingRetransmissions());
@@ -1265,10 +1302,11 @@
   EXPECT_FALSE(QuicSentPacketManagerPeer::HasPendingPackets(&manager_));
 
   // Ensure both packets get discarded when packet 2 is acked.
-  QuicPacketNumber acked[] = {3};
+  uint64_t acked[] = {3};
   ExpectAcksAndLosses(true, acked, QUIC_ARRAYSIZE(acked), nullptr, 0);
-  manager_.OnAckFrameStart(3, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(3, 4);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   VerifyUnackedPackets(nullptr, 0);
   VerifyRetransmittablePackets(nullptr, 0);
@@ -1311,7 +1349,7 @@
 
   // Ack a retransmission.
   // Ensure no packets are lost.
-  QuicPacketNumber largest_acked = 102;
+  QuicPacketNumber largest_acked = QuicPacketNumber(102);
   EXPECT_CALL(*send_algorithm_,
               OnCongestionEvent(true, _, _,
                                 Pointwise(PacketNumberEq(), {largest_acked}),
@@ -1321,7 +1359,8 @@
   // RTO's use loss detection instead of immediately declaring retransmitted
   // packets lost.
   for (int i = 1; i <= 99; ++i) {
-    EXPECT_CALL(debug_delegate, OnPacketLoss(i, LOSS_RETRANSMISSION, _));
+    EXPECT_CALL(debug_delegate,
+                OnPacketLoss(QuicPacketNumber(i), LOSS_RETRANSMISSION, _));
   }
   if (manager_.session_decides_what_to_write()) {
     if (GetQuicReloadableFlag(quic_fix_mark_for_loss_retransmission)) {
@@ -1346,8 +1385,9 @@
       EXPECT_CALL(notifier_, OnFrameLost(_)).Times(98);
     }
   }
-  manager_.OnAckFrameStart(102, QuicTime::Delta::Zero(), clock_.Now());
-  manager_.OnAckRange(102, 103);
+  manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 }
 
@@ -1445,7 +1485,7 @@
 
   // Ack a retransmission and expect no call to OnRetransmissionTimeout.
   // This will include packets in the lost packet map.
-  QuicPacketNumber largest_acked = 102;
+  QuicPacketNumber largest_acked = QuicPacketNumber(102);
   EXPECT_CALL(*send_algorithm_,
               OnCongestionEvent(true, _, _,
                                 Pointwise(PacketNumberEq(), {largest_acked}),
@@ -1474,8 +1514,9 @@
       EXPECT_CALL(notifier_, OnFrameLost(_)).Times(98);
     }
   }
-  manager_.OnAckFrameStart(102, QuicTime::Delta::Zero(), clock_.Now());
-  manager_.OnAckRange(102, 103);
+  manager_.OnAckFrameStart(QuicPacketNumber(102), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(102), QuicPacketNumber(103));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 }
 
@@ -1521,8 +1562,9 @@
   // Ack a retransmission and ensure OnRetransmissionTimeout is called.
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
   ExpectAck(2);
-  manager_.OnAckFrameStart(2, QuicTime::Delta::Zero(), clock_.Now());
-  manager_.OnAckRange(2, 3);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   // The original packet and newest should be outstanding.
@@ -1572,8 +1614,9 @@
   // Ack a retransmission and ensure OnRetransmissionTimeout is called.
   EXPECT_CALL(*send_algorithm_, OnRetransmissionTimeout(true));
   ExpectAck(3);
-  manager_.OnAckFrameStart(3, QuicTime::Delta::Zero(), clock_.Now());
-  manager_.OnAckRange(3, 4);
+  manager_.OnAckFrameStart(QuicPacketNumber(3), QuicTime::Delta::Zero(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(3), QuicPacketNumber(4));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   // The first two packets should still be outstanding.
@@ -1773,8 +1816,9 @@
   // Ack a packet before the first RTO and ensure the RTO timeout returns to the
   // original value and OnRetransmissionTimeout is not called or reverted.
   ExpectAck(2);
-  manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(2, 3);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
   EXPECT_FALSE(manager_.HasPendingRetransmissions());
   EXPECT_EQ(5 * kDefaultLength,
@@ -1907,8 +1951,9 @@
   // set the loss timeout.
   ExpectAck(2);
   EXPECT_CALL(*loss_algorithm, DetectLosses(_, _, _, _, _, _));
-  manager_.OnAckFrameStart(2, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(2, 3);
+  manager_.OnAckFrameStart(QuicPacketNumber(2), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(2), QuicPacketNumber(3));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   QuicTime timeout(clock_.Now() + QuicTime::Delta::FromMilliseconds(10));
@@ -2419,19 +2464,21 @@
 }
 
 TEST_P(QuicSentPacketManagerTest, PathMtuIncreased) {
-  EXPECT_CALL(*send_algorithm_, OnPacketSent(_, BytesInFlight(), 1, _, _));
-  SerializedPacket packet(1, PACKET_4BYTE_PACKET_NUMBER, nullptr,
-                          kDefaultLength + 100, false, false);
-  manager_.OnPacketSent(&packet, 0, clock_.Now(), NOT_RETRANSMISSION,
-                        HAS_RETRANSMITTABLE_DATA);
+  EXPECT_CALL(*send_algorithm_,
+              OnPacketSent(_, BytesInFlight(), QuicPacketNumber(1), _, _));
+  SerializedPacket packet(QuicPacketNumber(1), PACKET_4BYTE_PACKET_NUMBER,
+                          nullptr, kDefaultLength + 100, false, false);
+  manager_.OnPacketSent(&packet, QuicPacketNumber(), clock_.Now(),
+                        NOT_RETRANSMISSION, HAS_RETRANSMITTABLE_DATA);
 
   // Ack the large packet and expect the path MTU to increase.
   ExpectAck(1);
   EXPECT_CALL(*network_change_visitor_,
               OnPathMtuIncreased(kDefaultLength + 100));
   QuicAckFrame ack_frame = InitAckFrame(1);
-  manager_.OnAckFrameStart(1, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(1, 2);
+  manager_.OnAckFrameStart(QuicPacketNumber(1), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(1), QuicPacketNumber(2));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 }
 
@@ -2441,26 +2488,28 @@
     SendDataPacket(i);
   }
   // Ack [5, 7), [10, 12), [15, 17).
-  QuicPacketNumber acked1[] = {5, 6, 10, 11, 15, 16};
-  QuicPacketNumber lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
+  uint64_t acked1[] = {5, 6, 10, 11, 15, 16};
+  uint64_t lost1[] = {1, 2, 3, 4, 7, 8, 9, 12, 13};
   ExpectAcksAndLosses(true, acked1, QUIC_ARRAYSIZE(acked1), lost1,
                       QUIC_ARRAYSIZE(lost1));
   EXPECT_CALL(notifier_, OnFrameLost(_)).Times(AnyNumber());
-  manager_.OnAckFrameStart(16, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(15, 17);
-  manager_.OnAckRange(10, 12);
-  manager_.OnAckRange(5, 7);
+  manager_.OnAckFrameStart(QuicPacketNumber(16), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(15), QuicPacketNumber(17));
+  manager_.OnAckRange(QuicPacketNumber(10), QuicPacketNumber(12));
+  manager_.OnAckRange(QuicPacketNumber(5), QuicPacketNumber(7));
   // Make sure empty range does not harm.
-  manager_.OnAckRange(4, 4);
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(4));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 
   // Ack [4, 8), [9, 13), [14, 21).
-  QuicPacketNumber acked2[] = {4, 7, 9, 12, 14, 17, 18, 19, 20};
+  uint64_t acked2[] = {4, 7, 9, 12, 14, 17, 18, 19, 20};
   ExpectAcksAndLosses(true, acked2, QUIC_ARRAYSIZE(acked2), nullptr, 0);
-  manager_.OnAckFrameStart(20, QuicTime::Delta::Infinite(), clock_.Now());
-  manager_.OnAckRange(14, 21);
-  manager_.OnAckRange(9, 13);
-  manager_.OnAckRange(4, 8);
+  manager_.OnAckFrameStart(QuicPacketNumber(20), QuicTime::Delta::Infinite(),
+                           clock_.Now());
+  manager_.OnAckRange(QuicPacketNumber(14), QuicPacketNumber(21));
+  manager_.OnAckRange(QuicPacketNumber(9), QuicPacketNumber(13));
+  manager_.OnAckRange(QuicPacketNumber(4), QuicPacketNumber(8));
   EXPECT_TRUE(manager_.OnAckFrameEnd(clock_.Now()));
 }
 
diff --git a/net/third_party/quic/core/quic_time_wait_list_manager_test.cc b/net/third_party/quic/core/quic_time_wait_list_manager_test.cc
index 42fdc34d6..762548ff 100644
--- a/net/third_party/quic/core/quic_time_wait_list_manager_test.cc
+++ b/net/third_party/quic/core/quic_time_wait_list_manager_test.cc
@@ -185,7 +185,7 @@
   QuicEncryptedPacket* ConstructEncryptedPacket(
       QuicConnectionId destination_connection_id,
       QuicConnectionId source_connection_id,
-      QuicPacketNumber packet_number) {
+      uint64_t packet_number) {
     return quic::test::ConstructEncryptedPacket(destination_connection_id,
                                                 source_connection_id, false,
                                                 false, packet_number, "data");
@@ -406,9 +406,8 @@
   QuicConnectionId connection_id = TestConnectionId(1);
   EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(connection_id));
   AddConnectionId(connection_id, QuicTimeWaitListManager::SEND_STATELESS_RESET);
-  QuicPacketNumber packet_number = 234;
   std::unique_ptr<QuicEncryptedPacket> packet(ConstructEncryptedPacket(
-      connection_id, EmptyQuicConnectionId(), packet_number));
+      connection_id, EmptyQuicConnectionId(), /*packet_number=*/234));
   // Let first write through.
   EXPECT_CALL(writer_,
               WritePacket(_, _, self_address_.host(), peer_address_, _))
@@ -433,9 +432,8 @@
   EXPECT_CALL(visitor_, OnConnectionAddedToTimeWaitList(other_connection_id));
   AddConnectionId(other_connection_id,
                   QuicTimeWaitListManager::SEND_STATELESS_RESET);
-  QuicPacketNumber other_packet_number = 23423;
   std::unique_ptr<QuicEncryptedPacket> other_packet(ConstructEncryptedPacket(
-      other_connection_id, EmptyQuicConnectionId(), other_packet_number));
+      other_connection_id, EmptyQuicConnectionId(), /*packet_number=*/23423));
   EXPECT_CALL(writer_, WritePacket(_, _, _, _, _)).Times(0);
   EXPECT_CALL(visitor_, OnWriteBlocked(&time_wait_list_manager_));
   ProcessPacket(other_connection_id);
diff --git a/net/third_party/quic/core/quic_trace_visitor.cc b/net/third_party/quic/core/quic_trace_visitor.cc
index c597fa86..2b30bc72 100644
--- a/net/third_party/quic/core/quic_trace_visitor.cc
+++ b/net/third_party/quic/core/quic_trace_visitor.cc
@@ -59,7 +59,7 @@
   quic_trace::Event* event = trace_.add_events();
   event->set_event_type(quic_trace::PACKET_SENT);
   event->set_time_us(ConvertTimestampToRecordedFormat(sent_time));
-  event->set_packet_number(serialized_packet.packet_number);
+  event->set_packet_number(serialized_packet.packet_number.ToUint64());
   event->set_packet_size(serialized_packet.encrypted_length);
   event->set_encryption_level(
       EncryptionLevelToProto(serialized_packet.encryption_level));
@@ -140,8 +140,8 @@
         quic_trace::AckBlock* block = info->add_acked_packets();
         // We record intervals as [a, b], whereas the in-memory representation
         // we currently use is [a, b).
-        block->set_first_packet(interval.min());
-        block->set_last_packet(interval.max() - 1);
+        block->set_first_packet(interval.min().ToUint64());
+        block->set_last_packet(interval.max().ToUint64() - 1);
       }
       break;
     }
@@ -240,7 +240,7 @@
   quic_trace::Event* event = trace_.add_events();
   event->set_time_us(ConvertTimestampToRecordedFormat(ack_receive_time));
   event->set_packet_number(
-      connection_->received_packet_manager().GetLargestObserved());
+      connection_->received_packet_manager().GetLargestObserved().ToUint64());
   event->set_event_type(quic_trace::PACKET_RECEIVED);
 
   // TODO(vasilvv): consider removing this copy.
@@ -255,7 +255,7 @@
   quic_trace::Event* event = trace_.add_events();
   event->set_time_us(ConvertTimestampToRecordedFormat(detection_time));
   event->set_event_type(quic_trace::PACKET_LOST);
-  event->set_packet_number(lost_packet_number);
+  event->set_packet_number(lost_packet_number.ToUint64());
   PopulateTransportState(event->mutable_transport_state());
 }
 
@@ -265,7 +265,7 @@
   event->set_time_us(ConvertTimestampToRecordedFormat(receive_time));
   event->set_event_type(quic_trace::PACKET_RECEIVED);
   event->set_packet_number(
-      connection_->received_packet_manager().GetLargestObserved());
+      connection_->received_packet_manager().GetLargestObserved().ToUint64());
 
   // TODO(vasilvv): consider removing this copy.
   QuicWindowUpdateFrame copy_of_update = frame;
diff --git a/net/third_party/quic/core/quic_trace_visitor_test.cc b/net/third_party/quic/core/quic_trace_visitor_test.cc
index b78dbab5..e5203d622 100644
--- a/net/third_party/quic/core/quic_trace_visitor_test.cc
+++ b/net/third_party/quic/core/quic_trace_visitor_test.cc
@@ -135,20 +135,22 @@
 
         const quic_trace::AckInfo& info = frame.ack_info();
         for (const auto& block : info.acked_packets()) {
-          packets.Add(block.first_packet(), block.last_packet() + 1);
+          packets.Add(QuicPacketNumber(block.first_packet()),
+                      QuicPacketNumber(block.last_packet()) + 1);
         }
       }
     }
     if (packet.event_type() == quic_trace::PACKET_LOST) {
-      packets.Add(packet.packet_number(), packet.packet_number() + 1);
+      packets.Add(QuicPacketNumber(packet.packet_number()),
+                  QuicPacketNumber(packet.packet_number()) + 1);
     }
   }
 
   ASSERT_EQ(1u, packets.Size());
-  EXPECT_EQ(1u, packets.begin()->min());
+  EXPECT_EQ(QuicPacketNumber(1u), packets.begin()->min());
   // We leave some room (20 packets) for the packets which did not receive
   // conclusive status at the end of simulation.
-  EXPECT_GT(packets.rbegin()->max(), packets_sent_ - 20);
+  EXPECT_GT(packets.rbegin()->max(), QuicPacketNumber(packets_sent_ - 20));
 }
 
 TEST_F(QuicTraceVisitorTest, TransportState) {
diff --git a/net/third_party/quic/core/quic_transmission_info.cc b/net/third_party/quic/core/quic_transmission_info.cc
index 0ea2443..c8e502e 100644
--- a/net/third_party/quic/core/quic_transmission_info.cc
+++ b/net/third_party/quic/core/quic_transmission_info.cc
@@ -15,9 +15,7 @@
       in_flight(false),
       state(OUTSTANDING),
       has_crypto_handshake(false),
-      num_padding_bytes(0),
-      retransmission(kInvalidPacketNumber),
-      largest_acked(kInvalidPacketNumber) {}
+      num_padding_bytes(0) {}
 
 QuicTransmissionInfo::QuicTransmissionInfo(
     EncryptionLevel level,
@@ -35,9 +33,7 @@
       in_flight(false),
       state(OUTSTANDING),
       has_crypto_handshake(has_crypto_handshake),
-      num_padding_bytes(num_padding_bytes),
-      retransmission(kInvalidPacketNumber),
-      largest_acked(kInvalidPacketNumber) {}
+      num_padding_bytes(num_padding_bytes) {}
 
 QuicTransmissionInfo::QuicTransmissionInfo(const QuicTransmissionInfo& other) =
     default;
diff --git a/net/third_party/quic/core/quic_types.h b/net/third_party/quic/core/quic_types.h
index 5f3e02cc..11bbcb4 100644
--- a/net/third_party/quic/core/quic_types.h
+++ b/net/third_party/quic/core/quic_types.h
@@ -12,6 +12,7 @@
 #include <vector>
 
 #include "net/third_party/quic/core/quic_connection_id.h"
+#include "net/third_party/quic/core/quic_packet_number.h"
 #include "net/third_party/quic/core/quic_time.h"
 #include "net/third_party/quic/platform/api/quic_export.h"
 
@@ -27,7 +28,6 @@
 
 typedef uint64_t QuicByteCount;
 typedef uint64_t QuicPacketCount;
-typedef uint64_t QuicPacketNumber;
 typedef uint64_t QuicPublicResetNonceProof;
 typedef uint64_t QuicStreamOffset;
 typedef std::array<char, 32> DiversificationNonce;
diff --git a/net/third_party/quic/core/quic_unacked_packet_map.cc b/net/third_party/quic/core/quic_unacked_packet_map.cc
index 7c46bfa..224cf95 100644
--- a/net/third_party/quic/core/quic_unacked_packet_map.cc
+++ b/net/third_party/quic/core/quic_unacked_packet_map.cc
@@ -25,11 +25,7 @@
 }  // namespace
 
 QuicUnackedPacketMap::QuicUnackedPacketMap()
-    : largest_sent_packet_(0),
-      largest_sent_retransmittable_packet_(0),
-      largest_sent_largest_acked_(0),
-      largest_acked_(0),
-      least_unacked_(kFirstSendingPacketNumber),
+    : least_unacked_(FirstSendingPacketNumber()),
       bytes_in_flight_(0),
       pending_crypto_packet_count_(0),
       last_crypto_packet_sent_time_(QuicTime::Zero()),
@@ -49,7 +45,10 @@
                                          bool set_in_flight) {
   QuicPacketNumber packet_number = packet->packet_number;
   QuicPacketLength bytes_sent = packet->encrypted_length;
-  QUIC_BUG_IF(largest_sent_packet_ >= packet_number) << packet_number;
+  QUIC_BUG_IF(largest_sent_packet_.IsInitialized() &&
+              largest_sent_packet_ >= packet_number)
+      << "largest_sent_packet_: " << largest_sent_packet_
+      << ", packet_number: " << packet_number;
   DCHECK_GE(packet_number, least_unacked_ + unacked_packets_.size());
   while (least_unacked_ + unacked_packets_.size() < packet_number) {
     unacked_packets_.push_back(QuicTransmissionInfo());
@@ -62,9 +61,13 @@
       packet->encryption_level, packet->packet_number_length, transmission_type,
       sent_time, bytes_sent, has_crypto_handshake, packet->num_padding_bytes);
   info.largest_acked = packet->largest_acked;
-  largest_sent_largest_acked_ =
-      std::max(largest_sent_largest_acked_, packet->largest_acked);
-  if (old_packet_number > 0) {
+  if (packet->largest_acked.IsInitialized()) {
+    largest_sent_largest_acked_ =
+        largest_sent_largest_acked_.IsInitialized()
+            ? std::max(largest_sent_largest_acked_, packet->largest_acked)
+            : packet->largest_acked;
+  }
+  if (old_packet_number.IsInitialized()) {
     TransferRetransmissionInfo(old_packet_number, packet_number,
                                transmission_type, &info);
   }
@@ -78,7 +81,7 @@
   unacked_packets_.push_back(info);
   // Swap the retransmittable frames to avoid allocations.
   // TODO(ianswett): Could use emplace_back when Chromium can.
-  if (old_packet_number == kInvalidPacketNumber) {
+  if (!old_packet_number.IsInitialized()) {
     if (has_crypto_handshake) {
       ++pending_crypto_packet_count_;
       last_crypto_packet_sent_time_ = sent_time;
@@ -180,12 +183,12 @@
     QuicTransmissionInfo* info) {
   if (session_decides_what_to_write_) {
     DeleteFrames(&info->retransmittable_frames);
-    info->retransmission = kInvalidPacketNumber;
+    info->retransmission.Clear();
     return;
   }
-  while (info->retransmission != kInvalidPacketNumber) {
+  while (info->retransmission.IsInitialized()) {
     const QuicPacketNumber retransmission = info->retransmission;
-    info->retransmission = kInvalidPacketNumber;
+    info->retransmission.Clear();
     info = &unacked_packets_[retransmission - least_unacked_];
   }
 
@@ -209,7 +212,7 @@
 
 void QuicUnackedPacketMap::IncreaseLargestAcked(
     QuicPacketNumber largest_acked) {
-  DCHECK_LE(largest_acked_, largest_acked);
+  DCHECK(!largest_acked_.IsInitialized() || largest_acked_ <= largest_acked);
   largest_acked_ = largest_acked;
 }
 
@@ -218,7 +221,8 @@
     const QuicTransmissionInfo& info) const {
   // Packet can be used for RTT measurement if it may yet be acked as the
   // largest observed packet by the receiver.
-  return QuicUtils::IsAckable(info.state) && packet_number > largest_acked_;
+  return QuicUtils::IsAckable(info.state) &&
+         (!largest_acked_.IsInitialized() || packet_number > largest_acked_);
 }
 
 bool QuicUnackedPacketMap::IsPacketUsefulForCongestionControl(
@@ -233,15 +237,16 @@
     // Packet may have retransmittable frames, or the data may have been
     // retransmitted with a new packet number.
     // Allow for an extra 1 RTT before stopping to track old packets.
-    return info.retransmission > largest_acked_ ||
+    return (info.retransmission.IsInitialized() &&
+            (!largest_acked_.IsInitialized() ||
+             info.retransmission > largest_acked_)) ||
            HasRetransmittableFrames(info);
   }
 
   // Wait for 1 RTT before giving up on the lost packet.
-  if (info.retransmission > largest_acked_) {
-    return true;
-  }
-  return false;
+  return info.retransmission.IsInitialized() &&
+         (!largest_acked_.IsInitialized() ||
+          info.retransmission > largest_acked_);
 }
 
 bool QuicUnackedPacketMap::IsPacketUseless(
@@ -472,7 +477,7 @@
 
 void QuicUnackedPacketMap::SetSessionDecideWhatToWrite(
     bool session_decides_what_to_write) {
-  if (largest_sent_packet_ > 0) {
+  if (largest_sent_packet_.IsInitialized()) {
     QUIC_BUG << "Cannot change session_decide_what_to_write with packets sent.";
     return;
   }
diff --git a/net/third_party/quic/core/quic_unacked_packet_map_test.cc b/net/third_party/quic/core/quic_unacked_packet_map_test.cc
index b33b065..fb836fd3 100644
--- a/net/third_party/quic/core/quic_unacked_packet_map_test.cc
+++ b/net/third_party/quic/core/quic_unacked_packet_map_test.cc
@@ -46,30 +46,31 @@
 
   ~QuicUnackedPacketMapTest() override {}
 
-  SerializedPacket CreateRetransmittablePacket(QuicPacketNumber packet_number) {
+  SerializedPacket CreateRetransmittablePacket(uint64_t packet_number) {
     return CreateRetransmittablePacketForStream(
         packet_number, QuicUtils::GetHeadersStreamId(
                            CurrentSupportedVersions()[0].transport_version));
   }
 
   SerializedPacket CreateRetransmittablePacketForStream(
-      QuicPacketNumber packet_number,
+      uint64_t packet_number,
       QuicStreamId stream_id) {
-    SerializedPacket packet(packet_number, PACKET_1BYTE_PACKET_NUMBER, nullptr,
-                            kDefaultLength, false, false);
+    SerializedPacket packet(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
     QuicStreamFrame frame;
     frame.stream_id = stream_id;
     packet.retransmittable_frames.push_back(QuicFrame(frame));
     return packet;
   }
 
-  SerializedPacket CreateNonRetransmittablePacket(
-      QuicPacketNumber packet_number) {
-    return SerializedPacket(packet_number, PACKET_1BYTE_PACKET_NUMBER, nullptr,
-                            kDefaultLength, false, false);
+  SerializedPacket CreateNonRetransmittablePacket(uint64_t packet_number) {
+    return SerializedPacket(QuicPacketNumber(packet_number),
+                            PACKET_1BYTE_PACKET_NUMBER, nullptr, kDefaultLength,
+                            false, false);
   }
 
-  void VerifyInFlightPackets(QuicPacketNumber* packets, size_t num_packets) {
+  void VerifyInFlightPackets(uint64_t* packets, size_t num_packets) {
     unacked_packets_.RemoveObsoletePackets();
     if (num_packets == 0) {
       EXPECT_FALSE(unacked_packets_.HasInFlightPackets());
@@ -79,12 +80,16 @@
     if (num_packets == 1) {
       EXPECT_TRUE(unacked_packets_.HasInFlightPackets());
       EXPECT_FALSE(unacked_packets_.HasMultipleInFlightPackets());
-      ASSERT_TRUE(unacked_packets_.IsUnacked(packets[0]));
-      EXPECT_TRUE(unacked_packets_.GetTransmissionInfo(packets[0]).in_flight);
+      ASSERT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[0])));
+      EXPECT_TRUE(
+          unacked_packets_.GetTransmissionInfo(QuicPacketNumber(packets[0]))
+              .in_flight);
     }
     for (size_t i = 0; i < num_packets; ++i) {
-      ASSERT_TRUE(unacked_packets_.IsUnacked(packets[i]));
-      EXPECT_TRUE(unacked_packets_.GetTransmissionInfo(packets[i]).in_flight);
+      ASSERT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[i])));
+      EXPECT_TRUE(
+          unacked_packets_.GetTransmissionInfo(QuicPacketNumber(packets[i]))
+              .in_flight);
     }
     size_t in_flight_count = 0;
     for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
@@ -96,7 +101,7 @@
     EXPECT_EQ(num_packets, in_flight_count);
   }
 
-  void VerifyUnackedPackets(QuicPacketNumber* packets, size_t num_packets) {
+  void VerifyUnackedPackets(uint64_t* packets, size_t num_packets) {
     unacked_packets_.RemoveObsoletePackets();
     if (num_packets == 0) {
       EXPECT_TRUE(unacked_packets_.empty());
@@ -107,13 +112,13 @@
     }
     EXPECT_FALSE(unacked_packets_.empty());
     for (size_t i = 0; i < num_packets; ++i) {
-      EXPECT_TRUE(unacked_packets_.IsUnacked(packets[i])) << packets[i];
+      EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(packets[i])))
+          << packets[i];
     }
     EXPECT_EQ(num_packets, unacked_packets_.GetNumUnackedPacketsDebugOnly());
   }
 
-  void VerifyRetransmittablePackets(QuicPacketNumber* packets,
-                                    size_t num_packets) {
+  void VerifyRetransmittablePackets(uint64_t* packets, size_t num_packets) {
     unacked_packets_.RemoveObsoletePackets();
     size_t num_retransmittable_packets = 0;
     for (QuicUnackedPacketMap::const_iterator it = unacked_packets_.begin();
@@ -124,29 +129,33 @@
     }
     EXPECT_EQ(num_packets, num_retransmittable_packets);
     for (size_t i = 0; i < num_packets; ++i) {
-      EXPECT_TRUE(unacked_packets_.HasRetransmittableFrames(packets[i]))
+      EXPECT_TRUE(unacked_packets_.HasRetransmittableFrames(
+          QuicPacketNumber(packets[i])))
           << " packets[" << i << "]:" << packets[i];
     }
   }
 
-  void UpdatePacketState(QuicPacketNumber packet_number,
-                         SentPacketState state) {
-    unacked_packets_.GetMutableTransmissionInfo(packet_number)->state = state;
+  void UpdatePacketState(uint64_t packet_number, SentPacketState state) {
+    unacked_packets_
+        .GetMutableTransmissionInfo(QuicPacketNumber(packet_number))
+        ->state = state;
   }
 
   void RetransmitAndSendPacket(uint64_t old_packet_number,
                                uint64_t new_packet_number,
                                TransmissionType transmission_type) {
-    DCHECK(unacked_packets_.HasRetransmittableFrames(old_packet_number));
+    DCHECK(unacked_packets_.HasRetransmittableFrames(
+        QuicPacketNumber(old_packet_number)));
     if (!unacked_packets_.session_decides_what_to_write()) {
       SerializedPacket packet(
           CreateNonRetransmittablePacket(new_packet_number));
-      unacked_packets_.AddSentPacket(&packet, old_packet_number,
+      unacked_packets_.AddSentPacket(&packet,
+                                     QuicPacketNumber(old_packet_number),
                                      transmission_type, now_, true);
       return;
     }
-    QuicTransmissionInfo* info =
-        unacked_packets_.GetMutableTransmissionInfo(old_packet_number);
+    QuicTransmissionInfo* info = unacked_packets_.GetMutableTransmissionInfo(
+        QuicPacketNumber(old_packet_number));
     QuicStreamId stream_id = QuicUtils::GetHeadersStreamId(
         CurrentSupportedVersions()[0].transport_version);
     for (const auto& frame : info->retransmittable_frames) {
@@ -158,10 +167,11 @@
     UpdatePacketState(
         old_packet_number,
         QuicUtils::RetransmissionTypeToPacketState(transmission_type));
-    info->retransmission = new_packet_number;
+    info->retransmission = QuicPacketNumber(new_packet_number);
     SerializedPacket packet(
         CreateRetransmittablePacketForStream(new_packet_number, stream_id));
-    unacked_packets_.AddSentPacket(&packet, 0, transmission_type, now_, true);
+    unacked_packets_.AddSentPacket(&packet, QuicPacketNumber(),
+                                   transmission_type, now_, true);
   }
   QuicUnackedPacketMap unacked_packets_;
   QuicTime now_;
@@ -173,14 +183,15 @@
 TEST_P(QuicUnackedPacketMapTest, RttOnly) {
   // Acks are only tracked for RTT measurement purposes.
   SerializedPacket packet(CreateNonRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_, false);
+  unacked_packets_.AddSentPacket(&packet, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, false);
 
-  QuicPacketNumber unacked[] = {1};
+  uint64_t unacked[] = {1};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(nullptr, 0);
   VerifyRetransmittablePackets(nullptr, 0);
 
-  unacked_packets_.IncreaseLargestAcked(1);
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
   VerifyUnackedPackets(nullptr, 0);
   VerifyInFlightPackets(nullptr, 0);
   VerifyRetransmittablePackets(nullptr, 0);
@@ -189,24 +200,25 @@
 TEST_P(QuicUnackedPacketMapTest, RetransmittableInflightAndRtt) {
   // Simulate a retransmittable packet being sent and acked.
   SerializedPacket packet(CreateRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
 
-  QuicPacketNumber unacked[] = {1};
+  uint64_t unacked[] = {1};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyRetransmittablePackets(unacked, QUIC_ARRAYSIZE(unacked));
 
-  unacked_packets_.RemoveRetransmittability(1);
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyRetransmittablePackets(nullptr, 0);
 
-  unacked_packets_.IncreaseLargestAcked(1);
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(1));
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyRetransmittablePackets(nullptr, 0);
 
-  unacked_packets_.RemoveFromInFlight(1);
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
   VerifyUnackedPackets(nullptr, 0);
   VerifyInFlightPackets(nullptr, 0);
   VerifyRetransmittablePackets(nullptr, 0);
@@ -215,12 +227,13 @@
 TEST_P(QuicUnackedPacketMapTest, StopRetransmission) {
   const QuicStreamId stream_id = 2;
   SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
-  unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
 
-  QuicPacketNumber unacked[] = {1};
+  uint64_t unacked[] = {1};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
-  QuicPacketNumber retransmittable[] = {1};
+  uint64_t retransmittable[] = {1};
   VerifyRetransmittablePackets(retransmittable,
                                QUIC_ARRAYSIZE(retransmittable));
 
@@ -237,12 +250,13 @@
 TEST_P(QuicUnackedPacketMapTest, StopRetransmissionOnOtherStream) {
   const QuicStreamId stream_id = 2;
   SerializedPacket packet(CreateRetransmittablePacketForStream(1, stream_id));
-  unacked_packets_.AddSentPacket(&packet, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
 
-  QuicPacketNumber unacked[] = {1};
+  uint64_t unacked[] = {1};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
-  QuicPacketNumber retransmittable[] = {1};
+  uint64_t retransmittable[] = {1};
   VerifyRetransmittablePackets(retransmittable,
                                QUIC_ARRAYSIZE(retransmittable));
 
@@ -259,13 +273,14 @@
 TEST_P(QuicUnackedPacketMapTest, StopRetransmissionAfterRetransmission) {
   const QuicStreamId stream_id = 2;
   SerializedPacket packet1(CreateRetransmittablePacketForStream(1, stream_id));
-  unacked_packets_.AddSentPacket(&packet1, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet1, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
   RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION);
 
-  QuicPacketNumber unacked[] = {1, 2};
+  uint64_t unacked[] = {1, 2};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
-  std::vector<QuicPacketNumber> retransmittable;
+  std::vector<uint64_t> retransmittable;
   if (unacked_packets_.session_decides_what_to_write()) {
     retransmittable = {1, 2};
   } else {
@@ -287,13 +302,14 @@
   // Simulate a retransmittable packet being sent, retransmitted, and the first
   // transmission being acked.
   SerializedPacket packet1(CreateRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet1, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet1, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
   RetransmitAndSendPacket(1, 2, LOSS_RETRANSMISSION);
 
-  QuicPacketNumber unacked[] = {1, 2};
+  uint64_t unacked[] = {1, 2};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
-  std::vector<QuicPacketNumber> retransmittable;
+  std::vector<uint64_t> retransmittable;
   if (unacked_packets_.session_decides_what_to_write()) {
     retransmittable = {1, 2};
   } else {
@@ -302,23 +318,23 @@
   VerifyRetransmittablePackets(&retransmittable[0], retransmittable.size());
 
   EXPECT_CALL(notifier_, IsFrameOutstanding(_)).WillRepeatedly(Return(false));
-  unacked_packets_.RemoveRetransmittability(1);
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(1));
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyRetransmittablePackets(nullptr, 0);
 
-  unacked_packets_.IncreaseLargestAcked(2);
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyRetransmittablePackets(nullptr, 0);
 
-  unacked_packets_.RemoveFromInFlight(2);
-  QuicPacketNumber unacked2[] = {1};
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  uint64_t unacked2[] = {1};
   VerifyUnackedPackets(unacked2, QUIC_ARRAYSIZE(unacked2));
   VerifyInFlightPackets(unacked2, QUIC_ARRAYSIZE(unacked2));
   VerifyRetransmittablePackets(nullptr, 0);
 
-  unacked_packets_.RemoveFromInFlight(1);
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
   VerifyUnackedPackets(nullptr, 0);
   VerifyInFlightPackets(nullptr, 0);
   VerifyRetransmittablePackets(nullptr, 0);
@@ -327,31 +343,34 @@
 TEST_P(QuicUnackedPacketMapTest, RetransmitThreeTimes) {
   // Simulate a retransmittable packet being sent and retransmitted twice.
   SerializedPacket packet1(CreateRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet1, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet1, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
   SerializedPacket packet2(CreateRetransmittablePacket(2));
-  unacked_packets_.AddSentPacket(&packet2, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet2, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
 
-  QuicPacketNumber unacked[] = {1, 2};
+  uint64_t unacked[] = {1, 2};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
-  QuicPacketNumber retransmittable[] = {1, 2};
+  uint64_t retransmittable[] = {1, 2};
   VerifyRetransmittablePackets(retransmittable,
                                QUIC_ARRAYSIZE(retransmittable));
 
   // Early retransmit 1 as 3 and send new data as 4.
-  unacked_packets_.IncreaseLargestAcked(2);
-  unacked_packets_.RemoveFromInFlight(2);
-  unacked_packets_.RemoveRetransmittability(2);
-  unacked_packets_.RemoveFromInFlight(1);
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
   RetransmitAndSendPacket(1, 3, LOSS_RETRANSMISSION);
   SerializedPacket packet4(CreateRetransmittablePacket(4));
-  unacked_packets_.AddSentPacket(&packet4, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet4, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
 
-  QuicPacketNumber unacked2[] = {1, 3, 4};
+  uint64_t unacked2[] = {1, 3, 4};
   VerifyUnackedPackets(unacked2, QUIC_ARRAYSIZE(unacked2));
-  QuicPacketNumber pending2[] = {3, 4};
+  uint64_t pending2[] = {3, 4};
   VerifyInFlightPackets(pending2, QUIC_ARRAYSIZE(pending2));
-  std::vector<QuicPacketNumber> retransmittable2;
+  std::vector<uint64_t> retransmittable2;
   if (unacked_packets_.session_decides_what_to_write()) {
     retransmittable2 = {1, 3, 4};
   } else {
@@ -360,15 +379,16 @@
   VerifyRetransmittablePackets(&retransmittable2[0], retransmittable2.size());
 
   // Early retransmit 3 (formerly 1) as 5, and remove 1 from unacked.
-  unacked_packets_.IncreaseLargestAcked(4);
-  unacked_packets_.RemoveFromInFlight(4);
-  unacked_packets_.RemoveRetransmittability(4);
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(4));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(4));
   RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
   SerializedPacket packet6(CreateRetransmittablePacket(6));
-  unacked_packets_.AddSentPacket(&packet6, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet6, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
 
-  std::vector<QuicPacketNumber> unacked3;
-  std::vector<QuicPacketNumber> retransmittable3;
+  std::vector<uint64_t> unacked3;
+  std::vector<uint64_t> retransmittable3;
   if (unacked_packets_.session_decides_what_to_write()) {
     unacked3 = {3, 5, 6};
     retransmittable3 = {3, 5, 6};
@@ -378,17 +398,17 @@
   }
   VerifyUnackedPackets(&unacked3[0], unacked3.size());
   VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size());
-  QuicPacketNumber pending3[] = {3, 5, 6};
+  uint64_t pending3[] = {3, 5, 6};
   VerifyInFlightPackets(pending3, QUIC_ARRAYSIZE(pending3));
 
   // Early retransmit 5 as 7 and ensure in flight packet 3 is not removed.
-  unacked_packets_.IncreaseLargestAcked(6);
-  unacked_packets_.RemoveFromInFlight(6);
-  unacked_packets_.RemoveRetransmittability(6);
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(6));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(6));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(6));
   RetransmitAndSendPacket(5, 7, LOSS_RETRANSMISSION);
 
-  std::vector<QuicPacketNumber> unacked4;
-  std::vector<QuicPacketNumber> retransmittable4;
+  std::vector<uint64_t> unacked4;
+  std::vector<uint64_t> retransmittable4;
   if (unacked_packets_.session_decides_what_to_write()) {
     unacked4 = {3, 5, 7};
     retransmittable4 = {3, 5, 7};
@@ -398,42 +418,44 @@
   }
   VerifyUnackedPackets(&unacked4[0], unacked4.size());
   VerifyRetransmittablePackets(&retransmittable4[0], retransmittable4.size());
-  QuicPacketNumber pending4[] = {3, 5, 7};
+  uint64_t pending4[] = {3, 5, 7};
   VerifyInFlightPackets(pending4, QUIC_ARRAYSIZE(pending4));
 
   // Remove the older two transmissions from in flight.
-  unacked_packets_.RemoveFromInFlight(3);
-  unacked_packets_.RemoveFromInFlight(5);
-  QuicPacketNumber pending5[] = {7};
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
+  uint64_t pending5[] = {7};
   VerifyInFlightPackets(pending5, QUIC_ARRAYSIZE(pending5));
 }
 
 TEST_P(QuicUnackedPacketMapTest, RetransmitFourTimes) {
   // Simulate a retransmittable packet being sent and retransmitted twice.
   SerializedPacket packet1(CreateRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet1, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet1, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
   SerializedPacket packet2(CreateRetransmittablePacket(2));
-  unacked_packets_.AddSentPacket(&packet2, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet2, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
 
-  QuicPacketNumber unacked[] = {1, 2};
+  uint64_t unacked[] = {1, 2};
   VerifyUnackedPackets(unacked, QUIC_ARRAYSIZE(unacked));
   VerifyInFlightPackets(unacked, QUIC_ARRAYSIZE(unacked));
-  QuicPacketNumber retransmittable[] = {1, 2};
+  uint64_t retransmittable[] = {1, 2};
   VerifyRetransmittablePackets(retransmittable,
                                QUIC_ARRAYSIZE(retransmittable));
 
   // Early retransmit 1 as 3.
-  unacked_packets_.IncreaseLargestAcked(2);
-  unacked_packets_.RemoveFromInFlight(2);
-  unacked_packets_.RemoveRetransmittability(2);
-  unacked_packets_.RemoveFromInFlight(1);
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(2));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(2));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(1));
   RetransmitAndSendPacket(1, 3, LOSS_RETRANSMISSION);
 
-  QuicPacketNumber unacked2[] = {1, 3};
+  uint64_t unacked2[] = {1, 3};
   VerifyUnackedPackets(unacked2, QUIC_ARRAYSIZE(unacked2));
-  QuicPacketNumber pending2[] = {3};
+  uint64_t pending2[] = {3};
   VerifyInFlightPackets(pending2, QUIC_ARRAYSIZE(pending2));
-  std::vector<QuicPacketNumber> retransmittable2;
+  std::vector<uint64_t> retransmittable2;
   if (unacked_packets_.session_decides_what_to_write()) {
     retransmittable2 = {1, 3};
   } else {
@@ -444,13 +466,14 @@
   // TLP 3 (formerly 1) as 4, and don't remove 1 from unacked.
   RetransmitAndSendPacket(3, 4, TLP_RETRANSMISSION);
   SerializedPacket packet5(CreateRetransmittablePacket(5));
-  unacked_packets_.AddSentPacket(&packet5, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet5, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
 
-  QuicPacketNumber unacked3[] = {1, 3, 4, 5};
+  uint64_t unacked3[] = {1, 3, 4, 5};
   VerifyUnackedPackets(unacked3, QUIC_ARRAYSIZE(unacked3));
-  QuicPacketNumber pending3[] = {3, 4, 5};
+  uint64_t pending3[] = {3, 4, 5};
   VerifyInFlightPackets(pending3, QUIC_ARRAYSIZE(pending3));
-  std::vector<QuicPacketNumber> retransmittable3;
+  std::vector<uint64_t> retransmittable3;
   if (unacked_packets_.session_decides_what_to_write()) {
     retransmittable3 = {1, 3, 4, 5};
   } else {
@@ -459,23 +482,23 @@
   VerifyRetransmittablePackets(&retransmittable3[0], retransmittable3.size());
 
   // Early retransmit 4 as 6 and ensure in flight packet 3 is removed.
-  unacked_packets_.IncreaseLargestAcked(5);
-  unacked_packets_.RemoveFromInFlight(5);
-  unacked_packets_.RemoveRetransmittability(5);
-  unacked_packets_.RemoveFromInFlight(3);
-  unacked_packets_.RemoveFromInFlight(4);
+  unacked_packets_.IncreaseLargestAcked(QuicPacketNumber(5));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(5));
+  unacked_packets_.RemoveRetransmittability(QuicPacketNumber(5));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(3));
+  unacked_packets_.RemoveFromInFlight(QuicPacketNumber(4));
   RetransmitAndSendPacket(4, 6, LOSS_RETRANSMISSION);
 
-  std::vector<QuicPacketNumber> unacked4;
+  std::vector<uint64_t> unacked4;
   if (unacked_packets_.session_decides_what_to_write()) {
     unacked4 = {4, 6};
   } else {
     unacked4 = {4, 6};
   }
   VerifyUnackedPackets(&unacked4[0], unacked4.size());
-  QuicPacketNumber pending4[] = {6};
+  uint64_t pending4[] = {6};
   VerifyInFlightPackets(pending4, QUIC_ARRAYSIZE(pending4));
-  std::vector<QuicPacketNumber> retransmittable4;
+  std::vector<uint64_t> retransmittable4;
   if (unacked_packets_.session_decides_what_to_write()) {
     retransmittable4 = {4, 6};
   } else {
@@ -488,18 +511,20 @@
   // Simulate a retransmittable packet being sent, retransmitted, and the first
   // transmission being acked.
   SerializedPacket packet1(CreateRetransmittablePacket(1));
-  unacked_packets_.AddSentPacket(&packet1, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet1, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
   SerializedPacket packet3(CreateRetransmittablePacket(3));
-  unacked_packets_.AddSentPacket(&packet3, 0, NOT_RETRANSMISSION, now_, true);
+  unacked_packets_.AddSentPacket(&packet3, QuicPacketNumber(),
+                                 NOT_RETRANSMISSION, now_, true);
   RetransmitAndSendPacket(3, 5, LOSS_RETRANSMISSION);
 
-  EXPECT_EQ(1u, unacked_packets_.GetLeastUnacked());
-  EXPECT_TRUE(unacked_packets_.IsUnacked(1));
-  EXPECT_FALSE(unacked_packets_.IsUnacked(2));
-  EXPECT_TRUE(unacked_packets_.IsUnacked(3));
-  EXPECT_FALSE(unacked_packets_.IsUnacked(4));
-  EXPECT_TRUE(unacked_packets_.IsUnacked(5));
-  EXPECT_EQ(5u, unacked_packets_.largest_sent_packet());
+  EXPECT_EQ(QuicPacketNumber(1u), unacked_packets_.GetLeastUnacked());
+  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(1)));
+  EXPECT_FALSE(unacked_packets_.IsUnacked(QuicPacketNumber(2)));
+  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(3)));
+  EXPECT_FALSE(unacked_packets_.IsUnacked(QuicPacketNumber(4)));
+  EXPECT_TRUE(unacked_packets_.IsUnacked(QuicPacketNumber(5)));
+  EXPECT_EQ(QuicPacketNumber(5u), unacked_packets_.largest_sent_packet());
 }
 
 TEST_P(QuicUnackedPacketMapTest, AggregateContiguousAckedStreamFrames) {
diff --git a/net/third_party/quic/test_tools/quic_connection_peer.cc b/net/third_party/quic/test_tools/quic_connection_peer.cc
index 3b2d1d8..2443523e 100644
--- a/net/third_party/quic/test_tools/quic_connection_peer.cc
+++ b/net/third_party/quic/test_tools/quic_connection_peer.cc
@@ -275,9 +275,8 @@
 }
 
 // static
-bool QuicConnectionPeer::HasRetransmittableFrames(
-    QuicConnection* connection,
-    QuicPacketNumber packet_number) {
+bool QuicConnectionPeer::HasRetransmittableFrames(QuicConnection* connection,
+                                                  uint64_t packet_number) {
   return QuicSentPacketManagerPeer::HasRetransmittableFrames(
       GetSentPacketManager(connection), packet_number);
 }
diff --git a/net/third_party/quic/test_tools/quic_connection_peer.h b/net/third_party/quic/test_tools/quic_connection_peer.h
index 90d63ee..6aede1d 100644
--- a/net/third_party/quic/test_tools/quic_connection_peer.h
+++ b/net/third_party/quic/test_tools/quic_connection_peer.h
@@ -123,7 +123,7 @@
   static void SetAckDecimationDelay(QuicConnection* connection,
                                     float ack_decimation_delay);
   static bool HasRetransmittableFrames(QuicConnection* connection,
-                                       QuicPacketNumber packet_number);
+                                       uint64_t packet_number);
   static bool GetNoStopWaitingFrames(QuicConnection* connection);
   static void SetNoStopWaitingFrames(QuicConnection* connection,
                                      bool no_stop_waiting_frames);
diff --git a/net/third_party/quic/test_tools/quic_packet_creator_peer.cc b/net/third_party/quic/test_tools/quic_packet_creator_peer.cc
index c6a98c9..0d7e6f4 100644
--- a/net/third_party/quic/test_tools/quic_packet_creator_peer.cc
+++ b/net/third_party/quic/test_tools/quic_packet_creator_peer.cc
@@ -44,8 +44,14 @@
 }
 
 void QuicPacketCreatorPeer::SetPacketNumber(QuicPacketCreator* creator,
-                                            QuicPacketNumber s) {
-  creator->packet_.packet_number = s;
+                                            uint64_t s) {
+  DCHECK_NE(0u, s);
+  creator->packet_.packet_number = QuicPacketNumber(s);
+}
+
+// static
+void QuicPacketCreatorPeer::ClearPacketNumber(QuicPacketCreator* creator) {
+  creator->packet_.packet_number.Clear();
 }
 
 // static
diff --git a/net/third_party/quic/test_tools/quic_packet_creator_peer.h b/net/third_party/quic/test_tools/quic_packet_creator_peer.h
index 655e8dd..697995fe1d 100644
--- a/net/third_party/quic/test_tools/quic_packet_creator_peer.h
+++ b/net/third_party/quic/test_tools/quic_packet_creator_peer.h
@@ -27,7 +27,8 @@
       QuicPacketNumberLength packet_number_length);
   static QuicPacketNumberLength GetPacketNumberLength(
       QuicPacketCreator* creator);
-  static void SetPacketNumber(QuicPacketCreator* creator, QuicPacketNumber s);
+  static void SetPacketNumber(QuicPacketCreator* creator, uint64_t s);
+  static void ClearPacketNumber(QuicPacketCreator* creator);
   static void FillPacketHeader(QuicPacketCreator* creator,
                                QuicPacketHeader* header);
   static void CreateStreamFrame(QuicPacketCreator* creator,
diff --git a/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.cc b/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.cc
index 52813e9d..08ffe346 100644
--- a/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.cc
+++ b/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.cc
@@ -85,18 +85,19 @@
 // static
 bool QuicSentPacketManagerPeer::IsRetransmission(
     QuicSentPacketManager* sent_packet_manager,
-    QuicPacketNumber packet_number) {
+    uint64_t packet_number) {
   DCHECK(HasRetransmittableFrames(sent_packet_manager, packet_number));
   if (!HasRetransmittableFrames(sent_packet_manager, packet_number)) {
     return false;
   }
   if (sent_packet_manager->session_decides_what_to_write()) {
     return sent_packet_manager->unacked_packets_
-               .GetTransmissionInfo(packet_number)
+               .GetTransmissionInfo(QuicPacketNumber(packet_number))
                .transmission_type != NOT_RETRANSMISSION;
   }
   for (auto transmission_info : sent_packet_manager->unacked_packets_) {
-    if (transmission_info.retransmission == packet_number) {
+    if (transmission_info.retransmission.IsInitialized() &&
+        transmission_info.retransmission == QuicPacketNumber(packet_number)) {
       return true;
     }
   }
@@ -106,9 +107,10 @@
 // static
 void QuicSentPacketManagerPeer::MarkForRetransmission(
     QuicSentPacketManager* sent_packet_manager,
-    QuicPacketNumber packet_number,
+    uint64_t packet_number,
     TransmissionType transmission_type) {
-  sent_packet_manager->MarkForRetransmission(packet_number, transmission_type);
+  sent_packet_manager->MarkForRetransmission(QuicPacketNumber(packet_number),
+                                             transmission_type);
 }
 
 // static
@@ -198,16 +200,17 @@
 // static
 bool QuicSentPacketManagerPeer::IsUnacked(
     QuicSentPacketManager* sent_packet_manager,
-    QuicPacketNumber packet_number) {
-  return sent_packet_manager->unacked_packets_.IsUnacked(packet_number);
+    uint64_t packet_number) {
+  return sent_packet_manager->unacked_packets_.IsUnacked(
+      QuicPacketNumber(packet_number));
 }
 
 // static
 bool QuicSentPacketManagerPeer::HasRetransmittableFrames(
     QuicSentPacketManager* sent_packet_manager,
-    QuicPacketNumber packet_number) {
+    uint64_t packet_number) {
   return sent_packet_manager->unacked_packets_.HasRetransmittableFrames(
-      packet_number);
+      QuicPacketNumber(packet_number));
 }
 
 // static
diff --git a/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.h b/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.h
index 4aa02b8..28ded1d 100644
--- a/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.h
+++ b/net/third_party/quic/test_tools/quic_sent_packet_manager_peer.h
@@ -52,10 +52,10 @@
 
   // Returns true if |packet_number| is a retransmission of a packet.
   static bool IsRetransmission(QuicSentPacketManager* sent_packet_manager,
-                               QuicPacketNumber packet_number);
+                               uint64_t packet_number);
 
   static void MarkForRetransmission(QuicSentPacketManager* sent_packet_manager,
-                                    QuicPacketNumber packet_number,
+                                    uint64_t packet_number,
                                     TransmissionType transmission_type);
 
   static QuicTime::Delta GetRetransmissionDelay(
@@ -93,11 +93,11 @@
   static bool UsingPacing(const QuicSentPacketManager* sent_packet_manager);
 
   static bool IsUnacked(QuicSentPacketManager* sent_packet_manager,
-                        QuicPacketNumber packet_number);
+                        uint64_t packet_number);
 
   static bool HasRetransmittableFrames(
       QuicSentPacketManager* sent_packet_manager,
-      QuicPacketNumber packet_number);
+      uint64_t packet_number);
 
   static QuicUnackedPacketMap* GetUnackedPacketMap(
       QuicSentPacketManager* sent_packet_manager);
diff --git a/net/third_party/quic/test_tools/quic_test_utils.cc b/net/third_party/quic/test_tools/quic_test_utils.cc
index 47e3108..237fec7 100644
--- a/net/third_party/quic/test_tools/quic_test_utils.cc
+++ b/net/third_party/quic/test_tools/quic_test_utils.cc
@@ -66,7 +66,7 @@
   DCHECK_GT(ack_blocks.size(), 0u);
 
   QuicAckFrame ack;
-  QuicPacketNumber end_of_previous_block = 1;
+  QuicPacketNumber end_of_previous_block(1);
   for (const QuicAckBlock& block : ack_blocks) {
     DCHECK_GE(block.start, end_of_previous_block);
     DCHECK_GT(block.limit, block.start);
@@ -80,16 +80,21 @@
 }
 
 QuicAckFrame InitAckFrame(uint64_t largest_acked) {
-  return InitAckFrame({{1, largest_acked + 1}});
+  return InitAckFrame(QuicPacketNumber(largest_acked));
+}
+
+QuicAckFrame InitAckFrame(QuicPacketNumber largest_acked) {
+  return InitAckFrame({{QuicPacketNumber(1), largest_acked + 1}});
 }
 
 QuicAckFrame MakeAckFrameWithAckBlocks(size_t num_ack_blocks,
                                        uint64_t least_unacked) {
   QuicAckFrame ack;
-  ack.largest_acked = 2 * num_ack_blocks + least_unacked;
+  ack.largest_acked = QuicPacketNumber(2 * num_ack_blocks + least_unacked);
   // Add enough received packets to get num_ack_blocks ack blocks.
-  for (QuicPacketNumber i = 2; i < 2 * num_ack_blocks + 1; i += 2) {
-    ack.packets.Add(least_unacked + i);
+  for (QuicPacketNumber i = QuicPacketNumber(2);
+       i < QuicPacketNumber(2 * num_ack_blocks + 1); i += 2) {
+    ack.packets.Add(i + least_unacked);
   }
   return ack;
 }
@@ -464,7 +469,7 @@
   // Transfer ownership of the packet to the SentPacketManager and the
   // ack notifier to the AckNotifierManager.
   QuicConnectionPeer::GetSentPacketManager(this)->OnPacketSent(
-      packet, 0, QuicTime::Zero(), NOT_RETRANSMISSION,
+      packet, QuicPacketNumber(), QuicTime::Zero(), NOT_RETRANSMISSION,
       HAS_RETRANSMITTABLE_DATA);
 }
 
@@ -847,7 +852,7 @@
   header.version_flag = version_flag;
   header.reset_flag = reset_flag;
   header.packet_number_length = packet_number_length;
-  header.packet_number = packet_number;
+  header.packet_number = QuicPacketNumber(packet_number);
   QuicFrame frame(QuicStreamFrame(
       QuicUtils::GetCryptoStreamId(
           versions != nullptr
@@ -864,8 +869,9 @@
       BuildUnsizedDataPacket(&framer, header, frames));
   EXPECT_TRUE(packet != nullptr);
   char* buffer = new char[kMaxPacketSize];
-  size_t encrypted_length = framer.EncryptPayload(
-      ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize);
+  size_t encrypted_length =
+      framer.EncryptPayload(ENCRYPTION_NONE, QuicPacketNumber(packet_number),
+                            *packet, buffer, kMaxPacketSize);
   EXPECT_NE(0u, encrypted_length);
   return new QuicEncryptedPacket(buffer, encrypted_length, true);
 }
@@ -899,7 +905,7 @@
   header.version_flag = version_flag;
   header.reset_flag = reset_flag;
   header.packet_number_length = packet_number_length;
-  header.packet_number = packet_number;
+  header.packet_number = QuicPacketNumber(packet_number);
   QuicFrame frame(QuicStreamFrame(1, false, 0, QuicStringPiece(data)));
   QuicFrames frames;
   frames.push_back(frame);
@@ -918,8 +924,9 @@
       false /* no diversification nonce */, packet_number_length)] = 0x1F;
 
   char* buffer = new char[kMaxPacketSize];
-  size_t encrypted_length = framer.EncryptPayload(
-      ENCRYPTION_NONE, packet_number, *packet, buffer, kMaxPacketSize);
+  size_t encrypted_length =
+      framer.EncryptPayload(ENCRYPTION_NONE, QuicPacketNumber(packet_number),
+                            *packet, buffer, kMaxPacketSize);
   EXPECT_NE(0u, encrypted_length);
   return new QuicEncryptedPacket(buffer, encrypted_length, true);
 }
diff --git a/net/third_party/quic/test_tools/quic_test_utils.h b/net/third_party/quic/test_tools/quic_test_utils.h
index b9940d60..7841910 100644
--- a/net/third_party/quic/test_tools/quic_test_utils.h
+++ b/net/third_party/quic/test_tools/quic_test_utils.h
@@ -196,6 +196,7 @@
 // Testing convenience method to construct a QuicAckFrame with 1 ack block which
 // covers packet number range [1, |largest_acked| + 1).
 // Equivalent to InitAckFrame({{1, largest_acked + 1}})
+QuicAckFrame InitAckFrame(uint64_t largest_acked);
 QuicAckFrame InitAckFrame(QuicPacketNumber largest_acked);
 
 // Testing convenience method to construct a QuicAckFrame with |num_ack_blocks|