1- use base64 :: { prelude :: BASE64_STANDARD , Engine } ;
1+ use solana_packet :: PACKET_DATA_SIZE ;
22use solana_rpc_client:: rpc_client:: SerializableTransaction ;
33use static_assertions:: const_assert;
44
5- /// From agave rpc/src/rpc.rs [MAX_BASE64_SIZE]
6- pub ( crate ) const MAX_ENCODED_TRANSACTION_SIZE : usize = 1644 ;
5+ /// Maximum serialized transaction size that can be sent over the wire.
6+ pub ( crate ) const MAX_TRANSACTION_WIRE_SIZE : usize = PACKET_DATA_SIZE ;
77
88/// How many process and commit buffer instructions fit into a single transaction
99#[ allow( unused) ] // serves as documentation as well
@@ -34,7 +34,7 @@ pub const MAX_PROCESS_AND_CLOSE_PER_TX: u8 = 2;
3434/// close buffer instructions fit into a single transaction when
3535/// using lookup tables but not including the buffer account
3636#[ allow( unused) ] // serves as documentation as well
37- pub const MAX_PROCESS_AND_CLOSE_PER_TX_USING_LOOKUP : u8 = 5 ;
37+ pub const MAX_PROCESS_AND_CLOSE_PER_TX_USING_LOOKUP : u8 = 4 ;
3838
3939/// How many finalize instructions fit into a single transaction
4040#[ allow( unused) ] // serves as documentation as well
@@ -54,7 +54,7 @@ pub const MAX_UNDELEGATE_PER_TX: u8 = 3;
5454/// when using address lookup tables
5555/// NOTE: that we assume the rent reimbursement account to be the delegated account
5656#[ allow( unused) ] // serves as documentation as well
57- pub const MAX_UNDELEGATE_PER_TX_USING_LOOKUP : u8 = 16 ;
57+ pub const MAX_UNDELEGATE_PER_TX_USING_LOOKUP : u8 = 15 ;
5858
5959// Allows us to run undelegate instructions without rechunking them since we know
6060// that we didn't process more than we also can undelegate
@@ -66,12 +66,11 @@ const_assert!(
6666 MAX_PROCESS_PER_TX_USING_LOOKUP <= MAX_UNDELEGATE_PER_TX_USING_LOOKUP
6767) ;
6868
69- pub fn serialize_and_encode_base64 (
69+ pub fn serialized_transaction_size (
7070 transaction : & impl SerializableTransaction ,
71- ) -> String {
72- // SAFETY: runs statically
73- let serialized = bincode:: serialize ( transaction) . unwrap ( ) ;
74- BASE64_STANDARD . encode ( serialized)
71+ ) -> usize {
72+ // SAFETY: runs on transactions we already serialize before sending.
73+ usize:: try_from ( bincode:: serialized_size ( transaction) . unwrap ( ) ) . unwrap ( )
7574}
7675
7776#[ cfg( test) ]
@@ -131,7 +130,7 @@ mod test {
131130 NoLookupTable ,
132131 UseLookupTable ,
133132 }
134- fn encoded_tx_size (
133+ fn transaction_wire_size (
135134 auth : & Keypair ,
136135 ixs : & [ Instruction ] ,
137136 opts : & TransactionOpts ,
@@ -165,8 +164,7 @@ mod test {
165164 )
166165 } ) ?;
167166
168- let encoded = serialize_and_encode_base64 ( & versioned_tx) ;
169- Ok ( encoded. len ( ) )
167+ Ok ( serialized_transaction_size ( & versioned_tx) )
170168 }
171169
172170 // -----------------
@@ -309,7 +307,7 @@ mod test {
309307 . collect :: < Vec < _ > > ( ) ;
310308
311309 let tx_size =
312- encoded_tx_size ( auth, & ixs, & tx_opts) . unwrap ( ) ;
310+ transaction_wire_size ( auth, & ixs, & tx_opts) . unwrap ( ) ;
313311 tx_sizes. push ( ( size, tx_size) ) ;
314312 }
315313 tx_lines. push ( tx_sizes) ;
@@ -349,51 +347,8 @@ mod test {
349347 run ( auth, 10 ) ;
350348 run ( auth, 15 ) ;
351349 run ( auth, 20 ) ;
352- /*
353- 0 ixs:
354- 0: 184| 10: 184| 20: 184| 50: 184| 100: 184| 200: 184| 500: 184|1024: 184
355- 0: 184| 10: 184| 20: 184| 50: 184| 100: 184| 200: 184| 500: 184|1024: 184
356- 1 ixs:
357- 0: 620| 10: 636| 20: 648| 50: 688| 100: 756| 200: 888| 500: 1288|1024: 1988
358- 0: 336| 10: 348| 20: 364| 50: 404| 100: 472| 200: 604| 500: 1004|1024: 1704
359- 2 ixs:
360- 0: 932| 10: 960| 20: 984| 50: 1064| 100: 1200| 200: 1468| 500: 2268|1024: 3664
361- 0: 400| 10: 424| 20: 452| 50: 532| 100: 668| 200: 936| 500: 1736|1024: 3132
362- 5 ixs:
363- 0: 1864| 10: 1932| 20: 1996| 50: 2196| 100: 2536| 200: 3204| 500: 5204|1024: 8696
364- 0: 588| 10: 652| 20: 720| 50: 920| 100: 1260| 200: 1928| 500: 3928|1024: 7420
365- 8 ixs:
366- 0: 2796| 10: 2904| 20: 3008| 50: 3328| 100: 3872| 200: 4940| 500: 8140|1024:13728
367- 0: 776| 10: 880| 20: 988| 50: 1308| 100: 1852| 200: 2920| 500: 6120|1024:11708
368- 10 ixs:
369- 0: 3416| 10: 3552| 20: 3684| 50: 4084| 100: 4764| 200: 6096| 500:10096|1024:17084
370- 0: 900| 10: 1032| 20: 1168| 50: 1568| 100: 2248| 200: 3580| 500: 7580|1024:14568
371- 15 ixs:
372- 0: 4972| 10: 5172| 20: 5372| 50: 5972| 100: 6992| 200: 8992| 500:14992|1024:25472
373- 0: 1212| 10: 1412| 20: 1612| 50: 2212| 100: 3232| 200: 5232| 500:11232|1024:21712
374- 20 ixs:
375- 0: 6524| 10: 6792| 20: 7056| 50: 7856| 100: 9216| 200:11884| 500:19884|1024:33856
376- 0: 1528| 10: 1792| 20: 2060| 50: 2860| 100: 4220| 200: 6888| 500:14888|1024:28860
377-
378- Legend:
379-
380- x ixs:
381- data size/ix: encoded size | ...
382- data size/ix: encoded size | ... (using lookup tables)
383-
384- Given that max transaction size is 1644 bytes, we can see that the max data size is:
385-
386- - 1 ixs: slightly larger than 500 bytes
387- - 2 ixs: slightly larger than 200 bytes
388- - 5 ixs: slightly larger than 100 bytes
389- - 8 ixs: slightly larger than 50 bytes
390- - 10 ixs: slightly larger than 20 bytes
391- - 15 ixs: slightly larger than 10 bytes
392- - 20 ixs: no data supported (only lamport changes)
393-
394- Also it is clear that using a lookup table makes a huge difference especially if we commit
395- lots of different accounts.
396- */
350+ // This logs raw wire sizes. The sendability limit is
351+ // MAX_TRANSACTION_WIRE_SIZE.
397352 }
398353
399354 // -----------------
@@ -573,13 +528,13 @@ mod test {
573528 & [ & auth] ,
574529 )
575530 . unwrap ( ) ;
576- let encoded = serialize_and_encode_base64 ( & versioned_tx) ;
531+ let tx_size = serialized_transaction_size ( & versioned_tx) ;
577532 info ! (
578533 chunks = chunks,
579- size_bytes = encoded . len ( ) ,
534+ size_bytes = tx_size ,
580535 "Transaction size measured"
581536 ) ;
582- if encoded . len ( ) > MAX_ENCODED_TRANSACTION_SIZE {
537+ if tx_size > MAX_TRANSACTION_WIRE_SIZE {
583538 return chunks - 1 ;
584539 }
585540 }
@@ -662,13 +617,13 @@ mod test {
662617 & [ & auth] ,
663618 )
664619 . unwrap ( ) ;
665- let encoded = serialize_and_encode_base64 ( & versioned_tx) ;
620+ let tx_size = serialized_transaction_size ( & versioned_tx) ;
666621 info ! (
667622 chunks = chunks,
668- size_bytes = encoded . len ( ) ,
623+ size_bytes = tx_size ,
669624 "Transaction size measured with lookup table"
670625 ) ;
671- if encoded . len ( ) > MAX_ENCODED_TRANSACTION_SIZE {
626+ if tx_size > MAX_TRANSACTION_WIRE_SIZE {
672627 return chunks - 1 ;
673628 }
674629 }
0 commit comments