Test that the penalizing node claims any published HTLC transactions Node topology: l1 <-> l2 <-> l3 <-> l4 l4 pushes money to l1, who doesn't fulfill (freezing htlc across l2-l3) we snapshot l2 l2 pushes money to l3 (updating state) l2 + l3 go offline;
(node_factory, bitcoind, chainparams)
| 1147 | @unittest.skipIf(os.getenv('TEST_DB_PROVIDER', 'sqlite3') != 'sqlite3', "Makes use of the sqlite3 db") |
| 1148 | @pytest.mark.slow_test |
| 1149 | def test_penalty_htlc_tx_fulfill(node_factory, bitcoind, chainparams): |
| 1150 | """ Test that the penalizing node claims any published |
| 1151 | HTLC transactions |
| 1152 | |
| 1153 | Node topology: |
| 1154 | l1 <-> l2 <-> l3 <-> l4 |
| 1155 | |
| 1156 | l4 pushes money to l1, who doesn't fulfill (freezing htlc across l2-l3) |
| 1157 | we snapshot l2 |
| 1158 | l2 pushes money to l3 (updating state) |
| 1159 | l2 + l3 go offline; l2 is backed up from snapshot |
| 1160 | l1 fails the channel with l2, fulfilling the stranded htlc onchain |
| 1161 | l2 comes back online, force closes channel with l3 |
| 1162 | |
| 1163 | block chain advances, l2 broadcasts their htlc fulfill tx |
| 1164 | l3 comes back online, sees l2's cheat. takes funds from htlc fulfill tx. |
| 1165 | some blocks are mined. the dust settles. |
| 1166 | |
| 1167 | we check the accounting. |
| 1168 | """ |
| 1169 | |
| 1170 | # We track channel balances, to verify that accounting is ok. |
| 1171 | coin_mvt_plugin = os.path.join(os.getcwd(), 'tests/plugins/coin_movements.py') |
| 1172 | balance_snaps = os.path.join(os.getcwd(), 'tests/plugins/balance_snaps.py') |
| 1173 | |
| 1174 | l1, l2, l3, l4 = node_factory.line_graph(4, |
| 1175 | opts=[{'disconnect': ['-WIRE_UPDATE_FULFILL_HTLC'], |
| 1176 | 'may_reconnect': True, |
| 1177 | 'dev-no-reconnect': None}, |
| 1178 | {'plugin': [coin_mvt_plugin, balance_snaps], |
| 1179 | 'disable-mpp': None, |
| 1180 | 'dev-no-reconnect': None, |
| 1181 | 'may_reconnect': True, |
| 1182 | 'allow_broken_log': True}, |
| 1183 | {'plugin': [coin_mvt_plugin, balance_snaps], |
| 1184 | 'dev-no-reconnect': None, |
| 1185 | 'may_reconnect': True, |
| 1186 | 'allow_broken_log': True}, |
| 1187 | {'dev-no-reconnect': None, |
| 1188 | 'may_reconnect': True}], |
| 1189 | wait_for_announce=True) |
| 1190 | |
| 1191 | channel_id = first_channel_id(l2, l3) |
| 1192 | |
| 1193 | # push some money so that 1 + 4 can both send htlcs |
| 1194 | inv = l2.rpc.invoice(10**9 // 2, '1', 'balancer') |
| 1195 | l1.rpc.pay(inv['bolt11']) |
| 1196 | l1.rpc.waitsendpay(inv['payment_hash']) |
| 1197 | |
| 1198 | inv = l4.rpc.invoice(10**9 // 2, '1', 'balancer') |
| 1199 | l2.rpc.pay(inv['bolt11']) |
| 1200 | l2.rpc.waitsendpay(inv['payment_hash']) |
| 1201 | |
| 1202 | # now we send one 'sticky' htlc: l4->l1 |
| 1203 | amt = 10**8 // 2 |
| 1204 | sticky_inv = l1.rpc.invoice(amt, '2', 'sticky') |
| 1205 | route = l4.rpc.getroute(l1.info['id'], amt, 1)['route'] |
| 1206 | l4.rpc.sendpay(route, sticky_inv['payment_hash'], payment_secret=sticky_inv['payment_secret']) |
nothing calls this directly
no test coverage detected