From 1899e603ebf036b2d0ea0728907bd6f8ffc26406 Mon Sep 17 00:00:00 2001
From: Jon Cinque <jon.cinque@gmail.com>
Date: Mon, 24 Oct 2022 20:19:43 -0400
Subject: [PATCH] feat: double PACKET_DATA_SIZE

---
 rpc/src/rpc.rs                       | 17 ++++++++++++-----
 sdk/src/packet.rs                    |  3 ++-
 web3.js/src/transaction/constants.ts |  4 +++-
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/rpc/src/rpc.rs b/rpc/src/rpc.rs
index 11838cf1bc..f429fc5abb 100644
--- a/rpc/src/rpc.rs
+++ b/rpc/src/rpc.rs
@@ -4415,8 +4415,11 @@ pub mod rpc_obsolete_v1_7 {
     }
 }
 
-const MAX_BASE58_SIZE: usize = 1683; // Golden, bump if PACKET_DATA_SIZE changes
-const MAX_BASE64_SIZE: usize = 1644; // Golden, bump if PACKET_DATA_SIZE changes
+// These values need to be updated if PACKET_DATA_SIZE changes. The correct values can
+// be found by hand or by simply encoding `PACKET_DATA_SIZE` bytes and checking length.
+// `test_max_encoded_tx_goldens` ensures these values are correct.
+const MAX_BASE58_SIZE: usize = 3365;
+const MAX_BASE64_SIZE: usize = 3288;
 fn decode_and_deserialize<T>(
     encoded: String,
     encoding: TransactionBinaryEncoding,
@@ -8376,7 +8379,7 @@ pub mod tests {
     }
 
     #[test]
-    fn test_worst_case_encoded_tx_goldens() {
+    fn test_max_encoded_tx_goldens() {
         let ff_tx = vec![0xffu8; PACKET_DATA_SIZE];
         let tx58 = bs58::encode(&ff_tx).into_string();
         assert_eq!(tx58.len(), MAX_BASE58_SIZE);
@@ -8386,8 +8389,12 @@ pub mod tests {
 
     #[test]
     fn test_decode_and_deserialize_too_large_payloads_fail() {
-        // +2 because +1 still fits in base64 encoded worst-case
-        let too_big = PACKET_DATA_SIZE + 2;
+        // 4 base64 digits are generated from groups of 3 bytes; however, those 4 digits
+        // are generated even if the group only has 1 or 2 bytes.
+        // So, we need 4 - (PACKET_DATA_SIZE % 3) extra bytes to ensure we'll spill over
+        let extra_bytes = 4 - (PACKET_DATA_SIZE % 3);
+        let too_big = PACKET_DATA_SIZE + extra_bytes;
+
         let tx_ser = vec![0xffu8; too_big];
 
         let tx58 = bs58::encode(&tx_ser).into_string();
diff --git a/sdk/src/packet.rs b/sdk/src/packet.rs
index 08389860f9..12714028d7 100644
--- a/sdk/src/packet.rs
+++ b/sdk/src/packet.rs
@@ -15,7 +15,8 @@ static_assertions::const_assert_eq!(PACKET_DATA_SIZE, 1232);
 ///   1280 is IPv6 minimum MTU
 ///   40 bytes is the size of the IPv6 header
 ///   8 bytes is the size of the fragment header
-pub const PACKET_DATA_SIZE: usize = 1280 - 40 - 8;
+/// Double the minimum to support larger than MTU transactions
+pub const PACKET_DATA_SIZE: usize = 2 * (1280 - 40 - 8);
 
 bitflags! {
     #[repr(C)]
diff --git a/web3.js/src/transaction/constants.ts b/web3.js/src/transaction/constants.ts
index 075337e8dc..3d4960464f 100644
--- a/web3.js/src/transaction/constants.ts
+++ b/web3.js/src/transaction/constants.ts
@@ -4,8 +4,10 @@
  * 1280 is IPv6 minimum MTU
  * 40 bytes is the size of the IPv6 header
  * 8 bytes is the size of the fragment header
+ *
+ * Double the minimum for larger transactions
  */
-export const PACKET_DATA_SIZE = 1280 - 40 - 8;
+export const PACKET_DATA_SIZE = 2 * (1280 - 40 - 8);
 
 export const VERSION_PREFIX_MASK = 0x7f;
 
-- 
2.38.1

