@@ -7048,3 +7048,109 @@ def test_htlc_tlv_crash(node_factory):
7048
7048
7049
7049
l1 .rpc .waitsendpay (inv1 ['payment_hash' ], TIMEOUT )
7050
7050
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