pytest: fix flake in test_htlc_in_timeout

Since wait_for_onchaind_tx doesn't actually wait for the call to bitcoind to
return, we have a race in checking if the txid is in the mempool.  Fix this
by making wait_for_onchaind_tx actually wait for the response (except for delayed txs!).

```
2024-11-15T07:15:22.0836959Z     def test_htlc_in_timeout(node_factory, bitcoind, executor):
2024-11-15T07:15:22.0837722Z         """Test that we drop onchain if the peer doesn't accept fulfilled HTLC"""
2024-11-15T07:15:22.0838208Z     
2024-11-15T07:15:22.0838585Z         # HTLC 1->2, 1 fails after 2 has sent committed the fulfill
2024-11-15T07:15:22.0839137Z         disconnects = ['-WIRE_REVOKE_AND_ACK*2']
2024-11-15T07:15:22.0839741Z         # Feerates identical so we don't get gratuitous commit to update them
2024-11-15T07:15:22.0840304Z         l1 = node_factory.get_node(disconnect=disconnects,
2024-11-15T07:15:22.0840839Z                                    options={'dev-no-reconnect': None},
2024-11-15T07:15:22.0841285Z                                    feerates=(7500, 7500, 7500, 7500))
2024-11-15T07:15:22.0841673Z         l2 = node_factory.get_node()
2024-11-15T07:15:22.0842278Z         # Give it some sats for anchor spend!
2024-11-15T07:15:22.0842679Z         l2.fundwallet(25000, mine_block=False)
2024-11-15T07:15:22.0843013Z     
2024-11-15T07:15:22.0843342Z         l1.rpc.connect(l2.info['id'], 'localhost', l2.port)
2024-11-15T07:15:22.0843753Z         chanid, _ = l1.fundchannel(l2, 10**6)
2024-11-15T07:15:22.0844058Z     
2024-11-15T07:15:22.0844291Z         sync_blockheight(bitcoind, [l1, l2])
2024-11-15T07:15:22.0844606Z     
2024-11-15T07:15:22.0844958Z         amt = 200000000
2024-11-15T07:15:22.0845713Z         inv = l2.rpc.invoice(amt, 'test_htlc_in_timeout', 'desc')['bolt11']
2024-11-15T07:15:22.0846612Z         assert only_one(l2.rpc.listinvoices('test_htlc_in_timeout')['invoices'])['status'] == 'unpaid'
2024-11-15T07:15:22.0847141Z     
2024-11-15T07:15:22.0847430Z         executor.submit(l1.dev_pay, inv, dev_use_shadow=False)
2024-11-15T07:15:22.0847805Z     
2024-11-15T07:15:22.0848041Z         # l1 will disconnect and not reconnect.
2024-11-15T07:15:22.0848660Z         l1.daemon.wait_for_log('dev_disconnect: -WIRE_REVOKE_AND_ACK')
2024-11-15T07:15:22.0850393Z     
2024-11-15T07:15:22.0851297Z         # Deadline HTLC expiry minus 1/2 cltv-expiry delta (rounded up) (== cltv - 3).  cltv is 5+1.
2024-11-15T07:15:22.0852146Z         # shadow route can add extra blocks!
2024-11-15T07:15:22.0852622Z         status = only_one(l1.rpc.call('paystatus')['pay'])
2024-11-15T07:15:22.0853044Z         if 'shadow' in status:
2024-11-15T07:15:22.0853861Z             shadowlen = 6 * status['shadow'].count('Added 6 cltv delay for shadow')
2024-11-15T07:15:22.0854325Z         else:
2024-11-15T07:15:22.0854547Z             shadowlen = 0
2024-11-15T07:15:22.0854845Z         bitcoind.generate_block(2 + shadowlen)
2024-11-15T07:15:22.0855292Z         assert not l2.daemon.is_in_log('hit deadline')
2024-11-15T07:15:22.0855669Z         bitcoind.generate_block(1)
2024-11-15T07:15:22.0855950Z     
2024-11-15T07:15:22.0856406Z         l2.daemon.wait_for_log('Fulfilled HTLC 0 SENT_REMOVE_COMMIT cltv .* hit deadline')
2024-11-15T07:15:22.0856997Z         l2.daemon.wait_for_log('sendrawtx exit 0')
2024-11-15T07:15:22.0857360Z         l2.bitcoin.generate_block(1)
2024-11-15T07:15:22.0857741Z         l2.daemon.wait_for_log(' to ONCHAIN')
2024-11-15T07:15:22.0858137Z         l1.daemon.wait_for_log(' to ONCHAIN')
2024-11-15T07:15:22.0858644Z     
2024-11-15T07:15:22.0859068Z         # L2 will collect HTLC (iff no shadow route)
2024-11-15T07:15:22.0859741Z         _, txid, blocks = l2.wait_for_onchaind_tx('OUR_HTLC_SUCCESS_TX',
2024-11-15T07:15:22.0860287Z                                                   'OUR_UNILATERAL/THEIR_HTLC')
2024-11-15T07:15:22.0860662Z         assert blocks == 0
2024-11-15T07:15:22.0860908Z     
2024-11-15T07:15:22.0861262Z         # If we try to reuse the same output as we used for the anchor spend, then
2024-11-15T07:15:22.0861951Z         # bitcoind can reject it.  In that case we'll try again after we get change
2024-11-15T07:15:22.0862433Z         # from anchor spend.
2024-11-15T07:15:22.0862768Z         if txid not in bitcoind.rpc.getrawmempool():
2024-11-15T07:15:22.0863354Z             bitcoind.generate_block(1)
2024-11-15T07:15:22.0863735Z >           bitcoind.generate_block(1, wait_for_mempool=1)
2024-11-15T07:15:22.0864019Z 
```

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2024-11-16 10:20:21 +10:30
parent cac20129c6
commit bd0b8e960e

View File

@ -1334,6 +1334,12 @@ class LightningNode(object):
rawtx = re.search(r'.* tx ([0-9a-fA-F]*)', r).group(1)
txid = self.bitcoin.rpc.decoderawtransaction(rawtx, True)['txid']
ret = ret + ((rawtx, txid, blocks),)
# If it's delayed, we get 'Deferring broadcast of txid' on next line, otherwise
# we get 'Broadcasting txid'. In the latter, make sure bitcoind has it!
r = self.daemon.wait_for_log('Deferring broadcast of txid|Broadcasting txid')
if 'Broadcasting txid' in r:
self.daemon.wait_for_log(f"plugin-bcli: sendrawtx exit.*{rawtx}")
return ret
def wait_for_onchaind_tx(self, name, resolve):