@@ -4989,6 +4989,165 @@ mod tests {
49894989 ) ;
49904990 }
49914991
4992+ /// Helper: completes a noise handshake and returns the outbound encryptor ready for encryption.
4993+ fn get_test_encryptor ( ) -> PeerChannelEncryptor {
4994+ use crate :: ln:: peer_channel_encryptor:: PeerChannelEncryptor ;
4995+ use bitcoin:: secp256k1:: { Secp256k1 , SecretKey } ;
4996+
4997+ let secp_ctx = Secp256k1 :: new ( ) ;
4998+ // Inbound peer identity (the "responder").
4999+ let inbound_secret = SecretKey :: from_slice ( & [ 42 ; 32 ] ) . unwrap ( ) ;
5000+ let inbound_pubkey =
5001+ bitcoin:: secp256k1:: PublicKey :: from_secret_key ( & secp_ctx, & inbound_secret) ;
5002+ let inbound_signer = crate :: util:: test_utils:: TestNodeSigner :: new ( inbound_secret) ;
5003+
5004+ // Outbound peer identity (the "initiator").
5005+ let outbound_secret = SecretKey :: from_slice ( & [ 43 ; 32 ] ) . unwrap ( ) ;
5006+ let outbound_signer = crate :: util:: test_utils:: TestNodeSigner :: new ( outbound_secret) ;
5007+
5008+ let outbound_ephemeral = SecretKey :: from_slice ( & [ 44 ; 32 ] ) . unwrap ( ) ;
5009+ let inbound_ephemeral = SecretKey :: from_slice ( & [ 45 ; 32 ] ) . unwrap ( ) ;
5010+
5011+ let mut outbound = PeerChannelEncryptor :: new_outbound ( inbound_pubkey, outbound_ephemeral) ;
5012+ let mut inbound = PeerChannelEncryptor :: new_inbound ( & & inbound_signer) ;
5013+
5014+ let act_one = outbound. get_act_one ( & secp_ctx) ;
5015+ let act_two = inbound
5016+ . process_act_one_with_keys ( & act_one, & & inbound_signer, inbound_ephemeral, & secp_ctx)
5017+ . unwrap ( ) ;
5018+ let ( act_three, _) = outbound. process_act_two ( & act_two, & & outbound_signer) . unwrap ( ) ;
5019+ let _ = inbound. process_act_three ( & act_three) . unwrap ( ) ;
5020+
5021+ outbound
5022+ }
5023+
5024+ #[ test]
5025+ fn test_chunked_message_queue_ping_padding ( ) {
5026+ // Tests that Ping padding correctly fills the remainder of a chunk.
5027+ let mut encryptor = get_test_encryptor ( ) ;
5028+
5029+ // Test various remainder sizes to ensure padding works correctly.
5030+ for msg_size in [ 40 , 100 , 500 , 1000 , 5000 , 30000 , 65535 ] {
5031+ let mut queue = ChunkedMessageQueue :: new ( ) ;
5032+ // Push a raw blob of msg_size bytes to simulate encrypted message data.
5033+ let fake_data = vec ! [ 0u8 ; msg_size] ;
5034+ queue. buffer . extend_from_slice ( & fake_data) ;
5035+ queue. pending_msg_bytes += msg_size;
5036+
5037+ queue. pad_and_finalize_chunk ( & mut encryptor) ;
5038+ assert_eq ! (
5039+ queue. pending_bytes( ) % CHUNK_SIZE ,
5040+ 0 ,
5041+ "Buffer not chunk-aligned after padding for msg_size={}" ,
5042+ msg_size
5043+ ) ;
5044+ assert ! (
5045+ queue. pending_bytes( ) >= CHUNK_SIZE ,
5046+ "Buffer should be at least one chunk for msg_size={}" ,
5047+ msg_size
5048+ ) ;
5049+ }
5050+ }
5051+
5052+ #[ test]
5053+ fn test_chunked_message_queue_small_remainder_overflow ( ) {
5054+ // Tests the edge case where remainder < MIN_ENCRYPTED_PING_SIZE, requiring two Pings.
5055+ let mut encryptor = get_test_encryptor ( ) ;
5056+
5057+ // Test remainders from 1 to MIN_ENCRYPTED_PING_SIZE-1 (the overflow cases).
5058+ for remainder in 1 ..MIN_ENCRYPTED_PING_SIZE {
5059+ let mut queue = ChunkedMessageQueue :: new ( ) ;
5060+ // Fill buffer so that exactly `remainder` bytes are left in the current chunk.
5061+ let fill_size = CHUNK_SIZE - remainder;
5062+ queue. buffer . resize ( fill_size, 0 ) ;
5063+ queue. pending_msg_bytes = fill_size;
5064+
5065+ queue. pad_and_finalize_chunk ( & mut encryptor) ;
5066+ assert_eq ! (
5067+ queue. pending_bytes( ) % CHUNK_SIZE ,
5068+ 0 ,
5069+ "Buffer not chunk-aligned for remainder={}" ,
5070+ remainder
5071+ ) ;
5072+ // Should overflow into exactly 2 chunks.
5073+ assert_eq ! (
5074+ queue. pending_bytes( ) ,
5075+ 2 * CHUNK_SIZE ,
5076+ "Expected 2 chunks for small remainder={}" ,
5077+ remainder
5078+ ) ;
5079+ }
5080+ }
5081+
5082+ #[ test]
5083+ fn test_chunked_message_queue_chunk_alignment ( ) {
5084+ // Tests that after multiple messages the buffer stays correctly aligned after padding.
5085+ let mut encryptor = get_test_encryptor ( ) ;
5086+ let mut queue = ChunkedMessageQueue :: new ( ) ;
5087+
5088+ // Encrypt several Ping messages of various sizes.
5089+ for pong_len in [ 0u16 , 64 , 256 , 1024 ] {
5090+ let ping = msgs:: Ping { ponglen : pong_len, byteslen : 64 } ;
5091+ let msg: wire:: Message < ( ) > = wire:: Message :: Ping ( ping) ;
5092+ queue. encrypt_and_push_message ( & mut encryptor, msg) ;
5093+ }
5094+
5095+ let pending_before_pad = queue. pending_bytes ( ) ;
5096+ assert ! ( pending_before_pad > 0 ) ;
5097+
5098+ queue. pad_and_finalize_chunk ( & mut encryptor) ;
5099+
5100+ assert_eq ! ( queue. pending_bytes( ) % CHUNK_SIZE , 0 ) ;
5101+ assert ! ( queue. pending_bytes( ) >= pending_before_pad) ;
5102+ }
5103+
5104+ #[ test]
5105+ fn test_chunked_message_queue_buffer_compaction ( ) {
5106+ // Tests that maybe_compact drains sent bytes appropriately.
5107+ let mut queue = ChunkedMessageQueue :: new ( ) ;
5108+
5109+ // Fill with 2 chunks worth of data.
5110+ queue. buffer . resize ( 2 * CHUNK_SIZE , 0xAB ) ;
5111+ queue. pending_msg_bytes = 2 * CHUNK_SIZE ;
5112+ assert_eq ! ( queue. pending_bytes( ) , 2 * CHUNK_SIZE ) ;
5113+
5114+ // Simulate sending the first chunk.
5115+ queue. send_offset = CHUNK_SIZE ;
5116+ queue. pending_msg_bytes = CHUNK_SIZE ;
5117+ queue. maybe_compact ( ) ;
5118+
5119+ // After compaction, send_offset should be 0 and buffer should be one chunk.
5120+ assert_eq ! ( queue. send_offset, 0 ) ;
5121+ assert_eq ! ( queue. buffer. len( ) , CHUNK_SIZE ) ;
5122+ assert_eq ! ( queue. pending_bytes( ) , CHUNK_SIZE ) ;
5123+ }
5124+
5125+ #[ test]
5126+ fn test_chunked_message_queue_pending_msg_bytes_tracking ( ) {
5127+ // Tests that pending_msg_bytes correctly tracks message bytes vs padding bytes.
5128+ let mut encryptor = get_test_encryptor ( ) ;
5129+ let mut queue = ChunkedMessageQueue :: new ( ) ;
5130+
5131+ // Encrypt a small message.
5132+ let ping = msgs:: Ping { ponglen : 0 , byteslen : 64 } ;
5133+ let msg: wire:: Message < ( ) > = wire:: Message :: Ping ( ping) ;
5134+ queue. encrypt_and_push_message ( & mut encryptor, msg) ;
5135+
5136+ let msg_bytes = queue. pending_msg_bytes ;
5137+ assert ! ( msg_bytes > 0 ) ;
5138+ assert_eq ! ( msg_bytes, queue. pending_bytes( ) ) ;
5139+
5140+ // After padding, pending_bytes increases but pending_msg_bytes stays the same.
5141+ queue. pad_and_finalize_chunk ( & mut encryptor) ;
5142+
5143+ assert_eq ! ( queue. pending_msg_bytes, msg_bytes) ;
5144+ assert ! ( queue. pending_bytes( ) > msg_bytes) ;
5145+ assert_eq ! ( queue. pending_bytes( ) % CHUNK_SIZE , 0 ) ;
5146+
5147+ // total_buffered_bytes should use pending_msg_bytes, not pending_bytes.
5148+ assert_eq ! ( queue. total_buffered_bytes( ) , msg_bytes) ;
5149+ }
5150+
49925151 #[ test]
49935152 fn test_filter_addresses ( ) {
49945153 // Tests the filter_addresses function.
0 commit comments