@@ -7048,3 +7048,109 @@ def test_htlc_tlv_crash(node_factory):
70487048
70497049    l1 .rpc .waitsendpay (inv1 ['payment_hash' ], TIMEOUT )
70507050    l1 .rpc .waitsendpay (inv2 ['payment_hash' ], TIMEOUT )
7051+ 
7052+ 
7053+ @pytest .mark .openchannel ('v1' ) 
7054+ @pytest .mark .openchannel ('v2' ) 
7055+ def  test_bolt11_annotation_persistence (node_factory ):
7056+     """Test that HTLCs maintain proper linkage to payment records with BOLT11.""" 
7057+     l1 , l2  =  node_factory .line_graph (2 )
7058+ 
7059+     inv  =  l2 .rpc .invoice (100000 , 'test_annotation' , 'Test Description' )['bolt11' ]
7060+     l1 .dev_pay (inv , dev_use_shadow = False )
7061+ 
7062+     payments  =  l1 .rpc .listpays ()['pays' ]
7063+     payment  =  [p  for  p  in  payments  if  p ['bolt11' ] ==  inv ][0 ]
7064+     payment_hash  =  payment ['payment_hash' ]
7065+ 
7066+     # Verify HTLCs have payment_id references 
7067+     htlcs  =  l1 .db_query (f""" 
7068+         SELECT payment_id, partid, groupid 
7069+         FROM channel_htlcs 
7070+         WHERE payment_hash = x'{ payment_hash }  
7071+     """ )
7072+     assert  len (htlcs ) >  0 
7073+ 
7074+     # Get payment records for verification 
7075+     payment_records  =  l1 .db_query (f""" 
7076+         SELECT id, partid, groupid 
7077+         FROM payments 
7078+         WHERE payment_hash = x'{ payment_hash }  
7079+     """ )
7080+     assert  len (payment_records ) >  0 
7081+ 
7082+     # Verify each HTLC links to correct payment record 
7083+     for  htlc  in  htlcs :
7084+         assert  htlc ['payment_id' ] is  not None 
7085+ 
7086+         # Find matching payment record 
7087+         matching_payments  =  [p  for  p  in  payment_records 
7088+                            if  p ['id' ] ==  htlc ['payment_id' ]
7089+                            and  p ['partid' ] ==  htlc ['partid' ]
7090+                            and  p ['groupid' ] ==  htlc ['groupid' ]]
7091+         assert  len (matching_payments ) ==  1 
7092+ 
7093+     # Verify payment_id index exists for performance 
7094+     indexes  =  l1 .db_query (""" 
7095+         SELECT name FROM sqlite_master 
7096+         WHERE type = 'index' AND name = 'channel_htlcs_payment_id_idx' 
7097+     """ )
7098+     assert  len (indexes ) ==  1 
7099+ 
7100+     l1 .restart ()
7101+ 
7102+     # After restart, verify BOLT11 annotation persistence 
7103+     payments_after  =  l1 .rpc .listpays ()['pays' ]
7104+     payment_after  =  [p  for  p  in  payments_after  if  p ['bolt11' ] ==  inv ]
7105+     assert  len (payment_after ) ==  1 
7106+ 
7107+     # Verify payment data integrity 
7108+     assert  payment_after [0 ]['payment_hash' ] ==  payment_hash 
7109+     assert  payment_after [0 ]['status' ] ==  'complete' 
7110+ 
7111+     # Verify HTLCs still have payment_id linkage after restart 
7112+     htlcs_after  =  l1 .db_query (f""" 
7113+         SELECT payment_id, partid, groupid 
7114+         FROM channel_htlcs 
7115+         WHERE payment_hash = x'{ payment_hash }  
7116+     """ )
7117+     assert  len (htlcs_after ) ==  len (htlcs )
7118+ 
7119+     for  htlc  in  htlcs_after :
7120+         assert  htlc ['payment_id' ] is  not None 
7121+ 
7122+         # Re-verify linkage integrity after restart 
7123+         payment_check  =  l1 .db_query (f""" 
7124+             SELECT COUNT(*) as count 
7125+             FROM payments 
7126+             WHERE id = { htlc ['payment_id' ]}  
7127+             AND partid = { htlc ['partid' ]}  
7128+             AND groupid = { htlc ['groupid' ]}  
7129+         """ )
7130+         assert  payment_check [0 ]['count' ] ==  1 
7131+ 
7132+ 
7133+ @pytest .mark .openchannel ('v1' ) 
7134+ @pytest .mark .openchannel ('v2' ) 
7135+ def  test_bolt11_payment_id_migration (node_factory ):
7136+     """Test that the migration properly adds payment_id column to channel_htlcs.""" 
7137+     l1 , l2  =  node_factory .line_graph (2 )
7138+ 
7139+     # Create some payments to test migration worked 
7140+     inv1  =  l2 .rpc .invoice (100000 , 'pre_migration_1' , 'Test Description' )['bolt11' ]
7141+     inv2  =  l2 .rpc .invoice (200000 , 'pre_migration_2' , 'Test Description 2' )['bolt11' ]
7142+ 
7143+     l1 .dev_pay (inv1 , dev_use_shadow = False )
7144+     l1 .dev_pay (inv2 , dev_use_shadow = False )
7145+ 
7146+     # Verify payment_id column exists in schema 
7147+     schema  =  l1 .db_query ("SELECT sql FROM sqlite_master WHERE name = 'channel_htlcs'" )
7148+     assert  any ('payment_id'  in  row ['sql' ] for  row  in  schema )
7149+ 
7150+     # Verify index exists 
7151+     indexes  =  l1 .db_query ("SELECT name FROM sqlite_master WHERE type = 'index' AND name = 'channel_htlcs_payment_id_idx'" )
7152+     assert  len (indexes ) ==  1 
7153+ 
7154+     # Verify HTLCs have proper linkage 
7155+     htlcs  =  l1 .db_query ("SELECT payment_id FROM channel_htlcs WHERE payment_id IS NOT NULL" )
7156+     assert  len (htlcs ) >=  2 
0 commit comments