Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 28 additions & 7 deletions tests/test_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
mine_funding_to_announce, first_scid,
CHANNEL_SIZE
)
from pyln.testing.utils import VALGRIND, EXPERIMENTAL_DUAL_FUND, FUNDAMOUNT, RUST, SLOW_MACHINE
from pyln.testing.utils import VALGRIND, EXPERIMENTAL_DUAL_FUND, FUNDAMOUNT, RUST, SLOW_MACHINE, env

import coincurve
import hmac
Expand Down Expand Up @@ -1489,7 +1489,9 @@ def test_funding_cancel_race(node_factory, bitcoind, executor):
bitcoind.generate_block(1)
wait_for(lambda: len(l1.rpc.listfunds()["outputs"]) != 0)

if VALGRIND:
# Under ASan 20 nodes alone use about 12GB, which with the other
# workers' nodes runs a CI runner out of memory.
if VALGRIND or env("ASAN", "0") == "1":
num = 5
elif SLOW_MACHINE:
num = 20
Expand Down Expand Up @@ -1572,7 +1574,9 @@ def test_funding_v2_cancel_race(node_factory, bitcoind, executor):
bitcoind.generate_block(1)
wait_for(lambda: len(l1.rpc.listfunds()["outputs"]) != 0)

if VALGRIND:
# Under ASan 20 nodes alone use about 12GB, which with the other
# workers' nodes runs a CI runner out of memory.
if VALGRIND or env("ASAN", "0") == "1":
num = 5
elif SLOW_MACHINE:
num = 20
Expand Down Expand Up @@ -1610,22 +1614,39 @@ def test_funding_v2_cancel_race(node_factory, bitcoind, executor):

for i, c in enumerate(completes):
try:
# A command that fights over the shared command pointer hangs
# here until TIMEOUT raises TimeoutError (not an RpcError).
c[1].result(TIMEOUT)
completes[i] = (completes[i][0], True)
except RpcError:
completes[i] = (completes[i][0], False)

# Only up to one should succeed.
num_successes = sum(c[1] is True for c in completes)
assert num_successes <= 1, f"Multiple successes in {completes}, cancels = {cancels}"
num_complete += num_successes
# openchannel_update is idempotent: repeating it once the
# commitments are secured just echoes the inflight back, so several
# of these calls may legitimately succeed.
num_complete += sum(c[1] is True for c in completes)

for c in cancels:
try:
c[1].result(TIMEOUT)
num_cancel += 1
except RpcError:
pass

# What must not happen is more than one commitment for this open.
# Check the node's own inflight records rather than comparing the
# returned PSBTs: the inflight's PSBT is mutated in place
# (wally_psbt_combine/psbt_finalize) once tx-signatures arrive, so
# two responses for the same commitment can serialize differently.
inflights = [
inf
for chan in l1.rpc.listpeerchannels(n.info["id"])["channels"]
for inf in chan.get("inflight", [])
]
assert len(inflights) <= 1, (
f"Multiple inflights {inflights}, "
f"completes = {completes}, cancels = {cancels}"
)
# Free up funds for next time
l1.rpc.unreserveinputs(psbt)

Expand Down
Loading